@nemesis-oss/ollama-sdk 1.0.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
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-DC11aDJn.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-DC11aDJn.cjs';
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-CDWq8oxJ.cjs';
2
+ export { w as AppliedSkillResult, x as ApplySkillOptions, F as FormatOption, L as ListResponse, y as Logprob, z as LogprobToken, B as ModelDetails, H as ParsedFrontmatter, R as RequestCancellationOptions, I as Role, J as Skill, K as SkillFrontmatter, N as SkillSummary, O as ToolCallFunction, Q as ToolExecutionContext, U as ToolExecutionFailure, X as ToolExecutionSuccess, Y as ToolFunctionDefinition, Z as ToolProperty, _ as ToolRegistryOptions, $ as WebSearchResult, a0 as applySkill, a1 as parseFrontmatter } from './compose-CDWq8oxJ.cjs';
3
3
  import { z } from 'zod';
4
4
  import * as Otel from '@opentelemetry/api';
5
5
 
@@ -52,6 +52,22 @@ declare class OllamaRateLimitError extends OllamaClientError {
52
52
  retryAfterMs?: number | undefined;
53
53
  }) | undefined);
54
54
  }
55
+ /**
56
+ * Thrown client-side, before a network request is made, by `QuotaManager.assertCanProceed`
57
+ * (see `src/quota.ts`) when issuing the request would exceed a configured usage budget for
58
+ * one of its rolling windows. This is distinct from `OllamaRateLimitError`, which reflects
59
+ * the server's own 429 response — Ollama Cloud does not expose account-level quota via the
60
+ * API, so `QuotaManager` tracks usage against budgets the caller configures locally and
61
+ * fails fast rather than waiting for the server to reject the request.
62
+ */
63
+ declare class OllamaQuotaExceededError extends OllamaClientError {
64
+ readonly windowId: string;
65
+ readonly resetAt: number;
66
+ constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {
67
+ windowId: string;
68
+ resetAt: number;
69
+ });
70
+ }
55
71
  declare class OllamaServerError extends OllamaClientError {
56
72
  constructor(message: string, options?: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> | undefined);
57
73
  }
@@ -88,6 +104,22 @@ declare class OllamaUnsupportedCapabilityError extends OllamaClientError {
88
104
  capability: string;
89
105
  });
90
106
  }
107
+ /**
108
+ * Thrown client-side, before any network call, when `config.endpoints` uses
109
+ * `OllamaEndpoint.models` to scope endpoints/credentials to specific models and the
110
+ * requested `model` isn't in any configured endpoint's allow-list. This is a routing
111
+ * misconfiguration, not a connectivity problem — the SDK deliberately does not "probe"
112
+ * unauthorized endpoints to find one that happens to work (that would burn quota on keys
113
+ * that were never entitled to the model and produce non-deterministic startup behavior).
114
+ */
115
+ declare class OllamaModelRoutingError extends OllamaClientError {
116
+ readonly model: string;
117
+ readonly availableModels: readonly string[];
118
+ constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code' | 'retryable'> & {
119
+ model: string;
120
+ availableModels: readonly string[];
121
+ });
122
+ }
91
123
  declare class OllamaAgentMaxIterationsError extends OllamaClientError {
92
124
  readonly maxIterations: number;
93
125
  constructor(message: string, options: Omit<OllamaClientErrorOptions, 'code'> & {
@@ -202,6 +234,8 @@ interface ChatStreamResult {
202
234
  readonly message: Message;
203
235
  readonly model: string;
204
236
  readonly done: boolean;
237
+ /** Mirrors the final chunk's `done_reason` (e.g. `"stop"`, `"load"`, `"unload"`). */
238
+ readonly doneReason?: string | undefined;
205
239
  readonly totalDurationMs?: number | undefined;
206
240
  readonly usage?: TokenUsage | undefined;
207
241
  readonly raw?: ChatResponse | undefined;
@@ -210,6 +244,8 @@ interface GenerateStreamResult {
210
244
  readonly response: string;
211
245
  readonly model: string;
212
246
  readonly done: boolean;
247
+ /** Mirrors the final chunk's `done_reason` (e.g. `"stop"`, `"load"`, `"unload"`). */
248
+ readonly doneReason?: string | undefined;
213
249
  readonly totalDurationMs?: number | undefined;
214
250
  readonly usage?: TokenUsage | undefined;
215
251
  readonly raw?: GenerateResponse | undefined;
@@ -369,17 +405,67 @@ interface OllamaEndpoint {
369
405
  readonly apiKey?: string | undefined;
370
406
  readonly headers?: Record<string, string> | undefined;
371
407
  readonly priority?: number | undefined;
408
+ /**
409
+ * Restricts this endpoint/credential to a specific set of models — for the common case
410
+ * of several Ollama Cloud API keys, each entitled to a different model. When set,
411
+ * `EndpointRegistry.candidates(model)` only returns this endpoint for a request whose
412
+ * `model` is in the list, so cross-endpoint failover never retries a request against a
413
+ * credential that isn't authorized for the requested model. Omit (the default) to make
414
+ * the endpoint eligible for every model, preserving prior behavior.
415
+ */
416
+ readonly models?: readonly string[] | undefined;
372
417
  }
373
418
  interface EndpointHealth {
374
419
  readonly endpoint: OllamaEndpoint;
375
420
  readonly failureCount: number;
376
421
  readonly lastFailureTimestamp?: number | undefined;
377
422
  readonly isCoolingDown: boolean;
423
+ /** In-flight requests currently attempting this endpoint — see `acquire`/`release`. */
424
+ readonly activeRequests: number;
378
425
  }
379
426
  interface EndpointRegistryOptions {
380
427
  readonly failureThreshold?: number | undefined;
381
428
  readonly cooldownMs?: number | undefined;
382
429
  readonly now?: (() => number) | undefined;
430
+ /**
431
+ * How candidates that share the same `priority` are ordered within `candidates()`.
432
+ * `'priority'` (the default) keeps them in registration order, so the same candidate is
433
+ * always tried first while it stays healthy. `'round-robin'` rotates each same-priority
434
+ * group by one position per `candidates()` call — i.e. per `chat`/`generate`/etc. call —
435
+ * so consecutive requests spread across a pool of interchangeable endpoints/credentials
436
+ * instead of always preferring the first one (the common case: several Ollama Cloud keys
437
+ * registered with no `models` restriction, meant to be used interchangeably). Endpoints
438
+ * at different priorities are unaffected either way — a higher-priority one is still
439
+ * always tried first, and failover to the rest of the group still applies if the
440
+ * rotated-to-front candidate fails.
441
+ *
442
+ * `'least-connections'` instead orders each same-priority group by ascending in-flight
443
+ * request count (tracked via `acquire`/`release`, ties broken by registration order),
444
+ * so a request always prefers whichever candidate currently has the fewest requests
445
+ * still in progress. Unlike `'round-robin'`, this remains correct under uneven or
446
+ * overlapping request durations — e.g. several Ollama Cloud accounts each limited to 1
447
+ * concurrent request: firing several requests at once (`Promise.all`) deterministically
448
+ * lands each on a different account rather than risking two landing on the same
449
+ * still-busy one, because `candidates()` and the subsequent `acquire()` for the chosen
450
+ * candidate run synchronously with no `await` in between — JS's single-threaded
451
+ * execution means no two concurrent calls can observe the same "0 active" snapshot for
452
+ * the same candidate.
453
+ */
454
+ readonly strategy?: 'priority' | 'round-robin' | 'least-connections' | undefined;
455
+ /**
456
+ * Caps in-flight requests per endpoint (tracked via `acquire`/`release`). Unset (the
457
+ * default) means no cap — candidates are never treated as saturated. When set, a
458
+ * request whose every otherwise-eligible candidate is already at this cap waits
459
+ * (`waitForCapacity`, FIFO per candidate) for one of them to free up, instead of being
460
+ * sent to an already-saturated candidate. Pairs naturally with `strategy:
461
+ * 'least-connections'` for a pool of accounts each limited to N concurrent requests —
462
+ * e.g. `maxConcurrentPerEndpoint: 1` for several Ollama Cloud free-tier accounts, so
463
+ * `N + 1` concurrent calls against `N` such accounts run `N` immediately and queue the
464
+ * rest, rather than the `(N+1)`th overrunning whichever account looks "least busy" at
465
+ * that instant. Waiting is bounded by the request's own timeout/`AbortSignal`, same as
466
+ * any other in-flight request — it never blocks indefinitely on its own.
467
+ */
468
+ readonly maxConcurrentPerEndpoint?: number | undefined;
383
469
  }
384
470
  declare class EndpointRegistry {
385
471
  private readonly endpoints;
@@ -388,11 +474,66 @@ declare class EndpointRegistry {
388
474
  private readonly failureThreshold;
389
475
  private readonly cooldownMs;
390
476
  private readonly now;
477
+ private readonly strategy;
478
+ private roundRobinCounter;
479
+ private readonly activeCounts;
480
+ private readonly maxConcurrentPerEndpoint;
481
+ private readonly waiters;
391
482
  constructor(endpoints: readonly OllamaEndpoint[], options?: EndpointRegistryOptions);
392
- candidates(): OllamaEndpoint[];
483
+ /**
484
+ * Marks one more request as in-flight against `name`. Callers (`OllamaClient`) must
485
+ * pair every `acquire` with a `release` once that attempt finishes, success or not —
486
+ * see `OllamaClient.executeWithFailover`. Only affects candidate ordering when
487
+ * `strategy` is `'least-connections'`; harmless (just bookkeeping) otherwise, and
488
+ * always reflected in `status()`'s `activeRequests`.
489
+ */
490
+ acquire(name: string): void;
491
+ /** Releases one in-flight request marked via `acquire`, waking one waiter for `name` if any. */
492
+ release(name: string): void;
493
+ /**
494
+ * `candidates` filtered down to those currently under `maxConcurrentPerEndpoint` (all
495
+ * of them, unchanged, if that option is unset).
496
+ */
497
+ filterWithCapacity(candidates: readonly OllamaEndpoint[]): OllamaEndpoint[];
498
+ /**
499
+ * Resolves once any endpoint named in `names` has spare capacity under
500
+ * `maxConcurrentPerEndpoint` (a no-op resolve if that option is unset, or if one
501
+ * already does). Otherwise queues (FIFO per name) until a matching `release()` frees a
502
+ * slot, or rejects if `signal` aborts first — mirroring whatever aborted it
503
+ * (`OllamaTimeoutError`/the caller's own abort reason) so callers see the same error
504
+ * shape as any other in-flight request that times out or is cancelled. FIFO order is
505
+ * best-effort (a newly-arriving request can still win a race for a slot that just
506
+ * freed) — the capacity cap itself, not fairness, is the guarantee this exists for.
507
+ */
508
+ waitForCapacity(names: readonly string[], signal?: AbortSignal): Promise<void>;
509
+ /**
510
+ * Rotates each same-`priority` group in `sorted` (already sorted highest-priority-first)
511
+ * by one position further per call, wrapping around within the group. Priority tiers
512
+ * themselves are never reordered — only candidates that were already tied.
513
+ */
514
+ private applyRoundRobin;
515
+ /**
516
+ * Reorders each same-`priority` group in `sorted` by ascending in-flight request count
517
+ * (from `acquire`/`release`); a stable sort, so candidates tied on active count keep
518
+ * their relative (priority-then-registration) order. Priority tiers themselves are
519
+ * never reordered.
520
+ */
521
+ private applyLeastConnections;
522
+ /**
523
+ * Endpoints eligible for `model`, sorted healthy-first-by-priority (falling back to
524
+ * soonest-to-recover if every eligible endpoint is cooling down); same-priority
525
+ * candidates are further reordered per `options.strategy` (see
526
+ * `EndpointRegistryOptions.strategy`). When `model` is given, endpoints whose `models`
527
+ * allow-list doesn't include it are excluded entirely — see `OllamaEndpoint.models`.
528
+ * Omit `model` to consider every configured endpoint, regardless of any `models`
529
+ * restriction (used for non-model-scoped operations).
530
+ */
531
+ candidates(model?: string): OllamaEndpoint[];
393
532
  reportSuccess(name: string): void;
394
533
  reportFailure(name: string): void;
395
534
  list(): readonly OllamaEndpoint[];
535
+ /** True if any configured endpoint restricts itself to a `models` allow-list. */
536
+ hasModelScopedEndpoints(): boolean;
396
537
  status(): EndpointHealth[];
397
538
  }
398
539
 
@@ -402,6 +543,35 @@ declare class EndpointRegistry {
402
543
 
403
544
  declare const DEFAULT_BASE_URL = "http://localhost:11434";
404
545
  declare const DEFAULT_TIMEOUT_MS = 30000;
546
+ /**
547
+ * Fixed host for Ollama's hosted web tools (`/api/web_search`, `/api/web_fetch`) — see
548
+ * `OllamaClient.webSearch`/`webFetch`. These are an Ollama Cloud service reachable only
549
+ * at this host, independent of any locally-configured `baseUrl`/`endpoints`.
550
+ */
551
+ declare const OLLAMA_CLOUD_BASE_URL = "https://ollama.com";
552
+ /** One named credential for the `credentials`/`modelBindings` config shape. */
553
+ interface OllamaCredentialConfig {
554
+ readonly apiKey: string;
555
+ /** Overrides `OllamaClientConfig.baseUrl` for requests made with this credential. */
556
+ readonly baseUrl?: string | undefined;
557
+ readonly headers?: Record<string, string> | undefined;
558
+ }
559
+ /**
560
+ * Builds synthetic `OllamaEndpoint`s (named `credential:<id>`) from `config.credentials` +
561
+ * `config.modelBindings` — an ergonomic, map-based alternative to writing out `endpoints`
562
+ * with per-entry `models` allow-lists directly. Both shapes feed the same
563
+ * `EndpointRegistry`/`executeWithFailover` routing engine; this is pure config sugar, not
564
+ * a separate routing mechanism. Returns `[]` if `config.credentials` is unset.
565
+ *
566
+ * A model bound to one credential (`modelBindings: { "minimax-m3": "coder" }`) scopes that
567
+ * credential to only that model, same as `OllamaEndpoint.models`. A model bound to several
568
+ * credentials (`modelBindings: { "gpt-oss:120b": ["key1", "key2"] }`) makes ordinary
569
+ * endpoint failover apply between them. `config.defaultCredential`, if set, is given a
570
+ * lower priority than explicitly-bound credentials and no `models` restriction, so it acts
571
+ * as a catch-all for any model without an explicit binding without ever pre-empting one
572
+ * that has.
573
+ */
574
+ declare function resolveCredentialEndpoints(config: Pick<OllamaClientConfig, 'credentials' | 'modelBindings' | 'defaultCredential' | 'baseUrl'>): readonly OllamaEndpoint[];
405
575
  declare const DEFAULT_FAILOVER_CODES: readonly string[];
406
576
  interface OllamaClientConfig {
407
577
  /**
@@ -418,9 +588,49 @@ interface OllamaClientConfig {
418
588
  readonly apiKey?: string;
419
589
  /** Static headers merged into every request. */
420
590
  readonly headers?: Record<string, string>;
421
- /** Multiple named endpoints for rotation and automatic failover. */
591
+ /**
592
+ * Multiple named endpoints for rotation and automatic failover. Each endpoint may
593
+ * carry its own `apiKey` and, via `models`, be scoped to only the models that
594
+ * credential is entitled to — see `OllamaEndpoint.models` for routing several
595
+ * per-model Ollama Cloud API keys through a single client.
596
+ */
422
597
  readonly endpoints?: readonly OllamaEndpoint[];
423
- /** Tuning options for endpoint circuit breaker. */
598
+ /**
599
+ * Named credentials, keyed by an id you choose — an ergonomic alternative to writing
600
+ * out `endpoints` by hand for the common "several Ollama Cloud API keys, each entitled
601
+ * to different models" shape. Combine with `modelBindings` to scope each credential to
602
+ * the models it's authorized for; a credential with no binding (or set as
603
+ * `defaultCredential`) is eligible for every model, same as an `OllamaEndpoint` with no
604
+ * `models`. Merges additively with `endpoints` if both are given.
605
+ */
606
+ readonly credentials?: Readonly<Record<string, OllamaCredentialConfig>>;
607
+ /**
608
+ * Maps a model name to the `credentials` id (or ids, for several keys authorized for
609
+ * the same model — ordinary failover applies between them) that may serve it. Has no
610
+ * effect without `credentials`. Referencing an id not present in `credentials` throws
611
+ * at construction time.
612
+ */
613
+ readonly modelBindings?: Readonly<Record<string, string | readonly string[]>>;
614
+ /**
615
+ * The `credentials` id to fall back to for a model with no entry in `modelBindings`.
616
+ * Unset means such a model has no synthesized-from-`credentials` route — it still
617
+ * routes normally through any plain `endpoints` entry without a `models` restriction.
618
+ */
619
+ readonly defaultCredential?: string | undefined;
620
+ /**
621
+ * Tuning options for the endpoint circuit breaker, and candidate selection ordering —
622
+ * pass `{ strategy: 'round-robin' }` to spread requests across a pool of same-priority
623
+ * endpoints/credentials (e.g. several unbound `credentials`) instead of always
624
+ * preferring the first one, or `{ strategy: 'least-connections' }` to route each
625
+ * request to whichever candidate currently has the fewest requests in flight (e.g.
626
+ * several free-tier Ollama Cloud accounts, each capped at 1 concurrent request — this
627
+ * deterministically spreads concurrent `Promise.all`-style calls one-per-account rather
628
+ * than risking two landing on the same still-busy one), and `maxConcurrentPerEndpoint`
629
+ * to cap that at an exact number and queue (rather than overrun a saturated candidate)
630
+ * once every eligible one is at capacity — e.g. `{ strategy: 'least-connections',
631
+ * maxConcurrentPerEndpoint: 1 }` for accounts that only allow one request at a time.
632
+ * See `EndpointRegistryOptions`.
633
+ */
424
634
  readonly endpointHealth?: EndpointRegistryOptions;
425
635
  /** Error codes that trigger failover to the next candidate endpoint. */
426
636
  readonly failoverOn?: readonly string[];
@@ -519,6 +729,9 @@ type RequestRunner = <T>(op: (http: HttpClient, signal: AbortSignal) => Promise<
519
729
  signal?: AbortSignal | undefined;
520
730
  timeoutMs?: number | undefined;
521
731
  singleEndpoint?: boolean | undefined;
732
+ model?: string | undefined;
733
+ /** See `OllamaClient.executeWithFailover`'s `holdUntil` doc. */
734
+ holdUntil?: ((result: T) => Promise<unknown>) | undefined;
522
735
  }) => Promise<T>;
523
736
  /**
524
737
  * Every operation here targets one specific Ollama server's local model catalog or blob
@@ -568,13 +781,15 @@ declare class ModelsClient {
568
781
  *
569
782
  * @remarks
570
783
  * This is a typed pass-through to Ollama's own OpenAI-compatible `/v1` endpoints — it
571
- * implements the subset of the OpenAI Chat Completions API that Ollama documents as
572
- * supported (https://docs.ollama.com/api/openai-compatibility), not the full OpenAI
573
- * surface (Responses API, hosted tools like web/file search, computer use, code
574
- * interpreter, or server-side conversation state). Notably, `tools` is supported by
575
- * Ollama's compat layer but `tool_choice` and `parallel_tool_calls` are explicitly
576
- * **not** — deliberately omitted from {@link OpenAIChatCompletionRequest} rather than
577
- * typed as accepted-but-ignored.
784
+ * implements the subset of the OpenAI API surface that Ollama documents as supported
785
+ * (https://docs.ollama.com/api/openai-compatibility), not the full OpenAI surface (hosted
786
+ * tools like web/file search, computer use, code interpreter, or stateful server-side
787
+ * conversation state). Notably, `tools` is supported by Ollama's compat layer but
788
+ * `tool_choice` and `parallel_tool_calls` are not — both are still typed on
789
+ * {@link OpenAIChatCompletionRequest} (accepted-but-ignored) so consumers passing a
790
+ * standard OpenAI request object don't get spurious type errors; see the `@remarks` on
791
+ * each field. `/v1/responses` is supported non-statefully — see
792
+ * {@link OpenAIResponsesRequest}.
578
793
  */
579
794
 
580
795
  interface OpenAIToolCall {
@@ -621,6 +836,34 @@ interface OpenAIChatCompletionRequest {
621
836
  readonly frequency_penalty?: number | undefined;
622
837
  readonly user?: string | undefined;
623
838
  readonly tools?: readonly OpenAITool[] | undefined;
839
+ /**
840
+ * @remarks Accepted for OpenAI compatibility but ignored by Ollama — every tool the
841
+ * model is given remains callable regardless of this value.
842
+ */
843
+ readonly tool_choice?: 'none' | 'auto' | 'required' | {
844
+ readonly type: 'function';
845
+ readonly function: {
846
+ readonly name: string;
847
+ };
848
+ } | undefined;
849
+ /**
850
+ * @remarks Accepted for OpenAI compatibility but ignored by Ollama — Ollama does not
851
+ * control tool-call parallelism through this flag.
852
+ */
853
+ readonly parallel_tool_calls?: boolean | undefined;
854
+ /**
855
+ * Effort level for thinking models (e.g. `deepseek-r1`, `qwen3`). Equivalent to
856
+ * `reasoning.effort`; only effective for models that support reasoning/thinking.
857
+ */
858
+ readonly reasoning_effort?: 'high' | 'medium' | 'low' | 'max' | 'none' | undefined;
859
+ /**
860
+ * Effort level for thinking models (e.g. `deepseek-r1`, `qwen3`), nested OpenAI-style.
861
+ * Equivalent to `reasoning_effort`; only effective for models that support
862
+ * reasoning/thinking.
863
+ */
864
+ readonly reasoning?: {
865
+ readonly effort?: 'high' | 'medium' | 'low' | 'max' | 'none' | undefined;
866
+ } | undefined;
624
867
  }
625
868
  interface OpenAIChatCompletionChoice {
626
869
  readonly index: number;
@@ -649,12 +892,60 @@ interface OpenAIListModelsResponse {
649
892
  readonly object: 'list';
650
893
  readonly data: readonly OpenAIModelItem[];
651
894
  }
895
+ /**
896
+ * Request body for OpenAI's Responses API (`/v1/responses`), added in Ollama v0.13.3.
897
+ *
898
+ * @remarks
899
+ * Ollama implements this **non-statefully**: every call is independent, so
900
+ * {@link previous_response_id} and {@link conversation} — OpenAI's mechanisms for
901
+ * resuming server-side conversation state — are accepted for compatibility but ignored.
902
+ * Send the full conversation in `input` on every call, the same as `/api/chat`.
903
+ */
904
+ interface OpenAIResponsesRequest {
905
+ readonly model: string;
906
+ readonly input: string | readonly OpenAIMessage[];
907
+ readonly instructions?: string | undefined;
908
+ readonly tools?: readonly OpenAITool[] | undefined;
909
+ readonly stream?: boolean | undefined;
910
+ readonly temperature?: number | undefined;
911
+ readonly top_p?: number | undefined;
912
+ readonly max_output_tokens?: number | undefined;
913
+ /** @remarks Not supported by Ollama, which is stateless across calls — accepted but ignored. */
914
+ readonly previous_response_id?: string | undefined;
915
+ /** @remarks Not supported by Ollama, which is stateless across calls — accepted but ignored. */
916
+ readonly conversation?: string | undefined;
917
+ readonly truncation?: string | undefined;
918
+ }
919
+ interface OpenAIResponsesOutputTextContent {
920
+ readonly type: 'output_text';
921
+ readonly text: string;
922
+ }
923
+ interface OpenAIResponsesOutputMessage {
924
+ readonly type: 'message';
925
+ readonly role?: string | undefined;
926
+ readonly content: readonly OpenAIResponsesOutputTextContent[];
927
+ }
928
+ /** Non-stateful response shape for `/v1/responses`; see {@link OpenAIResponsesRequest}. */
929
+ interface OpenAIResponsesResponse {
930
+ readonly id: string;
931
+ readonly object: 'response';
932
+ readonly created: number;
933
+ readonly model: string;
934
+ readonly output: readonly OpenAIResponsesOutputMessage[];
935
+ readonly usage?: {
936
+ readonly input_tokens: number;
937
+ readonly output_tokens: number;
938
+ readonly total_tokens: number;
939
+ } | undefined;
940
+ }
652
941
  declare class OpenAICompatClient {
653
942
  private readonly http;
654
943
  constructor(http: HttpClient);
655
944
  createChatCompletion(request: OpenAIChatCompletionRequest, signal?: AbortSignal): Promise<OpenAIChatCompletionResponse>;
656
945
  chatCompletions(request: OpenAIChatCompletionRequest, signal?: AbortSignal): Promise<OpenAIChatCompletionResponse>;
657
946
  listModels(signal?: AbortSignal): Promise<OpenAIListModelsResponse>;
947
+ createResponses(request: OpenAIResponsesRequest, signal?: AbortSignal): Promise<OpenAIResponsesResponse>;
948
+ responses(request: OpenAIResponsesRequest, signal?: AbortSignal): Promise<OpenAIResponsesResponse>;
658
949
  }
659
950
 
660
951
  /**
@@ -719,6 +1010,14 @@ declare class OllamaClient {
719
1010
  private readonly failoverCodes;
720
1011
  private readonly fetchImpl;
721
1012
  private readonly logger;
1013
+ /**
1014
+ * API key for Ollama's hosted web tools (`webSearch`/`webFetch`), which always target
1015
+ * `OLLAMA_CLOUD_BASE_URL` regardless of `config.endpoints` — an Ollama account API key
1016
+ * is inherently a single global credential, not tied to any one inference endpoint.
1017
+ * Resolved the same way as a single-endpoint `apiKey` (`config.apiKey` falling back to
1018
+ * `OLLAMA_API_KEY`), independent of whether `config.endpoints` was used instead.
1019
+ */
1020
+ private readonly cloudApiKey;
722
1021
  constructor(config?: OllamaClientConfig);
723
1022
  get modelsClient(): ModelsClient;
724
1023
  /**
@@ -741,6 +1040,25 @@ declare class OllamaClient {
741
1040
  * ADR 0008. Defaults to `false`, preserving normal failover for inference calls.
742
1041
  */
743
1042
  singleEndpoint?: boolean | undefined;
1043
+ /**
1044
+ * The model this request targets, used to filter candidates by
1045
+ * `OllamaEndpoint.models` (credential-scoped routing — see that field's docs).
1046
+ * Requests without a `model` (e.g. `listModels`) consider every configured
1047
+ * endpoint, same as before this option existed.
1048
+ */
1049
+ model?: string | undefined;
1050
+ /**
1051
+ * For an operation whose real completion outlasts its own returned promise — a
1052
+ * streaming response, specifically — defers releasing the endpoint's concurrency
1053
+ * slot (see `EndpointRegistryOptions.maxConcurrentPerEndpoint`/`'least-connections'`)
1054
+ * until the promise this returns settles, instead of releasing as soon as
1055
+ * `operation` resolves. Pass `(stream) => stream.finalResult` for `chatStream`/
1056
+ * `generateStream` so the slot stays held for as long as the underlying HTTP
1057
+ * connection realistically does — until the stream is fully consumed, errors, or is
1058
+ * aborted. Omit for anything whose returned promise already represents the whole
1059
+ * request/response (the default, and correct for every non-streaming call).
1060
+ */
1061
+ holdUntil?: ((result: T) => Promise<unknown>) | undefined;
744
1062
  }): Promise<T>;
745
1063
  chat(req: ChatRequestOptions & {
746
1064
  stream: true;
@@ -781,8 +1099,27 @@ declare class OllamaClient {
781
1099
  readonly version: () => Promise<VersionResponse>;
782
1100
  readonly createBlob: (digest: string, data: BinaryBody) => Promise<void>;
783
1101
  readonly checkBlob: (digest: string) => Promise<boolean>;
1102
+ /**
1103
+ * Ollama's hosted web search tool (`POST https://ollama.com/api/web_search`) — a fixed
1104
+ * Ollama Cloud service, unrelated to `config.endpoints`/`baseUrl` and not proxied
1105
+ * through a local server. Requires an Ollama account API key: pass `apiKey` to the
1106
+ * client constructor or set `OLLAMA_API_KEY`. Applies the same default `timeoutMs` and
1107
+ * retry policy as inference calls, but never cross-endpoint-fails-over — there is only
1108
+ * ever the one cloud endpoint to call.
1109
+ */
784
1110
  webSearch(req: WebSearchRequestOptions): Promise<WebSearchResponse>;
1111
+ /**
1112
+ * Ollama's hosted web fetch tool (`POST https://ollama.com/api/web_fetch`) — see
1113
+ * {@link OllamaClient.webSearch} for the cloud-endpoint/auth/timeout/retry behavior,
1114
+ * which applies identically here.
1115
+ */
785
1116
  webFetch(req: WebFetchRequestOptions): Promise<WebFetchResponse>;
1117
+ /**
1118
+ * Runs `operation` against the fixed Ollama Cloud host with this client's default
1119
+ * timeout and retry policy — the same primitives `executeWithFailover` uses, minus the
1120
+ * multi-candidate loop, since `webSearch`/`webFetch` only ever have the one endpoint.
1121
+ */
1122
+ private executeCloudRequest;
786
1123
  capabilities(model: string): Promise<ModelCapabilities>;
787
1124
  runtimeMode(): RuntimeMode;
788
1125
  healthCheck(): Promise<EndpointHealthCheckResult[]>;
@@ -837,6 +1174,89 @@ declare function toDataStream<TChunk, TFinal>(stream: OllamaStream<TChunk, TFina
837
1174
  */
838
1175
  declare function toResponse<TChunk, TFinal>(stream: OllamaStream<TChunk, TFinal>, init?: ResponseInit): Response;
839
1176
 
1177
+ /**
1178
+ * Client-side usage budgeting.
1179
+ *
1180
+ * Ollama Cloud does not expose account-level quota or remaining-budget through the API —
1181
+ * chat/generate responses carry only per-request token counts, and there is no header or
1182
+ * endpoint that reports how much of your plan's session or weekly limit is left (the only
1183
+ * way to see that today is the https://ollama.com dashboard or the 90%-usage email). See
1184
+ * https://github.com/ollama/ollama/issues/15663.
1185
+ *
1186
+ * `QuotaManager` does not — and cannot — read Ollama's real limits. It tracks usage you
1187
+ * record against budgets *you* configure over one or more rolling windows, and refuses to
1188
+ * proceed once a window's budget is spent. Pair it with `OllamaRateLimitError` (thrown by
1189
+ * `OllamaClient` on the server's actual 429) as the authoritative signal; treat
1190
+ * `QuotaManager` as a local safety net that fails fast before the request is even sent.
1191
+ */
1192
+
1193
+ interface QuotaWindowConfig {
1194
+ /** Identifies this window in status reports and thrown errors (e.g. "session", "weekly"). */
1195
+ readonly id: string;
1196
+ /** Length of the rolling window in milliseconds, after which usage resets to zero. */
1197
+ readonly windowMs: number;
1198
+ /** Token budget for the window. Omit to only track requests. */
1199
+ readonly maxTokens?: number;
1200
+ /** Request-count budget for the window. Omit to only track tokens. */
1201
+ readonly maxRequests?: number;
1202
+ }
1203
+ interface QuotaWindowStatus extends QuotaWindowConfig {
1204
+ readonly tokensUsed: number;
1205
+ readonly requestsMade: number;
1206
+ readonly windowStartedAt: number;
1207
+ readonly windowResetAt: number;
1208
+ readonly remainingTokens?: number;
1209
+ readonly remainingRequests?: number;
1210
+ }
1211
+ interface QuotaManagerOptions {
1212
+ readonly windows: readonly QuotaWindowConfig[];
1213
+ /** Clock override for testing. Defaults to `Date.now`. */
1214
+ readonly now?: () => number;
1215
+ }
1216
+ declare class QuotaManager {
1217
+ private readonly now;
1218
+ private readonly windows;
1219
+ constructor(options: QuotaManagerOptions);
1220
+ private rollover;
1221
+ /** Current usage, budgets, and reset time for every configured window. */
1222
+ status(): readonly QuotaWindowStatus[];
1223
+ /**
1224
+ * True if one more request — optionally estimated at `estimatedTokens` — would stay
1225
+ * within every configured window's budget. Read-only; does not record usage.
1226
+ */
1227
+ canProceed(estimatedTokens?: number): boolean;
1228
+ /**
1229
+ * Throws `OllamaQuotaExceededError` for the first window that `canProceed(estimatedTokens)`
1230
+ * would fail on; otherwise a no-op. Call before issuing a request.
1231
+ */
1232
+ assertCanProceed(estimatedTokens?: number): void;
1233
+ /** Records one request's actual usage — a raw API response or a pre-normalized `TokenUsage` — against every window. */
1234
+ recordUsage(usage: RawUsageSource | TokenUsage): void;
1235
+ /** Resets one window (by `id`) or, if omitted, all windows — zeroing usage and restarting their clocks. */
1236
+ reset(windowId?: string): void;
1237
+ }
1238
+ interface OllamaCloudFreeTierQuotaBudgets {
1239
+ /** Budget for the free tier's ~5-hour session window. Omit to skip tracking it. */
1240
+ readonly session?: {
1241
+ readonly maxTokens?: number;
1242
+ readonly maxRequests?: number;
1243
+ };
1244
+ /** Budget for the free tier's 7-day weekly window. Omit to skip tracking it. */
1245
+ readonly weekly?: {
1246
+ readonly maxTokens?: number;
1247
+ readonly maxRequests?: number;
1248
+ };
1249
+ readonly now?: () => number;
1250
+ }
1251
+ /**
1252
+ * Convenience factory mirroring Ollama Cloud free-tier's documented reset cadence — a
1253
+ * session window that resets every 5 hours and a weekly window that resets every 7 days
1254
+ * (see https://ollama.com/pricing). Ollama does not publish the actual token/request
1255
+ * ceilings for either window, so you must supply the budgets yourself (e.g. from your own
1256
+ * observed usage) — this only wires up the window durations.
1257
+ */
1258
+ declare function createOllamaCloudFreeTierQuota(budgets: OllamaCloudFreeTierQuotaBudgets): QuotaManager;
1259
+
840
1260
  /**
841
1261
  * Zod schema conversion to JSON Schema for Ollama structured outputs.
842
1262
  */
@@ -1041,4 +1461,19 @@ declare const ATTR_OLLAMA_AGENT_MAX_ITERATIONS = "ollama.agent.max_iterations";
1041
1461
  declare const ATTR_OLLAMA_AGENT_ITERATION = "ollama.agent.iteration";
1042
1462
  declare const GEN_AI_SYSTEM_OLLAMA = "ollama";
1043
1463
 
1044
- 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 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, extractUsage, inferRuntimeMode, listAvailableModels, loadMcpTools, mapError, normalizeChatStream, normalizeGenerateStream, normalizeProgressStream, parseNdjsonStream, parseStructuredOutput, registerMcpTools, setSpanError, toDataStream, toResponse, toTextStream, withRetry, withSpan, zodToJsonSchema };
1464
+ /**
1465
+ * Cross-runtime helpers with no Node.js API dependency, so they stay safe to import from
1466
+ * the core client bundle (see ADR 0006 — Edge Runtime CI).
1467
+ */
1468
+ /**
1469
+ * Encodes an image to a base64 string, matching the wire format Ollama's `/api/chat` and
1470
+ * `/api/generate` `images` arrays expect.
1471
+ *
1472
+ * - A `string` is assumed to already be base64-encoded and is returned unchanged.
1473
+ * - A `Uint8Array` is base64-encoded using whichever universal primitive the runtime
1474
+ * exposes: `Buffer` on Node.js, `btoa` on browsers/Edge runtimes. Chunked so it doesn't
1475
+ * blow the engine's max call-stack/argument-count limits on large images.
1476
+ */
1477
+ declare function encodeImage(image: Uint8Array | string): Promise<string>;
1478
+
1479
+ 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, OLLAMA_CLOUD_BASE_URL, OllamaAbortError, OllamaAgentMaxIterationsError, OllamaAuthError, OllamaClient, type OllamaClientConfig, OllamaClientError, type OllamaClientErrorOptions, type OllamaCloudFreeTierQuotaBudgets, type OllamaCredentialConfig, type OllamaEndpoint, type OllamaErrorRequestContext, type OllamaErrorResponseContext, OllamaGenericClientError, OllamaMcpError, OllamaModelRoutingError, OllamaNetworkError, OllamaNotFoundError, OllamaQuotaExceededError, 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, QuotaManager, type QuotaManagerOptions, type QuotaWindowConfig, type QuotaWindowStatus, 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, createOllamaCloudFreeTierQuota, createTimeoutSignal, defineTool, detectModelCapabilities, encodeImage, extractUsage, inferRuntimeMode, listAvailableModels, loadMcpTools, mapError, normalizeChatStream, normalizeGenerateStream, normalizeProgressStream, parseNdjsonStream, parseStructuredOutput, registerMcpTools, resolveCredentialEndpoints, setSpanError, toDataStream, toResponse, toTextStream, withRetry, withSpan, zodToJsonSchema };