ai 7.0.106 → 7.0.108

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 (37) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +390 -95
  4. package/dist/index.js.map +1 -1
  5. package/dist/internal/index.d.ts +16 -2
  6. package/dist/internal/index.js +323 -53
  7. package/dist/internal/index.js.map +1 -1
  8. package/docs/00-introduction/index.mdx +1 -1
  9. package/docs/02-getting-started/03-nextjs-pages-router.mdx +1 -1
  10. package/docs/02-getting-started/05-nuxt.mdx +1 -1
  11. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +31 -0
  12. package/docs/03-ai-sdk-core/19-tool-search.mdx +4 -2
  13. package/docs/04-ai-sdk-ui/02-chatbot.mdx +26 -11
  14. package/docs/04-ai-sdk-ui/05-completion.mdx +1 -1
  15. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +7 -0
  16. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +7 -0
  17. package/docs/07-reference/01-ai-sdk-core/23-tool-search.mdx +3 -2
  18. package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +1 -1
  19. package/package.json +11 -11
  20. package/src/generate-speech/generate-speech.ts +44 -4
  21. package/src/generate-text/generate-text.ts +29 -16
  22. package/src/generate-text/invoke-tool-callbacks-from-stream.ts +68 -16
  23. package/src/generate-text/parse-tool-call.ts +64 -12
  24. package/src/generate-text/stream-language-model-call.ts +32 -21
  25. package/src/generate-text/stream-text.ts +1 -1
  26. package/src/generate-text/tool-call-repair-function.ts +2 -0
  27. package/src/generate-video/generate-video.ts +61 -10
  28. package/src/middleware/wrap-provider.ts +2 -0
  29. package/src/model/as-language-model-v4.ts +166 -6
  30. package/src/test/mock-server-response.ts +19 -3
  31. package/src/text-stream/pipe-text-stream-to-response.ts +3 -5
  32. package/src/ui/http-chat-transport.ts +12 -2
  33. package/src/ui/last-assistant-message-is-complete-with-approval-responses.ts +1 -1
  34. package/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +2 -1
  35. package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +1 -3
  36. package/src/util/data-url.ts +13 -1
  37. package/src/util/write-to-server-response.ts +7 -3
@@ -1721,6 +1721,8 @@ type ToolApprovalConfiguration<TOOLS extends ToolSet, RUNTIME_CONTEXT extends Co
1721
1721
  [key in keyof TOOLS]?: ToolApprovalStatus | SingleToolApprovalFunction<InferToolInput<TOOLS[key]>, InferToolContext<TOOLS[key]>, RUNTIME_CONTEXT>;
1722
1722
  };
1723
1723
 
1724
+ type ResolvedToolCallers = Record<string, ReadonlyArray<string>>;
1725
+
1724
1726
  declare const symbol$1: unique symbol;
1725
1727
  declare class InvalidToolInputError extends AISDKError {
1726
1728
  private readonly [symbol$1];
@@ -1761,6 +1763,7 @@ declare class NoSuchToolError extends AISDKError {
1761
1763
  * @param options.tools - The tools that are available.
1762
1764
  * @param options.inputSchema - A function that returns the JSON Schema for a tool.
1763
1765
  * @param options.error - The error that occurred while parsing the tool call.
1766
+ * @param options.abortSignal - An optional signal for cancelling the repair.
1764
1767
  */
1765
1768
  type ToolCallRepairFunction<TOOLS extends ToolSet> = (options: {
1766
1769
  instructions: Instructions | undefined;
@@ -1775,6 +1778,7 @@ type ToolCallRepairFunction<TOOLS extends ToolSet> = (options: {
1775
1778
  toolName: string;
1776
1779
  }) => PromiseLike<JSONSchema7>;
1777
1780
  error: NoSuchToolError | InvalidToolInputError;
1781
+ abortSignal?: AbortSignal;
1778
1782
  }) => Promise<LanguageModelV4ToolCall | null>;
1779
1783
 
1780
1784
  type ToolOutput<TOOLS extends ToolSet> = TypedToolResult<TOOLS> | TypedToolError<TOOLS>;
@@ -2679,15 +2683,25 @@ declare function createRestrictedTelemetryDispatcher<TOOLS extends ToolSet, RUNT
2679
2683
  includeToolsContext?: IncludedToolsContext<TOOLS>;
2680
2684
  }): RestrictedTelemetryDispatcher<TOOLS, RUNTIME_CONTEXT, OUTPUT>;
2681
2685
 
2682
- declare function parseToolCall<TOOLS extends ToolSet>({ toolCall, tools, repairToolCall, refineToolInput, messages, instructions, }: {
2686
+ declare function parseToolCall<TOOLS extends ToolSet>({ toolCall, tools, repairToolCall, refineToolInput, messages, instructions, abortSignal, }: {
2683
2687
  toolCall: LanguageModelV4ToolCall;
2684
2688
  tools: TOOLS | undefined;
2685
2689
  repairToolCall: ToolCallRepairFunction<TOOLS> | undefined;
2686
2690
  refineToolInput?: ToolInputRefinement<TOOLS> | undefined;
2687
2691
  instructions: Instructions | undefined;
2688
2692
  messages: ModelMessage[];
2693
+ abortSignal?: AbortSignal;
2689
2694
  }): Promise<TypedToolCall<TOOLS>>;
2690
2695
 
2696
+ /** Create discovery state for one generation, never for a shared tool instance. */
2697
+ declare function createToolSearchState({ tools, toolCallers, }: {
2698
+ tools: ToolSet | undefined;
2699
+ toolCallers: ResolvedToolCallers | undefined;
2700
+ }): (activeTools: ToolSet | undefined, options?: {
2701
+ toolsContext?: InferToolSetContext<ToolSet>;
2702
+ experimental_sandbox?: Experimental_SandboxSession;
2703
+ }) => ToolSet | undefined;
2704
+
2691
2705
  type CollectedToolApprovals<TOOLS extends ToolSet> = {
2692
2706
  approvalRequest: ToolApprovalRequest;
2693
2707
  approvalResponse: ToolApprovalResponse;
@@ -2750,4 +2764,4 @@ declare function toResponseMessages<TOOLS extends ToolSet>({ content: inputConte
2750
2764
  tools: TOOLS | undefined;
2751
2765
  }): Promise<Array<AssistantModelMessage | ToolModelMessage>>;
2752
2766
 
2753
- export { type CollectedToolApprovals, DefaultStepResult, type DownloadFunction, addLanguageModelUsage, asLanguageModelUsage, collectToolApprovals, convertToLanguageModelPrompt, createAsyncIterableStream, createDefaultDownloadFunction, createNullLanguageModelUsage, createRestrictedTelemetryDispatcher, createTelemetryDispatcher, createToolModelOutput, downloadAssets, mapToolResultOutput, mergeAbortSignals, mergeCallbacks, parseToolCall, prepareLanguageModelCallOptions as prepareCallSettings, prepareLanguageModelCallOptions, prepareRetries, prepareToolChoice, prepareTools, resolveLanguageModel, signToolApproval, standardizePrompt, toResponseMessages, validateApprovedToolApprovals, verifyToolApprovalSignature };
2767
+ export { type CollectedToolApprovals, DefaultStepResult, type DownloadFunction, addLanguageModelUsage, asLanguageModelUsage, collectToolApprovals, convertToLanguageModelPrompt, createAsyncIterableStream, createDefaultDownloadFunction, createNullLanguageModelUsage, createRestrictedTelemetryDispatcher, createTelemetryDispatcher, createToolModelOutput, createToolSearchState, downloadAssets, mapToolResultOutput, mergeAbortSignals, mergeCallbacks, parseToolCall, prepareLanguageModelCallOptions as prepareCallSettings, prepareLanguageModelCallOptions, prepareRetries, prepareToolChoice, prepareTools, resolveLanguageModel, signToolApproval, standardizePrompt, toResponseMessages, validateApprovedToolApprovals, verifyToolApprovalSignature };
@@ -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.106" : "0.0.0-test";
94
+ var VERSION = true ? "7.0.108" : "0.0.0-test";
95
95
 
96
96
  // src/util/download/download.ts
97
97
  var download = async ({
@@ -1066,7 +1066,7 @@ async function createToolModelOutput({
1066
1066
  toolCallId,
1067
1067
  input,
1068
1068
  output,
1069
- tool,
1069
+ tool: tool2,
1070
1070
  errorMode
1071
1071
  }) {
1072
1072
  if (errorMode === "text") {
@@ -1074,8 +1074,8 @@ async function createToolModelOutput({
1074
1074
  } else if (errorMode === "json") {
1075
1075
  return { type: "error-json", value: toJSONValue(output) };
1076
1076
  }
1077
- if (tool == null ? void 0 : tool.toModelOutput) {
1078
- return await tool.toModelOutput({ toolCallId, input, output });
1077
+ if (tool2 == null ? void 0 : tool2.toModelOutput) {
1078
+ return await tool2.toModelOutput({ toolCallId, input, output });
1079
1079
  }
1080
1080
  return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: toJSONValue(output) };
1081
1081
  }
@@ -1115,25 +1115,25 @@ async function prepareTools({
1115
1115
  return void 0;
1116
1116
  }
1117
1117
  const languageModelTools = [];
1118
- for (const [name12, tool] of orderToolEntries({ tools, toolOrder })) {
1119
- const toolType = tool.type;
1118
+ for (const [name12, tool2] of orderToolEntries({ tools, toolOrder })) {
1119
+ const toolType = tool2.type;
1120
1120
  switch (toolType) {
1121
1121
  case void 0:
1122
1122
  case "dynamic":
1123
1123
  case "function": {
1124
1124
  const description = resolveToolDescription({
1125
- tool,
1125
+ tool: tool2,
1126
1126
  toolName: name12,
1127
1127
  toolsContext,
1128
1128
  experimental_sandbox: sandbox
1129
1129
  });
1130
- const providerOptions = tool.providerOptions;
1131
- const inputExamples = tool.inputExamples;
1132
- const strict = tool.strict;
1130
+ const providerOptions = tool2.providerOptions;
1131
+ const inputExamples = tool2.inputExamples;
1132
+ const strict = tool2.strict;
1133
1133
  languageModelTools.push({
1134
1134
  type: "function",
1135
1135
  name: name12,
1136
- inputSchema: await asSchema(tool.inputSchema).jsonSchema,
1136
+ inputSchema: await asSchema(tool2.inputSchema).jsonSchema,
1137
1137
  ...description != null ? { description } : {},
1138
1138
  ...inputExamples != null ? { inputExamples } : {},
1139
1139
  ...providerOptions != null ? { providerOptions } : {},
@@ -1145,8 +1145,8 @@ async function prepareTools({
1145
1145
  languageModelTools.push({
1146
1146
  type: "provider",
1147
1147
  name: name12,
1148
- id: tool.id,
1149
- args: tool.args
1148
+ id: tool2.id,
1149
+ args: tool2.args
1150
1150
  });
1151
1151
  break;
1152
1152
  }
@@ -1173,12 +1173,12 @@ function orderToolEntries({
1173
1173
  return [...orderedTools, ...unorderedTools];
1174
1174
  }
1175
1175
  function resolveToolDescription({
1176
- tool,
1176
+ tool: tool2,
1177
1177
  toolName,
1178
1178
  toolsContext,
1179
1179
  experimental_sandbox: sandbox
1180
1180
  }) {
1181
- return tool.description === void 0 ? void 0 : typeof tool.description === "string" ? tool.description : tool.description({
1181
+ return tool2.description === void 0 ? void 0 : typeof tool2.description === "string" ? tool2.description : tool2.description({
1182
1182
  context: toolsContext[toolName],
1183
1183
  experimental_sandbox: sandbox
1184
1184
  });
@@ -2126,6 +2126,9 @@ function asImageModelV4(model) {
2126
2126
  });
2127
2127
  }
2128
2128
 
2129
+ // src/model/as-language-model-v4.ts
2130
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
2131
+
2129
2132
  // src/model/as-language-model-v3.ts
2130
2133
  function asLanguageModelV3(model) {
2131
2134
  if (model.specificationVersion === "v3") {
@@ -2213,11 +2216,131 @@ function asLanguageModelV4(model) {
2213
2216
  const v3Model = model.specificationVersion === "v2" ? asLanguageModelV3(model) : model;
2214
2217
  return new Proxy(v3Model, {
2215
2218
  get(target, prop) {
2216
- if (prop === "specificationVersion") return "v4";
2217
- return target[prop];
2219
+ switch (prop) {
2220
+ case "specificationVersion":
2221
+ return "v4";
2222
+ case "doGenerate":
2223
+ return async (options) => {
2224
+ const result = await target.doGenerate({
2225
+ ...options,
2226
+ prompt: convertV4PromptToV3(options.prompt)
2227
+ });
2228
+ return {
2229
+ ...result,
2230
+ content: result.content.map(convertV3ContentToV4)
2231
+ };
2232
+ };
2233
+ case "doStream":
2234
+ return async (options) => {
2235
+ const result = await target.doStream({
2236
+ ...options,
2237
+ prompt: convertV4PromptToV3(options.prompt)
2238
+ });
2239
+ return {
2240
+ ...result,
2241
+ stream: convertV3StreamToV4(result.stream)
2242
+ };
2243
+ };
2244
+ default:
2245
+ return target[prop];
2246
+ }
2218
2247
  }
2219
2248
  });
2220
2249
  }
2250
+ function convertV4PromptToV3(prompt) {
2251
+ return prompt.map((message) => {
2252
+ if (message.role === "system") {
2253
+ return message;
2254
+ }
2255
+ return {
2256
+ ...message,
2257
+ content: message.content.map((part) => {
2258
+ switch (part.type) {
2259
+ case "file":
2260
+ return {
2261
+ ...part,
2262
+ data: convertV4FileDataToV3(part.data)
2263
+ };
2264
+ case "tool-result":
2265
+ return {
2266
+ ...part,
2267
+ output: convertV4ToolResultOutputToV3(part.output)
2268
+ };
2269
+ default:
2270
+ return part;
2271
+ }
2272
+ })
2273
+ };
2274
+ });
2275
+ }
2276
+ function convertV4FileDataToV3(data) {
2277
+ switch (data.type) {
2278
+ case "data":
2279
+ return data.data;
2280
+ case "url":
2281
+ return data.url;
2282
+ case "reference":
2283
+ case "text":
2284
+ return data;
2285
+ }
2286
+ }
2287
+ function convertV4ToolResultOutputToV3(output) {
2288
+ if (output.type !== "content") {
2289
+ return output;
2290
+ }
2291
+ return {
2292
+ ...output,
2293
+ value: output.value.map((part) => {
2294
+ if (part.type !== "file") {
2295
+ return part;
2296
+ }
2297
+ switch (part.data.type) {
2298
+ case "data":
2299
+ return {
2300
+ type: "file-data",
2301
+ data: typeof part.data.data === "string" ? part.data.data : convertUint8ArrayToBase64(part.data.data),
2302
+ mediaType: part.mediaType,
2303
+ filename: part.filename,
2304
+ providerOptions: part.providerOptions
2305
+ };
2306
+ case "url":
2307
+ return {
2308
+ type: "file-url",
2309
+ url: part.data.url.toString(),
2310
+ providerOptions: part.providerOptions
2311
+ };
2312
+ case "reference":
2313
+ return {
2314
+ type: "file-id",
2315
+ fileId: part.data.reference,
2316
+ providerOptions: part.providerOptions
2317
+ };
2318
+ case "text":
2319
+ return part;
2320
+ }
2321
+ })
2322
+ };
2323
+ }
2324
+ function convertV3ContentToV4(content) {
2325
+ return content.type === "file" ? {
2326
+ ...content,
2327
+ data: { type: "data", data: content.data }
2328
+ } : content;
2329
+ }
2330
+ function convertV3StreamToV4(stream) {
2331
+ return stream.pipeThrough(
2332
+ new TransformStream({
2333
+ transform(chunk, controller) {
2334
+ controller.enqueue(
2335
+ chunk.type === "file" ? {
2336
+ ...chunk,
2337
+ data: { type: "data", data: chunk.data }
2338
+ } : chunk
2339
+ );
2340
+ }
2341
+ })
2342
+ );
2343
+ }
2221
2344
 
2222
2345
  // src/model/as-reranking-model-v4.ts
2223
2346
  function asRerankingModelV4(model) {
@@ -2968,7 +3091,8 @@ async function parseToolCall({
2968
3091
  repairToolCall,
2969
3092
  refineToolInput,
2970
3093
  messages,
2971
- instructions
3094
+ instructions,
3095
+ abortSignal
2972
3096
  }) {
2973
3097
  try {
2974
3098
  if (tools == null) {
@@ -2991,20 +3115,26 @@ async function parseToolCall({
2991
3115
  }
2992
3116
  let repairedToolCall = null;
2993
3117
  try {
2994
- repairedToolCall = await repairToolCall({
2995
- toolCall,
2996
- tools,
2997
- inputSchema: async ({ toolName }) => {
2998
- var _a12;
2999
- const inputSchema = (_a12 = getOwn(tools, toolName)) == null ? void 0 : _a12.inputSchema;
3000
- return await asSchema2(inputSchema).jsonSchema;
3001
- },
3002
- instructions,
3003
- system: instructions,
3004
- messages,
3005
- error
3118
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
3119
+ repairedToolCall = await waitForPromiseWithAbortSignal({
3120
+ promise: repairToolCall({
3121
+ toolCall,
3122
+ tools,
3123
+ inputSchema: async ({ toolName }) => {
3124
+ var _a12;
3125
+ const inputSchema = (_a12 = getOwn(tools, toolName)) == null ? void 0 : _a12.inputSchema;
3126
+ return await asSchema2(inputSchema).jsonSchema;
3127
+ },
3128
+ instructions,
3129
+ system: instructions,
3130
+ messages,
3131
+ error,
3132
+ abortSignal
3133
+ }),
3134
+ abortSignal
3006
3135
  });
3007
3136
  } catch (repairError) {
3137
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
3008
3138
  throw new ToolCallRepairError({
3009
3139
  cause: repairError,
3010
3140
  originalError: error
@@ -3013,15 +3143,18 @@ async function parseToolCall({
3013
3143
  if (repairedToolCall == null) {
3014
3144
  throw error;
3015
3145
  }
3016
- return await refineParsedToolCallInput({
3146
+ const parsedRepairedToolCall = await refineParsedToolCallInput({
3017
3147
  toolCall: await doParseToolCall({ toolCall: repairedToolCall, tools }),
3018
3148
  refineToolInput
3019
3149
  });
3150
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
3151
+ return parsedRepairedToolCall;
3020
3152
  }
3021
3153
  } catch (error) {
3154
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
3022
3155
  const parsedInput = await safeParseJSON({ text: toolCall.input });
3023
3156
  const input = parsedInput.success ? parsedInput.value : toolCall.input;
3024
- const tool = getOwn(tools, toolCall.toolName);
3157
+ const tool2 = getOwn(tools, toolCall.toolName);
3025
3158
  return {
3026
3159
  type: "tool-call",
3027
3160
  toolCallId: toolCall.toolCallId,
@@ -3030,13 +3163,41 @@ async function parseToolCall({
3030
3163
  dynamic: true,
3031
3164
  invalid: true,
3032
3165
  error,
3033
- title: tool == null ? void 0 : tool.title,
3166
+ title: tool2 == null ? void 0 : tool2.title,
3034
3167
  providerExecuted: toolCall.providerExecuted,
3035
3168
  providerMetadata: toolCall.providerMetadata,
3036
- ...(tool == null ? void 0 : tool.metadata) != null ? { toolMetadata: tool.metadata } : {}
3169
+ ...(tool2 == null ? void 0 : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
3037
3170
  };
3038
3171
  }
3039
3172
  }
3173
+ async function waitForPromiseWithAbortSignal({
3174
+ promise,
3175
+ abortSignal
3176
+ }) {
3177
+ if (abortSignal == null) {
3178
+ return await promise;
3179
+ }
3180
+ return await new Promise((resolve, reject) => {
3181
+ const cleanup = () => {
3182
+ abortSignal.removeEventListener("abort", onAbort);
3183
+ };
3184
+ const onAbort = () => {
3185
+ cleanup();
3186
+ reject(abortSignal.reason);
3187
+ };
3188
+ Promise.resolve(promise).then((value) => {
3189
+ cleanup();
3190
+ resolve(value);
3191
+ }).catch((error) => {
3192
+ cleanup();
3193
+ reject(error);
3194
+ });
3195
+ abortSignal.addEventListener("abort", onAbort, { once: true });
3196
+ if (abortSignal.aborted) {
3197
+ onAbort();
3198
+ }
3199
+ });
3200
+ }
3040
3201
  async function refineParsedToolCallInput({
3041
3202
  toolCall,
3042
3203
  refineToolInput
@@ -3074,8 +3235,8 @@ async function doParseToolCall({
3074
3235
  tools
3075
3236
  }) {
3076
3237
  const toolName = toolCall.toolName;
3077
- const tool = getOwn(tools, toolName);
3078
- if (tool == null) {
3238
+ const tool2 = getOwn(tools, toolName);
3239
+ if (tool2 == null) {
3079
3240
  if (toolCall.providerExecuted && toolCall.dynamic) {
3080
3241
  return await parseProviderExecutedDynamicToolCall(toolCall);
3081
3242
  }
@@ -3084,7 +3245,7 @@ async function doParseToolCall({
3084
3245
  availableTools: Object.keys(tools)
3085
3246
  });
3086
3247
  }
3087
- const schema = asSchema2(tool.inputSchema);
3248
+ const schema = asSchema2(tool2.inputSchema);
3088
3249
  const parseResult = toolCall.input.trim() === "" ? await safeValidateTypes2({ value: {}, schema }) : await safeParseJSON({ text: toolCall.input, schema });
3089
3250
  if (parseResult.success === false) {
3090
3251
  throw new InvalidToolInputError({
@@ -3093,16 +3254,16 @@ async function doParseToolCall({
3093
3254
  cause: parseResult.error
3094
3255
  });
3095
3256
  }
3096
- return tool.type === "dynamic" ? {
3257
+ return tool2.type === "dynamic" ? {
3097
3258
  type: "tool-call",
3098
3259
  toolCallId: toolCall.toolCallId,
3099
3260
  toolName: toolCall.toolName,
3100
3261
  input: parseResult.value,
3101
3262
  providerExecuted: toolCall.providerExecuted,
3102
3263
  providerMetadata: toolCall.providerMetadata,
3103
- ...tool.metadata != null ? { toolMetadata: tool.metadata } : {},
3264
+ ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
3104
3265
  dynamic: true,
3105
- title: tool.title
3266
+ title: tool2.title
3106
3267
  } : {
3107
3268
  type: "tool-call",
3108
3269
  toolCallId: toolCall.toolCallId,
@@ -3110,11 +3271,119 @@ async function doParseToolCall({
3110
3271
  input: parseResult.value,
3111
3272
  providerExecuted: toolCall.providerExecuted,
3112
3273
  providerMetadata: toolCall.providerMetadata,
3113
- ...tool.metadata != null ? { toolMetadata: tool.metadata } : {},
3114
- title: tool.title
3274
+ ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
3275
+ title: tool2.title
3115
3276
  };
3116
3277
  }
3117
3278
 
3279
+ // src/tool-search/prepare-tool-search.ts
3280
+ import {
3281
+ experimental_getToolCaller as experimental_getToolCaller2
3282
+ } from "@ai-sdk/provider-utils";
3283
+
3284
+ // src/generate-text/tool-caller-configuration.ts
3285
+ import {
3286
+ experimental_getToolCaller
3287
+ } from "@ai-sdk/provider-utils";
3288
+ var DIRECT_TOOL_CALL = "AI_SDK_DIRECT_TOOL_CALL";
3289
+
3290
+ // src/tool-search/tool-search.ts
3291
+ import { jsonSchema, tool } from "@ai-sdk/provider-utils";
3292
+ var toolSearchSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.toolSearch");
3293
+ function isToolSearch(tool2) {
3294
+ return tool2[toolSearchSymbol] === true;
3295
+ }
3296
+
3297
+ // src/tool-search/prepare-tool-search.ts
3298
+ function createToolSearchState({
3299
+ tools,
3300
+ toolCallers
3301
+ }) {
3302
+ const searchTools = Object.entries(tools != null ? tools : {}).filter(
3303
+ ([, tool2]) => tool2.deferLoading || isToolSearch(tool2)
3304
+ );
3305
+ if (searchTools.length === 0) {
3306
+ return (activeTools) => activeTools;
3307
+ }
3308
+ const discovered = /* @__PURE__ */ new Set();
3309
+ const getCallers = (name12) => {
3310
+ var _a12;
3311
+ return (_a12 = getOwn(toolCallers, name12)) != null ? _a12 : [DIRECT_TOOL_CALL];
3312
+ };
3313
+ for (const [name12, tool2] of searchTools) {
3314
+ const callers = getCallers(name12);
3315
+ if (callers.some((name13) => {
3316
+ if (name13 === DIRECT_TOOL_CALL) {
3317
+ return false;
3318
+ }
3319
+ const caller = experimental_getToolCaller2(tools == null ? void 0 : tools[name13]);
3320
+ return (caller == null ? void 0 : caller.type) !== "local" || caller.prepareModelMessage == null;
3321
+ }) || isToolSearch(tool2) && tool2.deferLoading) {
3322
+ throw new InvalidArgumentError({
3323
+ parameter: "tools",
3324
+ value: name12,
3325
+ message: `tool "${name12}" must be callable directly or through code mode with toolDiscovery: 'conversation'. The search tool itself must not defer loading.`
3326
+ });
3327
+ }
3328
+ }
3329
+ return (activeTools, { toolsContext = {}, experimental_sandbox } = {}) => {
3330
+ if (activeTools == null) {
3331
+ return void 0;
3332
+ }
3333
+ const entries = Object.entries(activeTools);
3334
+ return Object.fromEntries(
3335
+ entries.filter(([name12, tool2]) => !tool2.deferLoading || discovered.has(name12)).map(([searchName, tool2]) => {
3336
+ if (!isToolSearch(tool2)) {
3337
+ return [searchName, tool2];
3338
+ }
3339
+ const callers = getCallers(searchName).filter(
3340
+ (name12) => name12 === DIRECT_TOOL_CALL || Object.hasOwn(activeTools, name12)
3341
+ );
3342
+ const candidates = entries.filter(
3343
+ ([name12, candidate]) => candidate.deferLoading && !isToolSearch(candidate) && callers.some((caller) => getCallers(name12).includes(caller))
3344
+ );
3345
+ return [
3346
+ searchName,
3347
+ {
3348
+ ...tool2,
3349
+ execute: ({ query }) => {
3350
+ const terms = [...new Set(tokenize(query))];
3351
+ const matches = candidates.map(([name12, candidate]) => {
3352
+ const description = resolveToolDescription({
3353
+ tool: candidate,
3354
+ toolName: name12,
3355
+ toolsContext,
3356
+ experimental_sandbox
3357
+ });
3358
+ const nameTerms = tokenize(name12);
3359
+ const descriptionTerms = tokenize(description != null ? description : "");
3360
+ const score = terms.reduce(
3361
+ (score2, term) => score2 + (nameTerms.includes(term) ? 2 : 0) + (descriptionTerms.includes(term) ? 1 : 0),
3362
+ 0
3363
+ );
3364
+ return { name: name12, description, score };
3365
+ }).filter((match) => match.score > 0).sort((a, b) => b.score - a.score).slice(0, 5);
3366
+ for (const { name: name12 } of matches) {
3367
+ discovered.add(name12);
3368
+ }
3369
+ return {
3370
+ tools: matches.map(({ name: name12, description }) => ({
3371
+ name: name12,
3372
+ ...description == null ? {} : { description }
3373
+ }))
3374
+ };
3375
+ }
3376
+ }
3377
+ ];
3378
+ })
3379
+ );
3380
+ };
3381
+ }
3382
+ function tokenize(text) {
3383
+ var _a12;
3384
+ return (_a12 = text.replace(/([a-z\d])([A-Z])/g, "$1 $2").toLowerCase().match(/[\p{L}\p{N}]+/gu)) != null ? _a12 : [];
3385
+ }
3386
+
3118
3387
  // src/generate-text/collect-tool-approvals.ts
3119
3388
  function collectToolApprovals({
3120
3389
  messages
@@ -3196,7 +3465,7 @@ function collectToolApprovals({
3196
3465
  import { convertBase64ToUint8Array } from "@ai-sdk/provider-utils";
3197
3466
 
3198
3467
  // src/util/canonical-hash.ts
3199
- import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
3468
+ import { convertUint8ArrayToBase64 as convertUint8ArrayToBase642 } from "@ai-sdk/provider-utils";
3200
3469
  var encoder = new TextEncoder();
3201
3470
  function canonicalJSON(value) {
3202
3471
  if (value === null || value === void 0) {
@@ -3215,7 +3484,7 @@ function canonicalJSON(value) {
3215
3484
  return `{${entries.join(",")}}`;
3216
3485
  }
3217
3486
  function toBase64url(bytes) {
3218
- return convertUint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3487
+ return convertUint8ArrayToBase642(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3219
3488
  }
3220
3489
  async function hashCanonical(value) {
3221
3490
  const digest = await crypto.subtle.digest(
@@ -3347,7 +3616,7 @@ async function resolveToolApproval({
3347
3616
  );
3348
3617
  }
3349
3618
  const toolName = toolCall.toolName;
3350
- const tool = getOwn(tools, toolName);
3619
+ const tool2 = getOwn(tools, toolName);
3351
3620
  const input = toolCall.input;
3352
3621
  const userDefinedToolApprovalStatus = getOwn(toolApproval, toolName);
3353
3622
  if (userDefinedToolApprovalStatus != null) {
@@ -3357,24 +3626,24 @@ async function resolveToolApproval({
3357
3626
  toolContext: await validateToolContext({
3358
3627
  toolName,
3359
3628
  context: getOwn(toolsContext, toolName),
3360
- contextSchema: tool == null ? void 0 : tool.contextSchema
3629
+ contextSchema: tool2 == null ? void 0 : tool2.contextSchema
3361
3630
  }),
3362
3631
  runtimeContext
3363
3632
  }) : userDefinedToolApprovalStatus;
3364
3633
  return normalizeToolApprovalStatus(approvalStatus);
3365
3634
  }
3366
- if ((tool == null ? void 0 : tool.needsApproval) == null) {
3635
+ if ((tool2 == null ? void 0 : tool2.needsApproval) == null) {
3367
3636
  return { type: "not-applicable" };
3368
3637
  }
3369
- const needsApproval = typeof tool.needsApproval === "function" ? await tool.needsApproval(input, {
3638
+ const needsApproval = typeof tool2.needsApproval === "function" ? await tool2.needsApproval(input, {
3370
3639
  toolCallId: toolCall.toolCallId,
3371
3640
  messages,
3372
3641
  context: await validateToolContext({
3373
3642
  toolName,
3374
3643
  context: getOwn(toolsContext, toolName),
3375
- contextSchema: tool == null ? void 0 : tool.contextSchema
3644
+ contextSchema: tool2 == null ? void 0 : tool2.contextSchema
3376
3645
  })
3377
- }) : tool.needsApproval;
3646
+ }) : tool2.needsApproval;
3378
3647
  return needsApproval ? { type: "user-approval" } : { type: "not-applicable" };
3379
3648
  }
3380
3649
  function normalizeToolApprovalStatus(status) {
@@ -3397,7 +3666,7 @@ async function validateApprovedToolApprovals({
3397
3666
  const invalid = [];
3398
3667
  for (const approval of approvedToolApprovals) {
3399
3668
  const { toolCall, approvalRequest } = approval;
3400
- const tool = getOwn(tools, toolCall.toolName);
3669
+ const tool2 = getOwn(tools, toolCall.toolName);
3401
3670
  if (toolApprovalSecret != null) {
3402
3671
  if (approvalRequest.signature == null) {
3403
3672
  throw new InvalidToolApprovalSignatureError({
@@ -3422,10 +3691,10 @@ async function validateApprovedToolApprovals({
3422
3691
  });
3423
3692
  }
3424
3693
  }
3425
- if (isExecutableTool(tool) && tool.inputSchema != null) {
3694
+ if (isExecutableTool(tool2) && tool2.inputSchema != null) {
3426
3695
  const validation = await safeValidateTypes3({
3427
3696
  value: toolCall.input,
3428
- schema: asSchema3(tool.inputSchema)
3697
+ schema: asSchema3(tool2.inputSchema)
3429
3698
  });
3430
3699
  if (!validation.success) {
3431
3700
  invalid.push({
@@ -3679,6 +3948,7 @@ export {
3679
3948
  createRestrictedTelemetryDispatcher,
3680
3949
  createTelemetryDispatcher,
3681
3950
  createToolModelOutput,
3951
+ createToolSearchState,
3682
3952
  downloadAssets,
3683
3953
  mapToolResultOutput,
3684
3954
  mergeAbortSignals,