Skip to content

[Bug]: Orchestrator V2 shows no reasoning effort for subagents #15214

Description

@Vantrongs

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. In a Claude thread, have the agent start a subagent with the Agent tool.
  2. Hover the subagent in the thread's Lineage list.

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: OrchestrationV2Subagent has model but no effort field, and projectedSubagentsToRuntime sets effort: null. For the subagents I checked, the projected records have model: "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_started carries no effort. The sources it lists are the Agent tool input's effort and the effort in 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's modelSelection.options carries it (effort: "high" in the thread I checked). The card builds its label from modelSelection.model alone (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

Subagent tooltip in Lineage: model, status and duration, no effort

Sidebar thread hover card: model without effort

Sidebar thread hover card: model without effort

Workaround

No response

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 3, 2026
  2. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    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 from OrchestrationV2Subagent, which stores model and no effort, through projectedSubagentsToRuntime, which sets effort: null.

    On the server, Claude's V2 adapter only keeps a model for that record: the Agent tool's model, or message.model on a later assistant snapshot. rememberClaudeSubagentLaunch doesn't read an effort field on the Agent tool input. task_started still 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 the effort on 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's modelSelection. When the subagent's model matches the parent's (or no model is known yet at task_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. SidebarThreadTooltip gets only the model label, even though modelSelection.options already has the effort. As you noted, that predates V2.
  3. added
    via-triageFiled through npx t3 triage
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 3, 2026
  4. fixfon commented on Oct 4, 2026

    @fixfon
    Contributor

    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 main at 4ee6bfd / nightly 2648.

    What I saw. A Claude Fable 5.1 thread at xhigh launched several Agent(subagent_type: "gsd-executor", model: "opus") subagents; the agent definition sets effort: high. Opening a subagent's thread, ProviderSubagentBar reads Claude 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 has options:[{effort:"xhigh"},{contextWindow:"1m"}].
    • Provider log: each subagent's task_started has task_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). Two general-purpose subagents without a definition effort show xhigh, the session's.
    • Reproduced on a dev build with a one-line prober agent (effort: high) under a Sonnet 5.5 parent: the subagent prints CLAUDE_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.json marks medium as 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"):

    1. Client fix for the bar: formatModelSelectionEffort names 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.
    2. Report the real effort: register PreToolUse/SubagentStop hooks in ClaudeAdapterV2 (as fix(claude): 🐛 show the effort a subagent actually runs at #13333 did on V1; their input carries agent_id = task_id and effort.level), add effort to OrchestrationV2Subagent, write it into the child thread's selection from syncSubagentThreadModel, and show Model · Effort in the Lineage/timeline tooltips and the mobile row. No fallback to the session effort. Verified live on a dev build: the subagent record gets effort: "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.

  5. spiky02plateau commented on Oct 4, 2026

    @spiky02plateau
    Contributor

    +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 shows Medium for 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 misrouted high job looks identical to a correct medium one.

    #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.

  6. isinghmitesh commented on Oct 5, 2026

    @isinghmitesh

    Also reproduced on macOS with T3 Code Nightly 0.0.46-nightly.20261005.2667 on 2026-10-05.

    A Claude Opus 5.5 parent launched three native Explore agents for read-only searches across three repositories. Our agent definitions pin model: claude-sonnet-5-5 and effort: 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" and perTurnEffort: "medium":

    Agent Assistant records Transcript model Transcript effort
    First repository search 29 claude-sonnet-5-5 medium
    Second repository search 40 claude-sonnet-5-5 medium
    Third repository search 5 claude-sonnet-5-5 medium

    Read-only inspection of statev2.sqlite, table orchestration_v2_projection_threads, showed that the two children with valid model attribution had modelSelection: {"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.

  7. chili-immo commented on Oct 7, 2026

    @chili-immo

    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

    1. Load a custom Codex agent such as ~/.codex/agents/explore.toml with 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."
    2. In a T3 Code Codex conversation, have the parent spawn that role through the native subagent tool (spawn_agent, exposed here as collaboration.spawn_agent), specifying agent_type: "explore" and omitting explicit model / reasoning_effort overrides. Do not use T3's delegate_task for this reproduction.

    3. Inspect the child model/effort label in T3. It displays Luna / Medium.

    4. Inspect the corresponding child rollout under ~/.codex/sessions/ and compare its effective turn_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: child turn_context at rollout line 19 records model = "gpt-6-luna", effort = "max".
    • analyst: child turn_context at 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 explore child sessions, all with a latest child context of gpt-6-luna / max and none with Medium.

    T3's live orchestrator_capabilities catalog 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_context in the Codex rollout; no change to the explicitly configured agent effort was needed in these cases.

    Related reports / proposed mitigation

    No full rollout or unrelated conversation content is attached; the evidence above is limited to the relevant configuration and model/effort fields.

  8. fixfon commented on Oct 10, 2026

    @fixfon
    Contributor

    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 effort parameter, max and xhigh) and the Codex reproduction above (role-pinned max shown 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 ClaudeAdapterV2 report the effort per subagent, it is stored on OrchestrationV2Subagent and in the child thread's selection, and the Lineage tooltip and mobile row show Model · 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions