@fgv/ts-extras-ollama 5.1.0-55 → 5.1.0-56

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 (2) hide show
  1. package/CAPABILITIES.md +52 -0
  2. package/package.json +13 -12
@@ -0,0 +1,52 @@
1
+ # `@fgv/ts-extras-ollama` — native Ollama sidecar Result boundary
2
+
3
+ > **This file is authoritative for what ``@fgv/ts-extras-ollama`` provides and what not to hand-roll.**
4
+ > `README.md`, where present, is getting-started material. The always-loaded index at
5
+ > [`.ai/instructions/LIBRARY_CAPABILITIES.md`](../../.ai/instructions/LIBRARY_CAPABILITIES.md)
6
+ > routes here; it never duplicates this content.
7
+
8
+
9
+ ---
10
+
11
+ [libraries/ts-extras-ollama](https://github.com/ErikFortune/fgv/tree/release/libraries/ts-extras-ollama)
12
+
13
+ **A Result-integration boundary over the official [`ollama`](https://github.com/ollama/ollama-js) JS library — owning ONLY the native-API surface the OpenAI-compat `/v1` endpoint cannot express.** Node-only at v0.1. The text-completion / streaming / tool-use path is **NOT** here — `@fgv/ts-extras/ai-assist` owns it via the `/v1` compat layer (point a provider descriptor's `endpoint` at `http://localhost:11434/v1` and call `callProviderCompletion` / `callProviderCompletionStream` / `executeClientToolTurn`). This package is the *native-only* complement: model management, streamed pulls, and grammar-constrained structured output.
14
+
15
+ `createOllamaClient({ host?, fetch?, headers? })` returns `Result<IOllamaClient>` (the opaque upstream `Ollama` handle, re-exported — anything not wrapped here is reachable on it directly). Every primitive is client-first and returns `Promise<Result<T>>`:
16
+
17
+ | Primitive | Wraps | Returns |
18
+ |---|---|---|
19
+ | `listModels(client)` | `GET /api/tags` | `ReadonlyArray<IOllamaModel>` — GGUF `size`/`family`/`parameterSize`/`quantizationLevel`/`modifiedAt` the `/v1/models` list can't give. |
20
+ | `listRunning(client)` | `GET /api/ps` | `ReadonlyArray<IOllamaRunningModel>` — loaded models + `sizeVram` + `expiresAt`. |
21
+ | `showModel(client, model, { verbose? })` | `POST /api/show` | `IOllamaModelInfo` — `modelfile`/`parameters`/`template`/`capabilities`/`modelInfo`. |
22
+ | `deleteModel(client, model)` | `DELETE /api/delete` | `IOllamaDeleteResult` (`{ model, deleted: true }` — not `Result<void>`). |
23
+ | `pullModel(client, { model, insecure?, onProgress?, signal? })` | `POST /api/pull` (streamed) | `IOllamaPullResult` (`{ model, finalStatus, chunkCount }`). Drives the JSON-lines progress stream internally; `onProgress` fires per chunk; the terminal `Result` resolves when the stream ends. `AbortSignal` cancels the in-flight download. |
24
+ | `chatStructured<T>(client, { model, messages, schema, options?, keepAlive?, signal? })` | `POST /api/chat` with `format` | `IOllamaChatStructuredResult<T>` (`{ value, raw, model, doneReason? }`). |
25
+
26
+ **The headline win — `chatStructured` no-drift, grammar-constrained output.** `schema` is a `JsonSchema.ISchemaValidator<T>` (`JsonSchema.object(...)` from `@fgv/ts-json-base`). The SAME object is BOTH the wire `format` (`schema.toJson()`, draft-07-sanitized to strip `$schema`/`additionalProperties` per the Gemini precedent) AND the reply validator (`schema.validate()`) — they cannot drift. `T` is derived via `JsonSchema.Static<typeof schema>` — no caller-supplied `T`, no cast. Ollama constrains the token sampler to the schema, so the reply is structurally guaranteed to match (a stronger guarantee than ai-assist's prompt-and-parse `generateJsonCompletion`, which asks-and-parses). `chatStructured` runs over the streaming chat path internally (the only path the `ollama` lib lets an `AbortSignal` cancel) and validates the assembled document whole.
27
+
28
+ **Dependency posture (mirrors `@fgv/ts-extras-transformers`):** `ollama` is a **peer + dev** dependency (bring your own pinned version); `@fgv/ts-utils` is **peer + dev** (consumer-provided, not installed transitively); only `@fgv/ts-json-base` is a hard **dependency** (`chatStructured` consumes `JsonSchema` as a first-class surface type).
29
+
30
+ **Explicitly NOT in scope:** text completion / chat / streaming (ai-assist via `/v1`); browser / CORS (`ollama/browser` + `OLLAMA_ORIGINS` — a future `@fgv/ts-web-extras-ollama` sibling); model authoring (`push`/`create`/`copy`); `keep_alive`/lifecycle policy (pass-through only); pull-progress UI; multi-host orchestration / pooling / retries; native tool-calling on `/api/chat` (ai-assist owns tool turns). **Native embeddings (`embed`) are CUT** — resolved by the `ai-assist-embeddings` design (OQ-1): Ollama embeddings are reachable via `/v1/embeddings` and are owned by `AiAssist.callProviderEmbedding` (the `ollama` descriptor's `baseUrl` already targets `http://localhost:11434/v1` — pass the embedding model via `modelOverride`, and use the per-call `endpoint` override for a non-default host). Native `/api/embed` adds only marginal diagnostics (`total_duration`/`prompt_eval_count`) not worth a parallel path; revisit additively only if a concrete consumer needs them.
31
+
32
+ **Upstream:** `ollama` `^0.6.0` (peer dependency).
33
+
34
+ ---
35
+
36
+ ---
37
+
38
+ ## Decision shortcuts
39
+
40
+ - **Managing a local Ollama sidecar — listing / inspecting / pulling / deleting models, or grammar-constrained structured output?** → `@fgv/ts-extras-ollama` (Node-only). `createOllamaClient({ host? })` → `Result<IOllamaClient>`, then `listModels` / `listRunning` / `showModel` / `deleteModel` (model management the `/v1` layer can't express), `pullModel({ model, onProgress?, signal? })` (streamed download progress → terminal `Result`), and **`chatStructured<T>({ model, messages, schema, signal? })`** for grammar-constrained JSON: the `JsonSchema.object(...)` schema is BOTH the wire `format` (draft-07-sanitized) AND the `schema.validate()` reply validator — one declaration, no drift, `T` derived via `JsonSchema.Static`. **For text completion / streaming / tool-use against the same daemon, this is the WRONG package — use `@fgv/ts-extras/ai-assist` with a provider `endpoint` of `http://localhost:11434/v1`.** Native `embed` is **CUT** — Ollama embeddings are owned by `AiAssist.callProviderEmbedding` via `/v1/embeddings` (see the "text → vector" decision shortcut and OQ-1), not this package. `ollama` is a peer dependency.
41
+
42
+ ---
43
+
44
+ ## Recent additions
45
+
46
+ *Newest first. **Generated** — see the repo index; do not hand-edit inside the markers.*
47
+
48
+ <!-- BEGIN GENERATED: recent-additions -->
49
+
50
+ - **2026-06-06** — Shipped first-class Ollama support across two activities. ([#468](https://github.com/ErikFortune/fgv/pull/468))
51
+
52
+ <!-- END GENERATED: recent-additions -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-extras-ollama",
3
- "version": "5.1.0-55",
3
+ "version": "5.1.0-56",
4
4
  "description": "Result-integration boundary over the ollama JS library for Node consumers (model management, streamed pull progress, grammar-constrained structured output)",
5
5
  "main": "lib/index.js",
6
6
  "types": "dist/ts-extras-ollama.d.ts",
@@ -22,6 +22,7 @@
22
22
  "dist",
23
23
  "CHANGELOG.json",
24
24
  "README.md",
25
+ "CAPABILITIES.md",
25
26
  "LICENSE",
26
27
  "!lib/test",
27
28
  "!dist/test",
@@ -46,17 +47,17 @@
46
47
  },
47
48
  "sideEffects": false,
48
49
  "dependencies": {
49
- "@fgv/ts-json-base": "5.1.0-55"
50
+ "@fgv/ts-json-base": "5.1.0-56"
50
51
  },
51
52
  "devDependencies": {
52
53
  "ollama": "^0.6.0",
53
54
  "@microsoft/api-extractor": "^7.55.2",
54
55
  "@rushstack/eslint-config": "4.6.4",
55
- "@rushstack/heft": "1.2.7",
56
- "@rushstack/heft-jest-plugin": "1.2.6",
57
- "@rushstack/heft-node-rig": "2.11.27",
56
+ "@rushstack/heft": "1.3.0",
57
+ "@rushstack/heft-jest-plugin": "2.0.17",
58
+ "@rushstack/heft-node-rig": "2.11.50",
58
59
  "@types/heft-jest": "1.0.6",
59
- "@types/jest": "^29.5.14",
60
+ "@types/jest": "^30.0.0",
60
61
  "@types/node": "^20.14.9",
61
62
  "@typescript-eslint/eslint-plugin": "^8.52.0",
62
63
  "@typescript-eslint/parser": "^8.52.0",
@@ -66,18 +67,18 @@
66
67
  "eslint-plugin-node": "^11.1.0",
67
68
  "eslint-plugin-promise": "^7.2.1",
68
69
  "eslint-plugin-tsdoc": "~0.5.2",
69
- "jest": "^29.7.0",
70
+ "jest": "^30.5.2",
70
71
  "rimraf": "^6.1.2",
71
- "ts-jest": "^29.4.6",
72
+ "ts-jest": "^29.4.12",
72
73
  "ts-node": "^10.9.2",
73
74
  "typescript": "5.9.3",
74
- "@fgv/heft-dual-rig": "5.1.0-55",
75
- "@fgv/ts-utils-jest": "5.1.0-55",
76
- "@fgv/ts-utils": "5.1.0-55"
75
+ "@fgv/heft-dual-rig": "5.1.0-56",
76
+ "@fgv/ts-utils": "5.1.0-56",
77
+ "@fgv/ts-utils-jest": "5.1.0-56"
77
78
  },
78
79
  "peerDependencies": {
79
80
  "ollama": "^0.6.0",
80
- "@fgv/ts-utils": "5.1.0-55"
81
+ "@fgv/ts-utils": "5.1.0-56"
81
82
  },
82
83
  "scripts": {
83
84
  "build": "heft build --clean",