@gajae-code/coding-agent 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -2
- package/dist/types/append-only-mode.d.ts +1 -1
- package/dist/types/cli/args.d.ts +4 -5
- package/dist/types/cli/daemon-cli.d.ts +12 -1
- package/dist/types/cli/notify-cli.d.ts +21 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +39 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/commands/notify.d.ts +28 -1
- package/dist/types/commands/sdk.d.ts +33 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
- package/dist/types/config/model-profile-activation.d.ts +35 -15
- package/dist/types/config/model-profiles.d.ts +11 -5
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/model-resolver.d.ts +39 -6
- package/dist/types/config/model-selector-value.d.ts +17 -0
- package/dist/types/config/models-config-schema.d.ts +10 -6
- package/dist/types/config/settings-schema.d.ts +133 -6
- package/dist/types/config/settings.d.ts +63 -35
- package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
- package/dist/types/coordinator-mcp/server.d.ts +6 -49
- package/dist/types/daemon/builtin.d.ts +6 -5
- package/dist/types/daemon/control-types.d.ts +1 -1
- package/dist/types/discovery/mcp-json.d.ts +12 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
- package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
- package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
- package/dist/types/extensibility/extensions/loader.d.ts +10 -1
- package/dist/types/extensibility/extensions/runner.d.ts +3 -3
- package/dist/types/extensibility/extensions/types.d.ts +141 -16
- package/dist/types/extensibility/hooks/types.d.ts +1 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
- package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
- package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
- package/dist/types/harness-control-plane/operate.d.ts +5 -5
- package/dist/types/harness-control-plane/owner.d.ts +18 -4
- package/dist/types/harness-control-plane/receipts.d.ts +0 -1
- package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
- package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
- package/dist/types/harness-control-plane/types.d.ts +3 -4
- package/dist/types/lsp/index.d.ts +1 -1
- package/dist/types/main.d.ts +32 -38
- package/dist/types/modes/acp/acp-agent.d.ts +224 -53
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
- package/dist/types/modes/acp/acp-mode.d.ts +6 -15
- package/dist/types/modes/acp/permission-mode.d.ts +4 -0
- package/dist/types/modes/acp/startup-options.d.ts +6 -0
- package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +1 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
- package/dist/types/modes/components/pet-capability.d.ts +37 -0
- package/dist/types/modes/components/pet-selector.d.ts +1 -1
- package/dist/types/modes/components/settings-selector.d.ts +15 -4
- package/dist/types/modes/components/welcome.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
- package/dist/types/modes/index.d.ts +0 -4
- package/dist/types/modes/interactive-mode.d.ts +5 -1
- package/dist/types/modes/runtime-init.d.ts +2 -2
- package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
- package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
- package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
- package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
- package/dist/types/modes/types.d.ts +16 -1
- package/dist/types/runtime-mcp/client.d.ts +2 -0
- package/dist/types/runtime-mcp/config.d.ts +5 -1
- package/dist/types/runtime-mcp/manager.d.ts +8 -1
- package/dist/types/runtime-mcp/types.d.ts +4 -0
- package/dist/types/sdk/acp/adapter.d.ts +67 -0
- package/dist/types/sdk/acp/index.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +53 -0
- package/dist/types/sdk/broker/discovery.d.ts +30 -0
- package/dist/types/sdk/broker/ensure.d.ts +33 -0
- package/dist/types/sdk/broker/identity.d.ts +3 -0
- package/dist/types/sdk/broker/index.d.ts +8 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
- package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
- package/dist/types/sdk/broker/runtime.d.ts +33 -0
- package/dist/types/sdk/broker/session-index.d.ts +57 -0
- package/dist/types/sdk/broker/state-version.d.ts +8 -0
- package/dist/types/sdk/broker/transport.d.ts +9 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
- package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
- package/dist/types/sdk/bus/config.d.ts +274 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
- package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
- package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
- package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
- package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
- package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
- package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
- package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
- package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
- package/dist/types/sdk/bus/session-control.d.ts +83 -0
- package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
- package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
- package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
- package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
- package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
- package/dist/types/sdk/cli/index.d.ts +1 -0
- package/dist/types/sdk/cli/session-cli.d.ts +19 -0
- package/dist/types/sdk/client/client.d.ts +1 -0
- package/dist/types/sdk/client/discovery.d.ts +27 -0
- package/dist/types/sdk/client/index.d.ts +2 -0
- package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
- package/dist/types/sdk/host/control/index.d.ts +2 -0
- package/dist/types/sdk/host/control/operations.d.ts +65 -0
- package/dist/types/sdk/host/events.d.ts +35 -0
- package/dist/types/sdk/host/host.d.ts +35 -0
- package/dist/types/sdk/host/index.d.ts +4 -0
- package/dist/types/sdk/host/query/cursor.d.ts +62 -0
- package/dist/types/sdk/host/query/handlers.d.ts +70 -0
- package/dist/types/sdk/host/query/index.d.ts +3 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
- package/dist/types/sdk/host/types.d.ts +32 -0
- package/dist/types/sdk/index.d.ts +6 -0
- package/dist/types/sdk/lifecycle-session.d.ts +14 -0
- package/dist/types/sdk/mcp/index.d.ts +1 -0
- package/dist/types/sdk/mcp/server.d.ts +37 -0
- package/dist/types/sdk/models.d.ts +44 -0
- package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
- package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
- package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
- package/dist/types/sdk/startup-capability.d.ts +50 -0
- package/dist/types/session/agent-session.d.ts +114 -21
- package/dist/types/session/default-model-selection.d.ts +25 -0
- package/dist/types/session/fallback-chain-controller.d.ts +52 -0
- package/dist/types/session/session-manager.d.ts +58 -1
- package/dist/types/setup/credential-auto-import.d.ts +36 -6
- package/dist/types/tools/ask-answer-registry.d.ts +1 -1
- package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
- package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
- package/dist/types/tools/browser/launch.d.ts +22 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
- package/dist/types/tools/browser/profile-posture.d.ts +37 -0
- package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
- package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
- package/dist/types/tools/browser/registry.d.ts +19 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
- package/dist/types/tools/index.d.ts +8 -8
- package/package.json +34 -13
- package/scripts/build-sdk-package-smoke.ts +94 -0
- package/scripts/capture-notifications-settings-showcase.ts +435 -0
- package/scripts/compile-args.ts +4 -2
- package/scripts/g005-daemon-smoke.ts +4 -5
- package/scripts/g011-daemon-path-smoke.ts +5 -5
- package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
- package/scripts/generate-sdk-operation-inventory.ts +867 -0
- package/scripts/generate-telegram-baseline-manifest.ts +128 -0
- package/scripts/manifest-schema.ts +124 -0
- package/scripts/run-test-manifest.ts +153 -0
- package/scripts/run-threat-model-check.ts +157 -0
- package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
- package/scripts/verify-gjc-sdk-rename.ts +90 -0
- package/src/append-only-mode.ts +1 -1
- package/src/cli/args.ts +43 -12
- package/src/cli/auth-gateway-cli.ts +2 -2
- package/src/cli/config-cli.ts +2 -1
- package/src/cli/daemon-cli.ts +63 -14
- package/src/cli/list-models.ts +1 -1
- package/src/cli/notify-cli.ts +288 -286
- package/src/cli.ts +21 -2
- package/src/commands/daemon.ts +50 -6
- package/src/commands/harness.ts +93 -36
- package/src/commands/launch.ts +5 -2
- package/src/commands/mcp-serve.ts +19 -12
- package/src/commands/notify.ts +36 -3
- package/src/commands/sdk.ts +426 -0
- package/src/commit/agentic/agent.ts +1 -0
- package/src/config/atomic-yaml-patch.ts +423 -0
- package/src/config/model-profile-activation.ts +240 -89
- package/src/config/model-profiles.ts +37 -34
- package/src/config/model-registry.ts +51 -26
- package/src/config/model-resolver.ts +138 -51
- package/src/config/model-selector-value.ts +50 -0
- package/src/config/models-config-schema.ts +14 -21
- package/src/config/settings-schema.ts +128 -10
- package/src/config/settings.ts +1120 -158
- package/src/coordinator-mcp/model-preset.ts +74 -20
- package/src/coordinator-mcp/server.ts +1597 -3052
- package/src/daemon/builtin.ts +8 -5
- package/src/daemon/control-types.ts +1 -1
- package/src/defaults/gjc/skills/team/SKILL.md +4 -4
- package/src/discovery/mcp-json.ts +327 -20
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/compact-handler.ts +3 -3
- package/src/extensibility/extensions/get-commands-handler.ts +2 -2
- package/src/extensibility/extensions/loader.ts +69 -5
- package/src/extensibility/extensions/runner.ts +112 -4
- package/src/extensibility/extensions/types.ts +176 -17
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/extensibility/slash-commands.ts +3 -3
- package/src/gjc-runtime/launch-tmux.ts +170 -86
- package/src/gjc-runtime/psmux-detect.ts +82 -4
- package/src/gjc-runtime/session-state-sidecar.ts +41 -31
- package/src/gjc-runtime/team-runtime.ts +54 -35
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -2
- package/src/gjc-runtime/tmux-sessions.ts +19 -13
- package/src/gjc-runtime/ultragoal-guard.ts +53 -6
- package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
- package/src/gjc-runtime/windows-powershell-command.ts +58 -0
- package/src/harness-control-plane/operate.ts +9 -9
- package/src/harness-control-plane/owner.ts +283 -39
- package/src/harness-control-plane/receipts.ts +0 -1
- package/src/harness-control-plane/sdk-transport.ts +395 -0
- package/src/harness-control-plane/session-transport.ts +94 -0
- package/src/harness-control-plane/types.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +36 -37
- package/src/lsp/client.ts +42 -6
- package/src/lsp/index.ts +2 -2
- package/src/main.ts +299 -204
- package/src/modes/DESIGN.md +258 -0
- package/src/modes/acp/acp-agent.ts +1228 -2612
- package/src/modes/acp/acp-client-bridge.ts +2 -20
- package/src/modes/acp/acp-event-mapper.ts +18 -2
- package/src/modes/acp/acp-mode.ts +8 -36
- package/src/modes/acp/permission-mode.ts +25 -0
- package/src/modes/acp/startup-options.ts +6 -0
- package/src/modes/components/agent-dashboard.ts +37 -17
- package/src/modes/components/custom-editor.ts +1 -0
- package/src/modes/components/gajae-pet-widget.ts +169 -20
- package/src/modes/components/model-selector.ts +93 -35
- package/src/modes/components/notifications-settings-editor.ts +1379 -0
- package/src/modes/components/pet-capability.ts +115 -0
- package/src/modes/components/pet-selector.ts +4 -6
- package/src/modes/components/settings-selector.ts +86 -11
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +1 -2
- package/src/modes/controllers/event-controller.ts +11 -16
- package/src/modes/controllers/extension-ui-controller.ts +357 -12
- package/src/modes/controllers/input-controller.ts +43 -13
- package/src/modes/controllers/selector-controller.ts +671 -44
- package/src/modes/index.ts +0 -22
- package/src/modes/interactive-mode.ts +108 -24
- package/src/modes/runtime-init.ts +298 -6
- package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
- package/src/modes/shared/agent-wire/event-contract.ts +7 -8
- package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
- package/src/modes/shared/agent-wire/event-observation.ts +16 -7
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
- package/src/modes/types.ts +16 -1
- package/src/runtime-mcp/client.ts +94 -19
- package/src/runtime-mcp/config.ts +27 -15
- package/src/runtime-mcp/manager.ts +343 -105
- package/src/runtime-mcp/oauth-flow.ts +42 -12
- package/src/runtime-mcp/transports/http.ts +49 -19
- package/src/runtime-mcp/transports/stdio.ts +47 -28
- package/src/runtime-mcp/types.ts +10 -0
- package/src/sdk/acp/adapter.ts +418 -0
- package/src/sdk/acp/index.ts +2 -0
- package/src/sdk/broker/broker.ts +642 -0
- package/src/sdk/broker/discovery.ts +94 -0
- package/src/sdk/broker/ensure.ts +249 -0
- package/src/sdk/broker/identity.ts +42 -0
- package/src/sdk/broker/index.ts +8 -0
- package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
- package/src/sdk/broker/internal-source.bunfig.toml +1 -0
- package/src/sdk/broker/lifecycle-ledger.ts +286 -0
- package/src/sdk/broker/lifecycle.ts +2157 -0
- package/src/sdk/broker/process-incarnation.ts +159 -0
- package/src/sdk/broker/runtime.ts +164 -0
- package/src/sdk/broker/session-index.ts +318 -0
- package/src/sdk/broker/state-version.ts +23 -0
- package/src/sdk/broker/transport.ts +125 -0
- package/src/sdk/bus/chat-command-policy.ts +107 -0
- package/src/sdk/bus/chat-daemon-cli.ts +214 -0
- package/src/sdk/bus/chat-daemon-control.ts +713 -0
- package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
- package/src/sdk/bus/chat-effect-journal.ts +353 -0
- package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
- package/src/sdk/bus/config.ts +433 -0
- package/src/sdk/bus/conversation-store.ts +391 -0
- package/src/sdk/bus/discord-conversation.ts +85 -0
- package/src/sdk/bus/discord-daemon.ts +2275 -0
- package/src/sdk/bus/discord-live-provider.ts +521 -0
- package/src/sdk/bus/discord-provider.ts +56 -0
- package/src/{notifications → sdk/bus}/html-format.ts +2 -2
- package/src/sdk/bus/index.ts +3943 -0
- package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
- package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
- package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
- package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
- package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
- package/src/sdk/bus/natives-augment.d.ts +38 -0
- package/src/sdk/bus/notification-orchestration.ts +535 -0
- package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
- package/src/sdk/bus/session-control.ts +333 -0
- package/src/sdk/bus/slack-conversation.ts +74 -0
- package/src/sdk/bus/slack-daemon.ts +2144 -0
- package/src/sdk/bus/slack-live-provider.ts +380 -0
- package/src/sdk/bus/slack-provider.ts +76 -0
- package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
- package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
- package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
- package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
- package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
- package/src/sdk/bus/telegram-setup.ts +663 -0
- package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
- package/src/sdk/cli/index.ts +1 -0
- package/src/sdk/cli/session-cli.ts +275 -0
- package/src/sdk/client/client.ts +1 -0
- package/src/sdk/client/discovery.ts +108 -0
- package/src/sdk/client/index.ts +2 -0
- package/src/sdk/host/control/dispatch.ts +367 -0
- package/src/sdk/host/control/index.ts +10 -0
- package/src/sdk/host/control/operations.ts +63 -0
- package/src/sdk/host/events.ts +91 -0
- package/src/sdk/host/host.ts +296 -0
- package/src/sdk/host/index.ts +4 -0
- package/src/sdk/host/query/cursor.ts +189 -0
- package/src/sdk/host/query/handlers.ts +533 -0
- package/src/sdk/host/query/index.ts +3 -0
- package/src/sdk/host/query/revision-store.ts +1126 -0
- package/src/sdk/host/reverse-leases.ts +325 -0
- package/src/sdk/host/types.ts +29 -0
- package/src/sdk/index.ts +13 -0
- package/src/sdk/lifecycle-session.ts +39 -0
- package/src/sdk/mcp/index.ts +1 -0
- package/src/sdk/mcp/server.ts +332 -0
- package/src/sdk/models.ts +168 -0
- package/src/sdk/protocol/adapter-validation.ts +48 -0
- package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
- package/src/sdk/protocol/operation-registry.ts +312 -0
- package/src/{sdk.ts → sdk/session.ts} +339 -212
- package/src/sdk/startup-capability.ts +189 -0
- package/src/session/agent-session.ts +2470 -866
- package/src/session/default-model-selection.ts +93 -0
- package/src/session/fallback-chain-controller.ts +136 -0
- package/src/session/session-manager.ts +447 -13
- package/src/session/session-storage.ts +8 -1
- package/src/setup/credential-auto-import.ts +290 -35
- package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
- package/src/slash-commands/builtin-registry.ts +33 -30
- package/src/task/executor.ts +62 -13
- package/src/tools/ask-answer-registry.ts +1 -1
- package/src/tools/ask.ts +13 -8
- package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
- package/src/tools/browser/benchmark/detector-report.ts +157 -0
- package/src/tools/browser/benchmark/run-suite.ts +39 -0
- package/src/tools/browser/launch.ts +124 -19
- package/src/tools/browser/profile-discovery.ts +63 -0
- package/src/tools/browser/profile-posture.ts +59 -0
- package/src/tools/browser/profile-reuse.ts +102 -0
- package/src/tools/browser/profile-warmup.ts +109 -0
- package/src/tools/browser/registry.ts +87 -11
- package/src/tools/browser/tab-protocol.ts +1 -0
- package/src/tools/browser/tab-supervisor.ts +1 -0
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/browser.ts +6 -0
- package/src/tools/index.ts +8 -8
- package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
- package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
- package/src/tools/telegram-send.ts +2 -2
- package/vendor/insane-search/MANIFEST.json +2 -1
- package/vendor/insane-search/engine/bias_check.py +4 -1
- package/vendor/insane-search/engine/phase0.py +26 -1
- package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
- package/dist/types/modes/bridge/auth.d.ts +0 -12
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
- package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
- package/dist/types/modes/bridge/event-stream.d.ts +0 -8
- package/dist/types/modes/rpc/host-tools.d.ts +0 -1
- package/dist/types/modes/rpc/host-uris.d.ts +0 -1
- package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
- package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
- package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
- package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
- package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
- package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
- package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
- package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
- package/dist/types/notifications/config.d.ts +0 -132
- package/src/harness-control-plane/rpc-adapter.ts +0 -290
- package/src/modes/bridge/auth.ts +0 -41
- package/src/modes/bridge/bridge-client-bridge.ts +0 -47
- package/src/modes/bridge/bridge-mode.ts +0 -675
- package/src/modes/bridge/bridge-ui-context.ts +0 -200
- package/src/modes/bridge/event-stream.ts +0 -70
- package/src/modes/rpc/host-tools.ts +0 -1
- package/src/modes/rpc/host-uris.ts +0 -1
- package/src/modes/rpc/rpc-client.ts +0 -1166
- package/src/modes/rpc/rpc-mode.ts +0 -1029
- package/src/modes/rpc/rpc-socket-security.ts +0 -115
- package/src/modes/rpc/rpc-types.ts +0 -637
- package/src/modes/shared/agent-wire/command-contract.ts +0 -18
- package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
- package/src/modes/shared/agent-wire/command-validation.ts +0 -181
- package/src/modes/shared/agent-wire/handshake.ts +0 -157
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
- package/src/modes/shared/agent-wire/protocol.ts +0 -46
- package/src/modes/shared/agent-wire/responses.ts +0 -17
- package/src/modes/shared/agent-wire/scopes.ts +0 -94
- package/src/modes/shared/agent-wire/session-registry.ts +0 -109
- package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
- package/src/modes/shared/agent-wire/ui-result.ts +0 -48
- package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
- package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
- package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
- package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
- package/src/notifications/config.ts +0 -219
- package/src/notifications/index.ts +0 -1835
- package/src/notifications/telegram-daemon-cli.ts +0 -243
- package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
- /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
- /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
- /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
- /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
- /package/src/{notifications → sdk/bus}/engine.ts +0 -0
- /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
- /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
- /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
- /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
- /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
|
@@ -1,426 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unattended run controller (#318).
|
|
3
|
-
*
|
|
4
|
-
* The single required owner of negotiated unattended state. Entering unattended
|
|
5
|
-
* mode is fail-closed: a controller can only be created via {@link
|
|
6
|
-
* UnattendedRunController.negotiate}, which rejects a missing/partial budget, an
|
|
7
|
-
* invalid declaration, or a provider that cannot account for tokens/cost.
|
|
8
|
-
*
|
|
9
|
-
* The controller owns budget accounting across metrics and phases. Scope/action
|
|
10
|
-
* authorization (#319) and the durable audit trail (#320) layer onto the same
|
|
11
|
-
* controller; this slice wires the budget floor and abort coordination.
|
|
12
|
-
*
|
|
13
|
-
* Attended mode never constructs a controller, so by construction the attended
|
|
14
|
-
* path is unaffected by everything here.
|
|
15
|
-
*/
|
|
16
|
-
import type {
|
|
17
|
-
RpcActionDenied,
|
|
18
|
-
RpcBudgetExceeded,
|
|
19
|
-
RpcBudgetMetric,
|
|
20
|
-
RpcScopeDenied,
|
|
21
|
-
RpcUnattendedActionClass,
|
|
22
|
-
RpcUnattendedBudget,
|
|
23
|
-
RpcUnattendedDeclaration,
|
|
24
|
-
RpcUnattendedRefusalCode,
|
|
25
|
-
} from "../../rpc/rpc-types";
|
|
26
|
-
import type { BridgeCommandScope } from "./scopes";
|
|
27
|
-
import { BRIDGE_COMMAND_SCOPES, MANDATORY_FLOOR_COMMAND_SCOPES } from "./scopes";
|
|
28
|
-
import { actionClassForScope, classifyBashAction, RPC_UNATTENDED_ACTION_CLASSES } from "./unattended-action-policy";
|
|
29
|
-
|
|
30
|
-
/** Coordinated abort surfaces invoked exactly once on a budget breach / abort. */
|
|
31
|
-
export interface UnattendedAbortHooks {
|
|
32
|
-
abortModelStream?(): void | Promise<void>;
|
|
33
|
-
abortBash?(): void | Promise<void>;
|
|
34
|
-
cancelHostTools?(reason: string): void | Promise<void>;
|
|
35
|
-
cancelHostUris?(reason: string): void | Promise<void>;
|
|
36
|
-
stopWorkflow?(reason: string): void | Promise<void>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export type UnattendedAuditEvent =
|
|
40
|
-
| { event: "unattended_negotiated"; run_id: string; actor: string }
|
|
41
|
-
| { event: "budget_exceeded"; payload: RpcBudgetExceeded }
|
|
42
|
-
| { event: "unattended_aborted"; run_id: string; reason: string }
|
|
43
|
-
| { event: "unattended_abort_settled"; run_id: string; status: "aborted" | "abort_failed"; failures: number }
|
|
44
|
-
| { event: "scope_denied"; payload: RpcScopeDenied }
|
|
45
|
-
| { event: "action_denied"; payload: RpcActionDenied };
|
|
46
|
-
|
|
47
|
-
export interface NegotiateContext {
|
|
48
|
-
runId: string;
|
|
49
|
-
sessionId?: string;
|
|
50
|
-
audit?(event: UnattendedAuditEvent): void;
|
|
51
|
-
abortHooks?: UnattendedAbortHooks;
|
|
52
|
-
/**
|
|
53
|
-
* Whether the active provider can report token usage and cost. Unattended
|
|
54
|
-
* mode rejects providers without this accounting up front (fail-closed).
|
|
55
|
-
*/
|
|
56
|
-
providerSupportsTokenCostMetrics?: boolean;
|
|
57
|
-
/** Injectable clock for deterministic tests. Defaults to Date.now. */
|
|
58
|
-
now?(): number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export class UnattendedNegotiationError extends Error {
|
|
62
|
-
constructor(
|
|
63
|
-
readonly code: RpcUnattendedRefusalCode,
|
|
64
|
-
message: string,
|
|
65
|
-
) {
|
|
66
|
-
super(message);
|
|
67
|
-
this.name = "UnattendedNegotiationError";
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export class UnattendedBudgetExceededError extends Error {
|
|
72
|
-
constructor(readonly payload: RpcBudgetExceeded) {
|
|
73
|
-
super(`budget_exceeded: ${payload.metric} ${payload.observed}/${payload.limit} at ${payload.phase}`);
|
|
74
|
-
this.name = "UnattendedBudgetExceededError";
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Thrown when a provider/tool reports a non-finite usage value (fail-closed). */
|
|
79
|
-
export class UnattendedAccountingError extends Error {
|
|
80
|
-
constructor(
|
|
81
|
-
readonly metric: RpcBudgetMetric,
|
|
82
|
-
readonly phase: string,
|
|
83
|
-
value: unknown,
|
|
84
|
-
) {
|
|
85
|
-
super(`non-finite ${metric} usage (${String(value)}) at ${phase}`);
|
|
86
|
-
this.name = "UnattendedAccountingError";
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Thrown when a command's coarse scope is outside the declared allowlist (#319). */
|
|
91
|
-
export class ScopeDeniedError extends Error {
|
|
92
|
-
constructor(readonly payload: RpcScopeDenied) {
|
|
93
|
-
super(`scope_denied: ${payload.scope}${payload.command ? ` (${payload.command})` : ""}`);
|
|
94
|
-
this.name = "ScopeDeniedError";
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** Thrown when an action class is outside the declared allowlist (default-deny, #319). */
|
|
99
|
-
export class ActionDeniedError extends Error {
|
|
100
|
-
constructor(readonly payload: RpcActionDenied) {
|
|
101
|
-
super(`action_denied: ${payload.action}${payload.command ? ` (${payload.command})` : ""}`);
|
|
102
|
-
this.name = "ActionDeniedError";
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
interface Usage {
|
|
107
|
-
tokens: number;
|
|
108
|
-
toolCalls: number;
|
|
109
|
-
costUsd: number;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function isPositiveFiniteNumber(v: unknown): v is number {
|
|
113
|
-
return typeof v === "number" && Number.isFinite(v) && v > 0;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function validateBudget(budget: unknown): RpcUnattendedBudget {
|
|
117
|
-
if (typeof budget !== "object" || budget === null) {
|
|
118
|
-
throw new UnattendedNegotiationError("incomplete_budget", "budget declaration is required for unattended mode");
|
|
119
|
-
}
|
|
120
|
-
const b = budget as Record<string, unknown>;
|
|
121
|
-
const fields: Array<keyof RpcUnattendedBudget> = [
|
|
122
|
-
"max_tokens",
|
|
123
|
-
"max_tool_calls",
|
|
124
|
-
"max_wall_time_ms",
|
|
125
|
-
"max_cost_usd",
|
|
126
|
-
];
|
|
127
|
-
for (const f of fields) {
|
|
128
|
-
if (!isPositiveFiniteNumber(b[f])) {
|
|
129
|
-
throw new UnattendedNegotiationError("incomplete_budget", `budget.${f} must be a positive finite number`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
max_tokens: b.max_tokens as number,
|
|
134
|
-
max_tool_calls: b.max_tool_calls as number,
|
|
135
|
-
max_wall_time_ms: b.max_wall_time_ms as number,
|
|
136
|
-
max_cost_usd: b.max_cost_usd as number,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export class UnattendedRunController {
|
|
141
|
-
readonly runId: string;
|
|
142
|
-
readonly sessionId?: string;
|
|
143
|
-
readonly actor: string;
|
|
144
|
-
readonly budget: RpcUnattendedBudget;
|
|
145
|
-
readonly scopes: ReadonlySet<string>;
|
|
146
|
-
readonly actionAllowlist: ReadonlySet<string>;
|
|
147
|
-
|
|
148
|
-
private readonly usage: Usage = { tokens: 0, toolCalls: 0, costUsd: 0 };
|
|
149
|
-
private readonly startedAt: number;
|
|
150
|
-
private readonly now: () => number;
|
|
151
|
-
private readonly audit?: (event: UnattendedAuditEvent) => void;
|
|
152
|
-
private readonly abortHooks: UnattendedAbortHooks;
|
|
153
|
-
private aborted = false;
|
|
154
|
-
private abortPromise?: Promise<void>;
|
|
155
|
-
|
|
156
|
-
private constructor(declaration: RpcUnattendedDeclaration, ctx: NegotiateContext, budget: RpcUnattendedBudget) {
|
|
157
|
-
this.runId = ctx.runId;
|
|
158
|
-
this.sessionId = ctx.sessionId;
|
|
159
|
-
this.actor = declaration.actor;
|
|
160
|
-
this.budget = budget;
|
|
161
|
-
this.scopes = new Set([...declaration.scopes, ...MANDATORY_FLOOR_COMMAND_SCOPES]);
|
|
162
|
-
this.actionAllowlist = new Set([
|
|
163
|
-
...declaration.action_allowlist,
|
|
164
|
-
...MANDATORY_FLOOR_COMMAND_SCOPES.map(actionClassForScope),
|
|
165
|
-
]);
|
|
166
|
-
this.now = ctx.now ?? Date.now;
|
|
167
|
-
this.audit = ctx.audit;
|
|
168
|
-
this.abortHooks = ctx.abortHooks ?? {};
|
|
169
|
-
this.startedAt = this.now();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/** Fail-closed entry: validate the declaration + budget, or throw. */
|
|
173
|
-
static negotiate(declaration: unknown, ctx: NegotiateContext): UnattendedRunController {
|
|
174
|
-
if (typeof declaration !== "object" || declaration === null) {
|
|
175
|
-
throw new UnattendedNegotiationError("invalid_unattended_declaration", "declaration is required");
|
|
176
|
-
}
|
|
177
|
-
const d = declaration as Record<string, unknown>;
|
|
178
|
-
if (typeof d.actor !== "string" || d.actor.trim() === "") {
|
|
179
|
-
throw new UnattendedNegotiationError("invalid_unattended_declaration", "declaration.actor is required");
|
|
180
|
-
}
|
|
181
|
-
if (!Array.isArray(d.scopes) || !d.scopes.every(s => typeof s === "string")) {
|
|
182
|
-
throw new UnattendedNegotiationError("invalid_unattended_declaration", "declaration.scopes must be string[]");
|
|
183
|
-
}
|
|
184
|
-
if (!Array.isArray(d.action_allowlist) || !d.action_allowlist.every(s => typeof s === "string")) {
|
|
185
|
-
throw new UnattendedNegotiationError(
|
|
186
|
-
"invalid_unattended_declaration",
|
|
187
|
-
"declaration.action_allowlist must be string[]",
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
const unknownScopes = d.scopes.filter(scope => !BRIDGE_COMMAND_SCOPES.includes(scope as BridgeCommandScope));
|
|
191
|
-
if (unknownScopes.length > 0) {
|
|
192
|
-
throw new UnattendedNegotiationError(
|
|
193
|
-
"invalid_unattended_declaration",
|
|
194
|
-
`declaration.scopes contains unknown scope(s): ${unknownScopes.join(", ")}`,
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
const unknownActions = d.action_allowlist.filter(
|
|
198
|
-
action => !RPC_UNATTENDED_ACTION_CLASSES.includes(action as RpcUnattendedActionClass),
|
|
199
|
-
);
|
|
200
|
-
if (unknownActions.length > 0) {
|
|
201
|
-
throw new UnattendedNegotiationError(
|
|
202
|
-
"invalid_unattended_declaration",
|
|
203
|
-
`declaration.action_allowlist contains unknown action class(es): ${unknownActions.join(", ")}`,
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
const budget = validateBudget(d.budget);
|
|
207
|
-
// Reject providers that cannot account for tokens/cost (fail-closed): require
|
|
208
|
-
// an explicit positive capability signal — omitted/unknown is refused too.
|
|
209
|
-
if (ctx.providerSupportsTokenCostMetrics !== true) {
|
|
210
|
-
throw new UnattendedNegotiationError(
|
|
211
|
-
"unsupported_budget_metric",
|
|
212
|
-
"unattended mode requires an explicit provider token/cost accounting capability",
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
const controller = new UnattendedRunController(d as unknown as RpcUnattendedDeclaration, ctx, budget);
|
|
216
|
-
ctx.audit?.({ event: "unattended_negotiated", run_id: ctx.runId, actor: controller.actor });
|
|
217
|
-
return controller;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
get isAborted(): boolean {
|
|
221
|
-
return this.aborted;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
usageSnapshot(): Readonly<Usage> & { wallTimeMs: number } {
|
|
225
|
-
return { ...this.usage, wallTimeMs: this.now() - this.startedAt };
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
remainingWallTimeMs(): number {
|
|
229
|
-
return Math.max(0, this.budget.max_wall_time_ms - (this.now() - this.startedAt));
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Authorize a command's coarse scope against the declared allowlist. Throws
|
|
234
|
-
* ScopeDeniedError (pre-side-effect) when the scope was not declared.
|
|
235
|
-
*/
|
|
236
|
-
authorizeScope(scope: BridgeCommandScope, command?: string): void {
|
|
237
|
-
if (this.scopes.has(scope)) return;
|
|
238
|
-
const payload: RpcScopeDenied = {
|
|
239
|
-
code: "scope_denied",
|
|
240
|
-
scope,
|
|
241
|
-
command,
|
|
242
|
-
run_id: this.runId,
|
|
243
|
-
session_id: this.sessionId,
|
|
244
|
-
pre_side_effect: true,
|
|
245
|
-
};
|
|
246
|
-
this.audit?.({ event: "scope_denied", payload });
|
|
247
|
-
throw new ScopeDeniedError(payload);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Authorize an action class against the declared allowlist. Default-deny: any
|
|
252
|
-
* class not explicitly declared is rejected with ActionDeniedError before the
|
|
253
|
-
* side effect runs.
|
|
254
|
-
*/
|
|
255
|
-
authorizeAction(action: RpcUnattendedActionClass, command?: string): void {
|
|
256
|
-
if (this.actionAllowlist.has(action)) return;
|
|
257
|
-
const payload: RpcActionDenied = {
|
|
258
|
-
code: "action_denied",
|
|
259
|
-
action,
|
|
260
|
-
command,
|
|
261
|
-
run_id: this.runId,
|
|
262
|
-
session_id: this.sessionId,
|
|
263
|
-
pre_side_effect: true,
|
|
264
|
-
};
|
|
265
|
-
this.audit?.({ event: "action_denied", payload });
|
|
266
|
-
throw new ActionDeniedError(payload);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Classify a bash command and authorize the resulting action class BEFORE the
|
|
271
|
-
* command is executed. Returns the classified action class on success.
|
|
272
|
-
*/
|
|
273
|
-
authorizeBash(command: string): RpcUnattendedActionClass {
|
|
274
|
-
this.authorizeScope("bash", command);
|
|
275
|
-
const action = classifyBashAction(command);
|
|
276
|
-
this.authorizeAction(action, command);
|
|
277
|
-
return action;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/** Convenience: map a coarse scope to its `command.<scope>` action class. */
|
|
281
|
-
static actionClassForScope = actionClassForScope;
|
|
282
|
-
|
|
283
|
-
/** Pre-turn estimate: refuse to start a turn that would obviously breach. */
|
|
284
|
-
preTurnEstimate(estimate: { tokens?: number; costUsd?: number }): void {
|
|
285
|
-
this.checkWallTime("pre-turn estimate");
|
|
286
|
-
if (estimate.tokens !== undefined) {
|
|
287
|
-
if (!Number.isFinite(estimate.tokens)) {
|
|
288
|
-
void this.fireAbort("accounting:tokens");
|
|
289
|
-
throw new UnattendedAccountingError("tokens", "pre-turn estimate", estimate.tokens);
|
|
290
|
-
}
|
|
291
|
-
if (this.usage.tokens + estimate.tokens > this.budget.max_tokens) {
|
|
292
|
-
this.breach("tokens", this.budget.max_tokens, this.usage.tokens + estimate.tokens, "pre-turn estimate");
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
if (estimate.costUsd !== undefined) {
|
|
296
|
-
if (!Number.isFinite(estimate.costUsd)) {
|
|
297
|
-
void this.fireAbort("accounting:cost");
|
|
298
|
-
throw new UnattendedAccountingError("cost", "pre-turn estimate", estimate.costUsd);
|
|
299
|
-
}
|
|
300
|
-
if (this.usage.costUsd + estimate.costUsd > this.budget.max_cost_usd) {
|
|
301
|
-
this.breach("cost", this.budget.max_cost_usd, this.usage.costUsd + estimate.costUsd, "pre-turn estimate");
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/** Reserve one tool-call unit BEFORE any side effect; breach if it would exceed. */
|
|
307
|
-
preflightToolCall(phase = "tool-call preflight"): void {
|
|
308
|
-
this.checkWallTime(phase);
|
|
309
|
-
if (this.usage.toolCalls + 1 > this.budget.max_tool_calls) {
|
|
310
|
-
this.breach("tool_calls", this.budget.max_tool_calls, this.usage.toolCalls + 1, phase);
|
|
311
|
-
}
|
|
312
|
-
this.usage.toolCalls += 1;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/** Post-turn reconciliation of actual token usage. Fails closed on non-finite. */
|
|
316
|
-
recordTokens(tokens: number, phase = "post-turn reconciliation"): void {
|
|
317
|
-
if (!Number.isFinite(tokens)) {
|
|
318
|
-
void this.fireAbort(`accounting:tokens`);
|
|
319
|
-
throw new UnattendedAccountingError("tokens", phase, tokens);
|
|
320
|
-
}
|
|
321
|
-
this.usage.tokens += Math.max(0, tokens);
|
|
322
|
-
if (this.usage.tokens > this.budget.max_tokens) {
|
|
323
|
-
this.breach("tokens", this.budget.max_tokens, this.usage.tokens, phase);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
recordCost(costUsd: number, phase = "post-turn reconciliation"): void {
|
|
328
|
-
if (!Number.isFinite(costUsd)) {
|
|
329
|
-
void this.fireAbort(`accounting:cost`);
|
|
330
|
-
throw new UnattendedAccountingError("cost", phase, costUsd);
|
|
331
|
-
}
|
|
332
|
-
this.usage.costUsd += Math.max(0, costUsd);
|
|
333
|
-
if (this.usage.costUsd > this.budget.max_cost_usd) {
|
|
334
|
-
this.breach("cost", this.budget.max_cost_usd, this.usage.costUsd, phase);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/** Combined post-turn reconciliation. */
|
|
339
|
-
reconcile(actual: { tokens?: number; costUsd?: number }, phase = "post-turn reconciliation"): void {
|
|
340
|
-
if (actual.tokens !== undefined) this.recordTokens(actual.tokens, phase);
|
|
341
|
-
if (actual.costUsd !== undefined) this.recordCost(actual.costUsd, phase);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/** Wall-time check; call before/inside long operations. */
|
|
345
|
-
checkWallTime(phase = "wall-time"): void {
|
|
346
|
-
const elapsed = this.now() - this.startedAt;
|
|
347
|
-
if (elapsed > this.budget.max_wall_time_ms) {
|
|
348
|
-
this.breach("wall_time", this.budget.max_wall_time_ms, elapsed, phase);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
private breach(metric: RpcBudgetMetric, limit: number, observed: number, phase: string): never {
|
|
353
|
-
// Initiate the (idempotent, awaitable) abort. breach() throws synchronously,
|
|
354
|
-
// so the payload reports `aborting`; the settled status (aborted/abort_failed)
|
|
355
|
-
// is emitted as an unattended_abort_settled audit event once hooks complete.
|
|
356
|
-
void this.fireAbort(`budget_exceeded:${metric}`);
|
|
357
|
-
const abortStatus: RpcBudgetExceeded["abort_status"] = "aborting";
|
|
358
|
-
const payload: RpcBudgetExceeded = {
|
|
359
|
-
code: "budget_exceeded",
|
|
360
|
-
metric,
|
|
361
|
-
limit,
|
|
362
|
-
observed,
|
|
363
|
-
phase,
|
|
364
|
-
run_id: this.runId,
|
|
365
|
-
session_id: this.sessionId,
|
|
366
|
-
abort_status: abortStatus,
|
|
367
|
-
};
|
|
368
|
-
this.audit?.({ event: "budget_exceeded", payload });
|
|
369
|
-
throw new UnattendedBudgetExceededError(payload);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Idempotent abort: runs every abort hook at most once. Safe to call from the
|
|
374
|
-
* synchronous breach path (which does not await) and from callers that do; both
|
|
375
|
-
* share a single abort promise so hook completion can be awaited deterministically.
|
|
376
|
-
*/
|
|
377
|
-
async abort(reason: string): Promise<void> {
|
|
378
|
-
await this.fireAbort(reason);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/** Returns the in-flight/settled abort completion once aborting has begun. */
|
|
382
|
-
get abortCompletion(): Promise<void> | undefined {
|
|
383
|
-
return this.abortPromise;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
private fireAbort(reason: string): Promise<void> {
|
|
387
|
-
if (this.abortPromise) return this.abortPromise;
|
|
388
|
-
this.aborted = true;
|
|
389
|
-
this.abortPromise = this.runAbortHooks().then(failures => {
|
|
390
|
-
this.audit?.({ event: "unattended_aborted", run_id: this.runId, reason });
|
|
391
|
-
this.audit?.({
|
|
392
|
-
event: "unattended_abort_settled",
|
|
393
|
-
run_id: this.runId,
|
|
394
|
-
status: failures === 0 ? "aborted" : "abort_failed",
|
|
395
|
-
failures,
|
|
396
|
-
});
|
|
397
|
-
});
|
|
398
|
-
return this.abortPromise;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Invoke every configured abort hook exactly once with per-hook isolation, so a
|
|
403
|
-
* failing hook never prevents the other cancellation surfaces from running.
|
|
404
|
-
* Returns the number of hooks that rejected.
|
|
405
|
-
*/
|
|
406
|
-
private async runAbortHooks(): Promise<number> {
|
|
407
|
-
const calls: Array<Promise<unknown>> = [];
|
|
408
|
-
const run = (fn: (() => void | Promise<void>) | undefined) => {
|
|
409
|
-
if (!fn) return;
|
|
410
|
-
// Invoke synchronously so the hook's synchronous prefix runs immediately,
|
|
411
|
-
// but capture sync throws and async rejections so allSettled isolates them.
|
|
412
|
-
try {
|
|
413
|
-
calls.push(Promise.resolve(fn()));
|
|
414
|
-
} catch (err) {
|
|
415
|
-
calls.push(Promise.reject(err));
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
run(this.abortHooks.abortModelStream);
|
|
419
|
-
run(this.abortHooks.abortBash);
|
|
420
|
-
run(() => this.abortHooks.cancelHostTools?.("unattended abort"));
|
|
421
|
-
run(() => this.abortHooks.cancelHostUris?.("unattended abort"));
|
|
422
|
-
run(() => this.abortHooks.stopWorkflow?.("unattended abort"));
|
|
423
|
-
const results = await Promise.allSettled(calls);
|
|
424
|
-
return results.filter(r => r.status === "rejected").length;
|
|
425
|
-
}
|
|
426
|
-
}
|