aieo 0.1.35 → 0.1.36

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.
package/dist/index.cjs CHANGED
@@ -36,12 +36,15 @@ __export(index_exports, {
36
36
  OUTRO: () => OUTRO,
37
37
  PROVIDERS: () => PROVIDERS,
38
38
  SYSTEM: () => SYSTEM,
39
+ WEB_SEARCH_TOOL_NAME: () => WEB_SEARCH_TOOL_NAME,
39
40
  addUsage: () => addUsage,
40
41
  callGenerateObject: () => callGenerateObject,
41
42
  callGenerateText: () => callGenerateText,
42
43
  callModel: () => callModel,
44
+ captureNativeResults: () => captureNativeResults,
43
45
  computeSessionCost: () => computeSessionCost,
44
46
  consoleLogger: () => consoleLogger,
47
+ createWebSearch: () => createWebSearch,
45
48
  emptyUsage: () => emptyUsage,
46
49
  gatewayEnvForProviders: () => gatewayEnvForProviders,
47
50
  gatewayUrlFor: () => gatewayUrlFor,
@@ -55,13 +58,19 @@ __export(index_exports, {
55
58
  getProviderForModel: () => getProviderForModel,
56
59
  getProviderOptions: () => getProviderOptions,
57
60
  getProviderTool: () => getProviderTool,
61
+ getSearchApiKey: () => getSearchApiKey,
58
62
  getTokenPricing: () => getTokenPricing,
59
63
  hasApiKeyForProvider: () => hasApiKeyForProvider,
64
+ hasSearchApiKey: () => hasSearchApiKey,
65
+ linkifyCitations: () => linkifyCitations,
60
66
  loadModelPricing: () => loadModelPricing,
61
67
  normalizeApiKey: () => normalizeApiKey,
62
68
  normalizeCallerBaseURL: () => normalizeCallerBaseURL,
63
69
  normalizeUsage: () => normalizeUsage,
64
70
  resolveLLMConfig: () => resolveLLMConfig,
71
+ resolveSearchBackend: () => resolveSearchBackend,
72
+ searchWeb: () => searchWeb,
73
+ stripCitations: () => stripCitations,
65
74
  withLegacyUsage: () => withLegacyUsage,
66
75
  withProviderCacheUsage: () => withProviderCacheUsage
67
76
  });
@@ -4181,35 +4190,35 @@ async function prepareTools({
4181
4190
  return { tools: void 0, toolChoice: void 0, toolWarnings, betas };
4182
4191
  }
4183
4192
  const anthropicTools2 = [];
4184
- for (const tool4 of tools) {
4185
- switch (tool4.type) {
4193
+ for (const tool5 of tools) {
4194
+ switch (tool5.type) {
4186
4195
  case "function": {
4187
- const cacheControl = validator.getCacheControl(tool4.providerOptions, {
4196
+ const cacheControl = validator.getCacheControl(tool5.providerOptions, {
4188
4197
  type: "tool definition",
4189
4198
  canCache: true
4190
4199
  });
4191
- const anthropicOptions = (_a20 = tool4.providerOptions) == null ? void 0 : _a20.anthropic;
4200
+ const anthropicOptions = (_a20 = tool5.providerOptions) == null ? void 0 : _a20.anthropic;
4192
4201
  const eagerInputStreaming = (_b20 = anthropicOptions == null ? void 0 : anthropicOptions.eagerInputStreaming) != null ? _b20 : defaultEagerInputStreaming;
4193
4202
  const deferLoading = anthropicOptions == null ? void 0 : anthropicOptions.deferLoading;
4194
4203
  const allowedCallers = anthropicOptions == null ? void 0 : anthropicOptions.allowedCallers;
4195
- if (!supportsStrictTools && tool4.strict != null) {
4204
+ if (!supportsStrictTools && tool5.strict != null) {
4196
4205
  toolWarnings.push({
4197
4206
  type: "unsupported",
4198
4207
  feature: "strict",
4199
- details: `Tool '${tool4.name}' has strict: ${tool4.strict}, but strict mode is not supported by this provider. The strict property will be ignored.`
4208
+ details: `Tool '${tool5.name}' has strict: ${tool5.strict}, but strict mode is not supported by this provider. The strict property will be ignored.`
4200
4209
  });
4201
4210
  }
4202
4211
  anthropicTools2.push({
4203
- name: tool4.name,
4204
- description: tool4.description,
4205
- input_schema: tool4.inputSchema,
4212
+ name: tool5.name,
4213
+ description: tool5.description,
4214
+ input_schema: tool5.inputSchema,
4206
4215
  cache_control: cacheControl,
4207
4216
  ...eagerInputStreaming ? { eager_input_streaming: true } : {},
4208
- ...supportsStrictTools === true && tool4.strict != null ? { strict: tool4.strict } : {},
4217
+ ...supportsStrictTools === true && tool5.strict != null ? { strict: tool5.strict } : {},
4209
4218
  ...deferLoading != null ? { defer_loading: deferLoading } : {},
4210
4219
  ...allowedCallers != null ? { allowed_callers: allowedCallers } : {},
4211
- ...tool4.inputExamples != null ? {
4212
- input_examples: tool4.inputExamples.map(
4220
+ ...tool5.inputExamples != null ? {
4221
+ input_examples: tool5.inputExamples.map(
4213
4222
  (example) => example.input
4214
4223
  )
4215
4224
  } : {}
@@ -4217,13 +4226,13 @@ async function prepareTools({
4217
4226
  if (supportsStructuredOutput === true) {
4218
4227
  betas.add("structured-outputs-2025-11-13");
4219
4228
  }
4220
- if (tool4.inputExamples != null || allowedCallers != null) {
4229
+ if (tool5.inputExamples != null || allowedCallers != null) {
4221
4230
  betas.add("advanced-tool-use-2025-11-20");
4222
4231
  }
4223
4232
  break;
4224
4233
  }
4225
4234
  case "provider": {
4226
- switch (tool4.id) {
4235
+ switch (tool5.id) {
4227
4236
  case "anthropic.code_execution_20250522": {
4228
4237
  betas.add("code-execution-2025-05-22");
4229
4238
  anthropicTools2.push({
@@ -4253,9 +4262,9 @@ async function prepareTools({
4253
4262
  anthropicTools2.push({
4254
4263
  name: "computer",
4255
4264
  type: "computer_20250124",
4256
- display_width_px: tool4.args.displayWidthPx,
4257
- display_height_px: tool4.args.displayHeightPx,
4258
- display_number: tool4.args.displayNumber,
4265
+ display_width_px: tool5.args.displayWidthPx,
4266
+ display_height_px: tool5.args.displayHeightPx,
4267
+ display_number: tool5.args.displayNumber,
4259
4268
  cache_control: void 0
4260
4269
  });
4261
4270
  break;
@@ -4265,10 +4274,10 @@ async function prepareTools({
4265
4274
  anthropicTools2.push({
4266
4275
  name: "computer",
4267
4276
  type: "computer_20251124",
4268
- display_width_px: tool4.args.displayWidthPx,
4269
- display_height_px: tool4.args.displayHeightPx,
4270
- display_number: tool4.args.displayNumber,
4271
- enable_zoom: tool4.args.enableZoom,
4277
+ display_width_px: tool5.args.displayWidthPx,
4278
+ display_height_px: tool5.args.displayHeightPx,
4279
+ display_number: tool5.args.displayNumber,
4280
+ enable_zoom: tool5.args.enableZoom,
4272
4281
  cache_control: void 0
4273
4282
  });
4274
4283
  break;
@@ -4278,9 +4287,9 @@ async function prepareTools({
4278
4287
  anthropicTools2.push({
4279
4288
  name: "computer",
4280
4289
  type: "computer_20241022",
4281
- display_width_px: tool4.args.displayWidthPx,
4282
- display_height_px: tool4.args.displayHeightPx,
4283
- display_number: tool4.args.displayNumber,
4290
+ display_width_px: tool5.args.displayWidthPx,
4291
+ display_height_px: tool5.args.displayHeightPx,
4292
+ display_number: tool5.args.displayNumber,
4284
4293
  cache_control: void 0
4285
4294
  });
4286
4295
  break;
@@ -4314,7 +4323,7 @@ async function prepareTools({
4314
4323
  }
4315
4324
  case "anthropic.text_editor_20250728": {
4316
4325
  const args = await validateTypes({
4317
- value: tool4.args,
4326
+ value: tool5.args,
4318
4327
  schema: textEditor_20250728ArgsSchema
4319
4328
  });
4320
4329
  anthropicTools2.push({
@@ -4354,7 +4363,7 @@ async function prepareTools({
4354
4363
  case "anthropic.web_fetch_20250910": {
4355
4364
  betas.add("web-fetch-2025-09-10");
4356
4365
  const args = await validateTypes({
4357
- value: tool4.args,
4366
+ value: tool5.args,
4358
4367
  schema: webFetch_20250910ArgsSchema
4359
4368
  });
4360
4369
  anthropicTools2.push({
@@ -4372,7 +4381,7 @@ async function prepareTools({
4372
4381
  case "anthropic.web_fetch_20260209": {
4373
4382
  betas.add("code-execution-web-tools-2026-02-09");
4374
4383
  const args = await validateTypes({
4375
- value: tool4.args,
4384
+ value: tool5.args,
4376
4385
  schema: webFetch_20260209ArgsSchema
4377
4386
  });
4378
4387
  anthropicTools2.push({
@@ -4389,7 +4398,7 @@ async function prepareTools({
4389
4398
  }
4390
4399
  case "anthropic.web_search_20250305": {
4391
4400
  const args = await validateTypes({
4392
- value: tool4.args,
4401
+ value: tool5.args,
4393
4402
  schema: webSearch_20250305ArgsSchema
4394
4403
  });
4395
4404
  anthropicTools2.push({
@@ -4406,7 +4415,7 @@ async function prepareTools({
4406
4415
  case "anthropic.web_search_20260209": {
4407
4416
  betas.add("code-execution-web-tools-2026-02-09");
4408
4417
  const args = await validateTypes({
4409
- value: tool4.args,
4418
+ value: tool5.args,
4410
4419
  schema: webSearch_20260209ArgsSchema
4411
4420
  });
4412
4421
  anthropicTools2.push({
@@ -4437,7 +4446,7 @@ async function prepareTools({
4437
4446
  case "anthropic.advisor_20260301": {
4438
4447
  betas.add("advisor-tool-2026-03-01");
4439
4448
  const args = await validateTypes({
4440
- value: tool4.args,
4449
+ value: tool5.args,
4441
4450
  schema: advisor_20260301ArgsSchema
4442
4451
  });
4443
4452
  anthropicTools2.push({
@@ -4452,7 +4461,7 @@ async function prepareTools({
4452
4461
  default: {
4453
4462
  toolWarnings.push({
4454
4463
  type: "unsupported",
4455
- feature: `provider-defined tool ${tool4.id}`
4464
+ feature: `provider-defined tool ${tool5.id}`
4456
4465
  });
4457
4466
  break;
4458
4467
  }
@@ -4462,7 +4471,7 @@ async function prepareTools({
4462
4471
  default: {
4463
4472
  toolWarnings.push({
4464
4473
  type: "unsupported",
4465
- feature: `tool ${tool4}`
4474
+ feature: `tool ${tool5}`
4466
4475
  });
4467
4476
  break;
4468
4477
  }
@@ -6432,7 +6441,7 @@ var AnthropicMessagesLanguageModel = class {
6432
6441
  betas.add("skills-2025-10-02");
6433
6442
  betas.add("files-api-2025-04-14");
6434
6443
  if (!(tools == null ? void 0 : tools.some(
6435
- (tool4) => tool4.type === "provider" && (tool4.id === "anthropic.code_execution_20250825" || tool4.id === "anthropic.code_execution_20260120")
6444
+ (tool5) => tool5.type === "provider" && (tool5.id === "anthropic.code_execution_20250825" || tool5.id === "anthropic.code_execution_20260120")
6436
6445
  ))) {
6437
6446
  warnings.push({
6438
6447
  type: "other",
@@ -8035,12 +8044,12 @@ function hasWebTool20260209WithoutCodeExecution(tools) {
8035
8044
  }
8036
8045
  let hasWebTool20260209 = false;
8037
8046
  let hasCodeExecutionTool = false;
8038
- for (const tool4 of tools) {
8039
- if ("type" in tool4 && (tool4.type === "web_fetch_20260209" || tool4.type === "web_search_20260209")) {
8047
+ for (const tool5 of tools) {
8048
+ if ("type" in tool5 && (tool5.type === "web_fetch_20260209" || tool5.type === "web_search_20260209")) {
8040
8049
  hasWebTool20260209 = true;
8041
8050
  continue;
8042
8051
  }
8043
- if (tool4.name === "code_execution") {
8052
+ if (tool5.name === "code_execution") {
8044
8053
  hasCodeExecutionTool = true;
8045
8054
  break;
8046
8055
  }
@@ -11749,8 +11758,8 @@ function prepareTools2({
11749
11758
  if (tools == null) {
11750
11759
  return { tools: void 0, toolConfig: void 0, toolWarnings };
11751
11760
  }
11752
- const hasFunctionTools = tools.some((tool4) => tool4.type === "function");
11753
- const hasProviderTools = tools.some((tool4) => tool4.type === "provider");
11761
+ const hasFunctionTools = tools.some((tool5) => tool5.type === "function");
11762
+ const hasProviderTools = tools.some((tool5) => tool5.type === "provider");
11754
11763
  if (hasFunctionTools && hasProviderTools && !isGemini3orNewer) {
11755
11764
  toolWarnings.push({
11756
11765
  type: "unsupported",
@@ -11759,16 +11768,16 @@ function prepareTools2({
11759
11768
  }
11760
11769
  if (hasProviderTools) {
11761
11770
  const googleTools2 = [];
11762
- const ProviderTools = tools.filter((tool4) => tool4.type === "provider");
11763
- ProviderTools.forEach((tool4) => {
11764
- switch (tool4.id) {
11771
+ const ProviderTools = tools.filter((tool5) => tool5.type === "provider");
11772
+ ProviderTools.forEach((tool5) => {
11773
+ switch (tool5.id) {
11765
11774
  case "google.google_search":
11766
11775
  if (isGemini2orNewer) {
11767
- googleTools2.push({ googleSearch: { ...tool4.args } });
11776
+ googleTools2.push({ googleSearch: { ...tool5.args } });
11768
11777
  } else {
11769
11778
  toolWarnings.push({
11770
11779
  type: "unsupported",
11771
- feature: `provider-defined tool ${tool4.id}`,
11780
+ feature: `provider-defined tool ${tool5.id}`,
11772
11781
  details: "Google Search requires Gemini 2.0 or newer."
11773
11782
  });
11774
11783
  }
@@ -11779,7 +11788,7 @@ function prepareTools2({
11779
11788
  } else {
11780
11789
  toolWarnings.push({
11781
11790
  type: "unsupported",
11782
- feature: `provider-defined tool ${tool4.id}`,
11791
+ feature: `provider-defined tool ${tool5.id}`,
11783
11792
  details: "Enterprise Web Search requires Gemini 2.0 or newer."
11784
11793
  });
11785
11794
  }
@@ -11790,7 +11799,7 @@ function prepareTools2({
11790
11799
  } else {
11791
11800
  toolWarnings.push({
11792
11801
  type: "unsupported",
11793
- feature: `provider-defined tool ${tool4.id}`,
11802
+ feature: `provider-defined tool ${tool5.id}`,
11794
11803
  details: "The URL context tool is not supported with other Gemini models than Gemini 2."
11795
11804
  });
11796
11805
  }
@@ -11801,18 +11810,18 @@ function prepareTools2({
11801
11810
  } else {
11802
11811
  toolWarnings.push({
11803
11812
  type: "unsupported",
11804
- feature: `provider-defined tool ${tool4.id}`,
11813
+ feature: `provider-defined tool ${tool5.id}`,
11805
11814
  details: "The code execution tool is not supported with other Gemini models than Gemini 2."
11806
11815
  });
11807
11816
  }
11808
11817
  break;
11809
11818
  case "google.file_search":
11810
11819
  if (supportsFileSearch) {
11811
- googleTools2.push({ fileSearch: { ...tool4.args } });
11820
+ googleTools2.push({ fileSearch: { ...tool5.args } });
11812
11821
  } else {
11813
11822
  toolWarnings.push({
11814
11823
  type: "unsupported",
11815
- feature: `provider-defined tool ${tool4.id}`,
11824
+ feature: `provider-defined tool ${tool5.id}`,
11816
11825
  details: "The file search tool is only supported with Gemini 2.5 models and Gemini 3 models."
11817
11826
  });
11818
11827
  }
@@ -11823,16 +11832,16 @@ function prepareTools2({
11823
11832
  retrieval: {
11824
11833
  vertex_rag_store: {
11825
11834
  rag_resources: {
11826
- rag_corpus: tool4.args.ragCorpus
11835
+ rag_corpus: tool5.args.ragCorpus
11827
11836
  },
11828
- similarity_top_k: tool4.args.topK
11837
+ similarity_top_k: tool5.args.topK
11829
11838
  }
11830
11839
  }
11831
11840
  });
11832
11841
  } else {
11833
11842
  toolWarnings.push({
11834
11843
  type: "unsupported",
11835
- feature: `provider-defined tool ${tool4.id}`,
11844
+ feature: `provider-defined tool ${tool5.id}`,
11836
11845
  details: "The RAG store tool is not supported with other Gemini models than Gemini 2."
11837
11846
  });
11838
11847
  }
@@ -11843,7 +11852,7 @@ function prepareTools2({
11843
11852
  } else {
11844
11853
  toolWarnings.push({
11845
11854
  type: "unsupported",
11846
- feature: `provider-defined tool ${tool4.id}`,
11855
+ feature: `provider-defined tool ${tool5.id}`,
11847
11856
  details: "The Google Maps grounding tool is not supported with Gemini models other than Gemini 2 or newer."
11848
11857
  });
11849
11858
  }
@@ -11851,19 +11860,19 @@ function prepareTools2({
11851
11860
  default:
11852
11861
  toolWarnings.push({
11853
11862
  type: "unsupported",
11854
- feature: `provider-defined tool ${tool4.id}`
11863
+ feature: `provider-defined tool ${tool5.id}`
11855
11864
  });
11856
11865
  break;
11857
11866
  }
11858
11867
  });
11859
11868
  if (hasFunctionTools && isGemini3orNewer && googleTools2.length > 0) {
11860
11869
  const functionDeclarations2 = [];
11861
- for (const tool4 of tools) {
11862
- if (tool4.type === "function") {
11870
+ for (const tool5 of tools) {
11871
+ if (tool5.type === "function") {
11863
11872
  functionDeclarations2.push({
11864
- name: tool4.name,
11865
- description: (_a20 = tool4.description) != null ? _a20 : "",
11866
- parameters: convertJSONSchemaToOpenAPISchema(tool4.inputSchema)
11873
+ name: tool5.name,
11874
+ description: (_a20 = tool5.description) != null ? _a20 : "",
11875
+ parameters: convertJSONSchemaToOpenAPISchema(tool5.inputSchema)
11867
11876
  });
11868
11877
  }
11869
11878
  }
@@ -11903,22 +11912,22 @@ function prepareTools2({
11903
11912
  }
11904
11913
  const functionDeclarations = [];
11905
11914
  let hasStrictTools = false;
11906
- for (const tool4 of tools) {
11907
- switch (tool4.type) {
11915
+ for (const tool5 of tools) {
11916
+ switch (tool5.type) {
11908
11917
  case "function":
11909
11918
  functionDeclarations.push({
11910
- name: tool4.name,
11911
- description: (_b20 = tool4.description) != null ? _b20 : "",
11912
- parameters: convertJSONSchemaToOpenAPISchema(tool4.inputSchema)
11919
+ name: tool5.name,
11920
+ description: (_b20 = tool5.description) != null ? _b20 : "",
11921
+ parameters: convertJSONSchemaToOpenAPISchema(tool5.inputSchema)
11913
11922
  });
11914
- if (tool4.strict === true) {
11923
+ if (tool5.strict === true) {
11915
11924
  hasStrictTools = true;
11916
11925
  }
11917
11926
  break;
11918
11927
  default:
11919
11928
  toolWarnings.push({
11920
11929
  type: "unsupported",
11921
- feature: `function tool ${tool4.name}`
11930
+ feature: `function tool ${tool5.name}`
11922
11931
  });
11923
11932
  break;
11924
11933
  }
@@ -12261,7 +12270,7 @@ var GoogleGenerativeAILanguageModel = class {
12261
12270
  }
12262
12271
  const isVertexProvider = this.config.provider.startsWith("google.vertex.");
12263
12272
  if ((tools == null ? void 0 : tools.some(
12264
- (tool4) => tool4.type === "provider" && tool4.id === "google.vertex_rag_store"
12273
+ (tool5) => tool5.type === "provider" && tool5.id === "google.vertex_rag_store"
12265
12274
  )) && !isVertexProvider) {
12266
12275
  warnings.push({
12267
12276
  type: "other",
@@ -16994,23 +17003,23 @@ function prepareChatTools({
16994
17003
  return { tools: void 0, toolChoice: void 0, toolWarnings };
16995
17004
  }
16996
17005
  const openaiTools2 = [];
16997
- for (const tool4 of tools) {
16998
- switch (tool4.type) {
17006
+ for (const tool5 of tools) {
17007
+ switch (tool5.type) {
16999
17008
  case "function":
17000
17009
  openaiTools2.push({
17001
17010
  type: "function",
17002
17011
  function: {
17003
- name: tool4.name,
17004
- description: tool4.description,
17005
- parameters: tool4.inputSchema,
17006
- ...tool4.strict != null ? { strict: tool4.strict } : {}
17012
+ name: tool5.name,
17013
+ description: tool5.description,
17014
+ parameters: tool5.inputSchema,
17015
+ ...tool5.strict != null ? { strict: tool5.strict } : {}
17007
17016
  }
17008
17017
  });
17009
17018
  break;
17010
17019
  default:
17011
17020
  toolWarnings.push({
17012
17021
  type: "unsupported",
17013
- feature: `tool type: ${tool4.type}`
17022
+ feature: `tool type: ${tool5.type}`
17014
17023
  });
17015
17024
  break;
17016
17025
  }
@@ -20721,26 +20730,26 @@ async function prepareResponsesTools({
20721
20730
  }
20722
20731
  const openaiTools2 = [];
20723
20732
  const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
20724
- for (const tool4 of tools) {
20725
- switch (tool4.type) {
20733
+ for (const tool5 of tools) {
20734
+ switch (tool5.type) {
20726
20735
  case "function": {
20727
- const openaiOptions = (_a20 = tool4.providerOptions) == null ? void 0 : _a20.openai;
20736
+ const openaiOptions = (_a20 = tool5.providerOptions) == null ? void 0 : _a20.openai;
20728
20737
  const deferLoading = openaiOptions == null ? void 0 : openaiOptions.deferLoading;
20729
20738
  openaiTools2.push({
20730
20739
  type: "function",
20731
- name: tool4.name,
20732
- description: tool4.description,
20733
- parameters: tool4.inputSchema,
20734
- ...tool4.strict != null ? { strict: tool4.strict } : {},
20740
+ name: tool5.name,
20741
+ description: tool5.description,
20742
+ parameters: tool5.inputSchema,
20743
+ ...tool5.strict != null ? { strict: tool5.strict } : {},
20735
20744
  ...deferLoading != null ? { defer_loading: deferLoading } : {}
20736
20745
  });
20737
20746
  break;
20738
20747
  }
20739
20748
  case "provider": {
20740
- switch (tool4.id) {
20749
+ switch (tool5.id) {
20741
20750
  case "openai.file_search": {
20742
20751
  const args = await validateTypes3({
20743
- value: tool4.args,
20752
+ value: tool5.args,
20744
20753
  schema: fileSearchArgsSchema2
20745
20754
  });
20746
20755
  openaiTools2.push({
@@ -20763,7 +20772,7 @@ async function prepareResponsesTools({
20763
20772
  }
20764
20773
  case "openai.shell": {
20765
20774
  const args = await validateTypes3({
20766
- value: tool4.args,
20775
+ value: tool5.args,
20767
20776
  schema: shellArgsSchema
20768
20777
  });
20769
20778
  openaiTools2.push({
@@ -20782,7 +20791,7 @@ async function prepareResponsesTools({
20782
20791
  }
20783
20792
  case "openai.web_search_preview": {
20784
20793
  const args = await validateTypes3({
20785
- value: tool4.args,
20794
+ value: tool5.args,
20786
20795
  schema: webSearchPreviewArgsSchema
20787
20796
  });
20788
20797
  openaiTools2.push({
@@ -20794,7 +20803,7 @@ async function prepareResponsesTools({
20794
20803
  }
20795
20804
  case "openai.web_search": {
20796
20805
  const args = await validateTypes3({
20797
- value: tool4.args,
20806
+ value: tool5.args,
20798
20807
  schema: webSearchArgsSchema
20799
20808
  });
20800
20809
  openaiTools2.push({
@@ -20808,7 +20817,7 @@ async function prepareResponsesTools({
20808
20817
  }
20809
20818
  case "openai.code_interpreter": {
20810
20819
  const args = await validateTypes3({
20811
- value: tool4.args,
20820
+ value: tool5.args,
20812
20821
  schema: codeInterpreterArgsSchema
20813
20822
  });
20814
20823
  openaiTools2.push({
@@ -20819,7 +20828,7 @@ async function prepareResponsesTools({
20819
20828
  }
20820
20829
  case "openai.image_generation": {
20821
20830
  const args = await validateTypes3({
20822
- value: tool4.args,
20831
+ value: tool5.args,
20823
20832
  schema: imageGenerationArgsSchema
20824
20833
  });
20825
20834
  openaiTools2.push({
@@ -20842,7 +20851,7 @@ async function prepareResponsesTools({
20842
20851
  }
20843
20852
  case "openai.mcp": {
20844
20853
  const args = await validateTypes3({
20845
- value: tool4.args,
20854
+ value: tool5.args,
20846
20855
  schema: mcpArgsSchema
20847
20856
  });
20848
20857
  const mapApprovalFilter = (filter4) => ({
@@ -20868,7 +20877,7 @@ async function prepareResponsesTools({
20868
20877
  }
20869
20878
  case "openai.custom": {
20870
20879
  const args = await validateTypes3({
20871
- value: tool4.args,
20880
+ value: tool5.args,
20872
20881
  schema: customArgsSchema
20873
20882
  });
20874
20883
  openaiTools2.push({
@@ -20882,7 +20891,7 @@ async function prepareResponsesTools({
20882
20891
  }
20883
20892
  case "openai.tool_search": {
20884
20893
  const args = await validateTypes3({
20885
- value: tool4.args,
20894
+ value: tool5.args,
20886
20895
  schema: toolSearchArgsSchema
20887
20896
  });
20888
20897
  openaiTools2.push({
@@ -20899,7 +20908,7 @@ async function prepareResponsesTools({
20899
20908
  default:
20900
20909
  toolWarnings.push({
20901
20910
  type: "unsupported",
20902
- feature: `function tool ${tool4}`
20911
+ feature: `function tool ${tool5}`
20903
20912
  });
20904
20913
  break;
20905
20914
  }
@@ -21071,7 +21080,7 @@ var OpenAIResponsesLanguageModel = class {
21071
21080
  "openai.apply_patch": "apply_patch",
21072
21081
  "openai.tool_search": "tool_search"
21073
21082
  },
21074
- resolveProviderToolName: (tool4) => tool4.id === "openai.custom" ? tool4.args.name : void 0
21083
+ resolveProviderToolName: (tool5) => tool5.id === "openai.custom" ? tool5.args.name : void 0
21075
21084
  });
21076
21085
  const customProviderToolNames = /* @__PURE__ */ new Set();
21077
21086
  const {
@@ -21108,14 +21117,14 @@ var OpenAIResponsesLanguageModel = class {
21108
21117
  }
21109
21118
  }
21110
21119
  function hasOpenAITool(id) {
21111
- return (tools == null ? void 0 : tools.find((tool4) => tool4.type === "provider" && tool4.id === id)) != null;
21120
+ return (tools == null ? void 0 : tools.find((tool5) => tool5.type === "provider" && tool5.id === id)) != null;
21112
21121
  }
21113
21122
  const topLogprobs = typeof (openaiOptions == null ? void 0 : openaiOptions.logprobs) === "number" ? openaiOptions == null ? void 0 : openaiOptions.logprobs : (openaiOptions == null ? void 0 : openaiOptions.logprobs) === true ? TOP_LOGPROBS_MAX : void 0;
21114
21123
  if (topLogprobs) {
21115
21124
  addInclude("message.output_text.logprobs");
21116
21125
  }
21117
21126
  const webSearchToolName = (_e = tools == null ? void 0 : tools.find(
21118
- (tool4) => tool4.type === "provider" && (tool4.id === "openai.web_search" || tool4.id === "openai.web_search_preview")
21127
+ (tool5) => tool5.type === "provider" && (tool5.id === "openai.web_search" || tool5.id === "openai.web_search_preview")
21119
21128
  )) == null ? void 0 : _e.name;
21120
21129
  if (webSearchToolName) {
21121
21130
  addInclude("web_search_call.action.sources");
@@ -21229,7 +21238,7 @@ var OpenAIResponsesLanguageModel = class {
21229
21238
  delete baseArgs.service_tier;
21230
21239
  }
21231
21240
  const shellToolEnvType = (_i = (_h = (_g = tools == null ? void 0 : tools.find(
21232
- (tool4) => tool4.type === "provider" && tool4.id === "openai.shell"
21241
+ (tool5) => tool5.type === "provider" && tool5.id === "openai.shell"
21233
21242
  )) == null ? void 0 : _g.args) == null ? void 0 : _h.environment) == null ? void 0 : _i.type;
21234
21243
  const isShellProviderExecuted = shellToolEnvType === "containerAuto" || shellToolEnvType === "containerReference";
21235
21244
  return {
@@ -23895,8 +23904,211 @@ var OUTRO = `
23895
23904
  Please write all the necessary code to fully implement the feature end-to-end. Do not make mock data or example placeholders!!!
23896
23905
  `;
23897
23906
 
23907
+ // src/search.ts
23908
+ var import_ai2 = require("ai");
23909
+ var import_zod = require("zod");
23910
+ var WEB_SEARCH_TOOL_NAME = "web_search";
23911
+ var EXA_SEARCH_URL = "https://api.exa.ai/search";
23912
+ var DEFAULT_MAX_USES = 3;
23913
+ var DEFAULT_NUM_RESULTS = 5;
23914
+ var DEFAULT_MAX_CHARACTERS = 4e3;
23915
+ function getSearchApiKey() {
23916
+ return normalizeApiKey(process.env.EXA_API_KEY);
23917
+ }
23918
+ function hasSearchApiKey() {
23919
+ return !!getSearchApiKey();
23920
+ }
23921
+ function resolveSearchBackend(provider) {
23922
+ return provider === "anthropic" ? "anthropic" : "exa";
23923
+ }
23924
+ async function searchWeb(query, opts = {}) {
23925
+ const apiKey = normalizeApiKey(opts.apiKey) || getSearchApiKey();
23926
+ if (!apiKey) throw new Error("EXA_API_KEY not configured");
23927
+ const res = await fetch(EXA_SEARCH_URL, {
23928
+ method: "POST",
23929
+ headers: { "content-type": "application/json", "x-api-key": apiKey },
23930
+ signal: opts.abortSignal,
23931
+ body: JSON.stringify({
23932
+ query,
23933
+ type: "auto",
23934
+ numResults: opts.numResults ?? DEFAULT_NUM_RESULTS,
23935
+ contents: {
23936
+ text: { maxCharacters: opts.maxCharacters ?? DEFAULT_MAX_CHARACTERS }
23937
+ },
23938
+ ...opts.allowedDomains?.length ? { includeDomains: opts.allowedDomains } : {},
23939
+ ...opts.blockedDomains?.length ? { excludeDomains: opts.blockedDomains } : {}
23940
+ })
23941
+ });
23942
+ if (!res.ok) {
23943
+ const body = await res.text().catch(() => "");
23944
+ throw new Error(`Exa search failed (${res.status}): ${body.slice(0, 300)}`);
23945
+ }
23946
+ const json = await res.json();
23947
+ const results = Array.isArray(json.results) ? json.results : [];
23948
+ return results.filter((r) => typeof r.url === "string").map((r) => ({
23949
+ url: r.url,
23950
+ title: r.title ?? null,
23951
+ pageAge: r.publishedDate ?? null,
23952
+ ...r.text ? { text: r.text } : {},
23953
+ type: "web_search_result"
23954
+ }));
23955
+ }
23956
+ function citationSnippet(backend) {
23957
+ const indexRule = backend === "exa" ? "Every result carries an `index` field. Use that number exactly as returned \u2014 never invent or renumber one. Indices are global across all searches in this conversation." : "Use the index Anthropic assigns to the search result you are citing.";
23958
+ return `
23959
+
23960
+ ## Citing web search results
23961
+ When you use information from a \`${WEB_SEARCH_TOOL_NAME}\` result, cite it inline as \`<cite index="N">anchor text</cite>\`. ${indexRule}
23962
+
23963
+ The anchor text is REQUIRED and becomes the link text \u2014 put the words being sourced inside the tag, e.g. \`<cite index="3">runs on the Lightning Network</cite>\`. Never emit an empty tag like \`<cite index="3"></cite>\`; a trailing marker with no anchor produces a broken link.
23964
+
23965
+ Do NOT name sources parenthetically (e.g. \`(Bitcoin Magazine)\`) or as bare URLs \u2014 observed models fall back to that style and it produces no link. Every source reference must be a cite tag.`;
23966
+ }
23967
+ function createWebSearch(opts) {
23968
+ const results = [];
23969
+ const backend = opts.backend ?? resolveSearchBackend(opts.provider);
23970
+ const maxUses = opts.maxUses ?? DEFAULT_MAX_USES;
23971
+ if (backend === "anthropic") {
23972
+ const apiKey = normalizeApiKey(opts.apiKey) || normalizeApiKey(process.env.ANTHROPIC_API_KEY);
23973
+ if (!apiKey) {
23974
+ return emptyHandle(results);
23975
+ }
23976
+ const baseURL = getGatewayBaseURL("anthropic");
23977
+ const anthropic2 = createAnthropic({ apiKey, ...baseURL && { baseURL } });
23978
+ return {
23979
+ tool: anthropic2.tools.webSearch_20250305({
23980
+ maxUses,
23981
+ ...opts.allowedDomains?.length ? { allowedDomains: opts.allowedDomains } : {},
23982
+ ...opts.blockedDomains?.length ? { blockedDomains: opts.blockedDomains } : {}
23983
+ }),
23984
+ backend,
23985
+ native: true,
23986
+ results,
23987
+ capture: (stepContent) => captureNativeResults(stepContent, results),
23988
+ promptSnippet: opts.citations ? citationSnippet("anthropic") : "",
23989
+ formatOutput: (markdown) => formatOutput(markdown, results, !!opts.citations)
23990
+ };
23991
+ }
23992
+ const searchApiKey = normalizeApiKey(opts.searchApiKey) || getSearchApiKey();
23993
+ if (!searchApiKey) {
23994
+ return emptyHandle(results);
23995
+ }
23996
+ let uses = 0;
23997
+ return {
23998
+ tool: (0, import_ai2.tool)({
23999
+ description: "Search the web for current information. Returns numbered results with page text. Prefer one specific query per call over broad multi-topic queries.",
24000
+ inputSchema: import_zod.z.object({
24001
+ query: import_zod.z.string().describe("The search query."),
24002
+ num_results: import_zod.z.number().int().min(1).max(10).optional().describe("How many results to return. Default 5.")
24003
+ }),
24004
+ execute: async ({
24005
+ query,
24006
+ num_results
24007
+ }) => {
24008
+ if (uses >= maxUses) {
24009
+ return {
24010
+ error: `web_search budget exhausted (${maxUses} calls). Answer with what you have.`
24011
+ };
24012
+ }
24013
+ uses++;
24014
+ try {
24015
+ const hits = await searchWeb(query, {
24016
+ numResults: num_results ?? opts.numResults,
24017
+ maxCharacters: opts.maxCharacters,
24018
+ allowedDomains: opts.allowedDomains,
24019
+ blockedDomains: opts.blockedDomains,
24020
+ apiKey: searchApiKey,
24021
+ abortSignal: opts.abortSignal
24022
+ });
24023
+ return hits.map((hit) => {
24024
+ const indexed = { ...hit, index: results.length + 1 };
24025
+ results.push(indexed);
24026
+ return indexed;
24027
+ });
24028
+ } catch (err) {
24029
+ return {
24030
+ error: `Search failed: ${err instanceof Error ? err.message : String(err)}`
24031
+ };
24032
+ }
24033
+ }
24034
+ }),
24035
+ backend,
24036
+ native: false,
24037
+ results,
24038
+ // Exa results are appended by `execute` above; walking the step
24039
+ // would double-count them.
24040
+ capture: () => {
24041
+ },
24042
+ promptSnippet: opts.citations ? citationSnippet("exa") : "",
24043
+ formatOutput: (markdown) => formatOutput(markdown, results, !!opts.citations)
24044
+ };
24045
+ }
24046
+ function emptyHandle(results) {
24047
+ return {
24048
+ tool: void 0,
24049
+ backend: void 0,
24050
+ native: false,
24051
+ results,
24052
+ capture: () => {
24053
+ },
24054
+ promptSnippet: "",
24055
+ formatOutput: (markdown) => formatOutput(markdown, results, false)
24056
+ };
24057
+ }
24058
+ function formatOutput(markdown, results, citations) {
24059
+ return citations ? linkifyCitations(markdown, results) : { content: stripCitations(markdown), converted: 0, skipped: 0 };
24060
+ }
24061
+ function captureNativeResults(stepContent, target) {
24062
+ if (!Array.isArray(stepContent)) return;
24063
+ for (const content of stepContent) {
24064
+ if (content?.type !== "tool-result") continue;
24065
+ if (content?.toolName !== WEB_SEARCH_TOOL_NAME) continue;
24066
+ const body = content.output ?? content.result ?? null;
24067
+ if (!Array.isArray(body)) continue;
24068
+ for (const r of body) {
24069
+ if (r && typeof r === "object" && typeof r.url === "string") {
24070
+ target.push({
24071
+ url: r.url,
24072
+ title: r.title ?? null,
24073
+ pageAge: r.pageAge ?? null,
24074
+ // Assigned here too, so `results` is shape-identical to the
24075
+ // Exa path. Anthropic's model derives its own indices from
24076
+ // the same ordering, so these agree by construction.
24077
+ index: target.length + 1,
24078
+ type: "web_search_result"
24079
+ });
24080
+ }
24081
+ }
24082
+ }
24083
+ }
24084
+ function stripCitations(markdown) {
24085
+ return markdown.replace(/[ \t]*<cite\b[^>]*>\s*<\/cite>/g, "").replace(/<cite\b[^>]*>(.*?)<\/cite>/g, "$1").replace(/<\/?cite\b[^>]*>/g, "");
24086
+ }
24087
+ function linkifyCitations(markdown, results) {
24088
+ let converted = 0;
24089
+ let skipped = 0;
24090
+ const content = markdown.replace(
24091
+ /<cite index="(\d+)(?:-\d+(?:,\d+-\d+)*)?">(.*?)<\/cite>/g,
24092
+ (_match, indexStr, anchor) => {
24093
+ const index = parseInt(indexStr, 10);
24094
+ const hit = results[index - 1];
24095
+ if (!hit || typeof hit.url !== "string") {
24096
+ skipped++;
24097
+ return anchor;
24098
+ }
24099
+ converted++;
24100
+ const text = anchor.trim() ? anchor.replace(/\]/g, "\\]") : `[${index}]`;
24101
+ return `[${text}](${hit.url})`;
24102
+ }
24103
+ );
24104
+ return { content, converted, skipped };
24105
+ }
24106
+
23898
24107
  // src/tools.ts
23899
24108
  function getProviderTool(provider, apiKey, toolName) {
24109
+ if (toolName === "webSearch") {
24110
+ return createWebSearch({ provider, apiKey }).tool;
24111
+ }
23900
24112
  switch (provider) {
23901
24113
  case "anthropic":
23902
24114
  return getAnthropicTool(apiKey, toolName);
@@ -23953,12 +24165,15 @@ function consoleLogger(name19) {
23953
24165
  OUTRO,
23954
24166
  PROVIDERS,
23955
24167
  SYSTEM,
24168
+ WEB_SEARCH_TOOL_NAME,
23956
24169
  addUsage,
23957
24170
  callGenerateObject,
23958
24171
  callGenerateText,
23959
24172
  callModel,
24173
+ captureNativeResults,
23960
24174
  computeSessionCost,
23961
24175
  consoleLogger,
24176
+ createWebSearch,
23962
24177
  emptyUsage,
23963
24178
  gatewayEnvForProviders,
23964
24179
  gatewayUrlFor,
@@ -23972,13 +24187,19 @@ function consoleLogger(name19) {
23972
24187
  getProviderForModel,
23973
24188
  getProviderOptions,
23974
24189
  getProviderTool,
24190
+ getSearchApiKey,
23975
24191
  getTokenPricing,
23976
24192
  hasApiKeyForProvider,
24193
+ hasSearchApiKey,
24194
+ linkifyCitations,
23977
24195
  loadModelPricing,
23978
24196
  normalizeApiKey,
23979
24197
  normalizeCallerBaseURL,
23980
24198
  normalizeUsage,
23981
24199
  resolveLLMConfig,
24200
+ resolveSearchBackend,
24201
+ searchWeb,
24202
+ stripCitations,
23982
24203
  withLegacyUsage,
23983
24204
  withProviderCacheUsage
23984
24205
  });