@nhtio/adk 0.1.0-master-2a4e1bd2 → 0.1.0-master-cd595e6f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/artifact_methods-CJDQ5Lv-.mjs +1 -0
- package/artifact_methods-D6k_82r3.js +1 -0
- package/batteries/artifacts/ecmascript.cjs +1 -1
- package/batteries/artifacts/ecmascript.mjs +1 -1
- package/batteries/artifacts/toon.cjs +1 -1
- package/batteries/artifacts/toon.mjs +1 -1
- package/batteries/artifacts/xml.cjs +1 -1
- package/batteries/artifacts/xml.mjs +1 -1
- package/batteries/artifacts/yaml.cjs +1 -1
- package/batteries/artifacts/yaml.mjs +1 -1
- package/batteries/artifacts.cjs +4 -4
- package/batteries/artifacts.mjs +4 -4
- package/batteries/dev-tools/forge.cjs +3 -3
- package/batteries/dev-tools/forge.mjs +3 -3
- package/batteries/dev-tools.cjs +2 -2
- package/batteries/dev-tools.mjs +2 -2
- package/batteries/encoding.cjs +7 -7
- package/batteries/encoding.mjs +7 -7
- package/batteries/generation/gemini/adapter.cjs +1 -1
- package/batteries/generation/gemini/adapter.mjs +1 -1
- package/batteries/generation/local_diffusion/adapter.cjs +1 -1
- package/batteries/generation/local_diffusion/adapter.mjs +1 -1
- package/batteries/generation/openai/adapter.cjs +1 -1
- package/batteries/generation/openai/adapter.mjs +1 -1
- package/batteries/isolation/browser.d.ts +1 -1
- package/batteries/isolation/child_process/transport.d.ts +2 -2
- package/batteries/isolation/child_process.cjs +4 -4
- package/batteries/isolation/child_process.cjs.map +1 -1
- package/batteries/isolation/child_process.mjs +4 -4
- package/batteries/isolation/child_process.mjs.map +1 -1
- package/batteries/isolation/codec.d.ts +2 -2
- package/batteries/isolation/crash_policy.d.ts +1 -1
- package/batteries/isolation/isolate_function.d.ts +2 -2
- package/batteries/isolation/protocol.d.ts +4 -4
- package/batteries/isolation/serve.d.ts +2 -2
- package/batteries/isolation/types.d.ts +4 -4
- package/batteries/isolation.cjs +1 -1
- package/batteries/isolation.mjs +1 -1
- package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
- package/batteries/llm/anthropic_messages/adapter.cjs.map +1 -1
- package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
- package/batteries/llm/anthropic_messages/adapter.mjs.map +1 -1
- package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
- package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
- package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
- package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
- package/batteries/llm/anthropic_messages/types.d.ts +2 -2
- package/batteries/llm/anthropic_messages/validation.cjs +3 -3
- package/batteries/llm/anthropic_messages/validation.cjs.map +1 -1
- package/batteries/llm/anthropic_messages/validation.mjs +3 -3
- package/batteries/llm/anthropic_messages/validation.mjs.map +1 -1
- package/batteries/llm/anthropic_messages.cjs +2 -2
- package/batteries/llm/anthropic_messages.mjs +2 -2
- package/batteries/llm/bedrock_converse/adapter.cjs +29 -7
- package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/adapter.mjs +30 -8
- package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
- package/batteries/llm/bedrock_converse/exceptions.cjs +3 -0
- package/batteries/llm/bedrock_converse/exceptions.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/exceptions.d.ts +6 -0
- package/batteries/llm/bedrock_converse/exceptions.mjs +3 -1
- package/batteries/llm/bedrock_converse/exceptions.mjs.map +1 -1
- package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
- package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
- package/batteries/llm/bedrock_converse/types.d.ts +6 -2
- package/batteries/llm/bedrock_converse/validation.cjs +7 -1
- package/batteries/llm/bedrock_converse/validation.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/validation.mjs +7 -1
- package/batteries/llm/bedrock_converse/validation.mjs.map +1 -1
- package/batteries/llm/bedrock_converse.cjs +2 -2
- package/batteries/llm/bedrock_converse.mjs +2 -2
- package/batteries/llm/claude_code_cli/adapter.cjs +6 -6
- package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/adapter.mjs +6 -6
- package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
- package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
- package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
- package/batteries/llm/claude_code_cli/types.d.ts +3 -2
- package/batteries/llm/claude_code_cli/validation.cjs +3 -3
- package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/validation.mjs +3 -3
- package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
- package/batteries/llm/claude_code_cli.cjs +1 -1
- package/batteries/llm/claude_code_cli.mjs +1 -1
- package/batteries/llm/gemini_generate_content/adapter.cjs +29 -7
- package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/adapter.mjs +30 -8
- package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content/exceptions.cjs +3 -0
- package/batteries/llm/gemini_generate_content/exceptions.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/exceptions.d.ts +6 -0
- package/batteries/llm/gemini_generate_content/exceptions.mjs +3 -1
- package/batteries/llm/gemini_generate_content/exceptions.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
- package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
- package/batteries/llm/gemini_generate_content/types.d.ts +7 -3
- package/batteries/llm/gemini_generate_content/validation.cjs +11 -2
- package/batteries/llm/gemini_generate_content/validation.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/validation.mjs +11 -2
- package/batteries/llm/gemini_generate_content/validation.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content.cjs +1 -1
- package/batteries/llm/gemini_generate_content.mjs +1 -1
- package/batteries/llm/litert_lm/adapter.cjs +6 -6
- package/batteries/llm/litert_lm/adapter.cjs.map +1 -1
- package/batteries/llm/litert_lm/adapter.mjs +6 -6
- package/batteries/llm/litert_lm/adapter.mjs.map +1 -1
- package/batteries/llm/litert_lm/helpers.cjs +3 -3
- package/batteries/llm/litert_lm/helpers.mjs +3 -3
- package/batteries/llm/litert_lm/types.d.ts +2 -2
- package/batteries/llm/litert_lm/validation.cjs +3 -3
- package/batteries/llm/litert_lm/validation.cjs.map +1 -1
- package/batteries/llm/litert_lm/validation.mjs +3 -3
- package/batteries/llm/litert_lm/validation.mjs.map +1 -1
- package/batteries/llm/litert_lm.cjs +1 -1
- package/batteries/llm/litert_lm.mjs +1 -1
- package/batteries/llm/ollama/adapter.cjs +6 -6
- package/batteries/llm/ollama/adapter.cjs.map +1 -1
- package/batteries/llm/ollama/adapter.mjs +6 -6
- package/batteries/llm/ollama/adapter.mjs.map +1 -1
- package/batteries/llm/ollama/helpers.cjs +4 -4
- package/batteries/llm/ollama/helpers.mjs +4 -4
- package/batteries/llm/ollama/types.d.ts +2 -2
- package/batteries/llm/ollama/validation.cjs +3 -3
- package/batteries/llm/ollama/validation.cjs.map +1 -1
- package/batteries/llm/ollama/validation.mjs +3 -3
- package/batteries/llm/ollama/validation.mjs.map +1 -1
- package/batteries/llm/ollama.cjs +2 -2
- package/batteries/llm/ollama.mjs +2 -2
- package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
- package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
- package/batteries/llm/openai_chat_completions/types.d.ts +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs +3 -3
- package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +3 -3
- package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions.cjs +2 -2
- package/batteries/llm/openai_chat_completions.mjs +2 -2
- package/batteries/llm/openai_responses/adapter.cjs +6 -6
- package/batteries/llm/openai_responses/adapter.cjs.map +1 -1
- package/batteries/llm/openai_responses/adapter.mjs +6 -6
- package/batteries/llm/openai_responses/adapter.mjs.map +1 -1
- package/batteries/llm/openai_responses/helpers.cjs +3 -3
- package/batteries/llm/openai_responses/helpers.mjs +3 -3
- package/batteries/llm/openai_responses/types.d.ts +2 -2
- package/batteries/llm/openai_responses/validation.cjs +3 -3
- package/batteries/llm/openai_responses/validation.cjs.map +1 -1
- package/batteries/llm/openai_responses/validation.mjs +3 -3
- package/batteries/llm/openai_responses/validation.mjs.map +1 -1
- package/batteries/llm/openai_responses.cjs +2 -2
- package/batteries/llm/openai_responses.mjs +2 -2
- package/batteries/llm/transformers_js/adapter.cjs +6 -6
- package/batteries/llm/transformers_js/adapter.cjs.map +1 -1
- package/batteries/llm/transformers_js/adapter.mjs +6 -6
- package/batteries/llm/transformers_js/adapter.mjs.map +1 -1
- package/batteries/llm/transformers_js/helpers.cjs +3 -3
- package/batteries/llm/transformers_js/helpers.mjs +3 -3
- package/batteries/llm/transformers_js/types.d.ts +2 -2
- package/batteries/llm/transformers_js/validation.cjs +3 -3
- package/batteries/llm/transformers_js/validation.cjs.map +1 -1
- package/batteries/llm/transformers_js/validation.mjs +3 -3
- package/batteries/llm/transformers_js/validation.mjs.map +1 -1
- package/batteries/llm/transformers_js.cjs +1 -1
- package/batteries/llm/transformers_js.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs +3 -3
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs +3 -3
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions.cjs +2 -2
- package/batteries/llm/webllm_chat_completions.mjs +2 -2
- package/batteries/llm.cjs +2 -2
- package/batteries/llm.mjs +2 -2
- package/batteries/media/builder.d.ts +3 -0
- package/batteries/media/contracts.cjs.map +1 -1
- package/batteries/media/contracts.d.ts +40 -1
- package/batteries/media/contracts.mjs.map +1 -1
- package/batteries/media/engines/sharp.cjs +36 -2
- package/batteries/media/engines/sharp.cjs.map +1 -1
- package/batteries/media/engines/sharp.mjs +36 -2
- package/batteries/media/engines/sharp.mjs.map +1 -1
- package/batteries/media/forge.cjs +5 -5
- package/batteries/media/forge.mjs +5 -5
- package/batteries/media/index.d.ts +1 -1
- package/batteries/media/lint.cjs +3 -2
- package/batteries/media/lint.cjs.map +1 -1
- package/batteries/media/lint.mjs +3 -2
- package/batteries/media/lint.mjs.map +1 -1
- package/batteries/media.cjs +66 -2
- package/batteries/media.cjs.map +1 -1
- package/batteries/media.mjs +66 -2
- package/batteries/media.mjs.map +1 -1
- package/batteries/orchestration/conformance.cjs +123 -74
- package/batteries/orchestration/conformance.cjs.map +1 -1
- package/batteries/orchestration/conformance.d.ts +10 -8
- package/batteries/orchestration/conformance.mjs +54 -5
- package/batteries/orchestration/conformance.mjs.map +1 -1
- package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
- package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
- package/batteries/orchestration/executor.cjs +2 -2
- package/batteries/orchestration/executor.mjs +2 -2
- package/batteries/orchestration/forge.cjs +4 -4
- package/batteries/orchestration/forge.mjs +4 -4
- package/batteries/orchestration/validation.cjs +2 -2
- package/batteries/orchestration/validation.mjs +2 -2
- package/batteries/orchestration.cjs +4 -4
- package/batteries/orchestration.mjs +4 -4
- package/batteries/sandbox/contracts/policy_enforcer.d.ts +13 -1
- package/batteries/sandbox/js/compartment.d.ts +7 -2
- package/batteries/sandbox/js/exceptions.d.ts +4 -0
- package/batteries/sandbox/js/runner.d.ts +1 -1
- package/batteries/sandbox/js/service.d.ts +1 -1
- package/batteries/sandbox/js/ses_contracts.d.ts +4 -3
- package/batteries/sandbox/js.cjs +17 -8
- package/batteries/sandbox/js.cjs.map +1 -1
- package/batteries/sandbox/js.mjs +17 -9
- package/batteries/sandbox/js.mjs.map +1 -1
- package/batteries/sandbox/manager.d.ts +4 -3
- package/batteries/sandbox/node/srt_enforcer.d.ts +1 -1
- package/batteries/sandbox/node.cjs +36 -12
- package/batteries/sandbox/node.cjs.map +1 -1
- package/batteries/sandbox/node.mjs +36 -12
- package/batteries/sandbox/node.mjs.map +1 -1
- package/batteries/sandbox/tools.cjs +1 -1
- package/batteries/sandbox/tools.mjs +1 -1
- package/batteries/sandbox/types.d.ts +10 -1
- package/batteries/sandbox.cjs +27 -9
- package/batteries/sandbox.cjs.map +1 -1
- package/batteries/sandbox.mjs +28 -11
- package/batteries/sandbox.mjs.map +1 -1
- package/batteries/skills.cjs +9 -9
- package/batteries/skills.mjs +9 -9
- package/batteries/tools/_shared.cjs +1 -1
- package/batteries/tools/_shared.mjs +1 -1
- package/batteries/tools/color.cjs +2 -2
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +2 -2
- package/batteries/tools/comparison.mjs +2 -2
- package/batteries/tools/data_structure.cjs +2 -2
- package/batteries/tools/data_structure.mjs +2 -2
- package/batteries/tools/datetime_extended.cjs +3 -3
- package/batteries/tools/datetime_extended.mjs +3 -3
- package/batteries/tools/datetime_math.cjs +3 -3
- package/batteries/tools/datetime_math.mjs +3 -3
- package/batteries/tools/encoding.cjs +2 -2
- package/batteries/tools/encoding.mjs +2 -2
- package/batteries/tools/formatting.cjs +2 -2
- package/batteries/tools/formatting.mjs +2 -2
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math.cjs +2 -2
- package/batteries/tools/math.mjs +2 -2
- package/batteries/tools/memory.cjs +5 -5
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +3 -3
- package/batteries/tools/parsing.mjs +3 -3
- package/batteries/tools/retrievables.cjs +5 -5
- package/batteries/tools/retrievables.mjs +5 -5
- package/batteries/tools/scrapper.cjs +1 -1
- package/batteries/tools/scrapper.mjs +1 -1
- package/batteries/tools/searxng.cjs +1 -1
- package/batteries/tools/searxng.mjs +1 -1
- package/batteries/tools/standing_instructions.cjs +3 -3
- package/batteries/tools/standing_instructions.mjs +3 -3
- package/batteries/tools/statistics.cjs +3 -3
- package/batteries/tools/statistics.mjs +3 -3
- package/batteries/tools/string_processing.cjs +2 -2
- package/batteries/tools/string_processing.mjs +2 -2
- package/batteries/tools/structured_data.cjs +2 -2
- package/batteries/tools/structured_data.mjs +2 -2
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +3 -3
- package/batteries/tools/time.mjs +3 -3
- package/batteries/tools/unit_conversion.cjs +2 -2
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries/tools.cjs +2 -2
- package/batteries/tools.mjs +2 -2
- package/batteries/validation.cjs +5 -5
- package/batteries/validation.mjs +5 -5
- package/batteries/vector/conformance/index.d.ts +11 -16
- package/batteries/vector/conformance.cjs +107 -36
- package/batteries/vector/conformance.cjs.map +1 -1
- package/batteries/vector/conformance.mjs +84 -13
- package/batteries/vector/conformance.mjs.map +1 -1
- package/batteries/vector/retrievable.cjs +1 -1
- package/batteries/vector/retrievable.mjs +1 -1
- package/batteries.cjs +5 -5
- package/batteries.mjs +5 -5
- package/{chat_common-DbbIESdo.mjs → chat_common-CmKV5Dz4.mjs} +2 -2
- package/{chat_common-DbbIESdo.mjs.map → chat_common-CmKV5Dz4.mjs.map} +1 -1
- package/{chat_common-B3O3zz-i.js → chat_common-Dpan9moo.js} +2 -2
- package/{chat_common-B3O3zz-i.js.map → chat_common-Dpan9moo.js.map} +1 -1
- package/{common-v9Jo9M5k.mjs → common-BpdHIpQE.mjs} +7 -7
- package/{common-v9Jo9M5k.mjs.map → common-BpdHIpQE.mjs.map} +1 -1
- package/{common-BV3HGeLj.js → common-H44Ik9ou.js} +7 -7
- package/{common-BV3HGeLj.js.map → common-H44Ik9ou.js.map} +1 -1
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-CbNyqSMy.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
- package/{dispatch_runner-CbNyqSMy.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
- package/{dispatch_runner-Bl3Xwebu.js → dispatch_runner-CKhm-scw.js} +5 -5
- package/{dispatch_runner-Bl3Xwebu.js.map → dispatch_runner-CKhm-scw.js.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/{ecmascript-BSnvyY8T.js → ecmascript-CCtgamDh.js} +3 -3
- package/{ecmascript-BSnvyY8T.js.map → ecmascript-CCtgamDh.js.map} +1 -1
- package/{ecmascript-CZ7_YKfZ.mjs → ecmascript-DcmUQ9Jx.mjs} +3 -3
- package/{ecmascript-CZ7_YKfZ.mjs.map → ecmascript-DcmUQ9Jx.mjs.map} +1 -1
- package/eslint.cjs +1 -1
- package/eslint.mjs +1 -1
- package/exceptions.cjs +1 -1
- package/exceptions.mjs +1 -1
- package/forge.cjs +2 -2
- package/forge.mjs +2 -2
- package/guards.cjs +7 -7
- package/guards.mjs +7 -7
- package/{helpers-CDmLDBq5.mjs → helpers-BH7HTtkD.mjs} +3 -3
- package/{helpers-CDmLDBq5.mjs.map → helpers-BH7HTtkD.mjs.map} +1 -1
- package/{helpers-Tvvwpx1M.js → helpers-CEjjkXso.js} +3 -3
- package/{helpers-Tvvwpx1M.js.map → helpers-CEjjkXso.js.map} +1 -1
- package/index.cjs +10 -10
- package/index.mjs +10 -10
- package/{isolation-BQCTQYZ_.js → isolation-7Jrcucgc.js} +11 -11
- package/isolation-7Jrcucgc.js.map +1 -0
- package/{isolation-7xbkc12r.mjs → isolation-CO0NiK8R.mjs} +11 -11
- package/isolation-CO0NiK8R.mjs.map +1 -0
- package/lib/classes/tokenizable.d.ts +2 -3
- package/mcp/adk-docs-corpus.json +2 -2
- package/package.json +469 -469
- package/{retrievable-C5dXuDhD.js → retrievable-BTwjmPnl.js} +3 -3
- package/{retrievable-C5dXuDhD.js.map → retrievable-BTwjmPnl.js.map} +1 -1
- package/{retrievable-gl_TIHnX.mjs → retrievable-CXTAUuuv.mjs} +3 -3
- package/{retrievable-gl_TIHnX.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
- package/{scrapper-DD6-_2u-.js → scrapper-CJexXXK-.js} +4 -4
- package/{scrapper-DD6-_2u-.js.map → scrapper-CJexXXK-.js.map} +1 -1
- package/{scrapper-u_orpxIB.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
- package/{scrapper-u_orpxIB.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
- package/{searxng-fVdJUCK2.mjs → searxng-BFTJ6rTE.mjs} +4 -4
- package/{searxng-fVdJUCK2.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
- package/{searxng-C7GK0Nrz.js → searxng-DzlGZG4V.js} +4 -4
- package/{searxng-C7GK0Nrz.js.map → searxng-DzlGZG4V.js.map} +1 -1
- package/server.json +2 -2
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-DriNQRj7.js → spooled_artifact-BpcesRBv.js} +384 -384
- package/spooled_artifact-BpcesRBv.js.map +1 -0
- package/{spooled_artifact-BkueYJhR.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
- package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-CfHRZUkl.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
- package/{spooled_markdown_artifact-CfHRZUkl.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
- package/{spooled_markdown_artifact-C_VkCDhF.js → spooled_markdown_artifact-wJPnE8Ij.js} +3 -3
- package/{spooled_markdown_artifact-C_VkCDhF.js.map → spooled_markdown_artifact-wJPnE8Ij.js.map} +1 -1
- package/{thought-B8JAi3-W.mjs → thought-BE1KGEhV.mjs} +3 -3
- package/{thought-B8JAi3-W.mjs.map → thought-BE1KGEhV.mjs.map} +1 -1
- package/{thought--fRgOwTP.js → thought-bS7O9O5H.js} +3 -3
- package/{thought--fRgOwTP.js.map → thought-bS7O9O5H.js.map} +1 -1
- package/{tokenizable-CWW7iSrD.js → tokenizable-BMZuGWRd.js} +35 -29
- package/tokenizable-BMZuGWRd.js.map +1 -0
- package/{tokenizable-DLMP68ZV.mjs → tokenizable-VB4Av8GF.mjs} +36 -30
- package/tokenizable-VB4Av8GF.mjs.map +1 -0
- package/{tool_call-CPjyvkm4.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
- package/{tool_call-CPjyvkm4.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
- package/{tool_call-DgqVwL5n.js → tool_call-Fs_Uh5wQ.js} +4 -4
- package/{tool_call-DgqVwL5n.js.map → tool_call-Fs_Uh5wQ.js.map} +1 -1
- package/{tools-BmLzkvNr.mjs → tools-B3_8C78Q.mjs} +6 -6
- package/{tools-BmLzkvNr.mjs.map → tools-B3_8C78Q.mjs.map} +1 -1
- package/{tools-DmcIe2Cb.js → tools-CqOcmHR8.js} +6 -6
- package/{tools-DmcIe2Cb.js.map → tools-CqOcmHR8.js.map} +1 -1
- package/{toon-BvTQsKdN.mjs → toon-BSlr88px.mjs} +5 -5
- package/{toon-BvTQsKdN.mjs.map → toon-BSlr88px.mjs.map} +1 -1
- package/{toon-B05eKx-q.js → toon-D71tkyI3.js} +5 -5
- package/{toon-B05eKx-q.js.map → toon-D71tkyI3.js.map} +1 -1
- package/{turn_runner-DEGCvfVZ.mjs → turn_runner-BHHD6h77.mjs} +5 -5
- package/{turn_runner-DEGCvfVZ.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
- package/{turn_runner-DT8TseR4.js → turn_runner-DhLI7OTH.js} +5 -5
- package/{turn_runner-DT8TseR4.js.map → turn_runner-DhLI7OTH.js.map} +1 -1
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/types-D6X_aUIb.mjs.map +1 -1
- package/types-DrSosVaM.js.map +1 -1
- package/{validate-lzy9nG_E.mjs → validate-Bi7FGjoq.mjs} +13 -1
- package/{validate-lzy9nG_E.mjs.map → validate-Bi7FGjoq.mjs.map} +1 -1
- package/{validate-CdOS7S2u.js → validate-CkQI-48O.js} +13 -1
- package/{validate-CdOS7S2u.js.map → validate-CkQI-48O.js.map} +1 -1
- package/{xml-DDTIMpY3.js → xml-BeNvlifb.js} +5 -5
- package/{xml-DDTIMpY3.js.map → xml-BeNvlifb.js.map} +1 -1
- package/{xml-VhJ4NrMB.mjs → xml-vyCZZiF_.mjs} +5 -5
- package/{xml-VhJ4NrMB.mjs.map → xml-vyCZZiF_.mjs.map} +1 -1
- package/{yaml-Cx16IYJq.js → yaml-DhLLa2cj.js} +5 -5
- package/{yaml-Cx16IYJq.js.map → yaml-DhLLa2cj.js.map} +1 -1
- package/{yaml-Du4wFGzL.mjs → yaml-Dtz0Bd7J.mjs} +5 -5
- package/{yaml-Du4wFGzL.mjs.map → yaml-Dtz0Bd7J.mjs.map} +1 -1
- package/artifact_methods-BMCahBLn.mjs +0 -1
- package/artifact_methods-f_bSy4kX.js +0 -1
- package/isolation-7xbkc12r.mjs.map +0 -1
- package/isolation-BQCTQYZ_.js.map +0 -1
- package/spooled_artifact-BkueYJhR.mjs.map +0 -1
- package/spooled_artifact-DriNQRj7.js.map +0 -1
- package/tokenizable-CWW7iSrD.js.map +0 -1
- package/tokenizable-DLMP68ZV.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.mjs","names":[],"sources":["../../../../src/batteries/llm/transformers_js/validation.ts"],"sourcesContent":["/**\n * Runtime validation schema and wrapper for transformers.js LLM adapter options.\n *\n * @module @nhtio/adk/batteries/llm/transformers_js/validation\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_OPTIONS } from './exceptions'\nimport { byteStoreSchema, TokenEncoding } from '@nhtio/adk/common'\nimport type { TransformersJsAdapterOptions } from './types'\n\nconst bucketLabelSchema = validator\n .string()\n .valid('standingInstructions', 'memories', 'retrievables', 'timeline')\n\nconst bucketOrderSchema = validator\n .array()\n .items(bucketLabelSchema)\n .unique()\n .default(['standingInstructions', 'memories', 'retrievables', 'timeline'])\n\nconst reasoningFieldPrecedenceSchema = validator\n .array()\n .items(validator.string().valid('reasoning', 'reasoning_content'))\n .unique()\n .min(1)\n .default(['reasoning', 'reasoning_content'])\n\nconst tokenEncodingSchema = validator\n .alternatives(\n // Derive from the canonical TokenEncoding array so new encodings (e.g. 'gemma') are accepted without\n // drift between the token counter and this validator.\n validator.string().valid(...TokenEncoding),\n validator.any().valid(null).optional()\n )\n .default(null)\n\nconst helperSchema = validator.function()\n\nconst helpersSchema = validator\n .object({\n descriptionToChatCompletionsJsonSchema: helperSchema.optional(),\n renderUntrustedContent: helperSchema.optional(),\n renderTrustedContent: helperSchema.optional(),\n renderArtifactHandleBody: helperSchema.optional(),\n renderRetrievableHandleBody: helperSchema.optional(),\n renderStandingInstructions: helperSchema.optional(),\n renderMemories: helperSchema.optional(),\n renderRetrievables: helperSchema.optional(),\n renderRetrievableSafetyDirective: helperSchema.optional(),\n renderFirstPartyRetrievables: helperSchema.optional(),\n renderThirdPartyPublicRetrievables: helperSchema.optional(),\n renderThirdPartyPrivateRetrievables: helperSchema.optional(),\n renderTimelineMessage: helperSchema.optional(),\n renderThought: helperSchema.optional(),\n filterThoughts: helperSchema.optional(),\n toolsToChatCompletionsTools: helperSchema.optional(),\n renderChatCompletionsSystemPrompt: helperSchema.optional(),\n renderChatCompletionsToolCallResult: helperSchema.optional(),\n buildChatCompletionsHistory: helperSchema.optional(),\n createChatCompletionsToolCallDeltaAccumulator: helperSchema.optional(),\n })\n .unknown(false)\n\nconst unsupportedMediaPolicySchema = validator\n .alternatives(\n validator.string().valid('throw', 'fallback-stash', 'synthetic-description'),\n validator\n .object({\n mode: validator.string().valid('fallback-stash').required(),\n stashKeys: validator.array().items(validator.string().min(1)).required(),\n })\n .unknown(false)\n )\n .default('throw')\n\nconst toolCallParserSchema = validator\n .alternatives(\n validator\n .string()\n .valid(\n 'auto',\n 'hermes',\n 'gemma',\n 'gpt_oss',\n 'pythonic',\n 'llama3_json',\n 'mistral',\n 'qwen3_coder',\n 'phi',\n 'none'\n ),\n validator.function()\n )\n .default('auto')\n\nconst reasoningParserSchema = validator\n .alternatives(\n validator.string().valid('auto', 'think_tag', 'harmony_analysis', 'gemma_channel', 'none'),\n validator.function()\n )\n .default('auto')\n\n/**\n * Validator schema for {@link TransformersJsAdapterOptions}. Rejects unknown keys (`.unknown(false)`)\n * and fills in defaults.\n */\nexport const transformersJsOptionsSchema = validator\n .object<TransformersJsAdapterOptions>({\n // ── Engine ──\n model: validator.string().min(1).required(),\n // The transformers.js pipeline is a callable object — accept either a function or an object.\n pipeline: validator\n .alternatives(validator.function(), validator.object().unknown(true))\n .optional(),\n createPipeline: validator.function().optional(),\n createStreamer: validator.function().optional(),\n // device/dtype: a scalar string OR a per-submodule Record (multimodal).\n device: validator.alternatives(validator.string(), validator.object().unknown(true)).optional(),\n dtype: validator.alternatives(validator.string(), validator.object().unknown(true)).optional(),\n // ONNX Runtime session options, forwarded verbatim to the loader. Open object — the runtime owns the\n // shape; we surface the lever without re-validating ORT's evolving option set.\n sessionOptions: validator.object().unknown(true).optional(),\n // KV-cache GPU-pin default. Left optional (NOT .default(true)) so the adapter's own `?? true` sees\n // `undefined` vs explicit `false` distinctly; the effective default is true, applied in the adapter.\n pinKvCacheToGpu: validator.boolean().optional(),\n onInitProgress: validator.function().optional(),\n isAvailable: validator.function().optional(),\n // ── Multimodal (opt-in) ──\n multimodal: validator\n .alternatives(\n validator.boolean(),\n validator.object({ image: validator.boolean(), audio: validator.boolean() }).unknown(false)\n )\n .optional(),\n multimodalEngine: validator.object().unknown(true).optional(),\n createMultimodal: validator.function().optional(),\n modelSource: validator.function().optional(),\n // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n onLifecycle: validator.function().optional(),\n onLoading: validator.function().optional(),\n onCompiling: validator.function().optional(),\n onReady: validator.function().optional(),\n onGenerating: validator.function().optional(),\n onComplete: validator.function().optional(),\n onError: validator.function().optional(),\n // ── Generation: PORTABLE canonical contract (shared with LiteRT-LM) ──\n // Optional (no defaults here) — the resolver fills defaults and applies canonical-wins precedence so\n // the native fields below still work as escape hatches.\n maxTokens: validator.number().integer().min(1).optional(),\n sampler: validator.string().valid('greedy', 'top-k', 'top-p').optional(),\n seed: validator.number().integer().optional(),\n // ── Generation: transformers.js-NATIVE escape hatches ── (explicit defaults — never let `generate`\n // guess; the resolver consults these only when the canonical field above is unset) ──\n maxNewTokens: validator.number().integer().min(1).optional(),\n doSample: validator.boolean().optional(),\n temperature: validator.number().min(0).default(0.7),\n topK: validator.number().integer().min(1).default(40),\n topP: validator.number().min(0).max(1).default(0.95),\n repetitionPenalty: validator.number().min(0).default(1.1),\n stopStrings: validator.array().items(validator.string()).optional(),\n enableThinking: validator.boolean().default(false),\n // ── ADK control ──\n stream: validator.boolean().default(true),\n bucketOrder: bucketOrderSchema,\n // Safe context budget (enforced only when `tokenEncoding` is non-null — counting is opt-in, but the\n // ceiling is pinned so once enabled it never silently exceeds a small on-device model's window).\n contextWindow: validator.number().integer().min(1).default(4096),\n selfIdentity: validator.string().min(1).default('assistant'),\n thoughtSurfacing: validator\n .string()\n .valid('all-self', 'latest-self', 'all')\n .default('all-self'),\n tokenEncoding: tokenEncodingSchema,\n replayCompatibility: validator.array().items(validator.string().min(1)).default([]),\n reasoningFieldPrecedence: reasoningFieldPrecedenceSchema,\n helpers: helpersSchema.optional(),\n spoolStore: byteStoreSchema.optional(),\n unsupportedMediaPolicy: unsupportedMediaPolicySchema,\n autoAck: validator.boolean().default(false),\n toolCallParser: toolCallParserSchema,\n forgeToolsFilter: validator.function().optional(),\n reasoningParser: reasoningParserSchema,\n reasoningOrphanRecovery: validator.boolean().default(true),\n extractMediaOutputs: validator.function().optional(),\n onRawGeneration: validator.function().optional(),\n onPromptAssembled: validator.function().optional(),\n })\n .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates raw adapter options against {@link transformersJsOptionsSchema}, filling in defaults.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults applied.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_OPTIONS} when `input` is invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsAdapterOptions => {\n const { value, error } = transformersJsOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error && isValidationError(error)) {\n throw new E_INVALID_TRANSFORMERS_JS_OPTIONS([formatValidationDetails(error)], { cause: error })\n }\n return value as TransformersJsAdapterOptions\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation.mjs","names":[],"sources":["../../../../src/batteries/llm/transformers_js/validation.ts"],"sourcesContent":["/**\n * Runtime validation schema and wrapper for transformers.js LLM adapter options.\n *\n * @module @nhtio/adk/batteries/llm/transformers_js/validation\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_OPTIONS } from './exceptions'\nimport { byteStoreSchema, TokenEncoding } from '@nhtio/adk/common'\nimport type { TransformersJsAdapterOptions } from './types'\n\nconst bucketLabelSchema = validator\n .string()\n .valid('standingInstructions', 'memories', 'retrievables', 'timeline')\n\nconst bucketOrderSchema = validator\n .array()\n .items(bucketLabelSchema)\n .unique()\n .default(['standingInstructions', 'memories', 'retrievables', 'timeline'])\n\nconst reasoningFieldPrecedenceSchema = validator\n .array()\n .items(validator.string().valid('reasoning', 'reasoning_content'))\n .unique()\n .min(1)\n .default(['reasoning', 'reasoning_content'])\n\nconst tokenEncodingSchema = validator\n .alternatives(\n // Known values are suggestions from the canonical list, not a whitelist: consumers may provide\n // a custom or newer tokenizer name. The field accepts any non-empty string, explicit null, or\n // absent (undefined = \"no token counting\"). `.optional()` preserves the null/undefined\n // disposition required by adk/require-validator-any-required.\n validator\n .string()\n .min(1)\n .description(`Known encodings: ${TokenEncoding.join(', ')}`),\n validator.any().valid(null).optional()\n )\n .default(null)\n\nconst helperSchema = validator.function()\n\nconst helpersSchema = validator\n .object({\n descriptionToChatCompletionsJsonSchema: helperSchema.optional(),\n renderUntrustedContent: helperSchema.optional(),\n renderTrustedContent: helperSchema.optional(),\n renderArtifactHandleBody: helperSchema.optional(),\n renderRetrievableHandleBody: helperSchema.optional(),\n renderStandingInstructions: helperSchema.optional(),\n renderMemories: helperSchema.optional(),\n renderRetrievables: helperSchema.optional(),\n renderRetrievableSafetyDirective: helperSchema.optional(),\n renderFirstPartyRetrievables: helperSchema.optional(),\n renderThirdPartyPublicRetrievables: helperSchema.optional(),\n renderThirdPartyPrivateRetrievables: helperSchema.optional(),\n renderTimelineMessage: helperSchema.optional(),\n renderThought: helperSchema.optional(),\n filterThoughts: helperSchema.optional(),\n toolsToChatCompletionsTools: helperSchema.optional(),\n renderChatCompletionsSystemPrompt: helperSchema.optional(),\n renderChatCompletionsToolCallResult: helperSchema.optional(),\n buildChatCompletionsHistory: helperSchema.optional(),\n createChatCompletionsToolCallDeltaAccumulator: helperSchema.optional(),\n })\n .unknown(false)\n\nconst unsupportedMediaPolicySchema = validator\n .alternatives(\n validator.string().valid('throw', 'fallback-stash', 'synthetic-description'),\n validator\n .object({\n mode: validator.string().valid('fallback-stash').required(),\n stashKeys: validator.array().items(validator.string().min(1)).required(),\n })\n .unknown(false)\n )\n .default('throw')\n\nconst toolCallParserSchema = validator\n .alternatives(\n validator\n .string()\n .valid(\n 'auto',\n 'hermes',\n 'gemma',\n 'gpt_oss',\n 'pythonic',\n 'llama3_json',\n 'mistral',\n 'qwen3_coder',\n 'phi',\n 'none'\n ),\n validator.function()\n )\n .default('auto')\n\nconst reasoningParserSchema = validator\n .alternatives(\n validator.string().valid('auto', 'think_tag', 'harmony_analysis', 'gemma_channel', 'none'),\n validator.function()\n )\n .default('auto')\n\n/**\n * Validator schema for {@link TransformersJsAdapterOptions}. Rejects unknown keys (`.unknown(false)`)\n * and fills in defaults.\n */\nexport const transformersJsOptionsSchema = validator\n .object<TransformersJsAdapterOptions>({\n // ── Engine ──\n model: validator.string().min(1).required(),\n // The transformers.js pipeline is a callable object — accept either a function or an object.\n pipeline: validator\n .alternatives(validator.function(), validator.object().unknown(true))\n .optional(),\n createPipeline: validator.function().optional(),\n createStreamer: validator.function().optional(),\n // device/dtype: a scalar string OR a per-submodule Record (multimodal).\n device: validator.alternatives(validator.string(), validator.object().unknown(true)).optional(),\n dtype: validator.alternatives(validator.string(), validator.object().unknown(true)).optional(),\n // ONNX Runtime session options, forwarded verbatim to the loader. Open object — the runtime owns the\n // shape; we surface the lever without re-validating ORT's evolving option set.\n sessionOptions: validator.object().unknown(true).optional(),\n // KV-cache GPU-pin default. Left optional (NOT .default(true)) so the adapter's own `?? true` sees\n // `undefined` vs explicit `false` distinctly; the effective default is true, applied in the adapter.\n pinKvCacheToGpu: validator.boolean().optional(),\n onInitProgress: validator.function().optional(),\n isAvailable: validator.function().optional(),\n // ── Multimodal (opt-in) ──\n multimodal: validator\n .alternatives(\n validator.boolean(),\n validator.object({ image: validator.boolean(), audio: validator.boolean() }).unknown(false)\n )\n .optional(),\n multimodalEngine: validator.object().unknown(true).optional(),\n createMultimodal: validator.function().optional(),\n modelSource: validator.function().optional(),\n // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n onLifecycle: validator.function().optional(),\n onLoading: validator.function().optional(),\n onCompiling: validator.function().optional(),\n onReady: validator.function().optional(),\n onGenerating: validator.function().optional(),\n onComplete: validator.function().optional(),\n onError: validator.function().optional(),\n // ── Generation: PORTABLE canonical contract (shared with LiteRT-LM) ──\n // Optional (no defaults here) — the resolver fills defaults and applies canonical-wins precedence so\n // the native fields below still work as escape hatches.\n maxTokens: validator.number().integer().min(1).optional(),\n sampler: validator.string().valid('greedy', 'top-k', 'top-p').optional(),\n seed: validator.number().integer().optional(),\n // ── Generation: transformers.js-NATIVE escape hatches ── (explicit defaults — never let `generate`\n // guess; the resolver consults these only when the canonical field above is unset) ──\n maxNewTokens: validator.number().integer().min(1).optional(),\n doSample: validator.boolean().optional(),\n temperature: validator.number().min(0).default(0.7),\n topK: validator.number().integer().min(1).default(40),\n topP: validator.number().min(0).max(1).default(0.95),\n repetitionPenalty: validator.number().min(0).default(1.1),\n stopStrings: validator.array().items(validator.string()).optional(),\n enableThinking: validator.boolean().default(false),\n // ── ADK control ──\n stream: validator.boolean().default(true),\n bucketOrder: bucketOrderSchema,\n // Safe context budget (enforced only when `tokenEncoding` is non-null — counting is opt-in, but the\n // ceiling is pinned so once enabled it never silently exceeds a small on-device model's window).\n contextWindow: validator.number().integer().min(1).default(4096),\n selfIdentity: validator.string().min(1).default('assistant'),\n thoughtSurfacing: validator\n .string()\n .valid('all-self', 'latest-self', 'all')\n .default('all-self'),\n tokenEncoding: tokenEncodingSchema,\n replayCompatibility: validator.array().items(validator.string().min(1)).default([]),\n reasoningFieldPrecedence: reasoningFieldPrecedenceSchema,\n helpers: helpersSchema.optional(),\n spoolStore: byteStoreSchema.optional(),\n unsupportedMediaPolicy: unsupportedMediaPolicySchema,\n autoAck: validator.boolean().default(false),\n toolCallParser: toolCallParserSchema,\n forgeToolsFilter: validator.function().optional(),\n reasoningParser: reasoningParserSchema,\n reasoningOrphanRecovery: validator.boolean().default(true),\n extractMediaOutputs: validator.function().optional(),\n onRawGeneration: validator.function().optional(),\n onPromptAssembled: validator.function().optional(),\n })\n .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates raw adapter options against {@link transformersJsOptionsSchema}, filling in defaults.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults applied.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_OPTIONS} when `input` is invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsAdapterOptions => {\n const { value, error } = transformersJsOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error && isValidationError(error)) {\n throw new E_INVALID_TRANSFORMERS_JS_OPTIONS([formatValidationDetails(error)], { cause: error })\n }\n return value as TransformersJsAdapterOptions\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
3
|
const require_tool_parsers = require("../../tool_parsers-csSBFWob.js");
|
|
4
|
-
const require_helpers = require("../../helpers-
|
|
4
|
+
const require_helpers = require("../../helpers-CEjjkXso.js");
|
|
5
5
|
const require_batteries_llm_openai_chat_completions_helpers = require("./openai_chat_completions/helpers.cjs");
|
|
6
6
|
const require_gpu_budget = require("../../gpu_budget-BBIUyLoj.js");
|
|
7
7
|
const require_lifecycle = require("../../lifecycle-vYQJ2rmf.js");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as mistralToolCallParser, D as qwen3CoderToolCallParser, E as pythonicToolCallParser, O as resolveToolCallParser, S as looseKeyedToolCallParser, T as phiToolCallParser, _ as defaultResolveToolCallParser, a as defaultBarePythonicToolCallParser, b as hermesToolCallParser, c as defaultGptOssToolCallParser, d as defaultLooseKeyedToolCallParser, f as defaultMistralToolCallParser, g as defaultQwen3CoderToolCallParser, h as defaultPythonicToolCallParser, i as createAutoToolCallParser, l as defaultHermesToolCallParser, m as defaultPhiToolCallParser, n as DEFAULT_TOOL_CALL_PARSER_ORDER, o as defaultCreateAutoToolCallParser, p as defaultNoneToolCallParser, r as barePythonicToolCallParser, s as defaultGemmaToolCallParser, t as BUNDLED_TOOL_CALL_PARSERS, u as defaultLlama3JsonToolCallParser, v as gemmaToolCallParser, w as noneToolCallParser, x as llama3JsonToolCallParser, y as gptOssToolCallParser } from "../../tool_parsers-DgZhgxV8.mjs";
|
|
2
|
-
import { A as renderMemories, F as renderThirdPartyPrivateRetrievables, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, _ as defaultRenderUntrustedContent, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, k as renderFirstPartyRetrievables, m as defaultRenderThirdPartyPublicRetrievables, o as defaultRenderChatCompletionsSystemPrompt, p as defaultRenderThirdPartyPrivateRetrievables, r as defaultDescriptionToChatCompletionsJsonSchema, s as defaultRenderFirstPartyRetrievables, u as defaultRenderRetrievableSafetyDirective, x as filterThoughts, y as descriptionToChatCompletionsJsonSchema, z as renderUntrustedContent } from "../../helpers-
|
|
2
|
+
import { A as renderMemories, F as renderThirdPartyPrivateRetrievables, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, _ as defaultRenderUntrustedContent, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, k as renderFirstPartyRetrievables, m as defaultRenderThirdPartyPublicRetrievables, o as defaultRenderChatCompletionsSystemPrompt, p as defaultRenderThirdPartyPrivateRetrievables, r as defaultDescriptionToChatCompletionsJsonSchema, s as defaultRenderFirstPartyRetrievables, u as defaultRenderRetrievableSafetyDirective, x as filterThoughts, y as descriptionToChatCompletionsJsonSchema, z as renderUntrustedContent } from "../../helpers-BH7HTtkD.mjs";
|
|
3
3
|
import { extractReasoningFields } from "./openai_chat_completions/helpers.mjs";
|
|
4
4
|
import { C as resolveReasoningParser, S as noneReasoningParser, _ as gemmaChannelReasoningParser, a as defaultResolveGenerationOptions, b as makeHarmonyAnalysisReasoningParser, c as DEFAULT_REASONING_PARSER_ORDER, d as defaultCreateAutoReasoningParser, f as defaultGemmaChannelReasoningParser, g as defaultThinkTagReasoningParser, h as defaultResolveReasoningParser, i as GENERATION_DEFAULTS, l as buildBundledReasoningParsers, m as defaultNoneReasoningParser, n as isGpuOutOfMemoryError, o as resolveGenerationOptions, p as defaultHarmonyAnalysisReasoningParser, r as probeGpuBudget, s as BUNDLED_REASONING_PARSERS, t as instrumentGpuBuffers, u as createAutoReasoningParser, v as harmonyAnalysisReasoningParser, w as thinkTagReasoningParser, x as makeThinkTagReasoningParser, y as makeGemmaChannelReasoningParser } from "../../gpu_budget-Bi2nUUil.mjs";
|
|
5
5
|
import { n as emitLifecycle, t as defaultEmitLifecycle } from "../../lifecycle-C4kwYJ-N.mjs";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../../chunk-Cek0wNdY.js");
|
|
3
3
|
const require_guards = require("../../../guards-05Uq3J4M.js");
|
|
4
|
-
const require_tokenizable = require("../../../tokenizable-
|
|
5
|
-
const require_spooled_artifact = require("../../../spooled_artifact-
|
|
6
|
-
const require_thought = require("../../../thought
|
|
7
|
-
const require_tool_call = require("../../../tool_call-
|
|
8
|
-
require("../../../common-
|
|
4
|
+
const require_tokenizable = require("../../../tokenizable-BMZuGWRd.js");
|
|
5
|
+
const require_spooled_artifact = require("../../../spooled_artifact-BpcesRBv.js");
|
|
6
|
+
const require_thought = require("../../../thought-bS7O9O5H.js");
|
|
7
|
+
const require_tool_call = require("../../../tool_call-Fs_Uh5wQ.js");
|
|
8
|
+
require("../../../common-H44Ik9ou.js");
|
|
9
9
|
require("../../../guards.cjs");
|
|
10
10
|
const require_tool_parsers = require("../../../tool_parsers-csSBFWob.js");
|
|
11
11
|
const require_batteries_storage_in_memory = require("../../storage/in_memory.cjs");
|
|
12
|
-
const require_helpers = require("../../../helpers-
|
|
12
|
+
const require_helpers = require("../../../helpers-CEjjkXso.js");
|
|
13
13
|
const require_batteries_llm_openai_chat_completions_helpers = require("../openai_chat_completions/helpers.cjs");
|
|
14
14
|
const require_lifecycle = require("../../../lifecycle-vYQJ2rmf.js");
|
|
15
15
|
const require_batteries_llm_webllm_chat_completions_exceptions = require("./exceptions.cjs");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.cjs","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 { emitLifecycle } from '../chat_common/lifecycle'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport { looksLikeSpooledArtifact, normalizeToolName } from '../chat_common/helpers'\nimport {\n Tokenizable,\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 defaultRenderRetrievableHandleBody,\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 extractReasoningFields,\n} from './helpers'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { Tool, Memory, TokenEncoding } from '@nhtio/adk/common'\nimport type { BatteryLifecyclePhase } from '../chat_common/lifecycle'\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 ReasoningField,\n} from './types'\n\n// MLC init-progress `text` markers that indicate the COMPILE sub-phase (WebGPU pipeline / shader build\n// / loading-from-cache), as opposed to network fetch. Best-effort: a miss just routes to `loading`, and\n// the coarse `compiling` marker before engine-create fires regardless.\nconst COMPILE_PROGRESS_RE =\n /shader|compil|from cache|gpu pipeline|finish loading|loading model from/i\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 'reasoningFieldPrecedence',\n 'helpers',\n 'strictToolChoice',\n 'unsupportedMediaPolicy',\n 'onInitProgress',\n 'isWebGPUAvailable',\n 'autoAck',\n 'enableThinking',\n // Observability hooks — never sent to the engine.\n 'onRawGeneration',\n 'onPromptAssembled',\n 'toolCallIdFilter',\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 renderRetrievableHandleBody:\n src.renderRetrievableHandleBody ?? defaultRenderRetrievableHandleBody,\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 /**\n * Whether the runtime can host a WebLLM engine — i.e. WebGPU (`navigator.gpu`) is present.\n *\n * @returns `true` when WebGPU is available in the current environment.\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 /**\n * Eagerly loads (and caches) the engine so the first dispatch does not pay the model-load cost.\n *\n * @param overrides - Optional option overrides layered over the constructor baseline.\n * @returns The resolved {@link WebLLMEngine}.\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 /** Drops the cached engine and any in-flight load so the next dispatch re-resolves it. */\n reset(): void {\n this.#engine = undefined\n this.#enginePromise = undefined\n }\n\n /**\n * Instance-level availability check, honouring an injected\n * {@link WebLLMChatCompletionsAdapterOptions.isWebGPUAvailable} override.\n *\n * @returns `true` when a WebLLM engine can run in the current environment.\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 emitLifecycle(merged, 'webllm', merged.model, 'loading', {\n detail: 'loading model + booting WebGPU runtime',\n })\n // Forward each MLC init-progress report ({progress 0..1, text, timeElapsed}) into a normalized\n // `loading` lifecycle report, while still calling the consumer's onInitProgress verbatim.\n const hasLifecycle =\n merged.onLifecycle ??\n merged.onLoading ??\n merged.onReady ??\n merged.onGenerating ??\n merged.onError\n const forwardedInitProgress = hasLifecycle\n ? (report: { progress?: number; text?: string }) => {\n // MLC's init reports cover BOTH fetch and shader/graph compilation; the text distinguishes\n // them (\"Loading model from cache\" / \"shader\" / \"GPU\" → the compile sub-phase). Route a\n // compile-flavored report to `compiling`, everything else to `loading`. Any miss falls back\n // to `loading` (no regression — the coarse `compiling` emit below still fires before create).\n const phase: BatteryLifecyclePhase = COMPILE_PROGRESS_RE.test(report?.text ?? '')\n ? 'compiling'\n : 'loading'\n emitLifecycle(merged, 'webllm', merged.model, phase, {\n ...(typeof report?.progress === 'number' ? { progress: report.progress } : {}),\n ...(report?.text ? { detail: report.text } : {}),\n raw: report,\n })\n merged.onInitProgress?.(report as never)\n }\n : merged.onInitProgress\n try {\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 // Coarse `compiling` marker: by the time MLC has the weights and is building the WebGPU pipeline,\n // this fires even if no init-report text matched COMPILE_PROGRESS_RE (the boundary the LiteRT chat\n // demo marks). Per-report `compiling` above refines it when MLC's text is granular enough.\n emitLifecycle(merged, 'webllm', merged.model, 'compiling', {\n detail: 'compiling model + WebGPU shaders',\n })\n const engine = await createEngine({\n model: merged.model,\n engineConfig: merged.engineConfig,\n chatOptions: merged.chatOptions,\n onInitProgress: forwardedInitProgress,\n })\n this.#engine = engine\n emitLifecycle(merged, 'webllm', merged.model, 'ready', { detail: 'engine ready' })\n return engine\n } catch (err) {\n this.#enginePromise = undefined\n emitLifecycle(merged, 'webllm', merged.model, 'error', { error: err })\n throw err\n }\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: artifact-reader tools ─────────────────────────────────────\n // Forged by the DispatchRunner CORE into `ctx.tools` before the input pipeline runs (generation is a\n // generic core concern; this battery owns only representation). Read the pre-forged `ctx.tools`\n // directly — no local merge, no bindContext here.\n\n // ── Step 4: pre-render tool-call results ──────────────────────────────\n const renderedToolCallResults = new Map<ToolCall, 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: ctx.tools.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, 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 +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n encoding,\n resolvedHelpers.renderRetrievableHandleBody\n )\n : 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 // Tool DECLARATIONS: WebLLM sends the visible tools as `body.tools` and MLC applies the model's\n // conversation template IN-PROCESS (browser), wrapping them per-model — so the exact rendered\n // string isn't reproducible here without the template. Tally the serialized tool JSON (the\n // reproducible, dominant component the adapter actually passes) as an honest FLOOR. Without this\n // the guard undercounts a tool-heavy prompt by the entire declaration block.\n let toolTokens = 0\n const visibleTools = ctx.tools.visible()\n if (visibleTools.length > 0) {\n const toolsJson = JSON.stringify(\n resolvedHelpers.toolsToChatCompletionsTools(visibleTools, {\n descriptionToChatCompletionsJsonSchema:\n resolvedHelpers.descriptionToChatCompletionsJsonSchema,\n })\n )\n toolTokens = await estimateTokensOf(new Tokenizable(toolsJson), encoding)\n }\n const total = spTokens + siTokens + memTokens + retTokens + tlTokens + toolTokens\n const perBucketObj = {\n systemPrompt: spTokens,\n standingInstructions: siTokens,\n memories: memTokens,\n retrievables: retTokens,\n timeline: tlTokens,\n tools: toolTokens,\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 = ctx.tools.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: ctx.tools,\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 renderRetrievableHandleBody: resolvedHelpers.renderRetrievableHandleBody,\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 // Thread the explicit thinking flag into extra_body.enable_thinking so the underlying chat\n // template never decides for itself (Qwen3/DeepSeek default thinking ON). Default OFF; merged with\n // any caller-supplied extra_body without clobbering it.\n body.extra_body = {\n ...(body.extra_body ?? {}),\n enable_thinking: merged.enableThinking ?? false,\n }\n const toolsArr = ctx.tools.visible()\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 // One id for this whole generation — correlates the TO tap (onPromptAssembled) with the FROM tap\n // (onRawGeneration) below.\n const dispatchStreamId = uuidv6()\n\n // Prompt-assembled observability tap: the EXACT request body going TO the engine, the instant it is\n // built and BEFORE create(). Mirror of onRawGeneration. Handed back AS-IS — no redaction — and\n // swallow observer errors so it can never corrupt the generation path.\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'webllm_chat_completions',\n kind: 'request-body',\n messages: body.messages,\n tools: body.tools,\n requestBody: body,\n streamed: stream,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // ── Step 7: invoke WebLLM engine ─────────────────────────────────────\n let completion: ChatCompletionsResponse | AsyncIterable<ChatCompletionsChunk>\n try {\n const engine = await this.#resolveEngine(merged)\n emitLifecycle(merged, 'webllm', merged.model, 'generating')\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 emitLifecycle(merged, 'webllm', merged.model, 'error', { error: err })\n ctx.nack(\n new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n\n // Spool store used to back string / Uint8Array tool returns. Bytes are written under the\n // call id; the resulting SpooledArtifact (or tool-configured subclass) is the model-visible\n // handle for the rest of the turn. Injectable via the `spoolStore` option so consumers can\n // back artifacts with durable storage (OPFS, Flydrive); defaults to an ephemeral per-dispatch\n // in-memory store. NOTE: an injected durable store persists across turns, so call ids must be\n // globally unique for that store (see the `spoolStore` option docs).\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n\n // ── Inner helper: persist + execute one assembled tool call ───────────\n const executeAndPersistToolCall = async (call: AssembledToolCall): Promise<void> => {\n // Resolve the vendor id once at ingress so reporting, persistence, and spooling agree.\n const callId = merged.toolCallIdFilter?.(call.id, ctx) ?? call.id\n const tool = ctx.tools.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 toolName = normalizeToolName(call.name)\n const results = new Tokenizable(parseError.message)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, {\n results,\n isError: true,\n isComplete: true,\n })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\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 toolName = normalizeToolName(call.name)\n // List the tools that DO exist so the model can self-correct on the next iteration\n // instead of guessing. Without this, a single typo'd / hallucinated tool name yields\n // a dead-end \"not found\" with no path forward.\n const available = ctx.tools\n .all()\n .map((t) => t.name)\n .sort()\n const errText =\n available.length > 0\n ? `Tool not found: ${toolName}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${toolName}. No tools are available this turn.`\n const results = new Tokenizable(errText)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, {\n results,\n isError: true,\n isComplete: true,\n })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\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(callId, { 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 (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(callId, 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 = await spoolStore.write(callId, 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(callId, {\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: callId,\n tool: tool.name,\n args,\n checksum,\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n // ArtifactTool results are the documented exception: they inline the slice the model queried\n // from a prior artifact (handing back a handle to a query result would be recursion). Every\n // other result keeps the secure default (inline:false → handle).\n inline: isArtifactTool,\n createdAt: completedAt2,\n updatedAt: completedAt2,\n completedAt: completedAt2,\n })\n )\n }\n\n // FALLBACK tool-call recovery. WebLLM's OpenAI-shaped `message.tool_calls` is authoritative; this is\n // consulted ONLY when the engine returned zero structured calls AND the caller opted in via\n // `localToolCallParser`. On-device small models routinely emit a call in a surface form the chat\n // template does not lift into `tool_calls` (`<call:name{…}`, a ```json block, bare `name\\nkey:\n // value`), landing it in `content`. Pure parse — returns assembled calls with `args` as the JSON\n // STRING `executeAndPersistToolCall` expects (empty when disabled or no match), so each call site can\n // reflect them in the onRawGeneration tap and then execute. Fully backward-compatible: absent option\n // → `[]` → today's native-only behaviour.\n const parseFallbackToolCalls = (content: string): AssembledToolCall[] => {\n if (merged.localToolCallParser === undefined) return []\n if (typeof content !== 'string' || content.length === 0) return []\n const parser = resolveToolCallParser(merged.localToolCallParser)\n const toolNames = ctx.tools.visible().map((t) => t.name)\n return parser(content, { toolNames }).calls.map((c) => ({\n id: uuidv6(),\n type: 'function' as const,\n name: c.name,\n args: JSON.stringify(c.arguments),\n }))\n }\n\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n const reasoningPrecedence = merged.reasoningFieldPrecedence ?? [\n 'reasoning',\n 'reasoning_content',\n ]\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 = dispatchStreamId\n\n let partialMessageContent = ''\n let sawMessageDelta = false\n\n // Reasoning may stream under more than one provider-specific field at once. Accumulate each\n // field's text under its own live stream id; at completion we dedup by content to decide\n // whether to persist one Thought or one per divergent field. The first field to appear keeps\n // the bare `streamId` (the common single-field case); any others get a `:field` suffix.\n const thoughtAccum = new Map<ReasoningField, string>()\n let primaryThoughtField: ReasoningField | undefined\n const thoughtStreamId = (field: ReasoningField): string =>\n field === primaryThoughtField ? streamId : `${streamId}:${field}`\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 // Finalize every reasoning stream we opened live, then dedup by content to decide how many\n // Thoughts to persist: one (fields agreed, or only one present) vs one per divergent field.\n for (const field of thoughtAccum.keys()) {\n helpers.reportThought(thoughtStreamId(field), '', { isComplete: true })\n }\n const thoughtExtracts = extractReasoningFields(\n Object.fromEntries(thoughtAccum) as Partial<Record<ReasoningField, string>>,\n reasoningPrecedence\n )\n if (thoughtExtracts.length === 1) {\n await ctx.storeThought(\n new Thought({\n id: streamId,\n content: thoughtExtracts[0].content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n } else {\n for (const { field, content } of thoughtExtracts) {\n await ctx.storeThought(\n new Thought({\n id: thoughtStreamId(field),\n content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n }\n const nativeCalls = accumulator.drain()\n // Fallback recovery (opt-in): if the engine streamed no structured calls, try to parse one out of\n // the accumulated `content`. Consulted only when native calls are absent, so the engine wins.\n const calls =\n nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(partialMessageContent)\n\n // Raw-generation observability tap (FROM the engine) — streaming path. `rawText`/`cleanedText`\n // are the accumulated assistant content; `toolCalls` are the calls this dispatch will act on\n // (native, or fallback-recovered — args JSON-parsed best-effort). Fired once at stream drain;\n // observer errors swallowed.\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: partialMessageContent,\n cleanedText: partialMessageContent,\n reasoning: thoughtExtracts.map((r) => r.content),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n helpers.log.debug({\n kind: 'accumulator-finalised',\n message: `Stream finalised: ${calls.length} tool call(s), message=${sawMessageDelta}, thoughtFields=${thoughtExtracts.length}`,\n payload: {\n toolCallCount: calls.length,\n sawMessageDelta,\n thoughtFieldCount: thoughtExtracts.length,\n },\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 // Stream every reasoning field present on this delta, in precedence order. No\n // mid-stream dedup — deltas are fragments; we compare full contents at completion.\n for (const field of reasoningPrecedence) {\n const reasoning = delta[field]\n if (typeof reasoning !== 'string' || reasoning.length === 0) continue\n if (!thoughtAccum.has(field)) {\n primaryThoughtField ??= field\n thoughtAccum.set(field, '')\n }\n thoughtAccum.set(field, thoughtAccum.get(field)! + reasoning)\n helpers.reportThought(thoughtStreamId(field), 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 emitLifecycle(merged, 'webllm', merged.model, 'error', { error: err })\n ctx.nack(\n new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n emitLifecycle(merged, 'webllm', merged.model, 'complete')\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 emitLifecycle(merged, 'webllm', merged.model, 'complete')\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 // Reasoning may arrive under more than one provider-specific field. A single extracted\n // entry (only one field present, or several but identical) keeps the historical\n // `${responseId}:thought` id; divergent fields each surface as their own thought.\n const reasoningExtracts = extractReasoningFields(msg, reasoningPrecedence)\n for (const { field, content } of reasoningExtracts) {\n const thoughtId =\n reasoningExtracts.length > 1 ? `${responseId}:thought:${field}` : `${responseId}:thought`\n helpers.reportThought(thoughtId, content, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: thoughtId,\n content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n const rawCalls = msg?.tool_calls ?? []\n const content = typeof msg?.content === 'string' ? msg.content : ''\n\n // Fallback recovery (opt-in): if the engine returned no structured calls, try to parse one out of the\n // assistant `content`. Consulted only when native calls are absent, so the engine always wins.\n const nativeCalls: 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 const calls = nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(content)\n\n // Raw-generation observability tap (FROM the engine) — non-streaming path. `rawText`/`cleanedText`\n // are the returned assistant content; `toolCalls` are the calls this dispatch will act on (native, or\n // fallback-recovered — args JSON-parsed best-effort). Fired once per terminal generation; observer\n // errors swallowed.\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: content,\n cleanedText: content,\n reasoning: reasoningExtracts.map((r) => r.content),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: false,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n if (calls.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 emitLifecycle(merged, 'webllm', merged.model, 'complete')\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 emitLifecycle(merged, 'webllm', merged.model, 'complete')\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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"}
|
|
1
|
+
{"version":3,"file":"adapter.cjs","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 { emitLifecycle } from '../chat_common/lifecycle'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport { looksLikeSpooledArtifact, normalizeToolName } from '../chat_common/helpers'\nimport {\n Tokenizable,\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 defaultRenderRetrievableHandleBody,\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 extractReasoningFields,\n} from './helpers'\nimport type { Tool, Memory } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { BatteryLifecyclePhase } from '../chat_common/lifecycle'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\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 ReasoningField,\n} from './types'\n\n// MLC init-progress `text` markers that indicate the COMPILE sub-phase (WebGPU pipeline / shader build\n// / loading-from-cache), as opposed to network fetch. Best-effort: a miss just routes to `loading`, and\n// the coarse `compiling` marker before engine-create fires regardless.\nconst COMPILE_PROGRESS_RE =\n /shader|compil|from cache|gpu pipeline|finish loading|loading model from/i\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 'reasoningFieldPrecedence',\n 'helpers',\n 'strictToolChoice',\n 'unsupportedMediaPolicy',\n 'onInitProgress',\n 'isWebGPUAvailable',\n 'autoAck',\n 'enableThinking',\n // Observability hooks — never sent to the engine.\n 'onRawGeneration',\n 'onPromptAssembled',\n 'toolCallIdFilter',\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 renderRetrievableHandleBody:\n src.renderRetrievableHandleBody ?? defaultRenderRetrievableHandleBody,\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: TokenEncodingId\n): Promise<number> => {\n return Promise.resolve(value.estimateTokens(encoding as TokenEncoding))\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 /**\n * Whether the runtime can host a WebLLM engine — i.e. WebGPU (`navigator.gpu`) is present.\n *\n * @returns `true` when WebGPU is available in the current environment.\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 /**\n * Eagerly loads (and caches) the engine so the first dispatch does not pay the model-load cost.\n *\n * @param overrides - Optional option overrides layered over the constructor baseline.\n * @returns The resolved {@link WebLLMEngine}.\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 /** Drops the cached engine and any in-flight load so the next dispatch re-resolves it. */\n reset(): void {\n this.#engine = undefined\n this.#enginePromise = undefined\n }\n\n /**\n * Instance-level availability check, honouring an injected\n * {@link WebLLMChatCompletionsAdapterOptions.isWebGPUAvailable} override.\n *\n * @returns `true` when a WebLLM engine can run in the current environment.\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 emitLifecycle(merged, 'webllm', merged.model, 'loading', {\n detail: 'loading model + booting WebGPU runtime',\n })\n // Forward each MLC init-progress report ({progress 0..1, text, timeElapsed}) into a normalized\n // `loading` lifecycle report, while still calling the consumer's onInitProgress verbatim.\n const hasLifecycle =\n merged.onLifecycle ??\n merged.onLoading ??\n merged.onReady ??\n merged.onGenerating ??\n merged.onError\n const forwardedInitProgress = hasLifecycle\n ? (report: { progress?: number; text?: string }) => {\n // MLC's init reports cover BOTH fetch and shader/graph compilation; the text distinguishes\n // them (\"Loading model from cache\" / \"shader\" / \"GPU\" → the compile sub-phase). Route a\n // compile-flavored report to `compiling`, everything else to `loading`. Any miss falls back\n // to `loading` (no regression — the coarse `compiling` emit below still fires before create).\n const phase: BatteryLifecyclePhase = COMPILE_PROGRESS_RE.test(report?.text ?? '')\n ? 'compiling'\n : 'loading'\n emitLifecycle(merged, 'webllm', merged.model, phase, {\n ...(typeof report?.progress === 'number' ? { progress: report.progress } : {}),\n ...(report?.text ? { detail: report.text } : {}),\n raw: report,\n })\n merged.onInitProgress?.(report as never)\n }\n : merged.onInitProgress\n try {\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 // Coarse `compiling` marker: by the time MLC has the weights and is building the WebGPU pipeline,\n // this fires even if no init-report text matched COMPILE_PROGRESS_RE (the boundary the LiteRT chat\n // demo marks). Per-report `compiling` above refines it when MLC's text is granular enough.\n emitLifecycle(merged, 'webllm', merged.model, 'compiling', {\n detail: 'compiling model + WebGPU shaders',\n })\n const engine = await createEngine({\n model: merged.model,\n engineConfig: merged.engineConfig,\n chatOptions: merged.chatOptions,\n onInitProgress: forwardedInitProgress,\n })\n this.#engine = engine\n emitLifecycle(merged, 'webllm', merged.model, 'ready', { detail: 'engine ready' })\n return engine\n } catch (err) {\n this.#enginePromise = undefined\n emitLifecycle(merged, 'webllm', merged.model, 'error', { error: err })\n throw err\n }\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: artifact-reader tools ─────────────────────────────────────\n // Forged by the DispatchRunner CORE into `ctx.tools` before the input pipeline runs (generation is a\n // generic core concern; this battery owns only representation). Read the pre-forged `ctx.tools`\n // directly — no local merge, no bindContext here.\n\n // ── Step 4: pre-render tool-call results ──────────────────────────────\n const renderedToolCallResults = new Map<ToolCall, 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: ctx.tools.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, rendered)\n }\n\n // ── Step 5: context window enforcement ────────────────────────────────\n if (merged.tokenEncoding !== null && merged.contextWindow !== undefined) {\n const encoding = merged.tokenEncoding as TokenEncodingId\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 +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n encoding as TokenEncoding,\n resolvedHelpers.renderRetrievableHandleBody\n )\n : 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 // Tool DECLARATIONS: WebLLM sends the visible tools as `body.tools` and MLC applies the model's\n // conversation template IN-PROCESS (browser), wrapping them per-model — so the exact rendered\n // string isn't reproducible here without the template. Tally the serialized tool JSON (the\n // reproducible, dominant component the adapter actually passes) as an honest FLOOR. Without this\n // the guard undercounts a tool-heavy prompt by the entire declaration block.\n let toolTokens = 0\n const visibleTools = ctx.tools.visible()\n if (visibleTools.length > 0) {\n const toolsJson = JSON.stringify(\n resolvedHelpers.toolsToChatCompletionsTools(visibleTools, {\n descriptionToChatCompletionsJsonSchema:\n resolvedHelpers.descriptionToChatCompletionsJsonSchema,\n })\n )\n toolTokens = await estimateTokensOf(new Tokenizable(toolsJson), encoding)\n }\n const total = spTokens + siTokens + memTokens + retTokens + tlTokens + toolTokens\n const perBucketObj = {\n systemPrompt: spTokens,\n standingInstructions: siTokens,\n memories: memTokens,\n retrievables: retTokens,\n timeline: tlTokens,\n tools: toolTokens,\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 = ctx.tools.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: ctx.tools,\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 renderRetrievableHandleBody: resolvedHelpers.renderRetrievableHandleBody,\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 // Thread the explicit thinking flag into extra_body.enable_thinking so the underlying chat\n // template never decides for itself (Qwen3/DeepSeek default thinking ON). Default OFF; merged with\n // any caller-supplied extra_body without clobbering it.\n body.extra_body = {\n ...(body.extra_body ?? {}),\n enable_thinking: merged.enableThinking ?? false,\n }\n const toolsArr = ctx.tools.visible()\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 // One id for this whole generation — correlates the TO tap (onPromptAssembled) with the FROM tap\n // (onRawGeneration) below.\n const dispatchStreamId = uuidv6()\n\n // Prompt-assembled observability tap: the EXACT request body going TO the engine, the instant it is\n // built and BEFORE create(). Mirror of onRawGeneration. Handed back AS-IS — no redaction — and\n // swallow observer errors so it can never corrupt the generation path.\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'webllm_chat_completions',\n kind: 'request-body',\n messages: body.messages,\n tools: body.tools,\n requestBody: body,\n streamed: stream,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // ── Step 7: invoke WebLLM engine ─────────────────────────────────────\n let completion: ChatCompletionsResponse | AsyncIterable<ChatCompletionsChunk>\n try {\n const engine = await this.#resolveEngine(merged)\n emitLifecycle(merged, 'webllm', merged.model, 'generating')\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 emitLifecycle(merged, 'webllm', merged.model, 'error', { error: err })\n ctx.nack(\n new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n\n // Spool store used to back string / Uint8Array tool returns. Bytes are written under the\n // call id; the resulting SpooledArtifact (or tool-configured subclass) is the model-visible\n // handle for the rest of the turn. Injectable via the `spoolStore` option so consumers can\n // back artifacts with durable storage (OPFS, Flydrive); defaults to an ephemeral per-dispatch\n // in-memory store. NOTE: an injected durable store persists across turns, so call ids must be\n // globally unique for that store (see the `spoolStore` option docs).\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n\n // ── Inner helper: persist + execute one assembled tool call ───────────\n const executeAndPersistToolCall = async (call: AssembledToolCall): Promise<void> => {\n // Resolve the vendor id once at ingress so reporting, persistence, and spooling agree.\n const callId = merged.toolCallIdFilter?.(call.id, ctx) ?? call.id\n const tool = ctx.tools.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 toolName = normalizeToolName(call.name)\n const results = new Tokenizable(parseError.message)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, {\n results,\n isError: true,\n isComplete: true,\n })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\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 toolName = normalizeToolName(call.name)\n // List the tools that DO exist so the model can self-correct on the next iteration\n // instead of guessing. Without this, a single typo'd / hallucinated tool name yields\n // a dead-end \"not found\" with no path forward.\n const available = ctx.tools\n .all()\n .map((t) => t.name)\n .sort()\n const errText =\n available.length > 0\n ? `Tool not found: ${toolName}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${toolName}. No tools are available this turn.`\n const results = new Tokenizable(errText)\n helpers.reportToolCall(callId, { tool: toolName, args })\n helpers.reportToolCall(callId, {\n results,\n isError: true,\n isComplete: true,\n })\n const checksum = computeChecksum(toolName, args)\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: toolName,\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(callId, { 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 (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(callId, 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 = await spoolStore.write(callId, 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(callId, {\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: callId,\n tool: tool.name,\n args,\n checksum,\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n // ArtifactTool results are the documented exception: they inline the slice the model queried\n // from a prior artifact (handing back a handle to a query result would be recursion). Every\n // other result keeps the secure default (inline:false → handle).\n inline: isArtifactTool,\n createdAt: completedAt2,\n updatedAt: completedAt2,\n completedAt: completedAt2,\n })\n )\n }\n\n // FALLBACK tool-call recovery. WebLLM's OpenAI-shaped `message.tool_calls` is authoritative; this is\n // consulted ONLY when the engine returned zero structured calls AND the caller opted in via\n // `localToolCallParser`. On-device small models routinely emit a call in a surface form the chat\n // template does not lift into `tool_calls` (`<call:name{…}`, a ```json block, bare `name\\nkey:\n // value`), landing it in `content`. Pure parse — returns assembled calls with `args` as the JSON\n // STRING `executeAndPersistToolCall` expects (empty when disabled or no match), so each call site can\n // reflect them in the onRawGeneration tap and then execute. Fully backward-compatible: absent option\n // → `[]` → today's native-only behaviour.\n const parseFallbackToolCalls = (content: string): AssembledToolCall[] => {\n if (merged.localToolCallParser === undefined) return []\n if (typeof content !== 'string' || content.length === 0) return []\n const parser = resolveToolCallParser(merged.localToolCallParser)\n const toolNames = ctx.tools.visible().map((t) => t.name)\n return parser(content, { toolNames }).calls.map((c) => ({\n id: uuidv6(),\n type: 'function' as const,\n name: c.name,\n args: JSON.stringify(c.arguments),\n }))\n }\n\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n const reasoningPrecedence = merged.reasoningFieldPrecedence ?? [\n 'reasoning',\n 'reasoning_content',\n ]\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 = dispatchStreamId\n\n let partialMessageContent = ''\n let sawMessageDelta = false\n\n // Reasoning may stream under more than one provider-specific field at once. Accumulate each\n // field's text under its own live stream id; at completion we dedup by content to decide\n // whether to persist one Thought or one per divergent field. The first field to appear keeps\n // the bare `streamId` (the common single-field case); any others get a `:field` suffix.\n const thoughtAccum = new Map<ReasoningField, string>()\n let primaryThoughtField: ReasoningField | undefined\n const thoughtStreamId = (field: ReasoningField): string =>\n field === primaryThoughtField ? streamId : `${streamId}:${field}`\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 // Finalize every reasoning stream we opened live, then dedup by content to decide how many\n // Thoughts to persist: one (fields agreed, or only one present) vs one per divergent field.\n for (const field of thoughtAccum.keys()) {\n helpers.reportThought(thoughtStreamId(field), '', { isComplete: true })\n }\n const thoughtExtracts = extractReasoningFields(\n Object.fromEntries(thoughtAccum) as Partial<Record<ReasoningField, string>>,\n reasoningPrecedence\n )\n if (thoughtExtracts.length === 1) {\n await ctx.storeThought(\n new Thought({\n id: streamId,\n content: thoughtExtracts[0].content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n } else {\n for (const { field, content } of thoughtExtracts) {\n await ctx.storeThought(\n new Thought({\n id: thoughtStreamId(field),\n content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n }\n const nativeCalls = accumulator.drain()\n // Fallback recovery (opt-in): if the engine streamed no structured calls, try to parse one out of\n // the accumulated `content`. Consulted only when native calls are absent, so the engine wins.\n const calls =\n nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(partialMessageContent)\n\n // Raw-generation observability tap (FROM the engine) — streaming path. `rawText`/`cleanedText`\n // are the accumulated assistant content; `toolCalls` are the calls this dispatch will act on\n // (native, or fallback-recovered — args JSON-parsed best-effort). Fired once at stream drain;\n // observer errors swallowed.\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: partialMessageContent,\n cleanedText: partialMessageContent,\n reasoning: thoughtExtracts.map((r) => r.content),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n helpers.log.debug({\n kind: 'accumulator-finalised',\n message: `Stream finalised: ${calls.length} tool call(s), message=${sawMessageDelta}, thoughtFields=${thoughtExtracts.length}`,\n payload: {\n toolCallCount: calls.length,\n sawMessageDelta,\n thoughtFieldCount: thoughtExtracts.length,\n },\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 // Stream every reasoning field present on this delta, in precedence order. No\n // mid-stream dedup — deltas are fragments; we compare full contents at completion.\n for (const field of reasoningPrecedence) {\n const reasoning = delta[field]\n if (typeof reasoning !== 'string' || reasoning.length === 0) continue\n if (!thoughtAccum.has(field)) {\n primaryThoughtField ??= field\n thoughtAccum.set(field, '')\n }\n thoughtAccum.set(field, thoughtAccum.get(field)! + reasoning)\n helpers.reportThought(thoughtStreamId(field), 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 emitLifecycle(merged, 'webllm', merged.model, 'error', { error: err })\n ctx.nack(\n new E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n emitLifecycle(merged, 'webllm', merged.model, 'complete')\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 emitLifecycle(merged, 'webllm', merged.model, 'complete')\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 // Reasoning may arrive under more than one provider-specific field. A single extracted\n // entry (only one field present, or several but identical) keeps the historical\n // `${responseId}:thought` id; divergent fields each surface as their own thought.\n const reasoningExtracts = extractReasoningFields(msg, reasoningPrecedence)\n for (const { field, content } of reasoningExtracts) {\n const thoughtId =\n reasoningExtracts.length > 1 ? `${responseId}:thought:${field}` : `${responseId}:thought`\n helpers.reportThought(thoughtId, content, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: thoughtId,\n content,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n const rawCalls = msg?.tool_calls ?? []\n const content = typeof msg?.content === 'string' ? msg.content : ''\n\n // Fallback recovery (opt-in): if the engine returned no structured calls, try to parse one out of the\n // assistant `content`. Consulted only when native calls are absent, so the engine always wins.\n const nativeCalls: 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 const calls = nativeCalls.length > 0 ? nativeCalls : parseFallbackToolCalls(content)\n\n // Raw-generation observability tap (FROM the engine) — non-streaming path. `rawText`/`cleanedText`\n // are the returned assistant content; `toolCalls` are the calls this dispatch will act on (native, or\n // fallback-recovered — args JSON-parsed best-effort). Fired once per terminal generation; observer\n // errors swallowed.\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: content,\n cleanedText: content,\n reasoning: reasoningExtracts.map((r) => r.content),\n toolCalls: calls.map((c) => {\n let parsedArgs: Record<string, unknown> = {}\n try {\n const p: unknown = JSON.parse(c.args || '{}')\n if (isObject(p)) parsedArgs = p as Record<string, unknown>\n } catch {\n /* leave args empty on unparseable JSON */\n }\n return { name: c.name, arguments: parsedArgs as never }\n }),\n streamed: false,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n if (calls.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 emitLifecycle(merged, 'webllm', merged.model, 'complete')\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 emitLifecycle(merged, 'webllm', merged.model, 'complete')\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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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as isInstanceOf, r as isObject, t as isError } from "../../../guards-BEpY7lBI.mjs";
|
|
2
|
-
import { r as Tokenizable } from "../../../tokenizable-
|
|
3
|
-
import {
|
|
4
|
-
import { n as Message, t as Thought } from "../../../thought-
|
|
5
|
-
import { n as Media, t as ToolCall } from "../../../tool_call-
|
|
6
|
-
import "../../../common-
|
|
2
|
+
import { r as Tokenizable } from "../../../tokenizable-VB4Av8GF.mjs";
|
|
3
|
+
import { f as ArtifactTool, h as canonicalStringify, t as SpooledArtifact } from "../../../spooled_artifact-Bw_7swIp.mjs";
|
|
4
|
+
import { n as Message, t as Thought } from "../../../thought-BE1KGEhV.mjs";
|
|
5
|
+
import { n as Media, t as ToolCall } from "../../../tool_call-Cfaj-6zK.mjs";
|
|
6
|
+
import "../../../common-BpdHIpQE.mjs";
|
|
7
7
|
import "../../../guards.mjs";
|
|
8
8
|
import { O as resolveToolCallParser } from "../../../tool_parsers-DgZhgxV8.mjs";
|
|
9
9
|
import { InMemorySpoolStore } from "../../storage/in_memory.mjs";
|
|
10
|
-
import { C as looksLikeSpooledArtifact, E as normalizeToolName, _ as defaultRenderUntrustedContent, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, l as defaultRenderRetrievableHandleBody, m as defaultRenderThirdPartyPublicRetrievables, o as defaultRenderChatCompletionsSystemPrompt, p as defaultRenderThirdPartyPrivateRetrievables, r as defaultDescriptionToChatCompletionsJsonSchema, s as defaultRenderFirstPartyRetrievables, u as defaultRenderRetrievableSafetyDirective, v as defaultToolsToChatCompletionsTools } from "../../../helpers-
|
|
10
|
+
import { C as looksLikeSpooledArtifact, E as normalizeToolName, _ as defaultRenderUntrustedContent, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, l as defaultRenderRetrievableHandleBody, m as defaultRenderThirdPartyPublicRetrievables, o as defaultRenderChatCompletionsSystemPrompt, p as defaultRenderThirdPartyPrivateRetrievables, r as defaultDescriptionToChatCompletionsJsonSchema, s as defaultRenderFirstPartyRetrievables, u as defaultRenderRetrievableSafetyDirective, v as defaultToolsToChatCompletionsTools } from "../../../helpers-BH7HTtkD.mjs";
|
|
11
11
|
import { defaultBuildChatCompletionsHistory, defaultCreateChatCompletionsToolCallDeltaAccumulator, defaultRenderChatCompletionsToolCallResult, defaultRenderTimelineMessage, extractReasoningFields } from "../openai_chat_completions/helpers.mjs";
|
|
12
12
|
import { n as emitLifecycle } from "../../../lifecycle-C4kwYJ-N.mjs";
|
|
13
13
|
import { E_INVALID_WEBLLM_CHAT_COMPLETIONS_OPTIONS, E_WEBLLM_CHAT_COMPLETIONS_CONTEXT_OVERFLOW, E_WEBLLM_CHAT_COMPLETIONS_INVALID_TOOL_CALL_ARGS, E_WEBLLM_CHAT_COMPLETIONS_STREAM_ERROR } from "./exceptions.mjs";
|