@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
package/batteries/sandbox/js.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
3
|
const require_exceptions = require("../../exceptions-DrHnAGQz.js");
|
|
4
4
|
const require_guards = require("../../guards-05Uq3J4M.js");
|
|
5
|
-
const require_spooled_artifact = require("../../spooled_artifact-
|
|
5
|
+
const require_spooled_artifact = require("../../spooled_artifact-BpcesRBv.js");
|
|
6
6
|
require("../../forge.cjs");
|
|
7
7
|
require("../../guards.cjs");
|
|
8
8
|
const require_batteries_tools__shared = require("../tools/_shared.cjs");
|
|
@@ -12,6 +12,8 @@ let _nhtio_validation = require("@nhtio/validation");
|
|
|
12
12
|
//#region src/batteries/sandbox/js/exceptions.ts
|
|
13
13
|
/** SES lockdown was unavailable or did not harden the guest realm. */
|
|
14
14
|
var E_SES_LOCKDOWN_REQUIRED = require_exceptions.createException("E_SES_LOCKDOWN_REQUIRED", "%s", "E_SES_LOCKDOWN_REQUIRED", 500, false);
|
|
15
|
+
/** In-process SES evaluation requires hardening the complete host realm. */
|
|
16
|
+
var E_SES_HOST_LOCKDOWN_REQUIRED = require_exceptions.createException("E_SES_HOST_LOCKDOWN_REQUIRED", "%s", "E_SES_HOST_LOCKDOWN_REQUIRED", 500, false);
|
|
15
17
|
/** A guest evaluation exceeded its tool-selected deadline. */
|
|
16
18
|
var E_SES_EVALUATION_TIMEOUT = require_exceptions.createException("E_SES_EVALUATION_TIMEOUT", "%s", "E_SES_EVALUATION_TIMEOUT", 408, false);
|
|
17
19
|
//#endregion
|
|
@@ -64,11 +66,17 @@ var render = (value) => {
|
|
|
64
66
|
};
|
|
65
67
|
}
|
|
66
68
|
};
|
|
67
|
-
/**
|
|
68
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Construct a minimal SES-backed in-process guest.
|
|
71
|
+
*
|
|
72
|
+
* @remarks In Node, SES lockdown is process-global: this hardens the whole host realm, not
|
|
73
|
+
* only the guest. Guest-scoped isolation requires a worker or child runtime.
|
|
74
|
+
*/
|
|
75
|
+
var createCompartmentRuntime = async (globals, limits, modules = {}, hostLockdown = true) => {
|
|
69
76
|
await import("ses");
|
|
70
77
|
const realm = globalThis;
|
|
71
78
|
if (typeof realm.lockdown !== "function" || typeof realm.Compartment !== "function") throw new E_SES_LOCKDOWN_REQUIRED(["SES lockdown() and Compartment are required"]);
|
|
79
|
+
if (!hostLockdown) throw new E_SES_HOST_LOCKDOWN_REQUIRED(["In-process SES evaluation requires host-realm lockdown; supply a worker or child guest for guest-only isolation"]);
|
|
72
80
|
if (!realm.__adkSesLocked) {
|
|
73
81
|
try {
|
|
74
82
|
realm.lockdown();
|
|
@@ -134,17 +142,17 @@ var createCompartmentRuntime = async (globals, limits, modules = {}) => {
|
|
|
134
142
|
//#endregion
|
|
135
143
|
//#region src/batteries/sandbox/js/service.ts
|
|
136
144
|
/** In-process runtime factory for environments where SES is available. */
|
|
137
|
-
var createGuestRuntime = async (globals, limits, modules = {}) => ({ async spawn() {
|
|
138
|
-
return createCompartmentRuntime(globals, limits, modules);
|
|
145
|
+
var createGuestRuntime = async (globals, limits, modules = {}, hostLockdown = true) => ({ async spawn() {
|
|
146
|
+
return createCompartmentRuntime(globals, limits, modules, hostLockdown);
|
|
139
147
|
} });
|
|
140
148
|
//#endregion
|
|
141
149
|
//#region src/batteries/sandbox/js/runner.ts
|
|
142
150
|
/** Host runner that retains capability implementations and exposes only enumerated names. */
|
|
143
|
-
var createGuestRunner = async (globals, limits = resolveGuestLimits(), modules = {}) => {
|
|
151
|
+
var createGuestRunner = async (globals, limits = resolveGuestLimits(), modules = {}, hostLockdown = true) => {
|
|
144
152
|
return { async spawn(options) {
|
|
145
153
|
const implementations = {};
|
|
146
154
|
for (const [name, declaration] of Object.entries(globals)) implementations[name] = (...args) => declaration.fn(args, options.signal ?? new AbortController().signal);
|
|
147
|
-
return (await createGuestRuntime(implementations, limits, modules)).spawn(options);
|
|
155
|
+
return (await createGuestRuntime(implementations, limits, modules, hostLockdown)).spawn(options);
|
|
148
156
|
} };
|
|
149
157
|
};
|
|
150
158
|
/** Type-only terminal outcome helper. */
|
|
@@ -167,7 +175,7 @@ var createEvaluateJavascriptTool = (config) => {
|
|
|
167
175
|
handler: async (raw, ctx) => {
|
|
168
176
|
const args = raw;
|
|
169
177
|
await require_batteries_tools__shared.runToolGate(config.gate, ctx, "evaluate_javascript", args);
|
|
170
|
-
const guest = await (config.runtime ?? await createGuestRunner(config.globals ?? {}, limits, config.modules ?? {})).spawn({
|
|
178
|
+
const guest = await (config.runtime ?? await createGuestRunner(config.globals ?? {}, limits, config.modules ?? {}, config.hostLockdown ?? true)).spawn({
|
|
171
179
|
modules: Object.keys(config.modules ?? {}),
|
|
172
180
|
globals: Object.keys(config.globals ?? {}).map((name) => ({
|
|
173
181
|
name,
|
|
@@ -190,6 +198,7 @@ var createEvaluateJavascriptTool = (config) => {
|
|
|
190
198
|
};
|
|
191
199
|
//#endregion
|
|
192
200
|
exports.E_SES_EVALUATION_TIMEOUT = E_SES_EVALUATION_TIMEOUT;
|
|
201
|
+
exports.E_SES_HOST_LOCKDOWN_REQUIRED = E_SES_HOST_LOCKDOWN_REQUIRED;
|
|
193
202
|
exports.E_SES_LOCKDOWN_REQUIRED = E_SES_LOCKDOWN_REQUIRED;
|
|
194
203
|
exports.createCompartmentRuntime = createCompartmentRuntime;
|
|
195
204
|
exports.createEvaluateJavascriptTool = createEvaluateJavascriptTool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js.cjs","names":[],"sources":["../../../src/batteries/sandbox/js/exceptions.ts","../../../src/batteries/sandbox/js/validation.ts","../../../src/batteries/sandbox/js/compartment.ts","../../../src/batteries/sandbox/js/service.ts","../../../src/batteries/sandbox/js/runner.ts","../../../src/batteries/sandbox/js/tool.ts"],"sourcesContent":["import { createException } from '../../../lib/utils/exceptions'\n\n/** SES lockdown was unavailable or did not harden the guest realm. */\nexport const E_SES_LOCKDOWN_REQUIRED = createException<[string]>(\n 'E_SES_LOCKDOWN_REQUIRED',\n '%s',\n 'E_SES_LOCKDOWN_REQUIRED',\n 500,\n false\n)\n/** A guest evaluation exceeded its tool-selected deadline. */\nexport const E_SES_EVALUATION_TIMEOUT = createException<[string]>(\n 'E_SES_EVALUATION_TIMEOUT',\n '%s',\n 'E_SES_EVALUATION_TIMEOUT',\n 408,\n false\n)\n","import { E_INVALID_SANDBOX_CONFIG } from '../exceptions'\nimport { guestLimitFloors, guestLimitsDefaults, hostcallQuotasDefaults } from '../types'\nimport type { GuestLimits, HostcallQuotas } from '../types'\n\nconst resolve = <T extends object>(\n partial: Partial<T> | undefined,\n defaults: T,\n floors: T,\n label: string\n): T => {\n const out = { ...defaults, ...(partial ?? {}) } as T\n for (const key of Object.keys(defaults)) {\n const value = (out as Record<string, number>)[key]\n const floor = (floors as Record<string, number>)[key]\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < floor\n )\n throw new E_INVALID_SANDBOX_CONFIG([\n `${label}.${key}=${String(value)} must be a finite integer >= ${floor}`,\n ])\n }\n return out\n}\n/** Resolve and validate all seven guest limits exactly once. */\nexport const resolveGuestLimits = (value?: Partial<GuestLimits>): GuestLimits =>\n resolve(value, guestLimitsDefaults, guestLimitFloors, 'limits')\n/** Resolve and validate all three hostcall quotas exactly once. */\nexport const resolveHostcallQuotas = (value?: Partial<HostcallQuotas>): HostcallQuotas =>\n resolve(\n value,\n hostcallQuotasDefaults,\n { hostcallTimeoutMs: 1, maxHostcallsPerEvaluation: 1, maxConcurrentHostcalls: 1 },\n 'hostcallQuotas'\n )\n","import { isError, isInstanceOf } from '@nhtio/adk/guards'\nimport { E_SES_LOCKDOWN_REQUIRED, E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport type { GuestOutcome, GuestLimits } from '../types'\n\nconst cut = (text: string, bytes: number): { text: string; truncated: boolean } => {\n const suffix = '… [cut]'\n if (new TextEncoder().encode(text).byteLength <= bytes) return { text, truncated: false }\n let value = text\n while (new TextEncoder().encode(`${value}${suffix}`).byteLength > bytes)\n value = value.slice(0, -1)\n return { text: `${value}${suffix}`, truncated: true }\n}\nconst render = (value: unknown): { value: unknown; encoding: 'encoder' | 'partial' } => {\n try {\n return {\n value: JSON.parse(JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? `${v}n` : v))),\n encoding: 'encoder',\n }\n } catch {\n return { value: `[unrepresentable ${typeof value}]`, encoding: 'partial' }\n }\n}\n/** Construct a minimal SES-backed in-process guest. The runtime boundary is intentionally explicit. */\nexport const createCompartmentRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {}\n) => {\n await import('ses')\n const realm = globalThis as typeof globalThis & {\n lockdown?: () => void\n Compartment?: new (\n endowments?: Record<string, unknown>,\n modules?: unknown\n ) => {\n evaluate: (source: string) => unknown\n }\n }\n if (typeof realm.lockdown !== 'function' || typeof realm.Compartment !== 'function')\n throw new E_SES_LOCKDOWN_REQUIRED(['SES lockdown() and Compartment are required'])\n // SES is process-global in Node. The first guest bootstrap hardens this realm; subsequent\n // in-process evaluations must verify the already-hardened realm rather than invoking lockdown()\n // a second time (SES deliberately throws SES_ALREADY_LOCKED_DOWN).\n if (!(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked) {\n try {\n realm.lockdown()\n } catch (error) {\n if (\n !(\n isInstanceOf(error, 'TypeError', TypeError) &&\n String(error).includes('SES_ALREADY_LOCKED_DOWN')\n )\n )\n throw error\n }\n ;(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked = true\n }\n const C = realm.Compartment\n return {\n async evaluate(source: string, o: { timeoutMs: number }): Promise<GuestOutcome> {\n const started = performance.now()\n let seq = 0\n let capped = false\n const logs: { seq: number; text: string; truncated: boolean }[] = []\n const consoleLike = {\n log: (...a: unknown[]) => {\n if (logs.length >= limits.maxLogEvents) {\n capped = true\n return\n }\n const text = cut(a.map(String).join(' '), limits.maxLogEventBytes)\n logs.push({ seq: ++seq, ...text })\n },\n }\n const end = (): number => Math.max(0, performance.now() - started)\n const timer = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new E_SES_EVALUATION_TIMEOUT(['evaluation exceeded timeout'])),\n o.timeoutMs\n )\n )\n try {\n const compartment = new C({ console: consoleLike, ...globals }, modules)\n const result = await Promise.race([\n Promise.resolve(compartment.evaluate(`(async()=>(${source}))()`)),\n timer,\n ])\n const rendered = render(result)\n return {\n ok: true,\n result: rendered.value,\n encoding: rendered.encoding,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) throw error\n const thrown = isError(error)\n ? { kind: 'error' as const, message: error.message, stack: error.stack }\n : { kind: 'opaque' as const }\n return {\n ok: false,\n thrown,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n }\n },\n async kill(): Promise<void> {\n /* Compartment cannot be forcibly killed; production adapters must use a worker. */\n },\n }\n}\n","import { createCompartmentRuntime } from './compartment'\nimport type { GuestLimits } from '../types'\nimport type { GuestRuntimeLike } from './ses_contracts'\n\n/** In-process runtime factory for environments where SES is available. */\nexport const createGuestRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {}\n): Promise<GuestRuntimeLike> => ({\n async spawn() {\n return createCompartmentRuntime(globals, limits, modules)\n },\n})\n","import { createGuestRuntime } from './service'\nimport { resolveGuestLimits } from './validation'\nimport type { GuestOutcome } from '../types'\nimport type { GuestGlobal, GuestRuntimeLike } from './ses_contracts'\n\n/** Host runner that retains capability implementations and exposes only enumerated names. */\nexport const createGuestRunner = async (\n globals: Record<string, GuestGlobal>,\n limits = resolveGuestLimits(),\n modules: Record<string, unknown> = {}\n): Promise<GuestRuntimeLike> => {\n return {\n async spawn(options): Promise<Awaited<ReturnType<GuestRuntimeLike['spawn']>>> {\n const implementations: Record<string, (...args: unknown[]) => unknown> = {}\n for (const [name, declaration] of Object.entries(globals))\n implementations[name] = (...args: unknown[]) =>\n declaration.fn(args, options.signal ?? new AbortController().signal)\n const runtime = await createGuestRuntime(implementations, limits, modules)\n return runtime.spawn(options)\n },\n }\n}\n/** Type-only terminal outcome helper. */\nexport const isGuestOutcome = (value: unknown): value is GuestOutcome =>\n Boolean(value && typeof value === 'object' && 'durationMs' in value)\n","import { Tool } from '@nhtio/adk/forge'\nimport { createGuestRunner } from './runner'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { runToolGate } from '../../tools/_shared'\nimport { E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport { resolveGuestLimits, resolveHostcallQuotas } from './validation'\nimport { E_SANDBOX_FAILED, E_SANDBOX_GATE_REQUIRED } from '../exceptions'\nimport type { EvaluateJavascriptConfig } from './ses_contracts'\n\n/** Assemble the SES JavaScript evaluation tool. */\nexport const createEvaluateJavascriptTool = (config: EvaluateJavascriptConfig): Tool => {\n if (!config.gate) throw new E_SANDBOX_GATE_REQUIRED(['evaluate_javascript requires a gate'])\n const limits = resolveGuestLimits(config.limits)\n resolveHostcallQuotas(config.hostcallQuotas)\n const inputSchema = validator.object({\n source: validator.string().required(),\n timeout_seconds: validator.number().min(1).default(30),\n })\n return new Tool({\n name: 'evaluate_javascript',\n description:\n 'Evaluate JavaScript in a hardened SES guest. No ambient fetch, process, require, Date.now, or Math.random. Injected capabilities are asynchronous.',\n inputSchema,\n trusted: false,\n handler: async (raw, ctx) => {\n const args = raw as { source: string; timeout_seconds: number }\n await runToolGate(config.gate, ctx, 'evaluate_javascript', args)\n const runtime =\n config.runtime ??\n (await createGuestRunner(config.globals ?? {}, limits, config.modules ?? {}))\n const guest = await runtime.spawn({\n modules: Object.keys(config.modules ?? {}),\n globals: Object.keys(config.globals ?? {}).map((name) => ({\n name,\n kind: 'async-fn' as const,\n })),\n limits,\n signal: ctx.abortSignal,\n })\n try {\n return JSON.stringify(\n await guest.evaluate(args.source, { timeoutMs: args.timeout_seconds * 1000 })\n )\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) {\n await guest.kill()\n throw new E_SANDBOX_FAILED([\n `Evaluation timed out after ${args.timeout_seconds} seconds (kind: timed-out).`,\n ])\n }\n throw error\n }\n },\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"js.cjs","names":[],"sources":["../../../src/batteries/sandbox/js/exceptions.ts","../../../src/batteries/sandbox/js/validation.ts","../../../src/batteries/sandbox/js/compartment.ts","../../../src/batteries/sandbox/js/service.ts","../../../src/batteries/sandbox/js/runner.ts","../../../src/batteries/sandbox/js/tool.ts"],"sourcesContent":["import { createException } from '../../../lib/utils/exceptions'\n\n/** SES lockdown was unavailable or did not harden the guest realm. */\nexport const E_SES_LOCKDOWN_REQUIRED = createException<[string]>(\n 'E_SES_LOCKDOWN_REQUIRED',\n '%s',\n 'E_SES_LOCKDOWN_REQUIRED',\n 500,\n false\n)\n/** In-process SES evaluation requires hardening the complete host realm. */\nexport const E_SES_HOST_LOCKDOWN_REQUIRED = createException<[string]>(\n 'E_SES_HOST_LOCKDOWN_REQUIRED',\n '%s',\n 'E_SES_HOST_LOCKDOWN_REQUIRED',\n 500,\n false\n)\n/** A guest evaluation exceeded its tool-selected deadline. */\nexport const E_SES_EVALUATION_TIMEOUT = createException<[string]>(\n 'E_SES_EVALUATION_TIMEOUT',\n '%s',\n 'E_SES_EVALUATION_TIMEOUT',\n 408,\n false\n)\n","import { E_INVALID_SANDBOX_CONFIG } from '../exceptions'\nimport { guestLimitFloors, guestLimitsDefaults, hostcallQuotasDefaults } from '../types'\nimport type { GuestLimits, HostcallQuotas } from '../types'\n\nconst resolve = <T extends object>(\n partial: Partial<T> | undefined,\n defaults: T,\n floors: T,\n label: string\n): T => {\n const out = { ...defaults, ...(partial ?? {}) } as T\n for (const key of Object.keys(defaults)) {\n const value = (out as Record<string, number>)[key]\n const floor = (floors as Record<string, number>)[key]\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < floor\n )\n throw new E_INVALID_SANDBOX_CONFIG([\n `${label}.${key}=${String(value)} must be a finite integer >= ${floor}`,\n ])\n }\n return out\n}\n/** Resolve and validate all seven guest limits exactly once. */\nexport const resolveGuestLimits = (value?: Partial<GuestLimits>): GuestLimits =>\n resolve(value, guestLimitsDefaults, guestLimitFloors, 'limits')\n/** Resolve and validate all three hostcall quotas exactly once. */\nexport const resolveHostcallQuotas = (value?: Partial<HostcallQuotas>): HostcallQuotas =>\n resolve(\n value,\n hostcallQuotasDefaults,\n { hostcallTimeoutMs: 1, maxHostcallsPerEvaluation: 1, maxConcurrentHostcalls: 1 },\n 'hostcallQuotas'\n )\n","import { isError, isInstanceOf } from '@nhtio/adk/guards'\nimport {\n E_SES_HOST_LOCKDOWN_REQUIRED,\n E_SES_LOCKDOWN_REQUIRED,\n E_SES_EVALUATION_TIMEOUT,\n} from './exceptions'\nimport type { GuestOutcome, GuestLimits } from '../types'\n\nconst cut = (text: string, bytes: number): { text: string; truncated: boolean } => {\n const suffix = '… [cut]'\n if (new TextEncoder().encode(text).byteLength <= bytes) return { text, truncated: false }\n let value = text\n while (new TextEncoder().encode(`${value}${suffix}`).byteLength > bytes)\n value = value.slice(0, -1)\n return { text: `${value}${suffix}`, truncated: true }\n}\nconst render = (value: unknown): { value: unknown; encoding: 'encoder' | 'partial' } => {\n try {\n return {\n value: JSON.parse(JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? `${v}n` : v))),\n encoding: 'encoder',\n }\n } catch {\n return { value: `[unrepresentable ${typeof value}]`, encoding: 'partial' }\n }\n}\n/**\n * Construct a minimal SES-backed in-process guest.\n *\n * @remarks In Node, SES lockdown is process-global: this hardens the whole host realm, not\n * only the guest. Guest-scoped isolation requires a worker or child runtime.\n */\nexport const createCompartmentRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {},\n hostLockdown = true\n) => {\n await import('ses')\n const realm = globalThis as typeof globalThis & {\n lockdown?: () => void\n Compartment?: new (\n endowments?: Record<string, unknown>,\n modules?: unknown\n ) => {\n evaluate: (source: string) => unknown\n }\n }\n if (typeof realm.lockdown !== 'function' || typeof realm.Compartment !== 'function')\n throw new E_SES_LOCKDOWN_REQUIRED(['SES lockdown() and Compartment are required'])\n if (!hostLockdown)\n throw new E_SES_HOST_LOCKDOWN_REQUIRED([\n 'In-process SES evaluation requires host-realm lockdown; supply a worker or child guest for guest-only isolation',\n ])\n // SES is process-global in Node. The first guest bootstrap hardens this realm; subsequent\n // in-process evaluations must verify the already-hardened realm rather than invoking lockdown()\n // a second time (SES deliberately throws SES_ALREADY_LOCKED_DOWN).\n if (!(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked) {\n try {\n realm.lockdown()\n } catch (error) {\n if (\n !(\n isInstanceOf(error, 'TypeError', TypeError) &&\n String(error).includes('SES_ALREADY_LOCKED_DOWN')\n )\n )\n throw error\n }\n ;(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked = true\n }\n const C = realm.Compartment\n return {\n async evaluate(source: string, o: { timeoutMs: number }): Promise<GuestOutcome> {\n const started = performance.now()\n let seq = 0\n let capped = false\n const logs: { seq: number; text: string; truncated: boolean }[] = []\n const consoleLike = {\n log: (...a: unknown[]) => {\n if (logs.length >= limits.maxLogEvents) {\n capped = true\n return\n }\n const text = cut(a.map(String).join(' '), limits.maxLogEventBytes)\n logs.push({ seq: ++seq, ...text })\n },\n }\n const end = (): number => Math.max(0, performance.now() - started)\n const timer = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new E_SES_EVALUATION_TIMEOUT(['evaluation exceeded timeout'])),\n o.timeoutMs\n )\n )\n try {\n const compartment = new C({ console: consoleLike, ...globals }, modules)\n const result = await Promise.race([\n Promise.resolve(compartment.evaluate(`(async()=>(${source}))()`)),\n timer,\n ])\n const rendered = render(result)\n return {\n ok: true,\n result: rendered.value,\n encoding: rendered.encoding,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) throw error\n const thrown = isError(error)\n ? { kind: 'error' as const, message: error.message, stack: error.stack }\n : { kind: 'opaque' as const }\n return {\n ok: false,\n thrown,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n }\n },\n async kill(): Promise<void> {\n /* Compartment cannot be forcibly killed; production adapters must use a worker. */\n },\n }\n}\n","import { createCompartmentRuntime } from './compartment'\nimport type { GuestLimits } from '../types'\nimport type { GuestRuntimeLike } from './ses_contracts'\n\n/** In-process runtime factory for environments where SES is available. */\nexport const createGuestRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {},\n hostLockdown = true\n): Promise<GuestRuntimeLike> => ({\n async spawn() {\n return createCompartmentRuntime(globals, limits, modules, hostLockdown)\n },\n})\n","import { createGuestRuntime } from './service'\nimport { resolveGuestLimits } from './validation'\nimport type { GuestOutcome } from '../types'\nimport type { GuestGlobal, GuestRuntimeLike } from './ses_contracts'\n\n/** Host runner that retains capability implementations and exposes only enumerated names. */\nexport const createGuestRunner = async (\n globals: Record<string, GuestGlobal>,\n limits = resolveGuestLimits(),\n modules: Record<string, unknown> = {},\n hostLockdown = true\n): Promise<GuestRuntimeLike> => {\n return {\n async spawn(options): Promise<Awaited<ReturnType<GuestRuntimeLike['spawn']>>> {\n const implementations: Record<string, (...args: unknown[]) => unknown> = {}\n for (const [name, declaration] of Object.entries(globals))\n implementations[name] = (...args: unknown[]) =>\n declaration.fn(args, options.signal ?? new AbortController().signal)\n const runtime = await createGuestRuntime(implementations, limits, modules, hostLockdown)\n return runtime.spawn(options)\n },\n }\n}\n/** Type-only terminal outcome helper. */\nexport const isGuestOutcome = (value: unknown): value is GuestOutcome =>\n Boolean(value && typeof value === 'object' && 'durationMs' in value)\n","import { Tool } from '@nhtio/adk/forge'\nimport { createGuestRunner } from './runner'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { runToolGate } from '../../tools/_shared'\nimport { E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport { resolveGuestLimits, resolveHostcallQuotas } from './validation'\nimport { E_SANDBOX_FAILED, E_SANDBOX_GATE_REQUIRED } from '../exceptions'\nimport type { EvaluateJavascriptConfig } from './ses_contracts'\n\n/** Assemble the SES JavaScript evaluation tool. */\nexport const createEvaluateJavascriptTool = (config: EvaluateJavascriptConfig): Tool => {\n if (!config.gate) throw new E_SANDBOX_GATE_REQUIRED(['evaluate_javascript requires a gate'])\n const limits = resolveGuestLimits(config.limits)\n resolveHostcallQuotas(config.hostcallQuotas)\n const inputSchema = validator.object({\n source: validator.string().required(),\n timeout_seconds: validator.number().min(1).default(30),\n })\n return new Tool({\n name: 'evaluate_javascript',\n description:\n 'Evaluate JavaScript in a hardened SES guest. No ambient fetch, process, require, Date.now, or Math.random. Injected capabilities are asynchronous.',\n inputSchema,\n trusted: false,\n handler: async (raw, ctx) => {\n const args = raw as { source: string; timeout_seconds: number }\n await runToolGate(config.gate, ctx, 'evaluate_javascript', args)\n const runtime =\n config.runtime ??\n (await createGuestRunner(\n config.globals ?? {},\n limits,\n config.modules ?? {},\n config.hostLockdown ?? true\n ))\n const guest = await runtime.spawn({\n modules: Object.keys(config.modules ?? {}),\n globals: Object.keys(config.globals ?? {}).map((name) => ({\n name,\n kind: 'async-fn' as const,\n })),\n limits,\n signal: ctx.abortSignal,\n })\n try {\n return JSON.stringify(\n await guest.evaluate(args.source, { timeoutMs: args.timeout_seconds * 1000 })\n )\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) {\n await guest.kill()\n throw new E_SANDBOX_FAILED([\n `Evaluation timed out after ${args.timeout_seconds} seconds (kind: timed-out).`,\n ])\n }\n throw error\n }\n },\n })\n}\n"],"mappings":"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"}
|
package/batteries/sandbox/js.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as createException } from "../../exceptions-DRYLe-J4.mjs";
|
|
2
2
|
import { n as isInstanceOf, t as isError } from "../../guards-BEpY7lBI.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { p as Tool } from "../../spooled_artifact-Bw_7swIp.mjs";
|
|
4
4
|
import "../../forge.mjs";
|
|
5
5
|
import "../../guards.mjs";
|
|
6
6
|
import { runToolGate } from "../tools/_shared.mjs";
|
|
@@ -10,6 +10,8 @@ import { validator } from "@nhtio/validation";
|
|
|
10
10
|
//#region src/batteries/sandbox/js/exceptions.ts
|
|
11
11
|
/** SES lockdown was unavailable or did not harden the guest realm. */
|
|
12
12
|
var E_SES_LOCKDOWN_REQUIRED = createException("E_SES_LOCKDOWN_REQUIRED", "%s", "E_SES_LOCKDOWN_REQUIRED", 500, false);
|
|
13
|
+
/** In-process SES evaluation requires hardening the complete host realm. */
|
|
14
|
+
var E_SES_HOST_LOCKDOWN_REQUIRED = createException("E_SES_HOST_LOCKDOWN_REQUIRED", "%s", "E_SES_HOST_LOCKDOWN_REQUIRED", 500, false);
|
|
13
15
|
/** A guest evaluation exceeded its tool-selected deadline. */
|
|
14
16
|
var E_SES_EVALUATION_TIMEOUT = createException("E_SES_EVALUATION_TIMEOUT", "%s", "E_SES_EVALUATION_TIMEOUT", 408, false);
|
|
15
17
|
//#endregion
|
|
@@ -62,11 +64,17 @@ var render = (value) => {
|
|
|
62
64
|
};
|
|
63
65
|
}
|
|
64
66
|
};
|
|
65
|
-
/**
|
|
66
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Construct a minimal SES-backed in-process guest.
|
|
69
|
+
*
|
|
70
|
+
* @remarks In Node, SES lockdown is process-global: this hardens the whole host realm, not
|
|
71
|
+
* only the guest. Guest-scoped isolation requires a worker or child runtime.
|
|
72
|
+
*/
|
|
73
|
+
var createCompartmentRuntime = async (globals, limits, modules = {}, hostLockdown = true) => {
|
|
67
74
|
await import("ses");
|
|
68
75
|
const realm = globalThis;
|
|
69
76
|
if (typeof realm.lockdown !== "function" || typeof realm.Compartment !== "function") throw new E_SES_LOCKDOWN_REQUIRED(["SES lockdown() and Compartment are required"]);
|
|
77
|
+
if (!hostLockdown) throw new E_SES_HOST_LOCKDOWN_REQUIRED(["In-process SES evaluation requires host-realm lockdown; supply a worker or child guest for guest-only isolation"]);
|
|
70
78
|
if (!realm.__adkSesLocked) {
|
|
71
79
|
try {
|
|
72
80
|
realm.lockdown();
|
|
@@ -132,17 +140,17 @@ var createCompartmentRuntime = async (globals, limits, modules = {}) => {
|
|
|
132
140
|
//#endregion
|
|
133
141
|
//#region src/batteries/sandbox/js/service.ts
|
|
134
142
|
/** In-process runtime factory for environments where SES is available. */
|
|
135
|
-
var createGuestRuntime = async (globals, limits, modules = {}) => ({ async spawn() {
|
|
136
|
-
return createCompartmentRuntime(globals, limits, modules);
|
|
143
|
+
var createGuestRuntime = async (globals, limits, modules = {}, hostLockdown = true) => ({ async spawn() {
|
|
144
|
+
return createCompartmentRuntime(globals, limits, modules, hostLockdown);
|
|
137
145
|
} });
|
|
138
146
|
//#endregion
|
|
139
147
|
//#region src/batteries/sandbox/js/runner.ts
|
|
140
148
|
/** Host runner that retains capability implementations and exposes only enumerated names. */
|
|
141
|
-
var createGuestRunner = async (globals, limits = resolveGuestLimits(), modules = {}) => {
|
|
149
|
+
var createGuestRunner = async (globals, limits = resolveGuestLimits(), modules = {}, hostLockdown = true) => {
|
|
142
150
|
return { async spawn(options) {
|
|
143
151
|
const implementations = {};
|
|
144
152
|
for (const [name, declaration] of Object.entries(globals)) implementations[name] = (...args) => declaration.fn(args, options.signal ?? new AbortController().signal);
|
|
145
|
-
return (await createGuestRuntime(implementations, limits, modules)).spawn(options);
|
|
153
|
+
return (await createGuestRuntime(implementations, limits, modules, hostLockdown)).spawn(options);
|
|
146
154
|
} };
|
|
147
155
|
};
|
|
148
156
|
/** Type-only terminal outcome helper. */
|
|
@@ -165,7 +173,7 @@ var createEvaluateJavascriptTool = (config) => {
|
|
|
165
173
|
handler: async (raw, ctx) => {
|
|
166
174
|
const args = raw;
|
|
167
175
|
await runToolGate(config.gate, ctx, "evaluate_javascript", args);
|
|
168
|
-
const guest = await (config.runtime ?? await createGuestRunner(config.globals ?? {}, limits, config.modules ?? {})).spawn({
|
|
176
|
+
const guest = await (config.runtime ?? await createGuestRunner(config.globals ?? {}, limits, config.modules ?? {}, config.hostLockdown ?? true)).spawn({
|
|
169
177
|
modules: Object.keys(config.modules ?? {}),
|
|
170
178
|
globals: Object.keys(config.globals ?? {}).map((name) => ({
|
|
171
179
|
name,
|
|
@@ -187,6 +195,6 @@ var createEvaluateJavascriptTool = (config) => {
|
|
|
187
195
|
});
|
|
188
196
|
};
|
|
189
197
|
//#endregion
|
|
190
|
-
export { E_SES_EVALUATION_TIMEOUT, E_SES_LOCKDOWN_REQUIRED, createCompartmentRuntime, createEvaluateJavascriptTool, createGuestRunner, createGuestRuntime, isGuestOutcome, resolveGuestLimits, resolveHostcallQuotas };
|
|
198
|
+
export { E_SES_EVALUATION_TIMEOUT, E_SES_HOST_LOCKDOWN_REQUIRED, E_SES_LOCKDOWN_REQUIRED, createCompartmentRuntime, createEvaluateJavascriptTool, createGuestRunner, createGuestRuntime, isGuestOutcome, resolveGuestLimits, resolveHostcallQuotas };
|
|
191
199
|
|
|
192
200
|
//# sourceMappingURL=js.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js.mjs","names":[],"sources":["../../../src/batteries/sandbox/js/exceptions.ts","../../../src/batteries/sandbox/js/validation.ts","../../../src/batteries/sandbox/js/compartment.ts","../../../src/batteries/sandbox/js/service.ts","../../../src/batteries/sandbox/js/runner.ts","../../../src/batteries/sandbox/js/tool.ts"],"sourcesContent":["import { createException } from '../../../lib/utils/exceptions'\n\n/** SES lockdown was unavailable or did not harden the guest realm. */\nexport const E_SES_LOCKDOWN_REQUIRED = createException<[string]>(\n 'E_SES_LOCKDOWN_REQUIRED',\n '%s',\n 'E_SES_LOCKDOWN_REQUIRED',\n 500,\n false\n)\n/** A guest evaluation exceeded its tool-selected deadline. */\nexport const E_SES_EVALUATION_TIMEOUT = createException<[string]>(\n 'E_SES_EVALUATION_TIMEOUT',\n '%s',\n 'E_SES_EVALUATION_TIMEOUT',\n 408,\n false\n)\n","import { E_INVALID_SANDBOX_CONFIG } from '../exceptions'\nimport { guestLimitFloors, guestLimitsDefaults, hostcallQuotasDefaults } from '../types'\nimport type { GuestLimits, HostcallQuotas } from '../types'\n\nconst resolve = <T extends object>(\n partial: Partial<T> | undefined,\n defaults: T,\n floors: T,\n label: string\n): T => {\n const out = { ...defaults, ...(partial ?? {}) } as T\n for (const key of Object.keys(defaults)) {\n const value = (out as Record<string, number>)[key]\n const floor = (floors as Record<string, number>)[key]\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < floor\n )\n throw new E_INVALID_SANDBOX_CONFIG([\n `${label}.${key}=${String(value)} must be a finite integer >= ${floor}`,\n ])\n }\n return out\n}\n/** Resolve and validate all seven guest limits exactly once. */\nexport const resolveGuestLimits = (value?: Partial<GuestLimits>): GuestLimits =>\n resolve(value, guestLimitsDefaults, guestLimitFloors, 'limits')\n/** Resolve and validate all three hostcall quotas exactly once. */\nexport const resolveHostcallQuotas = (value?: Partial<HostcallQuotas>): HostcallQuotas =>\n resolve(\n value,\n hostcallQuotasDefaults,\n { hostcallTimeoutMs: 1, maxHostcallsPerEvaluation: 1, maxConcurrentHostcalls: 1 },\n 'hostcallQuotas'\n )\n","import { isError, isInstanceOf } from '@nhtio/adk/guards'\nimport { E_SES_LOCKDOWN_REQUIRED, E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport type { GuestOutcome, GuestLimits } from '../types'\n\nconst cut = (text: string, bytes: number): { text: string; truncated: boolean } => {\n const suffix = '… [cut]'\n if (new TextEncoder().encode(text).byteLength <= bytes) return { text, truncated: false }\n let value = text\n while (new TextEncoder().encode(`${value}${suffix}`).byteLength > bytes)\n value = value.slice(0, -1)\n return { text: `${value}${suffix}`, truncated: true }\n}\nconst render = (value: unknown): { value: unknown; encoding: 'encoder' | 'partial' } => {\n try {\n return {\n value: JSON.parse(JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? `${v}n` : v))),\n encoding: 'encoder',\n }\n } catch {\n return { value: `[unrepresentable ${typeof value}]`, encoding: 'partial' }\n }\n}\n/** Construct a minimal SES-backed in-process guest. The runtime boundary is intentionally explicit. */\nexport const createCompartmentRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {}\n) => {\n await import('ses')\n const realm = globalThis as typeof globalThis & {\n lockdown?: () => void\n Compartment?: new (\n endowments?: Record<string, unknown>,\n modules?: unknown\n ) => {\n evaluate: (source: string) => unknown\n }\n }\n if (typeof realm.lockdown !== 'function' || typeof realm.Compartment !== 'function')\n throw new E_SES_LOCKDOWN_REQUIRED(['SES lockdown() and Compartment are required'])\n // SES is process-global in Node. The first guest bootstrap hardens this realm; subsequent\n // in-process evaluations must verify the already-hardened realm rather than invoking lockdown()\n // a second time (SES deliberately throws SES_ALREADY_LOCKED_DOWN).\n if (!(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked) {\n try {\n realm.lockdown()\n } catch (error) {\n if (\n !(\n isInstanceOf(error, 'TypeError', TypeError) &&\n String(error).includes('SES_ALREADY_LOCKED_DOWN')\n )\n )\n throw error\n }\n ;(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked = true\n }\n const C = realm.Compartment\n return {\n async evaluate(source: string, o: { timeoutMs: number }): Promise<GuestOutcome> {\n const started = performance.now()\n let seq = 0\n let capped = false\n const logs: { seq: number; text: string; truncated: boolean }[] = []\n const consoleLike = {\n log: (...a: unknown[]) => {\n if (logs.length >= limits.maxLogEvents) {\n capped = true\n return\n }\n const text = cut(a.map(String).join(' '), limits.maxLogEventBytes)\n logs.push({ seq: ++seq, ...text })\n },\n }\n const end = (): number => Math.max(0, performance.now() - started)\n const timer = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new E_SES_EVALUATION_TIMEOUT(['evaluation exceeded timeout'])),\n o.timeoutMs\n )\n )\n try {\n const compartment = new C({ console: consoleLike, ...globals }, modules)\n const result = await Promise.race([\n Promise.resolve(compartment.evaluate(`(async()=>(${source}))()`)),\n timer,\n ])\n const rendered = render(result)\n return {\n ok: true,\n result: rendered.value,\n encoding: rendered.encoding,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) throw error\n const thrown = isError(error)\n ? { kind: 'error' as const, message: error.message, stack: error.stack }\n : { kind: 'opaque' as const }\n return {\n ok: false,\n thrown,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n }\n },\n async kill(): Promise<void> {\n /* Compartment cannot be forcibly killed; production adapters must use a worker. */\n },\n }\n}\n","import { createCompartmentRuntime } from './compartment'\nimport type { GuestLimits } from '../types'\nimport type { GuestRuntimeLike } from './ses_contracts'\n\n/** In-process runtime factory for environments where SES is available. */\nexport const createGuestRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {}\n): Promise<GuestRuntimeLike> => ({\n async spawn() {\n return createCompartmentRuntime(globals, limits, modules)\n },\n})\n","import { createGuestRuntime } from './service'\nimport { resolveGuestLimits } from './validation'\nimport type { GuestOutcome } from '../types'\nimport type { GuestGlobal, GuestRuntimeLike } from './ses_contracts'\n\n/** Host runner that retains capability implementations and exposes only enumerated names. */\nexport const createGuestRunner = async (\n globals: Record<string, GuestGlobal>,\n limits = resolveGuestLimits(),\n modules: Record<string, unknown> = {}\n): Promise<GuestRuntimeLike> => {\n return {\n async spawn(options): Promise<Awaited<ReturnType<GuestRuntimeLike['spawn']>>> {\n const implementations: Record<string, (...args: unknown[]) => unknown> = {}\n for (const [name, declaration] of Object.entries(globals))\n implementations[name] = (...args: unknown[]) =>\n declaration.fn(args, options.signal ?? new AbortController().signal)\n const runtime = await createGuestRuntime(implementations, limits, modules)\n return runtime.spawn(options)\n },\n }\n}\n/** Type-only terminal outcome helper. */\nexport const isGuestOutcome = (value: unknown): value is GuestOutcome =>\n Boolean(value && typeof value === 'object' && 'durationMs' in value)\n","import { Tool } from '@nhtio/adk/forge'\nimport { createGuestRunner } from './runner'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { runToolGate } from '../../tools/_shared'\nimport { E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport { resolveGuestLimits, resolveHostcallQuotas } from './validation'\nimport { E_SANDBOX_FAILED, E_SANDBOX_GATE_REQUIRED } from '../exceptions'\nimport type { EvaluateJavascriptConfig } from './ses_contracts'\n\n/** Assemble the SES JavaScript evaluation tool. */\nexport const createEvaluateJavascriptTool = (config: EvaluateJavascriptConfig): Tool => {\n if (!config.gate) throw new E_SANDBOX_GATE_REQUIRED(['evaluate_javascript requires a gate'])\n const limits = resolveGuestLimits(config.limits)\n resolveHostcallQuotas(config.hostcallQuotas)\n const inputSchema = validator.object({\n source: validator.string().required(),\n timeout_seconds: validator.number().min(1).default(30),\n })\n return new Tool({\n name: 'evaluate_javascript',\n description:\n 'Evaluate JavaScript in a hardened SES guest. No ambient fetch, process, require, Date.now, or Math.random. Injected capabilities are asynchronous.',\n inputSchema,\n trusted: false,\n handler: async (raw, ctx) => {\n const args = raw as { source: string; timeout_seconds: number }\n await runToolGate(config.gate, ctx, 'evaluate_javascript', args)\n const runtime =\n config.runtime ??\n (await createGuestRunner(config.globals ?? {}, limits, config.modules ?? {}))\n const guest = await runtime.spawn({\n modules: Object.keys(config.modules ?? {}),\n globals: Object.keys(config.globals ?? {}).map((name) => ({\n name,\n kind: 'async-fn' as const,\n })),\n limits,\n signal: ctx.abortSignal,\n })\n try {\n return JSON.stringify(\n await guest.evaluate(args.source, { timeoutMs: args.timeout_seconds * 1000 })\n )\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) {\n await guest.kill()\n throw new E_SANDBOX_FAILED([\n `Evaluation timed out after ${args.timeout_seconds} seconds (kind: timed-out).`,\n ])\n }\n throw error\n }\n },\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"js.mjs","names":[],"sources":["../../../src/batteries/sandbox/js/exceptions.ts","../../../src/batteries/sandbox/js/validation.ts","../../../src/batteries/sandbox/js/compartment.ts","../../../src/batteries/sandbox/js/service.ts","../../../src/batteries/sandbox/js/runner.ts","../../../src/batteries/sandbox/js/tool.ts"],"sourcesContent":["import { createException } from '../../../lib/utils/exceptions'\n\n/** SES lockdown was unavailable or did not harden the guest realm. */\nexport const E_SES_LOCKDOWN_REQUIRED = createException<[string]>(\n 'E_SES_LOCKDOWN_REQUIRED',\n '%s',\n 'E_SES_LOCKDOWN_REQUIRED',\n 500,\n false\n)\n/** In-process SES evaluation requires hardening the complete host realm. */\nexport const E_SES_HOST_LOCKDOWN_REQUIRED = createException<[string]>(\n 'E_SES_HOST_LOCKDOWN_REQUIRED',\n '%s',\n 'E_SES_HOST_LOCKDOWN_REQUIRED',\n 500,\n false\n)\n/** A guest evaluation exceeded its tool-selected deadline. */\nexport const E_SES_EVALUATION_TIMEOUT = createException<[string]>(\n 'E_SES_EVALUATION_TIMEOUT',\n '%s',\n 'E_SES_EVALUATION_TIMEOUT',\n 408,\n false\n)\n","import { E_INVALID_SANDBOX_CONFIG } from '../exceptions'\nimport { guestLimitFloors, guestLimitsDefaults, hostcallQuotasDefaults } from '../types'\nimport type { GuestLimits, HostcallQuotas } from '../types'\n\nconst resolve = <T extends object>(\n partial: Partial<T> | undefined,\n defaults: T,\n floors: T,\n label: string\n): T => {\n const out = { ...defaults, ...(partial ?? {}) } as T\n for (const key of Object.keys(defaults)) {\n const value = (out as Record<string, number>)[key]\n const floor = (floors as Record<string, number>)[key]\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < floor\n )\n throw new E_INVALID_SANDBOX_CONFIG([\n `${label}.${key}=${String(value)} must be a finite integer >= ${floor}`,\n ])\n }\n return out\n}\n/** Resolve and validate all seven guest limits exactly once. */\nexport const resolveGuestLimits = (value?: Partial<GuestLimits>): GuestLimits =>\n resolve(value, guestLimitsDefaults, guestLimitFloors, 'limits')\n/** Resolve and validate all three hostcall quotas exactly once. */\nexport const resolveHostcallQuotas = (value?: Partial<HostcallQuotas>): HostcallQuotas =>\n resolve(\n value,\n hostcallQuotasDefaults,\n { hostcallTimeoutMs: 1, maxHostcallsPerEvaluation: 1, maxConcurrentHostcalls: 1 },\n 'hostcallQuotas'\n )\n","import { isError, isInstanceOf } from '@nhtio/adk/guards'\nimport {\n E_SES_HOST_LOCKDOWN_REQUIRED,\n E_SES_LOCKDOWN_REQUIRED,\n E_SES_EVALUATION_TIMEOUT,\n} from './exceptions'\nimport type { GuestOutcome, GuestLimits } from '../types'\n\nconst cut = (text: string, bytes: number): { text: string; truncated: boolean } => {\n const suffix = '… [cut]'\n if (new TextEncoder().encode(text).byteLength <= bytes) return { text, truncated: false }\n let value = text\n while (new TextEncoder().encode(`${value}${suffix}`).byteLength > bytes)\n value = value.slice(0, -1)\n return { text: `${value}${suffix}`, truncated: true }\n}\nconst render = (value: unknown): { value: unknown; encoding: 'encoder' | 'partial' } => {\n try {\n return {\n value: JSON.parse(JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? `${v}n` : v))),\n encoding: 'encoder',\n }\n } catch {\n return { value: `[unrepresentable ${typeof value}]`, encoding: 'partial' }\n }\n}\n/**\n * Construct a minimal SES-backed in-process guest.\n *\n * @remarks In Node, SES lockdown is process-global: this hardens the whole host realm, not\n * only the guest. Guest-scoped isolation requires a worker or child runtime.\n */\nexport const createCompartmentRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {},\n hostLockdown = true\n) => {\n await import('ses')\n const realm = globalThis as typeof globalThis & {\n lockdown?: () => void\n Compartment?: new (\n endowments?: Record<string, unknown>,\n modules?: unknown\n ) => {\n evaluate: (source: string) => unknown\n }\n }\n if (typeof realm.lockdown !== 'function' || typeof realm.Compartment !== 'function')\n throw new E_SES_LOCKDOWN_REQUIRED(['SES lockdown() and Compartment are required'])\n if (!hostLockdown)\n throw new E_SES_HOST_LOCKDOWN_REQUIRED([\n 'In-process SES evaluation requires host-realm lockdown; supply a worker or child guest for guest-only isolation',\n ])\n // SES is process-global in Node. The first guest bootstrap hardens this realm; subsequent\n // in-process evaluations must verify the already-hardened realm rather than invoking lockdown()\n // a second time (SES deliberately throws SES_ALREADY_LOCKED_DOWN).\n if (!(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked) {\n try {\n realm.lockdown()\n } catch (error) {\n if (\n !(\n isInstanceOf(error, 'TypeError', TypeError) &&\n String(error).includes('SES_ALREADY_LOCKED_DOWN')\n )\n )\n throw error\n }\n ;(realm as typeof realm & { __adkSesLocked?: boolean }).__adkSesLocked = true\n }\n const C = realm.Compartment\n return {\n async evaluate(source: string, o: { timeoutMs: number }): Promise<GuestOutcome> {\n const started = performance.now()\n let seq = 0\n let capped = false\n const logs: { seq: number; text: string; truncated: boolean }[] = []\n const consoleLike = {\n log: (...a: unknown[]) => {\n if (logs.length >= limits.maxLogEvents) {\n capped = true\n return\n }\n const text = cut(a.map(String).join(' '), limits.maxLogEventBytes)\n logs.push({ seq: ++seq, ...text })\n },\n }\n const end = (): number => Math.max(0, performance.now() - started)\n const timer = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new E_SES_EVALUATION_TIMEOUT(['evaluation exceeded timeout'])),\n o.timeoutMs\n )\n )\n try {\n const compartment = new C({ console: consoleLike, ...globals }, modules)\n const result = await Promise.race([\n Promise.resolve(compartment.evaluate(`(async()=>(${source}))()`)),\n timer,\n ])\n const rendered = render(result)\n return {\n ok: true,\n result: rendered.value,\n encoding: rendered.encoding,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) throw error\n const thrown = isError(error)\n ? { kind: 'error' as const, message: error.message, stack: error.stack }\n : { kind: 'opaque' as const }\n return {\n ok: false,\n thrown,\n durationMs: end(),\n logs,\n logsCapped: capped,\n logsComplete: true,\n }\n }\n },\n async kill(): Promise<void> {\n /* Compartment cannot be forcibly killed; production adapters must use a worker. */\n },\n }\n}\n","import { createCompartmentRuntime } from './compartment'\nimport type { GuestLimits } from '../types'\nimport type { GuestRuntimeLike } from './ses_contracts'\n\n/** In-process runtime factory for environments where SES is available. */\nexport const createGuestRuntime = async (\n globals: Record<string, (...args: unknown[]) => unknown>,\n limits: GuestLimits,\n modules: Record<string, unknown> = {},\n hostLockdown = true\n): Promise<GuestRuntimeLike> => ({\n async spawn() {\n return createCompartmentRuntime(globals, limits, modules, hostLockdown)\n },\n})\n","import { createGuestRuntime } from './service'\nimport { resolveGuestLimits } from './validation'\nimport type { GuestOutcome } from '../types'\nimport type { GuestGlobal, GuestRuntimeLike } from './ses_contracts'\n\n/** Host runner that retains capability implementations and exposes only enumerated names. */\nexport const createGuestRunner = async (\n globals: Record<string, GuestGlobal>,\n limits = resolveGuestLimits(),\n modules: Record<string, unknown> = {},\n hostLockdown = true\n): Promise<GuestRuntimeLike> => {\n return {\n async spawn(options): Promise<Awaited<ReturnType<GuestRuntimeLike['spawn']>>> {\n const implementations: Record<string, (...args: unknown[]) => unknown> = {}\n for (const [name, declaration] of Object.entries(globals))\n implementations[name] = (...args: unknown[]) =>\n declaration.fn(args, options.signal ?? new AbortController().signal)\n const runtime = await createGuestRuntime(implementations, limits, modules, hostLockdown)\n return runtime.spawn(options)\n },\n }\n}\n/** Type-only terminal outcome helper. */\nexport const isGuestOutcome = (value: unknown): value is GuestOutcome =>\n Boolean(value && typeof value === 'object' && 'durationMs' in value)\n","import { Tool } from '@nhtio/adk/forge'\nimport { createGuestRunner } from './runner'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { runToolGate } from '../../tools/_shared'\nimport { E_SES_EVALUATION_TIMEOUT } from './exceptions'\nimport { resolveGuestLimits, resolveHostcallQuotas } from './validation'\nimport { E_SANDBOX_FAILED, E_SANDBOX_GATE_REQUIRED } from '../exceptions'\nimport type { EvaluateJavascriptConfig } from './ses_contracts'\n\n/** Assemble the SES JavaScript evaluation tool. */\nexport const createEvaluateJavascriptTool = (config: EvaluateJavascriptConfig): Tool => {\n if (!config.gate) throw new E_SANDBOX_GATE_REQUIRED(['evaluate_javascript requires a gate'])\n const limits = resolveGuestLimits(config.limits)\n resolveHostcallQuotas(config.hostcallQuotas)\n const inputSchema = validator.object({\n source: validator.string().required(),\n timeout_seconds: validator.number().min(1).default(30),\n })\n return new Tool({\n name: 'evaluate_javascript',\n description:\n 'Evaluate JavaScript in a hardened SES guest. No ambient fetch, process, require, Date.now, or Math.random. Injected capabilities are asynchronous.',\n inputSchema,\n trusted: false,\n handler: async (raw, ctx) => {\n const args = raw as { source: string; timeout_seconds: number }\n await runToolGate(config.gate, ctx, 'evaluate_javascript', args)\n const runtime =\n config.runtime ??\n (await createGuestRunner(\n config.globals ?? {},\n limits,\n config.modules ?? {},\n config.hostLockdown ?? true\n ))\n const guest = await runtime.spawn({\n modules: Object.keys(config.modules ?? {}),\n globals: Object.keys(config.globals ?? {}).map((name) => ({\n name,\n kind: 'async-fn' as const,\n })),\n limits,\n signal: ctx.abortSignal,\n })\n try {\n return JSON.stringify(\n await guest.evaluate(args.source, { timeoutMs: args.timeout_seconds * 1000 })\n )\n } catch (error) {\n if (isInstanceOf(error, 'E_SES_EVALUATION_TIMEOUT', E_SES_EVALUATION_TIMEOUT)) {\n await guest.kill()\n throw new E_SANDBOX_FAILED([\n `Evaluation timed out after ${args.timeout_seconds} seconds (kind: timed-out).`,\n ])\n }\n throw error\n }\n },\n })\n}\n"],"mappings":"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"}
|
|
@@ -92,14 +92,15 @@ export interface CreateSandboxOptions {
|
|
|
92
92
|
/** Observability firehose: bypasses, fallbacks, drift outcomes, and the SRT version rules came from. */
|
|
93
93
|
readonly onSandbox?: (event: Parameters<ReturnType<typeof createSandboxObservability>>[0]) => void;
|
|
94
94
|
/**
|
|
95
|
-
* Permit
|
|
95
|
+
* Permit degraded operation when the environment cannot provide OS containment.
|
|
96
96
|
*
|
|
97
97
|
* @remarks
|
|
98
98
|
* Fires only for pre-execution conditions resolved once at construction — a platform the backend
|
|
99
99
|
* cannot sandbox that we still run on, dependency errors, or an absent optional peer. It NEVER fires
|
|
100
100
|
* for a violation (a violation means the sandbox worked), and native Windows is refused outright
|
|
101
|
-
* rather than degraded. When it fires the handle is permanently marked
|
|
102
|
-
*
|
|
101
|
+
* rather than degraded. When it fires the handle is permanently marked and every invocation emits
|
|
102
|
+
* a loud observability event. Execution STILL goes through `enforcer.run`; this option never runs
|
|
103
|
+
* a command unsandboxed, and the tool descriptions tell the model it has no OS containment.
|
|
103
104
|
*/
|
|
104
105
|
readonly allowUnsandboxedFallback?: boolean;
|
|
105
106
|
/** Ignore the per-call escape entirely, matching the reference consumer's strict mode. */
|
|
@@ -2,7 +2,7 @@ import type { SandboxPolicy } from "../types";
|
|
|
2
2
|
import type { SandboxPolicyEnforcer } from "../contracts/policy_enforcer";
|
|
3
3
|
type SrtConfig = {
|
|
4
4
|
filesystem: Record<string, unknown>;
|
|
5
|
-
network
|
|
5
|
+
network?: Record<string, unknown>;
|
|
6
6
|
/** SRT's Linux mandatory-deny scan depth is session-level. */
|
|
7
7
|
mandatoryDenySearchDepth?: number;
|
|
8
8
|
git?: {
|
|
@@ -101,7 +101,7 @@ var mapPolicy = (policy, runtime = {}) => {
|
|
|
101
101
|
denyWrite: nonEmpty(fs.denyWrite),
|
|
102
102
|
allowGitConfig: fs.allowGitConfig ?? false
|
|
103
103
|
},
|
|
104
|
-
network: {
|
|
104
|
+
...!net.disabled ? { network: {
|
|
105
105
|
allowedDomains,
|
|
106
106
|
deniedDomains,
|
|
107
107
|
deniedDomainReasons,
|
|
@@ -109,7 +109,7 @@ var mapPolicy = (policy, runtime = {}) => {
|
|
|
109
109
|
allowLocalBinding: false,
|
|
110
110
|
allowUnixSockets: [],
|
|
111
111
|
allowMachLookup: []
|
|
112
|
-
},
|
|
112
|
+
} } : {},
|
|
113
113
|
git: { safeDirectories: nonEmpty(fs.gitSafeDirectories ?? [process.cwd()]) }
|
|
114
114
|
};
|
|
115
115
|
};
|
|
@@ -210,7 +210,7 @@ var srtEnforcer = async (options) => {
|
|
|
210
210
|
filesystemDisabled: adopted ? Boolean(filesystem.disabled) : options.policy.filesystem.disabled,
|
|
211
211
|
network: {
|
|
212
212
|
disabled: adopted ? false : options.policy.network.disabled ?? false,
|
|
213
|
-
allowedDomains: adopted ? Array.isArray(network.allowedDomains) ? network.allowedDomains : [] : options.policy.network.disabled ?
|
|
213
|
+
allowedDomains: adopted ? Array.isArray(network.allowedDomains) ? network.allowedDomains : [] : options.policy.network.disabled ? void 0 : nonEmpty(options.policy.network.allowedDomains),
|
|
214
214
|
deniedDomains: adopted ? Array.isArray(network.deniedDomains) ? network.deniedDomains : [] : options.policy.network.disabled ? [] : nonEmpty(options.policy.network.deniedDomains)
|
|
215
215
|
},
|
|
216
216
|
mandatoryDeny: {
|
|
@@ -254,17 +254,41 @@ var srtEnforcer = async (options) => {
|
|
|
254
254
|
"pipe",
|
|
255
255
|
"pipe"
|
|
256
256
|
],
|
|
257
|
-
shell: false
|
|
257
|
+
shell: false,
|
|
258
|
+
detached: true
|
|
258
259
|
});
|
|
260
|
+
let terminate;
|
|
261
|
+
if (op.signal) {
|
|
262
|
+
terminate = () => {
|
|
263
|
+
try {
|
|
264
|
+
if (child.pid) process.kill(-child.pid, "SIGKILL");
|
|
265
|
+
else child.kill("SIGKILL");
|
|
266
|
+
} catch {
|
|
267
|
+
child.kill("SIGKILL");
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
if (op.signal.aborted) terminate();
|
|
271
|
+
else op.signal.addEventListener("abort", terminate, { once: true });
|
|
272
|
+
}
|
|
273
|
+
const cleanup = () => {
|
|
274
|
+
if (terminate && op.signal) op.signal.removeEventListener("abort", terminate);
|
|
275
|
+
terminate = void 0;
|
|
276
|
+
};
|
|
259
277
|
const completed = new Promise((settle) => {
|
|
260
|
-
child.once("error", () =>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
278
|
+
child.once("error", () => {
|
|
279
|
+
cleanup();
|
|
280
|
+
settle({
|
|
281
|
+
exitCode: 1,
|
|
282
|
+
failed: true
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
child.once("close", (code) => {
|
|
286
|
+
cleanup();
|
|
287
|
+
settle({
|
|
288
|
+
exitCode: code ?? 1,
|
|
289
|
+
failed: (code ?? 1) !== 0
|
|
290
|
+
});
|
|
291
|
+
});
|
|
268
292
|
});
|
|
269
293
|
return {
|
|
270
294
|
stdout: toWeb(child.stdout),
|