visionclaw 0.1.219-beta.0 → 0.1.219-dev.codex-issue-2805-worker-runtime.2
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/dist/agent/api-proxy.d.ts +0 -16
- package/dist/agent/api-proxy.d.ts.map +1 -1
- package/dist/agent/api-proxy.js +9 -8
- package/dist/agent/api-proxy.js.map +1 -1
- package/dist/agent/browser-launcher.d.ts +3 -0
- package/dist/agent/browser-launcher.d.ts.map +1 -1
- package/dist/agent/browser-launcher.js +101 -43
- package/dist/agent/browser-launcher.js.map +1 -1
- package/dist/agent/coding-conventions.d.ts +8 -0
- package/dist/agent/coding-conventions.d.ts.map +1 -0
- package/dist/agent/coding-conventions.js +19 -0
- package/dist/agent/coding-conventions.js.map +1 -0
- package/dist/agent/command-handlers.d.ts.map +1 -1
- package/dist/agent/command-handlers.js +4 -16
- package/dist/agent/command-handlers.js.map +1 -1
- package/dist/agent/context-action-restart-fallback.d.ts.map +1 -1
- package/dist/agent/context-action-restart-fallback.js +9 -3
- package/dist/agent/context-action-restart-fallback.js.map +1 -1
- package/dist/agent/context-refresh.d.ts.map +1 -1
- package/dist/agent/context-refresh.js +0 -7
- package/dist/agent/context-refresh.js.map +1 -1
- package/dist/agent/context.d.ts +2 -4
- package/dist/agent/context.d.ts.map +1 -1
- package/dist/agent/context.js +12 -21
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/engine-fallback.d.ts +0 -35
- package/dist/agent/engine-fallback.d.ts.map +1 -1
- package/dist/agent/engine-fallback.js +4 -3
- package/dist/agent/engine-fallback.js.map +1 -1
- package/dist/agent/engine-switch.d.ts +19 -38
- package/dist/agent/engine-switch.d.ts.map +1 -1
- package/dist/agent/engine-switch.js +46 -111
- package/dist/agent/engine-switch.js.map +1 -1
- package/dist/agent/engines/browser-tool-policy.d.ts +12 -1
- package/dist/agent/engines/browser-tool-policy.d.ts.map +1 -1
- package/dist/agent/engines/browser-tool-policy.js +17 -2
- package/dist/agent/engines/browser-tool-policy.js.map +1 -1
- package/dist/agent/engines/claude/executor-shell-groups.d.ts +11 -0
- package/dist/agent/engines/claude/executor-shell-groups.d.ts.map +1 -0
- package/dist/agent/engines/claude/executor-shell-groups.js +22 -0
- package/dist/agent/engines/claude/executor-shell-groups.js.map +1 -0
- package/dist/agent/engines/claude/session.d.ts +13 -4
- package/dist/agent/engines/claude/session.d.ts.map +1 -1
- package/dist/agent/engines/claude/session.js +165 -84
- package/dist/agent/engines/claude/session.js.map +1 -1
- package/dist/agent/engines/pi/shared/usage.d.ts +6 -8
- package/dist/agent/engines/pi/shared/usage.d.ts.map +1 -1
- package/dist/agent/engines/pi/shared/usage.js +24 -7
- package/dist/agent/engines/pi/shared/usage.js.map +1 -1
- package/dist/agent/engines/pi/tools.d.ts +3 -10
- package/dist/agent/engines/pi/tools.d.ts.map +1 -1
- package/dist/agent/engines/pi/tools.js +6 -20
- package/dist/agent/engines/pi/tools.js.map +1 -1
- package/dist/agent/engines/pi-coding/executor-shell.d.ts +4 -0
- package/dist/agent/engines/pi-coding/executor-shell.d.ts.map +1 -0
- package/dist/agent/engines/pi-coding/executor-shell.js +175 -0
- package/dist/agent/engines/pi-coding/executor-shell.js.map +1 -0
- package/dist/agent/engines/pi-coding/session.d.ts +4 -4
- package/dist/agent/engines/pi-coding/session.d.ts.map +1 -1
- package/dist/agent/engines/pi-coding/session.js +118 -66
- package/dist/agent/engines/pi-coding/session.js.map +1 -1
- package/dist/agent/engines/pi-coding/tools.d.ts +2 -5
- package/dist/agent/engines/pi-coding/tools.d.ts.map +1 -1
- package/dist/agent/engines/pi-coding/tools.js +7 -5
- package/dist/agent/engines/pi-coding/tools.js.map +1 -1
- package/dist/agent/engines/session-types.d.ts +8 -8
- package/dist/agent/engines/session-types.d.ts.map +1 -1
- package/dist/agent/external-context/interrupt.d.ts +0 -2
- package/dist/agent/external-context/interrupt.d.ts.map +1 -1
- package/dist/agent/external-context/interrupt.js +0 -1
- package/dist/agent/external-context/interrupt.js.map +1 -1
- package/dist/agent/external-context/registry.d.ts +0 -2
- package/dist/agent/external-context/registry.d.ts.map +1 -1
- package/dist/agent/external-context/registry.js +2 -4
- package/dist/agent/external-context/registry.js.map +1 -1
- package/dist/agent/external-context/runtime.d.ts.map +1 -1
- package/dist/agent/external-context/runtime.js +15 -14
- package/dist/agent/external-context/runtime.js.map +1 -1
- package/dist/agent/external-context/types.d.ts +0 -2
- package/dist/agent/external-context/types.d.ts.map +1 -1
- package/dist/agent/fast-responder.d.ts +4 -20
- package/dist/agent/fast-responder.d.ts.map +1 -1
- package/dist/agent/fast-responder.js +28 -42
- package/dist/agent/fast-responder.js.map +1 -1
- package/dist/agent/interrupt-handler.d.ts +4 -18
- package/dist/agent/interrupt-handler.d.ts.map +1 -1
- package/dist/agent/interrupt-handler.js +52 -283
- package/dist/agent/interrupt-handler.js.map +1 -1
- package/dist/agent/lab-run-system-prompt.d.ts.map +1 -1
- package/dist/agent/lab-run-system-prompt.js +4 -1
- package/dist/agent/lab-run-system-prompt.js.map +1 -1
- package/dist/agent/lifecycle-trace.d.ts.map +1 -1
- package/dist/agent/lifecycle-trace.js +6 -5
- package/dist/agent/lifecycle-trace.js.map +1 -1
- package/dist/agent/loop.d.ts +9 -3
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +288 -157
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory-protocol.d.ts +2 -2
- package/dist/agent/memory-protocol.d.ts.map +1 -1
- package/dist/agent/memory-protocol.js +3 -15
- package/dist/agent/memory-protocol.js.map +1 -1
- package/dist/agent/memory-store.d.ts +58 -0
- package/dist/agent/memory-store.d.ts.map +1 -0
- package/dist/agent/memory-store.js +152 -0
- package/dist/agent/memory-store.js.map +1 -0
- package/dist/agent/model-provider.d.ts +18 -5
- package/dist/agent/model-provider.d.ts.map +1 -1
- package/dist/agent/model-provider.js +58 -18
- package/dist/agent/model-provider.js.map +1 -1
- package/dist/agent/nightly-maintenance/dreaming-batch.d.ts +184 -0
- package/dist/agent/nightly-maintenance/dreaming-batch.d.ts.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-batch.js +192 -0
- package/dist/agent/nightly-maintenance/dreaming-batch.js.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-files.d.ts +48 -0
- package/dist/agent/nightly-maintenance/dreaming-files.d.ts.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-files.js +109 -0
- package/dist/agent/nightly-maintenance/dreaming-files.js.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-ledger.d.ts +62 -0
- package/dist/agent/nightly-maintenance/dreaming-ledger.d.ts.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-ledger.js +146 -0
- package/dist/agent/nightly-maintenance/dreaming-ledger.js.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-planner.d.ts +86 -0
- package/dist/agent/nightly-maintenance/dreaming-planner.d.ts.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-planner.js +304 -0
- package/dist/agent/nightly-maintenance/dreaming-planner.js.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-runner.d.ts +93 -0
- package/dist/agent/nightly-maintenance/dreaming-runner.d.ts.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-runner.js +156 -0
- package/dist/agent/nightly-maintenance/dreaming-runner.js.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-sources.d.ts +115 -0
- package/dist/agent/nightly-maintenance/dreaming-sources.d.ts.map +1 -0
- package/dist/agent/nightly-maintenance/dreaming-sources.js +270 -0
- package/dist/agent/nightly-maintenance/dreaming-sources.js.map +1 -0
- package/dist/agent/nightly-maintenance/index.d.ts +28 -8
- package/dist/agent/nightly-maintenance/index.d.ts.map +1 -1
- package/dist/agent/nightly-maintenance/index.js +42 -15
- package/dist/agent/nightly-maintenance/index.js.map +1 -1
- package/dist/agent/nightly-maintenance/skill-learning-gate.js +1 -1
- package/dist/agent/nightly-maintenance/skill-learning-gate.js.map +1 -1
- package/dist/agent/nightly-maintenance/vocabulary-processor.d.ts +1 -1
- package/dist/agent/nightly-maintenance/vocabulary-processor.d.ts.map +1 -1
- package/dist/agent/product-identity.d.ts +5 -4
- package/dist/agent/product-identity.d.ts.map +1 -1
- package/dist/agent/product-identity.js +7 -6
- package/dist/agent/product-identity.js.map +1 -1
- package/dist/agent/public-activity.js +1 -1
- package/dist/agent/public-activity.js.map +1 -1
- package/dist/agent/reply-watchdog.d.ts +5 -3
- package/dist/agent/reply-watchdog.d.ts.map +1 -1
- package/dist/agent/reply-watchdog.js +6 -4
- package/dist/agent/reply-watchdog.js.map +1 -1
- package/dist/agent/runtime-context.d.ts +27 -0
- package/dist/agent/runtime-context.d.ts.map +1 -0
- package/dist/agent/runtime-context.js +60 -0
- package/dist/agent/runtime-context.js.map +1 -0
- package/dist/agent/runtime-disclosure-policy.d.ts +6 -0
- package/dist/agent/runtime-disclosure-policy.d.ts.map +1 -0
- package/dist/agent/runtime-disclosure-policy.js +16 -0
- package/dist/agent/runtime-disclosure-policy.js.map +1 -0
- package/dist/agent/runtime-surface.d.ts +15 -4
- package/dist/agent/runtime-surface.d.ts.map +1 -1
- package/dist/agent/runtime-surface.js +0 -1
- package/dist/agent/runtime-surface.js.map +1 -1
- package/dist/agent/session-manager.d.ts +30 -126
- package/dist/agent/session-manager.d.ts.map +1 -1
- package/dist/agent/session-manager.js +60 -484
- package/dist/agent/session-manager.js.map +1 -1
- package/dist/agent/state.d.ts +42 -2
- package/dist/agent/state.d.ts.map +1 -1
- package/dist/agent/state.js +21 -11
- package/dist/agent/state.js.map +1 -1
- package/dist/agent/stream-handler.d.ts +6 -13
- package/dist/agent/stream-handler.d.ts.map +1 -1
- package/dist/agent/stream-handler.js +8 -62
- package/dist/agent/stream-handler.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +2 -0
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +21 -20
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-usage.d.ts.map +1 -1
- package/dist/agent/tool-usage.js +0 -1
- package/dist/agent/tool-usage.js.map +1 -1
- package/dist/agent/transcript/transcript-backfill.js +3 -3
- package/dist/agent/transcript/transcript-backfill.js.map +1 -1
- package/dist/agent/transcript/transcript-indexer.d.ts +3 -31
- package/dist/agent/transcript/transcript-indexer.d.ts.map +1 -1
- package/dist/agent/transcript/transcript-indexer.js +58 -57
- package/dist/agent/transcript/transcript-indexer.js.map +1 -1
- package/dist/agent/transcript-parsers/trivial-tools.d.ts.map +1 -1
- package/dist/agent/transcript-parsers/trivial-tools.js +0 -2
- package/dist/agent/transcript-parsers/trivial-tools.js.map +1 -1
- package/dist/agent/transcript-parsers/types.d.ts +1 -1
- package/dist/agent/transcript-summarizer.d.ts +14 -0
- package/dist/agent/transcript-summarizer.d.ts.map +1 -1
- package/dist/agent/transcript-summarizer.js +69 -45
- package/dist/agent/transcript-summarizer.js.map +1 -1
- package/dist/agent/usage/usage-report-queue.d.ts.map +1 -1
- package/dist/agent/usage/usage-report-queue.js +53 -52
- package/dist/agent/usage/usage-report-queue.js.map +1 -1
- package/dist/agent/usage/usage-report-types.d.ts +1 -1
- package/dist/agent/usage/usage-report-types.d.ts.map +1 -1
- package/dist/agent/vocabulary-glossary.d.ts +3 -3
- package/dist/agent/wake-cycle-runner.d.ts +14 -17
- package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
- package/dist/agent/wake-cycle-runner.js +121 -290
- package/dist/agent/wake-cycle-runner.js.map +1 -1
- package/dist/builtin-skills/owner-manual/SKILL.md +2 -2
- package/dist/calendar/occurrence-ownership.d.ts.map +1 -1
- package/dist/calendar/occurrence-ownership.js +6 -5
- package/dist/calendar/occurrence-ownership.js.map +1 -1
- package/dist/calendar/scheduler.d.ts.map +1 -1
- package/dist/calendar/scheduler.js +4 -3
- package/dist/calendar/scheduler.js.map +1 -1
- package/dist/channels/interface.d.ts +8 -2
- package/dist/channels/interface.d.ts.map +1 -1
- package/dist/channels/interface.js +8 -1
- package/dist/channels/interface.js.map +1 -1
- package/dist/channels/manager.d.ts.map +1 -1
- package/dist/channels/manager.js +5 -1
- package/dist/channels/manager.js.map +1 -1
- package/dist/channels/queue.d.ts.map +1 -1
- package/dist/channels/queue.js +8 -0
- package/dist/channels/queue.js.map +1 -1
- package/dist/channels/tui.d.ts +14 -1
- package/dist/channels/tui.d.ts.map +1 -1
- package/dist/channels/tui.js +64 -2
- package/dist/channels/tui.js.map +1 -1
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +22 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +13 -7
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +51 -64
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +28 -7
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +22 -20
- package/dist/config/types.js.map +1 -1
- package/dist/conversations/lazy-runtime.d.ts +5 -0
- package/dist/conversations/lazy-runtime.d.ts.map +1 -0
- package/dist/conversations/lazy-runtime.js +12 -0
- package/dist/conversations/lazy-runtime.js.map +1 -0
- package/dist/conversations/runtime.d.ts +17 -0
- package/dist/conversations/runtime.d.ts.map +1 -0
- package/dist/conversations/runtime.js +92 -0
- package/dist/conversations/runtime.js.map +1 -0
- package/dist/conversations/scheduler.d.ts +57 -0
- package/dist/conversations/scheduler.d.ts.map +1 -0
- package/dist/conversations/scheduler.js +175 -0
- package/dist/conversations/scheduler.js.map +1 -0
- package/dist/data-processing/pipeline.d.ts +0 -2
- package/dist/data-processing/pipeline.d.ts.map +1 -1
- package/dist/data-processing/pipeline.js +19 -24
- package/dist/data-processing/pipeline.js.map +1 -1
- package/dist/data-processing/restructure.d.ts +0 -2
- package/dist/data-processing/restructure.d.ts.map +1 -1
- package/dist/data-processing/restructure.js +6 -9
- package/dist/data-processing/restructure.js.map +1 -1
- package/dist/data-processing/types.d.ts +2 -9
- package/dist/data-processing/types.d.ts.map +1 -1
- package/dist/data-processing/types.js +2 -13
- package/dist/data-processing/types.js.map +1 -1
- package/dist/email/email-route-store.d.ts.map +1 -1
- package/dist/email/email-route-store.js +6 -5
- package/dist/email/email-route-store.js.map +1 -1
- package/dist/i18n/messages.d.ts +26 -2
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/i18n/messages.js +30 -5
- package/dist/i18n/messages.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +11 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +49 -1
- package/dist/logger.js.map +1 -1
- package/dist/obs/mini-app/status.d.ts.map +1 -1
- package/dist/obs/mini-app/status.js +0 -1
- package/dist/obs/mini-app/status.js.map +1 -1
- package/dist/onboarding/onboarding-service-client.d.ts +1 -0
- package/dist/onboarding/onboarding-service-client.d.ts.map +1 -1
- package/dist/onboarding/onboarding-service-client.js.map +1 -1
- package/dist/onboarding/remote-set-owner.d.ts.map +1 -1
- package/dist/onboarding/remote-set-owner.js +0 -1
- package/dist/onboarding/remote-set-owner.js.map +1 -1
- package/dist/onboarding/set-owner.d.ts +1 -1
- package/dist/onboarding/set-owner.d.ts.map +1 -1
- package/dist/onboarding/set-owner.js +3 -6
- package/dist/onboarding/set-owner.js.map +1 -1
- package/dist/reconfigure.d.ts.map +1 -1
- package/dist/reconfigure.js +1 -32
- package/dist/reconfigure.js.map +1 -1
- package/dist/reset.d.ts.map +1 -1
- package/dist/reset.js +3 -1
- package/dist/reset.js.map +1 -1
- package/dist/threads/active-threads-store.d.ts.map +1 -1
- package/dist/threads/active-threads-store.js +8 -27
- package/dist/threads/active-threads-store.js.map +1 -1
- package/dist/threads/dreaming-execution.d.ts +10 -0
- package/dist/threads/dreaming-execution.d.ts.map +1 -0
- package/dist/threads/dreaming-execution.js +78 -0
- package/dist/threads/dreaming-execution.js.map +1 -0
- package/dist/threads/execution-authority.d.ts +43 -0
- package/dist/threads/execution-authority.d.ts.map +1 -0
- package/dist/threads/execution-authority.js +75 -0
- package/dist/threads/execution-authority.js.map +1 -0
- package/dist/threads/execution-budget.d.ts +107 -0
- package/dist/threads/execution-budget.d.ts.map +1 -0
- package/dist/threads/execution-budget.js +257 -0
- package/dist/threads/execution-budget.js.map +1 -0
- package/dist/threads/execution-host.d.ts +17 -0
- package/dist/threads/execution-host.d.ts.map +1 -0
- package/dist/threads/execution-host.js +66 -0
- package/dist/threads/execution-host.js.map +1 -0
- package/dist/threads/execution-scheduler.d.ts +162 -0
- package/dist/threads/execution-scheduler.d.ts.map +1 -0
- package/dist/threads/execution-scheduler.js +413 -0
- package/dist/threads/execution-scheduler.js.map +1 -0
- package/dist/threads/execution-snapshot.d.ts +91 -0
- package/dist/threads/execution-snapshot.d.ts.map +1 -0
- package/dist/threads/execution-snapshot.js +146 -0
- package/dist/threads/execution-snapshot.js.map +1 -0
- package/dist/threads/execution-store.d.ts +374 -0
- package/dist/threads/execution-store.d.ts.map +1 -0
- package/dist/threads/execution-store.js +910 -0
- package/dist/threads/execution-store.js.map +1 -0
- package/dist/threads/execution-thread-error.d.ts +9 -0
- package/dist/threads/execution-thread-error.d.ts.map +1 -0
- package/dist/threads/execution-thread-error.js +12 -0
- package/dist/threads/execution-thread-error.js.map +1 -0
- package/dist/threads/executor-exit.d.ts +18 -0
- package/dist/threads/executor-exit.d.ts.map +1 -0
- package/dist/threads/executor-exit.js +21 -0
- package/dist/threads/executor-exit.js.map +1 -0
- package/dist/threads/foreground-task.d.ts +91 -0
- package/dist/threads/foreground-task.d.ts.map +1 -0
- package/dist/threads/foreground-task.js +191 -0
- package/dist/threads/foreground-task.js.map +1 -0
- package/dist/threads/foreman-business.d.ts +9 -0
- package/dist/threads/foreman-business.d.ts.map +1 -0
- package/dist/threads/foreman-business.js +117 -0
- package/dist/threads/foreman-business.js.map +1 -0
- package/dist/threads/foreman-client.d.ts +18 -0
- package/dist/threads/foreman-client.d.ts.map +1 -0
- package/dist/threads/foreman-client.js +51 -0
- package/dist/threads/foreman-client.js.map +1 -0
- package/dist/threads/foreman-delivery.d.ts +5 -0
- package/dist/threads/foreman-delivery.d.ts.map +1 -0
- package/dist/threads/foreman-delivery.js +21 -0
- package/dist/threads/foreman-delivery.js.map +1 -0
- package/dist/threads/foreman-execution.d.ts +32 -0
- package/dist/threads/foreman-execution.d.ts.map +1 -0
- package/dist/threads/foreman-execution.js +90 -0
- package/dist/threads/foreman-execution.js.map +1 -0
- package/dist/threads/foreman-host.d.ts +77 -0
- package/dist/threads/foreman-host.d.ts.map +1 -0
- package/dist/threads/foreman-host.js +891 -0
- package/dist/threads/foreman-host.js.map +1 -0
- package/dist/threads/foreman-protocol.d.ts +242 -0
- package/dist/threads/foreman-protocol.d.ts.map +1 -0
- package/dist/threads/foreman-protocol.js +116 -0
- package/dist/threads/foreman-protocol.js.map +1 -0
- package/dist/threads/foreman-store.d.ts +151 -0
- package/dist/threads/foreman-store.d.ts.map +1 -0
- package/dist/threads/foreman-store.js +299 -0
- package/dist/threads/foreman-store.js.map +1 -0
- package/dist/threads/generic-execution.d.ts +25 -0
- package/dist/threads/generic-execution.d.ts.map +1 -0
- package/dist/threads/generic-execution.js +86 -0
- package/dist/threads/generic-execution.js.map +1 -0
- package/dist/threads/init-thread-dir.d.ts +2 -2
- package/dist/threads/init-thread-dir.d.ts.map +1 -1
- package/dist/threads/init-thread-dir.js +6 -6
- package/dist/threads/init-thread-dir.js.map +1 -1
- package/dist/threads/ipc.d.ts +108 -2
- package/dist/threads/ipc.d.ts.map +1 -1
- package/dist/threads/ipc.js +14 -2
- package/dist/threads/ipc.js.map +1 -1
- package/dist/threads/lab-run-thread.d.ts +3 -5
- package/dist/threads/lab-run-thread.d.ts.map +1 -1
- package/dist/threads/lab-run-thread.js +3 -5
- package/dist/threads/lab-run-thread.js.map +1 -1
- package/dist/threads/lab-runtime-policy.d.ts +26 -21
- package/dist/threads/lab-runtime-policy.d.ts.map +1 -1
- package/dist/threads/lab-runtime-policy.js +31 -126
- package/dist/threads/lab-runtime-policy.js.map +1 -1
- package/dist/threads/process-group.d.ts +41 -0
- package/dist/threads/process-group.d.ts.map +1 -0
- package/dist/threads/process-group.js +161 -0
- package/dist/threads/process-group.js.map +1 -0
- package/dist/threads/relay-adapter.d.ts +8 -0
- package/dist/threads/relay-adapter.d.ts.map +1 -1
- package/dist/threads/relay-adapter.js +26 -1
- package/dist/threads/relay-adapter.js.map +1 -1
- package/dist/threads/supervisor.d.ts +191 -57
- package/dist/threads/supervisor.d.ts.map +1 -1
- package/dist/threads/supervisor.js +766 -427
- package/dist/threads/supervisor.js.map +1 -1
- package/dist/threads/task-workspace.d.ts +8 -0
- package/dist/threads/task-workspace.d.ts.map +1 -0
- package/dist/threads/task-workspace.js +52 -0
- package/dist/threads/task-workspace.js.map +1 -0
- package/dist/threads/worker-entry.d.ts.map +1 -1
- package/dist/threads/worker-entry.js +314 -34
- package/dist/threads/worker-entry.js.map +1 -1
- package/dist/threads/worker-execution-runtime.d.ts +75 -0
- package/dist/threads/worker-execution-runtime.d.ts.map +1 -0
- package/dist/threads/worker-execution-runtime.js +142 -0
- package/dist/threads/worker-execution-runtime.js.map +1 -0
- package/dist/threads/worker-execution.d.ts +35 -0
- package/dist/threads/worker-execution.d.ts.map +1 -0
- package/dist/threads/worker-execution.js +2 -0
- package/dist/threads/worker-execution.js.map +1 -0
- package/dist/threads/worker-runtime-policy.d.ts +42 -0
- package/dist/threads/worker-runtime-policy.d.ts.map +1 -0
- package/dist/threads/worker-runtime-policy.js +98 -0
- package/dist/threads/worker-runtime-policy.js.map +1 -0
- package/dist/tools/adapter-tool.d.ts +12 -0
- package/dist/tools/adapter-tool.d.ts.map +1 -0
- package/dist/tools/adapter-tool.js +2 -0
- package/dist/tools/adapter-tool.js.map +1 -0
- package/dist/tools/data-service.d.ts +2 -2
- package/dist/tools/delegation.d.ts +121 -0
- package/dist/tools/delegation.d.ts.map +1 -0
- package/dist/tools/delegation.js +106 -0
- package/dist/tools/delegation.js.map +1 -0
- package/dist/tools/dream-memory.d.ts +122 -0
- package/dist/tools/dream-memory.d.ts.map +1 -0
- package/dist/tools/dream-memory.js +513 -0
- package/dist/tools/dream-memory.js.map +1 -0
- package/dist/tools/email.d.ts +1 -1
- package/dist/tools/execution-control.d.ts +31 -0
- package/dist/tools/execution-control.d.ts.map +1 -0
- package/dist/tools/execution-control.js +71 -0
- package/dist/tools/execution-control.js.map +1 -0
- package/dist/tools/index.d.ts +5 -7
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -13
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp-manager.d.ts +1 -1
- package/dist/tools/memory.d.ts +1 -1
- package/dist/tools/memory.d.ts.map +1 -1
- package/dist/tools/memory.js +69 -45
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/notify.d.ts +5 -0
- package/dist/tools/notify.d.ts.map +1 -1
- package/dist/tools/notify.js +45 -10
- package/dist/tools/notify.js.map +1 -1
- package/dist/tools/skill.d.ts +1 -1
- package/dist/tools/totp.d.ts +1 -1
- package/dist/tui/client.d.ts +1 -16
- package/dist/tui/client.d.ts.map +1 -1
- package/dist/tui/client.js +0 -4
- package/dist/tui/client.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +0 -41
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/protocol.d.ts +2 -1
- package/dist/tui/protocol.d.ts.map +1 -1
- package/dist/tui/protocol.js +2 -1
- package/dist/tui/protocol.js.map +1 -1
- package/dist/tui/renderer.d.ts.map +1 -1
- package/dist/tui/renderer.js +0 -5
- package/dist/tui/renderer.js.map +1 -1
- package/dist/tui/request-store.d.ts +1 -1
- package/dist/tui/request-store.d.ts.map +1 -1
- package/dist/tui/request-store.js +2 -2
- package/dist/tui/request-store.js.map +1 -1
- package/dist/tui/server.d.ts.map +1 -1
- package/dist/tui/server.js +137 -25
- package/dist/tui/server.js.map +1 -1
- package/dist/utils/claude-transcripts.d.ts +6 -0
- package/dist/utils/claude-transcripts.d.ts.map +1 -1
- package/dist/utils/claude-transcripts.js +8 -2
- package/dist/utils/claude-transcripts.js.map +1 -1
- package/dist/utils/restart.d.ts.map +1 -1
- package/dist/utils/restart.js +6 -0
- package/dist/utils/restart.js.map +1 -1
- package/dist-agent/bundle.cjs +2 -2
- package/package.json +1 -1
- package/dist/agent/mailbox.d.ts +0 -50
- package/dist/agent/mailbox.d.ts.map +0 -1
- package/dist/agent/mailbox.js +0 -124
- package/dist/agent/mailbox.js.map +0 -1
- package/dist/agent/nightly-maintenance/memory-dreaming-sweep.d.ts +0 -77
- package/dist/agent/nightly-maintenance/memory-dreaming-sweep.d.ts.map +0 -1
- package/dist/agent/nightly-maintenance/memory-dreaming-sweep.js +0 -158
- package/dist/agent/nightly-maintenance/memory-dreaming-sweep.js.map +0 -1
- package/dist/agent/nightly-maintenance/memory-dreaming.d.ts +0 -116
- package/dist/agent/nightly-maintenance/memory-dreaming.d.ts.map +0 -1
- package/dist/agent/nightly-maintenance/memory-dreaming.js +0 -458
- package/dist/agent/nightly-maintenance/memory-dreaming.js.map +0 -1
- package/dist/threads/task-contracts.d.ts +0 -194
- package/dist/threads/task-contracts.d.ts.map +0 -1
- package/dist/threads/task-contracts.js +0 -82
- package/dist/threads/task-contracts.js.map +0 -1
- package/dist/threads/task-sidecar.d.ts +0 -145
- package/dist/threads/task-sidecar.d.ts.map +0 -1
- package/dist/threads/task-sidecar.js +0 -311
- package/dist/threads/task-sidecar.js.map +0 -1
- package/dist/threads/task-store.d.ts +0 -172
- package/dist/threads/task-store.d.ts.map +0 -1
- package/dist/threads/task-store.js +0 -599
- package/dist/threads/task-store.js.map +0 -1
- package/dist/threads/thread-task-context.d.ts +0 -40
- package/dist/threads/thread-task-context.d.ts.map +0 -1
- package/dist/threads/thread-task-context.js +0 -160
- package/dist/threads/thread-task-context.js.map +0 -1
- package/dist/threads/thread-task-controller.d.ts +0 -122
- package/dist/threads/thread-task-controller.d.ts.map +0 -1
- package/dist/threads/thread-task-controller.js +0 -276
- package/dist/threads/thread-task-controller.js.map +0 -1
- package/dist/threads/thread-task-runtime.d.ts +0 -354
- package/dist/threads/thread-task-runtime.d.ts.map +0 -1
- package/dist/threads/thread-task-runtime.js +0 -917
- package/dist/threads/thread-task-runtime.js.map +0 -1
- package/dist/tools/switch-session.d.ts +0 -15
- package/dist/tools/switch-session.d.ts.map +0 -1
- package/dist/tools/switch-session.js +0 -88
- package/dist/tools/switch-session.js.map +0 -1
- package/dist/tools/thread-tasks.d.ts +0 -23
- package/dist/tools/thread-tasks.d.ts.map +0 -1
- package/dist/tools/thread-tasks.js +0 -122
- package/dist/tools/thread-tasks.js.map +0 -1
package/dist/agent/loop.js
CHANGED
|
@@ -5,21 +5,20 @@
|
|
|
5
5
|
* sleep/wake loop. Each concern is delegated to a focused module:
|
|
6
6
|
*
|
|
7
7
|
* - HeartbeatManager: runtime heartbeat lifecycle
|
|
8
|
-
* - ReplyWatchdog:
|
|
9
|
-
* - WakeCycleRunner:
|
|
8
|
+
* - ReplyWatchdog: deterministic acknowledgment and handoff pressure timer
|
|
9
|
+
* - WakeCycleRunner: wake loop, stream processing, error retry,
|
|
10
10
|
* transcript indexing
|
|
11
11
|
* - InterruptHandler: mid-turn message injection
|
|
12
|
-
* - SessionManager:
|
|
12
|
+
* - SessionManager: conversation session management
|
|
13
13
|
* - ChannelManager: messaging channel adapters
|
|
14
14
|
*/
|
|
15
15
|
import { createDefaultExternalContextRegistry, ExternalContextRegistry } from "./external-context/registry.js";
|
|
16
|
-
import { randomUUID } from "node:crypto";
|
|
16
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
17
17
|
import { beginLifecycleRun, createLifecycleRunId, deriveShadowLifecycleState, endLifecycleRun, traceLifecycle, traceShadowLifecycle } from "./lifecycle-trace.js";
|
|
18
|
-
import { endForegroundWake } from "./lifecycle-transitions.js";
|
|
19
|
-
import { isProactiveWakeEnabled,
|
|
20
|
-
import { DEFAULT_THREAD_ID, resolveThreadId } from "../channels/interface.js";
|
|
18
|
+
import { closeHostEntry, endForegroundWake } from "./lifecycle-transitions.js";
|
|
19
|
+
import { isProactiveWakeEnabled, isTunnelEnabled, isWorkspaceEnabled } from "../config/types.js";
|
|
20
|
+
import { DEFAULT_THREAD_ID, normalizeChannelName, resolveThreadId } from "../channels/interface.js";
|
|
21
21
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
22
|
-
import { buildLabRunSystemPrompt } from "./lab-run-system-prompt.js";
|
|
23
22
|
import { SessionManager } from "./session-manager.js";
|
|
24
23
|
import { buildWakeContext } from "./context.js";
|
|
25
24
|
import { MessageQueue } from "../channels/queue.js";
|
|
@@ -28,7 +27,7 @@ import { ActivityTracker } from "./activity-tracker.js";
|
|
|
28
27
|
import { ThreadActivityController } from "../threads/thread-activity-controller.js";
|
|
29
28
|
import { shouldNotifyUpdate } from "../utils/version-check.js";
|
|
30
29
|
import { shouldRunProactiveUpgradeCheck } from "./update-reminder-policy.js";
|
|
31
|
-
import {
|
|
30
|
+
import { loadOwnerConfig, consumePendingUpgrade, consumePendingRestart, writePendingRestart, getConfigDir, ownerConfigExists, saveOwnerConfig, deleteOnboardingSession, } from "../config/index.js";
|
|
32
31
|
import { syncSystemTimezone } from "../utils/timezone.js";
|
|
33
32
|
import { logger } from "../logger.js";
|
|
34
33
|
import { cleanOldScreenshots } from "../tools/screenshot.js";
|
|
@@ -41,7 +40,7 @@ import { runOnboardingGate } from "./onboarding-gate.js";
|
|
|
41
40
|
import { OnboardingServiceClient } from "../onboarding/onboarding-service-client.js";
|
|
42
41
|
import { deliverPendingQqWelcome, sendWelcomeMessages } from "../onboarding/send-invite.js";
|
|
43
42
|
import { resumePendingChannelBinding } from "../onboarding/resume-channel-binding.js";
|
|
44
|
-
import { answerAndDrop, executionGateReply,
|
|
43
|
+
import { answerAndDrop, executionGateReply, runServiceGate, serviceGateMessage, shouldEnforceServiceGate } from "./service-gate.js";
|
|
45
44
|
import { InterruptHandler } from "./interrupt-handler.js";
|
|
46
45
|
import { ownerTranscriptionContext } from "../transcription-context.js";
|
|
47
46
|
import { transcribeVoiceMessages } from "../utils/transcribe.js";
|
|
@@ -56,13 +55,14 @@ import { t, resolveLocale } from "../i18n/index.js";
|
|
|
56
55
|
import { formatMessageSummary, previewIncomingForConsole, buildIncomingLogData } from "./message-format.js";
|
|
57
56
|
import { buildReplyMapKeyFromMessage, buildReplyTarget, groupActivityDeliveryTargetForMessage, resolveTaskReplyTarget } from "./reply-target.js";
|
|
58
57
|
import { notifyOwnerViaResolvedChain } from "./owner-notify.js";
|
|
59
|
-
import { hasUsableOwnerChannel, resolveOwnerDefaultTarget } from "./owner-channel-resolver.js";
|
|
58
|
+
import { hasUsableOwnerChannel, listBoundOwnerChannels, resolveOwnerDefaultTarget } from "./owner-channel-resolver.js";
|
|
59
|
+
import { runForemanBusinessRead } from "../threads/foreman-business.js";
|
|
60
60
|
import { buildRuntimeSurface, } from "./runtime-surface.js";
|
|
61
61
|
import { getAgentEngine } from "./engines/engine-factory.js";
|
|
62
62
|
import { prepareEngineSwitchBoundary } from "./engine-switch.js";
|
|
63
63
|
import { getClaudeTranscriptDirForProfileDir } from "../utils/claude-transcripts.js";
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
64
|
+
import { applyWorkerRuntimePolicyToSurface, isolateWorkerConfig } from "../threads/worker-runtime-policy.js";
|
|
65
|
+
import { noteMessagesHandedToModel } from "../threads/worker-execution-runtime.js";
|
|
66
66
|
import { closeTranscriptMemoryDb } from "./transcript/transcript-indexer.js";
|
|
67
67
|
import { closeUsageReportQueue } from "./usage/usage-report-queue.js";
|
|
68
68
|
import { maybeAutoBackfill, cancelAutoBackfill } from "./transcript/transcript-backfill.js";
|
|
@@ -83,17 +83,20 @@ import { normalizeAgentFeedback } from "./feedback.js";
|
|
|
83
83
|
import { AgentFeedbackOutbox } from "./feedback-outbox.js";
|
|
84
84
|
import { scheduleRestart, detectProcessManager, restartManagedProcess } from "../utils/restart.js";
|
|
85
85
|
import { NightlyMaintenance, NIGHTLY_RESTART_MIN_UPTIME_MS } from "./nightly-maintenance/index.js";
|
|
86
|
-
import {
|
|
87
|
-
import {
|
|
86
|
+
import { DreamingPlanner } from "./nightly-maintenance/dreaming-planner.js";
|
|
87
|
+
import { DreamingRunner } from "./nightly-maintenance/dreaming-runner.js";
|
|
88
88
|
import { maintainGlossary } from "./vocabulary-glossary.js";
|
|
89
89
|
import { isOwnerInitiatedMessage } from "./owner-initiated-eligibility.js";
|
|
90
90
|
import { retireLegacyServices } from "../service/retired-services.js";
|
|
91
91
|
import { backfillMissingThreadApplications, migrateLegacyThreadApplications, threadApplicationBackfillHealthEvent } from "../threads/application-migration.js";
|
|
92
|
-
import { currentApplicationContext, inheritThreadApplication } from "../threads/application-context.js";
|
|
92
|
+
import { currentApplicationContext, inheritThreadApplication, threadApplication } from "../threads/application-context.js";
|
|
93
|
+
import { ForemanHost } from "../threads/foreman-host.js";
|
|
94
|
+
import { ForemanStore } from "../threads/foreman-store.js";
|
|
95
|
+
import { canDelegateTasks, foremanEventsOf, getForemanClient, installForemanClient, isForemanRuntime, supportsTaskRuntime } from "../threads/foreman-protocol.js";
|
|
96
|
+
import { ForegroundTaskTracker, installForegroundTaskTracker } from "../threads/foreground-task.js";
|
|
93
97
|
import { ThreadApplicationConflict } from "../threads/thread-meta.js";
|
|
94
98
|
import { assertRuntimeApplicationId } from "../config/application-config.js";
|
|
95
99
|
import { migrateProfileToAgentsMd } from "../config/agents-md-migration.js";
|
|
96
|
-
import { ThreadTaskRuntime, endWakeThreadTasks, isTaskRelevantMessage, isTaskResumeMessage, retireStaleResume, setThreadTaskRuntime, } from "../threads/thread-task-runtime.js";
|
|
97
100
|
/**
|
|
98
101
|
* Grace period before an idle cross-runtime engine recovery restarts.
|
|
99
102
|
* Short on purpose: the gate only fires when nothing is in flight.
|
|
@@ -103,25 +106,38 @@ export { getAgentState } from "./state.js";
|
|
|
103
106
|
// Track the current SIGUSR2 handler so we can swap it out without
|
|
104
107
|
// removing listeners registered by other subsystems.
|
|
105
108
|
let activeSigusr2Handler = null;
|
|
106
|
-
/**
|
|
107
|
-
const
|
|
109
|
+
/** Bounded workers drain their local queue until it stays empty for this long. */
|
|
110
|
+
const WORKER_EXECUTION_IDLE_GRACE_MS = 10_000;
|
|
108
111
|
/**
|
|
109
112
|
* Main agent loop. This is the entry point that runs forever.
|
|
110
113
|
*/
|
|
111
114
|
export async function startAgentLoop(config, options) {
|
|
115
|
+
if (options?.signal?.aborted)
|
|
116
|
+
return;
|
|
112
117
|
const workerMode = options?.workerMode ?? null;
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
118
|
+
const workerExecution = workerMode?.execution ?? null;
|
|
119
|
+
if (workerMode && workerExecution) {
|
|
120
|
+
// Enforce isolation at the shared entry point, before channels, context or
|
|
121
|
+
// model services are initialized. Callers need only supply the execution.
|
|
122
|
+
workerMode.relay.restrictToInternalExecution();
|
|
123
|
+
config = isolateWorkerConfig(config);
|
|
124
|
+
}
|
|
116
125
|
// Thread supervisor (main process, multi-thread mode). Assigned during init
|
|
117
126
|
// when enabled; used to refresh cross-thread awareness before each wake.
|
|
118
127
|
let threadSupervisor = null;
|
|
128
|
+
// Foreman host, next to the supervisor in the main process (#2805).
|
|
129
|
+
let activeForemanHost = null;
|
|
130
|
+
// Set once agent state exists. Until then a background-task update is only
|
|
131
|
+
// queued; the loop's first iteration finds it.
|
|
132
|
+
let wakeGeneralLoop = null;
|
|
119
133
|
// HeartbeatManager is constructed after the supervisor and several awaited
|
|
120
134
|
// startup gates. Do not close over that later `const` — recovered workers
|
|
121
135
|
// and live inbound messages can fire these callbacks while it is still in
|
|
122
136
|
// the temporal dead zone.
|
|
123
137
|
let heartbeatForSupervisor = null;
|
|
124
138
|
let nightlyMaintenance = null;
|
|
139
|
+
// Dreaming batches run as maintenance executions on the thread supervisor.
|
|
140
|
+
let dreamingRunner = null;
|
|
125
141
|
let maintenanceRequested = false;
|
|
126
142
|
// =====================================================================
|
|
127
143
|
// 1. Initialization
|
|
@@ -163,19 +179,6 @@ export async function startAgentLoop(config, options) {
|
|
|
163
179
|
// orphaned worker can no longer commit claims owned by its successor.
|
|
164
180
|
...(workerMode ? { ownerId: workerMode.relay.workerInstanceId } : {}),
|
|
165
181
|
});
|
|
166
|
-
// Thread task store (#1996): opened by the same queue owner at the same
|
|
167
|
-
// moment it recovers in-flight claims, and fenced by the same identity.
|
|
168
|
-
// Lab runs are single-shot and keep no task list. Off unless the local
|
|
169
|
-
// config opts in (`threadTasksEnabled: true`). Null means disabled for
|
|
170
|
-
// this process; everything else behaves exactly as before.
|
|
171
|
-
const threadTasks = labRuntimePolicy || !isThreadTasksEnabled(config)
|
|
172
|
-
? null
|
|
173
|
-
: ThreadTaskRuntime.start({
|
|
174
|
-
threadId: executionContext.threadId,
|
|
175
|
-
writerId: workerMode ? workerMode.relay.workerInstanceId : randomUUID(),
|
|
176
|
-
config,
|
|
177
|
-
});
|
|
178
|
-
setThreadTaskRuntime(threadTasks);
|
|
179
182
|
const channelManager = new ChannelManager(config, messageQueue);
|
|
180
183
|
const activityTracker = new ActivityTracker();
|
|
181
184
|
const mainActivityController = workerMode
|
|
@@ -194,22 +197,93 @@ export async function startAgentLoop(config, options) {
|
|
|
194
197
|
// --- Thread supervisor (multi-thread architecture) ---
|
|
195
198
|
// Install before adapters start: connect/hello can immediately replay work.
|
|
196
199
|
// Recover old queues after channels are available for replies.
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
if (!workerMode && config.multiThread.enabled) {
|
|
200
|
+
// The host routes chats to in-process conversations and admitted Tasks to
|
|
201
|
+
// the independent worker pool. Execution workers never spawn nested hosts.
|
|
202
|
+
if (!workerMode) {
|
|
201
203
|
const { ThreadSupervisor } = await import("../threads/supervisor.js");
|
|
204
|
+
// Foreman (#2805): the host owns General's background tasks, their
|
|
205
|
+
// delivery obligations and fallback. Built before the supervisor so the
|
|
206
|
+
// supervisor can route workers' commands and `general` events to it.
|
|
207
|
+
let foremanHost = null;
|
|
208
|
+
let taskStore = null;
|
|
202
209
|
const supervisor = new ThreadSupervisor({
|
|
203
210
|
channelManager,
|
|
204
211
|
messageQueue,
|
|
205
212
|
deferRecovery: true,
|
|
206
|
-
maxConcurrentThreads: config.multiThread.maxConcurrentThreads,
|
|
213
|
+
maxConcurrentThreads: config.workers?.maxConcurrent ?? config.multiThread.maxConcurrentThreads,
|
|
207
214
|
idleTimeoutMs: config.multiThread.idleTtlMs,
|
|
208
215
|
config,
|
|
209
216
|
desktopRuntimeResolution: options?.desktopRuntimeResolution,
|
|
210
217
|
browserRuntimeResolution: options?.browserRuntimeResolution,
|
|
211
218
|
onFeedback: (feedback) => heartbeatForSupervisor?.enqueueFeedback(feedback),
|
|
212
219
|
onBusyChange: () => heartbeatForSupervisor?.nudge(),
|
|
220
|
+
onMaintenanceInput: () => dreamingRunner?.preempt(),
|
|
221
|
+
deliverExecutionEvent: (event, caller) => {
|
|
222
|
+
// Maintenance reads its executions from the store when they end.
|
|
223
|
+
if (caller.kind === "nightly")
|
|
224
|
+
return Promise.resolve(true);
|
|
225
|
+
if (caller.kind === "general")
|
|
226
|
+
return foremanHost?.deliverEvent(event, caller) ?? Promise.resolve(false);
|
|
227
|
+
if (caller.kind !== "tui")
|
|
228
|
+
return Promise.resolve(false);
|
|
229
|
+
return Promise.resolve(channelManager.getAdapter("tui") !== undefined);
|
|
230
|
+
},
|
|
231
|
+
// Workers install a Foreman client only when Foreman is on; this answers
|
|
232
|
+
// for the worker the supervisor actually talks to.
|
|
233
|
+
handleForemanCommand: (threadId, command) => foremanHost?.handle(threadId, command)
|
|
234
|
+
?? Promise.resolve({ ok: false, text: "Error: background tasks are not available in this conversation." }),
|
|
235
|
+
handleForemanBusinessRead: (executionId, command, workspace) => foremanHost?.readBusiness(executionId, command.tool, command.args, workspace)
|
|
236
|
+
?? Promise.resolve({ ok: false, text: "Business reads are unavailable" }),
|
|
237
|
+
});
|
|
238
|
+
supervisor.onExecutionEvent((event, caller) => {
|
|
239
|
+
if (caller.kind !== "tui")
|
|
240
|
+
return;
|
|
241
|
+
channelManager.getAdapter("tui")?.publishExecutionEvent(event);
|
|
242
|
+
});
|
|
243
|
+
const foremanExecutions = supervisor.executionService();
|
|
244
|
+
if (foremanExecutions) {
|
|
245
|
+
const store = new ForemanStore();
|
|
246
|
+
taskStore = store;
|
|
247
|
+
foremanHost = new ForemanHost({
|
|
248
|
+
canReadBusiness: (_threadId, target) => isWorkspaceEnabled(config) && target !== null
|
|
249
|
+
&& listBoundOwnerChannels(config, loadOwnerConfig()).some((owner) => owner.validationStatus === "verified"
|
|
250
|
+
&& owner.kind === "dm" && normalizeChannelName(owner.channel) === normalizeChannelName(target.channel) && owner.to === target.to),
|
|
251
|
+
readBusiness: runForemanBusinessRead,
|
|
252
|
+
allowDelegation: () => isForemanRuntime(config),
|
|
253
|
+
executions: foremanExecutions,
|
|
254
|
+
store,
|
|
255
|
+
enqueueToGeneral: (threadId, message) => {
|
|
256
|
+
if (threadId === DEFAULT_THREAD_ID) {
|
|
257
|
+
messageQueue.enqueue(message);
|
|
258
|
+
wakeGeneralLoop?.();
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// The conversation's durable queue and application admission.
|
|
262
|
+
const app = threadApplication(threadId, config);
|
|
263
|
+
if (!supervisor.tryRouteMessage({ ...message, threadId, ...(app ? { app } : {}) }, threadId)) {
|
|
264
|
+
throw new Error(`Thread ${threadId} did not accept a background-task update`);
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
deliver: (target, text, threadId) => channelManager.tryDeliver(target, text, {
|
|
268
|
+
logContext: "background task delivery",
|
|
269
|
+
context: { kind: "task_update", ...(threadId === DEFAULT_THREAD_ID ? {} : { businessThreadId: threadId }) },
|
|
270
|
+
}),
|
|
271
|
+
ownerTarget: () => {
|
|
272
|
+
const owner = resolveOwnerDefaultTarget(config, loadOwnerConfig());
|
|
273
|
+
return owner ? { channel: owner.channel, to: owner.to } : null;
|
|
274
|
+
},
|
|
275
|
+
locale: () => resolveLocale(loadOwnerConfig().language),
|
|
276
|
+
});
|
|
277
|
+
const host = foremanHost;
|
|
278
|
+
installForemanClient(supportsTaskRuntime() ? { delegationEnabled: isForemanRuntime(config), request: (command) => host.handle(DEFAULT_THREAD_ID, command) } : null);
|
|
279
|
+
}
|
|
280
|
+
activeForemanHost = foremanHost;
|
|
281
|
+
// Keep the Task ledger and delivery adapters alive until conversations and
|
|
282
|
+
// workers settle. Their final receipts may still arrive during shutdown.
|
|
283
|
+
registerShutdownCallback(async () => {
|
|
284
|
+
foremanHost?.stop();
|
|
285
|
+
await supervisor.shutdownAll();
|
|
286
|
+
taskStore?.close();
|
|
213
287
|
});
|
|
214
288
|
channelManager.setThreadRouter((msg, threadId) => supervisor.routeMessage(msg, threadId));
|
|
215
289
|
// Expose for the main-loop wake context to refresh its own awareness.
|
|
@@ -247,16 +321,14 @@ export async function startAgentLoop(config, options) {
|
|
|
247
321
|
catch (err) {
|
|
248
322
|
logger.warn(`Graceful shutdown did not complete cleanly: ${err instanceof Error ? err.message : String(err)}`);
|
|
249
323
|
}
|
|
250
|
-
// After the channels, so it never delays them. A short grace lets an
|
|
251
|
-
// in-flight sidecar call commit; unconsumed events wait for the next start.
|
|
252
|
-
await threadTasks?.close(2_000);
|
|
253
324
|
messageQueue.close();
|
|
254
325
|
logger.system("Graceful shutdown complete.");
|
|
255
326
|
});
|
|
256
327
|
// Runtime logs and active Claude/Pi transcripts share one provider-neutral
|
|
257
328
|
// upload path. Each worker owns a thread-local spool, so worker crashes and
|
|
258
329
|
// network outages cannot lose or corrupt the main process queue.
|
|
259
|
-
|
|
330
|
+
// A private-content execution (Dreaming) never ships its transcripts or logs.
|
|
331
|
+
const runtimeTelemetry = workerExecution?.privateContent ? null : startRuntimeTelemetryShipper(config, {
|
|
260
332
|
...(workerMode ? { threadId: workerMode.threadId } : {}),
|
|
261
333
|
});
|
|
262
334
|
registerShutdownCallback(async () => {
|
|
@@ -264,11 +336,10 @@ export async function startAgentLoop(config, options) {
|
|
|
264
336
|
});
|
|
265
337
|
if (threadSupervisor) {
|
|
266
338
|
threadSupervisor.recoverPendingThreads();
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
});
|
|
339
|
+
// After channels start, so delivered results reach their adapters.
|
|
340
|
+
threadSupervisor.startExecutions();
|
|
341
|
+
// Its first sweep sends fallbacks a restart left overdue.
|
|
342
|
+
activeForemanHost?.start();
|
|
272
343
|
}
|
|
273
344
|
// --- Resume an interrupted channel binding ---
|
|
274
345
|
// Runs BEFORE the onboarding gate on purpose. A binding whose completion tail
|
|
@@ -321,8 +392,8 @@ export async function startAgentLoop(config, options) {
|
|
|
321
392
|
wakeResolver = null;
|
|
322
393
|
}
|
|
323
394
|
}
|
|
324
|
-
/** Wait for
|
|
325
|
-
function
|
|
395
|
+
/** Wait for execution queue work or for the worker's idle grace period to elapse. */
|
|
396
|
+
function waitForExecutionQueueOrIdle() {
|
|
326
397
|
if (!messageQueue.isEmpty())
|
|
327
398
|
return Promise.resolve(true);
|
|
328
399
|
return new Promise((resolve) => {
|
|
@@ -345,7 +416,7 @@ export async function startAgentLoop(config, options) {
|
|
|
345
416
|
finish();
|
|
346
417
|
return;
|
|
347
418
|
}
|
|
348
|
-
timer = setTimeout(finish,
|
|
419
|
+
timer = setTimeout(finish, WORKER_EXECUTION_IDLE_GRACE_MS);
|
|
349
420
|
});
|
|
350
421
|
}
|
|
351
422
|
// --- Heartbeat manager ---
|
|
@@ -445,7 +516,6 @@ export async function startAgentLoop(config, options) {
|
|
|
445
516
|
hasRepliedInCycle: false,
|
|
446
517
|
notifiedUserThisWake: false,
|
|
447
518
|
liveAssistantTexts: new Set(),
|
|
448
|
-
codingCompletionTaskStartedAt: undefined,
|
|
449
519
|
restartTunnel: options?.restartTunnel,
|
|
450
520
|
commandDispatcher: heartbeat.commandDispatcher,
|
|
451
521
|
compacting: false,
|
|
@@ -467,9 +537,18 @@ export async function startAgentLoop(config, options) {
|
|
|
467
537
|
getActiveThreads: activeThreadSupervisor
|
|
468
538
|
? () => activeThreadSupervisor.getThreadsOverview()
|
|
469
539
|
: undefined,
|
|
540
|
+
executions: activeThreadSupervisor?.executionService() ?? undefined,
|
|
470
541
|
};
|
|
471
542
|
initAgentState(agentState);
|
|
472
543
|
const executionOwner = new ExecutionOwner(agentState);
|
|
544
|
+
wakeGeneralLoop = wakeMainLoop;
|
|
545
|
+
// Foreman's foreground limit, for conversational sessions that can delegate.
|
|
546
|
+
// Thread-local: getConfigDir() is the thread's own directory in a worker.
|
|
547
|
+
// Skill Learning drives this same session and is exempt.
|
|
548
|
+
const foregroundTasks = !workerExecution && canDelegateTasks()
|
|
549
|
+
? new ForegroundTaskTracker(getConfigDir(), () => new Date(), () => agentState.learning)
|
|
550
|
+
: null;
|
|
551
|
+
installForegroundTaskTracker(foregroundTasks);
|
|
473
552
|
// Arm the always-on runtime heartbeat loop now that `agentState` is
|
|
474
553
|
// wired. Workers deliberately skip runtime heartbeat; `heartbeat.nudge()`
|
|
475
554
|
// remains safe because it no-ops until startRuntime() is called.
|
|
@@ -530,8 +609,13 @@ export async function startAgentLoop(config, options) {
|
|
|
530
609
|
}
|
|
531
610
|
const builtRuntime = await buildRuntimeSurface(config, options?.desktopRuntimeResolution, options?.browserRuntimeResolution);
|
|
532
611
|
const startupDynamicMcpServerCount = builtRuntime.startupDynamicMcpServerCount;
|
|
533
|
-
|
|
534
|
-
|
|
612
|
+
// The host applies the restriction last; an adapter supplies only its tool
|
|
613
|
+
// registrations, and the host-owned budget is attached after everything else.
|
|
614
|
+
const runtimeSurface = workerExecution
|
|
615
|
+
? {
|
|
616
|
+
...applyWorkerRuntimePolicyToSurface(builtRuntime.runtimeSurface, workerExecution.policy, workerExecution.adapterTools),
|
|
617
|
+
executionBudget: workerExecution.budget,
|
|
618
|
+
}
|
|
535
619
|
: builtRuntime.runtimeSurface;
|
|
536
620
|
const finAppCapabilityChangedDuringBuild = finAppCapabilityState.active !== null &&
|
|
537
621
|
finAppCapabilityState.active !== runtimeSurface.credentialBacked.finApp;
|
|
@@ -568,11 +652,10 @@ export async function startAgentLoop(config, options) {
|
|
|
568
652
|
logger.system(`Loaded ${startupDynamicMcpServerCount} dynamic MCP server(s) from disk`);
|
|
569
653
|
}
|
|
570
654
|
// --- Engine switch boundary -----------------------------------------
|
|
571
|
-
// If
|
|
572
|
-
// `config.json` currently selects,
|
|
573
|
-
//
|
|
574
|
-
//
|
|
575
|
-
// post-collapse mailbox (no coding session to resume).
|
|
655
|
+
// If the prior transcript was written by a different engine than
|
|
656
|
+
// `config.json` currently selects, retire it into a fresh session with a
|
|
657
|
+
// summary. This must run BEFORE constructing SessionManager so the
|
|
658
|
+
// manager does not resume the retired session id.
|
|
576
659
|
const currentEngine = getAgentEngine(config);
|
|
577
660
|
let engineSwitchBoundary = null;
|
|
578
661
|
try {
|
|
@@ -582,32 +665,42 @@ export async function startAgentLoop(config, options) {
|
|
|
582
665
|
logger.warn(`[engine-switch] boundary handling failed; continuing with fresh sessions: ${err instanceof Error ? err.message : String(err)}`);
|
|
583
666
|
}
|
|
584
667
|
// One registry per agent process, shared by wake collection and both prompt paths.
|
|
585
|
-
const externalContextRegistry =
|
|
668
|
+
const externalContextRegistry = workerExecution
|
|
586
669
|
? new ExternalContextRegistry([])
|
|
587
670
|
: createDefaultExternalContextRegistry(config);
|
|
588
671
|
const session = new SessionManager(config, () => {
|
|
589
|
-
if (
|
|
590
|
-
return
|
|
591
|
-
}
|
|
672
|
+
if (workerExecution)
|
|
673
|
+
return workerExecution.buildSystemPrompt(config);
|
|
592
674
|
return buildSystemPrompt(config, ownerConfig, externalContextRegistry, {
|
|
593
675
|
hostCapabilities: runtimeSurface.hostCapabilities,
|
|
594
676
|
desktopAvailable: runtimeSurface.desktop.available,
|
|
595
677
|
browserSelection: runtimeSurface.browserSelection,
|
|
596
678
|
credentialBacked: runtimeSurface.credentialBacked,
|
|
597
679
|
conversation: { threadId: workerMode?.threadId },
|
|
680
|
+
foreman: canDelegateTasks(),
|
|
598
681
|
});
|
|
599
|
-
}, runtimeSurface, {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
});
|
|
603
|
-
// Hand the combined engine-switch summary to the freshly created
|
|
604
|
-
// general session (rotation + mailbox clearing already happened
|
|
605
|
-
// before SessionManager construction).
|
|
682
|
+
}, runtimeSurface, options?.workspaceCwd ? { workspaceCwd: options.workspaceCwd } : {});
|
|
683
|
+
// Hand the engine-switch summary to the freshly created session (rotation
|
|
684
|
+
// already happened before SessionManager construction).
|
|
606
685
|
if (engineSwitchBoundary) {
|
|
607
|
-
session.injectSummary(
|
|
686
|
+
session.injectSummary(engineSwitchBoundary.combinedSummary);
|
|
608
687
|
}
|
|
609
|
-
logger.system(`Dual session: ${ownerConfig.dualSessionEnabled ? "enabled" : "disabled"}`);
|
|
610
688
|
agentState.sessionManager = session;
|
|
689
|
+
if (workerExecution) {
|
|
690
|
+
// Exhausting the budget asks the active session to stop; the execution's
|
|
691
|
+
// usage, including the time already spent, survives this process.
|
|
692
|
+
const budget = workerExecution.budget;
|
|
693
|
+
budget.onStop((reason) => {
|
|
694
|
+
logger.warn(`[execution-budget] ${reason}; stopping run=${workerExecution.id}`);
|
|
695
|
+
session.requestStop();
|
|
696
|
+
});
|
|
697
|
+
const disarmDeadline = budget.armDeadline();
|
|
698
|
+
registerShutdownCallback(() => {
|
|
699
|
+
disarmDeadline();
|
|
700
|
+
budget.close();
|
|
701
|
+
return Promise.resolve();
|
|
702
|
+
});
|
|
703
|
+
}
|
|
611
704
|
registerShutdownCallback(async () => {
|
|
612
705
|
// Bound the whole release so it fits the supervisor budgets together with
|
|
613
706
|
// the earlier callbacks (pm2 kill_timeout 30s); a child still closing
|
|
@@ -634,26 +727,6 @@ export async function startAgentLoop(config, options) {
|
|
|
634
727
|
// Expose the wake function so out-of-loop components can trigger an
|
|
635
728
|
// immediate wake without threading the closure through every call site.
|
|
636
729
|
agentState.wakeMainLoop = wakeMainLoop;
|
|
637
|
-
// Thread task resumes (#1996 PR 5): after a wake the runtime queues the
|
|
638
|
-
// next runnable task as a system row and wakes the loop, so queued work
|
|
639
|
-
// continues without a new owner message, with proactive wakes off and in
|
|
640
|
-
// workers. It never queues while a wake runs or execution is gated; the
|
|
641
|
-
// row is still checked against the task when it is dequeued.
|
|
642
|
-
// TODO: a resume queued just before the service gate engages is discarded
|
|
643
|
-
// with the gated queue (main) or still runs (workers, which have no gate
|
|
644
|
-
// pass and whose system rows skip the gate reply). The window is tiny.
|
|
645
|
-
threadTasks?.enableResumes({
|
|
646
|
-
queue: messageQueue,
|
|
647
|
-
isBusy: () => agentState.busy || !messageQueue.isEmpty(),
|
|
648
|
-
isGated: () => readFundLeagueHold() !== null
|
|
649
|
-
// A worker's heartbeat holds the status from its start; the main
|
|
650
|
-
// process persists every change, so read that instead.
|
|
651
|
-
|| (workerMode ? persistedServiceStopped(getConfigFile()) : shouldEnforceServiceGate(heartbeat.lastServiceStatus)),
|
|
652
|
-
wake: wakeMainLoop,
|
|
653
|
-
});
|
|
654
|
-
// Startup: work that was queued, or resumed and interrupted, before the
|
|
655
|
-
// previous process stopped continues now.
|
|
656
|
-
void threadTasks?.requestResume();
|
|
657
730
|
const interruptHandler = new InterruptHandler({
|
|
658
731
|
externalContextRegistry,
|
|
659
732
|
session: session.activeSession,
|
|
@@ -676,6 +749,10 @@ export async function startAgentLoop(config, options) {
|
|
|
676
749
|
// Maintenance owns the session until the current skill/transcript settles.
|
|
677
750
|
// Inbound messages are already durable; process them at the next boundary.
|
|
678
751
|
if (nightlyMaintenance?.isRunning) {
|
|
752
|
+
// Owner input preempts a Dreaming batch; the step still ends only after
|
|
753
|
+
// its executor is confirmed stopped.
|
|
754
|
+
if (isOwnerInitiatedMessage(msg))
|
|
755
|
+
dreamingRunner?.preempt();
|
|
679
756
|
void interruptHandler.acknowledgeMaintenance(msg);
|
|
680
757
|
return;
|
|
681
758
|
}
|
|
@@ -806,6 +883,7 @@ export async function startAgentLoop(config, options) {
|
|
|
806
883
|
else {
|
|
807
884
|
registerShutdownCallback(() => {
|
|
808
885
|
closeTranscriptMemoryDb();
|
|
886
|
+
closeUsageReportQueue();
|
|
809
887
|
return Promise.resolve();
|
|
810
888
|
});
|
|
811
889
|
}
|
|
@@ -823,9 +901,19 @@ export async function startAgentLoop(config, options) {
|
|
|
823
901
|
messageQueue,
|
|
824
902
|
engineFallback,
|
|
825
903
|
agentState,
|
|
826
|
-
singleShot:
|
|
904
|
+
singleShot: workerExecution !== null,
|
|
827
905
|
});
|
|
828
906
|
if (!workerMode) {
|
|
907
|
+
const supervisorForDreaming = threadSupervisor;
|
|
908
|
+
dreamingRunner = supervisorForDreaming
|
|
909
|
+
? new DreamingRunner(new DreamingPlanner({
|
|
910
|
+
threadIds: () => supervisorForDreaming.getPersistedThreadIds(),
|
|
911
|
+
vocabularyLearning: () => config.vocabularyLearningEnabled !== false,
|
|
912
|
+
ownerPublicId: () => ownerConfig.ownerPublicId,
|
|
913
|
+
}), supervisorForDreaming)
|
|
914
|
+
: null;
|
|
915
|
+
if (!dreamingRunner)
|
|
916
|
+
logger.system("[nightly-maintenance] Dreaming needs the thread supervisor (multiThread); skipped on this profile");
|
|
829
917
|
nightlyMaintenance = new NightlyMaintenance({
|
|
830
918
|
tryAcquire: () => {
|
|
831
919
|
if (agentState.busy || agentState.learning || agentState.compacting || agentState.gated
|
|
@@ -836,12 +924,20 @@ export async function startAgentLoop(config, options) {
|
|
|
836
924
|
if (threadSupervisor && !resumeWorkers)
|
|
837
925
|
return null;
|
|
838
926
|
executionOwner.setBusy(true, "maintenance");
|
|
927
|
+
dreamingRunner?.beginStep();
|
|
839
928
|
heartbeat.nudge();
|
|
840
929
|
return () => {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
930
|
+
// Maintenance holds the slot the way a foreground wake does. Release
|
|
931
|
+
// it through Stopping so workers resume only after the slot is free.
|
|
932
|
+
endForegroundWake({
|
|
933
|
+
from: "Running",
|
|
934
|
+
cleanup: () => { agentState.learning = false; },
|
|
935
|
+
release: () => {
|
|
936
|
+
executionOwner.setBusy(false, "maintenance_release");
|
|
937
|
+
resumeWorkers?.();
|
|
938
|
+
heartbeat.nudge();
|
|
939
|
+
},
|
|
940
|
+
});
|
|
845
941
|
};
|
|
846
942
|
},
|
|
847
943
|
hasPendingSkills: hasPendingSkillLearning,
|
|
@@ -859,18 +955,18 @@ export async function startAgentLoop(config, options) {
|
|
|
859
955
|
watchdog.cancel();
|
|
860
956
|
}
|
|
861
957
|
},
|
|
862
|
-
|
|
958
|
+
startDreaming: () => {
|
|
863
959
|
if (config.vocabularyLearningEnabled !== false && ownerConfig.ownerPublicId) {
|
|
864
960
|
maintainGlossary(ownerConfig.ownerPublicId);
|
|
865
961
|
}
|
|
866
|
-
|
|
962
|
+
dreamingRunner?.startNight();
|
|
867
963
|
},
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
964
|
+
dreamBatch: async (localDay) => {
|
|
965
|
+
if (!dreamingRunner)
|
|
966
|
+
return "idle";
|
|
967
|
+
const step = await dreamingRunner.runBatch(localDay);
|
|
968
|
+
return step.kind;
|
|
872
969
|
},
|
|
873
|
-
lastDreamedDay: readDeepNightDreamDay,
|
|
874
970
|
canRestart: () => config.nightlyIdleRestartEnabled !== false
|
|
875
971
|
&& process.uptime() * 1000 >= NIGHTLY_RESTART_MIN_UPTIME_MS
|
|
876
972
|
&& detectProcessManager() !== null,
|
|
@@ -885,8 +981,14 @@ export async function startAgentLoop(config, options) {
|
|
|
885
981
|
if (options?.onReady) {
|
|
886
982
|
options.onReady({ agentState, sessionManager: session, messageQueue, ownerConfig });
|
|
887
983
|
}
|
|
888
|
-
|
|
889
|
-
|
|
984
|
+
const wakeOnShutdown = () => { session.requestStop(); wakeMainLoop(); };
|
|
985
|
+
options?.signal?.addEventListener("abort", wakeOnShutdown, { once: true });
|
|
986
|
+
registerShutdownCallback(() => {
|
|
987
|
+
options?.signal?.removeEventListener("abort", wakeOnShutdown);
|
|
988
|
+
return Promise.resolve();
|
|
989
|
+
});
|
|
990
|
+
logger.system(workerExecution
|
|
991
|
+
? "Single-shot worker loop started. Waiting for its execution dispatch..."
|
|
890
992
|
: "Agent loop started. Waiting for messages or heartbeat...");
|
|
891
993
|
// =====================================================================
|
|
892
994
|
// 2. Main loop
|
|
@@ -904,16 +1006,29 @@ export async function startAgentLoop(config, options) {
|
|
|
904
1006
|
let lastWakeScreenshotMs = 0;
|
|
905
1007
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- intentional infinite loop
|
|
906
1008
|
while (true) {
|
|
1009
|
+
if (options?.signal?.aborted)
|
|
1010
|
+
break;
|
|
907
1011
|
const leagueHold = readFundLeagueHold();
|
|
908
1012
|
if (leagueHold) {
|
|
909
|
-
|
|
910
|
-
|
|
1013
|
+
// The durable marker already blocks the next wake. A slot that is still
|
|
1014
|
+
// held stops first; an idle loop closes the entry directly. Neither
|
|
1015
|
+
// confirms an engine barrier.
|
|
1016
|
+
closeHostEntry({
|
|
1017
|
+
busy: agentState.busy,
|
|
1018
|
+
requestStop: () => { agentState.requestStop(); },
|
|
1019
|
+
markClosed: () => {
|
|
1020
|
+
executionOwner.setBusy(false, "league_hold");
|
|
1021
|
+
agentState.gated = true;
|
|
1022
|
+
},
|
|
1023
|
+
});
|
|
911
1024
|
await new Promise((resolve) => { wakeResolver = resolve; });
|
|
912
1025
|
wakeResolver = null;
|
|
913
1026
|
continue;
|
|
914
1027
|
}
|
|
915
1028
|
// --- Reset per-cycle state ---
|
|
916
1029
|
messageQueue.beginWakeCycle();
|
|
1030
|
+
// A task handed off in an earlier wake no longer blocks new foreground work.
|
|
1031
|
+
foregroundTasks?.beginWake();
|
|
917
1032
|
executionOwner.setBusy(false, "wake_reset");
|
|
918
1033
|
agentState.gated = false;
|
|
919
1034
|
agentState.stopRequested = false;
|
|
@@ -922,7 +1037,6 @@ export async function startAgentLoop(config, options) {
|
|
|
922
1037
|
agentState.notifiedUserThisWake = false;
|
|
923
1038
|
agentState.ownerEscalationsThisWake = 0;
|
|
924
1039
|
agentState.liveAssistantTexts = new Set();
|
|
925
|
-
agentState.codingCompletionTaskStartedAt = undefined;
|
|
926
1040
|
agentState.learning = false;
|
|
927
1041
|
agentState.replyMap.clear();
|
|
928
1042
|
session.clearStop();
|
|
@@ -954,11 +1068,6 @@ export async function startAgentLoop(config, options) {
|
|
|
954
1068
|
});
|
|
955
1069
|
nextProactiveWakeAt = sleepMs === null ? null : nextProactiveWakeAt ?? Date.now() + sleepMs;
|
|
956
1070
|
const isFirstWake = firstIteration;
|
|
957
|
-
// Worker: report idle status before sleeping so the supervisor's
|
|
958
|
-
// cross-thread awareness snapshot reflects this thread as idle.
|
|
959
|
-
if (workerMode && !isFirstWake) {
|
|
960
|
-
workerMode.relay.relayStatus(false, "idle");
|
|
961
|
-
}
|
|
962
1071
|
// We are about to go idle, which is the only safe moment to move back
|
|
963
1072
|
// across a runtime boundary: that costs a restart and collapses the
|
|
964
1073
|
// session into a summary, so doing it mid-conversation would cut a live
|
|
@@ -1007,6 +1116,8 @@ export async function startAgentLoop(config, options) {
|
|
|
1007
1116
|
resolve();
|
|
1008
1117
|
}
|
|
1009
1118
|
});
|
|
1119
|
+
if (options?.signal?.aborted)
|
|
1120
|
+
break;
|
|
1010
1121
|
if (proactiveWakeSchedule.changed && messageQueue.isEmpty()) {
|
|
1011
1122
|
proactiveWakeSchedule.changed = false;
|
|
1012
1123
|
nextProactiveWakeAt = null;
|
|
@@ -1116,21 +1227,23 @@ export async function startAgentLoop(config, options) {
|
|
|
1116
1227
|
stopRequested: agentState.stopRequested,
|
|
1117
1228
|
busy: agentState.busy,
|
|
1118
1229
|
recovering,
|
|
1119
|
-
//
|
|
1120
|
-
//
|
|
1121
|
-
barrierConfirmed:
|
|
1230
|
+
// Pi confirms this with `agent_settled`. An abort is not a receipt,
|
|
1231
|
+
// so an engine that cannot prove it stopped stays unconfirmed.
|
|
1232
|
+
barrierConfirmed: session.executionBarrierConfirmed(),
|
|
1122
1233
|
}),
|
|
1123
1234
|
legacy: {
|
|
1124
1235
|
busy: agentState.busy,
|
|
1125
1236
|
gated: agentState.gated,
|
|
1126
1237
|
stopRequested: agentState.stopRequested,
|
|
1127
1238
|
},
|
|
1128
|
-
barrierConfirmed:
|
|
1239
|
+
barrierConfirmed: session.executionBarrierConfirmed(),
|
|
1129
1240
|
});
|
|
1130
1241
|
};
|
|
1131
1242
|
const releaseLifecycleRun = (reason) => {
|
|
1132
1243
|
// Stopping is one beat when nothing is still in flight. The slot stays
|
|
1133
1244
|
// busy until cleanup finishes, so busy=false is not what ends the wake.
|
|
1245
|
+
// A worker thread is the same loop: its busy flag lives on the
|
|
1246
|
+
// supervisor, and it is cleared only after this cleanup.
|
|
1134
1247
|
endForegroundWake({
|
|
1135
1248
|
// A failed compaction is still this same foreground run. Phase 3 is
|
|
1136
1249
|
// what moves that path into Recovering before the wake ends.
|
|
@@ -1151,6 +1264,10 @@ export async function startAgentLoop(config, options) {
|
|
|
1151
1264
|
endLifecycleRun(lifecycleRunId);
|
|
1152
1265
|
},
|
|
1153
1266
|
release: () => {
|
|
1267
|
+
// The supervisor learns a worker is idle here, after cleanup, not
|
|
1268
|
+
// at the next sleep. The local slot is released for both loops.
|
|
1269
|
+
if (workerMode)
|
|
1270
|
+
workerMode.relay.relayStatus(false, "idle");
|
|
1154
1271
|
executionOwner.setBusy(false, reason, lifecycleRunId);
|
|
1155
1272
|
},
|
|
1156
1273
|
});
|
|
@@ -1191,10 +1308,6 @@ export async function startAgentLoop(config, options) {
|
|
|
1191
1308
|
continue;
|
|
1192
1309
|
}
|
|
1193
1310
|
}
|
|
1194
|
-
// Re-check a queued task resume against the task itself: a cancel,
|
|
1195
|
-
// change, wait or block since it was queued retires it unexecuted.
|
|
1196
|
-
if (retireStaleResume(messageQueue, threadTasks, msg))
|
|
1197
|
-
continue;
|
|
1198
1311
|
const gateReply = msg.channel === "system" ? null : executionGateReply(heartbeat, resolveLocale(ownerConfig.language));
|
|
1199
1312
|
if (gateReply !== null) {
|
|
1200
1313
|
await answerAndDrop(channelManager, messageQueue, msg, gateReply, tuiAdapter);
|
|
@@ -1207,9 +1320,6 @@ export async function startAgentLoop(config, options) {
|
|
|
1207
1320
|
if (trigger === "message" && messages.length === 0) {
|
|
1208
1321
|
releaseLifecycleRun("empty_message_batch");
|
|
1209
1322
|
heartbeat.nudge();
|
|
1210
|
-
// A retired stale resume ends here without a wake end; queue the next
|
|
1211
|
-
// runnable task (or the same one at its new version) instead.
|
|
1212
|
-
void threadTasks?.requestResume();
|
|
1213
1323
|
continue;
|
|
1214
1324
|
}
|
|
1215
1325
|
const correlatedTuiMessage = messages.find((message) => typeof message.meta?.tuiRequestId === "string");
|
|
@@ -1223,18 +1333,12 @@ export async function startAgentLoop(config, options) {
|
|
|
1223
1333
|
// batch. Telegram and fin-app may already have enriched their messages at
|
|
1224
1334
|
// ingress; the shared helper skips those, while QQ, Discord, and
|
|
1225
1335
|
// other channels get the same cloud/local pipeline.
|
|
1226
|
-
if (trigger === "message" && !
|
|
1336
|
+
if (trigger === "message" && !workerExecution) {
|
|
1227
1337
|
for (const msg of messages) {
|
|
1228
|
-
// A task resume is internal: no "typing…" for the owner.
|
|
1229
|
-
if (isTaskResumeMessage(msg))
|
|
1230
|
-
continue;
|
|
1231
1338
|
sendTypingToMessage(channelManager, msg).catch(() => { });
|
|
1232
1339
|
}
|
|
1233
1340
|
}
|
|
1234
1341
|
await transcribeVoiceMessages(messages, ownerTranscriptionContext(ownerConfig));
|
|
1235
|
-
// Event first, sidecar second (#1996): after transcription so a voice
|
|
1236
|
-
// request is stored with its text. Idempotent and fail-safe.
|
|
1237
|
-
threadTasks?.recordMessages(messages.filter(isTaskRelevantMessage));
|
|
1238
1342
|
for (const msg of messages) {
|
|
1239
1343
|
agentState.replyMap.set(buildReplyMapKeyFromMessage(msg), buildReplyTarget(msg));
|
|
1240
1344
|
}
|
|
@@ -1268,9 +1372,6 @@ export async function startAgentLoop(config, options) {
|
|
|
1268
1372
|
activityTracker.recordUserMessage(formatMessageSummary(msg));
|
|
1269
1373
|
}
|
|
1270
1374
|
logger.wake(trigger, messages.length);
|
|
1271
|
-
if (session.dualSessionEnabled) {
|
|
1272
|
-
logger.system(`Active session: ${session.activeMode}`);
|
|
1273
|
-
}
|
|
1274
1375
|
if (trigger === "heartbeat") {
|
|
1275
1376
|
try {
|
|
1276
1377
|
await session.activeSession.maybeCompact();
|
|
@@ -1324,7 +1425,7 @@ export async function startAgentLoop(config, options) {
|
|
|
1324
1425
|
logger.debug(`Pre-warm kick-off failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1325
1426
|
});
|
|
1326
1427
|
// --- Gather context ---
|
|
1327
|
-
const doVersionCheck = !
|
|
1428
|
+
const doVersionCheck = !workerExecution
|
|
1328
1429
|
&& shouldRunProactiveUpgradeCheck(config, trigger)
|
|
1329
1430
|
&& shouldNotifyUpdate();
|
|
1330
1431
|
// Throttle the wake screenshot: skip on errors, and skip if one was
|
|
@@ -1338,7 +1439,7 @@ export async function startAgentLoop(config, options) {
|
|
|
1338
1439
|
if (screenshotThrottled) {
|
|
1339
1440
|
logger.debug(`Skipping wake screenshot (captured ${Math.round((nowMs - lastWakeScreenshotMs) / 1000)}s ago, throttle ${WAKE_SCREENSHOT_MIN_INTERVAL_MS / 1000}s)`);
|
|
1340
1441
|
}
|
|
1341
|
-
const gathered =
|
|
1442
|
+
const gathered = workerExecution
|
|
1342
1443
|
? { calendarSummary: "" }
|
|
1343
1444
|
: await gatherWakeContext(config, doVersionCheck, skipScreenshot, ownerConfig.heartbeatIntervalMs);
|
|
1344
1445
|
const { screenshot, calendarSummary, versionUpdate } = gathered;
|
|
@@ -1348,25 +1449,26 @@ export async function startAgentLoop(config, options) {
|
|
|
1348
1449
|
// Refresh cross-thread awareness so the default thread's wake context lists
|
|
1349
1450
|
// concurrently-running worker threads. No-op when multiThread is disabled.
|
|
1350
1451
|
threadSupervisor?.refreshMainProcessAwareness();
|
|
1351
|
-
|
|
1452
|
+
// Foreman: this conversation's open background tasks, from the host's records.
|
|
1453
|
+
const foremanClient = workerExecution ? null : getForemanClient();
|
|
1454
|
+
const backgroundTasks = foremanClient ? await foremanClient.request({ type: "summary" }) : null;
|
|
1455
|
+
const contentBlocks = workerExecution
|
|
1352
1456
|
? [{ type: "text", text: messages.map((message) => message.text).join("\n\n") }]
|
|
1353
1457
|
: await buildWakeContext({
|
|
1458
|
+
...(backgroundTasks?.ok && backgroundTasks.text ? { backgroundTasksBlock: backgroundTasks.text } : {}),
|
|
1354
1459
|
config,
|
|
1355
1460
|
trigger,
|
|
1356
1461
|
messages,
|
|
1357
1462
|
calendarSummary,
|
|
1358
1463
|
screenshot,
|
|
1359
1464
|
versionUpdate,
|
|
1360
|
-
activeSession: session.dualSessionEnabled ? session.activeMode : undefined,
|
|
1361
|
-
sessionMemos: session.consumeMemosForActive(),
|
|
1362
|
-
codingSessionStatus: session.getCodingSessionStatus(),
|
|
1363
1465
|
justUpgraded: isFirstWake ? justUpgraded : null,
|
|
1364
1466
|
justRestarted: isFirstWake ? justRestarted : null,
|
|
1365
1467
|
ownerReachable: hasUsableOwnerChannel(config, ownerConfig),
|
|
1366
1468
|
});
|
|
1367
1469
|
logger.sendMultimodal(contentBlocks);
|
|
1368
1470
|
// --- Arm watchdog + run cycle ---
|
|
1369
|
-
if (!
|
|
1471
|
+
if (!workerExecution)
|
|
1370
1472
|
watchdog.arm(trigger, messages);
|
|
1371
1473
|
let tuiTerminalOutcome = {
|
|
1372
1474
|
state: "failed",
|
|
@@ -1383,8 +1485,20 @@ export async function startAgentLoop(config, options) {
|
|
|
1383
1485
|
operation: "query",
|
|
1384
1486
|
outcome: "started",
|
|
1385
1487
|
});
|
|
1488
|
+
let releaseConversationTurn;
|
|
1489
|
+
agentState.currentDispatchId = createHash("sha256").update(JSON.stringify(messages.map((message) => message.id))).digest("hex");
|
|
1386
1490
|
try {
|
|
1387
|
-
|
|
1491
|
+
if (!workerExecution) {
|
|
1492
|
+
releaseConversationTurn = await (options?.acquireConversationTurn?.(options.signal)
|
|
1493
|
+
?? threadSupervisor?.acquireConversationTurn(options?.signal));
|
|
1494
|
+
}
|
|
1495
|
+
if (options?.signal?.aborted) {
|
|
1496
|
+
messageQueue.requeueOwnedClaims();
|
|
1497
|
+
break;
|
|
1498
|
+
}
|
|
1499
|
+
// Accepted inputs are also replayed from the ledger on executor recovery.
|
|
1500
|
+
noteMessagesHandedToModel(messages);
|
|
1501
|
+
const result = await cycleRunner.run(contentBlocks, trigger, messages, consecutiveErrors);
|
|
1388
1502
|
traceLifecycle({
|
|
1389
1503
|
runId: lifecycleRunId,
|
|
1390
1504
|
stage: "model",
|
|
@@ -1393,6 +1507,10 @@ export async function startAgentLoop(config, options) {
|
|
|
1393
1507
|
evidence: { terminalState: result.terminalState },
|
|
1394
1508
|
});
|
|
1395
1509
|
consecutiveErrors = result.consecutiveErrors;
|
|
1510
|
+
if (options?.signal?.aborted) {
|
|
1511
|
+
messageQueue.requeueOwnedClaims();
|
|
1512
|
+
break;
|
|
1513
|
+
}
|
|
1396
1514
|
// A queue claim is not terminal until the complete wake cycle returns.
|
|
1397
1515
|
// If the worker dies during model/tool execution, the in-flight rows
|
|
1398
1516
|
// remain durable and are replayed by the next queue owner.
|
|
@@ -1400,9 +1518,24 @@ export async function startAgentLoop(config, options) {
|
|
|
1400
1518
|
// done its work: leave the claims in flight so the replacement process
|
|
1401
1519
|
// replays them on the new engine (issue #2519).
|
|
1402
1520
|
failoverRestartPending = !restartArmedBeforeWake && engineFallback.isRestartPending();
|
|
1403
|
-
//
|
|
1404
|
-
//
|
|
1405
|
-
|
|
1521
|
+
// Foreman: the background-task updates this turn handled, read before
|
|
1522
|
+
// their claims are released (mid-turn interrupts included).
|
|
1523
|
+
const handledForemanEvents = failoverRestartPending ? [] : foremanEventsOf(messageQueue.currentCycleClaims());
|
|
1524
|
+
// A completed foreground wake acknowledges its claims. Accepted background
|
|
1525
|
+
// work already belongs to the canonical Task ledger.
|
|
1526
|
+
if (!failoverRestartPending)
|
|
1527
|
+
messageQueue.markAllInFlightHandled();
|
|
1528
|
+
if (!failoverRestartPending) {
|
|
1529
|
+
// An accepted finish that is not waiting for the user ends the
|
|
1530
|
+
// foreground task; the next one starts from zero. A wake that only
|
|
1531
|
+
// ran out of recovery attempts or timed out keeps the count.
|
|
1532
|
+
if (result.finished === true && result.terminalState === "completed")
|
|
1533
|
+
foregroundTasks?.reset();
|
|
1534
|
+
// Whatever the turn did not deliver to the user is due for the fallback now.
|
|
1535
|
+
if (handledForemanEvents.length > 0) {
|
|
1536
|
+
void getForemanClient()?.request({ type: "turn_ended", events: handledForemanEvents });
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1406
1539
|
if (workerMode) {
|
|
1407
1540
|
workerMode.relay.finishActivityRun(result.terminalState);
|
|
1408
1541
|
}
|
|
@@ -1416,9 +1549,6 @@ export async function startAgentLoop(config, options) {
|
|
|
1416
1549
|
// terminal boundary. A later wake must not inherit this turn's claims
|
|
1417
1550
|
// and accidentally confirm them together with unrelated work.
|
|
1418
1551
|
try {
|
|
1419
|
-
// Released before the requeue: a replayed resume for an interrupted
|
|
1420
|
-
// task must run when it comes back (#2664 review P1-B).
|
|
1421
|
-
threadTasks?.releaseResume(messageQueue.currentCycleClaims());
|
|
1422
1552
|
messageQueue.requeueOwnedClaims();
|
|
1423
1553
|
}
|
|
1424
1554
|
catch (requeueErr) {
|
|
@@ -1440,6 +1570,7 @@ export async function startAgentLoop(config, options) {
|
|
|
1440
1570
|
throw err;
|
|
1441
1571
|
}
|
|
1442
1572
|
finally {
|
|
1573
|
+
releaseConversationTurn?.();
|
|
1443
1574
|
// Cleanup must always run, even if the extracted cycle runner throws
|
|
1444
1575
|
// unexpectedly, otherwise the reply watchdog timer can leak across
|
|
1445
1576
|
// wake cycles. The runtime heartbeat loop runs independently and
|
|
@@ -1471,21 +1602,21 @@ export async function startAgentLoop(config, options) {
|
|
|
1471
1602
|
// in the shared memories/ tree, so it runs only on the deep-night sweep
|
|
1472
1603
|
// (`nightly-maintenance.ts`) — once a day, while the agent is idle —
|
|
1473
1604
|
// rather than after every wake cycle.
|
|
1474
|
-
if (workerMode && !
|
|
1605
|
+
if (workerMode && !workerExecution) {
|
|
1475
1606
|
workerMode.relay.relayTurnComplete();
|
|
1476
1607
|
}
|
|
1477
1608
|
}
|
|
1478
|
-
if (
|
|
1609
|
+
if (workerExecution) {
|
|
1479
1610
|
if (!messageQueue.isEmpty()) {
|
|
1480
|
-
logger.system(`
|
|
1611
|
+
logger.system(`Worker execution turn ended with queued work; continuing run=${workerExecution.id}`);
|
|
1481
1612
|
continue;
|
|
1482
1613
|
}
|
|
1483
|
-
logger.system(`Single-shot
|
|
1484
|
-
if (await
|
|
1485
|
-
logger.system(`
|
|
1614
|
+
logger.system(`Single-shot worker turn ended; waiting ${WORKER_EXECUTION_IDLE_GRACE_MS / 1000}s for more messages: run=${workerExecution.id}`);
|
|
1615
|
+
if (await waitForExecutionQueueOrIdle()) {
|
|
1616
|
+
logger.system(`Worker execution received more work during idle grace; continuing run=${workerExecution.id}`);
|
|
1486
1617
|
continue;
|
|
1487
1618
|
}
|
|
1488
|
-
logger.system(`
|
|
1619
|
+
logger.system(`Worker execution queue idle for ${WORKER_EXECUTION_IDLE_GRACE_MS / 1000}s; ending worker run=${workerExecution.id}`);
|
|
1489
1620
|
break;
|
|
1490
1621
|
}
|
|
1491
1622
|
}
|