[fix] Say why the first turn is parked when no provider key exists [AGE-4232] - #6480
[fix] Say why the first turn is parked when no provider key exists [AGE-4232]#6480ashrafchowdury wants to merge 1 commit into
Conversation
…exists With no AI provider connected, the first message sent from Home showed an optimistic bubble under an assistant loader that never resolved: the seed is parked on the connect-model gate and no run is ever dispatched, so nothing could ever clear the loader. The "+ new session" tab stayed locked for the same reason — the lock waits on a founding run that cannot start. Render an in-thread callout in place of the loader while the gate is active, naming the missing key and opening the providers drawer through the existing `openProviderDrawerRequestAtom` hand-off. Treat an active gate as a settled first run so parallel sessions unlock and the user is never trapped. Closes #6441
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe onboarding hook now releases the new-session lock when the connect-model gate is active. The transcript replaces the indefinite first-turn loader with a provider setup callout and preserves the loader when a turn can start. Tests cover the callout text and setup action. ChangesConnect-model onboarding
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This localized change explains when a first message is waiting for a provider key and unlocks starting another session while preserving the existing setup and send flow; no actionable merge-blocking risk remains after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant PlaygroundOnboarding
participant TranscriptPlaceholder
participant ConnectModelCallout
participant ProviderDrawer
PlaygroundOnboarding->>PlaygroundOnboarding: detect active connect-model gate
PlaygroundOnboarding->>TranscriptPlaceholder: set canStart=false
TranscriptPlaceholder->>ConnectModelCallout: render waiting callout
ConnectModelCallout->>ProviderDrawer: request provider setup
ProviderDrawer-->>ConnectModelCallout: provider key connected
TranscriptPlaceholder->>TranscriptPlaceholder: restore loading state and held turn
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Linked Issues checkExplanation The changes satisfy issue ✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Context
Sign in to a workspace with no AI provider connected, type a first message into the Home composer, and press Enter. The message appears as a sent bubble, a "..." loader appears under it, and it never stops. No run request is ever sent, so nothing is waiting on the server.
The seed is parked on purpose.
useFirstRunSeedholds the send while the connect-model gate is active, and releases it the moment a key lands. That part works. What was missing is any sign of it:TranscriptPlaceholderrendered the assistant loader unconditionally for a pending first turn, so a parked seed and a running seed looked identical.The "+ new session" tab stayed locked for the same reason. Onboarding holds it until the founding run settles, and it waits on a run status. A gated project never produces a run, so the lock never lifted and the user could not start a second chat to get out.
Changes
The pending first turn now branches on the gate.
canStartwas already passed intoTranscriptPlaceholder(it is!modelBlockedat the call site), so no new state was needed.Before, for a parked seed:
After:
The new
ConnectModelCalloutsits in the same borderlessChatBubblethe loader used, so placement and width are unchanged. Its button writesopenProviderDrawerRequestAtom, the same hand-off the failed-run callout already uses, andConnectModelBanneropens the drawer as it does today. No new plumbing, and the existing connect, unlock, and auto-send sequence is untouched.It is deliberately not the failed-run callout. Nothing failed here, because nothing ran.
For the lock,
useAgentOnboardingnow treats an active gate as a settled first run, alongsideerror. Same rule: never trap the user. The candidate atom is swapped for an inert one once the lock is out of play, so a plain playground does not subscribe to the query-backed candidate sources.Tests
ConnectModelCallout.test.tsx, static-render, same shape as the existingAgentMessage.runError.test.tsx.pnpm lint-fixandtscclean. The 5 existingRunErrorBodytests still pass.What to QA
Closes #6441