@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
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Conversation lifecycle
|
|
3
|
-
*
|
|
2
|
+
* Conversation lifecycle helpers extracted from Conversation: abort and
|
|
3
|
+
* dispose. Each operates on a context interface so the Conversation class
|
|
4
4
|
* can delegate without exposing its full surface.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { getConfig } from "../config/loader.js";
|
|
8
|
-
import { createContextSummaryMessage } from "../context/window-manager.js";
|
|
9
8
|
import type { EventBus } from "../events/bus.js";
|
|
10
9
|
import type { AssistantDomainEvents } from "../events/domain-events.js";
|
|
11
10
|
import type { ToolProfiler } from "../events/tool-profiling-listener.js";
|
|
12
11
|
import { enqueueAutoAnalysisIfEnabled } from "../memory/auto-analysis-enqueue.js";
|
|
13
12
|
import { isAutoAnalysisConversation } from "../memory/auto-analysis-guard.js";
|
|
14
|
-
import { getConversation, getMessages } from "../memory/conversation-crud.js";
|
|
15
13
|
import { enqueueMemoryJob, isMemoryEnabled } from "../memory/jobs-store.js";
|
|
16
14
|
import { enqueueMemoryRetrospectiveIfEnabled } from "../memory/memory-retrospective-enqueue.js";
|
|
17
|
-
import { shouldExposePersonalMemory } from "../memory/v2/static-context.js";
|
|
18
15
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
19
16
|
import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
20
|
-
import {
|
|
17
|
+
import { disposeContextWindowManager } from "../plugins/defaults/compaction/manager-store.js";
|
|
21
18
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
22
19
|
import {
|
|
23
20
|
isUntrustedTrustClass,
|
|
@@ -28,15 +25,8 @@ import { type AbortReason, createAbortReason } from "../util/abort-reasons.js";
|
|
|
28
25
|
import { getLogger } from "../util/logger.js";
|
|
29
26
|
import { unregisterCallNotifiers } from "./conversation-notifiers.js";
|
|
30
27
|
import type { MessageQueue } from "./conversation-queue-manager.js";
|
|
31
|
-
import { stripInjectionsForCompaction } from "./conversation-runtime-assembly.js";
|
|
32
28
|
import { resetSkillToolProjection } from "./conversation-skill-tools.js";
|
|
33
|
-
import type {
|
|
34
|
-
SurfaceData,
|
|
35
|
-
SurfaceType,
|
|
36
|
-
UsageStats,
|
|
37
|
-
} from "./message-protocol.js";
|
|
38
|
-
import { filterMessagesForUntrustedActor } from "./message-provenance.js";
|
|
39
|
-
import { resolveTrustClass, type TrustContext } from "./trust-context.js";
|
|
29
|
+
import type { SurfaceData, SurfaceType } from "./message-protocol.js";
|
|
40
30
|
|
|
41
31
|
const log = getLogger("conversation-lifecycle");
|
|
42
32
|
|
|
@@ -75,17 +65,6 @@ export function reinjectImageSourcePaths(
|
|
|
75
65
|
|
|
76
66
|
// ── Context Interfaces ───────────────────────────────────────────────
|
|
77
67
|
|
|
78
|
-
export interface LoadFromDbContext {
|
|
79
|
-
readonly conversationId: string;
|
|
80
|
-
messages: Message[];
|
|
81
|
-
usageStats: UsageStats;
|
|
82
|
-
contextCompactedMessageCount: number;
|
|
83
|
-
contextCompactedAt: number | null;
|
|
84
|
-
trustContext?: TrustContext;
|
|
85
|
-
loadedHistoryTrustClass?: TrustClass;
|
|
86
|
-
loadedHistoryPersonalMemoryAllowed?: boolean;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
68
|
export interface AbortContext {
|
|
90
69
|
readonly conversationId: string;
|
|
91
70
|
isProcessing(): boolean;
|
|
@@ -127,236 +106,6 @@ export interface DisposeContext extends AbortContext {
|
|
|
127
106
|
abort(): void;
|
|
128
107
|
}
|
|
129
108
|
|
|
130
|
-
// ── loadFromDb ───────────────────────────────────────────────────────
|
|
131
|
-
|
|
132
|
-
export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
133
|
-
const trustClass = ctx.trustContext?.trustClass;
|
|
134
|
-
const allDbMessages = getMessages(ctx.conversationId);
|
|
135
|
-
const dbMessages = isUntrustedTrustClass(trustClass)
|
|
136
|
-
? filterMessagesForUntrustedActor(allDbMessages)
|
|
137
|
-
: allDbMessages;
|
|
138
|
-
|
|
139
|
-
const conv = getConversation(ctx.conversationId);
|
|
140
|
-
const contextSummary = !isUntrustedTrustClass(trustClass)
|
|
141
|
-
? conv?.contextSummary?.trim() || null
|
|
142
|
-
: null;
|
|
143
|
-
if (isUntrustedTrustClass(trustClass)) {
|
|
144
|
-
// Compacted summaries may include trusted/guardian-only details, so we
|
|
145
|
-
// disable summary-based context for untrusted actor views.
|
|
146
|
-
ctx.contextCompactedMessageCount = 0;
|
|
147
|
-
ctx.contextCompactedAt = null;
|
|
148
|
-
} else {
|
|
149
|
-
ctx.contextCompactedMessageCount = Math.max(
|
|
150
|
-
0,
|
|
151
|
-
Math.min(conv?.contextCompactedMessageCount ?? 0, dbMessages.length),
|
|
152
|
-
);
|
|
153
|
-
ctx.contextCompactedAt = conv?.contextCompactedAt ?? null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Every injection-strip event (`/clean` or compaction) updates
|
|
157
|
-
// `historyStrippedAt`. Messages older than this should skip metadata
|
|
158
|
-
// rehydration and have any injection prefixes still embedded in their
|
|
159
|
-
// content stripped, so the post-strip view survives reload and forks.
|
|
160
|
-
const historyStrippedAt = conv?.historyStrippedAt ?? null;
|
|
161
|
-
const slicedDbMessages = dbMessages.slice(ctx.contextCompactedMessageCount);
|
|
162
|
-
let preStrippedCount = 0;
|
|
163
|
-
if (historyStrippedAt != null) {
|
|
164
|
-
const boundary = slicedDbMessages.findIndex(
|
|
165
|
-
(m) => m.createdAt >= historyStrippedAt,
|
|
166
|
-
);
|
|
167
|
-
preStrippedCount = boundary === -1 ? slicedDbMessages.length : boundary;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Mirror the injection-time gate (`shouldExposePersonalMemory` in
|
|
171
|
-
// `conversation-agent-loop.ts`) so background/local conversations
|
|
172
|
-
// (sourceChannel `undefined` or `"vellum"`) can rehydrate the persisted
|
|
173
|
-
// v2 static memory block. Use `resolveTrustClass` for parity with the
|
|
174
|
-
// agent loop — it folds in the HTTP-auth-disabled dev bypass so
|
|
175
|
-
// rehydration and injection agree on the effective trust class.
|
|
176
|
-
const personalMemoryAllowed = shouldExposePersonalMemory({
|
|
177
|
-
sourceChannel: ctx.trustContext?.sourceChannel,
|
|
178
|
-
isTrustedActor: resolveTrustClass(ctx.trustContext) === "guardian",
|
|
179
|
-
});
|
|
180
|
-
const parsedMessages: Message[] = slicedDbMessages.map((m, index, arr) => {
|
|
181
|
-
const isPreStripped = index < preStrippedCount;
|
|
182
|
-
const role = m.role as "user" | "assistant";
|
|
183
|
-
let content: ContentBlock[];
|
|
184
|
-
try {
|
|
185
|
-
const parsed = JSON.parse(m.content);
|
|
186
|
-
content = Array.isArray(parsed)
|
|
187
|
-
? parsed
|
|
188
|
-
: [{ type: "text", text: m.content }];
|
|
189
|
-
} catch {
|
|
190
|
-
log.warn(
|
|
191
|
-
{ conversationId: ctx.conversationId, messageId: m.id },
|
|
192
|
-
"Invalid JSON in persisted message content, replacing with safe text block",
|
|
193
|
-
);
|
|
194
|
-
content = [{ type: "text", text: m.content }];
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
content = reinjectImageSourcePaths(content, role, m.metadata);
|
|
198
|
-
|
|
199
|
-
// Re-inject persisted injection blocks from metadata so it survives
|
|
200
|
-
// conversation reloads (eviction, restart, fork).
|
|
201
|
-
if (role === "user" && m.metadata && !isPreStripped) {
|
|
202
|
-
try {
|
|
203
|
-
const meta = JSON.parse(m.metadata);
|
|
204
|
-
const isTail = index === arr.length - 1;
|
|
205
|
-
|
|
206
|
-
// Rehydrate in reverse injection order (innermost block first)
|
|
207
|
-
// so the resulting layout matches `applyRuntimeInjections`'s
|
|
208
|
-
// after-memory-prefix splices in ascending injector order
|
|
209
|
-
// (pkb-context 30, pkb-reminder 35, memory-v2-static 38,
|
|
210
|
-
// now-md 40 — the v2 static block lands inside the memory
|
|
211
|
-
// prefix, so now-md splices *after* it):
|
|
212
|
-
// [<workspace>, <turn_context>, <memory>dynamic</memory>,
|
|
213
|
-
// <info>v2static</info>, <NOW.md>, <system_reminder>,
|
|
214
|
-
// <knowledge_base>, ...original]
|
|
215
|
-
// The v2 static block is replayed verbatim from stored metadata,
|
|
216
|
-
// so rows may carry either `<info>…</info>` or `<memory>…</memory>`
|
|
217
|
-
// depending on when they were persisted.
|
|
218
|
-
// Required so Anthropic's prefix cache keeps matching msg[0]
|
|
219
|
-
// across daemon restart and conversation eviction. The tail
|
|
220
|
-
// row only rehydrates `memoryInjectedBlock` — the next turn
|
|
221
|
-
// re-injects the rest fresh.
|
|
222
|
-
if (!isTail && typeof meta.pkbContextBlock === "string") {
|
|
223
|
-
content = [
|
|
224
|
-
{ type: "text" as const, text: meta.pkbContextBlock },
|
|
225
|
-
...content,
|
|
226
|
-
];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (!isTail && typeof meta.pkbSystemReminderBlock === "string") {
|
|
230
|
-
content = [
|
|
231
|
-
{ type: "text" as const, text: meta.pkbSystemReminderBlock },
|
|
232
|
-
...content,
|
|
233
|
-
];
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (!isTail && typeof meta.nowScratchpadBlock === "string") {
|
|
237
|
-
content = [
|
|
238
|
-
{ type: "text" as const, text: meta.nowScratchpadBlock },
|
|
239
|
-
...content,
|
|
240
|
-
];
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// The v2 static memory block (essentials/threads/recent/buffer
|
|
244
|
-
// wrapped in either `<info>…</info>` or `<memory>…</memory>`)
|
|
245
|
-
// carries personal user memory. Trust-gated to mirror
|
|
246
|
-
// `shouldExposePersonalMemory` at injection time — untrusted-actor
|
|
247
|
-
// views must not read persisted personal memory back through
|
|
248
|
-
// metadata. Skipped on the tail row because the next turn
|
|
249
|
-
// re-injects fresh content on full-mode turns.
|
|
250
|
-
if (
|
|
251
|
-
!isTail &&
|
|
252
|
-
personalMemoryAllowed &&
|
|
253
|
-
typeof meta.memoryV2StaticBlock === "string"
|
|
254
|
-
) {
|
|
255
|
-
content = [
|
|
256
|
-
{ type: "text" as const, text: meta.memoryV2StaticBlock },
|
|
257
|
-
...content,
|
|
258
|
-
];
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Memory remains rehydrated on all rows (existing behavior).
|
|
262
|
-
// Strip any pre-existing wrapper before re-wrapping so historical
|
|
263
|
-
// rows persisted with the wrapper (v2 path before the
|
|
264
|
-
// injectedBlockText contract was unified with v1's unwrapped form)
|
|
265
|
-
// don't render double-wrapped after rehydrate. Only unwrap when
|
|
266
|
-
// the full <memory>...</memory> pair is present so we don't mutate
|
|
267
|
-
// legitimate unwrapped payloads that happen to start with
|
|
268
|
-
// "<memory>\n" or end with "\n</memory>".
|
|
269
|
-
if (typeof meta.memoryInjectedBlock === "string") {
|
|
270
|
-
const block = meta.memoryInjectedBlock;
|
|
271
|
-
const inner =
|
|
272
|
-
block.startsWith("<memory>\n") && block.endsWith("\n</memory>")
|
|
273
|
-
? block.slice("<memory>\n".length, -"\n</memory>".length)
|
|
274
|
-
: block;
|
|
275
|
-
content = [
|
|
276
|
-
{
|
|
277
|
-
type: "text" as const,
|
|
278
|
-
text: `<memory>\n${inner}\n</memory>`,
|
|
279
|
-
},
|
|
280
|
-
...content,
|
|
281
|
-
];
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (!isTail && typeof meta.turnContextBlock === "string") {
|
|
285
|
-
content = [
|
|
286
|
-
{ type: "text" as const, text: meta.turnContextBlock },
|
|
287
|
-
...content,
|
|
288
|
-
];
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (!isTail && typeof meta.workspaceBlock === "string") {
|
|
292
|
-
content = [
|
|
293
|
-
{ type: "text" as const, text: meta.workspaceBlock },
|
|
294
|
-
...content,
|
|
295
|
-
];
|
|
296
|
-
}
|
|
297
|
-
} catch {
|
|
298
|
-
/* ignore parse errors — metadata may be malformed */
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return { role, content };
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
// Strip pre-clean messages only; post-clean messages keep the fresh
|
|
306
|
-
// injections they were generated with.
|
|
307
|
-
const messagesBeforeRepair =
|
|
308
|
-
preStrippedCount === 0
|
|
309
|
-
? parsedMessages
|
|
310
|
-
: [
|
|
311
|
-
...stripInjectionsForCompaction(
|
|
312
|
-
parsedMessages.slice(0, preStrippedCount),
|
|
313
|
-
),
|
|
314
|
-
...parsedMessages.slice(preStrippedCount),
|
|
315
|
-
];
|
|
316
|
-
|
|
317
|
-
// Normalize the canonical persisted history once at load. Every consumer
|
|
318
|
-
// of `ctx.messages` outside the agent loop (history edit/undo, PKB context
|
|
319
|
-
// tracking, surfaces) reads this list directly, so it must satisfy the
|
|
320
|
-
// provider pairing/alternation rules before any of them run. The agent
|
|
321
|
-
// loop's pre-run repair only repairs the transient per-turn message list it
|
|
322
|
-
// sends to the provider and never writes back here, so this pass is not
|
|
323
|
-
// redundant with it.
|
|
324
|
-
const { messages: repairedMessages, stats } =
|
|
325
|
-
repairHistory(messagesBeforeRepair);
|
|
326
|
-
if (
|
|
327
|
-
stats.assistantToolResultsMigrated > 0 ||
|
|
328
|
-
stats.missingToolResultsInserted > 0 ||
|
|
329
|
-
stats.orphanToolResultsDowngraded > 0 ||
|
|
330
|
-
stats.consecutiveSameRoleMerged > 0
|
|
331
|
-
) {
|
|
332
|
-
log.warn(
|
|
333
|
-
{ conversationId: ctx.conversationId, phase: "load", ...stats },
|
|
334
|
-
"Repaired persisted history",
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
ctx.messages = repairedMessages;
|
|
338
|
-
|
|
339
|
-
if (contextSummary) {
|
|
340
|
-
ctx.messages.unshift(createContextSummaryMessage(contextSummary));
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (conv) {
|
|
344
|
-
ctx.usageStats = {
|
|
345
|
-
inputTokens: conv.totalInputTokens,
|
|
346
|
-
outputTokens: conv.totalOutputTokens,
|
|
347
|
-
estimatedCost: conv.totalEstimatedCost,
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
ctx.loadedHistoryTrustClass = trustClass;
|
|
352
|
-
ctx.loadedHistoryPersonalMemoryAllowed = personalMemoryAllowed;
|
|
353
|
-
|
|
354
|
-
log.info(
|
|
355
|
-
{ conversationId: ctx.conversationId, count: ctx.messages.length },
|
|
356
|
-
"Loaded messages from DB",
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
109
|
// ── abort ─────────────────────────────────────────────────────────────
|
|
361
110
|
|
|
362
111
|
export function abortConversation(
|
|
@@ -493,4 +242,11 @@ export function disposeConversation(ctx: DisposeContext): void {
|
|
|
493
242
|
ctx.accumulatedSurfaceState.clear();
|
|
494
243
|
ctx.lastSurfaceAction.clear();
|
|
495
244
|
ctx.workspaceTopLevelContext = null;
|
|
245
|
+
// The compaction module owns the per-conversation ContextWindowManager, so
|
|
246
|
+
// teardown releases it directly. Moving this behind a compaction-plugin hook
|
|
247
|
+
// would let the module own disposal end-to-end, but the per-turn `stop` hook
|
|
248
|
+
// would first require relocating the manager's only
|
|
249
|
+
// cross-turn state — `nonPersistedPrefixCount` — off the manager so a
|
|
250
|
+
// per-turn dispose/rebuild stays correct.
|
|
251
|
+
disposeContextWindowManager(ctx.conversationId);
|
|
496
252
|
}
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
createUserMessage,
|
|
13
13
|
} from "../agent/message-types.js";
|
|
14
14
|
import {
|
|
15
|
-
type InterfaceId,
|
|
16
15
|
parseChannelId,
|
|
17
16
|
parseInterfaceId,
|
|
18
17
|
type TurnChannelContext,
|
|
@@ -29,22 +28,18 @@ import {
|
|
|
29
28
|
} from "../memory/conversation-crud.js";
|
|
30
29
|
import { extractPreferences } from "../notifications/preference-extractor.js";
|
|
31
30
|
import { createPreference } from "../notifications/preferences-store.js";
|
|
32
|
-
import type { Message } from "../providers/types.js";
|
|
33
31
|
import { routeGuardianReply } from "../runtime/guardian-reply-router.js";
|
|
34
32
|
import { publishConversationMessagesChanged } from "../runtime/sync/resource-sync-events.js";
|
|
35
33
|
import { getLogger } from "../util/logger.js";
|
|
36
|
-
import type { CleanResult } from "./conversation.js";
|
|
37
|
-
import type { PersistMessageOptions } from "./conversation-messaging.js";
|
|
34
|
+
import type { CleanResult, Conversation } from "./conversation.js";
|
|
38
35
|
import {
|
|
39
36
|
persistQueuedMessageBody,
|
|
40
37
|
serializePersistedUserMessageContent,
|
|
41
38
|
} from "./conversation-messaging.js";
|
|
42
39
|
import type {
|
|
43
|
-
MessageQueue,
|
|
44
40
|
QueuedMessage,
|
|
45
41
|
QueueDrainReason,
|
|
46
42
|
} from "./conversation-queue-manager.js";
|
|
47
|
-
import type { ChannelCapabilities } from "./conversation-runtime-assembly.js";
|
|
48
43
|
import {
|
|
49
44
|
buildSlashContextForContent,
|
|
50
45
|
classifySlash,
|
|
@@ -55,13 +50,9 @@ import { getModelInfo } from "./handlers/config-model.js";
|
|
|
55
50
|
import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
|
|
56
51
|
import type {
|
|
57
52
|
ServerMessage,
|
|
58
|
-
UsageStats,
|
|
59
53
|
UserMessageAttachment,
|
|
60
54
|
} from "./message-protocol.js";
|
|
61
|
-
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
62
|
-
import type { TraceEmitter } from "./trace-emitter.js";
|
|
63
55
|
import { buildTransportHints } from "./transport-hints.js";
|
|
64
|
-
import type { TrustContext } from "./trust-context.js";
|
|
65
56
|
import { resolveVerificationSessionIntent } from "./verification-session-intent.js";
|
|
66
57
|
|
|
67
58
|
const log = getLogger("conversation-process");
|
|
@@ -117,123 +108,6 @@ export function isModelSlashCommand(content: string): boolean {
|
|
|
117
108
|
return content.trim() === "/models";
|
|
118
109
|
}
|
|
119
110
|
|
|
120
|
-
// ── Context Interface ────────────────────────────────────────────────
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Subset of Conversation state that drainQueue / processMessage need access to.
|
|
124
|
-
* The Conversation class implements this interface so its instances can be
|
|
125
|
-
* passed directly to the extracted functions.
|
|
126
|
-
*/
|
|
127
|
-
export interface ProcessConversationContext {
|
|
128
|
-
readonly conversationId: string;
|
|
129
|
-
messages: Message[];
|
|
130
|
-
isProcessing(): boolean;
|
|
131
|
-
setProcessing(value: boolean): void;
|
|
132
|
-
abortController: AbortController | null;
|
|
133
|
-
currentRequestId?: string;
|
|
134
|
-
readonly queue: MessageQueue;
|
|
135
|
-
readonly traceEmitter: TraceEmitter;
|
|
136
|
-
/**
|
|
137
|
-
* Set of requestIds created by surface-action responses. Used to
|
|
138
|
-
* distinguish surface-action turns from regular user turns (e.g. for
|
|
139
|
-
* stale-surface auto-dismiss guards and batched-drain exclusion).
|
|
140
|
-
*/
|
|
141
|
-
readonly surfaceActionRequestIds: Set<string>;
|
|
142
|
-
currentActiveSurfaceId?: string;
|
|
143
|
-
currentPage?: string;
|
|
144
|
-
/** When true, the drain path should inject synthetic tool_result messages
|
|
145
|
-
* for any pending tool_use blocks abandoned by a steered abort. */
|
|
146
|
-
pendingSteerRepair?: boolean;
|
|
147
|
-
/** Cumulative token usage stats for the conversation. */
|
|
148
|
-
readonly usageStats: UsageStats;
|
|
149
|
-
/** Request-scoped skill IDs preactivated via config or programmatic injection. */
|
|
150
|
-
preactivatedSkillIds?: string[];
|
|
151
|
-
/** Add a skill ID to the preactivated set without replacing existing entries. */
|
|
152
|
-
addPreactivatedSkillId(id: string): void;
|
|
153
|
-
/** Assistant identity — used for scoping notification preferences. */
|
|
154
|
-
readonly assistantId?: string;
|
|
155
|
-
trustContext?: TrustContext;
|
|
156
|
-
channelCapabilities?: ChannelCapabilities;
|
|
157
|
-
/** Per-turn snapshot of trustContext, frozen at message-processing start. */
|
|
158
|
-
currentTurnTrustContext?: TrustContext;
|
|
159
|
-
/** Per-turn snapshot of channelCapabilities, frozen at message-processing start. */
|
|
160
|
-
currentTurnChannelCapabilities?: ChannelCapabilities;
|
|
161
|
-
ensureActorScopedHistory(): Promise<void>;
|
|
162
|
-
persistUserMessage(
|
|
163
|
-
options: PersistMessageOptions,
|
|
164
|
-
): Promise<{ id: string; deduplicated: boolean }>;
|
|
165
|
-
runAgentLoop(
|
|
166
|
-
content: string,
|
|
167
|
-
userMessageId: string,
|
|
168
|
-
options?: {
|
|
169
|
-
onEvent?: (msg: ServerMessage) => void;
|
|
170
|
-
isInteractive?: boolean;
|
|
171
|
-
isUserMessage?: boolean;
|
|
172
|
-
titleText?: string;
|
|
173
|
-
callSite?: LLMCallSite;
|
|
174
|
-
},
|
|
175
|
-
): Promise<void>;
|
|
176
|
-
getTurnChannelContext(): TurnChannelContext | null;
|
|
177
|
-
setTurnChannelContext(ctx: TurnChannelContext): void;
|
|
178
|
-
getTurnInterfaceContext(): TurnInterfaceContext | null;
|
|
179
|
-
setTurnInterfaceContext(ctx: TurnInterfaceContext): void;
|
|
180
|
-
emitActivityState(
|
|
181
|
-
phase:
|
|
182
|
-
| "idle"
|
|
183
|
-
| "thinking"
|
|
184
|
-
| "streaming"
|
|
185
|
-
| "tool_running"
|
|
186
|
-
| "awaiting_confirmation",
|
|
187
|
-
reason:
|
|
188
|
-
| "message_dequeued"
|
|
189
|
-
| "thinking_delta"
|
|
190
|
-
| "first_text_delta"
|
|
191
|
-
| "tool_use_start"
|
|
192
|
-
| "tool_result_received"
|
|
193
|
-
| "confirmation_requested"
|
|
194
|
-
| "confirmation_resolved"
|
|
195
|
-
| "message_complete"
|
|
196
|
-
| "generation_cancelled"
|
|
197
|
-
| "error_terminal"
|
|
198
|
-
| "preview_start"
|
|
199
|
-
| "context_compacting",
|
|
200
|
-
options?: {
|
|
201
|
-
anchor?: "assistant_turn" | "user_turn" | "global";
|
|
202
|
-
requestId?: string;
|
|
203
|
-
statusText?: string;
|
|
204
|
-
},
|
|
205
|
-
): void;
|
|
206
|
-
/** Force context compaction regardless of threshold/cooldown. */
|
|
207
|
-
forceCompact(): Promise<ContextWindowResult>;
|
|
208
|
-
/** Strip runtime injections and reset memory-injection state. */
|
|
209
|
-
forceClean(): Promise<CleanResult>;
|
|
210
|
-
/** Set transport-derived hints for the conversation. */
|
|
211
|
-
setTransportHints(hints: string[] | undefined): void;
|
|
212
|
-
/** IANA timezone reported by the active client for the current turn. */
|
|
213
|
-
clientTimezone?: string;
|
|
214
|
-
/**
|
|
215
|
-
* Apply client-reported host env (home dir, username) from transport
|
|
216
|
-
* metadata, gating on `supportsHostProxy` so non-host-proxy interfaces
|
|
217
|
-
* clear any stale values. Shared between the create/reuse path in
|
|
218
|
-
* `DaemonServer.applyTransportMetadata` and the queue-drain path below.
|
|
219
|
-
*/
|
|
220
|
-
applyHostEnvFromTransport(transport: ConversationTransportMetadata): void;
|
|
221
|
-
/** Apply the per-turn client timezone reported by transport metadata. */
|
|
222
|
-
applyClientTimezoneFromTransport(
|
|
223
|
-
transport: ConversationTransportMetadata,
|
|
224
|
-
): void;
|
|
225
|
-
/**
|
|
226
|
-
* Instantiate host proxies for capabilities that have become reachable
|
|
227
|
-
* mid-queue (e.g. a macOS client connected after a web turn was enqueued
|
|
228
|
-
* without a proxy). Called from drain paths before preactivation so skills
|
|
229
|
-
* are only activated when the proxy that services them is present.
|
|
230
|
-
*/
|
|
231
|
-
ensureHostProxiesForTurn(
|
|
232
|
-
sourceInterface: InterfaceId | undefined,
|
|
233
|
-
sourceActorPrincipalId?: string,
|
|
234
|
-
): void;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
111
|
function resolveQueuedTurnContext(
|
|
238
112
|
queued: {
|
|
239
113
|
turnChannelContext?: TurnChannelContext;
|
|
@@ -281,7 +155,7 @@ function resolveQueuedTurnInterfaceContext(
|
|
|
281
155
|
/** Build a SlashContext from the current conversation state and config. */
|
|
282
156
|
function buildSlashContext(
|
|
283
157
|
content: string,
|
|
284
|
-
conversation:
|
|
158
|
+
conversation: Conversation,
|
|
285
159
|
): SlashContext | undefined {
|
|
286
160
|
const turnInterface = conversation.getTurnInterfaceContext();
|
|
287
161
|
return buildSlashContextForContent(content, {
|
|
@@ -306,7 +180,7 @@ function buildSlashContext(
|
|
|
306
180
|
* accounting centralized in `MessageQueue` rather than mutating mid-walk.
|
|
307
181
|
*/
|
|
308
182
|
async function buildPassthroughBatch(
|
|
309
|
-
conversation:
|
|
183
|
+
conversation: Conversation,
|
|
310
184
|
): Promise<QueuedMessage[]> {
|
|
311
185
|
const head = conversation.queue.peek(0);
|
|
312
186
|
if (head === undefined) return [];
|
|
@@ -379,9 +253,7 @@ async function buildPassthroughBatch(
|
|
|
379
253
|
* history and injects synthetic error `tool_result` messages for any
|
|
380
254
|
* unmatched `tool_use` blocks.
|
|
381
255
|
*/
|
|
382
|
-
function repairPendingToolUseBlocks(
|
|
383
|
-
conversation: ProcessConversationContext,
|
|
384
|
-
): void {
|
|
256
|
+
function repairPendingToolUseBlocks(conversation: Conversation): void {
|
|
385
257
|
if (!conversation.pendingSteerRepair) return;
|
|
386
258
|
conversation.pendingSteerRepair = false;
|
|
387
259
|
|
|
@@ -452,7 +324,7 @@ function repairPendingToolUseBlocks(
|
|
|
452
324
|
* remaining queued messages would be stranded.
|
|
453
325
|
*/
|
|
454
326
|
export async function drainQueue(
|
|
455
|
-
conversation:
|
|
327
|
+
conversation: Conversation,
|
|
456
328
|
reason: QueueDrainReason = "loop_complete",
|
|
457
329
|
): Promise<void> {
|
|
458
330
|
// After a steer, drain only the promoted head message — don't batch
|
|
@@ -485,7 +357,7 @@ export async function drainQueue(
|
|
|
485
357
|
}
|
|
486
358
|
|
|
487
359
|
async function drainSingleMessage(
|
|
488
|
-
conversation:
|
|
360
|
+
conversation: Conversation,
|
|
489
361
|
next: QueuedMessage,
|
|
490
362
|
reason: QueueDrainReason,
|
|
491
363
|
): Promise<void> {
|
|
@@ -1059,7 +931,7 @@ async function drainSingleMessage(
|
|
|
1059
931
|
// runAgentLoop run. Per-message dequeue events and DB persistence are
|
|
1060
932
|
// preserved; the agent reply fans out to every batched client.
|
|
1061
933
|
async function drainBatch(
|
|
1062
|
-
conversation:
|
|
934
|
+
conversation: Conversation,
|
|
1063
935
|
batch: QueuedMessage[],
|
|
1064
936
|
reason: QueueDrainReason,
|
|
1065
937
|
): Promise<void> {
|
|
@@ -1490,7 +1362,7 @@ export interface ProcessMessageOptions {
|
|
|
1490
1362
|
* in a single call. Used by the message-handler path where blocking is expected.
|
|
1491
1363
|
*/
|
|
1492
1364
|
export async function processMessage(
|
|
1493
|
-
conversation:
|
|
1365
|
+
conversation: Conversation,
|
|
1494
1366
|
options: ProcessMessageOptions,
|
|
1495
1367
|
): Promise<string> {
|
|
1496
1368
|
const {
|