@nemesis-oss/ollama-sdk 1.4.1 → 1.5.1
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 +9 -0
- package/README.md +23 -2
- package/dist/{compose-DfAqKAFj.d.ts → compose-DLStUfaF.d.ts} +2 -2
- package/dist/{compose-BR70yb4W.d.cts → compose-DS-UWFx8.d.cts} +2 -2
- package/dist/generated-api.d.cts +4 -3
- package/dist/generated-api.d.ts +4 -3
- package/dist/generated-runtime.cjs +161 -1
- package/dist/generated-runtime.cjs.map +1 -1
- package/dist/generated-runtime.d.cts +35 -2
- package/dist/generated-runtime.d.ts +35 -2
- package/dist/generated-runtime.js +160 -2
- package/dist/generated-runtime.js.map +1 -1
- package/dist/index.cjs +158 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +158 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-generated.d.cts +4 -3
- package/dist/mcp-generated.d.ts +4 -3
- package/dist/mcp-http.d.cts +1 -1
- package/dist/mcp-http.d.ts +1 -1
- package/dist/mcp-stdio.d.cts +1 -1
- package/dist/mcp-stdio.d.ts +1 -1
- package/dist/{index-DIQ8NUbU.d.ts → runtime-CVQkbYgF.d.ts} +40 -2
- package/dist/{index-2RIErNT5.d.cts → runtime-IxRpUBjN.d.cts} +40 -2
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +3 -3
- package/dist/skills.d.ts +3 -3
- package/dist/skills.js.map +1 -1
- package/dist/{types-BQhgW-du.d.cts → types-5PAjLoCp.d.cts} +1 -1
- package/dist/{types-BQhgW-du.d.ts → types-5PAjLoCp.d.ts} +1 -1
- package/dist/{types-B9_axjum.d.cts → types-MOsWXEE7.d.cts} +1 -1
- package/dist/{types-B9_axjum.d.ts → types-MOsWXEE7.d.ts} +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- **Runtime Zod validation (Wave 10).** `OllamaRuntime` now accepts a `validateRequests: true` option. When enabled, every request body is validated against the operation's generated Zod schema BEFORE any HTTP request is made. Malformed requests throw `OllamaRequestValidationError` (a new `OllamaClientError` subclass) with the Zod issues attached. Unknown fields are stripped (Zod's default behavior), so callers can't accidentally send extra fields the contract doesn't allow. Opt-in — zero overhead when disabled (the default). See [ADR 0020](./docs/adr/0020-runtime-zod-validation.md).
|
|
6
|
+
|
|
7
|
+
## [1.4.1] - 2026-10-01
|
|
8
|
+
|
|
9
|
+
- **`noImplicitOverride` + exhaustive switch defaults.** Enabled `noImplicitOverride: true` in `tsconfig.json` so any future class method override must be explicitly marked with `override`. Added exhaustive `never` defaults to the 2 emitter switches over `JsonSchemaNode.type` — if the OpenAPI spec adds a new schema type, the build fails until the emitter is updated. See [ADR 0014](./docs/adr/0014-generated-surface-and-runtime-seam.md).
|
|
10
|
+
- **`using` declarations for resource cleanup (TS 5.2+).** Replaced 6 `try/finally` cleanup blocks (timers, stream readers, OpenTelemetry spans, timeout signals) with `using` / `await using` declarations via 3 new `Disposable` helpers in `src/utils.ts` (`disposableTimer`, `disposableReader`, `disposableSpan`). Eliminates the "forgot to clean up in the finally block" bug class — cleanup is now structurally guaranteed by the scope. 8 stateful `try/finally` blocks are intentionally NOT converted (correctly stateful). See [ADR 0014](./docs/adr/0014-generated-surface-and-runtime-seam.md).
|
|
11
|
+
|
|
12
|
+
## [1.4.0] - 2026-10-01
|
|
13
|
+
|
|
5
14
|
- **Contract-first hybrid architecture (Waves 1-9).** The SDK now ships a single canonical IR at `contracts/ir/ollama.ir.json` (compiled from `contracts/sources/` + `contracts/overlays/`) that drives seven consumers: TypeScript interfaces, generated API classes, MCP tool descriptors, operation metadata, field-level parity, Zod schemas, and bidirectional endpoint discovery. Adding a new Ollama operation now requires writing one overlay block; everything else is generated. See [ADRs 0013-0019](./docs/adr/README.md) for the full design.
|
|
6
15
|
- **Wave 1** — Contract foundation: sources, overlays, canonical IR, bidirectional endpoint discovery (catches new endpoints like `/v1/systemone` that the OpenAPI spec doesn't yet cover).
|
|
7
16
|
- **Wave 2** — Generated TypeScript interfaces in `src/generated/models/` (36 schemas), with a drift detector comparing against `src/types.ts`.
|
package/README.md
CHANGED
|
@@ -948,8 +948,9 @@ no method signatures have changed — existing callers continue to work.
|
|
|
948
948
|
### Runtime validation with generated Zod schemas
|
|
949
949
|
|
|
950
950
|
Every TypeScript interface in `src/generated/models/<name>.ts` has a paired Zod schema
|
|
951
|
-
in `src/generated/models/<name>.schema.ts`.
|
|
952
|
-
|
|
951
|
+
in `src/generated/models/<name>.schema.ts`. Two ways to use them:
|
|
952
|
+
|
|
953
|
+
**Per-call validation** — for one-off checks, import the schema directly:
|
|
953
954
|
|
|
954
955
|
```typescript
|
|
955
956
|
import { ChatRequestSchema } from '@nemesis-oss/ollama-sdk/generated/models/schemas';
|
|
@@ -962,6 +963,26 @@ if (!result.success) {
|
|
|
962
963
|
}
|
|
963
964
|
```
|
|
964
965
|
|
|
966
|
+
**Runtime-wide validation** (Wave 10) — opt in once on the runtime constructor
|
|
967
|
+
and every request body is validated automatically before the HTTP call:
|
|
968
|
+
|
|
969
|
+
```typescript
|
|
970
|
+
import { OllamaRuntime } from '@nemesis-oss/ollama-sdk/generated/runtime';
|
|
971
|
+
|
|
972
|
+
const runtime = new OllamaRuntime({ http, validateRequests: true });
|
|
973
|
+
// Every chat/generate/embed/create/copy/delete/pull/push/show request
|
|
974
|
+
// is now validated against the IR-derived Zod schema. Malformed requests
|
|
975
|
+
// throw OllamaRequestValidationError BEFORE any network call is made.
|
|
976
|
+
// Unknown fields are stripped (Zod default), so callers can't accidentally
|
|
977
|
+
// send extra fields the contract doesn't allow.
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
When validation fails, the runtime throws `OllamaRequestValidationError`
|
|
981
|
+
(an `OllamaClientError` subclass with `code: 'request_validation_error'`,
|
|
982
|
+
`retryable: false`) carrying the operation ID and the Zod issues array.
|
|
983
|
+
Zero overhead when `validateRequests` is not set — the default behavior
|
|
984
|
+
is unchanged. See [ADR 0020](./docs/adr/0020-runtime-zod-validation.md).
|
|
985
|
+
|
|
965
986
|
### Generated MCP tools
|
|
966
987
|
|
|
967
988
|
The IR also produces 21 MCP tool descriptors (one per documented Ollama operation) at
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { p as ToolDefinition, q as ToolCall, r as Message } from './types-5PAjLoCp.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -161,4 +161,4 @@ interface AppliedSkillResult {
|
|
|
161
161
|
*/
|
|
162
162
|
declare function applySkill(skill: Skill, options: ApplySkillOptions): AppliedSkillResult;
|
|
163
163
|
|
|
164
|
-
export { type
|
|
164
|
+
export { type AnyTool as A, type ParsedFrontmatter as P, type Skill as S, type ToolHandler as T, type Tool as a, ToolRegistry as b, type ToolExecutionResult as c, type AppliedSkillResult as d, type ApplySkillOptions as e, type SkillFrontmatter as f, type SkillSummary as g, type ToolExecutionContext as h, type ToolExecutionFailure as i, type ToolExecutionSuccess as j, type ToolRegistryOptions as k, applySkill as l, parseFrontmatter as p };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { p as ToolDefinition, q as ToolCall, r as Message } from './types-5PAjLoCp.cjs';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -161,4 +161,4 @@ interface AppliedSkillResult {
|
|
|
161
161
|
*/
|
|
162
162
|
declare function applySkill(skill: Skill, options: ApplySkillOptions): AppliedSkillResult;
|
|
163
163
|
|
|
164
|
-
export { type
|
|
164
|
+
export { type AnyTool as A, type ParsedFrontmatter as P, type Skill as S, type ToolHandler as T, type Tool as a, ToolRegistry as b, type ToolExecutionResult as c, type AppliedSkillResult as d, type ApplySkillOptions as e, type SkillFrontmatter as f, type SkillSummary as g, type ToolExecutionContext as h, type ToolExecutionFailure as i, type ToolExecutionSuccess as j, type ToolRegistryOptions as k, applySkill as l, parseFrontmatter as p };
|
package/dist/generated-api.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { O as OllamaRuntime } from './
|
|
2
|
-
export {
|
|
3
|
-
import './types-
|
|
1
|
+
import { O as OllamaRuntime } from './runtime-IxRpUBjN.cjs';
|
|
2
|
+
export { a as OperationDefinition } from './runtime-IxRpUBjN.cjs';
|
|
3
|
+
import './types-5PAjLoCp.cjs';
|
|
4
|
+
import 'zod';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.
|
package/dist/generated-api.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { O as OllamaRuntime } from './
|
|
2
|
-
export {
|
|
3
|
-
import './types-
|
|
1
|
+
import { O as OllamaRuntime } from './runtime-CVQkbYgF.js';
|
|
2
|
+
export { a as OperationDefinition } from './runtime-CVQkbYgF.js';
|
|
3
|
+
import './types-5PAjLoCp.js';
|
|
4
|
+
import 'zod';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
|
|
3
5
|
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
4
6
|
var __typeError = (msg) => {
|
|
5
7
|
throw TypeError(msg);
|
|
@@ -63,6 +65,15 @@ var OllamaClientError = class extends Error {
|
|
|
63
65
|
this.response = options.response;
|
|
64
66
|
}
|
|
65
67
|
};
|
|
68
|
+
var OllamaRequestValidationError = class extends OllamaClientError {
|
|
69
|
+
operationId;
|
|
70
|
+
issues;
|
|
71
|
+
constructor(message, options) {
|
|
72
|
+
super(message, { ...options, code: "request_validation_error", retryable: false });
|
|
73
|
+
this.operationId = options.operationId;
|
|
74
|
+
this.issues = options.issues;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
66
77
|
var OllamaGenericClientError = class extends OllamaClientError {
|
|
67
78
|
constructor(message, options) {
|
|
68
79
|
super(message, { ...options, code: "client_error" });
|
|
@@ -118,6 +129,136 @@ async function* parseNdjsonStream(stream) {
|
|
|
118
129
|
_promise && await _promise;
|
|
119
130
|
}
|
|
120
131
|
}
|
|
132
|
+
var ToolCallSchema = zod.z.object({
|
|
133
|
+
function: zod.z.object({
|
|
134
|
+
name: zod.z.string(),
|
|
135
|
+
description: zod.z.string().optional(),
|
|
136
|
+
arguments: zod.z.object({}).optional()
|
|
137
|
+
}).optional()
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// src/generated/models/ChatMessage.schema.ts
|
|
141
|
+
var ChatMessageSchema = zod.z.object({
|
|
142
|
+
role: zod.z.enum(["system", "user", "assistant", "tool"]),
|
|
143
|
+
content: zod.z.string(),
|
|
144
|
+
images: zod.z.array(zod.z.string()).optional(),
|
|
145
|
+
tool_calls: zod.z.array(ToolCallSchema).optional()
|
|
146
|
+
});
|
|
147
|
+
var ModelOptionsSchema = zod.z.object({
|
|
148
|
+
seed: zod.z.number().optional(),
|
|
149
|
+
temperature: zod.z.number().optional(),
|
|
150
|
+
top_k: zod.z.number().optional(),
|
|
151
|
+
top_p: zod.z.number().optional(),
|
|
152
|
+
min_p: zod.z.number().optional(),
|
|
153
|
+
stop: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]).optional(),
|
|
154
|
+
num_ctx: zod.z.number().optional(),
|
|
155
|
+
num_predict: zod.z.number().optional()
|
|
156
|
+
}).catchall(zod.z.unknown());
|
|
157
|
+
var ThinkValueSchema = zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.null()]);
|
|
158
|
+
var ToolDefinitionSchema = zod.z.object({
|
|
159
|
+
type: zod.z.enum(["function"]),
|
|
160
|
+
function: zod.z.object({
|
|
161
|
+
name: zod.z.string(),
|
|
162
|
+
description: zod.z.string().optional(),
|
|
163
|
+
parameters: zod.z.object({})
|
|
164
|
+
})
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// src/generated/models/ChatRequest.schema.ts
|
|
168
|
+
var ChatRequestSchema = zod.z.object({
|
|
169
|
+
model: zod.z.string(),
|
|
170
|
+
messages: zod.z.array(ChatMessageSchema),
|
|
171
|
+
tools: zod.z.array(ToolDefinitionSchema).optional(),
|
|
172
|
+
format: zod.z.union([zod.z.enum(["json"]), zod.z.object({})]).optional(),
|
|
173
|
+
options: ModelOptionsSchema.optional(),
|
|
174
|
+
stream: zod.z.boolean().optional(),
|
|
175
|
+
think: ThinkValueSchema.optional(),
|
|
176
|
+
keep_alive: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
|
|
177
|
+
logprobs: zod.z.boolean().optional(),
|
|
178
|
+
top_logprobs: zod.z.number().optional()
|
|
179
|
+
});
|
|
180
|
+
var GenerateRequestSchema = zod.z.object({
|
|
181
|
+
model: zod.z.string(),
|
|
182
|
+
prompt: zod.z.string().optional(),
|
|
183
|
+
suffix: zod.z.string().optional(),
|
|
184
|
+
images: zod.z.array(zod.z.string()).optional(),
|
|
185
|
+
format: zod.z.union([zod.z.string(), zod.z.object({})]).optional(),
|
|
186
|
+
system: zod.z.string().optional(),
|
|
187
|
+
stream: zod.z.boolean().optional(),
|
|
188
|
+
think: ThinkValueSchema.optional(),
|
|
189
|
+
raw: zod.z.boolean().optional(),
|
|
190
|
+
keep_alive: zod.z.union([zod.z.string(), zod.z.number()]).optional(),
|
|
191
|
+
options: ModelOptionsSchema.optional(),
|
|
192
|
+
logprobs: zod.z.boolean().optional(),
|
|
193
|
+
top_logprobs: zod.z.number().optional()
|
|
194
|
+
});
|
|
195
|
+
var EmbedRequestSchema = zod.z.object({
|
|
196
|
+
model: zod.z.string(),
|
|
197
|
+
input: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]),
|
|
198
|
+
truncate: zod.z.boolean().optional(),
|
|
199
|
+
dimensions: zod.z.number().optional(),
|
|
200
|
+
keep_alive: zod.z.string().optional(),
|
|
201
|
+
options: ModelOptionsSchema.optional()
|
|
202
|
+
});
|
|
203
|
+
var CreateRequestSchema = zod.z.object({
|
|
204
|
+
model: zod.z.string(),
|
|
205
|
+
from: zod.z.string().optional(),
|
|
206
|
+
template: zod.z.string().optional(),
|
|
207
|
+
renderer: zod.z.string().optional(),
|
|
208
|
+
parser: zod.z.string().optional(),
|
|
209
|
+
files: zod.z.object({}).catchall(zod.z.string()).optional(),
|
|
210
|
+
draft_files: zod.z.object({}).catchall(zod.z.string()).optional(),
|
|
211
|
+
license: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]).optional(),
|
|
212
|
+
system: zod.z.string().optional(),
|
|
213
|
+
parameters: zod.z.object({}).optional(),
|
|
214
|
+
messages: zod.z.array(ChatMessageSchema).optional(),
|
|
215
|
+
quantize: zod.z.string().optional(),
|
|
216
|
+
draft_quantize: zod.z.string().optional(),
|
|
217
|
+
requires: zod.z.string().optional(),
|
|
218
|
+
stream: zod.z.boolean().optional()
|
|
219
|
+
});
|
|
220
|
+
var CopyRequestSchema = zod.z.object({
|
|
221
|
+
source: zod.z.string(),
|
|
222
|
+
destination: zod.z.string()
|
|
223
|
+
});
|
|
224
|
+
var DeleteRequestSchema = zod.z.object({
|
|
225
|
+
model: zod.z.string()
|
|
226
|
+
});
|
|
227
|
+
var PullRequestSchema = zod.z.object({
|
|
228
|
+
model: zod.z.string(),
|
|
229
|
+
insecure: zod.z.boolean().optional(),
|
|
230
|
+
stream: zod.z.boolean().optional()
|
|
231
|
+
});
|
|
232
|
+
var PushRequestSchema = zod.z.object({
|
|
233
|
+
model: zod.z.string(),
|
|
234
|
+
insecure: zod.z.boolean().optional(),
|
|
235
|
+
stream: zod.z.boolean().optional()
|
|
236
|
+
});
|
|
237
|
+
var ShowRequestSchema = zod.z.object({
|
|
238
|
+
model: zod.z.string(),
|
|
239
|
+
verbose: zod.z.boolean().optional()
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// src/generated/runtime/schema-registry.ts
|
|
243
|
+
var requestSchemas = {
|
|
244
|
+
chat: ChatRequestSchema,
|
|
245
|
+
generate: GenerateRequestSchema,
|
|
246
|
+
embed: EmbedRequestSchema,
|
|
247
|
+
create: CreateRequestSchema,
|
|
248
|
+
copy: CopyRequestSchema,
|
|
249
|
+
delete: DeleteRequestSchema,
|
|
250
|
+
pull: PullRequestSchema,
|
|
251
|
+
push: PushRequestSchema,
|
|
252
|
+
show: ShowRequestSchema
|
|
253
|
+
// Operations without a registered request schema (blobs, ps, tags,
|
|
254
|
+
// version, systemOne, openai*, anthropic*) skip validation. This is
|
|
255
|
+
// deliberate — the OpenAPI spec doesn't define request bodies for
|
|
256
|
+
// GET/HEAD operations, and the compat-surface request schemas (OpenAI,
|
|
257
|
+
// Anthropic) are richer than what the IR currently models.
|
|
258
|
+
};
|
|
259
|
+
function getRequestSchema(operationId) {
|
|
260
|
+
return requestSchemas[operationId];
|
|
261
|
+
}
|
|
121
262
|
|
|
122
263
|
// src/generated/runtime/runtime.ts
|
|
123
264
|
function compareVersions(a, b) {
|
|
@@ -173,7 +314,24 @@ var OllamaRuntime = class {
|
|
|
173
314
|
*/
|
|
174
315
|
async invoke(req) {
|
|
175
316
|
assertOperationAllowed(req.operation, this.options);
|
|
176
|
-
|
|
317
|
+
let body = buildBody(req);
|
|
318
|
+
if (this.options.validateRequests === true && body !== void 0) {
|
|
319
|
+
const schema = getRequestSchema(req.operation.operationId);
|
|
320
|
+
if (schema) {
|
|
321
|
+
const result = schema.safeParse(body);
|
|
322
|
+
if (!result.success) {
|
|
323
|
+
throw new OllamaRequestValidationError(
|
|
324
|
+
`Request validation failed for operation "${req.operation.operationId}" (${req.operation.method} ${req.operation.path}): ` + result.error.issues.map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`).join("; "),
|
|
325
|
+
{
|
|
326
|
+
operationId: req.operation.operationId,
|
|
327
|
+
issues: result.error.issues,
|
|
328
|
+
request: { method: req.operation.method, url: req.operation.path }
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
body = result.data;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
177
335
|
const streaming = shouldStream(req);
|
|
178
336
|
const httpReq = {
|
|
179
337
|
path: req.operation.path,
|
|
@@ -201,5 +359,7 @@ var OllamaRuntime = class {
|
|
|
201
359
|
};
|
|
202
360
|
|
|
203
361
|
exports.OllamaRuntime = OllamaRuntime;
|
|
362
|
+
exports.getRequestSchema = getRequestSchema;
|
|
363
|
+
exports.requestSchemas = requestSchemas;
|
|
204
364
|
//# sourceMappingURL=generated-runtime.cjs.map
|
|
205
365
|
//# sourceMappingURL=generated-runtime.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/utils.ts","../src/streaming/ndjson.ts","../src/generated/runtime/runtime.ts"],"names":[],"mappings":"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","file":"generated-runtime.cjs","sourcesContent":["/**\n * Structured, typed error hierarchy for OllamaClient.\n */\n\nexport interface OllamaErrorRequestContext {\n readonly method?: string | undefined;\n readonly url?: string | undefined;\n readonly model?: string | undefined;\n}\n\nexport interface OllamaErrorResponseContext {\n readonly status?: number | undefined;\n readonly headers?: Record<string, string> | undefined;\n readonly body?: unknown;\n}\n\nexport interface OllamaClientErrorOptions extends ErrorOptions {\n readonly code: string;\n readonly status?: number | undefined;\n readonly retryable?: boolean | undefined;\n readonly request?: OllamaErrorRequestContext | undefined;\n readonly response?: OllamaErrorResponseContext | undefined;\n}\n\nexport class OllamaClientError extends Error {\n readonly code: string;\n readonly status?: number | undefined;\n readonly retryable: boolean;\n readonly request?: OllamaErrorRequestContext | undefined;\n readonly response?: OllamaErrorResponseContext | undefined;\n\n constructor(message: string, options: OllamaClientErrorOptions) {\n super(message, { cause: options.cause });\n this.name = this.constructor.name;\n this.code = options.code;\n this.status = options.status;\n this.retryable = options.retryable ?? false;\n this.request = options.request;\n this.response = options.response;\n }\n}\n\nexport class OllamaNetworkError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'network_error', retryable: true });\n }\n}\n\nexport class OllamaTimeoutError extends OllamaClientError {\n readonly timeoutMs?: number | undefined;\n constructor(\n message: string,\n options?:\n | (Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & { timeoutMs?: number | undefined })\n | undefined,\n ) {\n super(message, { ...options, code: 'timeout', retryable: true });\n this.timeoutMs = options?.timeoutMs;\n }\n}\n\nexport class OllamaAuthError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'auth_error', retryable: false });\n }\n}\n\nexport class OllamaNotFoundError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'not_found', retryable: false });\n }\n}\n\nexport class OllamaRateLimitError extends OllamaClientError {\n readonly retryAfterMs?: number | undefined;\n constructor(\n message: string,\n options?:\n | (Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n retryAfterMs?: number | undefined;\n })\n | undefined,\n ) {\n super(message, { ...options, code: 'rate_limited', retryable: true });\n this.retryAfterMs = options?.retryAfterMs;\n }\n}\n\n/**\n * Thrown client-side, before a network request is made, by `QuotaManager.assertCanProceed`\n * (see `src/quota.ts`) when issuing the request would exceed a configured usage budget for\n * one of its rolling windows. This is distinct from `OllamaRateLimitError`, which reflects\n * the server's own 429 response — Ollama Cloud does not expose account-level quota via the\n * API, so `QuotaManager` tracks usage against budgets the caller configures locally and\n * fails fast rather than waiting for the server to reject the request.\n */\nexport class OllamaQuotaExceededError extends OllamaClientError {\n readonly windowId: string;\n readonly resetAt: number;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n windowId: string;\n resetAt: number;\n },\n ) {\n super(message, { ...options, code: 'quota_exceeded', retryable: false });\n this.windowId = options.windowId;\n this.resetAt = options.resetAt;\n }\n}\n\nexport class OllamaServerError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'server_error', retryable: true });\n }\n}\n\nexport class OllamaAbortError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'aborted', retryable: false });\n }\n}\n\nexport class OllamaToolValidationError extends OllamaClientError {\n readonly toolName: string;\n readonly issues?: unknown;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & { toolName: string; issues?: unknown },\n ) {\n super(message, { ...options, code: 'tool_validation_error', retryable: false });\n this.toolName = options.toolName;\n this.issues = options.issues;\n }\n}\n\nexport class OllamaToolTimeoutError extends OllamaClientError {\n readonly toolName: string;\n readonly timeoutMs: number;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n toolName: string;\n timeoutMs: number;\n },\n ) {\n super(message, { ...options, code: 'tool_timeout', retryable: false });\n this.toolName = options.toolName;\n this.timeoutMs = options.timeoutMs;\n }\n}\n\n/**\n * Thrown client-side, before a network request is made, when a request asks for a\n * capability an endpoint is known not to support (e.g. structured output `format` against\n * an Ollama Cloud endpoint — see `ModelCapabilities.supportsStructuredOutputRequest` in\n * `src/capabilities/capabilities.ts`). Its `code` is included in `DEFAULT_FAILOVER_CODES`\n * by default, so in a multi-endpoint setup it causes failover to the next candidate rather\n * than failing outright — it only surfaces to the caller if every candidate is rejected.\n */\nexport class OllamaUnsupportedCapabilityError extends OllamaClientError {\n readonly capability: string;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & { capability: string },\n ) {\n super(message, { ...options, code: 'unsupported_capability', retryable: false });\n this.capability = options.capability;\n }\n}\n\n/**\n * Thrown client-side, before any network call, when `config.endpoints` uses\n * `OllamaEndpoint.models` to scope endpoints/credentials to specific models and the\n * requested `model` isn't in any configured endpoint's allow-list. This is a routing\n * misconfiguration, not a connectivity problem — the SDK deliberately does not \"probe\"\n * unauthorized endpoints to find one that happens to work (that would burn quota on keys\n * that were never entitled to the model and produce non-deterministic startup behavior).\n */\nexport class OllamaModelRoutingError extends OllamaClientError {\n readonly model: string;\n readonly availableModels: readonly string[];\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n model: string;\n availableModels: readonly string[];\n },\n ) {\n super(message, { ...options, code: 'model_routing_error', retryable: false });\n this.model = options.model;\n this.availableModels = options.availableModels;\n }\n}\n\n/**\n * Thrown before an agent tool loop starts when the selected model's /api/show metadata\n * does not advertise a capability required by the loop.\n */\nexport class OllamaIncompatibleModelError extends OllamaClientError {\n readonly model: string;\n readonly capability: string;\n readonly reportedCapabilities: readonly string[];\n\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n model: string;\n capability: string;\n reportedCapabilities: readonly string[];\n },\n ) {\n super(message, { ...options, code: 'incompatible_model', retryable: false });\n this.model = options.model;\n this.capability = options.capability;\n this.reportedCapabilities = options.reportedCapabilities;\n }\n}\nexport class OllamaAgentMaxToolCallsError extends OllamaClientError {\n readonly maxToolCalls: number;\n readonly toolCallsExecuted: number;\n\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n maxToolCalls: number;\n toolCallsExecuted: number;\n },\n ) {\n super(message, { ...options, code: 'agent_max_tool_calls_exceeded', retryable: false });\n this.maxToolCalls = options.maxToolCalls;\n this.toolCallsExecuted = options.toolCallsExecuted;\n }\n}\n\nexport class OllamaAgentMaxIterationsError extends OllamaClientError {\n readonly maxIterations: number;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & { maxIterations: number },\n ) {\n super(message, { ...options, code: 'agent_max_iterations_exceeded', retryable: false });\n this.maxIterations = options.maxIterations;\n }\n}\n\nexport class OllamaMcpError extends OllamaClientError {\n readonly mcpMethod: 'listTools' | 'callTool';\n readonly toolName?: string | undefined;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n mcpMethod: 'listTools' | 'callTool';\n toolName?: string | undefined;\n },\n ) {\n super(message, { ...options, code: 'mcp_error', retryable: options.retryable ?? false });\n this.mcpMethod = options.mcpMethod;\n this.toolName = options.toolName;\n }\n}\n\nexport class OllamaSkillNotFoundError extends OllamaClientError {\n readonly skillName: string;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & { skillName: string },\n ) {\n super(message, { ...options, code: 'skill_not_found', retryable: false });\n this.skillName = options.skillName;\n }\n}\n\nexport class OllamaSkillInvalidError extends OllamaClientError {\n readonly skillName: string;\n readonly path?: string | undefined;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n skillName: string;\n path?: string | undefined;\n },\n ) {\n super(message, { ...options, code: 'skill_invalid', retryable: false });\n this.skillName = options.skillName;\n this.path = options.path;\n }\n}\n\nexport class OllamaGenericClientError extends OllamaClientError {\n constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code'> | undefined) {\n super(message, { ...options, code: 'client_error' });\n }\n}\n\nfunction isDomAbortError(error: unknown): error is DOMException {\n return (\n typeof DOMException !== 'undefined' &&\n error instanceof DOMException &&\n error.name === 'AbortError'\n );\n}\n\nfunction statusToError(\n status: number,\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'status'>,\n): OllamaClientError {\n if (status === 401 || status === 403) {\n return new OllamaAuthError(message, { ...options, status });\n }\n if (status === 404) {\n return new OllamaNotFoundError(message, { ...options, status });\n }\n if (status === 429) {\n return new OllamaRateLimitError(message, { ...options, status });\n }\n if (status >= 500) {\n return new OllamaServerError(message, { ...options, status });\n }\n return new OllamaGenericClientError(message, { ...options, status });\n}\n\n/**\n * Maps arbitrary thrown exceptions into structured OllamaClientError instances.\n */\nexport function mapError(\n error: unknown,\n context: {\n request?: OllamaErrorRequestContext | undefined;\n response?: OllamaErrorResponseContext | undefined;\n } = {},\n): OllamaClientError {\n if (error instanceof OllamaClientError) {\n return error;\n }\n if (isDomAbortError(error)) {\n return new OllamaAbortError(error.message || 'Request was aborted', {\n cause: error,\n request: context.request,\n });\n }\n if (error instanceof TypeError) {\n return new OllamaNetworkError(error.message || 'Network request failed', {\n cause: error,\n request: context.request,\n });\n }\n if (context.response?.status !== undefined) {\n const message = error instanceof Error ? error.message : String(error);\n return statusToError(context.response.status, message, {\n cause: error,\n request: context.request,\n response: context.response,\n });\n }\n const message = error instanceof Error ? error.message : String(error);\n return new OllamaGenericClientError(message, {\n cause: error,\n request: context.request,\n response: context.response,\n });\n}\n","/**\n * Cross-runtime helpers with no Node.js API dependency, so they stay safe to import from\n * the core client bundle (see ADR 0006 — Edge Runtime CI).\n */\n\n/**\n * Encodes an image to a base64 string, matching the wire format Ollama's `/api/chat` and\n * `/api/generate` `images` arrays expect.\n *\n * - A `string` is assumed to already be base64-encoded and is returned unchanged.\n * - A `Uint8Array` is base64-encoded using whichever universal primitive the runtime\n * exposes: `Buffer` on Node.js, `btoa` on browsers/Edge runtimes. Chunked so it doesn't\n * blow the engine's max call-stack/argument-count limits on large images.\n */\nexport async function encodeImage(image: Uint8Array | string): Promise<string> {\n if (typeof image === 'string') return image;\n\n const bufferCtor = (\n globalThis as { Buffer?: { from(data: Uint8Array): { toString(encoding: string): string } } }\n ).Buffer;\n if (bufferCtor !== undefined) return bufferCtor.from(image).toString('base64');\n\n const CHUNK_SIZE = 0x8000;\n let binary = '';\n for (let i = 0; i < image.length; i += CHUNK_SIZE) {\n binary += String.fromCharCode(...image.subarray(i, i + CHUNK_SIZE));\n }\n return btoa(binary);\n}\n\nasync function encodeImages(\n images: readonly (string | Uint8Array)[] | undefined,\n): Promise<readonly string[] | undefined> {\n if (images === undefined) return undefined;\n return Promise.all(images.map((image) => encodeImage(image)));\n}\n\n/**\n * Returns `req` unchanged if `req.images` has no `Uint8Array` entries (the common case),\n * otherwise a shallow copy with `images` base64-encoded. Keeps `chat`/`generate` request\n * bodies wire-compatible without requiring callers to pre-encode raw image bytes.\n */\nexport async function withEncodedImages<\n T extends { images?: readonly (string | Uint8Array)[] | undefined },\n>(req: T): Promise<T> {\n if (!req.images?.some((image) => image instanceof Uint8Array)) return req;\n return { ...req, images: await encodeImages(req.images) };\n}\n\n/**\n * Applies {@link withEncodedImages} to each message's `images` array. Returns `messages`\n * unchanged (same reference) if no message carries a `Uint8Array` image.\n */\nexport async function withEncodedMessageImages<\n T extends { images?: readonly (string | Uint8Array)[] | undefined },\n>(messages: readonly T[]): Promise<readonly T[]> {\n if (!messages.some((message) => message.images?.some((image) => image instanceof Uint8Array)))\n return messages;\n return Promise.all(messages.map((message) => withEncodedImages(message)));\n}\n\n// ─── Disposable helpers (TS 5.2+ `using` declarations) ──────────────────\n//\n// These wrappers turn cleanup operations into `Disposable` / `AsyncDisposable`\n// values so callers can use `using` / `await using` declarations instead of\n// try/finally blocks. This eliminates the \"forgot to clean up in the finally\n// block\" bug class for timer, reader, and span lifecycles.\n\n/** Wraps a `setTimeout` handle so `clearTimeout` runs at scope exit. */\nexport function disposableTimer(timer: ReturnType<typeof setTimeout>): Disposable {\n return {\n [Symbol.dispose]() {\n clearTimeout(timer);\n },\n };\n}\n\n/** Wraps a `ReadableStreamDefaultReader` so `cancel()` + `releaseLock()` run at scope exit. */\nexport function disposableReader<T>(reader: ReadableStreamDefaultReader<T>): AsyncDisposable {\n return {\n async [Symbol.asyncDispose]() {\n try {\n await reader.cancel();\n } catch {\n /* stream may already be closed */\n }\n reader.releaseLock();\n },\n };\n}\n\n/** Wraps an OpenTelemetry span so `span.end()` runs at scope exit. */\nexport function disposableSpan(span: { end(): void }): Disposable {\n return {\n [Symbol.dispose]() {\n span.end();\n },\n };\n}\n","/**\n * NDJSON (newline-delimited JSON) stream reader for native fetch Response bodies.\n */\n\nimport { OllamaGenericClientError } from '../errors.js';\nimport { disposableReader } from '../utils.js';\n\n/**\n * Parses a byte stream from fetch body into an async generator of typed JSON chunks.\n */\nexport async function* parseNdjsonStream<T>(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<T, void, undefined> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n await using _reader = disposableReader(reader);\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n // Keep the last partial line in buffer\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n yield JSON.parse(trimmed) as T;\n } catch (err) {\n throw new OllamaGenericClientError(`Failed to parse stream JSON chunk: ${trimmed}`, {\n cause: err,\n });\n }\n }\n }\n\n if (buffer.trim()) {\n yield JSON.parse(buffer.trim()) as T;\n }\n // reader.cancel() + reader.releaseLock() called automatically via `await using _reader`\n}\n","/**\n * OllamaRuntime — the runtime seam generated API classes delegate to.\n *\n * This is the only hand-written file in `src/generated/runtime/`. Every\n * generated method in `src/generated/api/*-api.ts` ends with:\n *\n * ```ts\n * return this.runtime.invoke({ operation: chatOp, body: request });\n * ```\n *\n * The runtime is responsible for:\n * - Method/path resolution (from {@link OperationDefinition})\n * - Streaming default application (when the request doesn't set `stream`)\n * - Environment guard (rejecting cloud calls for local-only operations)\n * - Version constraint guard (failing fast when the server is too old)\n * - Delegating to the existing {@link HttpClient} for transport, retry,\n * telemetry, NDJSON/SSE parsing\n *\n * It is intentionally a thin adapter — the existing transport, streaming,\n * middleware, and error-mapping layers are preserved verbatim. This file\n * only adds the contract-aware glue between generated API classes and the\n * existing HttpClient.\n */\nimport { HttpClient, type HttpRequestOptions } from '../../transport/http.js';\nimport { parseNdjsonStream } from '../../streaming/ndjson.js';\nimport { OllamaGenericClientError } from '../../errors.js';\nimport type { OperationDefinition, InvokeRequest } from './operation-definition.js';\n\n/** Constructor options for {@link OllamaRuntime}. */\nexport interface OllamaRuntimeOptions {\n readonly http: HttpClient;\n /**\n * Whether this runtime is targeting a local Ollama instance. Defaults to\n * `true`. When `false`, operations marked `environment.cloud === false`\n * (i.e. local-only like `/v1/systemone`) are rejected at request time.\n */\n readonly localMode?: boolean;\n /**\n * Server version, if known (typically from a prior `/api/version` call).\n * When set, operations with `constraints.minOllamaVersion` are checked\n * against this value at request time.\n */\n readonly serverVersion?: string;\n}\n\nfunction compareVersions(a: string, b: string): number {\n const pa = a.split('.').map((s) => Number.parseInt(s, 10) ?? 0);\n const pb = b.split('.').map((s) => Number.parseInt(s, 10) ?? 0);\n for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va !== vb) return va - vb;\n }\n return 0;\n}\n\n/**\n * Apply environment + version guards before delegating to HttpClient.\n *\n * Throws {@link OllamaGenericClientError} when:\n * - The operation is local-only and the runtime is in cloud mode.\n * - The operation has `constraints.minOllamaVersion` and the server is older.\n */\nfunction assertOperationAllowed(\n operation: OperationDefinition,\n options: OllamaRuntimeOptions,\n): void {\n const localMode = options.localMode ?? true;\n if (!localMode && !operation.environment.cloud) {\n throw new OllamaGenericClientError(\n `Operation ${operation.operationId} (${operation.method} ${operation.path}) ` +\n `is local-only and not supported in cloud mode.`,\n );\n }\n if (\n operation.constraints?.minOllamaVersion &&\n options.serverVersion &&\n compareVersions(options.serverVersion, operation.constraints.minOllamaVersion) < 0\n ) {\n throw new OllamaGenericClientError(\n `Operation ${operation.operationId} (${operation.method} ${operation.path}) ` +\n `requires Ollama >= ${operation.constraints.minOllamaVersion} ` +\n `(server reports ${options.serverVersion}).`,\n );\n }\n}\n\n/**\n * Decide whether the request should stream. If the request body explicitly\n * sets `stream`, that wins. Otherwise the operation's `streamingDefault`\n * from the contract is used.\n */\nfunction shouldStream(req: InvokeRequest): boolean {\n if (req.body && typeof req.body === 'object' && 'stream' in req.body) {\n const explicit = (req.body as { stream?: unknown }).stream;\n if (typeof explicit === 'boolean') return explicit;\n }\n return Boolean(req.streamingDefault ?? req.operation.transport.streamingDefault);\n}\n\n/**\n * Apply the streaming default to the request body if needed.\n *\n * If the operation streams by default and the body doesn't set `stream`,\n * add `stream: true`. The user can always override by setting `stream`\n * explicitly on the request.\n */\nfunction buildBody(req: InvokeRequest): unknown {\n if (req.body === undefined) return undefined;\n if (typeof req.body !== 'object' || req.body === null) return req.body;\n const body = req.body as Record<string, unknown>;\n if (\n req.operation.transport.streaming &&\n req.operation.transport.streamingDefault &&\n body.stream === undefined\n ) {\n return { ...body, stream: true };\n }\n return body;\n}\n\n/** The runtime seam. */\nexport class OllamaRuntime {\n constructor(private readonly options: OllamaRuntimeOptions) {}\n\n /**\n * Invoke an operation. Called by every generated API method.\n *\n * Returns a `Promise<T>` for non-streaming operations, or an\n * `AsyncGenerator<T>` for streaming operations. The generated API\n * class's overloads pick the right return type at compile time.\n */\n async invoke<T = unknown>(req: InvokeRequest): Promise<T> {\n assertOperationAllowed(req.operation, this.options);\n const body = buildBody(req);\n const streaming = shouldStream(req);\n\n // The HttpClient expects the narrow method union 'GET' | 'POST' |\n // 'DELETE' | 'HEAD' | undefined — cast through `as` because our\n // OperationDefinition.method is the wider HttpMethod type.\n const httpReq: HttpRequestOptions = {\n path: req.operation.path,\n method: req.operation.method as 'GET' | 'POST' | 'DELETE' | 'HEAD',\n ...(body !== undefined ? { body } : {}),\n ...(req.signal !== undefined ? { signal: req.signal } : {}),\n // For streaming calls, request the raw Response so we can pipe it\n // through parseNdjsonStream directly. This inherits middleware,\n // retry, telemetry, and error-mapping from HttpClient — the\n // previous Wave 3 implementation bypassed them with a direct\n // `fetch()` call.\n ...(streaming ? { raw: true } : {}),\n };\n\n if (!streaming) {\n return (await this.options.http.request<T>(httpReq)) as T;\n }\n\n // Streaming: HttpClient returns the raw Response (via the `raw: true`\n // option) so we can read its body as an NDJSON stream.\n const response = await this.options.http.request<Response>(httpReq);\n if (!response.body) {\n throw new OllamaGenericClientError(\n `Operation ${req.operation.operationId}: streaming response had no body.`,\n );\n }\n return parseNdjsonStream<T>(response.body) as unknown as T;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/utils.ts","../src/streaming/ndjson.ts","../src/generated/models/ToolCall.schema.ts","../src/generated/models/ChatMessage.schema.ts","../src/generated/models/ModelOptions.schema.ts","../src/generated/models/ThinkValue.schema.ts","../src/generated/models/ToolDefinition.schema.ts","../src/generated/models/ChatRequest.schema.ts","../src/generated/models/GenerateRequest.schema.ts","../src/generated/models/EmbedRequest.schema.ts","../src/generated/models/CreateRequest.schema.ts","../src/generated/models/CopyRequest.schema.ts","../src/generated/models/DeleteRequest.schema.ts","../src/generated/models/PullRequest.schema.ts","../src/generated/models/PushRequest.schema.ts","../src/generated/models/ShowRequest.schema.ts","../src/generated/runtime/schema-registry.ts","../src/generated/runtime/runtime.ts"],"names":["z"],"mappings":"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","file":"generated-runtime.cjs","sourcesContent":["/**\n * Structured, typed error hierarchy for OllamaClient.\n */\n\nimport type { z } from 'zod';\n\nexport interface OllamaErrorRequestContext {\n readonly method?: string | undefined;\n readonly url?: string | undefined;\n readonly model?: string | undefined;\n}\n\nexport interface OllamaErrorResponseContext {\n readonly status?: number | undefined;\n readonly headers?: Record<string, string> | undefined;\n readonly body?: unknown;\n}\n\nexport interface OllamaClientErrorOptions extends ErrorOptions {\n readonly code: string;\n readonly status?: number | undefined;\n readonly retryable?: boolean | undefined;\n readonly request?: OllamaErrorRequestContext | undefined;\n readonly response?: OllamaErrorResponseContext | undefined;\n}\n\nexport class OllamaClientError extends Error {\n readonly code: string;\n readonly status?: number | undefined;\n readonly retryable: boolean;\n readonly request?: OllamaErrorRequestContext | undefined;\n readonly response?: OllamaErrorResponseContext | undefined;\n\n constructor(message: string, options: OllamaClientErrorOptions) {\n super(message, { cause: options.cause });\n this.name = this.constructor.name;\n this.code = options.code;\n this.status = options.status;\n this.retryable = options.retryable ?? false;\n this.request = options.request;\n this.response = options.response;\n }\n}\n\nexport class OllamaNetworkError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'network_error', retryable: true });\n }\n}\n\nexport class OllamaTimeoutError extends OllamaClientError {\n readonly timeoutMs?: number | undefined;\n constructor(\n message: string,\n options?:\n | (Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & { timeoutMs?: number | undefined })\n | undefined,\n ) {\n super(message, { ...options, code: 'timeout', retryable: true });\n this.timeoutMs = options?.timeoutMs;\n }\n}\n\nexport class OllamaAuthError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'auth_error', retryable: false });\n }\n}\n\nexport class OllamaNotFoundError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'not_found', retryable: false });\n }\n}\n\nexport class OllamaRateLimitError extends OllamaClientError {\n readonly retryAfterMs?: number | undefined;\n constructor(\n message: string,\n options?:\n | (Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n retryAfterMs?: number | undefined;\n })\n | undefined,\n ) {\n super(message, { ...options, code: 'rate_limited', retryable: true });\n this.retryAfterMs = options?.retryAfterMs;\n }\n}\n\n/**\n * Thrown client-side, before a network request is made, by `QuotaManager.assertCanProceed`\n * (see `src/quota.ts`) when issuing the request would exceed a configured usage budget for\n * one of its rolling windows. This is distinct from `OllamaRateLimitError`, which reflects\n * the server's own 429 response — Ollama Cloud does not expose account-level quota via the\n * API, so `QuotaManager` tracks usage against budgets the caller configures locally and\n * fails fast rather than waiting for the server to reject the request.\n */\nexport class OllamaQuotaExceededError extends OllamaClientError {\n readonly windowId: string;\n readonly resetAt: number;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n windowId: string;\n resetAt: number;\n },\n ) {\n super(message, { ...options, code: 'quota_exceeded', retryable: false });\n this.windowId = options.windowId;\n this.resetAt = options.resetAt;\n }\n}\n\nexport class OllamaServerError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'server_error', retryable: true });\n }\n}\n\nexport class OllamaAbortError extends OllamaClientError {\n constructor(\n message: string,\n options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined,\n ) {\n super(message, { ...options, code: 'aborted', retryable: false });\n }\n}\n\nexport class OllamaToolValidationError extends OllamaClientError {\n readonly toolName: string;\n readonly issues?: unknown;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & { toolName: string; issues?: unknown },\n ) {\n super(message, { ...options, code: 'tool_validation_error', retryable: false });\n this.toolName = options.toolName;\n this.issues = options.issues;\n }\n}\n\n/**\n * Thrown by `OllamaRuntime.invoke` when `validateRequests: true` is set and\n * the request body fails Zod validation against the operation's registered\n * schema. See ADR 0020 (runtime Zod validation).\n *\n * The error carries the original Zod issues so callers can inspect which\n * fields failed. No HTTP request is made when this error is thrown.\n */\nexport class OllamaRequestValidationError extends OllamaClientError {\n readonly operationId: string;\n readonly issues: readonly z.ZodIssue[];\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n operationId: string;\n issues: readonly z.ZodIssue[];\n },\n ) {\n super(message, { ...options, code: 'request_validation_error', retryable: false });\n this.operationId = options.operationId;\n this.issues = options.issues;\n }\n}\n\nexport class OllamaToolTimeoutError extends OllamaClientError {\n readonly toolName: string;\n readonly timeoutMs: number;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n toolName: string;\n timeoutMs: number;\n },\n ) {\n super(message, { ...options, code: 'tool_timeout', retryable: false });\n this.toolName = options.toolName;\n this.timeoutMs = options.timeoutMs;\n }\n}\n\n/**\n * Thrown client-side, before a network request is made, when a request asks for a\n * capability an endpoint is known not to support (e.g. structured output `format` against\n * an Ollama Cloud endpoint — see `ModelCapabilities.supportsStructuredOutputRequest` in\n * `src/capabilities/capabilities.ts`). Its `code` is included in `DEFAULT_FAILOVER_CODES`\n * by default, so in a multi-endpoint setup it causes failover to the next candidate rather\n * than failing outright — it only surfaces to the caller if every candidate is rejected.\n */\nexport class OllamaUnsupportedCapabilityError extends OllamaClientError {\n readonly capability: string;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & { capability: string },\n ) {\n super(message, { ...options, code: 'unsupported_capability', retryable: false });\n this.capability = options.capability;\n }\n}\n\n/**\n * Thrown client-side, before any network call, when `config.endpoints` uses\n * `OllamaEndpoint.models` to scope endpoints/credentials to specific models and the\n * requested `model` isn't in any configured endpoint's allow-list. This is a routing\n * misconfiguration, not a connectivity problem — the SDK deliberately does not \"probe\"\n * unauthorized endpoints to find one that happens to work (that would burn quota on keys\n * that were never entitled to the model and produce non-deterministic startup behavior).\n */\nexport class OllamaModelRoutingError extends OllamaClientError {\n readonly model: string;\n readonly availableModels: readonly string[];\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n model: string;\n availableModels: readonly string[];\n },\n ) {\n super(message, { ...options, code: 'model_routing_error', retryable: false });\n this.model = options.model;\n this.availableModels = options.availableModels;\n }\n}\n\n/**\n * Thrown before an agent tool loop starts when the selected model's /api/show metadata\n * does not advertise a capability required by the loop.\n */\nexport class OllamaIncompatibleModelError extends OllamaClientError {\n readonly model: string;\n readonly capability: string;\n readonly reportedCapabilities: readonly string[];\n\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {\n model: string;\n capability: string;\n reportedCapabilities: readonly string[];\n },\n ) {\n super(message, { ...options, code: 'incompatible_model', retryable: false });\n this.model = options.model;\n this.capability = options.capability;\n this.reportedCapabilities = options.reportedCapabilities;\n }\n}\nexport class OllamaAgentMaxToolCallsError extends OllamaClientError {\n readonly maxToolCalls: number;\n readonly toolCallsExecuted: number;\n\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n maxToolCalls: number;\n toolCallsExecuted: number;\n },\n ) {\n super(message, { ...options, code: 'agent_max_tool_calls_exceeded', retryable: false });\n this.maxToolCalls = options.maxToolCalls;\n this.toolCallsExecuted = options.toolCallsExecuted;\n }\n}\n\nexport class OllamaAgentMaxIterationsError extends OllamaClientError {\n readonly maxIterations: number;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & { maxIterations: number },\n ) {\n super(message, { ...options, code: 'agent_max_iterations_exceeded', retryable: false });\n this.maxIterations = options.maxIterations;\n }\n}\n\nexport class OllamaMcpError extends OllamaClientError {\n readonly mcpMethod: 'listTools' | 'callTool';\n readonly toolName?: string | undefined;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n mcpMethod: 'listTools' | 'callTool';\n toolName?: string | undefined;\n },\n ) {\n super(message, { ...options, code: 'mcp_error', retryable: options.retryable ?? false });\n this.mcpMethod = options.mcpMethod;\n this.toolName = options.toolName;\n }\n}\n\nexport class OllamaSkillNotFoundError extends OllamaClientError {\n readonly skillName: string;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & { skillName: string },\n ) {\n super(message, { ...options, code: 'skill_not_found', retryable: false });\n this.skillName = options.skillName;\n }\n}\n\nexport class OllamaSkillInvalidError extends OllamaClientError {\n readonly skillName: string;\n readonly path?: string | undefined;\n constructor(\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code'> & {\n skillName: string;\n path?: string | undefined;\n },\n ) {\n super(message, { ...options, code: 'skill_invalid', retryable: false });\n this.skillName = options.skillName;\n this.path = options.path;\n }\n}\n\nexport class OllamaGenericClientError extends OllamaClientError {\n constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code'> | undefined) {\n super(message, { ...options, code: 'client_error' });\n }\n}\n\nfunction isDomAbortError(error: unknown): error is DOMException {\n return (\n typeof DOMException !== 'undefined' &&\n error instanceof DOMException &&\n error.name === 'AbortError'\n );\n}\n\nfunction statusToError(\n status: number,\n message: string,\n options: Omit<OllamaClientErrorOptions, 'code' | 'status'>,\n): OllamaClientError {\n if (status === 401 || status === 403) {\n return new OllamaAuthError(message, { ...options, status });\n }\n if (status === 404) {\n return new OllamaNotFoundError(message, { ...options, status });\n }\n if (status === 429) {\n return new OllamaRateLimitError(message, { ...options, status });\n }\n if (status >= 500) {\n return new OllamaServerError(message, { ...options, status });\n }\n return new OllamaGenericClientError(message, { ...options, status });\n}\n\n/**\n * Maps arbitrary thrown exceptions into structured OllamaClientError instances.\n */\nexport function mapError(\n error: unknown,\n context: {\n request?: OllamaErrorRequestContext | undefined;\n response?: OllamaErrorResponseContext | undefined;\n } = {},\n): OllamaClientError {\n if (error instanceof OllamaClientError) {\n return error;\n }\n if (isDomAbortError(error)) {\n return new OllamaAbortError(error.message || 'Request was aborted', {\n cause: error,\n request: context.request,\n });\n }\n if (error instanceof TypeError) {\n return new OllamaNetworkError(error.message || 'Network request failed', {\n cause: error,\n request: context.request,\n });\n }\n if (context.response?.status !== undefined) {\n const message = error instanceof Error ? error.message : String(error);\n return statusToError(context.response.status, message, {\n cause: error,\n request: context.request,\n response: context.response,\n });\n }\n const message = error instanceof Error ? error.message : String(error);\n return new OllamaGenericClientError(message, {\n cause: error,\n request: context.request,\n response: context.response,\n });\n}\n","/**\n * Cross-runtime helpers with no Node.js API dependency, so they stay safe to import from\n * the core client bundle (see ADR 0006 — Edge Runtime CI).\n */\n\n/**\n * Encodes an image to a base64 string, matching the wire format Ollama's `/api/chat` and\n * `/api/generate` `images` arrays expect.\n *\n * - A `string` is assumed to already be base64-encoded and is returned unchanged.\n * - A `Uint8Array` is base64-encoded using whichever universal primitive the runtime\n * exposes: `Buffer` on Node.js, `btoa` on browsers/Edge runtimes. Chunked so it doesn't\n * blow the engine's max call-stack/argument-count limits on large images.\n */\nexport async function encodeImage(image: Uint8Array | string): Promise<string> {\n if (typeof image === 'string') return image;\n\n const bufferCtor = (\n globalThis as { Buffer?: { from(data: Uint8Array): { toString(encoding: string): string } } }\n ).Buffer;\n if (bufferCtor !== undefined) return bufferCtor.from(image).toString('base64');\n\n const CHUNK_SIZE = 0x8000;\n let binary = '';\n for (let i = 0; i < image.length; i += CHUNK_SIZE) {\n binary += String.fromCharCode(...image.subarray(i, i + CHUNK_SIZE));\n }\n return btoa(binary);\n}\n\nasync function encodeImages(\n images: readonly (string | Uint8Array)[] | undefined,\n): Promise<readonly string[] | undefined> {\n if (images === undefined) return undefined;\n return Promise.all(images.map((image) => encodeImage(image)));\n}\n\n/**\n * Returns `req` unchanged if `req.images` has no `Uint8Array` entries (the common case),\n * otherwise a shallow copy with `images` base64-encoded. Keeps `chat`/`generate` request\n * bodies wire-compatible without requiring callers to pre-encode raw image bytes.\n */\nexport async function withEncodedImages<\n T extends { images?: readonly (string | Uint8Array)[] | undefined },\n>(req: T): Promise<T> {\n if (!req.images?.some((image) => image instanceof Uint8Array)) return req;\n return { ...req, images: await encodeImages(req.images) };\n}\n\n/**\n * Applies {@link withEncodedImages} to each message's `images` array. Returns `messages`\n * unchanged (same reference) if no message carries a `Uint8Array` image.\n */\nexport async function withEncodedMessageImages<\n T extends { images?: readonly (string | Uint8Array)[] | undefined },\n>(messages: readonly T[]): Promise<readonly T[]> {\n if (!messages.some((message) => message.images?.some((image) => image instanceof Uint8Array)))\n return messages;\n return Promise.all(messages.map((message) => withEncodedImages(message)));\n}\n\n// ─── Disposable helpers (TS 5.2+ `using` declarations) ──────────────────\n//\n// These wrappers turn cleanup operations into `Disposable` / `AsyncDisposable`\n// values so callers can use `using` / `await using` declarations instead of\n// try/finally blocks. This eliminates the \"forgot to clean up in the finally\n// block\" bug class for timer, reader, and span lifecycles.\n\n/** Wraps a `setTimeout` handle so `clearTimeout` runs at scope exit. */\nexport function disposableTimer(timer: ReturnType<typeof setTimeout>): Disposable {\n return {\n [Symbol.dispose]() {\n clearTimeout(timer);\n },\n };\n}\n\n/** Wraps a `ReadableStreamDefaultReader` so `cancel()` + `releaseLock()` run at scope exit. */\nexport function disposableReader<T>(reader: ReadableStreamDefaultReader<T>): AsyncDisposable {\n return {\n async [Symbol.asyncDispose]() {\n try {\n await reader.cancel();\n } catch {\n /* stream may already be closed */\n }\n reader.releaseLock();\n },\n };\n}\n\n/** Wraps an OpenTelemetry span so `span.end()` runs at scope exit. */\nexport function disposableSpan(span: { end(): void }): Disposable {\n return {\n [Symbol.dispose]() {\n span.end();\n },\n };\n}\n","/**\n * NDJSON (newline-delimited JSON) stream reader for native fetch Response bodies.\n */\n\nimport { OllamaGenericClientError } from '../errors.js';\nimport { disposableReader } from '../utils.js';\n\n/**\n * Parses a byte stream from fetch body into an async generator of typed JSON chunks.\n */\nexport async function* parseNdjsonStream<T>(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<T, void, undefined> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n await using _reader = disposableReader(reader);\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n // Keep the last partial line in buffer\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n yield JSON.parse(trimmed) as T;\n } catch (err) {\n throw new OllamaGenericClientError(`Failed to parse stream JSON chunk: ${trimmed}`, {\n cause: err,\n });\n }\n }\n }\n\n if (buffer.trim()) {\n yield JSON.parse(buffer.trim()) as T;\n }\n // reader.cancel() + reader.releaseLock() called automatically via `await using _reader`\n}\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const ToolCallSchema = z.object({\n function: z\n .object({\n name: z.string(),\n description: z.string().optional(),\n arguments: z.object({}).optional(),\n })\n .optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\nimport { ToolCallSchema } from './ToolCall.schema.js';\n\nexport const ChatMessageSchema = z.object({\n role: z.enum(['system', 'user', 'assistant', 'tool']),\n content: z.string(),\n images: z.array(z.string()).optional(),\n tool_calls: z.array(ToolCallSchema).optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\n/** Runtime options that control text generation */\nexport const ModelOptionsSchema = z\n .object({\n seed: z.number().optional(),\n temperature: z.number().optional(),\n top_k: z.number().optional(),\n top_p: z.number().optional(),\n min_p: z.number().optional(),\n stop: z.union([z.string(), z.array(z.string())]).optional(),\n num_ctx: z.number().optional(),\n num_predict: z.number().optional(),\n })\n .catchall(z.unknown());\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\n/** Controls a model's thinking output. Use `/api/show` to discover the supported values and default for the selected model. `true` requests thinking, `false` requests no thinking output, and `null` uses the model default. String values are model-defined; supported names must match `/api/show` exactly. Numbers are not supported. */\nexport const ThinkValueSchema = z.union([z.boolean(), z.string(), z.null()]);\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const ToolDefinitionSchema = z.object({\n type: z.enum(['function']),\n function: z.object({\n name: z.string(),\n description: z.string().optional(),\n parameters: z.object({}),\n }),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\nimport { ChatMessageSchema } from './ChatMessage.schema.js';\nimport { ModelOptionsSchema } from './ModelOptions.schema.js';\nimport { ThinkValueSchema } from './ThinkValue.schema.js';\nimport { ToolDefinitionSchema } from './ToolDefinition.schema.js';\n\nexport const ChatRequestSchema = z.object({\n model: z.string(),\n messages: z.array(ChatMessageSchema),\n tools: z.array(ToolDefinitionSchema).optional(),\n format: z.union([z.enum(['json']), z.object({})]).optional(),\n options: ModelOptionsSchema.optional(),\n stream: z.boolean().optional(),\n think: ThinkValueSchema.optional(),\n keep_alive: z.union([z.string(), z.number()]).optional(),\n logprobs: z.boolean().optional(),\n top_logprobs: z.number().optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\nimport { ModelOptionsSchema } from './ModelOptions.schema.js';\nimport { ThinkValueSchema } from './ThinkValue.schema.js';\n\nexport const GenerateRequestSchema = z.object({\n model: z.string(),\n prompt: z.string().optional(),\n suffix: z.string().optional(),\n images: z.array(z.string()).optional(),\n format: z.union([z.string(), z.object({})]).optional(),\n system: z.string().optional(),\n stream: z.boolean().optional(),\n think: ThinkValueSchema.optional(),\n raw: z.boolean().optional(),\n keep_alive: z.union([z.string(), z.number()]).optional(),\n options: ModelOptionsSchema.optional(),\n logprobs: z.boolean().optional(),\n top_logprobs: z.number().optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\nimport { ModelOptionsSchema } from './ModelOptions.schema.js';\n\nexport const EmbedRequestSchema = z.object({\n model: z.string(),\n input: z.union([z.string(), z.array(z.string())]),\n truncate: z.boolean().optional(),\n dimensions: z.number().optional(),\n keep_alive: z.string().optional(),\n options: ModelOptionsSchema.optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\nimport { ChatMessageSchema } from './ChatMessage.schema.js';\n\nexport const CreateRequestSchema = z.object({\n model: z.string(),\n from: z.string().optional(),\n template: z.string().optional(),\n renderer: z.string().optional(),\n parser: z.string().optional(),\n files: z.object({}).catchall(z.string()).optional(),\n draft_files: z.object({}).catchall(z.string()).optional(),\n license: z.union([z.string(), z.array(z.string())]).optional(),\n system: z.string().optional(),\n parameters: z.object({}).optional(),\n messages: z.array(ChatMessageSchema).optional(),\n quantize: z.string().optional(),\n draft_quantize: z.string().optional(),\n requires: z.string().optional(),\n stream: z.boolean().optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const CopyRequestSchema = z.object({\n source: z.string(),\n destination: z.string(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const DeleteRequestSchema = z.object({\n model: z.string(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const PullRequestSchema = z.object({\n model: z.string(),\n insecure: z.boolean().optional(),\n stream: z.boolean().optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const PushRequestSchema = z.object({\n model: z.string(),\n insecure: z.boolean().optional(),\n stream: z.boolean().optional(),\n});\n","// AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.\n// Source: contracts/ir/ollama.ir.json (canonical Ollama IR).\n// Pairs with ./<name>.ts (the TypeScript interface).\n\nimport { z } from 'zod';\n\nexport const ShowRequestSchema = z.object({\n model: z.string(),\n verbose: z.boolean().optional(),\n});\n","/**\n * Schema registry — maps operationId → request/response Zod schemas.\n *\n * The runtime consults this registry to validate request bodies before\n * sending and response payloads after receiving. This is the runtime\n * enforcement layer described in ADR 0019 (Zod schema generation) and\n * ADR 0020 (runtime validation wiring).\n *\n * The registry is hand-written (not generated) because:\n * 1. Not every operation has a request schema (GET/HEAD have no body).\n * 2. Not every operation has a response schema (DELETE returns 204).\n * 3. The map is small (21 operations) and changes only when overlays\n * add new operations — at which point the generator should remind\n * the maintainer to update this file via the contract validator.\n *\n * When `validateRequests: true` is set on `OllamaRuntime` and an\n * operation has no registered request schema, the runtime skips\n * validation (it doesn't fail — the contract just doesn't have a\n * schema for that operation yet).\n */\nimport type { z } from 'zod';\nimport { ChatRequestSchema } from '../models/ChatRequest.schema.js';\nimport { GenerateRequestSchema } from '../models/GenerateRequest.schema.js';\nimport { EmbedRequestSchema } from '../models/EmbedRequest.schema.js';\nimport { CreateRequestSchema } from '../models/CreateRequest.schema.js';\nimport { CopyRequestSchema } from '../models/CopyRequest.schema.js';\nimport { DeleteRequestSchema } from '../models/DeleteRequest.schema.js';\nimport { PullRequestSchema } from '../models/PullRequest.schema.js';\nimport { PushRequestSchema } from '../models/PushRequest.schema.js';\nimport { ShowRequestSchema } from '../models/ShowRequest.schema.js';\n\n/**\n * Map from operationId → request schema. Response schemas are intentionally\n * NOT registered here — see ADR 0020 for the rationale (response validation\n * would break on legitimate forward-compat extensions to the wire format).\n */\nexport const requestSchemas: Readonly<Record<string, z.ZodType>> = {\n chat: ChatRequestSchema,\n generate: GenerateRequestSchema,\n embed: EmbedRequestSchema,\n create: CreateRequestSchema,\n copy: CopyRequestSchema,\n delete: DeleteRequestSchema,\n pull: PullRequestSchema,\n push: PushRequestSchema,\n show: ShowRequestSchema,\n // Operations without a registered request schema (blobs, ps, tags,\n // version, systemOne, openai*, anthropic*) skip validation. This is\n // deliberate — the OpenAPI spec doesn't define request bodies for\n // GET/HEAD operations, and the compat-surface request schemas (OpenAI,\n // Anthropic) are richer than what the IR currently models.\n};\n\n/** Look up a request schema by operationId. Returns `undefined` if no schema exists. */\nexport function getRequestSchema(operationId: string): z.ZodType | undefined {\n return requestSchemas[operationId];\n}\n","/**\n * OllamaRuntime — the runtime seam generated API classes delegate to.\n *\n * This is the only hand-written file in `src/generated/runtime/`. Every\n * generated method in `src/generated/api/*-api.ts` ends with:\n *\n * ```ts\n * return this.runtime.invoke({ operation: chatOp, body: request });\n * ```\n *\n * The runtime is responsible for:\n * - Method/path resolution (from {@link OperationDefinition})\n * - Streaming default application (when the request doesn't set `stream`)\n * - Environment guard (rejecting cloud calls for local-only operations)\n * - Version constraint guard (failing fast when the server is too old)\n * - Delegating to the existing {@link HttpClient} for transport, retry,\n * telemetry, NDJSON/SSE parsing\n *\n * It is intentionally a thin adapter — the existing transport, streaming,\n * middleware, and error-mapping layers are preserved verbatim. This file\n * only adds the contract-aware glue between generated API classes and the\n * existing HttpClient.\n */\nimport { HttpClient, type HttpRequestOptions } from '../../transport/http.js';\nimport { parseNdjsonStream } from '../../streaming/ndjson.js';\nimport { OllamaGenericClientError, OllamaRequestValidationError } from '../../errors.js';\nimport type { OperationDefinition, InvokeRequest } from './operation-definition.js';\nimport { getRequestSchema } from './schema-registry.js';\n\n/** Constructor options for {@link OllamaRuntime}. */\nexport interface OllamaRuntimeOptions {\n readonly http: HttpClient;\n /**\n * Whether this runtime is targeting a local Ollama instance. Defaults to\n * `true`. When `false`, operations marked `environment.cloud === false`\n * (i.e. local-only like `/v1/systemone`) are rejected at request time.\n */\n readonly localMode?: boolean;\n /**\n * Server version, if known (typically from a prior `/api/version` call).\n * When set, operations with `constraints.minOllamaVersion` are checked\n * against this value at request time.\n */\n readonly serverVersion?: string;\n /**\n * When `true`, the runtime validates every request body against the\n * generated Zod schema before sending it. Defaults to `false` — opt-in.\n *\n * Validation behavior:\n * - If the operation has a registered request schema (see\n * {@link schema-registry.ts}), the body is parsed via `safeParse`.\n * - On parse failure, throws `OllamaRequestValidationError` with the\n * Zod issues attached. No HTTP request is made.\n * - On parse success, the parsed (and stripped of unknown fields) body\n * is sent — this means callers can't accidentally send extra fields\n * that the contract doesn't allow.\n * - If the operation has NO registered schema (e.g. GET endpoints,\n * `/v1/systemone`, OpenAI/Anthropic compat surfaces), validation is\n * skipped silently.\n *\n * Response validation is intentionally NOT enabled — see ADR 0020 for\n * the rationale (forward-compat with wire-format extensions).\n */\n readonly validateRequests?: boolean;\n}\n\nfunction compareVersions(a: string, b: string): number {\n const pa = a.split('.').map((s) => Number.parseInt(s, 10) ?? 0);\n const pb = b.split('.').map((s) => Number.parseInt(s, 10) ?? 0);\n for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va !== vb) return va - vb;\n }\n return 0;\n}\n\n/**\n * Apply environment + version guards before delegating to HttpClient.\n *\n * Throws {@link OllamaGenericClientError} when:\n * - The operation is local-only and the runtime is in cloud mode.\n * - The operation has `constraints.minOllamaVersion` and the server is older.\n */\nfunction assertOperationAllowed(\n operation: OperationDefinition,\n options: OllamaRuntimeOptions,\n): void {\n const localMode = options.localMode ?? true;\n if (!localMode && !operation.environment.cloud) {\n throw new OllamaGenericClientError(\n `Operation ${operation.operationId} (${operation.method} ${operation.path}) ` +\n `is local-only and not supported in cloud mode.`,\n );\n }\n if (\n operation.constraints?.minOllamaVersion &&\n options.serverVersion &&\n compareVersions(options.serverVersion, operation.constraints.minOllamaVersion) < 0\n ) {\n throw new OllamaGenericClientError(\n `Operation ${operation.operationId} (${operation.method} ${operation.path}) ` +\n `requires Ollama >= ${operation.constraints.minOllamaVersion} ` +\n `(server reports ${options.serverVersion}).`,\n );\n }\n}\n\n/**\n * Decide whether the request should stream. If the request body explicitly\n * sets `stream`, that wins. Otherwise the operation's `streamingDefault`\n * from the contract is used.\n */\nfunction shouldStream(req: InvokeRequest): boolean {\n if (req.body && typeof req.body === 'object' && 'stream' in req.body) {\n const explicit = (req.body as { stream?: unknown }).stream;\n if (typeof explicit === 'boolean') return explicit;\n }\n return Boolean(req.streamingDefault ?? req.operation.transport.streamingDefault);\n}\n\n/**\n * Apply the streaming default to the request body if needed.\n *\n * If the operation streams by default and the body doesn't set `stream`,\n * add `stream: true`. The user can always override by setting `stream`\n * explicitly on the request.\n */\nfunction buildBody(req: InvokeRequest): unknown {\n if (req.body === undefined) return undefined;\n if (typeof req.body !== 'object' || req.body === null) return req.body;\n const body = req.body as Record<string, unknown>;\n if (\n req.operation.transport.streaming &&\n req.operation.transport.streamingDefault &&\n body.stream === undefined\n ) {\n return { ...body, stream: true };\n }\n return body;\n}\n\n/** The runtime seam. */\nexport class OllamaRuntime {\n constructor(private readonly options: OllamaRuntimeOptions) {}\n\n /**\n * Invoke an operation. Called by every generated API method.\n *\n * Returns a `Promise<T>` for non-streaming operations, or an\n * `AsyncGenerator<T>` for streaming operations. The generated API\n * class's overloads pick the right return type at compile time.\n */\n async invoke<T = unknown>(req: InvokeRequest): Promise<T> {\n assertOperationAllowed(req.operation, this.options);\n let body = buildBody(req);\n\n // Wave 10 (ADR 0020): runtime Zod validation. Opt-in via\n // `validateRequests: true` on the runtime constructor. Throws\n // `OllamaRequestValidationError` BEFORE any HTTP request is made\n // when the body fails validation. The validated (and stripped)\n // body replaces the original so unknown fields can't leak through.\n if (this.options.validateRequests === true && body !== undefined) {\n const schema = getRequestSchema(req.operation.operationId);\n if (schema) {\n const result = schema.safeParse(body);\n if (!result.success) {\n throw new OllamaRequestValidationError(\n `Request validation failed for operation \"${req.operation.operationId}\" ` +\n `(${req.operation.method} ${req.operation.path}): ` +\n result.error.issues\n .map((i) => `${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('; '),\n {\n operationId: req.operation.operationId,\n issues: result.error.issues,\n request: { method: req.operation.method, url: req.operation.path },\n },\n );\n }\n body = result.data;\n }\n }\n\n const streaming = shouldStream(req);\n\n // The HttpClient expects the narrow method union 'GET' | 'POST' |\n // 'DELETE' | 'HEAD' | undefined — cast through `as` because our\n // OperationDefinition.method is the wider HttpMethod type.\n const httpReq: HttpRequestOptions = {\n path: req.operation.path,\n method: req.operation.method as 'GET' | 'POST' | 'DELETE' | 'HEAD',\n ...(body !== undefined ? { body } : {}),\n ...(req.signal !== undefined ? { signal: req.signal } : {}),\n // For streaming calls, request the raw Response so we can pipe it\n // through parseNdjsonStream directly. This inherits middleware,\n // retry, telemetry, and error-mapping from HttpClient — the\n // previous Wave 3 implementation bypassed them with a direct\n // `fetch()` call.\n ...(streaming ? { raw: true } : {}),\n };\n\n if (!streaming) {\n return (await this.options.http.request<T>(httpReq)) as T;\n }\n\n // Streaming: HttpClient returns the raw Response (via the `raw: true`\n // option) so we can read its body as an NDJSON stream.\n const response = await this.options.http.request<Response>(httpReq);\n if (!response.body) {\n throw new OllamaGenericClientError(\n `Operation ${req.operation.operationId}: streaming response had no body.`,\n );\n }\n return parseNdjsonStream<T>(response.body) as unknown as T;\n }\n}\n"]}
|
|
@@ -1,2 +1,35 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import '
|
|
1
|
+
export { I as InvokeRequest, O as OllamaRuntime, b as OllamaRuntimeOptions, a as OperationDefinition, S as SchemaRef } from './runtime-IxRpUBjN.cjs';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import './types-5PAjLoCp.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Schema registry — maps operationId → request/response Zod schemas.
|
|
7
|
+
*
|
|
8
|
+
* The runtime consults this registry to validate request bodies before
|
|
9
|
+
* sending and response payloads after receiving. This is the runtime
|
|
10
|
+
* enforcement layer described in ADR 0019 (Zod schema generation) and
|
|
11
|
+
* ADR 0020 (runtime validation wiring).
|
|
12
|
+
*
|
|
13
|
+
* The registry is hand-written (not generated) because:
|
|
14
|
+
* 1. Not every operation has a request schema (GET/HEAD have no body).
|
|
15
|
+
* 2. Not every operation has a response schema (DELETE returns 204).
|
|
16
|
+
* 3. The map is small (21 operations) and changes only when overlays
|
|
17
|
+
* add new operations — at which point the generator should remind
|
|
18
|
+
* the maintainer to update this file via the contract validator.
|
|
19
|
+
*
|
|
20
|
+
* When `validateRequests: true` is set on `OllamaRuntime` and an
|
|
21
|
+
* operation has no registered request schema, the runtime skips
|
|
22
|
+
* validation (it doesn't fail — the contract just doesn't have a
|
|
23
|
+
* schema for that operation yet).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Map from operationId → request schema. Response schemas are intentionally
|
|
28
|
+
* NOT registered here — see ADR 0020 for the rationale (response validation
|
|
29
|
+
* would break on legitimate forward-compat extensions to the wire format).
|
|
30
|
+
*/
|
|
31
|
+
declare const requestSchemas: Readonly<Record<string, z.ZodType>>;
|
|
32
|
+
/** Look up a request schema by operationId. Returns `undefined` if no schema exists. */
|
|
33
|
+
declare function getRequestSchema(operationId: string): z.ZodType | undefined;
|
|
34
|
+
|
|
35
|
+
export { getRequestSchema, requestSchemas };
|
|
@@ -1,2 +1,35 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import '
|
|
1
|
+
export { I as InvokeRequest, O as OllamaRuntime, b as OllamaRuntimeOptions, a as OperationDefinition, S as SchemaRef } from './runtime-CVQkbYgF.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import './types-5PAjLoCp.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Schema registry — maps operationId → request/response Zod schemas.
|
|
7
|
+
*
|
|
8
|
+
* The runtime consults this registry to validate request bodies before
|
|
9
|
+
* sending and response payloads after receiving. This is the runtime
|
|
10
|
+
* enforcement layer described in ADR 0019 (Zod schema generation) and
|
|
11
|
+
* ADR 0020 (runtime validation wiring).
|
|
12
|
+
*
|
|
13
|
+
* The registry is hand-written (not generated) because:
|
|
14
|
+
* 1. Not every operation has a request schema (GET/HEAD have no body).
|
|
15
|
+
* 2. Not every operation has a response schema (DELETE returns 204).
|
|
16
|
+
* 3. The map is small (21 operations) and changes only when overlays
|
|
17
|
+
* add new operations — at which point the generator should remind
|
|
18
|
+
* the maintainer to update this file via the contract validator.
|
|
19
|
+
*
|
|
20
|
+
* When `validateRequests: true` is set on `OllamaRuntime` and an
|
|
21
|
+
* operation has no registered request schema, the runtime skips
|
|
22
|
+
* validation (it doesn't fail — the contract just doesn't have a
|
|
23
|
+
* schema for that operation yet).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Map from operationId → request schema. Response schemas are intentionally
|
|
28
|
+
* NOT registered here — see ADR 0020 for the rationale (response validation
|
|
29
|
+
* would break on legitimate forward-compat extensions to the wire format).
|
|
30
|
+
*/
|
|
31
|
+
declare const requestSchemas: Readonly<Record<string, z.ZodType>>;
|
|
32
|
+
/** Look up a request schema by operationId. Returns `undefined` if no schema exists. */
|
|
33
|
+
declare function getRequestSchema(operationId: string): z.ZodType | undefined;
|
|
34
|
+
|
|
35
|
+
export { getRequestSchema, requestSchemas };
|