@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
package/dist/agent/subagent.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ZRouterStreamBackend } from './backends/zrouter_stream.js';
|
|
2
|
+
import { readRouterCatalog } from '../utils/router_catalog.js';
|
|
1
3
|
/**
|
|
2
4
|
* SubAgent - Isolated agent for context-heavy operations
|
|
3
5
|
*
|
|
@@ -9,6 +11,8 @@
|
|
|
9
11
|
* Only the final summary is returned to the main agent, keeping the main context clean.
|
|
10
12
|
*/
|
|
11
13
|
import { randomUUID } from 'node:crypto';
|
|
14
|
+
import { realpathSync } from 'node:fs';
|
|
15
|
+
import { getSessionPathForCwd, saveSessionToFile } from '../session.js';
|
|
12
16
|
import { getDefaultModel } from '../utils/models.js';
|
|
13
17
|
import { debugLog } from '../utils/debug_log.js';
|
|
14
18
|
import { createBackendForProvider } from './backends/index.js';
|
|
@@ -16,9 +20,16 @@ import { accountBackendOptions, resolveRotation } from './backends/account_pool.
|
|
|
16
20
|
import { buildAccountRotation, subagentShouldRotate } from './backends/rotation_factory.js';
|
|
17
21
|
import { describeExecutionContext, resolveExecutionSettings } from './runtime/execution_context.js';
|
|
18
22
|
import { createRecoveryGuard } from './runtime/recovery.js';
|
|
23
|
+
import { listCommandJobs, shutdownCommandJobs } from './runtime/command_jobs.js';
|
|
24
|
+
import { awaitManagedCommandProgress, formatManagedCommandObservations } from './runtime/command_wait.js';
|
|
19
25
|
import { scheduleToolBatch, commandStillRunning } from './runtime/tool_scheduler.js';
|
|
20
26
|
import { configStore } from '../config.js';
|
|
21
|
-
import {
|
|
27
|
+
import { RequestEncoder, nativeHistoryContextId } from './request_encoder.js';
|
|
28
|
+
import { ToolResponseIntegrityError, ToolResponseStore } from './tool_response_store.js';
|
|
29
|
+
import { formatEvidenceContext } from './runtime/evidence.js';
|
|
30
|
+
import { acquireDelegatedEvidenceWriter, bindDelegatedEvidence, createDelegatedEvidenceHandoff } from './runtime/delegated_evidence.js';
|
|
31
|
+
import { recallToolResponseTool } from './tools/recall_tool_response.js';
|
|
32
|
+
import { sessionEvidenceTool } from './tools/session_evidence.js';
|
|
22
33
|
import { RESEARCH_TOOLS } from '../worker/toolsets.js';
|
|
23
34
|
import { renderPrompt } from '../utils/template.js';
|
|
24
35
|
import { executeToolWithRuntime } from './runtime/tool_runtime.js';
|
|
@@ -44,6 +55,18 @@ function isToolUseBlock(block) {
|
|
|
44
55
|
function getSubAgentModel(provider, preferredModel) {
|
|
45
56
|
if (preferredModel)
|
|
46
57
|
return preferredModel;
|
|
58
|
+
if (configStore.resolveLLMBackendConfig({ provider }).useProxy) {
|
|
59
|
+
if (configStore.getProvider() === provider)
|
|
60
|
+
return configStore.getModel();
|
|
61
|
+
const catalog = configStore.getRouterCatalog();
|
|
62
|
+
const rows = catalog?.models.filter(row => row.owned_by === provider && (catalog.version === 0 || row.capabilities?.chat));
|
|
63
|
+
const selected = rows?.find(row => row.is_default) ?? rows?.[0];
|
|
64
|
+
if (selected)
|
|
65
|
+
return selected.id;
|
|
66
|
+
if (!configStore.getRouterCatalog() || configStore.getRouterCatalog()?.version === 0)
|
|
67
|
+
return getDefaultModel(provider, 'cheap');
|
|
68
|
+
throw new Error('Select a Router model for this subagent.');
|
|
69
|
+
}
|
|
47
70
|
return getDefaultModel(provider, 'cheap');
|
|
48
71
|
}
|
|
49
72
|
/**
|
|
@@ -57,6 +80,12 @@ function getSubAgentModel(provider, preferredModel) {
|
|
|
57
80
|
*/
|
|
58
81
|
function createBackend(provider, apiKey) {
|
|
59
82
|
const config = configStore.get();
|
|
83
|
+
const resolved = configStore.resolveLLMBackendConfig({ provider, apiKeyOverride: apiKey });
|
|
84
|
+
if (resolved.useProxy) {
|
|
85
|
+
return new ZRouterStreamBackend({ apiKey: resolved.authToken, proxyUrl: resolved.proxyUrl, provider,
|
|
86
|
+
workspaceId: configStore.getRouterCatalogConnection()?.workspaceId,
|
|
87
|
+
catalog: readRouterCatalog({ origin: resolved.proxyUrl, token: resolved.authToken, workspaceId: configStore.getRouterCatalogConnection()?.workspaceId }) });
|
|
88
|
+
}
|
|
60
89
|
const accountOpts = accountBackendOptions(config, provider);
|
|
61
90
|
const rotationOpts = subagentShouldRotate(resolveRotation(config))
|
|
62
91
|
? buildAccountRotation(config) ?? {}
|
|
@@ -85,23 +114,27 @@ export class SubAgent {
|
|
|
85
114
|
cwd;
|
|
86
115
|
inputTokens = 0;
|
|
87
116
|
outputTokens = 0;
|
|
88
|
-
//
|
|
89
|
-
// WRITE) don't include `tool_search` or `recall_tool_response`, but the
|
|
90
|
-
// ToolContext shape is required — and keeping these isolated guarantees a
|
|
91
|
-
// subagent's tool results never leak into the parent's session store.
|
|
117
|
+
// Exact results remain in the child's owned session, separate from the parent.
|
|
92
118
|
toolResponseStore = new ToolResponseStore();
|
|
119
|
+
sessionId;
|
|
93
120
|
discoveredTools = new Set();
|
|
94
121
|
hooks;
|
|
95
122
|
approvalRequester;
|
|
96
123
|
constructor(config) {
|
|
97
|
-
this.config = config;
|
|
124
|
+
this.config = { ...config, commandPolicy: config.commandPolicy === undefined ? undefined : structuredClone(config.commandPolicy) };
|
|
125
|
+
this.sessionId = config.resumeSessionId ?? `subagent-${randomUUID()}`;
|
|
98
126
|
this.backend = config.backend ?? createBackend(config.provider, config.apiKey);
|
|
99
127
|
this.model = getSubAgentModel(config.provider, config.model);
|
|
100
|
-
this.cwd = config.cwd || process.cwd();
|
|
128
|
+
this.cwd = realpathSync(config.cwd || process.cwd());
|
|
101
129
|
this.hooks = config.hooks;
|
|
102
130
|
this.approvalRequester = config.approvalRequester;
|
|
103
131
|
debug('Created SubAgent with model=%s, cwd=%s, timeout=%dms', this.model, this.cwd, config.timeoutMs || 120000);
|
|
104
132
|
}
|
|
133
|
+
getSessionId() { return this.sessionId; }
|
|
134
|
+
getEvidenceSnapshot() { return this.toolResponseStore.evidence.getSnapshot(); }
|
|
135
|
+
getEvidenceHandoff(summary = '') {
|
|
136
|
+
return createDelegatedEvidenceHandoff({ sessionId: this.sessionId, parentSessionId: this.config.parentSessionId }, this.getEvidenceSnapshot(), summary);
|
|
137
|
+
}
|
|
105
138
|
/**
|
|
106
139
|
* Run a task and return a summary.
|
|
107
140
|
*
|
|
@@ -109,9 +142,15 @@ export class SubAgent {
|
|
|
109
142
|
* @param opts Optional overrides (abort signal, custom system prompt, tools)
|
|
110
143
|
*/
|
|
111
144
|
async run(task, opts) {
|
|
145
|
+
if (this.backend.getModelCapabilities?.(this.model)?.tools === false)
|
|
146
|
+
throw new Error('Chat-only models cannot run tool-dependent subagents.');
|
|
112
147
|
const signal = opts?.signal;
|
|
113
148
|
const startTime = Date.now();
|
|
114
149
|
const timeoutMs = this.config.timeoutMs || 120000; // 2 minute default
|
|
150
|
+
const deadlineAt = startTime + timeoutMs;
|
|
151
|
+
const deadline = new AbortController();
|
|
152
|
+
const runSignal = signal ? AbortSignal.any([signal, deadline.signal]) : deadline.signal;
|
|
153
|
+
const commandSessionId = this.sessionId;
|
|
115
154
|
const maxIterations = this.config.maxIterations || 5;
|
|
116
155
|
let iterations = 0;
|
|
117
156
|
let finalContent = '';
|
|
@@ -130,9 +169,18 @@ export class SubAgent {
|
|
|
130
169
|
// This summary-producing worker does not own the parent checklist or
|
|
131
170
|
// terminal answer lifecycle.
|
|
132
171
|
const tools = (opts?.tools ?? RESEARCH_TOOLS).filter(tool => !tool.finalResponse);
|
|
172
|
+
// A native host supplies a closed, bounded vocabulary. Adding ambient
|
|
173
|
+
// helper schemas can reject that otherwise valid request before dispatch.
|
|
174
|
+
if (!this.backend.preservesNativeHistory || opts?.tools === undefined) {
|
|
175
|
+
for (const tool of [recallToolResponseTool, sessionEvidenceTool]) {
|
|
176
|
+
if (!tools.some(existing => existing.definition.name === tool.definition.name))
|
|
177
|
+
tools.push(tool);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
133
180
|
const messages = [
|
|
181
|
+
...structuredClone(opts?.messages ?? []),
|
|
134
182
|
{
|
|
135
|
-
id:
|
|
183
|
+
id: `task_${randomUUID()}`,
|
|
136
184
|
role: 'user',
|
|
137
185
|
content: task,
|
|
138
186
|
timestamp: new Date()
|
|
@@ -140,36 +188,69 @@ export class SubAgent {
|
|
|
140
188
|
];
|
|
141
189
|
// Helper to check timeout
|
|
142
190
|
const checkTimeout = () => {
|
|
191
|
+
if (signal?.aborted)
|
|
192
|
+
throw new Error('Sub-agent cancelled');
|
|
143
193
|
const elapsed = Date.now() - startTime;
|
|
144
|
-
if (elapsed
|
|
194
|
+
if (elapsed >= timeoutMs || deadline.signal.aborted) {
|
|
145
195
|
throw new Error(`Sub-agent timed out after ${Math.round(elapsed / 1000)}s (limit: ${Math.round(timeoutMs / 1000)}s)`);
|
|
146
196
|
}
|
|
147
197
|
};
|
|
198
|
+
const deadlineTimer = setTimeout(() => deadline.abort(), timeoutMs);
|
|
199
|
+
let releaseWriter;
|
|
200
|
+
let evidenceBound = false;
|
|
201
|
+
const publishEvidence = () => {
|
|
202
|
+
opts?.onEvent?.({ type: 'evidence', sessionId: this.sessionId, snapshot: this.getEvidenceSnapshot() });
|
|
203
|
+
};
|
|
148
204
|
try {
|
|
205
|
+
releaseWriter = await acquireDelegatedEvidenceWriter({ sessionId: this.sessionId,
|
|
206
|
+
parentSessionId: this.config.parentSessionId, cwd: this.cwd });
|
|
207
|
+
await bindDelegatedEvidence(this.toolResponseStore, this.discoveredTools, { sessionId: this.sessionId, parentSessionId: this.config.parentSessionId, cwd: this.cwd }, this.config.resumeSessionId !== undefined);
|
|
208
|
+
evidenceBound = true;
|
|
209
|
+
await this.persistEvidenceCheckpoint();
|
|
210
|
+
publishEvidence();
|
|
149
211
|
while (iterations < maxIterations) {
|
|
150
|
-
if (signal?.aborted)
|
|
151
|
-
throw new Error('Sub-agent cancelled');
|
|
152
212
|
checkTimeout();
|
|
153
213
|
iterations++;
|
|
154
214
|
debug('Iteration %d/%d', iterations, maxIterations);
|
|
215
|
+
const evidence = formatEvidenceContext(this.getEvidenceSnapshot());
|
|
216
|
+
const executionContext = describeExecutionContext({
|
|
217
|
+
mode: 'delegated worker', cwd: this.cwd, tools: tools.map(tool => tool.definition.name),
|
|
218
|
+
mux: false, configScope: configStore.getConfigScope(), maxTokens: 2048,
|
|
219
|
+
outputLimitSource: 'delegated worker budget', settings: resolveExecutionSettings(configStore.get().execution), jobs: listCommandJobs(commandSessionId),
|
|
220
|
+
});
|
|
221
|
+
if (this.backend.preservesNativeHistory) {
|
|
222
|
+
// Stamp current host observations into a new user row. Earlier rows
|
|
223
|
+
// and the signed native system prefix keep their original bytes.
|
|
224
|
+
messages.push({ id: `host_context_${randomUUID()}`, role: 'user',
|
|
225
|
+
content: [evidence, executionContext].filter(Boolean).join('\n\n'), timestamp: new Date(),
|
|
226
|
+
metadata: { synthetic: true, hostContext: true } });
|
|
227
|
+
}
|
|
228
|
+
const system = pinnedTaskSystem(systemPrompt, task) + (this.backend.preservesNativeHistory
|
|
229
|
+
? '' : '\n\n' + evidence + '\n\n' + executionContext);
|
|
230
|
+
const definitions = tools.map(tool => tool.definition);
|
|
231
|
+
const contextId = nativeHistoryContextId(system, definitions);
|
|
155
232
|
const request = {
|
|
156
233
|
model: this.model,
|
|
157
234
|
maxTokens: 2048,
|
|
158
235
|
// R7 parity: pin the task in request.system so a long subagent run
|
|
159
236
|
// can't lose the task framing the same way the main loop could (F9).
|
|
160
|
-
system
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
outputLimitSource: 'delegated worker budget', settings: resolveExecutionSettings(configStore.get().execution), jobs: [],
|
|
164
|
-
}),
|
|
165
|
-
messages: this.formatMessages(messages),
|
|
166
|
-
tools: tools.map(t => t.definition),
|
|
237
|
+
system,
|
|
238
|
+
messages: this.formatMessages(messages, contextId),
|
|
239
|
+
tools: definitions,
|
|
167
240
|
// The inherited backend is pinned to the parent conversation; this is
|
|
168
241
|
// what tells it the prefix being sent is this run's instead.
|
|
169
242
|
agentRunId: this.agentRunId,
|
|
170
|
-
signal,
|
|
243
|
+
signal: runSignal,
|
|
171
244
|
};
|
|
172
|
-
const response = await this.backend.generate(request)
|
|
245
|
+
const response = await this.backend.generate(request).catch(error => {
|
|
246
|
+
opts?.onUsage?.({ inputTokens: 0, outputTokens: 0, totalTokens: 0, estimated: true, unreported: true });
|
|
247
|
+
throw error;
|
|
248
|
+
});
|
|
249
|
+
if (response.usage)
|
|
250
|
+
opts?.onUsage?.(response.usage);
|
|
251
|
+
else
|
|
252
|
+
opts?.onUsage?.({ inputTokens: 0, outputTokens: 0, totalTokens: 0, estimated: true, unreported: true });
|
|
253
|
+
checkTimeout();
|
|
173
254
|
// Normalize content to array — some backends/proxies may return a string
|
|
174
255
|
if (!Array.isArray(response.content)) {
|
|
175
256
|
const raw = response.content;
|
|
@@ -189,8 +270,47 @@ export class SubAgent {
|
|
|
189
270
|
if (isIncompleteModelResponse(response.stopReason)) {
|
|
190
271
|
throw new Error(incompleteModelResponseMessage(response.stopReason, request.maxTokens, response.usage?.outputTokens));
|
|
191
272
|
}
|
|
273
|
+
if (response.stopReason === 'refusal')
|
|
274
|
+
throw new Error('The model declined this request.');
|
|
192
275
|
// Check for tool use
|
|
193
|
-
const
|
|
276
|
+
const requestedToolBlocks = response.content.filter(isToolUseBlock);
|
|
277
|
+
const requestedIds = new Set();
|
|
278
|
+
for (const block of requestedToolBlocks) {
|
|
279
|
+
if (requestedIds.has(block.id)) {
|
|
280
|
+
throw new Error(`Provider response contains duplicate tool invocation ID ${block.id}; no call in this batch was executed.`);
|
|
281
|
+
}
|
|
282
|
+
requestedIds.add(block.id);
|
|
283
|
+
}
|
|
284
|
+
// Provider IDs describe this response, rather than retries of an owned
|
|
285
|
+
// operation. Allocate storage-safe identities before any tool effect,
|
|
286
|
+
// retaining the delegated source store's narrower 200-byte boundary.
|
|
287
|
+
const historicalIds = new Set(messages.flatMap(message => message.toolCalls?.map(call => call.id) ?? []));
|
|
288
|
+
const occupiedIds = new Set([...historicalIds, ...requestedIds]);
|
|
289
|
+
const toolUseBlocks = [];
|
|
290
|
+
for (const block of requestedToolBlocks) {
|
|
291
|
+
if (/^[A-Za-z0-9_-]{1,200}$/.test(block.id)
|
|
292
|
+
&& !historicalIds.has(block.id) && !await this.hasStoredToolIdentity(block.id)) {
|
|
293
|
+
toolUseBlocks.push(block);
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
let id;
|
|
297
|
+
let identityAttempts = 0;
|
|
298
|
+
do {
|
|
299
|
+
if (++identityAttempts > 16) {
|
|
300
|
+
throw new Error('Unable to allocate a fresh tool invocation identity. Inspect retained source availability before retrying.');
|
|
301
|
+
}
|
|
302
|
+
id = `tool_${randomUUID()}`;
|
|
303
|
+
} while (occupiedIds.has(id) || await this.hasStoredToolIdentity(id));
|
|
304
|
+
occupiedIds.add(id);
|
|
305
|
+
toolUseBlocks.push({ ...block, id });
|
|
306
|
+
}
|
|
307
|
+
if (this.backend.preservesNativeHistory && toolUseBlocks.length > 0) {
|
|
308
|
+
// Keep signed/opaque native blocks intact while pairing tool-use IDs
|
|
309
|
+
// with the canonical result identities admitted above.
|
|
310
|
+
const canonicalIds = new Map(requestedToolBlocks.map((block, index) => [block.id, toolUseBlocks[index].id]));
|
|
311
|
+
response.content = response.content.map(block => isToolUseBlock(block)
|
|
312
|
+
? { ...block, id: canonicalIds.get(block.id) } : block);
|
|
313
|
+
}
|
|
194
314
|
if (toolUseBlocks.length === 0) {
|
|
195
315
|
// No tools, extract final response
|
|
196
316
|
const textBlocks = response.content.filter(isTextBlock);
|
|
@@ -202,8 +322,15 @@ export class SubAgent {
|
|
|
202
322
|
}
|
|
203
323
|
debug('Executing %d tool(s): %s', toolUseBlocks.length, toolUseBlocks.map(tb => tb.name).join(', '));
|
|
204
324
|
// Execute tools and track what was accessed
|
|
325
|
+
const toolUseMessageId = `assistant_${randomUUID()}`;
|
|
205
326
|
const toolResults = await scheduleToolBatch(toolUseBlocks, tools, configStore.get().execution ?? {}, async (toolBlock, skipReason) => {
|
|
327
|
+
// Leave room for .json and its atomic-write suffix on 255-byte filesystems.
|
|
328
|
+
if (!/^[A-Za-z0-9_-]{1,200}$/.test(toolBlock.id))
|
|
329
|
+
throw new Error('Invalid delegated tool-call identity');
|
|
330
|
+
let retainingSource = false;
|
|
206
331
|
try {
|
|
332
|
+
if (this.toolResponseStore.getMeta(toolBlock.id))
|
|
333
|
+
throw new Error('Delegated tool call identity already retained; recall the original source using a fresh call ID.');
|
|
207
334
|
if (skipReason)
|
|
208
335
|
throw new Error(skipReason);
|
|
209
336
|
checkTimeout();
|
|
@@ -213,8 +340,12 @@ export class SubAgent {
|
|
|
213
340
|
context: {
|
|
214
341
|
cwd: this.cwd,
|
|
215
342
|
toolCallId: toolBlock.id,
|
|
216
|
-
|
|
343
|
+
onUsage: opts?.onUsage,
|
|
344
|
+
sessionId: commandSessionId,
|
|
345
|
+
managedCommandWaitSliceMs: 0,
|
|
346
|
+
signal: runSignal,
|
|
217
347
|
temporaryWriteRoot: this.config.temporaryWriteRoot,
|
|
348
|
+
commandPolicy: this.config.commandPolicy,
|
|
218
349
|
toolResponseStore: this.toolResponseStore,
|
|
219
350
|
discoveredTools: this.discoveredTools,
|
|
220
351
|
availableTools: tools,
|
|
@@ -229,21 +360,40 @@ export class SubAgent {
|
|
|
229
360
|
if (!result.isError) {
|
|
230
361
|
this.trackToolUsage(toolBlock.name, result.effectiveArgs, result.content);
|
|
231
362
|
}
|
|
363
|
+
retainingSource = true;
|
|
364
|
+
const source = this.evidenceSource(toolBlock.id, toolBlock.name, result.effectiveArgs, result.managedCommand);
|
|
365
|
+
if (result.verificationReceipt) {
|
|
366
|
+
source.origin = 'host_receipt';
|
|
367
|
+
source.verification = result.verificationReceipt;
|
|
368
|
+
}
|
|
369
|
+
const rendered = this.toolResponseStore.put(toolBlock.id, toolBlock.name, result.content, Boolean(runSignal.aborted || result.contentTruncated || result.managedCommand?.result.has_more || result.managedCommand?.result.output_truncated), { args: result.effectiveArgs, isError: result.isError, source: { ...source, messageId: toolUseMessageId } }).rendered;
|
|
370
|
+
await this.toolResponseStore.flush();
|
|
371
|
+
retainingSource = false;
|
|
372
|
+
publishEvidence();
|
|
232
373
|
return {
|
|
233
374
|
is_error: result.isError,
|
|
234
375
|
tool_use_id: toolBlock.id,
|
|
235
|
-
|
|
376
|
+
managedCommand: result.managedCommand,
|
|
377
|
+
content: applyRepeatGuard(toolBlock.name, toolBlock.input, result.isError ? `Error: ${rendered}` : rendered, result.isError ? undefined : result.managedCommand),
|
|
236
378
|
};
|
|
237
379
|
}
|
|
238
380
|
catch (err) {
|
|
381
|
+
// Source retention failure or reused identity must stop inference;
|
|
382
|
+
// neither establishes that an already dispatched effect did not run.
|
|
383
|
+
if (retainingSource || this.toolResponseStore.getMeta(toolBlock.id))
|
|
384
|
+
throw err;
|
|
239
385
|
debug('Tool %s failed: %s', toolBlock.name, err.message);
|
|
386
|
+
const content = `Error: ${err.message}`;
|
|
387
|
+
this.toolResponseStore.put(toolBlock.id, toolBlock.name, content, runSignal.aborted, { args: toolBlock.input, isError: true, source: { ...this.evidenceSource(toolBlock.id, toolBlock.name, toolBlock.input), messageId: toolUseMessageId } });
|
|
388
|
+
await this.toolResponseStore.flush();
|
|
389
|
+
publishEvidence();
|
|
240
390
|
return {
|
|
241
391
|
is_error: true,
|
|
242
392
|
tool_use_id: toolBlock.id,
|
|
243
|
-
content
|
|
393
|
+
content,
|
|
244
394
|
};
|
|
245
395
|
}
|
|
246
|
-
}, result => result.is_error || commandStillRunning(result.content),
|
|
396
|
+
}, result => result.is_error || result.managedCommand?.result.status === 'running' || commandStillRunning(result.content), runSignal);
|
|
247
397
|
opts?.onIteration?.({
|
|
248
398
|
iteration: iterations,
|
|
249
399
|
max: maxIterations,
|
|
@@ -255,9 +405,10 @@ export class SubAgent {
|
|
|
255
405
|
.map(b => b.text)
|
|
256
406
|
.join('\n');
|
|
257
407
|
messages.push({
|
|
258
|
-
id:
|
|
408
|
+
id: toolUseMessageId,
|
|
259
409
|
role: 'assistant',
|
|
260
410
|
content: textContent || '[Using tools...]',
|
|
411
|
+
...(this.backend.preservesNativeHistory ? { nativeContent: structuredClone(response.content), nativeModel: this.model, nativeContextId: contextId } : {}),
|
|
261
412
|
timestamp: new Date(),
|
|
262
413
|
toolCalls: toolUseBlocks.map(tb => ({
|
|
263
414
|
id: tb.id,
|
|
@@ -274,19 +425,39 @@ export class SubAgent {
|
|
|
274
425
|
messages.push({
|
|
275
426
|
id: `tool_${iterations}`,
|
|
276
427
|
role: 'user',
|
|
277
|
-
content: JSON.stringify(toolResults),
|
|
428
|
+
content: JSON.stringify(toolResults.map(({ managedCommand: _observation, ...result }) => result)),
|
|
278
429
|
timestamp: new Date()
|
|
279
430
|
});
|
|
431
|
+
checkTimeout();
|
|
280
432
|
const recoveryAction = recovery(toolResults.map((result, index) => ({
|
|
281
433
|
name: toolUseBlocks[index].name, content: result.content, isError: result.is_error,
|
|
434
|
+
managedCommand: result.managedCommand,
|
|
282
435
|
})));
|
|
283
436
|
if (recoveryAction === 'stop')
|
|
284
437
|
throw new Error('Automatic recovery budget exhausted after repeated tool failures.');
|
|
285
438
|
if (recoveryAction === 'recover')
|
|
286
439
|
messages.push({ id: `recovery_${iterations}`, role: 'user',
|
|
287
440
|
content: 'Repeated failures: inspect current capabilities, then try one changed recovery approach. Do not repeat the failing sequence.', timestamp: new Date() });
|
|
441
|
+
if (iterations < maxIterations && toolResults.every(result => !result.is_error && result.managedCommand !== undefined)) {
|
|
442
|
+
const waiting = await awaitManagedCommandProgress(toolResults.map(result => ({
|
|
443
|
+
...result.managedCommand, toolCallId: result.tool_use_id,
|
|
444
|
+
})), { signal: runSignal, deadlineAt, emit: opts?.onEvent });
|
|
445
|
+
checkTimeout();
|
|
446
|
+
if (waiting.waited) {
|
|
447
|
+
for (const observation of waiting.observations) {
|
|
448
|
+
this.toolResponseStore.put(`wait_${randomUUID()}`, 'read_command', JSON.stringify(observation.result), Boolean(observation.result.has_more || observation.result.output_truncated), { source: { ...this.evidenceSource(observation.toolCallId, 'read_command', {}, observation), originToolCallId: observation.toolCallId } });
|
|
449
|
+
}
|
|
450
|
+
await this.toolResponseStore.flush();
|
|
451
|
+
publishEvidence();
|
|
452
|
+
}
|
|
453
|
+
if (waiting.waited)
|
|
454
|
+
messages.push({ id: `command_observation_${randomUUID()}`, role: 'user',
|
|
455
|
+
content: formatManagedCommandObservations(waiting.observations), timestamp: new Date(),
|
|
456
|
+
metadata: { synthetic: true, hostContext: true } });
|
|
457
|
+
}
|
|
288
458
|
}
|
|
289
459
|
const durationMs = Date.now() - startTime;
|
|
460
|
+
await this.persistEvidenceCheckpoint();
|
|
290
461
|
// Exhausted maxIterations while still requesting tools = did NOT finish.
|
|
291
462
|
const exhausted = !completedCleanly;
|
|
292
463
|
const success = !exhausted;
|
|
@@ -308,6 +479,7 @@ export class SubAgent {
|
|
|
308
479
|
});
|
|
309
480
|
}
|
|
310
481
|
return {
|
|
482
|
+
evidence: this.getEvidenceHandoff(finalContent),
|
|
311
483
|
summary: finalContent || 'Sub-agent completed but produced no summary.',
|
|
312
484
|
filesRead: Array.from(this.filesRead),
|
|
313
485
|
commandsRun: this.commandsRun,
|
|
@@ -324,7 +496,15 @@ export class SubAgent {
|
|
|
324
496
|
}
|
|
325
497
|
catch (err) {
|
|
326
498
|
const durationMs = Date.now() - startTime;
|
|
327
|
-
|
|
499
|
+
let errMsg = err.message;
|
|
500
|
+
// Reads and inference receive the combined signal. Keep the public worker
|
|
501
|
+
// outcome specific to its controlling deadline or the user's cancellation.
|
|
502
|
+
try {
|
|
503
|
+
checkTimeout();
|
|
504
|
+
}
|
|
505
|
+
catch (controlError) {
|
|
506
|
+
errMsg = controlError.message;
|
|
507
|
+
}
|
|
328
508
|
debug('Task failed after %dms: %s', durationMs, errMsg);
|
|
329
509
|
if (this.hooks) {
|
|
330
510
|
await this.hooks.dispatch('SubagentStop', {
|
|
@@ -341,6 +521,7 @@ export class SubAgent {
|
|
|
341
521
|
});
|
|
342
522
|
}
|
|
343
523
|
return {
|
|
524
|
+
evidence: this.getEvidenceHandoff(''),
|
|
344
525
|
summary: '',
|
|
345
526
|
filesRead: Array.from(this.filesRead),
|
|
346
527
|
commandsRun: this.commandsRun,
|
|
@@ -355,6 +536,54 @@ export class SubAgent {
|
|
|
355
536
|
durationMs
|
|
356
537
|
};
|
|
357
538
|
}
|
|
539
|
+
finally {
|
|
540
|
+
clearTimeout(deadlineTimer);
|
|
541
|
+
if (releaseWriter) {
|
|
542
|
+
try {
|
|
543
|
+
if (evidenceBound)
|
|
544
|
+
await shutdownCommandJobs(commandSessionId);
|
|
545
|
+
}
|
|
546
|
+
finally {
|
|
547
|
+
await releaseWriter();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async hasStoredToolIdentity(id) {
|
|
553
|
+
if (this.toolResponseStore.getMeta(id)
|
|
554
|
+
|| this.toolResponseStore.evidence.getSnapshot().records.some(record => record.source.toolCallId === id))
|
|
555
|
+
return true;
|
|
556
|
+
try {
|
|
557
|
+
// A source can outlive its conversation row or arrive after binding.
|
|
558
|
+
// Missing indexed bodies and malformed originals still reserve their ID.
|
|
559
|
+
return await this.toolResponseStore.get(id) !== null;
|
|
560
|
+
}
|
|
561
|
+
catch (error) {
|
|
562
|
+
if (error instanceof ToolResponseIntegrityError)
|
|
563
|
+
return true;
|
|
564
|
+
throw error;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async persistEvidenceCheckpoint() {
|
|
568
|
+
await this.toolResponseStore.flush();
|
|
569
|
+
// Delegated instructions originate with the parent model, not the user.
|
|
570
|
+
// Save a canonical evidence checkpoint without synthesizing user directives
|
|
571
|
+
// or transferring a child conversation's permissions through task handoff.
|
|
572
|
+
await saveSessionToFile(getSessionPathForCwd(this.cwd, this.sessionId), this.sessionId, this.cwd, [], this.model, this.config.provider, undefined, undefined, { evidence: this.getEvidenceSnapshot(), mode: 'delegated' });
|
|
573
|
+
}
|
|
574
|
+
evidenceSource(toolCallId, toolName, args, managed) {
|
|
575
|
+
const source = { origin: managed ? 'host_receipt' : 'host_tool', toolCallId, toolName, cwd: this.cwd,
|
|
576
|
+
...(typeof args.path === 'string' ? { path: args.path } : {}) };
|
|
577
|
+
if (managed) {
|
|
578
|
+
const result = managed.result;
|
|
579
|
+
source.job = { sessionId: managed.sessionId, jobId: result.job_id, status: result.status, exitCode: result.exit_code ?? null,
|
|
580
|
+
startedAt: result.started_at, endedAt: result.ended_at, cursor: result.cursor, hasMore: result.has_more, outputTruncated: Boolean(result.output_truncated),
|
|
581
|
+
...(result.checked === undefined ? {} : { checked: result.checked }) };
|
|
582
|
+
source.artifact = { path: result.log_path };
|
|
583
|
+
if (result.verification)
|
|
584
|
+
source.verification = result.verification;
|
|
585
|
+
}
|
|
586
|
+
return source;
|
|
358
587
|
}
|
|
359
588
|
/**
|
|
360
589
|
* Track what the sub-agent accessed
|
|
@@ -378,7 +607,15 @@ export class SubAgent {
|
|
|
378
607
|
/**
|
|
379
608
|
* Format messages for the API
|
|
380
609
|
*/
|
|
381
|
-
formatMessages(messages) {
|
|
610
|
+
formatMessages(messages, contextId) {
|
|
611
|
+
if (this.backend.preservesNativeHistory) {
|
|
612
|
+
return new RequestEncoder({ preserveNativeHistory: true, model: this.model,
|
|
613
|
+
nativeContextId: contextId,
|
|
614
|
+
selectorVerdict: null,
|
|
615
|
+
currentTurnToolIds: new Set(messages.flatMap(message => message.toolCalls?.map(call => call.id) ?? [])),
|
|
616
|
+
renderForContext: () => null, loadImageBlock: () => null, loadVideoBlock: () => null,
|
|
617
|
+
}).encode(messages).messages;
|
|
618
|
+
}
|
|
382
619
|
return messages
|
|
383
620
|
.filter(m => m.role === 'user' || m.role === 'assistant')
|
|
384
621
|
.map(m => {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const TOOL_RESPONSE_DIRECTORY_ENTRY_LIMIT = 1024;
|
|
2
|
+
export declare const TOOL_RESPONSE_DIRECTORY_NAME_BYTE_LIMIT: number;
|
|
3
|
+
export declare const TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE = 16;
|
|
4
|
+
export interface ToolResponseDirectoryAdmission {
|
|
5
|
+
status: 'not_bound' | 'complete' | 'limited' | 'failed';
|
|
6
|
+
complete: boolean;
|
|
7
|
+
directoryComplete: boolean;
|
|
8
|
+
reasons: Array<'directory_entry_limit' | 'candidate_name_byte_limit' | 'source_retention_limit' | 'directory_error'>;
|
|
9
|
+
directoryEntriesRead: number;
|
|
10
|
+
directoryEntryLimit: number;
|
|
11
|
+
candidateNames: number;
|
|
12
|
+
candidateNameBytes: number;
|
|
13
|
+
candidateNameByteLimit: number;
|
|
14
|
+
bufferSize: number;
|
|
15
|
+
admittedSources: number;
|
|
16
|
+
skippedSources: number;
|
|
17
|
+
errorCode?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function emptyDirectoryAdmission(): ToolResponseDirectoryAdmission;
|
|
20
|
+
/** Bound discovery independently of unrelated directory size; known index names take priority. */
|
|
21
|
+
export declare function collectResponseFilenames(directory: string, indexedNames: readonly string[]): Promise<{
|
|
22
|
+
files: string[];
|
|
23
|
+
admission: ToolResponseDirectoryAdmission;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { opendir } from 'node:fs/promises';
|
|
2
|
+
import { EVIDENCE_MAX_RECORDS } from './runtime/evidence.js';
|
|
3
|
+
export const TOOL_RESPONSE_DIRECTORY_ENTRY_LIMIT = 1024;
|
|
4
|
+
export const TOOL_RESPONSE_DIRECTORY_NAME_BYTE_LIMIT = 64 * 1024;
|
|
5
|
+
export const TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE = 16;
|
|
6
|
+
export function emptyDirectoryAdmission() {
|
|
7
|
+
return { status: 'not_bound', complete: false, directoryComplete: false, reasons: [],
|
|
8
|
+
directoryEntriesRead: 0, directoryEntryLimit: TOOL_RESPONSE_DIRECTORY_ENTRY_LIMIT,
|
|
9
|
+
candidateNames: 0, candidateNameBytes: 0, candidateNameByteLimit: TOOL_RESPONSE_DIRECTORY_NAME_BYTE_LIMIT,
|
|
10
|
+
bufferSize: TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE, admittedSources: 0, skippedSources: 0 };
|
|
11
|
+
}
|
|
12
|
+
/** Bound discovery independently of unrelated directory size; known index names take priority. */
|
|
13
|
+
export async function collectResponseFilenames(directory, indexedNames) {
|
|
14
|
+
const admission = emptyDirectoryAdmission();
|
|
15
|
+
if (indexedNames.length > EVIDENCE_MAX_RECORDS * 2)
|
|
16
|
+
throw new RangeError('Indexed source filenames exceed the bounded evidence capacity');
|
|
17
|
+
const indexed = new Set(indexedNames);
|
|
18
|
+
const files = [...indexed].sort();
|
|
19
|
+
const discovered = new Set();
|
|
20
|
+
admission.candidateNameBytes = files.reduce((sum, name) => sum + Buffer.byteLength(name), 0);
|
|
21
|
+
if (admission.candidateNameBytes > admission.candidateNameByteLimit)
|
|
22
|
+
throw new RangeError('Indexed source filename metadata exceeds its admission byte limit');
|
|
23
|
+
const handle = await opendir(directory, { bufferSize: TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE });
|
|
24
|
+
// A boundary failure must close the descriptor even when an iterator rejects its next read.
|
|
25
|
+
try {
|
|
26
|
+
for await (const entry of handle) {
|
|
27
|
+
admission.directoryEntriesRead++;
|
|
28
|
+
if (admission.directoryEntriesRead > admission.directoryEntryLimit) {
|
|
29
|
+
admission.reasons.push('directory_entry_limit');
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
const name = entry.name;
|
|
33
|
+
if (name === '.evidence.json' || !name.endsWith('.json') || indexed.has(name))
|
|
34
|
+
continue;
|
|
35
|
+
const size = Buffer.byteLength(name);
|
|
36
|
+
if (admission.candidateNameBytes + size > admission.candidateNameByteLimit) {
|
|
37
|
+
admission.reasons.push('candidate_name_byte_limit');
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
if (discovered.has(name))
|
|
41
|
+
continue;
|
|
42
|
+
discovered.add(name);
|
|
43
|
+
admission.candidateNameBytes += size;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
try {
|
|
48
|
+
await handle.close();
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (error.code !== 'ERR_DIR_CLOSED')
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
files.push(...[...discovered].sort());
|
|
56
|
+
admission.candidateNames = files.length;
|
|
57
|
+
admission.directoryComplete = admission.reasons.length === 0;
|
|
58
|
+
admission.complete = admission.directoryComplete;
|
|
59
|
+
admission.status = admission.complete ? 'complete' : 'limited';
|
|
60
|
+
return { files, admission };
|
|
61
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Stats } from 'node:fs';
|
|
2
|
+
/** A source cannot be admitted without its complete, stable, bounded bytes. */
|
|
3
|
+
export declare class SourceAdmissionError extends Error {
|
|
4
|
+
}
|
|
5
|
+
export declare function readBoundedSource(path: string, maximumBytes: number): Promise<{
|
|
6
|
+
text: string;
|
|
7
|
+
info: Stats;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { lstat, open } from 'node:fs/promises';
|
|
3
|
+
import { TextDecoder } from 'node:util';
|
|
4
|
+
/** A source cannot be admitted without its complete, stable, bounded bytes. */
|
|
5
|
+
export class SourceAdmissionError extends Error {
|
|
6
|
+
}
|
|
7
|
+
export async function readBoundedSource(path, maximumBytes) {
|
|
8
|
+
if (!Number.isSafeInteger(maximumBytes) || maximumBytes < 1)
|
|
9
|
+
throw new RangeError('Invalid source byte admission limit');
|
|
10
|
+
// Nonblocking/no-follow protects a regular name changed to a FIFO or symlink.
|
|
11
|
+
const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
12
|
+
try {
|
|
13
|
+
const before = await handle.stat();
|
|
14
|
+
if (!before.isFile())
|
|
15
|
+
throw new SourceAdmissionError('Source admission requires a regular file');
|
|
16
|
+
if (!Number.isSafeInteger(before.size) || before.size < 0 || before.size > maximumBytes) {
|
|
17
|
+
throw new SourceAdmissionError(`Source exceeds byte admission limit (${maximumBytes})`);
|
|
18
|
+
}
|
|
19
|
+
// One sentinel byte catches growth even when a filesystem's stat timestamps are coarse.
|
|
20
|
+
const buffer = Buffer.allocUnsafe(before.size + 1);
|
|
21
|
+
let count = 0;
|
|
22
|
+
while (count < buffer.length) {
|
|
23
|
+
const { bytesRead } = await handle.read(buffer, count, Math.min(65536, buffer.length - count), count);
|
|
24
|
+
if (bytesRead === 0)
|
|
25
|
+
break;
|
|
26
|
+
count += bytesRead;
|
|
27
|
+
}
|
|
28
|
+
const after = await handle.stat();
|
|
29
|
+
const named = await lstat(path);
|
|
30
|
+
if (count > maximumBytes)
|
|
31
|
+
throw new SourceAdmissionError(`Source exceeds byte admission limit (${maximumBytes})`);
|
|
32
|
+
if (count !== before.size || after.size !== before.size || after.mtimeMs !== before.mtimeMs || after.ctimeMs !== before.ctimeMs
|
|
33
|
+
|| !named.isFile() || named.dev !== before.dev || named.ino !== before.ino
|
|
34
|
+
|| named.size !== before.size || named.mtimeMs !== before.mtimeMs || named.ctimeMs !== before.ctimeMs) {
|
|
35
|
+
throw new SourceAdmissionError('Source changed during bounded admission');
|
|
36
|
+
}
|
|
37
|
+
let text;
|
|
38
|
+
try {
|
|
39
|
+
text = new TextDecoder('utf-8', { fatal: true }).decode(buffer.subarray(0, count));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new SourceAdmissionError('Source admission requires valid UTF-8 bytes');
|
|
43
|
+
}
|
|
44
|
+
return { text, info: before };
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
await handle.close();
|
|
48
|
+
}
|
|
49
|
+
}
|