@nemesis-oss/ollama-sdk 1.12.1 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +145 -5
  3. package/dist/{anthropic-CKp5TmAP.d.ts → anthropic-DrDUfbfQ.d.ts} +65 -18
  4. package/dist/{anthropic-Did0lQxP.d.cts → anthropic-UeaVjLeP.d.cts} +65 -18
  5. package/dist/{compose-6UOPEknN.d.ts → compose-CeFbHJeO.d.ts} +1 -1
  6. package/dist/{compose-DhvoUrWa.d.cts → compose-DFkmtUOP.d.cts} +1 -1
  7. package/dist/generated-api.cjs +3 -2
  8. package/dist/generated-api.cjs.map +1 -1
  9. package/dist/generated-api.d.cts +15 -9
  10. package/dist/generated-api.d.ts +15 -9
  11. package/dist/generated-api.js +3 -2
  12. package/dist/generated-api.js.map +1 -1
  13. package/dist/generated-models-schemas.cjs +1 -1
  14. package/dist/generated-models-schemas.cjs.map +1 -1
  15. package/dist/generated-models-schemas.js +1 -1
  16. package/dist/generated-models-schemas.js.map +1 -1
  17. package/dist/generated-runtime.cjs +2 -1
  18. package/dist/generated-runtime.cjs.map +1 -1
  19. package/dist/generated-runtime.d.cts +2 -2
  20. package/dist/generated-runtime.d.ts +2 -2
  21. package/dist/generated-runtime.js +2 -1
  22. package/dist/generated-runtime.js.map +1 -1
  23. package/dist/index.cjs +209 -25
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +103 -12
  26. package/dist/index.d.ts +103 -12
  27. package/dist/index.js +203 -26
  28. package/dist/index.js.map +1 -1
  29. package/dist/mcp/tools.json +4 -4
  30. package/dist/mcp-generated.cjs +3 -2
  31. package/dist/mcp-generated.cjs.map +1 -1
  32. package/dist/mcp-generated.d.cts +2 -2
  33. package/dist/mcp-generated.d.ts +2 -2
  34. package/dist/mcp-generated.js +3 -2
  35. package/dist/mcp-generated.js.map +1 -1
  36. package/dist/{runtime-CIQYCRL3.d.ts → runtime-BIjr5ME4.d.ts} +1 -1
  37. package/dist/{runtime-DmI1cOEq.d.cts → runtime-C4RRHqOs.d.cts} +1 -1
  38. package/dist/skills.d.cts +3 -3
  39. package/dist/skills.d.ts +3 -3
  40. package/dist/testing.cjs +281 -0
  41. package/dist/testing.cjs.map +1 -0
  42. package/dist/testing.d.cts +336 -0
  43. package/dist/testing.d.ts +336 -0
  44. package/dist/testing.js +275 -0
  45. package/dist/testing.js.map +1 -0
  46. package/dist/{types-B57ZZfp3.d.cts → types-DbPnfVh-.d.cts} +20 -3
  47. package/dist/{types-B57ZZfp3.d.ts → types-DbPnfVh-.d.ts} +20 -3
  48. package/package.json +14 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.14.0] — Speculative-decoding model assembly & the public testing subpath: `draftGguf`, `draft_num_predict` docs, `@nemesis-oss/ollama-sdk/testing`
4
+
5
+ The October 12 digest ("Speculative Decoding & Draft Model Creation") reviewed the official model-creation surfaces — `draft_files` + `draft_quantize` on `POST /api/create`, the `draft_num_predict` Modelfile parameter and runtime option — and asked for an exportable zero-network mock server. Audited against the codebase first (see [ADR 0029](./docs/adr/0029-public-testing-subpath-speculative-draft-conveniences.md)): the digest's headline typing claims were stale — `draft_files`/`draft_quantize` already shipped on both the generated `CreateRequest` and the hand-written `CreateRequestOptions` (official OpenAPI, 2026-10-07 pin), and `draft_num_predict` was already typed + documented on the runtime `ModelOptions`; the "DRAFT `<model>`" Modelfile instruction the digest describes is not in the current official docs (only the parameter is). The real gaps — a path-based draft upload convenience, wire tests, discoverable documentation, and the not-exported mock server — are closed here. All additive, no breaking changes. 932 pre-existing tests stay green, 28 new tests added.
6
+
7
+ ### Speculative model assembly (`createModelFromGguf` → `draftGguf`)
8
+
9
+ - **`CreateModelFromGgufOptions.draftGguf`**: pass the draft network's GGUF path(s) alongside the primary shards — each is uploaded as a blob and assembled into `draft_files` under its basename, the same protocol as primary shards. Split draft GGUFs, explicit `draft_files` digest maps (merged; path uploads win on basename collision), and `draft_quantize` passthrough all work; no draft → no `draft_files` key on the wire at all.
10
+ - **Discoverable speculative-decoding docs**: `CreateRequestOptions.parameters` now documents `draft_num_predict` (separate draft models default to 4; `0` disables drafting; embedded MTP tensors require setting it explicitly — official Modelfile reference), and `draft_files`/`draft_quantize` carry the speculative-decoding context with the verification-semantics note that makes aggressive draft compression safe.
11
+ - Wire tests pin the whole contract: `createModel` round-trips `draft_files` + `draft_quantize` + `parameters.draft_num_predict`; `createModelFromGguf` uploads draft blobs separately (HEAD + POST per shard) and never leaks `draftGguf` or empty maps into the request body.
12
+
13
+ ### Public testing subpath (`@nemesis-oss/ollama-sdk/testing`)
14
+
15
+ - The SDK's internal mock engine is **promoted, not forked** (ADR 0029, same discipline as ADRs 0027/0028): `test/mocks/ollama-mock-server.ts` is now a re-export shim, so the SDK's own suite exercises exactly the code consumers import.
16
+ - **`createMockOllamaServer(options?)`** — the recommended factory. Built-in **default routes** answer the official liveness probe (`HEAD /` → 200, `GET /` → the plain-text body "Ollama is running" byte-for-byte) and `GET /api/version` (configurable version, default `0.14.0`), so `client.ping()` works against a fresh mock with zero setup. `defaultRoutes: false` restores bare 404s; `register()` always wins over the defaults.
17
+ - **Request recording** — `server.requests` captures every request (method, path, parsed body, timestamp), including default-route hits and 404s; `clearRequests()` for `beforeEach` hooks. Wire-level assertions without per-route callbacks.
18
+ - **In-band mid-stream error injection** — `injectErrorFrame: { message, after? }` emits an `{"error": "..."}` NDJSON frame while HTTP stays 200, exactly how a real daemon reports GPU OOM/driver crashes mid-generation. The default injection point is `chunks.length - 1`: every content chunk, then the error frame, with the final `done` frame never emitted — an error frame after `done` would be unread (the stream has already completed cleanly). `after: 0` errors before any content; explicit larger values move the position. The SDK's stream readers raise `OllamaStreamError` with the partial content.
19
+ - **`rawBody`** route option for exact non-NDJSON bodies (the liveness body uses it — no trailing newline).
20
+ - **Chunk builders** producing correctly-shaped `/api/chat` frames: `mockChatChunk` (one frame, counter defaults on the done frame for telemetry paths), `mockTextChunks` (chunked text + done frame), and `mockToolCallChunks` — parallel tool calls in one frame, the documented native shape, followed by the done frame.
21
+ - **Packaging**: dedicated `./testing` entry in the exports map (paired `.d.ts`/`.d.cts`), a new tsup entry, and the consumer-type verification now compiles a real CJS (node16) **and** ESM (nodenext) consumer importing the subpath. Node.js-only by design (`node:http`) — never imported from the Edge-safe main entry, so `verify:edge-runtime` stays clean.
22
+
23
+ ### Lab
24
+
25
+ - `lab/15-speculative-draft/measure-draft-speedup.ts`: live harness comparing `draft_num_predict` 0/4/8/16 — warm-up per setting, 5 samples each, median `tokensPerSecond` via `formatTelemetry`, and a speedup table against drafting-disabled. Makes "the server has no draft network, the option is being ignored" obvious at a glance.
26
+
27
+ ## [1.13.0] — docs.ollama.com re-audit: parity verifier reads checkbox state, strict compat types, web-search agent tools
28
+
29
+ A full re-read of docs.ollama.com (API reference, capability guides, integrations, OpenAPI spec) against the SDK. The native API was already at parity except for two upstream changes; the real defect was in the compatibility-parity tooling, which had been reporting fields Ollama documents as unsupported as "supported".
30
+
31
+ ### Fixed
32
+
33
+ - **Contract-parity verifier ignored `[ ]` (unsupported) checkboxes.** `verify:contract-parity` fetched the rendered HTML docs, which drop checkbox state, and the pinned fallback had been rewritten to `[Input]` markers — so every listed field read as supported and the OpenAI overlay claimed support for `tool_choice`, `logit_bias`, `user`, `n` and logprobs (chat), `best_of`, `echo`, `logit_bias`, `user`, `n` and logprobs (completions), `user` (embeddings) and `truncation` (responses). The fetcher now prefers the Mintlify markdown twin (`<page>.md`), endpoint sections are bounded by heading level (backticked headings supported), unchecked feature items (`* [ ] Logprobs`) read as unsupported, and unchecked request-field items count as explicit unsupported evidence. The overlay and IR are corrected (`logprobs` capability is now `unsupported` on `/v1/chat/completions` and `/v1/completions`), and the pinned fallbacks are re-pinned from the live markdown with checkbox state intact.
34
+ - **Strict compatibility request types now exclude documented-unsupported fields.** `OllamaOpenAIChatCompletionRequest` drops `tool_choice`, `logit_bias`, `user`, `n`, `logprobs`, `top_logprobs`; `OllamaOpenAICompletionRequest` drops `best_of`, `echo`, `logit_bias`, `user`, `n`, `logprobs`; `OllamaOpenAIEmbeddingRequest` drops `user` and narrows `input` to `string | string[]`; `OllamaOpenAIResponsesRequest` also drops `truncation`. Passing them is now a compile error (pinned by `@ts-expect-error` tests run under `npm run typecheck`). **Type-level breaking change only for code that opted into the strict types** — the broad `OpenAI*` interop types are unchanged.
35
+
36
+ ### Upstream API changes picked up
37
+
38
+ - **System One `choice` criteria limit raised from 26 to 255** (model-dependent) — generated Zod schema and request type updated; `score` stays at 2–26.
39
+ - **`/api/copy` documents a JSON `{ "status": "success" }` body** plus 400/404 error responses — the generated `NativeApi.copy()` now returns `StatusResponse` instead of `unknown`.
40
+
41
+ ### Added
42
+
43
+ - **`createWebTools(client, options?)`** (plus `createWebSearchTool`, `createWebFetchTool`, `formatWebSearchResult`, `formatWebFetchResult`): Ollama Cloud web search/fetch as model-callable `web_search`/`web_fetch` tools for `ToolRegistry`/`Agent` — the documented "Building a search agent" pattern. Arguments are validated at the registry boundary (`query`/`url` non-empty, `max_results` 1–10) before any network call; the abort signal propagates; output is bounded by `maxOutputChars` (default `2000 * 4`, as in the docs) by trimming content fields so it always stays valid JSON; `web_fetch` caps links (`maxLinks`, default 25). New example: `examples/web-search-agent.ts`.
44
+ - Tests for direct Ollama Cloud access through the bridges (`https://ollama.com/v1/chat/completions`, `/v1/responses`, `/v1/messages` with `Authorization: Bearer` and `anthropic-version: 2023-06-01`), docs-parser regression tests against the pinned markdown, and strict-type compile tests.
45
+
46
+ - **Strict chat images are base64-only.** `OllamaOpenAIChatContentPart.image_url` is now `` `data:${string}` `` (string or `{ url, detail? }`), so a remote `http(s)://` image URL — documented as unsupported on `/v1/chat/completions` — is a compile error. `OllamaOpenAIChatMessage`, `OllamaOpenAIChatContentPart`, and `OllamaOpenAIImageDataUrl` are now exported from the package root.
47
+ - OpenAPI source descriptions synced with upstream (System One `noul`/`score` criteria, `UsageResponse.granularity`). The one remaining intentional deviation — nullable `ModelSummary.details.families`, because the server serializes a nil slice as `null` — is documented in the source header and pinned by a test.
48
+
49
+ ### Documentation
50
+
51
+ - README and docs-site OpenAI/Anthropic guides: per-endpoint supported vs documented-unsupported tables, direct cloud access sections, and a web search agent section.
52
+
3
53
  ## [1.12.1] — Fix: model-affinity routing respects priority tiers
4
54
 
5
55
  ### Fixed
package/README.md CHANGED
@@ -28,12 +28,13 @@ Nexum’s model harness (2026-10-09) exercised this SDK via `gemma4:cloud` and `
28
28
  - 🌐 **High Availability & Failover**: Multi-endpoint registry with priority routing, circuit breaker failover, active health checks, and per-endpoint `models` allow-lists for routing several model-specific API keys through one client.
29
29
  - 🔌 **Model Context Protocol (MCP)**: First-class, transport-neutral `McpBridge` for converting MCP tool descriptors into Ollama function definitions and registering executable MCP-backed tools.
30
30
  - 📚 **Full Model Lifecycle**: `pullModel`, `pushModel`, `createModel`, `copyModel`, `deleteModel`, `listModels`, `showModel`, and `ps()` (currently loaded models) — full parity with Ollama's model management API.
31
- - 🔎 **Ollama Cloud Web Tools**: `webSearch`/`webFetch` wrap Ollama's hosted `/api/web_search` and `/api/web_fetch` tools at `ollama.com` (requires an `OLLAMA_API_KEY`), independent of any local `baseUrl`.
31
+ - 🔎 **Ollama Cloud Web Tools**: `webSearch`/`webFetch` wrap Ollama's hosted `/api/web_search` and `/api/web_fetch` tools at `ollama.com` (requires an `OLLAMA_API_KEY`), independent of any local `baseUrl` — and `createWebTools(client)` exposes them as model-callable `web_search`/`web_fetch` tools with bounded, valid-JSON output for the documented search-agent pattern.
32
32
  - 💳 **Ollama Cloud Usage & Balance**: `usage()`/`balance()` wrap Ollama's hosted account endpoints (`GET /api/usage`, `GET /api/balance`) — request counts, USD spend, cached-token totals bucketed by hour/day, and remaining included/purchased credits (including the legacy session/weekly plan shapes) — with the same fixed-cloud-host, API-key, timeout, and retry semantics as the web tools.
33
33
  - 🌉 **OpenAI & Anthropic Compatibility Bridges**: Built-in clients for `/v1/chat/completions`, `/v1/responses`, `/v1/models`, and `/v1/messages`, including `reasoning_effort`/`reasoning.effort` for thinking models — plus an ergonomic dual-mode `client.responses.create()` bridge that prefers native `/v1/responses` and transparently re-issues via `/api/chat` on older servers (pre-v0.13.3).
34
34
  - 💬 **KV-Cache-Aware Conversation Sessions**: `client.session(model, systemPrompt)` keeps an append-only, prefix-stable history that maximizes Ollama's KV-cache reuse across turns, surfaces per-turn + cumulative cache hit rates (`prompt_eval_cached_count`) so cache degradation is visible instead of silent, and offers a one-call `compact()` sliding-window escape hatch when a session outgrows its window.
35
35
  - 🛑 **Context-Window Safety**: Heuristic client-side token estimation warns (or throws, `onContextOverflow: 'throw'`) before a request is sent when the prompt approaches the effective `num_ctx` window — Ollama's default behavior is to _silently truncate_ oversized prompts — and `defaultContextLength` makes the window explicit on every request.
36
- - 📦 **Blob & Custom Model Publishing**: Content-addressed blob management per Ollama's documented protocol — `computeBlobDigest()` (SHA-256 → `sha256:<hex>`), `createBlobFromData()`/`createBlobFromFile()` (HEAD-check + upload, skipping existing blobs), and one-shot `createModelFromGguf()` (upload GGUF shard blobs, then `/api/create` with `files: {name: digest}`).
36
+ - 📦 **Blob & Custom Model Publishing**: Content-addressed blob management per Ollama's documented protocol — `computeBlobDigest()` (SHA-256 → `sha256:<hex>`), `createBlobFromData()`/`createBlobFromFile()` (HEAD-check + upload, skipping existing blobs), and one-shot `createModelFromGguf()` (upload GGUF shard blobs, then `/api/create` with `files: {name: digest}`) — with **speculative-decoding assembly**: `draftGguf` uploads the draft network's shards into `draft_files`, `draft_quantize` compresses them independently, and `parameters.draft_num_predict` tunes the per-step draft length.
37
+ - 🧪 **In-Memory Mock Server (`@nemesis-oss/ollama-sdk/testing`)**: The SDK's own deterministic test double, promoted public — `createMockOllamaServer()` with scriptable NDJSON routes, built-in liveness/version defaults (so `ping()` works out of the box), request recording for wire-level assertions, mid-stream **in-band error injection** (`{"error": "..."}` frames at HTTP 200, exactly how a real daemon reports GPU OOM), connection drops, and correctly-shaped chunk builders for streaming text and **parallel tool calls** — zero network, zero daemon, CI-deterministic.
37
38
  - 🧵 **Batched Embeddings with Backpressure**: `client.embedBatch()` splits corpora of any size into bounded `/api/embed` batches (default 32 inputs × 3 in flight) — order-preserving, fail-fast, progress-reporting — so RAG/vector ingestion can't OOM a local daemon or saturate `OLLAMA_MAX_QUEUE` the way `Promise.all` floods do, with per-string context-window pre-flight against silent truncation.
38
39
  - 🧹 **Client Teardown (`destroy()`)**: One call aborts every in-flight request, active stream, and queued capacity waiter with `OllamaAbortError` — the clean-exit path for `worker_threads`, CLI runners, and short-lived scripts where dangling fetch bodies keep the event loop alive.
39
40
  - 🧠 **Dynamic Context-Window Discovery**: `client.models.getContextLength({ model })` resolves the real window from the server — the allocated window of the running instance (`/api/ps`), the Modelfile `num_ctx` default, and the native GGUF maximum (`model_info`), in precedence order — so applications stop hardcoding 2048/4096 guesses.
@@ -497,6 +498,45 @@ await client.models.createModelFromGguf('my-model', [
497
498
  ]);
498
499
  ```
499
500
 
501
+ ### Speculative Decoding (Draft Models)
502
+
503
+ Ollama packages speculative decoding as a small **draft network** whose token
504
+ guesses are batch-verified against the primary weights in a single forward
505
+ pass — the draft runs ahead, the primary model confirms. On the wire this is
506
+ `draft_files` (draft GGUF digests) + `draft_quantize` on `/api/create`, the
507
+ `draft_num_predict` Modelfile parameter, and the `draft_num_predict` runtime
508
+ option at generation time. The SDK covers the full flow:
509
+
510
+ ```typescript
511
+ // 1. Assemble: primary + draft shards, draft weights quantized independently
512
+ // (draft tokens are verified, never returned — aggressive compression is
513
+ // usually safe). Separate draft models default draft_num_predict to 4;
514
+ // 0 disables drafting; models with embedded MTP tensors require setting
515
+ // it explicitly.
516
+ await client.models.createModelFromGguf('my-model', '/models/model.gguf', {
517
+ draftGguf: '/models/draft.gguf',
518
+ draftQuantize: 'q8_0',
519
+ parameters: { draft_num_predict: 8 },
520
+ });
521
+
522
+ // 2. Generate with drafting (also available ad hoc via options at runtime)
523
+ const response = await client.chat({
524
+ model: 'my-model',
525
+ messages: [{ role: 'user', content: 'Describe a lighthouse in a storm.' }],
526
+ options: { draft_num_predict: 8 },
527
+ });
528
+
529
+ // 3. Measure the speedup with the standardized telemetry
530
+ const t = formatTelemetry(response);
531
+ console.log(`${t.tokensPerSecond} tok/s (load ${t.modelLoadMs}ms)`);
532
+ ```
533
+
534
+ Already have the draft blobs uploaded? Pass the digest map directly —
535
+ `createModel({ draft_files: { 'draft.gguf': digest } })` — or merge both
536
+ (path uploads win on basename collision). A live measurement harness
537
+ comparing `draft_num_predict` settings lives at
538
+ `lab/15-speculative-draft/measure-draft-speedup.ts`.
539
+
500
540
  ### Token Log Probabilities (`logprobs`)
501
541
 
502
542
  Set `logprobs: true` (optionally with `top_logprobs`) on `chat()`/`generate()` to get per-token log probabilities back — useful for confidence scoring, speculative decoding, or agent routing decisions.
@@ -681,6 +721,21 @@ const page = await client.webFetch({ url: 'https://ollama.com/blog' });
681
721
  console.log(page.title, page.content.slice(0, 200));
682
722
  ```
683
723
 
724
+ #### Web search agent
725
+
726
+ `createWebTools(client)` turns the two endpoints into `web_search` / `web_fetch` tools for `ToolRegistry`/`Agent` — the [search-agent pattern](https://docs.ollama.com/capabilities/web-search#building-a-search-agent) from the Ollama docs. Arguments are validated (`query` non-empty, `max_results` 1–10) before any network call, the abort signal propagates, and output is trimmed to `maxOutputChars` (default `2000 * 4`, as in the docs) while staying valid JSON:
727
+
728
+ ```typescript
729
+ import { Agent, ToolRegistry, createWebTools } from '@nemesis-oss/ollama-sdk';
730
+
731
+ const agent = new Agent(client, { tools: new ToolRegistry(createWebTools(client)) });
732
+ const { finalMessage } = await agent.run({
733
+ model: 'qwen3:4b',
734
+ messages: [{ role: 'user', content: "what is ollama's new engine" }],
735
+ think: true,
736
+ });
737
+ ```
738
+
684
739
  These two methods don't participate in the multi-endpoint failover below — there's only ever the one cloud host to call — but they do use the same default `timeoutMs` and retry policy as everything else.
685
740
 
686
741
  ### Cloud Usage & Balance (Ollama Cloud account)
@@ -925,9 +980,38 @@ await client.openai.chatCompletions({
925
980
  });
926
981
  ```
927
982
 
928
- `tool_choice` and `parallel_tool_calls` are also typed on the request so a standard
929
- OpenAI request object type-checks unmodified, but Ollama's compat layer does not honor
930
- either — see the `@remarks` on each field in `OpenAIChatCompletionRequest`.
983
+ Fields Ollama documents as **unsupported** — `tool_choice`, `logit_bias`, `user`, `n`
984
+ and logprobs on `/v1/chat/completions`; `best_of`, `echo`, `logit_bias`, `user`, `n` and
985
+ logprobs on `/v1/completions`; `user` and token inputs on `/v1/embeddings`;
986
+ `previous_response_id`, `conversation` and `truncation` on `/v1/responses`; `tool_choice`
987
+ and `metadata` on `/v1/messages` — stay typed on the broad `OpenAI*`/`Anthropic*` request
988
+ types so a standard request object type-checks unmodified, and are compile-time errors on
989
+ the strict `OllamaOpenAI*`/`OllamaAnthropicMessagesRequest` types. For token log
990
+ probabilities use native `chat()`/`generate()` with `logprobs: true`.
991
+
992
+ **Direct Ollama Cloud access** needs no local server — the bridges speak to
993
+ `https://ollama.com/v1/...` with `Authorization: Bearer` (the hosted Anthropic endpoint
994
+ rejects `x-api-key`-only auth; the SDK always sends the bearer header plus
995
+ `anthropic-version: 2023-06-01`):
996
+
997
+ ```typescript
998
+ const cloud = new OllamaClient({
999
+ baseUrl: 'https://ollama.com',
1000
+ apiKey: process.env.OLLAMA_API_KEY,
1001
+ });
1002
+ await cloud.openai.chatCompletions({
1003
+ model: 'gemma4:31b',
1004
+ messages: [{ role: 'user', content: 'Hi' }],
1005
+ });
1006
+ await cloud.anthropic.messages({
1007
+ model: 'gemma4:31b',
1008
+ max_tokens: 1024,
1009
+ messages: [{ role: 'user', content: 'Hi' }],
1010
+ });
1011
+ ```
1012
+
1013
+ The cloud API does not support stateful Responses, built-in web search through
1014
+ `/v1/responses`, or custom/freeform tool-call replay.
931
1015
 
932
1016
  ### Multi-Endpoint High Availability Failover
933
1017
 
@@ -1420,6 +1504,62 @@ windows: [...] })` directly with your own `windowMs`/`maxTokens`/`maxRequests` p
1420
1504
 
1421
1505
  ---
1422
1506
 
1507
+ ### Testing with the In-Memory Mock Server (`/testing`)
1508
+
1509
+ The SDK ships its own deterministic test double as a dedicated subpath —
1510
+ `@nemesis-oss/ollama-sdk/testing` — the same engine the SDK's own test suite
1511
+ runs against (ADR 0029: promote, don't fork). No daemon, no network, no GPU:
1512
+ scriptable NDJSON routes on a real `node:http` server, built-in defaults for
1513
+ the official liveness probe and `/api/version`, wire-level request recording,
1514
+ and failure injection that covers what static cassettes can't.
1515
+
1516
+ ```typescript
1517
+ import {
1518
+ createMockOllamaServer,
1519
+ mockTextChunks,
1520
+ mockToolCallChunks,
1521
+ } from '@nemesis-oss/ollama-sdk/testing';
1522
+ import { OllamaClient } from '@nemesis-oss/ollama-sdk';
1523
+
1524
+ const server = createMockOllamaServer(); // ephemeral port, defaults on
1525
+ await server.start();
1526
+ const client = new OllamaClient({ baseUrl: server.baseUrl });
1527
+
1528
+ // Defaults answer out of the box: HEAD / (ping) and GET /api/version.
1529
+ // Register everything else — register() always wins over the defaults.
1530
+ server.register('/api/chat', {
1531
+ chunks: mockToolCallChunks([
1532
+ // Parallel tool calls: one frame, complete calls — the native shape.
1533
+ { name: 'get_weather', arguments: { city: 'Tokyo' } },
1534
+ { name: 'get_time', arguments: { tz: 'Asia/Tokyo' } },
1535
+ ]),
1536
+ chunkDelayMs: 10, // inter-chunk backpressure testing
1537
+ });
1538
+
1539
+ // Mid-stream failure, GPU-OOM style: HTTP stays 200, the done frame is
1540
+ // replaced by an {"error": "..."} frame — the SDK raises OllamaStreamError.
1541
+ server.register('/api/generate', {
1542
+ chunks: mockTextChunks('partial answer', { chunkSize: 8 }),
1543
+ injectErrorFrame: { message: 'CUDA out of memory' }, // after: N to move it
1544
+ });
1545
+
1546
+ // ... run your code against the client ...
1547
+
1548
+ // Wire-level assertions: every request was recorded.
1549
+ expect(server.requests[0]?.body).toMatchObject({ model: 'llama3.2' });
1550
+ server.clearRequests(); // and server.clear() between tests
1551
+
1552
+ await server.stop(); // idempotent — safe in afterEach
1553
+ ```
1554
+
1555
+ Per-route controls: `status` (503/502/429 bodies), `chunkDelayMs`,
1556
+ `dropConnectionMidStream` (connection reset mid-response), `onRequest`
1557
+ (per-route body capture), and `injectErrorFrame.after` (error position).
1558
+ Chunk builders: `mockChatChunk` (one frame with counter defaults),
1559
+ `mockTextChunks` (chunked text + done frame), `mockToolCallChunks` (parallel
1560
+ tool calls + done frame). Node.js only — the subpath builds on `node:http`
1561
+ and is never imported from the Edge-safe main entry.
1562
+
1423
1563
  ### Edge Runtime Compatibility
1424
1564
 
1425
1565
  The core client (`OllamaClient`, `Agent`, `ToolRegistry`, and everything exported from
@@ -1,4 +1,4 @@
1
- import { O as OllamaRuntime, H as HttpClient, A as AbortableAsyncIterable, af as SseEvent, y as OllamaClientError } from './runtime-CIQYCRL3.js';
1
+ import { O as OllamaRuntime, H as HttpClient, A as AbortableAsyncIterable, af as SseEvent, y as OllamaClientError } from './runtime-BIjr5ME4.js';
2
2
 
3
3
  /**
4
4
  * AUTO-GENERATED by `npm run contract:generate`. DO NOT EDIT.
@@ -484,7 +484,7 @@ interface SystemOneChoiceAnswer {
484
484
  interface SystemOneChoiceQuestion {
485
485
  readonly type: 'choice';
486
486
  readonly instructions: SystemOneContent;
487
- /** Option keys mapped to descriptions. A null description uses the key itself. Keys must not be blank; ties follow the model's option order. */
487
+ /** Option keys mapped to descriptions, or null for a bare label. Keys must not be blank; ties follow the model's option order. The option limit depends on the model. */
488
488
  readonly criteria: {
489
489
  [key: string]: string | null;
490
490
  };
@@ -528,7 +528,7 @@ interface SystemOneNoulAnswer {
528
528
  interface SystemOneNoulQuestion {
529
529
  readonly type: 'noul';
530
530
  readonly instructions: SystemOneContent;
531
- /** Optional descriptions for the two outcomes. Omitted entries use No and Yes. */
531
+ /** Optional descriptions for the two outcomes. Omitted entries use model-specific defaults. */
532
532
  readonly criteria?: {
533
533
  readonly false?: string | undefined;
534
534
  readonly true?: string | undefined;
@@ -614,7 +614,7 @@ interface SystemOneScoreAnswer {
614
614
  interface SystemOneScoreQuestion {
615
615
  readonly type: 'score';
616
616
  readonly instructions: SystemOneContent;
617
- /** Descriptions ordered from the lowest score (index 0) to the highest. Defines a scale from 0 to the number of criteria minus 1. */
617
+ /** Descriptions ordered from the lowest score (index 0) to the highest. Defines a scale from 0 to the number of criteria minus 1. The maximum number of levels depends on the model. */
618
618
  readonly criteria: readonly string[];
619
619
  }
620
620
 
@@ -721,7 +721,7 @@ declare class NativeApi {
721
721
  chat(request: ChatRequest & {
722
722
  stream: true;
723
723
  }): Promise<AsyncGenerator<ChatResponse, void, undefined>>;
724
- copy(request: CopyRequest): Promise<unknown>;
724
+ copy(request: CopyRequest): Promise<StatusResponse>;
725
725
  create(request: CreateRequest & {
726
726
  stream?: false;
727
727
  }): Promise<StatusResponse>;
@@ -859,11 +859,18 @@ interface OpenAIChatCompletionRequest {
859
859
  readonly seed?: number | undefined;
860
860
  readonly presence_penalty?: number | undefined;
861
861
  readonly frequency_penalty?: number | undefined;
862
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
862
863
  readonly user?: string | undefined;
864
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
863
865
  readonly logit_bias?: Record<string, number> | undefined;
866
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
864
867
  readonly n?: number | undefined;
865
- /** Ollama exposes log probabilities for supported reasoning/chat models. */
868
+ /**
869
+ * @remarks Logprobs are documented as unsupported on Ollama's `/v1/chat/completions`.
870
+ * Use native `chat({ logprobs: true, top_logprobs })` for token log probabilities.
871
+ */
866
872
  readonly logprobs?: boolean | undefined;
873
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
867
874
  readonly top_logprobs?: number | undefined;
868
875
  readonly tools?: readonly OpenAITool[] | undefined;
869
876
  /**
@@ -895,18 +902,34 @@ interface OpenAIChatCompletionRequest {
895
902
  readonly effort?: OpenAIReasoningEffort | undefined;
896
903
  } | undefined;
897
904
  }
898
- /** Ollama Chat Completions supports text plus base64 image content via a string image URL. */
905
+ /** A base64 data URL (`data:image/png;base64,...`) — the only image form Ollama accepts here. */
906
+ type OllamaOpenAIImageDataUrl = `data:${string}`;
907
+ /** Ollama Chat Completions supports text plus base64 image content. */
899
908
  type OllamaOpenAIChatContentPart = OpenAITextContentPart | {
900
909
  readonly type: 'image_url';
901
- /** Ollama's current compatibility docs accept an image URL string, including data URLs. */
902
- readonly image_url: string;
910
+ /**
911
+ * A base64 `data:` URL, as a string or inside the OpenAI `{ url, detail? }` object.
912
+ * Ollama documents remote image URLs as unsupported on `/v1/chat/completions`, so
913
+ * `http(s)://` URLs are a compile error here; resolve remote images to base64 first
914
+ * (e.g. with {@link resolveImageInput}) or use the native `images` field.
915
+ */
916
+ readonly image_url: OllamaOpenAIImageDataUrl | {
917
+ readonly url: OllamaOpenAIImageDataUrl;
918
+ readonly detail?: 'auto' | 'low' | 'high' | 'original' | undefined;
919
+ };
903
920
  };
904
921
  type OllamaOpenAIReasoningEffort = 'high' | 'medium' | 'low' | 'max' | 'none';
905
922
  type OllamaOpenAIChatMessage = Omit<OpenAIMessage, 'content'> & {
906
923
  readonly content: string | readonly OllamaOpenAIChatContentPart[];
907
924
  };
908
- /** Strict Ollama-documented Chat Completions request; excludes only the SDK-only parallel tool flag. */
909
- type OllamaOpenAIChatCompletionRequest = Omit<OpenAIChatCompletionRequest, 'messages' | 'parallel_tool_calls' | 'reasoning_effort' | 'reasoning'> & {
925
+ /**
926
+ * Strict Ollama-documented Chat Completions request. Excludes the fields
927
+ * https://docs.ollama.com/api/openai-compatibility marks unsupported (`tool_choice`,
928
+ * `logit_bias`, `user`, `n`, `logprobs`/`top_logprobs`) and the SDK-only
929
+ * `parallel_tool_calls` flag, so passing any of them is a compile-time error instead of
930
+ * a silently ignored request field.
931
+ */
932
+ type OllamaOpenAIChatCompletionRequest = Omit<OpenAIChatCompletionRequest, 'messages' | 'parallel_tool_calls' | 'reasoning_effort' | 'reasoning' | 'tool_choice' | 'logit_bias' | 'user' | 'n' | 'logprobs' | 'top_logprobs'> & {
910
933
  readonly messages: readonly OllamaOpenAIChatMessage[];
911
934
  readonly reasoning_effort?: OllamaOpenAIReasoningEffort | undefined;
912
935
  readonly reasoning?: {
@@ -985,7 +1008,10 @@ interface OpenAICompletionRequest {
985
1008
  readonly model: string;
986
1009
  /** Ollama currently accepts a string prompt for /v1/completions. */
987
1010
  readonly prompt: string;
988
- /** Number of log probability alternatives requested for completion tokens. */
1011
+ /**
1012
+ * @remarks Logprobs are documented as unsupported on Ollama's `/v1/completions`. Use
1013
+ * native `generate({ logprobs: true, top_logprobs })` for token log probabilities.
1014
+ */
989
1015
  readonly logprobs?: number | undefined;
990
1016
  readonly frequency_penalty?: number | undefined;
991
1017
  readonly presence_penalty?: number | undefined;
@@ -997,14 +1023,23 @@ interface OpenAICompletionRequest {
997
1023
  readonly top_p?: number | undefined;
998
1024
  readonly max_tokens?: number | undefined;
999
1025
  readonly suffix?: string | undefined;
1026
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
1000
1027
  readonly best_of?: number | undefined;
1028
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
1001
1029
  readonly echo?: boolean | undefined;
1030
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
1002
1031
  readonly logit_bias?: Record<string, number> | undefined;
1032
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
1003
1033
  readonly user?: string | undefined;
1034
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
1004
1035
  readonly n?: number | undefined;
1005
1036
  }
1006
1037
  /** Strict Ollama-documented Completions request. */
1007
- type OllamaOpenAICompletionRequest = OpenAICompletionRequest;
1038
+ /**
1039
+ * Strict Ollama-documented Completions request: excludes `best_of`, `echo`,
1040
+ * `logit_bias`, `user`, `n`, and `logprobs`, which Ollama documents as unsupported.
1041
+ */
1042
+ type OllamaOpenAICompletionRequest = Omit<OpenAICompletionRequest, 'best_of' | 'echo' | 'logit_bias' | 'user' | 'n' | 'logprobs'>;
1008
1043
  interface OpenAICompletionChoice {
1009
1044
  readonly text: string;
1010
1045
  readonly index: number;
@@ -1044,10 +1079,18 @@ interface OpenAIEmbeddingRequest {
1044
1079
  readonly input: OpenAIEmbeddingInput;
1045
1080
  readonly encoding_format?: 'float' | 'base64' | undefined;
1046
1081
  readonly dimensions?: number | undefined;
1082
+ /** @remarks Documented as unsupported by Ollama — accepted for OpenAI interop, ignored by the server. */
1047
1083
  readonly user?: string | undefined;
1048
1084
  }
1049
1085
  /** Strict Ollama-documented Embeddings request. */
1050
- type OllamaOpenAIEmbeddingRequest = OpenAIEmbeddingRequest;
1086
+ /**
1087
+ * Strict Ollama-documented Embeddings request: `input` is a string or an array of
1088
+ * strings (token and token-array inputs are documented as unsupported), and `user` is
1089
+ * excluded.
1090
+ */
1091
+ type OllamaOpenAIEmbeddingRequest = Omit<OpenAIEmbeddingRequest, 'input' | 'user'> & {
1092
+ readonly input: string | readonly string[];
1093
+ };
1051
1094
  interface OpenAIEmbeddingItem {
1052
1095
  readonly object: 'embedding';
1053
1096
  readonly embedding: readonly number[] | string;
@@ -1084,6 +1127,7 @@ interface OpenAIResponsesRequest {
1084
1127
  readonly previous_response_id?: string | undefined;
1085
1128
  /** @remarks Not supported by Ollama, which is stateless across calls — accepted but ignored. */
1086
1129
  readonly conversation?: string | undefined;
1130
+ /** @remarks Documented as unsupported by Ollama — accepted but ignored. */
1087
1131
  readonly truncation?: string | undefined;
1088
1132
  readonly reasoning?: {
1089
1133
  readonly effort?: OpenAIReasoningEffort | undefined;
@@ -1091,9 +1135,12 @@ interface OpenAIResponsesRequest {
1091
1135
  /** Ollama extension: boolean, model-defined string, or null for model default. */
1092
1136
  readonly think?: boolean | string | null | undefined;
1093
1137
  }
1094
- /** Strict Ollama-documented Responses request; excludes stateful and SDK-only request fields. */
1095
- /** Strict Ollama-documented Responses request; excludes only unsupported stateful fields. */
1096
- type OllamaOpenAIResponsesRequest = Omit<OpenAIResponsesRequest, 'previous_response_id' | 'conversation'>;
1138
+ /**
1139
+ * Strict Ollama-documented Responses request: excludes the stateful fields
1140
+ * (`previous_response_id`, `conversation`) and `truncation`, which Ollama documents as
1141
+ * unsupported.
1142
+ */
1143
+ type OllamaOpenAIResponsesRequest = Omit<OpenAIResponsesRequest, 'previous_response_id' | 'conversation' | 'truncation'>;
1097
1144
  type OpenAIResponsesStatus = 'completed' | 'failed' | 'in_progress' | 'cancelled' | 'queued' | 'incomplete';
1098
1145
  interface OpenAIResponsesError {
1099
1146
  readonly code?: string | undefined;
@@ -1646,4 +1693,4 @@ declare class AnthropicCompatClient {
1646
1693
  messages(request: AnthropicMessagesRequest, signal?: AbortSignal): Promise<AnthropicMessagesResponse | AnthropicMessagesStream>;
1647
1694
  }
1648
1695
 
1649
- export { type OllamaAnthropicThinkingConfig as $, type AnthropicMessagesRequest as A, type AnthropicImageContentBlock as B, type AnthropicMessage as C, AnthropicMessagesStream as D, type AnthropicMetadata as E, type AnthropicOutputConfig as F, type AnthropicRedactedThinkingContentBlock as G, type AnthropicSystem as H, type AnthropicSystemTextBlock as I, type AnthropicTextContentBlock as J, type AnthropicThinkingConfig as K, type AnthropicThinkingContentBlock as L, type AnthropicTool as M, NativeApi as N, type OpenAIChatCompletionRequest as O, type AnthropicToolChoice as P, type AnthropicToolResultContentBlock as Q, type RequestRunner as R, type SystemOneChoiceAnswer as S, type AnthropicToolUseContentBlock as T, type AnthropicUnknownStreamEvent as U, type OllamaAnthropicContentBlock as V, type OllamaAnthropicMessage as W, type OllamaAnthropicMessagesRequest as X, type OllamaAnthropicSystem as Y, type OllamaAnthropicSystemTextBlock as Z, type OllamaAnthropicTextContentBlock as _, type OpenAIChatCompletionResponse as a, type SystemOneConfidence as a$, type OllamaAnthropicTool as a0, type OllamaAnthropicToolResultContentBlock as a1, type OllamaOpenAIChatCompletionRequest as a2, type OllamaOpenAICompletionRequest as a3, type OllamaOpenAIEmbeddingRequest as a4, type OllamaOpenAIReasoningEffort as a5, type OllamaOpenAIResponsesRequest as a6, type OpenAIChatCompletionChoice as a7, type OpenAIChatCompletionChunkChoice as a8, type OpenAIChatCompletionDelta as a9, type OpenAIResponsesOutputItemAddedEvent as aA, type OpenAIResponsesOutputItemDoneEvent as aB, type OpenAIResponsesOutputMessage as aC, type OpenAIResponsesOutputReasoning as aD, type OpenAIResponsesOutputRefusal as aE, type OpenAIResponsesOutputTextContent as aF, type OpenAIResponsesOutputTextDeltaEvent as aG, type OpenAIResponsesOutputTextDoneEvent as aH, type OpenAIResponsesQueuedEvent as aI, type OpenAIResponsesReasoningSummaryPartAddedEvent as aJ, type OpenAIResponsesReasoningSummaryPartDoneEvent as aK, type OpenAIResponsesReasoningSummaryTextDeltaEvent as aL, type OpenAIResponsesReasoningSummaryTextDoneEvent as aM, type OpenAIResponsesReasoningTextDeltaEvent as aN, type OpenAIResponsesReasoningTextDoneEvent as aO, type OpenAIResponsesRefusalDeltaEvent as aP, type OpenAIResponsesRefusalDoneEvent as aQ, type OpenAIResponsesStatus as aR, OpenAIResponsesStream as aS, OpenAIResponsesStreamError as aT, type OpenAIResponsesUsage as aU, type OpenAIStreamOptions as aV, type OpenAITextContentPart as aW, type OpenAITool as aX, type OpenAIToolCall as aY, type OpenAIToolCallDelta as aZ, type OpenAIUsage as a_, OpenAIChatCompletionStream as aa, type OpenAICompletionChoice as ab, OpenAICompletionStream as ac, type OpenAIContentPart as ad, type OpenAIEmbeddingInput as ae, type OpenAIEmbeddingItem as af, type OpenAIFunctionDefinition as ag, type OpenAIImageUrlContentPart as ah, type OpenAIMessage as ai, type OpenAIReasoningEffort as aj, type OpenAIResponseFormat as ak, type OpenAIResponsesCompletedEvent as al, type OpenAIResponsesContentPartAddedEvent as am, type OpenAIResponsesContentPartDoneEvent as an, type OpenAIResponsesCreatedEvent as ao, type OpenAIResponsesError as ap, type OpenAIResponsesEventBase as aq, type OpenAIResponsesFailedEvent as ar, type OpenAIResponsesFunctionCallArgumentsDeltaEvent as as, type OpenAIResponsesFunctionCallArgumentsDoneEvent as at, type OpenAIResponsesInProgressEvent as au, type OpenAIResponsesIncompleteDetails as av, type OpenAIResponsesIncompleteEvent as aw, type OpenAIResponsesOutputContent as ax, type OpenAIResponsesOutputFunctionCall as ay, type OpenAIResponsesOutputItem as az, type OpenAIChatCompletionChunk as b, type SystemOneProbabilities as b0, type OpenAICompletionRequest as c, type OpenAICompletionResponse as d, type OpenAICompletionChunk as e, type OpenAIEmbeddingRequest as f, type OpenAIEmbeddingResponse as g, type OpenAIListModelsResponse as h, type OpenAIModelItem as i, type OpenAIResponsesRequest as j, type OpenAIResponsesResponse as k, type OpenAIResponsesStreamEvent as l, type AnthropicMessagesResponse as m, type AnthropicMessageStreamEvent as n, type SystemOneNoulAnswer as o, type SystemOneScoreAnswer as p, type SystemOneChoiceQuestion as q, type SystemOneNoulQuestion as r, type SystemOneScoreQuestion as s, type SystemOneRequest as t, type SystemOneResponse as u, type SystemOneContent as v, OpenAICompatClient as w, AnthropicCompatClient as x, type AnthropicCacheControl as y, type AnthropicContentBlock as z };
1696
+ export { type OllamaAnthropicThinkingConfig as $, type AnthropicMessagesRequest as A, type AnthropicImageContentBlock as B, type AnthropicMessage as C, AnthropicMessagesStream as D, type AnthropicMetadata as E, type AnthropicOutputConfig as F, type AnthropicRedactedThinkingContentBlock as G, type AnthropicSystem as H, type AnthropicSystemTextBlock as I, type AnthropicTextContentBlock as J, type AnthropicThinkingConfig as K, type AnthropicThinkingContentBlock as L, type AnthropicTool as M, NativeApi as N, type OpenAIChatCompletionRequest as O, type AnthropicToolChoice as P, type AnthropicToolResultContentBlock as Q, type RequestRunner as R, type SystemOneChoiceAnswer as S, type AnthropicToolUseContentBlock as T, type AnthropicUnknownStreamEvent as U, type OllamaAnthropicContentBlock as V, type OllamaAnthropicMessage as W, type OllamaAnthropicMessagesRequest as X, type OllamaAnthropicSystem as Y, type OllamaAnthropicSystemTextBlock as Z, type OllamaAnthropicTextContentBlock as _, type OpenAIChatCompletionResponse as a, type OpenAIToolCall as a$, type OllamaAnthropicTool as a0, type OllamaAnthropicToolResultContentBlock as a1, type OllamaOpenAIChatCompletionRequest as a2, type OllamaOpenAIChatContentPart as a3, type OllamaOpenAIChatMessage as a4, type OllamaOpenAICompletionRequest as a5, type OllamaOpenAIEmbeddingRequest as a6, type OllamaOpenAIImageDataUrl as a7, type OllamaOpenAIReasoningEffort as a8, type OllamaOpenAIResponsesRequest as a9, type OpenAIResponsesOutputContent as aA, type OpenAIResponsesOutputFunctionCall as aB, type OpenAIResponsesOutputItem as aC, type OpenAIResponsesOutputItemAddedEvent as aD, type OpenAIResponsesOutputItemDoneEvent as aE, type OpenAIResponsesOutputMessage as aF, type OpenAIResponsesOutputReasoning as aG, type OpenAIResponsesOutputRefusal as aH, type OpenAIResponsesOutputTextContent as aI, type OpenAIResponsesOutputTextDeltaEvent as aJ, type OpenAIResponsesOutputTextDoneEvent as aK, type OpenAIResponsesQueuedEvent as aL, type OpenAIResponsesReasoningSummaryPartAddedEvent as aM, type OpenAIResponsesReasoningSummaryPartDoneEvent as aN, type OpenAIResponsesReasoningSummaryTextDeltaEvent as aO, type OpenAIResponsesReasoningSummaryTextDoneEvent as aP, type OpenAIResponsesReasoningTextDeltaEvent as aQ, type OpenAIResponsesReasoningTextDoneEvent as aR, type OpenAIResponsesRefusalDeltaEvent as aS, type OpenAIResponsesRefusalDoneEvent as aT, type OpenAIResponsesStatus as aU, OpenAIResponsesStream as aV, OpenAIResponsesStreamError as aW, type OpenAIResponsesUsage as aX, type OpenAIStreamOptions as aY, type OpenAITextContentPart as aZ, type OpenAITool as a_, type OpenAIChatCompletionChoice as aa, type OpenAIChatCompletionChunkChoice as ab, type OpenAIChatCompletionDelta as ac, OpenAIChatCompletionStream as ad, type OpenAICompletionChoice as ae, OpenAICompletionStream as af, type OpenAIContentPart as ag, type OpenAIEmbeddingInput as ah, type OpenAIEmbeddingItem as ai, type OpenAIFunctionDefinition as aj, type OpenAIImageUrlContentPart as ak, type OpenAIMessage as al, type OpenAIReasoningEffort as am, type OpenAIResponseFormat as an, type OpenAIResponsesCompletedEvent as ao, type OpenAIResponsesContentPartAddedEvent as ap, type OpenAIResponsesContentPartDoneEvent as aq, type OpenAIResponsesCreatedEvent as ar, type OpenAIResponsesError as as, type OpenAIResponsesEventBase as at, type OpenAIResponsesFailedEvent as au, type OpenAIResponsesFunctionCallArgumentsDeltaEvent as av, type OpenAIResponsesFunctionCallArgumentsDoneEvent as aw, type OpenAIResponsesInProgressEvent as ax, type OpenAIResponsesIncompleteDetails as ay, type OpenAIResponsesIncompleteEvent as az, type OpenAIChatCompletionChunk as b, type OpenAIToolCallDelta as b0, type OpenAIUsage as b1, type SystemOneConfidence as b2, type SystemOneProbabilities as b3, type OpenAICompletionRequest as c, type OpenAICompletionResponse as d, type OpenAICompletionChunk as e, type OpenAIEmbeddingRequest as f, type OpenAIEmbeddingResponse as g, type OpenAIListModelsResponse as h, type OpenAIModelItem as i, type OpenAIResponsesRequest as j, type OpenAIResponsesResponse as k, type OpenAIResponsesStreamEvent as l, type AnthropicMessagesResponse as m, type AnthropicMessageStreamEvent as n, type SystemOneNoulAnswer as o, type SystemOneScoreAnswer as p, type SystemOneChoiceQuestion as q, type SystemOneNoulQuestion as r, type SystemOneScoreQuestion as s, type SystemOneRequest as t, type SystemOneResponse as u, type SystemOneContent as v, OpenAICompatClient as w, AnthropicCompatClient as x, type AnthropicCacheControl as y, type AnthropicContentBlock as z };