@nemesis-oss/ollama-sdk 1.7.0 → 1.9.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 (46) hide show
  1. package/CHANGELOG.md +168 -1
  2. package/README.md +181 -10
  3. package/dist/anthropic-5oYIRS6D.d.ts +1649 -0
  4. package/dist/anthropic-BIh45UXj.d.cts +1649 -0
  5. package/dist/{compose-DLStUfaF.d.ts → compose-DCVYMvOL.d.ts} +1 -1
  6. package/dist/{compose-DS-UWFx8.d.cts → compose-Dj6FdF2n.d.cts} +1 -1
  7. package/dist/generated-api.cjs +116 -9
  8. package/dist/generated-api.cjs.map +1 -1
  9. package/dist/generated-api.d.cts +321 -630
  10. package/dist/generated-api.d.ts +321 -630
  11. package/dist/generated-api.js +112 -10
  12. package/dist/generated-api.js.map +1 -1
  13. package/dist/generated-models-schemas.cjs +151 -3
  14. package/dist/generated-models-schemas.cjs.map +1 -1
  15. package/dist/generated-models-schemas.d.cts +228 -3
  16. package/dist/generated-models-schemas.d.ts +228 -3
  17. package/dist/generated-models-schemas.js +134 -4
  18. package/dist/generated-models-schemas.js.map +1 -1
  19. package/dist/generated-runtime.cjs +679 -60
  20. package/dist/generated-runtime.cjs.map +1 -1
  21. package/dist/generated-runtime.d.cts +22 -24
  22. package/dist/generated-runtime.d.ts +22 -24
  23. package/dist/generated-runtime.js +678 -61
  24. package/dist/generated-runtime.js.map +1 -1
  25. package/dist/index.cjs +2468 -132
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +1666 -864
  28. package/dist/index.d.ts +1666 -864
  29. package/dist/index.js +2432 -133
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp/tools.json +306 -73
  32. package/dist/mcp-generated.cjs +138 -7
  33. package/dist/mcp-generated.cjs.map +1 -1
  34. package/dist/mcp-generated.d.cts +2 -2
  35. package/dist/mcp-generated.d.ts +2 -2
  36. package/dist/mcp-generated.js +138 -7
  37. package/dist/mcp-generated.js.map +1 -1
  38. package/dist/{runtime-qwD72cpn.d.ts → runtime-C3rfpkZw.d.ts} +286 -5
  39. package/dist/{runtime-bQ48I-RC.d.cts → runtime-D2W9TfCJ.d.cts} +286 -5
  40. package/dist/skills.cjs.map +1 -1
  41. package/dist/skills.d.cts +3 -3
  42. package/dist/skills.d.ts +3 -3
  43. package/dist/skills.js.map +1 -1
  44. package/dist/{types-5PAjLoCp.d.cts → types-DVcX_zMp.d.cts} +110 -10
  45. package/dist/{types-5PAjLoCp.d.ts → types-DVcX_zMp.d.ts} +110 -10
  46. package/package.json +9 -5
@@ -63,6 +63,14 @@ var OllamaClientError = class extends Error {
63
63
  this.response = options.response;
64
64
  }
65
65
  };
66
+ var OllamaStreamError = class extends OllamaClientError {
67
+ /** Content accumulated before the in-band error frame, or '' if none. */
68
+ partialContent;
69
+ constructor(message, options) {
70
+ super(message, { ...options, code: "stream_error", retryable: false });
71
+ this.partialContent = options?.partialContent ?? "";
72
+ }
73
+ };
66
74
  var OllamaRequestValidationError = class extends OllamaClientError {
67
75
  operationId;
68
76
  issues;
@@ -72,6 +80,35 @@ var OllamaRequestValidationError = class extends OllamaClientError {
72
80
  this.issues = options.issues;
73
81
  }
74
82
  };
83
+ var OllamaRequestTooLargeError = class extends OllamaClientError {
84
+ operationId;
85
+ actualBytes;
86
+ maxBytes;
87
+ constructor(message, options) {
88
+ super(message, { ...options, code: "request_too_large", retryable: false, status: 413 });
89
+ this.operationId = options.operationId;
90
+ this.actualBytes = options.actualBytes;
91
+ this.maxBytes = options.maxBytes;
92
+ }
93
+ };
94
+ var OllamaResponseValidationError = class extends OllamaClientError {
95
+ operationId;
96
+ issues;
97
+ constructor(message, options) {
98
+ super(message, { ...options, code: "response_validation_error", retryable: false });
99
+ this.operationId = options.operationId;
100
+ this.issues = options.issues;
101
+ }
102
+ };
103
+ var OllamaServerVersionUnknownError = class extends OllamaClientError {
104
+ operationId;
105
+ minRequiredVersion;
106
+ constructor(message, options) {
107
+ super(message, { ...options, code: "server_version_unknown", retryable: false });
108
+ this.operationId = options.operationId;
109
+ this.minRequiredVersion = options.minRequiredVersion;
110
+ }
111
+ };
75
112
  var OllamaGenericClientError = class extends OllamaClientError {
76
113
  constructor(message, options) {
77
114
  super(message, { ...options, code: "client_error" });
@@ -92,6 +129,12 @@ function disposableReader(reader) {
92
129
  }
93
130
 
94
131
  // src/streaming/ndjson.ts
132
+ function isInBandErrorFrame(value) {
133
+ if (typeof value !== "object" || value === null) return false;
134
+ const record = value;
135
+ if (typeof record.error !== "string" || record.error.length === 0) return false;
136
+ return !("model" in record) && !("response" in record) && !("message" in record) && !("status" in record) && !("done" in record);
137
+ }
95
138
  async function* parseNdjsonStream(stream) {
96
139
  var _stack = [];
97
140
  try {
@@ -108,18 +151,127 @@ async function* parseNdjsonStream(stream) {
108
151
  for (const line of lines) {
109
152
  const trimmed = line.trim();
110
153
  if (!trimmed) continue;
154
+ let json;
111
155
  try {
112
- yield JSON.parse(trimmed);
156
+ json = JSON.parse(trimmed);
113
157
  } catch (err) {
114
158
  throw new OllamaGenericClientError(`Failed to parse stream JSON chunk: ${trimmed}`, {
115
159
  cause: err
116
160
  });
117
161
  }
162
+ if (isInBandErrorFrame(json)) {
163
+ throw new OllamaStreamError(json.error);
164
+ }
165
+ yield json;
118
166
  }
119
167
  }
120
168
  if (buffer.trim()) {
121
- yield JSON.parse(buffer.trim());
169
+ const trimmed = buffer.trim();
170
+ let json;
171
+ try {
172
+ json = JSON.parse(trimmed);
173
+ } catch (err) {
174
+ throw new OllamaGenericClientError(`Failed to parse stream JSON chunk: ${trimmed}`, {
175
+ cause: err
176
+ });
177
+ }
178
+ if (isInBandErrorFrame(json)) {
179
+ throw new OllamaStreamError(json.error);
180
+ }
181
+ yield json;
182
+ }
183
+ } catch (_) {
184
+ var _error = _, _hasError = true;
185
+ } finally {
186
+ var _promise = __callDispose(_stack, _error, _hasError);
187
+ _promise && await _promise;
188
+ }
189
+ }
190
+
191
+ // src/streaming/sse.ts
192
+ function dispatch(event, data, id, retry) {
193
+ if (data.length === 0) return void 0;
194
+ const joined = data.join("\n");
195
+ return {
196
+ ...event !== void 0 ? { event } : {},
197
+ data: joined.endsWith("\n") ? joined.slice(0, -1) : joined,
198
+ ...id !== void 0 ? { id } : {},
199
+ ...retry !== void 0 ? { retry } : {}
200
+ };
201
+ }
202
+ async function* parseSseStream(stream) {
203
+ var _stack = [];
204
+ try {
205
+ const reader = stream.getReader();
206
+ const decoder = new TextDecoder();
207
+ let buffer = "";
208
+ let eventType;
209
+ let data = [];
210
+ let lastEventId;
211
+ let retry;
212
+ const processLine = (line) => {
213
+ if (line.length === 0) {
214
+ const event = dispatch(eventType, data, lastEventId, retry);
215
+ eventType = void 0;
216
+ data = [];
217
+ retry = void 0;
218
+ return event;
219
+ }
220
+ if (line.startsWith(":")) return void 0;
221
+ const separator = line.indexOf(":");
222
+ const field = separator === -1 ? line : line.slice(0, separator);
223
+ let value = separator === -1 ? "" : line.slice(separator + 1);
224
+ if (value.startsWith(" ")) value = value.slice(1);
225
+ switch (field) {
226
+ case "event":
227
+ eventType = value;
228
+ break;
229
+ case "data":
230
+ data.push(value);
231
+ break;
232
+ case "id":
233
+ if (!value.includes("\0")) lastEventId = value;
234
+ break;
235
+ case "retry": {
236
+ if (/^\d+$/.test(value)) {
237
+ const parsed = Number(value);
238
+ if (Number.isSafeInteger(parsed)) retry = parsed;
239
+ }
240
+ break;
241
+ }
242
+ default:
243
+ break;
244
+ }
245
+ return void 0;
246
+ };
247
+ const _reader = __using(_stack, disposableReader(reader), true);
248
+ while (true) {
249
+ const { done, value } = await reader.read();
250
+ if (done) break;
251
+ buffer += decoder.decode(value, { stream: true });
252
+ while (true) {
253
+ const lf = buffer.indexOf("\n");
254
+ const cr = buffer.indexOf("\r");
255
+ if (lf === -1 && cr === -1) break;
256
+ if (cr !== -1 && lf === -1 && cr === buffer.length - 1) break;
257
+ const lineEnd = lf === -1 ? cr : cr === -1 ? lf : Math.min(lf, cr);
258
+ let separatorLength = 1;
259
+ if (buffer[lineEnd] === "\r" && buffer[lineEnd + 1] === "\n") {
260
+ separatorLength = 2;
261
+ }
262
+ const line = buffer.slice(0, lineEnd);
263
+ buffer = buffer.slice(lineEnd + separatorLength);
264
+ const event = processLine(line);
265
+ if (event) yield event;
266
+ }
122
267
  }
268
+ buffer += decoder.decode();
269
+ if (buffer.length > 0) {
270
+ const event = processLine(buffer);
271
+ if (event) yield event;
272
+ }
273
+ const terminal = dispatch(eventType, data, lastEventId, retry);
274
+ if (terminal) yield terminal;
123
275
  } catch (_) {
124
276
  var _error = _, _hasError = true;
125
277
  } finally {
@@ -127,6 +279,32 @@ async function* parseNdjsonStream(stream) {
127
279
  _promise && await _promise;
128
280
  }
129
281
  }
282
+ var IncludedBalanceSchema = z.object({
283
+ balance_usd: z.number(),
284
+ allowance_usd: z.number(),
285
+ period: z.object({
286
+ from: z.string(),
287
+ until: z.string()
288
+ })
289
+ });
290
+ var LegacyBalanceLimitSchema = z.object({
291
+ remaining_percent: z.number().min(0).max(100),
292
+ resets_at: z.string()
293
+ });
294
+
295
+ // src/generated/models/LegacyIncludedBalance.schema.ts
296
+ var LegacyIncludedBalanceSchema = z.object({
297
+ session: LegacyBalanceLimitSchema,
298
+ weekly: LegacyBalanceLimitSchema
299
+ });
300
+
301
+ // src/generated/models/BalanceResponse.schema.ts
302
+ var BalanceResponseSchema = z.object({
303
+ included: z.union([IncludedBalanceSchema, LegacyIncludedBalanceSchema]),
304
+ purchased: z.object({
305
+ balance_usd: z.number()
306
+ })
307
+ });
130
308
  var ToolCallSchema = z.object({
131
309
  function: z.object({
132
310
  name: z.string(),
@@ -175,28 +353,45 @@ var ChatRequestSchema = z.object({
175
353
  logprobs: z.boolean().optional(),
176
354
  top_logprobs: z.number().optional()
177
355
  });
178
- var GenerateRequestSchema = z.object({
179
- model: z.string(),
180
- prompt: z.string().optional(),
181
- suffix: z.string().optional(),
182
- images: z.array(z.string()).optional(),
183
- format: z.union([z.string(), z.object({})]).optional(),
184
- system: z.string().optional(),
185
- stream: z.boolean().optional(),
186
- think: ThinkValueSchema.optional(),
187
- raw: z.boolean().optional(),
188
- keep_alive: z.union([z.string(), z.number()]).optional(),
189
- options: ModelOptionsSchema.optional(),
190
- logprobs: z.boolean().optional(),
191
- top_logprobs: z.number().optional()
356
+ var TokenLogprobSchema = z.object({
357
+ token: z.string().optional(),
358
+ logprob: z.number().optional(),
359
+ bytes: z.array(z.number()).optional()
192
360
  });
193
- var EmbedRequestSchema = z.object({
194
- model: z.string(),
195
- input: z.union([z.string(), z.array(z.string())]),
196
- truncate: z.boolean().optional(),
197
- dimensions: z.number().optional(),
198
- keep_alive: z.string().optional(),
199
- options: ModelOptionsSchema.optional()
361
+
362
+ // src/generated/models/Logprob.schema.ts
363
+ var LogprobSchema = z.object({
364
+ token: z.string().optional(),
365
+ logprob: z.number().optional(),
366
+ bytes: z.array(z.number()).optional(),
367
+ top_logprobs: z.array(TokenLogprobSchema).optional()
368
+ });
369
+
370
+ // src/generated/models/ChatResponse.schema.ts
371
+ var ChatResponseSchema = z.object({
372
+ model: z.string().optional(),
373
+ created_at: z.string().optional(),
374
+ message: z.object({
375
+ role: z.enum(["assistant"]).optional(),
376
+ content: z.string().optional(),
377
+ thinking: z.string().optional(),
378
+ tool_calls: z.array(ToolCallSchema).optional(),
379
+ images: z.array(z.string()).optional()
380
+ }).optional(),
381
+ done: z.boolean().optional(),
382
+ done_reason: z.string().optional(),
383
+ total_duration: z.number().optional(),
384
+ load_duration: z.number().optional(),
385
+ prompt_eval_count: z.number().optional(),
386
+ prompt_eval_cached_count: z.number().optional(),
387
+ prompt_eval_duration: z.number().optional(),
388
+ eval_count: z.number().optional(),
389
+ eval_duration: z.number().optional(),
390
+ logprobs: z.array(LogprobSchema).optional()
391
+ });
392
+ var CopyRequestSchema = z.object({
393
+ source: z.string(),
394
+ destination: z.string()
200
395
  });
201
396
  var CreateRequestSchema = z.object({
202
397
  model: z.string(),
@@ -213,15 +408,94 @@ var CreateRequestSchema = z.object({
213
408
  quantize: z.string().optional(),
214
409
  draft_quantize: z.string().optional(),
215
410
  requires: z.string().optional(),
411
+ capabilities: z.array(z.string()).optional(),
216
412
  stream: z.boolean().optional()
217
413
  });
218
- var CopyRequestSchema = z.object({
219
- source: z.string(),
220
- destination: z.string()
221
- });
222
414
  var DeleteRequestSchema = z.object({
223
415
  model: z.string()
224
416
  });
417
+ var EmbedRequestSchema = z.object({
418
+ model: z.string(),
419
+ input: z.union([z.string(), z.array(z.string())]),
420
+ truncate: z.boolean().optional(),
421
+ dimensions: z.number().optional(),
422
+ keep_alive: z.string().optional(),
423
+ options: ModelOptionsSchema.optional()
424
+ });
425
+ var EmbedResponseSchema = z.object({
426
+ model: z.string().optional(),
427
+ embeddings: z.array(z.array(z.number())).optional(),
428
+ total_duration: z.number().optional(),
429
+ load_duration: z.number().optional(),
430
+ prompt_eval_count: z.number().optional()
431
+ });
432
+ var GenerateRequestSchema = z.object({
433
+ model: z.string(),
434
+ prompt: z.string().optional(),
435
+ suffix: z.string().optional(),
436
+ images: z.array(z.string()).optional(),
437
+ format: z.union([z.string(), z.object({})]).optional(),
438
+ system: z.string().optional(),
439
+ stream: z.boolean().optional(),
440
+ think: ThinkValueSchema.optional(),
441
+ raw: z.boolean().optional(),
442
+ keep_alive: z.union([z.string(), z.number()]).optional(),
443
+ options: ModelOptionsSchema.optional(),
444
+ logprobs: z.boolean().optional(),
445
+ top_logprobs: z.number().optional()
446
+ });
447
+ var GenerateResponseSchema = z.object({
448
+ model: z.string().optional(),
449
+ created_at: z.string().optional(),
450
+ response: z.string().optional(),
451
+ thinking: z.string().optional(),
452
+ done: z.boolean().optional(),
453
+ done_reason: z.string().optional(),
454
+ total_duration: z.number().optional(),
455
+ load_duration: z.number().optional(),
456
+ prompt_eval_count: z.number().optional(),
457
+ prompt_eval_cached_count: z.number().optional(),
458
+ prompt_eval_duration: z.number().optional(),
459
+ eval_count: z.number().optional(),
460
+ eval_duration: z.number().optional(),
461
+ logprobs: z.array(LogprobSchema).optional()
462
+ });
463
+ var ModelSummarySchema = z.object({
464
+ name: z.string().optional(),
465
+ model: z.string().optional(),
466
+ remote_model: z.string().optional(),
467
+ remote_host: z.string().optional(),
468
+ modified_at: z.string().optional(),
469
+ size: z.number().optional(),
470
+ digest: z.string().optional(),
471
+ details: z.object({
472
+ format: z.string().optional(),
473
+ family: z.string().optional(),
474
+ families: z.union([z.array(z.string()), z.null()]).optional(),
475
+ parameter_size: z.string().optional(),
476
+ quantization_level: z.string().optional()
477
+ }).optional()
478
+ });
479
+
480
+ // src/generated/models/ListResponse.schema.ts
481
+ var ListResponseSchema = z.object({
482
+ models: z.array(ModelSummarySchema).optional()
483
+ });
484
+ var PsSchema = z.object({
485
+ name: z.string().optional(),
486
+ model: z.string().optional(),
487
+ size: z.number().optional(),
488
+ digest: z.string().optional(),
489
+ details: z.object({}).optional(),
490
+ expires_at: z.string().optional(),
491
+ size_vram: z.number().optional(),
492
+ context_length: z.number().optional()
493
+ });
494
+
495
+ // src/generated/models/PsResponse.schema.ts
496
+ var PsResponseSchema = z.object({
497
+ models: z.array(PsSchema).optional()
498
+ });
225
499
  var PullRequestSchema = z.object({
226
500
  model: z.string(),
227
501
  insecure: z.boolean().optional(),
@@ -236,27 +510,194 @@ var ShowRequestSchema = z.object({
236
510
  model: z.string(),
237
511
  verbose: z.boolean().optional()
238
512
  });
513
+ var ThinkingSchema = z.object({
514
+ values: z.array(z.union([z.boolean(), z.string()])),
515
+ default: z.union([z.boolean(), z.string()])
516
+ });
517
+
518
+ // src/generated/models/ShowResponse.schema.ts
519
+ var ShowResponseSchema = z.object({
520
+ thinking: ThinkingSchema.optional(),
521
+ parameters: z.string().optional(),
522
+ license: z.string().optional(),
523
+ modified_at: z.string().optional(),
524
+ details: z.object({}).optional(),
525
+ template: z.string().optional(),
526
+ capabilities: z.array(z.string()).optional(),
527
+ model_info: z.object({}).optional()
528
+ });
529
+ var StatusResponseSchema = z.object({
530
+ status: z.string().optional()
531
+ });
532
+ var SystemOneContentSchema = z.union([
533
+ z.string().regex(new RegExp("\\S")),
534
+ z.object({}).catchall(z.unknown()),
535
+ z.array(z.unknown())
536
+ ]);
537
+
538
+ // src/generated/models/SystemOneChoiceQuestion.schema.ts
539
+ var SystemOneChoiceQuestionSchema = z.object({
540
+ type: z.enum(["choice"]),
541
+ instructions: SystemOneContentSchema,
542
+ criteria: z.object({}).catchall(z.union([z.string(), 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)), {
543
+ message: 'property names must match pattern "\\S"'
544
+ })
545
+ });
546
+ var SystemOneNoulQuestionSchema = z.object({
547
+ type: z.enum(["noul"]),
548
+ instructions: SystemOneContentSchema,
549
+ criteria: z.object({
550
+ false: z.string().optional(),
551
+ true: z.string().optional()
552
+ }).optional()
553
+ });
554
+ var SystemOneScoreQuestionSchema = z.object({
555
+ type: z.enum(["score"]),
556
+ instructions: SystemOneContentSchema,
557
+ criteria: z.array(z.string()).min(2).max(26)
558
+ });
559
+
560
+ // src/generated/models/SystemOneRequest.schema.ts
561
+ var SystemOneRequestSchema = z.object({
562
+ model: z.string().regex(new RegExp("\\S")),
563
+ state: SystemOneContentSchema,
564
+ images: z.array(z.string()).optional(),
565
+ questions: z.object({}).catchall(
566
+ z.union([
567
+ SystemOneChoiceQuestionSchema,
568
+ SystemOneNoulQuestionSchema,
569
+ SystemOneScoreQuestionSchema
570
+ ])
571
+ ).refine((v) => Object.keys(v).length >= 1, { message: "must have at least 1 properties" }).refine((v) => Object.keys(v).length <= 64, { message: "must have at most 64 properties" }).refine((v) => Object.keys(v).every((k) => new RegExp("\\S").test(k)), {
572
+ message: 'property names must match pattern "\\S"'
573
+ }),
574
+ keep_alive: z.union([z.string(), z.number()]).optional()
575
+ });
576
+ var SystemOneConfidenceSchema = z.number().min(0).max(1);
577
+ var SystemOneProbabilitiesSchema = z.object({}).catchall(z.number().min(0).max(1));
578
+
579
+ // src/generated/models/SystemOneChoiceAnswer.schema.ts
580
+ var SystemOneChoiceAnswerSchema = z.object({
581
+ type: z.enum(["choice"]),
582
+ choice: z.string(),
583
+ probabilities: SystemOneProbabilitiesSchema,
584
+ confidence: SystemOneConfidenceSchema
585
+ });
586
+ var SystemOneNoulAnswerSchema = z.object({
587
+ type: z.enum(["noul"]),
588
+ noul: z.number().min(0).max(1)
589
+ });
590
+ var SystemOneScoreAnswerSchema = z.object({
591
+ type: z.enum(["score"]),
592
+ score: z.number().min(0).max(25),
593
+ legend: z.object({}).catchall(z.string()),
594
+ probabilities: SystemOneProbabilitiesSchema,
595
+ confidence: SystemOneConfidenceSchema
596
+ });
597
+
598
+ // src/generated/models/SystemOneResponse.schema.ts
599
+ var SystemOneResponseSchema = z.object({
600
+ model: z.string(),
601
+ answers: z.object({}).catchall(
602
+ z.union([SystemOneChoiceAnswerSchema, SystemOneNoulAnswerSchema, SystemOneScoreAnswerSchema])
603
+ ),
604
+ usage: z.object({
605
+ input_tokens: z.number().min(0),
606
+ output_tokens: z.number().min(0)
607
+ })
608
+ });
609
+ var UsageMetricsSchema = z.object({
610
+ request_count: z.number().min(0),
611
+ usage_usd: z.number().optional(),
612
+ input_tokens: z.number().optional(),
613
+ cached_input_tokens: z.number().optional(),
614
+ output_tokens: z.number().optional()
615
+ });
616
+
617
+ // src/generated/models/UsageBucket.schema.ts
618
+ var UsageBucketSchema = z.intersection(
619
+ UsageMetricsSchema,
620
+ z.object({
621
+ from: z.string(),
622
+ until: z.string(),
623
+ partial: z.boolean().optional()
624
+ })
625
+ );
626
+
627
+ // src/generated/models/UsageResponse.schema.ts
628
+ var UsageResponseSchema = z.object({
629
+ range: z.enum(["24h", "7d", "30d"]),
630
+ scope: z.enum(["self", "team"]),
631
+ granularity: z.enum(["hour", "day"]),
632
+ from: z.string(),
633
+ until: z.string(),
634
+ totals: UsageMetricsSchema,
635
+ buckets: z.array(UsageBucketSchema)
636
+ });
637
+ var VersionResponseSchema = z.object({
638
+ version: z.string().optional()
639
+ });
640
+ var WebFetchRequestSchema = z.object({
641
+ url: z.string()
642
+ });
643
+ var WebFetchResponseSchema = z.object({
644
+ title: z.string().optional(),
645
+ content: z.string().optional(),
646
+ links: z.array(z.string()).optional()
647
+ });
648
+ var WebSearchRequestSchema = z.object({
649
+ query: z.string(),
650
+ max_results: z.number().min(1).max(10).optional()
651
+ });
652
+ var WebSearchResultSchema = z.object({
653
+ title: z.string().optional(),
654
+ url: z.string().optional(),
655
+ content: z.string().optional()
656
+ });
657
+
658
+ // src/generated/models/WebSearchResponse.schema.ts
659
+ var WebSearchResponseSchema = z.object({
660
+ results: z.array(WebSearchResultSchema).optional()
661
+ });
239
662
 
240
663
  // src/generated/runtime/schema-registry.ts
241
664
  var requestSchemas = {
242
665
  chat: ChatRequestSchema,
243
- generate: GenerateRequestSchema,
244
- embed: EmbedRequestSchema,
245
- create: CreateRequestSchema,
246
666
  copy: CopyRequestSchema,
667
+ create: CreateRequestSchema,
247
668
  delete: DeleteRequestSchema,
669
+ embed: EmbedRequestSchema,
670
+ generate: GenerateRequestSchema,
248
671
  pull: PullRequestSchema,
249
672
  push: PushRequestSchema,
250
- show: ShowRequestSchema
251
- // Operations without a registered request schema (blobs, ps, tags,
252
- // version, systemOne, openai*, anthropic*) skip validation. This is
253
- // deliberate — the OpenAPI spec doesn't define request bodies for
254
- // GET/HEAD operations, and the compat-surface request schemas (OpenAI,
255
- // Anthropic) are richer than what the IR currently models.
673
+ show: ShowRequestSchema,
674
+ systemOne: SystemOneRequestSchema,
675
+ webFetch: WebFetchRequestSchema,
676
+ webSearch: WebSearchRequestSchema
677
+ };
678
+ var responseSchemas = {
679
+ balance: BalanceResponseSchema,
680
+ chat: ChatResponseSchema,
681
+ create: StatusResponseSchema,
682
+ embed: EmbedResponseSchema,
683
+ generate: GenerateResponseSchema,
684
+ ps: PsResponseSchema,
685
+ pull: StatusResponseSchema,
686
+ push: StatusResponseSchema,
687
+ show: ShowResponseSchema,
688
+ systemOne: SystemOneResponseSchema,
689
+ tags: ListResponseSchema,
690
+ usage: UsageResponseSchema,
691
+ version: VersionResponseSchema,
692
+ webFetch: WebFetchResponseSchema,
693
+ webSearch: WebSearchResponseSchema
256
694
  };
257
695
  function getRequestSchema(operationId) {
258
696
  return requestSchemas[operationId];
259
697
  }
698
+ function getResponseSchema(operationId) {
699
+ return responseSchemas[operationId];
700
+ }
260
701
 
261
702
  // src/generated/runtime/runtime.ts
262
703
  function compareVersions(a, b) {
@@ -269,18 +710,13 @@ function compareVersions(a, b) {
269
710
  }
270
711
  return 0;
271
712
  }
272
- function assertOperationAllowed(operation, options) {
273
- const localMode = options.localMode ?? true;
274
- if (!localMode && !operation.environment.cloud) {
275
- throw new OllamaGenericClientError(
276
- `Operation ${operation.operationId} (${operation.method} ${operation.path}) is local-only and not supported in cloud mode.`
277
- );
278
- }
279
- if (operation.constraints?.minOllamaVersion && options.serverVersion && compareVersions(options.serverVersion, operation.constraints.minOllamaVersion) < 0) {
280
- throw new OllamaGenericClientError(
281
- `Operation ${operation.operationId} (${operation.method} ${operation.path}) requires Ollama >= ${operation.constraints.minOllamaVersion} (server reports ${options.serverVersion}).`
282
- );
283
- }
713
+ async function fetchServerVersion(http) {
714
+ const result = await http.request({
715
+ path: "/api/version",
716
+ method: "GET"
717
+ });
718
+ if (result && typeof result.version === "string") return result.version;
719
+ return void 0;
284
720
  }
285
721
  function shouldStream(req) {
286
722
  if (req.body && typeof req.body === "object" && "stream" in req.body) {
@@ -302,7 +738,35 @@ var OllamaRuntime = class {
302
738
  constructor(options) {
303
739
  this.options = options;
304
740
  }
305
- options;
741
+ /**
742
+ * Cached promise of the Ollama server version, populated lazily the first
743
+ * time a version-gated operation is invoked. `undefined` until then.
744
+ *
745
+ * Wave 12 (P0 #5): see {@link OllamaRuntimeOptions.enforceVersion}.
746
+ */
747
+ serverVersionCache;
748
+ /**
749
+ * Wave 15 (P0): resolve the HTTP backend for a given operation.
750
+ *
751
+ * Operations with a declared `host` (e.g. web search/fetch at
752
+ * https://ollama.com) must route to a HttpClient pointed at that host,
753
+ * not the default one. The runtime accepts an optional `cloudHttp`
754
+ * backend for this purpose — if the operation declares a host and no
755
+ * cloud backend is configured, the runtime throws rather than silently
756
+ * sending the request to the wrong server.
757
+ */
758
+ resolveHttpBackend(operation) {
759
+ if (operation.host) {
760
+ const cloudHttp = this.options.cloudHttp;
761
+ if (!cloudHttp) {
762
+ throw new OllamaGenericClientError(
763
+ `Operation ${operation.operationId} (${operation.method} ${operation.path}) targets host "${operation.host}" but the runtime has no cloudHttp backend configured. Use OllamaClient.webSearch() / OllamaClient.webFetch() for cloud-hosted operations, or construct OllamaRuntime with a cloudHttp option.`
764
+ );
765
+ }
766
+ return cloudHttp;
767
+ }
768
+ return this.options.http;
769
+ }
306
770
  /**
307
771
  * Invoke an operation. Called by every generated API method.
308
772
  *
@@ -311,7 +775,7 @@ var OllamaRuntime = class {
311
775
  * class's overloads pick the right return type at compile time.
312
776
  */
313
777
  async invoke(req) {
314
- assertOperationAllowed(req.operation, this.options);
778
+ await this.assertOperationAllowed(req.operation);
315
779
  let body = buildBody(req);
316
780
  if (this.options.validateRequests === true && body !== void 0) {
317
781
  const schema = getRequestSchema(req.operation.operationId);
@@ -330,32 +794,185 @@ var OllamaRuntime = class {
330
794
  body = result.data;
331
795
  }
332
796
  }
797
+ if (body !== void 0) {
798
+ const serialized = serializeForByteCount(body);
799
+ const hasImages = bodyHasImages(body);
800
+ const maxBytesWithImages = req.operation.constraints?.maxRequestBytesWithImages;
801
+ const maxBytesBase = req.operation.constraints?.maxRequestBytes;
802
+ const applicableLimit = hasImages && maxBytesWithImages !== void 0 ? maxBytesWithImages : maxBytesBase;
803
+ if (applicableLimit !== void 0 && serialized.byteLength > applicableLimit) {
804
+ throw new OllamaRequestTooLargeError(
805
+ `Operation ${req.operation.operationId} (${req.operation.method} ${req.operation.path}) request body is ${serialized.byteLength} bytes, exceeding the contract limit of ${applicableLimit} bytes` + (hasImages ? " (images limit)." : "."),
806
+ {
807
+ operationId: req.operation.operationId,
808
+ actualBytes: serialized.byteLength,
809
+ maxBytes: applicableLimit,
810
+ request: { method: req.operation.method, url: req.operation.path }
811
+ }
812
+ );
813
+ }
814
+ }
333
815
  const streaming = shouldStream(req);
816
+ const resolvedPath = resolvePathParams(req.operation.path, req.pathParams);
817
+ const pathWithQuery = applyQueryParams(resolvedPath, req.queryParams);
818
+ const model = req.model ?? extractModelFromBody(body);
819
+ const headers = {};
820
+ if (req.headerParams) {
821
+ for (const [key, value] of Object.entries(req.headerParams)) {
822
+ headers[key] = value;
823
+ }
824
+ }
334
825
  const httpReq = {
335
- path: req.operation.path,
826
+ path: pathWithQuery,
336
827
  method: req.operation.method,
337
828
  ...body !== void 0 ? { body } : {},
829
+ ...Object.keys(headers).length > 0 ? { headers } : {},
338
830
  ...req.signal !== void 0 ? { signal: req.signal } : {},
339
- // For streaming calls, request the raw Response so we can pipe it
340
- // through parseNdjsonStream directly. This inherits middleware,
341
- // retry, telemetry, and error-mapping from HttpClient — the
342
- // previous Wave 3 implementation bypassed them with a direct
343
- // `fetch()` call.
344
- ...streaming ? { raw: true } : {}
831
+ ...streaming ? { raw: true } : {},
832
+ ...model !== void 0 ? { model } : {}
345
833
  };
346
834
  if (!streaming) {
347
- return await this.options.http.request(httpReq);
835
+ const result = await this.resolveHttpBackend(req.operation).request(httpReq);
836
+ if (this.options.validateResponses === true) {
837
+ const responseSchema = getResponseSchema(req.operation.operationId);
838
+ if (responseSchema) {
839
+ const result2 = responseSchema.safeParse(result);
840
+ if (!result2.success) {
841
+ throw new OllamaResponseValidationError(
842
+ `Response validation failed for operation "${req.operation.operationId}" (${req.operation.method} ${req.operation.path}): ` + result2.error.issues.map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`).join("; "),
843
+ {
844
+ operationId: req.operation.operationId,
845
+ issues: result2.error.issues,
846
+ request: { method: req.operation.method, url: req.operation.path }
847
+ }
848
+ );
849
+ }
850
+ }
851
+ }
852
+ return result;
348
853
  }
349
- const response = await this.options.http.request(httpReq);
854
+ const response = await this.resolveHttpBackend(req.operation).request(httpReq);
350
855
  if (!response.body) {
351
856
  throw new OllamaGenericClientError(
352
857
  `Operation ${req.operation.operationId}: streaming response had no body.`
353
858
  );
354
859
  }
355
- return parseNdjsonStream(response.body);
860
+ return parseStreamByMode(req.operation.transport.mode, response.body);
861
+ }
862
+ /**
863
+ * Apply environment + version guards before delegating to HttpClient.
864
+ *
865
+ * Throws {@link OllamaGenericClientError} when:
866
+ * - The operation is local-only and the runtime is in cloud mode.
867
+ * - The operation has `constraints.minOllamaVersion` and the server is older.
868
+ *
869
+ * Wave 12 (P0 #5): when `minOllamaVersion` is declared but the runtime's
870
+ * `serverVersion` is unknown AND `enforceVersion` is `'auto'` or
871
+ * `'strict'`, the runtime lazily fetches `/api/version` (cached on the
872
+ * runtime instance) so the constraint is actually enforced even when the
873
+ * caller didn't supply it. Previously the constraint was only enforced
874
+ * when `serverVersion` was manually supplied — meaning in practice it was
875
+ * almost never enforced.
876
+ */
877
+ async assertOperationAllowed(operation) {
878
+ const localMode = this.options.localMode ?? true;
879
+ if (!localMode && !operation.environment.cloud) {
880
+ throw new OllamaGenericClientError(
881
+ `Operation ${operation.operationId} (${operation.method} ${operation.path}) is local-only and not supported in cloud mode.`
882
+ );
883
+ }
884
+ const minVersion = operation.constraints?.minOllamaVersion;
885
+ if (!minVersion) return;
886
+ let serverVersion = this.options.serverVersion;
887
+ const policy = this.options.enforceVersion ?? "auto";
888
+ if (!serverVersion && policy !== "off") {
889
+ if (!this.serverVersionCache) {
890
+ const p = fetchServerVersion(this.options.http).catch((err) => {
891
+ if (policy === "strict") {
892
+ throw new OllamaServerVersionUnknownError(
893
+ `Operation ${operation.operationId} requires Ollama >= ${minVersion} but the runtime could not determine the server version (enforceVersion: 'strict').`,
894
+ {
895
+ operationId: operation.operationId,
896
+ minRequiredVersion: minVersion,
897
+ cause: err
898
+ }
899
+ );
900
+ }
901
+ return void 0;
902
+ });
903
+ this.serverVersionCache = p;
904
+ }
905
+ serverVersion = await this.serverVersionCache ?? void 0;
906
+ }
907
+ if (serverVersion && compareVersions(serverVersion, minVersion) < 0) {
908
+ throw new OllamaGenericClientError(
909
+ `Operation ${operation.operationId} (${operation.method} ${operation.path}) requires Ollama >= ${minVersion} (server reports ${serverVersion}).`
910
+ );
911
+ }
356
912
  }
357
913
  };
914
+ function parseStreamByMode(mode, body) {
915
+ if (mode === "ndjson") {
916
+ return parseNdjsonStream(body);
917
+ }
918
+ if (mode === "sse") {
919
+ return parseSseStreamAsJson(body);
920
+ }
921
+ throw new OllamaGenericClientError(
922
+ `Transport mode "${mode}" is not a streaming mode; cannot parse a stream for it.`
923
+ );
924
+ }
925
+ async function* parseSseStreamAsJson(body) {
926
+ for await (const event of parseSseStream(body)) {
927
+ const data = event.data;
928
+ if (!data) continue;
929
+ if (data === "[DONE]") return;
930
+ try {
931
+ yield JSON.parse(data);
932
+ } catch (err) {
933
+ throw new OllamaGenericClientError(`Failed to parse SSE event data as JSON: ${data}`, {
934
+ cause: err
935
+ });
936
+ }
937
+ }
938
+ }
939
+ function serializeForByteCount(body) {
940
+ if (body instanceof Uint8Array) return body;
941
+ if (typeof body === "string") return new TextEncoder().encode(body);
942
+ const json = JSON.stringify(body);
943
+ return new TextEncoder().encode(json);
944
+ }
945
+ function bodyHasImages(body) {
946
+ if (typeof body !== "object" || body === null) return false;
947
+ const obj = body;
948
+ const images = obj.images;
949
+ return Array.isArray(images) && images.length > 0;
950
+ }
951
+ function resolvePathParams(pathTemplate, pathParams) {
952
+ if (!pathTemplate.includes("{")) return pathTemplate;
953
+ const params = pathParams ?? {};
954
+ return pathTemplate.replace(/\{([^}]+)\}/g, (_match, name) => {
955
+ const value = params[name];
956
+ if (value === void 0) {
957
+ throw new OllamaGenericClientError(
958
+ `Missing path parameter "${name}" for path template "${pathTemplate}". Provide it via the pathParams field on the invoke() request.`
959
+ );
960
+ }
961
+ return encodeURIComponent(value);
962
+ });
963
+ }
964
+ function extractModelFromBody(body) {
965
+ if (typeof body !== "object" || body === null) return void 0;
966
+ const obj = body;
967
+ const model = obj.model;
968
+ return typeof model === "string" ? model : void 0;
969
+ }
970
+ function applyQueryParams(path, queryParams) {
971
+ if (!queryParams || Object.keys(queryParams).length === 0) return path;
972
+ const pairs = Object.entries(queryParams).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
973
+ return `${path}?${pairs}`;
974
+ }
358
975
 
359
- export { OllamaRuntime, getRequestSchema, requestSchemas };
976
+ export { OllamaRuntime, getRequestSchema, getResponseSchema, requestSchemas, responseSchemas };
360
977
  //# sourceMappingURL=generated-runtime.js.map
361
978
  //# sourceMappingURL=generated-runtime.js.map