@nhtio/adk 0.1.0-master-e04b0eba → 0.1.0-master-d3e80e7a
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/CHANGELOG.md +40 -0
- package/batteries/embeddings/index.d.ts +25 -0
- package/batteries/embeddings/openai/adapter.cjs +185 -0
- package/batteries/embeddings/openai/adapter.cjs.map +1 -0
- package/batteries/embeddings/openai/adapter.d.ts +74 -0
- package/batteries/embeddings/openai/adapter.mjs +183 -0
- package/batteries/embeddings/openai/adapter.mjs.map +1 -0
- package/batteries/embeddings/openai/exceptions.cjs +48 -0
- package/batteries/embeddings/openai/exceptions.cjs.map +1 -0
- package/batteries/embeddings/openai/exceptions.d.ts +45 -0
- package/batteries/embeddings/openai/exceptions.mjs +43 -0
- package/batteries/embeddings/openai/exceptions.mjs.map +1 -0
- package/batteries/embeddings/openai/helpers.cjs +25 -0
- package/batteries/embeddings/openai/helpers.cjs.map +1 -0
- package/batteries/embeddings/openai/helpers.d.ts +25 -0
- package/batteries/embeddings/openai/helpers.mjs +23 -0
- package/batteries/embeddings/openai/helpers.mjs.map +1 -0
- package/batteries/embeddings/openai/index.d.ts +17 -0
- package/batteries/embeddings/openai/types.cjs +2 -0
- package/batteries/embeddings/openai/types.d.ts +123 -0
- package/batteries/embeddings/openai/types.mjs +0 -0
- package/batteries/embeddings/openai/validation.cjs +56 -0
- package/batteries/embeddings/openai/validation.cjs.map +1 -0
- package/batteries/embeddings/openai/validation.d.ts +24 -0
- package/batteries/embeddings/openai/validation.mjs +53 -0
- package/batteries/embeddings/openai/validation.mjs.map +1 -0
- package/batteries/embeddings/openai.cjs +14 -0
- package/batteries/embeddings/openai.mjs +5 -0
- package/batteries/embeddings/webllm/adapter.cjs +147 -0
- package/batteries/embeddings/webllm/adapter.cjs.map +1 -0
- package/batteries/embeddings/webllm/adapter.d.ts +74 -0
- package/batteries/embeddings/webllm/adapter.mjs +145 -0
- package/batteries/embeddings/webllm/adapter.mjs.map +1 -0
- package/batteries/embeddings/webllm/exceptions.cjs +31 -0
- package/batteries/embeddings/webllm/exceptions.cjs.map +1 -0
- package/batteries/embeddings/webllm/exceptions.d.ts +25 -0
- package/batteries/embeddings/webllm/exceptions.mjs +28 -0
- package/batteries/embeddings/webllm/exceptions.mjs.map +1 -0
- package/batteries/embeddings/webllm/index.d.ts +15 -0
- package/batteries/embeddings/webllm/types.cjs +2 -0
- package/batteries/embeddings/webllm/types.d.ts +52 -0
- package/batteries/embeddings/webllm/types.mjs +0 -0
- package/batteries/embeddings/webllm/validation.cjs +43 -0
- package/batteries/embeddings/webllm/validation.cjs.map +1 -0
- package/batteries/embeddings/webllm/validation.d.ts +25 -0
- package/batteries/embeddings/webllm/validation.mjs +40 -0
- package/batteries/embeddings/webllm/validation.mjs.map +1 -0
- package/batteries/embeddings/webllm.cjs +10 -0
- package/batteries/embeddings/webllm.mjs +4 -0
- package/batteries/embeddings.cjs +15 -0
- package/batteries/embeddings.mjs +6 -0
- package/batteries/index.d.ts +1 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs +14 -73
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +8 -67
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +2 -2
- package/batteries/llm/openai_chat_completions/helpers.mjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +7 -6
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.mjs +7 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs +1 -1
- package/batteries/storage/flydrive.cjs +1 -1
- package/batteries/storage/flydrive.mjs +1 -1
- package/batteries/storage/in_memory.cjs +1 -1
- package/batteries/storage/in_memory.mjs +1 -1
- package/batteries/storage/opfs.cjs +1 -1
- package/batteries/storage/opfs.mjs +1 -1
- package/batteries/tools/color.cjs +2 -2
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +3 -3
- package/batteries/tools/comparison.mjs +3 -3
- package/batteries/tools/data_structure.cjs +3 -3
- package/batteries/tools/data_structure.mjs +3 -3
- package/batteries/tools/datetime_extended.cjs +2 -2
- package/batteries/tools/datetime_extended.mjs +2 -2
- package/batteries/tools/datetime_math.cjs +2 -2
- package/batteries/tools/datetime_math.mjs +2 -2
- package/batteries/tools/encoding.cjs +3 -3
- package/batteries/tools/encoding.mjs +3 -3
- package/batteries/tools/formatting.cjs +3 -3
- package/batteries/tools/formatting.mjs +3 -3
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math.cjs +3 -3
- package/batteries/tools/math.mjs +3 -3
- package/batteries/tools/memory.cjs +5 -5
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +4 -4
- package/batteries/tools/parsing.mjs +4 -4
- package/batteries/tools/retrievables.cjs +4 -4
- package/batteries/tools/retrievables.mjs +4 -4
- package/batteries/tools/standing_instructions.cjs +4 -4
- package/batteries/tools/standing_instructions.mjs +4 -4
- package/batteries/tools/statistics.cjs +4 -4
- package/batteries/tools/statistics.mjs +4 -4
- package/batteries/tools/string_processing.cjs +3 -3
- package/batteries/tools/string_processing.mjs +3 -3
- package/batteries/tools/structured_data.cjs +3 -3
- package/batteries/tools/structured_data.mjs +3 -3
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +2 -2
- package/batteries/tools/time.mjs +2 -2
- package/batteries/tools/unit_conversion.cjs +2 -2
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries.cjs +13 -0
- package/batteries.mjs +8 -3
- package/{common-DuKWGTVd.js → common-D_e5zYsG.js} +8 -8
- package/{common-DuKWGTVd.js.map → common-D_e5zYsG.js.map} +1 -1
- package/{common-ClCHam5-.mjs → common-lMrnzoyn.mjs} +8 -8
- package/{common-ClCHam5-.mjs.map → common-lMrnzoyn.mjs.map} +1 -1
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-uNtS-XSP.mjs → dispatch_runner-CDF3X0nv.mjs} +3 -3
- package/{dispatch_runner-uNtS-XSP.mjs.map → dispatch_runner-CDF3X0nv.mjs.map} +1 -1
- package/{dispatch_runner-CEFHXRJZ.js → dispatch_runner-CpuyATj1.js} +3 -3
- package/{dispatch_runner-CEFHXRJZ.js.map → dispatch_runner-CpuyATj1.js.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/exceptions.cjs +1 -1
- package/exceptions.mjs +1 -1
- package/forge.cjs +4 -4
- package/forge.mjs +4 -4
- package/guards.cjs +8 -8
- package/guards.mjs +8 -8
- package/index.cjs +12 -12
- package/index.mjs +12 -12
- package/lib/exceptions/runtime.d.ts +5 -0
- package/lib/types/turn_runner.d.ts +32 -10
- package/lib/utils/retry.cjs +107 -0
- package/lib/utils/retry.cjs.map +1 -0
- package/lib/utils/retry.d.ts +63 -0
- package/lib/utils/retry.mjs +102 -0
- package/lib/utils/retry.mjs.map +1 -0
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +128 -63
- package/{runtime-DyD9oQjH.js → runtime-MFFcJrRv.js} +6 -2
- package/runtime-MFFcJrRv.js.map +1 -0
- package/{runtime-CDIZwCT0.mjs → runtime-j92CNi5z.mjs} +6 -2
- package/runtime-j92CNi5z.mjs.map +1 -0
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-CHvDDYGA.js → spooled_artifact-B8gIIn9h.js} +4 -4
- package/{spooled_artifact-CHvDDYGA.js.map → spooled_artifact-B8gIIn9h.js.map} +1 -1
- package/{spooled_artifact-D-JrpY4W.mjs → spooled_artifact-CWoKUDEm.mjs} +4 -4
- package/{spooled_artifact-D-JrpY4W.mjs.map → spooled_artifact-CWoKUDEm.mjs.map} +1 -1
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-B4eWOfCX.mjs → spooled_markdown_artifact-CNle4jXN.mjs} +3 -3
- package/{spooled_markdown_artifact-B4eWOfCX.mjs.map → spooled_markdown_artifact-CNle4jXN.mjs.map} +1 -1
- package/{spooled_markdown_artifact-BYfPqFvk.js → spooled_markdown_artifact-DQX0RCdI.js} +3 -3
- package/{spooled_markdown_artifact-BYfPqFvk.js.map → spooled_markdown_artifact-DQX0RCdI.js.map} +1 -1
- package/{thought-DBNsR6l8.js → thought-BD6AkkOr.js} +4 -4
- package/{thought-DBNsR6l8.js.map → thought-BD6AkkOr.js.map} +1 -1
- package/{thought-D9IS11b5.mjs → thought-B_P8LiB6.mjs} +4 -4
- package/{thought-D9IS11b5.mjs.map → thought-B_P8LiB6.mjs.map} +1 -1
- package/{tool-CsYuHhiS.mjs → tool-CRZSUcdP.mjs} +3 -3
- package/{tool-CsYuHhiS.mjs.map → tool-CRZSUcdP.mjs.map} +1 -1
- package/{tool-DIHzOZiV.js → tool-CX9vNHAw.js} +3 -3
- package/{tool-DIHzOZiV.js.map → tool-CX9vNHAw.js.map} +1 -1
- package/{tool_call-CkOVOhg0.js → tool_call--7ti-frB.js} +4 -4
- package/{tool_call-CkOVOhg0.js.map → tool_call--7ti-frB.js.map} +1 -1
- package/{tool_call-Bs_Q5LOG.mjs → tool_call-BUeMuCc6.mjs} +4 -4
- package/{tool_call-Bs_Q5LOG.mjs.map → tool_call-BUeMuCc6.mjs.map} +1 -1
- package/{tool_registry-CX3ofUh9.mjs → tool_registry-BGHg6KTq.mjs} +2 -2
- package/{tool_registry-CX3ofUh9.mjs.map → tool_registry-BGHg6KTq.mjs.map} +1 -1
- package/{tool_registry-CKk5ooxm.js → tool_registry-CtCQ4Xoz.js} +2 -2
- package/{tool_registry-CKk5ooxm.js.map → tool_registry-CtCQ4Xoz.js.map} +1 -1
- package/{turn_runner-D0qGIrRI.js → turn_runner-BJTtAORU.js} +7 -6
- package/turn_runner-BJTtAORU.js.map +1 -0
- package/{turn_runner-C1-mup84.mjs → turn_runner-C02LZHjt.mjs} +8 -7
- package/turn_runner-C02LZHjt.mjs.map +1 -0
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/runtime-CDIZwCT0.mjs.map +0 -1
- package/runtime-DyD9oQjH.js.map +0 -1
- package/turn_runner-C1-mup84.mjs.map +0 -1
- package/turn_runner-D0qGIrRI.js.map +0 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../chunk-Ble4zEEl.js");
|
|
3
|
+
const require_tool_registry = require("../../../tool_registry-CtCQ4Xoz.js");
|
|
4
|
+
require("../../../guards.cjs");
|
|
5
|
+
const require_batteries_embeddings_openai_helpers = require("../openai/helpers.cjs");
|
|
6
|
+
const require_batteries_embeddings_webllm_exceptions = require("./exceptions.cjs");
|
|
7
|
+
const require_batteries_embeddings_webllm_validation = require("./validation.cjs");
|
|
8
|
+
//#region src/batteries/embeddings/webllm/adapter.ts
|
|
9
|
+
/**
|
|
10
|
+
* WebLLM (WebGPU, in-process) Embeddings adapter battery.
|
|
11
|
+
*
|
|
12
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/adapter
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* Embeddings battery backed by WebLLM's in-process `engine.embeddings.create()` (the OpenAI-style
|
|
16
|
+
* embeddings API exposed by `@mlc-ai/web-llm`). Runs entirely in the browser on WebGPU — no
|
|
17
|
+
* network round-trip, no API key.
|
|
18
|
+
*
|
|
19
|
+
* This class is the **same battery** as {@link @nhtio/adk/batteries/embeddings/openai!OpenAIEmbeddingsAdapter}
|
|
20
|
+
* in every user-facing respect — identical method surface (`isAvailable` / `dimensions` /
|
|
21
|
+
* `preload` / `reset` / `embed` / `embedMany`), identical `number[]` return shape, identical
|
|
22
|
+
* query/document prefix handling (the shared `applyEmbeddingPrefix` helper) — differing only in
|
|
23
|
+
* the engine. Construction validates eagerly and throws
|
|
24
|
+
* {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} on failure.
|
|
25
|
+
*
|
|
26
|
+
* `@mlc-ai/web-llm` is an optional peer dependency, imported lazily so non-WebGPU consumers pay
|
|
27
|
+
* nothing for it.
|
|
28
|
+
*/
|
|
29
|
+
var defaultCreateEngine = async ({ model, engineConfig, chatOptions, onInitProgress }) => {
|
|
30
|
+
const { CreateMLCEngine } = await import("@mlc-ai/web-llm");
|
|
31
|
+
return await CreateMLCEngine(model, {
|
|
32
|
+
...engineConfig ?? {},
|
|
33
|
+
initProgressCallback: onInitProgress
|
|
34
|
+
}, chatOptions);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Embeddings adapter for WebLLM's in-process embeddings API.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* Reusable: construct once, call {@link WebLLMEmbeddingsAdapter.embed} / {@link embedMany} as many
|
|
41
|
+
* times as needed. The engine is resolved lazily on first use (or via {@link preload}) and cached
|
|
42
|
+
* with single-flight semantics so concurrent calls share one load.
|
|
43
|
+
*/
|
|
44
|
+
var WebLLMEmbeddingsAdapter = class WebLLMEmbeddingsAdapter {
|
|
45
|
+
#options;
|
|
46
|
+
#engine;
|
|
47
|
+
#enginePromise;
|
|
48
|
+
/**
|
|
49
|
+
* Whether WebGPU — and therefore this battery — is available in the current runtime.
|
|
50
|
+
*/
|
|
51
|
+
static isAvailable() {
|
|
52
|
+
return typeof globalThis.navigator !== "undefined" && "gpu" in globalThis.navigator && typeof globalThis.navigator.gpu !== "undefined";
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* @param options - Constructor options. Validated eagerly.
|
|
56
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when `options` does not satisfy
|
|
57
|
+
* {@link @nhtio/adk/batteries/embeddings/webllm/validation!webLLMEmbeddingsOptionsSchema} (e.g. missing `model`).
|
|
58
|
+
*/
|
|
59
|
+
constructor(options) {
|
|
60
|
+
this.#options = require_batteries_embeddings_webllm_validation.validateOptions(options);
|
|
61
|
+
this.#engine = this.#options.engine;
|
|
62
|
+
}
|
|
63
|
+
/** Declared output dimensionality (from options), or `undefined` if not configured. */
|
|
64
|
+
get dimensions() {
|
|
65
|
+
return this.#options.dimensions;
|
|
66
|
+
}
|
|
67
|
+
/** Whether WebGPU is available, honoring an injected `isWebGPUAvailable` probe. */
|
|
68
|
+
isAvailable() {
|
|
69
|
+
return (this.#options.isWebGPUAvailable ?? WebLLMEmbeddingsAdapter.isAvailable)();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Eagerly loads (and caches) the engine so the first `embed` call is fast. Idempotent.
|
|
73
|
+
*
|
|
74
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when no WebGPU is available and no engine
|
|
75
|
+
* was injected.
|
|
76
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when engine creation fails.
|
|
77
|
+
*/
|
|
78
|
+
async preload() {
|
|
79
|
+
await this.#resolveEngine();
|
|
80
|
+
}
|
|
81
|
+
/** Drops the cached engine and in-flight load so the next call reloads. */
|
|
82
|
+
reset() {
|
|
83
|
+
this.#engine = void 0;
|
|
84
|
+
this.#enginePromise = void 0;
|
|
85
|
+
}
|
|
86
|
+
async #resolveEngine() {
|
|
87
|
+
if (this.#engine) return this.#engine;
|
|
88
|
+
if (!this.isAvailable()) throw new require_batteries_embeddings_webllm_exceptions.E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS(["WebLLM requires a browser/runtime with WebGPU support"]);
|
|
89
|
+
this.#enginePromise ??= (async () => {
|
|
90
|
+
const createEngine = this.#options.createEngine ?? defaultCreateEngine;
|
|
91
|
+
try {
|
|
92
|
+
const engine = await createEngine({
|
|
93
|
+
model: this.#options.model,
|
|
94
|
+
engineConfig: this.#options.engineConfig,
|
|
95
|
+
chatOptions: this.#options.chatOptions,
|
|
96
|
+
onInitProgress: this.#options.onInitProgress
|
|
97
|
+
});
|
|
98
|
+
this.#engine = engine;
|
|
99
|
+
return engine;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
this.#enginePromise = void 0;
|
|
102
|
+
throw new require_batteries_embeddings_webllm_exceptions.E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([require_tool_registry.isError(err) ? err.message : String(err)]);
|
|
103
|
+
}
|
|
104
|
+
})();
|
|
105
|
+
return this.#enginePromise;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Embeds a single string.
|
|
109
|
+
*
|
|
110
|
+
* @param text - The input text.
|
|
111
|
+
* @param opts - Per-call options (`kind`).
|
|
112
|
+
* @returns The embedding vector as a plain `number[]`.
|
|
113
|
+
*/
|
|
114
|
+
async embed(text, opts) {
|
|
115
|
+
const [vec] = await this.embedMany([text], opts);
|
|
116
|
+
return vec;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Embeds a batch of strings in a single engine call.
|
|
120
|
+
*
|
|
121
|
+
* @param texts - The input texts.
|
|
122
|
+
* @param opts - Per-call options (`kind`). Defaults to `kind: 'document'`.
|
|
123
|
+
* @returns One embedding vector per input, in input order, each a plain `number[]`.
|
|
124
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when the engine call fails or returns a
|
|
125
|
+
* malformed result.
|
|
126
|
+
*/
|
|
127
|
+
async embedMany(texts, opts) {
|
|
128
|
+
if (texts.length === 0) return [];
|
|
129
|
+
const input = require_batteries_embeddings_openai_helpers.applyEmbeddingPrefix(texts, opts?.kind ?? "document", this.#options);
|
|
130
|
+
const engine = await this.#resolveEngine();
|
|
131
|
+
let response;
|
|
132
|
+
try {
|
|
133
|
+
response = await engine.embeddings.create({
|
|
134
|
+
model: this.#options.model,
|
|
135
|
+
input
|
|
136
|
+
});
|
|
137
|
+
} catch (err) {
|
|
138
|
+
throw new require_batteries_embeddings_webllm_exceptions.E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([require_tool_registry.isError(err) ? err.message : String(err)]);
|
|
139
|
+
}
|
|
140
|
+
if (!response || !Array.isArray(response.data) || response.data.length !== input.length) throw new require_batteries_embeddings_webllm_exceptions.E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([`expected ${input.length} vectors, got ${response?.data?.length ?? "none"}`]);
|
|
141
|
+
return response.data.slice().sort((a, b) => a.index - b.index).map((d) => d.embedding);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
//#endregion
|
|
145
|
+
exports.WebLLMEmbeddingsAdapter = WebLLMEmbeddingsAdapter;
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=adapter.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.cjs","names":["#options","#engine","#resolveEngine","#enginePromise"],"sources":["../../../../src/batteries/embeddings/webllm/adapter.ts"],"sourcesContent":["/**\n * WebLLM (WebGPU, in-process) Embeddings adapter battery.\n *\n * @module @nhtio/adk/batteries/embeddings/webllm/adapter\n *\n * @remarks\n * Embeddings battery backed by WebLLM's in-process `engine.embeddings.create()` (the OpenAI-style\n * embeddings API exposed by `@mlc-ai/web-llm`). Runs entirely in the browser on WebGPU — no\n * network round-trip, no API key.\n *\n * This class is the **same battery** as {@link @nhtio/adk/batteries/embeddings/openai!OpenAIEmbeddingsAdapter}\n * in every user-facing respect — identical method surface (`isAvailable` / `dimensions` /\n * `preload` / `reset` / `embed` / `embedMany`), identical `number[]` return shape, identical\n * query/document prefix handling (the shared `applyEmbeddingPrefix` helper) — differing only in\n * the engine. Construction validates eagerly and throws\n * {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} on failure.\n *\n * `@mlc-ai/web-llm` is an optional peer dependency, imported lazily so non-WebGPU consumers pay\n * nothing for it.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validateOptions } from './validation'\nimport { applyEmbeddingPrefix } from '../openai/helpers'\nimport { E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS, E_WEBLLM_EMBEDDINGS_ENGINE_ERROR } from './exceptions'\nimport type { EmbedOptions } from '../openai/types'\nimport type {\n WebLLMEmbeddingsAdapterOptions,\n WebLLMEmbeddingsEngine,\n CreateWebLLMEmbeddingsEngine,\n} from './types'\n\nconst defaultCreateEngine: CreateWebLLMEmbeddingsEngine = async ({\n model,\n engineConfig,\n chatOptions,\n onInitProgress,\n}) => {\n const { CreateMLCEngine } = await import('@mlc-ai/web-llm')\n return (await CreateMLCEngine(\n model,\n { ...(engineConfig ?? {}), initProgressCallback: onInitProgress },\n chatOptions\n )) as WebLLMEmbeddingsEngine\n}\n\n/**\n * Embeddings adapter for WebLLM's in-process embeddings API.\n *\n * @remarks\n * Reusable: construct once, call {@link WebLLMEmbeddingsAdapter.embed} / {@link embedMany} as many\n * times as needed. The engine is resolved lazily on first use (or via {@link preload}) and cached\n * with single-flight semantics so concurrent calls share one load.\n */\nexport class WebLLMEmbeddingsAdapter {\n readonly #options: WebLLMEmbeddingsAdapterOptions\n #engine: WebLLMEmbeddingsEngine | undefined\n #enginePromise: Promise<WebLLMEmbeddingsEngine> | undefined\n\n /**\n * Whether WebGPU — and therefore this battery — is available in the current runtime.\n */\n public static isAvailable(): boolean {\n return (\n typeof globalThis.navigator !== 'undefined' &&\n 'gpu' in globalThis.navigator &&\n typeof (globalThis.navigator as { gpu?: unknown }).gpu !== 'undefined'\n )\n }\n\n /**\n * @param options - Constructor options. Validated eagerly.\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when `options` does not satisfy\n * {@link @nhtio/adk/batteries/embeddings/webllm/validation!webLLMEmbeddingsOptionsSchema} (e.g. missing `model`).\n */\n constructor(options: unknown) {\n this.#options = validateOptions(options)\n this.#engine = this.#options.engine\n }\n\n /** Declared output dimensionality (from options), or `undefined` if not configured. */\n get dimensions(): number | undefined {\n return this.#options.dimensions\n }\n\n /** Whether WebGPU is available, honoring an injected `isWebGPUAvailable` probe. */\n isAvailable(): boolean {\n return (this.#options.isWebGPUAvailable ?? WebLLMEmbeddingsAdapter.isAvailable)()\n }\n\n /**\n * Eagerly loads (and caches) the engine so the first `embed` call is fast. Idempotent.\n *\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when no WebGPU is available and no engine\n * was injected.\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when engine creation fails.\n */\n async preload(): Promise<void> {\n await this.#resolveEngine()\n }\n\n /** Drops the cached engine and in-flight load so the next call reloads. */\n reset(): void {\n this.#engine = undefined\n this.#enginePromise = undefined\n }\n\n async #resolveEngine(): Promise<WebLLMEmbeddingsEngine> {\n if (this.#engine) return this.#engine\n if (!this.isAvailable()) {\n throw new E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS([\n 'WebLLM requires a browser/runtime with WebGPU support',\n ])\n }\n this.#enginePromise ??= (async () => {\n const createEngine = this.#options.createEngine ?? defaultCreateEngine\n try {\n const engine = await createEngine({\n model: this.#options.model,\n engineConfig: this.#options.engineConfig,\n chatOptions: this.#options.chatOptions,\n onInitProgress: this.#options.onInitProgress,\n })\n this.#engine = engine\n return engine\n } catch (err) {\n // Clear the cached promise so a later call can retry a transient load failure.\n this.#enginePromise = undefined\n throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n })()\n return this.#enginePromise\n }\n\n /**\n * Embeds a single string.\n *\n * @param text - The input text.\n * @param opts - Per-call options (`kind`).\n * @returns The embedding vector as a plain `number[]`.\n */\n async embed(text: string, opts?: EmbedOptions): Promise<number[]> {\n const [vec] = await this.embedMany([text], opts)\n return vec\n }\n\n /**\n * Embeds a batch of strings in a single engine call.\n *\n * @param texts - The input texts.\n * @param opts - Per-call options (`kind`). Defaults to `kind: 'document'`.\n * @returns One embedding vector per input, in input order, each a plain `number[]`.\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when the engine call fails or returns a\n * malformed result.\n */\n async embedMany(texts: string[], opts?: EmbedOptions): Promise<number[][]> {\n if (texts.length === 0) return []\n const kind = opts?.kind ?? 'document'\n const input = applyEmbeddingPrefix(texts, kind, this.#options)\n\n const engine = await this.#resolveEngine()\n\n let response: { data?: Array<{ embedding: number[]; index: number }> }\n try {\n response = await engine.embeddings.create({ model: this.#options.model, input })\n } catch (err) {\n throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n\n if (!response || !Array.isArray(response.data) || response.data.length !== input.length) {\n throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([\n `expected ${input.length} vectors, got ${response?.data?.length ?? 'none'}`,\n ])\n }\n return response.data\n .slice()\n .sort((a, b) => a.index - b.index)\n .map((d) => d.embedding)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAM,sBAAoD,OAAO,EAC/D,OACA,cACA,aACA,qBACI;CACJ,MAAM,EAAE,oBAAoB,MAAM,OAAO;CACzC,OAAQ,MAAM,gBACZ,OACA;EAAE,GAAI,gBAAgB,CAAC;EAAI,sBAAsB;CAAe,GAChE,WACF;AACF;;;;;;;;;AAUA,IAAa,0BAAb,MAAa,wBAAwB;CACnC;CACA;CACA;;;;CAKA,OAAc,cAAuB;EACnC,OACE,OAAO,WAAW,cAAc,eAChC,SAAS,WAAW,aACpB,OAAQ,WAAW,UAAgC,QAAQ;CAE/D;;;;;;CAOA,YAAY,SAAkB;EAC5B,KAAKA,WAAW,+CAAA,gBAAgB,OAAO;EACvC,KAAKC,UAAU,KAAKD,SAAS;CAC/B;;CAGA,IAAI,aAAiC;EACnC,OAAO,KAAKA,SAAS;CACvB;;CAGA,cAAuB;EACrB,QAAQ,KAAKA,SAAS,qBAAqB,wBAAwB,aAAa;CAClF;;;;;;;;CASA,MAAM,UAAyB;EAC7B,MAAM,KAAKE,eAAe;CAC5B;;CAGA,QAAc;EACZ,KAAKD,UAAU,KAAA;EACf,KAAKE,iBAAiB,KAAA;CACxB;CAEA,MAAMD,iBAAkD;EACtD,IAAI,KAAKD,SAAS,OAAO,KAAKA;EAC9B,IAAI,CAAC,KAAK,YAAY,GACpB,MAAM,IAAI,+CAAA,oCAAoC,CAC5C,uDACF,CAAC;EAEH,KAAKE,oBAAoB,YAAY;GACnC,MAAM,eAAe,KAAKH,SAAS,gBAAgB;GACnD,IAAI;IACF,MAAM,SAAS,MAAM,aAAa;KAChC,OAAO,KAAKA,SAAS;KACrB,cAAc,KAAKA,SAAS;KAC5B,aAAa,KAAKA,SAAS;KAC3B,gBAAgB,KAAKA,SAAS;IAChC,CAAC;IACD,KAAKC,UAAU;IACf,OAAO;GACT,SAAS,KAAK;IAEZ,KAAKE,iBAAiB,KAAA;IACtB,MAAM,IAAI,+CAAA,iCAAiC,CAAC,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC;GACvF;EACF,GAAG;EACH,OAAO,KAAKA;CACd;;;;;;;;CASA,MAAM,MAAM,MAAc,MAAwC;EAChE,MAAM,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,GAAG,IAAI;EAC/C,OAAO;CACT;;;;;;;;;;CAWA,MAAM,UAAU,OAAiB,MAA0C;EACzE,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC;EAEhC,MAAM,QAAQ,4CAAA,qBAAqB,OADtB,MAAM,QAAQ,YACqB,KAAKH,QAAQ;EAE7D,MAAM,SAAS,MAAM,KAAKE,eAAe;EAEzC,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,OAAO,WAAW,OAAO;IAAE,OAAO,KAAKF,SAAS;IAAO;GAAM,CAAC;EACjF,SAAS,KAAK;GACZ,MAAM,IAAI,+CAAA,iCAAiC,CAAC,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC;EACvF;EAEA,IAAI,CAAC,YAAY,CAAC,MAAM,QAAQ,SAAS,IAAI,KAAK,SAAS,KAAK,WAAW,MAAM,QAC/E,MAAM,IAAI,+CAAA,iCAAiC,CACzC,YAAY,MAAM,OAAO,gBAAgB,UAAU,MAAM,UAAU,QACrE,CAAC;EAEH,OAAO,SAAS,KACb,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,KAAK,MAAM,EAAE,SAAS;CAC3B;AACF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebLLM (WebGPU, in-process) Embeddings adapter battery.
|
|
3
|
+
*
|
|
4
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/adapter
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Embeddings battery backed by WebLLM's in-process `engine.embeddings.create()` (the OpenAI-style
|
|
8
|
+
* embeddings API exposed by `@mlc-ai/web-llm`). Runs entirely in the browser on WebGPU — no
|
|
9
|
+
* network round-trip, no API key.
|
|
10
|
+
*
|
|
11
|
+
* This class is the **same battery** as {@link @nhtio/adk/batteries/embeddings/openai!OpenAIEmbeddingsAdapter}
|
|
12
|
+
* in every user-facing respect — identical method surface (`isAvailable` / `dimensions` /
|
|
13
|
+
* `preload` / `reset` / `embed` / `embedMany`), identical `number[]` return shape, identical
|
|
14
|
+
* query/document prefix handling (the shared `applyEmbeddingPrefix` helper) — differing only in
|
|
15
|
+
* the engine. Construction validates eagerly and throws
|
|
16
|
+
* {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} on failure.
|
|
17
|
+
*
|
|
18
|
+
* `@mlc-ai/web-llm` is an optional peer dependency, imported lazily so non-WebGPU consumers pay
|
|
19
|
+
* nothing for it.
|
|
20
|
+
*/
|
|
21
|
+
import type { EmbedOptions } from "../openai/types";
|
|
22
|
+
/**
|
|
23
|
+
* Embeddings adapter for WebLLM's in-process embeddings API.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Reusable: construct once, call {@link WebLLMEmbeddingsAdapter.embed} / {@link embedMany} as many
|
|
27
|
+
* times as needed. The engine is resolved lazily on first use (or via {@link preload}) and cached
|
|
28
|
+
* with single-flight semantics so concurrent calls share one load.
|
|
29
|
+
*/
|
|
30
|
+
export declare class WebLLMEmbeddingsAdapter {
|
|
31
|
+
#private;
|
|
32
|
+
/**
|
|
33
|
+
* Whether WebGPU — and therefore this battery — is available in the current runtime.
|
|
34
|
+
*/
|
|
35
|
+
static isAvailable(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* @param options - Constructor options. Validated eagerly.
|
|
38
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when `options` does not satisfy
|
|
39
|
+
* {@link @nhtio/adk/batteries/embeddings/webllm/validation!webLLMEmbeddingsOptionsSchema} (e.g. missing `model`).
|
|
40
|
+
*/
|
|
41
|
+
constructor(options: unknown);
|
|
42
|
+
/** Declared output dimensionality (from options), or `undefined` if not configured. */
|
|
43
|
+
get dimensions(): number | undefined;
|
|
44
|
+
/** Whether WebGPU is available, honoring an injected `isWebGPUAvailable` probe. */
|
|
45
|
+
isAvailable(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Eagerly loads (and caches) the engine so the first `embed` call is fast. Idempotent.
|
|
48
|
+
*
|
|
49
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when no WebGPU is available and no engine
|
|
50
|
+
* was injected.
|
|
51
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when engine creation fails.
|
|
52
|
+
*/
|
|
53
|
+
preload(): Promise<void>;
|
|
54
|
+
/** Drops the cached engine and in-flight load so the next call reloads. */
|
|
55
|
+
reset(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Embeds a single string.
|
|
58
|
+
*
|
|
59
|
+
* @param text - The input text.
|
|
60
|
+
* @param opts - Per-call options (`kind`).
|
|
61
|
+
* @returns The embedding vector as a plain `number[]`.
|
|
62
|
+
*/
|
|
63
|
+
embed(text: string, opts?: EmbedOptions): Promise<number[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Embeds a batch of strings in a single engine call.
|
|
66
|
+
*
|
|
67
|
+
* @param texts - The input texts.
|
|
68
|
+
* @param opts - Per-call options (`kind`). Defaults to `kind: 'document'`.
|
|
69
|
+
* @returns One embedding vector per input, in input order, each a plain `number[]`.
|
|
70
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when the engine call fails or returns a
|
|
71
|
+
* malformed result.
|
|
72
|
+
*/
|
|
73
|
+
embedMany(texts: string[], opts?: EmbedOptions): Promise<number[][]>;
|
|
74
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { o as isError } from "../../../tool_registry-BGHg6KTq.mjs";
|
|
2
|
+
import "../../../guards.mjs";
|
|
3
|
+
import { applyEmbeddingPrefix } from "../openai/helpers.mjs";
|
|
4
|
+
import { E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS, E_WEBLLM_EMBEDDINGS_ENGINE_ERROR } from "./exceptions.mjs";
|
|
5
|
+
import { validateOptions } from "./validation.mjs";
|
|
6
|
+
//#region src/batteries/embeddings/webllm/adapter.ts
|
|
7
|
+
/**
|
|
8
|
+
* WebLLM (WebGPU, in-process) Embeddings adapter battery.
|
|
9
|
+
*
|
|
10
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/adapter
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Embeddings battery backed by WebLLM's in-process `engine.embeddings.create()` (the OpenAI-style
|
|
14
|
+
* embeddings API exposed by `@mlc-ai/web-llm`). Runs entirely in the browser on WebGPU — no
|
|
15
|
+
* network round-trip, no API key.
|
|
16
|
+
*
|
|
17
|
+
* This class is the **same battery** as {@link @nhtio/adk/batteries/embeddings/openai!OpenAIEmbeddingsAdapter}
|
|
18
|
+
* in every user-facing respect — identical method surface (`isAvailable` / `dimensions` /
|
|
19
|
+
* `preload` / `reset` / `embed` / `embedMany`), identical `number[]` return shape, identical
|
|
20
|
+
* query/document prefix handling (the shared `applyEmbeddingPrefix` helper) — differing only in
|
|
21
|
+
* the engine. Construction validates eagerly and throws
|
|
22
|
+
* {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} on failure.
|
|
23
|
+
*
|
|
24
|
+
* `@mlc-ai/web-llm` is an optional peer dependency, imported lazily so non-WebGPU consumers pay
|
|
25
|
+
* nothing for it.
|
|
26
|
+
*/
|
|
27
|
+
var defaultCreateEngine = async ({ model, engineConfig, chatOptions, onInitProgress }) => {
|
|
28
|
+
const { CreateMLCEngine } = await import("@mlc-ai/web-llm");
|
|
29
|
+
return await CreateMLCEngine(model, {
|
|
30
|
+
...engineConfig ?? {},
|
|
31
|
+
initProgressCallback: onInitProgress
|
|
32
|
+
}, chatOptions);
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Embeddings adapter for WebLLM's in-process embeddings API.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* Reusable: construct once, call {@link WebLLMEmbeddingsAdapter.embed} / {@link embedMany} as many
|
|
39
|
+
* times as needed. The engine is resolved lazily on first use (or via {@link preload}) and cached
|
|
40
|
+
* with single-flight semantics so concurrent calls share one load.
|
|
41
|
+
*/
|
|
42
|
+
var WebLLMEmbeddingsAdapter = class WebLLMEmbeddingsAdapter {
|
|
43
|
+
#options;
|
|
44
|
+
#engine;
|
|
45
|
+
#enginePromise;
|
|
46
|
+
/**
|
|
47
|
+
* Whether WebGPU — and therefore this battery — is available in the current runtime.
|
|
48
|
+
*/
|
|
49
|
+
static isAvailable() {
|
|
50
|
+
return typeof globalThis.navigator !== "undefined" && "gpu" in globalThis.navigator && typeof globalThis.navigator.gpu !== "undefined";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @param options - Constructor options. Validated eagerly.
|
|
54
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when `options` does not satisfy
|
|
55
|
+
* {@link @nhtio/adk/batteries/embeddings/webllm/validation!webLLMEmbeddingsOptionsSchema} (e.g. missing `model`).
|
|
56
|
+
*/
|
|
57
|
+
constructor(options) {
|
|
58
|
+
this.#options = validateOptions(options);
|
|
59
|
+
this.#engine = this.#options.engine;
|
|
60
|
+
}
|
|
61
|
+
/** Declared output dimensionality (from options), or `undefined` if not configured. */
|
|
62
|
+
get dimensions() {
|
|
63
|
+
return this.#options.dimensions;
|
|
64
|
+
}
|
|
65
|
+
/** Whether WebGPU is available, honoring an injected `isWebGPUAvailable` probe. */
|
|
66
|
+
isAvailable() {
|
|
67
|
+
return (this.#options.isWebGPUAvailable ?? WebLLMEmbeddingsAdapter.isAvailable)();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Eagerly loads (and caches) the engine so the first `embed` call is fast. Idempotent.
|
|
71
|
+
*
|
|
72
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when no WebGPU is available and no engine
|
|
73
|
+
* was injected.
|
|
74
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when engine creation fails.
|
|
75
|
+
*/
|
|
76
|
+
async preload() {
|
|
77
|
+
await this.#resolveEngine();
|
|
78
|
+
}
|
|
79
|
+
/** Drops the cached engine and in-flight load so the next call reloads. */
|
|
80
|
+
reset() {
|
|
81
|
+
this.#engine = void 0;
|
|
82
|
+
this.#enginePromise = void 0;
|
|
83
|
+
}
|
|
84
|
+
async #resolveEngine() {
|
|
85
|
+
if (this.#engine) return this.#engine;
|
|
86
|
+
if (!this.isAvailable()) throw new E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS(["WebLLM requires a browser/runtime with WebGPU support"]);
|
|
87
|
+
this.#enginePromise ??= (async () => {
|
|
88
|
+
const createEngine = this.#options.createEngine ?? defaultCreateEngine;
|
|
89
|
+
try {
|
|
90
|
+
const engine = await createEngine({
|
|
91
|
+
model: this.#options.model,
|
|
92
|
+
engineConfig: this.#options.engineConfig,
|
|
93
|
+
chatOptions: this.#options.chatOptions,
|
|
94
|
+
onInitProgress: this.#options.onInitProgress
|
|
95
|
+
});
|
|
96
|
+
this.#engine = engine;
|
|
97
|
+
return engine;
|
|
98
|
+
} catch (err) {
|
|
99
|
+
this.#enginePromise = void 0;
|
|
100
|
+
throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([isError(err) ? err.message : String(err)]);
|
|
101
|
+
}
|
|
102
|
+
})();
|
|
103
|
+
return this.#enginePromise;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Embeds a single string.
|
|
107
|
+
*
|
|
108
|
+
* @param text - The input text.
|
|
109
|
+
* @param opts - Per-call options (`kind`).
|
|
110
|
+
* @returns The embedding vector as a plain `number[]`.
|
|
111
|
+
*/
|
|
112
|
+
async embed(text, opts) {
|
|
113
|
+
const [vec] = await this.embedMany([text], opts);
|
|
114
|
+
return vec;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Embeds a batch of strings in a single engine call.
|
|
118
|
+
*
|
|
119
|
+
* @param texts - The input texts.
|
|
120
|
+
* @param opts - Per-call options (`kind`). Defaults to `kind: 'document'`.
|
|
121
|
+
* @returns One embedding vector per input, in input order, each a plain `number[]`.
|
|
122
|
+
* @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when the engine call fails or returns a
|
|
123
|
+
* malformed result.
|
|
124
|
+
*/
|
|
125
|
+
async embedMany(texts, opts) {
|
|
126
|
+
if (texts.length === 0) return [];
|
|
127
|
+
const input = applyEmbeddingPrefix(texts, opts?.kind ?? "document", this.#options);
|
|
128
|
+
const engine = await this.#resolveEngine();
|
|
129
|
+
let response;
|
|
130
|
+
try {
|
|
131
|
+
response = await engine.embeddings.create({
|
|
132
|
+
model: this.#options.model,
|
|
133
|
+
input
|
|
134
|
+
});
|
|
135
|
+
} catch (err) {
|
|
136
|
+
throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([isError(err) ? err.message : String(err)]);
|
|
137
|
+
}
|
|
138
|
+
if (!response || !Array.isArray(response.data) || response.data.length !== input.length) throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([`expected ${input.length} vectors, got ${response?.data?.length ?? "none"}`]);
|
|
139
|
+
return response.data.slice().sort((a, b) => a.index - b.index).map((d) => d.embedding);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
//#endregion
|
|
143
|
+
export { WebLLMEmbeddingsAdapter };
|
|
144
|
+
|
|
145
|
+
//# sourceMappingURL=adapter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.mjs","names":["#options","#engine","#resolveEngine","#enginePromise"],"sources":["../../../../src/batteries/embeddings/webllm/adapter.ts"],"sourcesContent":["/**\n * WebLLM (WebGPU, in-process) Embeddings adapter battery.\n *\n * @module @nhtio/adk/batteries/embeddings/webllm/adapter\n *\n * @remarks\n * Embeddings battery backed by WebLLM's in-process `engine.embeddings.create()` (the OpenAI-style\n * embeddings API exposed by `@mlc-ai/web-llm`). Runs entirely in the browser on WebGPU — no\n * network round-trip, no API key.\n *\n * This class is the **same battery** as {@link @nhtio/adk/batteries/embeddings/openai!OpenAIEmbeddingsAdapter}\n * in every user-facing respect — identical method surface (`isAvailable` / `dimensions` /\n * `preload` / `reset` / `embed` / `embedMany`), identical `number[]` return shape, identical\n * query/document prefix handling (the shared `applyEmbeddingPrefix` helper) — differing only in\n * the engine. Construction validates eagerly and throws\n * {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} on failure.\n *\n * `@mlc-ai/web-llm` is an optional peer dependency, imported lazily so non-WebGPU consumers pay\n * nothing for it.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validateOptions } from './validation'\nimport { applyEmbeddingPrefix } from '../openai/helpers'\nimport { E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS, E_WEBLLM_EMBEDDINGS_ENGINE_ERROR } from './exceptions'\nimport type { EmbedOptions } from '../openai/types'\nimport type {\n WebLLMEmbeddingsAdapterOptions,\n WebLLMEmbeddingsEngine,\n CreateWebLLMEmbeddingsEngine,\n} from './types'\n\nconst defaultCreateEngine: CreateWebLLMEmbeddingsEngine = async ({\n model,\n engineConfig,\n chatOptions,\n onInitProgress,\n}) => {\n const { CreateMLCEngine } = await import('@mlc-ai/web-llm')\n return (await CreateMLCEngine(\n model,\n { ...(engineConfig ?? {}), initProgressCallback: onInitProgress },\n chatOptions\n )) as WebLLMEmbeddingsEngine\n}\n\n/**\n * Embeddings adapter for WebLLM's in-process embeddings API.\n *\n * @remarks\n * Reusable: construct once, call {@link WebLLMEmbeddingsAdapter.embed} / {@link embedMany} as many\n * times as needed. The engine is resolved lazily on first use (or via {@link preload}) and cached\n * with single-flight semantics so concurrent calls share one load.\n */\nexport class WebLLMEmbeddingsAdapter {\n readonly #options: WebLLMEmbeddingsAdapterOptions\n #engine: WebLLMEmbeddingsEngine | undefined\n #enginePromise: Promise<WebLLMEmbeddingsEngine> | undefined\n\n /**\n * Whether WebGPU — and therefore this battery — is available in the current runtime.\n */\n public static isAvailable(): boolean {\n return (\n typeof globalThis.navigator !== 'undefined' &&\n 'gpu' in globalThis.navigator &&\n typeof (globalThis.navigator as { gpu?: unknown }).gpu !== 'undefined'\n )\n }\n\n /**\n * @param options - Constructor options. Validated eagerly.\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when `options` does not satisfy\n * {@link @nhtio/adk/batteries/embeddings/webllm/validation!webLLMEmbeddingsOptionsSchema} (e.g. missing `model`).\n */\n constructor(options: unknown) {\n this.#options = validateOptions(options)\n this.#engine = this.#options.engine\n }\n\n /** Declared output dimensionality (from options), or `undefined` if not configured. */\n get dimensions(): number | undefined {\n return this.#options.dimensions\n }\n\n /** Whether WebGPU is available, honoring an injected `isWebGPUAvailable` probe. */\n isAvailable(): boolean {\n return (this.#options.isWebGPUAvailable ?? WebLLMEmbeddingsAdapter.isAvailable)()\n }\n\n /**\n * Eagerly loads (and caches) the engine so the first `embed` call is fast. Idempotent.\n *\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS} when no WebGPU is available and no engine\n * was injected.\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when engine creation fails.\n */\n async preload(): Promise<void> {\n await this.#resolveEngine()\n }\n\n /** Drops the cached engine and in-flight load so the next call reloads. */\n reset(): void {\n this.#engine = undefined\n this.#enginePromise = undefined\n }\n\n async #resolveEngine(): Promise<WebLLMEmbeddingsEngine> {\n if (this.#engine) return this.#engine\n if (!this.isAvailable()) {\n throw new E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS([\n 'WebLLM requires a browser/runtime with WebGPU support',\n ])\n }\n this.#enginePromise ??= (async () => {\n const createEngine = this.#options.createEngine ?? defaultCreateEngine\n try {\n const engine = await createEngine({\n model: this.#options.model,\n engineConfig: this.#options.engineConfig,\n chatOptions: this.#options.chatOptions,\n onInitProgress: this.#options.onInitProgress,\n })\n this.#engine = engine\n return engine\n } catch (err) {\n // Clear the cached promise so a later call can retry a transient load failure.\n this.#enginePromise = undefined\n throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n })()\n return this.#enginePromise\n }\n\n /**\n * Embeds a single string.\n *\n * @param text - The input text.\n * @param opts - Per-call options (`kind`).\n * @returns The embedding vector as a plain `number[]`.\n */\n async embed(text: string, opts?: EmbedOptions): Promise<number[]> {\n const [vec] = await this.embedMany([text], opts)\n return vec\n }\n\n /**\n * Embeds a batch of strings in a single engine call.\n *\n * @param texts - The input texts.\n * @param opts - Per-call options (`kind`). Defaults to `kind: 'document'`.\n * @returns One embedding vector per input, in input order, each a plain `number[]`.\n * @throws {@link @nhtio/adk/batteries/embeddings/webllm/exceptions!E_WEBLLM_EMBEDDINGS_ENGINE_ERROR} when the engine call fails or returns a\n * malformed result.\n */\n async embedMany(texts: string[], opts?: EmbedOptions): Promise<number[][]> {\n if (texts.length === 0) return []\n const kind = opts?.kind ?? 'document'\n const input = applyEmbeddingPrefix(texts, kind, this.#options)\n\n const engine = await this.#resolveEngine()\n\n let response: { data?: Array<{ embedding: number[]; index: number }> }\n try {\n response = await engine.embeddings.create({ model: this.#options.model, input })\n } catch (err) {\n throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n\n if (!response || !Array.isArray(response.data) || response.data.length !== input.length) {\n throw new E_WEBLLM_EMBEDDINGS_ENGINE_ERROR([\n `expected ${input.length} vectors, got ${response?.data?.length ?? 'none'}`,\n ])\n }\n return response.data\n .slice()\n .sort((a, b) => a.index - b.index)\n .map((d) => d.embedding)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAM,sBAAoD,OAAO,EAC/D,OACA,cACA,aACA,qBACI;CACJ,MAAM,EAAE,oBAAoB,MAAM,OAAO;CACzC,OAAQ,MAAM,gBACZ,OACA;EAAE,GAAI,gBAAgB,CAAC;EAAI,sBAAsB;CAAe,GAChE,WACF;AACF;;;;;;;;;AAUA,IAAa,0BAAb,MAAa,wBAAwB;CACnC;CACA;CACA;;;;CAKA,OAAc,cAAuB;EACnC,OACE,OAAO,WAAW,cAAc,eAChC,SAAS,WAAW,aACpB,OAAQ,WAAW,UAAgC,QAAQ;CAE/D;;;;;;CAOA,YAAY,SAAkB;EAC5B,KAAKA,WAAW,gBAAgB,OAAO;EACvC,KAAKC,UAAU,KAAKD,SAAS;CAC/B;;CAGA,IAAI,aAAiC;EACnC,OAAO,KAAKA,SAAS;CACvB;;CAGA,cAAuB;EACrB,QAAQ,KAAKA,SAAS,qBAAqB,wBAAwB,aAAa;CAClF;;;;;;;;CASA,MAAM,UAAyB;EAC7B,MAAM,KAAKE,eAAe;CAC5B;;CAGA,QAAc;EACZ,KAAKD,UAAU,KAAA;EACf,KAAKE,iBAAiB,KAAA;CACxB;CAEA,MAAMD,iBAAkD;EACtD,IAAI,KAAKD,SAAS,OAAO,KAAKA;EAC9B,IAAI,CAAC,KAAK,YAAY,GACpB,MAAM,IAAI,oCAAoC,CAC5C,uDACF,CAAC;EAEH,KAAKE,oBAAoB,YAAY;GACnC,MAAM,eAAe,KAAKH,SAAS,gBAAgB;GACnD,IAAI;IACF,MAAM,SAAS,MAAM,aAAa;KAChC,OAAO,KAAKA,SAAS;KACrB,cAAc,KAAKA,SAAS;KAC5B,aAAa,KAAKA,SAAS;KAC3B,gBAAgB,KAAKA,SAAS;IAChC,CAAC;IACD,KAAKC,UAAU;IACf,OAAO;GACT,SAAS,KAAK;IAEZ,KAAKE,iBAAiB,KAAA;IACtB,MAAM,IAAI,iCAAiC,CAAC,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC;GACvF;EACF,GAAG;EACH,OAAO,KAAKA;CACd;;;;;;;;CASA,MAAM,MAAM,MAAc,MAAwC;EAChE,MAAM,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,GAAG,IAAI;EAC/C,OAAO;CACT;;;;;;;;;;CAWA,MAAM,UAAU,OAAiB,MAA0C;EACzE,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC;EAEhC,MAAM,QAAQ,qBAAqB,OADtB,MAAM,QAAQ,YACqB,KAAKH,QAAQ;EAE7D,MAAM,SAAS,MAAM,KAAKE,eAAe;EAEzC,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,OAAO,WAAW,OAAO;IAAE,OAAO,KAAKF,SAAS;IAAO;GAAM,CAAC;EACjF,SAAS,KAAK;GACZ,MAAM,IAAI,iCAAiC,CAAC,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC;EACvF;EAEA,IAAI,CAAC,YAAY,CAAC,MAAM,QAAQ,SAAS,IAAI,KAAK,SAAS,KAAK,WAAW,MAAM,QAC/E,MAAM,IAAI,iCAAiC,CACzC,YAAY,MAAM,OAAO,gBAAgB,UAAU,MAAM,UAAU,QACrE,CAAC;EAEH,OAAO,SAAS,KACb,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,KAAK,MAAM,EAAE,SAAS;CAC3B;AACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../chunk-Ble4zEEl.js");
|
|
3
|
+
const require_exceptions = require("../../../exceptions-CitH5wZI.js");
|
|
4
|
+
require("../../../factories.cjs");
|
|
5
|
+
//#region src/batteries/embeddings/webllm/exceptions.ts
|
|
6
|
+
/**
|
|
7
|
+
* Battery-scoped exception constructors for WebLLM Embeddings adapter failures.
|
|
8
|
+
*
|
|
9
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/exceptions
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Battery-scoped exception classes for the WebLLM Embeddings adapter, minted via `createException`
|
|
13
|
+
* from `@nhtio/adk/factories`. The categories mirror the OpenAI Embeddings battery one-to-one —
|
|
14
|
+
* only the engine-specific failure exception differs (engine error vs HTTP error).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Thrown when the resolved adapter options fail validation against
|
|
18
|
+
* `webLLMEmbeddingsOptionsSchema` — e.g. a missing/empty `model`, an unknown option key, or no
|
|
19
|
+
* WebGPU support in the current runtime. Fatal: config bugs fail loud, not at embed time.
|
|
20
|
+
*/
|
|
21
|
+
var E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS = require_exceptions.createException("E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS", "Invalid WebLLM Embeddings adapter options: %s", "E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS", 529, true);
|
|
22
|
+
/**
|
|
23
|
+
* Thrown when the WebLLM engine fails to load or `engine.embeddings.create()` throws/returns a
|
|
24
|
+
* malformed result. Non-fatal. Printf arg: `[detail]`.
|
|
25
|
+
*/
|
|
26
|
+
var E_WEBLLM_EMBEDDINGS_ENGINE_ERROR = require_exceptions.createException("E_WEBLLM_EMBEDDINGS_ENGINE_ERROR", "WebLLM Embeddings engine error: %s", "E_WEBLLM_EMBEDDINGS_ENGINE_ERROR", 502, false);
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS = E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS;
|
|
29
|
+
exports.E_WEBLLM_EMBEDDINGS_ENGINE_ERROR = E_WEBLLM_EMBEDDINGS_ENGINE_ERROR;
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=exceptions.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.cjs","names":[],"sources":["../../../../src/batteries/embeddings/webllm/exceptions.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for WebLLM Embeddings adapter failures.\n *\n * @module @nhtio/adk/batteries/embeddings/webllm/exceptions\n *\n * @remarks\n * Battery-scoped exception classes for the WebLLM Embeddings adapter, minted via `createException`\n * from `@nhtio/adk/factories`. The categories mirror the OpenAI Embeddings battery one-to-one —\n * only the engine-specific failure exception differs (engine error vs HTTP error).\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options fail validation against\n * `webLLMEmbeddingsOptionsSchema` — e.g. a missing/empty `model`, an unknown option key, or no\n * WebGPU support in the current runtime. Fatal: config bugs fail loud, not at embed time.\n */\nexport const E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS = createException<[string]>(\n 'E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS',\n 'Invalid WebLLM Embeddings adapter options: %s',\n 'E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the WebLLM engine fails to load or `engine.embeddings.create()` throws/returns a\n * malformed result. Non-fatal. Printf arg: `[detail]`.\n */\nexport const E_WEBLLM_EMBEDDINGS_ENGINE_ERROR = createException<[string]>(\n 'E_WEBLLM_EMBEDDINGS_ENGINE_ERROR',\n 'WebLLM Embeddings engine error: %s',\n 'E_WEBLLM_EMBEDDINGS_ENGINE_ERROR',\n 502,\n false\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkBA,IAAa,sCAAsC,mBAAA,gBACjD,uCACA,iDACA,uCACA,KACA,IACF;;;;;AAMA,IAAa,mCAAmC,mBAAA,gBAC9C,oCACA,sCACA,oCACA,KACA,KACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Battery-scoped exception constructors for WebLLM Embeddings adapter failures.
|
|
3
|
+
*
|
|
4
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/exceptions
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Battery-scoped exception classes for the WebLLM Embeddings adapter, minted via `createException`
|
|
8
|
+
* from `@nhtio/adk/factories`. The categories mirror the OpenAI Embeddings battery one-to-one —
|
|
9
|
+
* only the engine-specific failure exception differs (engine error vs HTTP error).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when the resolved adapter options fail validation against
|
|
13
|
+
* `webLLMEmbeddingsOptionsSchema` — e.g. a missing/empty `model`, an unknown option key, or no
|
|
14
|
+
* WebGPU support in the current runtime. Fatal: config bugs fail loud, not at embed time.
|
|
15
|
+
*/
|
|
16
|
+
export declare const E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS: import("../../../factories").CreatedException<[
|
|
17
|
+
string
|
|
18
|
+
]>;
|
|
19
|
+
/**
|
|
20
|
+
* Thrown when the WebLLM engine fails to load or `engine.embeddings.create()` throws/returns a
|
|
21
|
+
* malformed result. Non-fatal. Printf arg: `[detail]`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const E_WEBLLM_EMBEDDINGS_ENGINE_ERROR: import("../../../factories").CreatedException<[
|
|
24
|
+
string
|
|
25
|
+
]>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { t as createException } from "../../../exceptions-BeWH2FwP.mjs";
|
|
2
|
+
import "../../../factories.mjs";
|
|
3
|
+
//#region src/batteries/embeddings/webllm/exceptions.ts
|
|
4
|
+
/**
|
|
5
|
+
* Battery-scoped exception constructors for WebLLM Embeddings adapter failures.
|
|
6
|
+
*
|
|
7
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/exceptions
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Battery-scoped exception classes for the WebLLM Embeddings adapter, minted via `createException`
|
|
11
|
+
* from `@nhtio/adk/factories`. The categories mirror the OpenAI Embeddings battery one-to-one —
|
|
12
|
+
* only the engine-specific failure exception differs (engine error vs HTTP error).
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Thrown when the resolved adapter options fail validation against
|
|
16
|
+
* `webLLMEmbeddingsOptionsSchema` — e.g. a missing/empty `model`, an unknown option key, or no
|
|
17
|
+
* WebGPU support in the current runtime. Fatal: config bugs fail loud, not at embed time.
|
|
18
|
+
*/
|
|
19
|
+
var E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS = createException("E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS", "Invalid WebLLM Embeddings adapter options: %s", "E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS", 529, true);
|
|
20
|
+
/**
|
|
21
|
+
* Thrown when the WebLLM engine fails to load or `engine.embeddings.create()` throws/returns a
|
|
22
|
+
* malformed result. Non-fatal. Printf arg: `[detail]`.
|
|
23
|
+
*/
|
|
24
|
+
var E_WEBLLM_EMBEDDINGS_ENGINE_ERROR = createException("E_WEBLLM_EMBEDDINGS_ENGINE_ERROR", "WebLLM Embeddings engine error: %s", "E_WEBLLM_EMBEDDINGS_ENGINE_ERROR", 502, false);
|
|
25
|
+
//#endregion
|
|
26
|
+
export { E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS, E_WEBLLM_EMBEDDINGS_ENGINE_ERROR };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=exceptions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.mjs","names":[],"sources":["../../../../src/batteries/embeddings/webllm/exceptions.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for WebLLM Embeddings adapter failures.\n *\n * @module @nhtio/adk/batteries/embeddings/webllm/exceptions\n *\n * @remarks\n * Battery-scoped exception classes for the WebLLM Embeddings adapter, minted via `createException`\n * from `@nhtio/adk/factories`. The categories mirror the OpenAI Embeddings battery one-to-one —\n * only the engine-specific failure exception differs (engine error vs HTTP error).\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options fail validation against\n * `webLLMEmbeddingsOptionsSchema` — e.g. a missing/empty `model`, an unknown option key, or no\n * WebGPU support in the current runtime. Fatal: config bugs fail loud, not at embed time.\n */\nexport const E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS = createException<[string]>(\n 'E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS',\n 'Invalid WebLLM Embeddings adapter options: %s',\n 'E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the WebLLM engine fails to load or `engine.embeddings.create()` throws/returns a\n * malformed result. Non-fatal. Printf arg: `[detail]`.\n */\nexport const E_WEBLLM_EMBEDDINGS_ENGINE_ERROR = createException<[string]>(\n 'E_WEBLLM_EMBEDDINGS_ENGINE_ERROR',\n 'WebLLM Embeddings engine error: %s',\n 'E_WEBLLM_EMBEDDINGS_ENGINE_ERROR',\n 502,\n false\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,IAAa,sCAAsC,gBACjD,uCACA,iDACA,uCACA,KACA,IACF;;;;;AAMA,IAAa,mCAAmC,gBAC9C,oCACA,sCACA,oCACA,KACA,KACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebLLM Embeddings adapter battery — WebGPU/in-process embeddings via `@mlc-ai/web-llm`.
|
|
3
|
+
*
|
|
4
|
+
* @module @nhtio/adk/batteries/embeddings/webllm
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Browser/WebGPU-only, so reachable solely through this subpath (never re-exported from the
|
|
8
|
+
* environment-neutral `@nhtio/adk/batteries/embeddings` barrel). Re-exports the adapter class, the
|
|
9
|
+
* validation schema + `validateOptions` wrapper, every option / engine type alias (including the
|
|
10
|
+
* shared base shapes re-exported from the OpenAI battery), and the battery-scoped exceptions.
|
|
11
|
+
*/
|
|
12
|
+
export { WebLLMEmbeddingsAdapter } from "./adapter";
|
|
13
|
+
export { webLLMEmbeddingsOptionsSchema, validateOptions } from "./validation";
|
|
14
|
+
export type { EmbeddingKind, EmbedOptions, BaseEmbeddingsAdapterOptions, WebLLMEmbeddingsAdapterOptions, WebLLMEmbeddingsEngine, WebLLMEmbeddingsInitProgressReport, CreateWebLLMEmbeddingsEngine, } from "./types";
|
|
15
|
+
export { E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS, E_WEBLLM_EMBEDDINGS_ENGINE_ERROR } from "./exceptions";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Option and engine types for the WebLLM Embeddings adapter.
|
|
3
|
+
*
|
|
4
|
+
* @module @nhtio/adk/batteries/embeddings/webllm/types
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Builds on the **shared** embeddings option base owned by the OpenAI Embeddings battery
|
|
8
|
+
* ({@link @nhtio/adk/batteries/embeddings/openai/types!BaseEmbeddingsAdapterOptions}). The two
|
|
9
|
+
* batteries differ only in their engine: this one `Omit`s nothing from the base (the base carries
|
|
10
|
+
* no HTTP fields) and adds the WebGPU/MLC engine knobs — exactly how the WebLLM Chat Completions
|
|
11
|
+
* battery extends the OpenAI Chat Completions option type.
|
|
12
|
+
*/
|
|
13
|
+
import type { BaseEmbeddingsAdapterOptions } from "../openai/types";
|
|
14
|
+
import type { ChatOptions, InitProgressReport, MLCEngineConfig, MLCEngineInterface } from '@mlc-ai/web-llm';
|
|
15
|
+
export type { EmbeddingKind, EmbedOptions, BaseEmbeddingsAdapterOptions } from "../openai/types";
|
|
16
|
+
/** The WebLLM engine handle this battery drives. Alias of `MLCEngineInterface`. */
|
|
17
|
+
export type WebLLMEmbeddingsEngine = MLCEngineInterface;
|
|
18
|
+
/** Progress report emitted while the engine loads weights. Alias of `InitProgressReport`. */
|
|
19
|
+
export type WebLLMEmbeddingsInitProgressReport = InitProgressReport;
|
|
20
|
+
/**
|
|
21
|
+
* Factory for lazily creating a WebLLM engine. Defaults to `CreateMLCEngine` from
|
|
22
|
+
* `@mlc-ai/web-llm`; override to inject a pre-configured engine, a web-worker engine, or a test
|
|
23
|
+
* double.
|
|
24
|
+
*/
|
|
25
|
+
export type CreateWebLLMEmbeddingsEngine = (input: {
|
|
26
|
+
model: string;
|
|
27
|
+
engineConfig?: MLCEngineConfig;
|
|
28
|
+
chatOptions?: ChatOptions | ChatOptions[];
|
|
29
|
+
onInitProgress?: (report: InitProgressReport) => void;
|
|
30
|
+
}) => Promise<WebLLMEmbeddingsEngine>;
|
|
31
|
+
/**
|
|
32
|
+
* Constructor options for {@link @nhtio/adk/batteries/embeddings/webllm/adapter!WebLLMEmbeddingsAdapter}.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* Extends the shared {@link BaseEmbeddingsAdapterOptions} (carrying the required `model` and the
|
|
36
|
+
* shared prefix options) with WebGPU/MLC engine fields. `model` accepts any MLC embedding model id
|
|
37
|
+
* (e.g. `snowflake-arctic-embed-m-q0f32-MLC`) — there is no default; the caller names it.
|
|
38
|
+
*/
|
|
39
|
+
export interface WebLLMEmbeddingsAdapterOptions extends BaseEmbeddingsAdapterOptions {
|
|
40
|
+
/** A pre-loaded engine. When provided, the battery uses it directly and skips lazy creation. */
|
|
41
|
+
engine?: WebLLMEmbeddingsEngine;
|
|
42
|
+
/** Override the engine factory. Default: `CreateMLCEngine` via a lazy dynamic import. */
|
|
43
|
+
createEngine?: CreateWebLLMEmbeddingsEngine;
|
|
44
|
+
/** Passed to `CreateMLCEngine` as the engine config (app config, cache, log level, etc.). */
|
|
45
|
+
engineConfig?: MLCEngineConfig;
|
|
46
|
+
/** Passed to `CreateMLCEngine` as chat options (model-specific knobs). */
|
|
47
|
+
chatOptions?: ChatOptions | ChatOptions[];
|
|
48
|
+
/** Called with load-progress reports while weights download/compile. */
|
|
49
|
+
onInitProgress?: (report: InitProgressReport) => void;
|
|
50
|
+
/** Override the WebGPU availability probe. Default: checks `navigator.gpu`. */
|
|
51
|
+
isWebGPUAvailable?: () => boolean;
|
|
52
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../chunk-Ble4zEEl.js");
|
|
3
|
+
require("../../../guards.cjs");
|
|
4
|
+
const require_batteries_embeddings_webllm_exceptions = require("./exceptions.cjs");
|
|
5
|
+
let _nhtio_validation = require("@nhtio/validation");
|
|
6
|
+
//#region src/batteries/embeddings/webllm/validation.ts
|
|
7
|
+
/**
|
|
8
|
+
* Validator schema for `WebLLMEmbeddingsAdapterOptions`. Rejects unknown top-level keys.
|
|
9
|
+
*/
|
|
10
|
+
var webLLMEmbeddingsOptionsSchema = _nhtio_validation.validator.object({
|
|
11
|
+
model: _nhtio_validation.validator.string().min(1).required(),
|
|
12
|
+
queryPrefix: _nhtio_validation.validator.string().optional(),
|
|
13
|
+
documentPrefix: _nhtio_validation.validator.string().optional(),
|
|
14
|
+
dimensions: _nhtio_validation.validator.number().integer().min(1).optional(),
|
|
15
|
+
engine: _nhtio_validation.validator.object().unknown(true).optional(),
|
|
16
|
+
createEngine: _nhtio_validation.validator.function().optional(),
|
|
17
|
+
engineConfig: _nhtio_validation.validator.object().unknown(true).optional(),
|
|
18
|
+
chatOptions: _nhtio_validation.validator.alternatives(_nhtio_validation.validator.object().unknown(true), _nhtio_validation.validator.array().items(_nhtio_validation.validator.object().unknown(true))).optional(),
|
|
19
|
+
onInitProgress: _nhtio_validation.validator.function().optional(),
|
|
20
|
+
isWebGPUAvailable: _nhtio_validation.validator.function().optional()
|
|
21
|
+
}).unknown(false);
|
|
22
|
+
var formatValidationDetails = (err) => err.details.map((d) => d.message).join(" and ");
|
|
23
|
+
/**
|
|
24
|
+
* Validates an arbitrary input against `webLLMEmbeddingsOptionsSchema` and returns the resolved
|
|
25
|
+
* options shape. Throws `E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS` (carrying the validator's report on
|
|
26
|
+
* `cause`) on failure.
|
|
27
|
+
*
|
|
28
|
+
* @param input - The raw options object to validate.
|
|
29
|
+
* @returns The resolved options object with defaults filled in.
|
|
30
|
+
*/
|
|
31
|
+
var validateOptions = (input) => {
|
|
32
|
+
const { value, error } = webLLMEmbeddingsOptionsSchema.validate(input, {
|
|
33
|
+
abortEarly: false,
|
|
34
|
+
convert: false
|
|
35
|
+
});
|
|
36
|
+
if (error) throw new require_batteries_embeddings_webllm_exceptions.E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS([formatValidationDetails(error)], { cause: error });
|
|
37
|
+
return value;
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
exports.validateOptions = validateOptions;
|
|
41
|
+
exports.webLLMEmbeddingsOptionsSchema = webLLMEmbeddingsOptionsSchema;
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=validation.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.cjs","names":[],"sources":["../../../../src/batteries/embeddings/webllm/validation.ts"],"sourcesContent":["/**\n * Runtime validation schema and wrapper for WebLLM Embeddings adapter options.\n *\n * @module @nhtio/adk/batteries/embeddings/webllm/validation\n *\n * @remarks\n * Validates `WebLLMEmbeddingsAdapterOptions` at construction time. Throws\n * `E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS` on failure. `model` is required; unknown top-level keys\n * are rejected so typos fail loud. WebGPU availability is checked at engine-resolution time (not\n * here), since an `engine` may be injected for tests/non-WebGPU paths.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS } from './exceptions'\nimport type { WebLLMEmbeddingsAdapterOptions } from './types'\n\n/**\n * Validator schema for `WebLLMEmbeddingsAdapterOptions`. Rejects unknown top-level keys.\n */\nexport const webLLMEmbeddingsOptionsSchema = validator\n .object<WebLLMEmbeddingsAdapterOptions>({\n // Shared base\n model: validator.string().min(1).required(),\n queryPrefix: validator.string().optional(),\n documentPrefix: validator.string().optional(),\n dimensions: validator.number().integer().min(1).optional(),\n // Engine knobs\n engine: validator.object().unknown(true).optional(),\n createEngine: validator.function().optional(),\n engineConfig: validator.object().unknown(true).optional(),\n chatOptions: validator\n .alternatives(\n validator.object().unknown(true),\n validator.array().items(validator.object().unknown(true))\n )\n .optional(),\n onInitProgress: validator.function().optional(),\n isWebGPUAvailable: validator.function().optional(),\n })\n .unknown(false)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates an arbitrary input against `webLLMEmbeddingsOptionsSchema` and returns the resolved\n * options shape. Throws `E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS` (carrying the validator's report on\n * `cause`) on failure.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults filled in.\n */\nexport const validateOptions = (input: unknown): WebLLMEmbeddingsAdapterOptions => {\n const { value, error } = webLLMEmbeddingsOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error) {\n throw new E_INVALID_WEBLLM_EMBEDDINGS_OPTIONS([formatValidationDetails(error)], {\n cause: error,\n })\n }\n return value as WebLLMEmbeddingsAdapterOptions\n}\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nvoid isValidationError\n"],"mappings":";;;;;;;;;AAoBA,IAAa,gCAAgC,kBAAA,UAC1C,OAAuC;CAEtC,OAAO,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;CAC1C,aAAa,kBAAA,UAAU,OAAO,EAAE,SAAS;CACzC,gBAAgB,kBAAA,UAAU,OAAO,EAAE,SAAS;CAC5C,YAAY,kBAAA,UAAU,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,SAAS;CAEzD,QAAQ,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS;CAClD,cAAc,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC5C,cAAc,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS;CACxD,aAAa,kBAAA,UACV,aACC,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,GAC/B,kBAAA,UAAU,MAAM,EAAE,MAAM,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,CAAC,CAC1D,EACC,SAAS;CACZ,gBAAgB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC9C,mBAAmB,kBAAA,UAAU,SAAS,EAAE,SAAS;AACnD,CAAC,EACA,QAAQ,KAAK;AAEhB,IAAM,2BAA2B,QAC/B,IAAI,QAAQ,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO;;;;;;;;;AAUhD,IAAa,mBAAmB,UAAmD;CACjF,MAAM,EAAE,OAAO,UAAU,8BAA8B,SAAS,OAAO;EACrE,YAAY;EACZ,SAAS;CACX,CAAC;CACD,IAAI,OACF,MAAM,IAAI,+CAAA,oCAAoC,CAAC,wBAAwB,KAAK,CAAC,GAAG,EAC9E,OAAO,MACT,CAAC;CAEH,OAAO;AACT"}
|