test(e2e): spendlog cost for streaming /v1/messages via responses bridge - #33753
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
|
Greptile SummaryThis PR adds end-to-end spend-tracking coverage for streaming
Confidence Score: 5/5Test-only change with no modifications to production proxy or spend pipeline code; safe to merge. Every changed file is confined to tests/e2e/. The two previously flagged issues — a stale self.gateway reference in SpendClient.messages_stream and a filter-consistency gap between the polling predicate and the costed list — are both resolved in this head: the method correctly calls self.proxy.messages_stream(...), and the test now asserts bridged == costed before checking len(bridged) == 1, which catches any extra non-bridged costed rows. No production code is touched. No files require special attention.
|
| Filename | Overview |
|---|---|
| tests/e2e/quota_management/spend_tracking/test_spend_tracking_e2e.py | Adds test_streaming_messages_via_responses_bridge_tracks_spend with well-structured two-stage assertion: all costed rows must be bridged (bridged == costed), then exactly one bridged row is required — addressing the filter-consistency concern from a prior review. Also adds call_type and custom_llm_provider to _summarize diagnostics. |
| tests/e2e/quota_management/spend_tracking/spend_e2e_client.py | Adds messages_stream wrapper on SpendClient that correctly delegates to self.proxy.messages_stream(...) — consistent with every other method in the class and the proxy: ProxyClient dataclass field. |
| tests/e2e/proxy_client.py | Adds messages_stream route to the shared ProxyClient, delegating to transport.stream("/v1/messages", ...) — follows the same pattern as chat_stream. |
| tests/e2e/quota_management/spend_tracking/conftest.py | Registers openai-responses-codex → openai/gpt-5.3-codex in DRIVER_MODELS, providing the Responses-only deployment the new test targets. |
| tests/e2e/coverage_registry/quota_management.yaml | Adds quota_management.spend_tracking.messages_bridge.logs_cost registry entry at tier P1 with correct source, exercised_on, and rationale fields. |
| tests/e2e/CLAUDE.md | Adds messages_bridge to the <spend_tracking> variant vocabulary and re-wraps the existing token list — documentation-only change. |
Reviews (8): Last reviewed commit: "test(e2e): spendlog cost for streaming /..." | Re-trigger Greptile
Greptile SummaryAdds a new live e2e test (
Confidence Score: 4/5All changes are confined to the e2e test suite with no production code touched; safe to merge. The test logic, gateway additions, and docker-compose stanza are consistent with existing patterns. The only concern is a minor filter mismatch in the new test where tests/e2e/quota_management/spend_tracking/test_spend_tracking_e2e.py — the costed filter on line 168 should mirror the predicate's call_type guard.
|
| Filename | Overview |
|---|---|
| tests/e2e/quota_management/spend_tracking/test_spend_tracking_e2e.py | Adds the new messages bridge test with a slightly looser costed filter than the polling predicate; also widens _summarize. |
| tests/e2e/e2e_gateway.py | Adds messages_stream method to Gateway, consistent with existing chat_stream pattern. |
| tests/e2e/quota_management/spend_tracking/conftest.py | Adds openai-responses-codex to DRIVER_MODELS with the same auto-registration pattern as existing drivers. |
| tests/e2e/quota_management/spend_tracking/spend_e2e_client.py | Adds messages_stream to SpendClient, mirroring the chat_stream shape. |
| tests/e2e/docker-compose.yml | Adds the openai-responses-codex deployment stanza, consistent with existing model entries. |
| tests/e2e/coverage_registry/quota_management.yaml | Adds messages_bridge.logs_cost coverage entry with accurate source and rationale. |
| tests/e2e/CLAUDE.md | Reformats spend_tracking vocabulary to include messages_bridge. |
Reviews (2): Last reviewed commit: "test(e2e): spendlog cost for streaming /..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
CI note for the reviewer: the two red checks are both base/environment, not this diff (which is tests/e2e only).
Everything else is green and Greptile is 5/5 on the head commit |
|
@greptileai please review the current head 12a5305. The follow-up commit reconciles the costed-row selection with the polling predicate by sharing one |
2a312ae to
cc419c0
Compare
|
@greptileai please review the current head cc419c0. Rebased onto current staging to adopt the Gateway to ProxyClient rename from #33750 (the previous head no longer merged cleanly). No behavior change: messages_stream now lives on ProxyClient and the spend client calls self.proxy; the test and its assertions are unchanged. |
|
bugbot run |
cc419c0 to
b9ca047
Compare
|
@greptileai good catch, fixed. The stale |
b9ca047 to
325462e
Compare
|
@greptileai please review the current head 325462e. Rebased again onto current staging to resolve a conflict from #33831 (which added a native |
325462e to
babb8bf
Compare
|
@greptileai please review the current head babb8bf. Rebased onto current staging now that #33839 (load-suite migration to ProxyClient) has merged, clearing the base-drift e2e basedpyright failure. No change to this PR's diff beyond the rebase. |
Add a live spend-tracking e2e that drives a streaming anthropic-format /v1/messages request through litellm's anthropic-messages -> OpenAI Responses adapter and asserts the consumed stream writes exactly one SpendLogs row with nonzero cost and token counts, attributed to the calling key under custom_llm_provider openai and the /v1/messages call_type. The deployment is a Responses-only OpenAI model (gpt-5.3-codex), so a served, costed row proves the Responses path was taken; the chat-completions bridge would have failed at OpenAI on an endpoint the model does not expose. Adds a streaming /v1/messages method to the shared Gateway and the suite client, the model to the inline compose config and driver-model registration, a coverage registry row (quota_management.spend_tracking.messages_bridge.logs_cost), and the matching variant vocab entry. The _summarize spend-row detail also gains call_type and custom_llm_provider so a failed assertion prints the fields it asserts on. The costed-row selection and the polling predicate share one is_bridged_costed guard (spend>0 AND anthropic_messages call_type) so a stray costed row under a different call_type fails loud. Resolves LIT-4546
babb8bf to
48659a6
Compare
|
@greptileai please review the current head 48659a6. Rebased onto current staging after #33837 removed the bundled tests/e2e/docker-compose.yml; resolved the modify/delete by dropping this PR's edit to that file. The openai-responses-codex deployment is still registered by the suite via DRIVER_MODELS (conftest), so the test is unaffected. All .py files are byte-identical to the previously 5/5 head. |
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 48659a6. Configure here.
Relevant issues
Linear ticket
Resolves LIT-4546
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Screenshots / Proof of Fix
Captured at commit
f57971f604against a live proxy running the publishedghcr.io/berriai/litellm:main-latestimage, hitting the real OpenAI Responses API and costing real dollarsBring the suite's compose stack up (namespaced so it does not collide with other local proxies) with
OPENAI_API_KEYintests/e2e/.env, remapping the proxy off 4000 so it does not clash with another local proxy:Run the new test against it:
The same behavior by hand: generate a scoped key, POST a streaming
/v1/messagesrequest (anthropic format) to the responses-bridged deploymentopenai-responses-codex->openai/gpt-5.3-codex, a Responses-only OpenAI model, consume the whole SSE stream:Poll
/spend/logsfor that key once the batch write lands; exactly one row appears, carrying a nonzero cost and token counts, the openai provider, and the/v1/messagesbilling identity:custom_llm_provider: openaion agpt-5.3-codexrow that is only reachable via/v1/responses, undercall_type: anthropic_messages, is the combination that proves the Responses adapter served the/v1/messagesrequest. A chat-completions bridge would have failed at OpenAI on an endpoint the model does not expose, so the test cannot pass via the wrong pathIndependent end-to-end run (Devin)
Devin independently checked out the branch, brought up the namespaced e2e compose stack, and ran the new test against a live proxy hitting the real OpenAI Responses API for real money. The test passed (
1 passed in 15.93s), and the by-hand repro produced exactly one costed/spend/logsrow for the scoped key:spend $0.00018375,custom_llm_provider openai,call_type anthropic_messages,model openai/gpt-5.3-codex, andprompt_tokens 17 + completion_tokens 11 == total_tokens 28, with the streaming/v1/messagesresponse coming back200 text/event-streamand ending inmessage_stopThe test passing:
The single costed
/spend/logsrow it asserts on:Full-resolution screen recording: https://raw.githubusercontent.com/yassin-berriai/litellm-pr-media/main/pr33753-lit4546/e2e_run.mp4
Type
✅ Test
Changes
Existing in-suite spend coverage only drives streaming
/chat/completions; nothing exercised/v1/messagesthrough the OpenAI Responses adapter. In litellm anycustom_llm_provider == "openai"model called on/v1/messagesis bridged throughLiteLLMMessagesToResponsesAPIHandler(the anthropic-messages -> Responses adapter) unlessuse_chat_completions_url_for_anthropic_messagesis set, so the switch is provider-based rather than a per-model mode flagThe new test
test_streaming_messages_via_responses_bridge_tracks_spendcreates a scoped key, POSTs/v1/messageswithstream: trueto a Responses-only OpenAI deployment, consumes the whole SSE stream, then polls/spend/logsto a deadline and asserts exactly one costed row for the key with nonzero prompt and completion tokens that sum to the total,custom_llm_provider == "openai", and acall_typethat keeps the/v1/messagesbilling identity. Picking a Responses-only model (gpt-5.3-codex) makes the assertion path unambiguous, since the row could not have come from the chat-completions bridgeSupporting changes are a streaming
/v1/messagesmethod on the sharedGateway(so other suites get the route for free) and on the spend suite client, theopenai-responses-codexdeployment added to the inlinedocker-compose.ymlconfig and the suite's driver-model registration, a coverage-registry rowquota_management.spend_tracking.messages_bridge.logs_cost, and the matchingmessages_bridgeentry in the spend_tracking variant vocab. The_summarizespend-row detail also gainscall_typeandcustom_llm_providerso a failed assertion prints the two fields it asserts onQA runbook
tests/e2e/quota_management/spend_tracking/test_spend_tracking_e2e.py::test_streaming_messages_via_responses_bridge_tracks_spend- a fully consumed streaming/v1/messagesrequest bridged to the OpenAI Responses adapter writes exactly one SpendLogs row with cost and token counts, attributed to the calling keydocker compose -f docker-compose.yml up -d) withOPENAI_API_KEYintests/e2e/.env; the inline config already registersopenai-responses-codex->openai/gpt-5.3-codexcurl -X POST http://localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -d '{"models":[]}'/v1/messageswith that key,"model":"openai-responses-codex","stream":true, and a short message; read the SSE stream tomessage_stopand expect a 200 withcontent-type: text/event-streamGET /spend/logs?api_key=<key>until one row appears; expectspend > 0, nonzeroprompt_tokensandcompletion_tokenssumming tototal_tokens,custom_llm_provider == "openai", andcall_type == "anthropic_messages"Final Attestation
Note
Low Risk
Test-only changes (e2e clients, registry, docs); no proxy or spend-tracking production code modified.
Overview
Adds end-to-end coverage that a fully consumed streaming
/v1/messagescall against an OpenAI Responses-only deployment (openai-responses-codex→gpt-5.3-codex) produces exactly one costed spend row with correct token math,custom_llm_provider: openai, and aanthropic_messagescall_type (messages billing identity, not chat).Supporting harness changes:
messages_streamonProxyClientandSpendClient, the codex deployment in spend suite driver models, amessages_bridgecoverage-registry row and CLAUDE.md variant vocab, andcall_type/custom_llm_providerin spend-row failure summaries.Reviewed by Cursor Bugbot for commit 48659a6. Bugbot is set up for automated code reviews on this repo. Configure here.