@nhtio/adk 1.20260624.1 → 1.20260625.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 (101) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/batteries/llm/litert_lm/adapter.cjs +535 -0
  3. package/batteries/llm/litert_lm/adapter.cjs.map +1 -0
  4. package/batteries/llm/litert_lm/adapter.d.ts +62 -0
  5. package/batteries/llm/litert_lm/adapter.mjs +533 -0
  6. package/batteries/llm/litert_lm/adapter.mjs.map +1 -0
  7. package/batteries/llm/litert_lm/exceptions.cjs +68 -0
  8. package/batteries/llm/litert_lm/exceptions.cjs.map +1 -0
  9. package/batteries/llm/litert_lm/exceptions.d.ts +71 -0
  10. package/batteries/llm/litert_lm/exceptions.mjs +62 -0
  11. package/batteries/llm/litert_lm/exceptions.mjs.map +1 -0
  12. package/batteries/llm/litert_lm/helpers.cjs +378 -0
  13. package/batteries/llm/litert_lm/helpers.cjs.map +1 -0
  14. package/batteries/llm/litert_lm/helpers.d.ts +201 -0
  15. package/batteries/llm/litert_lm/helpers.mjs +341 -0
  16. package/batteries/llm/litert_lm/helpers.mjs.map +1 -0
  17. package/batteries/llm/litert_lm/index.d.ts +31 -0
  18. package/batteries/llm/litert_lm/types.cjs +2 -0
  19. package/batteries/llm/litert_lm/types.d.ts +151 -0
  20. package/batteries/llm/litert_lm/types.mjs +0 -0
  21. package/batteries/llm/litert_lm/validation.cjs +109 -0
  22. package/batteries/llm/litert_lm/validation.cjs.map +1 -0
  23. package/batteries/llm/litert_lm/validation.d.ts +19 -0
  24. package/batteries/llm/litert_lm/validation.mjs +106 -0
  25. package/batteries/llm/litert_lm/validation.mjs.map +1 -0
  26. package/batteries/llm/litert_lm.cjs +52 -0
  27. package/batteries/llm/litert_lm.mjs +7 -0
  28. package/batteries/media/lint.cjs +1 -1
  29. package/batteries/media/lint.mjs +1 -1
  30. package/batteries/tools/scrapper.cjs +1 -1
  31. package/batteries/tools/scrapper.mjs +1 -1
  32. package/batteries/tools/searxng.cjs +1 -1
  33. package/batteries/tools/searxng.mjs +1 -1
  34. package/batteries/tools.cjs +2 -2
  35. package/batteries/tools.mjs +2 -2
  36. package/batteries/vector/chroma.cjs +1 -1
  37. package/batteries/vector/chroma.mjs +1 -1
  38. package/batteries/vector/clickhouse.cjs +1 -1
  39. package/batteries/vector/clickhouse.mjs +1 -1
  40. package/batteries/vector/cloudflare.cjs +1 -1
  41. package/batteries/vector/cloudflare.mjs +1 -1
  42. package/batteries/vector/couchbase.cjs +1 -1
  43. package/batteries/vector/couchbase.mjs +1 -1
  44. package/batteries/vector/duckdb.cjs +1 -1
  45. package/batteries/vector/duckdb.mjs +1 -1
  46. package/batteries/vector/elasticsearch.cjs +1 -1
  47. package/batteries/vector/elasticsearch.mjs +1 -1
  48. package/batteries/vector/hnswlib.cjs +1 -1
  49. package/batteries/vector/hnswlib.mjs +1 -1
  50. package/batteries/vector/in_memory.cjs +1 -1
  51. package/batteries/vector/in_memory.mjs +1 -1
  52. package/batteries/vector/lancedb.cjs +1 -1
  53. package/batteries/vector/lancedb.mjs +1 -1
  54. package/batteries/vector/mariadb.cjs +1 -1
  55. package/batteries/vector/mariadb.mjs +1 -1
  56. package/batteries/vector/milvus.cjs +1 -1
  57. package/batteries/vector/milvus.mjs +1 -1
  58. package/batteries/vector/opensearch.cjs +1 -1
  59. package/batteries/vector/opensearch.mjs +1 -1
  60. package/batteries/vector/oracle23ai.cjs +1 -1
  61. package/batteries/vector/oracle23ai.mjs +1 -1
  62. package/batteries/vector/orama.cjs +1 -1
  63. package/batteries/vector/orama.mjs +1 -1
  64. package/batteries/vector/pgvector.cjs +1 -1
  65. package/batteries/vector/pgvector.mjs +1 -1
  66. package/batteries/vector/pinecone.cjs +1 -1
  67. package/batteries/vector/pinecone.mjs +1 -1
  68. package/batteries/vector/qdrant.cjs +1 -1
  69. package/batteries/vector/qdrant.mjs +1 -1
  70. package/batteries/vector/redis.cjs +1 -1
  71. package/batteries/vector/redis.mjs +1 -1
  72. package/batteries/vector/s3vectors.cjs +1 -1
  73. package/batteries/vector/s3vectors.mjs +1 -1
  74. package/batteries/vector/sqlite_vec.cjs +1 -1
  75. package/batteries/vector/sqlite_vec.mjs +1 -1
  76. package/batteries/vector/typesense.cjs +1 -1
  77. package/batteries/vector/typesense.mjs +1 -1
  78. package/batteries/vector/vespa.cjs +1 -1
  79. package/batteries/vector/vespa.mjs +1 -1
  80. package/batteries/vector/weaviate.cjs +1 -1
  81. package/batteries/vector/weaviate.mjs +1 -1
  82. package/batteries/vector.cjs +2 -2
  83. package/batteries/vector.mjs +2 -2
  84. package/batteries.cjs +16 -16
  85. package/batteries.mjs +16 -16
  86. package/eslint.cjs +1 -1
  87. package/eslint.mjs +1 -1
  88. package/index.cjs +1 -1
  89. package/index.mjs +1 -1
  90. package/mcp/adk-docs-corpus.json +1 -1
  91. package/package.json +185 -151
  92. package/{scrapper-BUCxsVVi.js → scrapper-B5G70UqQ.js} +2 -2
  93. package/{scrapper-BUCxsVVi.js.map → scrapper-B5G70UqQ.js.map} +1 -1
  94. package/{scrapper-CxmS0VaD.mjs → scrapper-DpTMyQcz.mjs} +2 -2
  95. package/{scrapper-CxmS0VaD.mjs.map → scrapper-DpTMyQcz.mjs.map} +1 -1
  96. package/{searxng-Dgh-4RpS.mjs → searxng-L-wd-A_n.mjs} +2 -2
  97. package/{searxng-Dgh-4RpS.mjs.map → searxng-L-wd-A_n.mjs.map} +1 -1
  98. package/{searxng-CgxQluyF.js → searxng-Q79l7IdQ.js} +2 -2
  99. package/{searxng-CgxQluyF.js.map → searxng-Q79l7IdQ.js.map} +1 -1
  100. package/server.json +2 -2
  101. package/skills/adk-assembly/SKILL.md +2 -2
package/CHANGELOG.md CHANGED
@@ -19,6 +19,26 @@ upgrading.
19
19
 
20
20
  ### Added
21
21
 
22
+ - **New opt-in LLM battery `@nhtio/adk/batteries/llm/litert_lm` — on-device WebGPU inference of Google's
23
+ `.litertlm` models.** Ships `LiteRtLmAdapter`, a one-line {@link DispatchExecutorFn} wrapping
24
+ [`@litert-lm/core`](https://www.npmjs.com/package/@litert-lm/core) (browser/WebGPU + a bundled wasm
25
+ runtime). Unlike the WebLLM battery it is **standalone, not an OpenAI-wire subclass**: it drives
26
+ LiteRT's native `Engine.create() → createConversation({ preface }) → sendMessageStreaming():
27
+ ReadableStream<Message>` API, takes tool-call `arguments` as a parsed object (no `JSON.parse`), and
28
+ surfaces "thinking" via `Message.channels` → ADK thoughts. Full parity with the other batteries: text,
29
+ streaming, thoughts, tool use, sampler/limit controls (`samplerParams`, `maxOutputTokens`,
30
+ `maxNumTokens`, `backend`), and the typed multimodal contract (`audioModalityEnabled` /
31
+ `visionModalityEnabled`). It reuses the format-agnostic render helpers; only the wire-shape mappers are
32
+ LiteRT-native (`buildLiteRtConversationInput`, `toolsToLiteRtTools`, `renderLiteRtToolResult`, the
33
+ streaming accumulator), each swappable via `helpers`. `STASH_KEY` is `'liteRtLm'`; exceptions are the
34
+ `E_LITERT_LM_*` family plus `E_INVALID_LITERT_LM_OPTIONS` and `E_UNSUPPORTED_MEDIA_MODALITY`.
35
+ - **`@litert-lm/core` is an optional peer dependency**, pinned exact (`0.13.1`) — it ships its own
36
+ ~19 MB wasm and is **not** bundled into `@nhtio/adk`. Install it yourself (`pnpm add @litert-lm/core`)
37
+ when you want this battery; it is never required for type-checking a consumer.
38
+ - **The published `@litert-lm/core` docs lag the library** — tool use, channels, sampler controls, and
39
+ multimodality are typed but undocumented. The adapter is mapped against the installed `.d.ts` (the
40
+ source of truth); re-verify on upgrade. Preview `.litertlm` models are text-in/text-out today, so the
41
+ native multimodal path is built-to-contract but not yet exercisable end-to-end.
22
42
  - **Serialization: the ADK primitives now round-trip through [`@nhtio/encoder`](https://encoder.nht.io).**
23
43
  Encode an entire conversation graph — `Message`s with nested `Identity`, `Tokenizable`, and `Media`;
24
44
  `ToolCall`s with their results; `Memory`, `Thought`, `Retrievable`, `Registry` — to a string with
@@ -0,0 +1,535 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../chunk-Cek0wNdY.js");
3
+ const require_tool_registry = require("../../../tool_registry-CIIfbY_w.js");
4
+ const require_thought = require("../../../thought-CU7PYkB1.js");
5
+ const require_spooled_artifact = require("../../../spooled_artifact-MbMz6NXX.js");
6
+ require("../../../common-CpcsEqPY.js");
7
+ const require_tool_call = require("../../../tool_call-BixyvnWZ.js");
8
+ require("../../../guards.cjs");
9
+ const require_batteries_storage_in_memory = require("../../storage/in_memory.cjs");
10
+ const require_helpers = require("../../../helpers-1okZzNCa.js");
11
+ const require_batteries_llm_litert_lm_exceptions = require("./exceptions.cjs");
12
+ const require_batteries_llm_litert_lm_validation = require("./validation.cjs");
13
+ const require_batteries_llm_litert_lm_helpers = require("./helpers.cjs");
14
+ let luxon = require("luxon");
15
+ let js_sha256 = require("js-sha256");
16
+ let uuid = require("uuid");
17
+ //#region src/batteries/llm/litert_lm/adapter.ts
18
+ /**
19
+ * Browser/WebGPU executor adapter for Google's LiteRT-LM (`@litert-lm/core`).
20
+ *
21
+ * @module @nhtio/adk/batteries/llm/litert_lm/adapter
22
+ *
23
+ * @remarks
24
+ * On-device LLM inference via WebGPU + a bundled wasm runtime, `.litertlm` models. Unlike the WebLLM
25
+ * battery (a thin extension of the OpenAI Chat Completions wire shape), LiteRT-LM has its **own** API —
26
+ * `Engine.create() → engine.createConversation({ preface }) → conversation.sendMessageStreaming():
27
+ * ReadableStream<Message>` — with native `Message`/`Tool`/`tool_calls`/`tool_response` shapes (tool-call
28
+ * `arguments` arrive as a parsed object, not a JSON string). So this is a standalone adapter that reuses
29
+ * the ADK's format-agnostic render helpers but maps history/tools/results to LiteRT's shapes.
30
+ *
31
+ * Three pluggable layers mirror the other LLM batteries: swappable translation helpers, three-layer
32
+ * options merging (constructor → `executor()` overrides → `ctx.stash.liteRtLm`), and an
33
+ * injectable/lazy engine (`engine` or `createEngine`, defaulting to a dynamic `@litert-lm/core` import).
34
+ *
35
+ * **The published `@litert-lm/core` docs lag the library** — every wire field here is mapped against the
36
+ * installed package's type declarations, the source of truth. The dependency is young (pinned exact);
37
+ * re-verify on upgrade.
38
+ */
39
+ var mergeHelpers = (layers) => {
40
+ let merged;
41
+ for (const layer of layers) {
42
+ if (!layer) continue;
43
+ merged = {
44
+ ...merged ?? {},
45
+ ...layer
46
+ };
47
+ }
48
+ return merged;
49
+ };
50
+ var mergeOptions = (baseline, exec, stash) => {
51
+ const layers = [
52
+ baseline,
53
+ exec ?? {},
54
+ stash ?? {}
55
+ ];
56
+ const out = {};
57
+ for (const layer of layers) for (const [k, v] of Object.entries(layer)) {
58
+ if (v === void 0) continue;
59
+ if (k === "helpers") continue;
60
+ out[k] = v;
61
+ }
62
+ const helpers = mergeHelpers(layers.map((l) => l.helpers));
63
+ if (helpers !== void 0) out.helpers = helpers;
64
+ return out;
65
+ };
66
+ var resolveHelpers = (overrides) => {
67
+ const src = overrides ?? {};
68
+ return {
69
+ descriptionToChatCompletionsJsonSchema: src.descriptionToChatCompletionsJsonSchema ?? require_helpers.defaultDescriptionToChatCompletionsJsonSchema,
70
+ renderUntrustedContent: src.renderUntrustedContent ?? require_helpers.defaultRenderUntrustedContent,
71
+ renderTrustedContent: src.renderTrustedContent ?? require_helpers.defaultRenderTrustedContent,
72
+ renderStandingInstructions: src.renderStandingInstructions ?? require_helpers.defaultRenderStandingInstructions,
73
+ renderMemories: src.renderMemories ?? require_helpers.defaultRenderMemories,
74
+ renderRetrievables: src.renderRetrievables ?? require_helpers.defaultRenderRetrievables,
75
+ renderRetrievableSafetyDirective: src.renderRetrievableSafetyDirective ?? require_helpers.defaultRenderRetrievableSafetyDirective,
76
+ renderFirstPartyRetrievables: src.renderFirstPartyRetrievables ?? require_helpers.defaultRenderFirstPartyRetrievables,
77
+ renderThirdPartyPublicRetrievables: src.renderThirdPartyPublicRetrievables ?? require_helpers.defaultRenderThirdPartyPublicRetrievables,
78
+ renderThirdPartyPrivateRetrievables: src.renderThirdPartyPrivateRetrievables ?? require_helpers.defaultRenderThirdPartyPrivateRetrievables,
79
+ renderThought: src.renderThought ?? require_helpers.defaultRenderThought,
80
+ filterThoughts: src.filterThoughts ?? require_helpers.defaultFilterThoughts,
81
+ renderChatCompletionsSystemPrompt: src.renderChatCompletionsSystemPrompt ?? require_helpers.defaultRenderChatCompletionsSystemPrompt,
82
+ toolsToLiteRtTools: src.toolsToLiteRtTools ?? require_batteries_llm_litert_lm_helpers.defaultToolsToLiteRtTools,
83
+ renderLiteRtToolResult: src.renderLiteRtToolResult ?? require_batteries_llm_litert_lm_helpers.defaultRenderLiteRtToolResult,
84
+ buildLiteRtConversationInput: src.buildLiteRtConversationInput ?? require_batteries_llm_litert_lm_helpers.defaultBuildLiteRtConversationInput,
85
+ createLiteRtStreamAccumulator: src.createLiteRtStreamAccumulator ?? require_batteries_llm_litert_lm_helpers.defaultCreateLiteRtStreamAccumulator
86
+ };
87
+ };
88
+ var nowIso = () => luxon.DateTime.now().toISO();
89
+ var computeChecksum = (tool, args) => (0, js_sha256.sha256)(require_tool_registry.canonicalStringify({
90
+ tool,
91
+ args
92
+ }));
93
+ /**
94
+ * Cross-environment executor adapter for LiteRT-LM.
95
+ *
96
+ * @remarks
97
+ * Construct with at least `{ model }`; wire `new LiteRtLmAdapter(opts).executor()` into a
98
+ * `DispatchRunner` as the `executorCallback`. The engine is resolved lazily on first dispatch (or
99
+ * eagerly via {@link LiteRtLmAdapter.preload}); pass `engine` to inject a pre-built one (e.g. in tests).
100
+ */
101
+ var LiteRtLmAdapter = class LiteRtLmAdapter {
102
+ /** The `ctx.stash` key under which per-dispatch option overrides are read. */
103
+ static STASH_KEY = "liteRtLm";
104
+ #baseline;
105
+ #engine;
106
+ #enginePromise;
107
+ /**
108
+ * Returns `true` when the current runtime exposes WebGPU (`navigator.gpu`).
109
+ */
110
+ static isAvailable() {
111
+ return typeof globalThis.navigator !== "undefined" && "gpu" in globalThis.navigator && typeof globalThis.navigator.gpu !== "undefined";
112
+ }
113
+ /**
114
+ * @param options - Raw adapter options, validated against `liteRtLmOptionsSchema`.
115
+ * @throws {@link @nhtio/adk/batteries!E_INVALID_LITERT_LM_OPTIONS} when `options` are invalid.
116
+ */
117
+ constructor(options) {
118
+ this.#baseline = require_batteries_llm_litert_lm_validation.validateOptions(options);
119
+ this.#engine = this.#baseline.engine;
120
+ }
121
+ /** Instance WebGPU-availability probe (honours the `isWebGPUAvailable` option override). */
122
+ isAvailable() {
123
+ return (this.#baseline.isWebGPUAvailable ?? LiteRtLmAdapter.isAvailable)();
124
+ }
125
+ /**
126
+ * Eagerly resolve (load) the engine before the first dispatch.
127
+ *
128
+ * @param overrides - Optional option overrides applied for this load.
129
+ * @returns The resolved {@link LiteRtLmEngine}.
130
+ */
131
+ async preload(overrides) {
132
+ const merged = require_batteries_llm_litert_lm_validation.validateOptions(mergeOptions(this.#baseline, overrides, void 0));
133
+ return this.#resolveEngine(merged);
134
+ }
135
+ /** Drop the cached engine and any in-flight load so the next dispatch re-resolves it. */
136
+ reset() {
137
+ this.#engine = void 0;
138
+ this.#enginePromise = void 0;
139
+ }
140
+ /** Build the LiteRT `EngineSettings` from the merged adapter options. */
141
+ #engineSettings(merged) {
142
+ const settings = { model: merged.model };
143
+ if (merged.backend !== void 0) settings.backend = merged.backend;
144
+ if (merged.maxNumTokens !== void 0) settings.mainExecutorSettings = { maxNumTokens: merged.maxNumTokens };
145
+ return settings;
146
+ }
147
+ async #resolveEngine(merged) {
148
+ if (merged.engine) {
149
+ this.#engine = merged.engine;
150
+ return merged.engine;
151
+ }
152
+ if (this.#engine) return this.#engine;
153
+ if (!(merged.isWebGPUAvailable ?? LiteRtLmAdapter.isAvailable)()) throw new require_batteries_llm_litert_lm_exceptions.E_INVALID_LITERT_LM_OPTIONS(["LiteRT-LM requires a browser/runtime with WebGPU support"]);
154
+ this.#enginePromise ??= (async () => {
155
+ const engineSettings = this.#engineSettings(merged);
156
+ const engine = await (merged.createEngine ?? (async ({ engineSettings: settings }) => {
157
+ const { Engine } = await import("@litert-lm/core");
158
+ return await Engine.create(settings, merged.inputPromptAsHint);
159
+ }))({
160
+ engineSettings,
161
+ onInitProgress: merged.onInitProgress
162
+ });
163
+ this.#engine = engine;
164
+ return engine;
165
+ })();
166
+ return this.#enginePromise;
167
+ }
168
+ /** Build the per-dispatch session config from the merged options. */
169
+ #sessionConfig(merged) {
170
+ const cfg = {};
171
+ if (merged.samplerParams !== void 0) cfg.samplerParams = merged.samplerParams;
172
+ if (merged.maxOutputTokens !== void 0) cfg.maxOutputTokens = merged.maxOutputTokens;
173
+ if (merged.audioModalityEnabled !== void 0) cfg.audioModalityEnabled = merged.audioModalityEnabled;
174
+ if (merged.visionModalityEnabled !== void 0) cfg.visionModalityEnabled = merged.visionModalityEnabled;
175
+ return Object.keys(cfg).length > 0 ? cfg : void 0;
176
+ }
177
+ /**
178
+ * Produce the bound {@link DispatchExecutorFn} the `DispatchRunner` invokes.
179
+ *
180
+ * @param overrides - Option overrides layered above the constructor baseline (below `ctx.stash`).
181
+ */
182
+ executor(overrides) {
183
+ const baseline = this.#baseline;
184
+ const adapterClass = LiteRtLmAdapter;
185
+ const self = this;
186
+ return async (ctx, helpers) => {
187
+ const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {});
188
+ const merged = require_batteries_llm_litert_lm_validation.validateOptions(mergeOptions(baseline, overrides, stashRaw && typeof stashRaw === "object" ? stashRaw : {}));
189
+ const h = resolveHelpers(merged.helpers);
190
+ const selfIdentity = merged.selfIdentity ?? "assistant";
191
+ const unsupportedMediaPolicy = merged.unsupportedMediaPolicy ?? "throw";
192
+ let mergedRegistry = ctx.tools;
193
+ const artifactCtors = /* @__PURE__ */ new Set();
194
+ for (const tc of ctx.turnToolCalls) {
195
+ const r = tc.results;
196
+ const arr = Array.isArray(r) ? r : [r];
197
+ for (const item of arr) if (require_spooled_artifact.SpooledArtifact.isSpooledArtifact(item)) {
198
+ const ctor = item.constructor;
199
+ if (typeof ctor.forgeTools === "function") artifactCtors.add(ctor);
200
+ }
201
+ }
202
+ if (artifactCtors.size > 0) {
203
+ const registries = [ctx.tools, ...[...artifactCtors].map((c) => c.forgeTools(ctx))];
204
+ mergedRegistry = require_tool_registry.ToolRegistry.merge(registries, { onCollision: "keep" });
205
+ mergedRegistry.bindContext(ctx);
206
+ }
207
+ const renderedToolCallResults = /* @__PURE__ */ new Map();
208
+ for (const tc of ctx.turnToolCalls) {
209
+ const tool = mergedRegistry.get(tc.tool);
210
+ const item = await h.renderLiteRtToolResult({
211
+ toolCall: tc,
212
+ results: tc.results,
213
+ tool,
214
+ unsupportedMediaPolicy,
215
+ renderUntrustedContent: h.renderUntrustedContent,
216
+ renderTrustedContent: h.renderTrustedContent,
217
+ warn: (m) => helpers.log.warn({
218
+ kind: "litert-render-warning",
219
+ message: m
220
+ })
221
+ });
222
+ renderedToolCallResults.set(tc.id, item);
223
+ }
224
+ if (merged.tokenEncoding && merged.contextWindow !== void 0) {
225
+ const enc = merged.tokenEncoding;
226
+ const tally = (s) => new require_tool_registry.Tokenizable(s).estimateTokens(enc);
227
+ let total = tally(ctx.systemPrompt.toString());
228
+ for (const si of ctx.standingInstructions) total += tally(si.toString());
229
+ for (const m of ctx.turnMemories) total += tally(m.content.toString());
230
+ for (const r of ctx.turnRetrievables) total += tally(await r.contentString?.() ?? "");
231
+ for (const m of ctx.turnMessages) total += tally(m.content?.toString() ?? "");
232
+ for (const t of ctx.turnThoughts) total += tally(t.content.toString());
233
+ for (const item of renderedToolCallResults.values()) {
234
+ const tr = item.tool_response;
235
+ total += tally(tr?.response?.content ?? "");
236
+ }
237
+ if (total > merged.contextWindow) throw new require_batteries_llm_litert_lm_exceptions.E_LITERT_LM_CONTEXT_OVERFLOW([
238
+ total,
239
+ merged.contextWindow,
240
+ String(enc),
241
+ `system+buckets+timeline=${total}`
242
+ ]);
243
+ }
244
+ const { preface, messages: turnMessages } = await h.buildLiteRtConversationInput({
245
+ systemPrompt: ctx.systemPrompt,
246
+ standingInstructions: ctx.standingInstructions,
247
+ memories: ctx.turnMemories,
248
+ retrievables: ctx.turnRetrievables,
249
+ messages: ctx.turnMessages,
250
+ thoughts: ctx.turnThoughts,
251
+ toolCalls: ctx.turnToolCalls,
252
+ tools: mergedRegistry,
253
+ renderedToolCallResults,
254
+ bucketOrder: merged.bucketOrder ?? [
255
+ "standingInstructions",
256
+ "memories",
257
+ "retrievables",
258
+ "timeline"
259
+ ],
260
+ selfIdentity,
261
+ thoughtSurfacing: merged.thoughtSurfacing ?? "all-self",
262
+ replayCompatibility: merged.replayCompatibility ?? [],
263
+ toolsToLiteRtTools: h.toolsToLiteRtTools,
264
+ renderThought: h.renderThought,
265
+ filterThoughts: h.filterThoughts,
266
+ renderUntrustedContent: h.renderUntrustedContent,
267
+ renderTrustedContent: h.renderTrustedContent,
268
+ renderChatCompletionsSystemPrompt: h.renderChatCompletionsSystemPrompt,
269
+ renderStandingInstructions: h.renderStandingInstructions,
270
+ renderMemories: h.renderMemories,
271
+ renderRetrievables: h.renderRetrievables,
272
+ renderRetrievableSafetyDirective: h.renderRetrievableSafetyDirective,
273
+ renderFirstPartyRetrievables: h.renderFirstPartyRetrievables,
274
+ renderThirdPartyPublicRetrievables: h.renderThirdPartyPublicRetrievables,
275
+ renderThirdPartyPrivateRetrievables: h.renderThirdPartyPrivateRetrievables,
276
+ warn: (m) => helpers.log.warn({
277
+ kind: "litert-history-warning",
278
+ message: m
279
+ })
280
+ });
281
+ const sessionConfig = self.#sessionConfig(merged);
282
+ const conversationConfig = {
283
+ preface,
284
+ ...sessionConfig ? { sessionConfig } : {},
285
+ ...merged.enableConstrainedDecoding !== void 0 ? { enableConstrainedDecoding: merged.enableConstrainedDecoding } : {},
286
+ ...merged.filterChannelContentFromKvCache !== void 0 ? { filterChannelContentFromKvCache: merged.filterChannelContentFromKvCache } : {}
287
+ };
288
+ let conversation;
289
+ try {
290
+ conversation = await (await self.#resolveEngine(merged)).createConversation(conversationConfig);
291
+ } catch (err) {
292
+ ctx.nack(new require_batteries_llm_litert_lm_exceptions.E_LITERT_LM_STREAM_ERROR([require_tool_registry.isError(err) ? err.message : String(err)]));
293
+ return;
294
+ }
295
+ const spoolStore = merged.spoolStore ?? new require_batteries_storage_in_memory.InMemorySpoolStore();
296
+ const stream = merged.stream ?? true;
297
+ const onAbort = () => {
298
+ try {
299
+ conversation.cancel();
300
+ } catch {}
301
+ };
302
+ if (ctx.abortSignal.aborted) {
303
+ onAbort();
304
+ return;
305
+ }
306
+ ctx.abortSignal.addEventListener("abort", onAbort, { once: true });
307
+ const executeAndPersistToolCall = async (call) => {
308
+ const tool = mergedRegistry.get(call.name);
309
+ const completedAt = nowIso();
310
+ if (!call.argsWellFormed) {
311
+ const results = new require_tool_registry.Tokenizable(new require_batteries_llm_litert_lm_exceptions.E_LITERT_LM_INVALID_TOOL_CALL_ARGS(["must be a JSON object", JSON.stringify(call.args)]).message);
312
+ helpers.reportToolCall(call.id, {
313
+ tool: call.name,
314
+ args: {}
315
+ });
316
+ helpers.reportToolCall(call.id, {
317
+ results,
318
+ isError: true,
319
+ isComplete: true
320
+ });
321
+ await ctx.storeToolCall(new require_tool_call.ToolCall({
322
+ id: call.id,
323
+ tool: call.name,
324
+ args: {},
325
+ checksum: computeChecksum(call.name, {}),
326
+ isComplete: true,
327
+ isError: true,
328
+ results,
329
+ createdAt: completedAt,
330
+ updatedAt: completedAt,
331
+ completedAt
332
+ }));
333
+ return;
334
+ }
335
+ if (!tool) {
336
+ const available = mergedRegistry.all().map((t) => t.name).sort();
337
+ const results = new require_tool_registry.Tokenizable(available.length > 0 ? `Tool not found: ${call.name}. Available tools: ${available.join(", ")}.` : `Tool not found: ${call.name}. No tools are available this turn.`);
338
+ helpers.reportToolCall(call.id, {
339
+ tool: call.name,
340
+ args: call.args
341
+ });
342
+ helpers.reportToolCall(call.id, {
343
+ results,
344
+ isError: true,
345
+ isComplete: true
346
+ });
347
+ await ctx.storeToolCall(new require_tool_call.ToolCall({
348
+ id: call.id,
349
+ tool: call.name,
350
+ args: call.args,
351
+ checksum: computeChecksum(call.name, call.args),
352
+ isComplete: true,
353
+ isError: true,
354
+ results,
355
+ createdAt: completedAt,
356
+ updatedAt: completedAt,
357
+ completedAt
358
+ }));
359
+ return;
360
+ }
361
+ helpers.reportToolCall(call.id, {
362
+ tool: tool.name,
363
+ args: call.args
364
+ });
365
+ const isArtifactTool = require_spooled_artifact.ArtifactTool.isArtifactTool(tool);
366
+ let results = new require_tool_registry.Tokenizable("");
367
+ let toolHadError = false;
368
+ try {
369
+ const raw = await tool.executor(ctx)(call.args);
370
+ if (isArtifactTool) results = require_tool_registry.Tokenizable.isTokenizable(raw) ? raw : typeof raw === "string" ? new require_tool_registry.Tokenizable(raw) : (() => {
371
+ throw new Error(`ArtifactTool "${tool.name}" returned a non-string/non-Tokenizable value`);
372
+ })();
373
+ else if (require_tool_call.Media.isMedia(raw)) results = raw;
374
+ else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => require_tool_call.Media.isMedia(m))) results = raw;
375
+ else if (typeof raw === "string" || require_tool_registry.isInstanceOf(raw, "Uint8Array", Uint8Array)) {
376
+ const reader = await spoolStore.write(call.id, raw);
377
+ results = new ((tool.artifactConstructor?.()) ?? require_spooled_artifact.SpooledArtifact)(reader);
378
+ } else {
379
+ const reader = await spoolStore.write(call.id, String(raw));
380
+ results = new ((tool.artifactConstructor?.()) ?? require_spooled_artifact.SpooledArtifact)(reader);
381
+ }
382
+ } catch (err) {
383
+ toolHadError = true;
384
+ let detailMsg = require_tool_registry.isError(err) ? err.message : String(err);
385
+ if (require_tool_registry.isError(err) && require_tool_registry.isError(err.cause) && err.cause.message !== err.message) detailMsg = `${detailMsg} ${err.cause.message}`;
386
+ results = new require_tool_registry.Tokenizable(detailMsg);
387
+ }
388
+ helpers.reportToolCall(call.id, {
389
+ results,
390
+ isError: toolHadError,
391
+ isComplete: true
392
+ });
393
+ const completedAt2 = nowIso();
394
+ await ctx.storeToolCall(new require_tool_call.ToolCall({
395
+ id: call.id,
396
+ tool: tool.name,
397
+ args: call.args,
398
+ checksum: computeChecksum(tool.name, call.args),
399
+ isComplete: true,
400
+ isError: toolHadError,
401
+ results,
402
+ fromArtifactTool: isArtifactTool,
403
+ createdAt: completedAt2,
404
+ updatedAt: completedAt2,
405
+ completedAt: completedAt2
406
+ }));
407
+ };
408
+ const assembleCalls = (raw) => raw.map((c) => ({
409
+ id: (0, uuid.v6)(),
410
+ name: c.name,
411
+ args: require_tool_registry.isObject(c.arguments) ? c.arguments : {},
412
+ argsWellFormed: require_tool_registry.isObject(c.arguments)
413
+ }));
414
+ if (stream) {
415
+ const accumulator = h.createLiteRtStreamAccumulator();
416
+ const streamId = (0, uuid.v6)();
417
+ let sawMessage = false;
418
+ const channelStreamIds = /* @__PURE__ */ new Map();
419
+ let readable;
420
+ try {
421
+ readable = conversation.sendMessageStreaming(turnMessages);
422
+ } catch (err) {
423
+ ctx.nack(new require_batteries_llm_litert_lm_exceptions.E_LITERT_LM_STREAM_ERROR([require_tool_registry.isError(err) ? err.message : String(err)]));
424
+ return;
425
+ }
426
+ try {
427
+ const reader = readable.getReader();
428
+ while (true) {
429
+ if (ctx.abortSignal.aborted) {
430
+ await reader.cancel().catch(() => void 0);
431
+ return;
432
+ }
433
+ const { value: chunk, done } = await reader.read();
434
+ if (done) break;
435
+ if (!chunk) continue;
436
+ const { contentDelta, channelDeltas } = accumulator.feed(chunk);
437
+ if (contentDelta.length > 0) {
438
+ sawMessage = true;
439
+ helpers.reportMessage(streamId, contentDelta);
440
+ }
441
+ for (const { channel, delta } of channelDeltas) {
442
+ if (!channelStreamIds.has(channel)) channelStreamIds.set(channel, (0, uuid.v6)());
443
+ helpers.reportThought(channelStreamIds.get(channel), delta);
444
+ }
445
+ }
446
+ } catch (err) {
447
+ if (ctx.abortSignal.aborted) return;
448
+ ctx.nack(new require_batteries_llm_litert_lm_exceptions.E_LITERT_LM_STREAM_ERROR([require_tool_registry.isError(err) ? err.message : String(err)]));
449
+ return;
450
+ }
451
+ if (sawMessage) {
452
+ helpers.reportMessage(streamId, "", { isComplete: true });
453
+ await ctx.storeMessage(new require_thought.Message({
454
+ id: streamId,
455
+ role: "assistant",
456
+ content: accumulator.content(),
457
+ identity: selfIdentity,
458
+ createdAt: nowIso(),
459
+ updatedAt: nowIso()
460
+ }));
461
+ }
462
+ for (const [channel, text] of Object.entries(accumulator.channels())) {
463
+ const id = channelStreamIds.get(channel) ?? (0, uuid.v6)();
464
+ helpers.reportThought(id, "", { isComplete: true });
465
+ await ctx.storeThought(new require_thought.Thought({
466
+ id,
467
+ content: text,
468
+ identity: selfIdentity,
469
+ createdAt: nowIso(),
470
+ updatedAt: nowIso()
471
+ }));
472
+ }
473
+ const calls = assembleCalls(accumulator.toolCalls());
474
+ if (calls.length === 0) {
475
+ if (merged.autoAck) ctx.ack();
476
+ return;
477
+ }
478
+ for (const call of calls) {
479
+ if (ctx.abortSignal.aborted) return;
480
+ await executeAndPersistToolCall(call);
481
+ }
482
+ return;
483
+ }
484
+ let final;
485
+ try {
486
+ final = await conversation.sendMessage(turnMessages);
487
+ } catch (err) {
488
+ ctx.nack(new require_batteries_llm_litert_lm_exceptions.E_LITERT_LM_STREAM_ERROR([require_tool_registry.isError(err) ? err.message : String(err)]));
489
+ return;
490
+ }
491
+ const responseId = (0, uuid.v6)();
492
+ const contentText = typeof final.content === "string" ? final.content : Array.isArray(final.content) ? final.content.filter((i) => i.type === "text" && typeof i.text === "string").map((i) => i.text).join("") : "";
493
+ if (contentText.length > 0) {
494
+ const messageId = `${responseId}:message`;
495
+ helpers.reportMessage(messageId, contentText, { isComplete: true });
496
+ await ctx.storeMessage(new require_thought.Message({
497
+ id: messageId,
498
+ role: "assistant",
499
+ content: contentText,
500
+ identity: selfIdentity,
501
+ createdAt: nowIso(),
502
+ updatedAt: nowIso()
503
+ }));
504
+ }
505
+ if (final.channels && typeof final.channels === "object") for (const [channel, text] of Object.entries(final.channels)) {
506
+ if (typeof text !== "string" || text.length === 0) continue;
507
+ const thoughtId = `${responseId}:thought:${channel}`;
508
+ helpers.reportThought(thoughtId, text, { isComplete: true });
509
+ await ctx.storeThought(new require_thought.Thought({
510
+ id: thoughtId,
511
+ content: text,
512
+ identity: selfIdentity,
513
+ createdAt: nowIso(),
514
+ updatedAt: nowIso()
515
+ }));
516
+ }
517
+ const calls = assembleCalls(Array.isArray(final.tool_calls) ? final.tool_calls.map((tc) => ({
518
+ name: tc.function?.name ?? "",
519
+ arguments: tc.function?.arguments ?? {}
520
+ })) : []);
521
+ if (calls.length === 0) {
522
+ if (merged.autoAck) ctx.ack();
523
+ return;
524
+ }
525
+ for (const call of calls) {
526
+ if (ctx.abortSignal.aborted) return;
527
+ await executeAndPersistToolCall(call);
528
+ }
529
+ };
530
+ }
531
+ };
532
+ //#endregion
533
+ exports.LiteRtLmAdapter = LiteRtLmAdapter;
534
+
535
+ //# sourceMappingURL=adapter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.cjs","names":["#baseline","#engine","#resolveEngine","#enginePromise","#engineSettings","#sessionConfig"],"sources":["../../../../src/batteries/llm/litert_lm/adapter.ts"],"sourcesContent":["/**\n * Browser/WebGPU executor adapter for Google's LiteRT-LM (`@litert-lm/core`).\n *\n * @module @nhtio/adk/batteries/llm/litert_lm/adapter\n *\n * @remarks\n * On-device LLM inference via WebGPU + a bundled wasm runtime, `.litertlm` models. Unlike the WebLLM\n * battery (a thin extension of the OpenAI Chat Completions wire shape), LiteRT-LM has its **own** API —\n * `Engine.create() → engine.createConversation({ preface }) → conversation.sendMessageStreaming():\n * ReadableStream<Message>` — with native `Message`/`Tool`/`tool_calls`/`tool_response` shapes (tool-call\n * `arguments` arrive as a parsed object, not a JSON string). So this is a standalone adapter that reuses\n * the ADK's format-agnostic render helpers but maps history/tools/results to LiteRT's shapes.\n *\n * Three pluggable layers mirror the other LLM batteries: swappable translation helpers, three-layer\n * options merging (constructor → `executor()` overrides → `ctx.stash.liteRtLm`), and an\n * injectable/lazy engine (`engine` or `createEngine`, defaulting to a dynamic `@litert-lm/core` import).\n *\n * **The published `@litert-lm/core` docs lag the library** — every wire field here is mapped against the\n * installed package's type declarations, the source of truth. The dependency is young (pinned exact);\n * re-verify on upgrade.\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport {\n Tokenizable,\n ToolRegistry,\n ToolCall,\n Message,\n Thought,\n SpooledArtifact,\n Media,\n ArtifactTool,\n} from '@nhtio/adk/common'\nimport {\n E_INVALID_LITERT_LM_OPTIONS,\n E_LITERT_LM_CONTEXT_OVERFLOW,\n E_LITERT_LM_STREAM_ERROR,\n E_LITERT_LM_INVALID_TOOL_CALL_ARGS,\n} from './exceptions'\nimport {\n defaultDescriptionToChatCompletionsJsonSchema,\n defaultRenderUntrustedContent,\n defaultRenderTrustedContent,\n defaultRenderStandingInstructions,\n defaultRenderMemories,\n defaultRenderRetrievables,\n defaultRenderRetrievableSafetyDirective,\n defaultRenderFirstPartyRetrievables,\n defaultRenderThirdPartyPublicRetrievables,\n defaultRenderThirdPartyPrivateRetrievables,\n defaultRenderThought,\n defaultFilterThoughts,\n defaultRenderChatCompletionsSystemPrompt,\n defaultToolsToLiteRtTools,\n defaultRenderLiteRtToolResult,\n defaultBuildLiteRtConversationInput,\n defaultCreateLiteRtStreamAccumulator,\n} from './helpers'\nimport type { Tool } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/dispatch_runner'\nimport type {\n LiteRtLmAdapterOptions,\n LiteRtLmEngine,\n LiteRtLmConversation,\n LiteRtMessage,\n LiteRtMessageContentItem,\n LiteRtEngineSettings,\n LiteRtConversationConfig,\n LiteRtSessionConfig,\n} from './types'\n\n// ─── Option merging (constructor → executor overrides → stash) ────────────────────────────────────\n\nconst mergeHelpers = (\n layers: ReadonlyArray<Partial<NonNullable<LiteRtLmAdapterOptions['helpers']>> | undefined>\n): Partial<NonNullable<LiteRtLmAdapterOptions['helpers']>> | undefined => {\n let merged: Partial<NonNullable<LiteRtLmAdapterOptions['helpers']>> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: LiteRtLmAdapterOptions,\n exec: Partial<LiteRtLmAdapterOptions> | undefined,\n stash: Partial<LiteRtLmAdapterOptions> | undefined\n): Partial<LiteRtLmAdapterOptions> => {\n const layers = [baseline as Partial<LiteRtLmAdapterOptions>, exec ?? {}, stash ?? {}]\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n for (const [k, v] of Object.entries(layer)) {\n if (v === undefined) continue\n if (k === 'helpers') continue\n out[k] = v\n }\n }\n const helpers = mergeHelpers(layers.map((l) => l.helpers))\n if (helpers !== undefined) out.helpers = helpers\n return out as Partial<LiteRtLmAdapterOptions>\n}\n\n// ─── Helper resolution (fall back to bundled defaults per field) ──────────────────────────────────\n\ninterface ResolvedHelpers {\n descriptionToChatCompletionsJsonSchema: typeof defaultDescriptionToChatCompletionsJsonSchema\n renderUntrustedContent: typeof defaultRenderUntrustedContent\n renderTrustedContent: typeof defaultRenderTrustedContent\n renderStandingInstructions: typeof defaultRenderStandingInstructions\n renderMemories: typeof defaultRenderMemories\n renderRetrievables: typeof defaultRenderRetrievables\n renderRetrievableSafetyDirective: typeof defaultRenderRetrievableSafetyDirective\n renderFirstPartyRetrievables: typeof defaultRenderFirstPartyRetrievables\n renderThirdPartyPublicRetrievables: typeof defaultRenderThirdPartyPublicRetrievables\n renderThirdPartyPrivateRetrievables: typeof defaultRenderThirdPartyPrivateRetrievables\n renderThought: typeof defaultRenderThought\n filterThoughts: typeof defaultFilterThoughts\n renderChatCompletionsSystemPrompt: typeof defaultRenderChatCompletionsSystemPrompt\n toolsToLiteRtTools: typeof defaultToolsToLiteRtTools\n renderLiteRtToolResult: typeof defaultRenderLiteRtToolResult\n buildLiteRtConversationInput: typeof defaultBuildLiteRtConversationInput\n createLiteRtStreamAccumulator: typeof defaultCreateLiteRtStreamAccumulator\n}\n\nconst resolveHelpers = (\n overrides: Partial<LiteRtLmAdapterOptions['helpers']> | undefined\n): ResolvedHelpers => {\n const src = (overrides ?? {}) as Record<string, unknown>\n return {\n descriptionToChatCompletionsJsonSchema:\n (src.descriptionToChatCompletionsJsonSchema as ResolvedHelpers['descriptionToChatCompletionsJsonSchema']) ??\n defaultDescriptionToChatCompletionsJsonSchema,\n renderUntrustedContent:\n (src.renderUntrustedContent as ResolvedHelpers['renderUntrustedContent']) ??\n defaultRenderUntrustedContent,\n renderTrustedContent:\n (src.renderTrustedContent as ResolvedHelpers['renderTrustedContent']) ??\n defaultRenderTrustedContent,\n renderStandingInstructions:\n (src.renderStandingInstructions as ResolvedHelpers['renderStandingInstructions']) ??\n defaultRenderStandingInstructions,\n renderMemories:\n (src.renderMemories as ResolvedHelpers['renderMemories']) ?? defaultRenderMemories,\n renderRetrievables:\n (src.renderRetrievables as ResolvedHelpers['renderRetrievables']) ??\n defaultRenderRetrievables,\n renderRetrievableSafetyDirective:\n (src.renderRetrievableSafetyDirective as ResolvedHelpers['renderRetrievableSafetyDirective']) ??\n defaultRenderRetrievableSafetyDirective,\n renderFirstPartyRetrievables:\n (src.renderFirstPartyRetrievables as ResolvedHelpers['renderFirstPartyRetrievables']) ??\n defaultRenderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables:\n (src.renderThirdPartyPublicRetrievables as ResolvedHelpers['renderThirdPartyPublicRetrievables']) ??\n defaultRenderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables:\n (src.renderThirdPartyPrivateRetrievables as ResolvedHelpers['renderThirdPartyPrivateRetrievables']) ??\n defaultRenderThirdPartyPrivateRetrievables,\n renderThought: (src.renderThought as ResolvedHelpers['renderThought']) ?? defaultRenderThought,\n filterThoughts:\n (src.filterThoughts as ResolvedHelpers['filterThoughts']) ?? defaultFilterThoughts,\n renderChatCompletionsSystemPrompt:\n (src.renderChatCompletionsSystemPrompt as ResolvedHelpers['renderChatCompletionsSystemPrompt']) ??\n defaultRenderChatCompletionsSystemPrompt,\n toolsToLiteRtTools:\n (src.toolsToLiteRtTools as ResolvedHelpers['toolsToLiteRtTools']) ??\n defaultToolsToLiteRtTools,\n renderLiteRtToolResult:\n (src.renderLiteRtToolResult as ResolvedHelpers['renderLiteRtToolResult']) ??\n defaultRenderLiteRtToolResult,\n buildLiteRtConversationInput:\n (src.buildLiteRtConversationInput as ResolvedHelpers['buildLiteRtConversationInput']) ??\n defaultBuildLiteRtConversationInput,\n createLiteRtStreamAccumulator:\n (src.createLiteRtStreamAccumulator as ResolvedHelpers['createLiteRtStreamAccumulator']) ??\n defaultCreateLiteRtStreamAccumulator,\n }\n}\n\nconst nowIso = (): string => DateTime.now().toISO() as string\n\nconst computeChecksum = (tool: string, args: Record<string, unknown>): string =>\n sha256(canonicalStringify({ tool, args }))\n\n/** An assembled tool call drained from the stream/response (args already a parsed object). */\ninterface AssembledLiteRtToolCall {\n id: string\n name: string\n args: Record<string, unknown>\n argsWellFormed: boolean\n}\n\n/**\n * Cross-environment executor adapter for LiteRT-LM.\n *\n * @remarks\n * Construct with at least `{ model }`; wire `new LiteRtLmAdapter(opts).executor()` into a\n * `DispatchRunner` as the `executorCallback`. The engine is resolved lazily on first dispatch (or\n * eagerly via {@link LiteRtLmAdapter.preload}); pass `engine` to inject a pre-built one (e.g. in tests).\n */\nexport class LiteRtLmAdapter {\n /** The `ctx.stash` key under which per-dispatch option overrides are read. */\n public static readonly STASH_KEY = 'liteRtLm' as const\n\n readonly #baseline: LiteRtLmAdapterOptions\n #engine: LiteRtLmEngine | undefined\n #enginePromise: Promise<LiteRtLmEngine> | undefined\n\n /**\n * Returns `true` when the current runtime exposes WebGPU (`navigator.gpu`).\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 - Raw adapter options, validated against `liteRtLmOptionsSchema`.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_LITERT_LM_OPTIONS} when `options` are invalid.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n this.#engine = this.#baseline.engine\n }\n\n /** Instance WebGPU-availability probe (honours the `isWebGPUAvailable` option override). */\n isAvailable(): boolean {\n return (this.#baseline.isWebGPUAvailable ?? LiteRtLmAdapter.isAvailable)()\n }\n\n /**\n * Eagerly resolve (load) the engine before the first dispatch.\n *\n * @param overrides - Optional option overrides applied for this load.\n * @returns The resolved {@link LiteRtLmEngine}.\n */\n async preload(overrides?: Partial<LiteRtLmAdapterOptions>): Promise<LiteRtLmEngine> {\n const merged = validateOptions(mergeOptions(this.#baseline, overrides, undefined))\n return this.#resolveEngine(merged)\n }\n\n /** Drop the cached engine and any in-flight load so the next dispatch re-resolves it. */\n reset(): void {\n this.#engine = undefined\n this.#enginePromise = undefined\n }\n\n /** Build the LiteRT `EngineSettings` from the merged adapter options. */\n #engineSettings(merged: LiteRtLmAdapterOptions): LiteRtEngineSettings {\n const settings: LiteRtEngineSettings = {\n model: merged.model as LiteRtEngineSettings['model'],\n }\n if (merged.backend !== undefined) settings.backend = merged.backend as never\n if (merged.maxNumTokens !== undefined) {\n settings.mainExecutorSettings = { maxNumTokens: merged.maxNumTokens }\n }\n return settings\n }\n\n async #resolveEngine(merged: LiteRtLmAdapterOptions): Promise<LiteRtLmEngine> {\n if (merged.engine) {\n this.#engine = merged.engine\n return merged.engine\n }\n if (this.#engine) return this.#engine\n const available = (merged.isWebGPUAvailable ?? LiteRtLmAdapter.isAvailable)()\n if (!available) {\n throw new E_INVALID_LITERT_LM_OPTIONS([\n 'LiteRT-LM requires a browser/runtime with WebGPU support',\n ])\n }\n this.#enginePromise ??= (async () => {\n const engineSettings = this.#engineSettings(merged)\n const createEngine =\n merged.createEngine ??\n (async ({ engineSettings: settings }) => {\n const { Engine } = await import('@litert-lm/core')\n return (await Engine.create(\n settings as never,\n merged.inputPromptAsHint\n )) as LiteRtLmEngine\n })\n const engine = await createEngine({\n engineSettings,\n onInitProgress: merged.onInitProgress,\n })\n this.#engine = engine\n return engine\n })()\n return this.#enginePromise\n }\n\n /** Build the per-dispatch session config from the merged options. */\n #sessionConfig(merged: LiteRtLmAdapterOptions): LiteRtSessionConfig | undefined {\n const cfg: LiteRtSessionConfig = {}\n if (merged.samplerParams !== undefined) cfg.samplerParams = merged.samplerParams as never\n if (merged.maxOutputTokens !== undefined) cfg.maxOutputTokens = merged.maxOutputTokens\n if (merged.audioModalityEnabled !== undefined)\n cfg.audioModalityEnabled = merged.audioModalityEnabled\n if (merged.visionModalityEnabled !== undefined)\n cfg.visionModalityEnabled = merged.visionModalityEnabled\n return Object.keys(cfg).length > 0 ? cfg : undefined\n }\n\n /**\n * Produce the bound {@link DispatchExecutorFn} the `DispatchRunner` invokes.\n *\n * @param overrides - Option overrides layered above the constructor baseline (below `ctx.stash`).\n */\n executor(overrides?: Partial<LiteRtLmAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = LiteRtLmAdapter\n const self = this\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n // 1. Three-layer merge + re-validate.\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<LiteRtLmAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n const h = resolveHelpers(merged.helpers)\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n const unsupportedMediaPolicy = merged.unsupportedMediaPolicy ?? 'throw'\n\n // 2. Forge artifact-query tools from prior turn's spooled artifacts; merge into ctx.tools.\n let mergedRegistry: ToolRegistry = ctx.tools\n const artifactCtors = new Set<{ forgeTools: (c: DispatchContext) => ToolRegistry }>()\n for (const tc of ctx.turnToolCalls) {\n const r = tc.results\n const arr = Array.isArray(r) ? r : [r]\n for (const item of arr) {\n if (SpooledArtifact.isSpooledArtifact(item)) {\n const ctor = (item as SpooledArtifact).constructor as unknown as {\n forgeTools?: (c: DispatchContext) => ToolRegistry\n }\n if (typeof ctor.forgeTools === 'function')\n artifactCtors.add(ctor as { forgeTools: (c: DispatchContext) => ToolRegistry })\n }\n }\n }\n if (artifactCtors.size > 0) {\n const registries = [ctx.tools, ...[...artifactCtors].map((c) => c.forgeTools(ctx))]\n mergedRegistry = ToolRegistry.merge(registries, { onCollision: 'keep' })\n mergedRegistry.bindContext(ctx)\n }\n\n // 3. Pre-render persisted tool-call results into LiteRT tool_response content items.\n const renderedToolCallResults = new Map<string, LiteRtMessageContentItem>()\n for (const tc of ctx.turnToolCalls) {\n const tool = mergedRegistry.get(tc.tool)\n const item = await h.renderLiteRtToolResult({\n toolCall: tc,\n results: tc.results,\n tool: tool as Tool | ArtifactTool | undefined,\n unsupportedMediaPolicy,\n renderUntrustedContent: h.renderUntrustedContent,\n renderTrustedContent: h.renderTrustedContent,\n warn: (m) => helpers.log.warn({ kind: 'litert-render-warning', message: m }),\n })\n renderedToolCallResults.set(tc.id, item)\n }\n\n // 4. Optional context-window enforcement.\n if (merged.tokenEncoding && merged.contextWindow !== undefined) {\n const enc = merged.tokenEncoding\n const tally = (s: string): number => new Tokenizable(s).estimateTokens(enc)\n let total = tally(ctx.systemPrompt.toString())\n for (const si of ctx.standingInstructions) total += tally(si.toString())\n for (const m of ctx.turnMemories) total += tally(m.content.toString())\n for (const r of ctx.turnRetrievables) total += tally((await r.contentString?.()) ?? '')\n for (const m of ctx.turnMessages) total += tally(m.content?.toString() ?? '')\n for (const t of ctx.turnThoughts) total += tally(t.content.toString())\n for (const item of renderedToolCallResults.values()) {\n const tr = (item as { tool_response?: { response?: { content?: string } } }).tool_response\n total += tally(tr?.response?.content ?? '')\n }\n if (total > merged.contextWindow) {\n throw new E_LITERT_LM_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n String(enc),\n `system+buckets+timeline=${total}`,\n ])\n }\n }\n\n // 5. Build LiteRT conversation input (preface + per-turn messages).\n const { preface, messages: turnMessages } = await h.buildLiteRtConversationInput({\n systemPrompt: ctx.systemPrompt,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: mergedRegistry,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? [\n 'standingInstructions',\n 'memories',\n 'retrievables',\n 'timeline',\n ],\n selfIdentity,\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n toolsToLiteRtTools: h.toolsToLiteRtTools,\n renderThought: h.renderThought,\n filterThoughts: h.filterThoughts,\n renderUntrustedContent: h.renderUntrustedContent,\n renderTrustedContent: h.renderTrustedContent,\n renderChatCompletionsSystemPrompt: h.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: h.renderStandingInstructions,\n renderMemories: h.renderMemories,\n renderRetrievables: h.renderRetrievables,\n renderRetrievableSafetyDirective: h.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: h.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: h.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: h.renderThirdPartyPrivateRetrievables,\n warn: (m) => helpers.log.warn({ kind: 'litert-history-warning', message: m }),\n })\n\n // 6. Resolve engine + create the conversation.\n const sessionConfig = self.#sessionConfig(merged)\n const conversationConfig: LiteRtConversationConfig = {\n preface,\n ...(sessionConfig ? { sessionConfig } : {}),\n ...(merged.enableConstrainedDecoding !== undefined\n ? { enableConstrainedDecoding: merged.enableConstrainedDecoding }\n : {}),\n ...(merged.filterChannelContentFromKvCache !== undefined\n ? { filterChannelContentFromKvCache: merged.filterChannelContentFromKvCache }\n : {}),\n }\n\n let conversation: LiteRtLmConversation\n try {\n const engine = await self.#resolveEngine(merged)\n conversation = await engine.createConversation(conversationConfig as never)\n } catch (err) {\n ctx.nack(new E_LITERT_LM_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n const stream = merged.stream ?? true\n\n // Wire abort → conversation.cancel().\n const onAbort = (): void => {\n try {\n conversation.cancel()\n } catch {\n /* cancel is best-effort */\n }\n }\n if (ctx.abortSignal.aborted) {\n onAbort()\n return\n }\n ctx.abortSignal.addEventListener('abort', onAbort, { once: true })\n\n // ── Tool execution + persistence (args already an object — no JSON.parse) ──\n const executeAndPersistToolCall = async (call: AssembledLiteRtToolCall): Promise<void> => {\n const tool = mergedRegistry.get(call.name)\n const completedAt = nowIso()\n\n if (!call.argsWellFormed) {\n const err = new E_LITERT_LM_INVALID_TOOL_CALL_ARGS([\n 'must be a JSON object',\n JSON.stringify(call.args),\n ])\n const results = new Tokenizable(err.message)\n helpers.reportToolCall(call.id, { tool: call.name, args: {} })\n helpers.reportToolCall(call.id, { results, isError: true, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: call.name,\n args: {},\n checksum: computeChecksum(call.name, {}),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n\n if (!tool) {\n const available = mergedRegistry\n .all()\n .map((t) => t.name)\n .sort()\n const errText =\n available.length > 0\n ? `Tool not found: ${call.name}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${call.name}. No tools are available this turn.`\n const results = new Tokenizable(errText)\n helpers.reportToolCall(call.id, { tool: call.name, args: call.args })\n helpers.reportToolCall(call.id, { results, isError: true, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: call.name,\n args: call.args,\n checksum: computeChecksum(call.name, call.args),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n\n helpers.reportToolCall(call.id, { tool: tool.name, args: call.args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(call.args)\n if (isArtifactTool) {\n results = Tokenizable.isTokenizable(raw)\n ? raw\n : typeof raw === 'string'\n ? new Tokenizable(raw)\n : (() => {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n })()\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(call.id, raw as string | Uint8Array)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(call.id, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n let detailMsg = isError(err) ? err.message : String(err)\n if (isError(err) && isError(err.cause) && err.cause.message !== err.message) {\n detailMsg = `${detailMsg} ${err.cause.message}`\n }\n results = new Tokenizable(detailMsg)\n }\n helpers.reportToolCall(call.id, { results, isError: toolHadError, isComplete: true })\n const completedAt2 = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: tool.name,\n args: call.args,\n checksum: computeChecksum(tool.name, call.args),\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n createdAt: completedAt2,\n updatedAt: completedAt2,\n completedAt: completedAt2,\n })\n )\n }\n\n const assembleCalls = (\n raw: ReadonlyArray<{ name: string; arguments: Record<string, unknown> }>\n ): AssembledLiteRtToolCall[] =>\n raw.map((c) => ({\n id: uuidv6(),\n name: c.name,\n args: isObject(c.arguments) ? (c.arguments as Record<string, unknown>) : {},\n argsWellFormed: isObject(c.arguments),\n }))\n\n // ── Streaming path ──\n if (stream) {\n const accumulator = h.createLiteRtStreamAccumulator()\n const streamId = uuidv6()\n let sawMessage = false\n const channelStreamIds = new Map<string, string>()\n\n let readable: ReadableStream<LiteRtMessage>\n try {\n readable = conversation.sendMessageStreaming(\n turnMessages as never\n ) as ReadableStream<LiteRtMessage>\n } catch (err) {\n ctx.nack(new E_LITERT_LM_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n try {\n const reader = readable.getReader()\n while (true) {\n if (ctx.abortSignal.aborted) {\n await reader.cancel().catch(() => undefined)\n return\n }\n const { value: chunk, done } = await reader.read()\n if (done) break\n if (!chunk) continue\n const { contentDelta, channelDeltas } = accumulator.feed(chunk)\n if (contentDelta.length > 0) {\n sawMessage = true\n helpers.reportMessage(streamId, contentDelta)\n }\n for (const { channel, delta } of channelDeltas) {\n if (!channelStreamIds.has(channel)) channelStreamIds.set(channel, uuidv6())\n helpers.reportThought(channelStreamIds.get(channel)!, delta)\n }\n }\n } catch (err) {\n if (ctx.abortSignal.aborted) return\n ctx.nack(new E_LITERT_LM_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n // Drain + persist.\n if (sawMessage) {\n helpers.reportMessage(streamId, '', { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: streamId,\n role: 'assistant',\n content: accumulator.content(),\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n for (const [channel, text] of Object.entries(accumulator.channels())) {\n const id = channelStreamIds.get(channel) ?? uuidv6()\n helpers.reportThought(id, '', { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id,\n content: text,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n const calls = assembleCalls(accumulator.toolCalls())\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n return\n }\n\n // ── Non-streaming path ──\n let final: LiteRtMessage\n try {\n final = (await conversation.sendMessage(turnMessages as never)) as LiteRtMessage\n } catch (err) {\n ctx.nack(new E_LITERT_LM_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n const responseId = uuidv6()\n const contentText =\n typeof final.content === 'string'\n ? final.content\n : Array.isArray(final.content)\n ? final.content\n .filter((i) => i.type === 'text' && typeof i.text === 'string')\n .map((i) => i.text)\n .join('')\n : ''\n if (contentText.length > 0) {\n const messageId = `${responseId}:message`\n helpers.reportMessage(messageId, contentText, { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: messageId,\n role: 'assistant',\n content: contentText,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n if (final.channels && typeof final.channels === 'object') {\n for (const [channel, text] of Object.entries(final.channels)) {\n if (typeof text !== 'string' || text.length === 0) continue\n const thoughtId = `${responseId}:thought:${channel}`\n helpers.reportThought(thoughtId, text, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: thoughtId,\n content: text,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n }\n const rawCalls = Array.isArray(final.tool_calls)\n ? final.tool_calls.map((tc) => ({\n name: tc.function?.name ?? '',\n arguments: (tc.function?.arguments ?? {}) as Record<string, unknown>,\n }))\n : []\n const calls = assembleCalls(rawCalls)\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,IAAM,gBACJ,WACwE;CACxE,IAAI;CACJ,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,OAAO;EACZ,SAAS;GAAE,GAAI,UAAU,CAAC;GAAI,GAAG;EAAM;CACzC;CACA,OAAO;AACT;AAEA,IAAM,gBACJ,UACA,MACA,UACoC;CACpC,MAAM,SAAS;EAAC;EAA6C,QAAQ,CAAC;EAAG,SAAS,CAAC;CAAC;CACpF,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,GAAG;EAC1C,IAAI,MAAM,KAAA,GAAW;EACrB,IAAI,MAAM,WAAW;EACrB,IAAI,KAAK;CACX;CAEF,MAAM,UAAU,aAAa,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC;CACzD,IAAI,YAAY,KAAA,GAAW,IAAI,UAAU;CACzC,OAAO;AACT;AAwBA,IAAM,kBACJ,cACoB;CACpB,MAAM,MAAO,aAAa,CAAC;CAC3B,OAAO;EACL,wCACG,IAAI,0CACL,gBAAA;EACF,wBACG,IAAI,0BACL,gBAAA;EACF,sBACG,IAAI,wBACL,gBAAA;EACF,4BACG,IAAI,8BACL,gBAAA;EACF,gBACG,IAAI,kBAAwD,gBAAA;EAC/D,oBACG,IAAI,sBACL,gBAAA;EACF,kCACG,IAAI,oCACL,gBAAA;EACF,8BACG,IAAI,gCACL,gBAAA;EACF,oCACG,IAAI,sCACL,gBAAA;EACF,qCACG,IAAI,uCACL,gBAAA;EACF,eAAgB,IAAI,iBAAsD,gBAAA;EAC1E,gBACG,IAAI,kBAAwD,gBAAA;EAC/D,mCACG,IAAI,qCACL,gBAAA;EACF,oBACG,IAAI,sBACL,wCAAA;EACF,wBACG,IAAI,0BACL,wCAAA;EACF,8BACG,IAAI,gCACL,wCAAA;EACF,+BACG,IAAI,iCACL,wCAAA;CACJ;AACF;AAEA,IAAM,eAAuB,MAAA,SAAS,IAAI,EAAE,MAAM;AAElD,IAAM,mBAAmB,MAAc,UAAA,GAAA,UAAA,QAC9B,sBAAA,mBAAmB;CAAE;CAAM;AAAK,CAAC,CAAC;;;;;;;;;AAkB3C,IAAa,kBAAb,MAAa,gBAAgB;;CAE3B,OAAuB,YAAY;CAEnC;CACA;CACA;;;;CAKA,OAAc,cAAuB;EACnC,OACE,OAAO,WAAW,cAAc,eAChC,SAAS,WAAW,aACpB,OAAQ,WAAW,UAAgC,QAAQ;CAE/D;;;;;CAMA,YAAY,SAAkB;EAC5B,KAAKA,YAAY,2CAAA,gBAAgB,OAAO;EACxC,KAAKC,UAAU,KAAKD,UAAU;CAChC;;CAGA,cAAuB;EACrB,QAAQ,KAAKA,UAAU,qBAAqB,gBAAgB,aAAa;CAC3E;;;;;;;CAQA,MAAM,QAAQ,WAAsE;EAClF,MAAM,SAAS,2CAAA,gBAAgB,aAAa,KAAKA,WAAW,WAAW,KAAA,CAAS,CAAC;EACjF,OAAO,KAAKE,eAAe,MAAM;CACnC;;CAGA,QAAc;EACZ,KAAKD,UAAU,KAAA;EACf,KAAKE,iBAAiB,KAAA;CACxB;;CAGA,gBAAgB,QAAsD;EACpE,MAAM,WAAiC,EACrC,OAAO,OAAO,MAChB;EACA,IAAI,OAAO,YAAY,KAAA,GAAW,SAAS,UAAU,OAAO;EAC5D,IAAI,OAAO,iBAAiB,KAAA,GAC1B,SAAS,uBAAuB,EAAE,cAAc,OAAO,aAAa;EAEtE,OAAO;CACT;CAEA,MAAMD,eAAe,QAAyD;EAC5E,IAAI,OAAO,QAAQ;GACjB,KAAKD,UAAU,OAAO;GACtB,OAAO,OAAO;EAChB;EACA,IAAI,KAAKA,SAAS,OAAO,KAAKA;EAE9B,IAAI,EADe,OAAO,qBAAqB,gBAAgB,aAC1D,GACH,MAAM,IAAI,2CAAA,4BAA4B,CACpC,0DACF,CAAC;EAEH,KAAKE,oBAAoB,YAAY;GACnC,MAAM,iBAAiB,KAAKC,gBAAgB,MAAM;GAUlD,MAAM,SAAS,OARb,OAAO,iBACN,OAAO,EAAE,gBAAgB,eAAe;IACvC,MAAM,EAAE,WAAW,MAAM,OAAO;IAChC,OAAQ,MAAM,OAAO,OACnB,UACA,OAAO,iBACT;GACF,IACgC;IAChC;IACA,gBAAgB,OAAO;GACzB,CAAC;GACD,KAAKH,UAAU;GACf,OAAO;EACT,GAAG;EACH,OAAO,KAAKE;CACd;;CAGA,eAAe,QAAiE;EAC9E,MAAM,MAA2B,CAAC;EAClC,IAAI,OAAO,kBAAkB,KAAA,GAAW,IAAI,gBAAgB,OAAO;EACnE,IAAI,OAAO,oBAAoB,KAAA,GAAW,IAAI,kBAAkB,OAAO;EACvE,IAAI,OAAO,yBAAyB,KAAA,GAClC,IAAI,uBAAuB,OAAO;EACpC,IAAI,OAAO,0BAA0B,KAAA,GACnC,IAAI,wBAAwB,OAAO;EACrC,OAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM,KAAA;CAC7C;;;;;;CAOA,SAAS,WAAiE;EACxE,MAAM,WAAW,KAAKH;EACtB,MAAM,eAAe;EACrB,MAAM,OAAO;EACb,OAAO,OAAO,KAAsB,YAAoD;GAEtF,MAAM,WAAW,IAAI,MAAM,IAAI,aAAa,WAAW,CAAC,CAAC;GAKzD,MAAM,SAAS,2CAAA,gBAAgB,aAAa,UAAU,WAHpD,YAAY,OAAO,aAAa,WAC3B,WACD,CAAC,CACwE,CAAC;GAChF,MAAM,IAAI,eAAe,OAAO,OAAO;GACvC,MAAM,eAAe,OAAO,gBAAgB;GAC5C,MAAM,yBAAyB,OAAO,0BAA0B;GAGhE,IAAI,iBAA+B,IAAI;GACvC,MAAM,gCAAgB,IAAI,IAA0D;GACpF,KAAK,MAAM,MAAM,IAAI,eAAe;IAClC,MAAM,IAAI,GAAG;IACb,MAAM,MAAM,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;IACrC,KAAK,MAAM,QAAQ,KACjB,IAAI,yBAAA,gBAAgB,kBAAkB,IAAI,GAAG;KAC3C,MAAM,OAAQ,KAAyB;KAGvC,IAAI,OAAO,KAAK,eAAe,YAC7B,cAAc,IAAI,IAA4D;IAClF;GAEJ;GACA,IAAI,cAAc,OAAO,GAAG;IAC1B,MAAM,aAAa,CAAC,IAAI,OAAO,GAAG,CAAC,GAAG,aAAa,EAAE,KAAK,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC;IAClF,iBAAiB,sBAAA,aAAa,MAAM,YAAY,EAAE,aAAa,OAAO,CAAC;IACvE,eAAe,YAAY,GAAG;GAChC;GAGA,MAAM,0CAA0B,IAAI,IAAsC;GAC1E,KAAK,MAAM,MAAM,IAAI,eAAe;IAClC,MAAM,OAAO,eAAe,IAAI,GAAG,IAAI;IACvC,MAAM,OAAO,MAAM,EAAE,uBAAuB;KAC1C,UAAU;KACV,SAAS,GAAG;KACN;KACN;KACA,wBAAwB,EAAE;KAC1B,sBAAsB,EAAE;KACxB,OAAO,MAAM,QAAQ,IAAI,KAAK;MAAE,MAAM;MAAyB,SAAS;KAAE,CAAC;IAC7E,CAAC;IACD,wBAAwB,IAAI,GAAG,IAAI,IAAI;GACzC;GAGA,IAAI,OAAO,iBAAiB,OAAO,kBAAkB,KAAA,GAAW;IAC9D,MAAM,MAAM,OAAO;IACnB,MAAM,SAAS,MAAsB,IAAI,sBAAA,YAAY,CAAC,EAAE,eAAe,GAAG;IAC1E,IAAI,QAAQ,MAAM,IAAI,aAAa,SAAS,CAAC;IAC7C,KAAK,MAAM,MAAM,IAAI,sBAAsB,SAAS,MAAM,GAAG,SAAS,CAAC;IACvE,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,MAAM,EAAE,QAAQ,SAAS,CAAC;IACrE,KAAK,MAAM,KAAK,IAAI,kBAAkB,SAAS,MAAO,MAAM,EAAE,gBAAgB,KAAM,EAAE;IACtF,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,MAAM,EAAE,SAAS,SAAS,KAAK,EAAE;IAC5E,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,MAAM,EAAE,QAAQ,SAAS,CAAC;IACrE,KAAK,MAAM,QAAQ,wBAAwB,OAAO,GAAG;KACnD,MAAM,KAAM,KAAiE;KAC7E,SAAS,MAAM,IAAI,UAAU,WAAW,EAAE;IAC5C;IACA,IAAI,QAAQ,OAAO,eACjB,MAAM,IAAI,2CAAA,6BAA6B;KACrC;KACA,OAAO;KACP,OAAO,GAAG;KACV,2BAA2B;IAC7B,CAAC;GAEL;GAGA,MAAM,EAAE,SAAS,UAAU,iBAAiB,MAAM,EAAE,6BAA6B;IAC/E,cAAc,IAAI;IAClB,sBAAsB,IAAI;IAC1B,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,UAAU,IAAI;IACd,UAAU,IAAI;IACd,WAAW,IAAI;IACf,OAAO;IACP;IACA,aAAa,OAAO,eAAe;KACjC;KACA;KACA;KACA;IACF;IACA;IACA,kBAAkB,OAAO,oBAAoB;IAC7C,qBAAqB,OAAO,uBAAuB,CAAC;IACpD,oBAAoB,EAAE;IACtB,eAAe,EAAE;IACjB,gBAAgB,EAAE;IAClB,wBAAwB,EAAE;IAC1B,sBAAsB,EAAE;IACxB,mCAAmC,EAAE;IACrC,4BAA4B,EAAE;IAC9B,gBAAgB,EAAE;IAClB,oBAAoB,EAAE;IACtB,kCAAkC,EAAE;IACpC,8BAA8B,EAAE;IAChC,oCAAoC,EAAE;IACtC,qCAAqC,EAAE;IACvC,OAAO,MAAM,QAAQ,IAAI,KAAK;KAAE,MAAM;KAA0B,SAAS;IAAE,CAAC;GAC9E,CAAC;GAGD,MAAM,gBAAgB,KAAKK,eAAe,MAAM;GAChD,MAAM,qBAA+C;IACnD;IACA,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;IACzC,GAAI,OAAO,8BAA8B,KAAA,IACrC,EAAE,2BAA2B,OAAO,0BAA0B,IAC9D,CAAC;IACL,GAAI,OAAO,oCAAoC,KAAA,IAC3C,EAAE,iCAAiC,OAAO,gCAAgC,IAC1E,CAAC;GACP;GAEA,IAAI;GACJ,IAAI;IAEF,eAAe,OAAM,MADA,KAAKH,eAAe,MAAM,GACnB,mBAAmB,kBAA2B;GAC5E,SAAS,KAAK;IACZ,IAAI,KAAK,IAAI,2CAAA,yBAAyB,CAAC,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC;IACjF;GACF;GAEA,MAAM,aAAa,OAAO,cAAc,IAAI,oCAAA,mBAAmB;GAC/D,MAAM,SAAS,OAAO,UAAU;GAGhC,MAAM,gBAAsB;IAC1B,IAAI;KACF,aAAa,OAAO;IACtB,QAAQ,CAER;GACF;GACA,IAAI,IAAI,YAAY,SAAS;IAC3B,QAAQ;IACR;GACF;GACA,IAAI,YAAY,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;GAGjE,MAAM,4BAA4B,OAAO,SAAiD;IACxF,MAAM,OAAO,eAAe,IAAI,KAAK,IAAI;IACzC,MAAM,cAAc,OAAO;IAE3B,IAAI,CAAC,KAAK,gBAAgB;KAKxB,MAAM,UAAU,IAAI,sBAAA,YAAY,IAJhB,2CAAA,mCAAmC,CACjD,yBACA,KAAK,UAAU,KAAK,IAAI,CAC1B,CACgC,EAAI,OAAO;KAC3C,QAAQ,eAAe,KAAK,IAAI;MAAE,MAAM,KAAK;MAAM,MAAM,CAAC;KAAE,CAAC;KAC7D,QAAQ,eAAe,KAAK,IAAI;MAAE;MAAS,SAAS;MAAM,YAAY;KAAK,CAAC;KAC5E,MAAM,IAAI,cACR,IAAI,kBAAA,SAAS;MACX,IAAI,KAAK;MACT,MAAM,KAAK;MACX,MAAM,CAAC;MACP,UAAU,gBAAgB,KAAK,MAAM,CAAC,CAAC;MACvC,YAAY;MACZ,SAAS;MACT;MACA,WAAW;MACX,WAAW;MACX;KACF,CAAC,CACH;KACA;IACF;IAEA,IAAI,CAAC,MAAM;KACT,MAAM,YAAY,eACf,IAAI,EACJ,KAAK,MAAM,EAAE,IAAI,EACjB,KAAK;KAKR,MAAM,UAAU,IAAI,sBAAA,YAHlB,UAAU,SAAS,IACf,mBAAmB,KAAK,KAAK,qBAAqB,UAAU,KAAK,IAAI,EAAE,KACvE,mBAAmB,KAAK,KAAK,oCACI;KACvC,QAAQ,eAAe,KAAK,IAAI;MAAE,MAAM,KAAK;MAAM,MAAM,KAAK;KAAK,CAAC;KACpE,QAAQ,eAAe,KAAK,IAAI;MAAE;MAAS,SAAS;MAAM,YAAY;KAAK,CAAC;KAC5E,MAAM,IAAI,cACR,IAAI,kBAAA,SAAS;MACX,IAAI,KAAK;MACT,MAAM,KAAK;MACX,MAAM,KAAK;MACX,UAAU,gBAAgB,KAAK,MAAM,KAAK,IAAI;MAC9C,YAAY;MACZ,SAAS;MACT;MACA,WAAW;MACX,WAAW;MACX;KACF,CAAC,CACH;KACA;IACF;IAEA,QAAQ,eAAe,KAAK,IAAI;KAAE,MAAM,KAAK;KAAM,MAAM,KAAK;IAAK,CAAC;IACpE,MAAM,iBAAiB,yBAAA,aAAa,eAAe,IAAI;IACvD,IAAI,UACF,IAAI,sBAAA,YAAY,EAAE;IACpB,IAAI,eAAe;IACnB,IAAI;KACF,MAAM,MAAM,MAAM,KAAK,SAAS,GAAG,EAAE,KAAK,IAAI;KAC9C,IAAI,gBACF,UAAU,sBAAA,YAAY,cAAc,GAAG,IACnC,MACA,OAAO,QAAQ,WACb,IAAI,sBAAA,YAAY,GAAG,WACZ;MACL,MAAM,IAAI,MACR,iBAAiB,KAAK,KAAK,8CAC7B;KACF,GAAG;UACJ,IAAI,kBAAA,MAAM,QAAQ,GAAG,GAC1B,UAAU;UACL,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,OAAO,MAAM,kBAAA,MAAM,QAAQ,CAAC,CAAC,GAClF,UAAU;UACL,IAAI,OAAO,QAAQ,YAAY,sBAAA,aAAa,KAAK,cAAc,UAAU,GAAG;MACjF,MAAM,SAAS,MAAM,WAAW,MAAM,KAAK,IAAI,GAA0B;MAEzE,UAAU,MADY,KAAc,sBAAsB,MAAK,yBAAA,iBACpC,MAAM;KACnC,OAAO;MACL,MAAM,SAAS,MAAM,WAAW,MAAM,KAAK,IAAI,OAAO,GAAG,CAAC;MAE1D,UAAU,MADY,KAAc,sBAAsB,MAAK,yBAAA,iBACpC,MAAM;KACnC;IACF,SAAS,KAAK;KACZ,eAAe;KACf,IAAI,YAAY,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;KACvD,IAAI,sBAAA,QAAQ,GAAG,KAAK,sBAAA,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,YAAY,IAAI,SAClE,YAAY,GAAG,UAAU,GAAG,IAAI,MAAM;KAExC,UAAU,IAAI,sBAAA,YAAY,SAAS;IACrC;IACA,QAAQ,eAAe,KAAK,IAAI;KAAE;KAAS,SAAS;KAAc,YAAY;IAAK,CAAC;IACpF,MAAM,eAAe,OAAO;IAC5B,MAAM,IAAI,cACR,IAAI,kBAAA,SAAS;KACX,IAAI,KAAK;KACT,MAAM,KAAK;KACX,MAAM,KAAK;KACX,UAAU,gBAAgB,KAAK,MAAM,KAAK,IAAI;KAC9C,YAAY;KACZ,SAAS;KACT;KACA,kBAAkB;KAClB,WAAW;KACX,WAAW;KACX,aAAa;IACf,CAAC,CACH;GACF;GAEA,MAAM,iBACJ,QAEA,IAAI,KAAK,OAAO;IACd,KAAA,GAAA,KAAA,IAAW;IACX,MAAM,EAAE;IACR,MAAM,sBAAA,SAAS,EAAE,SAAS,IAAK,EAAE,YAAwC,CAAC;IAC1E,gBAAgB,sBAAA,SAAS,EAAE,SAAS;GACtC,EAAE;GAGJ,IAAI,QAAQ;IACV,MAAM,cAAc,EAAE,8BAA8B;IACpD,MAAM,YAAA,GAAA,KAAA,IAAkB;IACxB,IAAI,aAAa;IACjB,MAAM,mCAAmB,IAAI,IAAoB;IAEjD,IAAI;IACJ,IAAI;KACF,WAAW,aAAa,qBACtB,YACF;IACF,SAAS,KAAK;KACZ,IAAI,KAAK,IAAI,2CAAA,yBAAyB,CAAC,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC;KACjF;IACF;IAEA,IAAI;KACF,MAAM,SAAS,SAAS,UAAU;KAClC,OAAO,MAAM;MACX,IAAI,IAAI,YAAY,SAAS;OAC3B,MAAM,OAAO,OAAO,EAAE,YAAY,KAAA,CAAS;OAC3C;MACF;MACA,MAAM,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,KAAK;MACjD,IAAI,MAAM;MACV,IAAI,CAAC,OAAO;MACZ,MAAM,EAAE,cAAc,kBAAkB,YAAY,KAAK,KAAK;MAC9D,IAAI,aAAa,SAAS,GAAG;OAC3B,aAAa;OACb,QAAQ,cAAc,UAAU,YAAY;MAC9C;MACA,KAAK,MAAM,EAAE,SAAS,WAAW,eAAe;OAC9C,IAAI,CAAC,iBAAiB,IAAI,OAAO,GAAG,iBAAiB,IAAI,UAAA,GAAA,KAAA,IAAgB,CAAC;OAC1E,QAAQ,cAAc,iBAAiB,IAAI,OAAO,GAAI,KAAK;MAC7D;KACF;IACF,SAAS,KAAK;KACZ,IAAI,IAAI,YAAY,SAAS;KAC7B,IAAI,KAAK,IAAI,2CAAA,yBAAyB,CAAC,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC;KACjF;IACF;IAGA,IAAI,YAAY;KACd,QAAQ,cAAc,UAAU,IAAI,EAAE,YAAY,KAAK,CAAC;KACxD,MAAM,IAAI,aACR,IAAI,gBAAA,QAAQ;MACV,IAAI;MACJ,MAAM;MACN,SAAS,YAAY,QAAQ;MAC7B,UAAU;MACV,WAAW,OAAO;MAClB,WAAW,OAAO;KACpB,CAAC,CACH;IACF;IACA,KAAK,MAAM,CAAC,SAAS,SAAS,OAAO,QAAQ,YAAY,SAAS,CAAC,GAAG;KACpE,MAAM,KAAK,iBAAiB,IAAI,OAAO,MAAA,GAAA,KAAA,IAAY;KACnD,QAAQ,cAAc,IAAI,IAAI,EAAE,YAAY,KAAK,CAAC;KAClD,MAAM,IAAI,aACR,IAAI,gBAAA,QAAQ;MACV;MACA,SAAS;MACT,UAAU;MACV,WAAW,OAAO;MAClB,WAAW,OAAO;KACpB,CAAC,CACH;IACF;IACA,MAAM,QAAQ,cAAc,YAAY,UAAU,CAAC;IACnD,IAAI,MAAM,WAAW,GAAG;KACtB,IAAI,OAAO,SAAS,IAAI,IAAI;KAC5B;IACF;IACA,KAAK,MAAM,QAAQ,OAAO;KACxB,IAAI,IAAI,YAAY,SAAS;KAC7B,MAAM,0BAA0B,IAAI;IACtC;IACA;GACF;GAGA,IAAI;GACJ,IAAI;IACF,QAAS,MAAM,aAAa,YAAY,YAAqB;GAC/D,SAAS,KAAK;IACZ,IAAI,KAAK,IAAI,2CAAA,yBAAyB,CAAC,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC;IACjF;GACF;GACA,MAAM,cAAA,GAAA,KAAA,IAAoB;GAC1B,MAAM,cACJ,OAAO,MAAM,YAAY,WACrB,MAAM,UACN,MAAM,QAAQ,MAAM,OAAO,IACzB,MAAM,QACH,QAAQ,MAAM,EAAE,SAAS,UAAU,OAAO,EAAE,SAAS,QAAQ,EAC7D,KAAK,MAAM,EAAE,IAAI,EACjB,KAAK,EAAE,IACV;GACR,IAAI,YAAY,SAAS,GAAG;IAC1B,MAAM,YAAY,GAAG,WAAW;IAChC,QAAQ,cAAc,WAAW,aAAa,EAAE,YAAY,KAAK,CAAC;IAClE,MAAM,IAAI,aACR,IAAI,gBAAA,QAAQ;KACV,IAAI;KACJ,MAAM;KACN,SAAS;KACT,UAAU;KACV,WAAW,OAAO;KAClB,WAAW,OAAO;IACpB,CAAC,CACH;GACF;GACA,IAAI,MAAM,YAAY,OAAO,MAAM,aAAa,UAC9C,KAAK,MAAM,CAAC,SAAS,SAAS,OAAO,QAAQ,MAAM,QAAQ,GAAG;IAC5D,IAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG;IACnD,MAAM,YAAY,GAAG,WAAW,WAAW;IAC3C,QAAQ,cAAc,WAAW,MAAM,EAAE,YAAY,KAAK,CAAC;IAC3D,MAAM,IAAI,aACR,IAAI,gBAAA,QAAQ;KACV,IAAI;KACJ,SAAS;KACT,UAAU;KACV,WAAW,OAAO;KAClB,WAAW,OAAO;IACpB,CAAC,CACH;GACF;GAQF,MAAM,QAAQ,cANG,MAAM,QAAQ,MAAM,UAAU,IAC3C,MAAM,WAAW,KAAK,QAAQ;IAC5B,MAAM,GAAG,UAAU,QAAQ;IAC3B,WAAY,GAAG,UAAU,aAAa,CAAC;GACzC,EAAE,IACF,CAAC,CAC+B;GACpC,IAAI,MAAM,WAAW,GAAG;IACtB,IAAI,OAAO,SAAS,IAAI,IAAI;IAC5B;GACF;GACA,KAAK,MAAM,QAAQ,OAAO;IACxB,IAAI,IAAI,YAAY,SAAS;IAC7B,MAAM,0BAA0B,IAAI;GACtC;EACF;CACF;AACF"}