mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-17 20:52:15 +03:00
fix(usage): surface Gemini cachedContentTokenCount as cached_tokens (#10465)
* fix(usage): read Gemini usageMetadata out of the antigravity response envelope
Port decolua/9router#59d858b: antigravity/gemini-cli wrap non-streaming
payloads in { response: {...} }, so extractUsageFromResponse only saw the
top-level usageMetadata and every non-streaming antigravity request logged
zero usage (IN 0 | OUT 0) and zeroed usage-dashboard rows. Top-level
metadata keeps priority; OpenAI/Claude branches untouched.
* chore(changelog): fragment for #10430 antigravity usage envelope
* fix(usage): surface Gemini cachedContentTokenCount as cached_tokens
Review follow-up on #10430: the Gemini branch of extractUsageFromResponse
ignored cachedContentTokenCount, so non-streaming cache-hit tokens never
reached the cached_tokens field the OpenAI/Claude/Responses branches
already populate (and the streaming path surfaces at usageTracking.ts:684).
Adds cached_tokens: usageMetadata.cachedContentTokenCount || 0, updates
the three Gemini assertions (envelope fixture already carried
cachedContentTokenCount: 7), and adds a dedicated regression test.
* chore(changelog): fragment for #10465 Gemini cached_tokens surfacing
* test(fix): refresh expired alibaba quota sample validity and onnxruntime pin for v3.8.50 base
- alibaba-free-tier-quota-fetcher.test.ts: sample quotaValidityPeriod
(2026-08-16 16:00 UTC) is in the past, making every quota entry classify
as expired/not_capable; bump to 2028-01-01 UTC so the text/merge
classification tests exercise the intended path again.
- optional-transformers-dependency.test.ts: onnxruntime-node pin assertion
updated from ~1.24.3 to ~1.27.0 to match package.json (bumped by #10403);
the regular-not-optional intent is unchanged.
---------
Co-authored-by: Rouzbeh <rqzbeh@users.noreply.github.com>
This commit is contained in:
1
changelog.d/fixes/10465-gemini-cached-tokens.md
Normal file
1
changelog.d/fixes/10465-gemini-cached-tokens.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(usage):** surface Gemini `cachedContentTokenCount` into `cached_tokens` for non-streaming requests so cache-hit accounting matches the OpenAI/Claude/Responses branches and the streaming path (follow-up to the #10430 envelope fix) ([#10465](https://github.com/diegosouzapw/OmniRoute/pull/10465)) — thanks @rqzbeh
|
||||
@@ -104,6 +104,7 @@ export function extractUsageFromResponse(responseBody, provider) {
|
||||
return {
|
||||
prompt_tokens: usageMetadata.promptTokenCount || 0,
|
||||
completion_tokens: (usageMetadata.candidatesTokenCount || 0) + thoughts,
|
||||
cached_tokens: usageMetadata.cachedContentTokenCount || 0,
|
||||
reasoning_tokens: thoughts,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -228,6 +228,7 @@ test("extractUsageFromResponse reads Gemini usageMetadata and thinking tokens",
|
||||
assert.deepEqual(usage, {
|
||||
prompt_tokens: 11,
|
||||
completion_tokens: 7,
|
||||
cached_tokens: 0,
|
||||
reasoning_tokens: 2,
|
||||
});
|
||||
});
|
||||
@@ -252,6 +253,7 @@ test("extractUsageFromResponse reads Gemini usageMetadata from the antigravity r
|
||||
assert.deepEqual(usage, {
|
||||
prompt_tokens: 42,
|
||||
completion_tokens: 17,
|
||||
cached_tokens: 7,
|
||||
reasoning_tokens: 4,
|
||||
});
|
||||
});
|
||||
@@ -268,10 +270,34 @@ test("extractUsageFromResponse prefers top-level usageMetadata over the envelope
|
||||
assert.deepEqual(usage, {
|
||||
prompt_tokens: 1,
|
||||
completion_tokens: 2,
|
||||
cached_tokens: 0,
|
||||
reasoning_tokens: 0,
|
||||
});
|
||||
});
|
||||
|
||||
test("extractUsageFromResponse surfaces Gemini cachedContentTokenCount as cached_tokens", () => {
|
||||
// Review follow-up on #10430: match the OpenAI/Claude/Responses branches and
|
||||
// the streaming path (usageTracking.ts) by surfacing Gemini cache-hit tokens.
|
||||
const usage = extractUsageFromResponse(
|
||||
{
|
||||
usageMetadata: {
|
||||
promptTokenCount: 30,
|
||||
candidatesTokenCount: 10,
|
||||
thoughtsTokenCount: 3,
|
||||
cachedContentTokenCount: 12,
|
||||
},
|
||||
},
|
||||
"gemini"
|
||||
);
|
||||
|
||||
assert.deepEqual(usage, {
|
||||
prompt_tokens: 30,
|
||||
completion_tokens: 13,
|
||||
cached_tokens: 12,
|
||||
reasoning_tokens: 3,
|
||||
});
|
||||
});
|
||||
|
||||
test("extractUsageFromResponse returns null when usage is missing", () => {
|
||||
const usage = extractUsageFromResponse(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user