aieo 0.1.35 → 0.1.37
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 +725 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +416 -2
- package/dist/index.d.ts +416 -2
- package/dist/index.js +708 -95
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -36,13 +36,20 @@ __export(index_exports, {
|
|
|
36
36
|
OUTRO: () => OUTRO,
|
|
37
37
|
PROVIDERS: () => PROVIDERS,
|
|
38
38
|
SYSTEM: () => SYSTEM,
|
|
39
|
+
WEB_FETCH_TOOL_NAME: () => WEB_FETCH_TOOL_NAME,
|
|
40
|
+
WEB_SEARCH_TOOL_NAME: () => WEB_SEARCH_TOOL_NAME,
|
|
39
41
|
addUsage: () => addUsage,
|
|
40
42
|
callGenerateObject: () => callGenerateObject,
|
|
41
43
|
callGenerateText: () => callGenerateText,
|
|
42
44
|
callModel: () => callModel,
|
|
45
|
+
captureNativeFetchResults: () => captureNativeFetchResults,
|
|
46
|
+
captureNativeResults: () => captureNativeResults,
|
|
43
47
|
computeSessionCost: () => computeSessionCost,
|
|
44
48
|
consoleLogger: () => consoleLogger,
|
|
49
|
+
createWebFetch: () => createWebFetch,
|
|
50
|
+
createWebSearch: () => createWebSearch,
|
|
45
51
|
emptyUsage: () => emptyUsage,
|
|
52
|
+
fetchUrl: () => fetchUrl,
|
|
46
53
|
gatewayEnvForProviders: () => gatewayEnvForProviders,
|
|
47
54
|
gatewayUrlFor: () => gatewayUrlFor,
|
|
48
55
|
gatewayUrlForModel: () => gatewayUrlForModel,
|
|
@@ -55,13 +62,23 @@ __export(index_exports, {
|
|
|
55
62
|
getProviderForModel: () => getProviderForModel,
|
|
56
63
|
getProviderOptions: () => getProviderOptions,
|
|
57
64
|
getProviderTool: () => getProviderTool,
|
|
65
|
+
getSearchApiKey: () => getSearchApiKey,
|
|
58
66
|
getTokenPricing: () => getTokenPricing,
|
|
59
67
|
hasApiKeyForProvider: () => hasApiKeyForProvider,
|
|
68
|
+
hasSearchApiKey: () => hasSearchApiKey,
|
|
69
|
+
htmlToText: () => htmlToText,
|
|
70
|
+
isPrivateAddress: () => isPrivateAddress,
|
|
71
|
+
linkifyCitations: () => linkifyCitations,
|
|
60
72
|
loadModelPricing: () => loadModelPricing,
|
|
61
73
|
normalizeApiKey: () => normalizeApiKey,
|
|
62
74
|
normalizeCallerBaseURL: () => normalizeCallerBaseURL,
|
|
63
75
|
normalizeUsage: () => normalizeUsage,
|
|
76
|
+
resolveFetchBackend: () => resolveFetchBackend,
|
|
64
77
|
resolveLLMConfig: () => resolveLLMConfig,
|
|
78
|
+
resolveSearchBackend: () => resolveSearchBackend,
|
|
79
|
+
searchWeb: () => searchWeb,
|
|
80
|
+
stripCitations: () => stripCitations,
|
|
81
|
+
validateFetchUrl: () => validateFetchUrl,
|
|
65
82
|
withLegacyUsage: () => withLegacyUsage,
|
|
66
83
|
withProviderCacheUsage: () => withProviderCacheUsage
|
|
67
84
|
});
|
|
@@ -4181,35 +4198,35 @@ async function prepareTools({
|
|
|
4181
4198
|
return { tools: void 0, toolChoice: void 0, toolWarnings, betas };
|
|
4182
4199
|
}
|
|
4183
4200
|
const anthropicTools2 = [];
|
|
4184
|
-
for (const
|
|
4185
|
-
switch (
|
|
4201
|
+
for (const tool6 of tools) {
|
|
4202
|
+
switch (tool6.type) {
|
|
4186
4203
|
case "function": {
|
|
4187
|
-
const cacheControl = validator.getCacheControl(
|
|
4204
|
+
const cacheControl = validator.getCacheControl(tool6.providerOptions, {
|
|
4188
4205
|
type: "tool definition",
|
|
4189
4206
|
canCache: true
|
|
4190
4207
|
});
|
|
4191
|
-
const anthropicOptions = (_a20 =
|
|
4208
|
+
const anthropicOptions = (_a20 = tool6.providerOptions) == null ? void 0 : _a20.anthropic;
|
|
4192
4209
|
const eagerInputStreaming = (_b20 = anthropicOptions == null ? void 0 : anthropicOptions.eagerInputStreaming) != null ? _b20 : defaultEagerInputStreaming;
|
|
4193
4210
|
const deferLoading = anthropicOptions == null ? void 0 : anthropicOptions.deferLoading;
|
|
4194
4211
|
const allowedCallers = anthropicOptions == null ? void 0 : anthropicOptions.allowedCallers;
|
|
4195
|
-
if (!supportsStrictTools &&
|
|
4212
|
+
if (!supportsStrictTools && tool6.strict != null) {
|
|
4196
4213
|
toolWarnings.push({
|
|
4197
4214
|
type: "unsupported",
|
|
4198
4215
|
feature: "strict",
|
|
4199
|
-
details: `Tool '${
|
|
4216
|
+
details: `Tool '${tool6.name}' has strict: ${tool6.strict}, but strict mode is not supported by this provider. The strict property will be ignored.`
|
|
4200
4217
|
});
|
|
4201
4218
|
}
|
|
4202
4219
|
anthropicTools2.push({
|
|
4203
|
-
name:
|
|
4204
|
-
description:
|
|
4205
|
-
input_schema:
|
|
4220
|
+
name: tool6.name,
|
|
4221
|
+
description: tool6.description,
|
|
4222
|
+
input_schema: tool6.inputSchema,
|
|
4206
4223
|
cache_control: cacheControl,
|
|
4207
4224
|
...eagerInputStreaming ? { eager_input_streaming: true } : {},
|
|
4208
|
-
...supportsStrictTools === true &&
|
|
4225
|
+
...supportsStrictTools === true && tool6.strict != null ? { strict: tool6.strict } : {},
|
|
4209
4226
|
...deferLoading != null ? { defer_loading: deferLoading } : {},
|
|
4210
4227
|
...allowedCallers != null ? { allowed_callers: allowedCallers } : {},
|
|
4211
|
-
...
|
|
4212
|
-
input_examples:
|
|
4228
|
+
...tool6.inputExamples != null ? {
|
|
4229
|
+
input_examples: tool6.inputExamples.map(
|
|
4213
4230
|
(example) => example.input
|
|
4214
4231
|
)
|
|
4215
4232
|
} : {}
|
|
@@ -4217,13 +4234,13 @@ async function prepareTools({
|
|
|
4217
4234
|
if (supportsStructuredOutput === true) {
|
|
4218
4235
|
betas.add("structured-outputs-2025-11-13");
|
|
4219
4236
|
}
|
|
4220
|
-
if (
|
|
4237
|
+
if (tool6.inputExamples != null || allowedCallers != null) {
|
|
4221
4238
|
betas.add("advanced-tool-use-2025-11-20");
|
|
4222
4239
|
}
|
|
4223
4240
|
break;
|
|
4224
4241
|
}
|
|
4225
4242
|
case "provider": {
|
|
4226
|
-
switch (
|
|
4243
|
+
switch (tool6.id) {
|
|
4227
4244
|
case "anthropic.code_execution_20250522": {
|
|
4228
4245
|
betas.add("code-execution-2025-05-22");
|
|
4229
4246
|
anthropicTools2.push({
|
|
@@ -4253,9 +4270,9 @@ async function prepareTools({
|
|
|
4253
4270
|
anthropicTools2.push({
|
|
4254
4271
|
name: "computer",
|
|
4255
4272
|
type: "computer_20250124",
|
|
4256
|
-
display_width_px:
|
|
4257
|
-
display_height_px:
|
|
4258
|
-
display_number:
|
|
4273
|
+
display_width_px: tool6.args.displayWidthPx,
|
|
4274
|
+
display_height_px: tool6.args.displayHeightPx,
|
|
4275
|
+
display_number: tool6.args.displayNumber,
|
|
4259
4276
|
cache_control: void 0
|
|
4260
4277
|
});
|
|
4261
4278
|
break;
|
|
@@ -4265,10 +4282,10 @@ async function prepareTools({
|
|
|
4265
4282
|
anthropicTools2.push({
|
|
4266
4283
|
name: "computer",
|
|
4267
4284
|
type: "computer_20251124",
|
|
4268
|
-
display_width_px:
|
|
4269
|
-
display_height_px:
|
|
4270
|
-
display_number:
|
|
4271
|
-
enable_zoom:
|
|
4285
|
+
display_width_px: tool6.args.displayWidthPx,
|
|
4286
|
+
display_height_px: tool6.args.displayHeightPx,
|
|
4287
|
+
display_number: tool6.args.displayNumber,
|
|
4288
|
+
enable_zoom: tool6.args.enableZoom,
|
|
4272
4289
|
cache_control: void 0
|
|
4273
4290
|
});
|
|
4274
4291
|
break;
|
|
@@ -4278,9 +4295,9 @@ async function prepareTools({
|
|
|
4278
4295
|
anthropicTools2.push({
|
|
4279
4296
|
name: "computer",
|
|
4280
4297
|
type: "computer_20241022",
|
|
4281
|
-
display_width_px:
|
|
4282
|
-
display_height_px:
|
|
4283
|
-
display_number:
|
|
4298
|
+
display_width_px: tool6.args.displayWidthPx,
|
|
4299
|
+
display_height_px: tool6.args.displayHeightPx,
|
|
4300
|
+
display_number: tool6.args.displayNumber,
|
|
4284
4301
|
cache_control: void 0
|
|
4285
4302
|
});
|
|
4286
4303
|
break;
|
|
@@ -4314,7 +4331,7 @@ async function prepareTools({
|
|
|
4314
4331
|
}
|
|
4315
4332
|
case "anthropic.text_editor_20250728": {
|
|
4316
4333
|
const args = await validateTypes({
|
|
4317
|
-
value:
|
|
4334
|
+
value: tool6.args,
|
|
4318
4335
|
schema: textEditor_20250728ArgsSchema
|
|
4319
4336
|
});
|
|
4320
4337
|
anthropicTools2.push({
|
|
@@ -4354,7 +4371,7 @@ async function prepareTools({
|
|
|
4354
4371
|
case "anthropic.web_fetch_20250910": {
|
|
4355
4372
|
betas.add("web-fetch-2025-09-10");
|
|
4356
4373
|
const args = await validateTypes({
|
|
4357
|
-
value:
|
|
4374
|
+
value: tool6.args,
|
|
4358
4375
|
schema: webFetch_20250910ArgsSchema
|
|
4359
4376
|
});
|
|
4360
4377
|
anthropicTools2.push({
|
|
@@ -4372,7 +4389,7 @@ async function prepareTools({
|
|
|
4372
4389
|
case "anthropic.web_fetch_20260209": {
|
|
4373
4390
|
betas.add("code-execution-web-tools-2026-02-09");
|
|
4374
4391
|
const args = await validateTypes({
|
|
4375
|
-
value:
|
|
4392
|
+
value: tool6.args,
|
|
4376
4393
|
schema: webFetch_20260209ArgsSchema
|
|
4377
4394
|
});
|
|
4378
4395
|
anthropicTools2.push({
|
|
@@ -4389,7 +4406,7 @@ async function prepareTools({
|
|
|
4389
4406
|
}
|
|
4390
4407
|
case "anthropic.web_search_20250305": {
|
|
4391
4408
|
const args = await validateTypes({
|
|
4392
|
-
value:
|
|
4409
|
+
value: tool6.args,
|
|
4393
4410
|
schema: webSearch_20250305ArgsSchema
|
|
4394
4411
|
});
|
|
4395
4412
|
anthropicTools2.push({
|
|
@@ -4406,7 +4423,7 @@ async function prepareTools({
|
|
|
4406
4423
|
case "anthropic.web_search_20260209": {
|
|
4407
4424
|
betas.add("code-execution-web-tools-2026-02-09");
|
|
4408
4425
|
const args = await validateTypes({
|
|
4409
|
-
value:
|
|
4426
|
+
value: tool6.args,
|
|
4410
4427
|
schema: webSearch_20260209ArgsSchema
|
|
4411
4428
|
});
|
|
4412
4429
|
anthropicTools2.push({
|
|
@@ -4437,7 +4454,7 @@ async function prepareTools({
|
|
|
4437
4454
|
case "anthropic.advisor_20260301": {
|
|
4438
4455
|
betas.add("advisor-tool-2026-03-01");
|
|
4439
4456
|
const args = await validateTypes({
|
|
4440
|
-
value:
|
|
4457
|
+
value: tool6.args,
|
|
4441
4458
|
schema: advisor_20260301ArgsSchema
|
|
4442
4459
|
});
|
|
4443
4460
|
anthropicTools2.push({
|
|
@@ -4452,7 +4469,7 @@ async function prepareTools({
|
|
|
4452
4469
|
default: {
|
|
4453
4470
|
toolWarnings.push({
|
|
4454
4471
|
type: "unsupported",
|
|
4455
|
-
feature: `provider-defined tool ${
|
|
4472
|
+
feature: `provider-defined tool ${tool6.id}`
|
|
4456
4473
|
});
|
|
4457
4474
|
break;
|
|
4458
4475
|
}
|
|
@@ -4462,7 +4479,7 @@ async function prepareTools({
|
|
|
4462
4479
|
default: {
|
|
4463
4480
|
toolWarnings.push({
|
|
4464
4481
|
type: "unsupported",
|
|
4465
|
-
feature: `tool ${
|
|
4482
|
+
feature: `tool ${tool6}`
|
|
4466
4483
|
});
|
|
4467
4484
|
break;
|
|
4468
4485
|
}
|
|
@@ -6432,7 +6449,7 @@ var AnthropicMessagesLanguageModel = class {
|
|
|
6432
6449
|
betas.add("skills-2025-10-02");
|
|
6433
6450
|
betas.add("files-api-2025-04-14");
|
|
6434
6451
|
if (!(tools == null ? void 0 : tools.some(
|
|
6435
|
-
(
|
|
6452
|
+
(tool6) => tool6.type === "provider" && (tool6.id === "anthropic.code_execution_20250825" || tool6.id === "anthropic.code_execution_20260120")
|
|
6436
6453
|
))) {
|
|
6437
6454
|
warnings.push({
|
|
6438
6455
|
type: "other",
|
|
@@ -8035,12 +8052,12 @@ function hasWebTool20260209WithoutCodeExecution(tools) {
|
|
|
8035
8052
|
}
|
|
8036
8053
|
let hasWebTool20260209 = false;
|
|
8037
8054
|
let hasCodeExecutionTool = false;
|
|
8038
|
-
for (const
|
|
8039
|
-
if ("type" in
|
|
8055
|
+
for (const tool6 of tools) {
|
|
8056
|
+
if ("type" in tool6 && (tool6.type === "web_fetch_20260209" || tool6.type === "web_search_20260209")) {
|
|
8040
8057
|
hasWebTool20260209 = true;
|
|
8041
8058
|
continue;
|
|
8042
8059
|
}
|
|
8043
|
-
if (
|
|
8060
|
+
if (tool6.name === "code_execution") {
|
|
8044
8061
|
hasCodeExecutionTool = true;
|
|
8045
8062
|
break;
|
|
8046
8063
|
}
|
|
@@ -11749,8 +11766,8 @@ function prepareTools2({
|
|
|
11749
11766
|
if (tools == null) {
|
|
11750
11767
|
return { tools: void 0, toolConfig: void 0, toolWarnings };
|
|
11751
11768
|
}
|
|
11752
|
-
const hasFunctionTools = tools.some((
|
|
11753
|
-
const hasProviderTools = tools.some((
|
|
11769
|
+
const hasFunctionTools = tools.some((tool6) => tool6.type === "function");
|
|
11770
|
+
const hasProviderTools = tools.some((tool6) => tool6.type === "provider");
|
|
11754
11771
|
if (hasFunctionTools && hasProviderTools && !isGemini3orNewer) {
|
|
11755
11772
|
toolWarnings.push({
|
|
11756
11773
|
type: "unsupported",
|
|
@@ -11759,16 +11776,16 @@ function prepareTools2({
|
|
|
11759
11776
|
}
|
|
11760
11777
|
if (hasProviderTools) {
|
|
11761
11778
|
const googleTools2 = [];
|
|
11762
|
-
const ProviderTools = tools.filter((
|
|
11763
|
-
ProviderTools.forEach((
|
|
11764
|
-
switch (
|
|
11779
|
+
const ProviderTools = tools.filter((tool6) => tool6.type === "provider");
|
|
11780
|
+
ProviderTools.forEach((tool6) => {
|
|
11781
|
+
switch (tool6.id) {
|
|
11765
11782
|
case "google.google_search":
|
|
11766
11783
|
if (isGemini2orNewer) {
|
|
11767
|
-
googleTools2.push({ googleSearch: { ...
|
|
11784
|
+
googleTools2.push({ googleSearch: { ...tool6.args } });
|
|
11768
11785
|
} else {
|
|
11769
11786
|
toolWarnings.push({
|
|
11770
11787
|
type: "unsupported",
|
|
11771
|
-
feature: `provider-defined tool ${
|
|
11788
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11772
11789
|
details: "Google Search requires Gemini 2.0 or newer."
|
|
11773
11790
|
});
|
|
11774
11791
|
}
|
|
@@ -11779,7 +11796,7 @@ function prepareTools2({
|
|
|
11779
11796
|
} else {
|
|
11780
11797
|
toolWarnings.push({
|
|
11781
11798
|
type: "unsupported",
|
|
11782
|
-
feature: `provider-defined tool ${
|
|
11799
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11783
11800
|
details: "Enterprise Web Search requires Gemini 2.0 or newer."
|
|
11784
11801
|
});
|
|
11785
11802
|
}
|
|
@@ -11790,7 +11807,7 @@ function prepareTools2({
|
|
|
11790
11807
|
} else {
|
|
11791
11808
|
toolWarnings.push({
|
|
11792
11809
|
type: "unsupported",
|
|
11793
|
-
feature: `provider-defined tool ${
|
|
11810
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11794
11811
|
details: "The URL context tool is not supported with other Gemini models than Gemini 2."
|
|
11795
11812
|
});
|
|
11796
11813
|
}
|
|
@@ -11801,18 +11818,18 @@ function prepareTools2({
|
|
|
11801
11818
|
} else {
|
|
11802
11819
|
toolWarnings.push({
|
|
11803
11820
|
type: "unsupported",
|
|
11804
|
-
feature: `provider-defined tool ${
|
|
11821
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11805
11822
|
details: "The code execution tool is not supported with other Gemini models than Gemini 2."
|
|
11806
11823
|
});
|
|
11807
11824
|
}
|
|
11808
11825
|
break;
|
|
11809
11826
|
case "google.file_search":
|
|
11810
11827
|
if (supportsFileSearch) {
|
|
11811
|
-
googleTools2.push({ fileSearch: { ...
|
|
11828
|
+
googleTools2.push({ fileSearch: { ...tool6.args } });
|
|
11812
11829
|
} else {
|
|
11813
11830
|
toolWarnings.push({
|
|
11814
11831
|
type: "unsupported",
|
|
11815
|
-
feature: `provider-defined tool ${
|
|
11832
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11816
11833
|
details: "The file search tool is only supported with Gemini 2.5 models and Gemini 3 models."
|
|
11817
11834
|
});
|
|
11818
11835
|
}
|
|
@@ -11823,16 +11840,16 @@ function prepareTools2({
|
|
|
11823
11840
|
retrieval: {
|
|
11824
11841
|
vertex_rag_store: {
|
|
11825
11842
|
rag_resources: {
|
|
11826
|
-
rag_corpus:
|
|
11843
|
+
rag_corpus: tool6.args.ragCorpus
|
|
11827
11844
|
},
|
|
11828
|
-
similarity_top_k:
|
|
11845
|
+
similarity_top_k: tool6.args.topK
|
|
11829
11846
|
}
|
|
11830
11847
|
}
|
|
11831
11848
|
});
|
|
11832
11849
|
} else {
|
|
11833
11850
|
toolWarnings.push({
|
|
11834
11851
|
type: "unsupported",
|
|
11835
|
-
feature: `provider-defined tool ${
|
|
11852
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11836
11853
|
details: "The RAG store tool is not supported with other Gemini models than Gemini 2."
|
|
11837
11854
|
});
|
|
11838
11855
|
}
|
|
@@ -11843,7 +11860,7 @@ function prepareTools2({
|
|
|
11843
11860
|
} else {
|
|
11844
11861
|
toolWarnings.push({
|
|
11845
11862
|
type: "unsupported",
|
|
11846
|
-
feature: `provider-defined tool ${
|
|
11863
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11847
11864
|
details: "The Google Maps grounding tool is not supported with Gemini models other than Gemini 2 or newer."
|
|
11848
11865
|
});
|
|
11849
11866
|
}
|
|
@@ -11851,19 +11868,19 @@ function prepareTools2({
|
|
|
11851
11868
|
default:
|
|
11852
11869
|
toolWarnings.push({
|
|
11853
11870
|
type: "unsupported",
|
|
11854
|
-
feature: `provider-defined tool ${
|
|
11871
|
+
feature: `provider-defined tool ${tool6.id}`
|
|
11855
11872
|
});
|
|
11856
11873
|
break;
|
|
11857
11874
|
}
|
|
11858
11875
|
});
|
|
11859
11876
|
if (hasFunctionTools && isGemini3orNewer && googleTools2.length > 0) {
|
|
11860
11877
|
const functionDeclarations2 = [];
|
|
11861
|
-
for (const
|
|
11862
|
-
if (
|
|
11878
|
+
for (const tool6 of tools) {
|
|
11879
|
+
if (tool6.type === "function") {
|
|
11863
11880
|
functionDeclarations2.push({
|
|
11864
|
-
name:
|
|
11865
|
-
description: (_a20 =
|
|
11866
|
-
parameters: convertJSONSchemaToOpenAPISchema(
|
|
11881
|
+
name: tool6.name,
|
|
11882
|
+
description: (_a20 = tool6.description) != null ? _a20 : "",
|
|
11883
|
+
parameters: convertJSONSchemaToOpenAPISchema(tool6.inputSchema)
|
|
11867
11884
|
});
|
|
11868
11885
|
}
|
|
11869
11886
|
}
|
|
@@ -11903,22 +11920,22 @@ function prepareTools2({
|
|
|
11903
11920
|
}
|
|
11904
11921
|
const functionDeclarations = [];
|
|
11905
11922
|
let hasStrictTools = false;
|
|
11906
|
-
for (const
|
|
11907
|
-
switch (
|
|
11923
|
+
for (const tool6 of tools) {
|
|
11924
|
+
switch (tool6.type) {
|
|
11908
11925
|
case "function":
|
|
11909
11926
|
functionDeclarations.push({
|
|
11910
|
-
name:
|
|
11911
|
-
description: (_b20 =
|
|
11912
|
-
parameters: convertJSONSchemaToOpenAPISchema(
|
|
11927
|
+
name: tool6.name,
|
|
11928
|
+
description: (_b20 = tool6.description) != null ? _b20 : "",
|
|
11929
|
+
parameters: convertJSONSchemaToOpenAPISchema(tool6.inputSchema)
|
|
11913
11930
|
});
|
|
11914
|
-
if (
|
|
11931
|
+
if (tool6.strict === true) {
|
|
11915
11932
|
hasStrictTools = true;
|
|
11916
11933
|
}
|
|
11917
11934
|
break;
|
|
11918
11935
|
default:
|
|
11919
11936
|
toolWarnings.push({
|
|
11920
11937
|
type: "unsupported",
|
|
11921
|
-
feature: `function tool ${
|
|
11938
|
+
feature: `function tool ${tool6.name}`
|
|
11922
11939
|
});
|
|
11923
11940
|
break;
|
|
11924
11941
|
}
|
|
@@ -12261,7 +12278,7 @@ var GoogleGenerativeAILanguageModel = class {
|
|
|
12261
12278
|
}
|
|
12262
12279
|
const isVertexProvider = this.config.provider.startsWith("google.vertex.");
|
|
12263
12280
|
if ((tools == null ? void 0 : tools.some(
|
|
12264
|
-
(
|
|
12281
|
+
(tool6) => tool6.type === "provider" && tool6.id === "google.vertex_rag_store"
|
|
12265
12282
|
)) && !isVertexProvider) {
|
|
12266
12283
|
warnings.push({
|
|
12267
12284
|
type: "other",
|
|
@@ -16994,23 +17011,23 @@ function prepareChatTools({
|
|
|
16994
17011
|
return { tools: void 0, toolChoice: void 0, toolWarnings };
|
|
16995
17012
|
}
|
|
16996
17013
|
const openaiTools2 = [];
|
|
16997
|
-
for (const
|
|
16998
|
-
switch (
|
|
17014
|
+
for (const tool6 of tools) {
|
|
17015
|
+
switch (tool6.type) {
|
|
16999
17016
|
case "function":
|
|
17000
17017
|
openaiTools2.push({
|
|
17001
17018
|
type: "function",
|
|
17002
17019
|
function: {
|
|
17003
|
-
name:
|
|
17004
|
-
description:
|
|
17005
|
-
parameters:
|
|
17006
|
-
...
|
|
17020
|
+
name: tool6.name,
|
|
17021
|
+
description: tool6.description,
|
|
17022
|
+
parameters: tool6.inputSchema,
|
|
17023
|
+
...tool6.strict != null ? { strict: tool6.strict } : {}
|
|
17007
17024
|
}
|
|
17008
17025
|
});
|
|
17009
17026
|
break;
|
|
17010
17027
|
default:
|
|
17011
17028
|
toolWarnings.push({
|
|
17012
17029
|
type: "unsupported",
|
|
17013
|
-
feature: `tool type: ${
|
|
17030
|
+
feature: `tool type: ${tool6.type}`
|
|
17014
17031
|
});
|
|
17015
17032
|
break;
|
|
17016
17033
|
}
|
|
@@ -20721,26 +20738,26 @@ async function prepareResponsesTools({
|
|
|
20721
20738
|
}
|
|
20722
20739
|
const openaiTools2 = [];
|
|
20723
20740
|
const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
|
|
20724
|
-
for (const
|
|
20725
|
-
switch (
|
|
20741
|
+
for (const tool6 of tools) {
|
|
20742
|
+
switch (tool6.type) {
|
|
20726
20743
|
case "function": {
|
|
20727
|
-
const openaiOptions = (_a20 =
|
|
20744
|
+
const openaiOptions = (_a20 = tool6.providerOptions) == null ? void 0 : _a20.openai;
|
|
20728
20745
|
const deferLoading = openaiOptions == null ? void 0 : openaiOptions.deferLoading;
|
|
20729
20746
|
openaiTools2.push({
|
|
20730
20747
|
type: "function",
|
|
20731
|
-
name:
|
|
20732
|
-
description:
|
|
20733
|
-
parameters:
|
|
20734
|
-
...
|
|
20748
|
+
name: tool6.name,
|
|
20749
|
+
description: tool6.description,
|
|
20750
|
+
parameters: tool6.inputSchema,
|
|
20751
|
+
...tool6.strict != null ? { strict: tool6.strict } : {},
|
|
20735
20752
|
...deferLoading != null ? { defer_loading: deferLoading } : {}
|
|
20736
20753
|
});
|
|
20737
20754
|
break;
|
|
20738
20755
|
}
|
|
20739
20756
|
case "provider": {
|
|
20740
|
-
switch (
|
|
20757
|
+
switch (tool6.id) {
|
|
20741
20758
|
case "openai.file_search": {
|
|
20742
20759
|
const args = await validateTypes3({
|
|
20743
|
-
value:
|
|
20760
|
+
value: tool6.args,
|
|
20744
20761
|
schema: fileSearchArgsSchema2
|
|
20745
20762
|
});
|
|
20746
20763
|
openaiTools2.push({
|
|
@@ -20763,7 +20780,7 @@ async function prepareResponsesTools({
|
|
|
20763
20780
|
}
|
|
20764
20781
|
case "openai.shell": {
|
|
20765
20782
|
const args = await validateTypes3({
|
|
20766
|
-
value:
|
|
20783
|
+
value: tool6.args,
|
|
20767
20784
|
schema: shellArgsSchema
|
|
20768
20785
|
});
|
|
20769
20786
|
openaiTools2.push({
|
|
@@ -20782,7 +20799,7 @@ async function prepareResponsesTools({
|
|
|
20782
20799
|
}
|
|
20783
20800
|
case "openai.web_search_preview": {
|
|
20784
20801
|
const args = await validateTypes3({
|
|
20785
|
-
value:
|
|
20802
|
+
value: tool6.args,
|
|
20786
20803
|
schema: webSearchPreviewArgsSchema
|
|
20787
20804
|
});
|
|
20788
20805
|
openaiTools2.push({
|
|
@@ -20794,7 +20811,7 @@ async function prepareResponsesTools({
|
|
|
20794
20811
|
}
|
|
20795
20812
|
case "openai.web_search": {
|
|
20796
20813
|
const args = await validateTypes3({
|
|
20797
|
-
value:
|
|
20814
|
+
value: tool6.args,
|
|
20798
20815
|
schema: webSearchArgsSchema
|
|
20799
20816
|
});
|
|
20800
20817
|
openaiTools2.push({
|
|
@@ -20808,7 +20825,7 @@ async function prepareResponsesTools({
|
|
|
20808
20825
|
}
|
|
20809
20826
|
case "openai.code_interpreter": {
|
|
20810
20827
|
const args = await validateTypes3({
|
|
20811
|
-
value:
|
|
20828
|
+
value: tool6.args,
|
|
20812
20829
|
schema: codeInterpreterArgsSchema
|
|
20813
20830
|
});
|
|
20814
20831
|
openaiTools2.push({
|
|
@@ -20819,7 +20836,7 @@ async function prepareResponsesTools({
|
|
|
20819
20836
|
}
|
|
20820
20837
|
case "openai.image_generation": {
|
|
20821
20838
|
const args = await validateTypes3({
|
|
20822
|
-
value:
|
|
20839
|
+
value: tool6.args,
|
|
20823
20840
|
schema: imageGenerationArgsSchema
|
|
20824
20841
|
});
|
|
20825
20842
|
openaiTools2.push({
|
|
@@ -20842,7 +20859,7 @@ async function prepareResponsesTools({
|
|
|
20842
20859
|
}
|
|
20843
20860
|
case "openai.mcp": {
|
|
20844
20861
|
const args = await validateTypes3({
|
|
20845
|
-
value:
|
|
20862
|
+
value: tool6.args,
|
|
20846
20863
|
schema: mcpArgsSchema
|
|
20847
20864
|
});
|
|
20848
20865
|
const mapApprovalFilter = (filter4) => ({
|
|
@@ -20868,7 +20885,7 @@ async function prepareResponsesTools({
|
|
|
20868
20885
|
}
|
|
20869
20886
|
case "openai.custom": {
|
|
20870
20887
|
const args = await validateTypes3({
|
|
20871
|
-
value:
|
|
20888
|
+
value: tool6.args,
|
|
20872
20889
|
schema: customArgsSchema
|
|
20873
20890
|
});
|
|
20874
20891
|
openaiTools2.push({
|
|
@@ -20882,7 +20899,7 @@ async function prepareResponsesTools({
|
|
|
20882
20899
|
}
|
|
20883
20900
|
case "openai.tool_search": {
|
|
20884
20901
|
const args = await validateTypes3({
|
|
20885
|
-
value:
|
|
20902
|
+
value: tool6.args,
|
|
20886
20903
|
schema: toolSearchArgsSchema
|
|
20887
20904
|
});
|
|
20888
20905
|
openaiTools2.push({
|
|
@@ -20899,7 +20916,7 @@ async function prepareResponsesTools({
|
|
|
20899
20916
|
default:
|
|
20900
20917
|
toolWarnings.push({
|
|
20901
20918
|
type: "unsupported",
|
|
20902
|
-
feature: `function tool ${
|
|
20919
|
+
feature: `function tool ${tool6}`
|
|
20903
20920
|
});
|
|
20904
20921
|
break;
|
|
20905
20922
|
}
|
|
@@ -21071,7 +21088,7 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
21071
21088
|
"openai.apply_patch": "apply_patch",
|
|
21072
21089
|
"openai.tool_search": "tool_search"
|
|
21073
21090
|
},
|
|
21074
|
-
resolveProviderToolName: (
|
|
21091
|
+
resolveProviderToolName: (tool6) => tool6.id === "openai.custom" ? tool6.args.name : void 0
|
|
21075
21092
|
});
|
|
21076
21093
|
const customProviderToolNames = /* @__PURE__ */ new Set();
|
|
21077
21094
|
const {
|
|
@@ -21108,14 +21125,14 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
21108
21125
|
}
|
|
21109
21126
|
}
|
|
21110
21127
|
function hasOpenAITool(id) {
|
|
21111
|
-
return (tools == null ? void 0 : tools.find((
|
|
21128
|
+
return (tools == null ? void 0 : tools.find((tool6) => tool6.type === "provider" && tool6.id === id)) != null;
|
|
21112
21129
|
}
|
|
21113
21130
|
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
21131
|
if (topLogprobs) {
|
|
21115
21132
|
addInclude("message.output_text.logprobs");
|
|
21116
21133
|
}
|
|
21117
21134
|
const webSearchToolName = (_e = tools == null ? void 0 : tools.find(
|
|
21118
|
-
(
|
|
21135
|
+
(tool6) => tool6.type === "provider" && (tool6.id === "openai.web_search" || tool6.id === "openai.web_search_preview")
|
|
21119
21136
|
)) == null ? void 0 : _e.name;
|
|
21120
21137
|
if (webSearchToolName) {
|
|
21121
21138
|
addInclude("web_search_call.action.sources");
|
|
@@ -21229,7 +21246,7 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
21229
21246
|
delete baseArgs.service_tier;
|
|
21230
21247
|
}
|
|
21231
21248
|
const shellToolEnvType = (_i = (_h = (_g = tools == null ? void 0 : tools.find(
|
|
21232
|
-
(
|
|
21249
|
+
(tool6) => tool6.type === "provider" && tool6.id === "openai.shell"
|
|
21233
21250
|
)) == null ? void 0 : _g.args) == null ? void 0 : _h.environment) == null ? void 0 : _i.type;
|
|
21234
21251
|
const isShellProviderExecuted = shellToolEnvType === "containerAuto" || shellToolEnvType === "containerReference";
|
|
21235
21252
|
return {
|
|
@@ -23895,8 +23912,604 @@ var OUTRO = `
|
|
|
23895
23912
|
Please write all the necessary code to fully implement the feature end-to-end. Do not make mock data or example placeholders!!!
|
|
23896
23913
|
`;
|
|
23897
23914
|
|
|
23915
|
+
// src/search.ts
|
|
23916
|
+
var import_ai2 = require("ai");
|
|
23917
|
+
var import_zod = require("zod");
|
|
23918
|
+
var WEB_SEARCH_TOOL_NAME = "web_search";
|
|
23919
|
+
var EXA_SEARCH_URL = "https://api.exa.ai/search";
|
|
23920
|
+
var DEFAULT_MAX_USES = 3;
|
|
23921
|
+
var DEFAULT_NUM_RESULTS = 5;
|
|
23922
|
+
var DEFAULT_MAX_CHARACTERS = 4e3;
|
|
23923
|
+
function getSearchApiKey() {
|
|
23924
|
+
return normalizeApiKey(process.env.EXA_API_KEY);
|
|
23925
|
+
}
|
|
23926
|
+
function hasSearchApiKey() {
|
|
23927
|
+
return !!getSearchApiKey();
|
|
23928
|
+
}
|
|
23929
|
+
function resolveSearchBackend(provider) {
|
|
23930
|
+
return provider === "anthropic" ? "anthropic" : "exa";
|
|
23931
|
+
}
|
|
23932
|
+
async function searchWeb(query, opts = {}) {
|
|
23933
|
+
const apiKey = normalizeApiKey(opts.apiKey) || getSearchApiKey();
|
|
23934
|
+
if (!apiKey) throw new Error("EXA_API_KEY not configured");
|
|
23935
|
+
const res = await fetch(EXA_SEARCH_URL, {
|
|
23936
|
+
method: "POST",
|
|
23937
|
+
headers: { "content-type": "application/json", "x-api-key": apiKey },
|
|
23938
|
+
signal: opts.abortSignal,
|
|
23939
|
+
body: JSON.stringify({
|
|
23940
|
+
query,
|
|
23941
|
+
type: "auto",
|
|
23942
|
+
numResults: opts.numResults ?? DEFAULT_NUM_RESULTS,
|
|
23943
|
+
contents: {
|
|
23944
|
+
text: { maxCharacters: opts.maxCharacters ?? DEFAULT_MAX_CHARACTERS }
|
|
23945
|
+
},
|
|
23946
|
+
...opts.allowedDomains?.length ? { includeDomains: opts.allowedDomains } : {},
|
|
23947
|
+
...opts.blockedDomains?.length ? { excludeDomains: opts.blockedDomains } : {}
|
|
23948
|
+
})
|
|
23949
|
+
});
|
|
23950
|
+
if (!res.ok) {
|
|
23951
|
+
const body = await res.text().catch(() => "");
|
|
23952
|
+
throw new Error(`Exa search failed (${res.status}): ${body.slice(0, 300)}`);
|
|
23953
|
+
}
|
|
23954
|
+
const json = await res.json();
|
|
23955
|
+
const results = Array.isArray(json.results) ? json.results : [];
|
|
23956
|
+
return results.filter((r) => typeof r.url === "string").map((r) => ({
|
|
23957
|
+
url: r.url,
|
|
23958
|
+
title: r.title ?? null,
|
|
23959
|
+
pageAge: r.publishedDate ?? null,
|
|
23960
|
+
...r.text ? { text: r.text } : {},
|
|
23961
|
+
type: "web_search_result"
|
|
23962
|
+
}));
|
|
23963
|
+
}
|
|
23964
|
+
function citationSnippet(backend) {
|
|
23965
|
+
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.";
|
|
23966
|
+
return `
|
|
23967
|
+
|
|
23968
|
+
## Citing web search results
|
|
23969
|
+
When you use information from a \`${WEB_SEARCH_TOOL_NAME}\` result, cite it inline as \`<cite index="N">anchor text</cite>\`. ${indexRule}
|
|
23970
|
+
|
|
23971
|
+
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.
|
|
23972
|
+
|
|
23973
|
+
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.`;
|
|
23974
|
+
}
|
|
23975
|
+
function createWebSearch(opts) {
|
|
23976
|
+
const results = [];
|
|
23977
|
+
const backend = opts.backend ?? resolveSearchBackend(opts.provider);
|
|
23978
|
+
const maxUses = opts.maxUses ?? DEFAULT_MAX_USES;
|
|
23979
|
+
if (backend === "anthropic") {
|
|
23980
|
+
const apiKey = normalizeApiKey(opts.apiKey) || normalizeApiKey(process.env.ANTHROPIC_API_KEY);
|
|
23981
|
+
if (!apiKey) {
|
|
23982
|
+
return emptyHandle(results);
|
|
23983
|
+
}
|
|
23984
|
+
const baseURL = getGatewayBaseURL("anthropic");
|
|
23985
|
+
const anthropic2 = createAnthropic({ apiKey, ...baseURL && { baseURL } });
|
|
23986
|
+
return {
|
|
23987
|
+
tool: anthropic2.tools.webSearch_20250305({
|
|
23988
|
+
maxUses,
|
|
23989
|
+
...opts.allowedDomains?.length ? { allowedDomains: opts.allowedDomains } : {},
|
|
23990
|
+
...opts.blockedDomains?.length ? { blockedDomains: opts.blockedDomains } : {}
|
|
23991
|
+
}),
|
|
23992
|
+
backend,
|
|
23993
|
+
native: true,
|
|
23994
|
+
results,
|
|
23995
|
+
capture: (stepContent) => captureNativeResults(stepContent, results),
|
|
23996
|
+
promptSnippet: opts.citations ? citationSnippet("anthropic") : "",
|
|
23997
|
+
formatOutput: (markdown) => formatOutput(markdown, results, !!opts.citations)
|
|
23998
|
+
};
|
|
23999
|
+
}
|
|
24000
|
+
const searchApiKey = normalizeApiKey(opts.searchApiKey) || getSearchApiKey();
|
|
24001
|
+
if (!searchApiKey) {
|
|
24002
|
+
return emptyHandle(results);
|
|
24003
|
+
}
|
|
24004
|
+
let uses = 0;
|
|
24005
|
+
return {
|
|
24006
|
+
tool: (0, import_ai2.tool)({
|
|
24007
|
+
description: "Search the web for current information. Returns numbered results with page text. Prefer one specific query per call over broad multi-topic queries.",
|
|
24008
|
+
inputSchema: import_zod.z.object({
|
|
24009
|
+
query: import_zod.z.string().describe("The search query."),
|
|
24010
|
+
num_results: import_zod.z.number().int().min(1).max(10).optional().describe("How many results to return. Default 5.")
|
|
24011
|
+
}),
|
|
24012
|
+
execute: async ({
|
|
24013
|
+
query,
|
|
24014
|
+
num_results
|
|
24015
|
+
}) => {
|
|
24016
|
+
if (uses >= maxUses) {
|
|
24017
|
+
return {
|
|
24018
|
+
error: `web_search budget exhausted (${maxUses} calls). Answer with what you have.`
|
|
24019
|
+
};
|
|
24020
|
+
}
|
|
24021
|
+
uses++;
|
|
24022
|
+
try {
|
|
24023
|
+
const hits = await searchWeb(query, {
|
|
24024
|
+
numResults: num_results ?? opts.numResults,
|
|
24025
|
+
maxCharacters: opts.maxCharacters,
|
|
24026
|
+
allowedDomains: opts.allowedDomains,
|
|
24027
|
+
blockedDomains: opts.blockedDomains,
|
|
24028
|
+
apiKey: searchApiKey,
|
|
24029
|
+
abortSignal: opts.abortSignal
|
|
24030
|
+
});
|
|
24031
|
+
return hits.map((hit) => {
|
|
24032
|
+
const indexed = { ...hit, index: results.length + 1 };
|
|
24033
|
+
results.push(indexed);
|
|
24034
|
+
return indexed;
|
|
24035
|
+
});
|
|
24036
|
+
} catch (err) {
|
|
24037
|
+
return {
|
|
24038
|
+
error: `Search failed: ${err instanceof Error ? err.message : String(err)}`
|
|
24039
|
+
};
|
|
24040
|
+
}
|
|
24041
|
+
}
|
|
24042
|
+
}),
|
|
24043
|
+
backend,
|
|
24044
|
+
native: false,
|
|
24045
|
+
results,
|
|
24046
|
+
// Exa results are appended by `execute` above; walking the step
|
|
24047
|
+
// would double-count them.
|
|
24048
|
+
capture: () => {
|
|
24049
|
+
},
|
|
24050
|
+
promptSnippet: opts.citations ? citationSnippet("exa") : "",
|
|
24051
|
+
formatOutput: (markdown) => formatOutput(markdown, results, !!opts.citations)
|
|
24052
|
+
};
|
|
24053
|
+
}
|
|
24054
|
+
function emptyHandle(results) {
|
|
24055
|
+
return {
|
|
24056
|
+
tool: void 0,
|
|
24057
|
+
backend: void 0,
|
|
24058
|
+
native: false,
|
|
24059
|
+
results,
|
|
24060
|
+
capture: () => {
|
|
24061
|
+
},
|
|
24062
|
+
promptSnippet: "",
|
|
24063
|
+
formatOutput: (markdown) => formatOutput(markdown, results, false)
|
|
24064
|
+
};
|
|
24065
|
+
}
|
|
24066
|
+
function formatOutput(markdown, results, citations) {
|
|
24067
|
+
return citations ? linkifyCitations(markdown, results) : { content: stripCitations(markdown), converted: 0, skipped: 0 };
|
|
24068
|
+
}
|
|
24069
|
+
function captureNativeResults(stepContent, target) {
|
|
24070
|
+
if (!Array.isArray(stepContent)) return;
|
|
24071
|
+
for (const content of stepContent) {
|
|
24072
|
+
if (content?.type !== "tool-result") continue;
|
|
24073
|
+
if (content?.toolName !== WEB_SEARCH_TOOL_NAME) continue;
|
|
24074
|
+
const body = content.output ?? content.result ?? null;
|
|
24075
|
+
if (!Array.isArray(body)) continue;
|
|
24076
|
+
for (const r of body) {
|
|
24077
|
+
if (r && typeof r === "object" && typeof r.url === "string") {
|
|
24078
|
+
target.push({
|
|
24079
|
+
url: r.url,
|
|
24080
|
+
title: r.title ?? null,
|
|
24081
|
+
pageAge: r.pageAge ?? null,
|
|
24082
|
+
// Assigned here too, so `results` is shape-identical to the
|
|
24083
|
+
// Exa path. Anthropic's model derives its own indices from
|
|
24084
|
+
// the same ordering, so these agree by construction.
|
|
24085
|
+
index: target.length + 1,
|
|
24086
|
+
type: "web_search_result"
|
|
24087
|
+
});
|
|
24088
|
+
}
|
|
24089
|
+
}
|
|
24090
|
+
}
|
|
24091
|
+
}
|
|
24092
|
+
function stripCitations(markdown) {
|
|
24093
|
+
return markdown.replace(/[ \t]*<cite\b[^>]*>\s*<\/cite>/g, "").replace(/<cite\b[^>]*>(.*?)<\/cite>/g, "$1").replace(/<\/?cite\b[^>]*>/g, "");
|
|
24094
|
+
}
|
|
24095
|
+
function linkifyCitations(markdown, results) {
|
|
24096
|
+
let converted = 0;
|
|
24097
|
+
let skipped = 0;
|
|
24098
|
+
const content = markdown.replace(
|
|
24099
|
+
/<cite index="(\d+)(?:-\d+(?:,\d+-\d+)*)?">(.*?)<\/cite>/g,
|
|
24100
|
+
(_match, indexStr, anchor) => {
|
|
24101
|
+
const index = parseInt(indexStr, 10);
|
|
24102
|
+
const hit = results[index - 1];
|
|
24103
|
+
if (!hit || typeof hit.url !== "string") {
|
|
24104
|
+
skipped++;
|
|
24105
|
+
return anchor;
|
|
24106
|
+
}
|
|
24107
|
+
converted++;
|
|
24108
|
+
const text = anchor.trim() ? anchor.replace(/\]/g, "\\]") : `[${index}]`;
|
|
24109
|
+
return `[${text}](${hit.url})`;
|
|
24110
|
+
}
|
|
24111
|
+
);
|
|
24112
|
+
return { content, converted, skipped };
|
|
24113
|
+
}
|
|
24114
|
+
|
|
24115
|
+
// src/fetch.ts
|
|
24116
|
+
var import_ai3 = require("ai");
|
|
24117
|
+
var import_zod2 = require("zod");
|
|
24118
|
+
var import_node_net = require("net");
|
|
24119
|
+
var import_promises = require("dns/promises");
|
|
24120
|
+
var WEB_FETCH_TOOL_NAME = "web_fetch";
|
|
24121
|
+
var DEFAULT_MAX_USES2 = 5;
|
|
24122
|
+
var DEFAULT_MAX_CHARACTERS2 = 4e4;
|
|
24123
|
+
var CHARS_PER_TOKEN = 4;
|
|
24124
|
+
var DEFAULT_TIMEOUT_MS = 2e4;
|
|
24125
|
+
var MAX_REDIRECTS = 5;
|
|
24126
|
+
var MAX_BODY_BYTES = 4 * 1024 * 1024;
|
|
24127
|
+
var USER_AGENT = "aieo-web-fetch/1 (+https://github.com/stakwork/stakgraph)";
|
|
24128
|
+
var ACCEPT = "text/html, application/xhtml+xml, text/plain;q=0.9, application/json;q=0.9, text/*;q=0.8, */*;q=0.5";
|
|
24129
|
+
function resolveFetchBackend(provider) {
|
|
24130
|
+
return provider === "anthropic" ? "anthropic" : "http";
|
|
24131
|
+
}
|
|
24132
|
+
var PRIVATE_ADDRESSES = buildBlockList();
|
|
24133
|
+
function buildBlockList() {
|
|
24134
|
+
const b = new import_node_net.BlockList();
|
|
24135
|
+
const v42 = [
|
|
24136
|
+
["0.0.0.0", 8],
|
|
24137
|
+
// "this" network
|
|
24138
|
+
["10.0.0.0", 8],
|
|
24139
|
+
// RFC 1918
|
|
24140
|
+
["100.64.0.0", 10],
|
|
24141
|
+
// carrier-grade NAT
|
|
24142
|
+
["127.0.0.0", 8],
|
|
24143
|
+
// loopback
|
|
24144
|
+
["169.254.0.0", 16],
|
|
24145
|
+
// link-local, incl. cloud metadata at 169.254.169.254
|
|
24146
|
+
["172.16.0.0", 12],
|
|
24147
|
+
// RFC 1918
|
|
24148
|
+
["192.0.0.0", 24],
|
|
24149
|
+
// IETF protocol assignments
|
|
24150
|
+
["192.168.0.0", 16],
|
|
24151
|
+
// RFC 1918
|
|
24152
|
+
["198.18.0.0", 15],
|
|
24153
|
+
// benchmarking
|
|
24154
|
+
["224.0.0.0", 4],
|
|
24155
|
+
// multicast
|
|
24156
|
+
["240.0.0.0", 4]
|
|
24157
|
+
// reserved, incl. broadcast
|
|
24158
|
+
];
|
|
24159
|
+
for (const [net, prefix] of v42) b.addSubnet(net, prefix, "ipv4");
|
|
24160
|
+
b.addAddress("::", "ipv6");
|
|
24161
|
+
b.addAddress("::1", "ipv6");
|
|
24162
|
+
const v6 = [
|
|
24163
|
+
["64:ff9b::", 96],
|
|
24164
|
+
// NAT64
|
|
24165
|
+
["2002::", 16],
|
|
24166
|
+
// 6to4
|
|
24167
|
+
["fc00::", 7],
|
|
24168
|
+
// unique local
|
|
24169
|
+
["fe80::", 10],
|
|
24170
|
+
// link-local
|
|
24171
|
+
["fec0::", 10],
|
|
24172
|
+
// site-local (deprecated, still routed on old gear)
|
|
24173
|
+
["ff00::", 8]
|
|
24174
|
+
// multicast
|
|
24175
|
+
];
|
|
24176
|
+
for (const [net, prefix] of v6) b.addSubnet(net, prefix, "ipv6");
|
|
24177
|
+
return b;
|
|
24178
|
+
}
|
|
24179
|
+
function isPrivateAddress(ip) {
|
|
24180
|
+
const bare = ip.startsWith("[") && ip.endsWith("]") ? ip.slice(1, -1) : ip;
|
|
24181
|
+
const family = (0, import_node_net.isIP)(bare);
|
|
24182
|
+
try {
|
|
24183
|
+
if (family === 4) return PRIVATE_ADDRESSES.check(bare, "ipv4");
|
|
24184
|
+
if (family === 6) return PRIVATE_ADDRESSES.check(bare, "ipv6");
|
|
24185
|
+
} catch {
|
|
24186
|
+
}
|
|
24187
|
+
return true;
|
|
24188
|
+
}
|
|
24189
|
+
var defaultLookup = async (hostname) => {
|
|
24190
|
+
const addresses = await (0, import_promises.lookup)(hostname, { all: true });
|
|
24191
|
+
return addresses.map((a) => a.address);
|
|
24192
|
+
};
|
|
24193
|
+
function matchesDomain(host, domains) {
|
|
24194
|
+
return domains.some((d) => {
|
|
24195
|
+
const dom = d.trim().toLowerCase().replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/^\*\./, "").replace(/\.$/, "");
|
|
24196
|
+
return !!dom && (host === dom || host.endsWith("." + dom));
|
|
24197
|
+
});
|
|
24198
|
+
}
|
|
24199
|
+
async function validateFetchUrl(raw, opts = {}) {
|
|
24200
|
+
let url;
|
|
24201
|
+
try {
|
|
24202
|
+
url = new URL(raw);
|
|
24203
|
+
} catch {
|
|
24204
|
+
throw new Error(`Not a valid absolute URL: ${raw}`);
|
|
24205
|
+
}
|
|
24206
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
24207
|
+
throw new Error(`Only http(s) URLs can be fetched, got ${url.protocol}`);
|
|
24208
|
+
}
|
|
24209
|
+
if (url.username || url.password) {
|
|
24210
|
+
throw new Error("URLs with embedded credentials are not fetched");
|
|
24211
|
+
}
|
|
24212
|
+
const host = url.hostname.replace(/\.$/, "").toLowerCase();
|
|
24213
|
+
if (!host) throw new Error("URL has no host");
|
|
24214
|
+
if (host === "localhost" || host.endsWith(".localhost")) {
|
|
24215
|
+
throw new Error("Refusing to fetch a local address");
|
|
24216
|
+
}
|
|
24217
|
+
if (opts.allowedDomains?.length && !matchesDomain(host, opts.allowedDomains)) {
|
|
24218
|
+
throw new Error(`${host} is not in the allowed domains`);
|
|
24219
|
+
}
|
|
24220
|
+
if (opts.blockedDomains?.length && matchesDomain(host, opts.blockedDomains)) {
|
|
24221
|
+
throw new Error(`${host} is a blocked domain`);
|
|
24222
|
+
}
|
|
24223
|
+
const literal = host.startsWith("[") ? host.slice(1, -1) : host;
|
|
24224
|
+
if ((0, import_node_net.isIP)(literal)) {
|
|
24225
|
+
if (isPrivateAddress(literal)) {
|
|
24226
|
+
throw new Error("Refusing to fetch a private or reserved address");
|
|
24227
|
+
}
|
|
24228
|
+
return url;
|
|
24229
|
+
}
|
|
24230
|
+
let addresses;
|
|
24231
|
+
try {
|
|
24232
|
+
addresses = await (opts.lookup ?? defaultLookup)(host);
|
|
24233
|
+
} catch (err) {
|
|
24234
|
+
throw new Error(
|
|
24235
|
+
`Could not resolve ${host}: ${err instanceof Error ? err.message : String(err)}`
|
|
24236
|
+
);
|
|
24237
|
+
}
|
|
24238
|
+
if (!addresses.length) throw new Error(`Could not resolve ${host}`);
|
|
24239
|
+
if (addresses.some(isPrivateAddress)) {
|
|
24240
|
+
throw new Error(`Refusing to fetch ${host}: it resolves to a private or reserved address`);
|
|
24241
|
+
}
|
|
24242
|
+
return url;
|
|
24243
|
+
}
|
|
24244
|
+
async function fetchUrl(rawUrl, opts = {}) {
|
|
24245
|
+
const maxCharacters = opts.maxCharacters ?? DEFAULT_MAX_CHARACTERS2;
|
|
24246
|
+
const signals = [AbortSignal.timeout(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS)];
|
|
24247
|
+
if (opts.abortSignal) signals.push(opts.abortSignal);
|
|
24248
|
+
const signal = AbortSignal.any(signals);
|
|
24249
|
+
let url = await validateFetchUrl(rawUrl, opts);
|
|
24250
|
+
let res;
|
|
24251
|
+
for (let hop = 0; ; hop++) {
|
|
24252
|
+
try {
|
|
24253
|
+
res = await fetch(url, {
|
|
24254
|
+
method: "GET",
|
|
24255
|
+
redirect: "manual",
|
|
24256
|
+
signal,
|
|
24257
|
+
headers: { "user-agent": USER_AGENT, accept: ACCEPT }
|
|
24258
|
+
});
|
|
24259
|
+
} catch (err) {
|
|
24260
|
+
throw new Error(`Could not connect to ${url.hostname}: ${describeTransportError(err)}`);
|
|
24261
|
+
}
|
|
24262
|
+
if (!isRedirect(res.status)) break;
|
|
24263
|
+
const location = res.headers.get("location");
|
|
24264
|
+
await discard(res);
|
|
24265
|
+
if (!location) throw new Error(`Redirect (${res.status}) without a Location header`);
|
|
24266
|
+
if (hop >= MAX_REDIRECTS) throw new Error(`Too many redirects (more than ${MAX_REDIRECTS})`);
|
|
24267
|
+
let next;
|
|
24268
|
+
try {
|
|
24269
|
+
next = new URL(location, url).toString();
|
|
24270
|
+
} catch {
|
|
24271
|
+
throw new Error(`Redirect to an invalid URL: ${location}`);
|
|
24272
|
+
}
|
|
24273
|
+
url = await validateFetchUrl(next, opts);
|
|
24274
|
+
}
|
|
24275
|
+
if (!res.ok) {
|
|
24276
|
+
await discard(res);
|
|
24277
|
+
throw new Error(`HTTP ${res.status} fetching ${url.hostname}`);
|
|
24278
|
+
}
|
|
24279
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
24280
|
+
const mediaType = contentType.split(";")[0].trim().toLowerCase() || null;
|
|
24281
|
+
if (mediaType === "application/pdf") {
|
|
24282
|
+
await discard(res);
|
|
24283
|
+
throw new Error(
|
|
24284
|
+
"PDF documents are not supported by this fetch backend (only Anthropic's native web_fetch reads PDFs)"
|
|
24285
|
+
);
|
|
24286
|
+
}
|
|
24287
|
+
if (!isTextual(mediaType)) {
|
|
24288
|
+
await discard(res);
|
|
24289
|
+
throw new Error(`Unsupported content type: ${mediaType}`);
|
|
24290
|
+
}
|
|
24291
|
+
const { bytes, capped } = await readCapped(res, MAX_BODY_BYTES);
|
|
24292
|
+
const raw = decode(bytes, contentType);
|
|
24293
|
+
const isHtml = mediaType === "text/html" || mediaType === "application/xhtml+xml" || looksLikeHtml(raw);
|
|
24294
|
+
const { title, text } = isHtml ? htmlToText(raw) : { title: null, text: raw.trim() };
|
|
24295
|
+
const truncated = capped || text.length > maxCharacters;
|
|
24296
|
+
return {
|
|
24297
|
+
url: url.toString(),
|
|
24298
|
+
title,
|
|
24299
|
+
text: truncated ? text.slice(0, maxCharacters) : text,
|
|
24300
|
+
mediaType,
|
|
24301
|
+
retrievedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24302
|
+
truncated,
|
|
24303
|
+
type: "web_fetch_result"
|
|
24304
|
+
};
|
|
24305
|
+
}
|
|
24306
|
+
function describeTransportError(err) {
|
|
24307
|
+
const e = err;
|
|
24308
|
+
if (e?.name === "TimeoutError") return "timed out";
|
|
24309
|
+
if (e?.name === "AbortError") return "aborted";
|
|
24310
|
+
const cause = e?.cause;
|
|
24311
|
+
if (cause?.message) return cause.code ? `${cause.message} (${cause.code})` : cause.message;
|
|
24312
|
+
return e?.message ?? String(err);
|
|
24313
|
+
}
|
|
24314
|
+
function isRedirect(status) {
|
|
24315
|
+
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
24316
|
+
}
|
|
24317
|
+
async function discard(res) {
|
|
24318
|
+
await res.body?.cancel().catch(() => {
|
|
24319
|
+
});
|
|
24320
|
+
}
|
|
24321
|
+
function isTextual(mediaType) {
|
|
24322
|
+
if (!mediaType) return true;
|
|
24323
|
+
if (mediaType.startsWith("text/")) return true;
|
|
24324
|
+
if (mediaType.endsWith("+json") || mediaType.endsWith("+xml")) return true;
|
|
24325
|
+
return mediaType === "application/json" || mediaType === "application/xml" || mediaType === "application/xhtml+xml" || mediaType === "application/javascript";
|
|
24326
|
+
}
|
|
24327
|
+
async function readCapped(res, maxBytes) {
|
|
24328
|
+
const body = res.body;
|
|
24329
|
+
if (!body) return { bytes: new Uint8Array(await res.arrayBuffer()), capped: false };
|
|
24330
|
+
const reader = body.getReader();
|
|
24331
|
+
const chunks = [];
|
|
24332
|
+
let total = 0;
|
|
24333
|
+
let capped = false;
|
|
24334
|
+
for (; ; ) {
|
|
24335
|
+
const { done, value } = await reader.read();
|
|
24336
|
+
if (done) break;
|
|
24337
|
+
if (!value) continue;
|
|
24338
|
+
if (total + value.byteLength > maxBytes) {
|
|
24339
|
+
chunks.push(value.subarray(0, maxBytes - total));
|
|
24340
|
+
total = maxBytes;
|
|
24341
|
+
capped = true;
|
|
24342
|
+
await reader.cancel().catch(() => {
|
|
24343
|
+
});
|
|
24344
|
+
break;
|
|
24345
|
+
}
|
|
24346
|
+
chunks.push(value);
|
|
24347
|
+
total += value.byteLength;
|
|
24348
|
+
}
|
|
24349
|
+
const out = new Uint8Array(total);
|
|
24350
|
+
let offset = 0;
|
|
24351
|
+
for (const c of chunks) {
|
|
24352
|
+
out.set(c, offset);
|
|
24353
|
+
offset += c.byteLength;
|
|
24354
|
+
}
|
|
24355
|
+
return { bytes: out, capped };
|
|
24356
|
+
}
|
|
24357
|
+
function decode(bytes, contentType) {
|
|
24358
|
+
const charset = /charset=["']?([\w.:-]+)/i.exec(contentType)?.[1] ?? "utf-8";
|
|
24359
|
+
try {
|
|
24360
|
+
return new TextDecoder(charset).decode(bytes);
|
|
24361
|
+
} catch {
|
|
24362
|
+
return new TextDecoder("utf-8").decode(bytes);
|
|
24363
|
+
}
|
|
24364
|
+
}
|
|
24365
|
+
function looksLikeHtml(s) {
|
|
24366
|
+
return /^\s*(?:<!doctype\s+html|<html[\s>]|<head[\s>]|<body[\s>])/i.test(s.slice(0, 1024));
|
|
24367
|
+
}
|
|
24368
|
+
var NAMED_ENTITIES = {
|
|
24369
|
+
nbsp: " ",
|
|
24370
|
+
lt: "<",
|
|
24371
|
+
gt: ">",
|
|
24372
|
+
quot: '"',
|
|
24373
|
+
apos: "'",
|
|
24374
|
+
mdash: "\u2014",
|
|
24375
|
+
ndash: "\u2013",
|
|
24376
|
+
hellip: "\u2026",
|
|
24377
|
+
copy: "\xA9",
|
|
24378
|
+
reg: "\xAE",
|
|
24379
|
+
trade: "\u2122",
|
|
24380
|
+
laquo: "\xAB",
|
|
24381
|
+
raquo: "\xBB",
|
|
24382
|
+
ldquo: "\u201C",
|
|
24383
|
+
rdquo: "\u201D",
|
|
24384
|
+
lsquo: "\u2018",
|
|
24385
|
+
rsquo: "\u2019",
|
|
24386
|
+
bull: "\u2022",
|
|
24387
|
+
middot: "\xB7",
|
|
24388
|
+
times: "\xD7",
|
|
24389
|
+
deg: "\xB0"
|
|
24390
|
+
};
|
|
24391
|
+
function codePoint(cp, fallback) {
|
|
24392
|
+
if (!Number.isFinite(cp) || cp <= 0 || cp > 1114111 || cp >= 55296 && cp <= 57343) {
|
|
24393
|
+
return fallback;
|
|
24394
|
+
}
|
|
24395
|
+
return String.fromCodePoint(cp);
|
|
24396
|
+
}
|
|
24397
|
+
function decodeEntities(s) {
|
|
24398
|
+
return s.replace(/&#x([0-9a-f]{1,6});/gi, (m, hex) => codePoint(parseInt(hex, 16), m)).replace(/&#(\d{1,7});/g, (m, dec) => codePoint(parseInt(dec, 10), m)).replace(/&([a-z]+);/gi, (m, name19) => NAMED_ENTITIES[name19.toLowerCase()] ?? m).replace(/&/g, "&");
|
|
24399
|
+
}
|
|
24400
|
+
var BLOCK_TAGS = "p|div|section|article|header|footer|main|aside|nav|h[1-6]|ul|ol|tr|table|thead|tbody|tfoot|blockquote|pre|hr|dd|dt|dl|figure|figcaption|form|fieldset|address|details|summary";
|
|
24401
|
+
function htmlToText(html) {
|
|
24402
|
+
const titleMatch = /<title[^>]*>([\s\S]*?)<\/title>/i.exec(html);
|
|
24403
|
+
const title = titleMatch ? decodeEntities(titleMatch[1]).replace(/\s+/g, " ").trim() || null : null;
|
|
24404
|
+
const stripped = html.replace(/<!--[\s\S]*?-->/g, " ").replace(/<(script|style|noscript|svg|template|head)\b[\s\S]*?<\/\1\s*>/gi, " ").replace(/<br\s*\/?>/gi, "\n").replace(/<li\b[^>]*>/gi, "\n- ").replace(new RegExp(`<\\/?(?:${BLOCK_TAGS})\\b[^>]*>`, "gi"), "\n").replace(/<[^>]+>/g, " ");
|
|
24405
|
+
const text = decodeEntities(stripped).replace(/[ \t\r\f\v ]+/g, " ").replace(/ ?\n ?/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
24406
|
+
return { title, text };
|
|
24407
|
+
}
|
|
24408
|
+
function createWebFetch(opts) {
|
|
24409
|
+
const results = [];
|
|
24410
|
+
const backend = opts.backend ?? resolveFetchBackend(opts.provider);
|
|
24411
|
+
const maxUses = opts.maxUses ?? DEFAULT_MAX_USES2;
|
|
24412
|
+
const maxCharacters = opts.maxCharacters ?? (opts.maxContentTokens ? opts.maxContentTokens * CHARS_PER_TOKEN : DEFAULT_MAX_CHARACTERS2);
|
|
24413
|
+
const maxContentTokens = opts.maxContentTokens ?? (opts.maxCharacters ? Math.ceil(opts.maxCharacters / CHARS_PER_TOKEN) : void 0);
|
|
24414
|
+
if (backend === "anthropic") {
|
|
24415
|
+
const apiKey = normalizeApiKey(opts.apiKey) || normalizeApiKey(process.env.ANTHROPIC_API_KEY);
|
|
24416
|
+
if (!apiKey) {
|
|
24417
|
+
return emptyFetchHandle(results);
|
|
24418
|
+
}
|
|
24419
|
+
const baseURL = getGatewayBaseURL("anthropic");
|
|
24420
|
+
const anthropic2 = createAnthropic({ apiKey, ...baseURL && { baseURL } });
|
|
24421
|
+
return {
|
|
24422
|
+
tool: anthropic2.tools.webFetch_20250910({
|
|
24423
|
+
maxUses,
|
|
24424
|
+
...maxContentTokens ? { maxContentTokens } : {},
|
|
24425
|
+
...opts.allowedDomains?.length ? { allowedDomains: opts.allowedDomains } : {},
|
|
24426
|
+
...opts.blockedDomains?.length ? { blockedDomains: opts.blockedDomains } : {}
|
|
24427
|
+
}),
|
|
24428
|
+
backend,
|
|
24429
|
+
native: true,
|
|
24430
|
+
results,
|
|
24431
|
+
capture: (stepContent) => captureNativeFetchResults(stepContent, results)
|
|
24432
|
+
};
|
|
24433
|
+
}
|
|
24434
|
+
let uses = 0;
|
|
24435
|
+
return {
|
|
24436
|
+
tool: (0, import_ai3.tool)({
|
|
24437
|
+
description: "Fetch a specific web page by URL and return its text. HTML is converted to plain text; JSON and plain text come back as-is. Use this to read a page whose address you already have \u2014 one the user gave you, or one returned by web_search. It is not a search engine: it needs a full http(s) URL. PDFs and other binary content are not supported.",
|
|
24438
|
+
inputSchema: import_zod2.z.object({
|
|
24439
|
+
url: import_zod2.z.string().describe("The absolute http(s) URL to fetch.")
|
|
24440
|
+
}),
|
|
24441
|
+
execute: async ({ url }, ctx) => {
|
|
24442
|
+
if (uses >= maxUses) {
|
|
24443
|
+
return {
|
|
24444
|
+
error: `web_fetch budget exhausted (${maxUses} calls). Work with what you have.`
|
|
24445
|
+
};
|
|
24446
|
+
}
|
|
24447
|
+
uses++;
|
|
24448
|
+
try {
|
|
24449
|
+
const page = await fetchUrl(url, {
|
|
24450
|
+
maxCharacters,
|
|
24451
|
+
allowedDomains: opts.allowedDomains,
|
|
24452
|
+
blockedDomains: opts.blockedDomains,
|
|
24453
|
+
abortSignal: ctx?.abortSignal ?? opts.abortSignal,
|
|
24454
|
+
lookup: opts.lookup
|
|
24455
|
+
});
|
|
24456
|
+
results.push(page);
|
|
24457
|
+
return page;
|
|
24458
|
+
} catch (err) {
|
|
24459
|
+
return {
|
|
24460
|
+
error: `Fetch failed: ${err instanceof Error ? err.message : String(err)}`
|
|
24461
|
+
};
|
|
24462
|
+
}
|
|
24463
|
+
}
|
|
24464
|
+
}),
|
|
24465
|
+
backend,
|
|
24466
|
+
native: false,
|
|
24467
|
+
results,
|
|
24468
|
+
// HTTP results are appended by `execute` above; walking the step
|
|
24469
|
+
// would double-count them.
|
|
24470
|
+
capture: () => {
|
|
24471
|
+
}
|
|
24472
|
+
};
|
|
24473
|
+
}
|
|
24474
|
+
function emptyFetchHandle(results) {
|
|
24475
|
+
return {
|
|
24476
|
+
tool: void 0,
|
|
24477
|
+
backend: void 0,
|
|
24478
|
+
native: false,
|
|
24479
|
+
results,
|
|
24480
|
+
capture: () => {
|
|
24481
|
+
}
|
|
24482
|
+
};
|
|
24483
|
+
}
|
|
24484
|
+
function captureNativeFetchResults(stepContent, target) {
|
|
24485
|
+
if (!Array.isArray(stepContent)) return;
|
|
24486
|
+
for (const content of stepContent) {
|
|
24487
|
+
if (content?.type !== "tool-result") continue;
|
|
24488
|
+
if (content?.toolName !== WEB_FETCH_TOOL_NAME) continue;
|
|
24489
|
+
const body = content.output ?? content.result ?? null;
|
|
24490
|
+
if (!body || typeof body !== "object") continue;
|
|
24491
|
+
if (body.type !== "web_fetch_result" || typeof body.url !== "string") continue;
|
|
24492
|
+
const doc = body.content ?? {};
|
|
24493
|
+
const source = doc.source ?? {};
|
|
24494
|
+
target.push({
|
|
24495
|
+
url: body.url,
|
|
24496
|
+
title: doc.title ?? null,
|
|
24497
|
+
...source.type === "text" && typeof source.data === "string" ? { text: source.data } : {},
|
|
24498
|
+
mediaType: source.mediaType ?? source.media_type ?? null,
|
|
24499
|
+
retrievedAt: body.retrievedAt ?? body.retrieved_at ?? null,
|
|
24500
|
+
type: "web_fetch_result"
|
|
24501
|
+
});
|
|
24502
|
+
}
|
|
24503
|
+
}
|
|
24504
|
+
|
|
23898
24505
|
// src/tools.ts
|
|
23899
24506
|
function getProviderTool(provider, apiKey, toolName) {
|
|
24507
|
+
if (toolName === "webSearch") {
|
|
24508
|
+
return createWebSearch({ provider, apiKey }).tool;
|
|
24509
|
+
}
|
|
24510
|
+
if (toolName === "webFetch") {
|
|
24511
|
+
return createWebFetch({ provider, apiKey }).tool;
|
|
24512
|
+
}
|
|
23900
24513
|
switch (provider) {
|
|
23901
24514
|
case "anthropic":
|
|
23902
24515
|
return getAnthropicTool(apiKey, toolName);
|
|
@@ -23953,13 +24566,20 @@ function consoleLogger(name19) {
|
|
|
23953
24566
|
OUTRO,
|
|
23954
24567
|
PROVIDERS,
|
|
23955
24568
|
SYSTEM,
|
|
24569
|
+
WEB_FETCH_TOOL_NAME,
|
|
24570
|
+
WEB_SEARCH_TOOL_NAME,
|
|
23956
24571
|
addUsage,
|
|
23957
24572
|
callGenerateObject,
|
|
23958
24573
|
callGenerateText,
|
|
23959
24574
|
callModel,
|
|
24575
|
+
captureNativeFetchResults,
|
|
24576
|
+
captureNativeResults,
|
|
23960
24577
|
computeSessionCost,
|
|
23961
24578
|
consoleLogger,
|
|
24579
|
+
createWebFetch,
|
|
24580
|
+
createWebSearch,
|
|
23962
24581
|
emptyUsage,
|
|
24582
|
+
fetchUrl,
|
|
23963
24583
|
gatewayEnvForProviders,
|
|
23964
24584
|
gatewayUrlFor,
|
|
23965
24585
|
gatewayUrlForModel,
|
|
@@ -23972,13 +24592,23 @@ function consoleLogger(name19) {
|
|
|
23972
24592
|
getProviderForModel,
|
|
23973
24593
|
getProviderOptions,
|
|
23974
24594
|
getProviderTool,
|
|
24595
|
+
getSearchApiKey,
|
|
23975
24596
|
getTokenPricing,
|
|
23976
24597
|
hasApiKeyForProvider,
|
|
24598
|
+
hasSearchApiKey,
|
|
24599
|
+
htmlToText,
|
|
24600
|
+
isPrivateAddress,
|
|
24601
|
+
linkifyCitations,
|
|
23977
24602
|
loadModelPricing,
|
|
23978
24603
|
normalizeApiKey,
|
|
23979
24604
|
normalizeCallerBaseURL,
|
|
23980
24605
|
normalizeUsage,
|
|
24606
|
+
resolveFetchBackend,
|
|
23981
24607
|
resolveLLMConfig,
|
|
24608
|
+
resolveSearchBackend,
|
|
24609
|
+
searchWeb,
|
|
24610
|
+
stripCitations,
|
|
24611
|
+
validateFetchUrl,
|
|
23982
24612
|
withLegacyUsage,
|
|
23983
24613
|
withProviderCacheUsage
|
|
23984
24614
|
});
|