Repository navigation
[Bug]: Orchestrator V2 shows no reasoning effort for subagents #15214
Description
Activity
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.needs-triageIssue needs maintainer review and initial categorization.Issue needs maintainer review and initial categorization.
on Oct 3, 2026 Note
Grok responding on behalf of Julius.
Triage
Thanks @Vantrongs for tracing this through the contracts and checking the transcripts. I confirmed it on current
main. This is a real follow-up to #14842 (closed), not a duplicate. That issue was closed because Orchestrator V2 stopped labeling every subagent with the parent session's effort. Now the Lineage tooltip shows no effort at all, even when Claude Code's own transcript already recorded one.What I found
The tooltip in your screenshot is
SubagentTooltipContent. It renders the subagent's model, status, and duration, and has no effort slot. Its data comes fromOrchestrationV2Subagent, which storesmodeland no effort, throughprojectedSubagentsToRuntime, which setseffort: null.On the server, Claude's V2 adapter only keeps a model for that record: the Agent tool's
model, ormessage.modelon a later assistant snapshot.rememberClaudeSubagentLaunchdoesn't read aneffortfield on the Agent tool input.task_startedstill has no effort field, and the SDK's assistant message (BetaMessage) doesn't carry one either. The"effort":"high"values you found are on Claude Code's transcript records, which this path doesn't read.Likely fix area
A maintainer will decide on the fix direction. Copying the parent thread's effort into the tooltip would bring back #14842, so the safer shape is to show the effort the subagent actually ran at and nothing until it's known. For a Claude subagent the possible sources are the Agent tool input's
effort, the agent definition's frontmatter, and theefforton its transcript assistant records. Falling back to the session effort is only correct when none of those set one.Related surfaces
- Opening the subagent's own thread uses
ProviderSubagentBar, which formats the effort from that child thread'smodelSelection. When the subagent's model matches the parent's (or no model is known yet attask_started), the child keeps the parent's selection, so that bar can show the session effort. When the model differs, the child selection is only{ instanceId, model }, and the bar shows the catalog default rather than the transcript value. - The sidebar thread hover card is a separate change.
SidebarThreadTooltipgets only the model label, even thoughmodelSelection.optionsalready has the effort. As you noted, that predates V2.
- Opening the subagent's own thread uses
- addedvia-triageFiled through npx t3 triageFiled through npx t3 triageand removedneeds-triageIssue needs maintainer review and initial categorization.Issue needs maintainer review and initial categorization.
on Oct 3, 2026 Same bug on macOS desktop 0.0.46-nightly.20261004.2644 (Claude Code 2.1.289, Agent SDK 0.3.276), with the "wrong value" variant of the related surface in the triage note. Still present on
mainat 4ee6bfd / nightly 2648.What I saw. A Claude Fable 5.1 thread at
xhighlaunched severalAgent(subagent_type: "gsd-executor", model: "opus")subagents; the agent definition setseffort: high. Opening a subagent's thread,ProviderSubagentBarreadsClaude Opus 5.5 Medium.Evidence.
statev2.sqlite→orchestration_v2_projection_threads: the child threads have"modelSelection":{"instanceId":"claudeAgent","model":"claude-opus-5-5"}with no options; the parent hasoptions:[{effort:"xhigh"},{contextWindow:"1m"}].- Provider log: each subagent's
task_startedhastask_id,tool_use_id,description,subagent_type,is_backgrounded,spawn_depth,task_type,prompt; no model or effort. 103 streamed assistant events, none with an effort field. - Claude Code transcripts (
subagents/agent-<id>.jsonl, metadata only): every assistant record has"effort":"high"and"model":"claude-opus-5-5"(197, 212, 163, 110, 32 records across five executors). Twogeneral-purposesubagents without a definition effort showxhigh, the session's. - Reproduced on a dev build with a one-line
proberagent (effort: high) under a Sonnet 5.5 parent: the subagent printsCLAUDE_EFFORT=high, the bar says Medium. - The label comes from
formatModelSelectionEffort→getProviderOptionCurrentLabel, which with no stated option falls back to the catalog default;model-manifest.jsonmarksmediumas Opus 5.5's default.
So the bar is not showing a stale or inherited value; it shows the catalog default for a selection that has no effort at all.
Proposed split, following the triage note's direction ("the effort the subagent actually ran at and nothing until it's known"):
- Client fix for the bar:
formatModelSelectionEffortnames an effort only when the selection states one or the provider reported one; a catalog default is not the subagent's effort. Small, tested, no new data. Opened as fix(clients): subagent bar stops guessing the subagent's effort #15710. - Report the real effort: register
PreToolUse/SubagentStophooks inClaudeAdapterV2(as fix(claude): 🐛 show the effort a subagent actually runs at #13333 did on V1; their input carriesagent_id=task_idandeffort.level), addefforttoOrchestrationV2Subagent, write it into the child thread's selection fromsyncSubagentThreadModel, and showModel · Effortin the Lineage/timeline tooltips and the mobile row. No fallback to the session effort. Verified live on a dev build: the subagent record getseffort: "high"and the bar and tooltip show High. This overlaps fix(web): show subagent effort and speed in hover cards #13056 (saved effort for app-owned subagents in the same tooltips); the two are complementary. I would like your approval of this direction and scope before opening it, per CONTRIBUTING.
Happy to adjust either if you prefer a different shape.
+1 to the step 2 direction from @fixfon, reading the real effort from the hooks.
My setup depends on this. I keep a few agent definitions that differ only in
effort:frontmatter (medium,high,xhigh), and the parent picks one per task. With Opus 5.5 children, the bar showsMediumfor all of them today, which is the catalog default. So I can't tell from the UI whether a task went to the agent I meant, and a misroutedhighjob looks identical to a correctmediumone.#15710 stops the wrong label, which already helps. Showing the effort the subagent actually ran at, next to the model in Lineage and on mobile, would close the loop.
Also reproduced on macOS with T3 Code Nightly
0.0.46-nightly.20261005.2667on 2026-10-05.A Claude Opus 5.5 parent launched three native
Exploreagents for read-only searches across three repositories. Our agent definitions pinmodel: claude-sonnet-5-5andeffort: medium. T3 displayed all three subagents as Sonnet 5.5 at high effort.I checked the underlying Claude Code subagent JSONL transcripts. All 74 Sonnet assistant records had both
effort: "medium"andperTurnEffort: "medium":Agent Assistant records Transcript model Transcript effort First repository search 29 claude-sonnet-5-5mediumSecond repository search 40 claude-sonnet-5-5mediumThird repository search 5 claude-sonnet-5-5mediumRead-only inspection of
statev2.sqlite, tableorchestration_v2_projection_threads, showed that the two children with valid model attribution hadmodelSelection: {"instanceId":"claudeAgent","model":"claude-sonnet-5-5"}with no effort options. The third child's model selection was<synthetic>after a usage-limit error, although its preceding 40 Sonnet assistant records consistently recorded medium effort.This confirms the missing-effort metadata on this build. The high label is the user's UI observation; we have not traced which formatting path selected that label. The transcripts indicate that the agents ran at the configured medium effort.
Related to #15896, with the mismatch in the opposite direction. Showing the recorded effort, or leaving it unknown until reported, would avoid this confusion.
Investigated and posted with Codex on the user's behalf, using local transcript metadata and read-only T3 state inspection.
Codex-specific reproduction: native Luna/Max subagents displayed as Medium
Adding a Codex reproduction to this existing issue rather than opening a duplicate. The mismatch affects native Codex subagents, not only Claude or tasks launched through T3's
delegate_task.Environment
- T3 Code Nightly 0.0.46-nightly.20261007.2774 (running desktop app).
- Codex CLI / harness 0.160.0.
- macOS 26.5.2, arm64.
- Parent: gpt-6.1-sol / ultra.
- Child roles: custom explore and analyst, configured for gpt-6-luna / max.
- Observed on October 7, 2026.
Steps to reproduce
-
Load a custom Codex agent such as
~/.codex/agents/explore.tomlwith explicit model and effort:name = "explore" description = "Read-only codebase exploration." model = "gpt-6-luna" model_reasoning_effort = "max" developer_instructions = "Inspect the assigned files and return concise evidence. Do not edit files."
-
In a T3 Code Codex conversation, have the parent spawn that role through the native subagent tool (
spawn_agent, exposed here ascollaboration.spawn_agent), specifyingagent_type: "explore"and omitting explicitmodel/reasoning_effortoverrides. Do not use T3'sdelegate_taskfor this reproduction. -
Inspect the child model/effort label in T3. It displays Luna / Medium.
-
Inspect the corresponding child rollout under
~/.codex/sessions/and compare its effectiveturn_context: gpt-6-luna / max. When the rollout contains a forked parent prefix, use the child's own current/latest context, not an earlier inherited parent context.
Expected behavior
T3 should display the child's recorded effective effort, Max. If it has not received that information, it should show an unknown/omitted value rather than present the model's catalog default as the child's actual effort.
Actual behavior and evidence
Two native children spawned during the same conversation both displayed Luna / Medium in T3, as confirmed by the user viewing the app:
explore: childturn_contextat rollout line 19 recordsmodel = "gpt-6-luna",effort = "max".analyst: childturn_contextat rollout line 20 records the same model and effort.
Relevant field-only excerpt from each child context (other fields omitted):
{"type":"turn_context","payload":{"model":"gpt-6-luna","effort":"max"}}This is not just a discrepancy with the intended TOML settings: the runtime rollout records Max for both children. A bounded check of the newest 40 rollout files from that day also found nine
explorechild sessions, all with a latest child context of gpt-6-luna / max and none with Medium.T3's live
orchestrator_capabilitiescatalog advertises medium as Luna's default. That is consistent with the catalog-default fallback discussed in this issue; the exact metadata-loss point for this Codex reproduction has not been independently traced in source.Impact / workaround
The label makes correctly configured Max-effort delegation appear to have silently downgraded to Medium. This undermines confidence in model routing and agent settings. The available workaround is to inspect the child's own
turn_contextin the Codex rollout; no change to the explicitly configured agent effort was needed in these cases.Related reports / proposed mitigation
- [Bug]: Subagent thread bar shows Medium for a Claude subagent that runs at high effort #15896: related Claude reproduction of the misleading subagent effort label.
- fix(clients): subagent bar stops guessing the subagent's effort #15710: proposed mitigation to stop guessing an unreported child effort; this would avoid a false Medium label, but displaying the recorded Max still requires effective child metadata.
- Subagent reasoning level is displayed incorrectly openai/codex#14965: upstream Codex precedent where a role-pinned child effort differs from the spawn banner. That report concerns Codex's own display, whereas this reproduction is the T3 display.
No full rollout or unrelated conversation content is attached; the evidence above is limited to the relevant configuration and model/effort fields.
Status and one question, no rush.
#15710 is still the small client-only fix (the subagent bar names an effort only when the selection or the provider states one). Since it was opened, three more reports landed with the same shape: #15896 (Agent tool
effortparameter,maxandxhigh) and the Codex reproduction above (role-pinnedmaxshown as Medium). Each has transcript or rollout evidence that the child ran at the configured effort. That fix removes the false Medium on all of them, for any provider, since the rule is provider-agnostic.Showing the real value is the second step I described above: hooks in
ClaudeAdapterV2report the effort per subagent, it is stored onOrchestrationV2Subagentand in the child thread's selection, and the Lineage tooltip and mobile row showModel · Effort. It is built and verified locally. Per CONTRIBUTING I have not opened it. It would be Claude-only for now; a Codex source would need its own change.Question for the maintainers: is that direction and scope acceptable, so I can open it as a separate PR that links back here? If you would rather keep the fix to #15710 alone, or fold the data source into #13056, that works too and I will adjust.
Before submitting
Area
apps/server
Steps to reproduce
Expected behavior
Next to the model, the subagent shows the reasoning effort it runs at, as the Agents panel did before V2, or nothing when T3 can't know it.
Actual behavior
The tooltip shows the model (
Claude Opus 5.5), the status and the duration, and no effort. The effort never reaches the client:OrchestrationV2Subagenthasmodelbut no effort field, andprojectedSubagentsToRuntimesetseffort: null. For the subagents I checked, the projected records havemodel: "claude-opus-5-5"and no effort, while each assistant record in their Claude Code transcripts has"effort":"high".#14842 was closed as resolved by Orchestrator V2: the wrong effort it reported is gone because no effort is shown at all. As it found, the SDK's
task_startedcarries no effort. The sources it lists are the Agent tool input'seffortand theeffortin the agent definition's frontmatter. Without either, I assume the subagent runs at the session's effort, but I haven't verified that.The thread's own effort isn't shown either. The sidebar hover card for a thread lists the project, environment, branch and model (
Claude Opus 5.5), but not the effort, although the thread'smodelSelection.optionscarries it (effort: "high"in the thread I checked). The card builds its label frommodelSelection.modelalone (Sidebar.tsx). This was the same before V2, so it isn't a regression, but with both in place you could see at a glance what each thread and subagent runs at.Impact
Minor bug or occasional failure
Version or commit
0.0.46-nightly.20261003.2623 (fed41fa)
Environment
Desktop app on Linux (NixOS, Wayland, niri); Claude Code 2.1.288, Opus 5.5
Logs or stack traces
No response
Screenshots, recordings, or supporting files
Subagent tooltip in Lineage: model, status and duration, no effort
Sidebar thread hover card: model without effort
Workaround
No response