@ai-sdk/openai 3.0.17 → 3.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/index.d.mts +20 -1
  3. package/dist/index.d.ts +20 -1
  4. package/dist/index.js +15 -17
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +15 -17
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/internal/index.d.mts +20 -1
  9. package/dist/internal/index.d.ts +20 -1
  10. package/dist/internal/index.js +14 -16
  11. package/dist/internal/index.js.map +1 -1
  12. package/dist/internal/index.mjs +14 -16
  13. package/dist/internal/index.mjs.map +1 -1
  14. package/docs/03-openai.mdx +67 -11
  15. package/package.json +8 -4
  16. package/src/index.ts +2 -0
  17. package/src/responses/openai-responses-language-model.ts +24 -26
  18. package/src/responses/openai-responses-provider-metadata.ts +23 -1
  19. package/src/chat/__fixtures__/azure-model-router.1.chunks.txt +0 -8
  20. package/src/chat/__snapshots__/openai-chat-language-model.test.ts.snap +0 -88
  21. package/src/chat/convert-to-openai-chat-messages.test.ts +0 -516
  22. package/src/chat/openai-chat-language-model.test.ts +0 -3496
  23. package/src/chat/openai-chat-prepare-tools.test.ts +0 -322
  24. package/src/completion/openai-completion-language-model.test.ts +0 -752
  25. package/src/embedding/__snapshots__/openai-embedding-model.test.ts.snap +0 -43
  26. package/src/embedding/openai-embedding-model.test.ts +0 -146
  27. package/src/image/openai-image-model.test.ts +0 -722
  28. package/src/openai-error.test.ts +0 -34
  29. package/src/openai-language-model-capabilities.test.ts +0 -93
  30. package/src/openai-provider.test.ts +0 -98
  31. package/src/responses/__fixtures__/openai-apply-patch-tool-delete.1.chunks.txt +0 -5
  32. package/src/responses/__fixtures__/openai-apply-patch-tool.1.chunks.txt +0 -38
  33. package/src/responses/__fixtures__/openai-apply-patch-tool.1.json +0 -69
  34. package/src/responses/__fixtures__/openai-code-interpreter-tool.1.chunks.txt +0 -393
  35. package/src/responses/__fixtures__/openai-code-interpreter-tool.1.json +0 -137
  36. package/src/responses/__fixtures__/openai-error.1.chunks.txt +0 -4
  37. package/src/responses/__fixtures__/openai-error.1.json +0 -8
  38. package/src/responses/__fixtures__/openai-file-search-tool.1.chunks.txt +0 -94
  39. package/src/responses/__fixtures__/openai-file-search-tool.1.json +0 -89
  40. package/src/responses/__fixtures__/openai-file-search-tool.2.chunks.txt +0 -93
  41. package/src/responses/__fixtures__/openai-file-search-tool.2.json +0 -112
  42. package/src/responses/__fixtures__/openai-image-generation-tool.1.chunks.txt +0 -16
  43. package/src/responses/__fixtures__/openai-image-generation-tool.1.json +0 -96
  44. package/src/responses/__fixtures__/openai-local-shell-tool.1.chunks.txt +0 -7
  45. package/src/responses/__fixtures__/openai-local-shell-tool.1.json +0 -70
  46. package/src/responses/__fixtures__/openai-mcp-tool-approval.1.chunks.txt +0 -11
  47. package/src/responses/__fixtures__/openai-mcp-tool-approval.1.json +0 -169
  48. package/src/responses/__fixtures__/openai-mcp-tool-approval.2.chunks.txt +0 -123
  49. package/src/responses/__fixtures__/openai-mcp-tool-approval.2.json +0 -176
  50. package/src/responses/__fixtures__/openai-mcp-tool-approval.3.chunks.txt +0 -11
  51. package/src/responses/__fixtures__/openai-mcp-tool-approval.3.json +0 -169
  52. package/src/responses/__fixtures__/openai-mcp-tool-approval.4.chunks.txt +0 -84
  53. package/src/responses/__fixtures__/openai-mcp-tool-approval.4.json +0 -182
  54. package/src/responses/__fixtures__/openai-mcp-tool.1.chunks.txt +0 -373
  55. package/src/responses/__fixtures__/openai-mcp-tool.1.json +0 -159
  56. package/src/responses/__fixtures__/openai-reasoning-encrypted-content.1.chunks.txt +0 -110
  57. package/src/responses/__fixtures__/openai-reasoning-encrypted-content.1.json +0 -117
  58. package/src/responses/__fixtures__/openai-shell-tool.1.chunks.txt +0 -182
  59. package/src/responses/__fixtures__/openai-shell-tool.1.json +0 -73
  60. package/src/responses/__fixtures__/openai-web-search-tool.1.chunks.txt +0 -185
  61. package/src/responses/__fixtures__/openai-web-search-tool.1.json +0 -266
  62. package/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap +0 -10955
  63. package/src/responses/convert-to-openai-responses-input.test.ts +0 -3223
  64. package/src/responses/openai-responses-api.test.ts +0 -89
  65. package/src/responses/openai-responses-language-model.test.ts +0 -6927
  66. package/src/responses/openai-responses-prepare-tools.test.ts +0 -924
  67. package/src/speech/openai-speech-model.test.ts +0 -202
  68. package/src/tool/local-shell.test-d.ts +0 -20
  69. package/src/tool/web-search.test-d.ts +0 -13
  70. package/src/transcription/openai-transcription-model.test.ts +0 -507
@@ -255,24 +255,34 @@ The following provider options are available:
255
255
 
256
256
  The OpenAI responses provider also returns provider-specific metadata:
257
257
 
258
+ For Responses models, you can type this metadata using `OpenaiResponsesProviderMetadata`:
259
+
258
260
  ```ts
259
- const { providerMetadata } = await generateText({
260
- model: openai.responses('gpt-5'),
261
+ import { openai, type OpenaiResponsesProviderMetadata } from '@ai-sdk/openai';
262
+ import { generateText } from 'ai';
263
+
264
+ const result = await generateText({
265
+ model: openai('gpt-5'),
261
266
  });
262
267
 
263
- const openaiMetadata = providerMetadata?.openai;
264
- ```
268
+ const providerMetadata = result.providerMetadata as
269
+ | OpenaiResponsesProviderMetadata
270
+ | undefined;
265
271
 
266
- The following OpenAI-specific metadata is returned:
272
+ const { responseId, logprobs, serviceTier } = providerMetadata?.openai ?? {};
267
273
 
268
- - **responseId** _string_
269
- The ID of the response. Can be used to continue a conversation.
274
+ // responseId can be used to continue a conversation (previousResponseId).
275
+ console.log(responseId);
276
+ ```
270
277
 
271
- - **cachedPromptTokens** _number_
272
- The number of prompt tokens that were a cache hit.
278
+ The following OpenAI-specific metadata may be returned:
273
279
 
274
- - **reasoningTokens** _number_
275
- The number of reasoning tokens that the model generated.
280
+ - **responseId** _string | null | undefined_
281
+ The ID of the response. Can be used to continue a conversation.
282
+ - **logprobs** _(optional)_
283
+ Log probabilities of output tokens (when enabled).
284
+ - **serviceTier** _(optional)_
285
+ Service tier information returned by the API.
276
286
 
277
287
  #### Reasoning Output
278
288
 
@@ -929,6 +939,52 @@ for (const part of result.content) {
929
939
  API.
930
940
  </Note>
931
941
 
942
+ #### Typed providerMetadata in Reasoning Parts
943
+
944
+ When using the OpenAI Responses API, reasoning output parts can include provider metadata.
945
+ To handle this metadata in a type-safe way, use `OpenaiResponsesReasoningProviderMetadata`.
946
+
947
+ For reasoning parts, when `part.type === 'reasoning'`, the `providerMetadata` is provided in the form of `OpenaiResponsesReasoningProviderMetadata`.
948
+
949
+ This metadata includes the following fields:
950
+
951
+ - `itemId`
952
+ The ID of the reasoning item in the Responses API.
953
+ - `reasoningEncryptedContent` (optional)
954
+ Encrypted reasoning content (only returned when requested via `include: ['reasoning.encrypted_content']`).
955
+
956
+ ```ts
957
+ import {
958
+ openai,
959
+ type OpenaiResponsesReasoningProviderMetadata,
960
+ type OpenAIResponsesProviderOptions,
961
+ } from '@ai-sdk/openai';
962
+ import { generateText } from 'ai';
963
+
964
+ const result = await generateText({
965
+ model: openai('gpt-5'),
966
+ prompt: 'How many "r"s are in the word "strawberry"?',
967
+ providerOptions: {
968
+ openai: {
969
+ store: false,
970
+ include: ['reasoning.encrypted_content'],
971
+ } satisfies OpenAIResponsesProviderOptions,
972
+ },
973
+ });
974
+
975
+ for (const part of result.content) {
976
+ if (part.type === 'reasoning') {
977
+ const providerMetadata = part.providerMetadata as
978
+ | OpenaiResponsesReasoningProviderMetadata
979
+ | undefined;
980
+
981
+ const { itemId, reasoningEncryptedContent } =
982
+ providerMetadata?.openai ?? {};
983
+ console.log(itemId, reasoningEncryptedContent);
984
+ }
985
+ }
986
+ ```
987
+
932
988
  #### Typed providerMetadata in Source Document Parts
933
989
 
934
990
  For source document parts, when `part.type === 'source'` and `sourceType === 'document'`, the `providerMetadata` is provided as `OpenaiResponsesSourceDocumentProviderMetadata`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "3.0.17",
3
+ "version": "3.0.19",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -10,6 +10,10 @@
10
10
  "dist/**/*",
11
11
  "docs/**/*",
12
12
  "src",
13
+ "!src/**/*.test.ts",
14
+ "!src/**/*.test-d.ts",
15
+ "!src/**/__snapshots__",
16
+ "!src/**/__fixtures__",
13
17
  "CHANGELOG.md",
14
18
  "README.md",
15
19
  "internal.d.ts"
@@ -32,15 +36,15 @@
32
36
  }
33
37
  },
34
38
  "dependencies": {
35
- "@ai-sdk/provider": "3.0.4",
36
- "@ai-sdk/provider-utils": "4.0.8"
39
+ "@ai-sdk/provider": "3.0.5",
40
+ "@ai-sdk/provider-utils": "4.0.9"
37
41
  },
38
42
  "devDependencies": {
39
43
  "@types/node": "20.17.24",
40
44
  "tsup": "^8",
41
45
  "typescript": "5.8.3",
42
46
  "zod": "3.25.76",
43
- "@ai-sdk/test-server": "1.0.2",
47
+ "@ai-sdk/test-server": "1.0.3",
44
48
  "@vercel/ai-tsconfig": "0.0.0"
45
49
  },
46
50
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -3,6 +3,8 @@ export type { OpenAIProvider, OpenAIProviderSettings } from './openai-provider';
3
3
  export type { OpenAIResponsesProviderOptions } from './responses/openai-responses-options';
4
4
  export type { OpenAIChatLanguageModelOptions } from './chat/openai-chat-options';
5
5
  export type {
6
+ OpenaiResponsesProviderMetadata,
7
+ OpenaiResponsesReasoningProviderMetadata,
6
8
  OpenaiResponsesTextProviderMetadata,
7
9
  OpenaiResponsesSourceDocumentProviderMetadata,
8
10
  } from './responses/openai-responses-provider-metadata';
@@ -63,6 +63,8 @@ import {
63
63
  } from './openai-responses-options';
64
64
  import { prepareResponsesTools } from './openai-responses-prepare-tools';
65
65
  import {
66
+ ResponsesProviderMetadata,
67
+ ResponsesReasoningProviderMetadata,
66
68
  ResponsesSourceDocumentProviderMetadata,
67
69
  ResponsesTextProviderMetadata,
68
70
  } from './openai-responses-provider-metadata';
@@ -498,7 +500,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
498
500
  [providerOptionsName]: {
499
501
  itemId: part.id,
500
502
  reasoningEncryptedContent: part.encrypted_content ?? null,
501
- },
503
+ } satisfies ResponsesReasoningProviderMetadata,
502
504
  },
503
505
  });
504
506
  }
@@ -864,17 +866,15 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
864
866
  }
865
867
 
866
868
  const providerMetadata: SharedV3ProviderMetadata = {
867
- [providerOptionsName]: { responseId: response.id },
869
+ [providerOptionsName]: {
870
+ responseId: response.id,
871
+ ...(logprobs.length > 0 ? { logprobs } : {}),
872
+ ...(typeof response.service_tier === 'string'
873
+ ? { serviceTier: response.service_tier }
874
+ : {}),
875
+ } satisfies ResponsesProviderMetadata,
868
876
  };
869
877
 
870
- if (logprobs.length > 0) {
871
- providerMetadata[providerOptionsName].logprobs = logprobs;
872
- }
873
-
874
- if (typeof response.service_tier === 'string') {
875
- providerMetadata[providerOptionsName].serviceTier = response.service_tier;
876
- }
877
-
878
878
  const usage = response.usage!; // defined when there is no error
879
879
 
880
880
  return {
@@ -1188,7 +1188,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1188
1188
  itemId: value.item.id,
1189
1189
  reasoningEncryptedContent:
1190
1190
  value.item.encrypted_content ?? null,
1191
- },
1191
+ } satisfies ResponsesReasoningProviderMetadata,
1192
1192
  },
1193
1193
  });
1194
1194
  }
@@ -1496,7 +1496,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1496
1496
  itemId: value.item.id,
1497
1497
  reasoningEncryptedContent:
1498
1498
  value.item.encrypted_content ?? null,
1499
- },
1499
+ } satisfies ResponsesReasoningProviderMetadata,
1500
1500
  },
1501
1501
  });
1502
1502
  }
@@ -1641,7 +1641,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1641
1641
  type: 'reasoning-end',
1642
1642
  id: `${value.item_id}:${summaryIndex}`,
1643
1643
  providerMetadata: {
1644
- [providerOptionsName]: { itemId: value.item_id },
1644
+ [providerOptionsName]: {
1645
+ itemId: value.item_id,
1646
+ } satisfies ResponsesReasoningProviderMetadata,
1645
1647
  },
1646
1648
  });
1647
1649
  activeReasoningPart.summaryParts[summaryIndex] =
@@ -1658,7 +1660,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1658
1660
  reasoningEncryptedContent:
1659
1661
  activeReasoning[value.item_id]?.encryptedContent ??
1660
1662
  null,
1661
- },
1663
+ } satisfies ResponsesReasoningProviderMetadata,
1662
1664
  },
1663
1665
  });
1664
1666
  }
@@ -1670,7 +1672,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1670
1672
  providerMetadata: {
1671
1673
  [providerOptionsName]: {
1672
1674
  itemId: value.item_id,
1673
- },
1675
+ } satisfies ResponsesReasoningProviderMetadata,
1674
1676
  },
1675
1677
  });
1676
1678
  } else if (value.type === 'response.reasoning_summary_part.done') {
@@ -1681,7 +1683,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1681
1683
  type: 'reasoning-end',
1682
1684
  id: `${value.item_id}:${value.summary_index}`,
1683
1685
  providerMetadata: {
1684
- [providerOptionsName]: { itemId: value.item_id },
1686
+ [providerOptionsName]: {
1687
+ itemId: value.item_id,
1688
+ } satisfies ResponsesReasoningProviderMetadata,
1685
1689
  },
1686
1690
  });
1687
1691
 
@@ -1784,18 +1788,12 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
1784
1788
  flush(controller) {
1785
1789
  const providerMetadata: SharedV3ProviderMetadata = {
1786
1790
  [providerOptionsName]: {
1787
- responseId,
1788
- },
1791
+ responseId: responseId,
1792
+ ...(logprobs.length > 0 ? { logprobs } : {}),
1793
+ ...(serviceTier !== undefined ? { serviceTier } : {}),
1794
+ } satisfies ResponsesProviderMetadata,
1789
1795
  };
1790
1796
 
1791
- if (logprobs.length > 0) {
1792
- providerMetadata[providerOptionsName].logprobs = logprobs;
1793
- }
1794
-
1795
- if (serviceTier !== undefined) {
1796
- providerMetadata[providerOptionsName].serviceTier = serviceTier;
1797
- }
1798
-
1799
1797
  controller.enqueue({
1800
1798
  type: 'finish',
1801
1799
  finishReason,
@@ -1,4 +1,7 @@
1
- import { openaiResponsesChunkSchema } from './openai-responses-api';
1
+ import {
2
+ openaiResponsesChunkSchema,
3
+ OpenAIResponsesLogprobs,
4
+ } from './openai-responses-api';
2
5
  import { InferSchema } from '@ai-sdk/provider-utils';
3
6
 
4
7
  type OpenaiResponsesChunk = InferSchema<typeof openaiResponsesChunkSchema>;
@@ -8,6 +11,25 @@ type ResponsesOutputTextAnnotationProviderMetadata = Extract<
8
11
  { type: 'response.output_text.annotation.added' }
9
12
  >['annotation'];
10
13
 
14
+ export type ResponsesProviderMetadata = {
15
+ responseId: string | null | undefined;
16
+ logprobs?: Array<OpenAIResponsesLogprobs>;
17
+ serviceTier?: string;
18
+ };
19
+
20
+ export type ResponsesReasoningProviderMetadata = {
21
+ itemId: string;
22
+ reasoningEncryptedContent?: string | null;
23
+ };
24
+
25
+ export type OpenaiResponsesReasoningProviderMetadata = {
26
+ openai: ResponsesReasoningProviderMetadata;
27
+ };
28
+
29
+ export type OpenaiResponsesProviderMetadata = {
30
+ openai: ResponsesProviderMetadata;
31
+ };
32
+
11
33
  export type ResponsesTextProviderMetadata = {
12
34
  itemId: string;
13
35
  annotations?: Array<ResponsesOutputTextAnnotationProviderMetadata>;
@@ -1,8 +0,0 @@
1
- {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
2
- {"choices":[{"content_filter_results":{},"delta":{"content":"","refusal":null,"role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"D3WbtIxo1Q2j1Q","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
3
- {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Capital"},"finish_reason":null,"index":0,"logprobs":null}],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"NNpA6Dj2U","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
4
- {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" of"},"finish_reason":null,"index":0,"logprobs":null}],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"etvV32yk5dbxb","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
5
- {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Denmark"},"finish_reason":null,"index":0,"logprobs":null}],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"iDOuV7Jz","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
6
- {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"."},"finish_reason":null,"index":0,"logprobs":null}],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"ywLH2r1kcaeOOkq","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
7
- {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"Zarov0xJhP","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
8
- {"choices":[],"created":1762317021,"id":"chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt","model":"gpt-5-nano-2025-08-07","obfuscation":"DjqQ9RbEQMJ3PX","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":78,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":64,"rejected_prediction_tokens":0},"prompt_tokens":15,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":93}}
@@ -1,88 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`doStream > should set .modelId for model-router request 1`] = `
4
- [
5
- {
6
- "type": "stream-start",
7
- "warnings": [],
8
- },
9
- {
10
- "id": "chatcmpl-CYPS1lijGoK8gd9lYzY3r9Sx50nbt",
11
- "modelId": "gpt-5-nano-2025-08-07",
12
- "timestamp": 2025-11-05T04:30:21.000Z,
13
- "type": "response-metadata",
14
- },
15
- {
16
- "id": "0",
17
- "type": "text-start",
18
- },
19
- {
20
- "delta": "",
21
- "id": "0",
22
- "type": "text-delta",
23
- },
24
- {
25
- "delta": "Capital",
26
- "id": "0",
27
- "type": "text-delta",
28
- },
29
- {
30
- "delta": " of",
31
- "id": "0",
32
- "type": "text-delta",
33
- },
34
- {
35
- "delta": " Denmark",
36
- "id": "0",
37
- "type": "text-delta",
38
- },
39
- {
40
- "delta": ".",
41
- "id": "0",
42
- "type": "text-delta",
43
- },
44
- {
45
- "id": "0",
46
- "type": "text-end",
47
- },
48
- {
49
- "finishReason": {
50
- "raw": "stop",
51
- "unified": "stop",
52
- },
53
- "providerMetadata": {
54
- "openai": {
55
- "acceptedPredictionTokens": 0,
56
- "rejectedPredictionTokens": 0,
57
- },
58
- },
59
- "type": "finish",
60
- "usage": {
61
- "inputTokens": {
62
- "cacheRead": 0,
63
- "cacheWrite": undefined,
64
- "noCache": 15,
65
- "total": 15,
66
- },
67
- "outputTokens": {
68
- "reasoning": 64,
69
- "text": 14,
70
- "total": 78,
71
- },
72
- "raw": {
73
- "completion_tokens": 78,
74
- "completion_tokens_details": {
75
- "accepted_prediction_tokens": 0,
76
- "reasoning_tokens": 64,
77
- "rejected_prediction_tokens": 0,
78
- },
79
- "prompt_tokens": 15,
80
- "prompt_tokens_details": {
81
- "cached_tokens": 0,
82
- },
83
- "total_tokens": 93,
84
- },
85
- },
86
- },
87
- ]
88
- `;