ai 7.0.111 → 7.0.113

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 (50) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/index.d.ts +27 -0
  3. package/dist/index.js +345 -222
  4. package/dist/index.js.map +1 -1
  5. package/dist/internal/index.d.ts +2 -1
  6. package/dist/internal/index.js +125 -31
  7. package/dist/internal/index.js.map +1 -1
  8. package/docs/03-agents/06-tool-approvals.mdx +16 -0
  9. package/docs/03-ai-sdk-core/37-speech.mdx +2 -0
  10. package/docs/03-ai-sdk-core/40-middleware.mdx +92 -7
  11. package/docs/06-advanced/02-stopping-streams.mdx +8 -0
  12. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +3 -3
  13. package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +1 -1
  14. package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +18 -0
  15. package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +9 -3
  16. package/package.json +12 -12
  17. package/src/embed/embed-many.ts +18 -2
  18. package/src/generate-speech/generate-speech.ts +15 -4
  19. package/src/generate-speech/generated-audio-file.ts +0 -8
  20. package/src/generate-text/execute-tools-from-stream.ts +0 -2
  21. package/src/generate-text/generate-text.ts +1 -0
  22. package/src/generate-text/generated-file.ts +0 -8
  23. package/src/generate-text/invoke-tool-callbacks-from-stream.ts +9 -8
  24. package/src/generate-text/output.ts +0 -2
  25. package/src/generate-text/parse-tool-call.ts +38 -25
  26. package/src/generate-text/prune-messages.ts +3 -1
  27. package/src/generate-text/stream-text.ts +1 -0
  28. package/src/generate-text/to-response-messages.ts +7 -0
  29. package/src/generate-text/tool-call.ts +26 -0
  30. package/src/generate-text/validate-tool-approvals.ts +39 -3
  31. package/src/generate-video/generate-video.ts +0 -2
  32. package/src/middleware/extract-reasoning-middleware.ts +1 -1
  33. package/src/middleware/wrap-embedding-model.ts +9 -1
  34. package/src/model/get-embedding-model-provider-options-transformer.ts +17 -0
  35. package/src/prompt/content-part.ts +3 -0
  36. package/src/prompt/convert-to-language-model-prompt.ts +12 -2
  37. package/src/prompt/file-part-data.ts +11 -1
  38. package/src/registry/custom-provider.ts +12 -5
  39. package/src/ui/chat.ts +108 -17
  40. package/src/ui/convert-to-model-messages.ts +8 -0
  41. package/src/ui/direct-chat-transport.ts +2 -0
  42. package/src/ui/process-ui-message-stream.ts +6 -0
  43. package/src/ui/ui-messages.ts +10 -0
  44. package/src/ui/validate-ui-messages.ts +100 -134
  45. package/src/ui-message-stream/handle-ui-message-stream-finish.ts +5 -3
  46. package/src/ui-message-stream/to-ui-message-chunk.ts +7 -0
  47. package/src/ui-message-stream/ui-message-chunks.ts +2 -0
  48. package/src/ui-message-stream/ui-message-stream-on-end-callback.ts +8 -0
  49. package/src/ui-message-stream/ui-message-stream-outcome.ts +4 -0
  50. package/src/util/write-to-server-response.ts +0 -2
@@ -2911,7 +2911,7 @@ declare function verifyToolApprovalSignature({ secret, signature, approvalId, to
2911
2911
  * message history before they are executed. Checks HMAC signature (when
2912
2912
  * configured), input schema, and approval policy.
2913
2913
  */
2914
- declare function validateApprovedToolApprovals<TOOLS extends ToolSet, RUNTIME_CONTEXT extends Context | unknown | never>({ approvedToolApprovals, tools, toolApproval, messages, toolsContext, runtimeContext, toolApprovalSecret, }: {
2914
+ declare function validateApprovedToolApprovals<TOOLS extends ToolSet, RUNTIME_CONTEXT extends Context | unknown | never>({ approvedToolApprovals, tools, toolApproval, messages, toolsContext, runtimeContext, toolApprovalSecret, refineToolInput, }: {
2915
2915
  approvedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
2916
2916
  tools: TOOLS | undefined;
2917
2917
  toolApproval: ToolApprovalConfiguration<TOOLS, RUNTIME_CONTEXT> | undefined;
@@ -2919,6 +2919,7 @@ declare function validateApprovedToolApprovals<TOOLS extends ToolSet, RUNTIME_CO
2919
2919
  toolsContext: InferToolSetContext<TOOLS>;
2920
2920
  runtimeContext: RUNTIME_CONTEXT;
2921
2921
  toolApprovalSecret?: string | Uint8Array;
2922
+ refineToolInput?: ToolInputRefinement<TOOLS>;
2922
2923
  }): Promise<{
2923
2924
  approvedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
2924
2925
  deniedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
@@ -91,7 +91,7 @@ import {
91
91
  } from "@ai-sdk/provider-utils";
92
92
 
93
93
  // src/version.ts
94
- var VERSION = true ? "7.0.111" : "0.0.0-test";
94
+ var VERSION = true ? "7.0.113" : "0.0.0-test";
95
95
 
96
96
  // src/util/download/download.ts
97
97
  var download = async ({
@@ -241,6 +241,13 @@ function convertUrlToFilePartData(url) {
241
241
  }
242
242
  return { data: { type: "url", url }, mediaType: void 0 };
243
243
  }
244
+ function convertUrlStringToFilePartData(content) {
245
+ const result = convertUrlToFilePartData(new URL(content));
246
+ if (result.data.type === "url" && result.data.url.toString() !== content) {
247
+ result.data.originalUrl = content;
248
+ }
249
+ return result;
250
+ }
244
251
  function convertInlineDataToFilePartData(content) {
245
252
  if (content instanceof Uint8Array) {
246
253
  return { data: { type: "data", data: content }, mediaType: void 0 };
@@ -292,7 +299,7 @@ function convertToLanguageModelV4FilePart(content) {
292
299
  }
293
300
  if (typeof content === "string") {
294
301
  try {
295
- return convertUrlToFilePartData(new URL(content));
302
+ return convertUrlStringToFilePartData(content);
296
303
  } catch (e) {
297
304
  return convertInlineDataToFilePartData(content);
298
305
  }
@@ -893,6 +900,7 @@ function mapToolResultOutput({
893
900
  }
894
901
  case "file-url": {
895
902
  const mediaType = (_a12 = item.mediaType) != null ? _a12 : getMediaTypeFromUrl(item.url);
903
+ const url = new URL(item.url);
896
904
  let message = `The "file-url" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'url', url } instead.`;
897
905
  if (!item.mediaType) {
898
906
  const inferenceSuffix = mediaType === "application/octet-stream" ? `Unable to infer media type from URL. Defaulting to 'application/octet-stream'.` : `Inferred media type '${mediaType}' from URL.`;
@@ -905,7 +913,11 @@ function mapToolResultOutput({
905
913
  });
906
914
  return {
907
915
  type: "file",
908
- data: { type: "url", url: new URL(item.url) },
916
+ data: {
917
+ type: "url",
918
+ url,
919
+ ...url.toString() !== item.url ? { originalUrl: item.url } : {}
920
+ },
909
921
  mediaType,
910
922
  providerOptions: item.providerOptions
911
923
  };
@@ -961,6 +973,7 @@ function mapToolResultOutput({
961
973
  };
962
974
  }
963
975
  case "image-url": {
976
+ const url = new URL(item.url);
964
977
  warnings.push({
965
978
  type: "deprecated",
966
979
  setting: '"tool-result" content of type "image-url"',
@@ -968,7 +981,11 @@ function mapToolResultOutput({
968
981
  });
969
982
  return {
970
983
  type: "file",
971
- data: { type: "url", url: new URL(item.url) },
984
+ data: {
985
+ type: "url",
986
+ url,
987
+ ...url.toString() !== item.url ? { originalUrl: item.url } : {}
988
+ },
972
989
  mediaType: "image",
973
990
  providerOptions: item.providerOptions
974
991
  };
@@ -1445,7 +1462,10 @@ var toolApprovalRequestSchema = z.object(
1445
1462
  type: z.literal("tool-approval-request"),
1446
1463
  approvalId: z.string(),
1447
1464
  toolCallId: z.string(),
1448
- reason: z.string().optional()
1465
+ reason: z.string().optional(),
1466
+ isAutomatic: z.boolean().optional(),
1467
+ signature: z.string().optional(),
1468
+ inputSchemaInput: z.unknown().optional()
1449
1469
  }
1450
1470
  );
1451
1471
  var toolApprovalResponseSchema = z.object({
@@ -3096,6 +3116,20 @@ function getOwn(obj, key) {
3096
3116
  return obj != null && Object.hasOwn(obj, key) ? obj[key] : void 0;
3097
3117
  }
3098
3118
 
3119
+ // src/generate-text/tool-call.ts
3120
+ var inputSchemaInputSymbol = /* @__PURE__ */ Symbol("ai-sdk-tool-call-input-schema-input");
3121
+ function setToolCallInputSchemaInput(toolCall, inputSchemaInput) {
3122
+ Object.defineProperty(toolCall, inputSchemaInputSymbol, {
3123
+ value: inputSchemaInput
3124
+ });
3125
+ return toolCall;
3126
+ }
3127
+ function getToolCallInputSchemaInput(toolCall) {
3128
+ return inputSchemaInputSymbol in toolCall ? {
3129
+ value: toolCall[inputSchemaInputSymbol]
3130
+ } : void 0;
3131
+ }
3132
+
3099
3133
  // src/generate-text/parse-tool-call.ts
3100
3134
  async function parseToolCall({
3101
3135
  toolCall,
@@ -3218,10 +3252,12 @@ async function refineParsedToolCallInput({
3218
3252
  if (refine == null) {
3219
3253
  return toolCall;
3220
3254
  }
3221
- return {
3255
+ const refinedToolCall = {
3222
3256
  ...toolCall,
3223
3257
  input: await refine(toolCall.input)
3224
3258
  };
3259
+ const inputSchemaInput = getToolCallInputSchemaInput(toolCall);
3260
+ return inputSchemaInput == null ? refinedToolCall : setToolCallInputSchemaInput(refinedToolCall, inputSchemaInput.value);
3225
3261
  }
3226
3262
  async function parseProviderExecutedDynamicToolCall(toolCall) {
3227
3263
  const parseResult = toolCall.input.trim() === "" ? { success: true, value: {} } : await safeParseJSON({ text: toolCall.input });
@@ -3266,26 +3302,29 @@ async function doParseToolCall({
3266
3302
  cause: parseResult.error
3267
3303
  });
3268
3304
  }
3269
- return tool2.type === "dynamic" ? {
3270
- type: "tool-call",
3271
- toolCallId: toolCall.toolCallId,
3272
- toolName: toolCall.toolName,
3273
- input: parseResult.value,
3274
- providerExecuted: toolCall.providerExecuted,
3275
- providerMetadata: toolCall.providerMetadata,
3276
- ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
3277
- dynamic: true,
3278
- title: tool2.title
3279
- } : {
3280
- type: "tool-call",
3281
- toolCallId: toolCall.toolCallId,
3282
- toolName,
3283
- input: parseResult.value,
3284
- providerExecuted: toolCall.providerExecuted,
3285
- providerMetadata: toolCall.providerMetadata,
3286
- ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
3287
- title: tool2.title
3288
- };
3305
+ return setToolCallInputSchemaInput(
3306
+ tool2.type === "dynamic" ? {
3307
+ type: "tool-call",
3308
+ toolCallId: toolCall.toolCallId,
3309
+ toolName: toolCall.toolName,
3310
+ input: parseResult.value,
3311
+ providerExecuted: toolCall.providerExecuted,
3312
+ providerMetadata: toolCall.providerMetadata,
3313
+ ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
3314
+ dynamic: true,
3315
+ title: tool2.title
3316
+ } : {
3317
+ type: "tool-call",
3318
+ toolCallId: toolCall.toolCallId,
3319
+ toolName,
3320
+ input: parseResult.value,
3321
+ providerExecuted: toolCall.providerExecuted,
3322
+ providerMetadata: toolCall.providerMetadata,
3323
+ ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
3324
+ title: tool2.title
3325
+ },
3326
+ parseResult.rawValue
3327
+ );
3289
3328
  }
3290
3329
 
3291
3330
  // src/generate-text/validate-tool-context.ts
@@ -3607,6 +3646,33 @@ import {
3607
3646
  safeValidateTypes as safeValidateTypes3
3608
3647
  } from "@ai-sdk/provider-utils";
3609
3648
 
3649
+ // src/util/is-deep-equal-data.ts
3650
+ function isDeepEqualData(obj1, obj2) {
3651
+ if (obj1 === obj2) return true;
3652
+ if (obj1 == null || obj2 == null) return false;
3653
+ if (typeof obj1 !== "object" && typeof obj2 !== "object")
3654
+ return obj1 === obj2;
3655
+ if (obj1.constructor !== obj2.constructor) return false;
3656
+ if (obj1 instanceof Date && obj2 instanceof Date) {
3657
+ return obj1.getTime() === obj2.getTime();
3658
+ }
3659
+ if (Array.isArray(obj1)) {
3660
+ if (obj1.length !== obj2.length) return false;
3661
+ for (let i = 0; i < obj1.length; i++) {
3662
+ if (!isDeepEqualData(obj1[i], obj2[i])) return false;
3663
+ }
3664
+ return true;
3665
+ }
3666
+ const keys1 = Object.keys(obj1);
3667
+ const keys2 = Object.keys(obj2);
3668
+ if (keys1.length !== keys2.length) return false;
3669
+ for (const key of keys1) {
3670
+ if (!keys2.includes(key)) return false;
3671
+ if (!isDeepEqualData(obj1[key], obj2[key])) return false;
3672
+ }
3673
+ return true;
3674
+ }
3675
+
3610
3676
  // src/generate-text/resolve-tool-approval.ts
3611
3677
  async function resolveToolApproval({
3612
3678
  tools,
@@ -3670,14 +3736,15 @@ async function validateApprovedToolApprovals({
3670
3736
  messages,
3671
3737
  toolsContext,
3672
3738
  runtimeContext,
3673
- toolApprovalSecret
3739
+ toolApprovalSecret,
3740
+ refineToolInput
3674
3741
  }) {
3675
3742
  var _a12;
3676
3743
  const approved = [];
3677
3744
  const denied = [];
3678
3745
  const invalid = [];
3679
3746
  for (const approval of approvedToolApprovals) {
3680
- const { toolCall, approvalRequest } = approval;
3747
+ const { approvalRequest, toolCall } = approval;
3681
3748
  const tool2 = getOwn(tools, toolCall.toolName);
3682
3749
  if (toolApprovalSecret != null) {
3683
3750
  if (approvalRequest.signature == null) {
@@ -3704,17 +3771,42 @@ async function validateApprovedToolApprovals({
3704
3771
  }
3705
3772
  }
3706
3773
  if (isExecutableTool(tool2) && tool2.inputSchema != null) {
3774
+ const hasInputSchemaInput = Object.prototype.hasOwnProperty.call(
3775
+ approvalRequest,
3776
+ "inputSchemaInput"
3777
+ );
3707
3778
  const validation = await safeValidateTypes3({
3708
- value: toolCall.input,
3779
+ value: hasInputSchemaInput ? approvalRequest.inputSchemaInput : toolCall.input,
3709
3780
  schema: asSchema3(tool2.inputSchema)
3710
3781
  });
3782
+ let validationError;
3711
3783
  if (!validation.success) {
3784
+ validationError = validation.error;
3785
+ } else {
3786
+ try {
3787
+ const revalidatedToolCall = await refineParsedToolCallInput({
3788
+ toolCall: {
3789
+ ...toolCall,
3790
+ input: validation.value
3791
+ },
3792
+ refineToolInput
3793
+ });
3794
+ if (!isDeepEqualData(revalidatedToolCall.input, toolCall.input)) {
3795
+ validationError = new Error(
3796
+ "Approved tool input does not match the validated schema output."
3797
+ );
3798
+ }
3799
+ } catch (error) {
3800
+ validationError = error;
3801
+ }
3802
+ }
3803
+ if (validationError != null) {
3712
3804
  invalid.push({
3713
3805
  ...approval,
3714
3806
  error: new InvalidToolInputError({
3715
3807
  toolName: toolCall.toolName,
3716
3808
  toolInput: JSON.stringify(toolCall.input),
3717
- cause: validation.error
3809
+ cause: validationError
3718
3810
  })
3719
3811
  });
3720
3812
  continue;
@@ -3852,13 +3944,15 @@ async function toResponseMessages({
3852
3944
  break;
3853
3945
  }
3854
3946
  case "tool-approval-request":
3947
+ const inputSchemaInput = getToolCallInputSchemaInput(part.toolCall);
3855
3948
  content.push({
3856
3949
  type: "tool-approval-request",
3857
3950
  approvalId: part.approvalId,
3858
3951
  toolCallId: part.toolCall.toolCallId,
3859
3952
  ...part.reason != null ? { reason: part.reason } : {},
3860
3953
  isAutomatic: part.isAutomatic,
3861
- ...part.signature != null ? { signature: part.signature } : {}
3954
+ ...part.signature != null ? { signature: part.signature } : {},
3955
+ ...inputSchemaInput != null && !isDeepEqualData(inputSchemaInput.value, part.toolCall.input) ? { inputSchemaInput: inputSchemaInput.value } : {}
3862
3956
  });
3863
3957
  break;
3864
3958
  }