@fgv/ts-extras-transformers 5.1.0-55 → 5.1.0-57

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 +55 -0
  2. package/package.json +12 -11
@@ -0,0 +1,55 @@
1
+ # `@fgv/ts-extras-transformers` + `@fgv/ts-web-extras-transformers` — local transformers (HuggingFace) Result boundary
2
+
3
+ > **This file is authoritative for what ``@fgv/ts-extras-transformers`` 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-transformers](https://github.com/ErikFortune/fgv/tree/release/libraries/ts-extras-transformers)
12
+ [libraries/ts-web-extras-transformers](https://github.com/ErikFortune/fgv/tree/release/libraries/ts-web-extras-transformers)
13
+
14
+ **A Result-integration boundary over `@huggingface/transformers` (transformers.js) for running models locally — not an opinionated ML helper.** Like the WebAuthn pair, these add exactly one thing: thin `captureAsyncResult` wrappers that convert the upstream throw-on-failure calls into `Promise<Result<T>>`, with **no opinionated orchestration** (no pipeline cache, no model-download management, no device/quantization policy). The two packages expose an **identical surface**; pick the package at the composition root — Node uses the native ONNX backend, browser uses the WASM/WebGPU backend.
15
+
16
+ | Package | Function | Return |
17
+ |---|---|---|
18
+ | both | `loadPipeline(task, model?, options?)` | `Promise<Result<AllTasks[T]>>` (the upstream pipeline instance) |
19
+ | both | `classify(classifier, text, options?)` | `Promise<Result<TextClassificationOutput>>` (upstream default / top label unless `options.top_k` set) |
20
+ | both | `classifyAll(classifier, text, options?)` | `Promise<Result<TextClassificationOutput>>` — forces `top_k: null`, so the **full per-label vector** is returned; use when you compare every label against thresholds |
21
+ | both | `embed(extractor, text, options?)` | `Promise<Result<Tensor>>` — raw upstream `Tensor`, no pooling/normalisation applied (pass `{ pooling: 'mean', normalize: true }` via `options` for a sentence vector; extract a JS array with the Tensor's `.tolist()`) |
22
+ | both | `summarize(summarizer, text, options?)` | `Promise<Result<SummarizationOutput>>` — `[{ summary_text }]`; pass `min_length`/`max_length`/`max_new_tokens` via `options`. Local cheap/fast path vs. a frontier LLM for simple/medium inputs |
23
+
24
+ `Tensor`, `TextClassificationPipeline`, `TextClassificationOutput`, `FeatureExtractionPipeline`, `SummarizationPipeline`, `SummarizationOutput`, `AllTasks`, `PipelineType` are re-exported from both packages. Get an extractor via `loadPipeline('feature-extraction', modelId)`, a classifier via `loadPipeline('text-classification', modelId)`, a summarizer via `loadPipeline('summarization', modelId)`.
25
+
26
+ **Explicitly NOT in scope:** pipeline cache / lifecycle / dispose, model registry or download management, GPU/CPU/WebGPU device-selection policy, quantization selection, embedding-store integration, classifier label allowlists, request batching, IndexedDB cache configuration. `generate` (text generation) is deferred until a concrete consumer needs it. For any of these, use `@huggingface/transformers` directly with `captureAsyncResult`.
27
+
28
+ **Consuming from a dual web/CLI bundle (load-bearing pattern):** when one module is reachable from a browser bundle, keep your reusable core **facade-agnostic** — take the facade function (`classify`/`classifyAll`/`embed`) as an injected parameter and import facade types as `import type` only (erased, so no runtime facade enters the bundle). Import the **browser** facade on the web path; load the **Node** facade on the CLI path via `import(/* webpackIgnore: true */ '@fgv/ts-extras-transformers')` so its node-native deps never reach the browser graph. Validate the browser bundle with the real bundler (`webpack`/etc.) — type-check + jsdom tests do not exercise it. The `samples/testbed` `local-classifier-safety` and `local-embedding-search` scenarios are the reference consumers.
29
+
30
+ **Upstream:** `@huggingface/transformers` `~4.2.0` (a **peer dependency** of both packages — bring your own; `skipLibCheck` is required for its type definitions).
31
+
32
+ ---
33
+
34
+ ---
35
+
36
+ ## Decision shortcuts
37
+
38
+ - **Running a HuggingFace model locally (text classification / embeddings / summarization) with a Result boundary?** → `loadPipeline` + `classify` / `classifyAll` / `embed` / `summarize` from `@fgv/ts-extras-transformers` (Node) or `@fgv/ts-web-extras-transformers` (browser). Thin `Result`-wrapped facade over `@huggingface/transformers` — no caching/device/quantization policy (use the upstream lib directly for that). Use `classifyAll` when you need the full per-label vector (it bakes in `top_k: null`); `embed` returns the raw `Tensor` (pass `{ pooling: 'mean', normalize: true }` for a sentence vector). **In a browser bundle, keep your core facade-agnostic (inject the fn, type-only imports) and load the Node facade only via `import(/* webpackIgnore: true */ ...)` on the CLI path** — see the `samples/testbed` `local-classifier-safety` / `local-embedding-search` / `local-summarization` scenarios.
39
+ - **Summarizing text locally (cheap/fast, small model) vs. in the cloud?** → **local:** `summarize` from `@fgv/ts-extras-transformers` (e.g. `loadPipeline('summarization', 'Xenova/distilbart-cnn-6-6')`) — the cheap/fast/offline path for simple/medium inputs. **Cloud (quality on long/complex docs):** a completion via `@fgv/ts-extras/ai-assist`. The escalation policy (when to defer to the cloud) is the consumer's, not the facade's.
40
+ - **Need a text embedding (`text → vector`)?** Three paths; pick by where the weights run:
41
+ - **In-process / local / offline (you own the model lifecycle)** — on-device RAG pre-filter, privacy-sensitive, zero per-call cost → `embed` / `loadPipeline('feature-extraction', …)` from **`@fgv/ts-extras-transformers`** (Node) or **`@fgv/ts-web-extras-transformers`** (browser). Returns a raw `Tensor` (pass `{ pooling: 'mean', normalize: true }` for a sentence vector). You manage model download / cache / device / quantization.
42
+ - **Cross-provider cloud HTTP** — OpenAI `text-embedding-3-*`, Gemini `gemini-embedding-001`, Mistral `mistral-embed`, **or a self-hosted OpenAI-compatible / Ollama server via the `endpoint` override** → `AiAssist.callProviderEmbedding` from **`@fgv/ts-extras/ai-assist`**. Batch in, `number[][]` out, `Result`-wrapped, descriptor-driven. **This is also the Ollama answer** — point it at `http://localhost:11434/v1`; there is no separate Ollama-native embedding API (the `@fgv/ts-extras-ollama` native `embed` was cut — see OQ-1).
43
+ - One-line mental model: **`@fgv/ts-extras-transformers` = the weights run in *your* process; `callProviderEmbedding` = the weights run on *a server you `fetch`*.** Same local-vs-distant split as completion.
44
+
45
+ ---
46
+
47
+ ## Recent additions
48
+
49
+ *Newest first. **Generated** — see the repo index; do not hand-edit inside the markers.*
50
+
51
+ <!-- BEGIN GENERATED: recent-additions -->
52
+
53
+ *No stream has recorded a `sourceLine` against this package yet.*
54
+
55
+ <!-- END GENERATED: recent-additions -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-extras-transformers",
3
- "version": "5.1.0-55",
3
+ "version": "5.1.0-57",
4
4
  "description": "Result-integration boundary over @huggingface/transformers for Node consumers (loadPipeline, classify, classifyAll, embed)",
5
5
  "main": "lib/index.js",
6
6
  "types": "dist/ts-extras-transformers.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",
@@ -49,11 +50,11 @@
49
50
  "@huggingface/transformers": "~4.2.0",
50
51
  "@microsoft/api-extractor": "^7.55.2",
51
52
  "@rushstack/eslint-config": "4.6.4",
52
- "@rushstack/heft": "1.2.7",
53
- "@rushstack/heft-jest-plugin": "1.2.6",
54
- "@rushstack/heft-node-rig": "2.11.27",
53
+ "@rushstack/heft": "1.3.0",
54
+ "@rushstack/heft-jest-plugin": "2.0.17",
55
+ "@rushstack/heft-node-rig": "2.11.50",
55
56
  "@types/heft-jest": "1.0.6",
56
- "@types/jest": "^29.5.14",
57
+ "@types/jest": "^30.0.0",
57
58
  "@types/node": "^20.14.9",
58
59
  "@typescript-eslint/eslint-plugin": "^8.52.0",
59
60
  "@typescript-eslint/parser": "^8.52.0",
@@ -63,18 +64,18 @@
63
64
  "eslint-plugin-node": "^11.1.0",
64
65
  "eslint-plugin-promise": "^7.2.1",
65
66
  "eslint-plugin-tsdoc": "~0.5.2",
66
- "jest": "^29.7.0",
67
+ "jest": "^30.5.2",
67
68
  "rimraf": "^6.1.2",
68
- "ts-jest": "^29.4.6",
69
+ "ts-jest": "^29.4.12",
69
70
  "ts-node": "^10.9.2",
70
71
  "typescript": "5.9.3",
71
- "@fgv/heft-dual-rig": "5.1.0-55",
72
- "@fgv/ts-utils": "5.1.0-55",
73
- "@fgv/ts-utils-jest": "5.1.0-55"
72
+ "@fgv/heft-dual-rig": "5.1.0-57",
73
+ "@fgv/ts-utils-jest": "5.1.0-57",
74
+ "@fgv/ts-utils": "5.1.0-57"
74
75
  },
75
76
  "peerDependencies": {
76
77
  "@huggingface/transformers": "~4.2.0",
77
- "@fgv/ts-utils": "5.1.0-55"
78
+ "@fgv/ts-utils": "5.1.0-57"
78
79
  },
79
80
  "scripts": {
80
81
  "build": "heft build --clean",