A Late-Night Sprint: Unifying UI, Smarter AI, and Taming Deployment Gremlins
A deep dive into a recent development session, covering a significant UI component migration, the introduction of intelligent AI model recommendations, and overcoming common deployment challenges.
It was late, the kind of late where the only sounds are the hum of your server and the click of your keyboard. The mission for the evening: a final push to migrate our ProviderModelPicker UI component across the remaining pages, ensure a critical AI workflow was humming, and ship it all to production. What started as a focused task evolved into a journey through UI consolidation, intelligent AI model selection, and a few valuable lessons learned about deployment and large language model interactions.
The Grand Unification: ProviderModelPicker Takes Center Stage
One of the most satisfying parts of any refactor is watching disparate, redundant code coalesce into a single, elegant solution. Our ProviderModelPicker component was designed to be the single source of truth for selecting AI providers and models throughout our application. This session was about bringing that vision to full fruition.
We tackled three key pages, each previously sporting its own flavor of model selection logic:
src/app/(dashboard)/dashboard/auto-fix/page.tsx: A robustauto-fixinterface, now shedding 52 lines of custom button grid logic.src/app/(dashboard)/dashboard/workflows/new/page.tsx: The entry point for creating new workflows, now 61 lines leaner.src/app/(dashboard)/dashboard/projects/[id]/page.tsx: Our comprehensive project detail page, which previously hosted complex blog and enrichment pickers, saw a massive reduction of 220 lines!
The result? A cleaner codebase, a more consistent user experience, and a much happier future self when it comes to maintenance. With commit a25f6b5 ("feat: migrate remaining pages to ProviderModelPicker component"), the migration was complete, and the old, sprawling src/components/discussion/provider-picker.tsx (183 lines!) was finally retired and deleted.
Under the Hood: The Brains Behind Smart AI Model Selection
Beyond the UI, a significant improvement landed in our AI workflow engine: intelligent provider and model recommendation. Our goal is to ensure that for any given step in a workflow, the optimal LLM is automatically suggested.
We introduced src/server/services/provider-recommendation.ts, a new service designed to auto-recommend the best provider/model based on the type of step:
- LLM-intensive tasks: Default to
google/gemini-2.5-profor its advanced reasoning capabilities. - Review/critique steps: Opt for
anthropic/claude-sonnet-4-6, known for its strong conversational and analytical prowess. - Fast, lightweight operations: Utilize
google/gemini-2.5-flashfor speed and cost-effectiveness.
This service was then wired into our action-points.ts router, ensuring both createWorkflow and createGroupWorkflow benefit from these smart defaults. This isn't just about convenience; it's about optimizing performance, cost, and output quality across our diverse AI-powered features.
Enriching the AI Experience: Wisdom Sources and Truncation Tales
Our note-enrichment.ts service, responsible for providing context to our AI models, also received a significant upgrade. We expanded its "wisdom sources" to include:
consolidationscode_patternsworkflow_insightsmemory_entries
This means our AI now has a much richer tapestry of information to draw from when generating insights and action points.
However, this enhancement brought a classic LLM challenge to the forefront: JSON truncation. When feeding long notes to the enrichment LLM call with a maxTokens limit of 4096, the JSON output would often be cut off mid-parse. This resulted in raw, incomplete JSON displayed in the UI and, critically, zero action points being extracted.
Lesson Learned: Always account for the full potential output size when interacting with LLMs, especially when expecting structured data like JSON.
Our solution involved:
- Increasing
maxTokens: Bumping it up to 16384 dramatically reduced truncation incidents. - Robust Recovery Parser: Implementing a regex-based recovery parser that can gracefully handle partially truncated JSON, ensuring we still extract as much valid data as possible.
This fix was crucial for the reliability of our AI-driven insights. We also took the opportunity to improve our action point extraction prompt, instructing the LLM to scan every subsection and re-scan for verification, leading to more comprehensive and accurate results.
Deployment Adventures: Taming the Docker Beast
No late-night session is complete without a minor deployment hiccup. Earlier in the day, an attempt to deploy with docker compose up -d app while an old container was still running resulted in the dreaded Conflict. The container name is already in use error.
While a quick docker compose down app && docker compose up -d app resolved it then, it's a good reminder of Docker's lifecycle management. Thankfully, for this session's deployment, the Recreate step worked smoothly, indicating it might have been a transient issue or a specific state from the earlier session. It's a small detail, but understanding these little quirks is vital for smooth operations.
Current Status and The Road Ahead
As the night winds down, the system is purring. All UI migrations are committed and deployed successfully. Our Ipcha Mistabra workflow (b29285b4-401b-4f50-a1d6-e739ca89b1ef), a 12-step beast of a process, is currently at step 7, actively utilizing the new auto-recommendation features (Gemini 2.5 Pro for LLM steps, Claude Sonnet 4-6 for reviews).
Immediate next steps include:
- Monitoring the
Ipcha Mistabraworkflow to ensure it progresses smoothly through to the synthesis step. - Cleaning up old tRPC procedures like
discussions.availableProvidersthat are now obsolete. - Exploring new models like Kimi (kimi-k2-0711-preview) for review preferences.
- Laying the groundwork for "Bring Your Own Key" (BYOK) functionality by wiring
userIdinto provider resolution. - Adding RLS policies for our
project_syncstable to enhance security.
It's been a productive session, pushing the boundaries of our AI capabilities while refining our codebase. The journey continues, one commit, one deploy, and one late-night insight at a time.