Skip to content

Fix Codex subagent final result preservation#602

Merged
tiann merged 3 commits into
tiann:mainfrom
SmallSpider0:fix/codex-subagent-final-results-v2
May 9, 2026
Merged

Fix Codex subagent final result preservation#602
tiann merged 3 commits into
tiann:mainfrom
SmallSpider0:fix/codex-subagent-final-results-v2

Conversation

@SmallSpider0
Copy link
Copy Markdown
Contributor

Summary

Fix Codex subagent result handling so completed subagent cards preserve the actual final assistant message instead of sometimes showing only a terminal status such as done.

Problem

In some Codex multi-agent flows, a child agent could complete successfully but the parent-side result would only contain a completion marker (done / completed) rather than the child agent's final message.

This could happen when:

  • wait_agent returned a completed/done status without a message
  • child terminal events and child message events arrived in a non-ideal order
  • later child trace/tool events arrived after the card had already reached a terminal state

Changes

  • Track each child Codex runtime's latest final agent_message
  • Use that cached final message as fallback when wait_agent reports completed/done without a message
  • Normalize done, complete, and completed agent states consistently
  • Preserve structured completed-state payloads instead of collapsing them to bare completed status
  • Prevent terminal child agent cards from regressing back to running due to late child events
  • Allow explicit parent operations like send_input / resume_agent to remain visible without letting late child tool events overwrite terminal state
  • Reset cached final message and terminal state on child task_started
  • Preserve late child messages as completed result updates instead of writing/running updates

Tests

cd cli
bun run test -- src/codex/utils/appServerEventConverter.test.ts src/codex/codexRemoteLauncher.test.ts
bun run typecheck

Also smoke-tested against a deployed local HAPI build with real Codex subagents:

  • spawned two subagents
  • waited for both
  • verified wait_agent result contained full final messages, not only done

Notes

This is a clean resubmission from the latest upstream main, replacing the closed PR #599 without force-pushing the old branch.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Findings

  • [Major] Empty status message suppresses structured output — statusObjectFromAgentState now preserves completed agent states such as { status: 'completed', message: '', output: { value: 42 } }, but the launcher reads record.message with nullish coalescing, so an empty string is treated as the final result and the structured output is dropped. That reintroduces the blank/terminal-only completed card for this added case. Evidence cli/src/codex/codexRemoteLauncher.ts:962.
    Suggested fix:
    const extractAgentStatusMessage = (record: Record<string, unknown>): unknown => {
        const message = asString(record.message);
        if (message) return message;
        if (record.output !== undefined && record.output !== null) return record.output;
        if (record.result !== undefined && record.result !== null) return record.result;
        if (record.finalMessage !== undefined && record.finalMessage !== null) return record.finalMessage;
        return record.final_message;
    };

Summary

  • Review mode: initial
  • One issue found: completed child-agent states with blank message still lose structured output in the launcher.

Testing

  • Not run (automation)

HAPI Bot

Comment thread cli/src/codex/codexRemoteLauncher.ts
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Findings

  • [Minor] Reset the new harness flag between tests — emitChildWaitStructuredOutput is enabled by the new structured-output test, but afterEach resets the neighboring child-event flags without resetting this one. Because the harness object is shared, every later test now runs with agentsStates carrying message: '' and output: { value: 42 }, so the suite becomes order-dependent and can mask regressions in the normal child-message path. Evidence cli/src/codex/codexRemoteLauncher.test.ts:1078.
    Suggested fix:
    harness.emitChildDoneStatusWithoutMessage = false;
    harness.emitChildWaitStructuredOutput = false;
    harness.emitChildTaskCompleteBeforeMessage = false;

Summary

  • Review mode: follow-up after new commits
  • One test-isolation issue found in the follow-up changes. The prior structured-output finding appears addressed in the launcher path.

Testing

  • Not run (automation; bun is unavailable in this runner: /bin/bash: bun: command not found)

HAPI Bot

Comment thread cli/src/codex/codexRemoteLauncher.test.ts
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Findings

  • No findings.

Summary

  • Review mode: follow-up after new commits
  • No issues found in the latest PR diff. The prior HAPI Bot test-isolation finding is fixed in the current head.
  • Residual risk: Codex app-server event ordering is hard to exhaustively validate from the diff alone.

Testing

  • Not run (automation/review only; PR code not executed)

HAPI Bot

@tiann tiann merged commit 3eac345 into tiann:main May 9, 2026
2 checks passed
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.

2 participants