Conversation
Claude Code can consult a stronger model mid-turn through its advisor tool, but T3 Code had no way to turn it on, and a consult that did run (from the user's own Claude settings) rendered as a generic "Tool call" that spun until the end of the turn. The advisor is a server-side tool: its result arrives in the assistant stream as an `advisor_tool_result` block, never as a `tool_result` user message, so nothing ever closed the item. Adds an "Advisor model" field to the Claude provider settings and passes it to the Agent SDK as the `advisorModel` settings key. Completes the advisor item on its own result block, and titles it "Advisor consult" instead of the generic tool-call label. Written by Claude Opus 5 in Claude Code.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ef51c0d. Configure here.
| title: titleForTool(itemType), | ||
| detail, | ||
| title: isAdvisor ? "Advisor consult" : titleForTool(itemType), | ||
| ...(detail ? { detail } : {}), |
There was a problem hiding this comment.
Advisor title lost on input deltas
Medium Severity
The advisor start path sets title to Advisor consult and omits the empty input summary, but input_json_delta always recomputes title via titleForTool and detail via summarizeToolRequest. Those frames write the generic Tool call label and advisor: {} back onto the in-flight item, so item.completed publishes the label this change was meant to replace.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ef51c0d. Configure here.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR adds a configurable second-model Claude advisor and changes shared stream-processing and timeline behavior, including additional model usage and cost. The new defaulted setting and an unresolved concrete concern about advisor titles being overwritten during input deltas require human review. You can add or adjust custom eligibility rules. Learn more. |
|
Thanks for the PR. We're not taking changes to the orchestration and provider layers right now: that part of the server is being rewritten for V2, and merging into the current code would either conflict with or be thrown away by that work. Closing for now. If this is still an issue once V2 lands, please reopen (or open a fresh PR against the new code) and we'll take a proper look. |


Problem
Claude Code can consult a stronger model in the middle of a turn through its advisor tool. T3 Code had no way to turn this on.
It was also already broken when it did run.
CLAUDE_SETTING_SOURCESincludesuser, so a developer withadvisorModelin~/.claude/settings.jsonalready got advisor consults inside T3 Code. The advisor is a server-side tool: theserver_tool_useblock opens the item, but the result arrives in the assistant stream as anadvisor_tool_resultblock, never as atool_resultuser message.handleUserMessageis the only path that completes a tool item, and it matches ontool_result, so nothing closed the item. The consult rendered as a generic "Tool call" and spun until the end-of-turn sweep swept it up — a lying spinner.Fix
advisorModelsettings key.advisor_tool_resultblock arrives, matched bytool_use_idrather than block index (the result lands at a different index from the request).The settings key is deliberate, not the hidden
--advisorCLI flag. The flag aborts session start when the advisor cannot advise the thread model; the settings path logs and runs the turn without an advisor, which is the behavior you want for a per-instance setting.Before / after
Claude provider settings, Runtime section:
The field is derived from the contracts schema by
deriveProviderSettingsFields, so web and desktop pick it up with no component change. Mobile has no provider config form, so there is nothing to add there.Tests
ClaudeAdapter.test.ts: the advisor model reaches the SDK, is omitted when the field is empty, and the item completes on its result block. The completion test emits noresultmessage on purpose, so the end-of-turn sweep cannot mask the bug. Stubbing the new branch out makes it hang and fail.settings.test.ts: default, round-trip, and server-patch decoding for the new field.ProviderSettingsForm.test.ts: field order.Not in this PR
usage.iterationscarriesadvisor_messageentries and the finalmodelUsagegains a separate entry for the advisor model with its owncostUSD, butemitThreadTokenUsagereads top-level usage only. Advisor spend stays invisible in the context meter. That is a separate change./advisorin the composer. Claude's init message lists it, so it appears in the command menu and does nothing useful, because it is an interactive picker that mutates Claude's ownsettings.json. That is why this PR is a setting and not a chat command. T3 Code forwards every Claude built-in unfiltered, so/model,/config, and about forty others behave the same way. Filtering interactive-only commands is a separate concern.Written by Claude Opus 5 in Claude Code.
Note
Medium Risk
Touches Claude stream event handling and session settings for a server-side tool path; mistakes could leave tool items stuck or mis-complete unrelated tools, but scope is narrow and heavily tested.
Overview
Adds a configurable Advisor model on the Claude provider (contracts + settings UI field order) and forwards it to the Agent SDK as
advisorModelwhen set, omitting it when empty so Claude Code’s own config can apply.Fixes advisor timeline handling in
ClaudeAdapter: the advisor is a server-side tool whose result arrives as anadvisor_tool_resultstream block (not a usertool_result). The adapter now completes the in-flight tool item when that block arrives (matched bytool_use_id), labels it Advisor consult without empty input detail, and keepsadvisor_tool_resultblocks from being dropped in subagent stream filtering.Tests cover SDK option wiring, completion without an end-of-turn sweep, settings decode/patch, and provider form fields; user docs describe
fable/opus/sonnetand capability rules.Reviewed by Cursor Bugbot for commit ef51c0d. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add
advisorModelsetting to Claude provider and handle advisor tool lifecycle inClaudeAdapteradvisorModelas a trimmed-string field toClaudeSettingsandClaudeSettingsPatchin settings.ts, with an empty default and a form-field position betweenhomePathandautoCompactWindow.makeClaudeAdapterin ClaudeAdapter.ts now passes a non-emptyadvisorModelinto Claude query settings, and handles advisor tool blocks: advisor tool starts use the title "Advisor consult" and omit the generic empty-input detail; advisor result blocks (typeadvisor_tool_result) from nested streams complete the in-flight advisor item by tool-use ID, emittingitem.completedwith no result text.Macroscope summarized ef51c0d.