ai-vercel-gateway: usage.cost leaves out gateway surcharges, and the BYOK credential type is not exposed
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 55/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- backend-api-design
Direzione di ricerca
Start with packages/ai-vercel-gateway/src/utils/gateway-cost.ts and the gateway response metadata described in the issue. Trace how withGatewayCost sets usage.cost and how providerUsageDetails is assembled, then check the related tests. Done when usage exposes the gateway-debited amount, surcharge information, and credential type as described.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What happens
Follow-up to #1845 (fixed in #1873, thank you). withGatewayCost copies provider_metadata.gateway.cost to usage.cost and documents it as the amount debited:
When the gateway adds a surcharge (Custom Reporting user / tags writes, Zero Data Retention), cost is the inference charge only. The amount debited is gatewayCost, which is cost + surchargeCost. Vercel's generation lookup docs define gateway_cost as "Total amount debited from your AI Gateway balance for this generation", and total_cost as including "any surcharges (for example, Zero Data Retention or Custom Reporting writes)".
The response also says which credential served the request (routing.modelAttempts[].providerAttempts[].credentialType: byok or system). That is not carried over either, so a consumer cannot tell whether cost: 0 means a BYOK request, which the provider bills at marketCost. We use costDetails.upstreamCost ?? cost for that today.
Repro
@tanstack/ai 1.0.0, @tanstack/ai-vercel-gateway 1.0.0, server-side chat() on Node 24
provider_metadata.gateway from POST https://ai-gateway.vercel.sh/v1/responses with max_output_tokens: 16:
| Model (credential) | providerOptions.gateway |
cost |
marketCost |
surchargeCost |
gatewayCost |
|---|---|---|---|---|---|
openai/gpt-4.1-nano (system) |
none | 0.0000019 | 0.0000019 | 0 | 0.0000019 |
openai/gpt-4.1-nano (system) |
user + tags |
0.0000019 | 0.0000019 | 0.00015 | 0.0001519 |
anthropic/claude-sonnet-5.5 (byok) |
none | 0 | 0.00008 | 0 | 0 |
anthropic/claude-sonnet-5.5 (byok) |
user + tags |
0 | 0.00008 | 0.00015 | 0.00015 |
The same user + tags requests through the adapter:
let usage
await chat({
adapter: createVercelGatewayText(model, key),
messages: [{ role: 'user', content: 'Reply with OK.' }],
threadId: 'repro',
stream: false,
modelOptions: { max_output_tokens: 16, gateway: { user: 'u1', tags: ['t1'] } },
middleware: [{ name: 'usage', onFinish: (_ctx, info) => { usage = info.usage } }],
})
| Model | usage.cost |
usage.costDetails |
usage.providerUsageDetails |
GET /v1/generation for that id |
|---|---|---|---|---|
openai/gpt-4.1-nano |
0.0000019 | { upstreamCost: 0.0000019 } |
generationId, finalProvider: 'azure' |
gateway_cost 0.0001519, surcharge_cost 0.00015, is_byok false |
anthropic/claude-sonnet-5.5 |
0 | { upstreamCost: 0.00008 } |
generationId, finalProvider: 'anthropic' |
gateway_cost 0.00015, surcharge_cost 0.00015, is_byok true |
Expected
usage.cost is what the gateway debits (gatewayCost), or the surcharge is available next to it (for example surchargeCost and gatewayCost in providerUsageDetails). The credential type is carried in providerUsageDetails as well.
Why
Per-run cost in our analytics should match the gateway bill. For BYOK runs we report the provider's list price instead, which only works when we can tell BYOK from system credits.
- Lingua principale
- TypeScript
- Stelle
- 3.2k
- Fork
- 372
- Merge medio
- 1g 5h
- PR unite (30g)
- 233
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di TanStack/ai
-
openai-base: a Responses max_output_tokens cutoff ends as RUN_ERROR without usage instead of finishReason 'length'Forse già presa @tombeckenham l’ha presa oggi. Apertahas-pr waiting-on: maintainer
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
TanStack/ai#1916 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 1-2 giorni Idoneità per principianti 58/100
I maintainer di solito rispondono entro 1 giorno
-
`ChatEngine.handleTextMessageContentEvent` is O(n²) in answer length: `startsWith(before)` copies the whole accumulated text on every chunkForse già presa @tombeckenham l’ha presa oggi. Apertawaiting-on: maintainer
TanStack/ai#1951 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
openai-base: streamed `apply_patch` calls reach the app with an empty `diff`Forse già presa @tombeckenham l’ha presa oggi. Apertahas-pr waiting-on: maintainer
TanStack/ai#1947 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
needsApproval client tools can't be approved without a server (custom connection adapters)Forse già presa @jherr l’ha presa oggi. Apertawaiting-on: maintainer
TanStack/ai#1945 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
CopilotKit/openmuse#215 ·
I maintainer di solito rispondono entro 3 giorni
-
b:minor bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
software-mansion/argent#1698 ·
I maintainer di solito rispondono entro 1 giorno
-
e2e-failure ready-to-code
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
redhat-developer/rhdh-plugin-export-overlays#4624 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno