Skip to content

feat(usage): record streamAborted on mid-stream-death attempts - #1652

Draft
kartikkabadi wants to merge 1 commit into
lidge-jun:devfrom
kartikkabadi:codex/stream-aborted-marker
Draft

feat(usage): record streamAborted on mid-stream-death attempts#1652
kartikkabadi wants to merge 1 commit into
lidge-jun:devfrom
kartikkabadi:codex/stream-aborted-marker

Conversation

@kartikkabadi

Copy link
Copy Markdown

Summary

Ports codex-router PR #139's streamAborted metering marker into opencodex: when an upstream stream dies after its 200 head was already committed, the persisted usage attempt must not meter as a success the client never received. The turn is recorded with the synthetic 502 terminal plus streamAborted: true; client cancellations keep opencodex's own 499 client_cancel semantics and never carry the marker.

Changes

  • src/usage/log.ts — optional streamAborted?: boolean on PersistedUsageAttempt, whitelisted in normalizeUsageAttempt so only the literal true marker survives the round trip. Backward compatible: ordinary and legacy rows keep their exact JSONL shape.
  • src/server/relay.ts — set the marker on both mid-stream read-failure paths:
    • consumeForInspection onReadError (native passthrough): onTerminal("failed", 502) plus streamAborted: true on the active attempt.
    • trackSseForRequestLog read failure (translated responses): incomplete/502 terminal plus the marker, guarded so a cancel-drained pending read never pollutes the 499 row.
  • tests/usage-log.test.ts — 4 new tests: marker persistence, backward-compatible omission (undefined/false), legacy rows stay readable, and raw JSONL round trip.
  • tests/stream-aborted-marker.test.ts (new) — drives both relay paths end to end through addFinalRequestLog to the persisted JSONL row: mid-stream death meters 502 + streamAborted: true; client cancel meters 499 with no marker.

Verification

  • bun test tests/usage-log.test.ts — 34 pass (30 pre-existing + 4 new).
  • bun test tests/stream-aborted-marker.test.ts — 4 pass (new file).
  • Adjacent relay suites still green: tests/consume-for-inspection-cancel.test.ts, tests/sse-inspector-bounds.test.ts — 34 pass.
  • bunx tsc --noEmit — clean for the files in this PR (remaining errors are peers' in-flight edits in other branches' files: src/lib/token-estimate.ts, src/server/responses/empty-completion-guard.ts).

Coordination notes

  • src/server/request-log.ts was not modified (TokenCapPort owns it). addFinalRequestLog's existing ...attempt spread carries the marker into the persisted row; the only shared assumption is logCtx.activeAttempt mutation, which relay.ts already uses for transportPhase/terminalSource.
  • tests/usage-log.test.ts also carries a small pre-existing working-tree edit to the "persists the rate-limit-429 recovery kind" test (durationMs 4→1, sendCount 2→1, deduped recoveryKinds, usageStatus reported→unreported) that was present before this branch's work and was kept as-is per main-agent direction; it is not authored by this PR.
  • Known gap (out of this slice's file ownership): the eager relay path (relay-eager.ts onSynthetic "failed", wired in responses/core.ts) synthesizes the same 502 terminal but does not yet set streamAborted. Follow-up recommended.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Port the codex-router lidge-jun#139 streamAborted metering marker: when an upstream
stream dies after its 200 head was committed, the persisted usage attempt
now carries streamAborted: true alongside the synthetic 502 terminal so the
turn never meters as a success the client did not receive.

- usage/log.ts: optional streamAborted on PersistedUsageAttempt, whitelisted
  in normalizeUsageAttempt (only the literal true marker survives the round
  trip; ordinary and legacy rows keep their exact shape).
- relay.ts: set the marker on consumeForInspection's mid-stream read-failure
  path (failed/502) and on trackSseForRequestLog's read-failure path
  (incomplete/502). Client-cancel (499) semantics are untouched and never
  carry the marker.
- tests: usage-log.test.ts gains persistence/backward-compat coverage;
  stream-aborted-marker.test.ts drives the relay paths end to end through
  addFinalRequestLog to the persisted JSONL row.
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3c1b5d6a-8169-4cd7-b04f-913873e707c6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ All CI tests are green on my local testing.
  • ⬜ I pushed my PR to the latest dev commit.
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This PR stays in draft until every box above is ticked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant