@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
|
@@ -98,51 +98,125 @@ export async function embedConceptPageJob(
|
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
const contentHash = embeddingInputContentHash({ type: "text", text });
|
|
102
101
|
const expectedDim = config.memory.qdrant.vectorSize;
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
// The status provider is the cache lookup key for any prior row; the
|
|
103
|
+
// *actual* provider/model come back on the embedded result. They usually
|
|
104
|
+
// match, but a backend swap mid-run would surface here — body and summary
|
|
105
|
+
// are then re-embedded together so both rows write under the same identity.
|
|
106
|
+
const cacheProvider = status.provider;
|
|
107
|
+
const cacheModel = status.model!;
|
|
108
|
+
|
|
109
|
+
const db = getDb();
|
|
105
110
|
|
|
106
111
|
// Cache lookup: same (targetType, targetId, provider, model) row gets
|
|
107
112
|
// reused across runs as long as `contentHash` matches. The dim mismatch
|
|
108
113
|
// check guards against a config change (vectorSize bumped) since the last
|
|
109
|
-
// write — in that case we treat the row as stale and re-embed.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
114
|
+
// write — in that case we treat the row as stale and re-embed. The body
|
|
115
|
+
// and (optional) summary share the same provider/model — but each gets
|
|
116
|
+
// its own cache row keyed by a distinct targetId so summary edits don't
|
|
117
|
+
// invalidate the body cache and vice versa.
|
|
118
|
+
const bodyContentHash = embeddingInputContentHash({ type: "text", text });
|
|
119
|
+
const bodyCache = readEmbeddingCache(
|
|
120
|
+
db,
|
|
121
|
+
slug,
|
|
122
|
+
cacheProvider,
|
|
123
|
+
cacheModel,
|
|
124
|
+
expectedDim,
|
|
125
|
+
);
|
|
126
|
+
const bodyCacheHit = bodyCache?.contentHash === bodyContentHash;
|
|
127
|
+
|
|
128
|
+
// Optional summary embedding — only when the page has a `summary` in its
|
|
129
|
+
// frontmatter. Pages without one fall back to body-only retrieval at
|
|
130
|
+
// query time (the activation pipeline reads the summary score as
|
|
131
|
+
// undefined and uses the body score directly).
|
|
132
|
+
const summaryText = page.frontmatter.summary?.trim() ?? "";
|
|
133
|
+
const hasSummary = summaryText.length > 0;
|
|
134
|
+
const summaryCacheId = `${slug}#summary`;
|
|
135
|
+
const summaryContentHash = hasSummary
|
|
136
|
+
? embeddingInputContentHash({ type: "text", text: summaryText })
|
|
137
|
+
: undefined;
|
|
138
|
+
const summaryCache = hasSummary
|
|
139
|
+
? readEmbeddingCache(
|
|
140
|
+
db,
|
|
141
|
+
summaryCacheId,
|
|
142
|
+
cacheProvider,
|
|
143
|
+
cacheModel,
|
|
144
|
+
expectedDim,
|
|
145
|
+
)
|
|
146
|
+
: null;
|
|
147
|
+
const summaryCacheHit =
|
|
148
|
+
hasSummary && summaryCache?.contentHash === summaryContentHash;
|
|
149
|
+
|
|
150
|
+
// Batch all cache misses into one `embedWithBackend` call. Each backend
|
|
151
|
+
// round-trip is the dominant cost — fresh body + fresh summary in a
|
|
152
|
+
// single batch saves a round-trip vs serial calls and gives both vectors
|
|
153
|
+
// the same provider/model regardless of any backend rotation mid-run.
|
|
154
|
+
type Slot = "body" | "summary";
|
|
155
|
+
const toEmbed: Array<{ type: "text"; text: string }> = [];
|
|
156
|
+
const slots: Slot[] = [];
|
|
157
|
+
if (!bodyCacheHit) {
|
|
158
|
+
toEmbed.push({ type: "text", text });
|
|
159
|
+
slots.push("body");
|
|
160
|
+
}
|
|
161
|
+
if (hasSummary && !summaryCacheHit) {
|
|
162
|
+
toEmbed.push({ type: "text", text: summaryText });
|
|
163
|
+
slots.push("summary");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let bodyDense: number[] | undefined = bodyCacheHit
|
|
167
|
+
? bodyCache!.dense
|
|
168
|
+
: undefined;
|
|
169
|
+
let summaryDense: number[] | undefined = summaryCacheHit
|
|
170
|
+
? summaryCache!.dense
|
|
171
|
+
: undefined;
|
|
172
|
+
let writeProvider = cacheProvider;
|
|
173
|
+
let writeModel = cacheModel;
|
|
174
|
+
let bodyFresh = false;
|
|
175
|
+
let summaryFresh = false;
|
|
176
|
+
if (toEmbed.length > 0) {
|
|
177
|
+
let embedded = await embedWithBackend(config, toEmbed);
|
|
178
|
+
let appliedSlots = slots;
|
|
179
|
+
// Backend rotation between `getMemoryBackendStatus()` and
|
|
180
|
+
// `embedWithBackend()` would tag the cached half with the old
|
|
181
|
+
// provider/model and the fresh half with the new — writing both into
|
|
182
|
+
// one Qdrant point mixes embedding spaces. Re-embed every slot fresh
|
|
183
|
+
// when we detect the rotation so the point's named vectors share one
|
|
184
|
+
// identity.
|
|
185
|
+
const rotated =
|
|
186
|
+
(bodyCacheHit || summaryCacheHit) &&
|
|
187
|
+
(embedded.provider !== cacheProvider || embedded.model !== cacheModel);
|
|
188
|
+
if (rotated) {
|
|
189
|
+
const allTexts: Array<{ type: "text"; text: string }> = [
|
|
190
|
+
{ type: "text", text },
|
|
191
|
+
];
|
|
192
|
+
const allSlots: Slot[] = ["body"];
|
|
193
|
+
if (hasSummary) {
|
|
194
|
+
allTexts.push({ type: "text", text: summaryText });
|
|
195
|
+
allSlots.push("summary");
|
|
196
|
+
}
|
|
197
|
+
embedded = await embedWithBackend(config, allTexts);
|
|
198
|
+
appliedSlots = allSlots;
|
|
199
|
+
bodyDense = undefined;
|
|
200
|
+
summaryDense = undefined;
|
|
201
|
+
}
|
|
202
|
+
writeProvider = embedded.provider;
|
|
203
|
+
writeModel = embedded.model;
|
|
204
|
+
for (let i = 0; i < appliedSlots.length; i++) {
|
|
205
|
+
const vector = embedded.vectors[i];
|
|
206
|
+
if (!vector) continue;
|
|
207
|
+
if (appliedSlots[i] === "body") {
|
|
208
|
+
bodyDense = vector;
|
|
209
|
+
bodyFresh = true;
|
|
210
|
+
} else {
|
|
211
|
+
summaryDense = vector;
|
|
212
|
+
summaryFresh = true;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
145
215
|
}
|
|
216
|
+
// Body embedding is the ground truth — without it the page can't surface.
|
|
217
|
+
// (Cache hit paths populate `bodyDense` above; a fresh embed that returned
|
|
218
|
+
// no vectors short-circuits here too.)
|
|
219
|
+
if (!bodyDense) return;
|
|
146
220
|
|
|
147
221
|
// Sparse is cheap (in-process tokenization) and changes any time the body
|
|
148
222
|
// changes, so we always recompute it rather than caching alongside dense.
|
|
@@ -151,57 +225,45 @@ export async function embedConceptPageJob(
|
|
|
151
225
|
// corpus for the first time), fall back to the legacy TF-only encoding —
|
|
152
226
|
// the next reembed pass overwrites the page once stats are available.
|
|
153
227
|
const corpusStats = getConceptPageCorpusStats();
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
228
|
+
const encodeSparse = (input: string) =>
|
|
229
|
+
corpusStats
|
|
230
|
+
? generateBm25DocEmbedding(input, corpusStats, {
|
|
231
|
+
k1: config.memory.v2.bm25_k1,
|
|
232
|
+
b: config.memory.v2.bm25_b,
|
|
233
|
+
})
|
|
234
|
+
: generateSparseEmbedding(input);
|
|
235
|
+
const sparse = encodeSparse(text);
|
|
236
|
+
const summarySparse = hasSummary ? encodeSparse(summaryText) : undefined;
|
|
160
237
|
|
|
161
238
|
const now = Date.now();
|
|
162
239
|
// Persist freshly embedded vectors for cross-restart reuse. On cache hit
|
|
163
240
|
// the existing row already has identical content + hash, so the write
|
|
164
|
-
// would be a no-op — skip it.
|
|
165
|
-
//
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
set: {
|
|
191
|
-
vectorBlob: blobValue,
|
|
192
|
-
vectorJson: null,
|
|
193
|
-
dimensions: dense.length,
|
|
194
|
-
contentHash,
|
|
195
|
-
updatedAt: now,
|
|
196
|
-
},
|
|
197
|
-
})
|
|
198
|
-
.run();
|
|
199
|
-
} catch (err) {
|
|
200
|
-
log.warn(
|
|
201
|
-
{ err, slug },
|
|
202
|
-
"Failed to write concept-page embedding cache row",
|
|
203
|
-
);
|
|
204
|
-
}
|
|
241
|
+
// would be a no-op — skip it. Backend rotation flips a cache hit into a
|
|
242
|
+
// fresh embed (see `rotated` above); the `*Fresh` flags capture that so
|
|
243
|
+
// the new vector overwrites the now-stale cache row under the new
|
|
244
|
+
// provider/model identity. Best-effort: write failure is not fatal, we
|
|
245
|
+
// still want the Qdrant upsert below to fire.
|
|
246
|
+
if (bodyFresh) {
|
|
247
|
+
writeEmbeddingCache(db, {
|
|
248
|
+
slug,
|
|
249
|
+
cacheId: slug,
|
|
250
|
+
dense: bodyDense,
|
|
251
|
+
contentHash: bodyContentHash,
|
|
252
|
+
provider: writeProvider,
|
|
253
|
+
model: writeModel,
|
|
254
|
+
now,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
if (hasSummary && summaryFresh && summaryDense && summaryContentHash) {
|
|
258
|
+
writeEmbeddingCache(db, {
|
|
259
|
+
slug,
|
|
260
|
+
cacheId: summaryCacheId,
|
|
261
|
+
dense: summaryDense,
|
|
262
|
+
contentHash: summaryContentHash,
|
|
263
|
+
provider: writeProvider,
|
|
264
|
+
model: writeModel,
|
|
265
|
+
now,
|
|
266
|
+
});
|
|
205
267
|
}
|
|
206
268
|
|
|
207
269
|
// Apply anisotropy correction at the boundary between the (raw) cached
|
|
@@ -210,19 +272,129 @@ export async function embedConceptPageJob(
|
|
|
210
272
|
// the cache survives and the (cheap) correction math reruns over each
|
|
211
273
|
// cached vector. Pass-through when no calibration is fit yet.
|
|
212
274
|
const correctedDense = await applyCorrectionIfCalibrated(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
275
|
+
bodyDense,
|
|
276
|
+
writeProvider,
|
|
277
|
+
writeModel,
|
|
216
278
|
);
|
|
279
|
+
const correctedSummaryDense = summaryDense
|
|
280
|
+
? await applyCorrectionIfCalibrated(summaryDense, writeProvider, writeModel)
|
|
281
|
+
: undefined;
|
|
217
282
|
|
|
218
283
|
await upsertConceptPageEmbedding({
|
|
219
284
|
slug,
|
|
220
285
|
dense: correctedDense,
|
|
221
286
|
sparse,
|
|
287
|
+
summary:
|
|
288
|
+
correctedSummaryDense && summarySparse
|
|
289
|
+
? { dense: correctedSummaryDense, sparse: summarySparse }
|
|
290
|
+
: undefined,
|
|
222
291
|
updatedAt: now,
|
|
223
292
|
});
|
|
224
293
|
}
|
|
225
294
|
|
|
295
|
+
/** SQLite cache row shape returned by `readEmbeddingCache`. */
|
|
296
|
+
interface EmbeddingCacheEntry {
|
|
297
|
+
dense: number[];
|
|
298
|
+
contentHash: string;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Look up a cached dense vector keyed on `(targetType, targetId, provider,
|
|
303
|
+
* model)`. Returns the row only when the persisted dimensions match the
|
|
304
|
+
* configured expectation — a stale row from a previous `vectorSize` is
|
|
305
|
+
* treated as a cache miss so the caller re-embeds.
|
|
306
|
+
*/
|
|
307
|
+
function readEmbeddingCache(
|
|
308
|
+
db: ReturnType<typeof getDb>,
|
|
309
|
+
cacheId: string,
|
|
310
|
+
provider: string,
|
|
311
|
+
model: string,
|
|
312
|
+
expectedDim: number,
|
|
313
|
+
): EmbeddingCacheEntry | null {
|
|
314
|
+
const row = db
|
|
315
|
+
.select({
|
|
316
|
+
vectorBlob: memoryEmbeddings.vectorBlob,
|
|
317
|
+
vectorJson: memoryEmbeddings.vectorJson,
|
|
318
|
+
dimensions: memoryEmbeddings.dimensions,
|
|
319
|
+
contentHash: memoryEmbeddings.contentHash,
|
|
320
|
+
})
|
|
321
|
+
.from(memoryEmbeddings)
|
|
322
|
+
.where(
|
|
323
|
+
and(
|
|
324
|
+
eq(memoryEmbeddings.targetType, CONCEPT_PAGE_TARGET_TYPE),
|
|
325
|
+
eq(memoryEmbeddings.targetId, cacheId),
|
|
326
|
+
eq(memoryEmbeddings.provider, provider),
|
|
327
|
+
eq(memoryEmbeddings.model, model),
|
|
328
|
+
),
|
|
329
|
+
)
|
|
330
|
+
.get();
|
|
331
|
+
if (!row || row.dimensions !== expectedDim) return null;
|
|
332
|
+
// A row without a contentHash is a legacy/corrupt entry — treat as a miss
|
|
333
|
+
// and force a re-embed rather than misalign the cache key.
|
|
334
|
+
if (row.contentHash === null) return null;
|
|
335
|
+
const dense = row.vectorBlob
|
|
336
|
+
? blobToVector(row.vectorBlob as Buffer)
|
|
337
|
+
: (JSON.parse(row.vectorJson!) as number[]);
|
|
338
|
+
return { dense, contentHash: row.contentHash };
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Persist a freshly embedded dense vector in the SQLite cache. Best-effort:
|
|
343
|
+
* a write failure is logged and swallowed so the Qdrant upsert still runs.
|
|
344
|
+
*/
|
|
345
|
+
function writeEmbeddingCache(
|
|
346
|
+
db: ReturnType<typeof getDb>,
|
|
347
|
+
params: {
|
|
348
|
+
slug: string;
|
|
349
|
+
cacheId: string;
|
|
350
|
+
dense: number[];
|
|
351
|
+
contentHash: string;
|
|
352
|
+
provider: string;
|
|
353
|
+
model: string;
|
|
354
|
+
now: number;
|
|
355
|
+
},
|
|
356
|
+
): void {
|
|
357
|
+
const { slug, cacheId, dense, contentHash, provider, model, now } = params;
|
|
358
|
+
try {
|
|
359
|
+
const blobValue = vectorToBlob(dense);
|
|
360
|
+
db.insert(memoryEmbeddings)
|
|
361
|
+
.values({
|
|
362
|
+
id: randomUUID(),
|
|
363
|
+
targetType: CONCEPT_PAGE_TARGET_TYPE,
|
|
364
|
+
targetId: cacheId,
|
|
365
|
+
provider,
|
|
366
|
+
model,
|
|
367
|
+
dimensions: dense.length,
|
|
368
|
+
vectorBlob: blobValue,
|
|
369
|
+
vectorJson: null,
|
|
370
|
+
contentHash,
|
|
371
|
+
createdAt: now,
|
|
372
|
+
updatedAt: now,
|
|
373
|
+
})
|
|
374
|
+
.onConflictDoUpdate({
|
|
375
|
+
target: [
|
|
376
|
+
memoryEmbeddings.targetType,
|
|
377
|
+
memoryEmbeddings.targetId,
|
|
378
|
+
memoryEmbeddings.provider,
|
|
379
|
+
memoryEmbeddings.model,
|
|
380
|
+
],
|
|
381
|
+
set: {
|
|
382
|
+
vectorBlob: blobValue,
|
|
383
|
+
vectorJson: null,
|
|
384
|
+
dimensions: dense.length,
|
|
385
|
+
contentHash,
|
|
386
|
+
updatedAt: now,
|
|
387
|
+
},
|
|
388
|
+
})
|
|
389
|
+
.run();
|
|
390
|
+
} catch (err) {
|
|
391
|
+
log.warn(
|
|
392
|
+
{ err, slug, cacheId },
|
|
393
|
+
"Failed to write concept-page embedding cache row",
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
226
398
|
/**
|
|
227
399
|
* Enqueue an `embed_concept_page` job (async, fire-and-forget). Modeled on
|
|
228
400
|
* `enqueuePkbIndexJob` — callers that want a slug re-embedded after a write
|
package/src/memory/jobs-store.ts
CHANGED
|
@@ -42,7 +42,8 @@ export type MemoryJobType =
|
|
|
42
42
|
| "memory_v2_consolidate"
|
|
43
43
|
| "memory_v2_migrate"
|
|
44
44
|
| "memory_v2_reembed"
|
|
45
|
-
| "memory_v2_activation_recompute"
|
|
45
|
+
| "memory_v2_activation_recompute"
|
|
46
|
+
| "memory_retrospective";
|
|
46
47
|
|
|
47
48
|
export const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
48
49
|
"embed_segment",
|
|
@@ -52,6 +53,7 @@ export const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
|
52
53
|
"embed_graph_node",
|
|
53
54
|
"embed_pkb_file",
|
|
54
55
|
"graph_trigger_embed",
|
|
56
|
+
"embed_concept_page",
|
|
55
57
|
];
|
|
56
58
|
|
|
57
59
|
export const SLOW_LLM_JOB_TYPES: MemoryJobType[] = [
|
|
@@ -65,6 +67,7 @@ export const SLOW_LLM_JOB_TYPES: MemoryJobType[] = [
|
|
|
65
67
|
"memory_v2_sweep",
|
|
66
68
|
"memory_v2_consolidate",
|
|
67
69
|
"memory_v2_migrate",
|
|
70
|
+
"memory_retrospective",
|
|
68
71
|
"backfill",
|
|
69
72
|
"graph_bootstrap",
|
|
70
73
|
];
|
|
@@ -251,6 +254,53 @@ export function upsertAutoAnalysisJob(
|
|
|
251
254
|
}
|
|
252
255
|
}
|
|
253
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Upsert a pending `memory_retrospective` job keyed by `conversationId`. All
|
|
259
|
+
* four retrospective triggers (interval, message_count, compaction,
|
|
260
|
+
* lifecycle) collapse into a single pending row per conversation — rapid
|
|
261
|
+
* triggers coalesce instead of double-firing. The `runAfter` parameter on a
|
|
262
|
+
* follow-up enqueue overwrites the existing row's `runAfter` so a sooner
|
|
263
|
+
* trigger can pull a later-scheduled job earlier; a later-scheduled trigger
|
|
264
|
+
* does NOT push a sooner-scheduled row further out (consumer takes the
|
|
265
|
+
* minimum). The trigger metadata is intentionally not retained — it is only
|
|
266
|
+
* useful for observability at enqueue time.
|
|
267
|
+
*/
|
|
268
|
+
export function upsertMemoryRetrospectiveJob(
|
|
269
|
+
payload: { conversationId: string },
|
|
270
|
+
runAfter: number = Date.now(),
|
|
271
|
+
dbOverride?: Parameters<ReturnType<typeof getDb>["transaction"]>[0] extends (
|
|
272
|
+
tx: infer T,
|
|
273
|
+
) => unknown
|
|
274
|
+
? T
|
|
275
|
+
: never,
|
|
276
|
+
): void {
|
|
277
|
+
const db = dbOverride ?? getDb();
|
|
278
|
+
const existing = db
|
|
279
|
+
.select()
|
|
280
|
+
.from(memoryJobs)
|
|
281
|
+
.where(
|
|
282
|
+
and(
|
|
283
|
+
eq(memoryJobs.type, "memory_retrospective"),
|
|
284
|
+
eq(memoryJobs.status, "pending"),
|
|
285
|
+
sql`json_extract(${memoryJobs.payload}, '$.conversationId') = ${payload.conversationId}`,
|
|
286
|
+
),
|
|
287
|
+
)
|
|
288
|
+
.get();
|
|
289
|
+
if (existing) {
|
|
290
|
+
// Take the minimum of the existing and incoming runAfter so the earliest
|
|
291
|
+
// trigger always wins. A later trigger never pushes work further out.
|
|
292
|
+
const nextRunAfter = Math.min(existing.runAfter, runAfter);
|
|
293
|
+
if (nextRunAfter !== existing.runAfter) {
|
|
294
|
+
db.update(memoryJobs)
|
|
295
|
+
.set({ runAfter: nextRunAfter, updatedAt: Date.now() })
|
|
296
|
+
.where(eq(memoryJobs.id, existing.id))
|
|
297
|
+
.run();
|
|
298
|
+
}
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
enqueueMemoryJob("memory_retrospective", payload, runAfter, dbOverride);
|
|
302
|
+
}
|
|
303
|
+
|
|
254
304
|
/**
|
|
255
305
|
* Check whether a pending or running job of the given type already exists.
|
|
256
306
|
* Used to prevent duplicate enqueues for long-running maintenance jobs.
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
getLastScheduledCleanupEnqueueMs,
|
|
12
12
|
markScheduledCleanupEnqueued,
|
|
13
13
|
} from "./cleanup-schedule-state.js";
|
|
14
|
-
import { isMemoryV2ReadActive } from "./context-search/sources/memory-v2.js";
|
|
15
14
|
import { conversationAnalyzeJob } from "./conversation-analyze-job.js";
|
|
16
15
|
import { maybeRunDbMaintenance } from "./db-maintenance.js";
|
|
17
16
|
import { bootstrapFromHistory } from "./graph/bootstrap.js";
|
|
@@ -68,6 +67,8 @@ import {
|
|
|
68
67
|
resetRunningJobsToPending,
|
|
69
68
|
SLOW_LLM_JOB_TYPES,
|
|
70
69
|
} from "./jobs-store.js";
|
|
70
|
+
import { memoryRetrospectiveJob } from "./memory-retrospective-job.js";
|
|
71
|
+
import { sweepOrphanMemoryRetrospectiveConversations } from "./memory-retrospective-startup-cleanup.js";
|
|
71
72
|
import { QdrantCircuitOpenError } from "./qdrant-circuit-breaker.js";
|
|
72
73
|
import {
|
|
73
74
|
memoryV2ActivationRecomputeJob,
|
|
@@ -79,6 +80,26 @@ import { memoryV2SweepJob } from "./v2/sweep-job.js";
|
|
|
79
80
|
|
|
80
81
|
const log = getLogger("memory-jobs-worker");
|
|
81
82
|
|
|
83
|
+
/**
|
|
84
|
+
* V1 job types that read or write the v1 Qdrant collection via
|
|
85
|
+
* `getQdrantClient()`. When `memory.v2.enabled` is true, the v1 client is
|
|
86
|
+
* intentionally left uninitialized in `lifecycle.ts`, so these handlers would
|
|
87
|
+
* throw `BackendUnavailableError` and accumulate as a deferred backlog. Stale
|
|
88
|
+
* rows from indexer.ts and other unguarded enqueue sites must short-circuit
|
|
89
|
+
* here for the same reason `graph_extract` does below.
|
|
90
|
+
*/
|
|
91
|
+
const V1_QDRANT_JOB_TYPES = new Set<MemoryJobType>([
|
|
92
|
+
"embed_segment",
|
|
93
|
+
"embed_summary",
|
|
94
|
+
"embed_media",
|
|
95
|
+
"embed_attachment",
|
|
96
|
+
"embed_graph_node",
|
|
97
|
+
"embed_pkb_file",
|
|
98
|
+
"graph_trigger_embed",
|
|
99
|
+
"rebuild_index",
|
|
100
|
+
"delete_qdrant_vectors",
|
|
101
|
+
]);
|
|
102
|
+
|
|
82
103
|
/**
|
|
83
104
|
* Job types whose handlers have been removed. Existing rows may still sit in
|
|
84
105
|
* the database — the worker completes them silently instead of throwing.
|
|
@@ -112,6 +133,19 @@ export function startMemoryJobsWorker(): MemoryJobsWorker {
|
|
|
112
133
|
log.info({ recovered }, "Recovered stale running memory jobs");
|
|
113
134
|
}
|
|
114
135
|
|
|
136
|
+
// After running-job recovery (so legitimate in-flight retries aren't
|
|
137
|
+
// swept), clean up orphan memory-retrospective background conversations
|
|
138
|
+
// left behind by daemon crashes mid-job. Best-effort — never block worker
|
|
139
|
+
// startup on cleanup failures.
|
|
140
|
+
try {
|
|
141
|
+
sweepOrphanMemoryRetrospectiveConversations();
|
|
142
|
+
} catch (err) {
|
|
143
|
+
log.warn(
|
|
144
|
+
{ err },
|
|
145
|
+
"Memory-retrospective startup cleanup failed; continuing worker startup",
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
115
149
|
let stopped = false;
|
|
116
150
|
let tickRunning = false;
|
|
117
151
|
let timer: ReturnType<typeof setTimeout>;
|
|
@@ -125,16 +159,24 @@ export function startMemoryJobsWorker(): MemoryJobsWorker {
|
|
|
125
159
|
enableScheduledCleanup: true,
|
|
126
160
|
});
|
|
127
161
|
if (processed > 0) {
|
|
128
|
-
|
|
162
|
+
// Per-tick claim budget equals the lane caps, so when a tick
|
|
163
|
+
// processed work the next tick must run immediately to drain any
|
|
164
|
+
// remaining backlog. Holding the 1.5s floor between ticks would cap
|
|
165
|
+
// sustained throughput at lane-cap jobs per 1.5s and starve large
|
|
166
|
+
// backlogs of short jobs.
|
|
167
|
+
currentIntervalMs = 0;
|
|
129
168
|
} else {
|
|
130
169
|
currentIntervalMs = Math.min(
|
|
131
|
-
currentIntervalMs * 2,
|
|
170
|
+
Math.max(currentIntervalMs * 2, POLL_INTERVAL_MIN_MS),
|
|
132
171
|
POLL_INTERVAL_MAX_MS,
|
|
133
172
|
);
|
|
134
173
|
}
|
|
135
174
|
} catch (err) {
|
|
136
175
|
log.error({ err }, "Memory worker tick failed");
|
|
137
|
-
currentIntervalMs = Math.min(
|
|
176
|
+
currentIntervalMs = Math.min(
|
|
177
|
+
Math.max(currentIntervalMs * 2, POLL_INTERVAL_MIN_MS),
|
|
178
|
+
POLL_INTERVAL_MAX_MS,
|
|
179
|
+
);
|
|
138
180
|
} finally {
|
|
139
181
|
tickRunning = false;
|
|
140
182
|
}
|
|
@@ -463,6 +505,9 @@ async function processJob(
|
|
|
463
505
|
job: MemoryJob,
|
|
464
506
|
config: AssistantConfig,
|
|
465
507
|
): Promise<void> {
|
|
508
|
+
if (config.memory.v2.enabled && V1_QDRANT_JOB_TYPES.has(job.type)) {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
466
511
|
switch (job.type) {
|
|
467
512
|
case "embed_segment":
|
|
468
513
|
await embedSegmentJob(job, config);
|
|
@@ -510,6 +555,11 @@ async function processJob(
|
|
|
510
555
|
await embedGraphTriggerJob(job, config);
|
|
511
556
|
return;
|
|
512
557
|
case "graph_extract":
|
|
558
|
+
// Stale rows enqueued before v2 was enabled (or by any unguarded v1
|
|
559
|
+
// path) must not consume embedding/extraction budget when v2 is on.
|
|
560
|
+
if (config.memory.v2.enabled) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
513
563
|
await graphExtractJob(job, config);
|
|
514
564
|
return;
|
|
515
565
|
case "conversation_analyze":
|
|
@@ -551,6 +601,9 @@ async function processJob(
|
|
|
551
601
|
case "memory_v2_activation_recompute":
|
|
552
602
|
await memoryV2ActivationRecomputeJob(job, config);
|
|
553
603
|
return;
|
|
604
|
+
case "memory_retrospective":
|
|
605
|
+
await memoryRetrospectiveJob(job, config);
|
|
606
|
+
return;
|
|
554
607
|
|
|
555
608
|
default: {
|
|
556
609
|
const rawType = (job as { type: string }).type;
|
|
@@ -623,8 +676,8 @@ export const GRAPH_MAINTENANCE_CHECKPOINTS = {
|
|
|
623
676
|
* Enqueue periodic graph maintenance jobs.
|
|
624
677
|
*
|
|
625
678
|
* Mutually exclusive between v1 and v2:
|
|
626
|
-
* - v2 active (
|
|
627
|
-
*
|
|
679
|
+
* - v2 active (`memory.v2.enabled` on) → only `memory_v2_consolidate` is
|
|
680
|
+
* scheduled.
|
|
628
681
|
* - v2 inactive → the four v1 entries (decay, consolidate, pattern_scan,
|
|
629
682
|
* narrative) are scheduled instead.
|
|
630
683
|
*
|
|
@@ -643,7 +696,7 @@ export function maybeEnqueueGraphMaintenanceJobs(
|
|
|
643
696
|
config: AssistantConfig,
|
|
644
697
|
nowMs = Date.now(),
|
|
645
698
|
): void {
|
|
646
|
-
const v2Active =
|
|
699
|
+
const v2Active = config.memory.v2.enabled;
|
|
647
700
|
|
|
648
701
|
const schedule: Array<{
|
|
649
702
|
key: string;
|