Repository navigation
fix(web,mobile): /side starts the side chat on the composer's model - #31847
juliusmarminge wants to merge 4 commits into
Conversation
The fake environment can now offer side chats, answers a fork by listing the new thread in the shell, and records dispatched commands. The new ChatView test picks a model in the composer that differs from the thread's saved one, sends `/side ...`, and expects the side chat's turn to carry the picked model. It fails on main: the turn has no modelSelection, so the server falls back to the forked thread's model. AI-assisted; verified with the tests and tools listed above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The model picked in the composer is only a client draft until a message is sent, and both clients dropped it on the `/side` path, so the side chat's first turn ran on the thread's saved model. Carry the composer's model selection through `/side` into the side chat's first startTurn as `modelSelection`: on web from the send context's selection, on mobile from `draft.modelSelection ?? thread.modelSelection`, the same value a normal send uses. The server already prefers a turn's modelSelection over the thread's. The web fake environment now pushes its server config to a live subscription on install, so a test's `sideChats` option reaches an app whose connection outlived the previous test. The mobile composer test now asserts the picked model reaches startSideChat. AI-assisted; verified with the tests and tools listed above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without a usable provider the composer's selection is the no-provider placeholder, which must never be dispatched; the side chat then falls back to the model it forked with, as before. AI-assisted; verified with the tests and tools listed above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — The /side command now uses the composer's selected model on web and mobile, while retaining existing fallback and failure handling. The change is limited to explicitly initiated side-chat sends and leaves product defaults unchanged. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Thanks @juliusmarminge for the fix and thorough verification! #32315 by @Iweisc landed as e455200077 and already carries the composer model selection into side chat turns on web and mobile, so I’m closing this as covered. |
Problem
/side <question>ignored the model picked in the composer and started the side chat on the thread's saved model. Repro on main (6f54322e4a), web dev server, fresh database: send one message on GPT-6-Astra, switch the composer's picker to GPT-6-Luna (or Claude Haiku 5.5) without sending, then send/side Reply with the single word: ping. The side chat's first run usedcodex/gpt-6-astrain both cases, while the composer still showed the picked model.Change
The composer's model selection is only a client draft until a message is sent, and the
/sidepath never forwarded it: the side chat's firststartTurnhad nomodelSelection, so the server used the model the fork copied from the parent.useComposerSendpassessendCtx.selectedModelSelection(the same selection a normal send uses) toonSideChat;ChatViewhands it touseSideChat.open, which adds it to the side chat's firststartTurn. When the composer has no usable provider the selection is the no-provider placeholder, so nothing is passed and the side chat keeps the model it forked with. The prompt-less "open side chat" entry points send no turn and are unchanged.useThreadComposerStatepassesdraft.modelSelection ?? thread.modelSelection(the normal send's value) touseStartSideChat, which adds it tostartTurn.No server or contract change:
modelSelectionon a turn start already exists, and the server already handles a provider switch on a side chat's first turn (portable context handoff).Scope and approval
Fixes #31831
Verification
vp test run src/components/ChatView.browser.test.tsx(apps/web): new test/side starts the side chat on the model picked in the composerfails on main withexpected undefined to deeply equal { instanceId: 'codex', model: 'gpt-5.5' }and passes with the fix (2/2 in the file). The shared web test fake (apps/web/test/fakeEnvironment.ts) gains an opt-in side-chat capability, a second Codex model, command answers and command recording for it.vp test run src/state/thread-task-permissions.test.ts(apps/mobile): the existing/sidetest now picks a model different from the thread's and asserts it reachesstartSideChat(11/11).vp run typecheckin apps/web and apps/mobile;vp run check:changed.6f54322e4a, after the branch head). Persisted model of each side chat's first run (orchestration_v2_projection_runs):6f54322e4a)/side …codex/gpt-6-astracodex/gpt-6-luna/side …codex/gpt-6-astraclaudeAgent/claude-haiku-5-5(context handoff 6 Astra → Haiku 5.5 shown in the side chat)The side chat (right panel) composer chip shows the model its run used; the main composer shows the pick.
6f54322e4a)Capture environment: T3 preview browser (Chromium), no device emulation, DPR 1, 1280×800, light theme; each side's own dev server on a fresh database (
T3CODE_DEV_SEED=0), driven through the UI with the steps above. No diff images: the before/after differ by design in the run model shown, and the frames come from separate live runs.Not checked: the mobile client on a device (covered by the mobile unit test and typecheck only), desktop (wraps the web code path).
AI-assisted; verified with the tests and tools listed above.