@alan-ai-hq/agent-manager 0.1.113 → 0.1.115
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/LICENSE +88 -0
- package/dist/__tests__/binding-switch-git.test.d.ts +2 -0
- package/dist/__tests__/binding-switch-git.test.d.ts.map +1 -0
- package/dist/__tests__/binding-switch-git.test.js +555 -0
- package/dist/__tests__/binding-switch-git.test.js.map +1 -0
- package/dist/__tests__/cli-ensure-install.test.d.ts +2 -0
- package/dist/__tests__/cli-ensure-install.test.d.ts.map +1 -0
- package/dist/__tests__/cli-ensure-install.test.js +177 -0
- package/dist/__tests__/cli-ensure-install.test.js.map +1 -0
- package/dist/__tests__/cli-executable.test.d.ts +2 -0
- package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
- package/dist/__tests__/cli-executable.test.js +155 -0
- package/dist/__tests__/cli-executable.test.js.map +1 -0
- package/dist/__tests__/cli-executable.windows.test.d.ts +2 -0
- package/dist/__tests__/cli-executable.windows.test.d.ts.map +1 -0
- package/dist/__tests__/cli-executable.windows.test.js +123 -0
- package/dist/__tests__/cli-executable.windows.test.js.map +1 -0
- package/dist/__tests__/cli-help.test.d.ts +2 -0
- package/dist/__tests__/cli-help.test.d.ts.map +1 -0
- package/dist/__tests__/cli-help.test.js +47 -0
- package/dist/__tests__/cli-help.test.js.map +1 -0
- package/dist/__tests__/computer-readiness.test.d.ts +2 -0
- package/dist/__tests__/computer-readiness.test.d.ts.map +1 -0
- package/dist/__tests__/computer-readiness.test.js +63 -0
- package/dist/__tests__/computer-readiness.test.js.map +1 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.d.ts +2 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.d.ts.map +1 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.js +93 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.js.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.js +139 -0
- package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
- package/dist/__tests__/daemon-native-hooks.test.d.ts +2 -0
- package/dist/__tests__/daemon-native-hooks.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-native-hooks.test.js +94 -0
- package/dist/__tests__/daemon-native-hooks.test.js.map +1 -0
- package/dist/__tests__/daemon-reconcile-ask.test.d.ts +2 -0
- package/dist/__tests__/daemon-reconcile-ask.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-reconcile-ask.test.js +100 -0
- package/dist/__tests__/daemon-reconcile-ask.test.js.map +1 -0
- package/dist/__tests__/daemon-runner-status.test.d.ts +2 -0
- package/dist/__tests__/daemon-runner-status.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-runner-status.test.js +102 -0
- package/dist/__tests__/daemon-runner-status.test.js.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.js +435 -0
- package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
- package/dist/__tests__/daemon.test.d.ts +2 -0
- package/dist/__tests__/daemon.test.d.ts.map +1 -0
- package/dist/__tests__/daemon.test.js +4884 -0
- package/dist/__tests__/daemon.test.js.map +1 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts +2 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts.map +1 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.js +129 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.js.map +1 -0
- package/dist/__tests__/event-journal-stress.test.d.ts +2 -0
- package/dist/__tests__/event-journal-stress.test.d.ts.map +1 -0
- package/dist/__tests__/event-journal-stress.test.js +124 -0
- package/dist/__tests__/event-journal-stress.test.js.map +1 -0
- package/dist/__tests__/event-journal.test.d.ts +2 -0
- package/dist/__tests__/event-journal.test.d.ts.map +1 -0
- package/dist/__tests__/event-journal.test.js +264 -0
- package/dist/__tests__/event-journal.test.js.map +1 -0
- package/dist/__tests__/event-outbox-persist-failure.test.d.ts +2 -0
- package/dist/__tests__/event-outbox-persist-failure.test.d.ts.map +1 -0
- package/dist/__tests__/event-outbox-persist-failure.test.js +143 -0
- package/dist/__tests__/event-outbox-persist-failure.test.js.map +1 -0
- package/dist/__tests__/event-outbox.test.d.ts +2 -0
- package/dist/__tests__/event-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/event-outbox.test.js +602 -0
- package/dist/__tests__/event-outbox.test.js.map +1 -0
- package/dist/__tests__/execution-activity-tracker.test.d.ts +2 -0
- package/dist/__tests__/execution-activity-tracker.test.d.ts.map +1 -0
- package/dist/__tests__/execution-activity-tracker.test.js +64 -0
- package/dist/__tests__/execution-activity-tracker.test.js.map +1 -0
- package/dist/__tests__/execution-lease-client.test.d.ts +2 -0
- package/dist/__tests__/execution-lease-client.test.d.ts.map +1 -0
- package/dist/__tests__/execution-lease-client.test.js +274 -0
- package/dist/__tests__/execution-lease-client.test.js.map +1 -0
- package/dist/__tests__/fake-provider-cli.test.d.ts +2 -0
- package/dist/__tests__/fake-provider-cli.test.d.ts.map +1 -0
- package/dist/__tests__/fake-provider-cli.test.js +46 -0
- package/dist/__tests__/fake-provider-cli.test.js.map +1 -0
- package/dist/__tests__/generated-images.test.d.ts +2 -0
- package/dist/__tests__/generated-images.test.d.ts.map +1 -0
- package/dist/__tests__/generated-images.test.js +132 -0
- package/dist/__tests__/generated-images.test.js.map +1 -0
- package/dist/__tests__/helpers/sandbox-outbox.d.ts +3 -0
- package/dist/__tests__/helpers/sandbox-outbox.d.ts.map +1 -0
- package/dist/__tests__/helpers/sandbox-outbox.js +23 -0
- package/dist/__tests__/helpers/sandbox-outbox.js.map +1 -0
- package/dist/__tests__/install-command.test.d.ts +2 -0
- package/dist/__tests__/install-command.test.d.ts.map +1 -0
- package/dist/__tests__/install-command.test.js +185 -0
- package/dist/__tests__/install-command.test.js.map +1 -0
- package/dist/__tests__/integration-cli.test.d.ts +2 -0
- package/dist/__tests__/integration-cli.test.d.ts.map +1 -0
- package/dist/__tests__/integration-cli.test.js +150 -0
- package/dist/__tests__/integration-cli.test.js.map +1 -0
- package/dist/__tests__/lifecycle-contracts.test.d.ts +2 -0
- package/dist/__tests__/lifecycle-contracts.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-contracts.test.js +66 -0
- package/dist/__tests__/lifecycle-contracts.test.js.map +1 -0
- package/dist/__tests__/lifecycle-logger.test.d.ts +2 -0
- package/dist/__tests__/lifecycle-logger.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-logger.test.js +49 -0
- package/dist/__tests__/lifecycle-logger.test.js.map +1 -0
- package/dist/__tests__/local-daemon-lifecycle.test.d.ts +2 -0
- package/dist/__tests__/local-daemon-lifecycle.test.d.ts.map +1 -0
- package/dist/__tests__/local-daemon-lifecycle.test.js +594 -0
- package/dist/__tests__/local-daemon-lifecycle.test.js.map +1 -0
- package/dist/__tests__/local-git-status.test.d.ts +2 -0
- package/dist/__tests__/local-git-status.test.d.ts.map +1 -0
- package/dist/__tests__/local-git-status.test.js +31 -0
- package/dist/__tests__/local-git-status.test.js.map +1 -0
- package/dist/__tests__/mcp-config-adapters-files.test.d.ts +2 -0
- package/dist/__tests__/mcp-config-adapters-files.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-config-adapters-files.test.js +486 -0
- package/dist/__tests__/mcp-config-adapters-files.test.js.map +1 -0
- package/dist/__tests__/mcp-config-adapters.test.d.ts +2 -0
- package/dist/__tests__/mcp-config-adapters.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-config-adapters.test.js +492 -0
- package/dist/__tests__/mcp-config-adapters.test.js.map +1 -0
- package/dist/__tests__/mcp-sync.test.d.ts +2 -0
- package/dist/__tests__/mcp-sync.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-sync.test.js +21 -0
- package/dist/__tests__/mcp-sync.test.js.map +1 -0
- package/dist/__tests__/model-scan-runner.test.d.ts +2 -0
- package/dist/__tests__/model-scan-runner.test.d.ts.map +1 -0
- package/dist/__tests__/model-scan-runner.test.js +80 -0
- package/dist/__tests__/model-scan-runner.test.js.map +1 -0
- package/dist/__tests__/native-hook-command.test.d.ts +2 -0
- package/dist/__tests__/native-hook-command.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-command.test.js +386 -0
- package/dist/__tests__/native-hook-command.test.js.map +1 -0
- package/dist/__tests__/native-hook-config.test.d.ts +2 -0
- package/dist/__tests__/native-hook-config.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-config.test.js +374 -0
- package/dist/__tests__/native-hook-config.test.js.map +1 -0
- package/dist/__tests__/native-hook-drain.test.d.ts +2 -0
- package/dist/__tests__/native-hook-drain.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-drain.test.js +197 -0
- package/dist/__tests__/native-hook-drain.test.js.map +1 -0
- package/dist/__tests__/native-hook-inbox.test.d.ts +2 -0
- package/dist/__tests__/native-hook-inbox.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-inbox.test.js +139 -0
- package/dist/__tests__/native-hook-inbox.test.js.map +1 -0
- package/dist/__tests__/native-session.test.d.ts +2 -0
- package/dist/__tests__/native-session.test.d.ts.map +1 -0
- package/dist/__tests__/native-session.test.js +41 -0
- package/dist/__tests__/native-session.test.js.map +1 -0
- package/dist/__tests__/native-stream-outbox.test.d.ts +2 -0
- package/dist/__tests__/native-stream-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/native-stream-outbox.test.js +231 -0
- package/dist/__tests__/native-stream-outbox.test.js.map +1 -0
- package/dist/__tests__/native-stream-platform.test.d.ts +2 -0
- package/dist/__tests__/native-stream-platform.test.d.ts.map +1 -0
- package/dist/__tests__/native-stream-platform.test.js +20 -0
- package/dist/__tests__/native-stream-platform.test.js.map +1 -0
- package/dist/__tests__/native-transcript-cursor.test.d.ts +2 -0
- package/dist/__tests__/native-transcript-cursor.test.d.ts.map +1 -0
- package/dist/__tests__/native-transcript-cursor.test.js +60 -0
- package/dist/__tests__/native-transcript-cursor.test.js.map +1 -0
- package/dist/__tests__/native-transcript-stream.test.d.ts +2 -0
- package/dist/__tests__/native-transcript-stream.test.d.ts.map +1 -0
- package/dist/__tests__/native-transcript-stream.test.js +378 -0
- package/dist/__tests__/native-transcript-stream.test.js.map +1 -0
- package/dist/__tests__/network-diagnostics.test.d.ts +2 -0
- package/dist/__tests__/network-diagnostics.test.d.ts.map +1 -0
- package/dist/__tests__/network-diagnostics.test.js +26 -0
- package/dist/__tests__/network-diagnostics.test.js.map +1 -0
- package/dist/__tests__/observable-map.test.d.ts +2 -0
- package/dist/__tests__/observable-map.test.d.ts.map +1 -0
- package/dist/__tests__/observable-map.test.js +54 -0
- package/dist/__tests__/observable-map.test.js.map +1 -0
- package/dist/__tests__/outbox-baseline.bench.test.d.ts +2 -0
- package/dist/__tests__/outbox-baseline.bench.test.d.ts.map +1 -0
- package/dist/__tests__/outbox-baseline.bench.test.js +108 -0
- package/dist/__tests__/outbox-baseline.bench.test.js.map +1 -0
- package/dist/__tests__/provider-auth-preflight.test.d.ts +2 -0
- package/dist/__tests__/provider-auth-preflight.test.d.ts.map +1 -0
- package/dist/__tests__/provider-auth-preflight.test.js +123 -0
- package/dist/__tests__/provider-auth-preflight.test.js.map +1 -0
- package/dist/__tests__/provider-model-discovery.test.d.ts +2 -0
- package/dist/__tests__/provider-model-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/provider-model-discovery.test.js +1071 -0
- package/dist/__tests__/provider-model-discovery.test.js.map +1 -0
- package/dist/__tests__/resource-diagnostics.test.d.ts +2 -0
- package/dist/__tests__/resource-diagnostics.test.d.ts.map +1 -0
- package/dist/__tests__/resource-diagnostics.test.js +138 -0
- package/dist/__tests__/resource-diagnostics.test.js.map +1 -0
- package/dist/__tests__/resume-fallback-env.test.d.ts +2 -0
- package/dist/__tests__/resume-fallback-env.test.d.ts.map +1 -0
- package/dist/__tests__/resume-fallback-env.test.js +28 -0
- package/dist/__tests__/resume-fallback-env.test.js.map +1 -0
- package/dist/__tests__/run-journal.test.d.ts +2 -0
- package/dist/__tests__/run-journal.test.d.ts.map +1 -0
- package/dist/__tests__/run-journal.test.js +121 -0
- package/dist/__tests__/run-journal.test.js.map +1 -0
- package/dist/__tests__/run-start-gate.test.d.ts +2 -0
- package/dist/__tests__/run-start-gate.test.d.ts.map +1 -0
- package/dist/__tests__/run-start-gate.test.js +18 -0
- package/dist/__tests__/run-start-gate.test.js.map +1 -0
- package/dist/__tests__/runtime-capabilities-sync.test.d.ts +2 -0
- package/dist/__tests__/runtime-capabilities-sync.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-capabilities-sync.test.js +66 -0
- package/dist/__tests__/runtime-capabilities-sync.test.js.map +1 -0
- package/dist/__tests__/runtime-config.test.d.ts +2 -0
- package/dist/__tests__/runtime-config.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-config.test.js +137 -0
- package/dist/__tests__/runtime-config.test.js.map +1 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts +2 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.js +253 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.js.map +1 -0
- package/dist/__tests__/runtime-registration.test.d.ts +2 -0
- package/dist/__tests__/runtime-registration.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-registration.test.js +109 -0
- package/dist/__tests__/runtime-registration.test.js.map +1 -0
- package/dist/__tests__/sandbox-outbox-storage.test.d.ts +2 -0
- package/dist/__tests__/sandbox-outbox-storage.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-outbox-storage.test.js +81 -0
- package/dist/__tests__/sandbox-outbox-storage.test.js.map +1 -0
- package/dist/__tests__/sandbox-outbox.test.d.ts +2 -0
- package/dist/__tests__/sandbox-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-outbox.test.js +300 -0
- package/dist/__tests__/sandbox-outbox.test.js.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.js +600 -0
- package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
- package/dist/__tests__/service-manager-deadline.test.d.ts +2 -0
- package/dist/__tests__/service-manager-deadline.test.d.ts.map +1 -0
- package/dist/__tests__/service-manager-deadline.test.js +36 -0
- package/dist/__tests__/service-manager-deadline.test.js.map +1 -0
- package/dist/__tests__/service-manager.test.d.ts +2 -0
- package/dist/__tests__/service-manager.test.d.ts.map +1 -0
- package/dist/__tests__/service-manager.test.js +769 -0
- package/dist/__tests__/service-manager.test.js.map +1 -0
- package/dist/__tests__/service-stop-ownership.test.d.ts +2 -0
- package/dist/__tests__/service-stop-ownership.test.d.ts.map +1 -0
- package/dist/__tests__/service-stop-ownership.test.js +89 -0
- package/dist/__tests__/service-stop-ownership.test.js.map +1 -0
- package/dist/__tests__/skill-invocation.test.d.ts +2 -0
- package/dist/__tests__/skill-invocation.test.d.ts.map +1 -0
- package/dist/__tests__/skill-invocation.test.js +40 -0
- package/dist/__tests__/skill-invocation.test.js.map +1 -0
- package/dist/__tests__/sleep-inhibitor-real.test.d.ts +2 -0
- package/dist/__tests__/sleep-inhibitor-real.test.d.ts.map +1 -0
- package/dist/__tests__/sleep-inhibitor-real.test.js +68 -0
- package/dist/__tests__/sleep-inhibitor-real.test.js.map +1 -0
- package/dist/__tests__/sleep-inhibitor.test.d.ts +2 -0
- package/dist/__tests__/sleep-inhibitor.test.d.ts.map +1 -0
- package/dist/__tests__/sleep-inhibitor.test.js +236 -0
- package/dist/__tests__/sleep-inhibitor.test.js.map +1 -0
- package/dist/__tests__/status-local-workspace.test.d.ts +2 -0
- package/dist/__tests__/status-local-workspace.test.d.ts.map +1 -0
- package/dist/__tests__/status-local-workspace.test.js +121 -0
- package/dist/__tests__/status-local-workspace.test.js.map +1 -0
- package/dist/__tests__/suspension-detector.test.d.ts +2 -0
- package/dist/__tests__/suspension-detector.test.d.ts.map +1 -0
- package/dist/__tests__/suspension-detector.test.js +112 -0
- package/dist/__tests__/suspension-detector.test.js.map +1 -0
- package/dist/__tests__/web-presenter-parent-events.test.d.ts +2 -0
- package/dist/__tests__/web-presenter-parent-events.test.d.ts.map +1 -0
- package/dist/__tests__/web-presenter-parent-events.test.js +168 -0
- package/dist/__tests__/web-presenter-parent-events.test.js.map +1 -0
- package/dist/__tests__/workspace-probe-concurrency.test.d.ts +2 -0
- package/dist/__tests__/workspace-probe-concurrency.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-probe-concurrency.test.js +54 -0
- package/dist/__tests__/workspace-probe-concurrency.test.js.map +1 -0
- package/dist/__tests__/workspace-relocation.test.d.ts +2 -0
- package/dist/__tests__/workspace-relocation.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-relocation.test.js +66 -0
- package/dist/__tests__/workspace-relocation.test.js.map +1 -0
- package/dist/__tests__/workspace-rpc.test.d.ts +2 -0
- package/dist/__tests__/workspace-rpc.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-rpc.test.js +90 -0
- package/dist/__tests__/workspace-rpc.test.js.map +1 -0
- package/dist/__tests__/workspace-run-lease.test.d.ts +2 -0
- package/dist/__tests__/workspace-run-lease.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-run-lease.test.js +331 -0
- package/dist/__tests__/workspace-run-lease.test.js.map +1 -0
- package/dist/__tests__/ws-client-connection.test.d.ts +2 -0
- package/dist/__tests__/ws-client-connection.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-connection.test.js +295 -0
- package/dist/__tests__/ws-client-connection.test.js.map +1 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts +2 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.js +63 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.js.map +1 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts +2 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.js +236 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.js.map +1 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts +2 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.js +211 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.js.map +1 -0
- package/dist/antigravity-api-key-config.d.ts +2 -0
- package/dist/antigravity-api-key-config.d.ts.map +1 -0
- package/dist/antigravity-api-key-config.js +79 -0
- package/dist/antigravity-api-key-config.js.map +1 -0
- package/dist/binding-switch-git.d.ts +26 -0
- package/dist/binding-switch-git.d.ts.map +1 -0
- package/dist/binding-switch-git.js +871 -0
- package/dist/binding-switch-git.js.map +1 -0
- package/dist/cli-ensure-install.d.ts +34 -0
- package/dist/cli-ensure-install.d.ts.map +1 -0
- package/dist/cli-ensure-install.js +154 -0
- package/dist/cli-ensure-install.js.map +1 -0
- package/dist/cli-executable.d.ts +44 -0
- package/dist/cli-executable.d.ts.map +1 -0
- package/dist/cli-executable.js +435 -0
- package/dist/cli-executable.js.map +1 -0
- package/dist/cli-help.d.ts +11 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +65 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/computer-readiness.d.ts +41 -0
- package/dist/computer-readiness.d.ts.map +1 -0
- package/dist/computer-readiness.js +191 -0
- package/dist/computer-readiness.js.map +1 -0
- package/dist/core-agent.d.ts +32 -0
- package/dist/core-agent.d.ts.map +1 -0
- package/dist/core-agent.js +331 -0
- package/dist/core-agent.js.map +1 -0
- package/dist/daemon-execute.d.ts +42 -0
- package/dist/daemon-execute.d.ts.map +1 -0
- package/dist/daemon-execute.js +666 -0
- package/dist/daemon-execute.js.map +1 -0
- package/dist/daemon-helpers.d.ts +150 -0
- package/dist/daemon-helpers.d.ts.map +1 -0
- package/dist/daemon-helpers.js +157 -0
- package/dist/daemon-helpers.js.map +1 -0
- package/dist/daemon-local-control.d.ts +208 -0
- package/dist/daemon-local-control.d.ts.map +1 -0
- package/dist/daemon-local-control.js +826 -0
- package/dist/daemon-local-control.js.map +1 -0
- package/dist/daemon-local-http.d.ts +57 -0
- package/dist/daemon-local-http.d.ts.map +1 -0
- package/dist/daemon-local-http.js +375 -0
- package/dist/daemon-local-http.js.map +1 -0
- package/dist/daemon-native-hooks.d.ts +17 -0
- package/dist/daemon-native-hooks.d.ts.map +1 -0
- package/dist/daemon-native-hooks.js +54 -0
- package/dist/daemon-native-hooks.js.map +1 -0
- package/dist/daemon-provider-scan.d.ts +33 -0
- package/dist/daemon-provider-scan.d.ts.map +1 -0
- package/dist/daemon-provider-scan.js +187 -0
- package/dist/daemon-provider-scan.js.map +1 -0
- package/dist/daemon-runner-status.d.ts +164 -0
- package/dist/daemon-runner-status.d.ts.map +1 -0
- package/dist/daemon-runner-status.js +424 -0
- package/dist/daemon-runner-status.js.map +1 -0
- package/dist/daemon-start.d.ts +5 -0
- package/dist/daemon-start.d.ts.map +1 -0
- package/dist/daemon-start.js +1313 -0
- package/dist/daemon-start.js.map +1 -0
- package/dist/daemon-workspace.d.ts +36 -0
- package/dist/daemon-workspace.d.ts.map +1 -0
- package/dist/daemon-workspace.js +154 -0
- package/dist/daemon-workspace.js.map +1 -0
- package/dist/daemon.d.ts +59 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +681 -0
- package/dist/daemon.js.map +1 -0
- package/dist/event-journal-crypto.d.ts +14 -0
- package/dist/event-journal-crypto.d.ts.map +1 -0
- package/dist/event-journal-crypto.js +89 -0
- package/dist/event-journal-crypto.js.map +1 -0
- package/dist/event-journal-paths.d.ts +10 -0
- package/dist/event-journal-paths.d.ts.map +1 -0
- package/dist/event-journal-paths.js +29 -0
- package/dist/event-journal-paths.js.map +1 -0
- package/dist/event-journal-recovery.d.ts +83 -0
- package/dist/event-journal-recovery.d.ts.map +1 -0
- package/dist/event-journal-recovery.js +333 -0
- package/dist/event-journal-recovery.js.map +1 -0
- package/dist/event-journal-types.d.ts +54 -0
- package/dist/event-journal-types.d.ts.map +1 -0
- package/dist/event-journal-types.js +10 -0
- package/dist/event-journal-types.js.map +1 -0
- package/dist/event-journal-writer.d.ts +44 -0
- package/dist/event-journal-writer.d.ts.map +1 -0
- package/dist/event-journal-writer.js +182 -0
- package/dist/event-journal-writer.js.map +1 -0
- package/dist/event-outbox.d.ts +113 -0
- package/dist/event-outbox.d.ts.map +1 -0
- package/dist/event-outbox.js +707 -0
- package/dist/event-outbox.js.map +1 -0
- package/dist/execution-activity-tracker.d.ts +43 -0
- package/dist/execution-activity-tracker.d.ts.map +1 -0
- package/dist/execution-activity-tracker.js +116 -0
- package/dist/execution-activity-tracker.js.map +1 -0
- package/dist/execution-lease-client.d.ts +62 -0
- package/dist/execution-lease-client.d.ts.map +1 -0
- package/dist/execution-lease-client.js +271 -0
- package/dist/execution-lease-client.js.map +1 -0
- package/dist/fake-provider-cli.d.ts +13 -0
- package/dist/fake-provider-cli.d.ts.map +1 -0
- package/dist/fake-provider-cli.js +53 -0
- package/dist/fake-provider-cli.js.map +1 -0
- package/dist/generated-images.d.ts +2 -0
- package/dist/generated-images.d.ts.map +1 -0
- package/dist/generated-images.js +2 -0
- package/dist/generated-images.js.map +1 -0
- package/dist/index.cjs +47033 -45514
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +224 -0
- package/dist/index.js.map +1 -0
- package/dist/install-command.d.ts +2 -0
- package/dist/install-command.d.ts.map +1 -0
- package/dist/install-command.js +96 -0
- package/dist/install-command.js.map +1 -0
- package/dist/integration-cli.d.ts +14 -0
- package/dist/integration-cli.d.ts.map +1 -0
- package/dist/integration-cli.js +80 -0
- package/dist/integration-cli.js.map +1 -0
- package/dist/lifecycle-logger.d.ts +25 -0
- package/dist/lifecycle-logger.d.ts.map +1 -0
- package/dist/lifecycle-logger.js +73 -0
- package/dist/lifecycle-logger.js.map +1 -0
- package/dist/local-daemon-lifecycle.d.ts +112 -0
- package/dist/local-daemon-lifecycle.d.ts.map +1 -0
- package/dist/local-daemon-lifecycle.js +433 -0
- package/dist/local-daemon-lifecycle.js.map +1 -0
- package/dist/local-git-status.d.ts +14 -0
- package/dist/local-git-status.d.ts.map +1 -0
- package/dist/local-git-status.js +43 -0
- package/dist/local-git-status.js.map +1 -0
- package/dist/managed-mcp.d.ts +7 -0
- package/dist/managed-mcp.d.ts.map +1 -0
- package/dist/managed-mcp.js +16 -0
- package/dist/managed-mcp.js.map +1 -0
- package/dist/mcp-config-adapters.d.ts +57 -0
- package/dist/mcp-config-adapters.d.ts.map +1 -0
- package/dist/mcp-config-adapters.js +929 -0
- package/dist/mcp-config-adapters.js.map +1 -0
- package/dist/mcp-sync.d.ts +44 -0
- package/dist/mcp-sync.d.ts.map +1 -0
- package/dist/mcp-sync.js +68 -0
- package/dist/mcp-sync.js.map +1 -0
- package/dist/model-scan-runner.d.ts +15 -0
- package/dist/model-scan-runner.d.ts.map +1 -0
- package/dist/model-scan-runner.js +56 -0
- package/dist/model-scan-runner.js.map +1 -0
- package/dist/native-hook-command.d.ts +31 -0
- package/dist/native-hook-command.d.ts.map +1 -0
- package/dist/native-hook-command.js +289 -0
- package/dist/native-hook-command.js.map +1 -0
- package/dist/native-hook-config.d.ts +43 -0
- package/dist/native-hook-config.d.ts.map +1 -0
- package/dist/native-hook-config.js +601 -0
- package/dist/native-hook-config.js.map +1 -0
- package/dist/native-hook-drain.d.ts +34 -0
- package/dist/native-hook-drain.d.ts.map +1 -0
- package/dist/native-hook-drain.js +83 -0
- package/dist/native-hook-drain.js.map +1 -0
- package/dist/native-hook-inbox.d.ts +40 -0
- package/dist/native-hook-inbox.d.ts.map +1 -0
- package/dist/native-hook-inbox.js +217 -0
- package/dist/native-hook-inbox.js.map +1 -0
- package/dist/native-project-config.d.ts +11 -0
- package/dist/native-project-config.d.ts.map +1 -0
- package/dist/native-project-config.js +49 -0
- package/dist/native-project-config.js.map +1 -0
- package/dist/native-session.d.ts +20 -0
- package/dist/native-session.d.ts.map +1 -0
- package/dist/native-session.js +213 -0
- package/dist/native-session.js.map +1 -0
- package/dist/native-stream-journal.d.ts +22 -0
- package/dist/native-stream-journal.d.ts.map +1 -0
- package/dist/native-stream-journal.js +98 -0
- package/dist/native-stream-journal.js.map +1 -0
- package/dist/native-stream-outbox.d.ts +40 -0
- package/dist/native-stream-outbox.d.ts.map +1 -0
- package/dist/native-stream-outbox.js +358 -0
- package/dist/native-stream-outbox.js.map +1 -0
- package/dist/native-stream-platform.d.ts +4 -0
- package/dist/native-stream-platform.d.ts.map +1 -0
- package/dist/native-stream-platform.js +11 -0
- package/dist/native-stream-platform.js.map +1 -0
- package/dist/native-transcript-cursor.d.ts +33 -0
- package/dist/native-transcript-cursor.d.ts.map +1 -0
- package/dist/native-transcript-cursor.js +108 -0
- package/dist/native-transcript-cursor.js.map +1 -0
- package/dist/native-transcript-stream.d.ts +20 -0
- package/dist/native-transcript-stream.d.ts.map +1 -0
- package/dist/native-transcript-stream.js +438 -0
- package/dist/native-transcript-stream.js.map +1 -0
- package/dist/network-diagnostics.d.ts +8 -0
- package/dist/network-diagnostics.d.ts.map +1 -0
- package/dist/network-diagnostics.js +56 -0
- package/dist/network-diagnostics.js.map +1 -0
- package/dist/observable-map.d.ts +13 -0
- package/dist/observable-map.d.ts.map +1 -0
- package/dist/observable-map.js +30 -0
- package/dist/observable-map.js.map +1 -0
- package/dist/provider-auth-preflight.d.ts +19 -0
- package/dist/provider-auth-preflight.d.ts.map +1 -0
- package/dist/provider-auth-preflight.js +107 -0
- package/dist/provider-auth-preflight.js.map +1 -0
- package/dist/provider-model-discovery.d.ts +33 -0
- package/dist/provider-model-discovery.d.ts.map +1 -0
- package/dist/provider-model-discovery.js +731 -0
- package/dist/provider-model-discovery.js.map +1 -0
- package/dist/resource-diagnostics.d.ts +21 -0
- package/dist/resource-diagnostics.d.ts.map +1 -0
- package/dist/resource-diagnostics.js +161 -0
- package/dist/resource-diagnostics.js.map +1 -0
- package/dist/resume-fallback-env.d.ts +3 -0
- package/dist/resume-fallback-env.d.ts.map +1 -0
- package/dist/resume-fallback-env.js +14 -0
- package/dist/resume-fallback-env.js.map +1 -0
- package/dist/run-journal.d.ts +51 -0
- package/dist/run-journal.d.ts.map +1 -0
- package/dist/run-journal.js +193 -0
- package/dist/run-journal.js.map +1 -0
- package/dist/runtime-backends.d.ts +2 -0
- package/dist/runtime-backends.d.ts.map +1 -0
- package/dist/runtime-backends.js +2 -0
- package/dist/runtime-backends.js.map +1 -0
- package/dist/runtime-capabilities-sync.d.ts +40 -0
- package/dist/runtime-capabilities-sync.d.ts.map +1 -0
- package/dist/runtime-capabilities-sync.js +56 -0
- package/dist/runtime-capabilities-sync.js.map +1 -0
- package/dist/runtime-config.d.ts +26 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +170 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/runtime-presenter.d.ts +81 -0
- package/dist/runtime-presenter.d.ts.map +1 -0
- package/dist/runtime-presenter.js +422 -0
- package/dist/runtime-presenter.js.map +1 -0
- package/dist/runtime-registration.d.ts +40 -0
- package/dist/runtime-registration.d.ts.map +1 -0
- package/dist/runtime-registration.js +143 -0
- package/dist/runtime-registration.js.map +1 -0
- package/dist/sandbox-outbox-storage.d.ts +13 -0
- package/dist/sandbox-outbox-storage.d.ts.map +1 -0
- package/dist/sandbox-outbox-storage.js +98 -0
- package/dist/sandbox-outbox-storage.js.map +1 -0
- package/dist/sandbox-outbox.d.ts +115 -0
- package/dist/sandbox-outbox.d.ts.map +1 -0
- package/dist/sandbox-outbox.js +213 -0
- package/dist/sandbox-outbox.js.map +1 -0
- package/dist/sandbox.d.ts +34 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +469 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/service-manager.d.ts +113 -0
- package/dist/service-manager.d.ts.map +1 -0
- package/dist/service-manager.js +1065 -0
- package/dist/service-manager.js.map +1 -0
- package/dist/skills/__tests__/local-skill-source.test.d.ts +2 -0
- package/dist/skills/__tests__/local-skill-source.test.d.ts.map +1 -0
- package/dist/skills/__tests__/local-skill-source.test.js +373 -0
- package/dist/skills/__tests__/local-skill-source.test.js.map +1 -0
- package/dist/skills/__tests__/managed-skill-store.test.d.ts +2 -0
- package/dist/skills/__tests__/managed-skill-store.test.d.ts.map +1 -0
- package/dist/skills/__tests__/managed-skill-store.test.js +114 -0
- package/dist/skills/__tests__/managed-skill-store.test.js.map +1 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.d.ts +2 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.d.ts.map +1 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.js +251 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.js.map +1 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.d.ts +2 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.d.ts.map +1 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.js +664 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.js.map +1 -0
- package/dist/skills/__tests__/skill-bundle.test.d.ts +2 -0
- package/dist/skills/__tests__/skill-bundle.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill-bundle.test.js +42 -0
- package/dist/skills/__tests__/skill-bundle.test.js.map +1 -0
- package/dist/skills/__tests__/skill-control-client.test.d.ts +2 -0
- package/dist/skills/__tests__/skill-control-client.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill-control-client.test.js +49 -0
- package/dist/skills/__tests__/skill-control-client.test.js.map +1 -0
- package/dist/skills/__tests__/skill-source-config.test.d.ts +2 -0
- package/dist/skills/__tests__/skill-source-config.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill-source-config.test.js +295 -0
- package/dist/skills/__tests__/skill-source-config.test.js.map +1 -0
- package/dist/skills/local-skill-source.d.ts +77 -0
- package/dist/skills/local-skill-source.d.ts.map +1 -0
- package/dist/skills/local-skill-source.js +660 -0
- package/dist/skills/local-skill-source.js.map +1 -0
- package/dist/skills/managed-skill-store.d.ts +44 -0
- package/dist/skills/managed-skill-store.d.ts.map +1 -0
- package/dist/skills/managed-skill-store.js +160 -0
- package/dist/skills/managed-skill-store.js.map +1 -0
- package/dist/skills/runtime-skill-coordinator.d.ts +35 -0
- package/dist/skills/runtime-skill-coordinator.d.ts.map +1 -0
- package/dist/skills/runtime-skill-coordinator.js +166 -0
- package/dist/skills/runtime-skill-coordinator.js.map +1 -0
- package/dist/skills/runtime-skill-manager.d.ts +89 -0
- package/dist/skills/runtime-skill-manager.d.ts.map +1 -0
- package/dist/skills/runtime-skill-manager.js +934 -0
- package/dist/skills/runtime-skill-manager.js.map +1 -0
- package/dist/skills/skill-bundle.d.ts +2 -0
- package/dist/skills/skill-bundle.d.ts.map +1 -0
- package/dist/skills/skill-bundle.js +2 -0
- package/dist/skills/skill-bundle.js.map +1 -0
- package/dist/skills/skill-cli.d.ts +2 -0
- package/dist/skills/skill-cli.d.ts.map +1 -0
- package/dist/skills/skill-cli.js +81 -0
- package/dist/skills/skill-cli.js.map +1 -0
- package/dist/skills/skill-control-client.d.ts +20 -0
- package/dist/skills/skill-control-client.d.ts.map +1 -0
- package/dist/skills/skill-control-client.js +56 -0
- package/dist/skills/skill-control-client.js.map +1 -0
- package/dist/skills/skill-invocation.d.ts +10 -0
- package/dist/skills/skill-invocation.d.ts.map +1 -0
- package/dist/skills/skill-invocation.js +24 -0
- package/dist/skills/skill-invocation.js.map +1 -0
- package/dist/sleep-inhibitor.d.ts +32 -0
- package/dist/sleep-inhibitor.d.ts.map +1 -0
- package/dist/sleep-inhibitor.js +297 -0
- package/dist/sleep-inhibitor.js.map +1 -0
- package/dist/suspension-detector.d.ts +24 -0
- package/dist/suspension-detector.d.ts.map +1 -0
- package/dist/suspension-detector.js +59 -0
- package/dist/suspension-detector.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/web-presenter.d.ts +52 -0
- package/dist/web-presenter.d.ts.map +1 -0
- package/dist/web-presenter.js +264 -0
- package/dist/web-presenter.js.map +1 -0
- package/dist/workspace-relocation.d.ts +22 -0
- package/dist/workspace-relocation.d.ts.map +1 -0
- package/dist/workspace-relocation.js +90 -0
- package/dist/workspace-relocation.js.map +1 -0
- package/dist/workspace-rpc.d.ts +2 -0
- package/dist/workspace-rpc.d.ts.map +1 -0
- package/dist/workspace-rpc.js +15 -0
- package/dist/workspace-rpc.js.map +1 -0
- package/dist/workspace-run-lease.d.ts +116 -0
- package/dist/workspace-run-lease.d.ts.map +1 -0
- package/dist/workspace-run-lease.js +320 -0
- package/dist/workspace-run-lease.js.map +1 -0
- package/dist/ws-client.d.ts +168 -0
- package/dist/ws-client.d.ts.map +1 -0
- package/dist/ws-client.js +440 -0
- package/dist/ws-client.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { rm } from "node:fs/promises";
|
|
3
|
+
import { isDeepStrictEqual } from "node:util";
|
|
4
|
+
import { decodeJournalKey, sealJournalRecord } from "./event-journal-crypto.js";
|
|
5
|
+
import { eventJournalDir, segmentPath } from "./event-journal-paths.js";
|
|
6
|
+
import { markLegacyImportDone, recoverEventJournal, writeJournalAckStateAsync, } from "./event-journal-recovery.js";
|
|
7
|
+
import { EVENT_JOURNAL_ORDINARY_BATCH_MS, EVENT_JOURNAL_SEGMENT_BYTES, } from "./event-journal-types.js";
|
|
8
|
+
import { EventJournalWriter, readSegmentFileSize } from "./event-journal-writer.js";
|
|
9
|
+
const MAX_INTERMEDIATE_EVENTS_PER_RUN = 200;
|
|
10
|
+
const MAX_ENCRYPTED_OUTBOX_BYTES = 64 * 1024 * 1024;
|
|
11
|
+
const ACK_TIMEOUT_MS = 10_000;
|
|
12
|
+
const RETRY_DELAY_MS = 1_000;
|
|
13
|
+
const TERMINAL_EVENT_TYPES = new Set([
|
|
14
|
+
"agent_run_finished",
|
|
15
|
+
"query_complete",
|
|
16
|
+
"session_complete",
|
|
17
|
+
"session_error",
|
|
18
|
+
"complete",
|
|
19
|
+
]);
|
|
20
|
+
function decodeKey(encodedKey) {
|
|
21
|
+
try {
|
|
22
|
+
return decodeJournalKey(encodedKey);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new Error("event outbox encryption key must contain exactly 32 bytes");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function isTerminal(event) {
|
|
29
|
+
return TERMINAL_EVENT_TYPES.has(event.type);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* background_work heartbeats (BaseMachineAgent.runBackendWithActivityHeartbeat,
|
|
33
|
+
* ~every 10s for the life of a quiet tool call) prove daemon liveness to a
|
|
34
|
+
* currently-connected backend only — they carry no transcript content. They
|
|
35
|
+
* must never be allowed to evict real events (including `start`) from the
|
|
36
|
+
* durable outbox, so callers can drop them outright while disconnected and
|
|
37
|
+
* the outbox always evicts them first if any do get enqueued.
|
|
38
|
+
*/
|
|
39
|
+
export function isBackgroundHeartbeat(event) {
|
|
40
|
+
return event.type === "activity" && event.status === "background_work";
|
|
41
|
+
}
|
|
42
|
+
function parentToolUseIdOf(event) {
|
|
43
|
+
if ((event.type === "text" || event.type === "thinking") &&
|
|
44
|
+
typeof event.parentToolUseId === "string") {
|
|
45
|
+
return event.parentToolUseId;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function canCoalesceEvents(left, right) {
|
|
50
|
+
if (left.type !== right.type)
|
|
51
|
+
return false;
|
|
52
|
+
if (left.type !== "text" && left.type !== "thinking")
|
|
53
|
+
return false;
|
|
54
|
+
if (right.type !== "text" && right.type !== "thinking")
|
|
55
|
+
return false;
|
|
56
|
+
return parentToolUseIdOf(left) === parentToolUseIdOf(right);
|
|
57
|
+
}
|
|
58
|
+
function coalesceEvents(left, right) {
|
|
59
|
+
if ((left.type === "text" && right.type === "text") ||
|
|
60
|
+
(left.type === "thinking" && right.type === "thinking")) {
|
|
61
|
+
const parentToolUseId = parentToolUseIdOf(right) ?? parentToolUseIdOf(left);
|
|
62
|
+
return {
|
|
63
|
+
type: left.type,
|
|
64
|
+
text: `${left.text}${right.text}`,
|
|
65
|
+
ts: right.ts ?? left.ts,
|
|
66
|
+
...(parentToolUseId ? { parentToolUseId } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return right;
|
|
70
|
+
}
|
|
71
|
+
function payloadOf(entry) {
|
|
72
|
+
return {
|
|
73
|
+
event: entry.event,
|
|
74
|
+
...(entry.explicitSource ? { explicitSource: true } : {}),
|
|
75
|
+
...(entry.kind ? { kind: entry.kind } : {}),
|
|
76
|
+
...(entry.terminalCondensed ? { terminalCondensed: true } : {}),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function estimateEntryBytes(entry) {
|
|
80
|
+
const record = {
|
|
81
|
+
eventId: entry.eventId,
|
|
82
|
+
runId: entry.runId,
|
|
83
|
+
conversationId: entry.conversationId,
|
|
84
|
+
sequence: entry.sequence,
|
|
85
|
+
createdAtMs: entry.createdAtMs,
|
|
86
|
+
payload: payloadOf(entry),
|
|
87
|
+
};
|
|
88
|
+
// length prefix + iv + tag + ciphertext ≈ plaintext
|
|
89
|
+
return 4 + 12 + 16 + Buffer.byteLength(JSON.stringify(record), "utf8");
|
|
90
|
+
}
|
|
91
|
+
function entryFromRecord(record) {
|
|
92
|
+
const payload = record.payload;
|
|
93
|
+
if (!payload || typeof payload !== "object" || !payload.event)
|
|
94
|
+
return null;
|
|
95
|
+
return {
|
|
96
|
+
eventId: record.eventId,
|
|
97
|
+
conversationId: record.conversationId ?? "",
|
|
98
|
+
runId: record.runId,
|
|
99
|
+
event: payload.event,
|
|
100
|
+
createdAtMs: record.createdAtMs,
|
|
101
|
+
sequence: record.sequence,
|
|
102
|
+
...(payload.explicitSource ? { explicitSource: true } : {}),
|
|
103
|
+
...(payload.kind ? { kind: payload.kind } : {}),
|
|
104
|
+
...(payload.terminalCondensed ? { terminalCondensed: true } : {}),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Durable, encrypted, at-least-once event delivery for daemon-to-backend agent events.
|
|
109
|
+
* Compatibility facade over an append-only segmented journal: presenters enqueue memory
|
|
110
|
+
* work; AES/fsync runs on a single bounded async writer (≤25ms ordinary batching).
|
|
111
|
+
*/
|
|
112
|
+
export class EncryptedEventOutbox {
|
|
113
|
+
path;
|
|
114
|
+
pushLog;
|
|
115
|
+
entries = [];
|
|
116
|
+
segmentIds = new Map();
|
|
117
|
+
segmentSizes = new Map();
|
|
118
|
+
ackDirty = false;
|
|
119
|
+
ackFailure = null;
|
|
120
|
+
maintenance = null;
|
|
121
|
+
maintenanceTimer = null;
|
|
122
|
+
legacyImport = null;
|
|
123
|
+
acknowledgedEventIds;
|
|
124
|
+
sequences = new Map();
|
|
125
|
+
transmittedEventIds = new Set();
|
|
126
|
+
inFlight = new Map();
|
|
127
|
+
retryTimers = new Map();
|
|
128
|
+
deliveryTimer = null;
|
|
129
|
+
lastDeliveryAtMs = 0;
|
|
130
|
+
acknowledgementWaiters = new Map();
|
|
131
|
+
persistFailureLogged = false;
|
|
132
|
+
compactionState = "idle";
|
|
133
|
+
roundRobinCursor = 0;
|
|
134
|
+
runOrder = [];
|
|
135
|
+
writer;
|
|
136
|
+
journalDir;
|
|
137
|
+
key;
|
|
138
|
+
maxEncryptedBytes;
|
|
139
|
+
maxIntermediateEventsPerRun;
|
|
140
|
+
deliveryIntervalMs;
|
|
141
|
+
maxConcurrentDeliveries;
|
|
142
|
+
ordinaryBatchMs;
|
|
143
|
+
highWaterMarkLogged = false;
|
|
144
|
+
pendingBytes = 0;
|
|
145
|
+
cachedSegmentBytes = 0;
|
|
146
|
+
cachedSegmentCount = 0;
|
|
147
|
+
lastRecover;
|
|
148
|
+
refreshSegmentCache() {
|
|
149
|
+
this.cachedSegmentCount = this.segmentSizes.size;
|
|
150
|
+
this.cachedSegmentBytes = [...this.segmentSizes.values()].reduce((sum, bytes) => sum + bytes, 0);
|
|
151
|
+
}
|
|
152
|
+
constructor(path, encodedKey, pushLog = () => { }, options = {}) {
|
|
153
|
+
this.path = path;
|
|
154
|
+
this.pushLog = pushLog;
|
|
155
|
+
this.key = decodeKey(encodedKey);
|
|
156
|
+
this.journalDir = eventJournalDir(this.path);
|
|
157
|
+
this.maxEncryptedBytes = options.maxEncryptedBytes ?? MAX_ENCRYPTED_OUTBOX_BYTES;
|
|
158
|
+
this.maxIntermediateEventsPerRun =
|
|
159
|
+
options.maxIntermediateEventsPerRun ?? MAX_INTERMEDIATE_EVENTS_PER_RUN;
|
|
160
|
+
this.deliveryIntervalMs = options.deliveryIntervalMs ?? 0;
|
|
161
|
+
this.maxConcurrentDeliveries = options.maxConcurrentDeliveries ?? 1;
|
|
162
|
+
if (!Number.isSafeInteger(this.maxConcurrentDeliveries) ||
|
|
163
|
+
this.maxConcurrentDeliveries < 1 ||
|
|
164
|
+
this.maxConcurrentDeliveries > 4) {
|
|
165
|
+
throw new Error("event outbox maxConcurrentDeliveries must be between 1 and 4");
|
|
166
|
+
}
|
|
167
|
+
this.ordinaryBatchMs = options.ordinaryBatchMs ?? EVENT_JOURNAL_ORDINARY_BATCH_MS;
|
|
168
|
+
if (!Number.isSafeInteger(this.maxEncryptedBytes) || this.maxEncryptedBytes <= 0) {
|
|
169
|
+
throw new Error("event outbox maxEncryptedBytes must be a positive integer");
|
|
170
|
+
}
|
|
171
|
+
if (!Number.isSafeInteger(this.maxIntermediateEventsPerRun) ||
|
|
172
|
+
this.maxIntermediateEventsPerRun < 0) {
|
|
173
|
+
throw new Error("event outbox maxIntermediateEventsPerRun must be a non-negative integer");
|
|
174
|
+
}
|
|
175
|
+
if (!Number.isSafeInteger(this.deliveryIntervalMs) || this.deliveryIntervalMs < 0) {
|
|
176
|
+
throw new Error("event outbox deliveryIntervalMs must be a non-negative integer");
|
|
177
|
+
}
|
|
178
|
+
const pendingLegacy = [];
|
|
179
|
+
const recovered = recoverEventJournal({
|
|
180
|
+
legacyPath: this.path,
|
|
181
|
+
journalDir: this.journalDir,
|
|
182
|
+
key: this.key,
|
|
183
|
+
pushLog: this.pushLog,
|
|
184
|
+
appendLegacyRecords: (records) => {
|
|
185
|
+
pendingLegacy.push(...records);
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
this.lastRecover = {
|
|
189
|
+
truncatedIncompleteTail: recovered.truncatedIncompleteTail,
|
|
190
|
+
quarantinedSegments: recovered.quarantinedSegments,
|
|
191
|
+
importedLegacySnapshot: recovered.importedLegacySnapshot,
|
|
192
|
+
};
|
|
193
|
+
const segmentLimit = options.segmentBytes ?? EVENT_JOURNAL_SEGMENT_BYTES;
|
|
194
|
+
const { activeSequence, activeBytes } = this.resolveWriterCursor(recovered.segments, segmentLimit);
|
|
195
|
+
this.writer = new EventJournalWriter(this.journalDir, this.key, this.pushLog, {
|
|
196
|
+
onPersisted: (sequence, records, bytes) => {
|
|
197
|
+
const ids = this.segmentIds.get(sequence) ?? new Set();
|
|
198
|
+
for (const record of records)
|
|
199
|
+
ids.add(record.eventId);
|
|
200
|
+
this.segmentIds.set(sequence, ids);
|
|
201
|
+
this.segmentSizes.set(sequence, bytes);
|
|
202
|
+
this.refreshSegmentCache();
|
|
203
|
+
},
|
|
204
|
+
segmentBytes: segmentLimit,
|
|
205
|
+
ordinaryBatchMs: this.ordinaryBatchMs,
|
|
206
|
+
onPersistFailure: (error) => {
|
|
207
|
+
if (!error) {
|
|
208
|
+
this.persistFailureLogged = false;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (!this.persistFailureLogged) {
|
|
212
|
+
this.persistFailureLogged = true;
|
|
213
|
+
this.pushLog(`event_outbox_persist_failed error=${error} pending_entries=${this.entries.length}`);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
}, {
|
|
217
|
+
nextSegmentSequence: activeSequence,
|
|
218
|
+
currentSegmentBytes: activeBytes,
|
|
219
|
+
});
|
|
220
|
+
if (pendingLegacy.length > 0) {
|
|
221
|
+
for (const record of pendingLegacy) {
|
|
222
|
+
this.writer.enqueue(record, false);
|
|
223
|
+
}
|
|
224
|
+
if (recovered.needsImportMarker)
|
|
225
|
+
this.legacyImport = { count: recovered.legacyImportRecordCount ?? pendingLegacy.length };
|
|
226
|
+
}
|
|
227
|
+
this.refreshSegmentCache();
|
|
228
|
+
this.acknowledgedEventIds = new Set(recovered.ack.acknowledgedEventIds);
|
|
229
|
+
for (const segment of recovered.segments) {
|
|
230
|
+
this.segmentSizes.set(segment.sequence, segment.bytes);
|
|
231
|
+
this.segmentIds.set(segment.sequence, new Set(segment.records.map((record) => record.eventId)));
|
|
232
|
+
}
|
|
233
|
+
this.refreshSegmentCache();
|
|
234
|
+
const segmentsForHydrate = [...recovered.segments];
|
|
235
|
+
if (pendingLegacy.length)
|
|
236
|
+
segmentsForHydrate.push({
|
|
237
|
+
sequence: 0,
|
|
238
|
+
path: "",
|
|
239
|
+
bytes: 0,
|
|
240
|
+
records: pendingLegacy,
|
|
241
|
+
corrupt: false,
|
|
242
|
+
truncatedIncompleteTail: false,
|
|
243
|
+
});
|
|
244
|
+
this.hydrateFromSegments(segmentsForHydrate);
|
|
245
|
+
this.enforceRetentionPolicy();
|
|
246
|
+
if (this.acknowledgedEventIds.size)
|
|
247
|
+
this.persistAckState();
|
|
248
|
+
if (this.legacyImport)
|
|
249
|
+
void this.flushDurable().catch((error) => this.pushLog(`event_journal_import_failed ${String(error)}`));
|
|
250
|
+
}
|
|
251
|
+
resolveWriterCursor(segments, segmentLimit) {
|
|
252
|
+
if (segments.length === 0)
|
|
253
|
+
return { activeSequence: 1, activeBytes: 0 };
|
|
254
|
+
const last = segments[segments.length - 1];
|
|
255
|
+
if (last.bytes >= segmentLimit) {
|
|
256
|
+
return { activeSequence: last.sequence + 1, activeBytes: 0 };
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
activeSequence: last.sequence,
|
|
260
|
+
activeBytes: last.bytes || readSegmentFileSize(this.journalDir, last.sequence),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
hydrateFromSegments(segments) {
|
|
264
|
+
const pending = [];
|
|
265
|
+
for (const segment of segments) {
|
|
266
|
+
for (const record of segment.records) {
|
|
267
|
+
if (this.acknowledgedEventIds.has(record.eventId))
|
|
268
|
+
continue;
|
|
269
|
+
const entry = entryFromRecord(record);
|
|
270
|
+
if (!entry)
|
|
271
|
+
continue;
|
|
272
|
+
if (pending.some((existing) => existing.eventId === entry.eventId))
|
|
273
|
+
continue;
|
|
274
|
+
pending.push(entry);
|
|
275
|
+
const prior = this.sequences.get(entry.runId) ?? 0;
|
|
276
|
+
if (entry.sequence > prior)
|
|
277
|
+
this.sequences.set(entry.runId, entry.sequence);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
pending.sort((a, b) => {
|
|
281
|
+
if (a.runId !== b.runId)
|
|
282
|
+
return a.runId.localeCompare(b.runId);
|
|
283
|
+
return a.sequence - b.sequence;
|
|
284
|
+
});
|
|
285
|
+
this.entries = pending;
|
|
286
|
+
this.pendingBytes = pending.reduce((sum, entry) => sum + estimateEntryBytes(entry), 0);
|
|
287
|
+
for (const entry of pending)
|
|
288
|
+
this.trackRun(entry.runId);
|
|
289
|
+
}
|
|
290
|
+
trackRun(runId) {
|
|
291
|
+
if (!this.runOrder.includes(runId))
|
|
292
|
+
this.runOrder.push(runId);
|
|
293
|
+
}
|
|
294
|
+
nextSequence(runId) {
|
|
295
|
+
const next = (this.sequences.get(runId) ?? 0) + 1;
|
|
296
|
+
this.sequences.set(runId, next);
|
|
297
|
+
return next;
|
|
298
|
+
}
|
|
299
|
+
toRecord(entry) {
|
|
300
|
+
return sealJournalRecord({
|
|
301
|
+
eventId: entry.eventId,
|
|
302
|
+
runId: entry.runId,
|
|
303
|
+
conversationId: entry.conversationId,
|
|
304
|
+
sequence: entry.sequence,
|
|
305
|
+
createdAtMs: entry.createdAtMs,
|
|
306
|
+
payload: payloadOf(entry),
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
appendEntry(entry, immediateFlush) {
|
|
310
|
+
this.entries.push(entry);
|
|
311
|
+
this.pendingBytes += estimateEntryBytes(entry);
|
|
312
|
+
this.trackRun(entry.runId);
|
|
313
|
+
this.writer.enqueue(this.toRecord(entry), immediateFlush);
|
|
314
|
+
}
|
|
315
|
+
rewriteQueued(entry) {
|
|
316
|
+
const record = this.toRecord(entry);
|
|
317
|
+
if (!this.writer.updateQueued(entry.eventId, record)) {
|
|
318
|
+
// Already durable — append a replacement frame and ACK the stale id is not
|
|
319
|
+
// possible without diverging eventId; leave coalesced mutation only while queued.
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
enqueue(conversationId, runId, event) {
|
|
323
|
+
const last = this.entries[this.entries.length - 1];
|
|
324
|
+
if (last &&
|
|
325
|
+
!last.explicitSource &&
|
|
326
|
+
!this.isInFlight(last.eventId) &&
|
|
327
|
+
!this.transmittedEventIds.has(last.eventId) &&
|
|
328
|
+
last.kind !== "condensation_marker" &&
|
|
329
|
+
last.conversationId === conversationId &&
|
|
330
|
+
last.runId === runId &&
|
|
331
|
+
this.writer.hasQueued(last.eventId) &&
|
|
332
|
+
canCoalesceEvents(last.event, event)) {
|
|
333
|
+
this.pendingBytes -= estimateEntryBytes(last);
|
|
334
|
+
last.event = coalesceEvents(last.event, event);
|
|
335
|
+
last.createdAtMs = Date.now();
|
|
336
|
+
this.pendingBytes += estimateEntryBytes(last);
|
|
337
|
+
this.rewriteQueued(last);
|
|
338
|
+
this.enforceRetentionPolicy(runId, false);
|
|
339
|
+
return last.eventId;
|
|
340
|
+
}
|
|
341
|
+
const entry = {
|
|
342
|
+
eventId: randomUUID(),
|
|
343
|
+
conversationId,
|
|
344
|
+
runId,
|
|
345
|
+
event,
|
|
346
|
+
createdAtMs: Date.now(),
|
|
347
|
+
sequence: this.nextSequence(runId),
|
|
348
|
+
};
|
|
349
|
+
this.appendEntry(entry, isTerminal(event));
|
|
350
|
+
this.enforceRetentionPolicy(runId, isBackgroundHeartbeat(event));
|
|
351
|
+
return entry.eventId;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Durably enqueue an event whose id is derived from an external source cursor.
|
|
355
|
+
* Identical retries are idempotent, while reusing an id for different content
|
|
356
|
+
* fails closed so the backend can never observe divergent payloads under one
|
|
357
|
+
* receipt key.
|
|
358
|
+
*/
|
|
359
|
+
enqueueSource(conversationId, runId, eventId, event) {
|
|
360
|
+
if (!eventId.trim())
|
|
361
|
+
throw new Error("event outbox source event id must not be empty");
|
|
362
|
+
const existing = this.entries.find((entry) => entry.eventId === eventId);
|
|
363
|
+
if (existing) {
|
|
364
|
+
if (existing.explicitSource === true &&
|
|
365
|
+
existing.conversationId === conversationId &&
|
|
366
|
+
existing.runId === runId &&
|
|
367
|
+
isDeepStrictEqual(existing.event, event)) {
|
|
368
|
+
return eventId;
|
|
369
|
+
}
|
|
370
|
+
throw new Error(`event outbox source event id ${eventId} has divergent payload`);
|
|
371
|
+
}
|
|
372
|
+
if (this.acknowledgedEventIds.has(eventId)) {
|
|
373
|
+
return eventId;
|
|
374
|
+
}
|
|
375
|
+
const entry = {
|
|
376
|
+
eventId,
|
|
377
|
+
conversationId,
|
|
378
|
+
runId,
|
|
379
|
+
event,
|
|
380
|
+
createdAtMs: Date.now(),
|
|
381
|
+
sequence: this.nextSequence(runId),
|
|
382
|
+
explicitSource: true,
|
|
383
|
+
};
|
|
384
|
+
this.appendEntry(entry, true);
|
|
385
|
+
this.enforceRetentionPolicy(runId, false);
|
|
386
|
+
return eventId;
|
|
387
|
+
}
|
|
388
|
+
hasTerminalEvent(runId) {
|
|
389
|
+
return this.entries.some((entry) => entry.runId === runId && isTerminal(entry.event));
|
|
390
|
+
}
|
|
391
|
+
pendingCount() {
|
|
392
|
+
return this.entries.length;
|
|
393
|
+
}
|
|
394
|
+
/** Drain the async writer queue to durable segments. */
|
|
395
|
+
async flushDurable() {
|
|
396
|
+
await this.writer.flush();
|
|
397
|
+
if (this.writer.getPersistFailure())
|
|
398
|
+
return;
|
|
399
|
+
if (this.legacyImport) {
|
|
400
|
+
markLegacyImportDone(this.journalDir, this.legacyImport.count, this.pushLog);
|
|
401
|
+
this.legacyImport = null;
|
|
402
|
+
}
|
|
403
|
+
await this.flushMaintenance();
|
|
404
|
+
this.refreshSegmentCache();
|
|
405
|
+
}
|
|
406
|
+
metrics() {
|
|
407
|
+
const oldest = this.entries.reduce((min, entry) => {
|
|
408
|
+
if (min === null || entry.createdAtMs < min)
|
|
409
|
+
return entry.createdAtMs;
|
|
410
|
+
return min;
|
|
411
|
+
}, null);
|
|
412
|
+
const persistFailure = this.writer.getPersistFailure() ?? this.ackFailure;
|
|
413
|
+
const overloaded = this.pendingBytes > this.maxEncryptedBytes || this.writer.depth() > 2_000;
|
|
414
|
+
const degraded = persistFailure !== null ||
|
|
415
|
+
this.compactionState === "failed" ||
|
|
416
|
+
this.lastRecover.quarantinedSegments.length > 0;
|
|
417
|
+
return {
|
|
418
|
+
writerDepth: this.writer.depth(),
|
|
419
|
+
oldestPendingAgeMs: oldest === null ? null : Math.max(0, Date.now() - oldest),
|
|
420
|
+
segmentBytes: this.cachedSegmentBytes,
|
|
421
|
+
segmentCount: this.cachedSegmentCount,
|
|
422
|
+
compactionState: this.compactionState,
|
|
423
|
+
persistFailure,
|
|
424
|
+
overloaded,
|
|
425
|
+
degraded,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
waitForAcknowledgement(eventId, signal) {
|
|
429
|
+
if (signal?.aborted)
|
|
430
|
+
return Promise.reject(signal.reason);
|
|
431
|
+
if (!this.entries.some((entry) => entry.eventId === eventId))
|
|
432
|
+
return Promise.resolve();
|
|
433
|
+
return new Promise((resolve, reject) => {
|
|
434
|
+
const finish = () => {
|
|
435
|
+
signal?.removeEventListener("abort", abort);
|
|
436
|
+
resolve();
|
|
437
|
+
};
|
|
438
|
+
const abort = () => {
|
|
439
|
+
const remaining = this.acknowledgementWaiters.get(eventId)?.filter((waiter) => waiter !== finish) ?? [];
|
|
440
|
+
if (remaining.length)
|
|
441
|
+
this.acknowledgementWaiters.set(eventId, remaining);
|
|
442
|
+
else
|
|
443
|
+
this.acknowledgementWaiters.delete(eventId);
|
|
444
|
+
reject(signal?.reason);
|
|
445
|
+
};
|
|
446
|
+
const waiters = this.acknowledgementWaiters.get(eventId) ?? [];
|
|
447
|
+
waiters.push(finish);
|
|
448
|
+
this.acknowledgementWaiters.set(eventId, waiters);
|
|
449
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
disconnect() {
|
|
453
|
+
for (const attempt of this.inFlight.values())
|
|
454
|
+
clearTimeout(attempt.timer);
|
|
455
|
+
for (const timer of this.retryTimers.values())
|
|
456
|
+
clearTimeout(timer);
|
|
457
|
+
this.inFlight.clear();
|
|
458
|
+
this.retryTimers.clear();
|
|
459
|
+
this.clearDeliveryTimer();
|
|
460
|
+
}
|
|
461
|
+
flush(socket) {
|
|
462
|
+
while (socket.connected &&
|
|
463
|
+
this.inFlight.size < this.maxConcurrentDeliveries &&
|
|
464
|
+
this.entries.length > 0) {
|
|
465
|
+
const now = Date.now();
|
|
466
|
+
// A wall-clock correction must not turn a short delivery interval into an
|
|
467
|
+
// overflowing Node timeout (which otherwise becomes a 1 ms retry loop).
|
|
468
|
+
if (this.lastDeliveryAtMs > now)
|
|
469
|
+
this.lastDeliveryAtMs = now;
|
|
470
|
+
const deliveryDelayMs = Math.min(this.lastDeliveryAtMs + this.deliveryIntervalMs - now, 2_147_483_647);
|
|
471
|
+
if (deliveryDelayMs > 0) {
|
|
472
|
+
this.scheduleDelivery(socket, deliveryDelayMs);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
this.clearDeliveryTimer();
|
|
476
|
+
const entry = this.pickDeliveryEntry();
|
|
477
|
+
if (!entry)
|
|
478
|
+
return;
|
|
479
|
+
this.lastDeliveryAtMs = Date.now();
|
|
480
|
+
this.transmittedEventIds.add(entry.eventId);
|
|
481
|
+
const attempt = {
|
|
482
|
+
eventId: entry.eventId,
|
|
483
|
+
timer: setTimeout(() => settle({ ok: false, retryable: true }), ACK_TIMEOUT_MS),
|
|
484
|
+
};
|
|
485
|
+
this.inFlight.set(entry.runId, attempt);
|
|
486
|
+
attempt.timer.unref?.();
|
|
487
|
+
const settle = (result) => {
|
|
488
|
+
// Attempt identity matters: an old callback can refer to the same event
|
|
489
|
+
// after reconnect or timeout, but must not acknowledge the new attempt.
|
|
490
|
+
if (this.inFlight.get(entry.runId) !== attempt)
|
|
491
|
+
return;
|
|
492
|
+
clearTimeout(attempt.timer);
|
|
493
|
+
this.inFlight.delete(entry.runId);
|
|
494
|
+
if (result?.ok) {
|
|
495
|
+
this.removeEntry(entry.eventId);
|
|
496
|
+
this.transmittedEventIds.delete(entry.eventId);
|
|
497
|
+
this.acknowledgedEventIds.add(entry.eventId);
|
|
498
|
+
this.persistAckState();
|
|
499
|
+
for (const resolve of this.acknowledgementWaiters.get(entry.eventId) ?? [])
|
|
500
|
+
resolve();
|
|
501
|
+
this.acknowledgementWaiters.delete(entry.eventId);
|
|
502
|
+
queueMicrotask(() => this.flush(socket));
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
this.scheduleRetry(socket, entry.runId);
|
|
506
|
+
queueMicrotask(() => this.flush(socket));
|
|
507
|
+
};
|
|
508
|
+
try {
|
|
509
|
+
socket.emit("agent.event", {
|
|
510
|
+
eventId: entry.eventId,
|
|
511
|
+
conversationId: entry.conversationId,
|
|
512
|
+
runId: entry.runId,
|
|
513
|
+
event: entry.event,
|
|
514
|
+
}, settle);
|
|
515
|
+
}
|
|
516
|
+
catch {
|
|
517
|
+
settle({ ok: false, retryable: true });
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
isInFlight(eventId) {
|
|
522
|
+
return [...this.inFlight.values()].some((attempt) => attempt.eventId === eventId);
|
|
523
|
+
}
|
|
524
|
+
pickDeliveryEntry() {
|
|
525
|
+
if (this.entries.length === 0)
|
|
526
|
+
return undefined;
|
|
527
|
+
if (this.runOrder.length === 0)
|
|
528
|
+
return this.entries[0];
|
|
529
|
+
const runIds = this.runOrder.filter((runId) => this.entries.some((entry) => entry.runId === runId));
|
|
530
|
+
if (runIds.length === 0)
|
|
531
|
+
return this.entries[0];
|
|
532
|
+
for (let offset = 0; offset < runIds.length; offset += 1) {
|
|
533
|
+
const index = (this.roundRobinCursor + offset) % runIds.length;
|
|
534
|
+
const runId = runIds[index];
|
|
535
|
+
if (this.inFlight.has(runId) || this.retryTimers.has(runId))
|
|
536
|
+
continue;
|
|
537
|
+
const candidates = this.entries
|
|
538
|
+
.filter((entry) => entry.runId === runId)
|
|
539
|
+
.sort((a, b) => a.sequence - b.sequence);
|
|
540
|
+
const next = candidates[0];
|
|
541
|
+
if (!next)
|
|
542
|
+
continue;
|
|
543
|
+
this.roundRobinCursor = (index + 1) % runIds.length;
|
|
544
|
+
return next;
|
|
545
|
+
}
|
|
546
|
+
return undefined;
|
|
547
|
+
}
|
|
548
|
+
removeEntry(eventId) {
|
|
549
|
+
const index = this.entries.findIndex((entry) => entry.eventId === eventId);
|
|
550
|
+
if (index < 0)
|
|
551
|
+
return;
|
|
552
|
+
const [removed] = this.entries.splice(index, 1);
|
|
553
|
+
if (removed) {
|
|
554
|
+
this.pendingBytes -= estimateEntryBytes(removed);
|
|
555
|
+
if (!this.entries.some((entry) => entry.runId === removed.runId)) {
|
|
556
|
+
this.sequences.delete(removed.runId);
|
|
557
|
+
const runIndex = this.runOrder.indexOf(removed.runId);
|
|
558
|
+
if (runIndex >= 0)
|
|
559
|
+
this.runOrder.splice(runIndex, 1);
|
|
560
|
+
if (runIndex < this.roundRobinCursor)
|
|
561
|
+
this.roundRobinCursor--;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
this.writer.removeQueued(eventId);
|
|
565
|
+
}
|
|
566
|
+
isDroppableHeartbeat(entry) {
|
|
567
|
+
return (!this.isInFlight(entry.eventId) &&
|
|
568
|
+
!entry.explicitSource &&
|
|
569
|
+
entry.kind !== "condensation_marker" &&
|
|
570
|
+
isBackgroundHeartbeat(entry.event));
|
|
571
|
+
}
|
|
572
|
+
pickHeartbeatDropCandidate(matches) {
|
|
573
|
+
return this.entries.find((entry) => matches(entry) && this.isDroppableHeartbeat(entry));
|
|
574
|
+
}
|
|
575
|
+
dropEntry(entry) {
|
|
576
|
+
this.removeEntry(entry.eventId);
|
|
577
|
+
this.acknowledgedEventIds.add(entry.eventId);
|
|
578
|
+
}
|
|
579
|
+
enforceRetentionPolicy(preferredRunId, pruneRunHeartbeats = true) {
|
|
580
|
+
const droppedHeartbeatsByRunId = new Map();
|
|
581
|
+
const runIds = pruneRunHeartbeats
|
|
582
|
+
? preferredRunId
|
|
583
|
+
? [preferredRunId]
|
|
584
|
+
: [...new Set(this.entries.map((entry) => entry.runId))]
|
|
585
|
+
: [];
|
|
586
|
+
for (const runId of runIds) {
|
|
587
|
+
const heartbeats = this.entries.filter((entry) => entry.runId === runId && this.isDroppableHeartbeat(entry));
|
|
588
|
+
const excessHeartbeats = heartbeats.slice(0, Math.max(0, heartbeats.length - this.maxIntermediateEventsPerRun));
|
|
589
|
+
for (const drop of excessHeartbeats) {
|
|
590
|
+
this.dropEntry(drop);
|
|
591
|
+
droppedHeartbeatsByRunId.set(runId, (droppedHeartbeatsByRunId.get(runId) ?? 0) + 1);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
while (this.pendingBytes > this.maxEncryptedBytes) {
|
|
595
|
+
const drop = this.pickHeartbeatDropCandidate(() => true);
|
|
596
|
+
if (!drop)
|
|
597
|
+
break;
|
|
598
|
+
this.dropEntry(drop);
|
|
599
|
+
droppedHeartbeatsByRunId.set(drop.runId, (droppedHeartbeatsByRunId.get(drop.runId) ?? 0) + 1);
|
|
600
|
+
}
|
|
601
|
+
for (const [runId, count] of droppedHeartbeatsByRunId) {
|
|
602
|
+
this.pushLog(`event_outbox_heartbeat_pruned run=${runId} count=${count} max_encrypted_bytes=${this.maxEncryptedBytes}`);
|
|
603
|
+
}
|
|
604
|
+
if (this.pendingBytes > this.maxEncryptedBytes && !this.highWaterMarkLogged) {
|
|
605
|
+
this.highWaterMarkLogged = true;
|
|
606
|
+
this.pushLog(`event_outbox_high_watermark bytes=${this.pendingBytes} pending_entries=${this.entries.length} max_encrypted_bytes=${this.maxEncryptedBytes}`);
|
|
607
|
+
}
|
|
608
|
+
if (this.pendingBytes <= this.maxEncryptedBytes)
|
|
609
|
+
this.highWaterMarkLogged = false;
|
|
610
|
+
if (droppedHeartbeatsByRunId.size > 0)
|
|
611
|
+
this.persistAckState();
|
|
612
|
+
}
|
|
613
|
+
scheduleDelivery(socket, delayMs) {
|
|
614
|
+
if (this.deliveryTimer)
|
|
615
|
+
return;
|
|
616
|
+
this.deliveryTimer = setTimeout(() => {
|
|
617
|
+
this.deliveryTimer = null;
|
|
618
|
+
this.flush(socket);
|
|
619
|
+
}, delayMs);
|
|
620
|
+
this.deliveryTimer.unref?.();
|
|
621
|
+
}
|
|
622
|
+
persistAckState() {
|
|
623
|
+
this.ackDirty = true;
|
|
624
|
+
if (this.maintenanceTimer || this.maintenance)
|
|
625
|
+
return;
|
|
626
|
+
this.maintenanceTimer = setTimeout(() => {
|
|
627
|
+
this.maintenanceTimer = null;
|
|
628
|
+
void this.flushMaintenance();
|
|
629
|
+
}, this.ordinaryBatchMs);
|
|
630
|
+
this.maintenanceTimer.unref?.();
|
|
631
|
+
}
|
|
632
|
+
flushMaintenance() {
|
|
633
|
+
if (this.maintenanceTimer)
|
|
634
|
+
clearTimeout(this.maintenanceTimer);
|
|
635
|
+
this.maintenanceTimer = null;
|
|
636
|
+
if (this.maintenance)
|
|
637
|
+
return this.maintenance;
|
|
638
|
+
this.maintenance = this.maintain().finally(() => {
|
|
639
|
+
this.maintenance = null;
|
|
640
|
+
});
|
|
641
|
+
return this.maintenance;
|
|
642
|
+
}
|
|
643
|
+
async maintain() {
|
|
644
|
+
while (this.ackDirty) {
|
|
645
|
+
this.ackDirty = false;
|
|
646
|
+
this.compactionState = "running";
|
|
647
|
+
try {
|
|
648
|
+
await this.writer.flush();
|
|
649
|
+
if (this.writer.getPersistFailure()) {
|
|
650
|
+
this.ackDirty = true;
|
|
651
|
+
this.compactionState = "failed";
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
const durableAcks = new Set(this.acknowledgedEventIds);
|
|
655
|
+
const state = {
|
|
656
|
+
acknowledgedEventIds: [...durableAcks],
|
|
657
|
+
condensedRunIds: [],
|
|
658
|
+
};
|
|
659
|
+
await writeJournalAckStateAsync(this.journalDir, this.key, state);
|
|
660
|
+
for (const [sequence, ids] of this.segmentIds) {
|
|
661
|
+
if (sequence === this.writer.activeSegmentSequence() ||
|
|
662
|
+
![...ids].every((id) => durableAcks.has(id)))
|
|
663
|
+
continue;
|
|
664
|
+
await rm(segmentPath(this.journalDir, sequence), { force: true });
|
|
665
|
+
this.segmentIds.delete(sequence);
|
|
666
|
+
this.segmentSizes.delete(sequence);
|
|
667
|
+
this.refreshSegmentCache();
|
|
668
|
+
}
|
|
669
|
+
// ponytail: keep 10,000 recent receipts plus all retained frames. Older
|
|
670
|
+
// source retries use the backend's durable event-id deduplication.
|
|
671
|
+
const retained = new Set([...this.segmentIds.values()].flatMap((ids) => [...ids]));
|
|
672
|
+
const recent = new Set([...this.acknowledgedEventIds].slice(-10_000));
|
|
673
|
+
for (const id of this.acknowledgedEventIds) {
|
|
674
|
+
if (!retained.has(id) && !recent.has(id)) {
|
|
675
|
+
this.acknowledgedEventIds.delete(id);
|
|
676
|
+
this.ackDirty = true;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
this.ackFailure = null;
|
|
680
|
+
this.compactionState = "idle";
|
|
681
|
+
}
|
|
682
|
+
catch (error) {
|
|
683
|
+
this.ackDirty = true;
|
|
684
|
+
this.ackFailure = error instanceof Error ? error.message : String(error);
|
|
685
|
+
this.compactionState = "failed";
|
|
686
|
+
this.pushLog(`event_outbox_ack_persist_failed error=${this.ackFailure}`);
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
scheduleRetry(socket, runId) {
|
|
692
|
+
if (!socket.connected || this.retryTimers.has(runId))
|
|
693
|
+
return;
|
|
694
|
+
const timer = setTimeout(() => {
|
|
695
|
+
this.retryTimers.delete(runId);
|
|
696
|
+
this.flush(socket);
|
|
697
|
+
}, RETRY_DELAY_MS);
|
|
698
|
+
timer.unref?.();
|
|
699
|
+
this.retryTimers.set(runId, timer);
|
|
700
|
+
}
|
|
701
|
+
clearDeliveryTimer() {
|
|
702
|
+
if (this.deliveryTimer)
|
|
703
|
+
clearTimeout(this.deliveryTimer);
|
|
704
|
+
this.deliveryTimer = null;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
//# sourceMappingURL=event-outbox.js.map
|