aieo 0.1.36 → 0.1.38
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 +506 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +207 -14
- package/dist/index.d.ts +207 -14
- package/dist/index.js +498 -96
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -36,16 +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,
|
|
39
40
|
WEB_SEARCH_TOOL_NAME: () => WEB_SEARCH_TOOL_NAME,
|
|
40
41
|
addUsage: () => addUsage,
|
|
41
42
|
callGenerateObject: () => callGenerateObject,
|
|
42
43
|
callGenerateText: () => callGenerateText,
|
|
43
44
|
callModel: () => callModel,
|
|
45
|
+
captureNativeFetchResults: () => captureNativeFetchResults,
|
|
44
46
|
captureNativeResults: () => captureNativeResults,
|
|
45
47
|
computeSessionCost: () => computeSessionCost,
|
|
46
48
|
consoleLogger: () => consoleLogger,
|
|
49
|
+
createWebFetch: () => createWebFetch,
|
|
47
50
|
createWebSearch: () => createWebSearch,
|
|
48
51
|
emptyUsage: () => emptyUsage,
|
|
52
|
+
fetchUrl: () => fetchUrl,
|
|
49
53
|
gatewayEnvForProviders: () => gatewayEnvForProviders,
|
|
50
54
|
gatewayUrlFor: () => gatewayUrlFor,
|
|
51
55
|
gatewayUrlForModel: () => gatewayUrlForModel,
|
|
@@ -62,15 +66,19 @@ __export(index_exports, {
|
|
|
62
66
|
getTokenPricing: () => getTokenPricing,
|
|
63
67
|
hasApiKeyForProvider: () => hasApiKeyForProvider,
|
|
64
68
|
hasSearchApiKey: () => hasSearchApiKey,
|
|
69
|
+
htmlToText: () => htmlToText,
|
|
70
|
+
isPrivateAddress: () => isPrivateAddress,
|
|
65
71
|
linkifyCitations: () => linkifyCitations,
|
|
66
72
|
loadModelPricing: () => loadModelPricing,
|
|
67
73
|
normalizeApiKey: () => normalizeApiKey,
|
|
68
74
|
normalizeCallerBaseURL: () => normalizeCallerBaseURL,
|
|
69
75
|
normalizeUsage: () => normalizeUsage,
|
|
76
|
+
resolveFetchBackend: () => resolveFetchBackend,
|
|
70
77
|
resolveLLMConfig: () => resolveLLMConfig,
|
|
71
78
|
resolveSearchBackend: () => resolveSearchBackend,
|
|
72
79
|
searchWeb: () => searchWeb,
|
|
73
80
|
stripCitations: () => stripCitations,
|
|
81
|
+
validateFetchUrl: () => validateFetchUrl,
|
|
74
82
|
withLegacyUsage: () => withLegacyUsage,
|
|
75
83
|
withProviderCacheUsage: () => withProviderCacheUsage
|
|
76
84
|
});
|
|
@@ -4190,35 +4198,35 @@ async function prepareTools({
|
|
|
4190
4198
|
return { tools: void 0, toolChoice: void 0, toolWarnings, betas };
|
|
4191
4199
|
}
|
|
4192
4200
|
const anthropicTools2 = [];
|
|
4193
|
-
for (const
|
|
4194
|
-
switch (
|
|
4201
|
+
for (const tool6 of tools) {
|
|
4202
|
+
switch (tool6.type) {
|
|
4195
4203
|
case "function": {
|
|
4196
|
-
const cacheControl = validator.getCacheControl(
|
|
4204
|
+
const cacheControl = validator.getCacheControl(tool6.providerOptions, {
|
|
4197
4205
|
type: "tool definition",
|
|
4198
4206
|
canCache: true
|
|
4199
4207
|
});
|
|
4200
|
-
const anthropicOptions = (_a20 =
|
|
4208
|
+
const anthropicOptions = (_a20 = tool6.providerOptions) == null ? void 0 : _a20.anthropic;
|
|
4201
4209
|
const eagerInputStreaming = (_b20 = anthropicOptions == null ? void 0 : anthropicOptions.eagerInputStreaming) != null ? _b20 : defaultEagerInputStreaming;
|
|
4202
4210
|
const deferLoading = anthropicOptions == null ? void 0 : anthropicOptions.deferLoading;
|
|
4203
4211
|
const allowedCallers = anthropicOptions == null ? void 0 : anthropicOptions.allowedCallers;
|
|
4204
|
-
if (!supportsStrictTools &&
|
|
4212
|
+
if (!supportsStrictTools && tool6.strict != null) {
|
|
4205
4213
|
toolWarnings.push({
|
|
4206
4214
|
type: "unsupported",
|
|
4207
4215
|
feature: "strict",
|
|
4208
|
-
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.`
|
|
4209
4217
|
});
|
|
4210
4218
|
}
|
|
4211
4219
|
anthropicTools2.push({
|
|
4212
|
-
name:
|
|
4213
|
-
description:
|
|
4214
|
-
input_schema:
|
|
4220
|
+
name: tool6.name,
|
|
4221
|
+
description: tool6.description,
|
|
4222
|
+
input_schema: tool6.inputSchema,
|
|
4215
4223
|
cache_control: cacheControl,
|
|
4216
4224
|
...eagerInputStreaming ? { eager_input_streaming: true } : {},
|
|
4217
|
-
...supportsStrictTools === true &&
|
|
4225
|
+
...supportsStrictTools === true && tool6.strict != null ? { strict: tool6.strict } : {},
|
|
4218
4226
|
...deferLoading != null ? { defer_loading: deferLoading } : {},
|
|
4219
4227
|
...allowedCallers != null ? { allowed_callers: allowedCallers } : {},
|
|
4220
|
-
...
|
|
4221
|
-
input_examples:
|
|
4228
|
+
...tool6.inputExamples != null ? {
|
|
4229
|
+
input_examples: tool6.inputExamples.map(
|
|
4222
4230
|
(example) => example.input
|
|
4223
4231
|
)
|
|
4224
4232
|
} : {}
|
|
@@ -4226,13 +4234,13 @@ async function prepareTools({
|
|
|
4226
4234
|
if (supportsStructuredOutput === true) {
|
|
4227
4235
|
betas.add("structured-outputs-2025-11-13");
|
|
4228
4236
|
}
|
|
4229
|
-
if (
|
|
4237
|
+
if (tool6.inputExamples != null || allowedCallers != null) {
|
|
4230
4238
|
betas.add("advanced-tool-use-2025-11-20");
|
|
4231
4239
|
}
|
|
4232
4240
|
break;
|
|
4233
4241
|
}
|
|
4234
4242
|
case "provider": {
|
|
4235
|
-
switch (
|
|
4243
|
+
switch (tool6.id) {
|
|
4236
4244
|
case "anthropic.code_execution_20250522": {
|
|
4237
4245
|
betas.add("code-execution-2025-05-22");
|
|
4238
4246
|
anthropicTools2.push({
|
|
@@ -4262,9 +4270,9 @@ async function prepareTools({
|
|
|
4262
4270
|
anthropicTools2.push({
|
|
4263
4271
|
name: "computer",
|
|
4264
4272
|
type: "computer_20250124",
|
|
4265
|
-
display_width_px:
|
|
4266
|
-
display_height_px:
|
|
4267
|
-
display_number:
|
|
4273
|
+
display_width_px: tool6.args.displayWidthPx,
|
|
4274
|
+
display_height_px: tool6.args.displayHeightPx,
|
|
4275
|
+
display_number: tool6.args.displayNumber,
|
|
4268
4276
|
cache_control: void 0
|
|
4269
4277
|
});
|
|
4270
4278
|
break;
|
|
@@ -4274,10 +4282,10 @@ async function prepareTools({
|
|
|
4274
4282
|
anthropicTools2.push({
|
|
4275
4283
|
name: "computer",
|
|
4276
4284
|
type: "computer_20251124",
|
|
4277
|
-
display_width_px:
|
|
4278
|
-
display_height_px:
|
|
4279
|
-
display_number:
|
|
4280
|
-
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,
|
|
4281
4289
|
cache_control: void 0
|
|
4282
4290
|
});
|
|
4283
4291
|
break;
|
|
@@ -4287,9 +4295,9 @@ async function prepareTools({
|
|
|
4287
4295
|
anthropicTools2.push({
|
|
4288
4296
|
name: "computer",
|
|
4289
4297
|
type: "computer_20241022",
|
|
4290
|
-
display_width_px:
|
|
4291
|
-
display_height_px:
|
|
4292
|
-
display_number:
|
|
4298
|
+
display_width_px: tool6.args.displayWidthPx,
|
|
4299
|
+
display_height_px: tool6.args.displayHeightPx,
|
|
4300
|
+
display_number: tool6.args.displayNumber,
|
|
4293
4301
|
cache_control: void 0
|
|
4294
4302
|
});
|
|
4295
4303
|
break;
|
|
@@ -4323,7 +4331,7 @@ async function prepareTools({
|
|
|
4323
4331
|
}
|
|
4324
4332
|
case "anthropic.text_editor_20250728": {
|
|
4325
4333
|
const args = await validateTypes({
|
|
4326
|
-
value:
|
|
4334
|
+
value: tool6.args,
|
|
4327
4335
|
schema: textEditor_20250728ArgsSchema
|
|
4328
4336
|
});
|
|
4329
4337
|
anthropicTools2.push({
|
|
@@ -4363,7 +4371,7 @@ async function prepareTools({
|
|
|
4363
4371
|
case "anthropic.web_fetch_20250910": {
|
|
4364
4372
|
betas.add("web-fetch-2025-09-10");
|
|
4365
4373
|
const args = await validateTypes({
|
|
4366
|
-
value:
|
|
4374
|
+
value: tool6.args,
|
|
4367
4375
|
schema: webFetch_20250910ArgsSchema
|
|
4368
4376
|
});
|
|
4369
4377
|
anthropicTools2.push({
|
|
@@ -4381,7 +4389,7 @@ async function prepareTools({
|
|
|
4381
4389
|
case "anthropic.web_fetch_20260209": {
|
|
4382
4390
|
betas.add("code-execution-web-tools-2026-02-09");
|
|
4383
4391
|
const args = await validateTypes({
|
|
4384
|
-
value:
|
|
4392
|
+
value: tool6.args,
|
|
4385
4393
|
schema: webFetch_20260209ArgsSchema
|
|
4386
4394
|
});
|
|
4387
4395
|
anthropicTools2.push({
|
|
@@ -4398,7 +4406,7 @@ async function prepareTools({
|
|
|
4398
4406
|
}
|
|
4399
4407
|
case "anthropic.web_search_20250305": {
|
|
4400
4408
|
const args = await validateTypes({
|
|
4401
|
-
value:
|
|
4409
|
+
value: tool6.args,
|
|
4402
4410
|
schema: webSearch_20250305ArgsSchema
|
|
4403
4411
|
});
|
|
4404
4412
|
anthropicTools2.push({
|
|
@@ -4415,7 +4423,7 @@ async function prepareTools({
|
|
|
4415
4423
|
case "anthropic.web_search_20260209": {
|
|
4416
4424
|
betas.add("code-execution-web-tools-2026-02-09");
|
|
4417
4425
|
const args = await validateTypes({
|
|
4418
|
-
value:
|
|
4426
|
+
value: tool6.args,
|
|
4419
4427
|
schema: webSearch_20260209ArgsSchema
|
|
4420
4428
|
});
|
|
4421
4429
|
anthropicTools2.push({
|
|
@@ -4446,7 +4454,7 @@ async function prepareTools({
|
|
|
4446
4454
|
case "anthropic.advisor_20260301": {
|
|
4447
4455
|
betas.add("advisor-tool-2026-03-01");
|
|
4448
4456
|
const args = await validateTypes({
|
|
4449
|
-
value:
|
|
4457
|
+
value: tool6.args,
|
|
4450
4458
|
schema: advisor_20260301ArgsSchema
|
|
4451
4459
|
});
|
|
4452
4460
|
anthropicTools2.push({
|
|
@@ -4461,7 +4469,7 @@ async function prepareTools({
|
|
|
4461
4469
|
default: {
|
|
4462
4470
|
toolWarnings.push({
|
|
4463
4471
|
type: "unsupported",
|
|
4464
|
-
feature: `provider-defined tool ${
|
|
4472
|
+
feature: `provider-defined tool ${tool6.id}`
|
|
4465
4473
|
});
|
|
4466
4474
|
break;
|
|
4467
4475
|
}
|
|
@@ -4471,7 +4479,7 @@ async function prepareTools({
|
|
|
4471
4479
|
default: {
|
|
4472
4480
|
toolWarnings.push({
|
|
4473
4481
|
type: "unsupported",
|
|
4474
|
-
feature: `tool ${
|
|
4482
|
+
feature: `tool ${tool6}`
|
|
4475
4483
|
});
|
|
4476
4484
|
break;
|
|
4477
4485
|
}
|
|
@@ -6441,7 +6449,7 @@ var AnthropicMessagesLanguageModel = class {
|
|
|
6441
6449
|
betas.add("skills-2025-10-02");
|
|
6442
6450
|
betas.add("files-api-2025-04-14");
|
|
6443
6451
|
if (!(tools == null ? void 0 : tools.some(
|
|
6444
|
-
(
|
|
6452
|
+
(tool6) => tool6.type === "provider" && (tool6.id === "anthropic.code_execution_20250825" || tool6.id === "anthropic.code_execution_20260120")
|
|
6445
6453
|
))) {
|
|
6446
6454
|
warnings.push({
|
|
6447
6455
|
type: "other",
|
|
@@ -8044,12 +8052,12 @@ function hasWebTool20260209WithoutCodeExecution(tools) {
|
|
|
8044
8052
|
}
|
|
8045
8053
|
let hasWebTool20260209 = false;
|
|
8046
8054
|
let hasCodeExecutionTool = false;
|
|
8047
|
-
for (const
|
|
8048
|
-
if ("type" in
|
|
8055
|
+
for (const tool6 of tools) {
|
|
8056
|
+
if ("type" in tool6 && (tool6.type === "web_fetch_20260209" || tool6.type === "web_search_20260209")) {
|
|
8049
8057
|
hasWebTool20260209 = true;
|
|
8050
8058
|
continue;
|
|
8051
8059
|
}
|
|
8052
|
-
if (
|
|
8060
|
+
if (tool6.name === "code_execution") {
|
|
8053
8061
|
hasCodeExecutionTool = true;
|
|
8054
8062
|
break;
|
|
8055
8063
|
}
|
|
@@ -11758,8 +11766,8 @@ function prepareTools2({
|
|
|
11758
11766
|
if (tools == null) {
|
|
11759
11767
|
return { tools: void 0, toolConfig: void 0, toolWarnings };
|
|
11760
11768
|
}
|
|
11761
|
-
const hasFunctionTools = tools.some((
|
|
11762
|
-
const hasProviderTools = tools.some((
|
|
11769
|
+
const hasFunctionTools = tools.some((tool6) => tool6.type === "function");
|
|
11770
|
+
const hasProviderTools = tools.some((tool6) => tool6.type === "provider");
|
|
11763
11771
|
if (hasFunctionTools && hasProviderTools && !isGemini3orNewer) {
|
|
11764
11772
|
toolWarnings.push({
|
|
11765
11773
|
type: "unsupported",
|
|
@@ -11768,16 +11776,16 @@ function prepareTools2({
|
|
|
11768
11776
|
}
|
|
11769
11777
|
if (hasProviderTools) {
|
|
11770
11778
|
const googleTools2 = [];
|
|
11771
|
-
const ProviderTools = tools.filter((
|
|
11772
|
-
ProviderTools.forEach((
|
|
11773
|
-
switch (
|
|
11779
|
+
const ProviderTools = tools.filter((tool6) => tool6.type === "provider");
|
|
11780
|
+
ProviderTools.forEach((tool6) => {
|
|
11781
|
+
switch (tool6.id) {
|
|
11774
11782
|
case "google.google_search":
|
|
11775
11783
|
if (isGemini2orNewer) {
|
|
11776
|
-
googleTools2.push({ googleSearch: { ...
|
|
11784
|
+
googleTools2.push({ googleSearch: { ...tool6.args } });
|
|
11777
11785
|
} else {
|
|
11778
11786
|
toolWarnings.push({
|
|
11779
11787
|
type: "unsupported",
|
|
11780
|
-
feature: `provider-defined tool ${
|
|
11788
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11781
11789
|
details: "Google Search requires Gemini 2.0 or newer."
|
|
11782
11790
|
});
|
|
11783
11791
|
}
|
|
@@ -11788,7 +11796,7 @@ function prepareTools2({
|
|
|
11788
11796
|
} else {
|
|
11789
11797
|
toolWarnings.push({
|
|
11790
11798
|
type: "unsupported",
|
|
11791
|
-
feature: `provider-defined tool ${
|
|
11799
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11792
11800
|
details: "Enterprise Web Search requires Gemini 2.0 or newer."
|
|
11793
11801
|
});
|
|
11794
11802
|
}
|
|
@@ -11799,7 +11807,7 @@ function prepareTools2({
|
|
|
11799
11807
|
} else {
|
|
11800
11808
|
toolWarnings.push({
|
|
11801
11809
|
type: "unsupported",
|
|
11802
|
-
feature: `provider-defined tool ${
|
|
11810
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11803
11811
|
details: "The URL context tool is not supported with other Gemini models than Gemini 2."
|
|
11804
11812
|
});
|
|
11805
11813
|
}
|
|
@@ -11810,18 +11818,18 @@ function prepareTools2({
|
|
|
11810
11818
|
} else {
|
|
11811
11819
|
toolWarnings.push({
|
|
11812
11820
|
type: "unsupported",
|
|
11813
|
-
feature: `provider-defined tool ${
|
|
11821
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11814
11822
|
details: "The code execution tool is not supported with other Gemini models than Gemini 2."
|
|
11815
11823
|
});
|
|
11816
11824
|
}
|
|
11817
11825
|
break;
|
|
11818
11826
|
case "google.file_search":
|
|
11819
11827
|
if (supportsFileSearch) {
|
|
11820
|
-
googleTools2.push({ fileSearch: { ...
|
|
11828
|
+
googleTools2.push({ fileSearch: { ...tool6.args } });
|
|
11821
11829
|
} else {
|
|
11822
11830
|
toolWarnings.push({
|
|
11823
11831
|
type: "unsupported",
|
|
11824
|
-
feature: `provider-defined tool ${
|
|
11832
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11825
11833
|
details: "The file search tool is only supported with Gemini 2.5 models and Gemini 3 models."
|
|
11826
11834
|
});
|
|
11827
11835
|
}
|
|
@@ -11832,16 +11840,16 @@ function prepareTools2({
|
|
|
11832
11840
|
retrieval: {
|
|
11833
11841
|
vertex_rag_store: {
|
|
11834
11842
|
rag_resources: {
|
|
11835
|
-
rag_corpus:
|
|
11843
|
+
rag_corpus: tool6.args.ragCorpus
|
|
11836
11844
|
},
|
|
11837
|
-
similarity_top_k:
|
|
11845
|
+
similarity_top_k: tool6.args.topK
|
|
11838
11846
|
}
|
|
11839
11847
|
}
|
|
11840
11848
|
});
|
|
11841
11849
|
} else {
|
|
11842
11850
|
toolWarnings.push({
|
|
11843
11851
|
type: "unsupported",
|
|
11844
|
-
feature: `provider-defined tool ${
|
|
11852
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11845
11853
|
details: "The RAG store tool is not supported with other Gemini models than Gemini 2."
|
|
11846
11854
|
});
|
|
11847
11855
|
}
|
|
@@ -11852,7 +11860,7 @@ function prepareTools2({
|
|
|
11852
11860
|
} else {
|
|
11853
11861
|
toolWarnings.push({
|
|
11854
11862
|
type: "unsupported",
|
|
11855
|
-
feature: `provider-defined tool ${
|
|
11863
|
+
feature: `provider-defined tool ${tool6.id}`,
|
|
11856
11864
|
details: "The Google Maps grounding tool is not supported with Gemini models other than Gemini 2 or newer."
|
|
11857
11865
|
});
|
|
11858
11866
|
}
|
|
@@ -11860,19 +11868,19 @@ function prepareTools2({
|
|
|
11860
11868
|
default:
|
|
11861
11869
|
toolWarnings.push({
|
|
11862
11870
|
type: "unsupported",
|
|
11863
|
-
feature: `provider-defined tool ${
|
|
11871
|
+
feature: `provider-defined tool ${tool6.id}`
|
|
11864
11872
|
});
|
|
11865
11873
|
break;
|
|
11866
11874
|
}
|
|
11867
11875
|
});
|
|
11868
11876
|
if (hasFunctionTools && isGemini3orNewer && googleTools2.length > 0) {
|
|
11869
11877
|
const functionDeclarations2 = [];
|
|
11870
|
-
for (const
|
|
11871
|
-
if (
|
|
11878
|
+
for (const tool6 of tools) {
|
|
11879
|
+
if (tool6.type === "function") {
|
|
11872
11880
|
functionDeclarations2.push({
|
|
11873
|
-
name:
|
|
11874
|
-
description: (_a20 =
|
|
11875
|
-
parameters: convertJSONSchemaToOpenAPISchema(
|
|
11881
|
+
name: tool6.name,
|
|
11882
|
+
description: (_a20 = tool6.description) != null ? _a20 : "",
|
|
11883
|
+
parameters: convertJSONSchemaToOpenAPISchema(tool6.inputSchema)
|
|
11876
11884
|
});
|
|
11877
11885
|
}
|
|
11878
11886
|
}
|
|
@@ -11912,22 +11920,22 @@ function prepareTools2({
|
|
|
11912
11920
|
}
|
|
11913
11921
|
const functionDeclarations = [];
|
|
11914
11922
|
let hasStrictTools = false;
|
|
11915
|
-
for (const
|
|
11916
|
-
switch (
|
|
11923
|
+
for (const tool6 of tools) {
|
|
11924
|
+
switch (tool6.type) {
|
|
11917
11925
|
case "function":
|
|
11918
11926
|
functionDeclarations.push({
|
|
11919
|
-
name:
|
|
11920
|
-
description: (_b20 =
|
|
11921
|
-
parameters: convertJSONSchemaToOpenAPISchema(
|
|
11927
|
+
name: tool6.name,
|
|
11928
|
+
description: (_b20 = tool6.description) != null ? _b20 : "",
|
|
11929
|
+
parameters: convertJSONSchemaToOpenAPISchema(tool6.inputSchema)
|
|
11922
11930
|
});
|
|
11923
|
-
if (
|
|
11931
|
+
if (tool6.strict === true) {
|
|
11924
11932
|
hasStrictTools = true;
|
|
11925
11933
|
}
|
|
11926
11934
|
break;
|
|
11927
11935
|
default:
|
|
11928
11936
|
toolWarnings.push({
|
|
11929
11937
|
type: "unsupported",
|
|
11930
|
-
feature: `function tool ${
|
|
11938
|
+
feature: `function tool ${tool6.name}`
|
|
11931
11939
|
});
|
|
11932
11940
|
break;
|
|
11933
11941
|
}
|
|
@@ -12270,7 +12278,7 @@ var GoogleGenerativeAILanguageModel = class {
|
|
|
12270
12278
|
}
|
|
12271
12279
|
const isVertexProvider = this.config.provider.startsWith("google.vertex.");
|
|
12272
12280
|
if ((tools == null ? void 0 : tools.some(
|
|
12273
|
-
(
|
|
12281
|
+
(tool6) => tool6.type === "provider" && tool6.id === "google.vertex_rag_store"
|
|
12274
12282
|
)) && !isVertexProvider) {
|
|
12275
12283
|
warnings.push({
|
|
12276
12284
|
type: "other",
|
|
@@ -17003,23 +17011,23 @@ function prepareChatTools({
|
|
|
17003
17011
|
return { tools: void 0, toolChoice: void 0, toolWarnings };
|
|
17004
17012
|
}
|
|
17005
17013
|
const openaiTools2 = [];
|
|
17006
|
-
for (const
|
|
17007
|
-
switch (
|
|
17014
|
+
for (const tool6 of tools) {
|
|
17015
|
+
switch (tool6.type) {
|
|
17008
17016
|
case "function":
|
|
17009
17017
|
openaiTools2.push({
|
|
17010
17018
|
type: "function",
|
|
17011
17019
|
function: {
|
|
17012
|
-
name:
|
|
17013
|
-
description:
|
|
17014
|
-
parameters:
|
|
17015
|
-
...
|
|
17020
|
+
name: tool6.name,
|
|
17021
|
+
description: tool6.description,
|
|
17022
|
+
parameters: tool6.inputSchema,
|
|
17023
|
+
...tool6.strict != null ? { strict: tool6.strict } : {}
|
|
17016
17024
|
}
|
|
17017
17025
|
});
|
|
17018
17026
|
break;
|
|
17019
17027
|
default:
|
|
17020
17028
|
toolWarnings.push({
|
|
17021
17029
|
type: "unsupported",
|
|
17022
|
-
feature: `tool type: ${
|
|
17030
|
+
feature: `tool type: ${tool6.type}`
|
|
17023
17031
|
});
|
|
17024
17032
|
break;
|
|
17025
17033
|
}
|
|
@@ -20730,26 +20738,26 @@ async function prepareResponsesTools({
|
|
|
20730
20738
|
}
|
|
20731
20739
|
const openaiTools2 = [];
|
|
20732
20740
|
const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
|
|
20733
|
-
for (const
|
|
20734
|
-
switch (
|
|
20741
|
+
for (const tool6 of tools) {
|
|
20742
|
+
switch (tool6.type) {
|
|
20735
20743
|
case "function": {
|
|
20736
|
-
const openaiOptions = (_a20 =
|
|
20744
|
+
const openaiOptions = (_a20 = tool6.providerOptions) == null ? void 0 : _a20.openai;
|
|
20737
20745
|
const deferLoading = openaiOptions == null ? void 0 : openaiOptions.deferLoading;
|
|
20738
20746
|
openaiTools2.push({
|
|
20739
20747
|
type: "function",
|
|
20740
|
-
name:
|
|
20741
|
-
description:
|
|
20742
|
-
parameters:
|
|
20743
|
-
...
|
|
20748
|
+
name: tool6.name,
|
|
20749
|
+
description: tool6.description,
|
|
20750
|
+
parameters: tool6.inputSchema,
|
|
20751
|
+
...tool6.strict != null ? { strict: tool6.strict } : {},
|
|
20744
20752
|
...deferLoading != null ? { defer_loading: deferLoading } : {}
|
|
20745
20753
|
});
|
|
20746
20754
|
break;
|
|
20747
20755
|
}
|
|
20748
20756
|
case "provider": {
|
|
20749
|
-
switch (
|
|
20757
|
+
switch (tool6.id) {
|
|
20750
20758
|
case "openai.file_search": {
|
|
20751
20759
|
const args = await validateTypes3({
|
|
20752
|
-
value:
|
|
20760
|
+
value: tool6.args,
|
|
20753
20761
|
schema: fileSearchArgsSchema2
|
|
20754
20762
|
});
|
|
20755
20763
|
openaiTools2.push({
|
|
@@ -20772,7 +20780,7 @@ async function prepareResponsesTools({
|
|
|
20772
20780
|
}
|
|
20773
20781
|
case "openai.shell": {
|
|
20774
20782
|
const args = await validateTypes3({
|
|
20775
|
-
value:
|
|
20783
|
+
value: tool6.args,
|
|
20776
20784
|
schema: shellArgsSchema
|
|
20777
20785
|
});
|
|
20778
20786
|
openaiTools2.push({
|
|
@@ -20791,7 +20799,7 @@ async function prepareResponsesTools({
|
|
|
20791
20799
|
}
|
|
20792
20800
|
case "openai.web_search_preview": {
|
|
20793
20801
|
const args = await validateTypes3({
|
|
20794
|
-
value:
|
|
20802
|
+
value: tool6.args,
|
|
20795
20803
|
schema: webSearchPreviewArgsSchema
|
|
20796
20804
|
});
|
|
20797
20805
|
openaiTools2.push({
|
|
@@ -20803,7 +20811,7 @@ async function prepareResponsesTools({
|
|
|
20803
20811
|
}
|
|
20804
20812
|
case "openai.web_search": {
|
|
20805
20813
|
const args = await validateTypes3({
|
|
20806
|
-
value:
|
|
20814
|
+
value: tool6.args,
|
|
20807
20815
|
schema: webSearchArgsSchema
|
|
20808
20816
|
});
|
|
20809
20817
|
openaiTools2.push({
|
|
@@ -20817,7 +20825,7 @@ async function prepareResponsesTools({
|
|
|
20817
20825
|
}
|
|
20818
20826
|
case "openai.code_interpreter": {
|
|
20819
20827
|
const args = await validateTypes3({
|
|
20820
|
-
value:
|
|
20828
|
+
value: tool6.args,
|
|
20821
20829
|
schema: codeInterpreterArgsSchema
|
|
20822
20830
|
});
|
|
20823
20831
|
openaiTools2.push({
|
|
@@ -20828,7 +20836,7 @@ async function prepareResponsesTools({
|
|
|
20828
20836
|
}
|
|
20829
20837
|
case "openai.image_generation": {
|
|
20830
20838
|
const args = await validateTypes3({
|
|
20831
|
-
value:
|
|
20839
|
+
value: tool6.args,
|
|
20832
20840
|
schema: imageGenerationArgsSchema
|
|
20833
20841
|
});
|
|
20834
20842
|
openaiTools2.push({
|
|
@@ -20851,7 +20859,7 @@ async function prepareResponsesTools({
|
|
|
20851
20859
|
}
|
|
20852
20860
|
case "openai.mcp": {
|
|
20853
20861
|
const args = await validateTypes3({
|
|
20854
|
-
value:
|
|
20862
|
+
value: tool6.args,
|
|
20855
20863
|
schema: mcpArgsSchema
|
|
20856
20864
|
});
|
|
20857
20865
|
const mapApprovalFilter = (filter4) => ({
|
|
@@ -20877,7 +20885,7 @@ async function prepareResponsesTools({
|
|
|
20877
20885
|
}
|
|
20878
20886
|
case "openai.custom": {
|
|
20879
20887
|
const args = await validateTypes3({
|
|
20880
|
-
value:
|
|
20888
|
+
value: tool6.args,
|
|
20881
20889
|
schema: customArgsSchema
|
|
20882
20890
|
});
|
|
20883
20891
|
openaiTools2.push({
|
|
@@ -20891,7 +20899,7 @@ async function prepareResponsesTools({
|
|
|
20891
20899
|
}
|
|
20892
20900
|
case "openai.tool_search": {
|
|
20893
20901
|
const args = await validateTypes3({
|
|
20894
|
-
value:
|
|
20902
|
+
value: tool6.args,
|
|
20895
20903
|
schema: toolSearchArgsSchema
|
|
20896
20904
|
});
|
|
20897
20905
|
openaiTools2.push({
|
|
@@ -20908,7 +20916,7 @@ async function prepareResponsesTools({
|
|
|
20908
20916
|
default:
|
|
20909
20917
|
toolWarnings.push({
|
|
20910
20918
|
type: "unsupported",
|
|
20911
|
-
feature: `function tool ${
|
|
20919
|
+
feature: `function tool ${tool6}`
|
|
20912
20920
|
});
|
|
20913
20921
|
break;
|
|
20914
20922
|
}
|
|
@@ -21080,7 +21088,7 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
21080
21088
|
"openai.apply_patch": "apply_patch",
|
|
21081
21089
|
"openai.tool_search": "tool_search"
|
|
21082
21090
|
},
|
|
21083
|
-
resolveProviderToolName: (
|
|
21091
|
+
resolveProviderToolName: (tool6) => tool6.id === "openai.custom" ? tool6.args.name : void 0
|
|
21084
21092
|
});
|
|
21085
21093
|
const customProviderToolNames = /* @__PURE__ */ new Set();
|
|
21086
21094
|
const {
|
|
@@ -21117,14 +21125,14 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
21117
21125
|
}
|
|
21118
21126
|
}
|
|
21119
21127
|
function hasOpenAITool(id) {
|
|
21120
|
-
return (tools == null ? void 0 : tools.find((
|
|
21128
|
+
return (tools == null ? void 0 : tools.find((tool6) => tool6.type === "provider" && tool6.id === id)) != null;
|
|
21121
21129
|
}
|
|
21122
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;
|
|
21123
21131
|
if (topLogprobs) {
|
|
21124
21132
|
addInclude("message.output_text.logprobs");
|
|
21125
21133
|
}
|
|
21126
21134
|
const webSearchToolName = (_e = tools == null ? void 0 : tools.find(
|
|
21127
|
-
(
|
|
21135
|
+
(tool6) => tool6.type === "provider" && (tool6.id === "openai.web_search" || tool6.id === "openai.web_search_preview")
|
|
21128
21136
|
)) == null ? void 0 : _e.name;
|
|
21129
21137
|
if (webSearchToolName) {
|
|
21130
21138
|
addInclude("web_search_call.action.sources");
|
|
@@ -21238,7 +21246,7 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
21238
21246
|
delete baseArgs.service_tier;
|
|
21239
21247
|
}
|
|
21240
21248
|
const shellToolEnvType = (_i = (_h = (_g = tools == null ? void 0 : tools.find(
|
|
21241
|
-
(
|
|
21249
|
+
(tool6) => tool6.type === "provider" && tool6.id === "openai.shell"
|
|
21242
21250
|
)) == null ? void 0 : _g.args) == null ? void 0 : _h.environment) == null ? void 0 : _i.type;
|
|
21243
21251
|
const isShellProviderExecuted = shellToolEnvType === "containerAuto" || shellToolEnvType === "containerReference";
|
|
21244
21252
|
return {
|
|
@@ -23493,7 +23501,8 @@ function getModel(provider, opts) {
|
|
|
23493
23501
|
usage: { include: true },
|
|
23494
23502
|
...isMoonshot ? { provider: { order: ["moonshotai"], allow_fallbacks: true } } : {}
|
|
23495
23503
|
};
|
|
23496
|
-
|
|
23504
|
+
const gatewayModelId = baseURL ? `openrouter/${modelId}` : modelId;
|
|
23505
|
+
return openrouter(gatewayModelId, settings);
|
|
23497
23506
|
}
|
|
23498
23507
|
case "xai": {
|
|
23499
23508
|
if (baseURL) {
|
|
@@ -24104,11 +24113,404 @@ function linkifyCitations(markdown, results) {
|
|
|
24104
24113
|
return { content, converted, skipped };
|
|
24105
24114
|
}
|
|
24106
24115
|
|
|
24116
|
+
// src/fetch.ts
|
|
24117
|
+
var import_ai3 = require("ai");
|
|
24118
|
+
var import_zod2 = require("zod");
|
|
24119
|
+
var import_node_net = require("net");
|
|
24120
|
+
var import_promises = require("dns/promises");
|
|
24121
|
+
var WEB_FETCH_TOOL_NAME = "web_fetch";
|
|
24122
|
+
var DEFAULT_MAX_USES2 = 5;
|
|
24123
|
+
var DEFAULT_MAX_CHARACTERS2 = 4e4;
|
|
24124
|
+
var CHARS_PER_TOKEN = 4;
|
|
24125
|
+
var DEFAULT_TIMEOUT_MS = 2e4;
|
|
24126
|
+
var MAX_REDIRECTS = 5;
|
|
24127
|
+
var MAX_BODY_BYTES = 4 * 1024 * 1024;
|
|
24128
|
+
var USER_AGENT = "aieo-web-fetch/1 (+https://github.com/stakwork/stakgraph)";
|
|
24129
|
+
var ACCEPT = "text/html, application/xhtml+xml, text/plain;q=0.9, application/json;q=0.9, text/*;q=0.8, */*;q=0.5";
|
|
24130
|
+
function resolveFetchBackend(provider) {
|
|
24131
|
+
return provider === "anthropic" ? "anthropic" : "http";
|
|
24132
|
+
}
|
|
24133
|
+
var PRIVATE_ADDRESSES = buildBlockList();
|
|
24134
|
+
function buildBlockList() {
|
|
24135
|
+
const b = new import_node_net.BlockList();
|
|
24136
|
+
const v42 = [
|
|
24137
|
+
["0.0.0.0", 8],
|
|
24138
|
+
// "this" network
|
|
24139
|
+
["10.0.0.0", 8],
|
|
24140
|
+
// RFC 1918
|
|
24141
|
+
["100.64.0.0", 10],
|
|
24142
|
+
// carrier-grade NAT
|
|
24143
|
+
["127.0.0.0", 8],
|
|
24144
|
+
// loopback
|
|
24145
|
+
["169.254.0.0", 16],
|
|
24146
|
+
// link-local, incl. cloud metadata at 169.254.169.254
|
|
24147
|
+
["172.16.0.0", 12],
|
|
24148
|
+
// RFC 1918
|
|
24149
|
+
["192.0.0.0", 24],
|
|
24150
|
+
// IETF protocol assignments
|
|
24151
|
+
["192.168.0.0", 16],
|
|
24152
|
+
// RFC 1918
|
|
24153
|
+
["198.18.0.0", 15],
|
|
24154
|
+
// benchmarking
|
|
24155
|
+
["224.0.0.0", 4],
|
|
24156
|
+
// multicast
|
|
24157
|
+
["240.0.0.0", 4]
|
|
24158
|
+
// reserved, incl. broadcast
|
|
24159
|
+
];
|
|
24160
|
+
for (const [net, prefix] of v42) b.addSubnet(net, prefix, "ipv4");
|
|
24161
|
+
b.addAddress("::", "ipv6");
|
|
24162
|
+
b.addAddress("::1", "ipv6");
|
|
24163
|
+
const v6 = [
|
|
24164
|
+
["64:ff9b::", 96],
|
|
24165
|
+
// NAT64
|
|
24166
|
+
["2002::", 16],
|
|
24167
|
+
// 6to4
|
|
24168
|
+
["fc00::", 7],
|
|
24169
|
+
// unique local
|
|
24170
|
+
["fe80::", 10],
|
|
24171
|
+
// link-local
|
|
24172
|
+
["fec0::", 10],
|
|
24173
|
+
// site-local (deprecated, still routed on old gear)
|
|
24174
|
+
["ff00::", 8]
|
|
24175
|
+
// multicast
|
|
24176
|
+
];
|
|
24177
|
+
for (const [net, prefix] of v6) b.addSubnet(net, prefix, "ipv6");
|
|
24178
|
+
return b;
|
|
24179
|
+
}
|
|
24180
|
+
function isPrivateAddress(ip) {
|
|
24181
|
+
const bare = ip.startsWith("[") && ip.endsWith("]") ? ip.slice(1, -1) : ip;
|
|
24182
|
+
const family = (0, import_node_net.isIP)(bare);
|
|
24183
|
+
try {
|
|
24184
|
+
if (family === 4) return PRIVATE_ADDRESSES.check(bare, "ipv4");
|
|
24185
|
+
if (family === 6) return PRIVATE_ADDRESSES.check(bare, "ipv6");
|
|
24186
|
+
} catch {
|
|
24187
|
+
}
|
|
24188
|
+
return true;
|
|
24189
|
+
}
|
|
24190
|
+
var defaultLookup = async (hostname) => {
|
|
24191
|
+
const addresses = await (0, import_promises.lookup)(hostname, { all: true });
|
|
24192
|
+
return addresses.map((a) => a.address);
|
|
24193
|
+
};
|
|
24194
|
+
function matchesDomain(host, domains) {
|
|
24195
|
+
return domains.some((d) => {
|
|
24196
|
+
const dom = d.trim().toLowerCase().replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/^\*\./, "").replace(/\.$/, "");
|
|
24197
|
+
return !!dom && (host === dom || host.endsWith("." + dom));
|
|
24198
|
+
});
|
|
24199
|
+
}
|
|
24200
|
+
async function validateFetchUrl(raw, opts = {}) {
|
|
24201
|
+
let url;
|
|
24202
|
+
try {
|
|
24203
|
+
url = new URL(raw);
|
|
24204
|
+
} catch {
|
|
24205
|
+
throw new Error(`Not a valid absolute URL: ${raw}`);
|
|
24206
|
+
}
|
|
24207
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
24208
|
+
throw new Error(`Only http(s) URLs can be fetched, got ${url.protocol}`);
|
|
24209
|
+
}
|
|
24210
|
+
if (url.username || url.password) {
|
|
24211
|
+
throw new Error("URLs with embedded credentials are not fetched");
|
|
24212
|
+
}
|
|
24213
|
+
const host = url.hostname.replace(/\.$/, "").toLowerCase();
|
|
24214
|
+
if (!host) throw new Error("URL has no host");
|
|
24215
|
+
if (host === "localhost" || host.endsWith(".localhost")) {
|
|
24216
|
+
throw new Error("Refusing to fetch a local address");
|
|
24217
|
+
}
|
|
24218
|
+
if (opts.allowedDomains?.length && !matchesDomain(host, opts.allowedDomains)) {
|
|
24219
|
+
throw new Error(`${host} is not in the allowed domains`);
|
|
24220
|
+
}
|
|
24221
|
+
if (opts.blockedDomains?.length && matchesDomain(host, opts.blockedDomains)) {
|
|
24222
|
+
throw new Error(`${host} is a blocked domain`);
|
|
24223
|
+
}
|
|
24224
|
+
const literal = host.startsWith("[") ? host.slice(1, -1) : host;
|
|
24225
|
+
if ((0, import_node_net.isIP)(literal)) {
|
|
24226
|
+
if (isPrivateAddress(literal)) {
|
|
24227
|
+
throw new Error("Refusing to fetch a private or reserved address");
|
|
24228
|
+
}
|
|
24229
|
+
return url;
|
|
24230
|
+
}
|
|
24231
|
+
let addresses;
|
|
24232
|
+
try {
|
|
24233
|
+
addresses = await (opts.lookup ?? defaultLookup)(host);
|
|
24234
|
+
} catch (err) {
|
|
24235
|
+
throw new Error(
|
|
24236
|
+
`Could not resolve ${host}: ${err instanceof Error ? err.message : String(err)}`
|
|
24237
|
+
);
|
|
24238
|
+
}
|
|
24239
|
+
if (!addresses.length) throw new Error(`Could not resolve ${host}`);
|
|
24240
|
+
if (addresses.some(isPrivateAddress)) {
|
|
24241
|
+
throw new Error(`Refusing to fetch ${host}: it resolves to a private or reserved address`);
|
|
24242
|
+
}
|
|
24243
|
+
return url;
|
|
24244
|
+
}
|
|
24245
|
+
async function fetchUrl(rawUrl, opts = {}) {
|
|
24246
|
+
const maxCharacters = opts.maxCharacters ?? DEFAULT_MAX_CHARACTERS2;
|
|
24247
|
+
const signals = [AbortSignal.timeout(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS)];
|
|
24248
|
+
if (opts.abortSignal) signals.push(opts.abortSignal);
|
|
24249
|
+
const signal = AbortSignal.any(signals);
|
|
24250
|
+
let url = await validateFetchUrl(rawUrl, opts);
|
|
24251
|
+
let res;
|
|
24252
|
+
for (let hop = 0; ; hop++) {
|
|
24253
|
+
try {
|
|
24254
|
+
res = await fetch(url, {
|
|
24255
|
+
method: "GET",
|
|
24256
|
+
redirect: "manual",
|
|
24257
|
+
signal,
|
|
24258
|
+
headers: { "user-agent": USER_AGENT, accept: ACCEPT }
|
|
24259
|
+
});
|
|
24260
|
+
} catch (err) {
|
|
24261
|
+
throw new Error(`Could not connect to ${url.hostname}: ${describeTransportError(err)}`);
|
|
24262
|
+
}
|
|
24263
|
+
if (!isRedirect(res.status)) break;
|
|
24264
|
+
const location = res.headers.get("location");
|
|
24265
|
+
await discard(res);
|
|
24266
|
+
if (!location) throw new Error(`Redirect (${res.status}) without a Location header`);
|
|
24267
|
+
if (hop >= MAX_REDIRECTS) throw new Error(`Too many redirects (more than ${MAX_REDIRECTS})`);
|
|
24268
|
+
let next;
|
|
24269
|
+
try {
|
|
24270
|
+
next = new URL(location, url).toString();
|
|
24271
|
+
} catch {
|
|
24272
|
+
throw new Error(`Redirect to an invalid URL: ${location}`);
|
|
24273
|
+
}
|
|
24274
|
+
url = await validateFetchUrl(next, opts);
|
|
24275
|
+
}
|
|
24276
|
+
if (!res.ok) {
|
|
24277
|
+
await discard(res);
|
|
24278
|
+
throw new Error(`HTTP ${res.status} fetching ${url.hostname}`);
|
|
24279
|
+
}
|
|
24280
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
24281
|
+
const mediaType = contentType.split(";")[0].trim().toLowerCase() || null;
|
|
24282
|
+
if (mediaType === "application/pdf") {
|
|
24283
|
+
await discard(res);
|
|
24284
|
+
throw new Error(
|
|
24285
|
+
"PDF documents are not supported by this fetch backend (only Anthropic's native web_fetch reads PDFs)"
|
|
24286
|
+
);
|
|
24287
|
+
}
|
|
24288
|
+
if (!isTextual(mediaType)) {
|
|
24289
|
+
await discard(res);
|
|
24290
|
+
throw new Error(`Unsupported content type: ${mediaType}`);
|
|
24291
|
+
}
|
|
24292
|
+
const { bytes, capped } = await readCapped(res, MAX_BODY_BYTES);
|
|
24293
|
+
const raw = decode(bytes, contentType);
|
|
24294
|
+
const isHtml = mediaType === "text/html" || mediaType === "application/xhtml+xml" || looksLikeHtml(raw);
|
|
24295
|
+
const { title, text } = isHtml ? htmlToText(raw) : { title: null, text: raw.trim() };
|
|
24296
|
+
const truncated = capped || text.length > maxCharacters;
|
|
24297
|
+
return {
|
|
24298
|
+
url: url.toString(),
|
|
24299
|
+
title,
|
|
24300
|
+
text: truncated ? text.slice(0, maxCharacters) : text,
|
|
24301
|
+
mediaType,
|
|
24302
|
+
retrievedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24303
|
+
truncated,
|
|
24304
|
+
type: "web_fetch_result"
|
|
24305
|
+
};
|
|
24306
|
+
}
|
|
24307
|
+
function describeTransportError(err) {
|
|
24308
|
+
const e = err;
|
|
24309
|
+
if (e?.name === "TimeoutError") return "timed out";
|
|
24310
|
+
if (e?.name === "AbortError") return "aborted";
|
|
24311
|
+
const cause = e?.cause;
|
|
24312
|
+
if (cause?.message) return cause.code ? `${cause.message} (${cause.code})` : cause.message;
|
|
24313
|
+
return e?.message ?? String(err);
|
|
24314
|
+
}
|
|
24315
|
+
function isRedirect(status) {
|
|
24316
|
+
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
24317
|
+
}
|
|
24318
|
+
async function discard(res) {
|
|
24319
|
+
await res.body?.cancel().catch(() => {
|
|
24320
|
+
});
|
|
24321
|
+
}
|
|
24322
|
+
function isTextual(mediaType) {
|
|
24323
|
+
if (!mediaType) return true;
|
|
24324
|
+
if (mediaType.startsWith("text/")) return true;
|
|
24325
|
+
if (mediaType.endsWith("+json") || mediaType.endsWith("+xml")) return true;
|
|
24326
|
+
return mediaType === "application/json" || mediaType === "application/xml" || mediaType === "application/xhtml+xml" || mediaType === "application/javascript";
|
|
24327
|
+
}
|
|
24328
|
+
async function readCapped(res, maxBytes) {
|
|
24329
|
+
const body = res.body;
|
|
24330
|
+
if (!body) return { bytes: new Uint8Array(await res.arrayBuffer()), capped: false };
|
|
24331
|
+
const reader = body.getReader();
|
|
24332
|
+
const chunks = [];
|
|
24333
|
+
let total = 0;
|
|
24334
|
+
let capped = false;
|
|
24335
|
+
for (; ; ) {
|
|
24336
|
+
const { done, value } = await reader.read();
|
|
24337
|
+
if (done) break;
|
|
24338
|
+
if (!value) continue;
|
|
24339
|
+
if (total + value.byteLength > maxBytes) {
|
|
24340
|
+
chunks.push(value.subarray(0, maxBytes - total));
|
|
24341
|
+
total = maxBytes;
|
|
24342
|
+
capped = true;
|
|
24343
|
+
await reader.cancel().catch(() => {
|
|
24344
|
+
});
|
|
24345
|
+
break;
|
|
24346
|
+
}
|
|
24347
|
+
chunks.push(value);
|
|
24348
|
+
total += value.byteLength;
|
|
24349
|
+
}
|
|
24350
|
+
const out = new Uint8Array(total);
|
|
24351
|
+
let offset = 0;
|
|
24352
|
+
for (const c of chunks) {
|
|
24353
|
+
out.set(c, offset);
|
|
24354
|
+
offset += c.byteLength;
|
|
24355
|
+
}
|
|
24356
|
+
return { bytes: out, capped };
|
|
24357
|
+
}
|
|
24358
|
+
function decode(bytes, contentType) {
|
|
24359
|
+
const charset = /charset=["']?([\w.:-]+)/i.exec(contentType)?.[1] ?? "utf-8";
|
|
24360
|
+
try {
|
|
24361
|
+
return new TextDecoder(charset).decode(bytes);
|
|
24362
|
+
} catch {
|
|
24363
|
+
return new TextDecoder("utf-8").decode(bytes);
|
|
24364
|
+
}
|
|
24365
|
+
}
|
|
24366
|
+
function looksLikeHtml(s) {
|
|
24367
|
+
return /^\s*(?:<!doctype\s+html|<html[\s>]|<head[\s>]|<body[\s>])/i.test(s.slice(0, 1024));
|
|
24368
|
+
}
|
|
24369
|
+
var NAMED_ENTITIES = {
|
|
24370
|
+
nbsp: " ",
|
|
24371
|
+
lt: "<",
|
|
24372
|
+
gt: ">",
|
|
24373
|
+
quot: '"',
|
|
24374
|
+
apos: "'",
|
|
24375
|
+
mdash: "\u2014",
|
|
24376
|
+
ndash: "\u2013",
|
|
24377
|
+
hellip: "\u2026",
|
|
24378
|
+
copy: "\xA9",
|
|
24379
|
+
reg: "\xAE",
|
|
24380
|
+
trade: "\u2122",
|
|
24381
|
+
laquo: "\xAB",
|
|
24382
|
+
raquo: "\xBB",
|
|
24383
|
+
ldquo: "\u201C",
|
|
24384
|
+
rdquo: "\u201D",
|
|
24385
|
+
lsquo: "\u2018",
|
|
24386
|
+
rsquo: "\u2019",
|
|
24387
|
+
bull: "\u2022",
|
|
24388
|
+
middot: "\xB7",
|
|
24389
|
+
times: "\xD7",
|
|
24390
|
+
deg: "\xB0"
|
|
24391
|
+
};
|
|
24392
|
+
function codePoint(cp, fallback) {
|
|
24393
|
+
if (!Number.isFinite(cp) || cp <= 0 || cp > 1114111 || cp >= 55296 && cp <= 57343) {
|
|
24394
|
+
return fallback;
|
|
24395
|
+
}
|
|
24396
|
+
return String.fromCodePoint(cp);
|
|
24397
|
+
}
|
|
24398
|
+
function decodeEntities(s) {
|
|
24399
|
+
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, "&");
|
|
24400
|
+
}
|
|
24401
|
+
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";
|
|
24402
|
+
function htmlToText(html) {
|
|
24403
|
+
const titleMatch = /<title[^>]*>([\s\S]*?)<\/title>/i.exec(html);
|
|
24404
|
+
const title = titleMatch ? decodeEntities(titleMatch[1]).replace(/\s+/g, " ").trim() || null : null;
|
|
24405
|
+
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, " ");
|
|
24406
|
+
const text = decodeEntities(stripped).replace(/[ \t\r\f\v ]+/g, " ").replace(/ ?\n ?/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
24407
|
+
return { title, text };
|
|
24408
|
+
}
|
|
24409
|
+
function createWebFetch(opts) {
|
|
24410
|
+
const results = [];
|
|
24411
|
+
const backend = opts.backend ?? resolveFetchBackend(opts.provider);
|
|
24412
|
+
const maxUses = opts.maxUses ?? DEFAULT_MAX_USES2;
|
|
24413
|
+
const maxCharacters = opts.maxCharacters ?? (opts.maxContentTokens ? opts.maxContentTokens * CHARS_PER_TOKEN : DEFAULT_MAX_CHARACTERS2);
|
|
24414
|
+
const maxContentTokens = opts.maxContentTokens ?? (opts.maxCharacters ? Math.ceil(opts.maxCharacters / CHARS_PER_TOKEN) : void 0);
|
|
24415
|
+
if (backend === "anthropic") {
|
|
24416
|
+
const apiKey = normalizeApiKey(opts.apiKey) || normalizeApiKey(process.env.ANTHROPIC_API_KEY);
|
|
24417
|
+
if (!apiKey) {
|
|
24418
|
+
return emptyFetchHandle(results);
|
|
24419
|
+
}
|
|
24420
|
+
const baseURL = getGatewayBaseURL("anthropic");
|
|
24421
|
+
const anthropic2 = createAnthropic({ apiKey, ...baseURL && { baseURL } });
|
|
24422
|
+
return {
|
|
24423
|
+
tool: anthropic2.tools.webFetch_20250910({
|
|
24424
|
+
maxUses,
|
|
24425
|
+
...maxContentTokens ? { maxContentTokens } : {},
|
|
24426
|
+
...opts.allowedDomains?.length ? { allowedDomains: opts.allowedDomains } : {},
|
|
24427
|
+
...opts.blockedDomains?.length ? { blockedDomains: opts.blockedDomains } : {}
|
|
24428
|
+
}),
|
|
24429
|
+
backend,
|
|
24430
|
+
native: true,
|
|
24431
|
+
results,
|
|
24432
|
+
capture: (stepContent) => captureNativeFetchResults(stepContent, results)
|
|
24433
|
+
};
|
|
24434
|
+
}
|
|
24435
|
+
let uses = 0;
|
|
24436
|
+
return {
|
|
24437
|
+
tool: (0, import_ai3.tool)({
|
|
24438
|
+
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.",
|
|
24439
|
+
inputSchema: import_zod2.z.object({
|
|
24440
|
+
url: import_zod2.z.string().describe("The absolute http(s) URL to fetch.")
|
|
24441
|
+
}),
|
|
24442
|
+
execute: async ({ url }, ctx) => {
|
|
24443
|
+
if (uses >= maxUses) {
|
|
24444
|
+
return {
|
|
24445
|
+
error: `web_fetch budget exhausted (${maxUses} calls). Work with what you have.`
|
|
24446
|
+
};
|
|
24447
|
+
}
|
|
24448
|
+
uses++;
|
|
24449
|
+
try {
|
|
24450
|
+
const page = await fetchUrl(url, {
|
|
24451
|
+
maxCharacters,
|
|
24452
|
+
allowedDomains: opts.allowedDomains,
|
|
24453
|
+
blockedDomains: opts.blockedDomains,
|
|
24454
|
+
abortSignal: ctx?.abortSignal ?? opts.abortSignal,
|
|
24455
|
+
lookup: opts.lookup
|
|
24456
|
+
});
|
|
24457
|
+
results.push(page);
|
|
24458
|
+
return page;
|
|
24459
|
+
} catch (err) {
|
|
24460
|
+
return {
|
|
24461
|
+
error: `Fetch failed: ${err instanceof Error ? err.message : String(err)}`
|
|
24462
|
+
};
|
|
24463
|
+
}
|
|
24464
|
+
}
|
|
24465
|
+
}),
|
|
24466
|
+
backend,
|
|
24467
|
+
native: false,
|
|
24468
|
+
results,
|
|
24469
|
+
// HTTP results are appended by `execute` above; walking the step
|
|
24470
|
+
// would double-count them.
|
|
24471
|
+
capture: () => {
|
|
24472
|
+
}
|
|
24473
|
+
};
|
|
24474
|
+
}
|
|
24475
|
+
function emptyFetchHandle(results) {
|
|
24476
|
+
return {
|
|
24477
|
+
tool: void 0,
|
|
24478
|
+
backend: void 0,
|
|
24479
|
+
native: false,
|
|
24480
|
+
results,
|
|
24481
|
+
capture: () => {
|
|
24482
|
+
}
|
|
24483
|
+
};
|
|
24484
|
+
}
|
|
24485
|
+
function captureNativeFetchResults(stepContent, target) {
|
|
24486
|
+
if (!Array.isArray(stepContent)) return;
|
|
24487
|
+
for (const content of stepContent) {
|
|
24488
|
+
if (content?.type !== "tool-result") continue;
|
|
24489
|
+
if (content?.toolName !== WEB_FETCH_TOOL_NAME) continue;
|
|
24490
|
+
const body = content.output ?? content.result ?? null;
|
|
24491
|
+
if (!body || typeof body !== "object") continue;
|
|
24492
|
+
if (body.type !== "web_fetch_result" || typeof body.url !== "string") continue;
|
|
24493
|
+
const doc = body.content ?? {};
|
|
24494
|
+
const source = doc.source ?? {};
|
|
24495
|
+
target.push({
|
|
24496
|
+
url: body.url,
|
|
24497
|
+
title: doc.title ?? null,
|
|
24498
|
+
...source.type === "text" && typeof source.data === "string" ? { text: source.data } : {},
|
|
24499
|
+
mediaType: source.mediaType ?? source.media_type ?? null,
|
|
24500
|
+
retrievedAt: body.retrievedAt ?? body.retrieved_at ?? null,
|
|
24501
|
+
type: "web_fetch_result"
|
|
24502
|
+
});
|
|
24503
|
+
}
|
|
24504
|
+
}
|
|
24505
|
+
|
|
24107
24506
|
// src/tools.ts
|
|
24108
24507
|
function getProviderTool(provider, apiKey, toolName) {
|
|
24109
24508
|
if (toolName === "webSearch") {
|
|
24110
24509
|
return createWebSearch({ provider, apiKey }).tool;
|
|
24111
24510
|
}
|
|
24511
|
+
if (toolName === "webFetch") {
|
|
24512
|
+
return createWebFetch({ provider, apiKey }).tool;
|
|
24513
|
+
}
|
|
24112
24514
|
switch (provider) {
|
|
24113
24515
|
case "anthropic":
|
|
24114
24516
|
return getAnthropicTool(apiKey, toolName);
|
|
@@ -24165,16 +24567,20 @@ function consoleLogger(name19) {
|
|
|
24165
24567
|
OUTRO,
|
|
24166
24568
|
PROVIDERS,
|
|
24167
24569
|
SYSTEM,
|
|
24570
|
+
WEB_FETCH_TOOL_NAME,
|
|
24168
24571
|
WEB_SEARCH_TOOL_NAME,
|
|
24169
24572
|
addUsage,
|
|
24170
24573
|
callGenerateObject,
|
|
24171
24574
|
callGenerateText,
|
|
24172
24575
|
callModel,
|
|
24576
|
+
captureNativeFetchResults,
|
|
24173
24577
|
captureNativeResults,
|
|
24174
24578
|
computeSessionCost,
|
|
24175
24579
|
consoleLogger,
|
|
24580
|
+
createWebFetch,
|
|
24176
24581
|
createWebSearch,
|
|
24177
24582
|
emptyUsage,
|
|
24583
|
+
fetchUrl,
|
|
24178
24584
|
gatewayEnvForProviders,
|
|
24179
24585
|
gatewayUrlFor,
|
|
24180
24586
|
gatewayUrlForModel,
|
|
@@ -24191,15 +24597,19 @@ function consoleLogger(name19) {
|
|
|
24191
24597
|
getTokenPricing,
|
|
24192
24598
|
hasApiKeyForProvider,
|
|
24193
24599
|
hasSearchApiKey,
|
|
24600
|
+
htmlToText,
|
|
24601
|
+
isPrivateAddress,
|
|
24194
24602
|
linkifyCitations,
|
|
24195
24603
|
loadModelPricing,
|
|
24196
24604
|
normalizeApiKey,
|
|
24197
24605
|
normalizeCallerBaseURL,
|
|
24198
24606
|
normalizeUsage,
|
|
24607
|
+
resolveFetchBackend,
|
|
24199
24608
|
resolveLLMConfig,
|
|
24200
24609
|
resolveSearchBackend,
|
|
24201
24610
|
searchWeb,
|
|
24202
24611
|
stripCitations,
|
|
24612
|
+
validateFetchUrl,
|
|
24203
24613
|
withLegacyUsage,
|
|
24204
24614
|
withProviderCacheUsage
|
|
24205
24615
|
});
|