@vellumai/assistant 0.8.0 → 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/Dockerfile +5 -4
- package/README.md +2 -2
- 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 +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -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__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- 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-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 +35 -7
- 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 +77 -23
- 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-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-agent-loop-overflow.test.ts +1 -0
- 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 +1 -0
- 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 +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- 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 +23 -3
- 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 +0 -8
- 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__/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 +15 -0
- 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-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- 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 +118 -0
- 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-routes-managed-proxy.test.ts +12 -4
- 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-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- 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__/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__/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 +53 -20
- 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-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/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- 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 +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- 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-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 +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- 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 +32 -1
- 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 +79 -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 +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- 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 +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- 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/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 +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- 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 +9 -1
- 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/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- 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 +148 -127
- 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 +55 -6
- 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/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__/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 +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- 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__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- 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/published-pages-store.ts +16 -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 +1 -4
- 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 +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- 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 +628 -10
- 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 +72 -0
- 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 +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- 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 +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- 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 +15 -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/ipc-risk-types.ts +2 -0
- 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 +19 -3
- 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 +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- 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/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 +303 -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/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/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 +4 -4
- 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 +0 -18
- 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/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 +334 -86
- 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-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/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 -4
- 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-v2-routes.ts +13 -398
- 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/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/memory/register.test.ts +3 -3
- 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 +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- 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/069-seed-onboarding-threads.ts +8 -2
- 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 +22 -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 -498
- 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 -947
- 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 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -39,11 +39,13 @@ interface UpsertCall {
|
|
|
39
39
|
dense: number[];
|
|
40
40
|
sparse: { indices: number[]; values: number[] };
|
|
41
41
|
updatedAt: number;
|
|
42
|
+
kind?: string;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
interface PruneCall {
|
|
45
46
|
prefix: string;
|
|
46
47
|
activeSuffixes: readonly string[];
|
|
48
|
+
options?: { kind?: string };
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
interface TestState {
|
|
@@ -118,8 +120,9 @@ mock.module("../qdrant.js", () => ({
|
|
|
118
120
|
pruneSlugsWithPrefixExcept: async (
|
|
119
121
|
prefix: string,
|
|
120
122
|
activeSuffixes: readonly string[],
|
|
123
|
+
options?: { kind?: string },
|
|
121
124
|
) => {
|
|
122
|
-
state.pruneCalls.push({ prefix, activeSuffixes });
|
|
125
|
+
state.pruneCalls.push({ prefix, activeSuffixes, options });
|
|
123
126
|
},
|
|
124
127
|
}));
|
|
125
128
|
|
|
@@ -131,8 +134,12 @@ mock.module("../../../skills/catalog-cache.js", () => ({
|
|
|
131
134
|
}));
|
|
132
135
|
|
|
133
136
|
// Imported AFTER all mocks are wired so the module under test sees the stubs.
|
|
134
|
-
const {
|
|
135
|
-
|
|
137
|
+
const {
|
|
138
|
+
seedV2SkillEntries,
|
|
139
|
+
getSkillCapability,
|
|
140
|
+
listSkillEntries,
|
|
141
|
+
_resetSkillStoreForTests,
|
|
142
|
+
} = await import("../skill-store.js");
|
|
136
143
|
|
|
137
144
|
// ---------------------------------------------------------------------------
|
|
138
145
|
// Helpers
|
|
@@ -467,3 +474,51 @@ describe("getSkillCapability", () => {
|
|
|
467
474
|
expect(getSkillCapability("does-not-exist")).toBeNull();
|
|
468
475
|
});
|
|
469
476
|
});
|
|
477
|
+
|
|
478
|
+
describe("listSkillEntries", () => {
|
|
479
|
+
test("returns [] when the cache is empty (pre-seed)", () => {
|
|
480
|
+
expect(listSkillEntries()).toEqual([]);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
test("returns entries sorted by id after seeding", async () => {
|
|
484
|
+
// Insert in non-sorted order to prove the sort happens on read.
|
|
485
|
+
const skillB = makeSummary({ id: "example-skill-b" });
|
|
486
|
+
const skillA = makeSummary({ id: "example-skill-a" });
|
|
487
|
+
state.catalog = [skillB, skillA];
|
|
488
|
+
state.resolved = [
|
|
489
|
+
{ summary: skillB, state: "enabled" },
|
|
490
|
+
{ summary: skillA, state: "enabled" },
|
|
491
|
+
];
|
|
492
|
+
state.embedReturn = [
|
|
493
|
+
[0.1, 0.2, 0.3],
|
|
494
|
+
[0.4, 0.5, 0.6],
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
await seedV2SkillEntries();
|
|
498
|
+
|
|
499
|
+
const list = listSkillEntries();
|
|
500
|
+
expect(list).toHaveLength(2);
|
|
501
|
+
expect(list.map((e) => e.id)).toEqual([
|
|
502
|
+
"example-skill-a",
|
|
503
|
+
"example-skill-b",
|
|
504
|
+
]);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test("mutating the returned array does not affect subsequent calls", async () => {
|
|
508
|
+
const skillA = makeSummary({ id: "example-skill-a" });
|
|
509
|
+
state.catalog = [skillA];
|
|
510
|
+
state.resolved = [{ summary: skillA, state: "enabled" }];
|
|
511
|
+
state.embedReturn = [[0.1, 0.2, 0.3]];
|
|
512
|
+
|
|
513
|
+
await seedV2SkillEntries();
|
|
514
|
+
|
|
515
|
+
const first = listSkillEntries();
|
|
516
|
+
expect(first).toHaveLength(1);
|
|
517
|
+
first.length = 0;
|
|
518
|
+
first.push({ id: "injected", content: "junk" });
|
|
519
|
+
|
|
520
|
+
const second = listSkillEntries();
|
|
521
|
+
expect(second).toHaveLength(1);
|
|
522
|
+
expect(second[0].id).toBe("example-skill-a");
|
|
523
|
+
});
|
|
524
|
+
});
|
|
@@ -45,7 +45,7 @@ mock.module("../../../config/loader.js", () => ({
|
|
|
45
45
|
setNestedValue: () => {},
|
|
46
46
|
}));
|
|
47
47
|
|
|
48
|
-
const { readMemoryV2StaticContent,
|
|
48
|
+
const { readMemoryV2StaticContent, shouldExposePersonalMemory } =
|
|
49
49
|
await import("../static-context.js");
|
|
50
50
|
|
|
51
51
|
const MEMORY_FILES = [
|
|
@@ -140,21 +140,10 @@ describe("readMemoryV2StaticContent", () => {
|
|
|
140
140
|
});
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
describe("
|
|
144
|
-
test("blocks all turns until the cadence gate fires", () => {
|
|
145
|
-
expect(
|
|
146
|
-
shouldLoadMemoryV2Static({
|
|
147
|
-
shouldInjectNowAndPkb: false,
|
|
148
|
-
sourceChannel: "vellum",
|
|
149
|
-
isTrustedActor: true,
|
|
150
|
-
}),
|
|
151
|
-
).toBe(false);
|
|
152
|
-
});
|
|
153
|
-
|
|
143
|
+
describe("shouldExposePersonalMemory", () => {
|
|
154
144
|
test("allows guardian-trusted local conversations", () => {
|
|
155
145
|
expect(
|
|
156
|
-
|
|
157
|
-
shouldInjectNowAndPkb: true,
|
|
146
|
+
shouldExposePersonalMemory({
|
|
158
147
|
sourceChannel: "vellum",
|
|
159
148
|
isTrustedActor: true,
|
|
160
149
|
}),
|
|
@@ -163,8 +152,7 @@ describe("shouldLoadMemoryV2Static", () => {
|
|
|
163
152
|
|
|
164
153
|
test("allows local-channel conversations even when trust class is unknown (analyze runs, dev)", () => {
|
|
165
154
|
expect(
|
|
166
|
-
|
|
167
|
-
shouldInjectNowAndPkb: true,
|
|
155
|
+
shouldExposePersonalMemory({
|
|
168
156
|
sourceChannel: "vellum",
|
|
169
157
|
isTrustedActor: false,
|
|
170
158
|
}),
|
|
@@ -173,8 +161,7 @@ describe("shouldLoadMemoryV2Static", () => {
|
|
|
173
161
|
|
|
174
162
|
test("allows turns with no trust context (work-item task runs, internal background)", () => {
|
|
175
163
|
expect(
|
|
176
|
-
|
|
177
|
-
shouldInjectNowAndPkb: true,
|
|
164
|
+
shouldExposePersonalMemory({
|
|
178
165
|
sourceChannel: undefined,
|
|
179
166
|
isTrustedActor: false,
|
|
180
167
|
}),
|
|
@@ -192,8 +179,7 @@ describe("shouldLoadMemoryV2Static", () => {
|
|
|
192
179
|
test("allows guardian-trusted remote channels (user's own phone/Slack)", () => {
|
|
193
180
|
for (const channel of REMOTE_CHANNELS) {
|
|
194
181
|
expect(
|
|
195
|
-
|
|
196
|
-
shouldInjectNowAndPkb: true,
|
|
182
|
+
shouldExposePersonalMemory({
|
|
197
183
|
sourceChannel: channel,
|
|
198
184
|
isTrustedActor: true,
|
|
199
185
|
}),
|
|
@@ -204,8 +190,7 @@ describe("shouldLoadMemoryV2Static", () => {
|
|
|
204
190
|
test("blocks non-guardian remote-channel actors (the leak this gate exists to prevent)", () => {
|
|
205
191
|
for (const channel of REMOTE_CHANNELS) {
|
|
206
192
|
expect(
|
|
207
|
-
|
|
208
|
-
shouldInjectNowAndPkb: true,
|
|
193
|
+
shouldExposePersonalMemory({
|
|
209
194
|
sourceChannel: channel,
|
|
210
195
|
isTrustedActor: false,
|
|
211
196
|
}),
|
|
@@ -62,6 +62,23 @@ mock.module("../../../providers/provider-send-message.js", () => ({
|
|
|
62
62
|
response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
|
|
63
63
|
}));
|
|
64
64
|
|
|
65
|
+
// emitNotificationSignal spy — captures every notification the sweep emits
|
|
66
|
+
// so the failure-path test can assert on `activity.failed` shape and dedupe.
|
|
67
|
+
const emitCalls: Array<Record<string, unknown>> = [];
|
|
68
|
+
|
|
69
|
+
mock.module("../../../notifications/emit-signal.js", () => ({
|
|
70
|
+
emitNotificationSignal: async (params: Record<string, unknown>) => {
|
|
71
|
+
emitCalls.push(params);
|
|
72
|
+
return {
|
|
73
|
+
signalId: "sig-1",
|
|
74
|
+
deduplicated: false,
|
|
75
|
+
dispatched: true,
|
|
76
|
+
reason: "ok",
|
|
77
|
+
deliveryResults: [],
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
}));
|
|
81
|
+
|
|
65
82
|
// Workspace setup — temp dir per test run, pinned via VELLUM_WORKSPACE_DIR
|
|
66
83
|
// so `getWorkspaceDir()` resolves to the tmpdir.
|
|
67
84
|
let tmpWorkspace: string;
|
|
@@ -166,6 +183,7 @@ function extractFirstUserText(msgs: { content: unknown }[]): string {
|
|
|
166
183
|
function seedMessages(
|
|
167
184
|
conversationId: string,
|
|
168
185
|
rows: Array<{ role: string; content: string; offsetMs: number }>,
|
|
186
|
+
conversationType: "standard" | "background" | "scheduled" = "standard",
|
|
169
187
|
): void {
|
|
170
188
|
const db = getDb();
|
|
171
189
|
const now = Date.now();
|
|
@@ -175,6 +193,7 @@ function seedMessages(
|
|
|
175
193
|
title: null,
|
|
176
194
|
createdAt: now - 60_000,
|
|
177
195
|
updatedAt: now,
|
|
196
|
+
conversationType,
|
|
178
197
|
})
|
|
179
198
|
.run();
|
|
180
199
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -200,6 +219,7 @@ beforeEach(() => {
|
|
|
200
219
|
mkdirSync(join(tmpWorkspace, "memory"), { recursive: true });
|
|
201
220
|
providerCalls.length = 0;
|
|
202
221
|
providerStub = null;
|
|
222
|
+
emitCalls.length = 0;
|
|
203
223
|
});
|
|
204
224
|
|
|
205
225
|
// ---------------------------------------------------------------------------
|
|
@@ -417,6 +437,81 @@ describe("memoryV2SweepJob — recent messages", () => {
|
|
|
417
437
|
|
|
418
438
|
expect(written).toBe(0);
|
|
419
439
|
});
|
|
440
|
+
|
|
441
|
+
test("emits an activity.failed notification when provider.sendMessage throws", async () => {
|
|
442
|
+
// Simulate a transient provider failure once we're past the early
|
|
443
|
+
// bail checks. The sweep must (a) preserve the existing silent-failure
|
|
444
|
+
// contract by returning 0, and (b) surface the failure via the
|
|
445
|
+
// centralized notifications pipeline so the user sees it instead of
|
|
446
|
+
// the failure being silently swallowed.
|
|
447
|
+
providerStub = {
|
|
448
|
+
name: "stub",
|
|
449
|
+
sendMessage: async () => {
|
|
450
|
+
throw new Error("simulated provider failure");
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const written = await memoryV2SweepJob(makeJob(), CONFIG);
|
|
455
|
+
|
|
456
|
+
expect(written).toBe(0);
|
|
457
|
+
expect(emitCalls).toHaveLength(1);
|
|
458
|
+
const emitted = emitCalls[0]!;
|
|
459
|
+
expect(emitted.sourceEventName).toBe("activity.failed");
|
|
460
|
+
expect(emitted.sourceChannel).toBe("scheduler");
|
|
461
|
+
const day = new Date().toISOString().slice(0, 10);
|
|
462
|
+
expect(emitted.dedupeKey).toBe(`activity-failed:memory.v2.sweep:${day}`);
|
|
463
|
+
const contextPayload = emitted.contextPayload as Record<string, unknown>;
|
|
464
|
+
expect(contextPayload.jobName).toBe("memory.v2.sweep");
|
|
465
|
+
expect(contextPayload.errorKind).toBe("exception");
|
|
466
|
+
expect(contextPayload.errorMessage).toContain("simulated provider failure");
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
describe("memoryV2SweepJob — background/scheduled conversation filter", () => {
|
|
471
|
+
test("excludes background/scheduled conversation content from sweep input", async () => {
|
|
472
|
+
seedMessages(
|
|
473
|
+
`conv-bg-${++convCounter}`,
|
|
474
|
+
[
|
|
475
|
+
{
|
|
476
|
+
role: "assistant",
|
|
477
|
+
content:
|
|
478
|
+
"[heartbeat] internal automation chatter that should not leak",
|
|
479
|
+
offsetMs: -60_000,
|
|
480
|
+
},
|
|
481
|
+
],
|
|
482
|
+
"background",
|
|
483
|
+
);
|
|
484
|
+
seedMessages(
|
|
485
|
+
`conv-sched-${++convCounter}`,
|
|
486
|
+
[
|
|
487
|
+
{
|
|
488
|
+
role: "assistant",
|
|
489
|
+
content:
|
|
490
|
+
"[scheduled] scheduled-job chatter that should not leak either",
|
|
491
|
+
offsetMs: -45_000,
|
|
492
|
+
},
|
|
493
|
+
],
|
|
494
|
+
"scheduled",
|
|
495
|
+
);
|
|
496
|
+
seedMessages(`conv-user-${++convCounter}`, [
|
|
497
|
+
{
|
|
498
|
+
role: "user",
|
|
499
|
+
content: "Bob mentioned he prefers dark mode.",
|
|
500
|
+
offsetMs: -30_000,
|
|
501
|
+
},
|
|
502
|
+
]);
|
|
503
|
+
|
|
504
|
+
providerStub = makeEntriesProvider(["Bob prefers dark mode."]);
|
|
505
|
+
|
|
506
|
+
const written = await memoryV2SweepJob(makeJob(), CONFIG);
|
|
507
|
+
|
|
508
|
+
expect(written).toBe(1);
|
|
509
|
+
expect(providerCalls).toHaveLength(1);
|
|
510
|
+
const [{ userText }] = providerCalls;
|
|
511
|
+
expect(userText).toContain("Bob mentioned he prefers dark mode.");
|
|
512
|
+
expect(userText).not.toContain("internal automation chatter");
|
|
513
|
+
expect(userText).not.toContain("scheduled-job chatter");
|
|
514
|
+
});
|
|
420
515
|
});
|
|
421
516
|
|
|
422
517
|
function todaysArchiveBasename(now: Date = new Date()): string {
|
|
@@ -82,15 +82,44 @@ export async function save(
|
|
|
82
82
|
* The child row inherits everInjected as-is so previously-attached slugs are
|
|
83
83
|
* not re-injected on the child's first turn — matching the v1 semantics where
|
|
84
84
|
* a fork carries over all in-context memories.
|
|
85
|
+
*
|
|
86
|
+
* Synchronous so it can run inside the bun:sqlite transaction that wraps
|
|
87
|
+
* `forkConversation()` — keeping the state copy atomic with the message and
|
|
88
|
+
* attachment copies.
|
|
85
89
|
*/
|
|
86
|
-
export
|
|
90
|
+
export function forkActivationState(
|
|
87
91
|
database: DrizzleDb,
|
|
88
92
|
parentConversationId: string,
|
|
89
93
|
newConversationId: string,
|
|
90
|
-
):
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
): void {
|
|
95
|
+
const row = database
|
|
96
|
+
.select()
|
|
97
|
+
.from(activationState)
|
|
98
|
+
.where(eq(activationState.conversationId, parentConversationId))
|
|
99
|
+
.get();
|
|
100
|
+
if (!row) return;
|
|
101
|
+
|
|
102
|
+
database
|
|
103
|
+
.insert(activationState)
|
|
104
|
+
.values({
|
|
105
|
+
conversationId: newConversationId,
|
|
106
|
+
messageId: row.messageId,
|
|
107
|
+
stateJson: row.stateJson,
|
|
108
|
+
everInjectedJson: row.everInjectedJson,
|
|
109
|
+
currentTurn: row.currentTurn,
|
|
110
|
+
updatedAt: row.updatedAt,
|
|
111
|
+
})
|
|
112
|
+
.onConflictDoUpdate({
|
|
113
|
+
target: activationState.conversationId,
|
|
114
|
+
set: {
|
|
115
|
+
messageId: row.messageId,
|
|
116
|
+
stateJson: row.stateJson,
|
|
117
|
+
everInjectedJson: row.everInjectedJson,
|
|
118
|
+
currentTurn: row.currentTurn,
|
|
119
|
+
updatedAt: row.updatedAt,
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
.run();
|
|
94
123
|
}
|
|
95
124
|
|
|
96
125
|
/**
|
|
@@ -36,15 +36,13 @@
|
|
|
36
36
|
|
|
37
37
|
import type { AssistantConfig } from "../../config/types.js";
|
|
38
38
|
import { applyCorrectionIfCalibrated } from "../anisotropy.js";
|
|
39
|
-
import {
|
|
40
|
-
embedWithBackend,
|
|
41
|
-
generateSparseEmbedding,
|
|
42
|
-
} from "../embedding-backend.js";
|
|
39
|
+
import { embedWithBackend } from "../embedding-backend.js";
|
|
43
40
|
import { clampUnitInterval } from "../validation.js";
|
|
44
41
|
import type { EdgeIndex } from "./edge-index.js";
|
|
45
42
|
import { hybridQueryConceptPages } from "./qdrant.js";
|
|
46
43
|
import { rerankCandidates } from "./reranker.js";
|
|
47
44
|
import { simBatch } from "./sim.js";
|
|
45
|
+
import { generateBm25QueryEmbedding } from "./sparse-bm25.js";
|
|
48
46
|
import type { ActivationState, EverInjectedEntry } from "./types.js";
|
|
49
47
|
|
|
50
48
|
/**
|
|
@@ -125,12 +123,13 @@ export async function selectCandidates(
|
|
|
125
123
|
|
|
126
124
|
// (2) ANN top-50 against the concatenated turn text. Pure whitespace joins
|
|
127
125
|
// (no separators) keep the embedding behavior aligned with how callers
|
|
128
|
-
// would naturally read the three texts together.
|
|
126
|
+
// would naturally read the three texts together. Whitespace-only channels
|
|
127
|
+
// contribute no semantic content, so trim before deciding whether to embed.
|
|
129
128
|
const annQueryText = [userText, assistantText, nowText]
|
|
130
|
-
.filter((s) => s.length > 0)
|
|
129
|
+
.filter((s) => s.trim().length > 0)
|
|
131
130
|
.join("\n");
|
|
132
131
|
|
|
133
|
-
if (annQueryText.length > 0) {
|
|
132
|
+
if (annQueryText.trim().length > 0) {
|
|
134
133
|
throwIfAborted(signal);
|
|
135
134
|
const denseResult = await embedWithBackend(config, [annQueryText], {
|
|
136
135
|
signal,
|
|
@@ -141,7 +140,7 @@ export async function selectCandidates(
|
|
|
141
140
|
denseResult.model,
|
|
142
141
|
);
|
|
143
142
|
throwIfAborted(signal);
|
|
144
|
-
const sparse =
|
|
143
|
+
const sparse = generateBm25QueryEmbedding(annQueryText);
|
|
145
144
|
const limit =
|
|
146
145
|
config.memory.v2.ann_candidate_limit ?? UNLIMITED_ANN_CANDIDATE_LIMIT;
|
|
147
146
|
const hits = await hybridQueryConceptPages(dense, sparse, limit);
|
|
@@ -202,17 +201,19 @@ interface ComputeOwnActivationResult {
|
|
|
202
201
|
* + c_user · sim_u + c_assistant · sim_a + c_now · sim_n
|
|
203
202
|
* + c_user · α · r_norm_u + c_assistant · α · r_norm_a
|
|
204
203
|
* over the candidate set, where the rerank terms only fire for slugs that
|
|
205
|
-
* land in the unified top-K
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
204
|
+
* land in the unified top-K window. The pool is ranked by the rerank-eligible
|
|
205
|
+
* channels alone (`c_user · sim_u + c_assistant · sim_a`) so prior- or
|
|
206
|
+
* NOW-heavy slugs — which can't gain from rerank — don't starve out
|
|
207
|
+
* genuinely user/assistant-relevant slugs. Returns a sparse map keyed by
|
|
208
|
+
* slug; slugs whose computed value rounds to 0 are still included so callers
|
|
209
|
+
* can see the candidate set explicitly. Also returns a per-slug breakdown of
|
|
210
|
+
* the raw inputs (decayed prior + raw sims + rerank deltas) so callers can
|
|
211
|
+
* render contribution diagnostics without re-running the math.
|
|
210
212
|
*
|
|
211
213
|
* The three `simBatch` calls run concurrently — they hit independent named
|
|
212
214
|
* vectors and embed independent query texts. Cross-encoder rerank then runs
|
|
213
|
-
* once on the unified top-K
|
|
214
|
-
*
|
|
215
|
-
* past entries that only land in one channel.
|
|
215
|
+
* once on the unified top-K so an entry strong in both channels can't
|
|
216
|
+
* double-boost itself past entries that only land in one channel.
|
|
216
217
|
*/
|
|
217
218
|
export async function computeOwnActivation(
|
|
218
219
|
params: ComputeOwnActivationParams,
|
|
@@ -248,8 +249,16 @@ export async function computeOwnActivation(
|
|
|
248
249
|
simU: number;
|
|
249
250
|
simA: number;
|
|
250
251
|
simN: number;
|
|
251
|
-
/** Pre-rerank A_o;
|
|
252
|
+
/** Pre-rerank A_o; full sum used for the final activation value. */
|
|
252
253
|
preRerank: number;
|
|
254
|
+
/**
|
|
255
|
+
* Ranking signal for the unified rerank pool — only the channels that
|
|
256
|
+
* actually participate in rerank (user + assistant). Excluding
|
|
257
|
+
* `priorContribution` and `c_now * simN` prevents prior- or NOW-heavy
|
|
258
|
+
* slugs from consuming the rerank budget despite being ineligible for
|
|
259
|
+
* cross-encoder gains.
|
|
260
|
+
*/
|
|
261
|
+
rerankPoolScore: number;
|
|
253
262
|
}
|
|
254
263
|
const inputs: SlugInputs[] = slugList.map((slug) => {
|
|
255
264
|
const prev = priorState?.state[slug] ?? 0;
|
|
@@ -257,23 +266,24 @@ export async function computeOwnActivation(
|
|
|
257
266
|
const simA = simAssistant.get(slug) ?? 0;
|
|
258
267
|
const simN = simNow.get(slug) ?? 0;
|
|
259
268
|
const priorContribution = d * prev;
|
|
269
|
+
const rerankPoolScore = c_user * simU + c_assistant * simA;
|
|
260
270
|
return {
|
|
261
271
|
slug,
|
|
262
272
|
priorContribution,
|
|
263
273
|
simU,
|
|
264
274
|
simA,
|
|
265
275
|
simN,
|
|
266
|
-
preRerank:
|
|
267
|
-
|
|
276
|
+
preRerank: priorContribution + rerankPoolScore + c_now * simN,
|
|
277
|
+
rerankPoolScore,
|
|
268
278
|
};
|
|
269
279
|
});
|
|
270
280
|
|
|
271
|
-
// Unified top-K by
|
|
272
|
-
// slug set, so a slug strong on user can't crowd out one strong
|
|
273
|
-
// by virtue of appearing in both per-channel top-Ks. Both
|
|
274
|
-
// ride in a single `rerankCandidates` call so the worker
|
|
275
|
-
// forward-passes them together — half the per-call overhead
|
|
276
|
-
// serialised round-trips.
|
|
281
|
+
// Unified top-K by rerank-eligible signal only. Both channels rerank against
|
|
282
|
+
// the **same** slug set, so a slug strong on user can't crowd out one strong
|
|
283
|
+
// on assistant by virtue of appearing in both per-channel top-Ks. Both
|
|
284
|
+
// channel queries ride in a single `rerankCandidates` call so the worker
|
|
285
|
+
// tokenizes and forward-passes them together — half the per-call overhead
|
|
286
|
+
// of two serialised round-trips.
|
|
277
287
|
let userRerankBoost: ReadonlyMap<string, number> = new Map();
|
|
278
288
|
let assistantRerankBoost: ReadonlyMap<string, number> = new Map();
|
|
279
289
|
let inPoolSet: ReadonlySet<string> = new Set();
|
|
@@ -282,17 +292,20 @@ export async function computeOwnActivation(
|
|
|
282
292
|
throwIfAborted(signal);
|
|
283
293
|
const topSlugs = inputs
|
|
284
294
|
.slice()
|
|
285
|
-
.sort((a, b) => b.
|
|
295
|
+
.sort((a, b) => b.rerankPoolScore - a.rerankPoolScore)
|
|
286
296
|
.slice(0, rerankCfg.top_k)
|
|
287
297
|
.map((e) => e.slug);
|
|
288
298
|
if (topSlugs.length > 0) {
|
|
289
|
-
inPoolSet = new Set(topSlugs);
|
|
290
299
|
const [userScores, assistantScores] = await rerankCandidates(
|
|
291
300
|
[userText, assistantText],
|
|
292
301
|
topSlugs,
|
|
293
302
|
config,
|
|
294
303
|
);
|
|
295
304
|
throwIfAborted(signal);
|
|
305
|
+
// Build the pool from slugs the cross-encoder actually scored, so a
|
|
306
|
+
// backend failure (which yields empty maps) doesn't mislabel candidates
|
|
307
|
+
// as `inRerankPool` in the inspector.
|
|
308
|
+
inPoolSet = new Set([...userScores.keys(), ...assistantScores.keys()]);
|
|
296
309
|
userRerankBoost = normalizeRerankScores(userScores, rerankCfg.alpha);
|
|
297
310
|
assistantRerankBoost = normalizeRerankScores(
|
|
298
311
|
assistantScores,
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
// - `memory_v2_migrate` — one-shot v1→v2 synthesis (PR 16).
|
|
9
9
|
// - `memory_v2_reembed` — fan out an `embed_concept_page` job
|
|
10
|
-
// per
|
|
11
|
-
// (`__essentials__`, `__threads__`, `__recent__`, `__buffer__`).
|
|
10
|
+
// per concept-page slug.
|
|
12
11
|
// - `memory_v2_activation_recompute` — recompute persisted activation
|
|
13
12
|
// state for every conversation, no rendering. Used after consolidation
|
|
14
13
|
// replaces or deletes pages that other conversations still reference.
|
|
@@ -19,9 +18,6 @@
|
|
|
19
18
|
// the same code paths exercised by tests of those modules run unchanged when
|
|
20
19
|
// a backfill kicks them off.
|
|
21
20
|
|
|
22
|
-
import { readFile } from "node:fs/promises";
|
|
23
|
-
import { join } from "node:path";
|
|
24
|
-
|
|
25
21
|
import type { AssistantConfig } from "../../config/types.js";
|
|
26
22
|
import { getLogger } from "../../util/logger.js";
|
|
27
23
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
@@ -30,6 +26,7 @@ import { listConversations } from "../conversation-queries.js";
|
|
|
30
26
|
import { getDb } from "../db-connection.js";
|
|
31
27
|
import { enqueueEmbedConceptPageJob } from "../jobs/embed-concept-page.js";
|
|
32
28
|
import type { MemoryJob } from "../jobs-store.js";
|
|
29
|
+
import { stringifyMessageContent } from "../message-content.js";
|
|
33
30
|
import {
|
|
34
31
|
computeOwnActivation,
|
|
35
32
|
selectCandidates,
|
|
@@ -41,25 +38,11 @@ import {
|
|
|
41
38
|
MigrationAlreadyAppliedError,
|
|
42
39
|
runMemoryV2Migration,
|
|
43
40
|
} from "./migration.js";
|
|
41
|
+
import { loadNowText } from "./now-text.js";
|
|
44
42
|
import { listPages } from "./page-store.js";
|
|
45
43
|
|
|
46
44
|
const log = getLogger("memory-v2-backfill");
|
|
47
45
|
|
|
48
|
-
/**
|
|
49
|
-
* Reserved slugs the reembed job enqueues alongside the concept-page slugs.
|
|
50
|
-
* These name the four prose meta files (essentials/threads/recent/buffer)
|
|
51
|
-
* loaded into the system prompt by PR 11. Embedding them is forward-looking
|
|
52
|
-
* — the existing `embed-concept-page` handler treats unknown slugs as
|
|
53
|
-
* deletions (a no-op when no embedding exists), so enqueueing here is safe
|
|
54
|
-
* regardless of whether the meta files are ever embedded for retrieval.
|
|
55
|
-
*/
|
|
56
|
-
export const META_FILE_SLUGS = [
|
|
57
|
-
"__essentials__",
|
|
58
|
-
"__threads__",
|
|
59
|
-
"__recent__",
|
|
60
|
-
"__buffer__",
|
|
61
|
-
] as const;
|
|
62
|
-
|
|
63
46
|
// ---------------------------------------------------------------------------
|
|
64
47
|
// memory_v2_migrate — wraps runMemoryV2Migration
|
|
65
48
|
// ---------------------------------------------------------------------------
|
|
@@ -106,16 +89,22 @@ export async function memoryV2MigrateJob(
|
|
|
106
89
|
}
|
|
107
90
|
|
|
108
91
|
// ---------------------------------------------------------------------------
|
|
109
|
-
// memory_v2_reembed — fan out embed jobs for every page
|
|
92
|
+
// memory_v2_reembed — fan out embed jobs for every concept page
|
|
110
93
|
// ---------------------------------------------------------------------------
|
|
111
94
|
|
|
112
95
|
/**
|
|
113
|
-
* Job handler: enqueue an `embed_concept_page` job per concept-page slug
|
|
114
|
-
*
|
|
96
|
+
* Job handler: enqueue an `embed_concept_page` job per concept-page slug.
|
|
97
|
+
*
|
|
98
|
+
* Returns the total number of jobs enqueued. Callers (and tests) use the
|
|
99
|
+
* return value to assert progress without inspecting the job table directly.
|
|
115
100
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
101
|
+
* Note on meta files: `essentials.md` / `threads.md` / `recent.md` /
|
|
102
|
+
* `buffer.md` are direct-injected into the system prompt every turn via
|
|
103
|
+
* `_autoinject.md`. They are NOT enqueued for embedding here — their slugs
|
|
104
|
+
* (`__essentials__` etc.) contain underscores that the concept-page slug
|
|
105
|
+
* validator rejects (`[a-z0-9][a-z0-9-]*`), and they live at `memory/<name>.md`
|
|
106
|
+
* rather than `memory/concepts/<name>.md`, so path resolution would also miss.
|
|
107
|
+
* Embedding them would be redundant with the direct injection regardless.
|
|
119
108
|
*/
|
|
120
109
|
export async function memoryV2ReembedJob(
|
|
121
110
|
_job: MemoryJob,
|
|
@@ -127,16 +116,12 @@ export async function memoryV2ReembedJob(
|
|
|
127
116
|
for (const slug of slugs) {
|
|
128
117
|
enqueueEmbedConceptPageJob({ slug });
|
|
129
118
|
}
|
|
130
|
-
for (const slug of META_FILE_SLUGS) {
|
|
131
|
-
enqueueEmbedConceptPageJob({ slug });
|
|
132
|
-
}
|
|
133
119
|
|
|
134
|
-
const total = slugs.length + META_FILE_SLUGS.length;
|
|
135
120
|
log.info(
|
|
136
|
-
{ conceptPages: slugs.length,
|
|
121
|
+
{ conceptPages: slugs.length, total: slugs.length },
|
|
137
122
|
"Memory v2 reembed enqueued",
|
|
138
123
|
);
|
|
139
|
-
return
|
|
124
|
+
return slugs.length;
|
|
140
125
|
}
|
|
141
126
|
|
|
142
127
|
// ---------------------------------------------------------------------------
|
|
@@ -303,55 +288,3 @@ function lastExchangeTexts(conversationId: string): {
|
|
|
303
288
|
}
|
|
304
289
|
return { userText, assistantText };
|
|
305
290
|
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Coerce stored message content (JSON-serialized `ContentBlock[]` *or* plain
|
|
309
|
-
* string in legacy rows) into a single text string. Image / tool blocks are
|
|
310
|
-
* dropped — recompute only needs the spoken text.
|
|
311
|
-
*/
|
|
312
|
-
function stringifyMessageContent(stored: string): string {
|
|
313
|
-
let parsed: unknown;
|
|
314
|
-
try {
|
|
315
|
-
parsed = JSON.parse(stored);
|
|
316
|
-
} catch {
|
|
317
|
-
return stored.trim();
|
|
318
|
-
}
|
|
319
|
-
if (typeof parsed === "string") return parsed.trim();
|
|
320
|
-
if (!Array.isArray(parsed)) return "";
|
|
321
|
-
const parts: string[] = [];
|
|
322
|
-
for (const block of parsed) {
|
|
323
|
-
if (
|
|
324
|
-
block &&
|
|
325
|
-
typeof block === "object" &&
|
|
326
|
-
(block as { type?: string }).type === "text" &&
|
|
327
|
-
typeof (block as { text?: unknown }).text === "string"
|
|
328
|
-
) {
|
|
329
|
-
parts.push((block as { text: string }).text);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return parts.join("\n").trim();
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Read the prose meta files that compose the "NOW" context the activation
|
|
337
|
-
* pipeline correlates against. Mirrors the autoload order in
|
|
338
|
-
* `system-prompt.ts` so the same prose drives both injection and recompute.
|
|
339
|
-
* Missing or unreadable files are treated as empty.
|
|
340
|
-
*/
|
|
341
|
-
async function loadNowText(workspaceDir: string): Promise<string> {
|
|
342
|
-
const filenames = ["essentials.md", "threads.md", "recent.md"];
|
|
343
|
-
const reads = await Promise.all(
|
|
344
|
-
filenames.map(async (filename) => {
|
|
345
|
-
try {
|
|
346
|
-
const text = await readFile(
|
|
347
|
-
join(workspaceDir, "memory", filename),
|
|
348
|
-
"utf-8",
|
|
349
|
-
);
|
|
350
|
-
return text.trim();
|
|
351
|
-
} catch {
|
|
352
|
-
return "";
|
|
353
|
-
}
|
|
354
|
-
}),
|
|
355
|
-
);
|
|
356
|
-
return reads.filter((part) => part.length > 0).join("\n\n");
|
|
357
|
-
}
|