@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":"adapter.mjs","names":["#baseline","#pipeline","#resolvePipeline","#pipelinePromise","#mmEngine","#mmEnginePromise","#gen","#resolveMultimodalEngine","#multimodalFlags","#generateKwargs"],"sources":["../../../../src/batteries/llm/transformers_js/adapter.ts"],"sourcesContent":["/**\n * Dual-environment (Node + browser) executor adapter for transformers.js (`@huggingface/transformers`).\n *\n * @module @nhtio/adk/batteries/llm/transformers_js/adapter\n *\n * @remarks\n * On-device text generation via ONNX Runtime — `onnxruntime-node` (native) in Node, `onnxruntime-web`\n * (WASM + WebGPU) in the browser, auto-selected by the package. So this battery is\n * **environment-neutral**: it does NOT gate on WebGPU.\n *\n * **transformers.js is text-in / text-out.** It injects tool definitions into the chat template but\n * does NOT return structured tool calls or reasoning — the model emits both as **family-specific raw\n * text**. This adapter parses them out via the shared, configurable parser layer (`toolCallParser` /\n * `reasoningParser`, both defaulting to `'auto'`): after generation, the reasoning parser pulls\n * thinking into ADK Thoughts and the tool-call parser pulls calls into ADK ToolCalls, leaving clean\n * prose as the assistant Message.\n *\n * Three pluggable layers mirror the other LLM batteries: swappable translation helpers, three-layer\n * options merging (constructor → `executor()` overrides → `ctx.stash.transformersJs`), and an\n * injectable/lazy pipeline (`pipeline` or `createPipeline`, defaulting to a dynamic import).\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { withModelSource } from './model_source'\nimport { emitLifecycle } from '../chat_common/lifecycle'\nimport { E_LLM_GPU_OUT_OF_MEMORY } from '../chat_common/exceptions'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { resolveGenerationOptions } from '../chat_common/generation'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { resolveReasoningParser } from '../chat_common/reasoning_parsers'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport { isGpuOutOfMemoryError, probeGpuBudget } from '../chat_common/gpu_budget'\nimport {\n looksLikeSpooledArtifact,\n stripEnvelopeSpecialTokens,\n normalizeToolName,\n} 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_TRANSFORMERS_JS_CONTEXT_OVERFLOW,\n E_TRANSFORMERS_JS_STREAM_ERROR,\n E_TRANSFORMERS_JS_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 defaultRenderThought,\n defaultFilterThoughts,\n defaultRenderChatCompletionsSystemPrompt,\n defaultToolsToTransformersJsTools,\n defaultRenderTransformersJsToolResult,\n defaultRenderArtifactHandleBody,\n defaultBuildTransformersJsMessages,\n defaultMediaToTransformersInput,\n defaultCreateTransformersJsStreamAccumulator,\n} from './helpers'\nimport type { Tool } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { ParsedToolCall } from '../chat_common/tool_parsers'\nimport type { ChatSampler, ResolvedGenerationOptions } from '../chat_common/generation'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/dispatch_runner'\nimport type {\n TransformersJsAdapterOptions,\n TransformersJsPipeline,\n TransformersJsModel,\n TransformersJsProcessor,\n} from './types'\n\n// ─── Option merging (constructor → executor overrides → stash) ────────────────────────────────────\n\nconst mergeHelpers = (\n layers: ReadonlyArray<Partial<NonNullable<TransformersJsAdapterOptions['helpers']>> | undefined>\n): Partial<NonNullable<TransformersJsAdapterOptions['helpers']>> | undefined => {\n let merged: Partial<NonNullable<TransformersJsAdapterOptions['helpers']>> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: TransformersJsAdapterOptions,\n exec: Partial<TransformersJsAdapterOptions> | undefined,\n stash: Partial<TransformersJsAdapterOptions> | undefined\n): Partial<TransformersJsAdapterOptions> => {\n const layers = [baseline as Partial<TransformersJsAdapterOptions>, 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<TransformersJsAdapterOptions>\n}\n\n// ─── Helper resolution (fall back to bundled defaults per field) ──────────────────────────────────\n\ninterface ResolvedHelpers {\n descriptionToChatCompletionsJsonSchema: typeof defaultDescriptionToChatCompletionsJsonSchema\n renderUntrustedContent: typeof defaultRenderUntrustedContent\n renderTrustedContent: typeof defaultRenderTrustedContent\n renderStandingInstructions: typeof defaultRenderStandingInstructions\n renderMemories: typeof defaultRenderMemories\n renderRetrievables: typeof defaultRenderRetrievables\n renderRetrievableSafetyDirective: typeof defaultRenderRetrievableSafetyDirective\n renderFirstPartyRetrievables: typeof defaultRenderFirstPartyRetrievables\n renderThirdPartyPublicRetrievables: typeof defaultRenderThirdPartyPublicRetrievables\n renderThirdPartyPrivateRetrievables: typeof defaultRenderThirdPartyPrivateRetrievables\n renderThought: typeof defaultRenderThought\n filterThoughts: typeof defaultFilterThoughts\n renderChatCompletionsSystemPrompt: typeof defaultRenderChatCompletionsSystemPrompt\n toolsToTransformersJsTools: typeof defaultToolsToTransformersJsTools\n renderTransformersJsToolResult: typeof defaultRenderTransformersJsToolResult\n renderArtifactHandleBody: typeof defaultRenderArtifactHandleBody\n renderRetrievableHandleBody: typeof defaultRenderRetrievableHandleBody\n buildTransformersJsMessages: typeof defaultBuildTransformersJsMessages\n createTransformersJsStreamAccumulator: typeof defaultCreateTransformersJsStreamAccumulator\n}\n\nconst resolveHelpers = (\n overrides: Partial<TransformersJsAdapterOptions['helpers']> | undefined\n): ResolvedHelpers => {\n const src = (overrides ?? {}) as Record<string, unknown>\n const pick = <K extends keyof ResolvedHelpers>(\n key: K,\n dflt: ResolvedHelpers[K]\n ): ResolvedHelpers[K] => (src[key as string] as ResolvedHelpers[K]) ?? dflt\n return {\n descriptionToChatCompletionsJsonSchema: pick(\n 'descriptionToChatCompletionsJsonSchema',\n defaultDescriptionToChatCompletionsJsonSchema\n ),\n renderUntrustedContent: pick('renderUntrustedContent', defaultRenderUntrustedContent),\n renderTrustedContent: pick('renderTrustedContent', defaultRenderTrustedContent),\n renderStandingInstructions: pick(\n 'renderStandingInstructions',\n defaultRenderStandingInstructions\n ),\n renderMemories: pick('renderMemories', defaultRenderMemories),\n renderRetrievables: pick('renderRetrievables', defaultRenderRetrievables),\n renderRetrievableSafetyDirective: pick(\n 'renderRetrievableSafetyDirective',\n defaultRenderRetrievableSafetyDirective\n ),\n renderFirstPartyRetrievables: pick(\n 'renderFirstPartyRetrievables',\n defaultRenderFirstPartyRetrievables\n ),\n renderThirdPartyPublicRetrievables: pick(\n 'renderThirdPartyPublicRetrievables',\n defaultRenderThirdPartyPublicRetrievables\n ),\n renderThirdPartyPrivateRetrievables: pick(\n 'renderThirdPartyPrivateRetrievables',\n defaultRenderThirdPartyPrivateRetrievables\n ),\n renderThought: pick('renderThought', defaultRenderThought),\n filterThoughts: pick('filterThoughts', defaultFilterThoughts),\n renderChatCompletionsSystemPrompt: pick(\n 'renderChatCompletionsSystemPrompt',\n defaultRenderChatCompletionsSystemPrompt\n ),\n toolsToTransformersJsTools: pick(\n 'toolsToTransformersJsTools',\n defaultToolsToTransformersJsTools\n ),\n renderTransformersJsToolResult: pick(\n 'renderTransformersJsToolResult',\n defaultRenderTransformersJsToolResult\n ),\n renderArtifactHandleBody: pick('renderArtifactHandleBody', defaultRenderArtifactHandleBody),\n renderRetrievableHandleBody: pick(\n 'renderRetrievableHandleBody',\n defaultRenderRetrievableHandleBody\n ),\n buildTransformersJsMessages: pick(\n 'buildTransformersJsMessages',\n defaultBuildTransformersJsMessages\n ),\n createTransformersJsStreamAccumulator: pick(\n 'createTransformersJsStreamAccumulator',\n defaultCreateTransformersJsStreamAccumulator\n ),\n }\n}\n\nconst nowIso = (): string => DateTime.now().toISO() as string\n\nconst computeChecksum = (tool: string, args: Record<string, unknown>): string =>\n sha256(canonicalStringify({ tool, args }))\n\n/**\n * Wrap the consumer's `onInitProgress` so each transformers.js download event ALSO emits a normalized\n * `loading` lifecycle report. The HF `progress` field is 0..100 → forwarded as `progress` 0..1, with the\n * raw payload on `raw`. The original `onInitProgress` is still called verbatim (additive). Returns the\n * original callback unchanged when no lifecycle hooks are configured (zero overhead on the text path).\n */\nconst wrapTransformersInitProgress = (\n merged: TransformersJsAdapterOptions\n): TransformersJsAdapterOptions['onInitProgress'] => {\n const hasLifecycle =\n merged.onLifecycle ??\n merged.onLoading ??\n merged.onReady ??\n merged.onGenerating ??\n merged.onError\n if (!hasLifecycle) return merged.onInitProgress\n return (info: unknown) => {\n const p = (info as { progress?: number } | undefined)?.progress\n emitLifecycle(merged, 'transformers_js', merged.model, 'loading', {\n ...(typeof p === 'number' ? { progress: p / 100 } : {}),\n raw: info,\n })\n merged.onInitProgress?.(info as never)\n }\n}\n\n/** Markers that signal the start of tool-call / reasoning markup — used to stop streaming prose. */\nconst TEXT_MARKUP_MARKERS = [\n '<tool_call>',\n '<|tool_call>',\n '<|channel',\n '<think',\n '[TOOL_CALLS]',\n '<function=',\n]\n\n/** An assembled tool call ready for execution (args already a parsed object). */\ninterface AssembledToolCall {\n id: string\n name: string\n args: Record<string, unknown>\n argsWellFormed: boolean\n}\n\n/**\n * Translate a generation-time throw into the right battery exception: a typed, catchable\n * {@link @nhtio/adk/batteries!E_LLM_GPU_OUT_OF_MEMORY} when the message matches a known WebGPU\n * exhaustion signature (so an application can `catch` it structurally instead of string-matching ORT\n * internals — surface, don't impose), else the generic {@link E_TRANSFORMERS_JS_STREAM_ERROR}.\n *\n * @param err - The raw thrown value from `generate()` / streamer / pipeline.\n * @param contextNote - A short human-readable budget/window note carried on the OOM error's message,\n * shown to the user verbatim by the application layer.\n */\nconst toGenerationError = (\n err: unknown,\n contextNote: string\n):\n | InstanceType<typeof E_LLM_GPU_OUT_OF_MEMORY>\n | InstanceType<typeof E_TRANSFORMERS_JS_STREAM_ERROR> => {\n const message = isError(err) ? err.message : String(err)\n if (isGpuOutOfMemoryError(message)) {\n return new E_LLM_GPU_OUT_OF_MEMORY([message, contextNote], {\n cause: isError(err) ? err : undefined,\n })\n }\n return new E_TRANSFORMERS_JS_STREAM_ERROR([message])\n}\n\n/**\n * Whether the resolved device targets the WebGPU execution provider (a scalar `'webgpu'` or a\n * per-submodule record that puts the decoder on webgpu). KV-cache GPU-pinning only applies there —\n * on the wasm/cpu EP there is no `'gpu-buffer'` location and the pin would be meaningless.\n */\nconst isWebGpuDevice = (device: TransformersJsAdapterOptions['device']): boolean => {\n if (device === undefined) return false\n if (typeof device === 'string') return device === 'webgpu' || device === 'gpu'\n // Per-submodule record: pin if the decoder (or any submodule) runs on webgpu.\n return Object.values(device).some((d) => d === 'webgpu' || d === 'gpu')\n}\n\n/**\n * Build a `preferredOutputLocation` map pinning every KV-cache output (`present.N.key` /\n * `present.N.value`) to `'gpu-buffer'`, so the autoregressive KV cache lives in GPU memory instead of\n * the ONNX-Runtime-Web **wasm32 linear-memory heap** (hard-capped at 4 GiB by the 32-bit address space).\n *\n * @remarks\n * This is the battery's headline in-browser memory fix. transformers.js HAS auto-pinning for this\n * (session.js builds the same map for `cache_sessions` on webgpu), but it silently no-ops on models\n * whose config nests the head/layer counts (e.g. Gemma-4's `text_config`): `getCacheNames` returns\n * empty, so the decoder loads with `preferredOutputLocation: null` and the KV cache stays on the wasm\n * heap (measured: the live `present.*` tensors report `location: \"cpu\"`). Passing the map EXPLICITLY\n * moves them to `location: \"gpu-buffer\"` (measured). We over-specify the layer count — extra\n * `present.*` names that the model doesn't emit are simply ignored by the runtime — so we don't have to\n * read the architecture's layer count first. 96 covers every open-weight decoder we target.\n */\nconst buildKvCacheGpuPinMap = (layers = 96): Record<string, 'gpu-buffer'> => {\n const map: Record<string, 'gpu-buffer'> = {}\n for (let i = 0; i < layers; i++) {\n map[`present.${i}.key`] = 'gpu-buffer'\n map[`present.${i}.value`] = 'gpu-buffer'\n }\n return map\n}\n\n/**\n * Resolve the effective ONNX `session_options` for a load, applying the KV-cache GPU-pin DEFAULT.\n *\n * @remarks\n * Policy (surface-a-safe-default, keep the escape hatch): on the WebGPU EP, pin the KV cache to\n * `'gpu-buffer'` BY DEFAULT (keeps it off the 4 GiB wasm32 heap — the wall hit first in-browser). The\n * consumer can opt out wholesale (`pinKvCacheToGpu: false`) or override precisely (set their own\n * `sessionOptions.preferredOutputLocation`, which always wins — we never clobber an explicit one). On a\n * non-WebGPU device the pin is skipped (no `'gpu-buffer'` location exists there). Returns `undefined`\n * when there is nothing to pass (so the loader's `...(sessionOptions ? … : {})` spread stays a no-op).\n */\nconst resolveSessionOptions = (\n merged: TransformersJsAdapterOptions\n): TransformersJsAdapterOptions['sessionOptions'] | undefined => {\n const explicit = merged.sessionOptions\n const wantPin = (merged.pinKvCacheToGpu ?? true) && isWebGpuDevice(merged.device)\n // Don't pin if disabled, off-WebGPU, or the consumer already chose an output location (their call).\n if (!wantPin || explicit?.preferredOutputLocation !== undefined) return explicit\n return { ...(explicit ?? {}), preferredOutputLocation: buildKvCacheGpuPinMap() }\n}\n\n/**\n * Dual-environment executor adapter for transformers.js text generation.\n *\n * @remarks\n * Construct with at least `{ model }`; wire `new TransformersJsAdapter(opts).executor()` into a\n * `DispatchRunner` as the `executorCallback`. The pipeline is resolved lazily on first dispatch (or\n * eagerly via {@link TransformersJsAdapter.preload}); pass `pipeline` to inject a pre-built one.\n */\nexport class TransformersJsAdapter {\n /** The `ctx.stash` key under which per-dispatch option overrides are read. */\n public static readonly STASH_KEY = 'transformersJs' as const\n\n readonly #baseline: TransformersJsAdapterOptions\n #pipeline: TransformersJsPipeline | undefined\n #pipelinePromise: Promise<TransformersJsPipeline> | undefined\n #mmEngine: { model: TransformersJsModel; processor: TransformersJsProcessor } | undefined\n #mmEnginePromise:\n | Promise<{\n model: TransformersJsModel\n processor: TransformersJsProcessor\n }>\n | undefined\n\n /**\n * Whether this battery is available. transformers.js is environment-neutral (Node + browser), so this\n * is `true` whenever the runtime can import the peer — there is no WebGPU requirement. Static form\n * returns `true`; the instance form honours an injected `isAvailable` override.\n */\n public static isAvailable(): boolean {\n return true\n }\n\n /**\n * @param options - Raw adapter options, validated against `transformersJsOptionsSchema`.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_OPTIONS} when `options` are invalid.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n this.#pipeline = this.#baseline.pipeline\n }\n\n /** Instance availability probe (honours the `isAvailable` option override). */\n isAvailable(): boolean {\n return (this.#baseline.isAvailable ?? TransformersJsAdapter.isAvailable)()\n }\n\n /**\n * Eagerly resolve (load) the pipeline before the first dispatch.\n *\n * @param overrides - Optional option overrides applied for this load.\n */\n async preload(\n overrides?: Partial<TransformersJsAdapterOptions>\n ): Promise<TransformersJsPipeline> {\n const merged = validateOptions(mergeOptions(this.#baseline, overrides, undefined))\n return this.#resolvePipeline(merged)\n }\n\n /** Drop the cached pipeline/engine and any in-flight load so the next dispatch re-resolves it. */\n reset(): void {\n this.#pipeline = undefined\n this.#pipelinePromise = undefined\n this.#mmEngine = undefined\n this.#mmEnginePromise = undefined\n }\n\n /**\n * Release the loaded model's underlying ONNX sessions + GPU/wasm buffers, then drop all cached\n * references (so the next dispatch re-resolves a fresh pipeline).\n *\n * @remarks\n * `reset()` only nulls the JS references — it does NOT free the native ONNX Runtime sessions or the\n * WebGPU/wasm device memory they hold. Those leak until GC, and in a browser session that loads many\n * models back-to-back (e.g. a full matrix run) the accumulated sessions exhaust the heap, surfacing as\n * `Can't create a session … Failed to load external data file … memory copy`. transformers.js exposes\n * `PreTrainedModel.dispose()` (\"disposes of all the ONNX sessions created during inference\") and\n * `Pipeline.dispose()` — this awaits them so the memory is actually reclaimed between loads. Settles any\n * in-flight load first, swallows per-handle disposal errors (a half-loaded model must not throw out of\n * teardown), and finishes with `reset()`. Idempotent and safe to call when nothing is loaded.\n */\n async dispose(): Promise<void> {\n // Settle any in-flight load so we dispose the resolved handle rather than orphaning it.\n const pipeline = this.#pipeline ?? (await this.#pipelinePromise?.catch(() => undefined))\n const mmEngine = this.#mmEngine ?? (await this.#mmEnginePromise?.catch(() => undefined))\n const disposables: Array<Promise<unknown>> = []\n const pipeWithDispose = pipeline as { dispose?: () => Promise<unknown> } | undefined\n if (typeof pipeWithDispose?.dispose === 'function') {\n disposables.push(Promise.resolve(pipeWithDispose.dispose()).catch(() => undefined))\n }\n const mmModel = mmEngine?.model as { dispose?: () => Promise<unknown> } | undefined\n if (typeof mmModel?.dispose === 'function') {\n disposables.push(Promise.resolve(mmModel.dispose()).catch(() => undefined))\n }\n await Promise.all(disposables)\n this.reset()\n }\n\n /**\n * Free the WebGPU buffer cache by releasing the model's ONNX sessions, then reload the same model.\n *\n * @remarks\n * The consumer-facing lever for the ONNX Runtime Web WebGPU **buffer-freelist high-water-mark** (see\n * {@link @nhtio/adk/batteries!probeGpuBudget} and the battery's GPU-budget notes). ORT-web parks freed\n * activation buffers in per-size buckets sized to the largest tensor shape the model has run; the pool\n * is flushed ONLY when every session of the model is released (ORT clears the cache at\n * `sessionCount === 0`; microsoft/onnxruntime#22490). There is no public flag to flush it mid-life, so\n * the supported way to reclaim that retained working-set without permanently unloading the model is to\n * dispose the sessions and load again.\n *\n * This is exactly `dispose()` followed by `preload()` — surfaced as a named method because \"recycle to\n * free the GPU buffer cache\" is a distinct, intentional operation (e.g. an application offering a\n * \"free GPU memory\" action after a {@link @nhtio/adk/batteries!E_LLM_GPU_OUT_OF_MEMORY}), not a\n * teardown. It is NOT invoked automatically by the battery — the ADK surfaces the lever and leaves the\n * decision to the consumer. Re-incurs the cold-load cost (download is cached; the WebGPU graph/shader\n * compile is not). Idempotent.\n *\n * @param overrides - Optional option overrides applied to the reload (same as {@link preload}).\n */\n async recycle(overrides?: Partial<TransformersJsAdapterOptions>): Promise<void> {\n await this.dispose()\n await this.preload(overrides)\n }\n\n /**\n * Resolve the PORTABLE generation contract (shared with LiteRT-LM) from the merged options. Canonical\n * fields win; the transformers.js-native fields ({@link TransformersJsAdapterOptions.maxNewTokens},\n * `doSample`, `multimodal`, …) are the fallback layer consulted only when the canonical one is unset.\n */\n #gen(merged: TransformersJsAdapterOptions): ResolvedGenerationOptions {\n // Native `multimodal` is `boolean | {image,audio}` → normalise to the canonical `{image,audio}` shape.\n const mm = merged.multimodal\n const normalizedMultimodal: { image?: boolean; audio?: boolean } | undefined =\n mm === undefined || mm === false\n ? mm === false\n ? { image: false, audio: false }\n : undefined\n : mm === true\n ? { image: true, audio: true }\n : mm\n // Native `doSample` boolean → canonical sampler strategy. `true` becomes `'top-p'` (the common\n // nucleus default); an explicit `sampler` canonical field overrides this entirely.\n const nativeSampler: ChatSampler | undefined =\n merged.doSample === undefined ? undefined : merged.doSample ? 'top-p' : 'greedy'\n return resolveGenerationOptions(\n {\n maxTokens: merged.maxTokens,\n sampler: merged.sampler,\n temperature: merged.temperature,\n topK: merged.topK,\n topP: merged.topP,\n seed: merged.seed,\n enableThinking: merged.enableThinking,\n // The canonical `multimodal` IS the native field here (transformers.js already used `{image,audio}`);\n // pass it as both so canonical-wins is a no-op and the normalized shape flows through.\n multimodal: normalizedMultimodal,\n },\n {\n maxTokens: merged.maxNewTokens,\n sampler: nativeSampler,\n multimodal: normalizedMultimodal,\n }\n )\n }\n\n /** Normalise multimodal config to `{image,audio}` flags, or undefined when fully off. */\n #multimodalFlags(\n merged: TransformersJsAdapterOptions\n ): { image: boolean; audio: boolean } | undefined {\n const { multimodal } = this.#gen(merged)\n return multimodal.image || multimodal.audio ? multimodal : undefined\n }\n\n /** Resolve (and cache, single-flight) the multimodal model+processor pair. */\n async #resolveMultimodalEngine(merged: TransformersJsAdapterOptions): Promise<{\n model: TransformersJsModel\n processor: TransformersJsProcessor\n }> {\n if (merged.multimodalEngine) {\n this.#mmEngine = merged.multimodalEngine\n return merged.multimodalEngine\n }\n if (this.#mmEngine) return this.#mmEngine\n this.#mmEnginePromise ??= (async () => {\n emitLifecycle(merged, 'transformers_js', merged.model, 'loading', {\n detail: 'loading multimodal model + processor',\n })\n // Forward each provider download event into a `loading` lifecycle report (normalized 0..1).\n const forwardedInitProgress = wrapTransformersInitProgress(merged)\n try {\n const createMultimodal =\n merged.createMultimodal ??\n (async ({ model, device, dtype, onInitProgress, sessionOptions }) => {\n const transformers = await import('@huggingface/transformers')\n const { AutoModelForImageTextToText, AutoProcessor, env } = transformers\n const load = async () => {\n const [m, processor] = await Promise.all([\n AutoModelForImageTextToText.from_pretrained(model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n // Forward ONNX Runtime session options verbatim (e.g. preferredOutputLocation,\n // graphOptimizationLevel). A reachable lever, not auto-applied — see options doc.\n ...(sessionOptions ? { session_options: sessionOptions } : {}),\n } as never) as unknown as Promise<TransformersJsModel>,\n AutoProcessor.from_pretrained(model) as unknown as Promise<TransformersJsProcessor>,\n ])\n return { model: m, processor }\n }\n // When a custom model source is configured, serve files through it (OPFS / bundled / etc.)\n // behind the global-`env` mutex; otherwise load straight from HF (unchanged path).\n return merged.modelSource\n ? withModelSource(env as never, merged.modelSource, load)\n : load()\n })\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call, so this is \"now preparing the graph\", not a strict\n // post-download boundary).\n emitLifecycle(merged, 'transformers_js', merged.model, 'compiling', {\n detail: 'compiling multimodal model graph',\n })\n const mmSessionOptions = resolveSessionOptions(merged)\n const engine = await createMultimodal({\n model: merged.model,\n device: merged.device,\n dtype: merged.dtype,\n onInitProgress: forwardedInitProgress,\n ...(mmSessionOptions ? { sessionOptions: mmSessionOptions } : {}),\n })\n this.#mmEngine = engine\n emitLifecycle(merged, 'transformers_js', merged.model, 'ready', {\n detail: 'multimodal model + processor ready',\n // Surface the WebGPU budget so the consumer can relate its context window to the device's\n // per-allocation ceiling — observability, never an imposed cap. Absent on non-WebGPU runtimes.\n gpuBudget: await probeGpuBudget(),\n })\n return engine\n } catch (err) {\n this.#mmEnginePromise = undefined\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STREAM_ERROR([\n `could not load the transformers.js multimodal model: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#mmEnginePromise\n }\n\n async #resolvePipeline(merged: TransformersJsAdapterOptions): Promise<TransformersJsPipeline> {\n if (merged.pipeline) {\n this.#pipeline = merged.pipeline\n return merged.pipeline\n }\n if (this.#pipeline) return this.#pipeline\n this.#pipelinePromise ??= (async () => {\n emitLifecycle(merged, 'transformers_js', merged.model, 'loading', {\n detail: 'loading text-generation pipeline',\n })\n const forwardedInitProgress = wrapTransformersInitProgress(merged)\n try {\n const createPipeline =\n merged.createPipeline ??\n (async ({ model, device, dtype, onInitProgress, sessionOptions }) => {\n const transformers = await import('@huggingface/transformers')\n const { pipeline, env } = transformers\n const load = async () =>\n (await pipeline('text-generation', model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n // Forward ONNX Runtime session options verbatim (e.g. preferredOutputLocation,\n // graphOptimizationLevel). A reachable lever, not auto-applied — see options doc.\n ...(sessionOptions ? { session_options: sessionOptions } : {}),\n } as never)) as unknown as TransformersJsPipeline\n return merged.modelSource\n ? withModelSource(env as never, merged.modelSource, load)\n : load()\n })\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call, so this is \"now preparing the graph\", not a strict\n // post-download boundary).\n emitLifecycle(merged, 'transformers_js', merged.model, 'compiling', {\n detail: 'compiling text-generation graph',\n })\n const pipelineSessionOptions = resolveSessionOptions(merged)\n const pipe = await createPipeline({\n model: merged.model,\n device: merged.device,\n dtype: merged.dtype,\n onInitProgress: forwardedInitProgress,\n ...(pipelineSessionOptions ? { sessionOptions: pipelineSessionOptions } : {}),\n })\n this.#pipeline = pipe\n emitLifecycle(merged, 'transformers_js', merged.model, 'ready', {\n detail: 'text-generation pipeline ready',\n // Surface the WebGPU budget so the consumer can relate its context window to the device's\n // per-allocation ceiling — observability, never an imposed cap. Absent on non-WebGPU runtimes.\n gpuBudget: await probeGpuBudget(),\n })\n return pipe\n } catch (err) {\n this.#pipelinePromise = undefined\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STREAM_ERROR([\n `could not load the transformers.js pipeline: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#pipelinePromise\n }\n\n /**\n * Build the transformers.js `generate` kwargs from the merged options (excluding tools/streamer).\n *\n * @remarks\n * Every sampling/length knob is passed EXPLICITLY with a deterministic-friendly default (resolved via\n * the shared {@link resolveGenerationOptions} from the portable contract) so the downstream `generate`\n * never falls back to the model config's own guess — the source of per-model surprises. Greedy maps to\n * `do_sample:false`; `'top-k'`/`'top-p'` map to `do_sample:true` + the matching cutoff.\n */\n #generateKwargs(merged: TransformersJsAdapterOptions): Record<string, unknown> {\n const gen = this.#gen(merged)\n const doSample = gen.sampler !== 'greedy'\n const kw: Record<string, unknown> = {\n max_new_tokens: gen.maxTokens,\n do_sample: doSample,\n repetition_penalty: merged.repetitionPenalty ?? 1.1,\n }\n // Sampler knobs are meaningful ONLY when sampling. Greedy ignores them and transformers.js logs a\n // warning if they're set — so send them only when sampling. We always send BOTH top_k and top_p (the\n // generate() call accepts both regardless of strategy; the strategy just determines which dominates),\n // keeping the sampler fully specified. seed is forwarded when provided.\n if (doSample) {\n kw.temperature = gen.temperature\n kw.top_k = gen.topK\n kw.top_p = gen.topP\n if (gen.seed !== undefined) kw.seed = gen.seed\n }\n if (merged.stopStrings !== undefined) kw.stop_strings = [...merged.stopStrings]\n return kw\n }\n\n /**\n * Produce the bound {@link DispatchExecutorFn} the `DispatchRunner` invokes.\n *\n * @param overrides - Option overrides layered above the constructor baseline (below `ctx.stash`).\n */\n executor(overrides?: Partial<TransformersJsAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = TransformersJsAdapter\n const self = this\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n // 1. Three-layer merge + re-validate.\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<TransformersJsAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n const h = resolveHelpers(merged.helpers)\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n const unsupportedMediaPolicy = merged.unsupportedMediaPolicy ?? 'throw'\n const toolCallParser = resolveToolCallParser(merged.toolCallParser)\n const reasoningParser = resolveReasoningParser(merged.reasoningParser, undefined, {\n orphanRecovery: merged.reasoningOrphanRecovery,\n })\n\n // 2. Artifact-reader tools are forged by the DispatchRunner CORE into `ctx.tools` before the input\n // pipeline runs (generation is a generic core concern; this battery owns only representation).\n // Read the pre-forged `ctx.tools` directly — no local merge, no bindContext here.\n\n // 3. Pre-render persisted tool-call results into plain-text tool message bodies.\n const renderedToolCallResults = new Map<ToolCall, string>()\n for (const tc of ctx.turnToolCalls) {\n const tool = ctx.tools.get(tc.tool)\n const body = await h.renderTransformersJsToolResult({\n toolCall: tc,\n results: tc.results,\n tool: tool as Tool | ArtifactTool | undefined,\n unsupportedMediaPolicy,\n renderUntrustedContent: h.renderUntrustedContent,\n renderTrustedContent: h.renderTrustedContent,\n renderArtifactHandleBody: h.renderArtifactHandleBody,\n warn: (m) =>\n helpers.log.warn({\n kind: 'transformers-render-warning',\n message: m,\n }),\n })\n renderedToolCallResults.set(tc, body)\n }\n\n // 4. Optional context-window enforcement.\n if (merged.tokenEncoding && merged.contextWindow !== undefined) {\n const enc = merged.tokenEncoding\n const tally = (s: string): number => new Tokenizable(s).estimateTokens(enc)\n let total = tally(ctx.systemPrompt.toString())\n for (const si of ctx.standingInstructions) total += tally(si.toString())\n for (const m of ctx.turnMemories) total += tally(m.content.toString())\n for (const r of ctx.turnRetrievables) {\n total +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(r.id, enc, h.renderRetrievableHandleBody)\n : tally((await r.contentString?.()) ?? '')\n }\n for (const m of ctx.turnMessages) total += tally(m.content?.toString() ?? '')\n for (const t of ctx.turnThoughts) total += tally(t.content.toString())\n for (const body of renderedToolCallResults.values()) total += tally(body)\n // Tool DECLARATIONS: transformers.js feeds the visible tools to `apply_chat_template({tools})`,\n // where the MODEL'S OWN Jinja template wraps them (per-model, in-process) — so the exact rendered\n // string isn't reproducible here without running the processor. Tally the serialized tool JSON\n // (the reproducible, dominant component the adapter actually passes) as an honest FLOOR. Without\n // this the guard undercounts a tool-heavy prompt by the entire declaration block.\n const visibleTools = ctx.tools.visible()\n if (visibleTools.length > 0) {\n total += tally(JSON.stringify(h.toolsToTransformersJsTools(visibleTools)))\n }\n if (total > merged.contextWindow) {\n throw new E_TRANSFORMERS_JS_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n String(enc),\n `system+buckets+timeline+tools=${total}`,\n ])\n }\n }\n\n // 5. Build the transformers.js message array + tools (+ decoded media when multimodal).\n const mmFlags = self.#multimodalFlags(merged)\n const {\n messages: turnMessages,\n tools: toolDefs,\n images: mmImages,\n audio: mmAudio,\n } = await h.buildTransformersJsMessages({\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,\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n toolsToTransformersJsTools: h.toolsToTransformersJsTools,\n renderThought: h.renderThought,\n filterThoughts: h.filterThoughts,\n renderUntrustedContent: h.renderUntrustedContent,\n renderTrustedContent: h.renderTrustedContent,\n renderChatCompletionsSystemPrompt: h.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: h.renderStandingInstructions,\n renderMemories: h.renderMemories,\n renderRetrievables: h.renderRetrievables,\n renderRetrievableSafetyDirective: h.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: h.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: h.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: h.renderThirdPartyPrivateRetrievables,\n renderRetrievableHandleBody: h.renderRetrievableHandleBody,\n multimodal: mmFlags,\n decodeMedia: mmFlags ? (media) => defaultMediaToTransformersInput(media) : undefined,\n unsupportedMediaPolicy,\n warn: (m) =>\n helpers.log.warn({\n kind: 'transformers-history-warning',\n message: m,\n }),\n })\n\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n const stream = merged.stream ?? true\n\n // One id for this whole generation — correlates the TO tap (onPromptAssembled) with the FROM tap\n // (onRawGeneration) and the reported message; both dispatch paths below reuse it.\n const dispatchStreamId = uuidv6()\n\n // Prompt-assembled observability tap: the EXACT messages + tools going TO the model, the instant\n // assembly finished (above) and before the pipeline/generate dispatch (below). Mirror of\n // onRawGeneration. Handed back AS-IS — no redaction — and swallow observer errors so it can never\n // corrupt the generation path.\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'transformers_js',\n kind: 'rendered-prompt',\n messages: turnMessages,\n tools: toolDefs,\n streamed: stream,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n const gen = self.#gen(merged)\n const generateKwargs = self.#generateKwargs(merged)\n const toolNames = ctx.tools.visible().map((t) => t.name)\n // A short, user-facing note carried on a GPU-OOM error so the application can show WHY it failed\n // and what to change. We surface the budget/window relationship, never silently cap it.\n const oomNote =\n merged.contextWindow !== undefined\n ? `The configured context window (${merged.contextWindow} tokens, max ${gen.maxTokens} output) exceeded the available GPU memory. Reduce the context window or max output tokens and retry, recycle the adapter to free the WebGPU buffer cache, or switch to a smaller model.`\n : `The request exceeded the available GPU memory. Reduce the context window or max output tokens and retry, recycle the adapter to free the WebGPU buffer cache, or switch to a smaller model.`\n\n // 6. Resolve the engine: multimodal model+processor, or the text-generation pipeline.\n let pipe: TransformersJsPipeline | undefined\n let mmEngine: { model: TransformersJsModel; processor: TransformersJsProcessor } | undefined\n try {\n if (mmFlags) mmEngine = await self.#resolveMultimodalEngine(merged)\n else pipe = await self.#resolvePipeline(merged)\n } catch (err) {\n // A cold WebGPU load can itself exhaust the device (\"Failed to create session\"). Surface that as\n // the typed GPU-OOM so the consumer gets one consistent, catchable signal for load- and\n // generation-time exhaustion alike; otherwise pass through the (already-typed) stream error.\n const loadMsg = isError(err) ? err.message : String(err)\n ctx.nack(\n isGpuOutOfMemoryError(loadMsg)\n ? toGenerationError(err, oomNote)\n : isInstanceOf(err, 'E_TRANSFORMERS_JS_STREAM_ERROR', E_TRANSFORMERS_JS_STREAM_ERROR)\n ? err\n : new E_TRANSFORMERS_JS_STREAM_ERROR([loadMsg])\n )\n return\n }\n\n if (ctx.abortSignal.aborted) return\n\n // ── Tool execution + persistence (args already an object — no JSON.parse) ──\n const executeAndPersistToolCall = async (call: AssembledToolCall): Promise<void> => {\n const tool = ctx.tools.get(call.name)\n const completedAt = nowIso()\n if (!call.argsWellFormed) {\n const toolName = normalizeToolName(call.name)\n const err = new E_TRANSFORMERS_JS_INVALID_TOOL_CALL_ARGS([\n 'must be a JSON object',\n JSON.stringify(call.args),\n ])\n const results = new Tokenizable(err.message)\n helpers.reportToolCall(call.id, { tool: toolName, args: {} })\n helpers.reportToolCall(call.id, {\n results,\n isError: true,\n isComplete: true,\n })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: {},\n checksum: computeChecksum(toolName, {}),\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 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(call.id, { tool: toolName, args: call.args })\n helpers.reportToolCall(call.id, {\n results,\n isError: true,\n isComplete: true,\n })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: call.args,\n checksum: computeChecksum(toolName, call.args),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n helpers.reportToolCall(call.id, { tool: tool.name, args: call.args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(call.args)\n if (isArtifactTool) {\n results = Tokenizable.isTokenizable(raw)\n ? raw\n : typeof raw === 'string'\n ? new Tokenizable(raw)\n : (() => {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n })()\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(call.id, raw as string | Uint8Array)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(call.id, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n let detailMsg = isError(err) ? err.message : String(err)\n if (isError(err) && isError(err.cause) && err.cause.message !== err.message) {\n detailMsg = `${detailMsg} ${err.cause.message}`\n }\n results = new Tokenizable(detailMsg)\n }\n helpers.reportToolCall(call.id, {\n results,\n isError: toolHadError,\n isComplete: true,\n })\n const completedAt2 = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: tool.name,\n args: call.args,\n checksum: computeChecksum(tool.name, call.args),\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n // 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 const assembleCalls = (raw: ReadonlyArray<ParsedToolCall>): AssembledToolCall[] =>\n raw.map((c) => ({\n id: uuidv6(),\n name: c.name,\n args: isObject(c.arguments) ? (c.arguments as Record<string, unknown>) : {},\n argsWellFormed: isObject(c.arguments),\n }))\n\n // Parse the full generated text → reasoning + clean prose + tool calls, then persist.\n const finishFromText = async (\n rawText: string,\n streamId: string,\n streamedProse: boolean,\n generatedMedia: Media[] = []\n ): Promise<void> => {\n // Normalise away non-semantic envelope/turn-boundary special tokens (Llama `<|python_tag|>`/\n // `<|eom_id|>`, ChatML `<|im_end|>`, …) before parsing. The streaming path decodes with\n // skip_special_tokens:false (its live prose-stop gate needs the markers), so without this the\n // parsers would see `<|python_tag|>{json}<|eom_id|>` on stream and decline — even though the\n // batch path (skip_special_tokens:true) parses the identical call. Idempotent on batch text.\n const fullText = stripEnvelopeSpecialTokens(rawText)\n const reasoned = reasoningParser(fullText)\n const afterReasoning = reasoned.cleanedText\n const parsed = toolCallParser(afterReasoning, { toolNames })\n const cleanText = parsed.cleanedText\n\n // Raw-generation observability tap: surface what the model emitted vs. what parsed, before any\n // persistence. Purely observational — swallow callback errors so a misbehaving observer can\n // never corrupt the generation path.\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: fullText,\n cleanedText: cleanText,\n reasoning: reasoned.reasoning,\n toolCalls: parsed.calls,\n streamed: streamedProse,\n streamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // Persist reasoning as Thoughts. Drop any trace whose trimmed content is empty — an\n // empty/whitespace thought (e.g. a model's `<think>\\n\\n</think>` no-think artifact) carries no\n // information and is just a model quirk; there is no point surfacing it to the consumer.\n for (const trace of reasoned.reasoning) {\n if (trace.trim().length === 0) continue\n const id = uuidv6()\n helpers.reportThought(id, trace, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id,\n content: trace,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n // Persist the assistant message when there is clean prose OR generated media to carry. Media-only\n // turns (empty text + an audio/image attachment) are legitimate; the contract requires at least one\n // of `content`/`attachments`, so a turn with neither stores nothing (unchanged from before).\n if (cleanText.length > 0 || generatedMedia.length > 0) {\n if (streamedProse) {\n helpers.reportMessage(streamId, '', { isComplete: true })\n } else if (cleanText.length > 0) {\n helpers.reportMessage(streamId, cleanText, { isComplete: true })\n }\n await ctx.storeMessage(\n new Message({\n id: streamId,\n role: 'assistant',\n ...(cleanText.length > 0 ? { content: cleanText } : {}),\n ...(generatedMedia.length > 0 ? { attachments: generatedMedia } : {}),\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n // Execute tool calls.\n const calls = assembleCalls(parsed.calls)\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n\n // ── Streaming path ──\n // Unified generate: drives either the text-generation pipeline OR the multimodal model+processor.\n // Returns the final decoded text for the non-streaming path; streaming text arrives via `streamer`.\n // The raw generation object (model.generate / pipeline output) is captured here so the optional\n // `extractMediaOutputs` hook can surface GENERATED media (audio/image) as assistant attachments.\n let rawGenerationResult: unknown\n const runGenerate = async (streamer: unknown): Promise<string> => {\n if (mmEngine) {\n const { model, processor } = mmEngine\n const proc = processor as unknown as {\n apply_chat_template: (m: unknown, o: unknown) => unknown\n batch_decode: (t: unknown, o: unknown) => string[]\n }\n const callProc = processor as unknown as (\n ...args: unknown[]\n ) => Promise<Record<string, unknown>>\n const prompt = proc.apply_chat_template(turnMessages, {\n add_generation_prompt: true,\n tokenize: false,\n // Explicit thinking flag — never let the template default decide (Qwen3/DeepSeek default ON).\n enable_thinking: gen.enableThinking,\n // Pass tool DEFINITIONS through the native template mechanism, exactly as the pipeline path\n // does. Gemma 4's chat_template renders these as `<|tool>…<tool|>` blocks, which is what\n // cues the model to emit its TRAINED `call:NAME{…}` tool-call format. Omitting them (the\n // prior bug) left the model with no native cue, so it improvised raw JSON args that no\n // parser recognises. This is the multimodal-path equivalent of the pipeline's `tools` arg.\n ...(toolDefs.length > 0 ? { tools: toolDefs } : {}),\n })\n // processor(text, images, audio, options) — positional (verified against the real Gemma-4\n // `Gemma4Processor._call(text, images = null, audio = null, options)`). The audio slot is THIRD,\n // so when audio is present the images slot MUST be filled positionally (with `null` when there\n // is no image) — otherwise audio collapses into the images slot and the image processor throws\n // `image.rgb is not a function`. `if (images)`/`if (audio)` in the processor treat `null` as absent.\n const imageArg =\n mmImages.length === 0 ? null : mmImages.length === 1 ? mmImages[0] : mmImages\n const audioArg = mmAudio.length === 0 ? null : mmAudio.length === 1 ? mmAudio[0] : mmAudio\n const procArgs: unknown[] =\n mmAudio.length > 0\n ? [prompt, imageArg, audioArg] // audio needs the 3rd slot → fill images (null if none)\n : mmImages.length > 0\n ? [prompt, imageArg]\n : [prompt]\n const inputs = await callProc(...procArgs)\n // The processor INPUT tensors are GPU buffers we own. Free them no matter what — including\n // when generate() itself OOMs — so a failed generate doesn't leak its inputs and starve the\n // retry. (generate() is INSIDE this try precisely so the finally also covers its throw.)\n try {\n const out = await (\n model as unknown as { generate: (o: unknown) => Promise<unknown> }\n ).generate({\n ...inputs,\n ...generateKwargs,\n ...(streamer ? { streamer } : {}),\n })\n rawGenerationResult = out\n // Non-stream decode: slice the prompt tokens off, decode the new tail.\n try {\n const inputLen = (inputs.input_ids as { dims?: number[] } | undefined)?.dims?.[1] ?? 0\n const seq = out as { slice?: (...a: unknown[]) => unknown }\n const newTokens =\n typeof seq.slice === 'function' ? seq.slice(null, [inputLen, null]) : out\n const decoded = proc.batch_decode(newTokens, {\n skip_special_tokens: true,\n })\n // Free the slice tensor (a fresh GPU buffer) once decoded — but only when it's distinct\n // from `out`, which we still need for the media extractor (disposed after this returns).\n if (newTokens !== out) disposeTensors(newTokens)\n return (decoded?.[0] ?? '').toString()\n } catch {\n return ''\n }\n } finally {\n disposeTensors(inputs)\n }\n }\n const p = pipe as unknown as (m: unknown, k: unknown) => Promise<unknown>\n const output = await p(turnMessages, {\n ...generateKwargs,\n // Explicit thinking flag forwarded to the pipeline's internal apply_chat_template — never let\n // the template default decide (Qwen3/DeepSeek default thinking ON).\n enable_thinking: gen.enableThinking,\n ...(toolDefs.length > 0 ? { tools: toolDefs } : {}),\n ...(streamer ? { streamer } : {}),\n })\n rawGenerationResult = output\n return extractGeneratedText(output)\n }\n\n // Run the optional media-output extractor over the raw generation result, persisting each generated\n // media via `ctx.storeMediaBytes` and building first-party `Media` attachments. Returns [] when no\n // hook is configured or it yields nothing — the text-only path then attaches nothing (unchanged).\n const collectGeneratedMedia = async (): Promise<Media[]> => {\n if (!merged.extractMediaOutputs || rawGenerationResult === undefined) return []\n const outputs = await merged.extractMediaOutputs(rawGenerationResult)\n const media: Media[] = []\n for (const o of outputs) {\n const id = uuidv6()\n const reader = await ctx.storeMediaBytes(id, o.bytes)\n media.push(\n Media.toolGenerated({\n id,\n kind: o.kind,\n mimeType: o.mimeType,\n filename: o.filename ?? `${id}.${o.kind}`,\n reader,\n })\n )\n }\n return media\n }\n // Free the captured generate OUTPUT tensor after the media extractor (the only consumer of\n // rawGenerationResult) has run. Together with disposing the processor inputs in runGenerate,\n // this releases the caller-owned tensors per generate() — hygiene for the manual multimodal\n // path, which (unlike the pipeline path) hands back tensors we own. Only the multimodal path\n // captures a tensor here; the pipeline path returns plain objects, for which this is a no-op.\n const disposeGenerationOutput = (): void => {\n if (mmEngine && rawGenerationResult !== undefined) disposeTensors(rawGenerationResult)\n rawGenerationResult = undefined\n }\n\n if (stream) {\n const accumulator = h.createTransformersJsStreamAccumulator()\n const streamId = dispatchStreamId\n let proseStopped = false\n let streamedProse = false\n\n // The decoded-text sink: feed the accumulator + stream safe prose deltas (stopping prose once\n // tool-call/think markup appears; the clean message is persisted after generation completes).\n const onText = (text: string): void => {\n accumulator.feed(text)\n if (proseStopped) return\n if (TEXT_MARKUP_MARKERS.some((m) => accumulator.content().includes(m))) {\n proseStopped = true\n return\n }\n if (text.length > 0) {\n streamedProse = true\n helpers.reportMessage(streamId, text)\n }\n }\n\n // Default streamer factory imports the peer's TextStreamer; `createStreamer` overrides it\n // (e.g. tests inject a lightweight sink to avoid importing the heavy peer in the browser env).\n // The tokenizer comes from the multimodal processor when present, else the pipeline.\n const tokenizerHost = (mmEngine?.processor ?? pipe) as unknown as {\n tokenizer: unknown\n }\n const createStreamer =\n merged.createStreamer ??\n (async ({ onText: cb }) => {\n const { TextStreamer } = await import('@huggingface/transformers')\n return new TextStreamer(\n tokenizerHost.tokenizer as never,\n {\n skip_prompt: true,\n skip_special_tokens: false,\n callback_function: cb,\n } as never\n )\n })\n\n let streamer: unknown\n try {\n streamer = await createStreamer({\n pipeline: pipe as TransformersJsPipeline,\n onText,\n })\n } catch (err) {\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n ctx.nack(new E_TRANSFORMERS_JS_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n emitLifecycle(merged, 'transformers_js', merged.model, 'generating')\n try {\n await runGenerate(streamer)\n } catch (err) {\n if (ctx.abortSignal.aborted) return\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n ctx.nack(toGenerationError(err, oomNote))\n return\n }\n if (ctx.abortSignal.aborted) return\n const streamMedia = await collectGeneratedMedia()\n disposeGenerationOutput()\n await finishFromText(accumulator.content(), streamId, streamedProse, streamMedia)\n emitLifecycle(merged, 'transformers_js', merged.model, 'complete')\n return\n }\n\n // ── Non-streaming path ──\n let finalText: string\n emitLifecycle(merged, 'transformers_js', merged.model, 'generating')\n try {\n finalText = await runGenerate(undefined)\n } catch (err) {\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n ctx.nack(toGenerationError(err, oomNote))\n return\n }\n if (ctx.abortSignal.aborted) return\n const nonStreamMedia = await collectGeneratedMedia()\n disposeGenerationOutput()\n await finishFromText(finalText, dispatchStreamId, false, nonStreamMedia)\n emitLifecycle(merged, 'transformers_js', merged.model, 'complete')\n }\n }\n}\n\n/**\n * Free the GPU buffers backing a transformers.js value when running on the WebGPU EP.\n *\n * @remarks\n * onnxruntime-web does NOT garbage-collect GPU tensors — each `Tensor` whose `location` is\n * `'gpu-buffer'` owns a Dawn buffer that is reclaimed ONLY by an explicit `.dispose()`. In the\n * manual multimodal `model.generate()` path the battery creates the processor INPUT tensors and\n * captures the generate OUTPUT tensor; transformers.js frees its own internal decode-loop tensors\n * and KV cache, but these caller-owned tensors are ours to free. Skipping that leaks ~the full\n * activation set per `generate()`, so the SECOND generate on a loaded model (a tool-loop iteration,\n * the answer classifier, or simply the next turn) fails with \"Failed to allocate memory for buffer\n * mapping\". The matrix tests never caught this — each cell builds a fresh adapter and generates\n * exactly once.\n *\n * Accepts a processor-inputs object (a map of named tensors), a single tensor, or a nested\n * generate output; walks it shallowly and disposes anything tensor-shaped. Best-effort and never\n * throws — a disposal failure must not break generation. No-op for CPU/WASM tensors (which have no\n * `dispose` or aren't GPU-backed), so it's safe across execution providers.\n */\nconst disposeTensors = (value: unknown): void => {\n const tryDispose = (t: unknown): void => {\n const d = t as { dispose?: () => void; location?: string } | null | undefined\n if (d && typeof d.dispose === 'function') {\n try {\n d.dispose()\n } catch {\n /* best-effort: a failed dispose must never break generation */\n }\n }\n }\n if (value === null || value === undefined) return\n // A bare tensor (has its own dispose).\n if (typeof (value as { dispose?: unknown }).dispose === 'function') {\n tryDispose(value)\n return\n }\n // A processor-inputs map { input_ids, attention_mask, pixel_values, … } or an array of tensors.\n if (typeof value === 'object') {\n for (const v of Object.values(value as Record<string, unknown>)) tryDispose(v)\n }\n}\n\n/**\n * Pull the newly-generated assistant text out of a transformers.js text-generation result.\n *\n * @remarks\n * Chat input → `[{ generated_text: Message[] }]` (the last message is the new assistant turn);\n * string input → `[{ generated_text: string }]`. We always send chat input, so we take the last\n * message's content, falling back defensively to a string `generated_text`.\n */\nconst extractGeneratedText = (output: unknown): string => {\n const first = Array.isArray(output) ? output[0] : output\n const gen = (first as { generated_text?: unknown } | undefined)?.generated_text\n if (typeof gen === 'string') return gen\n if (Array.isArray(gen)) {\n const last = gen[gen.length - 1] as { content?: unknown } | undefined\n const content = last?.content\n if (typeof content === 'string') return content\n if (Array.isArray(content)) {\n return content\n .filter(\n (i): i is { type: string; text: string } =>\n isObject(i) && (i as { type?: unknown }).type === 'text'\n )\n .map((i) => i.text)\n .join('')\n }\n }\n return ''\n}\n\nexport { extractGeneratedText as __extractGeneratedText }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapter.mjs","names":["#baseline","#pipeline","#resolvePipeline","#pipelinePromise","#mmEngine","#mmEnginePromise","#gen","#resolveMultimodalEngine","#multimodalFlags","#generateKwargs"],"sources":["../../../../src/batteries/llm/transformers_js/adapter.ts"],"sourcesContent":["/**\n * Dual-environment (Node + browser) executor adapter for transformers.js (`@huggingface/transformers`).\n *\n * @module @nhtio/adk/batteries/llm/transformers_js/adapter\n *\n * @remarks\n * On-device text generation via ONNX Runtime — `onnxruntime-node` (native) in Node, `onnxruntime-web`\n * (WASM + WebGPU) in the browser, auto-selected by the package. So this battery is\n * **environment-neutral**: it does NOT gate on WebGPU.\n *\n * **transformers.js is text-in / text-out.** It injects tool definitions into the chat template but\n * does NOT return structured tool calls or reasoning — the model emits both as **family-specific raw\n * text**. This adapter parses them out via the shared, configurable parser layer (`toolCallParser` /\n * `reasoningParser`, both defaulting to `'auto'`): after generation, the reasoning parser pulls\n * thinking into ADK Thoughts and the tool-call parser pulls calls into ADK ToolCalls, leaving clean\n * prose as the assistant Message.\n *\n * Three pluggable layers mirror the other LLM batteries: swappable translation helpers, three-layer\n * options merging (constructor → `executor()` overrides → `ctx.stash.transformersJs`), and an\n * injectable/lazy pipeline (`pipeline` or `createPipeline`, defaulting to a dynamic import).\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { withModelSource } from './model_source'\nimport { emitLifecycle } from '../chat_common/lifecycle'\nimport { E_LLM_GPU_OUT_OF_MEMORY } from '../chat_common/exceptions'\nimport { isError, isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { resolveGenerationOptions } from '../chat_common/generation'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { resolveReasoningParser } from '../chat_common/reasoning_parsers'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport { isGpuOutOfMemoryError, probeGpuBudget } from '../chat_common/gpu_budget'\nimport {\n looksLikeSpooledArtifact,\n stripEnvelopeSpecialTokens,\n normalizeToolName,\n} 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_TRANSFORMERS_JS_CONTEXT_OVERFLOW,\n E_TRANSFORMERS_JS_STREAM_ERROR,\n E_TRANSFORMERS_JS_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 defaultRenderThought,\n defaultFilterThoughts,\n defaultRenderChatCompletionsSystemPrompt,\n defaultToolsToTransformersJsTools,\n defaultRenderTransformersJsToolResult,\n defaultRenderArtifactHandleBody,\n defaultBuildTransformersJsMessages,\n defaultMediaToTransformersInput,\n defaultCreateTransformersJsStreamAccumulator,\n} from './helpers'\nimport type { Tool } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { ParsedToolCall } from '../chat_common/tool_parsers'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\nimport type { ChatSampler, ResolvedGenerationOptions } from '../chat_common/generation'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/dispatch_runner'\nimport type {\n TransformersJsAdapterOptions,\n TransformersJsPipeline,\n TransformersJsModel,\n TransformersJsProcessor,\n} from './types'\n\n// ─── Option merging (constructor → executor overrides → stash) ────────────────────────────────────\n\nconst mergeHelpers = (\n layers: ReadonlyArray<Partial<NonNullable<TransformersJsAdapterOptions['helpers']>> | undefined>\n): Partial<NonNullable<TransformersJsAdapterOptions['helpers']>> | undefined => {\n let merged: Partial<NonNullable<TransformersJsAdapterOptions['helpers']>> | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? {}), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: TransformersJsAdapterOptions,\n exec: Partial<TransformersJsAdapterOptions> | undefined,\n stash: Partial<TransformersJsAdapterOptions> | undefined\n): Partial<TransformersJsAdapterOptions> => {\n const layers = [baseline as Partial<TransformersJsAdapterOptions>, 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<TransformersJsAdapterOptions>\n}\n\n// ─── Helper resolution (fall back to bundled defaults per field) ──────────────────────────────────\n\ninterface ResolvedHelpers {\n descriptionToChatCompletionsJsonSchema: typeof defaultDescriptionToChatCompletionsJsonSchema\n renderUntrustedContent: typeof defaultRenderUntrustedContent\n renderTrustedContent: typeof defaultRenderTrustedContent\n renderStandingInstructions: typeof defaultRenderStandingInstructions\n renderMemories: typeof defaultRenderMemories\n renderRetrievables: typeof defaultRenderRetrievables\n renderRetrievableSafetyDirective: typeof defaultRenderRetrievableSafetyDirective\n renderFirstPartyRetrievables: typeof defaultRenderFirstPartyRetrievables\n renderThirdPartyPublicRetrievables: typeof defaultRenderThirdPartyPublicRetrievables\n renderThirdPartyPrivateRetrievables: typeof defaultRenderThirdPartyPrivateRetrievables\n renderThought: typeof defaultRenderThought\n filterThoughts: typeof defaultFilterThoughts\n renderChatCompletionsSystemPrompt: typeof defaultRenderChatCompletionsSystemPrompt\n toolsToTransformersJsTools: typeof defaultToolsToTransformersJsTools\n renderTransformersJsToolResult: typeof defaultRenderTransformersJsToolResult\n renderArtifactHandleBody: typeof defaultRenderArtifactHandleBody\n renderRetrievableHandleBody: typeof defaultRenderRetrievableHandleBody\n buildTransformersJsMessages: typeof defaultBuildTransformersJsMessages\n createTransformersJsStreamAccumulator: typeof defaultCreateTransformersJsStreamAccumulator\n}\n\nconst resolveHelpers = (\n overrides: Partial<TransformersJsAdapterOptions['helpers']> | undefined\n): ResolvedHelpers => {\n const src = (overrides ?? {}) as Record<string, unknown>\n const pick = <K extends keyof ResolvedHelpers>(\n key: K,\n dflt: ResolvedHelpers[K]\n ): ResolvedHelpers[K] => (src[key as string] as ResolvedHelpers[K]) ?? dflt\n return {\n descriptionToChatCompletionsJsonSchema: pick(\n 'descriptionToChatCompletionsJsonSchema',\n defaultDescriptionToChatCompletionsJsonSchema\n ),\n renderUntrustedContent: pick('renderUntrustedContent', defaultRenderUntrustedContent),\n renderTrustedContent: pick('renderTrustedContent', defaultRenderTrustedContent),\n renderStandingInstructions: pick(\n 'renderStandingInstructions',\n defaultRenderStandingInstructions\n ),\n renderMemories: pick('renderMemories', defaultRenderMemories),\n renderRetrievables: pick('renderRetrievables', defaultRenderRetrievables),\n renderRetrievableSafetyDirective: pick(\n 'renderRetrievableSafetyDirective',\n defaultRenderRetrievableSafetyDirective\n ),\n renderFirstPartyRetrievables: pick(\n 'renderFirstPartyRetrievables',\n defaultRenderFirstPartyRetrievables\n ),\n renderThirdPartyPublicRetrievables: pick(\n 'renderThirdPartyPublicRetrievables',\n defaultRenderThirdPartyPublicRetrievables\n ),\n renderThirdPartyPrivateRetrievables: pick(\n 'renderThirdPartyPrivateRetrievables',\n defaultRenderThirdPartyPrivateRetrievables\n ),\n renderThought: pick('renderThought', defaultRenderThought),\n filterThoughts: pick('filterThoughts', defaultFilterThoughts),\n renderChatCompletionsSystemPrompt: pick(\n 'renderChatCompletionsSystemPrompt',\n defaultRenderChatCompletionsSystemPrompt\n ),\n toolsToTransformersJsTools: pick(\n 'toolsToTransformersJsTools',\n defaultToolsToTransformersJsTools\n ),\n renderTransformersJsToolResult: pick(\n 'renderTransformersJsToolResult',\n defaultRenderTransformersJsToolResult\n ),\n renderArtifactHandleBody: pick('renderArtifactHandleBody', defaultRenderArtifactHandleBody),\n renderRetrievableHandleBody: pick(\n 'renderRetrievableHandleBody',\n defaultRenderRetrievableHandleBody\n ),\n buildTransformersJsMessages: pick(\n 'buildTransformersJsMessages',\n defaultBuildTransformersJsMessages\n ),\n createTransformersJsStreamAccumulator: pick(\n 'createTransformersJsStreamAccumulator',\n defaultCreateTransformersJsStreamAccumulator\n ),\n }\n}\n\nconst nowIso = (): string => DateTime.now().toISO() as string\n\nconst computeChecksum = (tool: string, args: Record<string, unknown>): string =>\n sha256(canonicalStringify({ tool, args }))\n\n/**\n * Wrap the consumer's `onInitProgress` so each transformers.js download event ALSO emits a normalized\n * `loading` lifecycle report. The HF `progress` field is 0..100 → forwarded as `progress` 0..1, with the\n * raw payload on `raw`. The original `onInitProgress` is still called verbatim (additive). Returns the\n * original callback unchanged when no lifecycle hooks are configured (zero overhead on the text path).\n */\nconst wrapTransformersInitProgress = (\n merged: TransformersJsAdapterOptions\n): TransformersJsAdapterOptions['onInitProgress'] => {\n const hasLifecycle =\n merged.onLifecycle ??\n merged.onLoading ??\n merged.onReady ??\n merged.onGenerating ??\n merged.onError\n if (!hasLifecycle) return merged.onInitProgress\n return (info: unknown) => {\n const p = (info as { progress?: number } | undefined)?.progress\n emitLifecycle(merged, 'transformers_js', merged.model, 'loading', {\n ...(typeof p === 'number' ? { progress: p / 100 } : {}),\n raw: info,\n })\n merged.onInitProgress?.(info as never)\n }\n}\n\n/** Markers that signal the start of tool-call / reasoning markup — used to stop streaming prose. */\nconst TEXT_MARKUP_MARKERS = [\n '<tool_call>',\n '<|tool_call>',\n '<|channel',\n '<think',\n '[TOOL_CALLS]',\n '<function=',\n]\n\n/** An assembled tool call ready for execution (args already a parsed object). */\ninterface AssembledToolCall {\n id: string\n name: string\n args: Record<string, unknown>\n argsWellFormed: boolean\n}\n\n/**\n * Translate a generation-time throw into the right battery exception: a typed, catchable\n * {@link @nhtio/adk/batteries!E_LLM_GPU_OUT_OF_MEMORY} when the message matches a known WebGPU\n * exhaustion signature (so an application can `catch` it structurally instead of string-matching ORT\n * internals — surface, don't impose), else the generic {@link E_TRANSFORMERS_JS_STREAM_ERROR}.\n *\n * @param err - The raw thrown value from `generate()` / streamer / pipeline.\n * @param contextNote - A short human-readable budget/window note carried on the OOM error's message,\n * shown to the user verbatim by the application layer.\n */\nconst toGenerationError = (\n err: unknown,\n contextNote: string\n):\n | InstanceType<typeof E_LLM_GPU_OUT_OF_MEMORY>\n | InstanceType<typeof E_TRANSFORMERS_JS_STREAM_ERROR> => {\n const message = isError(err) ? err.message : String(err)\n if (isGpuOutOfMemoryError(message)) {\n return new E_LLM_GPU_OUT_OF_MEMORY([message, contextNote], {\n cause: isError(err) ? err : undefined,\n })\n }\n return new E_TRANSFORMERS_JS_STREAM_ERROR([message])\n}\n\n/**\n * Whether the resolved device targets the WebGPU execution provider (a scalar `'webgpu'` or a\n * per-submodule record that puts the decoder on webgpu). KV-cache GPU-pinning only applies there —\n * on the wasm/cpu EP there is no `'gpu-buffer'` location and the pin would be meaningless.\n */\nconst isWebGpuDevice = (device: TransformersJsAdapterOptions['device']): boolean => {\n if (device === undefined) return false\n if (typeof device === 'string') return device === 'webgpu' || device === 'gpu'\n // Per-submodule record: pin if the decoder (or any submodule) runs on webgpu.\n return Object.values(device).some((d) => d === 'webgpu' || d === 'gpu')\n}\n\n/**\n * Build a `preferredOutputLocation` map pinning every KV-cache output (`present.N.key` /\n * `present.N.value`) to `'gpu-buffer'`, so the autoregressive KV cache lives in GPU memory instead of\n * the ONNX-Runtime-Web **wasm32 linear-memory heap** (hard-capped at 4 GiB by the 32-bit address space).\n *\n * @remarks\n * This is the battery's headline in-browser memory fix. transformers.js HAS auto-pinning for this\n * (session.js builds the same map for `cache_sessions` on webgpu), but it silently no-ops on models\n * whose config nests the head/layer counts (e.g. Gemma-4's `text_config`): `getCacheNames` returns\n * empty, so the decoder loads with `preferredOutputLocation: null` and the KV cache stays on the wasm\n * heap (measured: the live `present.*` tensors report `location: \"cpu\"`). Passing the map EXPLICITLY\n * moves them to `location: \"gpu-buffer\"` (measured). We over-specify the layer count — extra\n * `present.*` names that the model doesn't emit are simply ignored by the runtime — so we don't have to\n * read the architecture's layer count first. 96 covers every open-weight decoder we target.\n */\nconst buildKvCacheGpuPinMap = (layers = 96): Record<string, 'gpu-buffer'> => {\n const map: Record<string, 'gpu-buffer'> = {}\n for (let i = 0; i < layers; i++) {\n map[`present.${i}.key`] = 'gpu-buffer'\n map[`present.${i}.value`] = 'gpu-buffer'\n }\n return map\n}\n\n/**\n * Resolve the effective ONNX `session_options` for a load, applying the KV-cache GPU-pin DEFAULT.\n *\n * @remarks\n * Policy (surface-a-safe-default, keep the escape hatch): on the WebGPU EP, pin the KV cache to\n * `'gpu-buffer'` BY DEFAULT (keeps it off the 4 GiB wasm32 heap — the wall hit first in-browser). The\n * consumer can opt out wholesale (`pinKvCacheToGpu: false`) or override precisely (set their own\n * `sessionOptions.preferredOutputLocation`, which always wins — we never clobber an explicit one). On a\n * non-WebGPU device the pin is skipped (no `'gpu-buffer'` location exists there). Returns `undefined`\n * when there is nothing to pass (so the loader's `...(sessionOptions ? … : {})` spread stays a no-op).\n */\nconst resolveSessionOptions = (\n merged: TransformersJsAdapterOptions\n): TransformersJsAdapterOptions['sessionOptions'] | undefined => {\n const explicit = merged.sessionOptions\n const wantPin = (merged.pinKvCacheToGpu ?? true) && isWebGpuDevice(merged.device)\n // Don't pin if disabled, off-WebGPU, or the consumer already chose an output location (their call).\n if (!wantPin || explicit?.preferredOutputLocation !== undefined) return explicit\n return { ...(explicit ?? {}), preferredOutputLocation: buildKvCacheGpuPinMap() }\n}\n\n/**\n * Dual-environment executor adapter for transformers.js text generation.\n *\n * @remarks\n * Construct with at least `{ model }`; wire `new TransformersJsAdapter(opts).executor()` into a\n * `DispatchRunner` as the `executorCallback`. The pipeline is resolved lazily on first dispatch (or\n * eagerly via {@link TransformersJsAdapter.preload}); pass `pipeline` to inject a pre-built one.\n */\nexport class TransformersJsAdapter {\n /** The `ctx.stash` key under which per-dispatch option overrides are read. */\n public static readonly STASH_KEY = 'transformersJs' as const\n\n readonly #baseline: TransformersJsAdapterOptions\n #pipeline: TransformersJsPipeline | undefined\n #pipelinePromise: Promise<TransformersJsPipeline> | undefined\n #mmEngine: { model: TransformersJsModel; processor: TransformersJsProcessor } | undefined\n #mmEnginePromise:\n | Promise<{\n model: TransformersJsModel\n processor: TransformersJsProcessor\n }>\n | undefined\n\n /**\n * Whether this battery is available. transformers.js is environment-neutral (Node + browser), so this\n * is `true` whenever the runtime can import the peer — there is no WebGPU requirement. Static form\n * returns `true`; the instance form honours an injected `isAvailable` override.\n */\n public static isAvailable(): boolean {\n return true\n }\n\n /**\n * @param options - Raw adapter options, validated against `transformersJsOptionsSchema`.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_OPTIONS} when `options` are invalid.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n this.#pipeline = this.#baseline.pipeline\n }\n\n /** Instance availability probe (honours the `isAvailable` option override). */\n isAvailable(): boolean {\n return (this.#baseline.isAvailable ?? TransformersJsAdapter.isAvailable)()\n }\n\n /**\n * Eagerly resolve (load) the pipeline before the first dispatch.\n *\n * @param overrides - Optional option overrides applied for this load.\n */\n async preload(\n overrides?: Partial<TransformersJsAdapterOptions>\n ): Promise<TransformersJsPipeline> {\n const merged = validateOptions(mergeOptions(this.#baseline, overrides, undefined))\n return this.#resolvePipeline(merged)\n }\n\n /** Drop the cached pipeline/engine and any in-flight load so the next dispatch re-resolves it. */\n reset(): void {\n this.#pipeline = undefined\n this.#pipelinePromise = undefined\n this.#mmEngine = undefined\n this.#mmEnginePromise = undefined\n }\n\n /**\n * Release the loaded model's underlying ONNX sessions + GPU/wasm buffers, then drop all cached\n * references (so the next dispatch re-resolves a fresh pipeline).\n *\n * @remarks\n * `reset()` only nulls the JS references — it does NOT free the native ONNX Runtime sessions or the\n * WebGPU/wasm device memory they hold. Those leak until GC, and in a browser session that loads many\n * models back-to-back (e.g. a full matrix run) the accumulated sessions exhaust the heap, surfacing as\n * `Can't create a session … Failed to load external data file … memory copy`. transformers.js exposes\n * `PreTrainedModel.dispose()` (\"disposes of all the ONNX sessions created during inference\") and\n * `Pipeline.dispose()` — this awaits them so the memory is actually reclaimed between loads. Settles any\n * in-flight load first, swallows per-handle disposal errors (a half-loaded model must not throw out of\n * teardown), and finishes with `reset()`. Idempotent and safe to call when nothing is loaded.\n */\n async dispose(): Promise<void> {\n // Settle any in-flight load so we dispose the resolved handle rather than orphaning it.\n const pipeline = this.#pipeline ?? (await this.#pipelinePromise?.catch(() => undefined))\n const mmEngine = this.#mmEngine ?? (await this.#mmEnginePromise?.catch(() => undefined))\n const disposables: Array<Promise<unknown>> = []\n const pipeWithDispose = pipeline as { dispose?: () => Promise<unknown> } | undefined\n if (typeof pipeWithDispose?.dispose === 'function') {\n disposables.push(Promise.resolve(pipeWithDispose.dispose()).catch(() => undefined))\n }\n const mmModel = mmEngine?.model as { dispose?: () => Promise<unknown> } | undefined\n if (typeof mmModel?.dispose === 'function') {\n disposables.push(Promise.resolve(mmModel.dispose()).catch(() => undefined))\n }\n await Promise.all(disposables)\n this.reset()\n }\n\n /**\n * Free the WebGPU buffer cache by releasing the model's ONNX sessions, then reload the same model.\n *\n * @remarks\n * The consumer-facing lever for the ONNX Runtime Web WebGPU **buffer-freelist high-water-mark** (see\n * {@link @nhtio/adk/batteries!probeGpuBudget} and the battery's GPU-budget notes). ORT-web parks freed\n * activation buffers in per-size buckets sized to the largest tensor shape the model has run; the pool\n * is flushed ONLY when every session of the model is released (ORT clears the cache at\n * `sessionCount === 0`; microsoft/onnxruntime#22490). There is no public flag to flush it mid-life, so\n * the supported way to reclaim that retained working-set without permanently unloading the model is to\n * dispose the sessions and load again.\n *\n * This is exactly `dispose()` followed by `preload()` — surfaced as a named method because \"recycle to\n * free the GPU buffer cache\" is a distinct, intentional operation (e.g. an application offering a\n * \"free GPU memory\" action after a {@link @nhtio/adk/batteries!E_LLM_GPU_OUT_OF_MEMORY}), not a\n * teardown. It is NOT invoked automatically by the battery — the ADK surfaces the lever and leaves the\n * decision to the consumer. Re-incurs the cold-load cost (download is cached; the WebGPU graph/shader\n * compile is not). Idempotent.\n *\n * @param overrides - Optional option overrides applied to the reload (same as {@link preload}).\n */\n async recycle(overrides?: Partial<TransformersJsAdapterOptions>): Promise<void> {\n await this.dispose()\n await this.preload(overrides)\n }\n\n /**\n * Resolve the PORTABLE generation contract (shared with LiteRT-LM) from the merged options. Canonical\n * fields win; the transformers.js-native fields ({@link TransformersJsAdapterOptions.maxNewTokens},\n * `doSample`, `multimodal`, …) are the fallback layer consulted only when the canonical one is unset.\n */\n #gen(merged: TransformersJsAdapterOptions): ResolvedGenerationOptions {\n // Native `multimodal` is `boolean | {image,audio}` → normalise to the canonical `{image,audio}` shape.\n const mm = merged.multimodal\n const normalizedMultimodal: { image?: boolean; audio?: boolean } | undefined =\n mm === undefined || mm === false\n ? mm === false\n ? { image: false, audio: false }\n : undefined\n : mm === true\n ? { image: true, audio: true }\n : mm\n // Native `doSample` boolean → canonical sampler strategy. `true` becomes `'top-p'` (the common\n // nucleus default); an explicit `sampler` canonical field overrides this entirely.\n const nativeSampler: ChatSampler | undefined =\n merged.doSample === undefined ? undefined : merged.doSample ? 'top-p' : 'greedy'\n return resolveGenerationOptions(\n {\n maxTokens: merged.maxTokens,\n sampler: merged.sampler,\n temperature: merged.temperature,\n topK: merged.topK,\n topP: merged.topP,\n seed: merged.seed,\n enableThinking: merged.enableThinking,\n // The canonical `multimodal` IS the native field here (transformers.js already used `{image,audio}`);\n // pass it as both so canonical-wins is a no-op and the normalized shape flows through.\n multimodal: normalizedMultimodal,\n },\n {\n maxTokens: merged.maxNewTokens,\n sampler: nativeSampler,\n multimodal: normalizedMultimodal,\n }\n )\n }\n\n /** Normalise multimodal config to `{image,audio}` flags, or undefined when fully off. */\n #multimodalFlags(\n merged: TransformersJsAdapterOptions\n ): { image: boolean; audio: boolean } | undefined {\n const { multimodal } = this.#gen(merged)\n return multimodal.image || multimodal.audio ? multimodal : undefined\n }\n\n /** Resolve (and cache, single-flight) the multimodal model+processor pair. */\n async #resolveMultimodalEngine(merged: TransformersJsAdapterOptions): Promise<{\n model: TransformersJsModel\n processor: TransformersJsProcessor\n }> {\n if (merged.multimodalEngine) {\n this.#mmEngine = merged.multimodalEngine\n return merged.multimodalEngine\n }\n if (this.#mmEngine) return this.#mmEngine\n this.#mmEnginePromise ??= (async () => {\n emitLifecycle(merged, 'transformers_js', merged.model, 'loading', {\n detail: 'loading multimodal model + processor',\n })\n // Forward each provider download event into a `loading` lifecycle report (normalized 0..1).\n const forwardedInitProgress = wrapTransformersInitProgress(merged)\n try {\n const createMultimodal =\n merged.createMultimodal ??\n (async ({ model, device, dtype, onInitProgress, sessionOptions }) => {\n const transformers = await import('@huggingface/transformers')\n const { AutoModelForImageTextToText, AutoProcessor, env } = transformers\n const load = async () => {\n const [m, processor] = await Promise.all([\n AutoModelForImageTextToText.from_pretrained(model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n // Forward ONNX Runtime session options verbatim (e.g. preferredOutputLocation,\n // graphOptimizationLevel). A reachable lever, not auto-applied — see options doc.\n ...(sessionOptions ? { session_options: sessionOptions } : {}),\n } as never) as unknown as Promise<TransformersJsModel>,\n AutoProcessor.from_pretrained(model) as unknown as Promise<TransformersJsProcessor>,\n ])\n return { model: m, processor }\n }\n // When a custom model source is configured, serve files through it (OPFS / bundled / etc.)\n // behind the global-`env` mutex; otherwise load straight from HF (unchanged path).\n return merged.modelSource\n ? withModelSource(env as never, merged.modelSource, load)\n : load()\n })\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call, so this is \"now preparing the graph\", not a strict\n // post-download boundary).\n emitLifecycle(merged, 'transformers_js', merged.model, 'compiling', {\n detail: 'compiling multimodal model graph',\n })\n const mmSessionOptions = resolveSessionOptions(merged)\n const engine = await createMultimodal({\n model: merged.model,\n device: merged.device,\n dtype: merged.dtype,\n onInitProgress: forwardedInitProgress,\n ...(mmSessionOptions ? { sessionOptions: mmSessionOptions } : {}),\n })\n this.#mmEngine = engine\n emitLifecycle(merged, 'transformers_js', merged.model, 'ready', {\n detail: 'multimodal model + processor ready',\n // Surface the WebGPU budget so the consumer can relate its context window to the device's\n // per-allocation ceiling — observability, never an imposed cap. Absent on non-WebGPU runtimes.\n gpuBudget: await probeGpuBudget(),\n })\n return engine\n } catch (err) {\n this.#mmEnginePromise = undefined\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STREAM_ERROR([\n `could not load the transformers.js multimodal model: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#mmEnginePromise\n }\n\n async #resolvePipeline(merged: TransformersJsAdapterOptions): Promise<TransformersJsPipeline> {\n if (merged.pipeline) {\n this.#pipeline = merged.pipeline\n return merged.pipeline\n }\n if (this.#pipeline) return this.#pipeline\n this.#pipelinePromise ??= (async () => {\n emitLifecycle(merged, 'transformers_js', merged.model, 'loading', {\n detail: 'loading text-generation pipeline',\n })\n const forwardedInitProgress = wrapTransformersInitProgress(merged)\n try {\n const createPipeline =\n merged.createPipeline ??\n (async ({ model, device, dtype, onInitProgress, sessionOptions }) => {\n const transformers = await import('@huggingface/transformers')\n const { pipeline, env } = transformers\n const load = async () =>\n (await pipeline('text-generation', model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n // Forward ONNX Runtime session options verbatim (e.g. preferredOutputLocation,\n // graphOptimizationLevel). A reachable lever, not auto-applied — see options doc.\n ...(sessionOptions ? { session_options: sessionOptions } : {}),\n } as never)) as unknown as TransformersJsPipeline\n return merged.modelSource\n ? withModelSource(env as never, merged.modelSource, load)\n : load()\n })\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call, so this is \"now preparing the graph\", not a strict\n // post-download boundary).\n emitLifecycle(merged, 'transformers_js', merged.model, 'compiling', {\n detail: 'compiling text-generation graph',\n })\n const pipelineSessionOptions = resolveSessionOptions(merged)\n const pipe = await createPipeline({\n model: merged.model,\n device: merged.device,\n dtype: merged.dtype,\n onInitProgress: forwardedInitProgress,\n ...(pipelineSessionOptions ? { sessionOptions: pipelineSessionOptions } : {}),\n })\n this.#pipeline = pipe\n emitLifecycle(merged, 'transformers_js', merged.model, 'ready', {\n detail: 'text-generation pipeline ready',\n // Surface the WebGPU budget so the consumer can relate its context window to the device's\n // per-allocation ceiling — observability, never an imposed cap. Absent on non-WebGPU runtimes.\n gpuBudget: await probeGpuBudget(),\n })\n return pipe\n } catch (err) {\n this.#pipelinePromise = undefined\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STREAM_ERROR([\n `could not load the transformers.js pipeline: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#pipelinePromise\n }\n\n /**\n * Build the transformers.js `generate` kwargs from the merged options (excluding tools/streamer).\n *\n * @remarks\n * Every sampling/length knob is passed EXPLICITLY with a deterministic-friendly default (resolved via\n * the shared {@link resolveGenerationOptions} from the portable contract) so the downstream `generate`\n * never falls back to the model config's own guess — the source of per-model surprises. Greedy maps to\n * `do_sample:false`; `'top-k'`/`'top-p'` map to `do_sample:true` + the matching cutoff.\n */\n #generateKwargs(merged: TransformersJsAdapterOptions): Record<string, unknown> {\n const gen = this.#gen(merged)\n const doSample = gen.sampler !== 'greedy'\n const kw: Record<string, unknown> = {\n max_new_tokens: gen.maxTokens,\n do_sample: doSample,\n repetition_penalty: merged.repetitionPenalty ?? 1.1,\n }\n // Sampler knobs are meaningful ONLY when sampling. Greedy ignores them and transformers.js logs a\n // warning if they're set — so send them only when sampling. We always send BOTH top_k and top_p (the\n // generate() call accepts both regardless of strategy; the strategy just determines which dominates),\n // keeping the sampler fully specified. seed is forwarded when provided.\n if (doSample) {\n kw.temperature = gen.temperature\n kw.top_k = gen.topK\n kw.top_p = gen.topP\n if (gen.seed !== undefined) kw.seed = gen.seed\n }\n if (merged.stopStrings !== undefined) kw.stop_strings = [...merged.stopStrings]\n return kw\n }\n\n /**\n * Produce the bound {@link DispatchExecutorFn} the `DispatchRunner` invokes.\n *\n * @param overrides - Option overrides layered above the constructor baseline (below `ctx.stash`).\n */\n executor(overrides?: Partial<TransformersJsAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = TransformersJsAdapter\n const self = this\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n // 1. Three-layer merge + re-validate.\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<TransformersJsAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n const h = resolveHelpers(merged.helpers)\n const selfIdentity = merged.selfIdentity ?? 'assistant'\n const unsupportedMediaPolicy = merged.unsupportedMediaPolicy ?? 'throw'\n const toolCallParser = resolveToolCallParser(merged.toolCallParser)\n const reasoningParser = resolveReasoningParser(merged.reasoningParser, undefined, {\n orphanRecovery: merged.reasoningOrphanRecovery,\n })\n\n // 2. Artifact-reader tools are forged by the DispatchRunner CORE into `ctx.tools` before the input\n // pipeline runs (generation is a generic core concern; this battery owns only representation).\n // Read the pre-forged `ctx.tools` directly — no local merge, no bindContext here.\n\n // 3. Pre-render persisted tool-call results into plain-text tool message bodies.\n const renderedToolCallResults = new Map<ToolCall, string>()\n for (const tc of ctx.turnToolCalls) {\n const tool = ctx.tools.get(tc.tool)\n const body = await h.renderTransformersJsToolResult({\n toolCall: tc,\n results: tc.results,\n tool: tool as Tool | ArtifactTool | undefined,\n unsupportedMediaPolicy,\n renderUntrustedContent: h.renderUntrustedContent,\n renderTrustedContent: h.renderTrustedContent,\n renderArtifactHandleBody: h.renderArtifactHandleBody,\n warn: (m) =>\n helpers.log.warn({\n kind: 'transformers-render-warning',\n message: m,\n }),\n })\n renderedToolCallResults.set(tc, body)\n }\n\n // 4. Optional context-window enforcement.\n if (merged.tokenEncoding && merged.contextWindow !== undefined) {\n const enc = merged.tokenEncoding\n const tally = (s: string): number =>\n new Tokenizable(s).estimateTokens(enc as TokenEncodingId)\n let total = tally(ctx.systemPrompt.toString())\n for (const si of ctx.standingInstructions) total += tally(si.toString())\n for (const m of ctx.turnMemories) total += tally(m.content.toString())\n for (const r of ctx.turnRetrievables) {\n total +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n enc as TokenEncoding,\n h.renderRetrievableHandleBody\n )\n : tally((await r.contentString?.()) ?? '')\n }\n for (const m of ctx.turnMessages) total += tally(m.content?.toString() ?? '')\n for (const t of ctx.turnThoughts) total += tally(t.content.toString())\n for (const body of renderedToolCallResults.values()) total += tally(body)\n // Tool DECLARATIONS: transformers.js feeds the visible tools to `apply_chat_template({tools})`,\n // where the MODEL'S OWN Jinja template wraps them (per-model, in-process) — so the exact rendered\n // string isn't reproducible here without running the processor. Tally the serialized tool JSON\n // (the reproducible, dominant component the adapter actually passes) as an honest FLOOR. Without\n // this the guard undercounts a tool-heavy prompt by the entire declaration block.\n const visibleTools = ctx.tools.visible()\n if (visibleTools.length > 0) {\n total += tally(JSON.stringify(h.toolsToTransformersJsTools(visibleTools)))\n }\n if (total > merged.contextWindow) {\n throw new E_TRANSFORMERS_JS_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n String(enc),\n `system+buckets+timeline+tools=${total}`,\n ])\n }\n }\n\n // 5. Build the transformers.js message array + tools (+ decoded media when multimodal).\n const mmFlags = self.#multimodalFlags(merged)\n const {\n messages: turnMessages,\n tools: toolDefs,\n images: mmImages,\n audio: mmAudio,\n } = await h.buildTransformersJsMessages({\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,\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n toolsToTransformersJsTools: h.toolsToTransformersJsTools,\n renderThought: h.renderThought,\n filterThoughts: h.filterThoughts,\n renderUntrustedContent: h.renderUntrustedContent,\n renderTrustedContent: h.renderTrustedContent,\n renderChatCompletionsSystemPrompt: h.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: h.renderStandingInstructions,\n renderMemories: h.renderMemories,\n renderRetrievables: h.renderRetrievables,\n renderRetrievableSafetyDirective: h.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: h.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: h.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: h.renderThirdPartyPrivateRetrievables,\n renderRetrievableHandleBody: h.renderRetrievableHandleBody,\n multimodal: mmFlags,\n decodeMedia: mmFlags ? (media) => defaultMediaToTransformersInput(media) : undefined,\n unsupportedMediaPolicy,\n warn: (m) =>\n helpers.log.warn({\n kind: 'transformers-history-warning',\n message: m,\n }),\n })\n\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n const stream = merged.stream ?? true\n\n // One id for this whole generation — correlates the TO tap (onPromptAssembled) with the FROM tap\n // (onRawGeneration) and the reported message; both dispatch paths below reuse it.\n const dispatchStreamId = uuidv6()\n\n // Prompt-assembled observability tap: the EXACT messages + tools going TO the model, the instant\n // assembly finished (above) and before the pipeline/generate dispatch (below). Mirror of\n // onRawGeneration. Handed back AS-IS — no redaction — and swallow observer errors so it can never\n // corrupt the generation path.\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'transformers_js',\n kind: 'rendered-prompt',\n messages: turnMessages,\n tools: toolDefs,\n streamed: stream,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n const gen = self.#gen(merged)\n const generateKwargs = self.#generateKwargs(merged)\n const toolNames = ctx.tools.visible().map((t) => t.name)\n // A short, user-facing note carried on a GPU-OOM error so the application can show WHY it failed\n // and what to change. We surface the budget/window relationship, never silently cap it.\n const oomNote =\n merged.contextWindow !== undefined\n ? `The configured context window (${merged.contextWindow} tokens, max ${gen.maxTokens} output) exceeded the available GPU memory. Reduce the context window or max output tokens and retry, recycle the adapter to free the WebGPU buffer cache, or switch to a smaller model.`\n : `The request exceeded the available GPU memory. Reduce the context window or max output tokens and retry, recycle the adapter to free the WebGPU buffer cache, or switch to a smaller model.`\n\n // 6. Resolve the engine: multimodal model+processor, or the text-generation pipeline.\n let pipe: TransformersJsPipeline | undefined\n let mmEngine: { model: TransformersJsModel; processor: TransformersJsProcessor } | undefined\n try {\n if (mmFlags) mmEngine = await self.#resolveMultimodalEngine(merged)\n else pipe = await self.#resolvePipeline(merged)\n } catch (err) {\n // A cold WebGPU load can itself exhaust the device (\"Failed to create session\"). Surface that as\n // the typed GPU-OOM so the consumer gets one consistent, catchable signal for load- and\n // generation-time exhaustion alike; otherwise pass through the (already-typed) stream error.\n const loadMsg = isError(err) ? err.message : String(err)\n ctx.nack(\n isGpuOutOfMemoryError(loadMsg)\n ? toGenerationError(err, oomNote)\n : isInstanceOf(err, 'E_TRANSFORMERS_JS_STREAM_ERROR', E_TRANSFORMERS_JS_STREAM_ERROR)\n ? err\n : new E_TRANSFORMERS_JS_STREAM_ERROR([loadMsg])\n )\n return\n }\n\n if (ctx.abortSignal.aborted) return\n\n // ── Tool execution + persistence (args already an object — no JSON.parse) ──\n const executeAndPersistToolCall = async (call: AssembledToolCall): Promise<void> => {\n const tool = ctx.tools.get(call.name)\n const completedAt = nowIso()\n if (!call.argsWellFormed) {\n const toolName = normalizeToolName(call.name)\n const err = new E_TRANSFORMERS_JS_INVALID_TOOL_CALL_ARGS([\n 'must be a JSON object',\n JSON.stringify(call.args),\n ])\n const results = new Tokenizable(err.message)\n helpers.reportToolCall(call.id, { tool: toolName, args: {} })\n helpers.reportToolCall(call.id, {\n results,\n isError: true,\n isComplete: true,\n })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: {},\n checksum: computeChecksum(toolName, {}),\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 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(call.id, { tool: toolName, args: call.args })\n helpers.reportToolCall(call.id, {\n results,\n isError: true,\n isComplete: true,\n })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: call.args,\n checksum: computeChecksum(toolName, call.args),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n return\n }\n helpers.reportToolCall(call.id, { tool: tool.name, args: call.args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(call.args)\n if (isArtifactTool) {\n results = Tokenizable.isTokenizable(raw)\n ? raw\n : typeof raw === 'string'\n ? new Tokenizable(raw)\n : (() => {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n })()\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(call.id, raw as string | Uint8Array)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(call.id, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n let detailMsg = isError(err) ? err.message : String(err)\n if (isError(err) && isError(err.cause) && err.cause.message !== err.message) {\n detailMsg = `${detailMsg} ${err.cause.message}`\n }\n results = new Tokenizable(detailMsg)\n }\n helpers.reportToolCall(call.id, {\n results,\n isError: toolHadError,\n isComplete: true,\n })\n const completedAt2 = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: tool.name,\n args: call.args,\n checksum: computeChecksum(tool.name, call.args),\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n // 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 const assembleCalls = (raw: ReadonlyArray<ParsedToolCall>): AssembledToolCall[] =>\n raw.map((c) => ({\n id: uuidv6(),\n name: c.name,\n args: isObject(c.arguments) ? (c.arguments as Record<string, unknown>) : {},\n argsWellFormed: isObject(c.arguments),\n }))\n\n // Parse the full generated text → reasoning + clean prose + tool calls, then persist.\n const finishFromText = async (\n rawText: string,\n streamId: string,\n streamedProse: boolean,\n generatedMedia: Media[] = []\n ): Promise<void> => {\n // Normalise away non-semantic envelope/turn-boundary special tokens (Llama `<|python_tag|>`/\n // `<|eom_id|>`, ChatML `<|im_end|>`, …) before parsing. The streaming path decodes with\n // skip_special_tokens:false (its live prose-stop gate needs the markers), so without this the\n // parsers would see `<|python_tag|>{json}<|eom_id|>` on stream and decline — even though the\n // batch path (skip_special_tokens:true) parses the identical call. Idempotent on batch text.\n const fullText = stripEnvelopeSpecialTokens(rawText)\n const reasoned = reasoningParser(fullText)\n const afterReasoning = reasoned.cleanedText\n const parsed = toolCallParser(afterReasoning, { toolNames })\n const cleanText = parsed.cleanedText\n\n // Raw-generation observability tap: surface what the model emitted vs. what parsed, before any\n // persistence. Purely observational — swallow callback errors so a misbehaving observer can\n // never corrupt the generation path.\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: fullText,\n cleanedText: cleanText,\n reasoning: reasoned.reasoning,\n toolCalls: parsed.calls,\n streamed: streamedProse,\n streamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // Persist reasoning as Thoughts. Drop any trace whose trimmed content is empty — an\n // empty/whitespace thought (e.g. a model's `<think>\\n\\n</think>` no-think artifact) carries no\n // information and is just a model quirk; there is no point surfacing it to the consumer.\n for (const trace of reasoned.reasoning) {\n if (trace.trim().length === 0) continue\n const id = uuidv6()\n helpers.reportThought(id, trace, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id,\n content: trace,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n // Persist the assistant message when there is clean prose OR generated media to carry. Media-only\n // turns (empty text + an audio/image attachment) are legitimate; the contract requires at least one\n // of `content`/`attachments`, so a turn with neither stores nothing (unchanged from before).\n if (cleanText.length > 0 || generatedMedia.length > 0) {\n if (streamedProse) {\n helpers.reportMessage(streamId, '', { isComplete: true })\n } else if (cleanText.length > 0) {\n helpers.reportMessage(streamId, cleanText, { isComplete: true })\n }\n await ctx.storeMessage(\n new Message({\n id: streamId,\n role: 'assistant',\n ...(cleanText.length > 0 ? { content: cleanText } : {}),\n ...(generatedMedia.length > 0 ? { attachments: generatedMedia } : {}),\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n // Execute tool calls.\n const calls = assembleCalls(parsed.calls)\n if (calls.length === 0) {\n if (merged.autoAck) ctx.ack()\n return\n }\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n await executeAndPersistToolCall(call)\n }\n }\n\n // ── Streaming path ──\n // Unified generate: drives either the text-generation pipeline OR the multimodal model+processor.\n // Returns the final decoded text for the non-streaming path; streaming text arrives via `streamer`.\n // The raw generation object (model.generate / pipeline output) is captured here so the optional\n // `extractMediaOutputs` hook can surface GENERATED media (audio/image) as assistant attachments.\n let rawGenerationResult: unknown\n const runGenerate = async (streamer: unknown): Promise<string> => {\n if (mmEngine) {\n const { model, processor } = mmEngine\n const proc = processor as unknown as {\n apply_chat_template: (m: unknown, o: unknown) => unknown\n batch_decode: (t: unknown, o: unknown) => string[]\n }\n const callProc = processor as unknown as (\n ...args: unknown[]\n ) => Promise<Record<string, unknown>>\n const prompt = proc.apply_chat_template(turnMessages, {\n add_generation_prompt: true,\n tokenize: false,\n // Explicit thinking flag — never let the template default decide (Qwen3/DeepSeek default ON).\n enable_thinking: gen.enableThinking,\n // Pass tool DEFINITIONS through the native template mechanism, exactly as the pipeline path\n // does. Gemma 4's chat_template renders these as `<|tool>…<tool|>` blocks, which is what\n // cues the model to emit its TRAINED `call:NAME{…}` tool-call format. Omitting them (the\n // prior bug) left the model with no native cue, so it improvised raw JSON args that no\n // parser recognises. This is the multimodal-path equivalent of the pipeline's `tools` arg.\n ...(toolDefs.length > 0 ? { tools: toolDefs } : {}),\n })\n // processor(text, images, audio, options) — positional (verified against the real Gemma-4\n // `Gemma4Processor._call(text, images = null, audio = null, options)`). The audio slot is THIRD,\n // so when audio is present the images slot MUST be filled positionally (with `null` when there\n // is no image) — otherwise audio collapses into the images slot and the image processor throws\n // `image.rgb is not a function`. `if (images)`/`if (audio)` in the processor treat `null` as absent.\n const imageArg =\n mmImages.length === 0 ? null : mmImages.length === 1 ? mmImages[0] : mmImages\n const audioArg = mmAudio.length === 0 ? null : mmAudio.length === 1 ? mmAudio[0] : mmAudio\n const procArgs: unknown[] =\n mmAudio.length > 0\n ? [prompt, imageArg, audioArg] // audio needs the 3rd slot → fill images (null if none)\n : mmImages.length > 0\n ? [prompt, imageArg]\n : [prompt]\n const inputs = await callProc(...procArgs)\n // The processor INPUT tensors are GPU buffers we own. Free them no matter what — including\n // when generate() itself OOMs — so a failed generate doesn't leak its inputs and starve the\n // retry. (generate() is INSIDE this try precisely so the finally also covers its throw.)\n try {\n const out = await (\n model as unknown as { generate: (o: unknown) => Promise<unknown> }\n ).generate({\n ...inputs,\n ...generateKwargs,\n ...(streamer ? { streamer } : {}),\n })\n rawGenerationResult = out\n // Non-stream decode: slice the prompt tokens off, decode the new tail.\n try {\n const inputLen = (inputs.input_ids as { dims?: number[] } | undefined)?.dims?.[1] ?? 0\n const seq = out as { slice?: (...a: unknown[]) => unknown }\n const newTokens =\n typeof seq.slice === 'function' ? seq.slice(null, [inputLen, null]) : out\n const decoded = proc.batch_decode(newTokens, {\n skip_special_tokens: true,\n })\n // Free the slice tensor (a fresh GPU buffer) once decoded — but only when it's distinct\n // from `out`, which we still need for the media extractor (disposed after this returns).\n if (newTokens !== out) disposeTensors(newTokens)\n return (decoded?.[0] ?? '').toString()\n } catch {\n return ''\n }\n } finally {\n disposeTensors(inputs)\n }\n }\n const p = pipe as unknown as (m: unknown, k: unknown) => Promise<unknown>\n const output = await p(turnMessages, {\n ...generateKwargs,\n // Explicit thinking flag forwarded to the pipeline's internal apply_chat_template — never let\n // the template default decide (Qwen3/DeepSeek default thinking ON).\n enable_thinking: gen.enableThinking,\n ...(toolDefs.length > 0 ? { tools: toolDefs } : {}),\n ...(streamer ? { streamer } : {}),\n })\n rawGenerationResult = output\n return extractGeneratedText(output)\n }\n\n // Run the optional media-output extractor over the raw generation result, persisting each generated\n // media via `ctx.storeMediaBytes` and building first-party `Media` attachments. Returns [] when no\n // hook is configured or it yields nothing — the text-only path then attaches nothing (unchanged).\n const collectGeneratedMedia = async (): Promise<Media[]> => {\n if (!merged.extractMediaOutputs || rawGenerationResult === undefined) return []\n const outputs = await merged.extractMediaOutputs(rawGenerationResult)\n const media: Media[] = []\n for (const o of outputs) {\n const id = uuidv6()\n const reader = await ctx.storeMediaBytes(id, o.bytes)\n media.push(\n Media.toolGenerated({\n id,\n kind: o.kind,\n mimeType: o.mimeType,\n filename: o.filename ?? `${id}.${o.kind}`,\n reader,\n })\n )\n }\n return media\n }\n // Free the captured generate OUTPUT tensor after the media extractor (the only consumer of\n // rawGenerationResult) has run. Together with disposing the processor inputs in runGenerate,\n // this releases the caller-owned tensors per generate() — hygiene for the manual multimodal\n // path, which (unlike the pipeline path) hands back tensors we own. Only the multimodal path\n // captures a tensor here; the pipeline path returns plain objects, for which this is a no-op.\n const disposeGenerationOutput = (): void => {\n if (mmEngine && rawGenerationResult !== undefined) disposeTensors(rawGenerationResult)\n rawGenerationResult = undefined\n }\n\n if (stream) {\n const accumulator = h.createTransformersJsStreamAccumulator()\n const streamId = dispatchStreamId\n let proseStopped = false\n let streamedProse = false\n\n // The decoded-text sink: feed the accumulator + stream safe prose deltas (stopping prose once\n // tool-call/think markup appears; the clean message is persisted after generation completes).\n const onText = (text: string): void => {\n accumulator.feed(text)\n if (proseStopped) return\n if (TEXT_MARKUP_MARKERS.some((m) => accumulator.content().includes(m))) {\n proseStopped = true\n return\n }\n if (text.length > 0) {\n streamedProse = true\n helpers.reportMessage(streamId, text)\n }\n }\n\n // Default streamer factory imports the peer's TextStreamer; `createStreamer` overrides it\n // (e.g. tests inject a lightweight sink to avoid importing the heavy peer in the browser env).\n // The tokenizer comes from the multimodal processor when present, else the pipeline.\n const tokenizerHost = (mmEngine?.processor ?? pipe) as unknown as {\n tokenizer: unknown\n }\n const createStreamer =\n merged.createStreamer ??\n (async ({ onText: cb }) => {\n const { TextStreamer } = await import('@huggingface/transformers')\n return new TextStreamer(\n tokenizerHost.tokenizer as never,\n {\n skip_prompt: true,\n skip_special_tokens: false,\n callback_function: cb,\n } as never\n )\n })\n\n let streamer: unknown\n try {\n streamer = await createStreamer({\n pipeline: pipe as TransformersJsPipeline,\n onText,\n })\n } catch (err) {\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n ctx.nack(new E_TRANSFORMERS_JS_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n emitLifecycle(merged, 'transformers_js', merged.model, 'generating')\n try {\n await runGenerate(streamer)\n } catch (err) {\n if (ctx.abortSignal.aborted) return\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n ctx.nack(toGenerationError(err, oomNote))\n return\n }\n if (ctx.abortSignal.aborted) return\n const streamMedia = await collectGeneratedMedia()\n disposeGenerationOutput()\n await finishFromText(accumulator.content(), streamId, streamedProse, streamMedia)\n emitLifecycle(merged, 'transformers_js', merged.model, 'complete')\n return\n }\n\n // ── Non-streaming path ──\n let finalText: string\n emitLifecycle(merged, 'transformers_js', merged.model, 'generating')\n try {\n finalText = await runGenerate(undefined)\n } catch (err) {\n emitLifecycle(merged, 'transformers_js', merged.model, 'error', {\n error: err,\n })\n ctx.nack(toGenerationError(err, oomNote))\n return\n }\n if (ctx.abortSignal.aborted) return\n const nonStreamMedia = await collectGeneratedMedia()\n disposeGenerationOutput()\n await finishFromText(finalText, dispatchStreamId, false, nonStreamMedia)\n emitLifecycle(merged, 'transformers_js', merged.model, 'complete')\n }\n }\n}\n\n/**\n * Free the GPU buffers backing a transformers.js value when running on the WebGPU EP.\n *\n * @remarks\n * onnxruntime-web does NOT garbage-collect GPU tensors — each `Tensor` whose `location` is\n * `'gpu-buffer'` owns a Dawn buffer that is reclaimed ONLY by an explicit `.dispose()`. In the\n * manual multimodal `model.generate()` path the battery creates the processor INPUT tensors and\n * captures the generate OUTPUT tensor; transformers.js frees its own internal decode-loop tensors\n * and KV cache, but these caller-owned tensors are ours to free. Skipping that leaks ~the full\n * activation set per `generate()`, so the SECOND generate on a loaded model (a tool-loop iteration,\n * the answer classifier, or simply the next turn) fails with \"Failed to allocate memory for buffer\n * mapping\". The matrix tests never caught this — each cell builds a fresh adapter and generates\n * exactly once.\n *\n * Accepts a processor-inputs object (a map of named tensors), a single tensor, or a nested\n * generate output; walks it shallowly and disposes anything tensor-shaped. Best-effort and never\n * throws — a disposal failure must not break generation. No-op for CPU/WASM tensors (which have no\n * `dispose` or aren't GPU-backed), so it's safe across execution providers.\n */\nconst disposeTensors = (value: unknown): void => {\n const tryDispose = (t: unknown): void => {\n const d = t as { dispose?: () => void; location?: string } | null | undefined\n if (d && typeof d.dispose === 'function') {\n try {\n d.dispose()\n } catch {\n /* best-effort: a failed dispose must never break generation */\n }\n }\n }\n if (value === null || value === undefined) return\n // A bare tensor (has its own dispose).\n if (typeof (value as { dispose?: unknown }).dispose === 'function') {\n tryDispose(value)\n return\n }\n // A processor-inputs map { input_ids, attention_mask, pixel_values, … } or an array of tensors.\n if (typeof value === 'object') {\n for (const v of Object.values(value as Record<string, unknown>)) tryDispose(v)\n }\n}\n\n/**\n * Pull the newly-generated assistant text out of a transformers.js text-generation result.\n *\n * @remarks\n * Chat input → `[{ generated_text: Message[] }]` (the last message is the new assistant turn);\n * string input → `[{ generated_text: string }]`. We always send chat input, so we take the last\n * message's content, falling back defensively to a string `generated_text`.\n */\nconst extractGeneratedText = (output: unknown): string => {\n const first = Array.isArray(output) ? output[0] : output\n const gen = (first as { generated_text?: unknown } | undefined)?.generated_text\n if (typeof gen === 'string') return gen\n if (Array.isArray(gen)) {\n const last = gen[gen.length - 1] as { content?: unknown } | undefined\n const content = last?.content\n if (typeof content === 'string') return content\n if (Array.isArray(content)) {\n return content\n .filter(\n (i): i is { type: string; text: string } =>\n isObject(i) && (i as { type?: unknown }).type === 'text'\n )\n .map((i) => i.text)\n .join('')\n }\n }\n return ''\n}\n\nexport { extractGeneratedText as __extractGeneratedText }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4FA,IAAM,gBACJ,WAC8E;CAC9E,IAAI;CACJ,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,OAAO;EACZ,SAAS;GAAE,GAAI,UAAU,CAAC;GAAI,GAAG;EAAM;CACzC;CACA,OAAO;AACT;AAEA,IAAM,gBACJ,UACA,MACA,UAC0C;CAC1C,MAAM,SAAS;EAAC;EAAmD,QAAQ,CAAC;EAAG,SAAS,CAAC;CAAC;CAC1F,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,GAAG;EAC1C,IAAI,MAAM,KAAA,GAAW;EACrB,IAAI,MAAM,WAAW;EACrB,IAAI,KAAK;CACX;CAEF,MAAM,UAAU,aAAa,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC;CACzD,IAAI,YAAY,KAAA,GAAW,IAAI,UAAU;CACzC,OAAO;AACT;AA0BA,IAAM,kBACJ,cACoB;CACpB,MAAM,MAAO,aAAa,CAAC;CAC3B,MAAM,QACJ,KACA,SACwB,IAAI,QAAyC;CACvE,OAAO;EACL,wCAAwC,KACtC,0CACA,6CACF;EACA,wBAAwB,KAAK,0BAA0B,6BAA6B;EACpF,sBAAsB,KAAK,wBAAwB,2BAA2B;EAC9E,4BAA4B,KAC1B,8BACA,iCACF;EACA,gBAAgB,KAAK,kBAAkB,qBAAqB;EAC5D,oBAAoB,KAAK,sBAAsB,yBAAyB;EACxE,kCAAkC,KAChC,oCACA,uCACF;EACA,8BAA8B,KAC5B,gCACA,mCACF;EACA,oCAAoC,KAClC,sCACA,yCACF;EACA,qCAAqC,KACnC,uCACA,0CACF;EACA,eAAe,KAAK,iBAAiB,oBAAoB;EACzD,gBAAgB,KAAK,kBAAkB,qBAAqB;EAC5D,mCAAmC,KACjC,qCACA,wCACF;EACA,4BAA4B,KAC1B,8BACA,iCACF;EACA,gCAAgC,KAC9B,kCACA,qCACF;EACA,0BAA0B,KAAK,4BAA4B,+BAA+B;EAC1F,6BAA6B,KAC3B,+BACA,kCACF;EACA,6BAA6B,KAC3B,+BACA,kCACF;EACA,uCAAuC,KACrC,yCACA,4CACF;CACF;AACF;AAEA,IAAM,eAAuB,SAAS,IAAI,EAAE,MAAM;AAElD,IAAM,mBAAmB,MAAc,SACrC,OAAO,mBAAmB;CAAE;CAAM;AAAK,CAAC,CAAC;;;;;;;AAQ3C,IAAM,gCACJ,WACmD;CAOnD,IAAI,EALF,OAAO,eACP,OAAO,aACP,OAAO,WACP,OAAO,gBACP,OAAO,UACU,OAAO,OAAO;CACjC,QAAQ,SAAkB;EACxB,MAAM,IAAK,MAA4C;EACvD,cAAc,QAAQ,mBAAmB,OAAO,OAAO,WAAW;GAChE,GAAI,OAAO,MAAM,WAAW,EAAE,UAAU,IAAI,IAAI,IAAI,CAAC;GACrD,KAAK;EACP,CAAC;EACD,OAAO,iBAAiB,IAAa;CACvC;AACF;;AAGA,IAAM,sBAAsB;CAC1B;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;AAoBA,IAAM,qBACJ,KACA,gBAGyD;CACzD,MAAM,UAAU,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;CACvD,IAAI,sBAAsB,OAAO,GAC/B,OAAO,IAAI,wBAAwB,CAAC,SAAS,WAAW,GAAG,EACzD,OAAO,QAAQ,GAAG,IAAI,MAAM,KAAA,EAC9B,CAAC;CAEH,OAAO,IAAI,+BAA+B,CAAC,OAAO,CAAC;AACrD;;;;;;AAOA,IAAM,kBAAkB,WAA4D;CAClF,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,IAAI,OAAO,WAAW,UAAU,OAAO,WAAW,YAAY,WAAW;CAEzE,OAAO,OAAO,OAAO,MAAM,EAAE,MAAM,MAAM,MAAM,YAAY,MAAM,KAAK;AACxE;;;;;;;;;;;;;;;;AAiBA,IAAM,yBAAyB,SAAS,OAAqC;CAC3E,MAAM,MAAoC,CAAC;CAC3C,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;EAC/B,IAAI,WAAW,EAAE,SAAS;EAC1B,IAAI,WAAW,EAAE,WAAW;CAC9B;CACA,OAAO;AACT;;;;;;;;;;;;AAaA,IAAM,yBACJ,WAC+D;CAC/D,MAAM,WAAW,OAAO;CAGxB,IAAI,GAFa,OAAO,mBAAmB,SAAS,eAAe,OAAO,MAAM,MAEhE,UAAU,4BAA4B,KAAA,GAAW,OAAO;CACxE,OAAO;EAAE,GAAI,YAAY,CAAC;EAAI,yBAAyB,sBAAsB;CAAE;AACjF;;;;;;;;;AAUA,IAAa,wBAAb,MAAa,sBAAsB;;CAEjC,OAAuB,YAAY;CAEnC;CACA;CACA;CACA;CACA;;;;;;CAYA,OAAc,cAAuB;EACnC,OAAO;CACT;;;;;CAMA,YAAY,SAAkB;EAC5B,KAAKA,YAAY,gBAAgB,OAAO;EACxC,KAAKC,YAAY,KAAKD,UAAU;CAClC;;CAGA,cAAuB;EACrB,QAAQ,KAAKA,UAAU,eAAe,sBAAsB,aAAa;CAC3E;;;;;;CAOA,MAAM,QACJ,WACiC;EACjC,MAAM,SAAS,gBAAgB,aAAa,KAAKA,WAAW,WAAW,KAAA,CAAS,CAAC;EACjF,OAAO,KAAKE,iBAAiB,MAAM;CACrC;;CAGA,QAAc;EACZ,KAAKD,YAAY,KAAA;EACjB,KAAKE,mBAAmB,KAAA;EACxB,KAAKC,YAAY,KAAA;EACjB,KAAKC,mBAAmB,KAAA;CAC1B;;;;;;;;;;;;;;;CAgBA,MAAM,UAAyB;EAE7B,MAAM,WAAW,KAAKJ,aAAc,MAAM,KAAKE,kBAAkB,YAAY,KAAA,CAAS;EACtF,MAAM,WAAW,KAAKC,aAAc,MAAM,KAAKC,kBAAkB,YAAY,KAAA,CAAS;EACtF,MAAM,cAAuC,CAAC;EAC9C,MAAM,kBAAkB;EACxB,IAAI,OAAO,iBAAiB,YAAY,YACtC,YAAY,KAAK,QAAQ,QAAQ,gBAAgB,QAAQ,CAAC,EAAE,YAAY,KAAA,CAAS,CAAC;EAEpF,MAAM,UAAU,UAAU;EAC1B,IAAI,OAAO,SAAS,YAAY,YAC9B,YAAY,KAAK,QAAQ,QAAQ,QAAQ,QAAQ,CAAC,EAAE,YAAY,KAAA,CAAS,CAAC;EAE5E,MAAM,QAAQ,IAAI,WAAW;EAC7B,KAAK,MAAM;CACb;;;;;;;;;;;;;;;;;;;;;;CAuBA,MAAM,QAAQ,WAAkE;EAC9E,MAAM,KAAK,QAAQ;EACnB,MAAM,KAAK,QAAQ,SAAS;CAC9B;;;;;;CAOA,KAAK,QAAiE;EAEpE,MAAM,KAAK,OAAO;EAClB,MAAM,uBACJ,OAAO,KAAA,KAAa,OAAO,QACvB,OAAO,QACL;GAAE,OAAO;GAAO,OAAO;EAAM,IAC7B,KAAA,IACF,OAAO,OACL;GAAE,OAAO;GAAM,OAAO;EAAK,IAC3B;EAGR,MAAM,gBACJ,OAAO,aAAa,KAAA,IAAY,KAAA,IAAY,OAAO,WAAW,UAAU;EAC1E,OAAO,yBACL;GACE,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB,aAAa,OAAO;GACpB,MAAM,OAAO;GACb,MAAM,OAAO;GACb,MAAM,OAAO;GACb,gBAAgB,OAAO;GAGvB,YAAY;EACd,GACA;GACE,WAAW,OAAO;GAClB,SAAS;GACT,YAAY;EACd,CACF;CACF;;CAGA,iBACE,QACgD;EAChD,MAAM,EAAE,eAAe,KAAKC,KAAK,MAAM;EACvC,OAAO,WAAW,SAAS,WAAW,QAAQ,aAAa,KAAA;CAC7D;;CAGA,MAAMC,yBAAyB,QAG5B;EACD,IAAI,OAAO,kBAAkB;GAC3B,KAAKH,YAAY,OAAO;GACxB,OAAO,OAAO;EAChB;EACA,IAAI,KAAKA,WAAW,OAAO,KAAKA;EAChC,KAAKC,sBAAsB,YAAY;GACrC,cAAc,QAAQ,mBAAmB,OAAO,OAAO,WAAW,EAChE,QAAQ,uCACV,CAAC;GAED,MAAM,wBAAwB,6BAA6B,MAAM;GACjE,IAAI;IACF,MAAM,mBACJ,OAAO,qBACN,OAAO,EAAE,OAAO,QAAQ,OAAO,gBAAgB,qBAAqB;KAEnE,MAAM,EAAE,6BAA6B,eAAe,QAAQ,MADjC,OAAO;KAElC,MAAM,OAAO,YAAY;MACvB,MAAM,CAAC,GAAG,aAAa,MAAM,QAAQ,IAAI,CACvC,4BAA4B,gBAAgB,OAAO;OACjD,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;OAC3B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;OACzB,GAAI,iBAAiB,EAAE,mBAAmB,eAAe,IAAI,CAAC;OAG9D,GAAI,iBAAiB,EAAE,iBAAiB,eAAe,IAAI,CAAC;MAC9D,CAAU,GACV,cAAc,gBAAgB,KAAK,CACrC,CAAC;MACD,OAAO;OAAE,OAAO;OAAG;MAAU;KAC/B;KAGA,OAAO,OAAO,cACV,gBAAgB,KAAc,OAAO,aAAa,IAAI,IACtD,KAAK;IACX;IAKF,cAAc,QAAQ,mBAAmB,OAAO,OAAO,aAAa,EAClE,QAAQ,mCACV,CAAC;IACD,MAAM,mBAAmB,sBAAsB,MAAM;IACrD,MAAM,SAAS,MAAM,iBAAiB;KACpC,OAAO,OAAO;KACd,QAAQ,OAAO;KACf,OAAO,OAAO;KACd,gBAAgB;KAChB,GAAI,mBAAmB,EAAE,gBAAgB,iBAAiB,IAAI,CAAC;IACjE,CAAC;IACD,KAAKD,YAAY;IACjB,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS;KAC9D,QAAQ;KAGR,WAAW,MAAM,eAAe;IAClC,CAAC;IACD,OAAO;GACT,SAAS,KAAK;IACZ,KAAKC,mBAAmB,KAAA;IACxB,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS,EAC9D,OAAO,IACT,CAAC;IACD,MAAM,IAAI,+BAA+B,CACvC,wDAAwD,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAAE,oEACnG,CAAC;GACH;EACF,GAAG;EACH,OAAO,KAAKA;CACd;CAEA,MAAMH,iBAAiB,QAAuE;EAC5F,IAAI,OAAO,UAAU;GACnB,KAAKD,YAAY,OAAO;GACxB,OAAO,OAAO;EAChB;EACA,IAAI,KAAKA,WAAW,OAAO,KAAKA;EAChC,KAAKE,sBAAsB,YAAY;GACrC,cAAc,QAAQ,mBAAmB,OAAO,OAAO,WAAW,EAChE,QAAQ,mCACV,CAAC;GACD,MAAM,wBAAwB,6BAA6B,MAAM;GACjE,IAAI;IACF,MAAM,iBACJ,OAAO,mBACN,OAAO,EAAE,OAAO,QAAQ,OAAO,gBAAgB,qBAAqB;KAEnE,MAAM,EAAE,UAAU,QAAQ,MADC,OAAO;KAElC,MAAM,OAAO,YACV,MAAM,SAAS,mBAAmB,OAAO;MACxC,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;MAC3B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;MACzB,GAAI,iBAAiB,EAAE,mBAAmB,eAAe,IAAI,CAAC;MAG9D,GAAI,iBAAiB,EAAE,iBAAiB,eAAe,IAAI,CAAC;KAC9D,CAAU;KACZ,OAAO,OAAO,cACV,gBAAgB,KAAc,OAAO,aAAa,IAAI,IACtD,KAAK;IACX;IAKF,cAAc,QAAQ,mBAAmB,OAAO,OAAO,aAAa,EAClE,QAAQ,kCACV,CAAC;IACD,MAAM,yBAAyB,sBAAsB,MAAM;IAC3D,MAAM,OAAO,MAAM,eAAe;KAChC,OAAO,OAAO;KACd,QAAQ,OAAO;KACf,OAAO,OAAO;KACd,gBAAgB;KAChB,GAAI,yBAAyB,EAAE,gBAAgB,uBAAuB,IAAI,CAAC;IAC7E,CAAC;IACD,KAAKF,YAAY;IACjB,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS;KAC9D,QAAQ;KAGR,WAAW,MAAM,eAAe;IAClC,CAAC;IACD,OAAO;GACT,SAAS,KAAK;IACZ,KAAKE,mBAAmB,KAAA;IACxB,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS,EAC9D,OAAO,IACT,CAAC;IACD,MAAM,IAAI,+BAA+B,CACvC,gDAAgD,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAAE,oEAC3F,CAAC;GACH;EACF,GAAG;EACH,OAAO,KAAKA;CACd;;;;;;;;;;CAWA,gBAAgB,QAA+D;EAC7E,MAAM,MAAM,KAAKG,KAAK,MAAM;EAC5B,MAAM,WAAW,IAAI,YAAY;EACjC,MAAM,KAA8B;GAClC,gBAAgB,IAAI;GACpB,WAAW;GACX,oBAAoB,OAAO,qBAAqB;EAClD;EAKA,IAAI,UAAU;GACZ,GAAG,cAAc,IAAI;GACrB,GAAG,QAAQ,IAAI;GACf,GAAG,QAAQ,IAAI;GACf,IAAI,IAAI,SAAS,KAAA,GAAW,GAAG,OAAO,IAAI;EAC5C;EACA,IAAI,OAAO,gBAAgB,KAAA,GAAW,GAAG,eAAe,CAAC,GAAG,OAAO,WAAW;EAC9E,OAAO;CACT;;;;;;CAOA,SAAS,WAAuE;EAC9E,MAAM,WAAW,KAAKN;EACtB,MAAM,eAAe;EACrB,MAAM,OAAO;EACb,OAAO,OAAO,KAAsB,YAAoD;GAEtF,MAAM,WAAW,IAAI,MAAM,IAAI,aAAa,WAAW,CAAC,CAAC;GAKzD,MAAM,SAAS,gBAAgB,aAAa,UAAU,WAHpD,YAAY,OAAO,aAAa,WAC3B,WACD,CAAC,CACwE,CAAC;GAChF,MAAM,IAAI,eAAe,OAAO,OAAO;GACvC,MAAM,eAAe,OAAO,gBAAgB;GAC5C,MAAM,yBAAyB,OAAO,0BAA0B;GAChE,MAAM,iBAAiB,sBAAsB,OAAO,cAAc;GAClE,MAAM,kBAAkB,uBAAuB,OAAO,iBAAiB,KAAA,GAAW,EAChF,gBAAgB,OAAO,wBACzB,CAAC;GAOD,MAAM,0CAA0B,IAAI,IAAsB;GAC1D,KAAK,MAAM,MAAM,IAAI,eAAe;IAClC,MAAM,OAAO,IAAI,MAAM,IAAI,GAAG,IAAI;IAClC,MAAM,OAAO,MAAM,EAAE,+BAA+B;KAClD,UAAU;KACV,SAAS,GAAG;KACN;KACN;KACA,wBAAwB,EAAE;KAC1B,sBAAsB,EAAE;KACxB,0BAA0B,EAAE;KAC5B,OAAO,MACL,QAAQ,IAAI,KAAK;MACf,MAAM;MACN,SAAS;KACX,CAAC;IACL,CAAC;IACD,wBAAwB,IAAI,IAAI,IAAI;GACtC;GAGA,IAAI,OAAO,iBAAiB,OAAO,kBAAkB,KAAA,GAAW;IAC9D,MAAM,MAAM,OAAO;IACnB,MAAM,SAAS,MACb,IAAI,YAAY,CAAC,EAAE,eAAe,GAAsB;IAC1D,IAAI,QAAQ,MAAM,IAAI,aAAa,SAAS,CAAC;IAC7C,KAAK,MAAM,MAAM,IAAI,sBAAsB,SAAS,MAAM,GAAG,SAAS,CAAC;IACvE,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,MAAM,EAAE,QAAQ,SAAS,CAAC;IACrE,KAAK,MAAM,KAAK,IAAI,kBAClB,SACE,CAAC,EAAE,UAAU,gBAAgB,kBAAkB,EAAE,OAAO,KAAK,EAAE,QAAQ,aAAa,IAChF,EAAE,QAAQ,qBACR,EAAE,IACF,KACA,EAAE,2BACJ,IACA,MAAO,MAAM,EAAE,gBAAgB,KAAM,EAAE;IAE/C,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,MAAM,EAAE,SAAS,SAAS,KAAK,EAAE;IAC5E,KAAK,MAAM,KAAK,IAAI,cAAc,SAAS,MAAM,EAAE,QAAQ,SAAS,CAAC;IACrE,KAAK,MAAM,QAAQ,wBAAwB,OAAO,GAAG,SAAS,MAAM,IAAI;IAMxE,MAAM,eAAe,IAAI,MAAM,QAAQ;IACvC,IAAI,aAAa,SAAS,GACxB,SAAS,MAAM,KAAK,UAAU,EAAE,2BAA2B,YAAY,CAAC,CAAC;IAE3E,IAAI,QAAQ,OAAO,eACjB,MAAM,IAAI,mCAAmC;KAC3C;KACA,OAAO;KACP,OAAO,GAAG;KACV,iCAAiC;IACnC,CAAC;GAEL;GAGA,MAAM,UAAU,KAAKQ,iBAAiB,MAAM;GAC5C,MAAM,EACJ,UAAU,cACV,OAAO,UACP,QAAQ,UACR,OAAO,YACL,MAAM,EAAE,4BAA4B;IACtC,cAAc,IAAI;IAClB,sBAAsB,IAAI;IAC1B,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,UAAU,IAAI;IACd,UAAU,IAAI;IACd,WAAW,IAAI;IACf,OAAO,IAAI;IACX;IACA,aAAa,OAAO,eAAe;KACjC;KACA;KACA;KACA;IACF;IACA;IACA,kBAAkB,OAAO,oBAAoB;IAC7C,qBAAqB,OAAO,uBAAuB,CAAC;IACpD,4BAA4B,EAAE;IAC9B,eAAe,EAAE;IACjB,gBAAgB,EAAE;IAClB,wBAAwB,EAAE;IAC1B,sBAAsB,EAAE;IACxB,mCAAmC,EAAE;IACrC,4BAA4B,EAAE;IAC9B,gBAAgB,EAAE;IAClB,oBAAoB,EAAE;IACtB,kCAAkC,EAAE;IACpC,8BAA8B,EAAE;IAChC,oCAAoC,EAAE;IACtC,qCAAqC,EAAE;IACvC,6BAA6B,EAAE;IAC/B,YAAY;IACZ,aAAa,WAAW,UAAU,gCAAgC,KAAK,IAAI,KAAA;IAC3E;IACA,OAAO,MACL,QAAQ,IAAI,KAAK;KACf,MAAM;KACN,SAAS;IACX,CAAC;GACL,CAAC;GAED,MAAM,aAAa,OAAO,cAAc,IAAI,mBAAmB;GAC/D,MAAM,SAAS,OAAO,UAAU;GAIhC,MAAM,mBAAmB,GAAO;GAMhC,IAAI,OAAO,mBACT,IAAI;IACF,OAAO,kBAAkB;KACvB,SAAS;KACT,MAAM;KACN,UAAU;KACV,OAAO;KACP,UAAU;KACV,UAAU;IACZ,CAAC;GACH,QAAQ,CAER;GAEF,MAAM,MAAM,KAAKF,KAAK,MAAM;GAC5B,MAAM,iBAAiB,KAAKG,gBAAgB,MAAM;GAClD,MAAM,YAAY,IAAI,MAAM,QAAQ,EAAE,KAAK,MAAM,EAAE,IAAI;GAGvD,MAAM,UACJ,OAAO,kBAAkB,KAAA,IACrB,kCAAkC,OAAO,cAAc,eAAe,IAAI,UAAU,4LACpF;GAGN,IAAI;GACJ,IAAI;GACJ,IAAI;IACF,IAAI,SAAS,WAAW,MAAM,KAAKF,yBAAyB,MAAM;SAC7D,OAAO,MAAM,KAAKL,iBAAiB,MAAM;GAChD,SAAS,KAAK;IAIZ,MAAM,UAAU,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;IACvD,IAAI,KACF,sBAAsB,OAAO,IACzB,kBAAkB,KAAK,OAAO,IAC9B,aAAa,KAAK,kCAAkC,8BAA8B,IAChF,MACA,IAAI,+BAA+B,CAAC,OAAO,CAAC,CACpD;IACA;GACF;GAEA,IAAI,IAAI,YAAY,SAAS;GAG7B,MAAM,4BAA4B,OAAO,SAA2C;IAClF,MAAM,OAAO,IAAI,MAAM,IAAI,KAAK,IAAI;IACpC,MAAM,cAAc,OAAO;IAC3B,IAAI,CAAC,KAAK,gBAAgB;KACxB,MAAM,WAAW,kBAAkB,KAAK,IAAI;KAK5C,MAAM,UAAU,IAAI,YAAY,IAJhB,yCAAyC,CACvD,yBACA,KAAK,UAAU,KAAK,IAAI,CAC1B,CACgC,EAAI,OAAO;KAC3C,QAAQ,eAAe,KAAK,IAAI;MAAE,MAAM;MAAU,MAAM,CAAC;KAAE,CAAC;KAC5D,QAAQ,eAAe,KAAK,IAAI;MAC9B;MACA,SAAS;MACT,YAAY;KACd,CAAC;KACD,MAAM,IAAI,cACR,IAAI,SAAS;MACX,IAAI,KAAK;MACT,MAAM;MACN,MAAM,CAAC;MACP,UAAU,gBAAgB,UAAU,CAAC,CAAC;MACtC,YAAY;MACZ,SAAS;MACT;MACA,WAAW;MACX,WAAW;MACX;KACF,CAAC,CACH;KACA;IACF;IACA,IAAI,CAAC,MAAM;KACT,MAAM,WAAW,kBAAkB,KAAK,IAAI;KAC5C,MAAM,YAAY,IAAI,MACnB,IAAI,EACJ,KAAK,MAAM,EAAE,IAAI,EACjB,KAAK;KAKR,MAAM,UAAU,IAAI,YAHlB,UAAU,SAAS,IACf,mBAAmB,SAAS,qBAAqB,UAAU,KAAK,IAAI,EAAE,KACtE,mBAAmB,SAAS,oCACK;KACvC,QAAQ,eAAe,KAAK,IAAI;MAAE,MAAM;MAAU,MAAM,KAAK;KAAK,CAAC;KACnE,QAAQ,eAAe,KAAK,IAAI;MAC9B;MACA,SAAS;MACT,YAAY;KACd,CAAC;KACD,MAAM,IAAI,cACR,IAAI,SAAS;MACX,IAAI,KAAK;MACT,MAAM;MACN,MAAM,KAAK;MACX,UAAU,gBAAgB,UAAU,KAAK,IAAI;MAC7C,YAAY;MACZ,SAAS;MACT;MACA,WAAW;MACX,WAAW;MACX;KACF,CAAC,CACH;KACA;IACF;IACA,QAAQ,eAAe,KAAK,IAAI;KAAE,MAAM,KAAK;KAAM,MAAM,KAAK;IAAK,CAAC;IACpE,MAAM,iBAAiB,aAAa,eAAe,IAAI;IACvD,IAAI,UACF,IAAI,YAAY,EAAE;IACpB,IAAI,eAAe;IACnB,IAAI;KACF,MAAM,MAAM,MAAM,KAAK,SAAS,GAAG,EAAE,KAAK,IAAI;KAC9C,IAAI,gBACF,UAAU,YAAY,cAAc,GAAG,IACnC,MACA,OAAO,QAAQ,WACb,IAAI,YAAY,GAAG,WACZ;MACL,MAAM,IAAI,MACR,iBAAiB,KAAK,KAAK,8CAC7B;KACF,GAAG;UACJ,IAAI,MAAM,QAAQ,GAAG,GAC1B,UAAU;UACL,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,OAAO,MAAM,MAAM,QAAQ,CAAC,CAAC,GAClF,UAAU;UACL,IAAI,yBAAyB,GAAG,GACrC,UAAU;UACL,IAAI,OAAO,QAAQ,YAAY,aAAa,KAAK,cAAc,UAAU,GAAG;MACjF,MAAM,SAAS,MAAM,WAAW,MAAM,KAAK,IAAI,GAA0B;MAEzE,UAAU,MADY,KAAc,sBAAsB,MAAK,iBACpC,MAAM;KACnC,OAAO;MACL,MAAM,SAAS,MAAM,WAAW,MAAM,KAAK,IAAI,OAAO,GAAG,CAAC;MAE1D,UAAU,MADY,KAAc,sBAAsB,MAAK,iBACpC,MAAM;KACnC;IACF,SAAS,KAAK;KACZ,eAAe;KACf,IAAI,YAAY,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;KACvD,IAAI,QAAQ,GAAG,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,YAAY,IAAI,SAClE,YAAY,GAAG,UAAU,GAAG,IAAI,MAAM;KAExC,UAAU,IAAI,YAAY,SAAS;IACrC;IACA,QAAQ,eAAe,KAAK,IAAI;KAC9B;KACA,SAAS;KACT,YAAY;IACd,CAAC;IACD,MAAM,eAAe,OAAO;IAC5B,MAAM,IAAI,cACR,IAAI,SAAS;KACX,IAAI,KAAK;KACT,MAAM,KAAK;KACX,MAAM,KAAK;KACX,UAAU,gBAAgB,KAAK,MAAM,KAAK,IAAI;KAC9C,YAAY;KACZ,SAAS;KACT;KACA,kBAAkB;KAIlB,QAAQ;KACR,WAAW;KACX,WAAW;KACX,aAAa;IACf,CAAC,CACH;GACF;GAEA,MAAM,iBAAiB,QACrB,IAAI,KAAK,OAAO;IACd,IAAI,GAAO;IACX,MAAM,EAAE;IACR,MAAM,SAAS,EAAE,SAAS,IAAK,EAAE,YAAwC,CAAC;IAC1E,gBAAgB,SAAS,EAAE,SAAS;GACtC,EAAE;GAGJ,MAAM,iBAAiB,OACrB,SACA,UACA,eACA,iBAA0B,CAAC,MACT;IAMlB,MAAM,WAAW,2BAA2B,OAAO;IACnD,MAAM,WAAW,gBAAgB,QAAQ;IACzC,MAAM,iBAAiB,SAAS;IAChC,MAAM,SAAS,eAAe,gBAAgB,EAAE,UAAU,CAAC;IAC3D,MAAM,YAAY,OAAO;IAKzB,IAAI,OAAO,iBACT,IAAI;KACF,OAAO,gBAAgB;MACrB,SAAS;MACT,aAAa;MACb,WAAW,SAAS;MACpB,WAAW,OAAO;MAClB,UAAU;MACV;KACF,CAAC;IACH,QAAQ,CAER;IAMF,KAAK,MAAM,SAAS,SAAS,WAAW;KACtC,IAAI,MAAM,KAAK,EAAE,WAAW,GAAG;KAC/B,MAAM,KAAK,GAAO;KAClB,QAAQ,cAAc,IAAI,OAAO,EAAE,YAAY,KAAK,CAAC;KACrD,MAAM,IAAI,aACR,IAAI,QAAQ;MACV;MACA,SAAS;MACT,UAAU;MACV,WAAW,OAAO;MAClB,WAAW,OAAO;KACpB,CAAC,CACH;IACF;IAKA,IAAI,UAAU,SAAS,KAAK,eAAe,SAAS,GAAG;KACrD,IAAI,eACF,QAAQ,cAAc,UAAU,IAAI,EAAE,YAAY,KAAK,CAAC;UACnD,IAAI,UAAU,SAAS,GAC5B,QAAQ,cAAc,UAAU,WAAW,EAAE,YAAY,KAAK,CAAC;KAEjE,MAAM,IAAI,aACR,IAAI,QAAQ;MACV,IAAI;MACJ,MAAM;MACN,GAAI,UAAU,SAAS,IAAI,EAAE,SAAS,UAAU,IAAI,CAAC;MACrD,GAAI,eAAe,SAAS,IAAI,EAAE,aAAa,eAAe,IAAI,CAAC;MACnE,UAAU;MACV,WAAW,OAAO;MAClB,WAAW,OAAO;KACpB,CAAC,CACH;IACF;IAGA,MAAM,QAAQ,cAAc,OAAO,KAAK;IACxC,IAAI,MAAM,WAAW,GAAG;KACtB,IAAI,OAAO,SAAS,IAAI,IAAI;KAC5B;IACF;IACA,KAAK,MAAM,QAAQ,OAAO;KACxB,IAAI,IAAI,YAAY,SAAS;KAC7B,MAAM,0BAA0B,IAAI;IACtC;GACF;GAOA,IAAI;GACJ,MAAM,cAAc,OAAO,aAAuC;IAChE,IAAI,UAAU;KACZ,MAAM,EAAE,OAAO,cAAc;KAC7B,MAAM,OAAO;KAIb,MAAM,WAAW;KAGjB,MAAM,SAAS,KAAK,oBAAoB,cAAc;MACpD,uBAAuB;MACvB,UAAU;MAEV,iBAAiB,IAAI;MAMrB,GAAI,SAAS,SAAS,IAAI,EAAE,OAAO,SAAS,IAAI,CAAC;KACnD,CAAC;KAMD,MAAM,WACJ,SAAS,WAAW,IAAI,OAAO,SAAS,WAAW,IAAI,SAAS,KAAK;KACvE,MAAM,WAAW,QAAQ,WAAW,IAAI,OAAO,QAAQ,WAAW,IAAI,QAAQ,KAAK;KAOnF,MAAM,SAAS,MAAM,SAAS,GAL5B,QAAQ,SAAS,IACb;MAAC;MAAQ;MAAU;KAAQ,IAC3B,SAAS,SAAS,IAChB,CAAC,QAAQ,QAAQ,IACjB,CAAC,MAAM,CAC0B;KAIzC,IAAI;MACF,MAAM,MAAM,MACV,MACA,SAAS;OACT,GAAG;OACH,GAAG;OACH,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;MACjC,CAAC;MACD,sBAAsB;MAEtB,IAAI;OACF,MAAM,WAAY,OAAO,WAA+C,OAAO,MAAM;OACrF,MAAM,MAAM;OACZ,MAAM,YACJ,OAAO,IAAI,UAAU,aAAa,IAAI,MAAM,MAAM,CAAC,UAAU,IAAI,CAAC,IAAI;OACxE,MAAM,UAAU,KAAK,aAAa,WAAW,EAC3C,qBAAqB,KACvB,CAAC;OAGD,IAAI,cAAc,KAAK,eAAe,SAAS;OAC/C,QAAQ,UAAU,MAAM,IAAI,SAAS;MACvC,QAAQ;OACN,OAAO;MACT;KACF,UAAU;MACR,eAAe,MAAM;KACvB;IACF;IAEA,MAAM,SAAS,MAAM,KAAE,cAAc;KACnC,GAAG;KAGH,iBAAiB,IAAI;KACrB,GAAI,SAAS,SAAS,IAAI,EAAE,OAAO,SAAS,IAAI,CAAC;KACjD,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;IACjC,CAAC;IACD,sBAAsB;IACtB,OAAO,qBAAqB,MAAM;GACpC;GAKA,MAAM,wBAAwB,YAA8B;IAC1D,IAAI,CAAC,OAAO,uBAAuB,wBAAwB,KAAA,GAAW,OAAO,CAAC;IAC9E,MAAM,UAAU,MAAM,OAAO,oBAAoB,mBAAmB;IACpE,MAAM,QAAiB,CAAC;IACxB,KAAK,MAAM,KAAK,SAAS;KACvB,MAAM,KAAK,GAAO;KAClB,MAAM,SAAS,MAAM,IAAI,gBAAgB,IAAI,EAAE,KAAK;KACpD,MAAM,KACJ,MAAM,cAAc;MAClB;MACA,MAAM,EAAE;MACR,UAAU,EAAE;MACZ,UAAU,EAAE,YAAY,GAAG,GAAG,GAAG,EAAE;MACnC;KACF,CAAC,CACH;IACF;IACA,OAAO;GACT;GAMA,MAAM,gCAAsC;IAC1C,IAAI,YAAY,wBAAwB,KAAA,GAAW,eAAe,mBAAmB;IACrF,sBAAsB,KAAA;GACxB;GAEA,IAAI,QAAQ;IACV,MAAM,cAAc,EAAE,sCAAsC;IAC5D,MAAM,WAAW;IACjB,IAAI,eAAe;IACnB,IAAI,gBAAgB;IAIpB,MAAM,UAAU,SAAuB;KACrC,YAAY,KAAK,IAAI;KACrB,IAAI,cAAc;KAClB,IAAI,oBAAoB,MAAM,MAAM,YAAY,QAAQ,EAAE,SAAS,CAAC,CAAC,GAAG;MACtE,eAAe;MACf;KACF;KACA,IAAI,KAAK,SAAS,GAAG;MACnB,gBAAgB;MAChB,QAAQ,cAAc,UAAU,IAAI;KACtC;IACF;IAKA,MAAM,gBAAiB,UAAU,aAAa;IAG9C,MAAM,iBACJ,OAAO,mBACN,OAAO,EAAE,QAAQ,SAAS;KACzB,MAAM,EAAE,iBAAiB,MAAM,OAAO;KACtC,OAAO,IAAI,aACT,cAAc,WACd;MACE,aAAa;MACb,qBAAqB;MACrB,mBAAmB;KACrB,CACF;IACF;IAEF,IAAI;IACJ,IAAI;KACF,WAAW,MAAM,eAAe;MAC9B,UAAU;MACV;KACF,CAAC;IACH,SAAS,KAAK;KACZ,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS,EAC9D,OAAO,IACT,CAAC;KACD,IAAI,KAAK,IAAI,+BAA+B,CAAC,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC;KACvF;IACF;IAEA,cAAc,QAAQ,mBAAmB,OAAO,OAAO,YAAY;IACnE,IAAI;KACF,MAAM,YAAY,QAAQ;IAC5B,SAAS,KAAK;KACZ,IAAI,IAAI,YAAY,SAAS;KAC7B,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS,EAC9D,OAAO,IACT,CAAC;KACD,IAAI,KAAK,kBAAkB,KAAK,OAAO,CAAC;KACxC;IACF;IACA,IAAI,IAAI,YAAY,SAAS;IAC7B,MAAM,cAAc,MAAM,sBAAsB;IAChD,wBAAwB;IACxB,MAAM,eAAe,YAAY,QAAQ,GAAG,UAAU,eAAe,WAAW;IAChF,cAAc,QAAQ,mBAAmB,OAAO,OAAO,UAAU;IACjE;GACF;GAGA,IAAI;GACJ,cAAc,QAAQ,mBAAmB,OAAO,OAAO,YAAY;GACnE,IAAI;IACF,YAAY,MAAM,YAAY,KAAA,CAAS;GACzC,SAAS,KAAK;IACZ,cAAc,QAAQ,mBAAmB,OAAO,OAAO,SAAS,EAC9D,OAAO,IACT,CAAC;IACD,IAAI,KAAK,kBAAkB,KAAK,OAAO,CAAC;IACxC;GACF;GACA,IAAI,IAAI,YAAY,SAAS;GAC7B,MAAM,iBAAiB,MAAM,sBAAsB;GACnD,wBAAwB;GACxB,MAAM,eAAe,WAAW,kBAAkB,OAAO,cAAc;GACvE,cAAc,QAAQ,mBAAmB,OAAO,OAAO,UAAU;EACnE;CACF;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,IAAM,kBAAkB,UAAyB;CAC/C,MAAM,cAAc,MAAqB;EACvC,MAAM,IAAI;EACV,IAAI,KAAK,OAAO,EAAE,YAAY,YAC5B,IAAI;GACF,EAAE,QAAQ;EACZ,QAAQ,CAER;CAEJ;CACA,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW;CAE3C,IAAI,OAAQ,MAAgC,YAAY,YAAY;EAClE,WAAW,KAAK;EAChB;CACF;CAEA,IAAI,OAAO,UAAU,UACnB,KAAK,MAAM,KAAK,OAAO,OAAO,KAAgC,GAAG,WAAW,CAAC;AAEjF;;;;;;;;;AAUA,IAAM,wBAAwB,WAA4B;CAExD,MAAM,OADQ,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK,SACe;CACjE,IAAI,OAAO,QAAQ,UAAU,OAAO;CACpC,IAAI,MAAM,QAAQ,GAAG,GAAG;EAEtB,MAAM,UADO,IAAI,IAAI,SAAS,IACR;EACtB,IAAI,OAAO,YAAY,UAAU,OAAO;EACxC,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAO,QACJ,QACE,MACC,SAAS,CAAC,KAAM,EAAyB,SAAS,MACtD,EACC,KAAK,MAAM,EAAE,IAAI,EACjB,KAAK,EAAE;CAEd;CACA,OAAO;AACT"}
|
|
@@ -1,12 +1,12 @@
|
|
|
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_spooled_artifact = require("../../../spooled_artifact-
|
|
5
|
-
const require_tool_call = require("../../../tool_call-
|
|
4
|
+
const require_spooled_artifact = require("../../../spooled_artifact-BpcesRBv.js");
|
|
5
|
+
const require_tool_call = require("../../../tool_call-Fs_Uh5wQ.js");
|
|
6
6
|
require("../../../guards.cjs");
|
|
7
7
|
require("../../../index.cjs");
|
|
8
8
|
const require_tool_parsers = require("../../../tool_parsers-csSBFWob.js");
|
|
9
|
-
const require_helpers = require("../../../helpers-
|
|
9
|
+
const require_helpers = require("../../../helpers-CEjjkXso.js");
|
|
10
10
|
const require_batteries_llm_openai_chat_completions_helpers = require("../openai_chat_completions/helpers.cjs");
|
|
11
11
|
const require_gpu_budget = require("../../../gpu_budget-BBIUyLoj.js");
|
|
12
12
|
const require_lifecycle = require("../../../lifecycle-vYQJ2rmf.js");
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as isError } from "../../../guards-BEpY7lBI.mjs";
|
|
2
|
-
import { t as SpooledArtifact } from "../../../spooled_artifact-
|
|
3
|
-
import { n as Media } from "../../../tool_call-
|
|
2
|
+
import { t as SpooledArtifact } from "../../../spooled_artifact-Bw_7swIp.mjs";
|
|
3
|
+
import { n as Media } from "../../../tool_call-Cfaj-6zK.mjs";
|
|
4
4
|
import "../../../guards.mjs";
|
|
5
5
|
import "../../../index.mjs";
|
|
6
6
|
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";
|
|
7
|
-
import { A as renderMemories, C as looksLikeSpooledArtifact, D as renderArtifactHandleBody, F as renderThirdPartyPrivateRetrievables, H as sanitizeFilenameForDescription, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, T as neutraliseDeveloperRulesTag, U as sanitizeMimeType, _ as defaultRenderUntrustedContent, a as defaultRenderArtifactHandleBody, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, j as renderRetrievableHandleBody, k as renderFirstPartyRetrievables, l as defaultRenderRetrievableHandleBody, 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-
|
|
7
|
+
import { A as renderMemories, C as looksLikeSpooledArtifact, D as renderArtifactHandleBody, F as renderThirdPartyPrivateRetrievables, H as sanitizeFilenameForDescription, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, T as neutraliseDeveloperRulesTag, U as sanitizeMimeType, _ as defaultRenderUntrustedContent, a as defaultRenderArtifactHandleBody, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, j as renderRetrievableHandleBody, k as renderFirstPartyRetrievables, l as defaultRenderRetrievableHandleBody, 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";
|
|
8
8
|
import { extractReasoningFields } from "../openai_chat_completions/helpers.mjs";
|
|
9
9
|
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";
|
|
10
10
|
import { n as emitLifecycle, t as defaultEmitLifecycle } from "../../../lifecycle-C4kwYJ-N.mjs";
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* The pipeline/streamer/message shapes are **local aliases** of `@huggingface/transformers` types
|
|
13
13
|
* (`export type X = Y`), never direct re-exports of the externalized peer (which breaks the bundler).
|
|
14
14
|
*/
|
|
15
|
-
import type {
|
|
15
|
+
import type { TokenEncodingId } from "../../../types";
|
|
16
16
|
import type { DispatchContext } from "../../../types";
|
|
17
17
|
import type { BatteryLifecycleHooks } from "../chat_common/index";
|
|
18
18
|
import type { SpoolStore, ToolRegistry } from "../../../common";
|
|
@@ -228,7 +228,7 @@ export interface TransformersJsAdapterOptions extends BatteryLifecycleHooks {
|
|
|
228
228
|
/** Which thoughts are surfaced into history. */
|
|
229
229
|
thoughtSurfacing?: 'all-self' | 'latest-self' | 'all';
|
|
230
230
|
/** Token encoding used for context-window accounting, or `null` to disable (default `null`). */
|
|
231
|
-
tokenEncoding?:
|
|
231
|
+
tokenEncoding?: TokenEncodingId | null;
|
|
232
232
|
/** Replay-compatibility tags whose opaque reasoning payloads may be replayed. */
|
|
233
233
|
replayCompatibility?: ReadonlyArray<string>;
|
|
234
234
|
/** Precedence order for reasoning/thought fields. */
|
|
@@ -1,8 +1,8 @@
|
|
|
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_common = require("../../../common-
|
|
4
|
+
const require_tokenizable = require("../../../tokenizable-BMZuGWRd.js");
|
|
5
|
+
const require_common = require("../../../common-H44Ik9ou.js");
|
|
6
6
|
require("../../../guards.cjs");
|
|
7
7
|
const require_batteries_llm_transformers_js_exceptions = require("./exceptions.cjs");
|
|
8
8
|
let _nhtio_validation = require("@nhtio/validation");
|
|
@@ -20,7 +20,7 @@ var bucketOrderSchema = _nhtio_validation.validator.array().items(bucketLabelSch
|
|
|
20
20
|
"timeline"
|
|
21
21
|
]);
|
|
22
22
|
var reasoningFieldPrecedenceSchema = _nhtio_validation.validator.array().items(_nhtio_validation.validator.string().valid("reasoning", "reasoning_content")).unique().min(1).default(["reasoning", "reasoning_content"]);
|
|
23
|
-
var tokenEncodingSchema = _nhtio_validation.validator.alternatives(_nhtio_validation.validator.string().
|
|
23
|
+
var tokenEncodingSchema = _nhtio_validation.validator.alternatives(_nhtio_validation.validator.string().min(1).description(`Known encodings: ${require_tokenizable.TokenEncoding.join(", ")}`), _nhtio_validation.validator.any().valid(null).optional()).default(null);
|
|
24
24
|
var helperSchema = _nhtio_validation.validator.function();
|
|
25
25
|
var helpersSchema = _nhtio_validation.validator.object({
|
|
26
26
|
descriptionToChatCompletionsJsonSchema: helperSchema.optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.cjs","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":";;;;;;;;;;;;;;AAYA,IAAM,oBAAoB,kBAAA,UACvB,OAAO,EACP,MAAM,wBAAwB,YAAY,gBAAgB,UAAU;AAEvE,IAAM,oBAAoB,kBAAA,UACvB,MAAM,EACN,MAAM,iBAAiB,EACvB,OAAO,EACP,QAAQ;CAAC;CAAwB;CAAY;CAAgB;AAAU,CAAC;AAE3E,IAAM,iCAAiC,kBAAA,UACpC,MAAM,EACN,MAAM,kBAAA,UAAU,OAAO,EAAE,MAAM,aAAa,mBAAmB,CAAC,EAChE,OAAO,EACP,IAAI,CAAC,EACL,QAAQ,CAAC,aAAa,mBAAmB,CAAC;AAE7C,IAAM,sBAAsB,kBAAA,UACzB,aAGC,kBAAA,UAAU,OAAO,EAAE,MAAM,GAAG,oBAAA,aAAa,GACzC,kBAAA,UAAU,IAAI,EAAE,MAAM,IAAI,EAAE,SAAS,CACvC,EACC,QAAQ,IAAI;AAEf,IAAM,eAAe,kBAAA,UAAU,SAAS;AAExC,IAAM,gBAAgB,kBAAA,UACnB,OAAO;CACN,wCAAwC,aAAa,SAAS;CAC9D,wBAAwB,aAAa,SAAS;CAC9C,sBAAsB,aAAa,SAAS;CAC5C,0BAA0B,aAAa,SAAS;CAChD,6BAA6B,aAAa,SAAS;CACnD,4BAA4B,aAAa,SAAS;CAClD,gBAAgB,aAAa,SAAS;CACtC,oBAAoB,aAAa,SAAS;CAC1C,kCAAkC,aAAa,SAAS;CACxD,8BAA8B,aAAa,SAAS;CACpD,oCAAoC,aAAa,SAAS;CAC1D,qCAAqC,aAAa,SAAS;CAC3D,uBAAuB,aAAa,SAAS;CAC7C,eAAe,aAAa,SAAS;CACrC,gBAAgB,aAAa,SAAS;CACtC,6BAA6B,aAAa,SAAS;CACnD,mCAAmC,aAAa,SAAS;CACzD,qCAAqC,aAAa,SAAS;CAC3D,6BAA6B,aAAa,SAAS;CACnD,+CAA+C,aAAa,SAAS;AACvE,CAAC,EACA,QAAQ,KAAK;AAEhB,IAAM,+BAA+B,kBAAA,UAClC,aACC,kBAAA,UAAU,OAAO,EAAE,MAAM,SAAS,kBAAkB,uBAAuB,GAC3E,kBAAA,UACG,OAAO;CACN,MAAM,kBAAA,UAAU,OAAO,EAAE,MAAM,gBAAgB,EAAE,SAAS;CAC1D,WAAW,kBAAA,UAAU,MAAM,EAAE,MAAM,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AACzE,CAAC,EACA,QAAQ,KAAK,CAClB,EACC,QAAQ,OAAO;AAElB,IAAM,uBAAuB,kBAAA,UAC1B,aACC,kBAAA,UACG,OAAO,EACP,MACC,QACA,UACA,SACA,WACA,YACA,eACA,WACA,eACA,OACA,MACF,GACF,kBAAA,UAAU,SAAS,CACrB,EACC,QAAQ,MAAM;AAEjB,IAAM,wBAAwB,kBAAA,UAC3B,aACC,kBAAA,UAAU,OAAO,EAAE,MAAM,QAAQ,aAAa,oBAAoB,iBAAiB,MAAM,GACzF,kBAAA,UAAU,SAAS,CACrB,EACC,QAAQ,MAAM;;;;;AAMjB,IAAa,8BAA8B,kBAAA,UACxC,OAAqC;CAEpC,OAAO,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;CAE1C,UAAU,kBAAA,UACP,aAAa,kBAAA,UAAU,SAAS,GAAG,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,CAAC,EACnE,SAAS;CACZ,gBAAgB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC9C,gBAAgB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAE9C,QAAQ,kBAAA,UAAU,aAAa,kBAAA,UAAU,OAAO,GAAG,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,CAAC,EAAE,SAAS;CAC9F,OAAO,kBAAA,UAAU,aAAa,kBAAA,UAAU,OAAO,GAAG,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,CAAC,EAAE,SAAS;CAG7F,gBAAgB,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS;CAG1D,iBAAiB,kBAAA,UAAU,QAAQ,EAAE,SAAS;CAC9C,gBAAgB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC9C,aAAa,kBAAA,UAAU,SAAS,EAAE,SAAS;CAE3C,YAAY,kBAAA,UACT,aACC,kBAAA,UAAU,QAAQ,GAClB,kBAAA,UAAU,OAAO;EAAE,OAAO,kBAAA,UAAU,QAAQ;EAAG,OAAO,kBAAA,UAAU,QAAQ;CAAE,CAAC,EAAE,QAAQ,KAAK,CAC5F,EACC,SAAS;CACZ,kBAAkB,kBAAA,UAAU,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS;CAC5D,kBAAkB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAChD,aAAa,kBAAA,UAAU,SAAS,EAAE,SAAS;CAE3C,aAAa,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC3C,WAAW,kBAAA,UAAU,SAAS,EAAE,SAAS;CACzC,aAAa,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC3C,SAAS,kBAAA,UAAU,SAAS,EAAE,SAAS;CACvC,cAAc,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC5C,YAAY,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC1C,SAAS,kBAAA,UAAU,SAAS,EAAE,SAAS;CAIvC,WAAW,kBAAA,UAAU,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,SAAS;CACxD,SAAS,kBAAA,UAAU,OAAO,EAAE,MAAM,UAAU,SAAS,OAAO,EAAE,SAAS;CACvE,MAAM,kBAAA,UAAU,OAAO,EAAE,QAAQ,EAAE,SAAS;CAG5C,cAAc,kBAAA,UAAU,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,SAAS;CAC3D,UAAU,kBAAA,UAAU,QAAQ,EAAE,SAAS;CACvC,aAAa,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAG;CAClD,MAAM,kBAAA,UAAU,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE;CACpD,MAAM,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAI;CACnD,mBAAmB,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;CACxD,aAAa,kBAAA,UAAU,MAAM,EAAE,MAAM,kBAAA,UAAU,OAAO,CAAC,EAAE,SAAS;CAClE,gBAAgB,kBAAA,UAAU,QAAQ,EAAE,QAAQ,KAAK;CAEjD,QAAQ,kBAAA,UAAU,QAAQ,EAAE,QAAQ,IAAI;CACxC,aAAa;CAGb,eAAe,kBAAA,UAAU,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;CAC/D,cAAc,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,WAAW;CAC3D,kBAAkB,kBAAA,UACf,OAAO,EACP,MAAM,YAAY,eAAe,KAAK,EACtC,QAAQ,UAAU;CACrB,eAAe;CACf,qBAAqB,kBAAA,UAAU,MAAM,EAAE,MAAM,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;CAClF,0BAA0B;CAC1B,SAAS,cAAc,SAAS;CAChC,YAAY,eAAA,gBAAgB,SAAS;CACrC,wBAAwB;CACxB,SAAS,kBAAA,UAAU,QAAQ,EAAE,QAAQ,KAAK;CAC1C,gBAAgB;CAChB,kBAAkB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAChD,iBAAiB;CACjB,yBAAyB,kBAAA,UAAU,QAAQ,EAAE,QAAQ,IAAI;CACzD,qBAAqB,kBAAA,UAAU,SAAS,EAAE,SAAS;CACnD,iBAAiB,kBAAA,UAAU,SAAS,EAAE,SAAS;CAC/C,mBAAmB,kBAAA,UAAU,SAAS,EAAE,SAAS;AACnD,CAAC,EACA,QAAQ,KAAK;AAEhB,IAAM,qBAAqB,UACzB,eAAA,QAAQ,KAAK,KAAK,MAAM,QAAS,MAA0B,OAAO;AAEpE,IAAM,2BAA2B,QAC/B,IAAI,QAAQ,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO;;;;;;;;AAShD,IAAa,mBAAmB,UAAiD;CAC/E,MAAM,EAAE,OAAO,UAAU,4BAA4B,SAAS,OAAO;EACnE,YAAY;EACZ,SAAS;CACX,CAAC;CACD,IAAI,SAAS,kBAAkB,KAAK,GAClC,MAAM,IAAI,iDAAA,kCAAkC,CAAC,wBAAwB,KAAK,CAAC,GAAG,EAAE,OAAO,MAAM,CAAC;CAEhG,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"validation.cjs","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,6 +1,6 @@
|
|
|
1
1
|
import { t as isError } from "../../../guards-BEpY7lBI.mjs";
|
|
2
|
-
import { n as TokenEncoding } from "../../../tokenizable-
|
|
3
|
-
import { o as byteStoreSchema } from "../../../common-
|
|
2
|
+
import { n as TokenEncoding } from "../../../tokenizable-VB4Av8GF.mjs";
|
|
3
|
+
import { o as byteStoreSchema } from "../../../common-BpdHIpQE.mjs";
|
|
4
4
|
import "../../../guards.mjs";
|
|
5
5
|
import { E_INVALID_TRANSFORMERS_JS_OPTIONS } from "./exceptions.mjs";
|
|
6
6
|
import { validator } from "@nhtio/validation";
|
|
@@ -18,7 +18,7 @@ var bucketOrderSchema = validator.array().items(bucketLabelSchema).unique().defa
|
|
|
18
18
|
"timeline"
|
|
19
19
|
]);
|
|
20
20
|
var reasoningFieldPrecedenceSchema = validator.array().items(validator.string().valid("reasoning", "reasoning_content")).unique().min(1).default(["reasoning", "reasoning_content"]);
|
|
21
|
-
var tokenEncodingSchema = validator.alternatives(validator.string().
|
|
21
|
+
var tokenEncodingSchema = validator.alternatives(validator.string().min(1).description(`Known encodings: ${TokenEncoding.join(", ")}`), validator.any().valid(null).optional()).default(null);
|
|
22
22
|
var helperSchema = validator.function();
|
|
23
23
|
var helpersSchema = validator.object({
|
|
24
24
|
descriptionToChatCompletionsJsonSchema: helperSchema.optional(),
|