@vellumai/assistant 0.8.8 → 0.8.9-staging.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/ARCHITECTURE.md +6 -6
- package/bun.lock +2 -2
- package/examples/plugins/echo/README.md +61 -60
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +235 -6
- package/package.json +2 -2
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
- package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
- package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
- package/src/__tests__/agent-loop-thinking.test.ts +36 -20
- package/src/__tests__/agent-loop.test.ts +441 -96
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
- package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
- package/src/__tests__/anthropic-provider.test.ts +1 -1
- package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +132 -0
- package/src/__tests__/approval-cascade.test.ts +5 -4
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction-events.test.ts +5 -5
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/context-overflow-reducer.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +142 -218
- package/src/__tests__/conversation-agent-loop.test.ts +297 -586
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +14 -14
- package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
- package/src/__tests__/conversation-queue.test.ts +9 -9
- package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +6 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
- package/src/__tests__/conversation-speed-override.test.ts +10 -9
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
- package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +12 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/history-repair-hook.test.ts +1 -1
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/inference-profile-reaper.test.ts +62 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
- package/src/__tests__/injector-background-turn.test.ts +13 -23
- package/src/__tests__/injector-chain.test.ts +268 -44
- package/src/__tests__/injector-disk-pressure.test.ts +210 -52
- package/src/__tests__/injector-document-comments.test.ts +97 -114
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-v3-suppression.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +131 -26
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +12 -23
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
- package/src/__tests__/steer-tool-repair.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-detail.test.ts +25 -7
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +1 -1
- package/src/__tests__/tool-error-hook.test.ts +1 -1
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +280 -0
- package/src/acp/auto-install.ts +232 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +225 -9
- package/src/acp/resolve-agent.ts +122 -17
- package/src/acp/resume-hint.ts +23 -0
- package/src/acp/session-manager.ts +507 -73
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +414 -248
- package/src/api/responses/conversation-message.ts +14 -1
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
- package/src/cli/lib/install-from-github.ts +464 -55
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +409 -0
- package/src/cli/lib/plugin-marketplace.ts +197 -0
- package/src/cli/lib/search-plugins.ts +195 -29
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/bundled-skills/acp/SKILL.md +85 -33
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
- package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-tool-registry.ts +4 -0
- package/src/config/call-site-defaults.ts +0 -2
- package/src/config/feature-flag-registry.json +15 -6
- package/src/config/schemas/call-site-catalog.ts +0 -14
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +0 -2
- package/src/context/compactor.ts +22 -4
- package/src/context/strip-injections.ts +8 -2
- package/src/context/window-manager.ts +27 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
- package/src/daemon/conversation-agent-loop.ts +175 -1055
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-process.ts +8 -136
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +293 -392
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +24 -8
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +404 -57
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +14 -19
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/server.ts +2 -0
- package/src/daemon/wake-conversation-ops.ts +269 -0
- package/src/embedded/plugin-api.ts +2 -2
- package/src/export/__tests__/transcript-formatter.test.ts +5 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +2 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
- package/src/memory/jobs-worker.ts +25 -1
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
- package/src/memory/v2/consolidation-job.ts +13 -4
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +6 -5
- package/src/plugin-api/types.ts +75 -0
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/plugins/defaults/empty-response/package.json +0 -1
- package/src/plugins/defaults/history-repair/package.json +0 -1
- package/src/plugins/defaults/index.ts +135 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
- package/src/plugins/defaults/title-generate/package.json +0 -1
- package/src/plugins/defaults/tool-error/package.json +0 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
- package/src/plugins/pipeline.ts +6 -293
- package/src/plugins/registry.ts +9 -37
- package/src/plugins/types.ts +76 -381
- package/src/plugins/user-loader.ts +30 -127
- package/src/prompts/__tests__/system-prompt.test.ts +6 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
- package/src/runtime/__tests__/agent-wake.test.ts +555 -691
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +108 -209
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +315 -55
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/acp-routes.test.ts +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +28 -2
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +18 -3
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
- package/src/runtime/routes/memory-v3-routes.ts +16 -6
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +8 -2
- package/src/tools/acp/spawn.test.ts +176 -195
- package/src/tools/acp/spawn.ts +37 -172
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +166 -50
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +25 -5
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
- package/docs/plugins.md +0 -832
- package/examples/plugins/echo/register.ts +0 -143
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
- package/src/__tests__/pipeline-runner.test.ts +0 -554
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/daemon/wake-target-adapter.ts +0 -253
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/register.ts +0 -35
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/register.ts +0 -23
- package/src/plugins/defaults/history-repair/register.ts +0 -24
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/title-generate/register.ts +0 -35
- package/src/plugins/defaults/tool-error/register.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
- package/src/plugins/external-api.ts +0 -104
- package/src/proactive-artifact/aux-message-injector.ts +0 -97
- package/src/proactive-artifact/decision.test.ts +0 -226
- package/src/proactive-artifact/decision.ts +0 -165
- package/src/proactive-artifact/index.ts +0 -7
- package/src/proactive-artifact/job.test.ts +0 -962
- package/src/proactive-artifact/job.ts +0 -372
- package/src/proactive-artifact/message-copy.ts +0 -58
- package/src/proactive-artifact/trigger-state.test.ts +0 -286
- package/src/proactive-artifact/trigger-state.ts +0 -123
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
|
@@ -50,7 +50,7 @@ let surfaceCalls: Array<{
|
|
|
50
50
|
surfaceId: string;
|
|
51
51
|
}> = [];
|
|
52
52
|
|
|
53
|
-
mock.module("../../daemon/conversation-
|
|
53
|
+
mock.module("../../daemon/conversation-registry.js", () => ({
|
|
54
54
|
findConversation: (_conversationId: string) => {
|
|
55
55
|
return mockConversation ?? undefined;
|
|
56
56
|
},
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* conversation, the wake is queued behind it (single-flight per
|
|
28
28
|
* `conversationId`).
|
|
29
29
|
* - While the wake's agent loop is running, the conversation is marked
|
|
30
|
-
* as processing (via
|
|
30
|
+
* as processing (via the conversation's processing marker) so a user send
|
|
31
31
|
* that arrives mid-wake is queued by `enqueueMessage` instead of
|
|
32
32
|
* launching a concurrent `agentLoop.run()` on the same conversation.
|
|
33
33
|
*
|
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
|
|
44
44
|
import type {
|
|
45
45
|
AgentEvent,
|
|
46
|
-
AgentLoop,
|
|
47
46
|
CheckpointDecision,
|
|
48
47
|
CheckpointInfo,
|
|
49
48
|
} from "../agent/loop.js";
|
|
@@ -51,19 +50,25 @@ import type { InterfaceId } from "../channels/types.js";
|
|
|
51
50
|
import { resolveEffectiveContextWindow } from "../config/llm-context-resolution.js";
|
|
52
51
|
import { getConfig } from "../config/loader.js";
|
|
53
52
|
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
53
|
+
import type { Conversation } from "../daemon/conversation.js";
|
|
54
54
|
import { getDiskPressureStatus } from "../daemon/disk-pressure-guard.js";
|
|
55
55
|
import {
|
|
56
56
|
classifyDiskPressureTurnPolicy,
|
|
57
57
|
type DiskPressureTurnPolicyDecision,
|
|
58
58
|
} from "../daemon/disk-pressure-policy.js";
|
|
59
59
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
60
|
+
import {
|
|
61
|
+
broadcastWakeSurface,
|
|
62
|
+
emitWakeAgentEvent,
|
|
63
|
+
persistWakeTailMessage,
|
|
64
|
+
scopeWakeAllowedTools,
|
|
65
|
+
} from "../daemon/wake-conversation-ops.js";
|
|
60
66
|
import { getConversationOverrideProfile } from "../memory/conversation-crud.js";
|
|
61
67
|
import {
|
|
62
68
|
buildProviderErrorResponsePayload,
|
|
63
69
|
recordRequestLog,
|
|
64
70
|
setAgentLoopExitReasonOnLatestLog,
|
|
65
71
|
} from "../memory/llm-request-log-store.js";
|
|
66
|
-
import type { TurnContext } from "../plugins/types.js";
|
|
67
72
|
import type { Message } from "../providers/types.js";
|
|
68
73
|
import { getLogger } from "../util/logger.js";
|
|
69
74
|
|
|
@@ -77,102 +82,6 @@ const WAKE_PREAMBLE =
|
|
|
77
82
|
const WAKE_POSTAMBLE =
|
|
78
83
|
"[system] End of message from external system, continue the conversation.";
|
|
79
84
|
|
|
80
|
-
/**
|
|
81
|
-
* Minimum surface area of a conversation needed to wake it. Defined as an
|
|
82
|
-
* interface rather than importing `Conversation` directly so the wake
|
|
83
|
-
* helper stays decoupled from the heavyweight conversation class and is
|
|
84
|
-
* easy to exercise under unit tests.
|
|
85
|
-
*
|
|
86
|
-
* Translation note: the wake deliberately hands the adapter a raw
|
|
87
|
-
* {@link AgentEvent} via {@link emitAgentEvent} rather than a
|
|
88
|
-
* `ServerMessage`. The normal user-turn path translates `AgentEvent` into
|
|
89
|
-
* the correctly-shaped wire protocol frames (e.g.
|
|
90
|
-
* `text_delta` → `assistant_text_delta` with `conversationId`) via the
|
|
91
|
-
* canonical handler in `conversation-agent-loop-handlers.ts`. Passing raw
|
|
92
|
-
* events means the adapter can reuse that translation rather than the
|
|
93
|
-
* wake helper shipping malformed frames.
|
|
94
|
-
*/
|
|
95
|
-
export interface WakeTarget {
|
|
96
|
-
readonly conversationId: string;
|
|
97
|
-
readonly agentLoop: Pick<AgentLoop, "run">;
|
|
98
|
-
/**
|
|
99
|
-
* Live LLM-visible history. We read a snapshot, append the internal hint
|
|
100
|
-
* for the run, and then (on non-empty output) append the resulting
|
|
101
|
-
* assistant message(s) to this array so subsequent turns see them.
|
|
102
|
-
*/
|
|
103
|
-
getMessages(): Message[];
|
|
104
|
-
pushMessage(message: Message): void;
|
|
105
|
-
/**
|
|
106
|
-
* Forward a raw agent event so the adapter can translate it to the
|
|
107
|
-
* correct `ServerMessage` shape (e.g. stamping `conversationId`,
|
|
108
|
-
* renaming `text_delta` → `assistant_text_delta`) before emission.
|
|
109
|
-
*
|
|
110
|
-
* Only called when the wake produces output worth emitting — silent
|
|
111
|
-
* no-op wakes never flush buffered events.
|
|
112
|
-
*/
|
|
113
|
-
emitAgentEvent(event: AgentEvent): void;
|
|
114
|
-
/** True if the conversation is already processing a turn. */
|
|
115
|
-
isProcessing(): boolean;
|
|
116
|
-
/**
|
|
117
|
-
* Toggle the conversation's in-flight processing marker. The wake
|
|
118
|
-
* wraps its `agentLoop.run()` invocation in
|
|
119
|
-
* `markProcessing(true) … markProcessing(false)` so a concurrent user
|
|
120
|
-
* send sees `isProcessing() === true` and queues the message instead
|
|
121
|
-
* of spawning a parallel agent loop.
|
|
122
|
-
*/
|
|
123
|
-
markProcessing(on: boolean): void;
|
|
124
|
-
/**
|
|
125
|
-
* Persist a single tail message produced by the wake (assistant
|
|
126
|
-
* outputs and intervening tool_result user messages). The daemon
|
|
127
|
-
* adapter is responsible for building channel/interface metadata and
|
|
128
|
-
* syncing the persisted message to the disk view so wake-produced
|
|
129
|
-
* messages match the canonical user-turn persistence path. Kept as a
|
|
130
|
-
* hook so `runtime/agent-wake.ts` stays decoupled from daemon
|
|
131
|
-
* internals (trust context, turn channel/interface contexts,
|
|
132
|
-
* disk-view layout).
|
|
133
|
-
*/
|
|
134
|
-
persistTailMessage(message: Message): Promise<void>;
|
|
135
|
-
/**
|
|
136
|
-
* Drain any messages that arrived (and were queued) while the wake
|
|
137
|
-
* was running. Optional because not every wake target has a queue —
|
|
138
|
-
* unit-test stubs typically omit it.
|
|
139
|
-
*
|
|
140
|
-
* The wake invokes this in its `finally` block AFTER
|
|
141
|
-
* `markProcessing(false)`. Order matters: if drain ran while
|
|
142
|
-
* processing was still true, `enqueueMessage`'s gate
|
|
143
|
-
* (`if (!ctx.isProcessing()) return ...`) would still see processing=true
|
|
144
|
-
* and the drain itself would be a no-op against any racy late sends.
|
|
145
|
-
* Running drain after processing is released matches the canonical
|
|
146
|
-
* user-turn finally path in `conversation-agent-loop.ts`.
|
|
147
|
-
*/
|
|
148
|
-
drainQueue?(): Promise<void>;
|
|
149
|
-
/**
|
|
150
|
-
* Called after a wake produces visible output (text or tool calls).
|
|
151
|
-
* The daemon adapter uses this to emit a live SSE event so connected
|
|
152
|
-
* clients see the wake indicator immediately. The `surfaceId` matches
|
|
153
|
-
* the `ui_surface` content block already injected into the first
|
|
154
|
-
* assistant tail message — both must share the same ID so the client
|
|
155
|
-
* doesn't render duplicates. Optional because unit-test stubs
|
|
156
|
-
* typically omit it.
|
|
157
|
-
*/
|
|
158
|
-
onWakeProducedOutput?(source: string, hint: string, surfaceId: string): void;
|
|
159
|
-
/**
|
|
160
|
-
* Apply a trust context to the underlying conversation before the agent
|
|
161
|
-
* loop runs. Internal background jobs (memory consolidation, update
|
|
162
|
-
* bulletin) use this to declare guardian trust so side-effect tools
|
|
163
|
-
* (file_edit, file_write, bash) clear the approval gate. Inbound message
|
|
164
|
-
* conversations populate trust via `processMessage()` and don't pass
|
|
165
|
-
* `trustContext` through the wake.
|
|
166
|
-
*/
|
|
167
|
-
setTrustContext?(ctx: TrustContext): void;
|
|
168
|
-
/**
|
|
169
|
-
* Temporarily restrict the tools visible/executable during this wake.
|
|
170
|
-
* Returns a restore callback so the wake can release the scope before any
|
|
171
|
-
* queued user turn is drained.
|
|
172
|
-
*/
|
|
173
|
-
setWakeAllowedTools?(tools: ReadonlySet<string>): () => void;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
85
|
export interface WakeOptions {
|
|
177
86
|
conversationId: string;
|
|
178
87
|
hint: string;
|
|
@@ -214,7 +123,7 @@ export interface WakeOptions {
|
|
|
214
123
|
* Documented intent: this wake must not trigger auto-threshold compaction.
|
|
215
124
|
*
|
|
216
125
|
* Today this is automatically satisfied because the wake invokes
|
|
217
|
-
* `
|
|
126
|
+
* `conversation.agentLoop.run()` directly, bypassing the daemon orchestrator
|
|
218
127
|
* (`conversation-agent-loop.ts`) where the compaction pipeline lives. The
|
|
219
128
|
* flag is recorded in the wake's structured log line so operators can
|
|
220
129
|
* verify the contract holds across refactors. If compaction is ever moved
|
|
@@ -279,9 +188,9 @@ export interface WakeResult {
|
|
|
279
188
|
*/
|
|
280
189
|
export interface WakeDeps {
|
|
281
190
|
/**
|
|
282
|
-
* Resolve the
|
|
191
|
+
* Resolve the live {@link Conversation} for a wake invocation.
|
|
283
192
|
* Returns `null` if the conversation doesn't exist, `"archived"` if it
|
|
284
|
-
* exists but is archived, or
|
|
193
|
+
* exists but is archived, or the `Conversation` to proceed with the wake.
|
|
285
194
|
*
|
|
286
195
|
* Receives the full {@link WakeOptions} so the default resolver can
|
|
287
196
|
* thread `trustContext` into `getOrCreateConversation`. Without that
|
|
@@ -290,7 +199,9 @@ export interface WakeDeps {
|
|
|
290
199
|
* out every guardian-provenance message — fatal for fork-based memory
|
|
291
200
|
* retrospectives.
|
|
292
201
|
*/
|
|
293
|
-
resolveTarget: (
|
|
202
|
+
resolveTarget: (
|
|
203
|
+
opts: WakeOptions,
|
|
204
|
+
) => Promise<Conversation | null | "archived">;
|
|
294
205
|
/** Timestamp source (for deterministic tests). */
|
|
295
206
|
now?: () => number;
|
|
296
207
|
}
|
|
@@ -298,12 +209,12 @@ export interface WakeDeps {
|
|
|
298
209
|
// ── Default resolution ────────────────────────────────────────────────
|
|
299
210
|
//
|
|
300
211
|
// When `wakeAgentForOpportunity()` is called without explicit `deps`,
|
|
301
|
-
// it resolves the
|
|
302
|
-
// `getOrCreateConversation
|
|
212
|
+
// it resolves the live conversation directly via `getConversation` and
|
|
213
|
+
// `getOrCreateConversation`.
|
|
303
214
|
|
|
304
215
|
async function defaultResolveTarget(
|
|
305
216
|
opts: WakeOptions,
|
|
306
|
-
): Promise<
|
|
217
|
+
): Promise<Conversation | null | "archived"> {
|
|
307
218
|
const { conversationId } = opts;
|
|
308
219
|
// Lazy-import daemon modules to avoid pulling heavyweight transitive
|
|
309
220
|
// deps (conversation store → config/loader → provider catalogs) at
|
|
@@ -313,8 +224,6 @@ async function defaultResolveTarget(
|
|
|
313
224
|
const { getConversation } = await import("../memory/conversation-crud.js");
|
|
314
225
|
const { getOrCreateConversation } =
|
|
315
226
|
await import("../daemon/conversation-store.js");
|
|
316
|
-
const { conversationToWakeTarget } =
|
|
317
|
-
await import("../daemon/wake-target-adapter.js");
|
|
318
227
|
try {
|
|
319
228
|
const existing = getConversation(conversationId);
|
|
320
229
|
if (!existing) return null;
|
|
@@ -334,7 +243,7 @@ async function defaultResolveTarget(
|
|
|
334
243
|
const conversation = await getOrCreateConversation(conversationId, {
|
|
335
244
|
trustContext: opts.trustContext,
|
|
336
245
|
});
|
|
337
|
-
return
|
|
246
|
+
return conversation;
|
|
338
247
|
} catch (err) {
|
|
339
248
|
log.warn(
|
|
340
249
|
{ err, conversationId },
|
|
@@ -385,15 +294,15 @@ async function runSingleFlight<T>(
|
|
|
385
294
|
* while our wake was queued.
|
|
386
295
|
*/
|
|
387
296
|
async function waitUntilIdle(
|
|
388
|
-
|
|
297
|
+
conversation: Conversation,
|
|
389
298
|
nowFn: () => number,
|
|
390
299
|
timeoutMs = 30_000,
|
|
391
300
|
): Promise<boolean> {
|
|
392
301
|
const deadline = nowFn() + timeoutMs;
|
|
393
|
-
while (
|
|
302
|
+
while (conversation.isProcessing() && nowFn() < deadline) {
|
|
394
303
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
395
304
|
}
|
|
396
|
-
return !
|
|
305
|
+
return !conversation.isProcessing();
|
|
397
306
|
}
|
|
398
307
|
|
|
399
308
|
function classifyWakeDiskPressurePolicy(opts: WakeOptions): {
|
|
@@ -417,25 +326,30 @@ function classifyWakeDiskPressurePolicy(opts: WakeOptions): {
|
|
|
417
326
|
return { decision, status };
|
|
418
327
|
}
|
|
419
328
|
|
|
420
|
-
|
|
329
|
+
/**
|
|
330
|
+
* Trust snapshot the wake hands to the agent loop. A wake has no compaction
|
|
331
|
+
* path (it runs with overflow recovery disabled), so this snapshot is unread
|
|
332
|
+
* except on the disk-pressure cleanup-mode path, whose guardian value scopes
|
|
333
|
+
* the compactor's image manifest if cleanup ever compacts. Other wakes pass an
|
|
334
|
+
* `unknown`-class snapshot so a missing actor cannot grant elevated trust.
|
|
335
|
+
*/
|
|
336
|
+
function buildWakeTrust(
|
|
421
337
|
opts: WakeOptions,
|
|
422
338
|
decision: DiskPressureTurnPolicyDecision,
|
|
423
|
-
):
|
|
424
|
-
if (decision.action !== "allow-cleanup-mode")
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
},
|
|
438
|
-
};
|
|
339
|
+
): TrustContext {
|
|
340
|
+
if (decision.action !== "allow-cleanup-mode") {
|
|
341
|
+
return {
|
|
342
|
+
sourceChannel: opts.sourceChannel ?? "vellum",
|
|
343
|
+
trustClass: "unknown",
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
return (
|
|
347
|
+
opts.trustContext ??
|
|
348
|
+
({
|
|
349
|
+
sourceChannel: opts.sourceChannel ?? "vellum",
|
|
350
|
+
trustClass: "guardian",
|
|
351
|
+
} satisfies TrustContext)
|
|
352
|
+
);
|
|
439
353
|
}
|
|
440
354
|
|
|
441
355
|
/**
|
|
@@ -492,9 +406,10 @@ function inspectWakeOutput(
|
|
|
492
406
|
* are serialized per `conversationId`.
|
|
493
407
|
*
|
|
494
408
|
* The `deps` argument is optional in production — when omitted, the
|
|
495
|
-
* default resolver imports `getConversation
|
|
496
|
-
*
|
|
497
|
-
* control over resolution continue to pass
|
|
409
|
+
* default resolver imports `getConversation` and
|
|
410
|
+
* `getOrCreateConversation` directly to return the live conversation.
|
|
411
|
+
* Tests that want tight control over resolution continue to pass
|
|
412
|
+
* explicit deps.
|
|
498
413
|
*/
|
|
499
414
|
export async function wakeAgentForOpportunity(
|
|
500
415
|
opts: WakeOptions,
|
|
@@ -525,7 +440,7 @@ export async function wakeAgentForOpportunity(
|
|
|
525
440
|
);
|
|
526
441
|
return { invoked: false, producedToolCalls: false, reason: "not_found" };
|
|
527
442
|
}
|
|
528
|
-
const
|
|
443
|
+
const conversation = resolved;
|
|
529
444
|
|
|
530
445
|
const { decision: diskPressureDecision, status: diskPressureStatus } =
|
|
531
446
|
classifyWakeDiskPressurePolicy(opts);
|
|
@@ -551,7 +466,7 @@ export async function wakeAgentForOpportunity(
|
|
|
551
466
|
};
|
|
552
467
|
}
|
|
553
468
|
|
|
554
|
-
const idle = await waitUntilIdle(
|
|
469
|
+
const idle = await waitUntilIdle(conversation, nowFn);
|
|
555
470
|
if (!idle) {
|
|
556
471
|
log.warn(
|
|
557
472
|
{ conversationId, source },
|
|
@@ -563,18 +478,18 @@ export async function wakeAgentForOpportunity(
|
|
|
563
478
|
// Apply caller-supplied trust before the agent loop reads its per-turn
|
|
564
479
|
// snapshot. Background jobs without an inbound message use this to
|
|
565
480
|
// declare guardian trust so side-effect tools clear the approval gate.
|
|
566
|
-
if (opts.trustContext
|
|
567
|
-
|
|
481
|
+
if (opts.trustContext) {
|
|
482
|
+
conversation.setTrustContext(opts.trustContext);
|
|
568
483
|
}
|
|
569
484
|
|
|
570
|
-
const baseline =
|
|
485
|
+
const baseline = conversation.getMessages();
|
|
571
486
|
// Snapshot the baseline length BEFORE the run starts. Incremental
|
|
572
|
-
// persistence
|
|
487
|
+
// persistence pushes onto `conversation.messages` mid-run, which grows the
|
|
573
488
|
// live history array `baseline` aliases. Reading `baseline.length`
|
|
574
489
|
// post-run would therefore include the tail we just pushed and the
|
|
575
490
|
// tail-slice math would skip every message.
|
|
576
491
|
const baselineLength = baseline.length;
|
|
577
|
-
const
|
|
492
|
+
const wakeTrust = buildWakeTrust(opts, diskPressureDecision);
|
|
578
493
|
// Build the hint injection. Three modes:
|
|
579
494
|
// - `skipHintInjection`: caller has already persisted an instruction
|
|
580
495
|
// message into the conversation history (typical for fork-based
|
|
@@ -674,7 +589,7 @@ export async function wakeAgentForOpportunity(
|
|
|
674
589
|
};
|
|
675
590
|
const safeEmit = (event: AgentEvent): void => {
|
|
676
591
|
try {
|
|
677
|
-
|
|
592
|
+
emitWakeAgentEvent(conversation, event);
|
|
678
593
|
} catch (err) {
|
|
679
594
|
log.warn(
|
|
680
595
|
{ conversationId, source, err },
|
|
@@ -744,8 +659,8 @@ export async function wakeAgentForOpportunity(
|
|
|
744
659
|
// Transition from buffered to live emission. Idempotent — only the
|
|
745
660
|
// first call has an effect. Mutates the first assistant message in
|
|
746
661
|
// the tail to prepend the ui_surface block, emits the live
|
|
747
|
-
// ui_surface event, then drains the buffered events through
|
|
748
|
-
//
|
|
662
|
+
// ui_surface event, then drains the buffered events through
|
|
663
|
+
// `emitWakeAgentEvent`. The translator is what stamps `conversationId`
|
|
749
664
|
// and renames `text_delta` → `assistant_text_delta`; bypassing it
|
|
750
665
|
// would ship malformed wire frames.
|
|
751
666
|
const goLive = (currentHistory: Message[]): void => {
|
|
@@ -772,13 +687,13 @@ export async function wakeAgentForOpportunity(
|
|
|
772
687
|
}
|
|
773
688
|
surfaceInjected = true;
|
|
774
689
|
}
|
|
775
|
-
if (!opts.suppressWakeSurface
|
|
690
|
+
if (!opts.suppressWakeSurface) {
|
|
776
691
|
try {
|
|
777
|
-
|
|
692
|
+
broadcastWakeSurface(conversation, source, hint, wakeSurfaceId);
|
|
778
693
|
} catch (err) {
|
|
779
694
|
log.warn(
|
|
780
695
|
{ conversationId, source, err },
|
|
781
|
-
"agent-wake:
|
|
696
|
+
"agent-wake: broadcastWakeSurface threw; continuing",
|
|
782
697
|
);
|
|
783
698
|
}
|
|
784
699
|
}
|
|
@@ -815,11 +730,11 @@ export async function wakeAgentForOpportunity(
|
|
|
815
730
|
if (start >= currentHistory.length) return;
|
|
816
731
|
const newMessages = currentHistory.slice(start);
|
|
817
732
|
for (const msg of newMessages) {
|
|
818
|
-
|
|
733
|
+
conversation.messages.push(msg);
|
|
819
734
|
}
|
|
820
735
|
for (const msg of newMessages) {
|
|
821
736
|
try {
|
|
822
|
-
await
|
|
737
|
+
await persistWakeTailMessage(conversation, msg);
|
|
823
738
|
} catch (err) {
|
|
824
739
|
log.warn(
|
|
825
740
|
{ conversationId, source, err, role: msg.role },
|
|
@@ -836,7 +751,7 @@ export async function wakeAgentForOpportunity(
|
|
|
836
751
|
// silently violating the user's pinned preference. Resolve the effective
|
|
837
752
|
// context budget here as well because wakes bypass the normal user-turn
|
|
838
753
|
// path that computes it for tool-result truncation. Read before
|
|
839
|
-
// `
|
|
754
|
+
// `setProcessing(true)` so a thrown DB/config read can't strand the
|
|
840
755
|
// processing flag.
|
|
841
756
|
const overrideProfile = getConversationOverrideProfile(conversationId);
|
|
842
757
|
const callSite = opts.callSite ?? "mainAgent";
|
|
@@ -864,15 +779,9 @@ export async function wakeAgentForOpportunity(
|
|
|
864
779
|
};
|
|
865
780
|
const applyWakeAllowedTools = (): boolean => {
|
|
866
781
|
if (!opts.allowedTools) return true;
|
|
867
|
-
if (!target.setWakeAllowedTools) {
|
|
868
|
-
log.warn(
|
|
869
|
-
{ conversationId, source, allowedTools: opts.allowedTools },
|
|
870
|
-
"agent-wake: target cannot apply requested tool allowlist; skipping",
|
|
871
|
-
);
|
|
872
|
-
return false;
|
|
873
|
-
}
|
|
874
782
|
try {
|
|
875
|
-
restoreWakeToolScope =
|
|
783
|
+
restoreWakeToolScope = scopeWakeAllowedTools(
|
|
784
|
+
conversation,
|
|
876
785
|
new Set(opts.allowedTools),
|
|
877
786
|
);
|
|
878
787
|
return true;
|
|
@@ -891,11 +800,7 @@ export async function wakeAgentForOpportunity(
|
|
|
891
800
|
// interleave writes to `conversation.messages`). This happens before
|
|
892
801
|
// applying a wake-scoped tool allowlist so a concurrent user turn cannot
|
|
893
802
|
// start under the wake's restricted tool set.
|
|
894
|
-
|
|
895
|
-
target.markProcessing(true);
|
|
896
|
-
} catch (err) {
|
|
897
|
-
throw err;
|
|
898
|
-
}
|
|
803
|
+
conversation.setProcessing(true);
|
|
899
804
|
|
|
900
805
|
// Fires after each tool-execution turn finalizes (assistant message
|
|
901
806
|
// + matching tool_result user message both in history). A single
|
|
@@ -927,31 +832,29 @@ export async function wakeAgentForOpportunity(
|
|
|
927
832
|
|
|
928
833
|
let updatedHistory: Message[];
|
|
929
834
|
try {
|
|
930
|
-
({ history: updatedHistory } = await
|
|
931
|
-
runInput,
|
|
835
|
+
({ history: updatedHistory } = await conversation.agentLoop.run({
|
|
836
|
+
messages: runInput,
|
|
932
837
|
onEvent,
|
|
933
|
-
{
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
},
|
|
954
|
-
));
|
|
838
|
+
requestId: `wake:${source}`,
|
|
839
|
+
onCheckpoint,
|
|
840
|
+
// Route through the caller-supplied call site (defaults to
|
|
841
|
+
// `mainAgent` so a normal user-turn wake shares the user's chat
|
|
842
|
+
// selection). Without an explicit callSite, the resolver in
|
|
843
|
+
// `RetryProvider` and the routing in `CallSiteRoutingProvider`
|
|
844
|
+
// short-circuit and silently drop both per-callsite config and the
|
|
845
|
+
// pinned `overrideProfile` below.
|
|
846
|
+
callSite,
|
|
847
|
+
trust: wakeTrust,
|
|
848
|
+
overrideProfile,
|
|
849
|
+
// Wake runs have no orchestrator-side mid-loop compaction path,
|
|
850
|
+
// so the budget gate stays disabled (`overflowRecovery.enabled =
|
|
851
|
+
// false`); `maxInputTokens` is still supplied for tool-result
|
|
852
|
+
// truncation.
|
|
853
|
+
resolveContextWindow: () => ({
|
|
854
|
+
maxInputTokens: effectiveContextWindow.maxInputTokens,
|
|
855
|
+
overflowRecovery: { enabled: false, safetyMarginRatio: 0 },
|
|
856
|
+
}),
|
|
857
|
+
}));
|
|
955
858
|
} catch (err) {
|
|
956
859
|
// Capture the error for post-finally logging, then short-circuit
|
|
957
860
|
// the rest of the try body — no tail to push/persist when the
|
|
@@ -1004,34 +907,32 @@ export async function wakeAgentForOpportunity(
|
|
|
1004
907
|
|
|
1005
908
|
// Drain queued messages AFTER tail is pushed + persisted so the
|
|
1006
909
|
// next dequeued user message sees the complete, up-to-date
|
|
1007
|
-
// history.
|
|
910
|
+
// history. setProcessing(false) must come first (the queue only
|
|
1008
911
|
// accepts entries while processing === true, and drain expects
|
|
1009
912
|
// processing to already be false). The finally block handles the
|
|
1010
913
|
// error/early-return paths where no tail was produced.
|
|
1011
914
|
restoreWakeAllowedTools();
|
|
1012
915
|
try {
|
|
1013
|
-
|
|
916
|
+
conversation.setProcessing(false);
|
|
1014
917
|
} catch (err) {
|
|
1015
918
|
log.warn(
|
|
1016
919
|
{ conversationId, source, err },
|
|
1017
|
-
"agent-wake:
|
|
920
|
+
"agent-wake: setProcessing(false) threw; continuing",
|
|
1018
921
|
);
|
|
1019
922
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
);
|
|
1028
|
-
}
|
|
923
|
+
try {
|
|
924
|
+
await conversation.drainQueue();
|
|
925
|
+
} catch (err) {
|
|
926
|
+
log.warn(
|
|
927
|
+
{ conversationId, source, err },
|
|
928
|
+
"agent-wake: drainQueue threw; continuing",
|
|
929
|
+
);
|
|
1029
930
|
}
|
|
1030
931
|
drainedInTry = true;
|
|
1031
932
|
|
|
1032
933
|
return { invoked: true, producedToolCalls };
|
|
1033
934
|
} finally {
|
|
1034
|
-
// The success path (above) already called
|
|
935
|
+
// The success path (above) already called setProcessing(false)
|
|
1035
936
|
// + drainQueue after tail persist. This catch-all handles the
|
|
1036
937
|
// error and early-return paths where no tail was produced — those
|
|
1037
938
|
// exit the try body before reaching the drain block, so
|
|
@@ -1039,22 +940,20 @@ export async function wakeAgentForOpportunity(
|
|
|
1039
940
|
if (!drainedInTry) {
|
|
1040
941
|
restoreWakeAllowedTools();
|
|
1041
942
|
try {
|
|
1042
|
-
|
|
943
|
+
conversation.setProcessing(false);
|
|
1043
944
|
} catch (err) {
|
|
1044
945
|
log.warn(
|
|
1045
946
|
{ conversationId, source, err },
|
|
1046
|
-
"agent-wake:
|
|
947
|
+
"agent-wake: setProcessing(false) threw; continuing",
|
|
1047
948
|
);
|
|
1048
949
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
);
|
|
1057
|
-
}
|
|
950
|
+
try {
|
|
951
|
+
await conversation.drainQueue();
|
|
952
|
+
} catch (err) {
|
|
953
|
+
log.warn(
|
|
954
|
+
{ conversationId, source, err },
|
|
955
|
+
"agent-wake: drainQueue threw; continuing",
|
|
956
|
+
);
|
|
1058
957
|
}
|
|
1059
958
|
}
|
|
1060
959
|
|
|
@@ -708,7 +708,7 @@ async function createCanonicalRequestForConfirmation(
|
|
|
708
708
|
{ DAEMON_INTERNAL_ASSISTANT_ID },
|
|
709
709
|
{ bridgeConfirmationRequestToGuardian },
|
|
710
710
|
] = await Promise.all([
|
|
711
|
-
import("../daemon/conversation-
|
|
711
|
+
import("../daemon/conversation-registry.js"),
|
|
712
712
|
import("../memory/canonical-guardian-store.js"),
|
|
713
713
|
import("../security/secret-scanner.js"),
|
|
714
714
|
import("../tools/tool-input-summary.js"),
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* 3. Consume user decisions and apply them to the underlying session
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { findConversation } from "../daemon/conversation-
|
|
12
|
+
import { findConversation } from "../daemon/conversation-registry.js";
|
|
13
13
|
import type { UserDecision } from "../permissions/types.js";
|
|
14
14
|
import { composeApprovalMessage } from "./approval-message-composer.js";
|
|
15
15
|
import type {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* `"timed_out"`.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
import { findConversation } from "../daemon/conversation-
|
|
33
|
+
import { findConversation } from "../daemon/conversation-registry.js";
|
|
34
34
|
import { showStandaloneSurface } from "../daemon/conversation-surfaces.js";
|
|
35
35
|
import { getLogger } from "../util/logger.js";
|
|
36
36
|
import { mintDecisionToken } from "./decision-token.js";
|