[Bug]: Native Codex subagents show the parent's reasoning effort instead of the one passed to spawn_agent#24435

opened5d agobyTthomlei

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. Start a Codex thread on gpt-6.1-sol with reasoning effort set to Low.
  2. Have the agent start a native subagent with Codex's spawn_agent and an explicit effort, for example {"model":"gpt-6.1-sol","reasoning_effort":"xhigh","fork_turns":"none","message":"..."}.
  3. Open the subagent's thread in T3. The subagent bar shows Low. t3_thread_configuration for the child thread also returns reasoningEffort: "low".
  4. Open the child's Codex rollout in ~/.codex/sessions/. Its turn_context has effort: "xhigh", and its thread_settings_applied event has reasoning_effort: "xhigh".

Expected behavior

The subagent shows the effort it runs at (Extra High here), or no effort until T3 knows it, as #15214 decided.

Actual behavior

The child thread shows the effort its parent had when it spawned the child, and ignores the reasoning_effort passed to spawn_agent. I checked three runs on the same day. All used gpt-6.1-sol for parent and children, and every child was spawned with reasoning_effort: "xhigh":

Parent effort at spawnT3 label on the childChild rollout turn_context.effort
LowLowxhigh
Extra HighExtra Highxhigh
LowLow (3 children)xhigh

Agents that check a child with t3_thread_configuration get the same wrong value. In my case the parent agent first told me the children ran at Low.

A read-only check of statev2.sqlite for the three children of the last run shows:

  • orchestration_v2_projection_threads: the child's modelSelection is the parent's, {"instanceId":"codex","model":"gpt-6.1-sol","options":[{"id":"reasoningEffort","value":"low"},{"id":"serviceTier","value":"default"}]}.
  • orchestration_v2_projection_subagents: model: null, modelSelection: null.
  • orchestration_v2_projection_provider_threads: nativeMetadata: null.

Likely cause

Code on main @ d53873b6a4. The same code is in v0.1.2.

  1. registerSubagentThread creates the child thread with { ...input.context.input.modelSelection, model: ... } (CodexAdapterV2.ts#L2894-L2897). This copies the parent's reasoningEffort and serviceTier options into the child. Only the model is replaced.
  2. An effort learned later, from thread/settings/updated or the thread/read recovery, goes through updateSubagentSelection and subagent.updated. That updates only the subagent record (ProjectionStore.ts#L872). The child thread's modelSelection stays unchanged.
  3. The subagent bar takes its label from formatModelSelectionEffort(activeThread.modelSelection, ..., reportedModelSelection) (ChatView.tsx#L1694-L1701). getProviderOptionStatedValue returns the thread's explicit option before any reported value (model.ts#L230-L239). So the copied parent effort wins, even when a reported value exists.

In this run the subagent records also got no selection at all. Their stored model is null, so the thread/read recovery at CodexAdapterV2.ts#L3031 should have run, but nothing was stored. The data I have doesn't show why.

A possible fix: don't copy the parent's effort options into a native child's selection. Use the spawn item's reasoningEffort when present, otherwise leave the effort unset, and update the child thread's selection when Codex reports the effort.

Related

  • #17694 reported the same copy for a native Codex child with a different model and effort. It was closed as the same root cause as #15896.
  • #15214 was closed after display support was verified on a delegated Codex child. Native Codex children weren't tested there.
  • The open PRs #21493 and #17420 don't change this case. #21493 only adds the recovery when the model is known and the effort isn't, and it writes to the subagent record. #17420 reads the subagent record for subagent list rows, not for the child thread's bar.
  • #24143 is the same kind of problem for Claude subagents.

Impact

Minor bug or occasional failure

Version or commit

T3 Code v0.1.2 (desktop). The same code is on main @ d53873b6a4.

Environment

Windows 11 Pro, T3 Code desktop v0.1.2, Codex CLI 0.164.0, gpt-6.1-sol

Logs or stack traces

shell
1# Parent rollout, spawn call (excerpt, prompt shortened)
2spawn_agent {"task_name":"..._a0001","fork_turns":"none","model":"gpt-6.1-sol","reasoning_effort":"xhigh","message":"..."}
3
4# Child rollout (excerpt)
5{"type":"turn_context","payload":{"model":"gpt-6.1-sol","effort":"xhigh","collaboration_mode":{"settings":{"model":"gpt-6.1-sol","reasoning_effort":"xhigh"}}, ...}}
6{"type":"event_msg","payload":{"type":"thread_settings_applied","thread_settings":{"model":"gpt-6.1-sol","reasoning_effort":"xhigh", ...}}}
7
8# t3_thread_configuration for the same child
9{"modelSelection":{"instanceId":"codex","model":"gpt-6.1-sol","options":[{"id":"reasoningEffort","value":"low"},{"id":"serviceTier","value":"default"}]}}

Screenshots, recordings, or supporting files

No response

Workaround

Before spawning, set the parent thread to the effort the children use. The child rollouts in ~/.codex/sessions/ show the effort the children actually ran at.