Repository navigation
refactor(codex): count native child tokens in run metrics - #8569
Conversation
A Codex child is a separate thread: its tokens never reach the parent's exec --json stream and live only in the child's rollout. This adds the read and the fold, called by nothing yet: codexChildUsageReadCommand (one bounded in-sandbox command, ids validated and shell-quoted), parseCodexChildUsage (the first turn_context, the last token_count), codexChildIDs (the completed spawn_agent receivers off a tee of the stream) and foldCodexChildUsage (the parent's entry first and always, one request per child thread with usage, child reasoning to the run total only), plus delegating() on the runner-held digest set. Fixtures: four child rollouts modelled on the 0.157.0 paid probe and one stream with completed and failed spawns. Signed-off-by: Dharit Shah <dhshah@redhat.com>
When a Codex agent has registered sub-agent roles or its exec --json stream reports a completed spawn, Run reads the children's rollouts with one bounded sandbox command after codex exits and folds each child's last cumulative usage into the totals and per_model_usage. The ids come off a tee of the stream; parseCodexStream's signature is unchanged. A failed read is a printer warning, never a failed run, and a killed, cancelled or timed-out iteration reports the parent's tokens only. Inert until the multi-agent tools are turned on: no agent on main can spawn, so the one visible change is that a delegating agent's metrics.json gains per_model_usage with the parent's entry. Signed-off-by: Dharit Shah <dhshah@redhat.com>
PR Summary by QodoCount Codex sub-agent tokens in run metrics
AI Description
Diagram
High-Level Assessment
Files changed (11)
|
|
🤖 Finished Review · ✅ Success · Started 2:35 PM UTC · Completed 2:51 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.17 |
Code Review by Qodo
1.
|
Site previewPreview: https://16a5ab64-site.fullsend-ai.workers.dev Commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
<!-- fullsend:risk-assessment --> DetailsLarge diff and high historical churn in touched runner files are balanced by zero protected or security paths, strong alignment with tracking issue #6970, and additive metrics counting that remains inert until native multi-agent tools are enabled. Previous run<!-- fullsend:risk-assessment --> DetailsLarge diff and high historical churn in touched runner files are balanced by zero protected or security paths, strong alignment with tracking issue #6970, and additive metrics counting that remains inert until multi-agent tools are enabled. Previous run (2)<!-- fullsend:risk-assessment --> DetailsLarge diff and high historical churn in touched runner files are balanced by zero protected or security paths, strong alignment with tracking issue #6970, and additive metrics counting that remains inert until multi-agent tools are enabled. Previous run (3)<!-- fullsend:risk-assessment --> DetailsLarge diff and high historical churn in touched runner files are balanced by zero protected or security paths, strong alignment with tracking issue #6970, and additive metrics counting that remains inert until multi-agent tools are enabled. Previous run (4)<!-- fullsend:risk-assessment --> DetailsLarge diff and high historical churn in touched runner files are balanced by zero protected or security paths, strong alignment with tracking issue #6970, and additive metrics counting that remains inert until multi-agent tools are enabled. Previous run (5)<!-- fullsend:risk-assessment --> DetailsModerate risk reflects a medium-to-large additive change primarily composed of tests with no protected or security-sensitive paths, balanced against elevated churn and coupling in touched runner files. Previous run (6)<!-- fullsend:risk-assessment --> DetailsModerate risk: large change size and elevated churn in touched documentation and runtime files are mitigated by zero protected or security-sensitive paths, comprehensive test coverage, and clear alignment with a structured multi-PR issue breakdown. |
ReviewFindingsLow
Earlier findings
Previous run<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImVkZ2UtY2FzZSIsImZpbGUiOiJpbnRlcm5hbC9ydW50aW1lL2NvZGV4X3N1YmFnZW50cy5nbyIsImlkIjoiZl9kOGIxZjQwYTU1YzdiZWE4IiwibGluZSI6NzYsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6ImxvZ2ljLWVycm9yIiwiZmlsZSI6ImludGVybmFsL3J1bnRpbWUvY29kZXhfc3ViYWdlbnRzLmdvIiwiaWQiOiJmXzM4MWM3ZjNiNzkzYTgwMTAiLCJsaW5lIjoyMjUsImFjdGlvbmFibGUiOmZhbHNlfSx7InNldmVyaXR5IjoibG93IiwiY2F0ZWdvcnkiOiJzdGFsZS1kb2MiLCJmaWxlIjoiZG9jcy9ydW50aW1lcy9jb2RleC5tZCIsImlkIjoiZl81MTM5ZWM1OWU2ODFkN2Q5IiwibGluZSI6MjgxLCJhY3Rpb25hYmxlIjpmYWxzZX0seyJzZXZlcml0eSI6ImxvdyIsImNhdGVnb3J5IjoiaW5jb21wbGV0ZS1kb2MiLCJmaWxlIjoiZG9jcy9jb250cmlidXRpbmcvcnVudGltZS1pbXBsZW1lbnRhdGlvbi5tZCIsImlkIjoiZl8xZjRhZDIxODMzMzFkZjBmIiwibGluZSI6MTA4MCwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImxvZ2ljLWVycm9yIiwiZmlsZSI6ImludGVybmFsL3J1bnRpbWUvY29kZXhfcnVuLmdvIiwiaWQiOiJmX2ZkYmY3N2Y5ZDJhZDE3YzIiLCJsaW5lIjo2NjcsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6InNlY3JldC1leHBvc3VyZSIsImZpbGUiOiJpbnRlcm5hbC9ydW50aW1lL2NvZGV4X3N1YmFnZW50cy5nbyIsImlkIjoiZl8yZjczZjJkMTE3OGI5Y2NhIiwibGluZSI6MzA0LCJhY3Rpb25hYmxlIjpmYWxzZX1dLCJkaXNwb3NpdGlvbnMiOlt7ImlkIjoiZl81MTM5ZWM1OWU2ODFkN2Q5Iiwic3RhdHVzIjoib3BlbiJ9LHsiaWQiOiJmXzFmNGFkMjE4MzMzMWRmMGYiLCJzdGF0dXMiOiJvcGVuIn0seyJpZCI6ImZfZmRiZjc3ZjlkMmFkMTdjMiIsInN0YXR1cyI6InJlc29sdmVkX2J5X2NoYW5nZSJ9LHsiaWQiOiJmXzJmNzNmMmQxMTc4YjljY2EiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifV19 --> ReviewFindingsMedium
Low
Next steps:
Previous run (2)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJhcHByb3ZlIiwiZmluZGluZ3MiOlt7InNldmVyaXR5IjoibG93IiwiY2F0ZWdvcnkiOiJzdGFsZS1kb2MiLCJmaWxlIjoiZG9jcy9ydW50aW1lcy9jb2RleC5tZCIsImlkIjoiZl81MTM5ZWM1OWU2ODFkN2Q5IiwibGluZSI6MjgxLCJhY3Rpb25hYmxlIjpmYWxzZX0seyJzZXZlcml0eSI6ImxvdyIsImNhdGVnb3J5IjoiaW5jb21wbGV0ZS1kb2MiLCJmaWxlIjoiZG9jcy9jb250cmlidXRpbmcvcnVudGltZS1pbXBsZW1lbnRhdGlvbi5tZCIsImlkIjoiZl8xZjRhZDIxODMzMzFkZjBmIiwibGluZSI6MTA4MCwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImxvZ2ljLWVycm9yIiwiZmlsZSI6ImludGVybmFsL3J1bnRpbWUvY29kZXhfcnVuLmdvIiwiaWQiOiJmX2ZkYmY3N2Y5ZDJhZDE3YzIiLCJsaW5lIjo2NjcsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6InNlY3JldC1leHBvc3VyZSIsImZpbGUiOiJpbnRlcm5hbC9ydW50aW1lL2NvZGV4X3N1YmFnZW50cy5nbyIsImlkIjoiZl8yZjczZjJkMTE3OGI5Y2NhIiwibGluZSI6MzA0LCJhY3Rpb25hYmxlIjpmYWxzZX1dLCJkaXNwb3NpdGlvbnMiOlt7ImlkIjoiZl81MTM5ZWM1OWU2ODFkN2Q5Iiwic3RhdHVzIjoib3BlbiJ9LHsiaWQiOiJmXzFmNGFkMjE4MzMzMWRmMGYiLCJzdGF0dXMiOiJvcGVuIn0seyJpZCI6ImZfZmRiZjc3ZjlkMmFkMTdjMiIsInN0YXR1cyI6InJlc29sdmVkX2J5X2NoYW5nZSJ9LHsiaWQiOiJmXzJmNzNmMmQxMTc4YjljY2EiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifV19 --> ReviewFindingsLow
Previous run (3)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJhcHByb3ZlIiwiZmluZGluZ3MiOlt7InNldmVyaXR5IjoibG93IiwiY2F0ZWdvcnkiOiJzdGFsZS1kb2MiLCJmaWxlIjoiZG9jcy9ydW50aW1lcy9jb2RleC5tZCIsImlkIjoiZl81MTM5ZWM1OWU2ODFkN2Q5IiwibGluZSI6MjcxLCJhY3Rpb25hYmxlIjpmYWxzZX0seyJzZXZlcml0eSI6ImxvdyIsImNhdGVnb3J5IjoiaW5jb21wbGV0ZS1kb2MiLCJmaWxlIjoiZG9jcy9jb250cmlidXRpbmcvcnVudGltZS1pbXBsZW1lbnRhdGlvbi5tZCIsImlkIjoiZl8xZjRhZDIxODMzMzFkZjBmIiwibGluZSI6MTA4MywiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImxvZ2ljLWVycm9yIiwiZmlsZSI6ImludGVybmFsL3J1bnRpbWUvY29kZXhfcnVuLmdvIiwiaWQiOiJmX2ZkYmY3N2Y5ZDJhZDE3YzIiLCJsaW5lIjo2NjcsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6InNlY3JldC1leHBvc3VyZSIsImZpbGUiOiJpbnRlcm5hbC9ydW50aW1lL2NvZGV4X3N1YmFnZW50cy5nbyIsImlkIjoiZl8yZjczZjJkMTE3OGI5Y2NhIiwibGluZSI6MzA0LCJhY3Rpb25hYmxlIjpmYWxzZX1dLCJkaXNwb3NpdGlvbnMiOlt7ImlkIjoiZl9mZGJmNzdmOWQyYWQxN2MyIiwic3RhdHVzIjoicmVzb2x2ZWRfYnlfY2hhbmdlIn0seyJpZCI6ImZfMmY3M2YyZDExNzhiOWNjYSIsInN0YXR1cyI6InJlc29sdmVkX2J5X2NoYW5nZSJ9LHsiaWQiOiJmXzUxMzllYzU5ZTY4MWQ3ZDkiLCJzdGF0dXMiOiJvcGVuIn0seyJpZCI6ImZfMWY0YWQyMTgzMzMxZGYwZiIsInN0YXR1cyI6Im9wZW4ifV19 --> ReviewFindingsLow
Earlier findings
Previous run (4)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImxvZ2ljLWVycm9yIiwiZmlsZSI6ImludGVybmFsL3J1bnRpbWUvY29kZXhfcnVuLmdvIiwiaWQiOiJmX2ZkYmY3N2Y5ZDJhZDE3YzIiLCJsaW5lIjo2NjcsImFjdGlvbmFibGUiOnRydWV9LHsic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6InNlY3JldC1leHBvc3VyZSIsImZpbGUiOiJpbnRlcm5hbC9ydW50aW1lL2NvZGV4X3N1YmFnZW50cy5nbyIsImlkIjoiZl8yZjczZjJkMTE3OGI5Y2NhIiwibGluZSI6MzA0LCJhY3Rpb25hYmxlIjpmYWxzZX0seyJzZXZlcml0eSI6ImxvdyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3MvcnVudGltZXMvY29kZXgubWQiLCJpZCI6ImZfNTEzOWVjNTllNjgxZDdkOSIsImxpbmUiOjI3MSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6ImluY29tcGxldGUtZG9jIiwiZmlsZSI6ImRvY3MvY29udHJpYnV0aW5nL3J1bnRpbWUtaW1wbGVtZW50YXRpb24ubWQiLCJpZCI6ImZfMWY0YWQyMTgzMzMxZGYwZiIsImxpbmUiOjEwODMsImFjdGlvbmFibGUiOmZhbHNlfV19 --> ReviewFindingsMedium
Low
Next steps:
Previous run (5)ReviewFindingsLow
Next steps:
Previous run (6)ReviewFindingsLow
Labels: PR changes the Codex agent runtime metrics code. Next steps:
|
Codex writes a token_count with its usage counters at zero when a request overflows the context window, and writes a token_count only after the response's tools finish, so a child's last token_count could read zero or miss its last response. The read now takes the thread total of the child's last token_usage_record, which codex writes as each response completes and never resets. A read cut at its 1 MiB bound is returned as an error, which Run prints as a warning, and a child with a counter past 2^40 is skipped so planted values cannot wrap the run's totals. The Run comment says the read follows any exit 0. Signed-off-by: Dharit Shah <dhshah@redhat.com>
|
Deferred: |
|
🤖 Finished Review · ✅ Success · Started 4:37 PM UTC · Completed 4:47 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $2.70 |
A rollout the read could not open, or one a failed search of the sessions directory did not find, looked like a child with no usage: a pipeline's status is its last command's, and find and grep send their errors to /dev/null. The read now prints an unreadable marker for such a child, and the fold returns it as an error, which Run prints as a warning, keeping the children it did read. A missing sessions directory warns the same way; a rollout missing from a directory searched without error still adds nothing. Signed-off-by: Dharit Shah <dhshah@redhat.com>
|
Done in 9517fa6: description cut from about 770 words to 220, nothing asked of maintainers; the one place it differs from ADR 0126 ( |
|
🤖 Finished Review · ✅ Success · Started 9:54 AM UTC · Completed 10:01 AM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $1.74 |
Superseded by updated review
…hild-usage Signed-off-by: Dharit Shah <dhshah@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 2:22 PM UTC · Completed 2:31 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $1.96 |
Superseded by updated review
A failed or timed-out read now folds the stdout that came back instead of discarding it, and the read keeps the last two record and turn_context lines so a torn last line falls back to the one before. A line that does not decode is reported, the cut warning says the child at the cut may be counted short, and a codex stopped at the budget or cancelled warns that its children can record more after the read. Signed-off-by: Dharit Shah <dhshah@redhat.com>
Codex writes one rollout per thread, so a second file named for the same id is planted. Each copy was folded as its own child, multiplying the child's tokens and requests; such an id now prints the unreadable marker and none of its copies count. Signed-off-by: Dharit Shah <dhshah@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 7:01 PM UTC · Completed 7:08 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $1.30 |
Superseded by updated review
|
Hey! Didn't got the time to review after asking for simplifications, thanks for doing them, much cleaner now. |
Summary
Adds Codex sub-agent token usage to the run totals and
per_model_usage, read from each child's rollout inside the sandbox after codex exits. A failed or partial read prints a warning, keeps the children it read, and never fails the run. No agent onmaincan spawn yet (#7829 turns codex's multi-agent tools off), so at merge the only change is a parent-onlyper_model_usagefor a Codex agent with registered roles.Related Issue
Part of #6970.
Changes
spawn_agentitems, read off a tee of the--jsonstream.token_usage_recordas each response completes.token_usage_record(the thread's cumulative total), not thetoken_countADR 0126 names, because codex zeroestoken_count's counters when a request overflows the context window.docs/cli/run.mddocuments codexper_model_usage.docs/runtimes/codex.mdanddocs/contributing/runtime-implementation.mdchange in the codex runtime: run the review/retro sub-agent rosters through codex's native spawn_agent roles #6970 PR that turns delegation on.Testing
make lintpassesinternal/runtime/codex_subagents_test.goChecklist
!for breaking changes)🤖 Generated with Claude Code