Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.4 KiB
Handoff: AI-chat thinking-blocks fix (PR #9841)
Branch: glm/fix-copilot-thinking-blocks · base main · file touched: frontend/src/lib/components/copilot/chat/anthropic.ts
The bug
Global AI chat (/sessions, dev-gated) 400s when an assistant turn uses the native
web_search tool while thinking is on AND ends in a tool call:
400 invalid_request_error
messages.N.content.M: `thinking` or `redacted_thinking` blocks in the latest assistant
message cannot be modified. These blocks must remain as they were in the original response.
Root cause: the turn was reconstructed keeping only thinking blocks, reordering them to the
front and dropping the server_tool_use / web_search_tool_result blocks. With interleaved
thinking (a 2nd thinking block after the web-search result) the 2nd block's signature no
longer validates.
What's already done (1 commit)
frontend/src/lib/components/copilot/chat/anthropic.ts:
parseAnthropicCompletion: store the full turn as_anthropicContent = finalMessage.content(replaces the thinking-only_anthropicThinkingBlocksextraction).convertOpenAIToAnthropicMessages: if_anthropicContentis present, emit it verbatim; skip the redundant standalone text message for that turn; the old_anthropicThinkingBlockspath is kept as a fallback for sessions persisted before this change.npm run check:fastpasses. Do NOT commitfrontend/package-lock.jsonchurn (revert if the install/check rewrites it).
Verify (still TODO)
- Run this worktree's frontend against the EE backend: from
frontend/,REMOTE=http://localhost:8000 npm run dev; open it in a browser. - Unlock global chat: DevTools console ->
localStorage.setItem('wm_dev_global_ai','1')-> reload. - Workspace demo-orange -> AI Sessions -> new session (Claude model, effort
high). - Prompt: "Search the web for the current NIST SP 800-63B minimum password length. After you get the number, in a follow-up step list the resources in my workspace. Think step by step between each tool call."
- Expected: Thinking -> web search -> Thinking -> list resources, and the auto-continuation
no longer 400s (on
mainit does). Capture the body to/api/w/demo-orange/ai/proxy/v1/messages: the replayed assistant content should keepthinking,server_tool_use,web_search_tool_resultin original order (not["thinking","thinking","tool_use"]).
Only NEW sessions are fixed — sessions already persisted in the old shape will still fail on continue; start a fresh session to test.
Remaining tasks
- Confirm the repro is fixed in-app; attach before/after screenshots to PR #9841.
- Add a unit test for
convertOpenAIToAnthropicMessages(nearAIChatManager.test.ts/global/core.test.ts): a turn with_anthropicContent = [thinking, server_tool_use, web_search_tool_result, thinking, tool_use]round-trips verbatim, and the preceding standalone text message is skipped. - Sanity-check a plain text turn (no tools) and an old-style session (only
_anthropicThinkingBlocks) still convert via the fallback. npm run check(full) before marking PR ready.- Remove this HANDOFF.md before the PR is marked ready for review.
Deploying to orange-dev preview
Frontend-only fix — cherry-pick the commit onto the preview's frontend branch and rebuild the frontend bundle (no backend/DB change). Already-broken sessions stay broken; verify in a new chat.