feat(codex): support explicit model or custom role per spawned subagent
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
**Motivation**
Buzz-managed Codex agents cannot currently select a lower-cost model or a
model-pinned custom-agent profile for one delegated task without changing the
model resolution for every subagent.
The live `spawn_agent` interface exposes:
- a task name and prompt;
- `gpt-5.6-sol` and `gpt-5.6-terra` as explicit model overrides; and
- no custom-agent role/profile selector.
This prevents a strong primary agent from delegating one bounded task to a
profile pinned to another available model such as `gpt-5.6-luna`, while leaving
ordinary subagent work unchanged.
### Verified reproduction
Environment: Buzz ACP managed Codex session on macOS, Codex CLI 0.145.0.
1. Create `.codex/agents/luna-worker.toml`:
```toml
name = "luna_worker"
description = "Bounded low-cost implementation worker."
model = "gpt-5.6-luna"
model_reasoning_effort = "max"
developer_instructions = "Perform only the bounded task and return evidence."
```
2. Spawn a child through the Buzz-provided collaboration tool using
`task_name = "luna_worker"`, no model override, and a fresh fork.
3. Inspect the child rollout metadata.
Actual result: the child runs on `gpt-5.6-sol`. Its thread metadata records the
path `/root/luna_worker` but `agent_role: null`, so the profile name is treated
only as a task label.
The same result occurs in a fresh Codex process that loads the profile before
startup, ruling out profile-discovery caching: the spawned child still records
`model: gpt-5.6-sol` and `agent_role: null`.
**Proposed solution**
Expose an explicit custom-agent selector on Buzz's Codex `spawn_agent` tool
(`agent_role`, `agent_type`, or equivalent) and forward it to Codex when the
child thread is created.
The selected profile should apply its configured model, reasoning effort,
developer instructions, and other supported session settings. The explicit
model override should also be sourced from the runtime's available model
catalog rather than a fixed Sol/Terra allowlist, so supported models such as
Luna can be selected directly when no custom profile is needed.
Suggested acceptance criteria:
1. `task_name` remains the human-readable task/path label.
2. A separate optional role/profile field selects a loaded built-in or custom
Codex agent.
3. A custom profile pinned to Luna/max produces child rollout metadata with
`model: gpt-5.6-luna` and the selected non-null agent role.
4. An explicit available model and reasoning effort can be selected for a
one-off child without changing global subagent defaults.
5. Omitting both fields preserves current inheritance behavior.
6. Unknown or unavailable profiles/models fail clearly before work begins.
7. Add an ACP integration test covering profile selection, direct model
selection, and the unchanged-default case.
**Alternatives considered**
- Set `agents.default_subagent_model` to Luna: rejected because it silently
changes unrelated subagent work.
- Create a separate Luna-backed managed Buzz agent: works around model
selection, but adds identity, routing, permissions, and closeout overhead for
what should be an ephemeral worker.
- Change the primary agent's model: solves a different problem and weakens the
high-consequence owner rather than routing only bounded work.
**Additional context**
- Codex documents model-pinned custom agents and per-spawn precedence:
https://learn.chatgpt.com/docs/agent-configuration/subagents
- #2543 is adjacent but not a duplicate: it requests changing the managed
primary agent's model mid-session; this request is selective model/profile
routing for a spawned child while the primary model stays fixed.
- Searched open and closed Buzz issues and PRs for `subagent`, `spawn_agent
model`, `model override`, `per-spawn`, `custom agent`, `agent_role`, and
`gpt-5.6-luna`; no matching issue was found.
Contributor guide
Assessment
This issue has not been assessed yet.