@nemesis-oss/ollama-sdk 1.1.0 → 1.4.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 (58) hide show
  1. package/CHANGELOG.md +43 -92
  2. package/README.md +749 -11
  3. package/dist/compose-BR70yb4W.d.cts +164 -0
  4. package/dist/compose-DfAqKAFj.d.ts +164 -0
  5. package/dist/generated-api.cjs +454 -0
  6. package/dist/generated-api.cjs.map +1 -0
  7. package/dist/generated-api.d.cts +1651 -0
  8. package/dist/generated-api.d.ts +1651 -0
  9. package/dist/generated-api.js +428 -0
  10. package/dist/generated-api.js.map +1 -0
  11. package/dist/generated-models-schemas.cjs +328 -0
  12. package/dist/generated-models-schemas.cjs.map +1 -0
  13. package/dist/generated-models-schemas.d.cts +463 -0
  14. package/dist/generated-models-schemas.d.ts +463 -0
  15. package/dist/generated-models-schemas.js +291 -0
  16. package/dist/generated-models-schemas.js.map +1 -0
  17. package/dist/generated-runtime.cjs +145 -0
  18. package/dist/generated-runtime.cjs.map +1 -0
  19. package/dist/generated-runtime.d.cts +2 -0
  20. package/dist/generated-runtime.d.ts +2 -0
  21. package/dist/generated-runtime.js +143 -0
  22. package/dist/generated-runtime.js.map +1 -0
  23. package/dist/index-2RIErNT5.d.cts +583 -0
  24. package/dist/index-DIQ8NUbU.d.ts +583 -0
  25. package/dist/index.cjs +2308 -184
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +1123 -421
  28. package/dist/index.d.ts +1123 -421
  29. package/dist/index.js +2293 -185
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp/tools.json +1058 -0
  32. package/dist/mcp-generated.cjs +386 -0
  33. package/dist/mcp-generated.cjs.map +1 -0
  34. package/dist/mcp-generated.d.cts +35 -0
  35. package/dist/mcp-generated.d.ts +35 -0
  36. package/dist/mcp-generated.js +381 -0
  37. package/dist/mcp-generated.js.map +1 -0
  38. package/dist/mcp-http.cjs +100 -0
  39. package/dist/mcp-http.cjs.map +1 -0
  40. package/dist/mcp-http.d.cts +48 -0
  41. package/dist/mcp-http.d.ts +48 -0
  42. package/dist/mcp-http.js +96 -0
  43. package/dist/mcp-http.js.map +1 -0
  44. package/dist/mcp-stdio.cjs +49 -0
  45. package/dist/mcp-stdio.cjs.map +1 -0
  46. package/dist/mcp-stdio.d.cts +34 -0
  47. package/dist/mcp-stdio.d.ts +34 -0
  48. package/dist/mcp-stdio.js +47 -0
  49. package/dist/mcp-stdio.js.map +1 -0
  50. package/dist/skills.cjs.map +1 -1
  51. package/dist/skills.d.cts +3 -2
  52. package/dist/skills.d.ts +3 -2
  53. package/dist/skills.js.map +1 -1
  54. package/dist/types-B9_axjum.d.cts +66 -0
  55. package/dist/types-B9_axjum.d.ts +66 -0
  56. package/dist/{compose-DJjVpDrk.d.cts → types-BQhgW-du.d.cts} +118 -172
  57. package/dist/{compose-DJjVpDrk.d.ts → types-BQhgW-du.d.ts} +118 -172
  58. package/package.json +96 -5
package/dist/index.d.cts CHANGED
@@ -1,307 +1,14 @@
1
- import { M as Message, C as ChatResponse, G as GenerateResponse, T as ToolCall, P as ProgressResponse, a as ModelResponse, S as ShowRequestOptions, b as ShowResponse, c as PullRequestOptions, d as PushRequestOptions, e as CreateRequestOptions, D as DeleteRequestOptions, f as StatusResponse, g as CopyRequestOptions, h as PsResponse, V as VersionResponse, i as ChatRequestOptions, j as GenerateRequestOptions, E as EmbedRequestOptions, k as EmbedResponse, l as EmbeddingsRequestOptions, m as EmbeddingsResponse, W as WebSearchRequestOptions, n as WebSearchResponse, o as WebFetchRequestOptions, p as WebFetchResponse, q as ToolHandler, r as Tool, A as AnyTool, s as ToolRegistry, t as ToolExecutionResult, u as ModelOptions, v as ToolDefinition } from './compose-DJjVpDrk.cjs';
2
- export { w as AppliedSkillResult, x as ApplySkillOptions, F as FormatOption, L as ListResponse, y as ModelDetails, z as ParsedFrontmatter, R as RequestCancellationOptions, B as Role, H as Skill, I as SkillFrontmatter, J as SkillSummary, K as ToolCallFunction, N as ToolExecutionContext, O as ToolExecutionFailure, Q as ToolExecutionSuccess, U as ToolFunctionDefinition, X as ToolProperty, Y as ToolRegistryOptions, Z as WebSearchResult, _ as applySkill, $ as parseFrontmatter } from './compose-DJjVpDrk.cjs';
1
+ import { F as FetchLike, M as Middleware, L as Logger, R as RequestLifecycleHook, H as HttpClient, a as OllamaStreamEvent, A as AbortableAsyncIterable, b as OllamaStreamEventType, P as ProgressStreamResult, B as BinaryBody, S as SseEvent, c as OllamaClientError, O as OllamaRuntime, C as ChatStreamResult, G as GenerateStreamResult, d as RawUsageSource, T as TokenUsage } from './index-2RIErNT5.cjs';
2
+ export { D as DoneEvent, E as ErrorEvent, e as HttpBody, f as HttpClientOptions, g as HttpRequestOptions, h as LifecycleErrorEvent, i as LifecycleRetryEvent, j as LifecycleStartEvent, k as LifecycleSuccessEvent, l as LogFn, m as MessageEvent, n as MiddlewareContext, N as NANOS_PER_MS, o as NANOS_PER_SECOND, p as NOOP_LOGGER, q as NextFunction, r as OllamaAbortError, s as OllamaAgentMaxIterationsError, t as OllamaAgentMaxToolCallsError, u as OllamaAuthError, v as OllamaClientErrorOptions, w as OllamaErrorRequestContext, x as OllamaErrorResponseContext, y as OllamaGenericClientError, z as OllamaIncompatibleModelError, I as OllamaMcpError, J as OllamaModelRoutingError, K as OllamaNetworkError, Q as OllamaNotFoundError, U as OllamaQuotaExceededError, V as OllamaRateLimitError, W as OllamaServerError, X as OllamaSkillInvalidError, Y as OllamaSkillNotFoundError, Z as OllamaTimeoutError, _ as OllamaToolTimeoutError, $ as OllamaToolValidationError, a0 as OllamaUnsupportedCapabilityError, a1 as RequestContext, a2 as RequestLifecycleEvent, a3 as ResponseContext, a4 as ThinkingEvent, a5 as TokenEvent, a6 as ToolCallEvent, a7 as composeMiddleware, a8 as createConsoleLogger, a9 as extractUsage, aa as mapError, ab as parseSseStream } from './index-2RIErNT5.cjs';
3
+ import { b as ThinkingMetadata, c as ModelResponse, S as ShowRequestOptions, d as ShowResponse, P as PullRequestOptions, e as ProgressResponse, f as PushRequestOptions, C as CreateRequestOptions, D as DeleteRequestOptions, g as StatusResponse, h as CopyRequestOptions, i as PsResponse, V as VersionResponse, j as ChatRequestOptions, k as ChatResponse, G as GenerateRequestOptions, l as GenerateResponse, E as EmbedRequestOptions, m as EmbedResponse, n as EmbeddingsRequestOptions, o as EmbeddingsResponse, W as WebSearchRequestOptions, p as WebSearchResponse, q as WebFetchRequestOptions, r as WebFetchResponse, T as ToolDefinition, a as ToolCall, M as Message, s as ModelOptions, t as ThinkValue } from './types-BQhgW-du.cjs';
4
+ export { F as FormatOption, L as ListResponse, u as Logprob, v as LogprobToken, w as ModelDetails, R as RequestCancellationOptions, x as Role, y as ToolCallFunction, z as ToolFunctionDefinition, A as ToolParameters, B as ToolProperty, H as WebSearchResult } from './types-BQhgW-du.cjs';
3
5
  import { z } from 'zod';
6
+ import { T as ToolHandler, e as Tool, f as AnyTool, g as ToolRegistry, h as ToolExecutionResult } from './compose-BR70yb4W.cjs';
7
+ export { A as AppliedSkillResult, b as ApplySkillOptions, P as ParsedFrontmatter, a as Skill, c as SkillFrontmatter, S as SkillSummary, i as ToolExecutionContext, j as ToolExecutionFailure, k as ToolExecutionSuccess, l as ToolRegistryOptions, d as applySkill, p as parseFrontmatter } from './compose-BR70yb4W.cjs';
8
+ import { a as McpClientLike, M as McpToolDescriptor } from './types-B9_axjum.cjs';
9
+ export { b as McpCallToolResult, c as McpContentBlock, d as McpIcon, e as McpListToolsParams, f as McpListToolsResult, g as McpRequestOptions, h as McpToolAnnotations, i as McpToolExecution } from './types-B9_axjum.cjs';
4
10
  import * as Otel from '@opentelemetry/api';
5
11
 
6
- /**
7
- * Structured, typed error hierarchy for OllamaClient.
8
- */
9
- interface OllamaErrorRequestContext {
10
- readonly method?: string | undefined;
11
- readonly url?: string | undefined;
12
- readonly model?: string | undefined;
13
- }
14
- interface OllamaErrorResponseContext {
15
- readonly status?: number | undefined;
16
- readonly headers?: Record<string, string> | undefined;
17
- readonly body?: unknown;
18
- }
19
- interface OllamaClientErrorOptions extends ErrorOptions {
20
- readonly code: string;
21
- readonly status?: number | undefined;
22
- readonly retryable?: boolean | undefined;
23
- readonly request?: OllamaErrorRequestContext | undefined;
24
- readonly response?: OllamaErrorResponseContext | undefined;
25
- }
26
- declare class OllamaClientError extends Error {
27
- readonly code: string;
28
- readonly status?: number | undefined;
29
- readonly retryable: boolean;
30
- readonly request?: OllamaErrorRequestContext | undefined;
31
- readonly response?: OllamaErrorResponseContext | undefined;
32
- constructor(message: string, options: OllamaClientErrorOptions);
33
- }
34
- declare class OllamaNetworkError extends OllamaClientError {
35
- constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined);
36
- }
37
- declare class OllamaTimeoutError extends OllamaClientError {
38
- readonly timeoutMs?: number | undefined;
39
- constructor(message: string, options?: (Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {
40
- timeoutMs?: number | undefined;
41
- }) | undefined);
42
- }
43
- declare class OllamaAuthError extends OllamaClientError {
44
- constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined);
45
- }
46
- declare class OllamaNotFoundError extends OllamaClientError {
47
- constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined);
48
- }
49
- declare class OllamaRateLimitError extends OllamaClientError {
50
- readonly retryAfterMs?: number | undefined;
51
- constructor(message: string, options?: (Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {
52
- retryAfterMs?: number | undefined;
53
- }) | undefined);
54
- }
55
- declare class OllamaServerError extends OllamaClientError {
56
- constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined);
57
- }
58
- declare class OllamaAbortError extends OllamaClientError {
59
- constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined);
60
- }
61
- declare class OllamaToolValidationError extends OllamaClientError {
62
- readonly toolName: string;
63
- readonly issues?: unknown;
64
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code'> & {
65
- toolName: string;
66
- issues?: unknown;
67
- });
68
- }
69
- declare class OllamaToolTimeoutError extends OllamaClientError {
70
- readonly toolName: string;
71
- readonly timeoutMs: number;
72
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {
73
- toolName: string;
74
- timeoutMs: number;
75
- });
76
- }
77
- /**
78
- * Thrown client-side, before a network request is made, when a request asks for a
79
- * capability an endpoint is known not to support (e.g. structured output `format` against
80
- * an Ollama Cloud endpoint — see `ModelCapabilities.supportsStructuredOutputRequest` in
81
- * `src/capabilities/capabilities.ts`). Its `code` is included in `DEFAULT_FAILOVER_CODES`
82
- * by default, so in a multi-endpoint setup it causes failover to the next candidate rather
83
- * than failing outright — it only surfaces to the caller if every candidate is rejected.
84
- */
85
- declare class OllamaUnsupportedCapabilityError extends OllamaClientError {
86
- readonly capability: string;
87
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {
88
- capability: string;
89
- });
90
- }
91
- declare class OllamaAgentMaxIterationsError extends OllamaClientError {
92
- readonly maxIterations: number;
93
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code'> & {
94
- maxIterations: number;
95
- });
96
- }
97
- declare class OllamaMcpError extends OllamaClientError {
98
- readonly mcpMethod: 'listTools' | 'callTool';
99
- readonly toolName?: string | undefined;
100
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code'> & {
101
- mcpMethod: 'listTools' | 'callTool';
102
- toolName?: string | undefined;
103
- });
104
- }
105
- declare class OllamaSkillNotFoundError extends OllamaClientError {
106
- readonly skillName: string;
107
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code'> & {
108
- skillName: string;
109
- });
110
- }
111
- declare class OllamaSkillInvalidError extends OllamaClientError {
112
- readonly skillName: string;
113
- readonly path?: string | undefined;
114
- constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code'> & {
115
- skillName: string;
116
- path?: string | undefined;
117
- });
118
- }
119
- declare class OllamaGenericClientError extends OllamaClientError {
120
- constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code'> | undefined);
121
- }
122
- /**
123
- * Maps arbitrary thrown exceptions into structured OllamaClientError instances.
124
- */
125
- declare function mapError(error: unknown, context?: {
126
- request?: OllamaErrorRequestContext | undefined;
127
- response?: OllamaErrorResponseContext | undefined;
128
- }): OllamaClientError;
129
-
130
- /**
131
- * Token usage and duration calculation utilities.
132
- */
133
- declare const NANOS_PER_MS = 1000000;
134
- declare const NANOS_PER_SECOND = 1000000000;
135
- interface TokenUsage {
136
- readonly promptTokens: number;
137
- readonly completionTokens: number;
138
- readonly totalTokens: number;
139
- readonly tokensPerSecond?: number | undefined;
140
- readonly loadDurationMs?: number | undefined;
141
- readonly promptEvalDurationMs?: number | undefined;
142
- readonly evalDurationMs?: number | undefined;
143
- readonly totalDurationMs?: number | undefined;
144
- }
145
- interface RawUsageSource {
146
- readonly prompt_eval_count?: number | undefined;
147
- readonly eval_count?: number | undefined;
148
- readonly total_duration?: number | undefined;
149
- readonly load_duration?: number | undefined;
150
- readonly prompt_eval_duration?: number | undefined;
151
- readonly eval_duration?: number | undefined;
152
- }
153
- /**
154
- * Extracts and normalizes token usage metrics from an Ollama response.
155
- */
156
- declare function extractUsage(raw: RawUsageSource): TokenUsage;
157
-
158
- /**
159
- * Streaming event types, listener contracts, and aggregated result shapes.
160
- */
161
-
162
- interface TokenEvent {
163
- readonly type: 'token';
164
- readonly data: {
165
- readonly delta: string;
166
- readonly role?: string | undefined;
167
- };
168
- }
169
- interface ThinkingEvent {
170
- readonly type: 'thinking';
171
- readonly data: {
172
- readonly delta: string;
173
- };
174
- }
175
- interface ToolCallEvent {
176
- readonly type: 'tool_call';
177
- readonly data: {
178
- readonly toolCall: ToolCall;
179
- };
180
- }
181
- interface MessageEvent<TChunk> {
182
- readonly type: 'message';
183
- readonly data: {
184
- readonly chunk: TChunk;
185
- };
186
- }
187
- interface DoneEvent<TFinal> {
188
- readonly type: 'done';
189
- readonly data: {
190
- readonly result: TFinal;
191
- };
192
- }
193
- interface ErrorEvent {
194
- readonly type: 'error';
195
- readonly data: {
196
- readonly error: OllamaClientError;
197
- };
198
- }
199
- type OllamaStreamEvent<TChunk, TFinal> = TokenEvent | ThinkingEvent | ToolCallEvent | MessageEvent<TChunk> | DoneEvent<TFinal> | ErrorEvent;
200
- type OllamaStreamEventType = OllamaStreamEvent<unknown, unknown>['type'];
201
- interface ChatStreamResult {
202
- readonly message: Message;
203
- readonly model: string;
204
- readonly done: boolean;
205
- /** Mirrors the final chunk's `done_reason` (e.g. `"stop"`, `"load"`, `"unload"`). */
206
- readonly doneReason?: string | undefined;
207
- readonly totalDurationMs?: number | undefined;
208
- readonly usage?: TokenUsage | undefined;
209
- readonly raw?: ChatResponse | undefined;
210
- }
211
- interface GenerateStreamResult {
212
- readonly response: string;
213
- readonly model: string;
214
- readonly done: boolean;
215
- /** Mirrors the final chunk's `done_reason` (e.g. `"stop"`, `"load"`, `"unload"`). */
216
- readonly doneReason?: string | undefined;
217
- readonly totalDurationMs?: number | undefined;
218
- readonly usage?: TokenUsage | undefined;
219
- readonly raw?: GenerateResponse | undefined;
220
- }
221
- interface ProgressStreamResult {
222
- readonly status: string;
223
- readonly completed?: number | undefined;
224
- readonly total?: number | undefined;
225
- readonly done: boolean;
226
- readonly raw?: ProgressResponse | undefined;
227
- }
228
- interface AbortableAsyncIterable<T> extends AsyncIterable<T> {
229
- abort?: (() => void) | undefined;
230
- }
231
-
232
- /**
233
- * Structured logger and request lifecycle interfaces.
234
- */
235
- interface LogFn {
236
- (message: string, context?: Record<string, unknown>): void;
237
- }
238
- interface Logger {
239
- readonly debug: LogFn;
240
- readonly info: LogFn;
241
- readonly warn: LogFn;
242
- readonly error: LogFn;
243
- }
244
- interface LifecycleStartEvent {
245
- readonly type: 'start';
246
- readonly requestId: string;
247
- readonly method: string;
248
- readonly url: string;
249
- readonly timestamp: number;
250
- }
251
- interface LifecycleSuccessEvent {
252
- readonly type: 'success';
253
- readonly requestId: string;
254
- readonly durationMs: number;
255
- readonly status: number;
256
- readonly timestamp: number;
257
- }
258
- interface LifecycleRetryEvent {
259
- readonly type: 'retry';
260
- readonly requestId: string;
261
- readonly attempt: number;
262
- readonly error: Error;
263
- readonly delayMs: number;
264
- readonly timestamp: number;
265
- }
266
- interface LifecycleErrorEvent {
267
- readonly type: 'error';
268
- readonly requestId: string;
269
- readonly durationMs: number;
270
- readonly error: Error;
271
- readonly timestamp: number;
272
- }
273
- type RequestLifecycleEvent = LifecycleStartEvent | LifecycleSuccessEvent | LifecycleRetryEvent | LifecycleErrorEvent;
274
- interface RequestLifecycleHook {
275
- (event: RequestLifecycleEvent): void;
276
- }
277
- declare const NOOP_LOGGER: Logger;
278
- declare function createConsoleLogger(prefix?: string): Logger;
279
-
280
- /**
281
- * Request/response middleware pipeline.
282
- */
283
- interface RequestContext {
284
- readonly url: string;
285
- readonly method: string;
286
- readonly headers: Record<string, string>;
287
- readonly body?: unknown;
288
- readonly signal?: AbortSignal;
289
- }
290
- interface ResponseContext {
291
- readonly status: number;
292
- readonly headers: Record<string, string>;
293
- readonly body: unknown;
294
- }
295
- type NextFunction = () => Promise<ResponseContext>;
296
- interface MiddlewareContext {
297
- readonly request: RequestContext;
298
- readonly next: NextFunction;
299
- }
300
- interface Middleware {
301
- (ctx: MiddlewareContext): Promise<ResponseContext>;
302
- }
303
- declare function composeMiddleware(middlewares: readonly Middleware[], finalHandler: (req: RequestContext) => Promise<ResponseContext>): (req: RequestContext) => Promise<ResponseContext>;
304
-
305
12
  /**
306
13
  * Exponential backoff with full jitter calculation.
307
14
  */
@@ -330,39 +37,7 @@ declare const DEFAULT_RETRY_CONFIG: RetryConfig;
330
37
  /**
331
38
  * Executes an async operation with retries according to config.
332
39
  */
333
- declare function withRetry<T>(operation: (attempt: number) => Promise<T>, config?: RetryConfig): Promise<T>;
334
-
335
- /**
336
- * Native fetch HTTP transport client for Ollama API.
337
- */
338
-
339
- type FetchLike = typeof globalThis.fetch;
340
- type BinaryBody = Uint8Array | ArrayBuffer | string | Blob | ReadableStream<Uint8Array>;
341
- type HttpBody = unknown;
342
- interface HttpClientOptions {
343
- readonly baseUrl: string;
344
- readonly apiKey?: string | undefined;
345
- readonly headers?: Record<string, string> | undefined;
346
- readonly fetch?: FetchLike | undefined;
347
- }
348
- interface HttpRequestOptions {
349
- readonly path: string;
350
- readonly method?: 'GET' | 'POST' | 'DELETE' | 'HEAD' | undefined;
351
- readonly body?: HttpBody;
352
- readonly rawBody?: BinaryBody | undefined;
353
- readonly headers?: Record<string, string> | undefined;
354
- readonly signal?: AbortSignal | undefined;
355
- }
356
- declare class HttpClient {
357
- readonly baseUrl: string;
358
- private readonly apiKey?;
359
- private readonly defaultHeaders;
360
- private readonly fetchImpl;
361
- constructor(options: HttpClientOptions);
362
- private buildHeaders;
363
- request<T>(options: HttpRequestOptions): Promise<T>;
364
- requestStream<T>(options: HttpRequestOptions): Promise<AbortableAsyncIterable<T>>;
365
- }
40
+ declare function withRetry<T>(operation: (attempt: number) => Promise<T>, config?: RetryConfig, signal?: AbortSignal): Promise<T>;
366
41
 
367
42
  /**
368
43
  * Multi-endpoint registry with priority routing and circuit breaker failover.
@@ -373,17 +48,67 @@ interface OllamaEndpoint {
373
48
  readonly apiKey?: string | undefined;
374
49
  readonly headers?: Record<string, string> | undefined;
375
50
  readonly priority?: number | undefined;
51
+ /**
52
+ * Restricts this endpoint/credential to a specific set of models — for the common case
53
+ * of several Ollama Cloud API keys, each entitled to a different model. When set,
54
+ * `EndpointRegistry.candidates(model)` only returns this endpoint for a request whose
55
+ * `model` is in the list, so cross-endpoint failover never retries a request against a
56
+ * credential that isn't authorized for the requested model. Omit (the default) to make
57
+ * the endpoint eligible for every model, preserving prior behavior.
58
+ */
59
+ readonly models?: readonly string[] | undefined;
376
60
  }
377
61
  interface EndpointHealth {
378
62
  readonly endpoint: OllamaEndpoint;
379
63
  readonly failureCount: number;
380
64
  readonly lastFailureTimestamp?: number | undefined;
381
65
  readonly isCoolingDown: boolean;
66
+ /** In-flight requests currently attempting this endpoint — see `acquire`/`release`. */
67
+ readonly activeRequests: number;
382
68
  }
383
69
  interface EndpointRegistryOptions {
384
70
  readonly failureThreshold?: number | undefined;
385
71
  readonly cooldownMs?: number | undefined;
386
72
  readonly now?: (() => number) | undefined;
73
+ /**
74
+ * How candidates that share the same `priority` are ordered within `candidates()`.
75
+ * `'priority'` (the default) keeps them in registration order, so the same candidate is
76
+ * always tried first while it stays healthy. `'round-robin'` rotates each same-priority
77
+ * group by one position per `candidates()` call — i.e. per `chat`/`generate`/etc. call —
78
+ * so consecutive requests spread across a pool of interchangeable endpoints/credentials
79
+ * instead of always preferring the first one (the common case: several Ollama Cloud keys
80
+ * registered with no `models` restriction, meant to be used interchangeably). Endpoints
81
+ * at different priorities are unaffected either way — a higher-priority one is still
82
+ * always tried first, and failover to the rest of the group still applies if the
83
+ * rotated-to-front candidate fails.
84
+ *
85
+ * `'least-connections'` instead orders each same-priority group by ascending in-flight
86
+ * request count (tracked via `acquire`/`release`, ties broken by registration order),
87
+ * so a request always prefers whichever candidate currently has the fewest requests
88
+ * still in progress. Unlike `'round-robin'`, this remains correct under uneven or
89
+ * overlapping request durations — e.g. several Ollama Cloud accounts each limited to 1
90
+ * concurrent request: firing several requests at once (`Promise.all`) deterministically
91
+ * lands each on a different account rather than risking two landing on the same
92
+ * still-busy one, because `candidates()` and the subsequent `acquire()` for the chosen
93
+ * candidate run synchronously with no `await` in between — JS's single-threaded
94
+ * execution means no two concurrent calls can observe the same "0 active" snapshot for
95
+ * the same candidate.
96
+ */
97
+ readonly strategy?: 'priority' | 'round-robin' | 'least-connections' | undefined;
98
+ /**
99
+ * Caps in-flight requests per endpoint (tracked via `acquire`/`release`). Unset (the
100
+ * default) means no cap — candidates are never treated as saturated. When set, a
101
+ * request whose every otherwise-eligible candidate is already at this cap waits
102
+ * (`waitForCapacity`, FIFO per candidate) for one of them to free up, instead of being
103
+ * sent to an already-saturated candidate. Pairs naturally with `strategy:
104
+ * 'least-connections'` for a pool of accounts each limited to N concurrent requests —
105
+ * e.g. `maxConcurrentPerEndpoint: 1` for several Ollama Cloud free-tier accounts, so
106
+ * `N + 1` concurrent calls against `N` such accounts run `N` immediately and queue the
107
+ * rest, rather than the `(N+1)`th overrunning whichever account looks "least busy" at
108
+ * that instant. Waiting is bounded by the request's own timeout/`AbortSignal`, same as
109
+ * any other in-flight request — it never blocks indefinitely on its own.
110
+ */
111
+ readonly maxConcurrentPerEndpoint?: number | undefined;
387
112
  }
388
113
  declare class EndpointRegistry {
389
114
  private readonly endpoints;
@@ -392,11 +117,66 @@ declare class EndpointRegistry {
392
117
  private readonly failureThreshold;
393
118
  private readonly cooldownMs;
394
119
  private readonly now;
120
+ private readonly strategy;
121
+ private roundRobinCounter;
122
+ private readonly activeCounts;
123
+ private readonly maxConcurrentPerEndpoint;
124
+ private readonly waiters;
395
125
  constructor(endpoints: readonly OllamaEndpoint[], options?: EndpointRegistryOptions);
396
- candidates(): OllamaEndpoint[];
126
+ /**
127
+ * Marks one more request as in-flight against `name`. Callers (`OllamaClient`) must
128
+ * pair every `acquire` with a `release` once that attempt finishes, success or not —
129
+ * see `OllamaClient.executeWithFailover`. Only affects candidate ordering when
130
+ * `strategy` is `'least-connections'`; harmless (just bookkeeping) otherwise, and
131
+ * always reflected in `status()`'s `activeRequests`.
132
+ */
133
+ acquire(name: string): void;
134
+ /** Releases one in-flight request marked via `acquire`, waking one waiter for `name` if any. */
135
+ release(name: string): void;
136
+ /**
137
+ * `candidates` filtered down to those currently under `maxConcurrentPerEndpoint` (all
138
+ * of them, unchanged, if that option is unset).
139
+ */
140
+ filterWithCapacity(candidates: readonly OllamaEndpoint[]): OllamaEndpoint[];
141
+ /**
142
+ * Resolves once any endpoint named in `names` has spare capacity under
143
+ * `maxConcurrentPerEndpoint` (a no-op resolve if that option is unset, or if one
144
+ * already does). Otherwise queues (FIFO per name) until a matching `release()` frees a
145
+ * slot, or rejects if `signal` aborts first — mirroring whatever aborted it
146
+ * (`OllamaTimeoutError`/the caller's own abort reason) so callers see the same error
147
+ * shape as any other in-flight request that times out or is cancelled. FIFO order is
148
+ * best-effort (a newly-arriving request can still win a race for a slot that just
149
+ * freed) — the capacity cap itself, not fairness, is the guarantee this exists for.
150
+ */
151
+ waitForCapacity(names: readonly string[], signal?: AbortSignal): Promise<void>;
152
+ /**
153
+ * Rotates each same-`priority` group in `sorted` (already sorted highest-priority-first)
154
+ * by one position further per call, wrapping around within the group. Priority tiers
155
+ * themselves are never reordered — only candidates that were already tied.
156
+ */
157
+ private applyRoundRobin;
158
+ /**
159
+ * Reorders each same-`priority` group in `sorted` by ascending in-flight request count
160
+ * (from `acquire`/`release`); a stable sort, so candidates tied on active count keep
161
+ * their relative (priority-then-registration) order. Priority tiers themselves are
162
+ * never reordered.
163
+ */
164
+ private applyLeastConnections;
165
+ /**
166
+ * Endpoints eligible for `model`, sorted healthy-first-by-priority (falling back to
167
+ * soonest-to-recover if every eligible endpoint is cooling down); same-priority
168
+ * candidates are further reordered per `options.strategy` (see
169
+ * `EndpointRegistryOptions.strategy`). When `model` is given, endpoints whose `models`
170
+ * allow-list doesn't include it are excluded entirely — see `OllamaEndpoint.models`.
171
+ * Omit `model` to consider every configured endpoint, regardless of any `models`
172
+ * restriction (used for non-model-scoped operations).
173
+ */
174
+ candidates(model?: string): OllamaEndpoint[];
397
175
  reportSuccess(name: string): void;
398
176
  reportFailure(name: string): void;
399
177
  list(): readonly OllamaEndpoint[];
178
+ /** True if any configured endpoint restricts itself to a `models` allow-list. */
179
+ hasModelScopedEndpoints(): boolean;
400
180
  status(): EndpointHealth[];
401
181
  }
402
182
 
@@ -406,6 +186,35 @@ declare class EndpointRegistry {
406
186
 
407
187
  declare const DEFAULT_BASE_URL = "http://localhost:11434";
408
188
  declare const DEFAULT_TIMEOUT_MS = 30000;
189
+ /**
190
+ * Fixed host for Ollama's hosted web tools (`/api/web_search`, `/api/web_fetch`) — see
191
+ * `OllamaClient.webSearch`/`webFetch`. These are an Ollama Cloud service reachable only
192
+ * at this host, independent of any locally-configured `baseUrl`/`endpoints`.
193
+ */
194
+ declare const OLLAMA_CLOUD_BASE_URL = "https://ollama.com";
195
+ /** One named credential for the `credentials`/`modelBindings` config shape. */
196
+ interface OllamaCredentialConfig {
197
+ readonly apiKey: string;
198
+ /** Overrides `OllamaClientConfig.baseUrl` for requests made with this credential. */
199
+ readonly baseUrl?: string | undefined;
200
+ readonly headers?: Record<string, string> | undefined;
201
+ }
202
+ /**
203
+ * Builds synthetic `OllamaEndpoint`s (named `credential:<id>`) from `config.credentials` +
204
+ * `config.modelBindings` — an ergonomic, map-based alternative to writing out `endpoints`
205
+ * with per-entry `models` allow-lists directly. Both shapes feed the same
206
+ * `EndpointRegistry`/`executeWithFailover` routing engine; this is pure config sugar, not
207
+ * a separate routing mechanism. Returns `[]` if `config.credentials` is unset.
208
+ *
209
+ * A model bound to one credential (`modelBindings: { "minimax-m3": "coder" }`) scopes that
210
+ * credential to only that model, same as `OllamaEndpoint.models`. A model bound to several
211
+ * credentials (`modelBindings: { "gpt-oss:120b": ["key1", "key2"] }`) makes ordinary
212
+ * endpoint failover apply between them. `config.defaultCredential`, if set, is given a
213
+ * lower priority than explicitly-bound credentials and no `models` restriction, so it acts
214
+ * as a catch-all for any model without an explicit binding without ever pre-empting one
215
+ * that has.
216
+ */
217
+ declare function resolveCredentialEndpoints(config: Pick<OllamaClientConfig, 'credentials' | 'modelBindings' | 'defaultCredential' | 'baseUrl'>): readonly OllamaEndpoint[];
409
218
  declare const DEFAULT_FAILOVER_CODES: readonly string[];
410
219
  interface OllamaClientConfig {
411
220
  /**
@@ -422,9 +231,49 @@ interface OllamaClientConfig {
422
231
  readonly apiKey?: string;
423
232
  /** Static headers merged into every request. */
424
233
  readonly headers?: Record<string, string>;
425
- /** Multiple named endpoints for rotation and automatic failover. */
234
+ /**
235
+ * Multiple named endpoints for rotation and automatic failover. Each endpoint may
236
+ * carry its own `apiKey` and, via `models`, be scoped to only the models that
237
+ * credential is entitled to — see `OllamaEndpoint.models` for routing several
238
+ * per-model Ollama Cloud API keys through a single client.
239
+ */
426
240
  readonly endpoints?: readonly OllamaEndpoint[];
427
- /** Tuning options for endpoint circuit breaker. */
241
+ /**
242
+ * Named credentials, keyed by an id you choose — an ergonomic alternative to writing
243
+ * out `endpoints` by hand for the common "several Ollama Cloud API keys, each entitled
244
+ * to different models" shape. Combine with `modelBindings` to scope each credential to
245
+ * the models it's authorized for; a credential with no binding (or set as
246
+ * `defaultCredential`) is eligible for every model, same as an `OllamaEndpoint` with no
247
+ * `models`. Merges additively with `endpoints` if both are given.
248
+ */
249
+ readonly credentials?: Readonly<Record<string, OllamaCredentialConfig>>;
250
+ /**
251
+ * Maps a model name to the `credentials` id (or ids, for several keys authorized for
252
+ * the same model — ordinary failover applies between them) that may serve it. Has no
253
+ * effect without `credentials`. Referencing an id not present in `credentials` throws
254
+ * at construction time.
255
+ */
256
+ readonly modelBindings?: Readonly<Record<string, string | readonly string[]>>;
257
+ /**
258
+ * The `credentials` id to fall back to for a model with no entry in `modelBindings`.
259
+ * Unset means such a model has no synthesized-from-`credentials` route — it still
260
+ * routes normally through any plain `endpoints` entry without a `models` restriction.
261
+ */
262
+ readonly defaultCredential?: string | undefined;
263
+ /**
264
+ * Tuning options for the endpoint circuit breaker, and candidate selection ordering —
265
+ * pass `{ strategy: 'round-robin' }` to spread requests across a pool of same-priority
266
+ * endpoints/credentials (e.g. several unbound `credentials`) instead of always
267
+ * preferring the first one, or `{ strategy: 'least-connections' }` to route each
268
+ * request to whichever candidate currently has the fewest requests in flight (e.g.
269
+ * several free-tier Ollama Cloud accounts, each capped at 1 concurrent request — this
270
+ * deterministically spreads concurrent `Promise.all`-style calls one-per-account rather
271
+ * than risking two landing on the same still-busy one), and `maxConcurrentPerEndpoint`
272
+ * to cap that at an exact number and queue (rather than overrun a saturated candidate)
273
+ * once every eligible one is at capacity — e.g. `{ strategy: 'least-connections',
274
+ * maxConcurrentPerEndpoint: 1 }` for accounts that only allow one request at a time.
275
+ * See `EndpointRegistryOptions`.
276
+ */
428
277
  readonly endpointHealth?: EndpointRegistryOptions;
429
278
  /** Error codes that trigger failover to the next candidate endpoint. */
430
279
  readonly failoverOn?: readonly string[];
@@ -456,7 +305,7 @@ interface EndpointHealthCheckResult {
456
305
  readonly version?: string;
457
306
  readonly error?: string;
458
307
  }
459
- declare function checkEndpointHealth(endpoint: OllamaEndpoint, fetchImpl?: FetchLike, timeoutMs?: number): Promise<EndpointHealthCheckResult>;
308
+ declare function checkEndpointHealth(endpoint: OllamaEndpoint, fetchImpl?: FetchLike, timeoutMs?: number, middleware?: readonly Middleware[] | undefined, onLifecycleEvent?: RequestLifecycleHook | undefined): Promise<EndpointHealthCheckResult>;
460
309
 
461
310
  /**
462
311
  * Model capability detection and runtime environment inference.
@@ -471,7 +320,11 @@ interface ModelCapabilities {
471
320
  readonly supportsEmbedding: boolean;
472
321
  readonly supportsCompletion: boolean;
473
322
  readonly supportsThinking: boolean;
323
+ /** Model-defined thinking values and default, when /api/show reports them. */
324
+ readonly thinking?: ThinkingMetadata | undefined;
474
325
  readonly supportsStreaming: true;
326
+ /** Maximum model context length reported by /api/show model_info, when available. */
327
+ readonly contextLength?: number | undefined;
475
328
  /**
476
329
  * Best-effort inference, not a guarantee: Ollama's `/api/show` does not report structured
477
330
  * output support as a queryable capability, so this is inferred from {@link inferRuntimeMode}
@@ -485,7 +338,7 @@ interface ModelCapabilities {
485
338
  readonly supportsStructuredOutputRequest: boolean;
486
339
  }
487
340
  declare function inferRuntimeMode(baseUrl: string): RuntimeMode;
488
- declare function detectModelCapabilities(http: HttpClient, model: string): Promise<ModelCapabilities>;
341
+ declare function detectModelCapabilities(http: HttpClient, model: string, signal?: AbortSignal): Promise<ModelCapabilities>;
489
342
  declare function listAvailableModels(http: HttpClient): Promise<ModelResponse[]>;
490
343
 
491
344
  /**
@@ -504,7 +357,8 @@ declare class OllamaStream<TChunk, TFinal> implements AsyncIterable<OllamaStream
504
357
  private readonly finalResultPromise;
505
358
  private resolveFinal;
506
359
  private rejectFinal;
507
- constructor(source: AbortableAsyncIterable<TChunk>, mapChunk: ChunkMapper<TChunk, TFinal>, aggregate: Aggregator<TChunk, TFinal>, initial: TFinal);
360
+ private removeAbortListener;
361
+ constructor(source: AbortableAsyncIterable<TChunk>, mapChunk: ChunkMapper<TChunk, TFinal>, aggregate: Aggregator<TChunk, TFinal>, initial: TFinal, signal?: AbortSignal);
508
362
  get finalResult(): Promise<TFinal>;
509
363
  abort(): void;
510
364
  on<TType extends OllamaStreamEventType>(type: TType, listener: (event: Extract<OllamaStreamEvent<TChunk, TFinal>, {
@@ -516,14 +370,22 @@ declare class OllamaStream<TChunk, TFinal> implements AsyncIterable<OllamaStream
516
370
  }
517
371
 
518
372
  /**
519
- * Model and blob management operations.
373
+ * Shared request-runner contract used by native and compatibility clients.
520
374
  */
521
375
 
522
376
  type RequestRunner = <T>(op: (http: HttpClient, signal: AbortSignal) => Promise<T>, opts?: {
523
- signal?: AbortSignal | undefined;
524
- timeoutMs?: number | undefined;
525
- singleEndpoint?: boolean | undefined;
377
+ readonly signal?: AbortSignal | undefined;
378
+ readonly timeoutMs?: number | undefined;
379
+ readonly singleEndpoint?: boolean | undefined;
380
+ readonly model?: string | undefined;
381
+ /** Defers endpoint capacity release until the returned promise settles. */
382
+ readonly holdUntil?: ((result: T) => Promise<unknown>) | undefined;
526
383
  }) => Promise<T>;
384
+
385
+ /**
386
+ * Model and blob management operations.
387
+ */
388
+
527
389
  /**
528
390
  * Every operation here targets one specific Ollama server's local model catalog or blob
529
391
  * store — unlike `chat`/`generate`/`embed`, a different endpoint isn't an interchangeable
@@ -592,11 +454,26 @@ interface OpenAIToolCall {
592
454
  readonly arguments: string;
593
455
  };
594
456
  }
457
+ interface OpenAITextContentPart {
458
+ readonly type: 'text';
459
+ readonly text: string;
460
+ }
461
+ interface OpenAIImageUrlContentPart {
462
+ readonly type: 'image_url';
463
+ /** Ollama accepts a data/image URL string or the standard OpenAI URL object. */
464
+ readonly image_url: string | {
465
+ readonly url: string;
466
+ readonly detail?: 'auto' | 'low' | 'high' | 'original' | undefined;
467
+ };
468
+ }
469
+ type OpenAIContentPart = OpenAITextContentPart | OpenAIImageUrlContentPart;
595
470
  interface OpenAIMessage {
596
471
  readonly role: 'system' | 'user' | 'assistant' | 'tool';
597
- readonly content: string;
472
+ readonly content: string | readonly OpenAIContentPart[];
598
473
  readonly name?: string | undefined;
599
474
  readonly tool_calls?: readonly OpenAIToolCall[] | undefined;
475
+ /** Ollama may emit model reasoning alongside assistant content. */
476
+ readonly reasoning?: string | undefined;
600
477
  /** Set on a `role: 'tool'` message to identify which call this is a result for. */
601
478
  readonly tool_call_id?: string | undefined;
602
479
  }
@@ -613,6 +490,15 @@ interface OpenAITool {
613
490
  readonly type: 'function';
614
491
  readonly function: OpenAIFunctionDefinition;
615
492
  }
493
+ type OpenAIReasoningEffort = 'high' | 'medium' | 'low' | 'max' | 'none' | 'minimal' | 'xhigh' | 'ultra' | (string & {});
494
+ type OpenAIResponseFormat = {
495
+ readonly type: 'text';
496
+ } | {
497
+ readonly type: 'json_object';
498
+ } | {
499
+ readonly type: 'json_schema';
500
+ readonly json_schema: Record<string, unknown>;
501
+ };
616
502
  interface OpenAIChatCompletionRequest {
617
503
  readonly model: string;
618
504
  readonly messages: readonly OpenAIMessage[];
@@ -623,9 +509,16 @@ interface OpenAIChatCompletionRequest {
623
509
  readonly stream_options?: OpenAIStreamOptions | undefined;
624
510
  readonly max_tokens?: number | undefined;
625
511
  readonly stop?: readonly string[] | undefined;
512
+ readonly response_format?: OpenAIResponseFormat | undefined;
513
+ readonly seed?: number | undefined;
626
514
  readonly presence_penalty?: number | undefined;
627
515
  readonly frequency_penalty?: number | undefined;
628
516
  readonly user?: string | undefined;
517
+ readonly logit_bias?: Record<string, number> | undefined;
518
+ readonly n?: number | undefined;
519
+ /** Ollama exposes log probabilities for supported reasoning/chat models. */
520
+ readonly logprobs?: boolean | undefined;
521
+ readonly top_logprobs?: number | undefined;
629
522
  readonly tools?: readonly OpenAITool[] | undefined;
630
523
  /**
631
524
  * @remarks Accepted for OpenAI compatibility but ignored by Ollama — every tool the
@@ -646,33 +539,92 @@ interface OpenAIChatCompletionRequest {
646
539
  * Effort level for thinking models (e.g. `deepseek-r1`, `qwen3`). Equivalent to
647
540
  * `reasoning.effort`; only effective for models that support reasoning/thinking.
648
541
  */
649
- readonly reasoning_effort?: 'high' | 'medium' | 'low' | 'max' | 'none' | undefined;
542
+ readonly reasoning_effort?: OpenAIReasoningEffort | undefined;
650
543
  /**
651
544
  * Effort level for thinking models (e.g. `deepseek-r1`, `qwen3`), nested OpenAI-style.
652
545
  * Equivalent to `reasoning_effort`; only effective for models that support
653
546
  * reasoning/thinking.
654
547
  */
655
548
  readonly reasoning?: {
656
- readonly effort?: 'high' | 'medium' | 'low' | 'max' | 'none' | undefined;
549
+ readonly effort?: OpenAIReasoningEffort | undefined;
657
550
  } | undefined;
658
551
  }
552
+ /** Ollama Chat Completions supports text plus base64 image content via a string image URL. */
553
+ type OllamaOpenAIChatContentPart = OpenAITextContentPart | {
554
+ readonly type: 'image_url';
555
+ /** Ollama's current compatibility docs accept an image URL string, including data URLs. */
556
+ readonly image_url: string;
557
+ };
558
+ type OllamaOpenAIReasoningEffort = 'high' | 'medium' | 'low' | 'max' | 'none';
559
+ type OllamaOpenAIChatMessage = Omit<OpenAIMessage, 'content'> & {
560
+ readonly content: string | readonly OllamaOpenAIChatContentPart[];
561
+ };
562
+ /** Strict Ollama-documented Chat Completions request; excludes only the SDK-only parallel tool flag. */
563
+ type OllamaOpenAIChatCompletionRequest = Omit<OpenAIChatCompletionRequest, 'messages' | 'parallel_tool_calls' | 'reasoning_effort' | 'reasoning'> & {
564
+ readonly messages: readonly OllamaOpenAIChatMessage[];
565
+ readonly reasoning_effort?: OllamaOpenAIReasoningEffort | undefined;
566
+ readonly reasoning?: {
567
+ readonly effort?: OllamaOpenAIReasoningEffort | undefined;
568
+ } | undefined;
569
+ };
659
570
  interface OpenAIChatCompletionChoice {
660
571
  readonly index: number;
661
572
  readonly message: OpenAIMessage;
662
573
  readonly finish_reason: string;
574
+ readonly logprobs?: Record<string, unknown> | null | undefined;
663
575
  }
664
- interface OpenAIChatCompletionResponse {
576
+ interface OpenAIToolCallDelta {
577
+ readonly index: number;
578
+ readonly id?: string | undefined;
579
+ readonly type?: 'function' | undefined;
580
+ readonly function?: {
581
+ readonly name?: string | undefined;
582
+ readonly arguments?: string | undefined;
583
+ } | undefined;
584
+ }
585
+ interface OpenAIChatCompletionDelta {
586
+ readonly role?: OpenAIMessage['role'] | undefined;
587
+ readonly content?: string | null | undefined;
588
+ readonly reasoning?: string | null | undefined;
589
+ readonly refusal?: string | null | undefined;
590
+ readonly tool_calls?: readonly OpenAIToolCallDelta[] | undefined;
591
+ }
592
+ interface OpenAIChatCompletionChunkChoice {
593
+ readonly index: number;
594
+ readonly delta: OpenAIChatCompletionDelta;
595
+ readonly finish_reason?: string | null | undefined;
596
+ readonly logprobs?: Record<string, unknown> | null | undefined;
597
+ }
598
+ interface OpenAIChatCompletionChunk {
665
599
  readonly id: string;
666
- readonly object: 'chat.completion';
600
+ readonly object: 'chat.completion.chunk';
667
601
  readonly created: number;
668
602
  readonly model: string;
669
- readonly choices: readonly OpenAIChatCompletionChoice[];
603
+ readonly system_fingerprint?: string | undefined;
604
+ readonly choices: readonly OpenAIChatCompletionChunkChoice[];
670
605
  readonly usage?: {
671
606
  readonly prompt_tokens: number;
672
607
  readonly completion_tokens: number;
673
608
  readonly total_tokens: number;
609
+ } | null | undefined;
610
+ }
611
+ interface OpenAIUsage {
612
+ readonly prompt_tokens: number;
613
+ readonly completion_tokens: number;
614
+ readonly total_tokens: number;
615
+ readonly prompt_tokens_details?: {
616
+ readonly cached_tokens?: number | undefined;
674
617
  } | undefined;
675
618
  }
619
+ interface OpenAIChatCompletionResponse {
620
+ readonly id: string;
621
+ readonly object: 'chat.completion';
622
+ readonly created: number;
623
+ readonly model: string;
624
+ readonly system_fingerprint?: string | undefined;
625
+ readonly choices: readonly OpenAIChatCompletionChoice[];
626
+ readonly usage?: OpenAIUsage | undefined;
627
+ }
676
628
  interface OpenAIModelItem {
677
629
  readonly id: string;
678
630
  readonly object: 'model';
@@ -683,6 +635,87 @@ interface OpenAIListModelsResponse {
683
635
  readonly object: 'list';
684
636
  readonly data: readonly OpenAIModelItem[];
685
637
  }
638
+ interface OpenAICompletionRequest {
639
+ readonly model: string;
640
+ /** Ollama currently accepts a string prompt for /v1/completions. */
641
+ readonly prompt: string;
642
+ /** Number of log probability alternatives requested for completion tokens. */
643
+ readonly logprobs?: number | undefined;
644
+ readonly frequency_penalty?: number | undefined;
645
+ readonly presence_penalty?: number | undefined;
646
+ readonly seed?: number | undefined;
647
+ readonly stop?: readonly string[] | undefined;
648
+ readonly stream?: boolean | undefined;
649
+ readonly stream_options?: OpenAIStreamOptions | undefined;
650
+ readonly temperature?: number | undefined;
651
+ readonly top_p?: number | undefined;
652
+ readonly max_tokens?: number | undefined;
653
+ readonly suffix?: string | undefined;
654
+ readonly best_of?: number | undefined;
655
+ readonly echo?: boolean | undefined;
656
+ readonly logit_bias?: Record<string, number> | undefined;
657
+ readonly user?: string | undefined;
658
+ readonly n?: number | undefined;
659
+ }
660
+ /** Strict Ollama-documented Completions request. */
661
+ type OllamaOpenAICompletionRequest = OpenAICompletionRequest;
662
+ interface OpenAICompletionChoice {
663
+ readonly text: string;
664
+ readonly index: number;
665
+ readonly logprobs?: Record<string, unknown> | null | undefined;
666
+ readonly finish_reason: string | null;
667
+ }
668
+ interface OpenAICompletionChunk {
669
+ readonly id: string;
670
+ readonly object: 'text_completion';
671
+ readonly created: number;
672
+ readonly model: string;
673
+ readonly system_fingerprint?: string | undefined;
674
+ readonly choices: readonly {
675
+ readonly text: string;
676
+ readonly index: number;
677
+ readonly logprobs?: Record<string, unknown> | null | undefined;
678
+ readonly finish_reason?: string | null | undefined;
679
+ }[];
680
+ readonly usage?: {
681
+ readonly prompt_tokens: number;
682
+ readonly completion_tokens: number;
683
+ readonly total_tokens: number;
684
+ } | null | undefined;
685
+ }
686
+ interface OpenAICompletionResponse {
687
+ readonly id: string;
688
+ readonly object: 'text_completion';
689
+ readonly created: number;
690
+ readonly model: string;
691
+ readonly system_fingerprint?: string | undefined;
692
+ readonly choices: readonly OpenAICompletionChoice[];
693
+ readonly usage?: OpenAIUsage | undefined;
694
+ }
695
+ type OpenAIEmbeddingInput = string | readonly string[] | readonly number[] | readonly (readonly number[])[];
696
+ interface OpenAIEmbeddingRequest {
697
+ readonly model: string;
698
+ readonly input: OpenAIEmbeddingInput;
699
+ readonly encoding_format?: 'float' | 'base64' | undefined;
700
+ readonly dimensions?: number | undefined;
701
+ readonly user?: string | undefined;
702
+ }
703
+ /** Strict Ollama-documented Embeddings request. */
704
+ type OllamaOpenAIEmbeddingRequest = OpenAIEmbeddingRequest;
705
+ interface OpenAIEmbeddingItem {
706
+ readonly object: 'embedding';
707
+ readonly embedding: readonly number[] | string;
708
+ readonly index: number;
709
+ }
710
+ interface OpenAIEmbeddingResponse {
711
+ readonly object: 'list';
712
+ readonly data: readonly OpenAIEmbeddingItem[];
713
+ readonly model: string;
714
+ readonly usage?: {
715
+ readonly prompt_tokens: number;
716
+ readonly total_tokens: number;
717
+ } | undefined;
718
+ }
686
719
  /**
687
720
  * Request body for OpenAI's Responses API (`/v1/responses`), added in Ollama v0.13.3.
688
721
  *
@@ -706,93 +739,601 @@ interface OpenAIResponsesRequest {
706
739
  /** @remarks Not supported by Ollama, which is stateless across calls — accepted but ignored. */
707
740
  readonly conversation?: string | undefined;
708
741
  readonly truncation?: string | undefined;
742
+ readonly reasoning?: {
743
+ readonly effort?: OpenAIReasoningEffort | undefined;
744
+ } | undefined;
745
+ /** Ollama extension: boolean, model-defined string, or null for model default. */
746
+ readonly think?: boolean | string | null | undefined;
747
+ }
748
+ /** Strict Ollama-documented Responses request; excludes stateful and SDK-only request fields. */
749
+ /** Strict Ollama-documented Responses request; excludes only unsupported stateful fields. */
750
+ type OllamaOpenAIResponsesRequest = Omit<OpenAIResponsesRequest, 'previous_response_id' | 'conversation'>;
751
+ type OpenAIResponsesStatus = 'completed' | 'failed' | 'in_progress' | 'cancelled' | 'queued' | 'incomplete';
752
+ interface OpenAIResponsesError {
753
+ readonly code?: string | undefined;
754
+ readonly message?: string | undefined;
755
+ readonly [key: string]: unknown;
756
+ }
757
+ interface OpenAIResponsesIncompleteDetails {
758
+ readonly reason?: string | undefined;
759
+ readonly [key: string]: unknown;
709
760
  }
710
761
  interface OpenAIResponsesOutputTextContent {
711
762
  readonly type: 'output_text';
712
763
  readonly text: string;
764
+ readonly annotations?: readonly Record<string, unknown>[] | undefined;
765
+ readonly logprobs?: readonly Record<string, unknown>[] | undefined;
766
+ }
767
+ interface OpenAIResponsesOutputRefusal {
768
+ readonly type: 'refusal';
769
+ readonly refusal: string;
713
770
  }
771
+ type OpenAIResponsesOutputContent = OpenAIResponsesOutputTextContent | OpenAIResponsesOutputRefusal;
714
772
  interface OpenAIResponsesOutputMessage {
715
773
  readonly type: 'message';
774
+ readonly id?: string | undefined;
775
+ readonly status?: OpenAIResponsesStatus | undefined;
716
776
  readonly role?: string | undefined;
717
- readonly content: readonly OpenAIResponsesOutputTextContent[];
777
+ readonly phase?: string | undefined;
778
+ readonly content: readonly OpenAIResponsesOutputContent[];
718
779
  }
719
- /** Non-stateful response shape for `/v1/responses`; see {@link OpenAIResponsesRequest}. */
780
+ interface OpenAIResponsesOutputFunctionCall {
781
+ readonly type: 'function_call';
782
+ readonly id?: string | undefined;
783
+ readonly call_id?: string | undefined;
784
+ readonly name: string;
785
+ readonly arguments: string;
786
+ readonly status?: OpenAIResponsesStatus | undefined;
787
+ }
788
+ interface OpenAIResponsesOutputReasoning {
789
+ readonly type: 'reasoning';
790
+ readonly id?: string | undefined;
791
+ readonly status?: OpenAIResponsesStatus | undefined;
792
+ readonly summary?: readonly {
793
+ readonly type: 'summary_text';
794
+ readonly text: string;
795
+ }[] | undefined;
796
+ readonly text?: string | undefined;
797
+ readonly encrypted_content?: string | undefined;
798
+ }
799
+ type OpenAIResponsesOutputItem = OpenAIResponsesOutputMessage | OpenAIResponsesOutputFunctionCall | OpenAIResponsesOutputReasoning;
800
+ interface OpenAIResponsesUsage {
801
+ readonly input_tokens: number;
802
+ readonly output_tokens: number;
803
+ readonly total_tokens: number;
804
+ readonly input_tokens_details?: Record<string, unknown> | undefined;
805
+ readonly output_tokens_details?: Record<string, unknown> | undefined;
806
+ }
807
+ /** Non-stateful response shape for the Ollama Responses compatibility endpoint. */
720
808
  interface OpenAIResponsesResponse {
721
809
  readonly id: string;
722
810
  readonly object: 'response';
723
811
  readonly created: number;
812
+ readonly created_at?: number | undefined;
813
+ readonly status?: OpenAIResponsesStatus | undefined;
814
+ readonly completed_at?: number | null | undefined;
815
+ readonly error?: OpenAIResponsesError | null | undefined;
816
+ readonly incomplete_details?: OpenAIResponsesIncompleteDetails | null | undefined;
724
817
  readonly model: string;
725
- readonly output: readonly OpenAIResponsesOutputMessage[];
726
- readonly usage?: {
727
- readonly input_tokens: number;
728
- readonly output_tokens: number;
729
- readonly total_tokens: number;
730
- } | undefined;
818
+ readonly output: readonly OpenAIResponsesOutputItem[];
819
+ readonly output_text?: string | undefined;
820
+ readonly previous_response_id?: string | null | undefined;
821
+ readonly parallel_tool_calls?: boolean | undefined;
822
+ readonly usage?: OpenAIResponsesUsage | undefined;
823
+ }
824
+ declare class OpenAIResponsesStreamError extends OllamaClientError {
825
+ readonly responsePayload: OpenAIResponsesResponse;
826
+ constructor(message: string, responsePayload: OpenAIResponsesResponse);
827
+ }
828
+ declare class OpenAIChatCompletionStream implements AsyncIterable<OpenAIChatCompletionChunk> {
829
+ private readonly source;
830
+ private readonly finalResultPromise;
831
+ private resolveFinal;
832
+ private rejectFinal;
833
+ private removeAbortListener;
834
+ constructor(source: AbortableAsyncIterable<SseEvent>, signal?: AbortSignal);
835
+ get finalResult(): Promise<OpenAIChatCompletionResponse>;
836
+ abort(): void;
837
+ [Symbol.asyncIterator](): AsyncGenerator<OpenAIChatCompletionChunk, void, undefined>;
838
+ }
839
+ declare class OpenAICompletionStream implements AsyncIterable<OpenAICompletionChunk> {
840
+ private readonly source;
841
+ private readonly finalResultPromise;
842
+ private resolveFinal;
843
+ private rejectFinal;
844
+ private removeAbortListener;
845
+ constructor(source: AbortableAsyncIterable<SseEvent>, signal?: AbortSignal);
846
+ get finalResult(): Promise<OpenAICompletionResponse>;
847
+ abort(): void;
848
+ [Symbol.asyncIterator](): AsyncGenerator<OpenAICompletionChunk, void, undefined>;
849
+ }
850
+ interface OpenAIResponsesEventBase {
851
+ readonly response_id?: string | undefined;
852
+ readonly sequence_number?: number | undefined;
853
+ }
854
+ interface OpenAIResponsesOutputTextDeltaEvent extends OpenAIResponsesEventBase {
855
+ readonly type: 'response.output_text.delta';
856
+ readonly item_id: string;
857
+ readonly output_index: number;
858
+ readonly content_index: number;
859
+ readonly delta: string;
860
+ }
861
+ interface OpenAIResponsesOutputTextDoneEvent extends OpenAIResponsesEventBase {
862
+ readonly type: 'response.output_text.done';
863
+ readonly item_id: string;
864
+ readonly output_index: number;
865
+ readonly content_index: number;
866
+ readonly text: string;
867
+ }
868
+ interface OpenAIResponsesFunctionCallArgumentsDeltaEvent extends OpenAIResponsesEventBase {
869
+ readonly type: 'response.function_call_arguments.delta';
870
+ readonly item_id: string;
871
+ readonly output_index: number;
872
+ readonly delta: string;
873
+ }
874
+ interface OpenAIResponsesFunctionCallArgumentsDoneEvent extends OpenAIResponsesEventBase {
875
+ readonly type: 'response.function_call_arguments.done';
876
+ readonly item_id: string;
877
+ readonly output_index: number;
878
+ readonly arguments: string;
879
+ readonly name?: string | undefined;
880
+ }
881
+ interface OpenAIResponsesReasoningTextDeltaEvent extends OpenAIResponsesEventBase {
882
+ readonly type: 'response.reasoning_text.delta';
883
+ readonly item_id: string;
884
+ readonly output_index: number;
885
+ readonly content_index: number;
886
+ readonly delta: string;
887
+ }
888
+ interface OpenAIResponsesReasoningTextDoneEvent extends OpenAIResponsesEventBase {
889
+ readonly type: 'response.reasoning_text.done';
890
+ readonly item_id: string;
891
+ readonly output_index: number;
892
+ readonly content_index: number;
893
+ readonly text: string;
894
+ }
895
+ interface OpenAIResponsesReasoningSummaryPartAddedEvent extends OpenAIResponsesEventBase {
896
+ readonly type: 'response.reasoning_summary_part.added';
897
+ readonly item_id: string;
898
+ readonly output_index: number;
899
+ readonly summary_index: number;
900
+ readonly part: {
901
+ readonly type: 'summary_text';
902
+ readonly text: string;
903
+ };
904
+ }
905
+ interface OpenAIResponsesReasoningSummaryPartDoneEvent extends OpenAIResponsesEventBase {
906
+ readonly type: 'response.reasoning_summary_part.done';
907
+ readonly item_id: string;
908
+ readonly output_index: number;
909
+ readonly summary_index: number;
910
+ readonly part: {
911
+ readonly type: 'summary_text';
912
+ readonly text: string;
913
+ };
914
+ readonly status?: 'incomplete' | undefined;
915
+ }
916
+ interface OpenAIResponsesReasoningSummaryTextDeltaEvent extends OpenAIResponsesEventBase {
917
+ readonly type: 'response.reasoning_summary_text.delta';
918
+ readonly item_id: string;
919
+ readonly output_index: number;
920
+ readonly summary_index: number;
921
+ readonly delta: string;
922
+ }
923
+ interface OpenAIResponsesReasoningSummaryTextDoneEvent extends OpenAIResponsesEventBase {
924
+ readonly type: 'response.reasoning_summary_text.done';
925
+ readonly item_id: string;
926
+ readonly output_index: number;
927
+ readonly summary_index: number;
928
+ readonly text: string;
929
+ }
930
+ interface OpenAIResponsesOutputItemAddedEvent extends OpenAIResponsesEventBase {
931
+ readonly type: 'response.output_item.added';
932
+ readonly item: OpenAIResponsesOutputItem;
933
+ readonly output_index: number;
934
+ }
935
+ interface OpenAIResponsesOutputItemDoneEvent extends OpenAIResponsesEventBase {
936
+ readonly type: 'response.output_item.done';
937
+ readonly item: OpenAIResponsesOutputItem;
938
+ readonly output_index: number;
939
+ }
940
+ interface OpenAIResponsesContentPartAddedEvent extends OpenAIResponsesEventBase {
941
+ readonly type: 'response.content_part.added';
942
+ readonly item_id: string;
943
+ readonly output_index: number;
944
+ readonly content_index: number;
945
+ readonly part: OpenAIResponsesOutputContent | {
946
+ readonly type: string;
947
+ readonly [key: string]: unknown;
948
+ };
949
+ }
950
+ interface OpenAIResponsesContentPartDoneEvent extends OpenAIResponsesEventBase {
951
+ readonly type: 'response.content_part.done';
952
+ readonly item_id: string;
953
+ readonly output_index: number;
954
+ readonly content_index: number;
955
+ readonly part: OpenAIResponsesOutputContent | {
956
+ readonly type: string;
957
+ readonly [key: string]: unknown;
958
+ };
959
+ }
960
+ interface OpenAIResponsesRefusalDeltaEvent extends OpenAIResponsesEventBase {
961
+ readonly type: 'response.refusal.delta';
962
+ readonly item_id: string;
963
+ readonly output_index: number;
964
+ readonly content_index: number;
965
+ readonly delta: string;
966
+ }
967
+ interface OpenAIResponsesRefusalDoneEvent extends OpenAIResponsesEventBase {
968
+ readonly type: 'response.refusal.done';
969
+ readonly item_id: string;
970
+ readonly output_index: number;
971
+ readonly content_index: number;
972
+ readonly refusal: string;
973
+ }
974
+ interface OpenAIResponsesCreatedEvent extends OpenAIResponsesEventBase {
975
+ readonly type: 'response.created';
976
+ readonly response: OpenAIResponsesResponse;
977
+ }
978
+ interface OpenAIResponsesInProgressEvent extends OpenAIResponsesEventBase {
979
+ readonly type: 'response.in_progress';
980
+ readonly response: OpenAIResponsesResponse;
981
+ }
982
+ interface OpenAIResponsesQueuedEvent extends OpenAIResponsesEventBase {
983
+ readonly type: 'response.queued';
984
+ readonly response: OpenAIResponsesResponse;
985
+ }
986
+ interface OpenAIResponsesCompletedEvent extends OpenAIResponsesEventBase {
987
+ readonly type: 'response.completed' | 'response.done';
988
+ readonly response: OpenAIResponsesResponse;
989
+ }
990
+ interface OpenAIResponsesFailedEvent extends OpenAIResponsesEventBase {
991
+ readonly type: 'response.failed';
992
+ readonly response: OpenAIResponsesResponse;
993
+ }
994
+ interface OpenAIResponsesIncompleteEvent extends OpenAIResponsesEventBase {
995
+ readonly type: 'response.incomplete';
996
+ readonly response: OpenAIResponsesResponse;
997
+ }
998
+ type OpenAIResponsesStreamEvent = OpenAIResponsesOutputTextDeltaEvent | OpenAIResponsesOutputTextDoneEvent | OpenAIResponsesFunctionCallArgumentsDeltaEvent | OpenAIResponsesFunctionCallArgumentsDoneEvent | OpenAIResponsesReasoningTextDeltaEvent | OpenAIResponsesReasoningTextDoneEvent | OpenAIResponsesReasoningSummaryPartAddedEvent | OpenAIResponsesReasoningSummaryPartDoneEvent | OpenAIResponsesReasoningSummaryTextDeltaEvent | OpenAIResponsesReasoningSummaryTextDoneEvent | OpenAIResponsesOutputItemAddedEvent | OpenAIResponsesOutputItemDoneEvent | OpenAIResponsesContentPartAddedEvent | OpenAIResponsesContentPartDoneEvent | OpenAIResponsesRefusalDeltaEvent | OpenAIResponsesRefusalDoneEvent | OpenAIResponsesCreatedEvent | OpenAIResponsesInProgressEvent | OpenAIResponsesQueuedEvent | OpenAIResponsesCompletedEvent | OpenAIResponsesFailedEvent | OpenAIResponsesIncompleteEvent | {
999
+ readonly type: string;
1000
+ readonly [key: string]: unknown;
1001
+ };
1002
+ declare class OpenAIResponsesStream implements AsyncIterable<OpenAIResponsesStreamEvent> {
1003
+ private readonly source;
1004
+ private readonly finalResultPromise;
1005
+ private resolveFinal;
1006
+ private rejectFinal;
1007
+ private removeAbortListener;
1008
+ constructor(source: AbortableAsyncIterable<SseEvent>, signal?: AbortSignal);
1009
+ get finalResult(): Promise<OpenAIResponsesResponse>;
1010
+ abort(): void;
1011
+ [Symbol.asyncIterator](): AsyncGenerator<OpenAIResponsesStreamEvent, void, undefined>;
731
1012
  }
732
1013
  declare class OpenAICompatClient {
733
1014
  private readonly http;
734
- constructor(http: HttpClient);
735
- createChatCompletion(request: OpenAIChatCompletionRequest, signal?: AbortSignal): Promise<OpenAIChatCompletionResponse>;
736
- chatCompletions(request: OpenAIChatCompletionRequest, signal?: AbortSignal): Promise<OpenAIChatCompletionResponse>;
1015
+ private readonly runner?;
1016
+ constructor(http: HttpClient, runner?: RequestRunner | undefined);
1017
+ private request;
1018
+ createChatCompletion(request: OpenAIChatCompletionRequest & {
1019
+ stream: true;
1020
+ }, signal?: AbortSignal): Promise<OpenAIChatCompletionStream>;
1021
+ createChatCompletion(request: OpenAIChatCompletionRequest & {
1022
+ stream?: false | undefined;
1023
+ }, signal?: AbortSignal): Promise<OpenAIChatCompletionResponse>;
1024
+ chatCompletions(request: OpenAIChatCompletionRequest & {
1025
+ stream: true;
1026
+ }, signal?: AbortSignal): Promise<OpenAIChatCompletionStream>;
1027
+ chatCompletions(request: OpenAIChatCompletionRequest & {
1028
+ stream?: false | undefined;
1029
+ }, signal?: AbortSignal): Promise<OpenAIChatCompletionResponse>;
737
1030
  listModels(signal?: AbortSignal): Promise<OpenAIListModelsResponse>;
738
- createResponses(request: OpenAIResponsesRequest, signal?: AbortSignal): Promise<OpenAIResponsesResponse>;
739
- responses(request: OpenAIResponsesRequest, signal?: AbortSignal): Promise<OpenAIResponsesResponse>;
1031
+ retrieveModel(model: string, signal?: AbortSignal): Promise<OpenAIModelItem>;
1032
+ getModel(model: string, signal?: AbortSignal): Promise<OpenAIModelItem>;
1033
+ createCompletion(request: OpenAICompletionRequest & {
1034
+ stream: true;
1035
+ }, signal?: AbortSignal): Promise<OpenAICompletionStream>;
1036
+ createCompletion(request: OpenAICompletionRequest & {
1037
+ stream?: false | undefined;
1038
+ }, signal?: AbortSignal): Promise<OpenAICompletionResponse>;
1039
+ completions(request: OpenAICompletionRequest & {
1040
+ stream: true;
1041
+ }, signal?: AbortSignal): Promise<OpenAICompletionStream>;
1042
+ completions(request: OpenAICompletionRequest & {
1043
+ stream?: false | undefined;
1044
+ }, signal?: AbortSignal): Promise<OpenAICompletionResponse>;
1045
+ createEmbedding(request: OpenAIEmbeddingRequest, signal?: AbortSignal): Promise<OpenAIEmbeddingResponse>;
1046
+ embeddings(request: OpenAIEmbeddingRequest, signal?: AbortSignal): Promise<OpenAIEmbeddingResponse>;
1047
+ createResponses(request: OpenAIResponsesRequest & {
1048
+ stream: true;
1049
+ }, signal?: AbortSignal): Promise<OpenAIResponsesStream>;
1050
+ createResponses(request: OpenAIResponsesRequest & {
1051
+ stream?: false | undefined;
1052
+ }, signal?: AbortSignal): Promise<OpenAIResponsesResponse>;
1053
+ responses(request: OpenAIResponsesRequest & {
1054
+ stream: true;
1055
+ }, signal?: AbortSignal): Promise<OpenAIResponsesStream>;
1056
+ responses(request: OpenAIResponsesRequest & {
1057
+ stream?: false | undefined;
1058
+ }, signal?: AbortSignal): Promise<OpenAIResponsesResponse>;
740
1059
  }
741
1060
 
742
1061
  /**
743
1062
  * Anthropic Compatibility interfaces and client helpers for Ollama.
744
- * Ollama supports Anthropic Messages API format.
745
- *
746
- * @remarks
747
- * This is a typed pass-through to Ollama's Anthropic-compatible `/v1/messages` endpoint
748
- * — a subset of Anthropic's Messages API (text content, system prompt, sampling
749
- * parameters, ephemeral prompt-caching hints via `cache_control`), not the full Anthropic
750
- * surface. Tool use (`tool_use`/`tool_result` content blocks), extended thinking,
751
- * citations, files, token counting, and the Batches API are not modeled here.
1063
+ * Ollama supports the Anthropic Messages API format.
752
1064
  */
753
1065
 
754
1066
  interface AnthropicCacheControl {
755
1067
  readonly type: 'ephemeral';
1068
+ readonly ttl?: '5m' | '1h' | undefined;
756
1069
  }
757
- interface AnthropicContentBlock {
1070
+ interface AnthropicTextContentBlock {
758
1071
  readonly type: 'text';
759
1072
  readonly text: string;
760
- /** Marks this block as a prompt-caching breakpoint (Anthropic's ephemeral cache). */
761
1073
  readonly cache_control?: AnthropicCacheControl | undefined;
762
1074
  }
1075
+ interface AnthropicImageContentBlock {
1076
+ readonly type: 'image';
1077
+ readonly source: {
1078
+ readonly type: 'base64';
1079
+ readonly media_type: string;
1080
+ readonly data: string;
1081
+ };
1082
+ }
1083
+ interface AnthropicToolUseContentBlock {
1084
+ readonly type: 'tool_use';
1085
+ readonly id: string;
1086
+ readonly name: string;
1087
+ readonly input: Record<string, unknown>;
1088
+ }
1089
+ interface AnthropicToolResultContentBlock {
1090
+ readonly type: 'tool_result';
1091
+ readonly tool_use_id: string;
1092
+ readonly content?: string | readonly AnthropicTextContentBlock[] | undefined;
1093
+ readonly is_error?: boolean | undefined;
1094
+ }
1095
+ interface AnthropicThinkingContentBlock {
1096
+ readonly type: 'thinking';
1097
+ readonly thinking: string;
1098
+ readonly signature?: string | undefined;
1099
+ }
1100
+ interface AnthropicRedactedThinkingContentBlock {
1101
+ readonly type: 'redacted_thinking';
1102
+ readonly data: string;
1103
+ }
1104
+ type AnthropicContentBlock = AnthropicTextContentBlock | AnthropicImageContentBlock | AnthropicToolUseContentBlock | AnthropicToolResultContentBlock | AnthropicThinkingContentBlock | AnthropicRedactedThinkingContentBlock;
763
1105
  interface AnthropicMessage {
764
1106
  readonly role: 'user' | 'assistant';
765
1107
  readonly content: string | readonly AnthropicContentBlock[];
766
1108
  }
1109
+ interface AnthropicSystemTextBlock {
1110
+ readonly type: 'text';
1111
+ readonly text: string;
1112
+ readonly cache_control?: AnthropicCacheControl | undefined;
1113
+ }
1114
+ type AnthropicSystem = string | readonly AnthropicSystemTextBlock[];
1115
+ interface AnthropicTool {
1116
+ readonly name: string;
1117
+ readonly description?: string | undefined;
1118
+ readonly input_schema: Record<string, unknown>;
1119
+ readonly eager_input_streaming?: boolean | undefined;
1120
+ }
1121
+ type AnthropicToolChoice = {
1122
+ readonly type: 'auto';
1123
+ readonly disable_parallel_tool_use?: boolean | undefined;
1124
+ } | {
1125
+ readonly type: 'any';
1126
+ readonly disable_parallel_tool_use?: boolean | undefined;
1127
+ } | {
1128
+ readonly type: 'tool';
1129
+ readonly name: string;
1130
+ readonly disable_parallel_tool_use?: boolean | undefined;
1131
+ } | {
1132
+ readonly type: 'none';
1133
+ };
1134
+ interface AnthropicThinkingConfig {
1135
+ readonly type: 'enabled' | 'disabled' | 'adaptive';
1136
+ readonly display?: 'omitted' | 'summarized' | 'updates' | undefined;
1137
+ /** Accepted by Ollama for compatibility but currently not enforced by the server. */
1138
+ readonly budget_tokens?: number | undefined;
1139
+ }
1140
+ interface AnthropicOutputConfig {
1141
+ readonly effort?: string | undefined;
1142
+ }
1143
+ interface AnthropicMetadata {
1144
+ readonly user_id?: string | undefined;
1145
+ }
767
1146
  interface AnthropicMessagesRequest {
768
1147
  readonly model: string;
769
1148
  readonly messages: readonly AnthropicMessage[];
770
- readonly system?: string | undefined;
1149
+ readonly system?: AnthropicSystem | undefined;
771
1150
  readonly max_tokens?: number | undefined;
772
1151
  readonly temperature?: number | undefined;
773
1152
  readonly top_p?: number | undefined;
774
1153
  readonly top_k?: number | undefined;
1154
+ readonly stop_sequences?: readonly string[] | undefined;
775
1155
  readonly stream?: boolean | undefined;
776
- }
1156
+ readonly tools?: readonly AnthropicTool[] | undefined;
1157
+ readonly thinking?: AnthropicThinkingConfig | undefined;
1158
+ readonly output_config?: AnthropicOutputConfig | undefined;
1159
+ /**
1160
+ * Accepted for Anthropic compatibility but currently ignored by Ollama.
1161
+ * Tool selection cannot be forced through the Ollama compatibility endpoint.
1162
+ */
1163
+ readonly tool_choice?: AnthropicToolChoice | undefined;
1164
+ /** Accepted for compatibility but currently ignored by Ollama. */
1165
+ readonly metadata?: AnthropicMetadata | undefined;
1166
+ }
1167
+ /** Strict Ollama-documented Messages request; excludes fields Ollama marks unsupported. */
1168
+ type OllamaAnthropicTextContentBlock = Omit<AnthropicTextContentBlock, 'cache_control'>;
1169
+ type OllamaAnthropicTool = Omit<AnthropicTool, 'eager_input_streaming'>;
1170
+ type OllamaAnthropicThinkingConfig = {
1171
+ readonly type: 'enabled' | 'disabled';
1172
+ /** Accepted by Ollama for compatibility but currently not enforced by the server. */
1173
+ readonly budget_tokens?: number | undefined;
1174
+ };
1175
+ type OllamaAnthropicToolResultContentBlock = Omit<AnthropicToolResultContentBlock, 'content'> & {
1176
+ readonly content?: string | readonly OllamaAnthropicTextContentBlock[] | undefined;
1177
+ };
1178
+ type OllamaAnthropicContentBlock = OllamaAnthropicTextContentBlock | AnthropicImageContentBlock | AnthropicToolUseContentBlock | OllamaAnthropicToolResultContentBlock | AnthropicThinkingContentBlock;
1179
+ type OllamaAnthropicMessage = Omit<AnthropicMessage, 'content'> & {
1180
+ readonly content: string | readonly OllamaAnthropicContentBlock[];
1181
+ };
1182
+ type OllamaAnthropicSystemTextBlock = Omit<AnthropicSystemTextBlock, 'cache_control'>;
1183
+ type OllamaAnthropicSystem = string | readonly OllamaAnthropicSystemTextBlock[];
1184
+ /** Strict Ollama-documented Messages request; excludes unsupported caching/tool-choice metadata. */
1185
+ type OllamaAnthropicMessagesRequest = Omit<AnthropicMessagesRequest, 'messages' | 'system' | 'tools' | 'thinking' | 'tool_choice' | 'metadata'> & {
1186
+ readonly messages: readonly OllamaAnthropicMessage[];
1187
+ readonly system?: OllamaAnthropicSystem | undefined;
1188
+ readonly tools?: readonly OllamaAnthropicTool[] | undefined;
1189
+ readonly thinking?: OllamaAnthropicThinkingConfig | undefined;
1190
+ };
777
1191
  interface AnthropicMessagesResponse {
778
1192
  readonly id: string;
779
1193
  readonly type: 'message';
780
1194
  readonly role: 'assistant';
781
1195
  readonly content: readonly AnthropicContentBlock[];
782
1196
  readonly model: string;
783
- readonly stop_reason: string;
1197
+ readonly stop_reason: string | null;
1198
+ readonly stop_sequence?: string | null | undefined;
784
1199
  readonly usage?: {
785
1200
  readonly input_tokens: number;
786
1201
  readonly output_tokens: number;
1202
+ readonly cache_creation_input_tokens?: number | undefined;
1203
+ readonly cache_read_input_tokens?: number | undefined;
1204
+ readonly cache_creation?: Record<string, unknown> | undefined;
1205
+ } | undefined;
1206
+ }
1207
+ interface AnthropicMessageStartEvent {
1208
+ readonly type: 'message_start';
1209
+ readonly message: AnthropicMessagesResponse;
1210
+ }
1211
+ interface AnthropicContentBlockStartEvent {
1212
+ readonly type: 'content_block_start';
1213
+ readonly index: number;
1214
+ readonly content_block: AnthropicContentBlock;
1215
+ }
1216
+ type AnthropicContentBlockDelta = {
1217
+ readonly type: 'text_delta';
1218
+ readonly text: string;
1219
+ } | {
1220
+ readonly type: 'input_json_delta';
1221
+ readonly partial_json: string;
1222
+ } | {
1223
+ readonly type: 'thinking_delta';
1224
+ readonly thinking: string;
1225
+ } | {
1226
+ readonly type: 'signature_delta';
1227
+ readonly signature: string;
1228
+ };
1229
+ interface AnthropicContentBlockDeltaEvent {
1230
+ readonly type: 'content_block_delta';
1231
+ readonly index: number;
1232
+ readonly delta: AnthropicContentBlockDelta;
1233
+ }
1234
+ interface AnthropicContentBlockStopEvent {
1235
+ readonly type: 'content_block_stop';
1236
+ readonly index: number;
1237
+ }
1238
+ interface AnthropicMessageDeltaEvent {
1239
+ readonly type: 'message_delta';
1240
+ readonly delta: {
1241
+ readonly stop_reason?: string | null | undefined;
1242
+ readonly stop_sequence?: string | null | undefined;
1243
+ };
1244
+ readonly usage?: {
1245
+ readonly input_tokens?: number | undefined;
1246
+ readonly output_tokens: number;
1247
+ readonly cache_creation_input_tokens?: number | undefined;
1248
+ readonly cache_read_input_tokens?: number | undefined;
1249
+ readonly cache_creation?: Record<string, unknown> | undefined;
787
1250
  } | undefined;
788
1251
  }
1252
+ interface AnthropicMessageStopEvent {
1253
+ readonly type: 'message_stop';
1254
+ }
1255
+ interface AnthropicPingEvent {
1256
+ readonly type: 'ping';
1257
+ }
1258
+ interface AnthropicErrorEvent {
1259
+ readonly type: 'error';
1260
+ readonly error: {
1261
+ readonly type: string;
1262
+ readonly message: string;
1263
+ };
1264
+ }
1265
+ interface AnthropicUnknownStreamEvent {
1266
+ /** Forward-compatible event type not yet modeled by this SDK. */
1267
+ readonly type: string;
1268
+ readonly [key: string]: unknown;
1269
+ }
1270
+ type AnthropicMessageStreamEvent = AnthropicMessageStartEvent | AnthropicContentBlockStartEvent | AnthropicContentBlockDeltaEvent | AnthropicContentBlockStopEvent | AnthropicMessageDeltaEvent | AnthropicMessageStopEvent | AnthropicPingEvent | AnthropicErrorEvent | AnthropicUnknownStreamEvent;
1271
+ declare class AnthropicMessagesStream implements AsyncIterable<AnthropicMessageStreamEvent> {
1272
+ private readonly source;
1273
+ private readonly finalResultPromise;
1274
+ private resolveFinal;
1275
+ private rejectFinal;
1276
+ private removeAbortListener;
1277
+ constructor(source: AbortableAsyncIterable<SseEvent>, signal?: AbortSignal);
1278
+ get finalResult(): Promise<AnthropicMessagesResponse>;
1279
+ abort(): void;
1280
+ [Symbol.asyncIterator](): AsyncGenerator<AnthropicMessageStreamEvent, void, undefined>;
1281
+ }
789
1282
  declare class AnthropicCompatClient {
790
1283
  private readonly http;
791
- constructor(http: HttpClient);
792
- createMessage(request: AnthropicMessagesRequest, signal?: AbortSignal): Promise<AnthropicMessagesResponse>;
793
- messages(request: AnthropicMessagesRequest, signal?: AbortSignal): Promise<AnthropicMessagesResponse>;
1284
+ private readonly runner?;
1285
+ constructor(http: HttpClient, runner?: RequestRunner | undefined);
1286
+ private request;
1287
+ createMessage(request: AnthropicMessagesRequest & {
1288
+ stream: true;
1289
+ }, signal?: AbortSignal): Promise<AnthropicMessagesStream>;
1290
+ createMessage(request: AnthropicMessagesRequest & {
1291
+ stream?: false | undefined;
1292
+ }, signal?: AbortSignal): Promise<AnthropicMessagesResponse>;
1293
+ createMessage(request: AnthropicMessagesRequest, signal?: AbortSignal): Promise<AnthropicMessagesResponse | AnthropicMessagesStream>;
1294
+ messages(request: AnthropicMessagesRequest & {
1295
+ stream: true;
1296
+ }, signal?: AbortSignal): Promise<AnthropicMessagesStream>;
1297
+ messages(request: AnthropicMessagesRequest & {
1298
+ stream?: false | undefined;
1299
+ }, signal?: AbortSignal): Promise<AnthropicMessagesResponse>;
1300
+ messages(request: AnthropicMessagesRequest, signal?: AbortSignal): Promise<AnthropicMessagesResponse | AnthropicMessagesStream>;
794
1301
  }
795
1302
 
1303
+ /**
1304
+ * High-level Ollama client — the original, hand-written API surface.
1305
+ *
1306
+ * **Wave 8 (ADR 0018) deprecation notice:**
1307
+ *
1308
+ * For new code, prefer the generated `NativeApi` from
1309
+ * {@link ./generated/runtime/runtime.js} + {@link ./generated/api/native-api.js}
1310
+ * instead. The generated surface:
1311
+ *
1312
+ * - Inherits every contract-layer guarantee (environment guards, version
1313
+ * guards, streaming defaults) automatically from the canonical IR.
1314
+ * - Stays in sync with the OpenAPI spec by construction — no hand-written
1315
+ * surface to drift.
1316
+ * - Uses the same `HttpClient` (and therefore the same middleware,
1317
+ * retry, telemetry, and streaming pipeline) as this client.
1318
+ *
1319
+ * The migration path is non-breaking:
1320
+ *
1321
+ * ```ts
1322
+ * // Before (still works, no breaking changes):
1323
+ * const client = new OllamaClient({ baseUrl: 'http://localhost:11434' });
1324
+ * const res = await client.chat({ model, messages });
1325
+ *
1326
+ * // After (recommended for new code):
1327
+ * const http = new HttpClient({ baseUrl: 'http://localhost:11434' });
1328
+ * const runtime = new OllamaRuntime({ http });
1329
+ * const api = new NativeApi(runtime);
1330
+ * const res = await api.chat({ model, messages, stream: false });
1331
+ * ```
1332
+ *
1333
+ * `OllamaClient` is preserved verbatim — existing callers do not need to
1334
+ * change anything. New methods and operations will land on the generated
1335
+ * surface first; `OllamaClient` will receive them only as a follow-up.
1336
+ */
796
1337
  declare class OllamaClient {
797
1338
  readonly registry: EndpointRegistry;
798
1339
  readonly models: ModelsClient;
@@ -801,8 +1342,43 @@ declare class OllamaClient {
801
1342
  private readonly failoverCodes;
802
1343
  private readonly fetchImpl;
803
1344
  private readonly logger;
1345
+ private readonly middleware;
1346
+ private readonly onLifecycleEvent;
1347
+ /**
1348
+ * API key for Ollama's hosted web tools (`webSearch`/`webFetch`), which always target
1349
+ * `OLLAMA_CLOUD_BASE_URL` regardless of `config.endpoints` — an Ollama account API key
1350
+ * is inherently a single global credential, not tied to any one inference endpoint.
1351
+ * Resolved the same way as a single-endpoint `apiKey` (`config.apiKey` falling back to
1352
+ * `OLLAMA_API_KEY`), independent of whether `config.endpoints` was used instead.
1353
+ */
1354
+ private readonly cloudApiKey;
804
1355
  constructor(config?: OllamaClientConfig);
805
1356
  get modelsClient(): ModelsClient;
1357
+ /**
1358
+ * Return a generated {@link OllamaRuntime} that shares this client's
1359
+ * transport (HttpClient + middleware + retry + telemetry).
1360
+ *
1361
+ * Wave 8 (ADR 0018) bridge: lets callers mix the existing `OllamaClient`
1362
+ * API with the generated `NativeApi` / `OpenAIApi` / `AnthropicApi`
1363
+ * surface without configuring two separate HttpClient instances.
1364
+ *
1365
+ * The returned runtime is bound to the registry's first candidate
1366
+ * endpoint (or the resolved single-endpoint config if no `endpoints`
1367
+ * array was provided). For multi-endpoint configs that need per-call
1368
+ * routing, prefer constructing `OllamaRuntime` directly with a
1369
+ * specific HttpClient:
1370
+ *
1371
+ * ```ts
1372
+ * const http = new HttpClient({ baseUrl: 'http://host-a:11434' });
1373
+ * const runtime = new OllamaRuntime({ http });
1374
+ * const api = new NativeApi(runtime);
1375
+ * ```
1376
+ *
1377
+ * The runtime is cached on first call — subsequent calls return the
1378
+ * same instance.
1379
+ */
1380
+ get runtime(): OllamaRuntime;
1381
+ private _runtime;
806
1382
  /**
807
1383
  * Fail-fast guard for `format` (structured output) requests: throws before any network
808
1384
  * call if the candidate endpoint is inferred as Ollama Cloud, which does not currently
@@ -823,6 +1399,25 @@ declare class OllamaClient {
823
1399
  * ADR 0008. Defaults to `false`, preserving normal failover for inference calls.
824
1400
  */
825
1401
  singleEndpoint?: boolean | undefined;
1402
+ /**
1403
+ * The model this request targets, used to filter candidates by
1404
+ * `OllamaEndpoint.models` (credential-scoped routing — see that field's docs).
1405
+ * Requests without a `model` (e.g. `listModels`) consider every configured
1406
+ * endpoint, same as before this option existed.
1407
+ */
1408
+ model?: string | undefined;
1409
+ /**
1410
+ * For an operation whose real completion outlasts its own returned promise — a
1411
+ * streaming response, specifically — defers releasing the endpoint's concurrency
1412
+ * slot (see `EndpointRegistryOptions.maxConcurrentPerEndpoint`/`'least-connections'`)
1413
+ * until the promise this returns settles, instead of releasing as soon as
1414
+ * `operation` resolves. Pass `(stream) => stream.finalResult` for `chatStream`/
1415
+ * `generateStream` so the slot stays held for as long as the underlying HTTP
1416
+ * connection realistically does — until the stream is fully consumed, errors, or is
1417
+ * aborted. Omit for anything whose returned promise already represents the whole
1418
+ * request/response (the default, and correct for every non-streaming call).
1419
+ */
1420
+ holdUntil?: ((result: T) => Promise<unknown>) | undefined;
826
1421
  }): Promise<T>;
827
1422
  chat(req: ChatRequestOptions & {
828
1423
  stream: true;
@@ -863,9 +1458,28 @@ declare class OllamaClient {
863
1458
  readonly version: () => Promise<VersionResponse>;
864
1459
  readonly createBlob: (digest: string, data: BinaryBody) => Promise<void>;
865
1460
  readonly checkBlob: (digest: string) => Promise<boolean>;
1461
+ /**
1462
+ * Ollama's hosted web search tool (`POST https://ollama.com/api/web_search`) — a fixed
1463
+ * Ollama Cloud service, unrelated to `config.endpoints`/`baseUrl` and not proxied
1464
+ * through a local server. Requires an Ollama account API key: pass `apiKey` to the
1465
+ * client constructor or set `OLLAMA_API_KEY`. Applies the same default `timeoutMs` and
1466
+ * retry policy as inference calls, but never cross-endpoint-fails-over — there is only
1467
+ * ever the one cloud endpoint to call.
1468
+ */
866
1469
  webSearch(req: WebSearchRequestOptions): Promise<WebSearchResponse>;
1470
+ /**
1471
+ * Ollama's hosted web fetch tool (`POST https://ollama.com/api/web_fetch`) — see
1472
+ * {@link OllamaClient.webSearch} for the cloud-endpoint/auth/timeout/retry behavior,
1473
+ * which applies identically here.
1474
+ */
867
1475
  webFetch(req: WebFetchRequestOptions): Promise<WebFetchResponse>;
868
- capabilities(model: string): Promise<ModelCapabilities>;
1476
+ /**
1477
+ * Runs `operation` against the fixed Ollama Cloud host with this client's default
1478
+ * timeout and retry policy — the same primitives `executeWithFailover` uses, minus the
1479
+ * multi-candidate loop, since `webSearch`/`webFetch` only ever have the one endpoint.
1480
+ */
1481
+ private executeCloudRequest;
1482
+ capabilities(model: string, signal?: AbortSignal): Promise<ModelCapabilities>;
869
1483
  runtimeMode(): RuntimeMode;
870
1484
  healthCheck(): Promise<EndpointHealthCheckResult[]>;
871
1485
  endpointStatus(): EndpointHealth[];
@@ -889,9 +1503,9 @@ declare function createTimeoutSignal(timeoutMs?: number, userSignal?: AbortSigna
889
1503
  * Normalization mappers and aggregators for Ollama streaming responses.
890
1504
  */
891
1505
 
892
- declare function normalizeChatStream(source: AbortableAsyncIterable<ChatResponse>): OllamaStream<ChatResponse, ChatStreamResult>;
893
- declare function normalizeGenerateStream(source: AbortableAsyncIterable<GenerateResponse>): OllamaStream<GenerateResponse, GenerateStreamResult>;
894
- declare function normalizeProgressStream(source: AbortableAsyncIterable<ProgressResponse>): OllamaStream<ProgressResponse, ProgressStreamResult>;
1506
+ declare function normalizeChatStream(source: AbortableAsyncIterable<ChatResponse>, signal?: AbortSignal): OllamaStream<ChatResponse, ChatStreamResult>;
1507
+ declare function normalizeGenerateStream(source: AbortableAsyncIterable<GenerateResponse>, signal?: AbortSignal): OllamaStream<GenerateResponse, GenerateStreamResult>;
1508
+ declare function normalizeProgressStream(source: AbortableAsyncIterable<ProgressResponse>, signal?: AbortSignal): OllamaStream<ProgressResponse, ProgressStreamResult>;
895
1509
 
896
1510
  /**
897
1511
  * NDJSON (newline-delimited JSON) stream reader for native fetch Response bodies.
@@ -919,6 +1533,89 @@ declare function toDataStream<TChunk, TFinal>(stream: OllamaStream<TChunk, TFina
919
1533
  */
920
1534
  declare function toResponse<TChunk, TFinal>(stream: OllamaStream<TChunk, TFinal>, init?: ResponseInit): Response;
921
1535
 
1536
+ /**
1537
+ * Client-side usage budgeting.
1538
+ *
1539
+ * Ollama Cloud does not expose account-level quota or remaining-budget through the API —
1540
+ * chat/generate responses carry only per-request token counts, and there is no header or
1541
+ * endpoint that reports how much of your plan's session or weekly limit is left (the only
1542
+ * way to see that today is the https://ollama.com dashboard or the 90%-usage email). See
1543
+ * https://github.com/ollama/ollama/issues/15663.
1544
+ *
1545
+ * `QuotaManager` does not — and cannot — read Ollama's real limits. It tracks usage you
1546
+ * record against budgets *you* configure over one or more rolling windows, and refuses to
1547
+ * proceed once a window's budget is spent. Pair it with `OllamaRateLimitError` (thrown by
1548
+ * `OllamaClient` on the server's actual 429) as the authoritative signal; treat
1549
+ * `QuotaManager` as a local safety net that fails fast before the request is even sent.
1550
+ */
1551
+
1552
+ interface QuotaWindowConfig {
1553
+ /** Identifies this window in status reports and thrown errors (e.g. "session", "weekly"). */
1554
+ readonly id: string;
1555
+ /** Length of the rolling window in milliseconds, after which usage resets to zero. */
1556
+ readonly windowMs: number;
1557
+ /** Token budget for the window. Omit to only track requests. */
1558
+ readonly maxTokens?: number;
1559
+ /** Request-count budget for the window. Omit to only track tokens. */
1560
+ readonly maxRequests?: number;
1561
+ }
1562
+ interface QuotaWindowStatus extends QuotaWindowConfig {
1563
+ readonly tokensUsed: number;
1564
+ readonly requestsMade: number;
1565
+ readonly windowStartedAt: number;
1566
+ readonly windowResetAt: number;
1567
+ readonly remainingTokens?: number;
1568
+ readonly remainingRequests?: number;
1569
+ }
1570
+ interface QuotaManagerOptions {
1571
+ readonly windows: readonly QuotaWindowConfig[];
1572
+ /** Clock override for testing. Defaults to `Date.now`. */
1573
+ readonly now?: () => number;
1574
+ }
1575
+ declare class QuotaManager {
1576
+ private readonly now;
1577
+ private readonly windows;
1578
+ constructor(options: QuotaManagerOptions);
1579
+ private rollover;
1580
+ /** Current usage, budgets, and reset time for every configured window. */
1581
+ status(): readonly QuotaWindowStatus[];
1582
+ /**
1583
+ * True if one more request — optionally estimated at `estimatedTokens` — would stay
1584
+ * within every configured window's budget. Read-only; does not record usage.
1585
+ */
1586
+ canProceed(estimatedTokens?: number): boolean;
1587
+ /**
1588
+ * Throws `OllamaQuotaExceededError` for the first window that `canProceed(estimatedTokens)`
1589
+ * would fail on; otherwise a no-op. Call before issuing a request.
1590
+ */
1591
+ assertCanProceed(estimatedTokens?: number): void;
1592
+ /** Records one request's actual usage — a raw API response or a pre-normalized `TokenUsage` — against every window. */
1593
+ recordUsage(usage: RawUsageSource | TokenUsage): void;
1594
+ /** Resets one window (by `id`) or, if omitted, all windows — zeroing usage and restarting their clocks. */
1595
+ reset(windowId?: string): void;
1596
+ }
1597
+ interface OllamaCloudFreeTierQuotaBudgets {
1598
+ /** Budget for the free tier's ~5-hour session window. Omit to skip tracking it. */
1599
+ readonly session?: {
1600
+ readonly maxTokens?: number;
1601
+ readonly maxRequests?: number;
1602
+ };
1603
+ /** Budget for the free tier's 7-day weekly window. Omit to skip tracking it. */
1604
+ readonly weekly?: {
1605
+ readonly maxTokens?: number;
1606
+ readonly maxRequests?: number;
1607
+ };
1608
+ readonly now?: () => number;
1609
+ }
1610
+ /**
1611
+ * Convenience factory mirroring Ollama Cloud free-tier's documented reset cadence — a
1612
+ * session window that resets every 5 hours and a weekly window that resets every 7 days
1613
+ * (see https://ollama.com/pricing). Ollama does not publish the actual token/request
1614
+ * ceilings for either window, so you must supply the budgets yourself (e.g. from your own
1615
+ * observed usage) — this only wires up the window durations.
1616
+ */
1617
+ declare function createOllamaCloudFreeTierQuota(budgets: OllamaCloudFreeTierQuotaBudgets): QuotaManager;
1618
+
922
1619
  /**
923
1620
  * Zod schema conversion to JSON Schema for Ollama structured outputs.
924
1621
  */
@@ -956,44 +1653,36 @@ interface DefineToolOptions<TParams, TResult> {
956
1653
  */
957
1654
  declare function defineTool<TParams, TResult>(options: DefineToolOptions<TParams, TResult>): Tool<TParams, TResult>;
958
1655
 
959
- /**
960
- * Duck-typed MCP (Model Context Protocol) client interfaces.
961
- * Decoupled from any specific MCP SDK.
962
- */
963
- interface McpToolDescriptor {
964
- readonly name: string;
965
- readonly description?: string;
966
- readonly inputSchema?: Record<string, unknown>;
967
- }
968
- interface McpListToolsResult {
969
- readonly tools: readonly McpToolDescriptor[];
970
- }
971
- interface McpContentBlock {
972
- readonly type: string;
973
- readonly text?: string;
974
- readonly [key: string]: unknown;
975
- }
976
- interface McpCallToolResult {
977
- readonly content: readonly McpContentBlock[];
978
- readonly isError?: boolean;
979
- }
980
- interface McpClientLike {
981
- listTools: () => Promise<McpListToolsResult>;
982
- callTool: (params: {
983
- readonly name: string;
984
- readonly arguments?: Record<string, unknown>;
985
- }) => Promise<McpCallToolResult>;
986
- }
987
-
988
1656
  /**
989
1657
  * Converts MCP tools into Ollama-compatible tools.
990
1658
  */
991
1659
 
1660
+ type McpToolResultMode = 'text' | 'structured';
992
1661
  interface LoadMcpToolsOptions {
993
- readonly namePrefix?: string;
1662
+ readonly namePrefix?: string | undefined;
1663
+ /** Maximum number of paginated tools/list responses to traverse. */
1664
+ readonly maxPages?: number | undefined;
1665
+ /**
1666
+ * Return MCP's raw CallToolResult to programmatic callers instead of the legacy
1667
+ * model-oriented text representation. The default preserves existing behavior.
1668
+ */
1669
+ readonly resultMode?: McpToolResultMode | undefined;
1670
+ }
1671
+ declare function listAllMcpTools(mcpClient: McpClientLike, options?: LoadMcpToolsOptions, signal?: AbortSignal): Promise<McpToolDescriptor[]>;
1672
+ declare function loadMcpTools(mcpClient: McpClientLike, options?: LoadMcpToolsOptions, signal?: AbortSignal): Promise<AnyTool[]>;
1673
+ declare function registerMcpTools(registry: ToolRegistry, mcpClient: McpClientLike, options?: LoadMcpToolsOptions, signal?: AbortSignal): Promise<void>;
1674
+
1675
+ type McpBridgeOptions = LoadMcpToolsOptions;
1676
+ declare class McpBridge {
1677
+ private readonly client;
1678
+ private readonly options;
1679
+ constructor(client: McpClientLike, options?: McpBridgeOptions);
1680
+ static toOllamaTools(tools: readonly McpToolDescriptor[], options?: McpBridgeOptions): ToolDefinition[];
1681
+ listTools(signal?: AbortSignal): Promise<readonly McpToolDescriptor[]>;
1682
+ definitions(signal?: AbortSignal): Promise<ToolDefinition[]>;
1683
+ loadTools(signal?: AbortSignal): Promise<AnyTool[]>;
1684
+ register(registry: ToolRegistry, signal?: AbortSignal): Promise<void>;
994
1685
  }
995
- declare function loadMcpTools(mcpClient: McpClientLike, options?: LoadMcpToolsOptions): Promise<AnyTool[]>;
996
- declare function registerMcpTools(registry: ToolRegistry, mcpClient: McpClientLike, options?: LoadMcpToolsOptions): Promise<void>;
997
1686
 
998
1687
  /**
999
1688
  * Agent loop options, turn state, and execution hooks.
@@ -1021,13 +1710,22 @@ interface AgentHooks {
1021
1710
  interface AgentConfig {
1022
1711
  readonly tools?: ToolRegistry | undefined;
1023
1712
  readonly maxIterations?: number | undefined;
1713
+ /** Maximum total tool calls allowed during one agent run. */
1714
+ readonly maxToolCalls?: number | undefined;
1024
1715
  readonly hooks?: AgentHooks | undefined;
1716
+ /** Validate tool support from /api/show before starting a tool-enabled run. Default: true. */
1717
+ readonly validateToolCapability?: boolean | undefined;
1718
+ /**
1719
+ * Automatic context size for tool-enabled runs when options.num_ctx is not supplied.
1720
+ * Defaults to 32768 and is clamped to the model-reported maximum when available.
1721
+ */
1722
+ readonly toolContextSize?: number | undefined;
1025
1723
  }
1026
1724
  interface AgentRunInput {
1027
1725
  readonly model: string;
1028
1726
  readonly messages: readonly Message[];
1029
1727
  readonly options?: ModelOptions | undefined;
1030
- readonly think?: boolean | 'low' | 'medium' | 'high' | 'max' | undefined;
1728
+ readonly think?: ThinkValue | undefined;
1031
1729
  readonly signal?: AbortSignal | undefined;
1032
1730
  }
1033
1731
 
@@ -1036,12 +1734,13 @@ interface AgentRunInput {
1036
1734
  */
1037
1735
 
1038
1736
  interface AgentChatClient {
1737
+ capabilities?: ((model: string, signal?: AbortSignal) => Promise<ModelCapabilities>) | undefined;
1039
1738
  chat(request: {
1040
1739
  readonly model: string;
1041
1740
  readonly messages: readonly Message[];
1042
1741
  readonly tools?: readonly ToolDefinition[] | undefined;
1043
1742
  readonly options?: ModelOptions | undefined;
1044
- readonly think?: boolean | 'low' | 'medium' | 'high' | 'max' | undefined;
1743
+ readonly think?: ThinkValue | undefined;
1045
1744
  readonly stream?: false | undefined;
1046
1745
  readonly signal?: AbortSignal | undefined;
1047
1746
  }): Promise<{
@@ -1052,9 +1751,9 @@ interface AgentChatClient {
1052
1751
  * Runs a multi-turn `chat` + tool-execution loop until the model responds without
1053
1752
  * requesting further tool calls, or `maxIterations` is exceeded. Tool calls within a
1054
1753
  * single turn are handed to `ToolRegistry.executeToolCalls` and their results are
1055
- * appended to history in the same order the model requested them, each tagged with the
1056
- * originating call's `tool_call_id` — see the {@link ToolCall} type docs for how that id
1057
- * is produced (Ollama's native tool-calling protocol has none; this SDK synthesizes one).
1754
+ * appended to history in the same order the model requested them. Native Ollama tool-result
1755
+ * messages use `tool_name` on the wire; the SDK-generated `toolCallId` remains execution
1756
+ * metadata and is not sent to Ollama.
1058
1757
  * `Agent` assigns ids defensively even when `AgentChatClient` isn't `OllamaClient` (e.g. a
1059
1758
  * custom/test implementation), so this guarantee holds regardless of which chat client is
1060
1759
  * supplied.
@@ -1063,7 +1762,10 @@ declare class Agent {
1063
1762
  private readonly client;
1064
1763
  private readonly tools?;
1065
1764
  private readonly maxIterations;
1765
+ private readonly maxToolCalls?;
1066
1766
  private readonly hooks?;
1767
+ private readonly validateToolCapability;
1768
+ private readonly toolContextSize;
1067
1769
  constructor(client: AgentChatClient, config?: AgentConfig);
1068
1770
  run(input: AgentRunInput): Promise<AgentResult>;
1069
1771
  private runLoop;
@@ -1138,4 +1840,4 @@ declare const GEN_AI_SYSTEM_OLLAMA = "ollama";
1138
1840
  */
1139
1841
  declare function encodeImage(image: Uint8Array | string): Promise<string>;
1140
1842
 
1141
- export { ATTR_GEN_AI_OPERATION_NAME, ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_SYSTEM, ATTR_GEN_AI_TOOL_CALL_ID, ATTR_GEN_AI_TOOL_NAME, ATTR_GEN_AI_USAGE_INPUT_TOKENS, ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_OLLAMA_AGENT_ITERATION, ATTR_OLLAMA_AGENT_MAX_ITERATIONS, ATTR_OLLAMA_ENDPOINT_ATTEMPT, ATTR_OLLAMA_ENDPOINT_NAME, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_URL_FULL, type AbortableAsyncIterable, Agent, type AgentChatClient, type AgentConfig, type AgentHooks, type AgentResult, type AgentRunInput, type AgentTurn, type AnthropicCacheControl, AnthropicCompatClient, type AnthropicContentBlock, type AnthropicMessage, type AnthropicMessagesRequest, type AnthropicMessagesResponse, AnyTool, type BackoffOptions, ChatRequestOptions, ChatResponse, type ChatStreamResult, CopyRequestOptions, CreateRequestOptions, DEFAULT_BACKOFF, DEFAULT_BASE_URL, DEFAULT_FAILOVER_CODES, DEFAULT_RETRY_CONFIG, DEFAULT_TIMEOUT_MS, type DefineToolOptions, DeleteRequestOptions, type DoneEvent, EmbedRequestOptions, EmbedResponse, EmbeddingsRequestOptions, EmbeddingsResponse, type EndpointHealth, type EndpointHealthCheckResult, EndpointRegistry, type EndpointRegistryOptions, type ErrorEvent, type FetchLike, GEN_AI_SYSTEM_OLLAMA, GenerateRequestOptions, GenerateResponse, type GenerateStreamResult, type HttpBody, HttpClient, type HttpClientOptions, type HttpRequestOptions, type LifecycleErrorEvent, type LifecycleRetryEvent, type LifecycleStartEvent, type LifecycleSuccessEvent, type LoadMcpToolsOptions, type LogFn, type Logger, type McpCallToolResult, type McpClientLike, type McpContentBlock, type McpListToolsResult, type McpToolDescriptor, Message, type MessageEvent, type Middleware, type MiddlewareContext, type ModelCapabilities, ModelOptions, ModelResponse, ModelsClient, NANOS_PER_MS, NANOS_PER_SECOND, NOOP_LOGGER, type NextFunction, OllamaAbortError, OllamaAgentMaxIterationsError, OllamaAuthError, OllamaClient, type OllamaClientConfig, OllamaClientError, type OllamaClientErrorOptions, type OllamaEndpoint, type OllamaErrorRequestContext, type OllamaErrorResponseContext, OllamaGenericClientError, OllamaMcpError, OllamaNetworkError, OllamaNotFoundError, OllamaRateLimitError, OllamaServerError, OllamaSkillInvalidError, OllamaSkillNotFoundError, OllamaStream, type OllamaStreamEvent, type OllamaStreamEventType, OllamaTimeoutError, OllamaToolTimeoutError, OllamaToolValidationError, OllamaUnsupportedCapabilityError, type OpenAIChatCompletionChoice, type OpenAIChatCompletionRequest, type OpenAIChatCompletionResponse, OpenAICompatClient, type OpenAIFunctionDefinition, type OpenAIListModelsResponse, type OpenAIMessage, type OpenAIModelItem, type OpenAIResponsesOutputMessage, type OpenAIResponsesOutputTextContent, type OpenAIResponsesRequest, type OpenAIResponsesResponse, type OpenAIStreamOptions, type OpenAITool, type OpenAIToolCall, ProgressResponse, type ProgressStreamResult, PsResponse, PullRequestOptions, PushRequestOptions, type RawUsageSource, type RequestContext, type RequestLifecycleEvent, type RequestLifecycleHook, type RequestRunner, type ResponseContext, type RetryConfig, type RuntimeMode, ShowRequestOptions, ShowResponse, type SpanAttributeValue, type SpanAttributes, StatusResponse, type SupportedSchema, type ThinkingEvent, type TimeoutSignal, type TokenEvent, type TokenUsage, Tool, ToolCall, type ToolCallEvent, ToolDefinition, ToolExecutionResult, ToolHandler, ToolRegistry, VersionResponse, WebFetchRequestOptions, WebFetchResponse, WebSearchRequestOptions, WebSearchResponse, addSpanEvent, calculateBackoff, checkEndpointHealth, composeMiddleware, createConsoleLogger, createTimeoutSignal, defineTool, detectModelCapabilities, encodeImage, extractUsage, inferRuntimeMode, listAvailableModels, loadMcpTools, mapError, normalizeChatStream, normalizeGenerateStream, normalizeProgressStream, parseNdjsonStream, parseStructuredOutput, registerMcpTools, setSpanError, toDataStream, toResponse, toTextStream, withRetry, withSpan, zodToJsonSchema };
1843
+ export { ATTR_GEN_AI_OPERATION_NAME, ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_SYSTEM, ATTR_GEN_AI_TOOL_CALL_ID, ATTR_GEN_AI_TOOL_NAME, ATTR_GEN_AI_USAGE_INPUT_TOKENS, ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_OLLAMA_AGENT_ITERATION, ATTR_OLLAMA_AGENT_MAX_ITERATIONS, ATTR_OLLAMA_ENDPOINT_ATTEMPT, ATTR_OLLAMA_ENDPOINT_NAME, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_URL_FULL, AbortableAsyncIterable, Agent, type AgentChatClient, type AgentConfig, type AgentHooks, type AgentResult, type AgentRunInput, type AgentTurn, type AnthropicCacheControl, AnthropicCompatClient, type AnthropicContentBlock, type AnthropicImageContentBlock, type AnthropicMessage, type AnthropicMessageStreamEvent, type AnthropicMessagesRequest, type AnthropicMessagesResponse, AnthropicMessagesStream, type AnthropicMetadata, type AnthropicOutputConfig, type AnthropicRedactedThinkingContentBlock, type AnthropicSystem, type AnthropicSystemTextBlock, type AnthropicTextContentBlock, type AnthropicThinkingConfig, type AnthropicThinkingContentBlock, type AnthropicTool, type AnthropicToolChoice, type AnthropicToolResultContentBlock, type AnthropicToolUseContentBlock, type AnthropicUnknownStreamEvent, AnyTool, type BackoffOptions, ChatRequestOptions, ChatResponse, ChatStreamResult, CopyRequestOptions, CreateRequestOptions, DEFAULT_BACKOFF, DEFAULT_BASE_URL, DEFAULT_FAILOVER_CODES, DEFAULT_RETRY_CONFIG, DEFAULT_TIMEOUT_MS, type DefineToolOptions, DeleteRequestOptions, EmbedRequestOptions, EmbedResponse, EmbeddingsRequestOptions, EmbeddingsResponse, type EndpointHealth, type EndpointHealthCheckResult, EndpointRegistry, type EndpointRegistryOptions, FetchLike, GEN_AI_SYSTEM_OLLAMA, GenerateRequestOptions, GenerateResponse, GenerateStreamResult, HttpClient, type LoadMcpToolsOptions, Logger, McpBridge, type McpBridgeOptions, McpClientLike, McpToolDescriptor, Message, Middleware, type ModelCapabilities, ModelOptions, ModelResponse, ModelsClient, OLLAMA_CLOUD_BASE_URL, type OllamaAnthropicContentBlock, type OllamaAnthropicMessage, type OllamaAnthropicMessagesRequest, type OllamaAnthropicSystem, type OllamaAnthropicSystemTextBlock, type OllamaAnthropicTextContentBlock, type OllamaAnthropicThinkingConfig, type OllamaAnthropicTool, type OllamaAnthropicToolResultContentBlock, OllamaClient, type OllamaClientConfig, OllamaClientError, type OllamaCloudFreeTierQuotaBudgets, type OllamaCredentialConfig, type OllamaEndpoint, type OllamaOpenAIChatCompletionRequest, type OllamaOpenAICompletionRequest, type OllamaOpenAIEmbeddingRequest, type OllamaOpenAIReasoningEffort, type OllamaOpenAIResponsesRequest, OllamaStream, OllamaStreamEvent, OllamaStreamEventType, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionChunkChoice, type OpenAIChatCompletionDelta, type OpenAIChatCompletionRequest, type OpenAIChatCompletionResponse, OpenAIChatCompletionStream, OpenAICompatClient, type OpenAICompletionChoice, type OpenAICompletionChunk, type OpenAICompletionRequest, type OpenAICompletionResponse, OpenAICompletionStream, type OpenAIContentPart, type OpenAIEmbeddingInput, type OpenAIEmbeddingItem, type OpenAIEmbeddingRequest, type OpenAIEmbeddingResponse, type OpenAIFunctionDefinition, type OpenAIImageUrlContentPart, type OpenAIListModelsResponse, type OpenAIMessage, type OpenAIModelItem, type OpenAIReasoningEffort, type OpenAIResponseFormat, type OpenAIResponsesCompletedEvent, type OpenAIResponsesContentPartAddedEvent, type OpenAIResponsesContentPartDoneEvent, type OpenAIResponsesCreatedEvent, type OpenAIResponsesError, type OpenAIResponsesEventBase, type OpenAIResponsesFailedEvent, type OpenAIResponsesFunctionCallArgumentsDeltaEvent, type OpenAIResponsesFunctionCallArgumentsDoneEvent, type OpenAIResponsesInProgressEvent, type OpenAIResponsesIncompleteDetails, type OpenAIResponsesIncompleteEvent, type OpenAIResponsesOutputContent, type OpenAIResponsesOutputFunctionCall, type OpenAIResponsesOutputItem, type OpenAIResponsesOutputItemAddedEvent, type OpenAIResponsesOutputItemDoneEvent, type OpenAIResponsesOutputMessage, type OpenAIResponsesOutputReasoning, type OpenAIResponsesOutputRefusal, type OpenAIResponsesOutputTextContent, type OpenAIResponsesOutputTextDeltaEvent, type OpenAIResponsesOutputTextDoneEvent, type OpenAIResponsesQueuedEvent, type OpenAIResponsesReasoningSummaryPartAddedEvent, type OpenAIResponsesReasoningSummaryPartDoneEvent, type OpenAIResponsesReasoningSummaryTextDeltaEvent, type OpenAIResponsesReasoningSummaryTextDoneEvent, type OpenAIResponsesReasoningTextDeltaEvent, type OpenAIResponsesReasoningTextDoneEvent, type OpenAIResponsesRefusalDeltaEvent, type OpenAIResponsesRefusalDoneEvent, type OpenAIResponsesRequest, type OpenAIResponsesResponse, type OpenAIResponsesStatus, OpenAIResponsesStream, OpenAIResponsesStreamError, type OpenAIResponsesStreamEvent, type OpenAIResponsesUsage, type OpenAIStreamOptions, type OpenAITextContentPart, type OpenAITool, type OpenAIToolCall, type OpenAIToolCallDelta, type OpenAIUsage, ProgressResponse, ProgressStreamResult, PsResponse, PullRequestOptions, PushRequestOptions, QuotaManager, type QuotaManagerOptions, type QuotaWindowConfig, type QuotaWindowStatus, RawUsageSource, RequestLifecycleHook, type RequestRunner, type RetryConfig, type RuntimeMode, ShowRequestOptions, ShowResponse, type SpanAttributeValue, type SpanAttributes, SseEvent, StatusResponse, type SupportedSchema, ThinkValue, ThinkingMetadata, type TimeoutSignal, TokenUsage, Tool, ToolCall, ToolDefinition, ToolExecutionResult, ToolHandler, ToolRegistry, VersionResponse, WebFetchRequestOptions, WebFetchResponse, WebSearchRequestOptions, WebSearchResponse, addSpanEvent, calculateBackoff, checkEndpointHealth, createOllamaCloudFreeTierQuota, createTimeoutSignal, defineTool, detectModelCapabilities, encodeImage, inferRuntimeMode, listAllMcpTools, listAvailableModels, loadMcpTools, normalizeChatStream, normalizeGenerateStream, normalizeProgressStream, parseNdjsonStream, parseStructuredOutput, registerMcpTools, resolveCredentialEndpoints, setSpanError, toDataStream, toResponse, toTextStream, withRetry, withSpan, zodToJsonSchema };