openai / openai/codex

codex exec: no way to register session as a thread-spawn subagent (parent linkage for headless fan-out)

Open
#44,429 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

CLI enhancement exec subagent
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

codex exec has no way to register its session as a subagent/thread-spawn child of an existing thread. The engine fully supports this linkage — threads.source = {"subagent":{"thread_spawn":{...}}} plus a thread_spawn_edges row — but it is only written by the in-process collab tools (SpawnAgentHandler) and the Codex app's create_thread path. A headless codex exec run, even when launched by a parent Codex session for exactly the same fan-out purpose, always lands in the thread store as a plain exec user thread with no parent linkage, so it is invisible in the Codex app's sidebar thread tree.

Motivation / use case

A Codex Desktop session that wants to fan out parallel subagents can currently only do so by shelling out to codex exec (when the host doesn't expose collab tools or create_thread to that session). The subagents work fine — but the user cannot see them in the Desktop sidebar, because the app renders the subagent hierarchy from thread_spawn_edges + the thread_spawn source marker, which exec never writes. The model/provider is irrelevant: the spawn inherits config either way.

This makes headless delegation a second-class citizen compared to in-app delegation, even though both run on the same engine.

Evidence (all on current main)

  • codex-rs/core/src/thread_manager.rs: exec sessions are hard-coded as session_source: SessionSource::Exec with thread_source: None (see ThreadManagerOptions defaults, ~line 262 and ~line 667). thread_source is only populated from resume history or the in-process spawn path — never from env, config, or CLI flags.
  • codex-rs/core/src/tools/handlers/multi_agents.rs: the collab tool surface (SpawnAgentHandler, WaitAgentHandler, SendInputHandler, CloseAgentHandler, ResumeAgentHandler) is what spawns linked subagents; its doc comment notes subagents "inherit runtime-only state such as provider, approval policy, sandbox, and cwd."
  • codex-rs/state/migrations/0021_thread_spawn_edges.sql + codex-rs/core/src/thread_manager.rs (list_live_thread_spawn_edges, list_thread_spawn_descendants): the spawn-edge table is the parent-child registry the UI consumes.
  • codex-rs/features/src/lib.rs: multi_agent is Stage::Stable, default_enabled: true — so the machinery is on by default; there is just no entry point from exec.
  • Observed locally: a codex exec run recorded in state_5.sqlite with source='exec', thread_source='user', agent_nickname=NULL, and zero thread_spawn_edges rows, while app-spawned subagents on the same machine have source={"subagent":{"thread_spawn":{"parent_thread_id":"...","depth":1,"agent_path":"/root/...","agent_nickname":"..."}}} plus an edge row.

Proposed change

Give codex exec (and ideally codex exec resume/fork) an opt-in way to declare its parentage, e.g.:

  • a CLI flag: codex exec --parent-thread <THREAD_ID> [--agent-path /root/<name>] [--agent-nickname <name>] [--agent-role <role>], or
  • env vars: CODEX_PARENT_THREAD_ID, CODEX_AGENT_PATH, CODEX_AGENT_NICKNAME, CODEX_AGENT_ROLE

When set, the exec session would:

  1. set thread_source to ThreadSource::Subagent with source = {"subagent":{"thread_spawn":{"parent_thread_id": ..., "depth": parent_depth + 1, ...}}},
  2. insert the thread_spawn_edges row (parent_thread_id, child_thread_id, status),
  3. enforce the existing spawn-depth limit (exceeds_thread_spawn_depth_limit).

This is a small, additive change: exec already knows its thread id and writes the rollout; it just needs to pass a ThreadSource and record the edge. It does not change default behavior.

Alternatives considered

  • Hand-editing the app’s state_5.sqlite to insert the edge row retroactively: fragile (WAL DB owned by the running app), gives sidebar grouping but no live streaming of the child turn, and risks corruption.
  • Exposing collab tools to every Desktop work session: also valuable, but orthogonal — this request is about the headless entry point, which scripts and external orchestrators use too.

Environment

  • codex-cli 0.153.4 (Codex Desktop bundled binary) on Windows 11
  • also reproduced with codex-cli 0.144.1 (npm install)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing ThreadManagerOptions and exec session setup in codex-rs/core/src/thread_manager.rs, then read the multi-agent handlers and the 0021_thread_spawn_edges.sql migration. Compare the existing app-spawn path with exec and its resume/fork variants. Done means an opt-in parent declaration records the subagent source and edge, enforces the depth limit, and preserves default exec behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, sqlite
Domain
backend, cli, databases
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.