ai 7.0.77 → 7.0.78

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.
@@ -165,7 +165,6 @@ Here are the capabilities of popular models:
165
165
  | [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-chat` | <Cross /> | <Check /> | <Check /> | <Check /> |
166
166
  | [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-reasoner` | <Cross /> | <Check /> | <Check /> | <Check /> |
167
167
  | [Cerebras](/providers/ai-sdk-providers/cerebras) | `gpt-oss-120b` | <Cross /> | <Check /> | <Check /> | <Check /> |
168
- | [Cerebras](/providers/ai-sdk-providers/cerebras) | `zai-glm-4.7` | <Cross /> | <Check /> | <Check /> | <Check /> |
169
168
  | [Cerebras](/providers/ai-sdk-providers/cerebras) | `gemma-4-31b` | <Check /> | <Check /> | <Check /> | <Check /> |
170
169
  | [Groq](/providers/ai-sdk-providers/groq) | `meta-llama/llama-4-scout-17b-16e-instruct` | <Check /> | <Check /> | <Check /> | <Check /> |
171
170
  | [Groq](/providers/ai-sdk-providers/groq) | `llama-3.3-70b-versatile` | <Cross /> | <Check /> | <Check /> | <Check /> |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.77",
3
+ "version": "7.0.78",
4
4
  "type": "module",
5
5
  "description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
6
6
  "license": "Apache-2.0",
@@ -42,7 +42,7 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@ai-sdk/gateway": "4.0.62",
45
+ "@ai-sdk/gateway": "4.0.63",
46
46
  "@ai-sdk/provider": "4.0.7",
47
47
  "@ai-sdk/provider-utils": "5.0.29"
48
48
  },
@@ -713,6 +713,7 @@ export async function generateText<
713
713
  const {
714
714
  approvedToolApprovals: localApprovedToolApprovals,
715
715
  deniedToolApprovals: revalidationDeniedToolApprovals,
716
+ invalidToolApprovals,
716
717
  } = await validateApprovedToolApprovals<TOOLS, RUNTIME_CONTEXT>({
717
718
  approvedToolApprovals: approvedToolApprovals.filter(
718
719
  toolApproval => !toolApproval.toolCall.providerExecuted,
@@ -735,7 +736,8 @@ export async function generateText<
735
736
 
736
737
  if (
737
738
  deniedToolApprovalsWithoutResults.length > 0 ||
738
- localApprovedToolApprovals.length > 0
739
+ localApprovedToolApprovals.length > 0 ||
740
+ invalidToolApprovals.length > 0
739
741
  ) {
740
742
  const toolResults = await executeTools({
741
743
  toolCalls: localApprovedToolApprovals.map(
@@ -790,6 +792,24 @@ export async function generateText<
790
792
  });
791
793
  }
792
794
 
795
+ // Report invalid approved tool calls to the model without executing
796
+ // them. Repairing the input after approval would change the operation
797
+ // that the user authorized.
798
+ for (const toolApproval of invalidToolApprovals) {
799
+ toolContent.push({
800
+ type: 'tool-result' as const,
801
+ toolCallId: toolApproval.toolCall.toolCallId,
802
+ toolName: toolApproval.toolCall.toolName,
803
+ output: await createToolModelOutput({
804
+ toolCallId: toolApproval.toolCall.toolCallId,
805
+ input: toolApproval.toolCall.input,
806
+ tool: getOwn(tools, toolApproval.toolCall.toolName),
807
+ output: toolApproval.error,
808
+ errorMode: 'text',
809
+ }),
810
+ });
811
+ }
812
+
793
813
  // add execution denied tool results for all denied tool approvals:
794
814
  for (const toolApproval of deniedToolApprovalsWithoutResults) {
795
815
  toolContent.push({
@@ -1714,6 +1714,7 @@ class DefaultStreamTextResult<
1714
1714
  const {
1715
1715
  approvedToolApprovals: localApprovedToolApprovals,
1716
1716
  deniedToolApprovals: revalidationDeniedToolApprovals,
1717
+ invalidToolApprovals,
1717
1718
  } = await validateApprovedToolApprovals<TOOLS, RUNTIME_CONTEXT>({
1718
1719
  approvedToolApprovals: approvedToolApprovals.filter(
1719
1720
  toolApproval => !toolApproval.toolCall.providerExecuted,
@@ -1766,6 +1767,23 @@ class DefaultStreamTextResult<
1766
1767
  } as StaticToolOutputDenied<TOOLS>);
1767
1768
  }
1768
1769
 
1770
+ for (const toolApproval of invalidToolApprovals) {
1771
+ toolExecutionStepStreamController?.enqueue({
1772
+ type: 'tool-error',
1773
+ toolCallId: toolApproval.toolCall.toolCallId,
1774
+ toolName: toolApproval.toolCall.toolName,
1775
+ input: toolApproval.toolCall.input,
1776
+ error: getErrorMessage(toolApproval.error),
1777
+ title: toolApproval.toolCall.title,
1778
+ ...(toolApproval.toolCall.dynamic === true
1779
+ ? { dynamic: true as const }
1780
+ : {}),
1781
+ ...(toolApproval.toolCall.toolMetadata != null
1782
+ ? { toolMetadata: toolApproval.toolCall.toolMetadata }
1783
+ : {}),
1784
+ } as TextStreamPart<TOOLS>);
1785
+ }
1786
+
1769
1787
  const toolOutputs: Array<ToolOutput<TOOLS>> = [];
1770
1788
 
1771
1789
  await Promise.all(
@@ -1804,7 +1822,8 @@ class DefaultStreamTextResult<
1804
1822
  // Local tool results (approved + denied) are sent as tool results:
1805
1823
  if (
1806
1824
  toolOutputs.length > 0 ||
1807
- localDeniedToolApprovalsWithoutResults.length > 0
1825
+ localDeniedToolApprovalsWithoutResults.length > 0 ||
1826
+ invalidToolApprovals.length > 0
1808
1827
  ) {
1809
1828
  const localToolContent: ToolContent = [];
1810
1829
 
@@ -1827,6 +1846,24 @@ class DefaultStreamTextResult<
1827
1846
  });
1828
1847
  }
1829
1848
 
1849
+ // Report invalid approved tool calls to the model without
1850
+ // executing them. Repairing the input after approval would change
1851
+ // the operation that the user authorized.
1852
+ for (const toolApproval of invalidToolApprovals) {
1853
+ localToolContent.push({
1854
+ type: 'tool-result' as const,
1855
+ toolCallId: toolApproval.toolCall.toolCallId,
1856
+ toolName: toolApproval.toolCall.toolName,
1857
+ output: await createToolModelOutput({
1858
+ toolCallId: toolApproval.toolCall.toolCallId,
1859
+ input: toolApproval.toolCall.input,
1860
+ tool: getOwn(tools, toolApproval.toolCall.toolName),
1861
+ output: toolApproval.error,
1862
+ errorMode: 'text',
1863
+ }),
1864
+ });
1865
+ }
1866
+
1830
1867
  // add execution denied tool results for denied local tool approvals:
1831
1868
  for (const toolApproval of localDeniedToolApprovalsWithoutResults) {
1832
1869
  localToolContent.push({
@@ -42,9 +42,15 @@ export async function validateApprovedToolApprovals<
42
42
  }): Promise<{
43
43
  approvedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
44
44
  deniedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
45
+ invalidToolApprovals: Array<
46
+ CollectedToolApprovals<TOOLS> & { error: InvalidToolInputError }
47
+ >;
45
48
  }> {
46
49
  const approved: Array<CollectedToolApprovals<TOOLS>> = [];
47
50
  const denied: Array<CollectedToolApprovals<TOOLS>> = [];
51
+ const invalid: Array<
52
+ CollectedToolApprovals<TOOLS> & { error: InvalidToolInputError }
53
+ > = [];
48
54
 
49
55
  for (const approval of approvedToolApprovals) {
50
56
  const { toolCall, approvalRequest } = approval;
@@ -88,11 +94,15 @@ export async function validateApprovedToolApprovals<
88
94
  });
89
95
 
90
96
  if (!validation.success) {
91
- throw new InvalidToolInputError({
92
- toolName: toolCall.toolName,
93
- toolInput: JSON.stringify(toolCall.input),
94
- cause: validation.error,
97
+ invalid.push({
98
+ ...approval,
99
+ error: new InvalidToolInputError({
100
+ toolName: toolCall.toolName,
101
+ toolInput: JSON.stringify(toolCall.input),
102
+ cause: validation.error,
103
+ }),
95
104
  });
105
+ continue;
96
106
  }
97
107
  }
98
108
 
@@ -119,5 +129,9 @@ export async function validateApprovedToolApprovals<
119
129
  }
120
130
  }
121
131
 
122
- return { approvedToolApprovals: approved, deniedToolApprovals: denied };
132
+ return {
133
+ approvedToolApprovals: approved,
134
+ deniedToolApprovals: denied,
135
+ invalidToolApprovals: invalid,
136
+ };
123
137
  }