@nemesis-oss/ollama-sdk 1.12.1 → 1.14.0
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/CHANGELOG.md +50 -0
- package/README.md +145 -5
- package/dist/{anthropic-CKp5TmAP.d.ts → anthropic-DrDUfbfQ.d.ts} +65 -18
- package/dist/{anthropic-Did0lQxP.d.cts → anthropic-UeaVjLeP.d.cts} +65 -18
- package/dist/{compose-6UOPEknN.d.ts → compose-CeFbHJeO.d.ts} +1 -1
- package/dist/{compose-DhvoUrWa.d.cts → compose-DFkmtUOP.d.cts} +1 -1
- package/dist/generated-api.cjs +3 -2
- package/dist/generated-api.cjs.map +1 -1
- package/dist/generated-api.d.cts +15 -9
- package/dist/generated-api.d.ts +15 -9
- package/dist/generated-api.js +3 -2
- package/dist/generated-api.js.map +1 -1
- package/dist/generated-models-schemas.cjs +1 -1
- package/dist/generated-models-schemas.cjs.map +1 -1
- package/dist/generated-models-schemas.js +1 -1
- package/dist/generated-models-schemas.js.map +1 -1
- package/dist/generated-runtime.cjs +2 -1
- package/dist/generated-runtime.cjs.map +1 -1
- package/dist/generated-runtime.d.cts +2 -2
- package/dist/generated-runtime.d.ts +2 -2
- package/dist/generated-runtime.js +2 -1
- package/dist/generated-runtime.js.map +1 -1
- package/dist/index.cjs +209 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -12
- package/dist/index.d.ts +103 -12
- package/dist/index.js +203 -26
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools.json +4 -4
- package/dist/mcp-generated.cjs +3 -2
- package/dist/mcp-generated.cjs.map +1 -1
- package/dist/mcp-generated.d.cts +2 -2
- package/dist/mcp-generated.d.ts +2 -2
- package/dist/mcp-generated.js +3 -2
- package/dist/mcp-generated.js.map +1 -1
- package/dist/{runtime-CIQYCRL3.d.ts → runtime-BIjr5ME4.d.ts} +1 -1
- package/dist/{runtime-DmI1cOEq.d.cts → runtime-C4RRHqOs.d.cts} +1 -1
- package/dist/skills.d.cts +3 -3
- package/dist/skills.d.ts +3 -3
- package/dist/testing.cjs +281 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +336 -0
- package/dist/testing.d.ts +336 -0
- package/dist/testing.js +275 -0
- package/dist/testing.js.map +1 -0
- package/dist/{types-B57ZZfp3.d.cts → types-DbPnfVh-.d.cts} +20 -3
- package/dist/{types-B57ZZfp3.d.ts → types-DbPnfVh-.d.ts} +20 -3
- package/package.json +14 -1
package/dist/index.cjs
CHANGED
|
@@ -2817,12 +2817,29 @@ var ModelsClient = class {
|
|
|
2817
2817
|
* await client.models.createModelFromGguf('my-model', '/path/to/model.gguf', {
|
|
2818
2818
|
* template: '{{ .Prompt }}',
|
|
2819
2819
|
* });
|
|
2820
|
+
*
|
|
2821
|
+
* // Speculative decoding: primary + draft shards + tuning:
|
|
2822
|
+
* await client.models.createModelFromGguf('my-model', '/path/to/model.gguf', {
|
|
2823
|
+
* draftGguf: '/path/to/draft.gguf',
|
|
2824
|
+
* draftQuantize: 'q8_0',
|
|
2825
|
+
* parameters: { draft_num_predict: 8 },
|
|
2826
|
+
* });
|
|
2820
2827
|
* ```
|
|
2821
2828
|
*
|
|
2829
|
+
* Speculative-decoding models assemble the same way: pass the draft
|
|
2830
|
+
* network's GGUF(s) as `draftGguf` (uploaded into `draft_files`), optionally
|
|
2831
|
+
* set `draft_quantize` to compress the draft weights independently of the
|
|
2832
|
+
* primary model, and set `parameters.draft_num_predict` to tune how many
|
|
2833
|
+
* tokens the draft network predicts per step (Ollama defaults separate
|
|
2834
|
+
* draft models to 4; `0` disables drafting; models with embedded MTP
|
|
2835
|
+
* tensors require setting it explicitly).
|
|
2836
|
+
*
|
|
2822
2837
|
* @param model Name for the new model (e.g. `'my-model:latest'`).
|
|
2823
2838
|
* @param gguf Path(s) to GGUF file(s) on the local filesystem.
|
|
2824
2839
|
* @param opts Everything else `/api/create` accepts (`template`, `system`,
|
|
2825
|
-
* `parameters`, `license`, `quantize`, …) except `files
|
|
2840
|
+
* `parameters`, `license`, `quantize`, `draftGguf`, …) except `files`,
|
|
2841
|
+
* `draft_files` (use `draftGguf` for path-based drafts; an explicit digest
|
|
2842
|
+
* map is still accepted and merged), `from`, and `stream`.
|
|
2826
2843
|
*/
|
|
2827
2844
|
async createModelFromGguf(model, gguf, opts) {
|
|
2828
2845
|
const paths = typeof gguf === "string" ? [gguf] : gguf;
|
|
@@ -2836,14 +2853,29 @@ var ModelsClient = class {
|
|
|
2836
2853
|
const uploaded = await this.createBlobFromFile(path, { signal: opts?.signal });
|
|
2837
2854
|
files[uploaded.fileName] = uploaded.digest;
|
|
2838
2855
|
}
|
|
2856
|
+
const draftOpt = opts?.draftGguf;
|
|
2857
|
+
const draftPaths = typeof draftOpt === "string" ? [draftOpt] : draftOpt ?? [];
|
|
2839
2858
|
const {
|
|
2840
2859
|
model: _model,
|
|
2841
2860
|
files: _files,
|
|
2842
2861
|
from: _from,
|
|
2843
2862
|
stream: _stream,
|
|
2863
|
+
draftGguf: _draftGguf,
|
|
2864
|
+
draft_files: _draftFiles,
|
|
2844
2865
|
...rest
|
|
2845
2866
|
} = opts ?? {};
|
|
2846
|
-
|
|
2867
|
+
const draftFiles = { ..._draftFiles ?? {} };
|
|
2868
|
+
for (const path of draftPaths) {
|
|
2869
|
+
const uploaded = await this.createBlobFromFile(path, { signal: opts?.signal });
|
|
2870
|
+
draftFiles[uploaded.fileName] = uploaded.digest;
|
|
2871
|
+
}
|
|
2872
|
+
return this.create({
|
|
2873
|
+
...rest,
|
|
2874
|
+
model,
|
|
2875
|
+
files,
|
|
2876
|
+
...Object.keys(draftFiles).length > 0 ? { draft_files: draftFiles } : {},
|
|
2877
|
+
stream: false
|
|
2878
|
+
});
|
|
2847
2879
|
}
|
|
2848
2880
|
};
|
|
2849
2881
|
|
|
@@ -2851,7 +2883,11 @@ var ModelsClient = class {
|
|
|
2851
2883
|
var OpenAIResponsesStreamError = class extends OllamaClientError {
|
|
2852
2884
|
responsePayload;
|
|
2853
2885
|
constructor(message, responsePayload) {
|
|
2854
|
-
super(message, {
|
|
2886
|
+
super(message, {
|
|
2887
|
+
code: "openai_responses_stream_error",
|
|
2888
|
+
retryable: false,
|
|
2889
|
+
response: { body: responsePayload }
|
|
2890
|
+
});
|
|
2855
2891
|
this.responsePayload = responsePayload;
|
|
2856
2892
|
}
|
|
2857
2893
|
};
|
|
@@ -2993,7 +3029,9 @@ var OpenAIChatCompletionStream = class {
|
|
|
2993
3029
|
} finally {
|
|
2994
3030
|
if (!completed) {
|
|
2995
3031
|
this.source.abort?.();
|
|
2996
|
-
this.rejectFinal(
|
|
3032
|
+
this.rejectFinal(
|
|
3033
|
+
new OllamaAbortError("OpenAI Chat Completion stream ended before completion")
|
|
3034
|
+
);
|
|
2997
3035
|
}
|
|
2998
3036
|
}
|
|
2999
3037
|
}
|
|
@@ -3122,7 +3160,14 @@ var OpenAIResponsesStream = class {
|
|
|
3122
3160
|
existing.kind = kind;
|
|
3123
3161
|
return existing;
|
|
3124
3162
|
}
|
|
3125
|
-
const state = {
|
|
3163
|
+
const state = {
|
|
3164
|
+
itemId,
|
|
3165
|
+
kind,
|
|
3166
|
+
content: /* @__PURE__ */ new Map(),
|
|
3167
|
+
summary: /* @__PURE__ */ new Map(),
|
|
3168
|
+
arguments: "",
|
|
3169
|
+
reasoningText: ""
|
|
3170
|
+
};
|
|
3126
3171
|
outputs.set(outputIndex, state);
|
|
3127
3172
|
return state;
|
|
3128
3173
|
};
|
|
@@ -3153,9 +3198,33 @@ var OpenAIResponsesStream = class {
|
|
|
3153
3198
|
const reconstructedOutput = () => [...outputs.entries()].sort(([a], [b]) => a - b).map(([outputIndex, state]) => {
|
|
3154
3199
|
const canonical = canonicalOutputItems.get(outputIndex);
|
|
3155
3200
|
if (canonical) return canonical;
|
|
3156
|
-
if (state.kind === "message")
|
|
3157
|
-
|
|
3158
|
-
|
|
3201
|
+
if (state.kind === "message")
|
|
3202
|
+
return {
|
|
3203
|
+
type: "message",
|
|
3204
|
+
...state.itemId ? { id: state.itemId } : {},
|
|
3205
|
+
...state.status ? { status: state.status } : {},
|
|
3206
|
+
role: state.role ?? "assistant",
|
|
3207
|
+
...state.phase ? { phase: state.phase } : {},
|
|
3208
|
+
content: [...state.content.entries()].sort(([a], [b]) => a - b).map(([, p]) => p)
|
|
3209
|
+
};
|
|
3210
|
+
if (state.kind === "function_call")
|
|
3211
|
+
return {
|
|
3212
|
+
type: "function_call",
|
|
3213
|
+
...state.itemId ? { id: state.itemId } : {},
|
|
3214
|
+
...state.callId ? { call_id: state.callId } : {},
|
|
3215
|
+
...state.status ? { status: state.status } : {},
|
|
3216
|
+
name: state.name ?? "",
|
|
3217
|
+
arguments: state.arguments
|
|
3218
|
+
};
|
|
3219
|
+
return {
|
|
3220
|
+
type: "reasoning",
|
|
3221
|
+
...state.itemId ? { id: state.itemId } : {},
|
|
3222
|
+
...state.status ? { status: state.status } : {},
|
|
3223
|
+
...state.summary.size ? {
|
|
3224
|
+
summary: [...state.summary.entries()].sort(([a], [b]) => a - b).map(([, text]) => ({ type: "summary_text", text }))
|
|
3225
|
+
} : {},
|
|
3226
|
+
...state.reasoningText ? { text: state.reasoningText } : {}
|
|
3227
|
+
};
|
|
3159
3228
|
});
|
|
3160
3229
|
try {
|
|
3161
3230
|
for await (const event of this.source) {
|
|
@@ -3199,7 +3268,12 @@ var OpenAIResponsesStream = class {
|
|
|
3199
3268
|
case "response.content_part.done": {
|
|
3200
3269
|
const e = payload;
|
|
3201
3270
|
if (e.part.type === "output_text" && "text" in e.part && typeof e.part.text === "string" || e.part.type === "refusal" && "refusal" in e.part && typeof e.part.refusal === "string") {
|
|
3202
|
-
applyContentPart(
|
|
3271
|
+
applyContentPart(
|
|
3272
|
+
e.output_index,
|
|
3273
|
+
e.item_id,
|
|
3274
|
+
e.content_index,
|
|
3275
|
+
e.part
|
|
3276
|
+
);
|
|
3203
3277
|
}
|
|
3204
3278
|
break;
|
|
3205
3279
|
}
|
|
@@ -3207,7 +3281,10 @@ var OpenAIResponsesStream = class {
|
|
|
3207
3281
|
const e = payload;
|
|
3208
3282
|
const s = ensureState(e.output_index, e.item_id, "message");
|
|
3209
3283
|
const p = s.content.get(e.content_index);
|
|
3210
|
-
s.content.set(e.content_index, {
|
|
3284
|
+
s.content.set(e.content_index, {
|
|
3285
|
+
type: "output_text",
|
|
3286
|
+
text: (p?.type === "output_text" ? p.text : "") + e.delta
|
|
3287
|
+
});
|
|
3211
3288
|
break;
|
|
3212
3289
|
}
|
|
3213
3290
|
case "response.output_text.done": {
|
|
@@ -3220,7 +3297,10 @@ var OpenAIResponsesStream = class {
|
|
|
3220
3297
|
const e = payload;
|
|
3221
3298
|
const s = ensureState(e.output_index, e.item_id, "message");
|
|
3222
3299
|
const p = s.content.get(e.content_index);
|
|
3223
|
-
s.content.set(e.content_index, {
|
|
3300
|
+
s.content.set(e.content_index, {
|
|
3301
|
+
type: "refusal",
|
|
3302
|
+
refusal: (p?.type === "refusal" ? p.refusal : "") + e.delta
|
|
3303
|
+
});
|
|
3224
3304
|
break;
|
|
3225
3305
|
}
|
|
3226
3306
|
case "response.refusal.done": {
|
|
@@ -3282,20 +3362,31 @@ var OpenAIResponsesStream = class {
|
|
|
3282
3362
|
const response = terminalFailure ?? terminalIncomplete;
|
|
3283
3363
|
const status = terminalFailure ? "failed" : "incomplete";
|
|
3284
3364
|
const detail = response.error?.message ?? response.incomplete_details?.reason ?? "unknown error";
|
|
3285
|
-
throw new OpenAIResponsesStreamError(
|
|
3365
|
+
throw new OpenAIResponsesStreamError(
|
|
3366
|
+
"OpenAI Responses stream " + status + ": " + detail,
|
|
3367
|
+
response
|
|
3368
|
+
);
|
|
3286
3369
|
}
|
|
3287
3370
|
if (!finalResponse) {
|
|
3288
|
-
if (!responseMeta)
|
|
3371
|
+
if (!responseMeta)
|
|
3372
|
+
throw new Error("OpenAI Responses stream ended without a terminal response payload");
|
|
3289
3373
|
if (responseMeta.status === "failed" || responseMeta.status === "incomplete") {
|
|
3290
3374
|
const detail = responseMeta.error?.message ?? responseMeta.incomplete_details?.reason ?? "unknown error";
|
|
3291
|
-
throw new OpenAIResponsesStreamError(
|
|
3375
|
+
throw new OpenAIResponsesStreamError(
|
|
3376
|
+
"OpenAI Responses stream " + responseMeta.status + ": " + detail,
|
|
3377
|
+
responseMeta
|
|
3378
|
+
);
|
|
3292
3379
|
}
|
|
3293
3380
|
finalResponse = { ...responseMeta, output: reconstructedOutput(), status: "completed" };
|
|
3294
3381
|
} else if (finalResponse.status === "failed" || finalResponse.status === "incomplete") {
|
|
3295
3382
|
const detail = finalResponse.error?.message ?? finalResponse.incomplete_details?.reason ?? "unknown error";
|
|
3296
|
-
throw new OpenAIResponsesStreamError(
|
|
3383
|
+
throw new OpenAIResponsesStreamError(
|
|
3384
|
+
"OpenAI Responses stream " + finalResponse.status + ": " + detail,
|
|
3385
|
+
finalResponse
|
|
3386
|
+
);
|
|
3297
3387
|
}
|
|
3298
|
-
if (finalResponse.output.length === 0 && outputs.size > 0)
|
|
3388
|
+
if (finalResponse.output.length === 0 && outputs.size > 0)
|
|
3389
|
+
finalResponse = { ...finalResponse, output: reconstructedOutput() };
|
|
3299
3390
|
completed = true;
|
|
3300
3391
|
this.removeAbortListener?.();
|
|
3301
3392
|
this.removeAbortListener = void 0;
|
|
@@ -3320,14 +3411,11 @@ var OpenAICompatClient = class {
|
|
|
3320
3411
|
}
|
|
3321
3412
|
request(operation, model, signal, holdUntil) {
|
|
3322
3413
|
if (this.runner) {
|
|
3323
|
-
return this.runner(
|
|
3324
|
-
|
|
3325
|
-
{
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
...holdUntil !== void 0 ? { holdUntil } : {}
|
|
3329
|
-
}
|
|
3330
|
-
);
|
|
3414
|
+
return this.runner((http, runnerSignal) => operation(http, runnerSignal), {
|
|
3415
|
+
...model !== void 0 ? { model } : {},
|
|
3416
|
+
...signal !== void 0 ? { signal } : {},
|
|
3417
|
+
...holdUntil !== void 0 ? { holdUntil } : {}
|
|
3418
|
+
});
|
|
3331
3419
|
}
|
|
3332
3420
|
return operation(this.http, signal);
|
|
3333
3421
|
}
|
|
@@ -3956,7 +4044,7 @@ var SystemOneContentSchema = zod.z.union([
|
|
|
3956
4044
|
var SystemOneChoiceQuestionSchema = zod.z.object({
|
|
3957
4045
|
type: zod.z.enum(["choice"]),
|
|
3958
4046
|
instructions: SystemOneContentSchema,
|
|
3959
|
-
criteria: zod.z.object({}).catchall(zod.z.union([zod.z.string(), zod.z.null()])).refine((v) => Object.keys(v).length >= 2, { message: "must have at least 2 properties" }).refine((v) => Object.keys(v).length <=
|
|
4047
|
+
criteria: zod.z.object({}).catchall(zod.z.union([zod.z.string(), zod.z.null()])).refine((v) => Object.keys(v).length >= 2, { message: "must have at least 2 properties" }).refine((v) => Object.keys(v).length <= 255, { message: "must have at most 255 properties" }).refine((v) => Object.keys(v).every((k) => new RegExp("\\S").test(k)), {
|
|
3960
4048
|
message: 'property names must match pattern "\\S"'
|
|
3961
4049
|
})
|
|
3962
4050
|
});
|
|
@@ -4095,6 +4183,7 @@ var requestSchemas = {
|
|
|
4095
4183
|
var responseSchemas = {
|
|
4096
4184
|
balance: BalanceResponseSchema,
|
|
4097
4185
|
chat: ChatResponseSchema,
|
|
4186
|
+
copy: StatusResponseSchema,
|
|
4098
4187
|
create: StatusResponseSchema,
|
|
4099
4188
|
embed: EmbedResponseSchema,
|
|
4100
4189
|
generate: GenerateResponseSchema,
|
|
@@ -5001,6 +5090,7 @@ var copyOp = {
|
|
|
5001
5090
|
method: "POST",
|
|
5002
5091
|
path: "/api/copy",
|
|
5003
5092
|
request: { $ref: "#/schemas/CopyRequest" },
|
|
5093
|
+
response: { $ref: "#/schemas/StatusResponse" },
|
|
5004
5094
|
environment: { local: true, cloud: false },
|
|
5005
5095
|
transport: { mode: "json", streaming: false },
|
|
5006
5096
|
capabilities: {},
|
|
@@ -6887,6 +6977,93 @@ var ToolRegistry = class {
|
|
|
6887
6977
|
};
|
|
6888
6978
|
}
|
|
6889
6979
|
};
|
|
6980
|
+
var WEB_SEARCH_TOOL_NAME = "web_search";
|
|
6981
|
+
var WEB_FETCH_TOOL_NAME = "web_fetch";
|
|
6982
|
+
var DEFAULT_MAX_OUTPUT_CHARS = 2e3 * 4;
|
|
6983
|
+
var DEFAULT_MAX_LINKS = 25;
|
|
6984
|
+
var TRUNCATION_MARKER = "\u2026[truncated]";
|
|
6985
|
+
var webSearchSchema = zod.z.object({
|
|
6986
|
+
query: zod.z.string().min(1).describe("The search query string"),
|
|
6987
|
+
max_results: zod.z.number().int().min(1).max(10).optional().describe("Maximum results to return (default 5, max 10)")
|
|
6988
|
+
});
|
|
6989
|
+
var webFetchSchema = zod.z.object({
|
|
6990
|
+
url: zod.z.string().min(1).describe("The URL of the web page to fetch")
|
|
6991
|
+
});
|
|
6992
|
+
function positiveInt2(value, fallback, name) {
|
|
6993
|
+
if (value === void 0) return fallback;
|
|
6994
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
6995
|
+
throw new RangeError(`${name} must be a positive integer, received ${String(value)}`);
|
|
6996
|
+
}
|
|
6997
|
+
return value;
|
|
6998
|
+
}
|
|
6999
|
+
function truncate(text, maxChars) {
|
|
7000
|
+
if (text.length <= maxChars) return text;
|
|
7001
|
+
if (maxChars <= TRUNCATION_MARKER.length) return text.slice(0, maxChars);
|
|
7002
|
+
return text.slice(0, maxChars - TRUNCATION_MARKER.length) + TRUNCATION_MARKER;
|
|
7003
|
+
}
|
|
7004
|
+
function formatWebSearchResult(res, maxChars) {
|
|
7005
|
+
const results = res.results.map(({ title, url, content }) => ({ title, url, content }));
|
|
7006
|
+
const full = JSON.stringify({ results });
|
|
7007
|
+
if (full.length <= maxChars || results.length === 0) return truncate(full, maxChars);
|
|
7008
|
+
const overhead = JSON.stringify({
|
|
7009
|
+
results: results.map((r) => ({ ...r, content: "" }))
|
|
7010
|
+
}).length;
|
|
7011
|
+
const perResult = Math.max(0, Math.floor((maxChars - overhead) / results.length));
|
|
7012
|
+
const trimmed = JSON.stringify({
|
|
7013
|
+
results: results.map((r) => ({ ...r, content: truncate(r.content, perResult) }))
|
|
7014
|
+
});
|
|
7015
|
+
return trimmed.length <= maxChars ? trimmed : truncate(trimmed, maxChars);
|
|
7016
|
+
}
|
|
7017
|
+
function formatWebFetchResult(res, maxChars, maxLinks = DEFAULT_MAX_LINKS) {
|
|
7018
|
+
const page = {
|
|
7019
|
+
title: res.title ?? "",
|
|
7020
|
+
content: res.content,
|
|
7021
|
+
links: (res.links ?? []).slice(0, maxLinks)
|
|
7022
|
+
};
|
|
7023
|
+
const full = JSON.stringify(page);
|
|
7024
|
+
if (full.length <= maxChars) return full;
|
|
7025
|
+
const overhead = JSON.stringify({ ...page, content: "" }).length;
|
|
7026
|
+
const trimmed = JSON.stringify({
|
|
7027
|
+
...page,
|
|
7028
|
+
content: truncate(page.content, Math.max(0, maxChars - overhead))
|
|
7029
|
+
});
|
|
7030
|
+
return trimmed.length <= maxChars ? trimmed : truncate(trimmed, maxChars);
|
|
7031
|
+
}
|
|
7032
|
+
function createWebSearchTool(client, options = {}) {
|
|
7033
|
+
const maxChars = positiveInt2(options.maxOutputChars, DEFAULT_MAX_OUTPUT_CHARS, "maxOutputChars");
|
|
7034
|
+
const defaultMaxResults = options.defaultMaxResults === void 0 ? void 0 : Math.min(positiveInt2(options.defaultMaxResults, 5, "defaultMaxResults"), 10);
|
|
7035
|
+
return defineTool({
|
|
7036
|
+
name: WEB_SEARCH_TOOL_NAME,
|
|
7037
|
+
description: "Search the web for current information. Returns a list of results, each with a title, url, and relevant content snippet.",
|
|
7038
|
+
schema: webSearchSchema,
|
|
7039
|
+
timeoutMs: options.timeoutMs,
|
|
7040
|
+
execute: async ({ query, max_results }, { signal }) => {
|
|
7041
|
+
const res = await client.webSearch({
|
|
7042
|
+
query,
|
|
7043
|
+
...(max_results ?? defaultMaxResults) !== void 0 ? { max_results: max_results ?? defaultMaxResults } : {},
|
|
7044
|
+
...signal !== void 0 ? { signal } : {}
|
|
7045
|
+
});
|
|
7046
|
+
return formatWebSearchResult(res, maxChars);
|
|
7047
|
+
}
|
|
7048
|
+
});
|
|
7049
|
+
}
|
|
7050
|
+
function createWebFetchTool(client, options = {}) {
|
|
7051
|
+
const maxChars = positiveInt2(options.maxOutputChars, DEFAULT_MAX_OUTPUT_CHARS, "maxOutputChars");
|
|
7052
|
+
const maxLinks = positiveInt2(options.maxLinks, DEFAULT_MAX_LINKS, "maxLinks");
|
|
7053
|
+
return defineTool({
|
|
7054
|
+
name: WEB_FETCH_TOOL_NAME,
|
|
7055
|
+
description: "Fetch a single web page by URL. Returns the page title, its main content, and links found on the page.",
|
|
7056
|
+
schema: webFetchSchema,
|
|
7057
|
+
timeoutMs: options.timeoutMs,
|
|
7058
|
+
execute: async ({ url }, { signal }) => {
|
|
7059
|
+
const res = await client.webFetch({ url, ...signal !== void 0 ? { signal } : {} });
|
|
7060
|
+
return formatWebFetchResult(res, maxChars, maxLinks);
|
|
7061
|
+
}
|
|
7062
|
+
});
|
|
7063
|
+
}
|
|
7064
|
+
function createWebTools(client, options = {}) {
|
|
7065
|
+
return [createWebSearchTool(client, options), createWebFetchTool(client, options)];
|
|
7066
|
+
}
|
|
6890
7067
|
|
|
6891
7068
|
// src/mcp/json-schema.ts
|
|
6892
7069
|
function label(path) {
|
|
@@ -7823,6 +8000,8 @@ exports.RETRYABLE_STATUS_CODES = RETRYABLE_STATUS_CODES;
|
|
|
7823
8000
|
exports.ResponsesModule = ResponsesModule;
|
|
7824
8001
|
exports.ToolCallAccumulator = ToolCallAccumulator;
|
|
7825
8002
|
exports.ToolRegistry = ToolRegistry;
|
|
8003
|
+
exports.WEB_FETCH_TOOL_NAME = WEB_FETCH_TOOL_NAME;
|
|
8004
|
+
exports.WEB_SEARCH_TOOL_NAME = WEB_SEARCH_TOOL_NAME;
|
|
7826
8005
|
exports.addSpanEvent = addSpanEvent;
|
|
7827
8006
|
exports.applySkill = applySkill;
|
|
7828
8007
|
exports.batchEmbed = batchEmbed;
|
|
@@ -7839,6 +8018,9 @@ exports.createDecision = createDecision;
|
|
|
7839
8018
|
exports.createModelAffinityScheduler = createModelAffinityScheduler;
|
|
7840
8019
|
exports.createOllamaCloudFreeTierQuota = createOllamaCloudFreeTierQuota;
|
|
7841
8020
|
exports.createTimeoutSignal = createTimeoutSignal;
|
|
8021
|
+
exports.createWebFetchTool = createWebFetchTool;
|
|
8022
|
+
exports.createWebSearchTool = createWebSearchTool;
|
|
8023
|
+
exports.createWebTools = createWebTools;
|
|
7842
8024
|
exports.defineTool = defineTool;
|
|
7843
8025
|
exports.detectModelCapabilities = detectModelCapabilities;
|
|
7844
8026
|
exports.embedBatchOverflowMessage = embedBatchOverflowMessage;
|
|
@@ -7855,6 +8037,8 @@ exports.fetchWithBackoff = fetchWithBackoff;
|
|
|
7855
8037
|
exports.findOversizedEmbedInputs = findOversizedEmbedInputs;
|
|
7856
8038
|
exports.findRunningModelContextLength = findRunningModelContextLength;
|
|
7857
8039
|
exports.formatTelemetry = formatTelemetry;
|
|
8040
|
+
exports.formatWebFetchResult = formatWebFetchResult;
|
|
8041
|
+
exports.formatWebSearchResult = formatWebSearchResult;
|
|
7858
8042
|
exports.imageStringNeedsResolution = imageStringNeedsResolution;
|
|
7859
8043
|
exports.inferRuntimeMode = inferRuntimeMode;
|
|
7860
8044
|
exports.isKeepAliveSugar = isKeepAliveSugar;
|