resume_agent restores subagent history but not original model/reasoning settings
What version of Codex CLI is running?
Observed while investigating codex-cli 0.137.0; I also checked current main and did not find resume-time restoration of the child thread model/reasoning settings from the rollout TurnContextItem.
What subscription do you have?
N/A - source-level bug report.
Which model were you using?
N/A. The bug is about resuming a previously spawned subagent whose stored turn context used a different model/reasoning effort than the parent/current session.
What platform is your computer?
Linux x86_64.
What terminal emulator and version are you using, if applicable?
N/A.
Codex doctor report
Not available for this source-level report.
What issue are you seeing?
resume_agent can restore a subagent thread history without restoring the subagent's original runtime model/reasoning settings.
For a spawned custom subagent, the rollout contains TurnContextItem entries recording the child turn context, including model, explicit effort, and/or collaboration_mode. However, the resume path constructs the resumed session from the caller-provided/current Config and the rollout history. It does not appear to apply the latest persisted TurnContextItem back onto the Config before starting the resumed session.
The result is that a resumed subagent can silently run under the current parent/default model and reasoning effort rather than the child thread's original custom-agent settings. This is especially visible for project/custom agents that pin a cheaper or narrower model, e.g. model = "gpt-5.4-mini" and model_reasoning_effort = "medium", while the parent uses a larger/high-effort model.
What steps can reproduce the bug?
One source-level reproduction approach:
- Spawn a custom subagent whose role config sets a different model/reasoning effort than the parent session, for example:
name = "researcher"
model = "gpt-5.4-mini"
model_reasoning_effort = "medium"
developer_instructions = "Act as a read-only researcher."
- Let the child run at least one turn so the rollout persists a
TurnContextItemfor the child with that model/reasoning configuration.
- Resume the child thread via
resume_agentfrom a parent/current config using a different model/reasoning effort.
- Inspect the resumed session config or emitted turn context. The resumed session can use the current/default config instead of the latest persisted child
TurnContextItem.
A focused unit test also demonstrates the issue: build a stored rollout with a latest RolloutItem::TurnContext whose model and effort differ from the supplied resume config, invoke the resume path, and assert the resumed config uses the rollout values. That assertion fails without applying the persisted turn context before session creation.
What is the expected behavior?
When resuming a subagent thread, Codex should preserve the subagent's original runtime settings from the latest persisted child TurnContextItem, at least for:
model- explicit
effort, or the effort implied bycollaboration_modewheneffortis absent
This keeps resumed custom agents consistent with the model/reasoning configuration they were spawned with.
Additional information
A minimal patch outline that worked locally:
- in the resume-from-rollout path, after loading rollout history and before constructing the resumed session, find the latest
RolloutItem::TurnContext; - set
config.model = Some(turn_context.model.clone()); - set
config.model_reasoning_effort = turn_context.effort.or_else(|| turn_context.collaboration_mode.as_ref()?.reasoning_effort()); - add regression coverage that resumes from a rollout whose latest
TurnContextItemuses a different model/effort than the supplied config.
This is related to custom subagent configuration issues such as #26363/#26408, but it is a separate resume-time consistency problem: even if spawn applies the custom role correctly, resume can lose the child's original runtime settings.
3 Comments
Possible implementation direction:
The resume path can restore the child runtime settings from the latest persisted
RolloutItem::TurnContextbefore constructing the resumed session.Roughly:
Then call this after loading rollout history and before creating/starting the resumed session.
A focused regression test would build a rollout history whose latest
TurnContextItemhas a differentmodelandeffortthan the supplied resume config, then assert the resumed session config uses the rollout values.resume_agentshould restore the child runtime profile as part of the child thread, not inherit it from the current parent.Persisted turn context can be treated as the source of truth for child model, reasoning effort, sandbox/approval, tool profile, and provider. On resume, emit a small drift warning if the resumed child differs from the stored profile.
That makes cost and behavior changes auditable.
---
_Generated with ax._
<!-- codex-26718:auto-reload-diagnosis -->
While investigating a separate cross-thread settings issue in #26930, I traced this report against current
mainat393f64565ab46f09d99ca4d9bd973537e72a114b. The configuration-ownership problem is still present, and there is an additional automatic trigger beyond explicitresume_agent: delivering a message to an unloaded/evicted V2 agent.Confirmed automatic-reload path
send_message/followup_taskcallsbuild_agent_resume_config(turn)using the sender's turn before ensuring that the recipient is loaded:https://github.com/openai/codex/blob/393f64565ab46f09d99ca4d9bd973537e72a114b/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs#L92-L97
https://github.com/openai/codex/blob/393f64565ab46f09d99ca4d9bd973537e72a114b/codex-rs/core/src/tools/handlers/multi_agents_common.rs#L181-L199
ThreadManager,ensure_v2_agent_loadedresumes the target using that supplied config:https://github.com/openai/codex/blob/393f64565ab46f09d99ca4d9bd973537e72a114b/codex-rs/core/src/agent/control/spawn.rs#L221-L283
Loaded recipients are unaffected because
ensure_v2_agent_loadedreturns before consuming the sender-derived config. The defect appears only when the logical recipient is still registered but its runtime session has been unloaded.Merged PR #26623 introduced reload-on-delivery. Its regression uses the same configuration for sender and recipient, so it proves history/message recovery but cannot detect profile inheritance:
https://github.com/openai/codex/blob/393f64565ab46f09d99ca4d9bd973537e72a114b/codex-rs/core/src/agent/control_tests.rs#L592-L685
Focused regression
A test that should fail on current
main:send_message.ThreadConfigSnapshotstill reports A.The same shared restoration behavior should cover explicit
resume_agent; either one shared control-level regression plus a delivery integration test, or focused coverage for both entry points, would make the ownership boundary clear.Smallest fix boundary
Keep the change in subagent resume/reload rather than generic thread-start override semantics. Before constructing the resumed subagent session, treat the stored target thread's latest model and reasoning effort as target-owned state and overlay them onto the caller-derived fallback config. Model and effort already exist in stored thread metadata and are synchronized from target turn/settings events.
Provider restoration is adjacent, but model plus effort is the smallest issue-backed correction. I would avoid bundling sandbox/tool-profile restoration until their resume ownership contract is explicit.
Codex's contribution guide says external PRs are invitation-only, so I have not opened one. Would maintainers like an external implementation of this scoped fix and regression? I can prepare it if invited.