@zergai/ztc 0.4.0-beta.1 → 0.5.0-beta.1
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/README.md +398 -45
- package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
- package/THIRD_PARTY_NOTICES.md +273 -12
- package/bin/zmux-darwin-arm64 +0 -0
- package/bin/ztc-audio-darwin-arm64 +0 -0
- package/bin/ztc-capture-darwin-arm64 +0 -0
- package/bin/ztc-computer-darwin-arm64 +0 -0
- package/bin/ztc-llm-darwin-arm64 +0 -0
- package/bin/ztc-tts-darwin-arm64 +0 -0
- package/bin/ztc-tui-darwin-arm64 +0 -0
- package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
- package/bin/zterm-darwin-arm64 +0 -0
- package/dist/App.js +1206 -209
- package/dist/agent/agent.d.ts +74 -8
- package/dist/agent/agent.js +1073 -184
- package/dist/agent/backends/account_rotation.d.ts +4 -0
- package/dist/agent/backends/account_rotation.js +8 -2
- package/dist/agent/backends/anthropic.d.ts +13 -0
- package/dist/agent/backends/anthropic.js +169 -28
- package/dist/agent/backends/claude_cli.js +18 -8
- package/dist/agent/backends/codex_app_server.d.ts +1 -0
- package/dist/agent/backends/codex_app_server.js +55 -3
- package/dist/agent/backends/codex_auth.d.ts +1 -0
- package/dist/agent/backends/codex_auth.js +67 -13
- package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
- package/dist/agent/backends/codex_buffered_recovery.js +293 -0
- package/dist/agent/backends/gemini.js +3 -1
- package/dist/agent/backends/http_error.d.ts +26 -0
- package/dist/agent/backends/http_error.js +221 -0
- package/dist/agent/backends/index.d.ts +9 -2
- package/dist/agent/backends/index.js +22 -2
- package/dist/agent/backends/openai.d.ts +0 -6
- package/dist/agent/backends/openai.js +5 -2
- package/dist/agent/backends/openai_compatible.d.ts +5 -4
- package/dist/agent/backends/openai_compatible.js +26 -19
- package/dist/agent/backends/openai_responses.d.ts +8 -3
- package/dist/agent/backends/openai_responses.js +77 -33
- package/dist/agent/backends/provider_ids.d.ts +1 -0
- package/dist/agent/backends/provider_ids.js +4 -0
- package/dist/agent/backends/request_metrics.js +12 -2
- package/dist/agent/backends/types.d.ts +109 -6
- package/dist/agent/backends/types.js +5 -1
- package/dist/agent/backends/zrouter_stream.d.ts +6 -1
- package/dist/agent/backends/zrouter_stream.js +160 -42
- package/dist/agent/background_registry.d.ts +2 -0
- package/dist/agent/background_registry.js +1 -0
- package/dist/agent/claim_observation.d.ts +6 -0
- package/dist/agent/claim_observation.js +54 -0
- package/dist/agent/commands/accounts.js +46 -177
- package/dist/agent/commands/attention.d.ts +2 -0
- package/dist/agent/commands/attention.js +67 -0
- package/dist/agent/commands/auth.js +18 -2
- package/dist/agent/commands/board.d.ts +2 -0
- package/dist/agent/commands/board.js +169 -0
- package/dist/agent/commands/clipboard.js +50 -1
- package/dist/agent/commands/compact.js +21 -13
- package/dist/agent/commands/config.js +4 -1
- package/dist/agent/commands/context.js +6 -1
- package/dist/agent/commands/desktop.d.ts +2 -0
- package/dist/agent/commands/desktop.js +29 -0
- package/dist/agent/commands/effort.js +14 -6
- package/dist/agent/commands/environment.d.ts +3 -0
- package/dist/agent/commands/environment.js +109 -0
- package/dist/agent/commands/evidence.d.ts +2 -0
- package/dist/agent/commands/evidence.js +9 -0
- package/dist/agent/commands/fork.js +4 -3
- package/dist/agent/commands/goal.d.ts +33 -1
- package/dist/agent/commands/goal.js +174 -14
- package/dist/agent/commands/goal_exit.d.ts +36 -0
- package/dist/agent/commands/goal_exit.js +120 -0
- package/dist/agent/commands/help.js +3 -1
- package/dist/agent/commands/history.js +3 -1
- package/dist/agent/commands/inbox.d.ts +2 -0
- package/dist/agent/commands/inbox.js +148 -0
- package/dist/agent/commands/index.js +16 -1
- package/dist/agent/commands/input_mode.js +8 -6
- package/dist/agent/commands/job.d.ts +2 -0
- package/dist/agent/commands/job.js +93 -0
- package/dist/agent/commands/keybindings.js +4 -1
- package/dist/agent/commands/label.d.ts +2 -0
- package/dist/agent/commands/label.js +77 -0
- package/dist/agent/commands/layout.d.ts +2 -0
- package/dist/agent/commands/layout.js +20 -0
- package/dist/agent/commands/mirror.js +16 -1
- package/dist/agent/commands/model.js +12 -2
- package/dist/agent/commands/permissions.d.ts +3 -1
- package/dist/agent/commands/permissions.js +79 -89
- package/dist/agent/commands/plan.js +5 -15
- package/dist/agent/commands/profile.js +21 -2
- package/dist/agent/commands/provider_selection.js +20 -1
- package/dist/agent/commands/rename.js +1 -1
- package/dist/agent/commands/resources.d.ts +2 -0
- package/dist/agent/commands/resources.js +67 -0
- package/dist/agent/commands/rewind.d.ts +3 -0
- package/dist/agent/commands/rewind.js +16 -0
- package/dist/agent/commands/runbooks.d.ts +2 -0
- package/dist/agent/commands/runbooks.js +73 -0
- package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
- package/dist/agent/commands/runbooks_lazy.js +8 -0
- package/dist/agent/commands/sessions.d.ts +1 -1
- package/dist/agent/commands/sessions.js +33 -5
- package/dist/agent/commands/settings.js +185 -39
- package/dist/agent/commands/setup.d.ts +2 -0
- package/dist/agent/commands/setup.js +78 -0
- package/dist/agent/commands/share.d.ts +2 -0
- package/dist/agent/commands/share.js +64 -0
- package/dist/agent/commands/status.js +14 -2
- package/dist/agent/commands/types.d.ts +99 -6
- package/dist/agent/commands/update.js +8 -0
- package/dist/agent/commands/usage.d.ts +2 -0
- package/dist/agent/commands/usage.js +8 -0
- package/dist/agent/factory.d.ts +11 -0
- package/dist/agent/factory.js +113 -88
- package/dist/agent/loop_policy.d.ts +6 -3
- package/dist/agent/loop_policy.js +12 -3
- package/dist/agent/measurement_guidance.d.ts +2 -0
- package/dist/agent/measurement_guidance.js +5 -0
- package/dist/agent/request_encoder.d.ts +8 -1
- package/dist/agent/request_encoder.js +95 -23
- package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
- package/dist/agent/runtime/benchmark_comparison.js +94 -0
- package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
- package/dist/agent/runtime/benchmark_contract.js +90 -0
- package/dist/agent/runtime/checked_commands.d.ts +32 -0
- package/dist/agent/runtime/checked_commands.js +119 -0
- package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
- package/dist/agent/runtime/command_execution_policy.js +91 -0
- package/dist/agent/runtime/command_jobs.d.ts +36 -18
- package/dist/agent/runtime/command_jobs.js +151 -13
- package/dist/agent/runtime/command_panes.d.ts +59 -0
- package/dist/agent/runtime/command_panes.js +398 -0
- package/dist/agent/runtime/command_wait.d.ts +19 -0
- package/dist/agent/runtime/command_wait.js +167 -0
- package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
- package/dist/agent/runtime/cpu_benchmark.js +126 -0
- package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
- package/dist/agent/runtime/delegated_evidence.js +80 -0
- package/dist/agent/runtime/evidence.d.ts +127 -0
- package/dist/agent/runtime/evidence.js +468 -0
- package/dist/agent/runtime/execution_context.d.ts +7 -0
- package/dist/agent/runtime/execution_context.js +39 -3
- package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
- package/dist/agent/runtime/json_verifier_recipe.js +66 -0
- package/dist/agent/runtime/measurements.d.ts +110 -0
- package/dist/agent/runtime/measurements.js +317 -0
- package/dist/agent/runtime/policy.d.ts +4 -0
- package/dist/agent/runtime/policy.js +31 -20
- package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
- package/dist/agent/runtime/provider_native_evidence.js +86 -0
- package/dist/agent/runtime/recovery.d.ts +2 -0
- package/dist/agent/runtime/recovery.js +45 -2
- package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
- package/dist/agent/runtime/remote_broker_transport.js +84 -0
- package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
- package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
- package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
- package/dist/agent/runtime/remote_journal_replay.js +233 -0
- package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
- package/dist/agent/runtime/remote_mutation_journal.js +208 -0
- package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
- package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
- package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
- package/dist/agent/runtime/remote_resource_errors.js +9 -0
- package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
- package/dist/agent/runtime/remote_resource_script.js +1009 -0
- package/dist/agent/runtime/remote_resources.d.ts +29 -0
- package/dist/agent/runtime/remote_resources.js +160 -0
- package/dist/agent/runtime/source_verification.d.ts +12 -0
- package/dist/agent/runtime/source_verification.js +210 -0
- package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
- package/dist/agent/runtime/source_verification_contract.js +203 -0
- package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
- package/dist/agent/runtime/tool_checkpoints.js +26 -0
- package/dist/agent/runtime/tool_effects.d.ts +5 -0
- package/dist/agent/runtime/tool_progress.d.ts +12 -0
- package/dist/agent/runtime/tool_progress.js +76 -0
- package/dist/agent/runtime/tool_runtime.d.ts +16 -1
- package/dist/agent/runtime/tool_runtime.js +204 -10
- package/dist/agent/runtime/tracing.d.ts +1 -1
- package/dist/agent/runtime/verifier_capture.d.ts +9 -0
- package/dist/agent/runtime/verifier_capture.js +100 -0
- package/dist/agent/runtime/verifier_contract.d.ts +24 -0
- package/dist/agent/runtime/verifier_contract.js +41 -0
- package/dist/agent/subagent.d.ts +20 -10
- package/dist/agent/subagent.js +266 -29
- package/dist/agent/tool_response_directory.d.ts +24 -0
- package/dist/agent/tool_response_directory.js +61 -0
- package/dist/agent/tool_response_source.d.ts +8 -0
- package/dist/agent/tool_response_source.js +49 -0
- package/dist/agent/tool_response_store.d.ts +75 -4
- package/dist/agent/tool_response_store.js +583 -64
- package/dist/agent/tools/ask_user.d.ts +3 -1
- package/dist/agent/tools/ask_user.js +30 -11
- package/dist/agent/tools/background.js +1 -0
- package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
- package/dist/agent/tools/benchmark_cpu.js +102 -0
- package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
- package/dist/agent/tools/compare_benchmarks.js +53 -0
- package/dist/agent/tools/deferred.js +1 -0
- package/dist/agent/tools/delegate.js +18 -2
- package/dist/agent/tools/helper_requirements.d.ts +7 -0
- package/dist/agent/tools/helper_requirements.js +19 -0
- package/dist/agent/tools/index.d.ts +1 -0
- package/dist/agent/tools/index.js +3 -0
- package/dist/agent/tools/measurement_report.d.ts +22 -0
- package/dist/agent/tools/measurement_report.js +190 -0
- package/dist/agent/tools/pane.d.ts +0 -7
- package/dist/agent/tools/pane.js +5 -4
- package/dist/agent/tools/project_context.d.ts +3 -0
- package/dist/agent/tools/project_context.js +45 -0
- package/dist/agent/tools/recall_tool_response.d.ts +3 -5
- package/dist/agent/tools/recall_tool_response.js +19 -29
- package/dist/agent/tools/registry.d.ts +1 -0
- package/dist/agent/tools/registry.js +23 -0
- package/dist/agent/tools/related_sessions.d.ts +2 -0
- package/dist/agent/tools/related_sessions.js +156 -0
- package/dist/agent/tools/routine.js +13 -3
- package/dist/agent/tools/session_evidence.d.ts +3 -0
- package/dist/agent/tools/session_evidence.js +72 -0
- package/dist/agent/tools/shell.d.ts +4 -3
- package/dist/agent/tools/shell.js +174 -47
- package/dist/agent/tools/tool_search.js +3 -2
- package/dist/agent/tools/types.d.ts +28 -0
- package/dist/agent/tools/verify_artifact.d.ts +2 -0
- package/dist/agent/tools/verify_artifact.js +60 -0
- package/dist/agent/tools/workflow.js +1 -0
- package/dist/app/activity.d.ts +6 -1
- package/dist/app/activity.js +81 -12
- package/dist/app/agent_runner.d.ts +6 -1
- package/dist/app/agent_runner.js +34 -19
- package/dist/app/command_context.js +106 -10
- package/dist/app/controller.d.ts +15 -4
- package/dist/app/controller.js +29 -3
- package/dist/app/escape_stop.d.ts +11 -0
- package/dist/app/escape_stop.js +15 -0
- package/dist/app/liveness.d.ts +6 -4
- package/dist/app/liveness.js +13 -3
- package/dist/app/model_catalog_cache.d.ts +5 -0
- package/dist/app/model_catalog_cache.js +138 -0
- package/dist/app/ordered_transcript.js +43 -4
- package/dist/app/prompt_turn.d.ts +14 -0
- package/dist/app/prompt_turn.js +53 -0
- package/dist/app/recap.d.ts +3 -0
- package/dist/app/recap.js +9 -3
- package/dist/app/restart.d.ts +3 -2
- package/dist/app/restart.js +22 -7
- package/dist/app/rewind.d.ts +3 -3
- package/dist/app/rewind.js +3 -3
- package/dist/app/selection_completion.d.ts +17 -2
- package/dist/app/selection_completion.js +84 -9
- package/dist/app/session_manager.d.ts +38 -6
- package/dist/app/session_manager.js +263 -60
- package/dist/app/session_messages.d.ts +3 -0
- package/dist/app/session_messages.js +60 -0
- package/dist/app/task_scope_router.d.ts +20 -0
- package/dist/app/task_scope_router.js +173 -0
- package/dist/app/transcript_window.d.ts +2 -0
- package/dist/app/transcript_window.js +4 -0
- package/dist/app/workspace_admission_details.d.ts +3 -0
- package/dist/app/workspace_admission_details.js +26 -0
- package/dist/app/workspace_layout_controller.d.ts +11 -0
- package/dist/app/workspace_layout_controller.js +88 -0
- package/dist/app/workspace_monitor.d.ts +1 -0
- package/dist/app/workspace_monitor.js +216 -0
- package/dist/app/workspace_presets.d.ts +29 -0
- package/dist/app/workspace_presets.js +192 -0
- package/dist/attention/queue.d.ts +37 -0
- package/dist/attention/queue.js +183 -0
- package/dist/bench/rf_shared.d.ts +2 -0
- package/dist/board/binding.d.ts +42 -0
- package/dist/board/binding.js +38 -0
- package/dist/board/client.d.ts +42 -0
- package/dist/board/client.js +60 -0
- package/dist/cli.js +1 -1
- package/dist/cli_args.js +19 -17
- package/dist/cli_main.js +110 -13
- package/dist/cli_ratatui.d.ts +183 -16
- package/dist/cli_ratatui.js +3989 -1255
- package/dist/components/ActivityLine.d.ts +3 -2
- package/dist/components/ActivityLine.js +2 -2
- package/dist/components/InputArea.d.ts +19 -1
- package/dist/components/InputArea.js +264 -190
- package/dist/components/MessageList.d.ts +2 -0
- package/dist/components/MessageList.js +3 -1
- package/dist/components/SingleMessage.d.ts +2 -0
- package/dist/components/SingleMessage.js +4 -2
- package/dist/components/StatusBar.d.ts +4 -2
- package/dist/components/StatusBar.js +3 -1
- package/dist/conductor_branch.js +3 -0
- package/dist/config/api_retry.d.ts +6 -1
- package/dist/config/api_retry.js +19 -1
- package/dist/config/defaults.d.ts +2 -1
- package/dist/config/defaults.js +9 -2
- package/dist/config/message_display.d.ts +1 -0
- package/dist/config/message_display.js +17 -2
- package/dist/config/permissions.d.ts +21 -0
- package/dist/config/permissions.js +89 -0
- package/dist/config/resolved.d.ts +2 -2
- package/dist/config/types.d.ts +32 -5
- package/dist/config.d.ts +38 -4
- package/dist/config.js +290 -42
- package/dist/context/project_intelligence.d.ts +44 -0
- package/dist/context/project_intelligence.js +246 -0
- package/dist/desktop/cli_launch.d.ts +8 -0
- package/dist/desktop/cli_launch.js +6 -0
- package/dist/desktop/cli_shim.d.ts +8 -0
- package/dist/desktop/cli_shim.js +120 -0
- package/dist/desktop/runtime.d.ts +16 -0
- package/dist/desktop/runtime.js +161 -0
- package/dist/desktop/worker_launch.d.ts +7 -0
- package/dist/desktop/worker_launch.js +7 -0
- package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
- package/dist/diagnostics/cargo_mutants_selection.js +48 -0
- package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
- package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
- package/dist/diagnostics/session_evidence_package.d.ts +40 -0
- package/dist/diagnostics/session_evidence_package.js +234 -0
- package/dist/diagnostics/session_export.d.ts +93 -0
- package/dist/diagnostics/session_export.js +634 -0
- package/dist/emulation/tool_adapters.js +48 -18
- package/dist/emulation/ztc_addendum.d.ts +1 -0
- package/dist/emulation/ztc_addendum.js +13 -12
- package/dist/environment/service_runner.d.ts +1 -0
- package/dist/environment/service_runner.js +68 -0
- package/dist/environment/store.d.ts +120 -0
- package/dist/environment/store.js +387 -0
- package/dist/events.d.ts +40 -1
- package/dist/events.js +10 -17
- package/dist/goal_contract.d.ts +25 -0
- package/dist/goal_contract.js +44 -0
- package/dist/headless.d.ts +31 -0
- package/dist/headless.js +578 -70
- package/dist/headless_cli.js +8 -0
- package/dist/headless_cli_args.d.ts +1 -0
- package/dist/headless_cli_args.js +1 -0
- package/dist/intake/cli.d.ts +1 -0
- package/dist/intake/cli.js +33 -0
- package/dist/intake/format.d.ts +2 -0
- package/dist/intake/format.js +14 -0
- package/dist/intake/notifications.d.ts +16 -0
- package/dist/intake/notifications.js +132 -0
- package/dist/intake/store.d.ts +56 -0
- package/dist/intake/store.js +238 -0
- package/dist/library.d.ts +8 -0
- package/dist/library.js +19 -10
- package/dist/mcp/client.d.ts +1 -0
- package/dist/mcp/client.js +20 -0
- package/dist/modes/builtin/plan.yaml +2 -2
- package/dist/modes/handlers.js +1 -1
- package/dist/onboarding/first_run.d.ts +3 -0
- package/dist/onboarding/first_run.js +33 -25
- package/dist/onboarding/setup.d.ts +32 -0
- package/dist/onboarding/setup.js +133 -0
- package/dist/onboarding/setup_agent_health.d.ts +17 -0
- package/dist/onboarding/setup_agent_health.js +79 -0
- package/dist/onboarding/setup_environment.d.ts +66 -0
- package/dist/onboarding/setup_environment.js +219 -0
- package/dist/onboarding/setup_workspace.d.ts +17 -0
- package/dist/onboarding/setup_workspace.js +129 -0
- package/dist/optimize/adapters/index.d.ts +4 -1
- package/dist/optimize/adapters/index.js +7 -0
- package/dist/optimize/adapters/kernelbench.js +14 -5
- package/dist/optimize/adapters/popcorn.js +3 -2
- package/dist/optimize/adapters/profile_benchmark.js +13 -7
- package/dist/optimize/adapters/rfbench.js +25 -14
- package/dist/optimize/adapters/types.d.ts +3 -0
- package/dist/optimize/adapters/zergpod.js +5 -2
- package/dist/optimize/baseline.js +10 -21
- package/dist/optimize/branch.js +9 -12
- package/dist/optimize/combine.js +2 -3
- package/dist/optimize/executor.js +34 -48
- package/dist/optimize/measurements.d.ts +55 -0
- package/dist/optimize/measurements.js +173 -0
- package/dist/optimize/results.d.ts +1 -0
- package/dist/optimize/results.js +11 -33
- package/dist/optimize/tge.js +2 -1
- package/dist/panes/initial_input.d.ts +19 -0
- package/dist/panes/initial_input.js +206 -0
- package/dist/panes/labels.d.ts +16 -0
- package/dist/panes/labels.js +42 -0
- package/dist/panes/model_catalog.d.ts +3 -3
- package/dist/panes/model_catalog.js +28 -4
- package/dist/panes/pane_registry.js +6 -2
- package/dist/panes/types.d.ts +3 -0
- package/dist/panes/ztc_launch.js +19 -0
- package/dist/plugin/optimization.d.ts +2 -0
- package/dist/plugin/optimization.js +1 -0
- package/dist/plugin/runtime.d.ts +2 -0
- package/dist/plugin/simulation.d.ts +6 -1
- package/dist/plugin/simulation_contract.d.ts +836 -1
- package/dist/plugin/simulation_documents.d.ts +22 -0
- package/dist/plugin/simulation_documents.js +1 -0
- package/dist/plugin/simulation_interventions.d.ts +103 -0
- package/dist/plugin/simulation_interventions.js +1 -0
- package/dist/plugin/simulation_living.d.ts +1 -0
- package/dist/plugin/simulation_living.js +3 -0
- package/dist/plugin/simulation_meetings.d.ts +121 -0
- package/dist/plugin/simulation_meetings.js +1 -0
- package/dist/plugin/simulation_story_review.d.ts +111 -0
- package/dist/plugin/simulation_story_review.js +1 -0
- package/dist/plugin/simulation_storyteller.d.ts +91 -0
- package/dist/plugin/simulation_storyteller.js +1 -0
- package/dist/plugin/simulation_structured.d.ts +2 -0
- package/dist/plugin/simulation_structured.js +2 -0
- package/dist/plugin/simulation_toolkit.d.ts +21 -0
- package/dist/plugin/simulation_toolkit.js +24 -0
- package/dist/prompts/tool_delegate_task.j2 +1 -1
- package/dist/remote-broker/Dockerfile +10 -0
- package/dist/remote-broker/archive.py +1227 -0
- package/dist/remote-broker/cutover.py +761 -0
- package/dist/remote-broker/requirements.txt +5 -0
- package/dist/remote-broker/resources.json +6 -0
- package/dist/remote-broker/resources.write-staging.example.json +18 -0
- package/dist/remote-broker/retained.py +686 -0
- package/dist/remote-broker/retained_cleanup.py +550 -0
- package/dist/remote-broker/server.py +648 -0
- package/dist/remote-broker/worker.py +1007 -0
- package/dist/router_auth.d.ts +31 -0
- package/dist/router_auth.js +155 -9
- package/dist/runbooks/catalog.d.ts +3 -0
- package/dist/runbooks/catalog.js +26 -0
- package/dist/runbooks/library.d.ts +11 -0
- package/dist/runbooks/library.js +95 -0
- package/dist/runbooks/package.d.ts +43 -0
- package/dist/runbooks/package.js +102 -0
- package/dist/session.d.ts +65 -13
- package/dist/session.js +548 -43
- package/dist/session_handoff.d.ts +25 -0
- package/dist/session_handoff.js +322 -0
- package/dist/session_handoff_contract.d.ts +89 -0
- package/dist/session_handoff_contract.js +179 -0
- package/dist/session_media.d.ts +41 -0
- package/dist/session_media.js +357 -0
- package/dist/session_ownership.d.ts +16 -0
- package/dist/session_ownership.js +221 -0
- package/dist/session_public.d.ts +10 -2
- package/dist/session_public.js +6 -1
- package/dist/simulation/dynamic_history.d.ts +42 -0
- package/dist/simulation/dynamic_history.js +173 -0
- package/dist/simulation/engines/swarm/pane_manager.js +7 -6
- package/dist/simulation/inference.d.ts +3 -1
- package/dist/simulation/inference.js +19 -1
- package/dist/simulation/intervention_generation.d.ts +27 -0
- package/dist/simulation/intervention_generation.js +246 -0
- package/dist/simulation/intervention_material.d.ts +4 -0
- package/dist/simulation/intervention_material.js +81 -0
- package/dist/simulation/living/context.d.ts +3130 -0
- package/dist/simulation/living/context.js +944 -0
- package/dist/simulation/living/definer.d.ts +12 -0
- package/dist/simulation/living/definer.js +223 -0
- package/dist/simulation/living/definition.d.ts +257 -0
- package/dist/simulation/living/definition.js +341 -0
- package/dist/simulation/living/frame.d.ts +259 -0
- package/dist/simulation/living/frame.js +223 -0
- package/dist/simulation/living/identifiers.d.ts +2 -0
- package/dist/simulation/living/identifiers.js +12 -0
- package/dist/simulation/living/index.d.ts +15 -0
- package/dist/simulation/living/index.js +15 -0
- package/dist/simulation/living/inference.d.ts +219 -0
- package/dist/simulation/living/inference.js +576 -0
- package/dist/simulation/living/mechanics.d.ts +54 -0
- package/dist/simulation/living/mechanics.js +588 -0
- package/dist/simulation/living/model-input.d.ts +25 -0
- package/dist/simulation/living/model-input.js +215 -0
- package/dist/simulation/living/open-world.d.ts +257 -0
- package/dist/simulation/living/open-world.js +102 -0
- package/dist/simulation/living/projection.d.ts +7 -0
- package/dist/simulation/living/projection.js +31 -0
- package/dist/simulation/living/recall.d.ts +17 -0
- package/dist/simulation/living/recall.js +25 -0
- package/dist/simulation/living/reduce.d.ts +15 -0
- package/dist/simulation/living/reduce.js +1853 -0
- package/dist/simulation/living/replay.d.ts +6 -0
- package/dist/simulation/living/replay.js +22 -0
- package/dist/simulation/living/runtime.d.ts +140 -0
- package/dist/simulation/living/runtime.js +3020 -0
- package/dist/simulation/living/shared-kinds.d.ts +24 -0
- package/dist/simulation/living/shared-kinds.js +96 -0
- package/dist/simulation/living/types.d.ts +2785 -0
- package/dist/simulation/living/types.js +669 -0
- package/dist/simulation/llm.d.ts +3 -1
- package/dist/simulation/llm.js +90 -30
- package/dist/simulation/memory/embedding.d.ts +1 -1
- package/dist/simulation/memory/embedding.js +9 -3
- package/dist/simulation/memory/filesystem.d.ts +2 -0
- package/dist/simulation/memory/filesystem.js +5 -1
- package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
- package/dist/simulation/memory/filesystem_file_tree.js +41 -10
- package/dist/simulation/memory/filesystem_invariants.js +1 -2
- package/dist/simulation/memory/filesystem_types.d.ts +1 -0
- package/dist/simulation/memory/memory.d.ts +2 -0
- package/dist/simulation/memory/memory.js +5 -1
- package/dist/simulation/orchestration/intent.js +0 -2
- package/dist/simulation/orchestration/lifecycle.js +0 -2
- package/dist/simulation/plugin_host.d.ts +25 -1
- package/dist/simulation/plugin_host.js +334 -17
- package/dist/simulation/session_documents.d.ts +20 -0
- package/dist/simulation/session_documents.js +62 -0
- package/dist/simulation/session_input_validation.d.ts +43 -0
- package/dist/simulation/session_input_validation.js +364 -0
- package/dist/simulation/session_inputs.d.ts +32 -0
- package/dist/simulation/session_inputs.js +154 -0
- package/dist/simulation/telemetry.d.ts +11 -14
- package/dist/simulation/telemetry.js +177 -54
- package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
- package/dist/simulation/toolkit/bounded_turns.js +80 -0
- package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
- package/dist/simulation/toolkit/dynamic_agents.js +218 -0
- package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
- package/dist/simulation/toolkit/dynamic_digest.js +8 -0
- package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
- package/dist/simulation/toolkit/dynamic_documents.js +71 -0
- package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
- package/dist/simulation/toolkit/dynamic_driver.js +269 -0
- package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
- package/dist/simulation/toolkit/dynamic_game.js +805 -0
- package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
- package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
- package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
- package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
- package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
- package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
- package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
- package/dist/simulation/toolkit/dynamic_progress.js +214 -0
- package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
- package/dist/simulation/toolkit/dynamic_projection.js +219 -0
- package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
- package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
- package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
- package/dist/simulation/toolkit/dynamic_state.js +1967 -0
- package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
- package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
- package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
- package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
- package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
- package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
- package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
- package/dist/simulation/toolkit/dynamic_world.js +377 -0
- package/dist/simulation/toolkit/structured_output.d.ts +5 -0
- package/dist/simulation/toolkit/structured_output.js +321 -0
- package/dist/simulation/types/world.d.ts +2 -0
- package/dist/simulation/world/artifact_store.js +1 -1
- package/dist/simulation/world/memory_manager.d.ts +5 -0
- package/dist/simulation/world/memory_manager.js +17 -2
- package/dist/simulation/world/state.d.ts +3 -2
- package/dist/simulation/world/state.js +15 -5
- package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
- package/dist/terminal_attach.d.ts +1 -0
- package/dist/terminal_attach.js +113 -0
- package/dist/tool_progress.d.ts +3 -0
- package/dist/tool_progress.js +27 -0
- package/dist/types.d.ts +145 -10
- package/dist/types.js +3 -0
- package/dist/ui/core/input.d.ts +3 -0
- package/dist/ui/core/input_segments.d.ts +18 -1
- package/dist/ui/core/input_segments.js +131 -47
- package/dist/ui/core/input_state.d.ts +12 -0
- package/dist/ui/core/layout_yoga.d.ts +1 -1
- package/dist/ui/core/turn_metadata.d.ts +5 -0
- package/dist/ui/core/turn_metadata.js +22 -0
- package/dist/ui/ink/render.d.ts +2 -1
- package/dist/ui/ink/render.js +6 -5
- package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
- package/dist/ui/ratatui/headless_pane_manager.js +293 -104
- package/dist/ui/ratatui/index.d.ts +1 -0
- package/dist/ui/ratatui/input.d.ts +4 -0
- package/dist/ui/ratatui/input.js +15 -0
- package/dist/ui/ratatui/ipc_path.d.ts +2 -0
- package/dist/ui/ratatui/ipc_path.js +29 -1
- package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
- package/dist/ui/ratatui/mux_persistence.js +139 -1
- package/dist/ui/ratatui/pane_relay.d.ts +1 -1
- package/dist/ui/ratatui/pane_relay.js +55 -27
- package/dist/ui/ratatui/process.d.ts +17 -1
- package/dist/ui/ratatui/process.js +80 -7
- package/dist/ui/ratatui/protocol.d.ts +236 -1
- package/dist/ui/ratatui/protocol.js +90 -0
- package/dist/ui/scrollback.d.ts +2 -1
- package/dist/ui/scrollback.js +9 -4
- package/dist/ui/stream_typewriter.d.ts +8 -3
- package/dist/ui/stream_typewriter.js +30 -1
- package/dist/ui/streaming_scrollback.d.ts +1 -0
- package/dist/ui/streaming_scrollback.js +1 -1
- package/dist/ui/transcript_render_cache.js +10 -0
- package/dist/ui/views/activity_line.d.ts +5 -3
- package/dist/ui/views/activity_line.js +65 -7
- package/dist/ui/views/app.d.ts +6 -3
- package/dist/ui/views/app.js +17 -6
- package/dist/ui/views/completion_menu.js +10 -5
- package/dist/ui/views/input_area.d.ts +7 -3
- package/dist/ui/views/input_area.js +15 -9
- package/dist/ui/views/message_list.d.ts +4 -1
- package/dist/ui/views/message_list.js +89 -19
- package/dist/ui/views/queue_panel.d.ts +3 -1
- package/dist/ui/views/queue_panel.js +9 -2
- package/dist/ui/views/status_bar.d.ts +4 -2
- package/dist/ui/views/status_bar.js +28 -13
- package/dist/ui/views/theme.d.ts +2 -0
- package/dist/ui/views/theme.js +2 -0
- package/dist/ui/widgets/color_panel.js +18 -0
- package/dist/ui/widgets/form.js +8 -0
- package/dist/ui/widgets/log_view.js +7 -0
- package/dist/ui/widgets/navigator_panel.js +8 -0
- package/dist/ui/widgets/prompt_viewer.js +2 -0
- package/dist/ui/widgets/questionnaire.d.ts +2 -0
- package/dist/ui/widgets/questionnaire.js +79 -16
- package/dist/ui/widgets/resume_panel.d.ts +2 -0
- package/dist/ui/widgets/resume_panel.js +26 -15
- package/dist/ui/widgets/rewind_panel.d.ts +2 -2
- package/dist/ui/widgets/rewind_panel.js +4 -2
- package/dist/ui/widgets/select.js +16 -27
- package/dist/ui/widgets/settings_panel.js +16 -0
- package/dist/ui/widgets/status_line_panel.d.ts +1 -0
- package/dist/ui/widgets/status_line_panel.js +30 -4
- package/dist/ui/widgets/text_input.d.ts +2 -0
- package/dist/ui/widgets/text_input.js +15 -1
- package/dist/ui/widgets/types.d.ts +2 -0
- package/dist/usage_projection.d.ts +24 -0
- package/dist/usage_projection.js +130 -0
- package/dist/usage_snapshot.d.ts +36 -0
- package/dist/usage_snapshot.js +131 -0
- package/dist/utils/assistant_message.d.ts +2 -0
- package/dist/utils/assistant_message.js +5 -0
- package/dist/utils/atomic_write.d.ts +6 -2
- package/dist/utils/atomic_write.js +29 -4
- package/dist/utils/checked_shell.d.ts +25 -0
- package/dist/utils/checked_shell.js +107 -0
- package/dist/utils/compaction.d.ts +4 -1
- package/dist/utils/compaction.js +31 -7
- package/dist/utils/context.d.ts +4 -4
- package/dist/utils/context.js +14 -12
- package/dist/utils/deepseek.d.ts +2 -2
- package/dist/utils/deepseek.js +13 -5
- package/dist/utils/ephemeral.js +4 -0
- package/dist/utils/ephemeral_tools.d.ts +18 -0
- package/dist/utils/ephemeral_tools.js +97 -0
- package/dist/utils/jev_client.d.ts +4 -0
- package/dist/utils/jev_client.js +15 -0
- package/dist/utils/model_cache.d.ts +15 -0
- package/dist/utils/model_cache.js +143 -0
- package/dist/utils/models.d.ts +4 -2
- package/dist/utils/models.js +12 -16
- package/dist/utils/reasoning.d.ts +8 -1
- package/dist/utils/reasoning.js +31 -11
- package/dist/utils/router_catalog.d.ts +49 -0
- package/dist/utils/router_catalog.js +271 -0
- package/dist/utils/sandbox.d.ts +9 -0
- package/dist/utils/sandbox.js +118 -15
- package/dist/utils/shell.d.ts +7 -0
- package/dist/utils/shell.js +98 -34
- package/dist/utils/subprocess_env.d.ts +3 -0
- package/dist/utils/subprocess_env.js +27 -1
- package/dist/web/accounts_mirror.d.ts +3 -1
- package/dist/web/accounts_mirror.js +13 -9
- package/dist/web/child_publication.d.ts +17 -0
- package/dist/web/child_publication.js +45 -0
- package/dist/web/mirror_authenticator.d.ts +31 -11
- package/dist/web/mirror_authenticator.js +67 -17
- package/dist/web/mirror_client.d.ts +31 -4
- package/dist/web/mirror_client.js +189 -23
- package/dist/web/mirror_stream.d.ts +84 -22
- package/dist/web/mirror_stream.js +676 -95
- package/dist/web/observer_query_redaction.d.ts +6 -0
- package/dist/web/observer_query_redaction.js +58 -0
- package/dist/web/pane_registry.d.ts +2 -0
- package/dist/web/pane_registry.js +86 -22
- package/dist/web/tool_image.d.ts +6 -0
- package/dist/web/tool_image.js +17 -0
- package/dist/web/view_plugin.d.ts +14 -0
- package/dist/web/view_plugin.js +23 -1
- package/dist/worker/executor.js +31 -12
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/toolsets.js +3 -1
- package/dist/worker/types.d.ts +12 -1
- package/dist/workflows/registry.js +1 -0
- package/dist/workflows/registry_handle.d.ts +2 -0
- package/dist/workflows/runtime.d.ts +2 -0
- package/dist/workflows/runtime.js +1 -0
- package/dist/workspace_agent.d.ts +7 -0
- package/dist/workspace_agent.js +36 -0
- package/dist/workspace_collision.d.ts +76 -0
- package/dist/workspace_collision.js +688 -0
- package/dist/workspace_layout.d.ts +18 -0
- package/dist/workspace_layout.js +121 -0
- package/dist/workspace_runtime.d.ts +44 -0
- package/dist/workspace_runtime.js +82 -0
- package/dist/workspace_session_context.d.ts +62 -0
- package/dist/workspace_session_context.js +160 -0
- package/dist/zlm-embed.mjs +32518 -9615
- package/dist/zlm.js +1 -0
- package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
- package/node_modules/@zerg/model-contracts/README.md +90 -0
- package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
- package/node_modules/@zerg/model-contracts/index.js +223 -0
- package/node_modules/@zerg/model-contracts/package.json +8 -0
- package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
- package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
- package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
- package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
- package/package.json +45 -24
- package/packages/model-contracts/LICENSE.md +375 -0
- package/packages/model-contracts/README.md +90 -0
- package/packages/model-contracts/index.d.ts +20 -0
- package/packages/model-contracts/index.js +223 -0
- package/packages/model-contracts/package.json +8 -0
- package/remote-broker/Dockerfile +10 -0
- package/remote-broker/README.md +308 -0
- package/remote-broker/archive.py +1227 -0
- package/remote-broker/cutover.py +761 -0
- package/remote-broker/requirements.txt +5 -0
- package/remote-broker/resources.example.json +6 -0
- package/remote-broker/resources.write-staging.example.json +18 -0
- package/remote-broker/retained.py +686 -0
- package/remote-broker/retained_cleanup.py +550 -0
- package/remote-broker/server.py +648 -0
- package/scripts/build-remote-broker.mjs +13 -0
- package/scripts/ensure-local-packages.mjs +6 -0
- package/scripts/node-pty-helpers.mjs +103 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** Private adapter from the public simulation plugin contract to the ZTC kernel. */
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { CODEX_REASONING_EFFORTS } from '../config/types.js';
|
|
2
4
|
import { SIMULATION_PLUGIN_API_VERSION } from '../plugin/simulation_contract.js';
|
|
3
5
|
import { llmComplete, SimulationAbortedError } from './llm.js';
|
|
4
6
|
import { getOrchestrator, registerOrchestrator, } from './orchestration/registry.js';
|
|
@@ -6,17 +8,28 @@ import { registerSimulationRuntimeBinding } from './runtime_bindings.js';
|
|
|
6
8
|
import { DEFAULT_SIM_CONFIG } from './types.js';
|
|
7
9
|
import { SIMULATION_CHECKPOINT_VERSION, } from './world/checkpoint.js';
|
|
8
10
|
import { SimState, getSimState, setSimState } from './world/state.js';
|
|
11
|
+
import { validateDocumentWrite, validateSessionDocuments } from './session_documents.js';
|
|
9
12
|
import { getVersion } from '../utils/version.js';
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
const dynamicStateToolkit = () => require('./toolkit/dynamic_state.js');
|
|
15
|
+
const inputValidation = () => require('./session_input_validation.js');
|
|
10
16
|
const HOST_VERSION = getVersion();
|
|
11
17
|
const HOST_CHECKPOINT_NAMESPACE = 'ztc.host';
|
|
12
18
|
const HOST_CAPABILITIES = Object.freeze([
|
|
13
19
|
'atomic-transitions',
|
|
14
20
|
'checkpoint-extensions',
|
|
21
|
+
'dynamic-state',
|
|
15
22
|
'notifications',
|
|
23
|
+
'per-request-inference-routing',
|
|
24
|
+
'player-commands',
|
|
16
25
|
'provider-inference',
|
|
26
|
+
'simulation-catalog',
|
|
17
27
|
]);
|
|
18
28
|
const MAX_RETAINED_SESSIONS = 32;
|
|
29
|
+
const MAX_PLAYER_COMMAND_BYTES = 16_384;
|
|
30
|
+
const MAX_PLAYER_COMMAND_IDS = 256;
|
|
19
31
|
const registrations = new Map();
|
|
32
|
+
const definitions = new Map();
|
|
20
33
|
const sessions = new Map();
|
|
21
34
|
const activeDrivers = new Map();
|
|
22
35
|
const startSignals = new Map();
|
|
@@ -89,6 +102,83 @@ function assertCreateRequest(request) {
|
|
|
89
102
|
throw new Error('Simulation startTime must be an ISO date');
|
|
90
103
|
}
|
|
91
104
|
}
|
|
105
|
+
function assertNonEmptyBoundedString(name, value, maximum) {
|
|
106
|
+
const length = value.trim().length;
|
|
107
|
+
if (length === 0 || length > maximum) {
|
|
108
|
+
throw new RangeError(`${name} must contain from 1 to ${maximum} characters`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function assertDefinition(definition, kind, maximumTurns = 100) {
|
|
112
|
+
if (definition.kind !== kind) {
|
|
113
|
+
throw new Error(`Simulation definition kind ${definition.kind} must match driver ${kind}`);
|
|
114
|
+
}
|
|
115
|
+
assertNonEmptyBoundedString('Simulation definition title', definition.title, 80);
|
|
116
|
+
assertNonEmptyBoundedString('Simulation definition summary', definition.summary, 400);
|
|
117
|
+
assertNonEmptyBoundedString('Simulation definition objective', definition.objective, 400);
|
|
118
|
+
if (!Number.isSafeInteger(definition.maxTurns) || definition.maxTurns < 1 || definition.maxTurns > maximumTurns) {
|
|
119
|
+
throw new RangeError(`Simulation definition maxTurns must be an integer from 1 to ${maximumTurns}`);
|
|
120
|
+
}
|
|
121
|
+
if (!Number.isSafeInteger(definition.estimatedMinutes)
|
|
122
|
+
|| definition.estimatedMinutes < 1
|
|
123
|
+
|| definition.estimatedMinutes > 1_440) {
|
|
124
|
+
throw new RangeError('Simulation definition estimatedMinutes must be an integer from 1 to 1440');
|
|
125
|
+
}
|
|
126
|
+
for (const [name, values, maximum] of [
|
|
127
|
+
['playerRoles', definition.playerRoles, 16],
|
|
128
|
+
['mechanics', definition.mechanics, 64],
|
|
129
|
+
]) {
|
|
130
|
+
if (values.length === 0 || values.length > maximum) {
|
|
131
|
+
throw new RangeError(`Simulation definition ${name} must contain from 1 to ${maximum} values`);
|
|
132
|
+
}
|
|
133
|
+
for (const value of values) {
|
|
134
|
+
assertNonEmptyBoundedString(`Simulation definition ${name} value`, value, 80);
|
|
135
|
+
}
|
|
136
|
+
if (new Set(values).size !== values.length) {
|
|
137
|
+
throw new Error(`Simulation definition ${name} must not contain duplicates`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function cloneDefinition(definition) {
|
|
142
|
+
return {
|
|
143
|
+
...definition,
|
|
144
|
+
playerRoles: [...definition.playerRoles],
|
|
145
|
+
mechanics: [...definition.mechanics],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function parsePlayerCommand(value) {
|
|
149
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
150
|
+
throw new TypeError('Simulation player command must be an object');
|
|
151
|
+
}
|
|
152
|
+
const candidate = value;
|
|
153
|
+
if (typeof candidate.commandId !== 'string') {
|
|
154
|
+
throw new TypeError('Simulation player command commandId must be a string');
|
|
155
|
+
}
|
|
156
|
+
if (typeof candidate.kind !== 'string') {
|
|
157
|
+
throw new TypeError('Simulation player command kind must be a string');
|
|
158
|
+
}
|
|
159
|
+
assertNonEmptyBoundedString('Simulation player command commandId', candidate.commandId, 200);
|
|
160
|
+
assertNonEmptyBoundedString('Simulation player command kind', candidate.kind, 120);
|
|
161
|
+
if (candidate.actorId !== undefined
|
|
162
|
+
&& (typeof candidate.actorId !== 'string' || candidate.actorId.trim().length === 0)) {
|
|
163
|
+
throw new TypeError('Simulation player command actorId must be a non-empty string');
|
|
164
|
+
}
|
|
165
|
+
if (candidate.payload === null
|
|
166
|
+
|| typeof candidate.payload !== 'object'
|
|
167
|
+
|| Array.isArray(candidate.payload)) {
|
|
168
|
+
throw new TypeError('Simulation player command payload must be an object');
|
|
169
|
+
}
|
|
170
|
+
const serialized = JSON.stringify(candidate);
|
|
171
|
+
if (serialized === undefined || Buffer.byteLength(serialized, 'utf8') > MAX_PLAYER_COMMAND_BYTES) {
|
|
172
|
+
throw new RangeError(`Simulation player command must be at most ${MAX_PLAYER_COMMAND_BYTES} bytes`);
|
|
173
|
+
}
|
|
174
|
+
const parsed = JSON.parse(serialized);
|
|
175
|
+
return {
|
|
176
|
+
commandId: parsed.commandId,
|
|
177
|
+
kind: parsed.kind,
|
|
178
|
+
...(parsed.actorId === undefined ? {} : { actorId: parsed.actorId }),
|
|
179
|
+
payload: parsed.payload,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
92
182
|
function driverKindForState(state) {
|
|
93
183
|
return state.config.runtimeBinding?.kind ?? state.config.orchestration ?? 'gamemaster';
|
|
94
184
|
}
|
|
@@ -98,9 +188,28 @@ function makeSessionRecord(state, requestedDriverKind) {
|
|
|
98
188
|
const restoredPluginData = hostExtension?.data.pluginData;
|
|
99
189
|
const restoredRevision = hostExtension?.data.revision;
|
|
100
190
|
const restoredActorMetadata = hostExtension?.data.actorMetadata;
|
|
101
|
-
|
|
191
|
+
const restoredPlayerCommandIds = hostExtension?.data.submittedPlayerCommandIds;
|
|
192
|
+
const restoredPendingPlayerCommand = hostExtension?.data.pendingPlayerCommand;
|
|
193
|
+
const restoredDynamicState = hostExtension?.data.dynamicState;
|
|
194
|
+
const driverKind = requestedDriverKind ?? driverKindForState(state);
|
|
195
|
+
const revision = typeof restoredRevision === 'number'
|
|
196
|
+
&& Number.isSafeInteger(restoredRevision)
|
|
197
|
+
&& restoredRevision >= 0
|
|
198
|
+
? restoredRevision
|
|
199
|
+
: 0;
|
|
200
|
+
const dynamicState = restoredDynamicState === undefined || restoredDynamicState === null
|
|
201
|
+
? null
|
|
202
|
+
: dynamicStateToolkit().parseDynamicSimulationState(restoredDynamicState);
|
|
203
|
+
if (dynamicState !== null
|
|
204
|
+
&& (dynamicState.gameKind !== driverKind || dynamicState.revision !== revision)) {
|
|
205
|
+
throw new Error('Checkpoint dynamic state does not match its host revision or driver');
|
|
206
|
+
}
|
|
207
|
+
validateRegisteredDynamicState(dynamicState, driverKind);
|
|
208
|
+
const record = {
|
|
102
209
|
state,
|
|
103
|
-
|
|
210
|
+
inputJournal: hostExtension?.data.inputJournal === undefined ? undefined : inputValidation().parseInputJournal(hostExtension.data.inputJournal),
|
|
211
|
+
lastTransition: null,
|
|
212
|
+
driverKind,
|
|
104
213
|
appliedTransitions: new Set(Array.isArray(restoredIds)
|
|
105
214
|
? restoredIds.filter((value) => typeof value === 'string')
|
|
106
215
|
: []),
|
|
@@ -110,18 +219,30 @@ function makeSessionRecord(state, requestedDriverKind) {
|
|
|
110
219
|
? Object.entries(restoredActorMetadata)
|
|
111
220
|
.filter((entry) => (entry[1] !== null && typeof entry[1] === 'object' && !Array.isArray(entry[1])))
|
|
112
221
|
: []),
|
|
222
|
+
submittedPlayerCommandIds: new Set(Array.isArray(restoredPlayerCommandIds)
|
|
223
|
+
? restoredPlayerCommandIds
|
|
224
|
+
.filter((value) => typeof value === 'string')
|
|
225
|
+
.slice(-MAX_PLAYER_COMMAND_IDS)
|
|
226
|
+
: []),
|
|
227
|
+
pendingPlayerCommand: restoredPendingPlayerCommand === undefined
|
|
228
|
+
|| restoredPendingPlayerCommand === null
|
|
229
|
+
? null
|
|
230
|
+
: parsePlayerCommand(restoredPendingPlayerCommand),
|
|
231
|
+
dynamicState,
|
|
113
232
|
pluginData: restoredPluginData !== null
|
|
114
233
|
&& typeof restoredPluginData === 'object'
|
|
115
234
|
&& !Array.isArray(restoredPluginData)
|
|
116
235
|
? structuredClone(restoredPluginData)
|
|
117
236
|
: {},
|
|
118
237
|
status: 'ready',
|
|
119
|
-
revision
|
|
120
|
-
&& Number.isSafeInteger(restoredRevision)
|
|
121
|
-
&& restoredRevision >= 0
|
|
122
|
-
? restoredRevision
|
|
123
|
-
: 0,
|
|
238
|
+
revision,
|
|
124
239
|
};
|
|
240
|
+
if (record.inputJournal)
|
|
241
|
+
inputValidation().validateSessionInputSnapshot(toSnapshot(record));
|
|
242
|
+
else
|
|
243
|
+
validateSessionDocuments(toSnapshot(record));
|
|
244
|
+
validateRegisteredDocuments(record);
|
|
245
|
+
return record;
|
|
125
246
|
}
|
|
126
247
|
function ensureSessionRecord(state, requestedDriverKind) {
|
|
127
248
|
const existing = sessions.get(state.id);
|
|
@@ -149,6 +270,8 @@ function requireSessionRecord(ref) {
|
|
|
149
270
|
}
|
|
150
271
|
function toDocumentSnapshot(document) {
|
|
151
272
|
return {
|
|
273
|
+
...(document.provenance === undefined ? {} : { provenance: structuredClone(document.provenance) }),
|
|
274
|
+
...(document.ownerActorId === undefined ? {} : { ownerActorId: document.ownerActorId }),
|
|
152
275
|
documentId: document.id,
|
|
153
276
|
label: document.label,
|
|
154
277
|
type: document.type,
|
|
@@ -185,6 +308,7 @@ function toSnapshot(record) {
|
|
|
185
308
|
})
|
|
186
309
|
: null;
|
|
187
310
|
return {
|
|
311
|
+
...(record.inputJournal === undefined ? {} : { inputJournal: structuredClone(record.inputJournal) }),
|
|
188
312
|
ref: sessionRef(record),
|
|
189
313
|
status: record.status,
|
|
190
314
|
revision: record.revision,
|
|
@@ -203,6 +327,9 @@ function toSnapshot(record) {
|
|
|
203
327
|
})),
|
|
204
328
|
documents: state.getDocumentTrail().map(toDocumentSnapshot),
|
|
205
329
|
world,
|
|
330
|
+
dynamicState: record.dynamicState === null
|
|
331
|
+
? null
|
|
332
|
+
: structuredClone(record.dynamicState),
|
|
206
333
|
pluginData: asJsonObject(record.pluginData),
|
|
207
334
|
};
|
|
208
335
|
}
|
|
@@ -279,7 +406,11 @@ function applyOperation(record, operation) {
|
|
|
279
406
|
});
|
|
280
407
|
return;
|
|
281
408
|
case 'document.write':
|
|
409
|
+
if (operation.ownerActorId !== undefined)
|
|
410
|
+
validateDocumentWrite(toSnapshot(record), operation);
|
|
282
411
|
record.state.addDocument({
|
|
412
|
+
...(operation.provenance === undefined ? {} : { provenance: structuredClone(operation.provenance) }),
|
|
413
|
+
...(operation.ownerActorId === undefined ? {} : { ownerActorId: operation.ownerActorId }),
|
|
283
414
|
type: operation.documentType,
|
|
284
415
|
label: operation.label,
|
|
285
416
|
content: operation.content,
|
|
@@ -289,6 +420,11 @@ function applyOperation(record, operation) {
|
|
|
289
420
|
revisionOf: operation.revisionOf,
|
|
290
421
|
});
|
|
291
422
|
return;
|
|
423
|
+
case 'session-inputs.resolve':
|
|
424
|
+
if (!record.inputJournal)
|
|
425
|
+
throw new Error('Session inputs are unavailable');
|
|
426
|
+
record.inputJournal.resolutions.push(...structuredClone(operation.resolutions));
|
|
427
|
+
return;
|
|
292
428
|
case 'document.comment': {
|
|
293
429
|
const result = record.state.addDocumentComment(operation.label, operation.author, operation.text, operation.authorActorId, operation.parentId, operation.sectionRef);
|
|
294
430
|
if (!result.ok) {
|
|
@@ -298,10 +434,51 @@ function applyOperation(record, operation) {
|
|
|
298
434
|
}
|
|
299
435
|
case 'plugin-data.set':
|
|
300
436
|
record.pluginData[operation.namespace] = asJsonObject(operation.value);
|
|
437
|
+
return;
|
|
438
|
+
case 'dynamic-state.commit': {
|
|
439
|
+
const next = dynamicStateToolkit().validateDynamicStateTransition({
|
|
440
|
+
previous: record.dynamicState,
|
|
441
|
+
next: operation.state,
|
|
442
|
+
driverKind: record.driverKind,
|
|
443
|
+
hostRevision: record.revision,
|
|
444
|
+
});
|
|
445
|
+
validateRegisteredDynamicState(next, record.driverKind);
|
|
446
|
+
if (next.history.at(-1)?.objectGraphBefore === undefined) {
|
|
447
|
+
throw new Error('A new dynamic state commit requires action-time context');
|
|
448
|
+
}
|
|
449
|
+
record.dynamicState = next;
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
301
452
|
}
|
|
302
453
|
}
|
|
303
|
-
|
|
454
|
+
const detachedValidators = new Map();
|
|
455
|
+
/** Register canonical checkpoint validators without loading a driver or claiming its inference boundary. */
|
|
456
|
+
export function registerSimulationCheckpointValidators(kind, validators) {
|
|
457
|
+
if (!kind.trim() || !validators.validateDynamicState || !validators.validateDocuments)
|
|
458
|
+
throw new Error('Checkpoint validators require a kind and both canonical validators');
|
|
459
|
+
detachedValidators.set(kind, validators);
|
|
460
|
+
}
|
|
461
|
+
function validateRegisteredDynamicState(state, driverKind) {
|
|
462
|
+
if (state === null)
|
|
463
|
+
return;
|
|
464
|
+
const validate = registrations.get(driverKind)?.validateDynamicState ?? detachedValidators.get(driverKind)?.validateDynamicState;
|
|
465
|
+
if (validate === undefined && state.initialization === null)
|
|
466
|
+
return;
|
|
467
|
+
if (validate === undefined)
|
|
468
|
+
throw new Error('Dynamic policy validator is unavailable');
|
|
469
|
+
validate(state);
|
|
470
|
+
}
|
|
471
|
+
function validateRegisteredDocuments(record) {
|
|
472
|
+
const validate = registrations.get(record.driverKind)?.validateDocuments ?? detachedValidators.get(record.driverKind)?.validateDocuments;
|
|
473
|
+
const initialization = record.dynamicState?.initialization;
|
|
474
|
+
if (initialization?.version === 2 && initialization.documents && !validate) {
|
|
475
|
+
throw new Error('Document policy validator is unavailable');
|
|
476
|
+
}
|
|
477
|
+
validate?.(toSnapshot(record));
|
|
478
|
+
}
|
|
479
|
+
function restoreTransitionMetadata(record, pluginData, dynamicState, revision, appliedTransitions) {
|
|
304
480
|
record.pluginData = pluginData;
|
|
481
|
+
record.dynamicState = dynamicState;
|
|
305
482
|
record.revision = revision;
|
|
306
483
|
record.appliedTransitions.clear();
|
|
307
484
|
for (const key of appliedTransitions)
|
|
@@ -314,26 +491,48 @@ async function applyTransition(record, batch) {
|
|
|
314
491
|
if (batch.expectedRevision !== record.revision) {
|
|
315
492
|
throw new Error(`Simulation transition expected revision ${batch.expectedRevision}; current revision is ${record.revision}`);
|
|
316
493
|
}
|
|
494
|
+
if (record.inputJournal || batch.operations.some(operation => operation.operation === 'session-inputs.resolve')) {
|
|
495
|
+
inputValidation().validateInputTransition(toSnapshot(record), batch);
|
|
496
|
+
}
|
|
497
|
+
const advanceTimeSteps = batch.advanceTimeSteps ?? 1;
|
|
498
|
+
if (!Number.isSafeInteger(advanceTimeSteps) || advanceTimeSteps < 1 || advanceTimeSteps > 12) {
|
|
499
|
+
throw new RangeError('Simulation advanceTimeSteps must be an integer from 1 to 12');
|
|
500
|
+
}
|
|
501
|
+
const dynamicCommits = batch.operations.filter(operation => (operation.operation === 'dynamic-state.commit')).length;
|
|
502
|
+
if ((record.dynamicState !== null || dynamicCommits > 0) && dynamicCommits !== 1) {
|
|
503
|
+
throw new Error('A dynamic transition must contain exactly one dynamic state commit');
|
|
504
|
+
}
|
|
317
505
|
const joinedPeriod = record.state.getActiveWorldTransitionPeriodNumber();
|
|
318
506
|
if (joinedPeriod !== null) {
|
|
319
507
|
if (batch.periodNumber !== undefined && batch.periodNumber !== joinedPeriod) {
|
|
320
508
|
throw new Error(`Simulation transition period ${batch.periodNumber} does not match active world period ${joinedPeriod}`);
|
|
321
509
|
}
|
|
510
|
+
const inputsBefore = structuredClone(record.inputJournal);
|
|
511
|
+
const lastTransitionBefore = record.lastTransition;
|
|
322
512
|
const pluginDataBefore = structuredClone(record.pluginData);
|
|
513
|
+
const dynamicStateBefore = record.dynamicState === null
|
|
514
|
+
? null
|
|
515
|
+
: structuredClone(record.dynamicState);
|
|
323
516
|
const revisionBefore = record.revision;
|
|
324
517
|
const appliedTransitionsBefore = new Set(record.appliedTransitions);
|
|
325
518
|
try {
|
|
326
519
|
for (const operation of batch.operations)
|
|
327
520
|
applyOperation(record, operation);
|
|
521
|
+
validateRegisteredDocuments(record);
|
|
328
522
|
record.revision += 1;
|
|
329
523
|
record.appliedTransitions.add(batch.idempotencyKey);
|
|
524
|
+
record.lastTransition = structuredClone(batch);
|
|
330
525
|
record.state.registerWorldTransitionRollback(() => {
|
|
331
|
-
|
|
526
|
+
record.inputJournal = inputsBefore;
|
|
527
|
+
record.lastTransition = lastTransitionBefore;
|
|
528
|
+
restoreTransitionMetadata(record, pluginDataBefore, dynamicStateBefore, revisionBefore, appliedTransitionsBefore);
|
|
332
529
|
});
|
|
333
530
|
return { applied: true, revision: record.revision };
|
|
334
531
|
}
|
|
335
532
|
catch (error) {
|
|
336
|
-
|
|
533
|
+
record.inputJournal = inputsBefore;
|
|
534
|
+
record.lastTransition = lastTransitionBefore;
|
|
535
|
+
restoreTransitionMetadata(record, pluginDataBefore, dynamicStateBefore, revisionBefore, appliedTransitionsBefore);
|
|
337
536
|
throw error;
|
|
338
537
|
}
|
|
339
538
|
}
|
|
@@ -345,21 +544,31 @@ async function applyTransition(record, batch) {
|
|
|
345
544
|
}
|
|
346
545
|
}
|
|
347
546
|
const pluginDataBefore = structuredClone(record.pluginData);
|
|
547
|
+
const inputJournalBefore = structuredClone(record.inputJournal);
|
|
548
|
+
const dynamicStateBefore = record.dynamicState === null
|
|
549
|
+
? null
|
|
550
|
+
: structuredClone(record.dynamicState);
|
|
348
551
|
const proposal = record.state.beginWorldTransition(batch.kind, batch.periodNumber);
|
|
349
552
|
try {
|
|
350
553
|
if (batch.periodNumber !== undefined) {
|
|
351
554
|
record.state.setRuntimePeriodNumber(batch.periodNumber);
|
|
352
|
-
|
|
555
|
+
for (let step = 0; step < advanceTimeSteps; step += 1) {
|
|
556
|
+
record.state.advanceTime();
|
|
557
|
+
}
|
|
353
558
|
}
|
|
354
559
|
for (const operation of batch.operations)
|
|
355
560
|
applyOperation(record, operation);
|
|
561
|
+
validateRegisteredDocuments(record);
|
|
356
562
|
record.state.commitWorldTransition(proposal.id);
|
|
357
563
|
record.revision += 1;
|
|
358
564
|
record.appliedTransitions.add(batch.idempotencyKey);
|
|
565
|
+
record.lastTransition = structuredClone(batch);
|
|
359
566
|
return { applied: true, revision: record.revision };
|
|
360
567
|
}
|
|
361
568
|
catch (error) {
|
|
569
|
+
record.inputJournal = inputJournalBefore;
|
|
362
570
|
record.pluginData = pluginDataBefore;
|
|
571
|
+
record.dynamicState = dynamicStateBefore;
|
|
363
572
|
record.state.rollbackWorldTransition(proposal.id, error);
|
|
364
573
|
if (previousPeriod === null)
|
|
365
574
|
record.state.clearRuntimePeriodNumber();
|
|
@@ -386,9 +595,33 @@ function hostCheckpointExtension(record) {
|
|
|
386
595
|
appliedTransitionIds: [...record.appliedTransitions].sort(),
|
|
387
596
|
pluginData: record.pluginData,
|
|
388
597
|
actorMetadata: Object.fromEntries(record.actorMetadata),
|
|
598
|
+
submittedPlayerCommandIds: [...record.submittedPlayerCommandIds].sort(),
|
|
599
|
+
pendingPlayerCommand: record.pendingPlayerCommand === null
|
|
600
|
+
? null
|
|
601
|
+
: asJsonObject(record.pendingPlayerCommand),
|
|
602
|
+
dynamicState: record.dynamicState === null
|
|
603
|
+
? null
|
|
604
|
+
: asJsonObject(record.dynamicState),
|
|
605
|
+
...(record.inputJournal === undefined ? {} : { inputJournal: asJsonObject(record.inputJournal) }),
|
|
389
606
|
},
|
|
390
607
|
};
|
|
391
608
|
}
|
|
609
|
+
export async function detachedSessionRecord(checkpoint) {
|
|
610
|
+
return makeSessionRecord(await SimState.fromCheckpoint(structuredClone(checkpoint), undefined, true));
|
|
611
|
+
}
|
|
612
|
+
export function detachedSessionSnapshot(record) {
|
|
613
|
+
return toSnapshot(record);
|
|
614
|
+
}
|
|
615
|
+
export function detachedSessionCheckpoint(record, source) {
|
|
616
|
+
const extensions = source.extensions;
|
|
617
|
+
return asJsonObject(record.state.createCheckpoint({ ...extensions, [HOST_CHECKPOINT_NAMESPACE]: hostCheckpointExtension(record) }));
|
|
618
|
+
}
|
|
619
|
+
export async function applyDetachedSessionTransition(record, batch) {
|
|
620
|
+
await applyTransition(record, batch);
|
|
621
|
+
}
|
|
622
|
+
export function getOriginalSessionTransition(ref) {
|
|
623
|
+
return structuredClone(requireSessionRecord(ref).lastTransition);
|
|
624
|
+
}
|
|
392
625
|
export function saveSimulationSessionCheckpoint(state, outputPath) {
|
|
393
626
|
const record = ensureSessionRecord(state);
|
|
394
627
|
return state.saveCheckpoint(outputPath, {
|
|
@@ -432,7 +665,7 @@ async function loadRegisteredDriver(kind) {
|
|
|
432
665
|
}
|
|
433
666
|
return driver;
|
|
434
667
|
}
|
|
435
|
-
function createDriverContext(record, controller, notify) {
|
|
668
|
+
function createDriverContext(record, controller, notify, playerCommand = null) {
|
|
436
669
|
const requireActiveAuthority = () => {
|
|
437
670
|
const active = activeDrivers.get(record.state.id);
|
|
438
671
|
if (record.status !== 'running'
|
|
@@ -449,6 +682,7 @@ function createDriverContext(record, controller, notify) {
|
|
|
449
682
|
return applyTransition(record, batch);
|
|
450
683
|
},
|
|
451
684
|
},
|
|
685
|
+
playerCommand: playerCommand === null ? null : parsePlayerCommand(playerCommand),
|
|
452
686
|
signal: controller.signal,
|
|
453
687
|
notify,
|
|
454
688
|
completeInference: (request) => {
|
|
@@ -458,6 +692,14 @@ function createDriverContext(record, controller, notify) {
|
|
|
458
692
|
};
|
|
459
693
|
}
|
|
460
694
|
async function completeInference(request, signal) {
|
|
695
|
+
const routing = request.routing;
|
|
696
|
+
if (routing !== undefined && (routing === null || typeof routing !== 'object'
|
|
697
|
+
|| !['character', 'game-master'].includes(routing.role)
|
|
698
|
+
|| typeof routing.provider !== 'string' || !routing.provider.trim()
|
|
699
|
+
|| typeof routing.model !== 'string' || !routing.model.trim()
|
|
700
|
+
|| !CODEX_REASONING_EFFORTS.includes(routing.reasoningEffort)
|
|
701
|
+
|| (routing.serviceTier !== undefined && routing.serviceTier !== 'priority')))
|
|
702
|
+
throw new Error('Invalid simulation inference route');
|
|
461
703
|
const text = await llmComplete(request.system, request.user, request.maxTokens, request.timeoutMs, {
|
|
462
704
|
stage: request.context.stage,
|
|
463
705
|
periodNumber: request.context.periodNumber,
|
|
@@ -466,7 +708,14 @@ async function completeInference(request, signal) {
|
|
|
466
708
|
requestId: request.context.requestId,
|
|
467
709
|
component: request.context.component,
|
|
468
710
|
attempt: request.context.attempt,
|
|
469
|
-
}, signal
|
|
711
|
+
}, signal, routing === undefined
|
|
712
|
+
? undefined
|
|
713
|
+
: {
|
|
714
|
+
provider: routing.provider,
|
|
715
|
+
model: routing.model,
|
|
716
|
+
codexEffort: routing.reasoningEffort,
|
|
717
|
+
codexFastMode: routing.serviceTier === 'priority',
|
|
718
|
+
}, undefined, request.outputSchema, request.outputSchemaStrict, request.bufferedRecovery === undefined ? undefined : { ...request.bufferedRecovery, onAttempt: request.onTransportAttempt });
|
|
470
719
|
return { text };
|
|
471
720
|
}
|
|
472
721
|
function pruneSessionRecords() {
|
|
@@ -501,7 +750,8 @@ async function makePrivateOrchestrator(kind) {
|
|
|
501
750
|
if (notification.type === 'progress')
|
|
502
751
|
onProgress(notification.message);
|
|
503
752
|
};
|
|
504
|
-
const
|
|
753
|
+
const playerCommand = record.pendingPlayerCommand;
|
|
754
|
+
const context = createDriverContext(record, controller, notify, playerCommand);
|
|
505
755
|
if (controller.signal.aborted) {
|
|
506
756
|
throw new SimulationAbortedError('Simulation stopped');
|
|
507
757
|
}
|
|
@@ -517,6 +767,10 @@ async function makePrivateOrchestrator(kind) {
|
|
|
517
767
|
if (controller.signal.aborted) {
|
|
518
768
|
throw new SimulationAbortedError('Simulation stopped');
|
|
519
769
|
}
|
|
770
|
+
if (playerCommand !== null
|
|
771
|
+
&& record.pendingPlayerCommand?.commandId === playerCommand.commandId) {
|
|
772
|
+
record.pendingPlayerCommand = null;
|
|
773
|
+
}
|
|
520
774
|
record.status = 'completed';
|
|
521
775
|
onComplete('Simulation completed');
|
|
522
776
|
}
|
|
@@ -548,6 +802,9 @@ export function validateSimulationDriverRegistration(registration) {
|
|
|
548
802
|
assertCompatibility(registration.compatibility);
|
|
549
803
|
if (!registration.kind.trim())
|
|
550
804
|
throw new Error('Simulation driver kind must not be empty');
|
|
805
|
+
if (registration.definition !== undefined) {
|
|
806
|
+
assertDefinition(registration.definition, registration.kind, registration.validateDynamicState === undefined ? 100 : Number.MAX_SAFE_INTEGER);
|
|
807
|
+
}
|
|
551
808
|
if (registrations.has(registration.kind) || getOrchestrator(registration.kind)) {
|
|
552
809
|
throw new Error(`Simulation driver ${registration.kind} is already registered`);
|
|
553
810
|
}
|
|
@@ -555,6 +812,9 @@ export function validateSimulationDriverRegistration(registration) {
|
|
|
555
812
|
export function registerSimulationDriver(registration) {
|
|
556
813
|
validateSimulationDriverRegistration(registration);
|
|
557
814
|
registrations.set(registration.kind, registration);
|
|
815
|
+
if (registration.definition !== undefined) {
|
|
816
|
+
definitions.set(registration.kind, cloneDefinition(registration.definition));
|
|
817
|
+
}
|
|
558
818
|
registerOrchestrator(registration.kind, () => makePrivateOrchestrator(registration.kind));
|
|
559
819
|
registerSimulationRuntimeBinding(registration.kind, {
|
|
560
820
|
rehydrate: async (state, context) => {
|
|
@@ -575,8 +835,21 @@ const simulationHost = {
|
|
|
575
835
|
checkpointSchemaVersions: [SIMULATION_CHECKPOINT_VERSION],
|
|
576
836
|
capabilities: HOST_CAPABILITIES,
|
|
577
837
|
},
|
|
838
|
+
listSimulationDefinitions() {
|
|
839
|
+
return [...definitions.values()]
|
|
840
|
+
.sort((left, right) => left.title.localeCompare(right.title))
|
|
841
|
+
.map(cloneDefinition);
|
|
842
|
+
},
|
|
578
843
|
async createSession(request) {
|
|
579
844
|
assertCreateRequest(request);
|
|
845
|
+
const requestedDynamicState = request.dynamicState === undefined
|
|
846
|
+
? null
|
|
847
|
+
: dynamicStateToolkit().parseDynamicSimulationState(request.dynamicState);
|
|
848
|
+
if (requestedDynamicState !== null
|
|
849
|
+
&& (requestedDynamicState.gameKind !== request.driverKind || requestedDynamicState.revision !== 0)) {
|
|
850
|
+
throw new Error('Initial dynamic state must match its driver at revision zero');
|
|
851
|
+
}
|
|
852
|
+
validateRegisteredDynamicState(requestedDynamicState, request.driverKind);
|
|
580
853
|
pruneSessionRecords();
|
|
581
854
|
if (!registrations.has(request.driverKind) && request.driverKind !== 'gamemaster') {
|
|
582
855
|
throw new Error(`Simulation driver ${request.driverKind} is not registered`);
|
|
@@ -613,18 +886,37 @@ const simulationHost = {
|
|
|
613
886
|
if (actor.metadata)
|
|
614
887
|
actorMetadata.set(created.id, structuredClone(actor.metadata));
|
|
615
888
|
}
|
|
616
|
-
|
|
617
|
-
const record = ensureSessionRecord(state, request.driverKind);
|
|
889
|
+
const record = makeSessionRecord(state, request.driverKind);
|
|
618
890
|
for (const [actorId, metadata] of actorMetadata) {
|
|
619
891
|
record.actorMetadata.set(actorId, metadata);
|
|
620
892
|
}
|
|
893
|
+
if (request.dynamicState !== undefined) {
|
|
894
|
+
record.dynamicState = requestedDynamicState;
|
|
895
|
+
}
|
|
621
896
|
if (request.pluginData)
|
|
622
897
|
record.pluginData.root = asJsonObject(request.pluginData);
|
|
898
|
+
try {
|
|
899
|
+
if (requestedDynamicState !== null) {
|
|
900
|
+
const documents = registrations.get(request.driverKind)?.initializeDocuments?.(requestedDynamicState) ?? [];
|
|
901
|
+
for (const document of documents)
|
|
902
|
+
applyOperation(record, document);
|
|
903
|
+
}
|
|
904
|
+
validateRegisteredDocuments(record);
|
|
905
|
+
}
|
|
906
|
+
catch (error) {
|
|
907
|
+
state.close();
|
|
908
|
+
throw error;
|
|
909
|
+
}
|
|
910
|
+
sessions.set(state.id, record);
|
|
911
|
+
setSimState(state);
|
|
623
912
|
return makeSession(record);
|
|
624
913
|
},
|
|
625
914
|
async loadSession(request) {
|
|
626
915
|
pruneSessionRecords();
|
|
627
|
-
|
|
916
|
+
if (request.outputDirectory !== undefined && request.outputDirectory.trim() === '') {
|
|
917
|
+
throw new Error('Simulation output directory cannot be empty');
|
|
918
|
+
}
|
|
919
|
+
const state = await SimState.loadCheckpoint(request.checkpointPath, request.outputDirectory);
|
|
628
920
|
try {
|
|
629
921
|
const checkpointDriverKind = driverKindForState(state);
|
|
630
922
|
if (request.driverKind !== undefined && request.driverKind !== checkpointDriverKind) {
|
|
@@ -656,6 +948,31 @@ const simulationHost = {
|
|
|
656
948
|
const record = sessions.get(ref.sessionId);
|
|
657
949
|
return record && record.driverKind === ref.driverKind ? makeSession(record) : null;
|
|
658
950
|
},
|
|
951
|
+
async submitPlayerCommand(ref, command) {
|
|
952
|
+
const record = requireSessionRecord(ref);
|
|
953
|
+
if (sessionRuns.has(record.state.id) || ['running', 'stopping'].includes(record.status)) {
|
|
954
|
+
throw new Error(`Simulation session ${record.state.id} cannot accept a command while running`);
|
|
955
|
+
}
|
|
956
|
+
const parsed = parsePlayerCommand(command);
|
|
957
|
+
if (record.submittedPlayerCommandIds.has(parsed.commandId)) {
|
|
958
|
+
return { accepted: false };
|
|
959
|
+
}
|
|
960
|
+
if (record.pendingPlayerCommand !== null) {
|
|
961
|
+
throw new Error(`Simulation session ${record.state.id} already has a pending player command`);
|
|
962
|
+
}
|
|
963
|
+
if (record.submittedPlayerCommandIds.size >= MAX_PLAYER_COMMAND_IDS) {
|
|
964
|
+
throw new Error(`Simulation session ${record.state.id} reached its ${MAX_PLAYER_COMMAND_IDS}-command bound`);
|
|
965
|
+
}
|
|
966
|
+
if (parsed.actorId !== undefined) {
|
|
967
|
+
const actor = record.state.getAllAgents().find(candidate => candidate.id === parsed.actorId);
|
|
968
|
+
if (actor?.humanControlled !== true) {
|
|
969
|
+
throw new Error(`Simulation player command actorId must name a human-controlled actor in session ${record.state.id}`);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
record.pendingPlayerCommand = parsed;
|
|
973
|
+
record.submittedPlayerCommandIds.add(parsed.commandId);
|
|
974
|
+
return { accepted: true };
|
|
975
|
+
},
|
|
659
976
|
async startSession(request) {
|
|
660
977
|
const record = requireSessionRecord(request.ref);
|
|
661
978
|
if (sessionRuns.has(record.state.id) || ['running', 'stopping'].includes(record.status)) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SimulationDocumentWriteV1, SimulationSessionSnapshotV1 } from '../plugin/simulation_contract.js';
|
|
2
|
+
import type { SimulationAuthorizedDocumentV1 } from '../plugin/simulation_interventions.js';
|
|
3
|
+
export declare class SimulationInputError extends Error {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
constructor(code: string, message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare const fail: (code: string, message: string) => never;
|
|
8
|
+
export declare function inputActorId(actor: SimulationSessionSnapshotV1['actors'][number]): string;
|
|
9
|
+
export declare function actors(snapshot: SimulationSessionSnapshotV1): {
|
|
10
|
+
actorId: string;
|
|
11
|
+
name: string;
|
|
12
|
+
role: string;
|
|
13
|
+
organization?: string;
|
|
14
|
+
humanControlled: boolean;
|
|
15
|
+
currentAction?: string;
|
|
16
|
+
metadata?: import("../plugin/simulation_contract.js").SimulationJsonObjectV1;
|
|
17
|
+
}[];
|
|
18
|
+
export declare function validateDocumentWrite(snapshot: SimulationSessionSnapshotV1, write: SimulationDocumentWriteV1): void;
|
|
19
|
+
export declare function sessionDocuments(snapshot: SimulationSessionSnapshotV1): SimulationAuthorizedDocumentV1[];
|
|
20
|
+
export declare function validateSessionDocuments(snapshot: SimulationSessionSnapshotV1): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
2
|
+
export class SimulationInputError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(code, message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.name = 'SimulationInputError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export const fail = (code, message) => { throw new SimulationInputError(code, message); };
|
|
11
|
+
export function inputActorId(actor) {
|
|
12
|
+
return typeof actor.metadata?.dynamicActorId === 'string' ? actor.metadata.dynamicActorId : actor.actorId;
|
|
13
|
+
}
|
|
14
|
+
export function actors(snapshot) { return snapshot.actors.map(actor => ({ ...actor, actorId: inputActorId(actor) })); }
|
|
15
|
+
export function validateDocumentWrite(snapshot, write) {
|
|
16
|
+
const roster = actors(snapshot);
|
|
17
|
+
if (!write.ownerActorId || !roster.some(actor => actor.actorId === write.ownerActorId)
|
|
18
|
+
|| !write.recipientActorIds.includes(write.ownerActorId) || new Set(write.recipientActorIds).size !== write.recipientActorIds.length
|
|
19
|
+
|| write.recipientActorIds.some(id => !roster.some(actor => actor.actorId === id)))
|
|
20
|
+
fail('recipient_invalid', 'Document owner and recipients must name the exact cast');
|
|
21
|
+
if (Buffer.byteLength(write.content, 'utf8') > 8192)
|
|
22
|
+
fail('body_too_large', 'Document exceeds its byte limit');
|
|
23
|
+
if (write.revisionOf) {
|
|
24
|
+
const prior = snapshot.documents.find(doc => doc.documentId === write.revisionOf);
|
|
25
|
+
if (!prior || snapshot.documents.some(doc => doc.revisionOf === prior.documentId)
|
|
26
|
+
|| prior.ownerActorId !== write.ownerActorId || !isDeepStrictEqual(prior.recipientActorIds, write.recipientActorIds))
|
|
27
|
+
fail('document_version_conflict', 'Document version or recipients changed');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function sessionDocuments(snapshot) {
|
|
31
|
+
const byId = new Map(snapshot.documents.map(doc => [doc.documentId, doc]));
|
|
32
|
+
return snapshot.documents.filter(doc => doc.ownerActorId !== undefined).map(doc => {
|
|
33
|
+
let root = doc;
|
|
34
|
+
let version = 1;
|
|
35
|
+
const seen = new Set([doc.documentId]);
|
|
36
|
+
while (root.revisionOf) {
|
|
37
|
+
const parent = byId.get(root.revisionOf);
|
|
38
|
+
if (!parent || seen.has(parent.documentId))
|
|
39
|
+
return fail('input_state_invalid', 'Document version chain is invalid');
|
|
40
|
+
seen.add(parent.documentId);
|
|
41
|
+
root = parent;
|
|
42
|
+
version += 1;
|
|
43
|
+
}
|
|
44
|
+
return { ...(doc.provenance === undefined ? {} : { provenance: structuredClone(doc.provenance) }), documentId: root.documentId, versionId: doc.documentId, version, ownerActorId: doc.ownerActorId, recipientActorIds: doc.recipientActorIds, body: doc.content, label: doc.label };
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function validateSessionDocuments(snapshot) {
|
|
48
|
+
sessionDocuments(snapshot);
|
|
49
|
+
for (const [index, doc] of snapshot.documents.entries()) {
|
|
50
|
+
if (doc.ownerActorId === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
try {
|
|
53
|
+
validateDocumentWrite({ ...snapshot, documents: snapshot.documents.slice(0, index) }, {
|
|
54
|
+
operation: 'document.write', ownerActorId: doc.ownerActorId, recipientActorIds: doc.recipientActorIds,
|
|
55
|
+
label: doc.label, documentType: doc.type, content: doc.content, createdBy: doc.createdBy, revisionOf: doc.revisionOf,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
fail('input_state_invalid', 'Session input references are invalid');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|