Skip to content

Commit 18fa71b

Browse files
committed
feat: add usage data to the service parsers
1 parent 57dc306 commit 18fa71b

File tree

5 files changed

+106
-15
lines changed

5 files changed

+106
-15
lines changed

_build/js/src/executor/services.ts

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,34 @@ export type ServiceType = 'chatgpt' | 'claude' | 'gemini';
44
export type BufferMode = 'buffered' | 'stream';
55
export type ParserType = keyof ServiceHandlers[BufferMode][ServiceType];
66

7+
export type UsageData = {
8+
usage: {
9+
promptTokens: number;
10+
completionTokens: number;
11+
};
12+
};
13+
714
export type ToolCalls = {
815
id: string;
916
name: string;
1017
arguments: string;
1118
}[];
1219

13-
export type TextDataMaybeTools = {
20+
export type TextDataMaybeTools = UsageData & {
1421
__type: 'TextDataMaybeTools';
1522
id: string;
1623
content: string;
1724
toolCalls?: ToolCalls;
1825
};
1926

20-
export type ToolsData = {
27+
export type ToolsData = UsageData & {
2128
__type: 'ToolsData';
2229
id: string;
2330
content?: undefined;
2431
toolCalls: ToolCalls;
2532
};
2633

27-
export type TextDataNoTools = {
34+
export type TextDataNoTools = UsageData & {
2835
__type: 'TextDataNoTools';
2936
id: string;
3037
content: string;
@@ -54,6 +61,10 @@ export type ChatGPTCompletionsData = {
5461
}[];
5562
};
5663
}[];
64+
usage: {
65+
prompt_tokens: number;
66+
completion_tokens: number;
67+
};
5768
};
5869

5970
export type ChatGPTStreamCompletionsData = {
@@ -72,6 +83,10 @@ export type ChatGPTStreamCompletionsData = {
7283
}[];
7384
};
7485
}[];
86+
usage: null | {
87+
prompt_tokens: number;
88+
completion_tokens: number;
89+
};
7590
};
7691

7792
export type ChatGPTImageData = {
@@ -95,6 +110,10 @@ export type ClaudeCompletionsData = {
95110
input: Record<string, unknown>;
96111
}
97112
)[];
113+
usage: {
114+
input_tokens: number;
115+
output_tokens: number;
116+
};
98117
};
99118

100119
export type ClaudeStreamCompletionsData =
@@ -140,6 +159,10 @@ export type GeminiCompletionsData = {
140159
}[];
141160
};
142161
}[];
162+
usageMetadata: {
163+
promptTokenCount: number;
164+
candidatesTokenCount: number;
165+
};
143166
};
144167

145168
export type GeminiStreamCompletionsData = {
@@ -154,6 +177,10 @@ export type GeminiStreamCompletionsData = {
154177
}[];
155178
};
156179
}[];
180+
usageMetadata: {
181+
promptTokenCount: number;
182+
candidatesTokenCount: number;
183+
};
157184
};
158185

159186
export type GeminiImageData = {
@@ -227,6 +254,10 @@ export const services: ServiceHandlers = {
227254
__type: 'TextDataNoTools',
228255
id,
229256
content: content as string,
257+
usage: {
258+
completionTokens: data?.usage.completion_tokens,
259+
promptTokens: data?.usage.prompt_tokens,
260+
},
230261
};
231262
}
232263

@@ -239,6 +270,10 @@ export const services: ServiceHandlers = {
239270
name: tool.function.name,
240271
arguments: tool.function.arguments,
241272
})),
273+
usage: {
274+
completionTokens: data?.usage.completion_tokens,
275+
promptTokens: data?.usage.prompt_tokens,
276+
},
242277
};
243278
}
244279

@@ -251,6 +286,10 @@ export const services: ServiceHandlers = {
251286
name: tool.function.name,
252287
arguments: tool.function.arguments,
253288
})),
289+
usage: {
290+
completionTokens: data?.usage.completion_tokens,
291+
promptTokens: data?.usage.prompt_tokens,
292+
},
254293
};
255294
},
256295
image: (data) => {
@@ -302,6 +341,10 @@ export const services: ServiceHandlers = {
302341
__type: 'TextDataNoTools',
303342
id,
304343
content: content as string,
344+
usage: {
345+
completionTokens: data?.usage.output_tokens,
346+
promptTokens: data?.usage.input_tokens,
347+
},
305348
};
306349
}
307350

@@ -310,6 +353,10 @@ export const services: ServiceHandlers = {
310353
__type: 'ToolsData',
311354
id,
312355
toolCalls: tools,
356+
usage: {
357+
completionTokens: data?.usage.output_tokens,
358+
promptTokens: data?.usage.input_tokens,
359+
},
313360
};
314361
}
315362

@@ -318,6 +365,10 @@ export const services: ServiceHandlers = {
318365
id,
319366
toolCalls: tools,
320367
content: content,
368+
usage: {
369+
completionTokens: data?.usage.output_tokens,
370+
promptTokens: data?.usage.input_tokens,
371+
},
321372
};
322373
},
323374
},
@@ -358,6 +409,10 @@ export const services: ServiceHandlers = {
358409
__type: 'TextDataNoTools',
359410
id: crypto.randomUUID(),
360411
content: content as string,
412+
usage: {
413+
completionTokens: data?.usageMetadata.candidatesTokenCount,
414+
promptTokens: data?.usageMetadata.promptTokenCount,
415+
},
361416
};
362417
}
363418

@@ -366,6 +421,10 @@ export const services: ServiceHandlers = {
366421
__type: 'ToolsData',
367422
id: crypto.randomUUID(),
368423
toolCalls: tools,
424+
usage: {
425+
completionTokens: data?.usageMetadata.candidatesTokenCount,
426+
promptTokens: data?.usageMetadata.promptTokenCount,
427+
},
369428
};
370429
}
371430

@@ -374,6 +433,10 @@ export const services: ServiceHandlers = {
374433
id: crypto.randomUUID(),
375434
content: content,
376435
toolCalls: tools,
436+
usage: {
437+
completionTokens: data?.usageMetadata.candidatesTokenCount,
438+
promptTokens: data?.usageMetadata.promptTokenCount,
439+
},
377440
};
378441
},
379442
image: (data) => {
@@ -394,6 +457,13 @@ export const services: ServiceHandlers = {
394457
stream: {
395458
chatgpt: {
396459
content: (newData, currentData) => {
460+
if (newData?.usage) {
461+
currentData.usage = {
462+
completionTokens: newData?.usage?.completion_tokens || 0,
463+
promptTokens: newData?.usage?.prompt_tokens || 0,
464+
};
465+
}
466+
397467
if (!newData?.choices?.[0]?.delta?.tool_calls && !newData?.choices?.[0]?.delta?.content) {
398468
return currentData;
399469
}
@@ -438,6 +508,10 @@ export const services: ServiceHandlers = {
438508
id: currentData.id,
439509
content: (currentData.content ?? '') + content,
440510
toolCalls,
511+
usage: {
512+
completionTokens: currentData.usage.completionTokens ?? 0,
513+
promptTokens: currentData.usage.promptTokens ?? 0,
514+
},
441515
};
442516
},
443517
},
@@ -475,6 +549,10 @@ export const services: ServiceHandlers = {
475549
id: currentData.id,
476550
content: (currentData.content ?? '') + content,
477551
toolCalls,
552+
usage: {
553+
completionTokens: currentData.usage.completionTokens || 0,
554+
promptTokens: currentData.usage.promptTokens || 0,
555+
},
478556
};
479557
},
480558
},
@@ -509,6 +587,10 @@ export const services: ServiceHandlers = {
509587
id: currentData.id,
510588
content: (currentData.content || '') + content,
511589
toolCalls,
590+
usage: {
591+
completionTokens: newData?.usageMetadata.candidatesTokenCount,
592+
promptTokens: newData?.usageMetadata.promptTokenCount,
593+
},
512594
};
513595
},
514596
},

_build/js/src/executor/streamHandlers.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ export const streamHandlers: Record<string, StreamHandler> = {
8282
const parsedData = JSON.parse(data);
8383
if (parsedData.type === 'message_start') {
8484
currentData.id = parsedData.message.id;
85+
currentData.usage = {
86+
promptTokens: parsedData.message.usage.input_tokens,
87+
completionTokens: 0,
88+
};
89+
continue;
90+
}
91+
92+
if (parsedData.type === 'message_delta') {
93+
currentData.usage.completionTokens = parsedData.usage.output_tokens;
8594
continue;
8695
}
8796

0 commit comments

Comments
 (0)