Repository navigation
fix(app-shell): the model picked in the AI assistant composer is the model the chat request sends, from the first message on - #33024
Conversation
…s pane remount (#32994) The chat hosts key ChatPane on the conversation id and the first send mints it, so the pane remounts mid-send. The composer's model pick was pane state and died there: the replayed first message sent the default model and the picker snapped back. The hosts (AiChatPage, the console dock, the Studio copilot) now own the pick and pass it to the pane. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4czLbpetCrYUqeRsq85
|
domain:ui#1 · os-elon-musk · session_016WV4cwxNJ1s5i1doop7KEv 席位核对 · ACCEPT ·
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 43370693670 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Requested by Elon · project thread
Fixes #32994
Clause-②: no (a client defect; if a published prop of
@object-ui/plugin-chatbotchanges shape the dev reportsyes)Metadata-protocol: none
维护者速读
ui/packages/app-shell/src/console/ai/AiChatPage.tsx(ChatPane 读宿主传入的选择)、ui/packages/app-shell/src/layout/ChatDockConversation.tsx、新测试AiChatPage.modelPickSurvivesFirstSend-32994.test.tsx。ui/下跑pnpm exec vitest run packages/app-shell/src/console/ai/__tests__/AiChatPage.modelPickSurvivesFirstSend-32994.test.tsx,应见 4 passed。What changes
Every chat host (
AiChatPage, the console dockChatDockConversation, the Studio copilotStudioAiCopilot) keysChatPaneon the conversation id. Since #32058 the first send creates the conversation, so the pane remounts in the middle of every first send of a new conversation. The composer's model pick wasuseStateinsideChatPane(theselectedModelId/effectiveModelIdpair beside theuseAiModelscall), so it died with the old pane: the replayed first message went out withdefaultModelIdand the picker showed the default again. Turns after it sent the default too, until the user picked again.ChatPanetakes two optional props,selectedModelIdandonSelectedModelChange. The three hosts own the pick in their own state (besidependingFirstMessageRef, which survives the same remount for the same reason) and pass it down. Without the props the pane keeps the pick itself, as before. The picker and the request still read one value,effectiveModelId, so the picker cannot show a model other than the one the next request sends.Cause:
ui/packages/app-shell/src/console/ai/AiChatPage.tsx, the pane-localselectedModelIdstate inChatPane, combined with thekeyon conversation id at each host'sChatPanemount.useObjectChat's per-sendmodelRefinjection was correct; it was handed the default.Responsibility: 8523ef9 (#32058, 2026-11-10) "create the AI chat conversation on the first send, not on every visit". Before it the conversation was minted on mount, so the remount happened before a user could pick. After it, every first send remounts the pane.
git merge-base --is-ancestor 8523ef9ac origin/mainexit 0.Bounded in-place fix, declared:
ui/packages/app-shell/src/views/studio-design/StudioAiCopilot.tsxis outside the claim's named file surface. It is the third host with the same keyed mount and the same defect, and the fix is the same two props, so it is fixed here (same defect class, mechanical, no other claim on the file, same test and gate family). The seat amends the claim's file surface.Tests
New
ui/packages/app-shell/src/console/ai/__tests__/AiChatPage.modelPickSurvivesFirstSend-32994.test.tsx, run on both the full-page build composer (AiChatPageat/ai/build) and the console dock (ChatDockConversation), with the realChatPane,useChatConversationanduseObjectChattransport. Themodelis read from the JSON body of each chat POST captured off afetchstub.Ablation (on the fix commit f3a19b4, before the main merge, through
scripts/ablation-replace.mjs):hostHoldsModelforced false, so the pane ignores the host. Both pick cases go red withexpected 'anthropic/claude-haiku-5.5' to be 'anthropic/claude-sonnet-5.5'(the defect as filed), both controls stay green. Restore proven: blob == HEAD,git diff HEADempty.Acceptance notes
ai_traces.model(card acceptance 2) is the seat's; this container has no cloud staging access. NOT MEASURED: a browser check. The dev stack was not booted in this container (it needs a whole-tree build first), and a model picker with more than one entry needs an AI model allowlist the local stack was not checked for. The test drives the real pane, conversation hook and transport instead.Verification
Local, head 501732c (after one merge of main)
pnpm exec vitest run packages/app-shell/src/console/ai packages/app-shell/src/layout/__tests__/ChatDock packages/app-shell/src/layout/__tests__/ConsoleChatbot packages/app-shell/src/views/studio-design(fromui/, under the verify lock): Test Files 392 passed (392), Tests 2894 passed (2894), VERDICT command-exit 0.pnpm --filter @object-ui/app-shell run type-check(src + tsconfig.test.json): exit 0.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 37 families, all exit 0, includingnode scripts/check-sdui-manifest.mjs.--ranreconciliation: 37 derived, 37 run, 0 NOT-MEASURED, 0 UNRUN.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4czLbpetCrYUqeRsq85