Skip to content

fix(codex): do not double-count a spawned sub-agent's replayed parent history - #1383

Merged
iamtoruk merged 1 commit into
mainfrom
fix/1380-codex-subagent-replay
Sep 14, 2026
Merged

iamtoruk merged 1 commit into
mainfrom
fix/1380-codex-subagent-replay

Conversation

@iamtoruk

Copy link
Copy Markdown
Member

Fixes #1380.

Codex writes a spawned sub-agent's rollout by replaying the parent's history first, keeping every event_msg/token_count line with its original timestamp and dropping the parent's token_usage_record items (codex-rs agent/control/spawn.rs). The child names its parent under source.subagent.thread_spawn.parent_thread_id, not forked_from_id, so the fork guard never engaged and every child re-counted its parent's prefix. That is the multiplier the report describes; ccusage documents and handles the same replay in its Codex adapter.

The parser now reads the parent id from either field (nested object on the plain JSON path, flattened on the compact decoder for oversized meta lines) and the existing fork guard and content-keyed dedup take over. One new test: a spawned child replaying its parent with original timestamps counts parent plus its own work only. It fails on main and passes here; the 48 existing Codex tests still pass.

Verified on this machine's corpus, 1,378 Codex rollouts of which 381 are spawned children: lifetime Codex totals drop by exactly 405 calls and 403,712 cache tokens, and those numbers equal the replayed prefixes summed directly from the files. Every other total is unchanged.

Two notes for the reporter's table: codeburn's "input" column is uncached input, so an exact count that includes cached tokens under input will always read higher; and the per-turn growth in turn_token_usage is per-response accumulation, not streaming, as the Codex source shows.

@iamtoruk
iamtoruk merged commit c6981b4 into main Sep 14, 2026
21 checks passed
@iamtoruk
iamtoruk deleted the fix/1380-codex-subagent-replay branch September 14, 2026 11:13
roy-tong added a commit to roy-tong/codeburn that referenced this pull request Sep 16, 2026
…per review

Re-verified on a fresh spread sample of codeset-release-evals (21 sessions,
404 events): exactly one info:null rate-limit ping per session, zero events
with info present but total_token_usage absent — matching the reviewer's
137k-event corpus. The missing-cumulative branch is a no-op on real data:

- CODEX_CACHE_VERSION stays 15 (no cold reparse for identical numbers; v16
  never shipped in a release)
- drop the -missing-cumulative-v1 parse suffix
- Quirks: null-info pings take the estimate path, not the dedup path; the
  earlier 54-of-1313 figure conflated them with partial-info events
- dedup layer 3 now documents the forkedFromId/getagentseal#1383 sub-agent caveat
iamtoruk pushed a commit that referenced this pull request Sep 16, 2026
…ng (#1264)

* fix(codex): keep token_count events in sessions that never write total_token_usage

* fix(codex): preserve distinct requests when cumulative usage is missing

* fix(codex): narrow missing-cumulative fix - byte-identical re-emissions still collapse (#257)

Real-data answer to the review's question: Codex does re-emit byte-identical
token_count events. Scanned 53 public rollout sessions (codeset-ai/
codeset-release-evals, 1313 token_count events): 603 (46%) are byte-identical
repeats of their predecessor (identical total AND last usage), 0 cumulative
monotonicity violations, 54 events carry no total_token_usage at all.

The missing-cumulative path now collapses a record whose info payload is
byte-identical to the previous event's (#257 semantics restored); only
records with differing payloads count as distinct requests. prevInfoIdentity
is persisted in the resume state. The #1088 invariant note is restored at
the dedupKey in adapted form; docs/providers/codex.md documents the
three-layer dedup and the accepted fork-cutoff trade-off.

* fix(codex): revert cache/parse version bumps, correct null-info docs per review

Re-verified on a fresh spread sample of codeset-release-evals (21 sessions,
404 events): exactly one info:null rate-limit ping per session, zero events
with info present but total_token_usage absent — matching the reviewer's
137k-event corpus. The missing-cumulative branch is a no-op on real data:

- CODEX_CACHE_VERSION stays 15 (no cold reparse for identical numbers; v16
  never shipped in a release)
- drop the -missing-cumulative-v1 parse suffix
- Quirks: null-info pings take the estimate path, not the dedup path; the
  earlier 54-of-1313 figure conflated them with partial-info events
- dedup layer 3 now documents the forkedFromId/#1383 sub-agent caveat

---------

Co-authored-by: Roy tong <tongxiarui@elliwooddeMacBook-Air.local>
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.

codex: cache tokens overcounted ~3.7x & input undercounted on new rollout format (streaming turn_token_usage snapshots)

1 participant