Publish the per-request id as a request-id response header - #105
Open
Nitjsefnie wants to merge 1 commit into
Open
Publish the per-request id as a request-id response header#105Nitjsefnie wants to merge 1 commit into
Nitjsefnie wants to merge 1 commit into
Conversation
Claude Code records the `request-id` response header into every transcript record as `requestId`. This proxy never sent one, so proxied transcripts carry no request id at all: measured on a real session, 0 of 4 usage-bearing records had one, against 753 of 756 in a native Anthropic session. That matters because a transcript legitimately repeats a record, and the request id is what downstream consumers use to resolve the repeat. Without it they double-count. Claude Code's own parser reported 4 turns and 47,986 fresh input tokens for a session whose true figures were 2 turns and 23,966; with the header present it reports both correctly, unchanged. The id already existed. `dispatch_request` mints `req_id` per request and threads it through logging and the monitor; it simply never reached the response. `RequestMonitorGuard` already carries it, and every response path in this module funnels through `monitor_response_body`, which destructures the response parts before streaming the body. Stamping it there covers all return sites at once, and applies to a streaming SSE response as well, which the body-level `message.id` cannot do because a stream's id arrives inside `message_start` rather than in the headers. An upstream-supplied header is preserved rather than overwritten: relabelling a real provider id with a local uuid would lose the more useful value. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stamps a
request-idheader on proxy responses so Claude Code records a usablerequestIdin transcripts. Without it, consumers that de-duplicate transcript records by request id count every request twice.Related Issues and Pull Requests
Fixes #104
Changes
src/server.rs: addedREQUEST_ID_HEADERand stamped it inmonitor_response_body, using thereq_idthatdispatch_requestalready mints andRequestMonitorGuardalready carries.return, because every response path in the module funnels through it, and it is applied to the response parts before the body is streamed, so a streaming SSE response carries the header too.request-idis preserved rather than overwritten.src/server.rs: addedrequest_id_header_testscovering a plain response, a streaming response, an upstream-supplied header, and an error response.Testing
cargo fmt --check,cargo clippy --all-targets -- -D warnings, andcargo testall pass on this branch. The four new tests pass.Verified end to end against a live proxy on Linux with the codex provider:
content-type,transfer-encoding,date; a proxied Claude Code session produced 4 usage-bearing transcript records, 0 withrequestId;parse_session.py --cachereported4 turnsandfresh: 47,986.request-id: 288ebaeb-9b8a-4a6a-8ebf-0b6372caa94c; an equivalent session produced 4 usage-bearing records, 4 withrequestId, resolving to 2 unique ids; the same parser reported2 turnsandfresh: 23,966, with real ids in itsrequestIdcolumn.The parser was not modified — the id was the only thing missing.
Follow-ups / Known Limitations
The header is stamped for responses that pass through
monitor_response_body. Any future response path that bypasses it would need the same treatment.Footer
Generated by Claude Opus 5 (implementation, testing, verification)