Skip to content

Commit d7080f4

Browse files
authored
fix: add reasoning tokens to usage stats for gemini models (#3339)
1 parent 9c54cf9 commit d7080f4

File tree

5 files changed

+34
-11
lines changed

5 files changed

+34
-11
lines changed

js/plugins/google-genai/src/common/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ export declare interface UsageMetadata {
378378
totalTokenCount?: number;
379379
/** Optional. Number of tokens in the cached content. */
380380
cachedContentTokenCount?: number;
381+
/** Optional. Number of tokens present in thoughts output. */
382+
thoughtsTokenCount?: number;
381383
}
382384

383385
export const TaskTypeSchema = z.enum([

js/plugins/google-genai/src/googleai/gemini.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ export function defineModel(
621621
...getBasicUsageStats(request.messages, candidateData),
622622
inputTokens: response.usageMetadata?.promptTokenCount,
623623
outputTokens: response.usageMetadata?.candidatesTokenCount,
624+
thoughtsTokens: response.usageMetadata?.thoughtsTokenCount,
624625
totalTokens: response.usageMetadata?.totalTokenCount,
625626
cachedContentTokens:
626627
response.usageMetadata?.cachedContentTokenCount,

js/plugins/google-genai/src/vertexai/gemini.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ export function defineModel(
643643
...getBasicUsageStats(request.messages, candidateData),
644644
inputTokens: response.usageMetadata?.promptTokenCount,
645645
outputTokens: response.usageMetadata?.candidatesTokenCount,
646+
thoughtsTokens: response.usageMetadata?.thoughtsTokenCount,
646647
totalTokens: response.usageMetadata?.totalTokenCount,
647648
cachedContentTokens:
648649
response.usageMetadata?.cachedContentTokenCount,

js/plugins/googleai/src/gemini.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
type StartChatParams,
3737
type Tool,
3838
type ToolConfig,
39+
type UsageMetadata,
3940
} from '@google/generative-ai';
4041
import {
4142
GENKIT_CLIENT_HEADER,
@@ -67,6 +68,13 @@ import { getApiKeyFromEnvVar } from './common';
6768
import { handleCacheIfNeeded } from './context-caching';
6869
import { extractCacheConfig } from './context-caching/utils';
6970

71+
// Extra type guard to keep the compiler happy and avoid a cast to any. The
72+
// legacy Gemini SDK is no longer maintained, and doesn't have updated types.
73+
// However, the REST API returns the data we want.
74+
type ExtendedUsageMetadata = UsageMetadata & {
75+
thoughtsTokenCount?: number;
76+
};
77+
7078
/**
7179
* See https://ai.google.dev/gemini-api/docs/safety-settings#safety-filters.
7280
*/
@@ -1385,16 +1393,18 @@ export function defineGoogleAIModel({
13851393
const candidateData =
13861394
candidates.map(fromJSONModeScopedGeminiCandidate) || [];
13871395

1396+
const usageMetadata = response.usageMetadata as ExtendedUsageMetadata;
1397+
13881398
return {
13891399
candidates: candidateData,
13901400
custom: response,
13911401
usage: {
13921402
...getBasicUsageStats(request.messages, candidateData),
1393-
inputTokens: response.usageMetadata?.promptTokenCount,
1394-
outputTokens: response.usageMetadata?.candidatesTokenCount,
1395-
totalTokens: response.usageMetadata?.totalTokenCount,
1396-
cachedContentTokens:
1397-
response.usageMetadata?.cachedContentTokenCount,
1403+
inputTokens: usageMetadata?.promptTokenCount,
1404+
outputTokens: usageMetadata?.candidatesTokenCount,
1405+
thoughtsTokens: usageMetadata?.thoughtsTokenCount,
1406+
totalTokens: usageMetadata?.totalTokenCount,
1407+
cachedContentTokens: usageMetadata?.cachedContentTokenCount,
13981408
},
13991409
};
14001410
};

js/plugins/vertexai/src/gemini.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import {
1818
FunctionCallingMode,
1919
FunctionDeclarationSchemaType,
20+
UsageMetadata,
2021
type Content,
2122
type FunctionDeclaration,
2223
type Part as GeminiPart,
@@ -63,11 +64,17 @@ import {
6364
} from 'genkit/model/middleware';
6465
import { runInNewSpan } from 'genkit/tracing';
6566
import { GoogleAuth } from 'google-auth-library';
66-
6767
import type { PluginOptions } from './common/types.js';
6868
import { handleCacheIfNeeded } from './context-caching/index.js';
6969
import { extractCacheConfig } from './context-caching/utils.js';
7070

71+
// Extra type guard to keep the compiler happy and avoid a cast to any. The
72+
// legacy Gemini SDK is no longer maintained, and doesn't have updated types.
73+
// However, the REST API returns the data we want.
74+
type ExtendedUsageMetadata = UsageMetadata & {
75+
thoughtsTokenCount?: number;
76+
};
77+
7178
export const SafetySettingsSchema = z.object({
7279
category: z.enum([
7380
/** The harm category is unspecified. */
@@ -1276,16 +1283,18 @@ export function defineGeminiModel({
12761283
fromGeminiCandidate(c, jsonMode)
12771284
);
12781285

1286+
const usageMetadata = response.usageMetadata as ExtendedUsageMetadata;
1287+
12791288
return {
12801289
candidates: candidateData,
12811290
custom: response,
12821291
usage: {
12831292
...getBasicUsageStats(request.messages, candidateData),
1284-
inputTokens: response.usageMetadata?.promptTokenCount,
1285-
outputTokens: response.usageMetadata?.candidatesTokenCount,
1286-
totalTokens: response.usageMetadata?.totalTokenCount,
1287-
cachedContentTokens:
1288-
response.usageMetadata?.cachedContentTokenCount,
1293+
inputTokens: usageMetadata?.promptTokenCount,
1294+
outputTokens: usageMetadata?.candidatesTokenCount,
1295+
totalTokens: usageMetadata?.totalTokenCount,
1296+
thoughtsTokens: usageMetadata?.thoughtsTokenCount,
1297+
cachedContentTokens: usageMetadata?.cachedContentTokenCount,
12891298
},
12901299
};
12911300
};

0 commit comments

Comments
 (0)