@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091926.ebb2d62
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/docs/activation-funnel-telemetry.md +310 -0
- 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 +273 -121
- package/package.json +2 -2
- package/scripts/sync-llm-catalog.ts +2 -0
- package/src/__tests__/activation-early-marking.test.ts +120 -0
- 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 +23 -8
- 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 +6 -5
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -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 +146 -0
- package/src/__tests__/compaction-events.test.ts +7 -7
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +265 -125
- package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
- 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 +158 -234
- package/src/__tests__/conversation-agent-loop.test.ts +342 -623
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
- package/src/__tests__/conversation-process-callsite.test.ts +15 -15
- package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
- package/src/__tests__/conversation-queue.test.ts +10 -10
- package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +7 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
- package/src/__tests__/conversation-speed-override.test.ts +11 -10
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
- package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -4
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +36 -0
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- 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 +17 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -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 +5 -1
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- 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__/llm-catalog-parity.test.ts +4 -0
- package/src/__tests__/llm-resolver.test.ts +73 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
- package/src/__tests__/persist-unsendable-image.test.ts +97 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +91 -81
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/published-app-updater.test.ts +138 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/retry-thinking-adaptive-only.test.ts +245 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +31 -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 +5 -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__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/web-fetch.test.ts +45 -0
- 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-config-stub.ts +0 -2
- 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/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +188 -28
- package/src/acp/resolve-agent.ts +119 -42
- 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 +403 -251
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/responses/conversation-message.ts +72 -13
- package/src/api/responses/memory-v3-selection-log.ts +19 -10
- package/src/approvals/guardian-request-resolvers.ts +27 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/memory-v3.ts +57 -199
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
- package/src/cli/lib/install-from-github.ts +797 -60
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +416 -0
- package/src/cli/lib/plugin-marketplace.ts +215 -0
- package/src/cli/lib/search-plugins.ts +201 -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 +9 -3
- package/src/config/acp-schema.ts +1 -7
- package/src/config/bundled-skills/acp/SKILL.md +80 -41
- 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 -3
- package/src/config/feature-flag-registry.json +10 -56
- package/src/config/llm-resolver.ts +39 -7
- package/src/config/loader.ts +5 -22
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
- package/src/config/schemas/call-site-catalog.ts +0 -21
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +17 -3
- package/src/config/schemas/memory-v3.ts +58 -8
- package/src/config/seed-inference-profiles.ts +18 -0
- package/src/context/compactor.ts +22 -4
- package/src/context/post-turn-tool-result-truncation.ts +39 -1
- package/src/context/strip-injections.ts +8 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +120 -42
- package/src/daemon/conversation-agent-loop.ts +308 -1297
- package/src/daemon/conversation-error.ts +31 -4
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-messaging.ts +17 -0
- package/src/daemon/conversation-process.ts +22 -141
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +361 -393
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +165 -11
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +444 -62
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +36 -46
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/persist-unsendable-image.ts +62 -25
- package/src/daemon/process-message.ts +1 -1
- package/src/daemon/server.ts +2 -0
- package/src/daemon/tool-side-effects.ts +15 -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__/activation-session-store.test.ts +41 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
- package/src/memory/activation-session-store.ts +43 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +5 -22
- 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/273-onboarding-events-funnel-columns.ts +46 -0
- package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/onboarding-events-store.ts +66 -18
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
- package/src/memory/v2/__tests__/page-store.test.ts +22 -0
- package/src/memory/v2/consolidation-job.ts +2 -63
- package/src/memory/v2/types.ts +5 -0
- package/src/messaging/providers/telegram-bot/api.ts +14 -5
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +9 -2
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +40 -11
- package/src/plugin-api/types.ts +108 -0
- package/src/plugins/defaults/compaction/compact.ts +106 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
- 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 +156 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
- 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/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
- package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
- 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 +76 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
- package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
- package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -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/external-api.ts +12 -2
- 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/system-prompt.ts +61 -10
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
- package/src/providers/anthropic/client.ts +9 -10
- package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
- package/src/providers/inference/logit-bias.ts +55 -0
- package/src/providers/model-catalog.ts +57 -0
- package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -1
- package/src/providers/retry.ts +57 -7
- package/src/providers/types.ts +6 -0
- 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 +466 -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__/stt-routes.test.ts +112 -0
- 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 +185 -32
- package/src/runtime/routes/acp-routes.ts +328 -30
- package/src/runtime/routes/app-management-routes.ts +3 -0
- 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/channel-verification-routes.ts +14 -5
- 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 +30 -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/inbound-stages/acl-enforcement.ts +33 -34
- 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 +65 -305
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/stt-routes.ts +45 -12
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +50 -15
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/services/published-app-updater.ts +30 -8
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
- package/src/telemetry/activation-funnel.ts +167 -0
- package/src/telemetry/types.ts +13 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
- package/src/telemetry/usage-telemetry-reporter.ts +26 -1
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +9 -19
- package/src/tools/acp/list-agents.ts +3 -15
- package/src/tools/acp/spawn.test.ts +173 -202
- 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/browser/browser-execution.ts +12 -2
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/web-fetch.ts +65 -24
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +32 -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/daemon/wake-target-adapter.ts +0 -253
- package/src/memory/v3/__tests__/assign.test.ts +0 -242
- package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
- package/src/memory/v3/__tests__/core.test.ts +0 -39
- package/src/memory/v3/__tests__/health.test.ts +0 -219
- package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
- package/src/memory/v3/__tests__/needle.test.ts +0 -107
- package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
- package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
- package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
- package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
- package/src/memory/v3/__tests__/router.test.ts +0 -332
- package/src/memory/v3/__tests__/selector.test.ts +0 -470
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
- package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
- package/src/memory/v3/__tests__/tree.test.ts +0 -192
- package/src/memory/v3/assign.ts +0 -268
- package/src/memory/v3/capabilities.ts +0 -124
- package/src/memory/v3/core.ts +0 -26
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +0 -314
- package/src/memory/v3/needle.ts +0 -115
- package/src/memory/v3/orchestrate.ts +0 -126
- package/src/memory/v3/page-content.ts +0 -34
- package/src/memory/v3/provider-blocks.ts +0 -26
- package/src/memory/v3/reconcile.ts +0 -523
- package/src/memory/v3/router.ts +0 -190
- package/src/memory/v3/selection-log-store.ts +0 -84
- package/src/memory/v3/selector.ts +0 -226
- package/src/memory/v3/shadow-plugin.ts +0 -411
- package/src/memory/v3/snapshot.ts +0 -209
- package/src/memory/v3/tree.ts +0 -174
- package/src/memory/v3/types.ts +0 -59
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- 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/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
- 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/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/util/map-limit.ts +0 -27
- /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__/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}/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}/llm-retry.ts +0 -0
|
@@ -19,10 +19,12 @@ import type { AgentLoopConfig, ResolvedSystemPrompt } from "../agent/loop.js";
|
|
|
19
19
|
import { AgentLoop } from "../agent/loop.js";
|
|
20
20
|
import type { AssistantActivityStateEvent } from "../api/events/assistant-activity-state.js";
|
|
21
21
|
import type {
|
|
22
|
+
ChannelId,
|
|
22
23
|
InterfaceId,
|
|
23
24
|
TurnChannelContext,
|
|
24
25
|
TurnInterfaceContext,
|
|
25
26
|
} from "../channels/types.js";
|
|
27
|
+
import { parseChannelId, parseInterfaceId } from "../channels/types.js";
|
|
26
28
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
27
29
|
import {
|
|
28
30
|
contextWindowConfigFromEffective,
|
|
@@ -31,12 +33,6 @@ import {
|
|
|
31
33
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
32
34
|
import { getConfig } from "../config/loader.js";
|
|
33
35
|
import type { LLMCallSite, Speed } from "../config/schemas/llm.js";
|
|
34
|
-
import type { ContextWindowConfig } from "../config/types.js";
|
|
35
|
-
import {
|
|
36
|
-
ContextWindowManager,
|
|
37
|
-
type ContextWindowResult,
|
|
38
|
-
getSummaryFromContextMessage,
|
|
39
|
-
} from "../context/window-manager.js";
|
|
40
36
|
import type { CesClient } from "../credential-execution/client.js";
|
|
41
37
|
import { EventBus } from "../events/bus.js";
|
|
42
38
|
import type { AssistantDomainEvents } from "../events/domain-events.js";
|
|
@@ -52,7 +48,8 @@ import { registerToolTraceListener } from "../events/tool-trace-listener.js";
|
|
|
52
48
|
import { resolveCanonicalGuardianRequest } from "../memory/canonical-guardian-store.js";
|
|
53
49
|
import {
|
|
54
50
|
getConversation,
|
|
55
|
-
|
|
51
|
+
getMessages,
|
|
52
|
+
resolveOverrideProfile,
|
|
56
53
|
setConversationHistoryStrippedAt,
|
|
57
54
|
} from "../memory/conversation-crud.js";
|
|
58
55
|
import { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
@@ -60,20 +57,43 @@ import { shouldExposePersonalMemory } from "../memory/v2/static-context.js";
|
|
|
60
57
|
import { PermissionPrompter } from "../permissions/prompter.js";
|
|
61
58
|
import { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
62
59
|
import type { UserDecision } from "../permissions/types.js";
|
|
63
|
-
import {
|
|
64
|
-
import
|
|
60
|
+
import { defaultCompact } from "../plugins/defaults/compaction/compact.js";
|
|
61
|
+
import {
|
|
62
|
+
createContextWindowManager,
|
|
63
|
+
getContextWindowManager,
|
|
64
|
+
} from "../plugins/defaults/compaction/manager-store.js";
|
|
65
|
+
import {
|
|
66
|
+
type ContextWindowManager,
|
|
67
|
+
type ContextWindowResult,
|
|
68
|
+
createContextSummaryMessage,
|
|
69
|
+
} from "../plugins/defaults/compaction/window-manager.js";
|
|
70
|
+
import { repairHistory } from "../plugins/defaults/history-repair/terminal.js";
|
|
71
|
+
import {
|
|
72
|
+
applyBootstrapTemplate,
|
|
73
|
+
buildSystemPrompt,
|
|
74
|
+
} from "../prompts/system-prompt.js";
|
|
75
|
+
import type { ContentBlock, Message } from "../providers/types.js";
|
|
65
76
|
import type { Provider } from "../providers/types.js";
|
|
66
|
-
import
|
|
77
|
+
import {
|
|
78
|
+
isUntrustedTrustClass,
|
|
79
|
+
type TrustClass,
|
|
80
|
+
} from "../runtime/actor-trust-resolver.js";
|
|
67
81
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
68
82
|
import type { AuthContext } from "../runtime/auth/types.js";
|
|
69
83
|
import type { InteractiveUiResult } from "../runtime/interactive-ui.js";
|
|
70
84
|
import { publishSyncInvalidation } from "../runtime/sync/sync-publisher.js";
|
|
85
|
+
import {
|
|
86
|
+
type ActivationMomentParam,
|
|
87
|
+
isActivationMomentParam,
|
|
88
|
+
} from "../telemetry/activation-funnel.js";
|
|
71
89
|
import { ToolExecutor } from "../tools/executor.js";
|
|
72
90
|
import { getAllToolDefinitions } from "../tools/registry.js";
|
|
73
91
|
import type { ToolLifecycleEvent } from "../tools/types.js";
|
|
74
92
|
import type { OnboardingContext } from "../types/onboarding-context.js";
|
|
75
93
|
import type { AbortReason } from "../util/abort-reasons.js";
|
|
76
94
|
import { getLogger } from "../util/logger.js";
|
|
95
|
+
import type { WorkspaceGitService } from "../workspace/git-service.js";
|
|
96
|
+
import type { commitTurnChanges } from "../workspace/turn-commit.js";
|
|
77
97
|
import type { AssistantAttachmentDraft } from "./assistant-attachments.js";
|
|
78
98
|
import type { AssistantSurface } from "./conversation-agent-loop.js";
|
|
79
99
|
import {
|
|
@@ -85,7 +105,7 @@ import { undo as undoImpl } from "./conversation-history.js";
|
|
|
85
105
|
import {
|
|
86
106
|
abortConversation,
|
|
87
107
|
disposeConversation,
|
|
88
|
-
|
|
108
|
+
reinjectImageSourcePaths,
|
|
89
109
|
} from "./conversation-lifecycle.js";
|
|
90
110
|
import type {
|
|
91
111
|
EnqueueMessageOptions,
|
|
@@ -99,10 +119,7 @@ import {
|
|
|
99
119
|
} from "./conversation-messaging.js";
|
|
100
120
|
// Extracted modules
|
|
101
121
|
import { registerConversationNotifiers } from "./conversation-notifiers.js";
|
|
102
|
-
import type {
|
|
103
|
-
ProcessConversationContext,
|
|
104
|
-
ProcessMessageOptions,
|
|
105
|
-
} from "./conversation-process.js";
|
|
122
|
+
import type { ProcessMessageOptions } from "./conversation-process.js";
|
|
106
123
|
import {
|
|
107
124
|
drainQueue as drainQueueImpl,
|
|
108
125
|
processMessage as processMessageImpl,
|
|
@@ -128,7 +145,6 @@ import {
|
|
|
128
145
|
createResolveToolsCallback,
|
|
129
146
|
createToolExecutor,
|
|
130
147
|
} from "./conversation-tool-setup.js";
|
|
131
|
-
import { refreshWorkspaceTopLevelContextIfNeeded as refreshWorkspaceImpl } from "./conversation-workspace.js";
|
|
132
148
|
import { canonicalizeTimeZone } from "./date-context.js";
|
|
133
149
|
import { HostAppControlProxy } from "./host-app-control-proxy.js";
|
|
134
150
|
import { HostCuProxy } from "./host-cu-proxy.js";
|
|
@@ -139,6 +155,7 @@ import type {
|
|
|
139
155
|
SurfaceType,
|
|
140
156
|
UsageStats,
|
|
141
157
|
} from "./message-protocol.js";
|
|
158
|
+
import { filterMessagesForUntrustedActor } from "./message-provenance.js";
|
|
142
159
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
143
160
|
import { isHostProxyTransport } from "./message-types/conversations.js";
|
|
144
161
|
import type { ConfirmationStateChanged } from "./message-types/messages.js";
|
|
@@ -198,21 +215,33 @@ export class Conversation {
|
|
|
198
215
|
estimatedCost: 0,
|
|
199
216
|
};
|
|
200
217
|
/** @internal */ readonly systemPrompt: string;
|
|
201
|
-
/** @internal */ contextWindowManager: ContextWindowManager;
|
|
202
218
|
/** @internal */ contextCompactedMessageCount = 0;
|
|
203
219
|
/** @internal */ contextCompactedAt: number | null = null;
|
|
220
|
+
/** @internal */ contextSummary: string | null = null;
|
|
221
|
+
/** @internal */ slackContextCompactionWatermarkTs: string | null = null;
|
|
222
|
+
/** @internal */ lastNotifiedInferenceProfile: string | null = null;
|
|
204
223
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* stripped and never re-emits them.
|
|
224
|
+
* Per-conversation inference-profile override mirrored from the DB row.
|
|
225
|
+
* `inferenceProfileSessionId`/`inferenceProfileExpiresAt` are set when the
|
|
226
|
+
* override is session-backed (expiring); both are null for a sticky
|
|
227
|
+
* override or when no override is active. Hydrated on load and kept in sync
|
|
228
|
+
* by the HTTP setters and the background expiry reaper so the live instance
|
|
229
|
+
* is the single source of truth for the per-turn override derivation.
|
|
230
|
+
* @internal
|
|
213
231
|
*/
|
|
214
|
-
|
|
232
|
+
inferenceProfile: string | null = null;
|
|
233
|
+
/** @internal */ inferenceProfileSessionId: string | null = null;
|
|
234
|
+
/** @internal */ inferenceProfileExpiresAt: number | null = null;
|
|
215
235
|
/** @internal */ currentRequestId?: string;
|
|
236
|
+
/**
|
|
237
|
+
* The {@link LLMCallSite} of the in-flight turn, set at turn start from
|
|
238
|
+
* `options?.callSite ?? "mainAgent"`. Lets the per-turn plugin context tell
|
|
239
|
+
* the main reply apart from background agent-loop work (compaction,
|
|
240
|
+
* subagents, …) on this same conversation. Per-turn mutable, mirroring
|
|
241
|
+
* {@link currentRequestId}.
|
|
242
|
+
* @internal
|
|
243
|
+
*/
|
|
244
|
+
currentCallSite?: LLMCallSite;
|
|
216
245
|
/** @internal */ hasNoClient = false;
|
|
217
246
|
/** @internal */ isSubagent = false;
|
|
218
247
|
/** @internal */ headlessLock = false;
|
|
@@ -242,11 +271,39 @@ export class Conversation {
|
|
|
242
271
|
/** @internal */ currentTurnTrustContext?: TrustContext;
|
|
243
272
|
/** @internal */ currentTurnChannelCapabilities?: ChannelCapabilities;
|
|
244
273
|
/** @internal */ currentTurnOverrideProfile?: string;
|
|
274
|
+
/** @internal */ toolRoutedProfile?: string;
|
|
245
275
|
/** @internal */ authContext?: AuthContext;
|
|
276
|
+
/** @internal */ currentTurnAuthContext?: AuthContext;
|
|
277
|
+
/** @internal */ currentTurnSourceActorPrincipalId?: string;
|
|
246
278
|
/** @internal */ loadedHistoryTrustClass?: TrustClass;
|
|
247
279
|
/** @internal */ loadedHistoryPersonalMemoryAllowed?: boolean;
|
|
248
280
|
/** @internal */ voiceCallControlPrompt?: string;
|
|
249
281
|
/** @internal */ transportHints?: string[];
|
|
282
|
+
/**
|
|
283
|
+
* Optional workspace-git seams, overridable in tests to stub the git
|
|
284
|
+
* initializer and turn-commit behavior. Default to the real
|
|
285
|
+
* implementations in the agent loop when unset.
|
|
286
|
+
* @internal
|
|
287
|
+
*/
|
|
288
|
+
getWorkspaceGitService?: (
|
|
289
|
+
workspaceDir: string,
|
|
290
|
+
) => Pick<WorkspaceGitService, "ensureInitialized">;
|
|
291
|
+
/** @internal */ commitTurnChanges?: typeof commitTurnChanges;
|
|
292
|
+
/**
|
|
293
|
+
* The conversation's immutable creation type (`interactive`, `background`,
|
|
294
|
+
* `scheduled`, …) as stored on the DB row. Cached on load (and set directly
|
|
295
|
+
* for subagent conversations) so the runtime-assembly path can derive the
|
|
296
|
+
* background-turn flag from live state without a per-injection DB read.
|
|
297
|
+
* @internal
|
|
298
|
+
*/
|
|
299
|
+
conversationType?: string;
|
|
300
|
+
/**
|
|
301
|
+
* The conversation's creation source (`user`, …) as stored on the DB row,
|
|
302
|
+
* cached on load so the runtime-assembly and disk-pressure paths can read it
|
|
303
|
+
* from live state without a per-turn DB row read.
|
|
304
|
+
* @internal
|
|
305
|
+
*/
|
|
306
|
+
source?: string;
|
|
250
307
|
/** @internal */ assistantId?: string;
|
|
251
308
|
/** @internal */ commandIntent?: {
|
|
252
309
|
type: string;
|
|
@@ -290,6 +347,12 @@ export class Conversation {
|
|
|
290
347
|
style?: string;
|
|
291
348
|
data?: Record<string, unknown>;
|
|
292
349
|
}>;
|
|
350
|
+
/**
|
|
351
|
+
* Commit-timing activation-rail tag (daemon-only). Rehydrated by
|
|
352
|
+
* `restoreSurfaceStateFromHistory` so a post-reload commit still records
|
|
353
|
+
* its funnel milestone. Never sent to the client.
|
|
354
|
+
*/
|
|
355
|
+
activationMoment?: ActivationMomentParam;
|
|
293
356
|
}
|
|
294
357
|
>();
|
|
295
358
|
/** @internal */ surfaceUndoStacks = new Map<string, string[]>();
|
|
@@ -340,6 +403,26 @@ export class Conversation {
|
|
|
340
403
|
*/
|
|
341
404
|
hostUsername?: string;
|
|
342
405
|
/** @internal */ clientTimezone?: string;
|
|
406
|
+
/**
|
|
407
|
+
* Per-turn temporal snapshot frozen by the agent loop and read by
|
|
408
|
+
* `applyRuntimeInjections` to build the `<turn_context>` timezone-mismatch
|
|
409
|
+
* affordance and `time_since_last_message` line. Holds the client-reported
|
|
410
|
+
* timezone captured at turn start and the human-readable gap since the
|
|
411
|
+
* previous user message (null unless it exceeds the long-absence threshold).
|
|
412
|
+
*
|
|
413
|
+
* Frozen here rather than read live in assembly so the client timezone is not
|
|
414
|
+
* clobbered when a newer message for the same conversation overwrites the
|
|
415
|
+
* live {@link clientTimezone} mid-turn (every inbound message re-applies
|
|
416
|
+
* transport metadata before it is enqueued). Its presence also gates the
|
|
417
|
+
* `<turn_context>` block: assembly emits the block only for turns the loop has
|
|
418
|
+
* frozen a snapshot for. The `current_time` value is computed fresh at each
|
|
419
|
+
* injection so post-compaction re-injections reflect the current wall clock.
|
|
420
|
+
* @internal
|
|
421
|
+
*/
|
|
422
|
+
currentTurnTemporalSnapshot?: {
|
|
423
|
+
clientTimezone: string | null;
|
|
424
|
+
timeSinceLastMessage: string | null;
|
|
425
|
+
};
|
|
343
426
|
public readonly traceEmitter: TraceEmitter;
|
|
344
427
|
/** @internal */ hasSystemPromptOverride: boolean;
|
|
345
428
|
/** @internal */ readonly graphMemory: ConversationGraphMemory;
|
|
@@ -359,6 +442,22 @@ export class Conversation {
|
|
|
359
442
|
/** @internal */ currentTurnChannelContext: TurnChannelContext | null = null;
|
|
360
443
|
/** @internal */ currentTurnInterfaceContext: TurnInterfaceContext | null =
|
|
361
444
|
null;
|
|
445
|
+
/**
|
|
446
|
+
* The conversation's recorded origin interface, cached from the DB row at
|
|
447
|
+
* load time. It is immutable once recorded, so it backs the `<turn_context>`
|
|
448
|
+
* interface fallback for turns that don't set a per-turn interface context
|
|
449
|
+
* (regenerate, wake, subagent) without a per-injection DB lookup.
|
|
450
|
+
* @internal
|
|
451
|
+
*/
|
|
452
|
+
originInterface: InterfaceId | undefined = undefined;
|
|
453
|
+
/**
|
|
454
|
+
* The conversation's recorded origin channel, cached from the DB row at load
|
|
455
|
+
* time. It is immutable once recorded, so it backs the `<turn_context>`
|
|
456
|
+
* channel fallback for turns that don't set a per-turn channel context
|
|
457
|
+
* (regenerate, wake, subagent) without a per-injection DB lookup.
|
|
458
|
+
* @internal
|
|
459
|
+
*/
|
|
460
|
+
originChannel: ChannelId | undefined = undefined;
|
|
362
461
|
/** @internal */ activityVersion = 0;
|
|
363
462
|
/** Last emitted activity state message, retained for replay on SSE reconnection. */
|
|
364
463
|
/** @internal */ lastActivityStateMsg: ServerMessage | null = null;
|
|
@@ -484,6 +583,7 @@ export class Conversation {
|
|
|
484
583
|
trustContext: this.currentTurnTrustContext,
|
|
485
584
|
channelCapabilities: this.currentTurnChannelCapabilities,
|
|
486
585
|
onboardingContext: this.getOnboardingContext(),
|
|
586
|
+
conversationId: this.conversationId,
|
|
487
587
|
}),
|
|
488
588
|
};
|
|
489
589
|
if (configuredMaxTokens !== undefined) {
|
|
@@ -518,7 +618,9 @@ export class Conversation {
|
|
|
518
618
|
agentLoopConfig.maxTokens = configuredMaxTokens;
|
|
519
619
|
}
|
|
520
620
|
|
|
521
|
-
this.agentLoop = new AgentLoop(
|
|
621
|
+
this.agentLoop = new AgentLoop({
|
|
622
|
+
provider,
|
|
623
|
+
systemPrompt,
|
|
522
624
|
conversationId: this.conversationId,
|
|
523
625
|
config: agentLoopConfig,
|
|
524
626
|
tools: toolDefs.length > 0 ? toolDefs : undefined,
|
|
@@ -526,7 +628,7 @@ export class Conversation {
|
|
|
526
628
|
resolveTools,
|
|
527
629
|
resolveSystemPrompt: resolveSystemPromptCallback,
|
|
528
630
|
});
|
|
529
|
-
|
|
631
|
+
createContextWindowManager({
|
|
530
632
|
provider,
|
|
531
633
|
systemPrompt: () => resolveSystemPromptCallback([]).systemPrompt,
|
|
532
634
|
config: initialContextWindowConfig,
|
|
@@ -538,16 +640,57 @@ export class Conversation {
|
|
|
538
640
|
});
|
|
539
641
|
}
|
|
540
642
|
|
|
643
|
+
/**
|
|
644
|
+
* The conversation's {@link ContextWindowManager}, owned by the compaction
|
|
645
|
+
* module's per-conversation store. The constructor builds and registers it
|
|
646
|
+
* there; this accessor resolves it on demand so the conversation holds no
|
|
647
|
+
* separate handle. Present for the conversation's whole in-memory lifetime
|
|
648
|
+
* (registered at construction, released on teardown), so a live conversation
|
|
649
|
+
* always resolves an instance.
|
|
650
|
+
*/
|
|
651
|
+
/** @internal */ get contextWindowManager(): ContextWindowManager {
|
|
652
|
+
const manager = getContextWindowManager(this.conversationId);
|
|
653
|
+
if (manager == null) {
|
|
654
|
+
throw new Error(
|
|
655
|
+
`ContextWindowManager missing for conversation ${this.conversationId} — the compaction store entry was released while the conversation is still live`,
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
return manager;
|
|
659
|
+
}
|
|
660
|
+
|
|
541
661
|
// ── Onboarding context ───────────────────────────────────────────
|
|
542
662
|
|
|
543
663
|
setOnboardingContext(ctx: OnboardingContext): void {
|
|
544
664
|
this.onboardingContext = ctx;
|
|
665
|
+
// Reseed BOOTSTRAP.md and mark the activation session at the earliest point
|
|
666
|
+
// the conversation knows its bootstrap selection — before the first turn's
|
|
667
|
+
// tool resolution, which `buildSystemPrompt` is too late for. See
|
|
668
|
+
// `applyBootstrapTemplate`.
|
|
669
|
+
if (ctx.bootstrapTemplate) {
|
|
670
|
+
applyBootstrapTemplate(ctx.bootstrapTemplate, this.conversationId);
|
|
671
|
+
}
|
|
545
672
|
}
|
|
546
673
|
|
|
547
674
|
getOnboardingContext(): OnboardingContext | undefined {
|
|
548
675
|
return this.onboardingContext;
|
|
549
676
|
}
|
|
550
677
|
|
|
678
|
+
/**
|
|
679
|
+
* Mirror an inference-profile override write onto the live instance so the
|
|
680
|
+
* per-turn override derivation reads current state without re-fetching the
|
|
681
|
+
* DB row. Called alongside the corresponding DB write by the HTTP setters
|
|
682
|
+
* and the background expiry reaper.
|
|
683
|
+
*/
|
|
684
|
+
applyInferenceProfileState(state: {
|
|
685
|
+
profile: string | null;
|
|
686
|
+
sessionId: string | null;
|
|
687
|
+
expiresAt: number | null;
|
|
688
|
+
}): void {
|
|
689
|
+
this.inferenceProfile = state.profile;
|
|
690
|
+
this.inferenceProfileSessionId = state.sessionId;
|
|
691
|
+
this.inferenceProfileExpiresAt = state.expiresAt;
|
|
692
|
+
}
|
|
693
|
+
|
|
551
694
|
// ── Prompt Cache Warming ─────────────────────────────────────────
|
|
552
695
|
|
|
553
696
|
/**
|
|
@@ -567,6 +710,7 @@ export class Conversation {
|
|
|
567
710
|
trustContext: this.currentTurnTrustContext,
|
|
568
711
|
channelCapabilities: this.currentTurnChannelCapabilities,
|
|
569
712
|
onboardingContext: this.getOnboardingContext(),
|
|
713
|
+
conversationId: this.conversationId,
|
|
570
714
|
});
|
|
571
715
|
const tools = getAllToolDefinitions();
|
|
572
716
|
const provider = this.provider;
|
|
@@ -605,7 +749,250 @@ export class Conversation {
|
|
|
605
749
|
// ── Lifecycle ────────────────────────────────────────────────────
|
|
606
750
|
|
|
607
751
|
async loadFromDb(): Promise<void> {
|
|
608
|
-
|
|
752
|
+
const trustClass = this.trustContext?.trustClass;
|
|
753
|
+
const allDbMessages = getMessages(this.conversationId);
|
|
754
|
+
const dbMessages = isUntrustedTrustClass(trustClass)
|
|
755
|
+
? filterMessagesForUntrustedActor(allDbMessages)
|
|
756
|
+
: allDbMessages;
|
|
757
|
+
|
|
758
|
+
const conv = getConversation(this.conversationId);
|
|
759
|
+
this.conversationType = conv?.conversationType ?? undefined;
|
|
760
|
+
this.originInterface = parseInterfaceId(conv?.originInterface) ?? undefined;
|
|
761
|
+
this.originChannel = parseChannelId(conv?.originChannel) ?? undefined;
|
|
762
|
+
this.source = conv?.source ?? undefined;
|
|
763
|
+
this.contextSummary = conv?.contextSummary ?? null;
|
|
764
|
+
this.slackContextCompactionWatermarkTs =
|
|
765
|
+
conv?.slackContextCompactionWatermarkTs ?? null;
|
|
766
|
+
this.lastNotifiedInferenceProfile =
|
|
767
|
+
conv?.lastNotifiedInferenceProfile ?? null;
|
|
768
|
+
this.inferenceProfile = conv?.inferenceProfile ?? null;
|
|
769
|
+
this.inferenceProfileSessionId = conv?.inferenceProfileSessionId ?? null;
|
|
770
|
+
this.inferenceProfileExpiresAt = conv?.inferenceProfileExpiresAt ?? null;
|
|
771
|
+
this.contextCompactedMessageCount = Math.max(
|
|
772
|
+
0,
|
|
773
|
+
conv?.contextCompactedMessageCount ?? 0,
|
|
774
|
+
);
|
|
775
|
+
this.contextCompactedAt = conv?.contextCompactedAt ?? null;
|
|
776
|
+
|
|
777
|
+
// Untrusted actor views never receive summary-based compaction: a
|
|
778
|
+
// compacted summary can embed trusted/guardian-only detail, so the
|
|
779
|
+
// summary message is suppressed and the persisted history is rendered
|
|
780
|
+
// unsliced. The slice boundary is clamped so it can never drop more rows
|
|
781
|
+
// than exist. Slack chronological context is a separate consumer that
|
|
782
|
+
// applies its own trust filtering downstream, so it reads the raw
|
|
783
|
+
// mirrored count rather than this in-context boundary.
|
|
784
|
+
const inContextCompactedCount = isUntrustedTrustClass(trustClass)
|
|
785
|
+
? 0
|
|
786
|
+
: Math.min(this.contextCompactedMessageCount, dbMessages.length);
|
|
787
|
+
const contextSummaryForHistory = isUntrustedTrustClass(trustClass)
|
|
788
|
+
? null
|
|
789
|
+
: this.contextSummary?.trim() || null;
|
|
790
|
+
|
|
791
|
+
// Every injection-strip event (`/clean` or compaction) updates
|
|
792
|
+
// `historyStrippedAt`. Messages older than this should skip metadata
|
|
793
|
+
// rehydration and have any injection prefixes still embedded in their
|
|
794
|
+
// content stripped, so the post-strip view survives reload and forks.
|
|
795
|
+
const historyStrippedAt = conv?.historyStrippedAt ?? null;
|
|
796
|
+
const slicedDbMessages = dbMessages.slice(inContextCompactedCount);
|
|
797
|
+
let preStrippedCount = 0;
|
|
798
|
+
if (historyStrippedAt != null) {
|
|
799
|
+
const boundary = slicedDbMessages.findIndex(
|
|
800
|
+
(m) => m.createdAt >= historyStrippedAt,
|
|
801
|
+
);
|
|
802
|
+
preStrippedCount = boundary === -1 ? slicedDbMessages.length : boundary;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// Mirror the injection-time gate (`shouldExposePersonalMemory` in
|
|
806
|
+
// `conversation-agent-loop.ts`) so background/local conversations
|
|
807
|
+
// (sourceChannel `undefined` or `"vellum"`) can rehydrate the persisted
|
|
808
|
+
// v2 static memory block. Use `resolveTrustClass` for parity with the
|
|
809
|
+
// agent loop — it folds in the HTTP-auth-disabled dev bypass so
|
|
810
|
+
// rehydration and injection agree on the effective trust class.
|
|
811
|
+
const personalMemoryAllowed = shouldExposePersonalMemory({
|
|
812
|
+
sourceChannel: this.trustContext?.sourceChannel,
|
|
813
|
+
isTrustedActor: resolveTrustClass(this.trustContext) === "guardian",
|
|
814
|
+
});
|
|
815
|
+
const parsedMessages: Message[] = slicedDbMessages.map((m, index, arr) => {
|
|
816
|
+
const isPreStripped = index < preStrippedCount;
|
|
817
|
+
const role = m.role as "user" | "assistant";
|
|
818
|
+
let content: ContentBlock[];
|
|
819
|
+
try {
|
|
820
|
+
const parsed = JSON.parse(m.content);
|
|
821
|
+
content = Array.isArray(parsed)
|
|
822
|
+
? parsed
|
|
823
|
+
: [{ type: "text", text: m.content }];
|
|
824
|
+
} catch {
|
|
825
|
+
log.warn(
|
|
826
|
+
{ conversationId: this.conversationId, messageId: m.id },
|
|
827
|
+
"Invalid JSON in persisted message content, replacing with safe text block",
|
|
828
|
+
);
|
|
829
|
+
content = [{ type: "text", text: m.content }];
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
content = reinjectImageSourcePaths(content, role, m.metadata);
|
|
833
|
+
|
|
834
|
+
// Re-inject persisted injection blocks from metadata so it survives
|
|
835
|
+
// conversation reloads (eviction, restart, fork).
|
|
836
|
+
if (role === "user" && m.metadata && !isPreStripped) {
|
|
837
|
+
try {
|
|
838
|
+
const meta = JSON.parse(m.metadata);
|
|
839
|
+
const isTail = index === arr.length - 1;
|
|
840
|
+
|
|
841
|
+
// Rehydrate in reverse injection order (innermost block first)
|
|
842
|
+
// so the resulting layout matches `applyRuntimeInjections`'s
|
|
843
|
+
// after-memory-prefix splices in ascending injector order
|
|
844
|
+
// (pkb-context 30, pkb-reminder 35, memory-v2-static 38,
|
|
845
|
+
// now-md 40 — the v2 static block lands inside the memory
|
|
846
|
+
// prefix, so now-md splices *after* it):
|
|
847
|
+
// [<workspace>, <turn_context>, <memory>dynamic</memory>,
|
|
848
|
+
// <info>v2static</info>, <NOW.md>, <system_reminder>,
|
|
849
|
+
// <knowledge_base>, ...original]
|
|
850
|
+
// The v2 static block is replayed verbatim from stored metadata,
|
|
851
|
+
// so rows may carry either `<info>…</info>` or `<memory>…</memory>`
|
|
852
|
+
// depending on when they were persisted.
|
|
853
|
+
// Required so Anthropic's prefix cache keeps matching msg[0]
|
|
854
|
+
// across daemon restart and conversation eviction. The tail
|
|
855
|
+
// row only rehydrates `memoryInjectedBlock` — the next turn
|
|
856
|
+
// re-injects the rest fresh.
|
|
857
|
+
if (!isTail && typeof meta.pkbContextBlock === "string") {
|
|
858
|
+
content = [
|
|
859
|
+
{ type: "text" as const, text: meta.pkbContextBlock },
|
|
860
|
+
...content,
|
|
861
|
+
];
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (!isTail && typeof meta.pkbSystemReminderBlock === "string") {
|
|
865
|
+
content = [
|
|
866
|
+
{ type: "text" as const, text: meta.pkbSystemReminderBlock },
|
|
867
|
+
...content,
|
|
868
|
+
];
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
if (!isTail && typeof meta.nowScratchpadBlock === "string") {
|
|
872
|
+
content = [
|
|
873
|
+
{ type: "text" as const, text: meta.nowScratchpadBlock },
|
|
874
|
+
...content,
|
|
875
|
+
];
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// The v2 static memory block (essentials/threads/recent/buffer
|
|
879
|
+
// wrapped in either `<info>…</info>` or `<memory>…</memory>`)
|
|
880
|
+
// carries personal user memory. Trust-gated to mirror
|
|
881
|
+
// `shouldExposePersonalMemory` at injection time — untrusted-actor
|
|
882
|
+
// views must not read persisted personal memory back through
|
|
883
|
+
// metadata. Skipped on the tail row because the next turn
|
|
884
|
+
// re-injects fresh content on full-mode turns.
|
|
885
|
+
if (
|
|
886
|
+
!isTail &&
|
|
887
|
+
personalMemoryAllowed &&
|
|
888
|
+
typeof meta.memoryV2StaticBlock === "string"
|
|
889
|
+
) {
|
|
890
|
+
content = [
|
|
891
|
+
{ type: "text" as const, text: meta.memoryV2StaticBlock },
|
|
892
|
+
...content,
|
|
893
|
+
];
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// Memory remains rehydrated on all rows (existing behavior).
|
|
897
|
+
// Strip any pre-existing wrapper before re-wrapping so historical
|
|
898
|
+
// rows persisted with the wrapper (v2 path before the
|
|
899
|
+
// injectedBlockText contract was unified with v1's unwrapped form)
|
|
900
|
+
// don't render double-wrapped after rehydrate. Only unwrap when
|
|
901
|
+
// the full <memory>...</memory> pair is present so we don't mutate
|
|
902
|
+
// legitimate unwrapped payloads that happen to start with
|
|
903
|
+
// "<memory>\n" or end with "\n</memory>".
|
|
904
|
+
if (typeof meta.memoryInjectedBlock === "string") {
|
|
905
|
+
const block = meta.memoryInjectedBlock;
|
|
906
|
+
const inner =
|
|
907
|
+
block.startsWith("<memory>\n") && block.endsWith("\n</memory>")
|
|
908
|
+
? block.slice("<memory>\n".length, -"\n</memory>".length)
|
|
909
|
+
: block;
|
|
910
|
+
content = [
|
|
911
|
+
{
|
|
912
|
+
type: "text" as const,
|
|
913
|
+
text: `<memory>\n${inner}\n</memory>`,
|
|
914
|
+
},
|
|
915
|
+
...content,
|
|
916
|
+
];
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
if (!isTail && typeof meta.turnContextBlock === "string") {
|
|
920
|
+
content = [
|
|
921
|
+
{ type: "text" as const, text: meta.turnContextBlock },
|
|
922
|
+
...content,
|
|
923
|
+
];
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (!isTail && typeof meta.workspaceBlock === "string") {
|
|
927
|
+
content = [
|
|
928
|
+
{ type: "text" as const, text: meta.workspaceBlock },
|
|
929
|
+
...content,
|
|
930
|
+
];
|
|
931
|
+
}
|
|
932
|
+
} catch {
|
|
933
|
+
/* ignore parse errors — metadata may be malformed */
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
return { role, content };
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
// Strip pre-clean messages only; post-clean messages keep the fresh
|
|
941
|
+
// injections they were generated with.
|
|
942
|
+
const messagesBeforeRepair =
|
|
943
|
+
preStrippedCount === 0
|
|
944
|
+
? parsedMessages
|
|
945
|
+
: [
|
|
946
|
+
...stripInjectionsForCompaction(
|
|
947
|
+
parsedMessages.slice(0, preStrippedCount),
|
|
948
|
+
),
|
|
949
|
+
...parsedMessages.slice(preStrippedCount),
|
|
950
|
+
];
|
|
951
|
+
|
|
952
|
+
// Normalize the canonical persisted history once at load. Every consumer
|
|
953
|
+
// of `this.messages` outside the agent loop (history edit/undo, PKB context
|
|
954
|
+
// tracking, surfaces) reads this list directly, so it must satisfy the
|
|
955
|
+
// provider pairing/alternation rules before any of them run. The agent
|
|
956
|
+
// loop's pre-run repair only repairs the transient per-turn message list it
|
|
957
|
+
// sends to the provider and never writes back here, so this pass is not
|
|
958
|
+
// redundant with it.
|
|
959
|
+
const { messages: repairedMessages, stats } =
|
|
960
|
+
repairHistory(messagesBeforeRepair);
|
|
961
|
+
if (
|
|
962
|
+
stats.assistantToolResultsMigrated > 0 ||
|
|
963
|
+
stats.missingToolResultsInserted > 0 ||
|
|
964
|
+
stats.orphanToolResultsDowngraded > 0 ||
|
|
965
|
+
stats.consecutiveSameRoleMerged > 0
|
|
966
|
+
) {
|
|
967
|
+
log.warn(
|
|
968
|
+
{ conversationId: this.conversationId, phase: "load", ...stats },
|
|
969
|
+
"Repaired persisted history",
|
|
970
|
+
);
|
|
971
|
+
}
|
|
972
|
+
this.messages = repairedMessages;
|
|
973
|
+
|
|
974
|
+
if (contextSummaryForHistory) {
|
|
975
|
+
this.messages.unshift(
|
|
976
|
+
createContextSummaryMessage(contextSummaryForHistory),
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
if (conv) {
|
|
981
|
+
this.usageStats = {
|
|
982
|
+
inputTokens: conv.totalInputTokens,
|
|
983
|
+
outputTokens: conv.totalOutputTokens,
|
|
984
|
+
estimatedCost: conv.totalEstimatedCost,
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
this.loadedHistoryTrustClass = trustClass;
|
|
989
|
+
this.loadedHistoryPersonalMemoryAllowed = personalMemoryAllowed;
|
|
990
|
+
|
|
991
|
+
log.info(
|
|
992
|
+
{ conversationId: this.conversationId, count: this.messages.length },
|
|
993
|
+
"Loaded messages from DB",
|
|
994
|
+
);
|
|
995
|
+
|
|
609
996
|
this.restoreSurfaceStateFromHistory();
|
|
610
997
|
this.graphMemory.restoreState();
|
|
611
998
|
}
|
|
@@ -627,6 +1014,14 @@ export class Conversation {
|
|
|
627
1014
|
for (const block of msg.content) {
|
|
628
1015
|
const b = block as unknown as Record<string, unknown>;
|
|
629
1016
|
if (b.type === "ui_surface" && typeof b.surfaceId === "string") {
|
|
1017
|
+
// Rehydrate the daemon-only commit-timing activation tag so a commit
|
|
1018
|
+
// after reload still records its funnel milestone. Validated and
|
|
1019
|
+
// dropped if malformed; this field never reaches the client.
|
|
1020
|
+
const activationMoment =
|
|
1021
|
+
typeof b.activationMoment === "string" &&
|
|
1022
|
+
isActivationMomentParam(b.activationMoment)
|
|
1023
|
+
? b.activationMoment
|
|
1024
|
+
: undefined;
|
|
630
1025
|
this.surfaceState.set(b.surfaceId, {
|
|
631
1026
|
surfaceType: (b.surfaceType ?? "dynamic_page") as SurfaceType,
|
|
632
1027
|
data: (b.data ?? {}) as SurfaceData,
|
|
@@ -639,6 +1034,7 @@ export class Conversation {
|
|
|
639
1034
|
data?: Record<string, unknown>;
|
|
640
1035
|
}>)
|
|
641
1036
|
: undefined,
|
|
1037
|
+
...(activationMoment ? { activationMoment } : {}),
|
|
642
1038
|
});
|
|
643
1039
|
}
|
|
644
1040
|
}
|
|
@@ -719,9 +1115,7 @@ export class Conversation {
|
|
|
719
1115
|
);
|
|
720
1116
|
}
|
|
721
1117
|
this.messages = [...messages];
|
|
722
|
-
this.contextWindowManager.
|
|
723
|
-
this.contextWindowManager.summaryIsInjected =
|
|
724
|
-
getSummaryFromContextMessage(messages[0]) != null;
|
|
1118
|
+
this.contextWindowManager.seedNonPersistedPrefix(messages.length);
|
|
725
1119
|
}
|
|
726
1120
|
|
|
727
1121
|
/**
|
|
@@ -969,7 +1363,9 @@ export class Conversation {
|
|
|
969
1363
|
|
|
970
1364
|
ensureHostProxiesForTurn(
|
|
971
1365
|
sourceInterface: import("../channels/types.js").InterfaceId | undefined,
|
|
972
|
-
sourceActorPrincipalId = this.
|
|
1366
|
+
sourceActorPrincipalId = this.currentTurnSourceActorPrincipalId ??
|
|
1367
|
+
this.currentTurnAuthContext?.actorPrincipalId ??
|
|
1368
|
+
this.authContext?.actorPrincipalId,
|
|
973
1369
|
): void {
|
|
974
1370
|
if (
|
|
975
1371
|
shouldAttachHostProxyForCapability(
|
|
@@ -1045,20 +1441,14 @@ export class Conversation {
|
|
|
1045
1441
|
}
|
|
1046
1442
|
|
|
1047
1443
|
async forceCompact(): Promise<ContextWindowResult> {
|
|
1048
|
-
const
|
|
1049
|
-
const overrideProfile =
|
|
1050
|
-
getConversationOverrideProfileFromRow(conversationRow) ?? null;
|
|
1444
|
+
const overrideProfile = resolveOverrideProfile(this) ?? null;
|
|
1051
1445
|
const config = getConfig();
|
|
1052
1446
|
const effectiveContextWindow = resolveEffectiveContextWindow({
|
|
1053
1447
|
llm: config.llm,
|
|
1054
1448
|
callSite: "mainAgent",
|
|
1055
1449
|
overrideProfile: overrideProfile ?? undefined,
|
|
1056
1450
|
});
|
|
1057
|
-
(
|
|
1058
|
-
this.contextWindowManager as ContextWindowManager & {
|
|
1059
|
-
updateConfig?: (config: ContextWindowConfig) => void;
|
|
1060
|
-
}
|
|
1061
|
-
).updateConfig?.(
|
|
1451
|
+
this.contextWindowManager.updateConfig(
|
|
1062
1452
|
contextWindowConfigFromEffective(
|
|
1063
1453
|
resolveCallSiteConfig("mainAgent", config.llm, {
|
|
1064
1454
|
overrideProfile: overrideProfile ?? undefined,
|
|
@@ -1073,25 +1463,23 @@ export class Conversation {
|
|
|
1073
1463
|
this.channelCapabilities,
|
|
1074
1464
|
{
|
|
1075
1465
|
trustClass: this.trustContext?.trustClass,
|
|
1076
|
-
contextSummary:
|
|
1077
|
-
contextCompactedMessageCount:
|
|
1078
|
-
conversationRow?.contextCompactedMessageCount,
|
|
1466
|
+
contextSummary: this.contextSummary,
|
|
1467
|
+
contextCompactedMessageCount: this.contextCompactedMessageCount,
|
|
1079
1468
|
slackContextCompactionWatermarkTs:
|
|
1080
|
-
|
|
1469
|
+
this.slackContextCompactionWatermarkTs,
|
|
1081
1470
|
},
|
|
1082
1471
|
)
|
|
1083
1472
|
: null;
|
|
1084
1473
|
const messagesToCompact =
|
|
1085
1474
|
slackChronologicalContext?.messages ?? this.messages;
|
|
1086
|
-
const result = await
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
);
|
|
1475
|
+
const result = await defaultCompact({
|
|
1476
|
+
conversationId: this.conversationId,
|
|
1477
|
+
messages: messagesToCompact,
|
|
1478
|
+
signal: this.abortController?.signal ?? undefined,
|
|
1479
|
+
force: true,
|
|
1480
|
+
overrideProfile,
|
|
1481
|
+
actorTrustClass: this.trustContext?.trustClass,
|
|
1482
|
+
});
|
|
1095
1483
|
// Track circuit-breaker state for user-initiated `/compact` and other
|
|
1096
1484
|
// forced paths so a successful forced compaction clears a stuck counter
|
|
1097
1485
|
// and a run of forced failures still trips the breaker. `summaryFailed`
|
|
@@ -1099,7 +1487,6 @@ export class Conversation {
|
|
|
1099
1487
|
// etc.) — skip those so they don't silently reset the counter.
|
|
1100
1488
|
if (result.summaryFailed !== undefined) {
|
|
1101
1489
|
await this.agentLoop.compactionCircuit.recordOutcome(
|
|
1102
|
-
this,
|
|
1103
1490
|
result.summaryFailed,
|
|
1104
1491
|
this.sendToClient,
|
|
1105
1492
|
);
|
|
@@ -1128,7 +1515,6 @@ export class Conversation {
|
|
|
1128
1515
|
const stripped = stripInjectionsForCompaction(this.messages);
|
|
1129
1516
|
this.messages = stripped;
|
|
1130
1517
|
await this.graphMemory.onCompacted(0);
|
|
1131
|
-
this.pendingPostCompactReinject = true;
|
|
1132
1518
|
setConversationHistoryStrippedAt(this.conversationId, Date.now());
|
|
1133
1519
|
const estimatedInputTokens = this.contextWindowManager.estimateInputTokens(
|
|
1134
1520
|
this.messages,
|
|
@@ -1308,13 +1694,13 @@ export class Conversation {
|
|
|
1308
1694
|
}
|
|
1309
1695
|
|
|
1310
1696
|
drainQueue(reason: QueueDrainReason = "loop_complete"): Promise<void> {
|
|
1311
|
-
return drainQueueImpl(this
|
|
1697
|
+
return drainQueueImpl(this, reason);
|
|
1312
1698
|
}
|
|
1313
1699
|
|
|
1314
1700
|
async processMessage(options: ProcessMessageOptions): Promise<string> {
|
|
1315
1701
|
this.cacheWarmAbort?.abort();
|
|
1316
1702
|
this.cacheWarmAbort = undefined;
|
|
1317
|
-
return processMessageImpl(this
|
|
1703
|
+
return processMessageImpl(this, {
|
|
1318
1704
|
...options,
|
|
1319
1705
|
onEvent: options.onEvent ?? this.sendToClient,
|
|
1320
1706
|
});
|
|
@@ -1346,10 +1732,6 @@ export class Conversation {
|
|
|
1346
1732
|
|
|
1347
1733
|
// ── Workspace ────────────────────────────────────────────────────
|
|
1348
1734
|
|
|
1349
|
-
refreshWorkspaceTopLevelContextIfNeeded(): void {
|
|
1350
|
-
refreshWorkspaceImpl(this);
|
|
1351
|
-
}
|
|
1352
|
-
|
|
1353
1735
|
markWorkspaceTopLevelDirty(): void {
|
|
1354
1736
|
this.workspaceTopLevelDirty = true;
|
|
1355
1737
|
}
|