Skip to content

feat(codex): surface nested subagents - #9637

Merged
brennanb2025 merged 9 commits into
mainfrom
brennanb2025/feature-surface-codex-sub-agents-models-and-orch
Jul 21, 2026
Merged

brennanb2025 merged 9 commits into
mainfrom
brennanb2025/feature-surface-codex-sub-agents-models-and-orch

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • install and trust native Codex SubagentStart and SubagentStop hooks across local, WSL, and SSH-managed paths
  • track Codex child roles, models, and working/waiting lifecycle states under the root agent row
  • accept child tool hooks as lifecycle evidence and retire child rows on native SubagentStop, with root Stop cleanup as a compatibility fallback for older or missing lifecycle events
  • preserve the root model and resumable provider session across child-origin hook events and SSH relay restarts
  • keep inferred Codex interrupts terminal when delayed child lifecycle hooks arrive
  • avoid repeating role-only child labels in the compact sidebar

Scope

This PR covers Codex CLI's in-process subagent visibility. The cross-worktree coordinator → worker graph and deduplication of workers visible through both Codex threads and Orca terminals remain follow-up work for #8251, so this PR does not close the umbrella issue.

Refs #8251

Current Codex CLI verification

Validated with two real, persisted-session Codex CLI 0.145.0 probes using gpt-5.6-sol: one child completed without tools, and one child ran a read-only shell tool before completing. The tool-using flow emitted:

SubagentStart → child PreToolUse → child PostToolUse → matching SubagentStop → root Stop

The SubagentStop carried the same child agent_id as SubagentStart. This verifies that the newest Codex CLI supplies the native lifecycle boundary Orca uses to remove the completed child promptly; root Stop remains a defensive compatibility cleanup path rather than the expected 0.145.0 path.

Earlier Codex CLI 0.144.6 end-to-end verification

A real Codex CLI 0.144.6 session (gpt-5.6-sol high) was also launched inside an isolated Orca dev instance from this worktree. The root spawned a real lifecycle_proof child, waited for its read-only task, and returned normally.

Live child working

The child tool hook creates a nested working row under the root while preserving the root model.

Live Codex child working

Compatibility lifecycle cleanup

The captured 0.144.6 flow did not emit a child SubagentStop. Orca used the root Stop as a compatibility cleanup boundary, while later child activity can safely recreate a child that is still running. The completed root remained visible with gpt-5.6-sol and no stale child row.

Live Codex lifecycle complete

Synthetic lifecycle matrix

The loopback Codex hook endpoint was also exercised directly for deterministic coverage of two concurrent children, per-child permission waiting, explicit child-stop ordering, model preservation, resume-session preservation, restart hydration, SSH relay context loss, and delayed child events after an inferred interrupt.

Working child roster

Both child roles and their distinct models render under the Codex root.

Codex subagents working

Child waiting for permission

A child PermissionRequest moves that child and the root to waiting while the sibling remains working. The root resume session remained qa-root-session in backing state.

Codex subagent waiting

Explicit lifecycle cleanup

Explicit child Stop events remove child rows incrementally, then the root resolves to Done with its model and resume session intact.

Codex subagents cleaned up

Verification

  • live Codex CLI 0.145.0 child spawn and completion in both no-tool and tool-using flows, including matching SubagentStart / SubagentStop identities
  • live Codex CLI 0.144.6 child spawn, child activity, root completion, and compatibility stale-row cleanup
  • focused hook/subagent suites, including the delayed post-interrupt lifecycle regression: 354 passed
  • Node TypeScript typecheck
  • changed-file oxlint and React Doctor lint
  • max-lines ratchet
  • git diff --check

@coderabbitai

coderabbitai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Codex subagent start/stop event support, explicit per-pane subagent rosters, lifecycle normalization, and persisted roster hydration. Status payloads and entries now preserve model metadata and expanded waiting/blocked states, while root provider sessions remain stable during child transitions. Renderer agent rows display model names and preserve derived child states across dashboard and sidebar views. Tests cover normalization, persistence, hook management, store behavior, and rendering.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding nested Codex subagent support.
Description check ✅ Passed It covers Summary, Screenshots, Testing, and Notes well, but the template's explicit AI Review Report and Security Audit sections are missing.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/agent-hooks/server.ts (1)

552-573: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Synchronize Codex lead state on inferred interrupts.

Only Claude’s lead cache is updated before synthesizing done. A later Codex child hook reconciles with its still-working lead cache and can resurrect the interrupted pane. Set the Codex lead state to done here while retaining its cached model; add a regression test with a delayed SubagentStop.

Proposed fix
     if (agentType === 'claude') {
       markClaudeLeadTurnInterrupted(this.state, existing.paneKey)
     }
+    if (agentType === 'codex') {
+      const lead = this.state.codexLeadStateByPaneKey.get(existing.paneKey)
+      this.state.codexLeadStateByPaneKey.set(existing.paneKey, {
+        state: 'done',
+        model: payload.model ?? lead?.model
+      })
+    }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5b64cb3f-ab99-46b4-a55a-38bb1c415d65

📥 Commits

Reviewing files that changed from the base of the PR and between f43e4a5 and 1b1e41b.

📒 Files selected for processing (4)
  • src/main/agent-hooks/server.test.ts
  • src/main/agent-hooks/server.ts
  • src/shared/agent-hook-listener.ts
  • src/shared/codex-subagent-roster.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/shared/codex-subagent-roster.test.ts
  • src/main/agent-hooks/server.test.ts
  • src/shared/agent-hook-listener.ts

@brennanb2025
brennanb2025 merged commit e986a7b into main Jul 21, 2026
15 checks passed
brennanb2025 added a commit that referenced this pull request Aug 18, 2026
…8251) (#14627)

Codex child rows have carried a model field end-to-end since #9637, but the
transcript reader never populated it, so every transcript-discovered child
rendered with an empty model chip. Read the child's own turn_context.model
from the rollout records already fetched for completion detection, so the
sidebar can distinguish an orchestrator model from a subagent model.

No added file I/O and no added rows: the model is parsed from records the
reconcile pass already read, and both row components already render
entry.model.
paidaxingyo666 pushed a commit to paidaxingyo666/Manta that referenced this pull request Aug 21, 2026
…tablyai#8251) (stablyai#14627)

Codex child rows have carried a model field end-to-end since stablyai#9637, but the
transcript reader never populated it, so every transcript-discovered child
rendered with an empty model chip. Read the child's own turn_context.model
from the rollout records already fetched for completion detection, so the
sidebar can distinguish an orchestrator model from a subagent model.

No added file I/O and no added rows: the model is parsed from records the
reconcile pass already read, and both row components already render
entry.model.
dallascrilley pushed a commit to dallascrilley/orca that referenced this pull request Aug 27, 2026
…tablyai#8251) (stablyai#14627)

Codex child rows have carried a model field end-to-end since stablyai#9637, but the
transcript reader never populated it, so every transcript-discovered child
rendered with an empty model chip. Read the child's own turn_context.model
from the rollout records already fetched for completion detection, so the
sidebar can distinguish an orchestrator model from a subagent model.

No added file I/O and no added rows: the model is parsed from records the
reconcile pass already read, and both row components already render
entry.model.
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
* feat(codex): surface nested subagents

* fix(codex): retire child rows on root stop

* fix(codex): preserve nested agent state on restart

* fix(codex): preserve nested agent identity

* fix(codex): preserve subagents across relay restarts

* chore(skills): refresh generated manifests

* fix(codex): keep inferred interrupts terminal

* chore(skills): record latest release snapshots
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
…tablyai#8251) (stablyai#14627)

Codex child rows have carried a model field end-to-end since stablyai#9637, but the
transcript reader never populated it, so every transcript-discovered child
rendered with an empty model chip. Read the child's own turn_context.model
from the rollout records already fetched for completion detection, so the
sidebar can distinguish an orchestrator model from a subagent model.

No added file I/O and no added rows: the model is parsed from records the
reconcile pass already read, and both row components already render
entry.model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant