@vellumai/assistant 0.7.3 → 0.8.1
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/AGENTS.md +11 -0
- package/ARCHITECTURE.md +29 -28
- package/Dockerfile +6 -4
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +3 -1
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4126 -959
- package/package.json +5 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-source.test.ts +3 -26
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +3 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +22 -7
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +25 -22
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/injector-chain.test.ts +24 -16
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -1888
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +164 -2
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +42 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-decision-primitive.ts +0 -13
- package/src/approvals/guardian-request-resolvers.ts +19 -102
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/relay-server.ts +42 -1
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +24 -5
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +163 -517
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +182 -345
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +17 -17
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +148 -33
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +33 -2
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
- package/src/daemon/conversation-agent-loop.ts +140 -107
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +68 -13
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +92 -26
- package/src/daemon/conversation-tool-setup.ts +33 -19
- package/src/daemon/conversation.ts +49 -10
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/shared.ts +26 -0
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +97 -36
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/host-transfer-proxy.ts +2 -2
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +128 -114
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +62 -14
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +28 -2
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/documents/document-store.ts +35 -1
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +42 -56
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +149 -128
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +148 -42
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +40 -31
- package/src/memory/context-search/sources/memory.ts +9 -2
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +108 -14
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/graph-search.test.ts +6 -5
- package/src/memory/graph/graph-search.ts +3 -4
- package/src/memory/graph/retriever.test.ts +12 -7
- package/src/memory/graph/retriever.ts +4 -5
- package/src/memory/graph/tool-handlers.ts +20 -11
- package/src/memory/graph/tools.ts +48 -9
- package/src/memory/indexer.ts +18 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
- package/src/memory/jobs/embed-concept-page.ts +261 -89
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +60 -7
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -5
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/qdrant-client.ts +3 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +5 -9
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +46 -9
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +768 -33
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +163 -8
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +8 -35
- package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +92 -86
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +466 -115
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +42 -0
- package/src/memory/v2/prompts/consolidation.ts +14 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +307 -133
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +88 -34
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +20 -17
- package/src/memory/v2/sweep-job.ts +127 -102
- package/src/memory/v2/types.ts +16 -5
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +61 -12
- package/src/notifications/decision-engine.ts +46 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +20 -5
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +63 -8
- package/src/proactive-artifact/job.ts +20 -2
- package/src/proactive-artifact/message-copy.ts +18 -1
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/templates/SOUL.md +13 -28
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +304 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/guardian-reply-router.ts +0 -10
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pending-interactions.ts +19 -15
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +7 -21
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +373 -82
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-bash-routes.ts +2 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-item-routes.test.ts +3 -9
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +105 -404
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/skills/include-graph.ts +35 -13
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/memory/register.test.ts +10 -8
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +28 -5
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +19 -1
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -492
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -477
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for the v2 routing wired into `ConversationGraphMemory.prepareMemory`.
|
|
3
3
|
*
|
|
4
|
-
* The wiring layer at `conversation-graph-memory.ts` reads
|
|
5
|
-
* decide whether to swap v1's injection step
|
|
4
|
+
* The wiring layer at `conversation-graph-memory.ts` reads
|
|
5
|
+
* `config.memory.v2.enabled` to decide whether to swap v1's injection step
|
|
6
|
+
* for the v2 activation pipeline.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
* mocking `injection.js` itself would clobber that sibling test when both
|
|
14
|
-
* files run in the same `bun test` invocation, since `mock.module` is
|
|
15
|
-
* process-global. Avoiding the mock keeps the suite hermetic in either order.
|
|
8
|
+
* This file uses the *real* `injectMemoryV2Block` and stubs only the
|
|
9
|
+
* lower-level deps (Qdrant client, embedding backend) the way
|
|
10
|
+
* `memory/v2/__tests__/injection.test.ts` does — mocking `injection.js`
|
|
11
|
+
* itself would clobber that sibling test when both files run in the same
|
|
12
|
+
* `bun test` invocation, since `mock.module` is process-global. Avoiding
|
|
13
|
+
* the mock keeps the suite hermetic in either order.
|
|
16
14
|
*/
|
|
17
15
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
18
16
|
import { tmpdir } from "node:os";
|
|
@@ -20,7 +18,6 @@ import { join } from "node:path";
|
|
|
20
18
|
import { Database } from "bun:sqlite";
|
|
21
19
|
import {
|
|
22
20
|
afterAll,
|
|
23
|
-
afterEach,
|
|
24
21
|
beforeAll,
|
|
25
22
|
beforeEach,
|
|
26
23
|
describe,
|
|
@@ -98,9 +95,11 @@ class MockQdrantClient {
|
|
|
98
95
|
_name: string,
|
|
99
96
|
params: { using: string; limit: number; filter?: unknown },
|
|
100
97
|
) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
// The four-channel hybrid query fires body-dense, body-sparse,
|
|
99
|
+
// summary-dense, summary-sparse in order; both dense channels share
|
|
100
|
+
// the dense queue and both sparse channels share the sparse queue.
|
|
101
|
+
const channel = params.using.endsWith("sparse") ? "sparse" : "dense";
|
|
102
|
+
return qdrantState.queryResponses[channel].shift() ?? { points: [] };
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
|
|
@@ -170,14 +169,14 @@ import type { DrizzleDb } from "../../db-connection.js";
|
|
|
170
169
|
|
|
171
170
|
const { ConversationGraphMemory } =
|
|
172
171
|
await import("../conversation-graph-memory.js");
|
|
173
|
-
const { _setOverridesForTesting } =
|
|
174
|
-
await import("../../../config/assistant-feature-flags.js");
|
|
175
172
|
const { applyNestedDefaults } = await import("../../../config/loader.js");
|
|
176
173
|
const { getSqliteFrom } = await import("../../db-connection.js");
|
|
177
174
|
const { migrateActivationState } =
|
|
178
175
|
await import("../../migrations/232-activation-state.js");
|
|
179
176
|
const schema = await import("../../schema.js");
|
|
180
177
|
const { _resetMemoryV2QdrantForTests } = await import("../../v2/qdrant.js");
|
|
178
|
+
const { hydrate: hydrateActivationState } =
|
|
179
|
+
await import("../../v2/activation-store.js");
|
|
181
180
|
|
|
182
181
|
// The wiring layer calls `getDb()` to fetch the SQLite handle. We mock
|
|
183
182
|
// only that one export and spread the real module so unrelated callers
|
|
@@ -240,10 +239,21 @@ function makeMemory(): InstanceType<typeof ConversationGraphMemory> {
|
|
|
240
239
|
return m;
|
|
241
240
|
}
|
|
242
241
|
|
|
243
|
-
/** Stage one set of dense/sparse hits for each channel of
|
|
244
|
-
* pipeline (1 candidate query + 3 simBatch channels).
|
|
242
|
+
/** Stage one set of body and summary dense/sparse hits for each channel of
|
|
243
|
+
* the activation pipeline (1 candidate query + 3 simBatch channels). Each
|
|
244
|
+
* `hybridQueryConceptPages` call now fires four sub-queries (body-dense,
|
|
245
|
+
* body-sparse, summary-dense, summary-sparse) so we push four entries per
|
|
246
|
+
* channel iteration. Hits without `summary*Score` set produce empty point
|
|
247
|
+
* lists for the summary channels — fine for tests that only care about body
|
|
248
|
+
* scoring. */
|
|
245
249
|
function stageTurn(
|
|
246
|
-
hits: Array<{
|
|
250
|
+
hits: Array<{
|
|
251
|
+
slug: string;
|
|
252
|
+
denseScore?: number;
|
|
253
|
+
sparseScore?: number;
|
|
254
|
+
summaryDenseScore?: number;
|
|
255
|
+
summarySparseScore?: number;
|
|
256
|
+
}>,
|
|
247
257
|
): void {
|
|
248
258
|
for (let i = 0; i < 4; i++) {
|
|
249
259
|
qdrantState.queryResponses.dense.push({
|
|
@@ -256,6 +266,22 @@ function stageTurn(
|
|
|
256
266
|
.filter((h) => h.sparseScore !== undefined)
|
|
257
267
|
.map((h) => ({ score: h.sparseScore, payload: { slug: h.slug } })),
|
|
258
268
|
});
|
|
269
|
+
qdrantState.queryResponses.dense.push({
|
|
270
|
+
points: hits
|
|
271
|
+
.filter((h) => h.summaryDenseScore !== undefined)
|
|
272
|
+
.map((h) => ({
|
|
273
|
+
score: h.summaryDenseScore,
|
|
274
|
+
payload: { slug: h.slug },
|
|
275
|
+
})),
|
|
276
|
+
});
|
|
277
|
+
qdrantState.queryResponses.sparse.push({
|
|
278
|
+
points: hits
|
|
279
|
+
.filter((h) => h.summarySparseScore !== undefined)
|
|
280
|
+
.map((h) => ({
|
|
281
|
+
score: h.summarySparseScore,
|
|
282
|
+
payload: { slug: h.slug },
|
|
283
|
+
})),
|
|
284
|
+
});
|
|
259
285
|
}
|
|
260
286
|
}
|
|
261
287
|
|
|
@@ -270,39 +296,12 @@ beforeEach(() => {
|
|
|
270
296
|
_resetMemoryV2QdrantForTests();
|
|
271
297
|
});
|
|
272
298
|
|
|
273
|
-
afterEach(() => {
|
|
274
|
-
_setOverridesForTesting({});
|
|
275
|
-
});
|
|
276
|
-
|
|
277
299
|
// ---------------------------------------------------------------------------
|
|
278
300
|
// Tests
|
|
279
301
|
// ---------------------------------------------------------------------------
|
|
280
302
|
|
|
281
303
|
describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)", () => {
|
|
282
|
-
test("
|
|
283
|
-
_setOverridesForTesting({ "memory-v2-enabled": false });
|
|
284
|
-
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
285
|
-
|
|
286
|
-
const memory = makeMemory();
|
|
287
|
-
const config = makeConfig(true);
|
|
288
|
-
const messages = makeMessages();
|
|
289
|
-
|
|
290
|
-
const result = await memory.prepareMemory(
|
|
291
|
-
messages,
|
|
292
|
-
config,
|
|
293
|
-
new AbortController().signal,
|
|
294
|
-
noopEvent,
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
expect(result.mode).toBe("per-turn");
|
|
298
|
-
expect(result.injectedBlockText).toBeNull();
|
|
299
|
-
// No v2 block prepended — the v1 retriever returned zero nodes so the
|
|
300
|
-
// user message is exactly the input.
|
|
301
|
-
expect(result.runMessages).toEqual(messages);
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
test("flag on + config off → v2 not run, messages unchanged", async () => {
|
|
305
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
304
|
+
test("config off → v2 not run, messages unchanged", async () => {
|
|
306
305
|
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
307
306
|
|
|
308
307
|
const memory = makeMemory();
|
|
@@ -321,8 +320,7 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)",
|
|
|
321
320
|
expect(result.runMessages).toEqual(messages);
|
|
322
321
|
});
|
|
323
322
|
|
|
324
|
-
test("
|
|
325
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
323
|
+
test("config on → v2 block prepended, mode is per-turn", async () => {
|
|
326
324
|
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
327
325
|
|
|
328
326
|
const memory = makeMemory();
|
|
@@ -339,7 +337,9 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)",
|
|
|
339
337
|
expect(result.mode).toBe("per-turn");
|
|
340
338
|
expect(result.injectedBlockText).not.toBeNull();
|
|
341
339
|
expect(result.injectedBlockText).not.toContain("<memory>");
|
|
342
|
-
expect(result.injectedBlockText).toContain(
|
|
340
|
+
expect(result.injectedBlockText).toContain(
|
|
341
|
+
"# memory/concepts/alice-vscode.md",
|
|
342
|
+
);
|
|
343
343
|
|
|
344
344
|
// The leading content block on the user message is the v2 block,
|
|
345
345
|
// wrapped exactly once.
|
|
@@ -361,7 +361,6 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)",
|
|
|
361
361
|
// Regression for the double-wrap bug: v2 cached `lastInjectedBlock`
|
|
362
362
|
// already wrapped, then `reinjectCachedMemory` re-wrapped via
|
|
363
363
|
// `injectTextBlock`, producing `<memory>\n<memory>\n...\n</memory>\n</memory>`.
|
|
364
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
365
364
|
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
366
365
|
|
|
367
366
|
const memory = makeMemory();
|
|
@@ -388,11 +387,10 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)",
|
|
|
388
387
|
expect(firstBlock.text.endsWith("\n</memory>")).toBe(true);
|
|
389
388
|
expect(firstBlock.text.match(/<memory>/g)?.length).toBe(1);
|
|
390
389
|
expect(firstBlock.text.match(/<\/memory>/g)?.length).toBe(1);
|
|
391
|
-
expect(firstBlock.text).toContain("
|
|
390
|
+
expect(firstBlock.text).toContain("# memory/concepts/alice-vscode.md");
|
|
392
391
|
});
|
|
393
392
|
|
|
394
|
-
test("
|
|
395
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
393
|
+
test("config on with empty Qdrant hits → no v2 block, v1 fallback skipped", async () => {
|
|
396
394
|
// No `stageTurn` call — every channel returns `{ points: [] }` so the
|
|
397
395
|
// candidate set is empty and `injectMemoryV2Block` returns block=null.
|
|
398
396
|
const memory = makeMemory();
|
|
@@ -412,8 +410,7 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)",
|
|
|
412
410
|
});
|
|
413
411
|
|
|
414
412
|
describe("ConversationGraphMemory.prepareMemory — v2 routing (context-load path)", () => {
|
|
415
|
-
test("
|
|
416
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
413
|
+
test("config on → v2 fires with mode=context-load", async () => {
|
|
417
414
|
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
418
415
|
|
|
419
416
|
// Fresh memory → initialized=false → runContextLoad branch.
|
|
@@ -430,7 +427,9 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (context-load pat
|
|
|
430
427
|
|
|
431
428
|
expect(result.mode).toBe("context-load");
|
|
432
429
|
expect(result.injectedBlockText).not.toBeNull();
|
|
433
|
-
expect(result.injectedBlockText).toContain(
|
|
430
|
+
expect(result.injectedBlockText).toContain(
|
|
431
|
+
"# memory/concepts/alice-vscode.md",
|
|
432
|
+
);
|
|
434
433
|
// injectedBlockText is the unwrapped inner content; the wrapper is
|
|
435
434
|
// applied at injection time on the run message.
|
|
436
435
|
expect(result.injectedBlockText).not.toContain("<memory>");
|
|
@@ -443,12 +442,11 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (context-load pat
|
|
|
443
442
|
expect(loadContextMemoryMock).not.toHaveBeenCalled();
|
|
444
443
|
});
|
|
445
444
|
|
|
446
|
-
test("
|
|
447
|
-
_setOverridesForTesting({ "memory-v2-enabled": false });
|
|
445
|
+
test("config off → v2 not run on first turn either", async () => {
|
|
448
446
|
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
449
447
|
|
|
450
448
|
const memory = new ConversationGraphMemory("conv-test-cl-off");
|
|
451
|
-
const config = makeConfig(
|
|
449
|
+
const config = makeConfig(false);
|
|
452
450
|
const messages = makeMessages("first message of the conversation here");
|
|
453
451
|
|
|
454
452
|
const result = await memory.prepareMemory(
|
|
@@ -462,3 +460,48 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (context-load pat
|
|
|
462
460
|
expect(result.injectedBlockText).toBeNull();
|
|
463
461
|
});
|
|
464
462
|
});
|
|
463
|
+
|
|
464
|
+
describe("ConversationGraphMemory.onCompacted — v2 activation eviction", () => {
|
|
465
|
+
test("clears everInjected so a previously-injected slug can re-attach", async () => {
|
|
466
|
+
// Without this wiring, `selectInjections` keeps subtracting the slug from
|
|
467
|
+
// every per-turn delta even though compaction discarded the cached
|
|
468
|
+
// `<memory>` attachment that previously made it visible.
|
|
469
|
+
const conversationId = "conv-test-evict";
|
|
470
|
+
const memory = new ConversationGraphMemory(conversationId);
|
|
471
|
+
const config = makeConfig(true);
|
|
472
|
+
|
|
473
|
+
// Turn 1 — context-load fires (initialized=false), injecting alice-vscode.
|
|
474
|
+
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
475
|
+
const initial = await memory.prepareMemory(
|
|
476
|
+
makeMessages("Tell me about Alice's editor preferences"),
|
|
477
|
+
config,
|
|
478
|
+
new AbortController().signal,
|
|
479
|
+
noopEvent,
|
|
480
|
+
);
|
|
481
|
+
expect(initial.injectedBlockText).toContain(
|
|
482
|
+
"# memory/concepts/alice-vscode.md",
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
const before = await hydrateActivationState(testDbHandle!, conversationId);
|
|
486
|
+
expect(before?.everInjected.map((e) => e.slug)).toContain("alice-vscode");
|
|
487
|
+
|
|
488
|
+
await memory.onCompacted(1);
|
|
489
|
+
|
|
490
|
+
const after = await hydrateActivationState(testDbHandle!, conversationId);
|
|
491
|
+
expect(after?.everInjected).toEqual([]);
|
|
492
|
+
|
|
493
|
+
// Turn 2 — same Qdrant relevance. With everInjected cleared the slug
|
|
494
|
+
// should appear again in the injection block (re-attached on the new
|
|
495
|
+
// user message after compaction).
|
|
496
|
+
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
497
|
+
const next = await memory.prepareMemory(
|
|
498
|
+
makeMessages("And what about Alice's editor again?"),
|
|
499
|
+
config,
|
|
500
|
+
new AbortController().signal,
|
|
501
|
+
noopEvent,
|
|
502
|
+
);
|
|
503
|
+
expect(next.injectedBlockText).toContain(
|
|
504
|
+
"# memory/concepts/alice-vscode.md",
|
|
505
|
+
);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tests for `handleRemember`
|
|
2
|
+
* Tests for `handleRemember` routing between v1 (PKB) and v2 (memory/).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* and NO PKB re-index job is enqueued.
|
|
7
|
-
* - Flag off → existing PKB path is unchanged (writes to `pkb/buffer.md`
|
|
8
|
-
* + `pkb/archive/<today>.md`, both files are re-indexed).
|
|
9
|
-
* - Archive filename uses today's local date.
|
|
4
|
+
* Routing follows `config.memory.v2.enabled`: when true, writes go to
|
|
5
|
+
* memory/; otherwise they fall back to v1 PKB.
|
|
10
6
|
*/
|
|
11
7
|
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
12
8
|
import { tmpdir } from "node:os";
|
|
13
9
|
import { join } from "node:path";
|
|
14
10
|
import {
|
|
15
11
|
afterAll,
|
|
16
|
-
afterEach,
|
|
17
12
|
beforeAll,
|
|
18
13
|
beforeEach,
|
|
19
14
|
describe,
|
|
@@ -62,11 +57,13 @@ afterAll(() => {
|
|
|
62
57
|
// Imports are deferred to after the env var is set so any internal use of
|
|
63
58
|
// `getWorkspaceDir()` resolves to the tmpdir.
|
|
64
59
|
const { handleRemember } = await import("../tool-handlers.js");
|
|
65
|
-
const { _setOverridesForTesting } =
|
|
66
|
-
await import("../../../config/assistant-feature-flags.js");
|
|
67
60
|
const { applyNestedDefaults } = await import("../../../config/loader.js");
|
|
68
61
|
|
|
69
62
|
const CONFIG = applyNestedDefaults({});
|
|
63
|
+
const CONFIG_V2_OFF = {
|
|
64
|
+
...CONFIG,
|
|
65
|
+
memory: { ...CONFIG.memory, v2: { ...CONFIG.memory.v2, enabled: false } },
|
|
66
|
+
};
|
|
70
67
|
|
|
71
68
|
beforeEach(() => {
|
|
72
69
|
enqueueCalls.length = 0;
|
|
@@ -76,10 +73,6 @@ beforeEach(() => {
|
|
|
76
73
|
rmSync(join(tmpWorkspace, "memory"), { recursive: true, force: true });
|
|
77
74
|
});
|
|
78
75
|
|
|
79
|
-
afterEach(() => {
|
|
80
|
-
_setOverridesForTesting({});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
76
|
function todaysArchiveBasename(now: Date = new Date()): string {
|
|
84
77
|
const yyyy = now.getFullYear();
|
|
85
78
|
const mm = String(now.getMonth() + 1).padStart(2, "0");
|
|
@@ -87,11 +80,7 @@ function todaysArchiveBasename(now: Date = new Date()): string {
|
|
|
87
80
|
return `${yyyy}-${mm}-${dd}.md`;
|
|
88
81
|
}
|
|
89
82
|
|
|
90
|
-
describe("handleRemember — memory
|
|
91
|
-
beforeEach(() => {
|
|
92
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
93
|
-
});
|
|
94
|
-
|
|
83
|
+
describe("handleRemember — memory.v2.enabled on", () => {
|
|
95
84
|
test("writes to memory/buffer.md and memory/archive/<today>.md", () => {
|
|
96
85
|
const result = handleRemember(
|
|
97
86
|
{ content: "Alice prefers VS Code over Vim" },
|
|
@@ -175,17 +164,13 @@ describe("handleRemember — memory-v2 flag on", () => {
|
|
|
175
164
|
});
|
|
176
165
|
});
|
|
177
166
|
|
|
178
|
-
describe("handleRemember — memory
|
|
179
|
-
beforeEach(() => {
|
|
180
|
-
_setOverridesForTesting({ "memory-v2-enabled": false });
|
|
181
|
-
});
|
|
182
|
-
|
|
167
|
+
describe("handleRemember — memory.v2.enabled off (v1 PKB path)", () => {
|
|
183
168
|
test("writes to pkb/buffer.md and pkb/archive/<today>.md", () => {
|
|
184
169
|
const result = handleRemember(
|
|
185
170
|
{ content: "v1 path still works" },
|
|
186
171
|
"conv-v1-1",
|
|
187
172
|
"default",
|
|
188
|
-
|
|
173
|
+
CONFIG_V2_OFF,
|
|
189
174
|
);
|
|
190
175
|
|
|
191
176
|
expect(result.success).toBe(true);
|
|
@@ -206,7 +191,7 @@ describe("handleRemember — memory-v2 flag off (v1 PKB path)", () => {
|
|
|
206
191
|
{ content: "index me" },
|
|
207
192
|
"conv-v1-2",
|
|
208
193
|
"default",
|
|
209
|
-
|
|
194
|
+
CONFIG_V2_OFF,
|
|
210
195
|
);
|
|
211
196
|
|
|
212
197
|
expect(result.success).toBe(true);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
let flagEnabled = false;
|
|
4
|
+
|
|
5
|
+
mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
6
|
+
isAssistantFeatureFlagEnabled: (_key: string, _config: unknown) =>
|
|
7
|
+
flagEnabled,
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
import { getRememberDescription } from "../tools.js";
|
|
11
|
+
|
|
12
|
+
const stubConfig = {} as unknown as Parameters<
|
|
13
|
+
typeof getRememberDescription
|
|
14
|
+
>[0];
|
|
15
|
+
|
|
16
|
+
describe("getRememberDescription", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
flagEnabled = false;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("flag off — returns the default high-pressure description", () => {
|
|
22
|
+
const desc = getRememberDescription(stubConfig);
|
|
23
|
+
expect(desc).toContain("**CRITICAL:**");
|
|
24
|
+
expect(desc).toContain("most frequently used tool");
|
|
25
|
+
expect(desc).toContain("almost every turn");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("flag on — returns the relaxed judgment-framing description", () => {
|
|
29
|
+
flagEnabled = true;
|
|
30
|
+
const desc = getRememberDescription(stubConfig);
|
|
31
|
+
expect(desc).not.toContain("**CRITICAL:**");
|
|
32
|
+
expect(desc).not.toContain("almost every turn");
|
|
33
|
+
expect(desc).toContain("a retrospective pass");
|
|
34
|
+
expect(desc).toContain("Use judgment");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("the two variants differ", () => {
|
|
38
|
+
flagEnabled = false;
|
|
39
|
+
const off = getRememberDescription(stubConfig);
|
|
40
|
+
flagEnabled = true;
|
|
41
|
+
const on = getRememberDescription(stubConfig);
|
|
42
|
+
expect(off).not.toBe(on);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("corrections-are-priority language is preserved in BOTH variants", () => {
|
|
46
|
+
flagEnabled = false;
|
|
47
|
+
expect(getRememberDescription(stubConfig)).toMatch(
|
|
48
|
+
/Corrections are.*highest priority/i,
|
|
49
|
+
);
|
|
50
|
+
flagEnabled = true;
|
|
51
|
+
expect(getRememberDescription(stubConfig)).toMatch(
|
|
52
|
+
/Corrections are.*highest priority/i,
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
|
|
9
9
|
import { and, desc, eq, inArray, ne, notInArray } from "drizzle-orm";
|
|
10
|
+
import { z } from "zod";
|
|
10
11
|
|
|
11
|
-
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
12
12
|
import type { AssistantConfig } from "../../config/types.js";
|
|
13
13
|
import { estimateTextTokens } from "../../context/token-estimator.js";
|
|
14
14
|
import type { ServerMessage } from "../../daemon/message-protocol.js";
|
|
@@ -20,9 +20,16 @@ import type {
|
|
|
20
20
|
import { getLogger } from "../../util/logger.js";
|
|
21
21
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
22
22
|
import { getDb } from "../db-connection.js";
|
|
23
|
+
import { embedWithRetry } from "../embed.js";
|
|
24
|
+
import { generateSparseEmbedding } from "../embedding-backend.js";
|
|
23
25
|
import type { QdrantSparseVector } from "../qdrant-client.js";
|
|
24
26
|
import { memorySummaries } from "../schema.js";
|
|
25
27
|
import { conversations } from "../schema/conversations.js";
|
|
28
|
+
import {
|
|
29
|
+
evictCompactedTurns as evictCompactedTurnsV2,
|
|
30
|
+
hydrate as hydrateV2State,
|
|
31
|
+
save as saveV2State,
|
|
32
|
+
} from "../v2/activation-store.js";
|
|
26
33
|
import {
|
|
27
34
|
injectMemoryV2Block,
|
|
28
35
|
type InjectMemoryV2Mode,
|
|
@@ -206,11 +213,33 @@ export class ConversationGraphMemory {
|
|
|
206
213
|
* Notify that context compaction just happened.
|
|
207
214
|
* On the next turn, we'll re-run full context load.
|
|
208
215
|
*/
|
|
209
|
-
onCompacted(compactedMessageCount: number): void {
|
|
216
|
+
async onCompacted(compactedMessageCount: number): Promise<void> {
|
|
210
217
|
// Evict everything — compaction summarized all prior turns.
|
|
211
218
|
// The tracker can't know exactly which turns were compacted,
|
|
212
219
|
// so we conservatively clear everything and reload.
|
|
213
|
-
this.tracker.
|
|
220
|
+
const upToTurn = this.tracker.getTurn();
|
|
221
|
+
this.tracker.evictCompactedTurns(upToTurn);
|
|
222
|
+
|
|
223
|
+
// Mirror the eviction on the v2 activation row: the cached `<memory>`
|
|
224
|
+
// attachments those slugs lived on are gone, but `everInjected` would
|
|
225
|
+
// otherwise keep them deduped from per-turn deltas forever.
|
|
226
|
+
try {
|
|
227
|
+
const db = getDb();
|
|
228
|
+
const state = await hydrateV2State(db, this.conversationId);
|
|
229
|
+
if (state) {
|
|
230
|
+
await saveV2State(
|
|
231
|
+
db,
|
|
232
|
+
this.conversationId,
|
|
233
|
+
evictCompactedTurnsV2(state, upToTurn),
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
} catch (err) {
|
|
237
|
+
log.warn(
|
|
238
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
239
|
+
"Failed to evict v2 activation state on compaction (non-fatal)",
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
214
243
|
this.needsReload = true;
|
|
215
244
|
log.info(
|
|
216
245
|
{ compactedMessageCount },
|
|
@@ -362,8 +391,15 @@ export class ConversationGraphMemory {
|
|
|
362
391
|
|
|
363
392
|
return await this.runPerTurn(messages, config, abortSignal);
|
|
364
393
|
} catch (err) {
|
|
394
|
+
const errCode =
|
|
395
|
+
err instanceof z.ZodError ? err.issues[0]?.code : undefined;
|
|
365
396
|
log.warn(
|
|
366
|
-
{
|
|
397
|
+
{
|
|
398
|
+
err: err instanceof Error ? err.message : String(err),
|
|
399
|
+
conversationId: this.conversationId,
|
|
400
|
+
turn: this.tracker.getTurn(),
|
|
401
|
+
errCode,
|
|
402
|
+
},
|
|
367
403
|
"Memory retrieval failed (non-fatal)",
|
|
368
404
|
);
|
|
369
405
|
return noopResult;
|
|
@@ -396,10 +432,19 @@ export class ConversationGraphMemory {
|
|
|
396
432
|
"",
|
|
397
433
|
signal,
|
|
398
434
|
);
|
|
399
|
-
this.initialized = true;
|
|
400
|
-
this.needsReload = false;
|
|
401
435
|
|
|
402
436
|
if (v2.routed) {
|
|
437
|
+
// Surface a user-query embedding so PKB hint search still runs on v2
|
|
438
|
+
// turns. v1's `loadContextMemory` produced these as a side effect of
|
|
439
|
+
// hybrid retrieval; the v2 path skips that retrieval, so embed
|
|
440
|
+
// explicitly here.
|
|
441
|
+
const userQueryEmbed = await this.computeQueryVectors(
|
|
442
|
+
rawUserText ?? userQuery ?? "",
|
|
443
|
+
config,
|
|
444
|
+
signal,
|
|
445
|
+
);
|
|
446
|
+
this.initialized = true;
|
|
447
|
+
this.needsReload = false;
|
|
403
448
|
this.lastInjectedBlock = v2.injectedBlockText;
|
|
404
449
|
this.lastInjectedNodeIds = [];
|
|
405
450
|
this.lastInjectedImages = new Map();
|
|
@@ -412,6 +457,8 @@ export class ConversationGraphMemory {
|
|
|
412
457
|
mode: "context-load" as const,
|
|
413
458
|
injectedBlockText: v2.injectedBlockText,
|
|
414
459
|
metrics: null,
|
|
460
|
+
userQueryVector: userQueryEmbed.dense,
|
|
461
|
+
userQuerySparseVector: userQueryEmbed.sparse,
|
|
415
462
|
};
|
|
416
463
|
}
|
|
417
464
|
|
|
@@ -423,6 +470,12 @@ export class ConversationGraphMemory {
|
|
|
423
470
|
config,
|
|
424
471
|
signal,
|
|
425
472
|
});
|
|
473
|
+
// Set initialized only after v1 retrieval succeeds. If `loadContextMemory`
|
|
474
|
+
// throws (transient DB/Qdrant failure), `prepareMemory` catches and
|
|
475
|
+
// returns noop, but we want the next turn to retry the bootstrap path
|
|
476
|
+
// rather than be stuck in per-turn mode.
|
|
477
|
+
this.initialized = true;
|
|
478
|
+
this.needsReload = false;
|
|
426
479
|
|
|
427
480
|
if (result.nodes.length === 0) {
|
|
428
481
|
this.lastInjectedBlock = null;
|
|
@@ -543,6 +596,14 @@ export class ConversationGraphMemory {
|
|
|
543
596
|
signal,
|
|
544
597
|
);
|
|
545
598
|
if (v2.routed) {
|
|
599
|
+
// Surface a per-turn query embedding so PKB hint search still runs
|
|
600
|
+
// on v2 turns. v1's `retrieveForTurn` produced these as a side effect;
|
|
601
|
+
// the v2 path skips that retrieval, so embed explicitly here.
|
|
602
|
+
const perTurnEmbed = await this.computeQueryVectors(
|
|
603
|
+
userLast,
|
|
604
|
+
config,
|
|
605
|
+
signal,
|
|
606
|
+
);
|
|
546
607
|
this.lastInjectedBlock = v2.injectedBlockText;
|
|
547
608
|
this.lastInjectedNodeIds = [];
|
|
548
609
|
this.lastInjectedImages = new Map();
|
|
@@ -555,6 +616,8 @@ export class ConversationGraphMemory {
|
|
|
555
616
|
mode: "per-turn" as const,
|
|
556
617
|
injectedBlockText: v2.injectedBlockText,
|
|
557
618
|
metrics: null,
|
|
619
|
+
queryVector: perTurnEmbed.dense,
|
|
620
|
+
sparseVector: perTurnEmbed.sparse,
|
|
558
621
|
};
|
|
559
622
|
}
|
|
560
623
|
|
|
@@ -627,8 +690,37 @@ export class ConversationGraphMemory {
|
|
|
627
690
|
}
|
|
628
691
|
|
|
629
692
|
/**
|
|
630
|
-
*
|
|
631
|
-
*
|
|
693
|
+
* Embed a query string for PKB hint search on v2 turns. v1 retrieval
|
|
694
|
+
* produced these vectors as a side effect; on v2 we skip retrieval, so
|
|
695
|
+
* the agent loop loses the dense/sparse pair it needs to drive
|
|
696
|
+
* `buildPkbReminderWithHints`. Failures here degrade PKB hints to the
|
|
697
|
+
* static fallback rather than blocking the turn.
|
|
698
|
+
*/
|
|
699
|
+
private async computeQueryVectors(
|
|
700
|
+
text: string,
|
|
701
|
+
config: AssistantConfig,
|
|
702
|
+
signal: AbortSignal,
|
|
703
|
+
): Promise<{ dense?: number[]; sparse?: QdrantSparseVector }> {
|
|
704
|
+
const trimmed = text.trim();
|
|
705
|
+
if (trimmed.length === 0) return {};
|
|
706
|
+
let dense: number[] | undefined;
|
|
707
|
+
try {
|
|
708
|
+
const result = await embedWithRetry(config, [trimmed], { signal });
|
|
709
|
+
dense = result.vectors[0];
|
|
710
|
+
} catch (err) {
|
|
711
|
+
log.warn(
|
|
712
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
713
|
+
"Failed to embed query for PKB hints on v2 path",
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
const sparseRaw = generateSparseEmbedding(trimmed);
|
|
717
|
+
const sparse = sparseRaw.indices.length > 0 ? sparseRaw : undefined;
|
|
718
|
+
return { dense, sparse };
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Run the v2 activation pipeline when the workspace config
|
|
723
|
+
* (`memory.v2.enabled`) is on.
|
|
632
724
|
*
|
|
633
725
|
* The two outcomes the caller distinguishes via `routed`:
|
|
634
726
|
* - `routed: false` — v2 disabled; caller falls through to the legacy v1
|
|
@@ -650,10 +742,7 @@ export class ConversationGraphMemory {
|
|
|
650
742
|
runMessages: Message[];
|
|
651
743
|
injectedBlockText: string | null;
|
|
652
744
|
}> {
|
|
653
|
-
if (
|
|
654
|
-
!isAssistantFeatureFlagEnabled("memory-v2-enabled", config) ||
|
|
655
|
-
!config.memory.v2.enabled
|
|
656
|
-
) {
|
|
745
|
+
if (!config.memory.v2.enabled) {
|
|
657
746
|
return { routed: false, runMessages: messages, injectedBlockText: null };
|
|
658
747
|
}
|
|
659
748
|
|
|
@@ -693,7 +782,11 @@ export class ConversationGraphMemory {
|
|
|
693
782
|
* Count the leading content blocks on a user message that were added by
|
|
694
783
|
* `injectMemoryBlock`. Memory-injected images use a 3-block pattern
|
|
695
784
|
* (opening `<memory_image>` text + image + closing `</memory_image>` text),
|
|
696
|
-
* followed by a `<memory>…</memory>` text block (legacy `<memory __injected>` is also accepted).
|
|
785
|
+
* followed by a `<memory>…</memory>` text block (legacy `<memory __injected>` is also accepted).
|
|
786
|
+
* The bare `<memory>` form is matched only when the block also ends with
|
|
787
|
+
* `\n</memory>`, so user-authored content that happens to begin with
|
|
788
|
+
* `<memory>` (for example, a message discussing the XML-like markup) is not
|
|
789
|
+
* mistaken for an injected prefix and stripped on re-injection. A legacy
|
|
697
790
|
* 2-block image pattern (no closing tag) is also accepted for backward
|
|
698
791
|
* compatibility. The injection prefix is always contiguous at the start,
|
|
699
792
|
* so we stop at the first non-memory block.
|
|
@@ -706,7 +799,8 @@ export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
|
|
|
706
799
|
const block = content[firstNonMemory];
|
|
707
800
|
if (
|
|
708
801
|
block.type === "text" &&
|
|
709
|
-
(block.text.startsWith("<memory>\n")
|
|
802
|
+
((block.text.startsWith("<memory>\n") &&
|
|
803
|
+
block.text.endsWith("\n</memory>")) ||
|
|
710
804
|
block.text.startsWith("<memory __injected>\n"))
|
|
711
805
|
) {
|
|
712
806
|
firstNonMemory++;
|
|
@@ -723,8 +723,12 @@ export function parseExtractionResponse(
|
|
|
723
723
|
|
|
724
724
|
// Auto-create event trigger when event_date is set but LLM didn't include one,
|
|
725
725
|
// or replace a malformed event trigger (event_date unset) with a valid one.
|
|
726
|
+
// Only auto-create for future events — past-dated memories (historical
|
|
727
|
+
// milestones, dated events that already happened) shouldn't generate
|
|
728
|
+
// ramp/follow-up reminders.
|
|
726
729
|
if (
|
|
727
730
|
node.eventDate != null &&
|
|
731
|
+
node.eventDate > now &&
|
|
728
732
|
(!Array.isArray(raw.triggers) ||
|
|
729
733
|
!raw.triggers.some((t) => t.type === "event" && t.event_date != null))
|
|
730
734
|
) {
|