@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
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export const DIAGNOSTIC_LIMITS = Object.freeze({
|
|
3
|
+
events: 1024,
|
|
4
|
+
snapshotBytes: 1024 * 1024,
|
|
5
|
+
eventBytes: 32 * 1024,
|
|
6
|
+
textBytes: 16 * 1024,
|
|
7
|
+
markdownBytes: 128 * 1024,
|
|
8
|
+
jsonDepth: 32,
|
|
9
|
+
});
|
|
10
|
+
export class DiagnosticExportError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
constructor(message, code) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.name = 'DiagnosticExportError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const kinds = new Set(['user', 'assistant', 'reasoning', 'tool_invocation', 'tool_result', 'system_notice',
|
|
19
|
+
'synthetic_host', 'legacy_unknown', 'runtime', 'mode', 'provider_response', 'turn_end', 'job']);
|
|
20
|
+
const origins = new Set(['user', 'assistant', 'host', 'provider', 'host_tool', 'system', 'synthetic_host', 'legacy_unknown']);
|
|
21
|
+
const bytes = (value) => Buffer.byteLength(value, 'utf8');
|
|
22
|
+
const sha = (value) => createHash('sha256').update(value, 'utf8').digest('hex');
|
|
23
|
+
const isObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
24
|
+
const count = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
25
|
+
const nullableString = (value) => value === null || typeof value === 'string';
|
|
26
|
+
const sensitiveKey = (key) => /^(?:api[-_]?key|(?:access|refresh|auth|session|id)[-_]?token|token|password|passwd|secret|client[-_]?secret|authorization|proxy[-_]?authorization|cookie|set[-_]?cookie|credentials?)$/i.test(key)
|
|
27
|
+
|| /(?:^|[-_])(?:api[-_]?key|password|passwd|secret|(?:access|refresh|auth|session|id)[-_]?token|auth|secret[-_]?access[-_]?key)$/i.test(key);
|
|
28
|
+
function jsonValid(value, depth = 0, ancestors = new Set(), budget = { remaining: 100_000 }) {
|
|
29
|
+
if (depth > DIAGNOSTIC_LIMITS.jsonDepth || --budget.remaining < 0)
|
|
30
|
+
return false;
|
|
31
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'string')
|
|
32
|
+
return true;
|
|
33
|
+
if (typeof value === 'number')
|
|
34
|
+
return Number.isFinite(value);
|
|
35
|
+
if (typeof value !== 'object' || ancestors.has(value))
|
|
36
|
+
return false;
|
|
37
|
+
const prototype = Object.getPrototypeOf(value);
|
|
38
|
+
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null)
|
|
39
|
+
return false;
|
|
40
|
+
ancestors.add(value);
|
|
41
|
+
try {
|
|
42
|
+
return Object.values(value).every(item => jsonValid(item, depth + 1, ancestors, budget));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
ancestors.delete(value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function structuredString(value) {
|
|
52
|
+
if (bytes(value) > DIAGNOSTIC_LIMITS.snapshotBytes || !/^[\s]*[\[{]/.test(value))
|
|
53
|
+
return undefined;
|
|
54
|
+
try {
|
|
55
|
+
const parsed = JSON.parse(value);
|
|
56
|
+
return jsonValid(parsed) ? parsed : undefined;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function utf8Prefix(value, maximum) {
|
|
63
|
+
const buffer = Buffer.from(value, 'utf8');
|
|
64
|
+
if (buffer.length <= maximum)
|
|
65
|
+
return value;
|
|
66
|
+
let end = maximum;
|
|
67
|
+
while (end > 0 && (buffer[end] & 0xc0) === 0x80)
|
|
68
|
+
end--;
|
|
69
|
+
return buffer.subarray(0, end).toString('utf8');
|
|
70
|
+
}
|
|
71
|
+
function collectCredentials(value, found, depth = 0) {
|
|
72
|
+
if (typeof value === 'string') {
|
|
73
|
+
const parsed = structuredString(value);
|
|
74
|
+
if (parsed !== undefined && depth <= DIAGNOSTIC_LIMITS.jsonDepth)
|
|
75
|
+
collectCredentials(parsed, found, depth + 1);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (depth > DIAGNOSTIC_LIMITS.jsonDepth || value === null || typeof value !== 'object')
|
|
79
|
+
return;
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
for (const item of value)
|
|
82
|
+
collectCredentials(item, found, depth + 1);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
for (const [key, item] of Object.entries(value)) {
|
|
86
|
+
if (sensitiveKey(key) && typeof item === 'string' && item)
|
|
87
|
+
found.add(item);
|
|
88
|
+
else
|
|
89
|
+
collectCredentials(item, found, depth + 1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function redactKnownCredentials(value, credentials) {
|
|
93
|
+
let result = value;
|
|
94
|
+
for (const credential of credentials)
|
|
95
|
+
result = result.split(credential).join('[REDACTED]');
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
function redactString(value, credentials) {
|
|
99
|
+
return redactKnownCredentials(value, credentials)
|
|
100
|
+
.replace(/-----BEGIN (?:[A-Z ]*PRIVATE KEY|OPENSSH PRIVATE KEY)-----[\s\S]*?(?:-----END (?:[A-Z ]*PRIVATE KEY|OPENSSH PRIVATE KEY)-----|$)/g, '[REDACTED PRIVATE KEY]')
|
|
101
|
+
.replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9_~+/=.:-]+/gi, match => `${match.split(/\s/)[0]} [REDACTED]`)
|
|
102
|
+
.replace(/\b(?:sk-[A-Za-z0-9_-]{10,}|gh[pousr]_[A-Za-z0-9_]{10,}|xox[baprs]-[A-Za-z0-9-]{10,})\b/g, '[REDACTED]')
|
|
103
|
+
.replace(/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g, '[REDACTED]')
|
|
104
|
+
.replace(/\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{2,}\.[A-Za-z0-9_-]{10,}={0,2}(?![A-Za-z0-9_-])/g, '[REDACTED]')
|
|
105
|
+
.replace(/\b(?:(?:sk|rk)_(?:live|test)_[A-Za-z0-9_]{10,}|github_pat_[A-Za-z0-9_]{10,}|npm_[A-Za-z0-9_]{10,})\b/g, '[REDACTED]')
|
|
106
|
+
.replace(/https:\/\/hooks\.(?:slack\.com|slack-gov\.com)\/services\/[A-Za-z0-9_-]+\/[A-Za-z0-9_-]+\/[A-Za-z0-9_-]+/gi, '[REDACTED]')
|
|
107
|
+
.replace(/\b([A-Za-z][A-Za-z0-9+.-]*:\/\/)[^\s/@]+(?::[^\s/@]*)?@/g, '$1[REDACTED]@')
|
|
108
|
+
.replace(/([?&](?:api[-_]?key|access[-_]?token|refresh[-_]?token|token|password|secret|client[-_]?secret)=)[^\s&#]*/gi, '$1[REDACTED]')
|
|
109
|
+
.replace(/\b((?:Cookie|Set-Cookie|X-Api-Key|Api-Key)\s*:\s*)[^\r\n]*/gi, '$1[REDACTED]')
|
|
110
|
+
.replace(/("(?:api[-_]?key|access[-_]?token|refresh[-_]?token|token|password|secret|client[-_]?secret|authorization|cookie)"\s*:\s*)"(?:\\.|[^"\\])*(?:"|$)/gi, '$1"[REDACTED]"')
|
|
111
|
+
.replace(/\b((?:[A-Z_]*API_KEY|[A-Z_]*(?:ACCESS_TOKEN|AUTH_TOKEN|SECRET|PASSWORD|PASSWD)|AWS_SECRET_ACCESS_KEY|_authToken|_auth|AUTHORIZATION)\s*[=:]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s,;]+)/gi, '$1[REDACTED]');
|
|
112
|
+
}
|
|
113
|
+
function redactJson(value, credentials, depth = 0, options = {}, path = []) {
|
|
114
|
+
if (depth > DIAGNOSTIC_LIMITS.jsonDepth + 4)
|
|
115
|
+
throw new DiagnosticExportError('Invalid JSON depth in diagnostic value', 'INVALID_EXPORT');
|
|
116
|
+
if (value === null || typeof value === 'boolean')
|
|
117
|
+
return value;
|
|
118
|
+
if (typeof value === 'number')
|
|
119
|
+
return value;
|
|
120
|
+
if (typeof value === 'string') {
|
|
121
|
+
// Parse before replacement: rewriting raw JSON keys can create duplicates
|
|
122
|
+
// that JSON.parse would discard before collision handling sees them.
|
|
123
|
+
const parsed = structuredString(value);
|
|
124
|
+
if (parsed !== undefined) {
|
|
125
|
+
// Embedded JSON is authored data, independently of its enclosing schema.
|
|
126
|
+
const nested = redactJson(parsed, credentials, depth + 1);
|
|
127
|
+
if (JSON.stringify(nested) !== JSON.stringify(parsed))
|
|
128
|
+
return JSON.stringify(nested);
|
|
129
|
+
}
|
|
130
|
+
return redactString(value, credentials);
|
|
131
|
+
}
|
|
132
|
+
if (Array.isArray(value))
|
|
133
|
+
return value.map((item, index) => redactJson(item, credentials, depth + 1, options, [...path, index]));
|
|
134
|
+
if (isObject(value)) {
|
|
135
|
+
const output = {};
|
|
136
|
+
const filterNames = options.propertyNames?.(path) ?? true;
|
|
137
|
+
const entries = Object.entries(value).map(([key, item]) => ({ key, item,
|
|
138
|
+
redactedKey: filterNames ? redactKnownCredentials(key, credentials) : key }));
|
|
139
|
+
// Reserve ordinary names first, including literal placeholders and aliases,
|
|
140
|
+
// so renamed keys never take the name of a later unchanged property.
|
|
141
|
+
const used = new Set(entries.filter(entry => entry.key === entry.redactedKey).map(entry => entry.key));
|
|
142
|
+
const suffixes = new Map();
|
|
143
|
+
for (const { key, item, redactedKey } of entries) {
|
|
144
|
+
let name = redactedKey;
|
|
145
|
+
if (key !== redactedKey) {
|
|
146
|
+
let suffix = suffixes.get(redactedKey) ?? 2;
|
|
147
|
+
while (used.has(name))
|
|
148
|
+
name = `${redactedKey} (${suffix++})`;
|
|
149
|
+
suffixes.set(redactedKey, suffix);
|
|
150
|
+
used.add(name);
|
|
151
|
+
}
|
|
152
|
+
// JSON parsing cannot change prototypes, even for literal __proto__ keys.
|
|
153
|
+
Object.defineProperty(output, name, { value: sensitiveKey(key) ? '[REDACTED]'
|
|
154
|
+
: redactJson(item, credentials, depth + 1, options, [...path, key]), enumerable: true });
|
|
155
|
+
}
|
|
156
|
+
return output;
|
|
157
|
+
}
|
|
158
|
+
throw new DiagnosticExportError('Invalid non-JSON diagnostic value', 'INVALID_EXPORT');
|
|
159
|
+
}
|
|
160
|
+
/** Default credential filtering shared by persistence annotations and exports. */
|
|
161
|
+
export function redactDiagnosticValue(value, options = {}) {
|
|
162
|
+
if (!jsonValid(value))
|
|
163
|
+
throw new DiagnosticExportError('Invalid, cyclic, or excessively deep JSON diagnostic value', 'INVALID_EXPORT');
|
|
164
|
+
const credentials = new Set();
|
|
165
|
+
collectCredentials(value, credentials);
|
|
166
|
+
return redactJson(value, [...credentials].sort((a, b) => b.length - a.length), 0, options);
|
|
167
|
+
}
|
|
168
|
+
function truncation(field, full, retained, availability) {
|
|
169
|
+
const digest = sha(full);
|
|
170
|
+
return { field, originalBytes: bytes(full), retainedBytes: Math.min(bytes(full), bytes(retained)), sha256: digest,
|
|
171
|
+
reference: `sha256:${digest}`, availability };
|
|
172
|
+
}
|
|
173
|
+
export function describeDiagnosticTruncation(field, fullText, retainedText, availability) {
|
|
174
|
+
const credentials = new Set();
|
|
175
|
+
collectCredentials([fullText, retainedText], credentials);
|
|
176
|
+
const known = [...credentials].sort((a, b) => b.length - a.length);
|
|
177
|
+
const full = redactJson(fullText, known);
|
|
178
|
+
const retained = redactJson(retainedText, known);
|
|
179
|
+
return truncation(field, full, retained, availability);
|
|
180
|
+
}
|
|
181
|
+
function boundEvent(event, credentials) {
|
|
182
|
+
if ((event.args !== undefined && !jsonValid(event.args)) || (event.data !== undefined && !jsonValid(event.data))) {
|
|
183
|
+
throw new DiagnosticExportError('Invalid JSON diagnostic event fields', 'INVALID_EXPORT');
|
|
184
|
+
}
|
|
185
|
+
const present = Object.fromEntries(Object.entries(event).filter(([, value]) => value !== undefined));
|
|
186
|
+
const redacted = redactJson(present, credentials, 0, {
|
|
187
|
+
propertyNames: path => path[0] === 'args' || path[0] === 'data',
|
|
188
|
+
});
|
|
189
|
+
const output = { ...redacted };
|
|
190
|
+
const annotations = [...(output.truncations ?? [])];
|
|
191
|
+
for (const field of ['content', 'id', 'storedRole', 'toolCallId', 'toolName', 'status']) {
|
|
192
|
+
const value = output[field];
|
|
193
|
+
if (typeof value === 'string' && bytes(value) > DIAGNOSTIC_LIMITS.textBytes) {
|
|
194
|
+
const retained = utf8Prefix(value, DIAGNOSTIC_LIMITS.textBytes);
|
|
195
|
+
output[field] = retained;
|
|
196
|
+
annotations.push(truncation(field, value, retained, 'truncated'));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
for (const field of ['args', 'data']) {
|
|
200
|
+
const value = output[field];
|
|
201
|
+
if (value !== undefined && bytes(JSON.stringify(value)) > DIAGNOSTIC_LIMITS.textBytes) {
|
|
202
|
+
// A partial JSON argument object can imply different tool behavior. Omit
|
|
203
|
+
// the whole field and retain an explicit identity for the redacted value.
|
|
204
|
+
annotations.push(truncation(field, JSON.stringify(value), '', 'unavailable'));
|
|
205
|
+
delete output[field];
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (annotations.length)
|
|
209
|
+
output.truncations = annotations;
|
|
210
|
+
if (bytes(JSON.stringify(output)) > DIAGNOSTIC_LIMITS.eventBytes) {
|
|
211
|
+
for (const field of ['content', 'args', 'data']) {
|
|
212
|
+
const value = output[field];
|
|
213
|
+
if (value === undefined)
|
|
214
|
+
continue;
|
|
215
|
+
const full = typeof value === 'string' ? value : JSON.stringify(value);
|
|
216
|
+
annotations.push(truncation(field, full, '', 'unavailable'));
|
|
217
|
+
delete output[field];
|
|
218
|
+
output.truncations = annotations;
|
|
219
|
+
if (bytes(JSON.stringify(output)) <= DIAGNOSTIC_LIMITS.eventBytes)
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (bytes(JSON.stringify(output)) > DIAGNOSTIC_LIMITS.eventBytes)
|
|
224
|
+
throw new DiagnosticExportError('Diagnostic event metadata exceeds its 32768-byte limit', 'LIMIT_EXCEEDED');
|
|
225
|
+
return output;
|
|
226
|
+
}
|
|
227
|
+
function eventValid(value) {
|
|
228
|
+
if (!isObject(value) || value.recordType !== 'event' || !nullableString(value.id) || !kinds.has(String(value.kind))
|
|
229
|
+
|| !origins.has(String(value.origin)) || !nullableString(value.storedRole) || !nullableString(value.timestamp))
|
|
230
|
+
return false;
|
|
231
|
+
if (value.timestamp !== null && !Number.isFinite(Date.parse(value.timestamp)))
|
|
232
|
+
return false;
|
|
233
|
+
if (value.content !== undefined && typeof value.content !== 'string')
|
|
234
|
+
return false;
|
|
235
|
+
if (value.args !== undefined && !jsonValid(value.args))
|
|
236
|
+
return false;
|
|
237
|
+
for (const key of ['toolCallId', 'toolName', 'status'])
|
|
238
|
+
if (value[key] !== undefined && !nullableString(value[key]))
|
|
239
|
+
return false;
|
|
240
|
+
if (value.data !== undefined && (!isObject(value.data) || !jsonValid(value.data)))
|
|
241
|
+
return false;
|
|
242
|
+
if (value.truncations !== undefined) {
|
|
243
|
+
if (!Array.isArray(value.truncations) || value.truncations.length > 64)
|
|
244
|
+
return false;
|
|
245
|
+
for (const item of value.truncations) {
|
|
246
|
+
if (!isObject(item) || typeof item.field !== 'string' || !count(item.originalBytes) || !count(item.retainedBytes)
|
|
247
|
+
|| item.retainedBytes > item.originalBytes || typeof item.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(item.sha256)
|
|
248
|
+
|| item.reference !== `sha256:${item.sha256}` || (item.availability !== 'truncated' && item.availability !== 'unavailable'))
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
return bytes(JSON.stringify(value)) <= DIAGNOSTIC_LIMITS.eventBytes;
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
export function createDiagnosticSnapshot() {
|
|
260
|
+
return { schemaVersion: 1, events: [], omittedEvents: 0, omittedTextBytes: 0 };
|
|
261
|
+
}
|
|
262
|
+
function boundedSnapshot(events, omittedEvents, omittedTextBytes, minimumOmittedEvents = 0) {
|
|
263
|
+
const sizes = events.map(event => bytes(JSON.stringify(event)));
|
|
264
|
+
let payloadBytes = sizes.reduce((total, size) => total + size, 0);
|
|
265
|
+
let dropped = 0;
|
|
266
|
+
const header = () => ({ schemaVersion: 1, events: [],
|
|
267
|
+
omittedEvents: Math.max(minimumOmittedEvents, omittedEvents + dropped), omittedTextBytes });
|
|
268
|
+
// The empty wrapper already accounts for the brackets. Every pair of
|
|
269
|
+
// adjacent retained events adds one comma; omission counters can grow too.
|
|
270
|
+
while (events.length - dropped > DIAGNOSTIC_LIMITS.events
|
|
271
|
+
|| bytes(JSON.stringify(header())) + payloadBytes + Math.max(0, events.length - dropped - 1)
|
|
272
|
+
> DIAGNOSTIC_LIMITS.snapshotBytes) {
|
|
273
|
+
payloadBytes -= sizes[dropped++];
|
|
274
|
+
}
|
|
275
|
+
return { ...header(), events: events.slice(dropped) };
|
|
276
|
+
}
|
|
277
|
+
export function recordDiagnosticEvent(snapshot, event) {
|
|
278
|
+
if ((event.args !== undefined && !jsonValid(event.args)) || (event.data !== undefined && !jsonValid(event.data))) {
|
|
279
|
+
throw new DiagnosticExportError('Invalid, cyclic, or excessively deep JSON diagnostic event', 'INVALID_EXPORT');
|
|
280
|
+
}
|
|
281
|
+
const present = Object.fromEntries(Object.entries(event).filter(([, value]) => value !== undefined));
|
|
282
|
+
const credentials = new Set();
|
|
283
|
+
collectCredentials(event, credentials);
|
|
284
|
+
const admitted = boundEvent({ ...present, recordType: 'event' }, [...credentials].sort((a, b) => b.length - a.length));
|
|
285
|
+
if (!eventValid(admitted))
|
|
286
|
+
throw new DiagnosticExportError('Diagnostic event has invalid kind, origin, identity, or timestamp', 'INVALID_EXPORT');
|
|
287
|
+
const eventBytesOmitted = (admitted.truncations ?? []).reduce((total, item) => total + item.originalBytes - item.retainedBytes, 0);
|
|
288
|
+
const same = admitted.id === null ? -1 : snapshot.events.findIndex(item => item.id === admitted.id);
|
|
289
|
+
if (same !== -1) {
|
|
290
|
+
if (JSON.stringify(snapshot.events[same]) === JSON.stringify(admitted))
|
|
291
|
+
return structuredClone(snapshot);
|
|
292
|
+
throw new DiagnosticExportError(`Diagnostic event identity conflict: ${admitted.id}`, 'INVALID_EXPORT');
|
|
293
|
+
}
|
|
294
|
+
return boundedSnapshot([...snapshot.events, admitted], snapshot.omittedEvents, snapshot.omittedTextBytes + eventBytesOmitted);
|
|
295
|
+
}
|
|
296
|
+
export function mergeDiagnosticSnapshots(first, second) {
|
|
297
|
+
if (parseDiagnosticSnapshot(first) === null || parseDiagnosticSnapshot(second) === null) {
|
|
298
|
+
throw new DiagnosticExportError('Invalid diagnostic snapshot merge input', 'INVALID_EXPORT');
|
|
299
|
+
}
|
|
300
|
+
const keys = (events) => {
|
|
301
|
+
const occurrences = new Map();
|
|
302
|
+
return events.map(event => {
|
|
303
|
+
if (event.id !== null)
|
|
304
|
+
return `id:${event.id}`;
|
|
305
|
+
// Internal occurrence keys preserve repeated anonymous legacy rows. They
|
|
306
|
+
// are not exported or presented as fabricated source identities.
|
|
307
|
+
const body = JSON.stringify(event);
|
|
308
|
+
const occurrence = occurrences.get(body) ?? 0;
|
|
309
|
+
occurrences.set(body, occurrence + 1);
|
|
310
|
+
return `anonymous:${body}:${occurrence}`;
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
const firstKeys = keys(first.events);
|
|
314
|
+
const secondKeys = keys(second.events);
|
|
315
|
+
const identities = new Map(firstKeys.map((key, index) => [key, first.events[index]]));
|
|
316
|
+
const order = [...firstKeys];
|
|
317
|
+
const pending = [];
|
|
318
|
+
for (const [index, key] of secondKeys.entries()) {
|
|
319
|
+
const event = second.events[index];
|
|
320
|
+
const existing = identities.get(key);
|
|
321
|
+
if (existing !== undefined) {
|
|
322
|
+
if (JSON.stringify(existing) !== JSON.stringify(event)) {
|
|
323
|
+
identities.set(key, reconcileCheckpointFact(existing, event));
|
|
324
|
+
}
|
|
325
|
+
// A shared retained identity anchors earlier records from an old
|
|
326
|
+
// checkpoint, including when clocks are missing or equal. Appending
|
|
327
|
+
// that old prefix would instead evict new events on each repeated save.
|
|
328
|
+
if (pending.length) {
|
|
329
|
+
order.splice(order.indexOf(key), 0, ...pending);
|
|
330
|
+
pending.length = 0;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
identities.set(key, event);
|
|
335
|
+
pending.push(key);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
order.push(...pending);
|
|
339
|
+
const events = order.map(key => structuredClone(identities.get(key)));
|
|
340
|
+
// Known capture times conserve chronology even when a repeated checkpoint
|
|
341
|
+
// contains older events previously dropped from the retained history. Equal
|
|
342
|
+
// or unknown times preserve their existing source order; no time is invented.
|
|
343
|
+
const chronological = events.every(item => item.timestamp !== null)
|
|
344
|
+
? events.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)) : events;
|
|
345
|
+
// Missing event identities are not retained. Recycled drops may overlap the
|
|
346
|
+
// previous omissions, so max is an honest lower bound and repeat-save stable.
|
|
347
|
+
return boundedSnapshot(chronological, 0, Math.max(first.omittedTextBytes, second.omittedTextBytes), Math.max(first.omittedEvents, second.omittedEvents));
|
|
348
|
+
}
|
|
349
|
+
export function parseDiagnosticSnapshot(value) {
|
|
350
|
+
if (!isObject(value) || value.schemaVersion !== 1 || !Array.isArray(value.events) || value.events.length > DIAGNOSTIC_LIMITS.events
|
|
351
|
+
|| !count(value.omittedEvents) || !count(value.omittedTextBytes) || !value.events.every(eventValid))
|
|
352
|
+
return null;
|
|
353
|
+
try {
|
|
354
|
+
if (bytes(JSON.stringify(value)) > DIAGNOSTIC_LIMITS.snapshotBytes)
|
|
355
|
+
return null;
|
|
356
|
+
const ids = value.events.flatMap(event => event.id === null ? [] : [event.id]);
|
|
357
|
+
if (new Set(ids).size !== ids.length)
|
|
358
|
+
return null;
|
|
359
|
+
return structuredClone(value);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function observedTimestamp(value) {
|
|
366
|
+
if (value instanceof Date)
|
|
367
|
+
return Number.isFinite(value.getTime()) ? value.toISOString() : null;
|
|
368
|
+
return typeof value === 'string' && Number.isFinite(Date.parse(value)) ? new Date(value).toISOString() : null;
|
|
369
|
+
}
|
|
370
|
+
function priorResultTruncation(message, toolCallId) {
|
|
371
|
+
const prior = message.metadata?.toolResultTruncation;
|
|
372
|
+
if (!isObject(prior))
|
|
373
|
+
return [];
|
|
374
|
+
const value = prior[toolCallId];
|
|
375
|
+
if (!isObject(value) || !count(value.originalBytes) || !count(value.retainedBytes) || value.retainedBytes > value.originalBytes
|
|
376
|
+
|| typeof value.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(value.sha256)
|
|
377
|
+
|| value.reference !== `sha256:${value.sha256}` || (value.availability !== 'truncated' && value.availability !== 'unavailable'))
|
|
378
|
+
return [];
|
|
379
|
+
return [{ field: 'content', originalBytes: value.originalBytes, retainedBytes: value.retainedBytes, sha256: value.sha256,
|
|
380
|
+
reference: value.reference, availability: value.availability }];
|
|
381
|
+
}
|
|
382
|
+
function messageProvenance(message) {
|
|
383
|
+
const correction = message.metadata?.taskHandoffCorrection;
|
|
384
|
+
const deliveryState = isObject(correction) && typeof correction.deliveryState === 'string' ? correction.deliveryState : undefined;
|
|
385
|
+
const provisional = message.metadata?.steeringPending === true || message.metadata?.unsentDraft === true || deliveryState === 'pending';
|
|
386
|
+
const displayProjection = message.role === 'tool' && typeof message.metadata?.toolGroupId === 'string';
|
|
387
|
+
return { ...(provisional ? { provisional: true } : {}), ...(deliveryState === undefined ? {} : { deliveryState }),
|
|
388
|
+
...(displayProjection ? { displayProjection: true } : {}) };
|
|
389
|
+
}
|
|
390
|
+
function retainedMessage(message) {
|
|
391
|
+
const provenance = messageProvenance(message);
|
|
392
|
+
return provenance.provisional !== true && provenance.displayProjection !== true;
|
|
393
|
+
}
|
|
394
|
+
function projectMessages(messages) {
|
|
395
|
+
const output = [];
|
|
396
|
+
for (const message of messages) {
|
|
397
|
+
const id = typeof message.id === 'string' && message.id ? message.id : null;
|
|
398
|
+
const storedRole = typeof message.role === 'string' ? message.role : null;
|
|
399
|
+
const timestamp = observedTimestamp(message.timestamp);
|
|
400
|
+
const synthetic = message.metadata?.synthetic === true;
|
|
401
|
+
const base = { recordType: 'event', id, storedRole, timestamp };
|
|
402
|
+
const provenance = messageProvenance(message);
|
|
403
|
+
if (provenance.displayProjection === true) {
|
|
404
|
+
output.push({ ...base, kind: 'synthetic_host', origin: 'host', content: message.content, data: provenance });
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (message.metadata?.toolResult === true) {
|
|
408
|
+
let blocks;
|
|
409
|
+
try {
|
|
410
|
+
blocks = JSON.parse(message.content);
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
blocks = null;
|
|
414
|
+
}
|
|
415
|
+
if (Array.isArray(blocks) && blocks.every(block => isObject(block) && typeof block.tool_use_id === 'string'
|
|
416
|
+
&& (typeof block.content === 'string' || Array.isArray(block.content)) && (block.is_error === undefined || typeof block.is_error === 'boolean'))) {
|
|
417
|
+
for (const block of blocks) {
|
|
418
|
+
const toolCallId = block.tool_use_id;
|
|
419
|
+
const truncations = priorResultTruncation(message, toolCallId);
|
|
420
|
+
output.push({ ...base, id: id === null ? null : `${id}:result:${toolCallId}`, kind: 'tool_result',
|
|
421
|
+
origin: synthetic ? 'synthetic_host' : 'host_tool', toolCallId,
|
|
422
|
+
content: typeof block.content === 'string' ? block.content : JSON.stringify(block.content),
|
|
423
|
+
status: block.is_error === true ? 'error' : 'complete', ...(truncations.length ? { truncations } : {}) });
|
|
424
|
+
}
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
// Invalid historical structured results remain host-origin observations;
|
|
428
|
+
// they never become authored user prose or inferred completed outcomes.
|
|
429
|
+
output.push({ ...base, kind: 'tool_result', origin: synthetic ? 'synthetic_host' : 'legacy_unknown',
|
|
430
|
+
content: message.content, status: null });
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
const kind = synthetic ? 'synthetic_host' : message.role === 'system' ? 'system_notice'
|
|
434
|
+
: message.role === 'tool' ? 'tool_result' : message.role === 'assistant' ? message.metadata?.reasoning === true ? 'reasoning' : 'assistant'
|
|
435
|
+
: message.role === 'user' ? 'user' : 'legacy_unknown';
|
|
436
|
+
const origin = synthetic ? 'synthetic_host' : message.role === 'system' ? 'system'
|
|
437
|
+
: message.role === 'tool' ? 'legacy_unknown' : message.role === 'assistant' ? 'assistant'
|
|
438
|
+
: message.role === 'user' ? 'user' : 'legacy_unknown';
|
|
439
|
+
output.push({ ...base, kind, origin, content: message.content,
|
|
440
|
+
...(Object.keys(provenance).length || typeof message.isStreaming === 'boolean'
|
|
441
|
+
? { data: { ...provenance, ...(typeof message.isStreaming === 'boolean' ? { isStreaming: message.isStreaming } : {}) } } : {}) });
|
|
442
|
+
if (typeof message.metadata?.reasoningContent === 'string') {
|
|
443
|
+
output.push({ ...base, id: id === null ? null : `${id}:reasoning`, kind: 'reasoning', origin: 'assistant',
|
|
444
|
+
content: message.metadata.reasoningContent });
|
|
445
|
+
}
|
|
446
|
+
for (const call of message.toolCalls ?? []) {
|
|
447
|
+
const callId = typeof call.id === 'string' ? call.id : null;
|
|
448
|
+
output.push({ ...base, id: id === null || callId === null ? null : `${id}:invocation:${callId}`,
|
|
449
|
+
kind: 'tool_invocation', origin: synthetic ? 'synthetic_host' : 'assistant',
|
|
450
|
+
timestamp: observedTimestamp(call.startedAt) ?? timestamp, toolCallId: callId,
|
|
451
|
+
toolName: typeof call.name === 'string' ? call.name : null, args: call.args,
|
|
452
|
+
status: typeof call.status === 'string' ? call.status : null,
|
|
453
|
+
data: { completedAt: observedTimestamp(call.completedAt) } });
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return output;
|
|
457
|
+
}
|
|
458
|
+
function reconcileCheckpointFact(prior, current) {
|
|
459
|
+
if (JSON.stringify(prior) === JSON.stringify(current))
|
|
460
|
+
return prior;
|
|
461
|
+
const sameSource = prior.kind === current.kind && prior.origin === current.origin && prior.storedRole === current.storedRole
|
|
462
|
+
&& prior.toolCallId === current.toolCallId && prior.toolName === current.toolName;
|
|
463
|
+
if (!sameSource)
|
|
464
|
+
throw new DiagnosticExportError(`Diagnostic canonical identity conflict: ${current.id}`, 'INVALID_EXPORT');
|
|
465
|
+
if (current.kind === 'assistant' || current.kind === 'reasoning') {
|
|
466
|
+
const authoredFacts = (event) => {
|
|
467
|
+
const fact = { ...event, timestamp: null };
|
|
468
|
+
if (fact.data !== undefined) {
|
|
469
|
+
fact.data = { ...fact.data };
|
|
470
|
+
if (typeof fact.data.isStreaming === 'boolean')
|
|
471
|
+
delete fact.data.isStreaming;
|
|
472
|
+
if (Object.keys(fact.data).length === 0)
|
|
473
|
+
delete fact.data;
|
|
474
|
+
}
|
|
475
|
+
return JSON.stringify(fact);
|
|
476
|
+
};
|
|
477
|
+
if (authoredFacts(prior) === authoredFacts(current)) {
|
|
478
|
+
const observedStreaming = prior.data?.isStreaming === false || current.data?.isStreaming === false
|
|
479
|
+
? false : prior.data?.isStreaming ?? current.data?.isStreaming;
|
|
480
|
+
const data = { ...prior.data, ...current.data,
|
|
481
|
+
...(observedStreaming === undefined ? {} : { isStreaming: observedStreaming }) };
|
|
482
|
+
const reconciled = { ...prior, timestamp: prior.timestamp ?? current.timestamp };
|
|
483
|
+
if (Object.keys(data).length)
|
|
484
|
+
reconciled.data = data;
|
|
485
|
+
else
|
|
486
|
+
delete reconciled.data;
|
|
487
|
+
return reconciled;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (current.kind === 'tool_invocation') {
|
|
491
|
+
const terminal = (status) => status === 'complete' || status === 'error';
|
|
492
|
+
if (terminal(prior.status)) {
|
|
493
|
+
if (!terminal(current.status))
|
|
494
|
+
return prior; // A stale live checkpoint cannot reopen a settled call.
|
|
495
|
+
if (prior.status !== current.status || JSON.stringify(prior.args) !== JSON.stringify(current.args)) {
|
|
496
|
+
throw new DiagnosticExportError(`Diagnostic settled invocation identity conflict: ${current.id}`, 'INVALID_EXPORT');
|
|
497
|
+
}
|
|
498
|
+
if (JSON.stringify(prior.data) === JSON.stringify(current.data))
|
|
499
|
+
return prior;
|
|
500
|
+
if (prior.data?.completedAt === current.data?.completedAt)
|
|
501
|
+
return { ...current, data: { ...prior.data, ...current.data } };
|
|
502
|
+
if (prior.data?.completedAt === null && typeof current.data?.completedAt === 'string')
|
|
503
|
+
return current;
|
|
504
|
+
if (current.data?.completedAt === null)
|
|
505
|
+
return prior;
|
|
506
|
+
}
|
|
507
|
+
else if (prior.status === 'running' && current.status === 'pending')
|
|
508
|
+
return prior;
|
|
509
|
+
else if (['pending', 'running', 'complete', 'error'].includes(current.status ?? '')) {
|
|
510
|
+
return { ...current, data: { ...current.data,
|
|
511
|
+
...(JSON.stringify(prior.args) === JSON.stringify(current.args) ? {} : {
|
|
512
|
+
argumentsUpdatedFromPriorCheckpoint: true,
|
|
513
|
+
argumentsSource: 'latest canonical checkpoint; model proposal can differ from admitted execution input',
|
|
514
|
+
}) } };
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (current.kind === 'tool_result' && prior.status === current.status) {
|
|
518
|
+
const sourceIdentity = (event) => event.truncations?.find(row => row.field === 'content')?.sha256
|
|
519
|
+
?? (event.content === undefined ? null : sha(event.content));
|
|
520
|
+
const priorIdentity = sourceIdentity(prior);
|
|
521
|
+
const currentIdentity = sourceIdentity(current);
|
|
522
|
+
if (priorIdentity !== null && priorIdentity === currentIdentity) {
|
|
523
|
+
return bytes(prior.content ?? '') >= bytes(current.content ?? '') ? prior : current;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if ((current.kind === 'assistant' || current.kind === 'reasoning') && prior.data?.isStreaming === true)
|
|
527
|
+
return current;
|
|
528
|
+
throw new DiagnosticExportError(`Diagnostic canonical identity conflict: ${current.id}`, 'INVALID_EXPORT');
|
|
529
|
+
}
|
|
530
|
+
/** Capture canonical message facts before checkpoint trimming or compaction.
|
|
531
|
+
* Telemetry remains immutable; only a matching canonical invocation may advance
|
|
532
|
+
* its observed lifecycle, and a matching result may retain a richer same-source preview. */
|
|
533
|
+
export function captureSessionDiagnosticSnapshot(input) {
|
|
534
|
+
const history = input.diagnostics === undefined ? createDiagnosticSnapshot() : parseDiagnosticSnapshot(input.diagnostics);
|
|
535
|
+
if (history === null)
|
|
536
|
+
throw new DiagnosticExportError('Invalid diagnostic snapshot', 'INVALID_EXPORT');
|
|
537
|
+
const projected = projectMessages(input.messages.filter(retainedMessage));
|
|
538
|
+
// Credential context includes provisional rows even though their mutable
|
|
539
|
+
// facts are excluded from retention; another admitted row can echo a secret.
|
|
540
|
+
const credentials = new Set();
|
|
541
|
+
collectCredentials([input.messages, history.events], credentials);
|
|
542
|
+
const known = [...credentials].sort((a, b) => b.length - a.length);
|
|
543
|
+
const prior = history.events.map(event => boundEvent(event, known));
|
|
544
|
+
const current = projected.map(event => boundEvent(event, known));
|
|
545
|
+
const positions = new Map(prior.flatMap((event, index) => event.id === null ? [] : [[event.id, index]]));
|
|
546
|
+
for (const [index, event] of current.entries()) {
|
|
547
|
+
const position = event.id === null ? undefined : positions.get(event.id);
|
|
548
|
+
if (position === undefined)
|
|
549
|
+
continue;
|
|
550
|
+
const reconciled = reconcileCheckpointFact(prior[position], event);
|
|
551
|
+
prior[position] = reconciled;
|
|
552
|
+
current[index] = reconciled;
|
|
553
|
+
}
|
|
554
|
+
const omittedBytes = (events) => events.reduce((total, event) => total
|
|
555
|
+
+ (event.truncations ?? []).reduce((sum, row) => sum + row.originalBytes - row.retainedBytes, 0), 0);
|
|
556
|
+
const previous = boundedSnapshot(prior, history.omittedEvents, Math.max(history.omittedTextBytes, omittedBytes(prior)));
|
|
557
|
+
const fresh = boundedSnapshot(current, 0, omittedBytes(current));
|
|
558
|
+
return mergeDiagnosticSnapshots(previous, fresh);
|
|
559
|
+
}
|
|
560
|
+
export function buildSessionDiagnosticDocument(input) {
|
|
561
|
+
if (input.sessionId !== undefined && input.sessionId !== null
|
|
562
|
+
&& (typeof input.sessionId !== 'string' || bytes(input.sessionId) > DIAGNOSTIC_LIMITS.textBytes)) {
|
|
563
|
+
throw new DiagnosticExportError('Diagnostic session header identity exceeds its 16384-byte limit', 'LIMIT_EXCEEDED');
|
|
564
|
+
}
|
|
565
|
+
let snapshot = captureSessionDiagnosticSnapshot(input);
|
|
566
|
+
const credentials = new Set();
|
|
567
|
+
collectCredentials([input.messages, input.diagnostics?.events ?? []], credentials);
|
|
568
|
+
const known = [...credentials].sort((a, b) => b.length - a.length);
|
|
569
|
+
// Pending inputs and mutable display cards remain useful live observations,
|
|
570
|
+
// but never enter the durable ledger as immutable admitted source facts.
|
|
571
|
+
const live = projectMessages(input.messages.filter(message => !retainedMessage(message)))
|
|
572
|
+
.map(event => boundEvent(event, known));
|
|
573
|
+
const liveOmittedBytes = live.reduce((total, event) => total
|
|
574
|
+
+ (event.truncations ?? []).reduce((sum, row) => sum + row.originalBytes - row.retainedBytes, 0), 0);
|
|
575
|
+
snapshot = mergeDiagnosticSnapshots(snapshot, boundedSnapshot(live, 0, liveOmittedBytes));
|
|
576
|
+
return { header: { recordType: 'header', schemaVersion: 1, sessionId: input.sessionId === undefined || input.sessionId === null ? null : redactString(input.sessionId, known), redacted: true,
|
|
577
|
+
omittedEvents: snapshot.omittedEvents, omittedTextBytes: snapshot.omittedTextBytes }, events: snapshot.events };
|
|
578
|
+
}
|
|
579
|
+
export function exportSessionDiagnostics(input) {
|
|
580
|
+
const document = buildSessionDiagnosticDocument(input);
|
|
581
|
+
return [document.header, ...document.events].map(record => JSON.stringify(record)).join('\n') + '\n';
|
|
582
|
+
}
|
|
583
|
+
export function parseDiagnosticExport(text) {
|
|
584
|
+
if (bytes(text) > DIAGNOSTIC_LIMITS.snapshotBytes + DIAGNOSTIC_LIMITS.eventBytes)
|
|
585
|
+
throw new DiagnosticExportError('Diagnostic export exceeds its byte limit', 'LIMIT_EXCEEDED');
|
|
586
|
+
let records;
|
|
587
|
+
try {
|
|
588
|
+
records = text.trim().split('\n').map(line => JSON.parse(line));
|
|
589
|
+
}
|
|
590
|
+
catch {
|
|
591
|
+
throw new DiagnosticExportError('Diagnostic export must contain valid JSONL records', 'INVALID_EXPORT');
|
|
592
|
+
}
|
|
593
|
+
const header = records[0];
|
|
594
|
+
if (!isObject(header) || header.recordType !== 'header')
|
|
595
|
+
throw new DiagnosticExportError('Diagnostic export requires a header record', 'INVALID_EXPORT');
|
|
596
|
+
if (header.schemaVersion !== 1)
|
|
597
|
+
throw new DiagnosticExportError('Diagnostic export requires schemaVersion=1', 'UNSUPPORTED_SCHEMA');
|
|
598
|
+
if (!nullableString(header.sessionId) || (header.sessionId !== null && bytes(header.sessionId) > DIAGNOSTIC_LIMITS.textBytes)
|
|
599
|
+
|| bytes(JSON.stringify(header)) > DIAGNOSTIC_LIMITS.eventBytes || header.redacted !== true || !count(header.omittedEvents) || !count(header.omittedTextBytes)
|
|
600
|
+
|| records.length - 1 > DIAGNOSTIC_LIMITS.events || !records.slice(1).every(eventValid))
|
|
601
|
+
throw new DiagnosticExportError('Diagnostic export contains invalid header or events', 'INVALID_EXPORT');
|
|
602
|
+
const events = records.slice(1);
|
|
603
|
+
const ids = events.flatMap(item => item.id === null ? [] : [item.id]);
|
|
604
|
+
if (new Set(ids).size !== ids.length)
|
|
605
|
+
throw new DiagnosticExportError('Diagnostic export contains duplicate event identity', 'INVALID_EXPORT');
|
|
606
|
+
const credentials = new Set();
|
|
607
|
+
collectCredentials(events, credentials);
|
|
608
|
+
const known = [...credentials].sort((a, b) => b.length - a.length);
|
|
609
|
+
return { header: { ...header, sessionId: header.sessionId === null ? null : redactString(header.sessionId, known) },
|
|
610
|
+
events: events.map(item => boundEvent(item, known)) };
|
|
611
|
+
}
|
|
612
|
+
const headings = {
|
|
613
|
+
user: 'User', assistant: 'Assistant', reasoning: 'Reasoning', tool_invocation: 'Tool invocation', tool_result: 'Tool result',
|
|
614
|
+
system_notice: 'System notice', synthetic_host: 'Synthetic host', legacy_unknown: 'Legacy unknown', runtime: 'Runtime capabilities', mode: 'Mode change',
|
|
615
|
+
provider_response: 'Provider response', turn_end: 'Turn end', job: 'Command job',
|
|
616
|
+
};
|
|
617
|
+
export function formatSessionDiagnosticsMarkdown(input) {
|
|
618
|
+
const document = buildSessionDiagnosticDocument(input);
|
|
619
|
+
const parts = [`# ZTC session diagnostics (v1)\n\nSession: ${document.header.sessionId ?? 'unknown'}\nCredential redaction: enabled.\n`];
|
|
620
|
+
let omitted = 0;
|
|
621
|
+
for (const event of document.events) {
|
|
622
|
+
const details = [event.content ?? '', event.args === undefined ? '' : `Arguments: ${JSON.stringify(event.args)}`,
|
|
623
|
+
event.data === undefined ? '' : `Details: ${JSON.stringify(event.data)}`].filter(Boolean).join('\n\n');
|
|
624
|
+
const references = (event.truncations ?? []).map(item => `Omitted ${item.field}: ${item.originalBytes - item.retainedBytes} bytes; ${item.reference}; availability=${item.availability}. A digest alone cannot retrieve omitted content.`).join('\n');
|
|
625
|
+
const row = `\n## ${headings[event.kind]}\n\nID: ${event.id ?? 'unknown'}; timestamp: ${event.timestamp ?? 'unknown'}; origin: ${event.origin}; stored role: ${event.storedRole ?? 'unknown'}${event.toolCallId === undefined ? '' : `; tool ID: ${event.toolCallId ?? 'unknown'}`}${event.toolName === undefined ? '' : `; tool: ${event.toolName ?? 'unknown'}`}${event.status === undefined ? '' : `; status: ${event.status ?? 'unknown'}`}\n\n${details}\n${references}\n`;
|
|
626
|
+
if (bytes(parts.join('')) + bytes(row) > DIAGNOSTIC_LIMITS.markdownBytes - 1024) {
|
|
627
|
+
omitted++;
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
parts.push(row);
|
|
631
|
+
}
|
|
632
|
+
parts.push(`\nExport omissions: at least ${document.header.omittedEvents} retained-history events and ${document.header.omittedTextBytes} text bytes; ${omitted} additional events omitted from Markdown. JSONL contains the retained event records. Truncated/unavailable content requires its original retained source, not its digest alone.\n`);
|
|
633
|
+
return parts.join('');
|
|
634
|
+
}
|