tests: openai cache coverage#5091
Conversation
Fixes a cost calculation bug where Anthropic prompt-cache tokens (both cache read and cache creation) were billed at standard rates even when the request used fast mode. Per Anthropic's pricing model, cache multipliers stack on top of the fast base input rate, meaning cache token costs should scale by the fast/standard input ratio rather than remaining at the standard cache rate. - Introduced `fastCacheRate`, a helper that scales a standard cache rate to the fast-mode equivalent by multiplying it by the fast/standard input price ratio. - Applied `fastCacheRate` as an early-return guard in `tieredCacheReadInputTokenRate`, `tieredCacheCreationInputTokenRate`, and `tieredCacheCreationInputAbove1hrTokenRate` so fast-mode requests use the correctly scaled cache rates. - Updated the existing fast-mode cache test (`TestComputeTextCost_FastMode_CacheStacksOnFastBase`) to reflect the correct expected values (cache tokens now scale 2× when the fast input rate is 2× the standard rate). - Added a regression test (`TestComputeTextCost_FastMode_Opus48CacheRegression`) pinning the real-world miscalculation observed with Anthropic Opus 4.8 fast mode + `cache_control`, where 44,667 5-minute cache-creation tokens were billed at the standard $6.25/MTok instead of the fast-scaled $12.50/MTok. - [x] Bug fix - [x] Core (Go) ```sh go test ./framework/modelcatalog/datasheet/... ``` The new regression test `TestComputeTextCost_FastMode_Opus48CacheRegression` will fail on the unfixed code and pass after this change. The updated `TestComputeTextCost_FastMode_CacheStacksOnFastBase` validates the general scaling behaviour. - [x] No None. - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
tejas ghatte seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. 💤 Files selected but had no reviewable changes (1)
⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Confidence Score: 4/5This is close, but the Responses streaming cases should be fixed before merging.
tests/e2e/api/collections/provider-harness.json Important Files Changed
Reviews (4): Last reviewed commit: "tests: openai cache coverage" | Re-trigger Greptile |
## Summary Adds support for Anthropic's data-residency billing feature (`inference_geo`). When Anthropic serves inference in the US (`inference_geo: "us"`), a 1.1x multiplier is applied to all token and cache costs. This PR propagates the `inference_geo` field through the full response pipeline (chat, responses, streaming, passthrough) and wires it into the cost computation layer, including a new database column and UI override field. A secondary fix ensures Anthropic server-tool web search request counts (`ServerToolUse.WebSearchRequests`) are correctly forwarded and billed in both streaming and non-streaming paths, where previously the count could be lost when the terminal chunk overwrote the accumulated usage. ## Changes - **`inference_geo` propagation**: `InferenceGeo *string` added to `BifrostChatResponse`, `BifrostResponsesResponse`, and `BifrostPassthroughUsage`. The field is forwarded from `AnthropicUsage` in all conversion paths: non-streaming chat, non-streaming responses, streaming chat (captured across events and set on the final chunk), streaming responses (`message_delta`), and passthrough. - **Data-residency multiplier in cost computation**: `serviceTier` gains an `inferenceGeoUS bool` flag. `tierFromResponse` now accepts and evaluates `inferenceGeo`. `computeTextCost` applies `InferenceGeoUSMultiplier` to token/cache costs only — the flat per-search fee is intentionally excluded. - **Database migration**: `migrationAddInferenceGeoMultiplierColumn` adds `inference_geo_us_multiplier` to `TableModelPricing`. The column is included in the pricing sync update list and mapped through `convertEntryToTablePricing` / `convertTablePricingToEntry`. - **Web search billing fix**: `accumulateAnthropicResponsesUsage` now carries `ServerToolUse.WebSearchRequests` into the accumulator so the count survives the terminal-chunk overwrite on streamed Responses requests. The non-streaming chat converter also forwards the count into `CompletionTokensDetails.NumSearchQueries`. - **UI**: `inference_geo_us_multiplier` added to the custom pricing override sheet and `PricingOverridePatch` TypeScript type. - **Tests**: New unit tests cover the accumulator web-search fix, chat/responses converter forwarding of `InferenceGeo` and web search counts, multiplier application (including the no-multiplier-column safe no-op), and `tierFromResponse` geo detection (case-insensitive). ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh # Core/Transports go test ./core/providers/anthropic/... ./framework/modelcatalog/datasheet/... # UI cd ui pnpm i || npm i pnpm build || npm run build ``` To validate end-to-end: send a request to an Anthropic model with data residency enabled. The response should include `inference_geo: "us"` and the computed cost should reflect the 1.1x multiplier on token/cache costs, with the per-search fee unchanged. ## Breaking changes - [ ] Yes - [x] No ## Security considerations No auth, secrets, or PII implications. The `inference_geo` value is sourced from Anthropic's API response and used only for billing computation. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
## Summary During OpenAI chat completion streaming, the `service_tier` field returned in stream chunks was being discarded, causing the final assembled response to lose priority/flex billing tier information. This PR captures `service_tier` as it appears in stream chunks and propagates it to the final response. ## Changes - Introduced a `serviceTier` variable to track the `service_tier` value echoed across streaming chunks. - After the stream completes and the final response is assembled, the captured `service_tier` is applied to the response so priority/flex billing metadata is preserved. ## Type of change - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Send a streaming chat completion request to an OpenAI endpoint using a `service_tier` (e.g., `"flex"` or `"priority"`). Verify that the final streamed response includes the correct `service_tier` value. ```sh go test ./... ``` ## Breaking changes - [ ] Yes - [x] No ## Related issues ## Security considerations No security implications. This change only propagates a billing tier metadata field from stream chunks to the final response object. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
b1879fc to
c59ec94
Compare
fb45714 to
c2a13cf
Compare
c2a13cf to
7176f83
Compare
c59ec94 to
b610755
Compare
Merge activity
|
The base branch was changed.

Summary
Adds Cross-Cut Round 31 to the provider harness E2E test suite, covering OpenAI prompt caching across the new
gpt-5.6model family (sol, terra, luna) and legacy models (gpt-4o, gpt-4.1, gpt-5, etc.). The suite validates thatprompt_cache_options,prompt_cache_breakpoint, andcache_write_tokensfields are correctly passed through and that cold-write/warm-read cache cycles produce the expected token accounting in both streaming and non-streaming modes.Changes
pcNoncecollection variable initialized once per run in the pre-request script so that all write/read request pairs within a run share a stable, unique cache key prefix without colliding across runs.cachePrefixcollection variable containing a deliberately verbose, stable system prompt designed to exceed provider minimum token thresholds for prompt caching eligibility.gpt-5.6(sol, terra, luna) non-streaming: testsprompt_cache_options+prompt_cache_breakpoint+cache_write_tokenson both/v1/chat/completionsand/v1/responsesendpoints via native and drop-in routes.gpt-5.6streaming: same coverage as 31.1 with SSE content-type assertions and streamed usage extraction.cached_tokensshape and cache hit on automatic (implicit) caching without explicit breakpoints.cache_write_tokens > 0; read assertions checkcached_tokens > 0. Responses API write tests additionally assert thatprompt_cache_optionsis echoed back in the response.Type of change
Affected areas
How to test
Run the collection via Newman against a live Bifrost instance with valid OpenAI credentials:
Expected outcome: all write requests report
cache_write_tokens > 0on cold cache, and all paired read requests reportcached_tokens > 0confirming a cache hit. Run the suite twice with differentpcNoncevalues to confirm isolation between runs.Screenshots/Recordings
N/A — no UI changes.
Breaking changes
Related issues
N/A
Security considerations
The
cachePrefixvalue is a static, non-sensitive string used solely to pad prompts to caching-eligible token lengths. No secrets, PII, or auth material is introduced.Checklist
docs/contributing/README.mdand followed the guidelines