ai 7.0.84 → 7.0.85

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.
@@ -1,5 +1,4 @@
1
1
  import type {
2
- LanguageModelV4Content,
3
2
  LanguageModelV4GenerateResult,
4
3
  LanguageModelV4ToolCall,
5
4
  } from '@ai-sdk/provider';
@@ -17,7 +16,6 @@ import {
17
16
  type ToolSet,
18
17
  } from '@ai-sdk/provider-utils';
19
18
  import { NoOutputGeneratedError } from '../error';
20
- import { ToolCallNotFoundForApprovalError } from '../error/tool-call-not-found-for-approval-error';
21
19
  import { logWarnings } from '../logger/log-warnings';
22
20
  import { resolveLanguageModel } from '../model/resolve-model';
23
21
  import type { ModelMessage } from '../prompt';
@@ -64,7 +62,7 @@ import { VERSION } from '../version';
64
62
  import type { ActiveTools } from './active-tools';
65
63
  import { calculateTokensPerSecond } from './calculate-tokens-per-second';
66
64
  import { collectToolApprovals } from './collect-tool-approvals';
67
- import type { ContentPart } from './content-part';
65
+ import { convertLanguageModelContent } from './convert-language-model-content';
68
66
  import { executeToolCall } from './execute-tool-call';
69
67
  import {
70
68
  filterActiveTools,
@@ -78,7 +76,6 @@ import type {
78
76
  GenerateTextOnStepStartCallback,
79
77
  } from './generate-text-events';
80
78
  import type { GenerateTextResult } from './generate-text-result';
81
- import { DefaultGeneratedFile } from './generated-file';
82
79
  import { isToolExecutionAllowedFinishReason } from './is-tool-execution-allowed-finish-reason';
83
80
  import type {
84
81
  OnLanguageModelCallEndCallback,
@@ -115,7 +112,6 @@ import {
115
112
  } from './tool-caller-configuration';
116
113
  import type { TypedToolCall } from './tool-call';
117
114
  import type { ToolCallRepairFunction } from './tool-call-repair-function';
118
- import type { TypedToolError } from './tool-error';
119
115
  import type {
120
116
  OnToolExecutionEndCallback,
121
117
  OnToolExecutionStartCallback,
@@ -123,7 +119,6 @@ import type {
123
119
  import type { ToolInputRefinement } from './tool-input-refinement';
124
120
  import type { ToolOrder } from './tool-order';
125
121
  import type { ToolOutput } from './tool-output';
126
- import type { TypedToolResult } from './tool-result';
127
122
  import type { ToolsContextParameter } from './tools-context-parameter';
128
123
  import { maybeSignApproval } from './tool-approval-signature';
129
124
  import { validateApprovedToolApprovals } from './validate-tool-approvals';
@@ -1088,7 +1083,7 @@ export async function generateText<
1088
1083
  > = {};
1089
1084
  const blockedToolCallIds = new Set<string>();
1090
1085
 
1091
- const modelCallContent = asContent({
1086
+ const modelCallContent = convertLanguageModelContent({
1092
1087
  content: currentModelResponse.content,
1093
1088
  toolCalls: stepToolCalls,
1094
1089
  toolOutputs: [],
@@ -1381,7 +1376,7 @@ export async function generateText<
1381
1376
  }
1382
1377
 
1383
1378
  // content:
1384
- const stepContent = asContent({
1379
+ const stepContent = convertLanguageModelContent({
1385
1380
  content: currentModelResponse.content,
1386
1381
  toolCalls: stepToolCalls,
1387
1382
  toolOutputs: clientToolOutputs,
@@ -1755,191 +1750,3 @@ class DefaultGenerateTextResult<
1755
1750
  return this._output;
1756
1751
  }
1757
1752
  }
1758
-
1759
- function asContent<TOOLS extends ToolSet>({
1760
- content,
1761
- toolCalls,
1762
- toolOutputs,
1763
- toolApprovalRequests,
1764
- toolApprovalResponses,
1765
- tools,
1766
- }: {
1767
- content: Array<LanguageModelV4Content>;
1768
- toolCalls: Array<TypedToolCall<TOOLS>>;
1769
- toolOutputs: Array<ToolOutput<TOOLS>>;
1770
- toolApprovalRequests: Array<ToolApprovalRequestOutput<TOOLS>>;
1771
- toolApprovalResponses: Array<ToolApprovalResponseOutput<TOOLS>>;
1772
- tools: TOOLS | undefined;
1773
- }): Array<ContentPart<TOOLS>> {
1774
- const contentParts: Array<ContentPart<TOOLS>> = [];
1775
- const toolOutputsWithApprovalResponses: Array<ToolOutput<TOOLS>> = [];
1776
- const toolOutputsWithoutApprovalResponses: Array<ToolOutput<TOOLS>> = [];
1777
- const toolCallIdsWithApprovalResponses = new Set(
1778
- toolApprovalResponses.map(
1779
- toolApprovalResponse => toolApprovalResponse.toolCall.toolCallId,
1780
- ),
1781
- );
1782
-
1783
- for (const part of content) {
1784
- switch (part.type) {
1785
- case 'text':
1786
- case 'reasoning':
1787
- case 'custom':
1788
- case 'source':
1789
- contentParts.push(part);
1790
- break;
1791
-
1792
- case 'file':
1793
- case 'reasoning-file': {
1794
- contentParts.push({
1795
- type: part.type as 'file' | 'reasoning-file',
1796
- file: new DefaultGeneratedFile({
1797
- data:
1798
- part.data.type === 'data'
1799
- ? part.data.data
1800
- : part.data.url.toString(),
1801
- mediaType: part.mediaType,
1802
- }),
1803
- ...(part.providerMetadata != null
1804
- ? { providerMetadata: part.providerMetadata }
1805
- : {}),
1806
- });
1807
- break;
1808
- }
1809
-
1810
- case 'tool-call': {
1811
- contentParts.push(
1812
- toolCalls.find(toolCall => toolCall.toolCallId === part.toolCallId)!,
1813
- );
1814
- break;
1815
- }
1816
-
1817
- case 'tool-result': {
1818
- const toolCall = toolCalls.find(
1819
- toolCall => toolCall.toolCallId === part.toolCallId,
1820
- );
1821
-
1822
- // Handle deferred results for provider-executed tools (e.g., programmatic tool calling).
1823
- // When a server tool (like code_execution) triggers a client tool, the server tool's
1824
- // result may be deferred to a later turn. In this case, there's no matching tool-call
1825
- // in the current response.
1826
- if (toolCall == null) {
1827
- const tool = getOwn(tools, part.toolName);
1828
- const supportsDeferredResults =
1829
- tool?.type === 'provider' && tool.supportsDeferredResults;
1830
-
1831
- if (!supportsDeferredResults) {
1832
- throw new Error(`Tool call ${part.toolCallId} not found.`);
1833
- }
1834
-
1835
- // Create tool result without tool call input (deferred result)
1836
- if (part.isError) {
1837
- contentParts.push({
1838
- type: 'tool-error' as const,
1839
- toolCallId: part.toolCallId,
1840
- toolName: part.toolName as keyof TOOLS & string,
1841
- input: undefined,
1842
- error: part.result,
1843
- providerExecuted: true,
1844
- dynamic: part.dynamic,
1845
- ...(part.providerMetadata != null
1846
- ? { providerMetadata: part.providerMetadata }
1847
- : {}),
1848
- ...(tool?.metadata != null
1849
- ? { toolMetadata: tool.metadata }
1850
- : {}),
1851
- } as TypedToolError<TOOLS>);
1852
- } else {
1853
- contentParts.push({
1854
- type: 'tool-result' as const,
1855
- toolCallId: part.toolCallId,
1856
- toolName: part.toolName as keyof TOOLS & string,
1857
- input: undefined,
1858
- output: part.result,
1859
- providerExecuted: true,
1860
- dynamic: part.dynamic,
1861
- ...(part.providerMetadata != null
1862
- ? { providerMetadata: part.providerMetadata }
1863
- : {}),
1864
- ...(tool?.metadata != null
1865
- ? { toolMetadata: tool.metadata }
1866
- : {}),
1867
- } as TypedToolResult<TOOLS>);
1868
- }
1869
- break;
1870
- }
1871
-
1872
- if (part.isError) {
1873
- contentParts.push({
1874
- type: 'tool-error' as const,
1875
- toolCallId: part.toolCallId,
1876
- toolName: part.toolName as keyof TOOLS & string,
1877
- input: toolCall.input,
1878
- error: part.result,
1879
- providerExecuted: true,
1880
- dynamic: toolCall.dynamic,
1881
- ...(part.providerMetadata != null
1882
- ? { providerMetadata: part.providerMetadata }
1883
- : {}),
1884
- ...(toolCall.toolMetadata != null
1885
- ? { toolMetadata: toolCall.toolMetadata }
1886
- : {}),
1887
- } as TypedToolError<TOOLS>);
1888
- } else {
1889
- contentParts.push({
1890
- type: 'tool-result' as const,
1891
- toolCallId: part.toolCallId,
1892
- toolName: part.toolName as keyof TOOLS & string,
1893
- input: toolCall.input,
1894
- output: part.result,
1895
- providerExecuted: true,
1896
- dynamic: toolCall.dynamic,
1897
- ...(part.providerMetadata != null
1898
- ? { providerMetadata: part.providerMetadata }
1899
- : {}),
1900
- ...(toolCall.toolMetadata != null
1901
- ? { toolMetadata: toolCall.toolMetadata }
1902
- : {}),
1903
- } as TypedToolResult<TOOLS>);
1904
- }
1905
- break;
1906
- }
1907
-
1908
- case 'tool-approval-request': {
1909
- const toolCall = toolCalls.find(
1910
- toolCall => toolCall.toolCallId === part.toolCallId,
1911
- );
1912
-
1913
- if (toolCall == null) {
1914
- throw new ToolCallNotFoundForApprovalError({
1915
- toolCallId: part.toolCallId,
1916
- approvalId: part.approvalId,
1917
- });
1918
- }
1919
-
1920
- contentParts.push({
1921
- type: 'tool-approval-request' as const,
1922
- approvalId: part.approvalId,
1923
- toolCall,
1924
- });
1925
- break;
1926
- }
1927
- }
1928
- }
1929
-
1930
- for (const toolOutput of toolOutputs) {
1931
- if (toolCallIdsWithApprovalResponses.has(toolOutput.toolCallId)) {
1932
- toolOutputsWithApprovalResponses.push(toolOutput);
1933
- } else {
1934
- toolOutputsWithoutApprovalResponses.push(toolOutput);
1935
- }
1936
- }
1937
-
1938
- return [
1939
- ...contentParts,
1940
- ...toolOutputsWithoutApprovalResponses,
1941
- ...toolApprovalRequests,
1942
- ...toolApprovalResponses,
1943
- ...toolOutputsWithApprovalResponses,
1944
- ];
1945
- }
@@ -2,6 +2,7 @@ import {
2
2
  convertBase64ToUint8Array,
3
3
  convertUint8ArrayToBase64,
4
4
  } from '@ai-sdk/provider-utils';
5
+ import type { JSONObject } from '@ai-sdk/provider';
5
6
 
6
7
  /**
7
8
  * A generated file.
@@ -23,6 +24,11 @@ export interface GeneratedFile {
23
24
  * @see https://www.iana.org/assignments/media-types/media-types.xhtml
24
25
  */
25
26
  readonly mediaType: string;
27
+
28
+ /**
29
+ * Provider-specific metadata for this file.
30
+ */
31
+ readonly providerMetadata?: Record<string, JSONObject>;
26
32
  }
27
33
 
28
34
  /**
@@ -35,18 +41,22 @@ export class DefaultGeneratedFile implements GeneratedFile {
35
41
  private uint8ArrayData: Uint8Array | undefined;
36
42
 
37
43
  readonly mediaType: string;
44
+ readonly providerMetadata?: Record<string, JSONObject>;
38
45
 
39
46
  constructor({
40
47
  data,
41
48
  mediaType,
49
+ providerMetadata,
42
50
  }: {
43
51
  data: string | Uint8Array;
44
52
  mediaType: string;
53
+ providerMetadata?: Record<string, JSONObject>;
45
54
  }) {
46
55
  const isUint8Array = data instanceof Uint8Array;
47
56
  this.base64Data = isUint8Array ? undefined : data;
48
57
  this.uint8ArrayData = isUint8Array ? data : undefined;
49
58
  this.mediaType = mediaType;
59
+ this.providerMetadata = providerMetadata;
50
60
  }
51
61
 
52
62
  // lazy conversion with caching to avoid unnecessary conversion overhead:
@@ -69,7 +79,11 @@ export class DefaultGeneratedFile implements GeneratedFile {
69
79
  export class DefaultGeneratedFileWithType extends DefaultGeneratedFile {
70
80
  readonly type = 'file';
71
81
 
72
- constructor(options: { data: string | Uint8Array; mediaType: string }) {
82
+ constructor(options: {
83
+ data: string | Uint8Array;
84
+ mediaType: string;
85
+ providerMetadata?: Record<string, JSONObject>;
86
+ }) {
73
87
  super(options);
74
88
  }
75
89
  }
@@ -15,7 +15,9 @@ export function canonicalJSON(value: unknown): string {
15
15
  return JSON.stringify(value);
16
16
  }
17
17
  if (Array.isArray(value)) {
18
- return `[${value.map(canonicalJSON).join(',')}]`;
18
+ return `[${value
19
+ .map(element => (element === undefined ? 'null' : canonicalJSON(element)))
20
+ .join(',')}]`;
19
21
  }
20
22
  const keys = Object.keys(value as Record<string, unknown>).sort();
21
23
  const entries = keys.map(