@nhtio/adk 0.1.0-master-f0aa531d

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 (297) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/batteries/index.d.ts +28 -0
  4. package/batteries/llm/index.d.ts +11 -0
  5. package/batteries/llm/openai_chat_completions/adapter.cjs +916 -0
  6. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -0
  7. package/batteries/llm/openai_chat_completions/adapter.d.ts +101 -0
  8. package/batteries/llm/openai_chat_completions/adapter.mjs +914 -0
  9. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -0
  10. package/batteries/llm/openai_chat_completions/exceptions.cjs +89 -0
  11. package/batteries/llm/openai_chat_completions/exceptions.cjs.map +1 -0
  12. package/batteries/llm/openai_chat_completions/exceptions.d.ts +97 -0
  13. package/batteries/llm/openai_chat_completions/exceptions.mjs +81 -0
  14. package/batteries/llm/openai_chat_completions/exceptions.mjs.map +1 -0
  15. package/batteries/llm/openai_chat_completions/helpers.cjs +819 -0
  16. package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -0
  17. package/batteries/llm/openai_chat_completions/helpers.d.ts +233 -0
  18. package/batteries/llm/openai_chat_completions/helpers.mjs +783 -0
  19. package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -0
  20. package/batteries/llm/openai_chat_completions/index.d.ts +27 -0
  21. package/batteries/llm/openai_chat_completions/types.cjs +1 -0
  22. package/batteries/llm/openai_chat_completions/types.d.ts +524 -0
  23. package/batteries/llm/openai_chat_completions/types.mjs +0 -0
  24. package/batteries/llm/openai_chat_completions/validation.cjs +190 -0
  25. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -0
  26. package/batteries/llm/openai_chat_completions/validation.d.ts +31 -0
  27. package/batteries/llm/openai_chat_completions/validation.mjs +187 -0
  28. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -0
  29. package/batteries/llm/openai_chat_completions.cjs +51 -0
  30. package/batteries/llm/openai_chat_completions.mjs +5 -0
  31. package/batteries/llm/webllm_chat_completions/adapter.cjs +658 -0
  32. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -0
  33. package/batteries/llm/webllm_chat_completions/adapter.d.ts +103 -0
  34. package/batteries/llm/webllm_chat_completions/adapter.mjs +656 -0
  35. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -0
  36. package/batteries/llm/webllm_chat_completions/exceptions.cjs +70 -0
  37. package/batteries/llm/webllm_chat_completions/exceptions.cjs.map +1 -0
  38. package/batteries/llm/webllm_chat_completions/exceptions.d.ts +74 -0
  39. package/batteries/llm/webllm_chat_completions/exceptions.mjs +65 -0
  40. package/batteries/llm/webllm_chat_completions/exceptions.mjs.map +1 -0
  41. package/batteries/llm/webllm_chat_completions/helpers.cjs +38 -0
  42. package/batteries/llm/webllm_chat_completions/helpers.d.ts +6 -0
  43. package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -0
  44. package/batteries/llm/webllm_chat_completions/index.d.ts +25 -0
  45. package/batteries/llm/webllm_chat_completions/types.d.ts +31 -0
  46. package/batteries/llm/webllm_chat_completions/validation.cjs +115 -0
  47. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -0
  48. package/batteries/llm/webllm_chat_completions/validation.d.ts +8 -0
  49. package/batteries/llm/webllm_chat_completions/validation.mjs +112 -0
  50. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -0
  51. package/batteries/llm/webllm_chat_completions.cjs +50 -0
  52. package/batteries/llm/webllm_chat_completions.mjs +6 -0
  53. package/batteries/llm.cjs +63 -0
  54. package/batteries/llm.mjs +10 -0
  55. package/batteries/storage/flydrive/index.d.ts +167 -0
  56. package/batteries/storage/flydrive.cjs +249 -0
  57. package/batteries/storage/flydrive.cjs.map +1 -0
  58. package/batteries/storage/flydrive.mjs +249 -0
  59. package/batteries/storage/flydrive.mjs.map +1 -0
  60. package/batteries/storage/in_memory/index.d.ts +106 -0
  61. package/batteries/storage/in_memory.cjs +121 -0
  62. package/batteries/storage/in_memory.cjs.map +1 -0
  63. package/batteries/storage/in_memory.mjs +119 -0
  64. package/batteries/storage/in_memory.mjs.map +1 -0
  65. package/batteries/storage/index.d.ts +18 -0
  66. package/batteries/storage/opfs/index.d.ts +299 -0
  67. package/batteries/storage/opfs.cjs +368 -0
  68. package/batteries/storage/opfs.cjs.map +1 -0
  69. package/batteries/storage/opfs.mjs +366 -0
  70. package/batteries/storage/opfs.mjs.map +1 -0
  71. package/batteries/storage.cjs +4 -0
  72. package/batteries/storage.mjs +2 -0
  73. package/batteries/tools/color/index.d.ts +37 -0
  74. package/batteries/tools/color.cjs +659 -0
  75. package/batteries/tools/color.cjs.map +1 -0
  76. package/batteries/tools/color.mjs +655 -0
  77. package/batteries/tools/color.mjs.map +1 -0
  78. package/batteries/tools/comparison/index.d.ts +29 -0
  79. package/batteries/tools/comparison.cjs +171 -0
  80. package/batteries/tools/comparison.cjs.map +1 -0
  81. package/batteries/tools/comparison.mjs +168 -0
  82. package/batteries/tools/comparison.mjs.map +1 -0
  83. package/batteries/tools/data_structure/index.d.ts +30 -0
  84. package/batteries/tools/data_structure.cjs +270 -0
  85. package/batteries/tools/data_structure.cjs.map +1 -0
  86. package/batteries/tools/data_structure.mjs +267 -0
  87. package/batteries/tools/data_structure.mjs.map +1 -0
  88. package/batteries/tools/datetime_extended/index.d.ts +51 -0
  89. package/batteries/tools/datetime_extended.cjs +309 -0
  90. package/batteries/tools/datetime_extended.cjs.map +1 -0
  91. package/batteries/tools/datetime_extended.mjs +302 -0
  92. package/batteries/tools/datetime_extended.mjs.map +1 -0
  93. package/batteries/tools/datetime_math/index.d.ts +36 -0
  94. package/batteries/tools/datetime_math.cjs +175 -0
  95. package/batteries/tools/datetime_math.cjs.map +1 -0
  96. package/batteries/tools/datetime_math.mjs +171 -0
  97. package/batteries/tools/datetime_math.mjs.map +1 -0
  98. package/batteries/tools/encoding/index.d.ts +36 -0
  99. package/batteries/tools/encoding.cjs +156 -0
  100. package/batteries/tools/encoding.cjs.map +1 -0
  101. package/batteries/tools/encoding.mjs +152 -0
  102. package/batteries/tools/encoding.mjs.map +1 -0
  103. package/batteries/tools/formatting/index.d.ts +28 -0
  104. package/batteries/tools/formatting.cjs +120 -0
  105. package/batteries/tools/formatting.cjs.map +1 -0
  106. package/batteries/tools/formatting.mjs +117 -0
  107. package/batteries/tools/formatting.mjs.map +1 -0
  108. package/batteries/tools/geo_basics/index.d.ts +33 -0
  109. package/batteries/tools/geo_basics.cjs +136 -0
  110. package/batteries/tools/geo_basics.cjs.map +1 -0
  111. package/batteries/tools/geo_basics.mjs +132 -0
  112. package/batteries/tools/geo_basics.mjs.map +1 -0
  113. package/batteries/tools/index.d.ts +32 -0
  114. package/batteries/tools/math/index.d.ts +37 -0
  115. package/batteries/tools/math.cjs +136 -0
  116. package/batteries/tools/math.cjs.map +1 -0
  117. package/batteries/tools/math.mjs +133 -0
  118. package/batteries/tools/math.mjs.map +1 -0
  119. package/batteries/tools/memory/index.d.ts +73 -0
  120. package/batteries/tools/memory.cjs +193 -0
  121. package/batteries/tools/memory.cjs.map +1 -0
  122. package/batteries/tools/memory.mjs +187 -0
  123. package/batteries/tools/memory.mjs.map +1 -0
  124. package/batteries/tools/parsing/index.d.ts +47 -0
  125. package/batteries/tools/parsing.cjs +191 -0
  126. package/batteries/tools/parsing.cjs.map +1 -0
  127. package/batteries/tools/parsing.mjs +185 -0
  128. package/batteries/tools/parsing.mjs.map +1 -0
  129. package/batteries/tools/retrievables/index.d.ts +81 -0
  130. package/batteries/tools/retrievables.cjs +215 -0
  131. package/batteries/tools/retrievables.cjs.map +1 -0
  132. package/batteries/tools/retrievables.mjs +209 -0
  133. package/batteries/tools/retrievables.mjs.map +1 -0
  134. package/batteries/tools/standing_instructions/index.d.ts +64 -0
  135. package/batteries/tools/standing_instructions.cjs +126 -0
  136. package/batteries/tools/standing_instructions.cjs.map +1 -0
  137. package/batteries/tools/standing_instructions.mjs +121 -0
  138. package/batteries/tools/standing_instructions.mjs.map +1 -0
  139. package/batteries/tools/statistics/index.d.ts +46 -0
  140. package/batteries/tools/statistics.cjs +253 -0
  141. package/batteries/tools/statistics.cjs.map +1 -0
  142. package/batteries/tools/statistics.mjs +248 -0
  143. package/batteries/tools/statistics.mjs.map +1 -0
  144. package/batteries/tools/string_processing/index.d.ts +29 -0
  145. package/batteries/tools/string_processing.cjs +154 -0
  146. package/batteries/tools/string_processing.cjs.map +1 -0
  147. package/batteries/tools/string_processing.mjs +151 -0
  148. package/batteries/tools/string_processing.mjs.map +1 -0
  149. package/batteries/tools/structured_data/index.d.ts +34 -0
  150. package/batteries/tools/structured_data.cjs +189 -0
  151. package/batteries/tools/structured_data.cjs.map +1 -0
  152. package/batteries/tools/structured_data.mjs +185 -0
  153. package/batteries/tools/structured_data.mjs.map +1 -0
  154. package/batteries/tools/text_analysis/index.d.ts +31 -0
  155. package/batteries/tools/text_analysis.cjs +120 -0
  156. package/batteries/tools/text_analysis.cjs.map +1 -0
  157. package/batteries/tools/text_analysis.mjs +117 -0
  158. package/batteries/tools/text_analysis.mjs.map +1 -0
  159. package/batteries/tools/text_comparison/index.d.ts +28 -0
  160. package/batteries/tools/text_comparison.cjs +96 -0
  161. package/batteries/tools/text_comparison.cjs.map +1 -0
  162. package/batteries/tools/text_comparison.mjs +93 -0
  163. package/batteries/tools/text_comparison.mjs.map +1 -0
  164. package/batteries/tools/time/index.d.ts +27 -0
  165. package/batteries/tools/time.cjs +63 -0
  166. package/batteries/tools/time.cjs.map +1 -0
  167. package/batteries/tools/time.mjs +60 -0
  168. package/batteries/tools/time.mjs.map +1 -0
  169. package/batteries/tools/unit_conversion/index.d.ts +19 -0
  170. package/batteries/tools/unit_conversion.cjs +452 -0
  171. package/batteries/tools/unit_conversion.cjs.map +1 -0
  172. package/batteries/tools/unit_conversion.mjs +450 -0
  173. package/batteries/tools/unit_conversion.mjs.map +1 -0
  174. package/batteries/tools.cjs +80 -0
  175. package/batteries/tools.mjs +21 -0
  176. package/batteries.cjs +142 -0
  177. package/batteries.mjs +30 -0
  178. package/chunk-KmRHZBOW.js +35 -0
  179. package/common-DeZaonK1.mjs +208 -0
  180. package/common-DeZaonK1.mjs.map +1 -0
  181. package/common-Od8edUXU.js +232 -0
  182. package/common-Od8edUXU.js.map +1 -0
  183. package/common.cjs +31 -0
  184. package/common.d.ts +108 -0
  185. package/common.mjs +8 -0
  186. package/dispatch_runner-9j6bXHL3.mjs +1609 -0
  187. package/dispatch_runner-9j6bXHL3.mjs.map +1 -0
  188. package/dispatch_runner-CsoH0nld.js +1627 -0
  189. package/dispatch_runner-CsoH0nld.js.map +1 -0
  190. package/dispatch_runner.cjs +3 -0
  191. package/dispatch_runner.d.ts +17 -0
  192. package/dispatch_runner.mjs +2 -0
  193. package/exceptions-D5YrO9Vm.js +280 -0
  194. package/exceptions-D5YrO9Vm.js.map +1 -0
  195. package/exceptions-NrzIHw_R.mjs +244 -0
  196. package/exceptions-NrzIHw_R.mjs.map +1 -0
  197. package/exceptions.cjs +33 -0
  198. package/exceptions.d.ts +52 -0
  199. package/exceptions.mjs +3 -0
  200. package/factories.cjs +4 -0
  201. package/factories.d.ts +39 -0
  202. package/factories.mjs +2 -0
  203. package/forge.cjs +9 -0
  204. package/forge.d.ts +49 -0
  205. package/forge.mjs +5 -0
  206. package/guards.cjs +96 -0
  207. package/guards.cjs.map +1 -0
  208. package/guards.d.ts +83 -0
  209. package/guards.mjs +72 -0
  210. package/guards.mjs.map +1 -0
  211. package/index.cjs +107 -0
  212. package/index.cjs.map +1 -0
  213. package/index.d.ts +18 -0
  214. package/index.mjs +31 -0
  215. package/index.mjs.map +1 -0
  216. package/lib/classes/artifact_tool.d.ts +129 -0
  217. package/lib/classes/base_exception.d.ts +83 -0
  218. package/lib/classes/identity.d.ts +71 -0
  219. package/lib/classes/media.d.ts +326 -0
  220. package/lib/classes/memory.d.ts +72 -0
  221. package/lib/classes/message.d.ts +137 -0
  222. package/lib/classes/registry.d.ts +79 -0
  223. package/lib/classes/retrievable.d.ts +100 -0
  224. package/lib/classes/spooled_artifact.d.ts +296 -0
  225. package/lib/classes/spooled_json_artifact.d.ts +158 -0
  226. package/lib/classes/spooled_markdown_artifact.d.ts +202 -0
  227. package/lib/classes/thought.d.ts +142 -0
  228. package/lib/classes/tokenizable.d.ts +124 -0
  229. package/lib/classes/tool.d.ts +228 -0
  230. package/lib/classes/tool_call.d.ts +190 -0
  231. package/lib/classes/tool_registry.d.ts +159 -0
  232. package/lib/classes/turn_gate.d.ts +109 -0
  233. package/lib/contracts/dispatch_context.d.ts +345 -0
  234. package/lib/contracts/media_reader.d.ts +60 -0
  235. package/lib/contracts/spool_reader.d.ts +80 -0
  236. package/lib/contracts/spooled_artifact_constructor.d.ts +38 -0
  237. package/lib/contracts/turn_runner_config.d.ts +101 -0
  238. package/lib/contracts/turn_runner_context.d.ts +267 -0
  239. package/lib/dispatch_runner.d.ts +98 -0
  240. package/lib/exceptions/runtime.d.ts +370 -0
  241. package/lib/helpers/media_readers.d.ts +39 -0
  242. package/lib/turn_runner.d.ts +144 -0
  243. package/lib/types/dispatch_context.d.ts +233 -0
  244. package/lib/types/dispatch_runner.d.ts +387 -0
  245. package/lib/types/turn_runner.d.ts +322 -0
  246. package/lib/utils/canonical_json.d.ts +18 -0
  247. package/lib/utils/exceptions.d.ts +78 -0
  248. package/lib/utils/guards.d.ts +32 -0
  249. package/lib/utils/validation.d.ts +77 -0
  250. package/package.json +334 -0
  251. package/runtime-BJVkrGQe.js +519 -0
  252. package/runtime-BJVkrGQe.js.map +1 -0
  253. package/runtime-CrEPIFgr.mjs +346 -0
  254. package/runtime-CrEPIFgr.mjs.map +1 -0
  255. package/skills/adk-assembly/SKILL.md +109 -0
  256. package/skills/adk-assembly/references/assembly-contract.md +66 -0
  257. package/skills/adk-assembly/references/executors-tools-pipelines-events.md +113 -0
  258. package/skills/adk-assembly/references/first-integration.md +93 -0
  259. package/skills/adk-assembly/references/storage-and-context.md +102 -0
  260. package/spooled_artifact-C5ZtGxuJ.mjs +544 -0
  261. package/spooled_artifact-C5ZtGxuJ.mjs.map +1 -0
  262. package/spooled_artifact-Cm9Te22K.js +568 -0
  263. package/spooled_artifact-Cm9Te22K.js.map +1 -0
  264. package/spooled_artifact.cjs +7 -0
  265. package/spooled_artifact.d.ts +40 -0
  266. package/spooled_artifact.mjs +3 -0
  267. package/spooled_markdown_artifact-BpUJol0W.mjs +771 -0
  268. package/spooled_markdown_artifact-BpUJol0W.mjs.map +1 -0
  269. package/spooled_markdown_artifact-RRB113sy.js +786 -0
  270. package/spooled_markdown_artifact-RRB113sy.js.map +1 -0
  271. package/thought-CDb457b4.mjs +470 -0
  272. package/thought-CDb457b4.mjs.map +1 -0
  273. package/thought-DuN2PgdO.js +494 -0
  274. package/thought-DuN2PgdO.js.map +1 -0
  275. package/tool-COSeH8I6.js +302 -0
  276. package/tool-COSeH8I6.js.map +1 -0
  277. package/tool-D2WB1EA1.mjs +296 -0
  278. package/tool-D2WB1EA1.mjs.map +1 -0
  279. package/tool_call-BKyyxGaZ.mjs +578 -0
  280. package/tool_call-BKyyxGaZ.mjs.map +1 -0
  281. package/tool_call-DFgzcVcU.js +608 -0
  282. package/tool_call-DFgzcVcU.js.map +1 -0
  283. package/tool_registry-Dkfprsck.js +641 -0
  284. package/tool_registry-Dkfprsck.js.map +1 -0
  285. package/tool_registry-DqLOyGyG.mjs +592 -0
  286. package/tool_registry-DqLOyGyG.mjs.map +1 -0
  287. package/turn_runner-CMm2BHdX.js +615 -0
  288. package/turn_runner-CMm2BHdX.js.map +1 -0
  289. package/turn_runner-y7eyEcJH.mjs +603 -0
  290. package/turn_runner-y7eyEcJH.mjs.map +1 -0
  291. package/turn_runner.cjs +3 -0
  292. package/turn_runner.d.ts +21 -0
  293. package/turn_runner.mjs +2 -0
  294. package/types.cjs +1 -0
  295. package/types.d.ts +56 -0
  296. package/types.mjs +0 -0
  297. package/vite-env.d.ts +23 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.mjs","names":["#baseline","#engine","#resolveEngine","#enginePromise"],"sources":["../../../../src/batteries/llm/webllm_chat_completions/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter for WebLLM Chat Completions compatible endpoints.\n *\n * @module @nhtio/adk/batteries/llm/webllm_chat_completions/adapter\n *\n * @remarks\n * Cross-environment LLM adapter for the WebLLM Chat Completions wire shape. Chat Completions was\n * chosen as the ADK's reference adapter because it is the de-facto interchange format for the\n * majority of OpenAI-compatible gateways (vLLM, Together, Groq, Fireworks, Ollama, Azure OpenAI,\n * OpenRouter, DeepSeek, Mistral La Plateforme, and most self-hosted deployments). Its tool-call\n * synthetic-history shape (`role: 'assistant', tool_calls: [...]` followed by `role: 'tool'` with\n * `tool_call_id`) is the lowest-common-denominator that every conformant gateway accepts.\n *\n * The adapter is built around three pluggable layers:\n *\n * 1. **Translation helpers** — the thirteen swappable functions exported from `./helpers` turn\n * ADK primitives ({@link @nhtio/adk!Tokenizable}, {@link @nhtio/adk!Memory}, {@link @nhtio/adk!Message}, {@link @nhtio/adk!Thought},\n * {@link @nhtio/adk!ToolCall}, {@link @nhtio/adk!Tool}, {@link @nhtio/adk!ArtifactTool}, {@link @nhtio/adk!SpooledArtifact}) into Chat\n * Completions wire shapes. Consumers override individual helpers via `options.helpers.*` to\n * customise envelope formats, bucket ordering, thought surfacing, or JSON Schema generation\n * without forking the adapter.\n * 2. **Three-layer options merging** — constructor baseline, per-`executor()` overrides, and\n * per-iteration `ctx.stash.webLLMChatCompletions` overrides combine with key-by-key\n * precedence for `helpers` and wholesale replacement for everything else.\n * The merged shape is re-validated on every iteration so a malformed stash override\n * fails loud, not silently.\n * 3. **WebLLM engine invocation** — accepts a preloaded `engine` or lazy `createEngine` factory.\n * The resolved request body is passed directly to WebLLM's OpenAI-compatible chat API.\n *\n * Per-iteration flow (steps 1–9 of the plan):\n * 1. Merge constructor / executor / stash options and re-validate.\n * 2. Resolve helpers, falling back to bundled `default*` for each unset field.\n * 3. Forge artifact-query tools by walking `ctx.turnToolCalls`, collecting unique\n * `SpooledArtifact` constructors, calling `<Ctor>.forgeTools(ctx)` on each, and merging the\n * results with `ctx.tools`.\n * 4. Pre-render every persisted tool-call result into the prompt-ready string the timeline will\n * use, cached by `tc.id`.\n * 5. When `tokenEncoding !== null`, sum the token weight of every persisted bucket and throw\n * {@link @nhtio/adk/batteries!E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW} when the total exceeds `contextWindow`.\n * 6. Build the request body via `buildChatCompletionsHistory`; carry vendor-opaque reasoning\n * blocks through the `_adk_reasoning_payloads` side-channel.\n * 7. Resolve or lazily create a WebLLM engine and call `engine.chat.completions.create(body)`.\n * 8. Streaming path: consume WebLLM's async chunk iterable; surface deltas through\n * `helpers.reportMessage` / `reportThought` / `reportToolCall`; assemble tool-call deltas via\n * the accumulator; persist `Message` / `Thought` / `ToolCall` records on stream end.\n * 9. Non-streaming path: consume the returned Chat Completion object; same persistence +\n * tool-execution loop.\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_WEBLLM_CHAT_COMPLETIONS_OPTIONS,\n E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW,\n E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR,\n E_WEBLLM_CHAT_COMPLETIONS_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 defaultRenderTimelineMessage,\n defaultRenderThought,\n defaultFilterThoughts,\n defaultToolsToChatCompletionsTools,\n defaultRenderChatCompletionsSystemPrompt,\n defaultRenderChatCompletionsToolCallResult,\n defaultBuildChatCompletionsHistory,\n defaultCreateChatCompletionsToolCallDeltaAccumulator,\n} from './helpers'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { Tool, Memory, TokenEncoding } from '@nhtio/adk/common'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/dispatch_runner'\nimport type {\n WebLLMChatCompletionsAdapterOptions,\n ChatCompletionsHelpers,\n WebLLMChatCompletionsRequestBody,\n ChatCompletionsChunk,\n ChatCompletionsResponse,\n AssembledToolCall,\n ChatCompletionsContentBlock,\n WebLLMEngine,\n} from './types'\n\n// ─── ADK-control keys (stripped before sending the request body) ──────────\n\nconst ADK_CONTROL_KEYS: ReadonlySet<string> = new Set([\n 'engine',\n 'createEngine',\n 'engineConfig',\n 'chatOptions',\n 'stream',\n 'bucketOrder',\n 'contextWindow',\n 'selfIdentity',\n 'thoughtSurfacing',\n 'tokenEncoding',\n 'replayCompatibility',\n 'helpers',\n 'strictToolChoice',\n 'unsupportedMediaPolicy',\n 'onInitProgress',\n 'isWebGPUAvailable',\n 'autoAck',\n])\n\n// ─── Option merging ───────────────────────────────────────────────────────────\n\nconst mergeHelpers = (\n layers: ReadonlyArray<Partial<ChatCompletionsHelpers> | undefined>\n): Partial<ChatCompletionsHelpers> | undefined => {\n let merged: Partial<ChatCompletionsHelpers> | 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: WebLLMChatCompletionsAdapterOptions,\n exec: Partial<WebLLMChatCompletionsAdapterOptions> | undefined,\n stash: Partial<WebLLMChatCompletionsAdapterOptions> | undefined\n): Partial<WebLLMChatCompletionsAdapterOptions> => {\n const layers = [baseline as Partial<WebLLMChatCompletionsAdapterOptions>, 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<WebLLMChatCompletionsAdapterOptions>\n}\n\n// ─── Helper resolution ────────────────────────────────────────────────────────\n\nconst resolveHelpers = (\n overrides: Partial<ChatCompletionsHelpers> | undefined\n): ChatCompletionsHelpers => {\n const src = overrides ?? {}\n return {\n descriptionToChatCompletionsJsonSchema:\n src.descriptionToChatCompletionsJsonSchema ?? defaultDescriptionToChatCompletionsJsonSchema,\n renderUntrustedContent: src.renderUntrustedContent ?? defaultRenderUntrustedContent,\n renderTrustedContent: src.renderTrustedContent ?? defaultRenderTrustedContent,\n renderStandingInstructions: src.renderStandingInstructions ?? defaultRenderStandingInstructions,\n renderMemories: src.renderMemories ?? defaultRenderMemories,\n renderRetrievables: src.renderRetrievables ?? defaultRenderRetrievables,\n renderRetrievableSafetyDirective:\n src.renderRetrievableSafetyDirective ?? defaultRenderRetrievableSafetyDirective,\n renderFirstPartyRetrievables:\n src.renderFirstPartyRetrievables ?? defaultRenderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables:\n src.renderThirdPartyPublicRetrievables ?? defaultRenderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables:\n src.renderThirdPartyPrivateRetrievables ?? defaultRenderThirdPartyPrivateRetrievables,\n renderTimelineMessage: src.renderTimelineMessage ?? defaultRenderTimelineMessage,\n renderThought: src.renderThought ?? defaultRenderThought,\n filterThoughts: src.filterThoughts ?? defaultFilterThoughts,\n toolsToChatCompletionsTools:\n src.toolsToChatCompletionsTools ?? defaultToolsToChatCompletionsTools,\n renderChatCompletionsSystemPrompt:\n src.renderChatCompletionsSystemPrompt ?? defaultRenderChatCompletionsSystemPrompt,\n renderChatCompletionsToolCallResult:\n src.renderChatCompletionsToolCallResult ?? defaultRenderChatCompletionsToolCallResult,\n buildChatCompletionsHistory:\n src.buildChatCompletionsHistory ?? defaultBuildChatCompletionsHistory,\n createChatCompletionsToolCallDeltaAccumulator:\n src.createChatCompletionsToolCallDeltaAccumulator ??\n defaultCreateChatCompletionsToolCallDeltaAccumulator,\n }\n}\n\n// ─── ID helpers ───────────────────────────────────────────────────────────────\n\n// Canonical (key-order-insensitive) checksum — MUST match the contract documented\n// on canonicalStringify and used by Tool.executor + dispatch_runner's streaming\n// helper, so ctx.toolCallCount(checksum) detects semantically-identical repeat\n// calls regardless of argument key order.\nconst computeChecksum = (tool: string, args: unknown): string =>\n sha256(canonicalStringify({ tool, args }))\n\nconst nowIso = (): string => DateTime.now().toISO() ?? new Date().toISOString()\n\n// ─── Token measurement ────────────────────────────────────────────────────────\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncoding\n): Promise<number> => {\n return Promise.resolve(value.estimateTokens(encoding))\n}\n\n// ─── Adapter class ────────────────────────────────────────────────────────────\n\n/**\n * Opinionated cross-environment LLM adapter for the WebLLM Chat Completions wire shape.\n *\n * @remarks\n * Construction validates options eagerly via {@link @nhtio/adk/batteries!validateOptions} and throws\n * {@link @nhtio/adk/batteries!E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS} on failure — config bugs fail loud, not at\n * dispatch time. The returned instance is reusable: call {@link WebLLMChatCompletionsAdapter.executor}\n * once per `DispatchRunner` configuration to obtain an {@link @nhtio/adk!DispatchExecutorFn} bound to the\n * baseline plus optional executor-scope overrides.\n *\n * Per-iteration overrides live on the active {@link @nhtio/adk!DispatchContext}'s\n * `stash.webLLMChatCompletions` slot and take highest precedence — they merge into the\n * executor-scope shape on every iteration. `helpers` merge key-by-key across all three layers;\n * every other field is replaced wholesale at the highest layer that\n * sets it.\n */\nexport class WebLLMChatCompletionsAdapter {\n /**\n * Customary key for per-iteration overrides on `ctx.stash`. The adapter reads\n * `ctx.stash.get(WebLLMChatCompletionsAdapter.STASH_KEY, {})` at the start of every\n * iteration and merges the value into the resolved options shape.\n */\n public static readonly STASH_KEY = 'webLLMChatCompletions' as const\n\n readonly #baseline: WebLLMChatCompletionsAdapterOptions\n #engine: WebLLMEngine | undefined\n #enginePromise: Promise<WebLLMEngine> | undefined\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-baseline options. Re-validated on every iteration after\n * per-dispatch and per-iteration overrides are layered in.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS} when `options` does not satisfy\n * {@link @nhtio/adk/batteries!webLLMChatCompletionsOptionsSchema}.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n this.#engine = this.#baseline.engine\n }\n\n async preload(overrides?: Partial<WebLLMChatCompletionsAdapterOptions>): Promise<WebLLMEngine> {\n const merged = validateOptions(mergeOptions(this.#baseline, overrides, undefined))\n return this.#resolveEngine(merged)\n }\n\n reset(): void {\n this.#engine = undefined\n this.#enginePromise = undefined\n }\n\n isAvailable(): boolean {\n return (this.#baseline.isWebGPUAvailable ?? WebLLMChatCompletionsAdapter.isAvailable)()\n }\n\n async #resolveEngine(merged: WebLLMChatCompletionsAdapterOptions): Promise<WebLLMEngine> {\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 ?? WebLLMChatCompletionsAdapter.isAvailable)()\n if (!available) {\n throw new E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS([\n 'WebLLM requires a browser/runtime with WebGPU support',\n ])\n }\n this.#enginePromise ??= (async () => {\n const createEngine =\n merged.createEngine ??\n (async ({ model, engineConfig, chatOptions, onInitProgress }) => {\n const { CreateMLCEngine } = await import('@mlc-ai/web-llm')\n return (await CreateMLCEngine(\n model,\n { ...(engineConfig ?? {}), initProgressCallback: onInitProgress },\n chatOptions\n )) as WebLLMEngine\n })\n const engine = await createEngine({\n model: merged.model,\n engineConfig: merged.engineConfig,\n chatOptions: merged.chatOptions,\n onInitProgress: merged.onInitProgress,\n })\n this.#engine = engine\n return engine\n })()\n return this.#enginePromise\n }\n\n /**\n * Returns an {@link @nhtio/adk!DispatchExecutorFn} bound to this adapter's baseline plus optional\n * executor-scope overrides. The returned function is reusable across iterations — every\n * iteration re-merges with `ctx.stash[STASH_KEY]` and re-validates the result.\n *\n * @param overrides - Optional executor-scope overrides. Higher precedence than the baseline,\n * lower precedence than `ctx.stash[STASH_KEY]`.\n * @returns An {@link @nhtio/adk!DispatchExecutorFn} suitable for `DispatchRunner`.\n */\n executor(overrides?: Partial<WebLLMChatCompletionsAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = WebLLMChatCompletionsAdapter\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n // Bridge helpers.log → the legacy `warn: (msg) => void` slot exposed by the per-call\n // helper signatures. Helpers downstream don't need to know the structured shape — they\n // emit a single string, which we route to `helpers.log.warn` with a stable `kind` so\n // observability middleware can still filter and aggregate.\n const localWarn = (msg: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message: msg })\n }\n\n // ── Step 1: merge & validate ──────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<WebLLMChatCompletionsAdapterOptions>)\n : {}\n const mergedRaw = mergeOptions(baseline, overrides, stashOverrides)\n const merged = validateOptions(mergedRaw)\n\n // Cross-field invariant: tokenEncoding non-null requires contextWindow.\n if (merged.tokenEncoding !== null && merged.contextWindow === undefined) {\n throw new E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n\n // ── Step 2: resolve helpers ───────────────────────────────────────────\n const resolvedHelpers = resolveHelpers(merged.helpers)\n\n // ── Step 3: forge artifact-query tools ────────────────────────────────\n const uniqueCtors = new Set<typeof SpooledArtifact>()\n for (const tc of ctx.turnToolCalls) {\n const results = tc.results as unknown as { constructor?: unknown }\n const ctor = results?.constructor\n if (ctor && SpooledArtifact.isSpooledArtifactConstructor(ctor)) {\n uniqueCtors.add(ctor as unknown as typeof SpooledArtifact)\n }\n }\n const forgedRegistries: ToolRegistry[] = []\n for (const ctor of uniqueCtors) {\n const forgeFn = (\n ctor as unknown as {\n forgeTools?: (c: DispatchContext) => ToolRegistry\n }\n ).forgeTools\n if (typeof forgeFn === 'function') {\n forgedRegistries.push(forgeFn.call(ctor, ctx))\n }\n }\n const mergedRegistry = ToolRegistry.merge([ctx.tools, ...forgedRegistries], {\n onCollision: 'replace',\n })\n mergedRegistry.bindContext(ctx)\n\n // ── Step 4: pre-render tool-call results ──────────────────────────────\n const renderedToolCallResults = new Map<string, string | ChatCompletionsContentBlock[]>()\n for (const tc of ctx.turnToolCalls) {\n const rendered = await resolvedHelpers.renderChatCompletionsToolCallResult({\n toolCall: tc,\n results: tc.results as\n | Tokenizable\n | SpooledArtifact\n | SpooledArtifact[]\n | Media\n | Media[],\n tool: mergedRegistry.get(tc.tool) as Tool | ArtifactTool | undefined,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn: localWarn,\n })\n renderedToolCallResults.set(tc.id, rendered)\n }\n\n // ── Step 5: context window enforcement ────────────────────────────────\n if (merged.tokenEncoding !== null && merged.contextWindow !== undefined) {\n const encoding = merged.tokenEncoding as TokenEncoding\n let spTokens = await estimateTokensOf(ctx.systemPrompt, encoding)\n let siTokens = 0\n for (const si of ctx.standingInstructions) {\n siTokens += await estimateTokensOf(si, encoding)\n }\n let memTokens = 0\n for (const mem of ctx.turnMemories as Set<Memory>) {\n memTokens += await estimateTokensOf(mem.content, encoding)\n }\n let retTokens = 0\n for (const r of ctx.turnRetrievables) {\n retTokens += await estimateTokensOf(r.content, encoding)\n }\n let tlTokens = 0\n for (const msg of ctx.turnMessages) {\n if (msg.content !== undefined) {\n tlTokens += await estimateTokensOf(msg.content, encoding)\n }\n }\n for (const th of ctx.turnThoughts) {\n tlTokens += await estimateTokensOf(th.content, encoding)\n }\n for (const rendered of renderedToolCallResults.values()) {\n const textPart =\n typeof rendered === 'string'\n ? rendered\n : rendered\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('\\n')\n const tk = new Tokenizable(textPart)\n tlTokens += await estimateTokensOf(tk, encoding)\n }\n const total = spTokens + siTokens + memTokens + retTokens + tlTokens\n const perBucketObj = {\n systemPrompt: spTokens,\n standingInstructions: siTokens,\n memories: memTokens,\n retrievables: retTokens,\n timeline: tlTokens,\n }\n helpers.log.debug({\n kind: 'context-window-usage',\n message: `Context window usage: ${total}/${merged.contextWindow} tokens`,\n payload: {\n total,\n limit: merged.contextWindow,\n encoding,\n perBucket: perBucketObj,\n },\n })\n if (total > merged.contextWindow) {\n const perBucket = JSON.stringify(perBucketObj)\n throw new E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n encoding,\n perBucket,\n ])\n }\n }\n\n // ── Step 5b: tool_choice + forged artifact-tools guard ────────────────\n // When `tool_choice` (or the `allowed_tools` variant) forces the model onto a specific\n // tool name and that name resolves to an ephemeral, forged artifact-query tool, surface\n // it as a structured warning (or throw under `strictToolChoice: true`). Forging an\n // artifact-query tool by name is almost always a misconfiguration — the tool may not\n // exist in the next iteration once the artifact ages out of `ctx.turnToolCalls`.\n const forcedToolNames: string[] = []\n const toolChoice = merged.tool_choice\n let toolChoiceVariant: 'function' | 'allowed_tools' = 'function'\n if (toolChoice && typeof toolChoice === 'object') {\n if ('function' in toolChoice && toolChoice.type === 'function') {\n forcedToolNames.push(toolChoice.function.name)\n } else if ('custom' in toolChoice && toolChoice.type === 'custom') {\n forcedToolNames.push(toolChoice.custom.name)\n } else if (toolChoice.type === 'allowed_tools') {\n toolChoiceVariant = 'allowed_tools'\n for (const entry of toolChoice.allowed_tools.tools) {\n if ('function' in entry) forcedToolNames.push(entry.function.name)\n else if ('custom' in entry) forcedToolNames.push(entry.custom.name)\n }\n }\n }\n const forcedForgedHits: Array<{ toolName: string }> = []\n for (const name of forcedToolNames) {\n const t = mergedRegistry.get(name) as { ephemeral?: boolean } | undefined\n if (t?.ephemeral === true) {\n forcedForgedHits.push({ toolName: name })\n }\n }\n if (forcedForgedHits.length > 0) {\n if (merged.strictToolChoice === true) {\n throw new E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS([\n `tool_choice forces forged ephemeral artifact-query tool(s): ${forcedForgedHits\n .map((h) => h.toolName)\n .join(\n ', '\n )} — these may not exist on the next iteration. Remove the override or unset strictToolChoice.`,\n ])\n }\n helpers.log.warn({\n kind: 'tool-choice-forged-artifact',\n message: `tool_choice forces ${forcedForgedHits.length} forged ephemeral artifact-query tool(s); this is almost always a misconfiguration`,\n payload: {\n toolNames: forcedForgedHits.map((h) => h.toolName),\n variant: toolChoiceVariant,\n },\n })\n }\n\n // ── Step 6: build request body ────────────────────────────────────────\n const { messages: wireMessages, reasoningPayloads } =\n await resolvedHelpers.buildChatCompletionsHistory({\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: merged.selfIdentity ?? 'assistant',\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n renderChatCompletionsToolCallResult: resolvedHelpers.renderChatCompletionsToolCallResult,\n renderChatCompletionsSystemPrompt: resolvedHelpers.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: resolvedHelpers.renderStandingInstructions,\n renderMemories: resolvedHelpers.renderMemories,\n renderRetrievables: resolvedHelpers.renderRetrievables,\n renderRetrievableSafetyDirective: resolvedHelpers.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: resolvedHelpers.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: resolvedHelpers.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: resolvedHelpers.renderThirdPartyPrivateRetrievables,\n renderTimelineMessage: resolvedHelpers.renderTimelineMessage,\n renderThought: resolvedHelpers.renderThought,\n filterThoughts: resolvedHelpers.filterThoughts,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn: localWarn,\n })\n\n const stream = merged.stream ?? true\n const body: WebLLMChatCompletionsRequestBody = {\n model: merged.model,\n messages: wireMessages,\n stream,\n }\n for (const [k, v] of Object.entries(merged)) {\n if (ADK_CONTROL_KEYS.has(k)) continue\n if (k === 'model' || k === 'messages' || k === 'stream') continue\n if (v === undefined) continue\n ;(body as Record<string, unknown>)[k] = v\n }\n const toolsArr = mergedRegistry.all()\n if (toolsArr.length > 0) {\n body.tools = resolvedHelpers.toolsToChatCompletionsTools(toolsArr, {\n descriptionToChatCompletionsJsonSchema:\n resolvedHelpers.descriptionToChatCompletionsJsonSchema,\n })\n }\n if (reasoningPayloads.length > 0) {\n body._adk_reasoning_payloads = reasoningPayloads\n }\n\n // ── Step 7: invoke WebLLM engine ─────────────────────────────────────\n let completion: ChatCompletionsResponse | AsyncIterable<ChatCompletionsChunk>\n try {\n const engine = await this.#resolveEngine(merged)\n completion = (await engine.chat.completions.create(body as never)) as\n | ChatCompletionsResponse\n | AsyncIterable<ChatCompletionsChunk>\n } catch (err) {\n helpers.log.error({\n kind: 'webllm-engine-error',\n message: `WebLLM engine failure: ${isError(err) ? err.message : String(err)}`,\n payload: { detail: isError(err) ? err.message : String(err) },\n })\n ctx.nack(\n new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n\n // Per-dispatch spool store used to back string / Uint8Array tool returns. Bytes are\n // written under the call id; the resulting SpooledArtifact (or tool-configured subclass)\n // is the model-visible handle for the rest of the turn.\n const spoolStore = new InMemorySpoolStore()\n\n // ── Inner helper: persist + execute one assembled tool call ───────────\n const executeAndPersistToolCall = async (call: AssembledToolCall): Promise<void> => {\n const tool = mergedRegistry.get(call.name)\n // Parse args defensively. The model may emit non-JSON or a non-object\n // JSON value (string, number, array, null); both are recoverable error\n // conditions, NOT dispatch-killers. A parse failure short-circuits to\n // a persisted error ToolCall — formatted by `E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS`\n // so consumers can match on the stable error code — letting the model\n // self-correct on the next iteration.\n let args: Record<string, unknown> = {}\n let parseError:\n | InstanceType<typeof E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS>\n | undefined\n if (call.args && call.args.length > 0) {\n try {\n const parsed: unknown = JSON.parse(call.args)\n if (isObject(parsed)) {\n args = parsed\n } else {\n const receivedKind = Array.isArray(parsed)\n ? 'array'\n : parsed === null\n ? 'null'\n : typeof parsed\n parseError = new E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS([\n `must be a JSON object; received ${receivedKind}`,\n call.args,\n ])\n }\n } catch {\n parseError = new E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS([\n 'are not valid JSON',\n call.args,\n ])\n }\n }\n const completedAt = nowIso()\n if (parseError !== undefined) {\n const results = new Tokenizable(parseError.message)\n helpers.reportToolCall(call.id, { tool: call.name, args })\n helpers.reportToolCall(call.id, {\n results,\n isError: true,\n isComplete: true,\n })\n const checksum = computeChecksum(call.name, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: call.name,\n args,\n checksum,\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n if (!tool) {\n const errText = `Tool not found: ${call.name}`\n const results = new Tokenizable(errText)\n helpers.reportToolCall(call.id, { tool: call.name, args })\n helpers.reportToolCall(call.id, {\n results,\n isError: true,\n isComplete: true,\n })\n const checksum = computeChecksum(call.name, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: call.name,\n args,\n checksum,\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n helpers.reportToolCall(call.id, { tool: tool.name, 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)(args)\n if (isArtifactTool) {\n // ArtifactTool: handler returns a string | Tokenizable that *is* the model-visible\n // answer to a query against a prior artifact. No spool write, no SpooledArtifact\n // construction — pass through (or wrap a bare string in Tokenizable).\n if (Tokenizable.isTokenizable(raw)) {\n results = raw\n } else if (typeof raw === 'string') {\n results = new Tokenizable(raw)\n } else {\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 = spoolStore.write(call.id, raw as string | Uint8Array)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n // Defensive fallback — wrap stringified value so the model gets *something*.\n const reader = 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 // Surface field-level validation detail from the cause chain so the\n // model can self-correct on the specific offending field. `E_INVALID_TOOL_ARGS`\n // carries the joi `ValidationException` on `cause`, whose message is the\n // joined field-level error text (e.g. `\"text\" is required`).\n let detailMsg = isError(err) ? err.message : String(err)\n if (\n isError(err) &&\n isError(err.cause) &&\n err.cause.message &&\n err.cause.message !== err.message\n ) {\n detailMsg = `${detailMsg} ${err.cause.message}`\n }\n results = new Tokenizable(detailMsg)\n }\n helpers.reportToolCall(call.id, {\n results,\n isError: toolHadError,\n isComplete: true,\n })\n const checksum = computeChecksum(tool.name, args)\n const completedAt2 = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: tool.name,\n args,\n checksum,\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 selfIdentity = merged.selfIdentity ?? 'assistant'\n\n // ── Step 8: streaming path ────────────────────────────────────────────\n if (stream) {\n const chunks = completion as AsyncIterable<ChatCompletionsChunk>\n if (!chunks || typeof chunks[Symbol.asyncIterator] !== 'function') {\n ctx.nack(new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR(['engine did not return a stream']))\n return\n }\n const accumulator = resolvedHelpers.createChatCompletionsToolCallDeltaAccumulator()\n const streamId = uuidv6()\n\n let partialMessageContent = ''\n let partialThoughtContent = ''\n let sawMessageDelta = false\n let sawThoughtDelta = false\n\n const drainAndPersist = async (): Promise<void> => {\n if (sawMessageDelta) {\n helpers.reportMessage(streamId, '', { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: streamId,\n role: 'assistant',\n content: partialMessageContent,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n if (sawThoughtDelta) {\n helpers.reportThought(streamId, '', { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: streamId,\n content: partialThoughtContent,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n const calls = accumulator.drain()\n helpers.log.debug({\n kind: 'accumulator-finalised',\n message: `Stream finalised: ${calls.length} tool call(s), message=${sawMessageDelta}, thought=${sawThoughtDelta}`,\n payload: { toolCallCount: calls.length, sawMessageDelta, sawThoughtDelta },\n })\n if (calls.length === 0) {\n // No tool calls — terminal text answer. Self-ack only when opted in;\n // otherwise leave unsignalled so the implementor's output pipeline\n // owns turn completion (autoAck defaults to false).\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 // Tool calls produced — do NOT ack; the runner will iterate again.\n }\n\n try {\n for await (const chunk of chunks) {\n if (ctx.abortSignal.aborted) return\n const delta = chunk.choices?.[0]?.delta\n if (!delta) continue\n if (typeof delta.content === 'string' && delta.content.length > 0) {\n sawMessageDelta = true\n partialMessageContent += delta.content\n helpers.reportMessage(streamId, delta.content)\n }\n const reasoning = (delta as { reasoning_content?: string | null }).reasoning_content\n if (typeof reasoning === 'string' && reasoning.length > 0) {\n sawThoughtDelta = true\n partialThoughtContent += reasoning\n helpers.reportThought(streamId, reasoning)\n }\n if (Array.isArray(delta.tool_calls)) {\n for (const d of delta.tool_calls) {\n accumulator.feed(d)\n }\n }\n }\n await drainAndPersist()\n } catch (err) {\n if (ctx.abortSignal.aborted) return\n helpers.log.error({\n kind: 'stream-error',\n message: `WebLLM stream failed: ${isError(err) ? err.message : String(err)}`,\n payload: { detail: isError(err) ? err.message : String(err) },\n })\n ctx.nack(\n new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n return\n }\n\n // ── Step 9: non-streaming path ────────────────────────────────────────\n const parsed = completion as ChatCompletionsResponse\n const choice = parsed.choices?.[0]\n if (!choice) {\n // Empty response, no tool calls — terminal. Self-ack only when opted in.\n if (merged.autoAck) ctx.ack()\n return\n }\n const msg = choice.message\n const responseId = parsed.id ?? uuidv6()\n\n if (msg && typeof msg.content === 'string' && msg.content.length > 0) {\n const messageId = `${responseId}:message`\n helpers.reportMessage(messageId, msg.content, { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: messageId,\n role: 'assistant',\n content: msg.content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n const reasoning = (msg as { reasoning_content?: string | null } | undefined)\n ?.reasoning_content\n if (typeof reasoning === 'string' && reasoning.length > 0) {\n const thoughtId = `${responseId}:thought`\n helpers.reportThought(thoughtId, reasoning, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: thoughtId,\n content: reasoning,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n const rawCalls = msg?.tool_calls ?? []\n if (rawCalls.length === 0) {\n // No tool calls — terminal text answer. Self-ack only when opted in;\n // otherwise the implementor's output pipeline owns completion.\n if (merged.autoAck) ctx.ack()\n return\n }\n const calls: AssembledToolCall[] = rawCalls.map((tc) => ({\n id: tc.id,\n type: tc.type ?? 'function',\n name: tc.function?.name ?? '',\n args: tc.function?.arguments ?? '',\n }))\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n // Tool calls produced — do NOT ack; the runner will iterate again.\n }\n }\n\n /**\n * Returns `true` when `value` is an {@link WebLLMChatCompletionsAdapter} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is an `WebLLMChatCompletionsAdapter` instance.\n */\n public static isWebLLMChatCompletionsAdapter(\n value: unknown\n ): value is WebLLMChatCompletionsAdapter {\n return isInstanceOf(value, 'WebLLMChatCompletionsAdapter', WebLLMChatCompletionsAdapter)\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_exceptions = require("../../../exceptions-D5YrO9Vm.js");
3
+ require("../../../factories.cjs");
4
+ //#region src/batteries/llm/webllm_chat_completions/exceptions.ts
5
+ /**
6
+ * Battery-scoped exception constructors for WebLLM Chat Completions adapter failures.
7
+ *
8
+ * @module @nhtio/adk/batteries/llm/webllm_chat_completions/exceptions
9
+ *
10
+ * @remarks
11
+ * Battery-scoped exception classes for the WebLLM Chat Completions adapter. These exceptions
12
+ * are owned by the battery (not the ADK core) and are minted via `createException` from
13
+ * `@nhtio/adk/factories`. Re-exported from the battery's barrel.
14
+ */
15
+ /**
16
+ * Thrown when the resolved adapter options (constructor, executor overrides, or per-dispatch
17
+ * `stash.webLLMChatCompletions`) fail validation against `webLLMChatCompletionsOptionsSchema`.
18
+ */
19
+ var E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS = require_exceptions.createException("E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS", "Invalid WebLLM Chat Completions adapter options: %s", "E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS", 529, true);
20
+ /**
21
+ * Thrown when the total token weight of the resolved request exceeds `contextWindow`. Only
22
+ * raised when `tokenEncoding` is non-null. Carries `{ total, contextWindow, tokenEncoding,
23
+ * perBucket }` in the message so middleware can target shedding.
24
+ */
25
+ var E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW = require_exceptions.createException("E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW", "WebLLM Chat Completions request token weight (%d) exceeds context window (%d) under encoding %s. Per-bucket breakdown: %s", "E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW", 529, true);
26
+ /**
27
+ * Thrown when the WebLLM engine call or async stream fails. Non-fatal — surfaced via
28
+ * `ctx.nack(...)`.
29
+ */
30
+ var E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR = require_exceptions.createException("E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR", "WebLLM Chat Completions stream error: %s", "E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR", 502, false);
31
+ /**
32
+ * Raised when a tool-call's `arguments` string emitted by the model is not a JSON object —
33
+ * either non-parseable JSON, or parseable JSON whose root is not an object (e.g. a bare string,
34
+ * number, array, or `null`).
35
+ *
36
+ * @remarks
37
+ * Non-fatal. The adapter does NOT throw this — it instantiates it inside
38
+ * `executeAndPersistToolCall`, pulls `.message` into a {@link @nhtio/adk!Tokenizable}, and persists a
39
+ * `ToolCall` record with `isError: true`. The model sees the formatted message in the next
40
+ * iteration's history and can self-correct. Consumers introspecting persisted error results
41
+ * can match on the `E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS` code substring.
42
+ *
43
+ * Printf args: `[reasonHeadline, rawArgs]`.
44
+ * - `reasonHeadline` — short reason such as `'are not valid JSON'` or
45
+ * `'must be a JSON object; received array'`.
46
+ * - `rawArgs` — the raw `arguments` string the model emitted, echoed back verbatim so
47
+ * the model can see what it sent.
48
+ */
49
+ var E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS = require_exceptions.createException("E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS", "Tool arguments %s. Raw value: %s", "E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS", 422, false);
50
+ /**
51
+ * Raised when a {@link @nhtio/adk!Media} instance whose modality cannot be natively represented in the
52
+ * WebLLM Chat Completions wire format reaches the adapter under `unsupportedMediaPolicy: 'throw'`.
53
+ *
54
+ * @remarks
55
+ * Today only `kind: 'video'` triggers this — Chat Completions natively supports `image`,
56
+ * `audio`, and `document` content blocks but has no video block. Consumers can opt out of the
57
+ * throw by switching to `'fallback-stash'` or `'synthetic-description'` (see
58
+ * {@link @nhtio/adk/batteries/llm/openai_chat_completions/types!UnsupportedMediaPolicy}).
59
+ *
60
+ * Printf args: `[kind, mimeType, filename]`.
61
+ */
62
+ var E_UNSUPPORTED_MEDIA_MODALITY = require_exceptions.createException("E_UNSUPPORTED_MEDIA_MODALITY", "WebLLM Chat Completions does not natively support media of kind %s (mime=%s, filename=%s). Configure adapter `unsupportedMediaPolicy` to `fallback-stash` or `synthetic-description` to handle this case.", "E_UNSUPPORTED_MEDIA_MODALITY", 422, true);
63
+ //#endregion
64
+ exports.E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS = E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS;
65
+ exports.E_UNSUPPORTED_MEDIA_MODALITY = E_UNSUPPORTED_MEDIA_MODALITY;
66
+ exports.E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW = E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW;
67
+ exports.E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS = E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS;
68
+ exports.E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR = E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR;
69
+
70
+ //# sourceMappingURL=exceptions.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.cjs","names":[],"sources":["../../../../src/batteries/llm/webllm_chat_completions/exceptions.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for WebLLM Chat Completions adapter failures.\n *\n * @module @nhtio/adk/batteries/llm/webllm_chat_completions/exceptions\n *\n * @remarks\n * Battery-scoped exception classes for the WebLLM Chat Completions adapter. These exceptions\n * are owned by the battery (not the ADK core) and are minted via `createException` from\n * `@nhtio/adk/factories`. Re-exported from the battery's barrel.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options (constructor, executor overrides, or per-dispatch\n * `stash.webLLMChatCompletions`) fail validation against `webLLMChatCompletionsOptionsSchema`.\n */\nexport const E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS = createException<[string]>(\n 'E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS',\n 'Invalid WebLLM Chat Completions adapter options: %s',\n 'E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the total token weight of the resolved request exceeds `contextWindow`. Only\n * raised when `tokenEncoding` is non-null. Carries `{ total, contextWindow, tokenEncoding,\n * perBucket }` in the message so middleware can target shedding.\n */\nexport const E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW = createException<\n [number, number, string, string]\n>(\n 'E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW',\n 'WebLLM Chat Completions request token weight (%d) exceeds context window (%d) under encoding %s. Per-bucket breakdown: %s',\n 'E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW',\n 529,\n true\n)\n\n/**\n * Thrown when the WebLLM engine call or async stream fails. Non-fatal — surfaced via\n * `ctx.nack(...)`.\n */\nexport const E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR = createException<[string]>(\n 'E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR',\n 'WebLLM Chat Completions stream error: %s',\n 'E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR',\n 502,\n false\n)\n\n/**\n * Raised when a tool-call's `arguments` string emitted by the model is not a JSON object —\n * either non-parseable JSON, or parseable JSON whose root is not an object (e.g. a bare string,\n * number, array, or `null`).\n *\n * @remarks\n * Non-fatal. The adapter does NOT throw this — it instantiates it inside\n * `executeAndPersistToolCall`, pulls `.message` into a {@link @nhtio/adk!Tokenizable}, and persists a\n * `ToolCall` record with `isError: true`. The model sees the formatted message in the next\n * iteration's history and can self-correct. Consumers introspecting persisted error results\n * can match on the `E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS` code substring.\n *\n * Printf args: `[reasonHeadline, rawArgs]`.\n * - `reasonHeadline` — short reason such as `'are not valid JSON'` or\n * `'must be a JSON object; received array'`.\n * - `rawArgs` — the raw `arguments` string the model emitted, echoed back verbatim so\n * the model can see what it sent.\n */\nexport const E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS = createException<[string, string]>(\n 'E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS',\n 'Tool arguments %s. Raw value: %s',\n 'E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS',\n 422,\n false\n)\n\n/**\n * Raised when a {@link @nhtio/adk!Media} instance whose modality cannot be natively represented in the\n * WebLLM Chat Completions wire format reaches the adapter under `unsupportedMediaPolicy: 'throw'`.\n *\n * @remarks\n * Today only `kind: 'video'` triggers this — Chat Completions natively supports `image`,\n * `audio`, and `document` content blocks but has no video block. Consumers can opt out of the\n * throw by switching to `'fallback-stash'` or `'synthetic-description'` (see\n * {@link @nhtio/adk/batteries/llm/openai_chat_completions/types!UnsupportedMediaPolicy}).\n *\n * Printf args: `[kind, mimeType, filename]`.\n */\nexport const E_UNSUPPORTED_MEDIA_MODALITY = createException<[string, string, string]>(\n 'E_UNSUPPORTED_MEDIA_MODALITY',\n 'WebLLM Chat Completions does not natively support media of kind %s (mime=%s, filename=%s). Configure adapter `unsupportedMediaPolicy` to `fallback-stash` or `synthetic-description` to handle this case.',\n 'E_UNSUPPORTED_MEDIA_MODALITY',\n 422,\n true\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,IAAa,4CAA4C,mBAAA,gBACvD,6CACA,uDACA,6CACA,KACA,IACF;;;;;;AAOA,IAAa,6CAA6C,mBAAA,gBAGxD,8CACA,6HACA,8CACA,KACA,IACF;;;;;AAMA,IAAa,yCAAyC,mBAAA,gBACpD,0CACA,4CACA,0CACA,KACA,KACF;;;;;;;;;;;;;;;;;;;AAoBA,IAAa,mDAAmD,mBAAA,gBAC9D,oDACA,oCACA,oDACA,KACA,KACF;;;;;;;;;;;;;AAcA,IAAa,+BAA+B,mBAAA,gBAC1C,gCACA,6MACA,gCACA,KACA,IACF"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Battery-scoped exception constructors for WebLLM Chat Completions adapter failures.
3
+ *
4
+ * @module @nhtio/adk/batteries/llm/webllm_chat_completions/exceptions
5
+ *
6
+ * @remarks
7
+ * Battery-scoped exception classes for the WebLLM Chat Completions adapter. These exceptions
8
+ * are owned by the battery (not the ADK core) and are minted via `createException` from
9
+ * `@nhtio/adk/factories`. Re-exported from the battery's barrel.
10
+ */
11
+ /**
12
+ * Thrown when the resolved adapter options (constructor, executor overrides, or per-dispatch
13
+ * `stash.webLLMChatCompletions`) fail validation against `webLLMChatCompletionsOptionsSchema`.
14
+ */
15
+ export declare const E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS: import("../../../factories").CreatedException<[
16
+ string
17
+ ]>;
18
+ /**
19
+ * Thrown when the total token weight of the resolved request exceeds `contextWindow`. Only
20
+ * raised when `tokenEncoding` is non-null. Carries `{ total, contextWindow, tokenEncoding,
21
+ * perBucket }` in the message so middleware can target shedding.
22
+ */
23
+ export declare const E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW: import("../../../factories").CreatedException<[
24
+ number,
25
+ number,
26
+ string,
27
+ string
28
+ ]>;
29
+ /**
30
+ * Thrown when the WebLLM engine call or async stream fails. Non-fatal — surfaced via
31
+ * `ctx.nack(...)`.
32
+ */
33
+ export declare const E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR: import("../../../factories").CreatedException<[
34
+ string
35
+ ]>;
36
+ /**
37
+ * Raised when a tool-call's `arguments` string emitted by the model is not a JSON object —
38
+ * either non-parseable JSON, or parseable JSON whose root is not an object (e.g. a bare string,
39
+ * number, array, or `null`).
40
+ *
41
+ * @remarks
42
+ * Non-fatal. The adapter does NOT throw this — it instantiates it inside
43
+ * `executeAndPersistToolCall`, pulls `.message` into a {@link @nhtio/adk!Tokenizable}, and persists a
44
+ * `ToolCall` record with `isError: true`. The model sees the formatted message in the next
45
+ * iteration's history and can self-correct. Consumers introspecting persisted error results
46
+ * can match on the `E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS` code substring.
47
+ *
48
+ * Printf args: `[reasonHeadline, rawArgs]`.
49
+ * - `reasonHeadline` — short reason such as `'are not valid JSON'` or
50
+ * `'must be a JSON object; received array'`.
51
+ * - `rawArgs` — the raw `arguments` string the model emitted, echoed back verbatim so
52
+ * the model can see what it sent.
53
+ */
54
+ export declare const E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS: import("../../../factories").CreatedException<[
55
+ string,
56
+ string
57
+ ]>;
58
+ /**
59
+ * Raised when a {@link @nhtio/adk!Media} instance whose modality cannot be natively represented in the
60
+ * WebLLM Chat Completions wire format reaches the adapter under `unsupportedMediaPolicy: 'throw'`.
61
+ *
62
+ * @remarks
63
+ * Today only `kind: 'video'` triggers this — Chat Completions natively supports `image`,
64
+ * `audio`, and `document` content blocks but has no video block. Consumers can opt out of the
65
+ * throw by switching to `'fallback-stash'` or `'synthetic-description'` (see
66
+ * {@link @nhtio/adk/batteries/llm/openai_chat_completions/types!UnsupportedMediaPolicy}).
67
+ *
68
+ * Printf args: `[kind, mimeType, filename]`.
69
+ */
70
+ export declare const E_UNSUPPORTED_MEDIA_MODALITY: import("../../../factories").CreatedException<[
71
+ string,
72
+ string,
73
+ string
74
+ ]>;
@@ -0,0 +1,65 @@
1
+ import { t as createException } from "../../../exceptions-NrzIHw_R.mjs";
2
+ import "../../../factories.mjs";
3
+ //#region src/batteries/llm/webllm_chat_completions/exceptions.ts
4
+ /**
5
+ * Battery-scoped exception constructors for WebLLM Chat Completions adapter failures.
6
+ *
7
+ * @module @nhtio/adk/batteries/llm/webllm_chat_completions/exceptions
8
+ *
9
+ * @remarks
10
+ * Battery-scoped exception classes for the WebLLM Chat Completions adapter. These exceptions
11
+ * are owned by the battery (not the ADK core) and are minted via `createException` from
12
+ * `@nhtio/adk/factories`. Re-exported from the battery's barrel.
13
+ */
14
+ /**
15
+ * Thrown when the resolved adapter options (constructor, executor overrides, or per-dispatch
16
+ * `stash.webLLMChatCompletions`) fail validation against `webLLMChatCompletionsOptionsSchema`.
17
+ */
18
+ var E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS = createException("E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS", "Invalid WebLLM Chat Completions adapter options: %s", "E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS", 529, true);
19
+ /**
20
+ * Thrown when the total token weight of the resolved request exceeds `contextWindow`. Only
21
+ * raised when `tokenEncoding` is non-null. Carries `{ total, contextWindow, tokenEncoding,
22
+ * perBucket }` in the message so middleware can target shedding.
23
+ */
24
+ var E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW = createException("E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW", "WebLLM Chat Completions request token weight (%d) exceeds context window (%d) under encoding %s. Per-bucket breakdown: %s", "E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW", 529, true);
25
+ /**
26
+ * Thrown when the WebLLM engine call or async stream fails. Non-fatal — surfaced via
27
+ * `ctx.nack(...)`.
28
+ */
29
+ var E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR = createException("E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR", "WebLLM Chat Completions stream error: %s", "E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR", 502, false);
30
+ /**
31
+ * Raised when a tool-call's `arguments` string emitted by the model is not a JSON object —
32
+ * either non-parseable JSON, or parseable JSON whose root is not an object (e.g. a bare string,
33
+ * number, array, or `null`).
34
+ *
35
+ * @remarks
36
+ * Non-fatal. The adapter does NOT throw this — it instantiates it inside
37
+ * `executeAndPersistToolCall`, pulls `.message` into a {@link @nhtio/adk!Tokenizable}, and persists a
38
+ * `ToolCall` record with `isError: true`. The model sees the formatted message in the next
39
+ * iteration's history and can self-correct. Consumers introspecting persisted error results
40
+ * can match on the `E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS` code substring.
41
+ *
42
+ * Printf args: `[reasonHeadline, rawArgs]`.
43
+ * - `reasonHeadline` — short reason such as `'are not valid JSON'` or
44
+ * `'must be a JSON object; received array'`.
45
+ * - `rawArgs` — the raw `arguments` string the model emitted, echoed back verbatim so
46
+ * the model can see what it sent.
47
+ */
48
+ var E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS = createException("E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS", "Tool arguments %s. Raw value: %s", "E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS", 422, false);
49
+ /**
50
+ * Raised when a {@link @nhtio/adk!Media} instance whose modality cannot be natively represented in the
51
+ * WebLLM Chat Completions wire format reaches the adapter under `unsupportedMediaPolicy: 'throw'`.
52
+ *
53
+ * @remarks
54
+ * Today only `kind: 'video'` triggers this — Chat Completions natively supports `image`,
55
+ * `audio`, and `document` content blocks but has no video block. Consumers can opt out of the
56
+ * throw by switching to `'fallback-stash'` or `'synthetic-description'` (see
57
+ * {@link @nhtio/adk/batteries/llm/openai_chat_completions/types!UnsupportedMediaPolicy}).
58
+ *
59
+ * Printf args: `[kind, mimeType, filename]`.
60
+ */
61
+ var E_UNSUPPORTED_MEDIA_MODALITY = createException("E_UNSUPPORTED_MEDIA_MODALITY", "WebLLM Chat Completions does not natively support media of kind %s (mime=%s, filename=%s). Configure adapter `unsupportedMediaPolicy` to `fallback-stash` or `synthetic-description` to handle this case.", "E_UNSUPPORTED_MEDIA_MODALITY", 422, true);
62
+ //#endregion
63
+ export { E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS, E_UNSUPPORTED_MEDIA_MODALITY, E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW, E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS, E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR };
64
+
65
+ //# sourceMappingURL=exceptions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.mjs","names":[],"sources":["../../../../src/batteries/llm/webllm_chat_completions/exceptions.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for WebLLM Chat Completions adapter failures.\n *\n * @module @nhtio/adk/batteries/llm/webllm_chat_completions/exceptions\n *\n * @remarks\n * Battery-scoped exception classes for the WebLLM Chat Completions adapter. These exceptions\n * are owned by the battery (not the ADK core) and are minted via `createException` from\n * `@nhtio/adk/factories`. Re-exported from the battery's barrel.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options (constructor, executor overrides, or per-dispatch\n * `stash.webLLMChatCompletions`) fail validation against `webLLMChatCompletionsOptionsSchema`.\n */\nexport const E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS = createException<[string]>(\n 'E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS',\n 'Invalid WebLLM Chat Completions adapter options: %s',\n 'E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the total token weight of the resolved request exceeds `contextWindow`. Only\n * raised when `tokenEncoding` is non-null. Carries `{ total, contextWindow, tokenEncoding,\n * perBucket }` in the message so middleware can target shedding.\n */\nexport const E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW = createException<\n [number, number, string, string]\n>(\n 'E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW',\n 'WebLLM Chat Completions request token weight (%d) exceeds context window (%d) under encoding %s. Per-bucket breakdown: %s',\n 'E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW',\n 529,\n true\n)\n\n/**\n * Thrown when the WebLLM engine call or async stream fails. Non-fatal — surfaced via\n * `ctx.nack(...)`.\n */\nexport const E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR = createException<[string]>(\n 'E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR',\n 'WebLLM Chat Completions stream error: %s',\n 'E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR',\n 502,\n false\n)\n\n/**\n * Raised when a tool-call's `arguments` string emitted by the model is not a JSON object —\n * either non-parseable JSON, or parseable JSON whose root is not an object (e.g. a bare string,\n * number, array, or `null`).\n *\n * @remarks\n * Non-fatal. The adapter does NOT throw this — it instantiates it inside\n * `executeAndPersistToolCall`, pulls `.message` into a {@link @nhtio/adk!Tokenizable}, and persists a\n * `ToolCall` record with `isError: true`. The model sees the formatted message in the next\n * iteration's history and can self-correct. Consumers introspecting persisted error results\n * can match on the `E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS` code substring.\n *\n * Printf args: `[reasonHeadline, rawArgs]`.\n * - `reasonHeadline` — short reason such as `'are not valid JSON'` or\n * `'must be a JSON object; received array'`.\n * - `rawArgs` — the raw `arguments` string the model emitted, echoed back verbatim so\n * the model can see what it sent.\n */\nexport const E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS = createException<[string, string]>(\n 'E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS',\n 'Tool arguments %s. Raw value: %s',\n 'E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS',\n 422,\n false\n)\n\n/**\n * Raised when a {@link @nhtio/adk!Media} instance whose modality cannot be natively represented in the\n * WebLLM Chat Completions wire format reaches the adapter under `unsupportedMediaPolicy: 'throw'`.\n *\n * @remarks\n * Today only `kind: 'video'` triggers this — Chat Completions natively supports `image`,\n * `audio`, and `document` content blocks but has no video block. Consumers can opt out of the\n * throw by switching to `'fallback-stash'` or `'synthetic-description'` (see\n * {@link @nhtio/adk/batteries/llm/openai_chat_completions/types!UnsupportedMediaPolicy}).\n *\n * Printf args: `[kind, mimeType, filename]`.\n */\nexport const E_UNSUPPORTED_MEDIA_MODALITY = createException<[string, string, string]>(\n 'E_UNSUPPORTED_MEDIA_MODALITY',\n 'WebLLM Chat Completions does not natively support media of kind %s (mime=%s, filename=%s). Configure adapter `unsupportedMediaPolicy` to `fallback-stash` or `synthetic-description` to handle this case.',\n 'E_UNSUPPORTED_MEDIA_MODALITY',\n 422,\n true\n)\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAa,4CAA4C,gBACvD,6CACA,uDACA,6CACA,KACA,IACF;;;;;;AAOA,IAAa,6CAA6C,gBAGxD,8CACA,6HACA,8CACA,KACA,IACF;;;;;AAMA,IAAa,yCAAyC,gBACpD,0CACA,4CACA,0CACA,KACA,KACF;;;;;;;;;;;;;;;;;;;AAoBA,IAAa,mDAAmD,gBAC9D,oDACA,oCACA,oDACA,KACA,KACF;;;;;;;;;;;;;AAcA,IAAa,+BAA+B,gBAC1C,gCACA,6MACA,gCACA,KACA,IACF"}
@@ -0,0 +1,38 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_batteries_llm_openai_chat_completions_helpers = require("../openai_chat_completions/helpers.cjs");
3
+ exports.buildChatCompletionsHistory = require_batteries_llm_openai_chat_completions_helpers.buildChatCompletionsHistory;
4
+ exports.createChatCompletionsToolCallDeltaAccumulator = require_batteries_llm_openai_chat_completions_helpers.createChatCompletionsToolCallDeltaAccumulator;
5
+ exports.defaultBuildChatCompletionsHistory = require_batteries_llm_openai_chat_completions_helpers.defaultBuildChatCompletionsHistory;
6
+ exports.defaultCreateChatCompletionsToolCallDeltaAccumulator = require_batteries_llm_openai_chat_completions_helpers.defaultCreateChatCompletionsToolCallDeltaAccumulator;
7
+ exports.defaultDescriptionToChatCompletionsJsonSchema = require_batteries_llm_openai_chat_completions_helpers.defaultDescriptionToChatCompletionsJsonSchema;
8
+ exports.defaultFilterThoughts = require_batteries_llm_openai_chat_completions_helpers.defaultFilterThoughts;
9
+ exports.defaultRenderChatCompletionsSystemPrompt = require_batteries_llm_openai_chat_completions_helpers.defaultRenderChatCompletionsSystemPrompt;
10
+ exports.defaultRenderChatCompletionsToolCallResult = require_batteries_llm_openai_chat_completions_helpers.defaultRenderChatCompletionsToolCallResult;
11
+ exports.defaultRenderFirstPartyRetrievables = require_batteries_llm_openai_chat_completions_helpers.defaultRenderFirstPartyRetrievables;
12
+ exports.defaultRenderMemories = require_batteries_llm_openai_chat_completions_helpers.defaultRenderMemories;
13
+ exports.defaultRenderRetrievableSafetyDirective = require_batteries_llm_openai_chat_completions_helpers.defaultRenderRetrievableSafetyDirective;
14
+ exports.defaultRenderRetrievables = require_batteries_llm_openai_chat_completions_helpers.defaultRenderRetrievables;
15
+ exports.defaultRenderStandingInstructions = require_batteries_llm_openai_chat_completions_helpers.defaultRenderStandingInstructions;
16
+ exports.defaultRenderThirdPartyPrivateRetrievables = require_batteries_llm_openai_chat_completions_helpers.defaultRenderThirdPartyPrivateRetrievables;
17
+ exports.defaultRenderThirdPartyPublicRetrievables = require_batteries_llm_openai_chat_completions_helpers.defaultRenderThirdPartyPublicRetrievables;
18
+ exports.defaultRenderThought = require_batteries_llm_openai_chat_completions_helpers.defaultRenderThought;
19
+ exports.defaultRenderTimelineMessage = require_batteries_llm_openai_chat_completions_helpers.defaultRenderTimelineMessage;
20
+ exports.defaultRenderTrustedContent = require_batteries_llm_openai_chat_completions_helpers.defaultRenderTrustedContent;
21
+ exports.defaultRenderUntrustedContent = require_batteries_llm_openai_chat_completions_helpers.defaultRenderUntrustedContent;
22
+ exports.defaultToolsToChatCompletionsTools = require_batteries_llm_openai_chat_completions_helpers.defaultToolsToChatCompletionsTools;
23
+ exports.descriptionToChatCompletionsJsonSchema = require_batteries_llm_openai_chat_completions_helpers.descriptionToChatCompletionsJsonSchema;
24
+ exports.filterThoughts = require_batteries_llm_openai_chat_completions_helpers.filterThoughts;
25
+ exports.renderChatCompletionsSystemPrompt = require_batteries_llm_openai_chat_completions_helpers.renderChatCompletionsSystemPrompt;
26
+ exports.renderChatCompletionsToolCallResult = require_batteries_llm_openai_chat_completions_helpers.renderChatCompletionsToolCallResult;
27
+ exports.renderFirstPartyRetrievables = require_batteries_llm_openai_chat_completions_helpers.renderFirstPartyRetrievables;
28
+ exports.renderMemories = require_batteries_llm_openai_chat_completions_helpers.renderMemories;
29
+ exports.renderRetrievableSafetyDirective = require_batteries_llm_openai_chat_completions_helpers.renderRetrievableSafetyDirective;
30
+ exports.renderRetrievables = require_batteries_llm_openai_chat_completions_helpers.renderRetrievables;
31
+ exports.renderStandingInstructions = require_batteries_llm_openai_chat_completions_helpers.renderStandingInstructions;
32
+ exports.renderThirdPartyPrivateRetrievables = require_batteries_llm_openai_chat_completions_helpers.renderThirdPartyPrivateRetrievables;
33
+ exports.renderThirdPartyPublicRetrievables = require_batteries_llm_openai_chat_completions_helpers.renderThirdPartyPublicRetrievables;
34
+ exports.renderThought = require_batteries_llm_openai_chat_completions_helpers.renderThought;
35
+ exports.renderTimelineMessage = require_batteries_llm_openai_chat_completions_helpers.renderTimelineMessage;
36
+ exports.renderTrustedContent = require_batteries_llm_openai_chat_completions_helpers.renderTrustedContent;
37
+ exports.renderUntrustedContent = require_batteries_llm_openai_chat_completions_helpers.renderUntrustedContent;
38
+ exports.toolsToChatCompletionsTools = require_batteries_llm_openai_chat_completions_helpers.toolsToChatCompletionsTools;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Swappable translation helpers for rendering ADK state into WebLLM Chat Completions requests.
3
+ *
4
+ * @module @nhtio/adk/batteries/llm/webllm_chat_completions/helpers
5
+ */
6
+ export { descriptionToChatCompletionsJsonSchema, defaultDescriptionToChatCompletionsJsonSchema, renderUntrustedContent, defaultRenderUntrustedContent, renderTrustedContent, defaultRenderTrustedContent, renderStandingInstructions, defaultRenderStandingInstructions, renderMemories, defaultRenderMemories, renderRetrievables, defaultRenderRetrievables, renderRetrievableSafetyDirective, defaultRenderRetrievableSafetyDirective, renderFirstPartyRetrievables, defaultRenderFirstPartyRetrievables, renderThirdPartyPublicRetrievables, defaultRenderThirdPartyPublicRetrievables, renderThirdPartyPrivateRetrievables, defaultRenderThirdPartyPrivateRetrievables, renderTimelineMessage, defaultRenderTimelineMessage, renderThought, defaultRenderThought, filterThoughts, defaultFilterThoughts, toolsToChatCompletionsTools, defaultToolsToChatCompletionsTools, renderChatCompletionsSystemPrompt, defaultRenderChatCompletionsSystemPrompt, renderChatCompletionsToolCallResult, defaultRenderChatCompletionsToolCallResult, buildChatCompletionsHistory, defaultBuildChatCompletionsHistory, createChatCompletionsToolCallDeltaAccumulator, defaultCreateChatCompletionsToolCallDeltaAccumulator, } from "../openai_chat_completions/helpers";
@@ -0,0 +1,2 @@
1
+ import { buildChatCompletionsHistory, createChatCompletionsToolCallDeltaAccumulator, defaultBuildChatCompletionsHistory, defaultCreateChatCompletionsToolCallDeltaAccumulator, defaultDescriptionToChatCompletionsJsonSchema, defaultFilterThoughts, defaultRenderChatCompletionsSystemPrompt, defaultRenderChatCompletionsToolCallResult, defaultRenderFirstPartyRetrievables, defaultRenderMemories, defaultRenderRetrievableSafetyDirective, defaultRenderRetrievables, defaultRenderStandingInstructions, defaultRenderThirdPartyPrivateRetrievables, defaultRenderThirdPartyPublicRetrievables, defaultRenderThought, defaultRenderTimelineMessage, defaultRenderTrustedContent, defaultRenderUntrustedContent, defaultToolsToChatCompletionsTools, descriptionToChatCompletionsJsonSchema, filterThoughts, renderChatCompletionsSystemPrompt, renderChatCompletionsToolCallResult, renderFirstPartyRetrievables, renderMemories, renderRetrievableSafetyDirective, renderRetrievables, renderStandingInstructions, renderThirdPartyPrivateRetrievables, renderThirdPartyPublicRetrievables, renderThought, renderTimelineMessage, renderTrustedContent, renderUntrustedContent, toolsToChatCompletionsTools } from "../openai_chat_completions/helpers.mjs";
2
+ export { buildChatCompletionsHistory, createChatCompletionsToolCallDeltaAccumulator, defaultBuildChatCompletionsHistory, defaultCreateChatCompletionsToolCallDeltaAccumulator, defaultDescriptionToChatCompletionsJsonSchema, defaultFilterThoughts, defaultRenderChatCompletionsSystemPrompt, defaultRenderChatCompletionsToolCallResult, defaultRenderFirstPartyRetrievables, defaultRenderMemories, defaultRenderRetrievableSafetyDirective, defaultRenderRetrievables, defaultRenderStandingInstructions, defaultRenderThirdPartyPrivateRetrievables, defaultRenderThirdPartyPublicRetrievables, defaultRenderThought, defaultRenderTimelineMessage, defaultRenderTrustedContent, defaultRenderUntrustedContent, defaultToolsToChatCompletionsTools, descriptionToChatCompletionsJsonSchema, filterThoughts, renderChatCompletionsSystemPrompt, renderChatCompletionsToolCallResult, renderFirstPartyRetrievables, renderMemories, renderRetrievableSafetyDirective, renderRetrievables, renderStandingInstructions, renderThirdPartyPrivateRetrievables, renderThirdPartyPublicRetrievables, renderThought, renderTimelineMessage, renderTrustedContent, renderUntrustedContent, toolsToChatCompletionsTools };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * WebLLM Chat Completions adapter battery with swappable translation helpers and wire types.
3
+ *
4
+ * @module @nhtio/adk/batteries/llm/webllm_chat_completions
5
+ *
6
+ * @remarks
7
+ * Opinionated WebLLM Chat Completions LLM battery. Ships a `WebLLMChatCompletionsAdapter` that
8
+ * targets WebLLM's in-process OpenAI-style Chat Completions API and translates the ADK's
9
+ * primitives into that wire shape.
10
+ *
11
+ * Re-exports the adapter class, every translation helper (each under its unprefixed name AND a
12
+ * `default*`-prefixed alias so consumers can compose partial overrides against the bundled
13
+ * defaults), every option / wire-shape type alias, the validation schema + `validateOptions`
14
+ * wrapper, and the six battery-scoped exception classes.
15
+ *
16
+ * See the project README for the design-decisions block governing this battery (trust-framed
17
+ * envelopes, per-tool trust, swappable translation helpers, per-dispatch override channel via
18
+ * `stash`, trust-tier-distinct envelopes, multi-identity rendering, opaque-reasoning
19
+ * round-trips, etc.).
20
+ */
21
+ export { WebLLMChatCompletionsAdapter } from "./adapter";
22
+ export { descriptionToChatCompletionsJsonSchema, defaultDescriptionToChatCompletionsJsonSchema, renderUntrustedContent, defaultRenderUntrustedContent, renderTrustedContent, defaultRenderTrustedContent, renderStandingInstructions, defaultRenderStandingInstructions, renderMemories, defaultRenderMemories, renderRetrievables, defaultRenderRetrievables, renderRetrievableSafetyDirective, defaultRenderRetrievableSafetyDirective, renderFirstPartyRetrievables, defaultRenderFirstPartyRetrievables, renderThirdPartyPublicRetrievables, defaultRenderThirdPartyPublicRetrievables, renderThirdPartyPrivateRetrievables, defaultRenderThirdPartyPrivateRetrievables, renderTimelineMessage, defaultRenderTimelineMessage, renderThought, defaultRenderThought, filterThoughts, defaultFilterThoughts, toolsToChatCompletionsTools, defaultToolsToChatCompletionsTools, renderChatCompletionsSystemPrompt, defaultRenderChatCompletionsSystemPrompt, renderChatCompletionsToolCallResult, defaultRenderChatCompletionsToolCallResult, buildChatCompletionsHistory, defaultBuildChatCompletionsHistory, createChatCompletionsToolCallDeltaAccumulator, defaultCreateChatCompletionsToolCallDeltaAccumulator, } from "./helpers";
23
+ export type { JsonSchema, ChatCompletionsTool, ChatCompletionsMessage, ChatCompletionsToolCallDelta, ChatCompletionsChunk, ChatCompletionsResponse, AssembledToolCall, ChatCompletionsToolCallDeltaAccumulator, ChatCompletionsBucketLabel, ChatCompletionsBucketOrder, UntrustedContentAttrs, TrustedContentAttrs, StandingInstructionAttrs, MemoryAttrs, RetrievableAttrs, ThoughtAttrs, WebLLMEngine, WebLLMChatCompletionsEngine, CreateWebLLMChatCompletionsEngine, WebLLMInitProgressReport, WebLLMChatCompletionsAdapterOptions, WebLLMChatCompletionsRequestBody, DescriptionLike, ChatCompletionsHelpers, } from "./types";
24
+ export { webLLMChatCompletionsOptionsSchema, validateOptions } from "./validation";
25
+ export { E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS, E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW, E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR, E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS, E_UNSUPPORTED_MEDIA_MODALITY, } from "./exceptions";
@@ -0,0 +1,31 @@
1
+ import type { ChatOptions, InitProgressReport, MLCEngineConfig, MLCEngineInterface } from '@mlc-ai/web-llm';
2
+ import type { OpenAIChatCompletionsAdapterOptions, OpenAIChatCompletionsRequestBody } from "../openai_chat_completions/types";
3
+ export type { JsonSchema, ChatCompletionsTool, ChatCompletionsMessage, ChatCompletionsToolCallDelta, ChatCompletionsChunk, ChatCompletionsResponse, AssembledToolCall, ChatCompletionsToolCallDeltaAccumulator, ChatCompletionsBucketLabel, ChatCompletionsBucketOrder, UntrustedContentAttrs, TrustedContentAttrs, StandingInstructionAttrs, MemoryAttrs, RetrievableAttrs, ThoughtAttrs, OpenAIChatCompletionsAdapterOptions, OpenAIChatCompletionsRequestBody, DescriptionLike, ChatCompletionsHelpers, UnsupportedMediaPolicy, ChatCompletionsContentBlock, } from "../openai_chat_completions/types";
4
+ export type WebLLMChatCompletionsRequestBody = Omit<OpenAIChatCompletionsRequestBody, 'model'> & {
5
+ model?: string;
6
+ };
7
+ export type WebLLMEngine = MLCEngineInterface;
8
+ export type WebLLMChatCompletionsEngine = WebLLMEngine;
9
+ export type WebLLMInitProgressReport = InitProgressReport;
10
+ export type CreateWebLLMChatCompletionsEngine = (input: {
11
+ model: string;
12
+ engineConfig?: MLCEngineConfig;
13
+ chatOptions?: ChatOptions | ChatOptions[];
14
+ onInitProgress?: (report: InitProgressReport) => void;
15
+ }) => Promise<WebLLMEngine>;
16
+ export interface WebLLMChatCompletionsAdapterOptions extends Omit<OpenAIChatCompletionsAdapterOptions, 'apiKey' | 'baseURL' | 'headers' | 'fetch' | 'retry' | 'requestTimeoutMs'> {
17
+ repetition_penalty?: number;
18
+ ignore_eos?: boolean;
19
+ extra_body?: Record<string, unknown>;
20
+ engine?: WebLLMEngine;
21
+ engineConfig?: MLCEngineConfig;
22
+ chatOptions?: ChatOptions | ChatOptions[];
23
+ createEngine?: (input: {
24
+ model: string;
25
+ engineConfig?: MLCEngineConfig;
26
+ chatOptions?: ChatOptions | ChatOptions[];
27
+ onInitProgress?: (report: InitProgressReport) => void;
28
+ }) => Promise<WebLLMEngine>;
29
+ onInitProgress?: (report: InitProgressReport) => void;
30
+ isWebGPUAvailable?: () => boolean;
31
+ }
@@ -0,0 +1,115 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../chunk-KmRHZBOW.js");
3
+ require("../../../guards.cjs");
4
+ const require_batteries_llm_webllm_chat_completions_exceptions = require("./exceptions.cjs");
5
+ let _nhtio_validation = require("@nhtio/validation");
6
+ //#region src/batteries/llm/webllm_chat_completions/validation.ts
7
+ var bucketLabelSchema = _nhtio_validation.validator.string().valid("standingInstructions", "memories", "retrievables", "timeline");
8
+ var bucketOrderSchema = _nhtio_validation.validator.array().items(bucketLabelSchema).unique().default([
9
+ "standingInstructions",
10
+ "memories",
11
+ "retrievables",
12
+ "timeline"
13
+ ]);
14
+ var tokenEncodingSchema = _nhtio_validation.validator.alternatives(_nhtio_validation.validator.string().valid("gpt2", "r50k_base", "p50k_base", "p50k_edit", "cl100k_base", "o200k_base", "gemini", "llama2", "claude"), _nhtio_validation.validator.any().valid(null)).default(null);
15
+ var helperSchema = _nhtio_validation.validator.function();
16
+ var helpersSchema = _nhtio_validation.validator.object({
17
+ descriptionToChatCompletionsJsonSchema: helperSchema.optional(),
18
+ renderUntrustedContent: helperSchema.optional(),
19
+ renderTrustedContent: helperSchema.optional(),
20
+ renderStandingInstructions: helperSchema.optional(),
21
+ renderMemories: helperSchema.optional(),
22
+ renderRetrievables: helperSchema.optional(),
23
+ renderRetrievableSafetyDirective: helperSchema.optional(),
24
+ renderFirstPartyRetrievables: helperSchema.optional(),
25
+ renderThirdPartyPublicRetrievables: helperSchema.optional(),
26
+ renderThirdPartyPrivateRetrievables: helperSchema.optional(),
27
+ renderTimelineMessage: helperSchema.optional(),
28
+ renderThought: helperSchema.optional(),
29
+ filterThoughts: helperSchema.optional(),
30
+ toolsToChatCompletionsTools: helperSchema.optional(),
31
+ renderChatCompletionsSystemPrompt: helperSchema.optional(),
32
+ renderChatCompletionsToolCallResult: helperSchema.optional(),
33
+ buildChatCompletionsHistory: helperSchema.optional(),
34
+ createChatCompletionsToolCallDeltaAccumulator: helperSchema.optional()
35
+ }).unknown(false);
36
+ var jsonSchemaSchema = _nhtio_validation.validator.object().unknown(true);
37
+ var responseFormatSchema = _nhtio_validation.validator.alternatives(_nhtio_validation.validator.object({ type: _nhtio_validation.validator.string().valid("text").required() }).unknown(false), _nhtio_validation.validator.object({ type: _nhtio_validation.validator.string().valid("json_object").required() }).unknown(false), _nhtio_validation.validator.object({
38
+ type: _nhtio_validation.validator.string().valid("json_schema").required(),
39
+ json_schema: _nhtio_validation.validator.object({
40
+ name: _nhtio_validation.validator.string().required(),
41
+ schema: jsonSchemaSchema.required(),
42
+ strict: _nhtio_validation.validator.boolean().optional(),
43
+ description: _nhtio_validation.validator.string().optional()
44
+ }).unknown(false).required()
45
+ }).unknown(false));
46
+ var toolChoiceItemSchema = _nhtio_validation.validator.alternatives(_nhtio_validation.validator.object({
47
+ type: _nhtio_validation.validator.string().valid("function").required(),
48
+ function: _nhtio_validation.validator.object({ name: _nhtio_validation.validator.string().required() }).unknown(false).required()
49
+ }).unknown(false), _nhtio_validation.validator.object({
50
+ type: _nhtio_validation.validator.string().valid("custom").required(),
51
+ custom: _nhtio_validation.validator.object({ name: _nhtio_validation.validator.string().required() }).unknown(false).required()
52
+ }).unknown(false));
53
+ var toolChoiceSchema = _nhtio_validation.validator.alternatives(_nhtio_validation.validator.string().valid("none", "auto", "required"), toolChoiceItemSchema, _nhtio_validation.validator.object({
54
+ type: _nhtio_validation.validator.string().valid("allowed_tools").required(),
55
+ allowed_tools: _nhtio_validation.validator.object({
56
+ mode: _nhtio_validation.validator.string().valid("auto", "required").required(),
57
+ tools: _nhtio_validation.validator.array().items(toolChoiceItemSchema).required()
58
+ }).unknown(false).required()
59
+ }).unknown(false));
60
+ var webLLMChatCompletionsOptionsSchema = _nhtio_validation.validator.object({
61
+ engine: _nhtio_validation.validator.object().unknown(true).optional(),
62
+ createEngine: _nhtio_validation.validator.function().optional(),
63
+ onInitProgress: _nhtio_validation.validator.function().optional(),
64
+ isWebGPUAvailable: _nhtio_validation.validator.function().optional(),
65
+ engineConfig: _nhtio_validation.validator.object().unknown(true).optional(),
66
+ chatOptions: _nhtio_validation.validator.alternatives(_nhtio_validation.validator.object().unknown(true), _nhtio_validation.validator.array().items(_nhtio_validation.validator.object().unknown(true))).optional(),
67
+ stream: _nhtio_validation.validator.boolean().default(true),
68
+ bucketOrder: bucketOrderSchema,
69
+ contextWindow: _nhtio_validation.validator.number().integer().min(1).optional(),
70
+ selfIdentity: _nhtio_validation.validator.string().min(1).default("assistant"),
71
+ thoughtSurfacing: _nhtio_validation.validator.string().valid("all-self", "latest-self", "all").default("all-self"),
72
+ tokenEncoding: tokenEncodingSchema,
73
+ replayCompatibility: _nhtio_validation.validator.array().items(_nhtio_validation.validator.string().min(1)).default([]),
74
+ helpers: helpersSchema.optional(),
75
+ strictToolChoice: _nhtio_validation.validator.boolean().default(false),
76
+ autoAck: _nhtio_validation.validator.boolean().default(false),
77
+ unsupportedMediaPolicy: _nhtio_validation.validator.alternatives(_nhtio_validation.validator.string().valid("throw", "fallback-stash", "synthetic-description"), _nhtio_validation.validator.object({
78
+ mode: _nhtio_validation.validator.string().valid("fallback-stash").required(),
79
+ stashKeys: _nhtio_validation.validator.array().items(_nhtio_validation.validator.string().min(1)).required()
80
+ }).unknown(false)).default("throw"),
81
+ model: _nhtio_validation.validator.string().required(),
82
+ frequency_penalty: _nhtio_validation.validator.number().min(-2).max(2).optional(),
83
+ logit_bias: _nhtio_validation.validator.object().pattern(_nhtio_validation.validator.string(), _nhtio_validation.validator.number()).optional(),
84
+ logprobs: _nhtio_validation.validator.boolean().optional(),
85
+ max_tokens: _nhtio_validation.validator.number().integer().min(1).optional(),
86
+ n: _nhtio_validation.validator.number().integer().min(1).optional(),
87
+ presence_penalty: _nhtio_validation.validator.number().min(-2).max(2).optional(),
88
+ response_format: responseFormatSchema.optional(),
89
+ seed: _nhtio_validation.validator.number().integer().optional(),
90
+ stop: _nhtio_validation.validator.alternatives(_nhtio_validation.validator.string(), _nhtio_validation.validator.array().items(_nhtio_validation.validator.string())).optional(),
91
+ stream_options: _nhtio_validation.validator.object().unknown(true).optional(),
92
+ temperature: _nhtio_validation.validator.number().min(0).max(2).optional(),
93
+ tool_choice: toolChoiceSchema.optional(),
94
+ top_logprobs: _nhtio_validation.validator.number().integer().min(0).optional(),
95
+ top_p: _nhtio_validation.validator.number().min(0).max(1).optional(),
96
+ user: _nhtio_validation.validator.string().optional(),
97
+ repetition_penalty: _nhtio_validation.validator.number().optional(),
98
+ ignore_eos: _nhtio_validation.validator.boolean().optional(),
99
+ extra_body: _nhtio_validation.validator.object().unknown(true).optional(),
100
+ max_completion_tokens: _nhtio_validation.validator.number().integer().min(1).optional()
101
+ }).unknown(false);
102
+ var formatValidationDetails = (err) => err.details.map((d) => d.message).join(" and ");
103
+ var validateOptions = (input) => {
104
+ const { value, error } = webLLMChatCompletionsOptionsSchema.validate(input, {
105
+ abortEarly: false,
106
+ convert: false
107
+ });
108
+ if (error) throw new require_batteries_llm_webllm_chat_completions_exceptions.E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS([formatValidationDetails(error)], { cause: error });
109
+ return value;
110
+ };
111
+ //#endregion
112
+ exports.validateOptions = validateOptions;
113
+ exports.webLLMChatCompletionsOptionsSchema = webLLMChatCompletionsOptionsSchema;
114
+
115
+ //# sourceMappingURL=validation.cjs.map