@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.
Files changed (48) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +145 -5
  3. package/dist/{anthropic-CKp5TmAP.d.ts → anthropic-DrDUfbfQ.d.ts} +65 -18
  4. package/dist/{anthropic-Did0lQxP.d.cts → anthropic-UeaVjLeP.d.cts} +65 -18
  5. package/dist/{compose-6UOPEknN.d.ts → compose-CeFbHJeO.d.ts} +1 -1
  6. package/dist/{compose-DhvoUrWa.d.cts → compose-DFkmtUOP.d.cts} +1 -1
  7. package/dist/generated-api.cjs +3 -2
  8. package/dist/generated-api.cjs.map +1 -1
  9. package/dist/generated-api.d.cts +15 -9
  10. package/dist/generated-api.d.ts +15 -9
  11. package/dist/generated-api.js +3 -2
  12. package/dist/generated-api.js.map +1 -1
  13. package/dist/generated-models-schemas.cjs +1 -1
  14. package/dist/generated-models-schemas.cjs.map +1 -1
  15. package/dist/generated-models-schemas.js +1 -1
  16. package/dist/generated-models-schemas.js.map +1 -1
  17. package/dist/generated-runtime.cjs +2 -1
  18. package/dist/generated-runtime.cjs.map +1 -1
  19. package/dist/generated-runtime.d.cts +2 -2
  20. package/dist/generated-runtime.d.ts +2 -2
  21. package/dist/generated-runtime.js +2 -1
  22. package/dist/generated-runtime.js.map +1 -1
  23. package/dist/index.cjs +209 -25
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +103 -12
  26. package/dist/index.d.ts +103 -12
  27. package/dist/index.js +203 -26
  28. package/dist/index.js.map +1 -1
  29. package/dist/mcp/tools.json +4 -4
  30. package/dist/mcp-generated.cjs +3 -2
  31. package/dist/mcp-generated.cjs.map +1 -1
  32. package/dist/mcp-generated.d.cts +2 -2
  33. package/dist/mcp-generated.d.ts +2 -2
  34. package/dist/mcp-generated.js +3 -2
  35. package/dist/mcp-generated.js.map +1 -1
  36. package/dist/{runtime-CIQYCRL3.d.ts → runtime-BIjr5ME4.d.ts} +1 -1
  37. package/dist/{runtime-DmI1cOEq.d.cts → runtime-C4RRHqOs.d.cts} +1 -1
  38. package/dist/skills.d.cts +3 -3
  39. package/dist/skills.d.ts +3 -3
  40. package/dist/testing.cjs +281 -0
  41. package/dist/testing.cjs.map +1 -0
  42. package/dist/testing.d.cts +336 -0
  43. package/dist/testing.d.ts +336 -0
  44. package/dist/testing.js +275 -0
  45. package/dist/testing.js.map +1 -0
  46. package/dist/{types-B57ZZfp3.d.cts → types-DbPnfVh-.d.cts} +20 -3
  47. package/dist/{types-B57ZZfp3.d.ts → types-DbPnfVh-.d.ts} +20 -3
  48. 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` and `from`.
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
- return this.create({ ...rest, model, files, stream: false });
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, { code: "openai_responses_stream_error", retryable: false, response: { body: responsePayload } });
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(new OllamaAbortError("OpenAI Chat Completion stream ended before completion"));
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 = { itemId, kind, content: /* @__PURE__ */ new Map(), summary: /* @__PURE__ */ new Map(), arguments: "", reasoningText: "" };
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") return { type: "message", ...state.itemId ? { id: state.itemId } : {}, ...state.status ? { status: state.status } : {}, role: state.role ?? "assistant", ...state.phase ? { phase: state.phase } : {}, content: [...state.content.entries()].sort(([a], [b]) => a - b).map(([, p]) => p) };
3157
- if (state.kind === "function_call") return { type: "function_call", ...state.itemId ? { id: state.itemId } : {}, ...state.callId ? { call_id: state.callId } : {}, ...state.status ? { status: state.status } : {}, name: state.name ?? "", arguments: state.arguments };
3158
- return { type: "reasoning", ...state.itemId ? { id: state.itemId } : {}, ...state.status ? { status: state.status } : {}, ...state.summary.size ? { summary: [...state.summary.entries()].sort(([a], [b]) => a - b).map(([, text]) => ({ type: "summary_text", text })) } : {}, ...state.reasoningText ? { text: state.reasoningText } : {} };
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(e.output_index, e.item_id, e.content_index, e.part);
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, { type: "output_text", text: (p?.type === "output_text" ? p.text : "") + e.delta });
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, { type: "refusal", refusal: (p?.type === "refusal" ? p.refusal : "") + e.delta });
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("OpenAI Responses stream " + status + ": " + detail, response);
3365
+ throw new OpenAIResponsesStreamError(
3366
+ "OpenAI Responses stream " + status + ": " + detail,
3367
+ response
3368
+ );
3286
3369
  }
3287
3370
  if (!finalResponse) {
3288
- if (!responseMeta) throw new Error("OpenAI Responses stream ended without a terminal response payload");
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("OpenAI Responses stream " + responseMeta.status + ": " + detail, responseMeta);
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("OpenAI Responses stream " + finalResponse.status + ": " + detail, finalResponse);
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) finalResponse = { ...finalResponse, output: reconstructedOutput() };
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
- (http, runnerSignal) => operation(http, runnerSignal),
3325
- {
3326
- ...model !== void 0 ? { model } : {},
3327
- ...signal !== void 0 ? { signal } : {},
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 <= 26, { message: "must have at most 26 properties" }).refine((v) => Object.keys(v).every((k) => new RegExp("\\S").test(k)), {
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;