Skip to content

Commit 7979f7f

Browse files
authored
feat (provider): support reasoning tokens, cached input tokens, total token in usage information (#6140)
## Background Over the past year, additional token usage information such as cached input tokens and reasoning tokens were added by many providers. In addition, the meaning of total tokens is now provider-dependent, with some providers including reasoning tokens in the total token count. ## Summary Standardize sending reasoning tokens, cached prompt tokens, and total tokens from the providers.
1 parent 8919eff commit 7979f7f

File tree

74 files changed

+3177
-2047
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+3177
-2047
lines changed

‎.changeset/silver-vans-march.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@ai-sdk/provider': major
3+
---
4+
5+
feat (provider): support reasoning tokens, cached input tokens, total token in usage information

‎content/providers/01-ai-sdk-providers/05-anthropic.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ const result = await generateText({
183183

184184
console.log(result.text);
185185
console.log(result.providerMetadata?.anthropic);
186-
// e.g. { cacheCreationInputTokens: 2118, cacheReadInputTokens: 0 }
186+
// e.g. { cacheCreationInputTokens: 2118 }
187187
```
188188

189189
You can also use cache control on system messages by providing multiple system messages at the head of your messages array:

‎examples/ai-core/src/generate-object/mock-error.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ async function main() {
1616
modelId: 'model-1',
1717
},
1818
finishReason: 'stop',
19-
usage: { inputTokens: 10, outputTokens: 20 },
19+
usage: {
20+
inputTokens: 10,
21+
outputTokens: 20,
22+
totalTokens: 30,
23+
},
2024
}),
2125
}),
2226
schema: z.object({ content: z.string() }),

‎examples/ai-core/src/generate-object/mock-repair-add-close.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ async function main() {
77
const result = await generateObject({
88
model: new MockLanguageModelV2({
99
doGenerate: async () => ({
10-
usage: { inputTokens: 10, outputTokens: 20 },
10+
usage: {
11+
inputTokens: 10,
12+
outputTokens: 20,
13+
totalTokens: 30,
14+
},
1115
warnings: [],
1216
finishReason: 'tool-calls',
1317
content: [

‎examples/ai-core/src/generate-object/mock.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ async function main() {
99
doGenerate: async () => ({
1010
content: [{ type: 'text', text: `{"content":"Hello, world!"}` }],
1111
finishReason: 'stop',
12-
usage: { inputTokens: 10, outputTokens: 20 },
12+
usage: {
13+
inputTokens: 10,
14+
outputTokens: 20,
15+
totalTokens: 30,
16+
},
1317
warnings: [],
1418
}),
1519
}),

‎examples/ai-core/src/generate-text/anthropic-cache-control.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ async function main() {
3535
});
3636

3737
console.log(result.text);
38-
console.log(result.providerMetadata?.anthropic);
39-
// e.g. { cacheCreationInputTokens: 2118, cacheReadInputTokens: 0 }
38+
console.log();
39+
40+
console.log('Cache read tokens:', result.usage.cachedInputTokens);
41+
console.log(
42+
'Cache write tokens:',
43+
result.providerMetadata?.anthropic?.cacheCreationInputTokens,
44+
);
4045
}
4146

4247
main().catch(console.error);

‎examples/ai-core/src/generate-text/mock-tool-call-repair-reask.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ async function main() {
99
model: new MockLanguageModelV2({
1010
doGenerate: async () => ({
1111
warnings: [],
12-
usage: { inputTokens: 10, outputTokens: 20 },
12+
usage: {
13+
inputTokens: 10,
14+
outputTokens: 20,
15+
totalTokens: 30,
16+
},
1317
finishReason: 'tool-calls',
1418
content: [
1519
{

‎examples/ai-core/src/generate-text/mock-tool-call-repair-structured-model.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ async function main() {
99
model: new MockLanguageModelV2({
1010
doGenerate: async () => ({
1111
warnings: [],
12-
usage: { inputTokens: 10, outputTokens: 20 },
12+
usage: {
13+
inputTokens: 10,
14+
outputTokens: 20,
15+
totalTokens: 30,
16+
},
1317
finishReason: 'tool-calls',
1418
content: [
1519
{

‎examples/ai-core/src/generate-text/mock.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ async function main() {
88
doGenerate: async () => ({
99
content: [{ type: 'text', text: `Hello, world!` }],
1010
finishReason: 'stop',
11-
usage: { inputTokens: 10, outputTokens: 20 },
11+
usage: {
12+
inputTokens: 10,
13+
outputTokens: 20,
14+
totalTokens: 30,
15+
},
1216
warnings: [],
1317
}),
1418
}),

‎examples/ai-core/src/generate-text/openai-reasoning.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@ import { generateText } from 'ai';
33
import 'dotenv/config';
44

55
async function main() {
6-
const { text, usage, providerMetadata } = await generateText({
6+
const { text, usage } = await generateText({
77
model: openai('o3-mini'),
88
prompt: 'How many "r"s are in the word "strawberry"?',
99
temperature: 0.5, // should get ignored (warning)
1010
maxOutputTokens: 1000, // mapped to max_completion_tokens
1111
});
1212

1313
console.log(text);
14-
console.log();
15-
console.log('Usage:', {
16-
...usage,
17-
reasoningTokens: providerMetadata?.openai?.reasoningTokens,
18-
});
14+
console.log('Usage:', usage);
1915
}
2016

2117
main().catch(console.error);

0 commit comments

Comments
 (0)