@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
|
@@ -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
|
-
}
|
|
@@ -6,17 +6,17 @@
|
|
|
6
6
|
* rewrites `memory/recent.md`, promotes new essentials/threads, and trims the
|
|
7
7
|
* buffer down to entries that arrived after the run started.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Consolidation runs as the assistant: `runBackgroundJob()` bootstraps a
|
|
10
|
+
* background conversation and routes the cutoff-templated prompt through
|
|
11
|
+
* `processMessage`, so the standard system prompt (SOUL.md + IDENTITY.md +
|
|
12
|
+
* persona + memory/* autoloads) and tool surface (read_file, write_file,
|
|
13
|
+
* edit_file, list_files, bash) are loaded. Care, judgment, and the
|
|
14
14
|
* assistant's voice are the point — there is no "consolidator persona" to
|
|
15
15
|
* substitute in.
|
|
16
16
|
*
|
|
17
17
|
* Lifecycle:
|
|
18
|
-
* 1. Bail if
|
|
19
|
-
*
|
|
18
|
+
* 1. Bail if `config.memory.v2.enabled` is false (the worker may have
|
|
19
|
+
* claimed a stale row from before v2 was disabled).
|
|
20
20
|
* 2. Acquire a single-process lock at `memory/.v2-state/consolidation.lock`
|
|
21
21
|
* so two overlapping schedule windows can't fight over the same files.
|
|
22
22
|
* The lock contains the holder's PID + timestamp so a crashed run leaves
|
|
@@ -26,21 +26,29 @@
|
|
|
26
26
|
* the next pass.
|
|
27
27
|
* 4. Read `memory/buffer.md`. Bail if empty (no work to do, but the lock
|
|
28
28
|
* and skip path still log so operators can confirm the schedule fired).
|
|
29
|
-
* 5.
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
29
|
+
* 5. Hand off to `runBackgroundJob()` with the templated prompt. The runner
|
|
30
|
+
* handles bootstrap + processMessage + timeout + error classification,
|
|
31
|
+
* and (because we set `suppressFailureNotifications: true`) does NOT
|
|
32
|
+
* emit an `activity.failed` notification on transient failures —
|
|
33
|
+
* consolidation runs on tight intervals, so a network blip or model
|
|
34
|
+
* hiccup should not spam the home feed. Sentry-side reporting is
|
|
35
|
+
* unchanged. The prompt body is loaded via `resolveConsolidationPrompt`
|
|
36
|
+
* which bounds any operator-provided override to a regular file under
|
|
37
|
+
* 1 MiB before substitution.
|
|
38
|
+
* 6. On success, enqueue `memory_v2_reembed` (re-index any pages the agent
|
|
39
|
+
* touched). Tracking touched pages via mtime would be more precise but
|
|
40
|
+
* is fragile across filesystems; the embedder's content-hash cache makes
|
|
41
|
+
* a conservative full-reembed effectively free. On failure no follow-ups
|
|
42
|
+
* are enqueued — the agent's writes may be partial and re-embedding
|
|
43
|
+
* partial state would be misleading.
|
|
44
|
+
* 7. Release the lock. If a prior holder's PID is no longer running, the
|
|
45
|
+
* stale lock is taken over automatically (single-writer per workspace,
|
|
46
|
+
* so a holder whose process died is unambiguously stale).
|
|
39
47
|
*
|
|
40
|
-
* The handler never propagates
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
48
|
+
* The handler never propagates exceptions from the run path — `runBackgroundJob`
|
|
49
|
+
* absorbs them and returns a structured result. A thrown error before the
|
|
50
|
+
* runner is invoked (e.g. mkdir failures) bubbles up and the jobs-worker
|
|
51
|
+
* treats it as a retryable failure.
|
|
44
52
|
*/
|
|
45
53
|
|
|
46
54
|
import {
|
|
@@ -53,15 +61,12 @@ import {
|
|
|
53
61
|
} from "node:fs";
|
|
54
62
|
import { dirname, join } from "node:path";
|
|
55
63
|
|
|
56
|
-
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
57
64
|
import type { AssistantConfig } from "../../config/types.js";
|
|
58
|
-
import {
|
|
59
|
-
import { wakeAgentForOpportunity } from "../../runtime/agent-wake.js";
|
|
65
|
+
import { runBackgroundJob } from "../../runtime/background-job-runner.js";
|
|
60
66
|
import { getLogger } from "../../util/logger.js";
|
|
61
67
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
62
68
|
import { isProcessAlive } from "../../util/process-liveness.js";
|
|
63
|
-
import {
|
|
64
|
-
import { deleteConversation } from "../conversation-crud.js";
|
|
69
|
+
import { formatBufferTimestamp } from "../graph/tool-handlers.js";
|
|
65
70
|
import {
|
|
66
71
|
enqueueMemoryJob,
|
|
67
72
|
type MemoryJob,
|
|
@@ -72,6 +77,17 @@ import { resolveConsolidationPrompt } from "./prompts/consolidation.js";
|
|
|
72
77
|
|
|
73
78
|
const log = getLogger("memory-v2-consolidate");
|
|
74
79
|
|
|
80
|
+
/** Stable identifier surfaced in `runBackgroundJob` logs and notifications. */
|
|
81
|
+
const JOB_NAME = "memory.consolidate";
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Hard timeout for the consolidation run. Consolidation reads the buffer,
|
|
85
|
+
* rewrites several files, and re-encodes essentials/threads — generous
|
|
86
|
+
* upper bound so a slow run isn't killed mid-edit, but bounded so a stuck
|
|
87
|
+
* provider can't pin the worker indefinitely.
|
|
88
|
+
*/
|
|
89
|
+
const CONSOLIDATION_TIMEOUT_MS = 15 * 60 * 1000;
|
|
90
|
+
|
|
75
91
|
/**
|
|
76
92
|
* Follow-up jobs to fan out after a successful consolidation.
|
|
77
93
|
*
|
|
@@ -85,14 +101,14 @@ const FOLLOW_UP_JOB_TYPES: readonly MemoryJobType[] = [
|
|
|
85
101
|
|
|
86
102
|
/**
|
|
87
103
|
* Job handler. See file header for the full lifecycle. Returns a discriminated
|
|
88
|
-
* union so tests can assert on the path taken (
|
|
89
|
-
* invoked) without having to spy on the filesystem.
|
|
104
|
+
* union so tests can assert on the path taken (disabled / locked / empty /
|
|
105
|
+
* invoked / failed) without having to spy on the filesystem.
|
|
90
106
|
*/
|
|
91
107
|
export type ConsolidationOutcome =
|
|
92
|
-
| { kind: "
|
|
108
|
+
| { kind: "disabled" }
|
|
93
109
|
| { kind: "locked"; holder: string }
|
|
94
110
|
| { kind: "empty_buffer" }
|
|
95
|
-
| { kind: "
|
|
111
|
+
| { kind: "run_failed"; reason?: string }
|
|
96
112
|
| {
|
|
97
113
|
kind: "invoked";
|
|
98
114
|
conversationId: string;
|
|
@@ -104,9 +120,9 @@ export async function memoryV2ConsolidateJob(
|
|
|
104
120
|
_job: MemoryJob,
|
|
105
121
|
config: AssistantConfig,
|
|
106
122
|
): Promise<ConsolidationOutcome> {
|
|
107
|
-
if (!
|
|
108
|
-
log.debug("memory
|
|
109
|
-
return { kind: "
|
|
123
|
+
if (!config.memory.v2.enabled) {
|
|
124
|
+
log.debug("memory.v2.enabled is false; consolidation skipped");
|
|
125
|
+
return { kind: "disabled" };
|
|
110
126
|
}
|
|
111
127
|
|
|
112
128
|
const memoryDir = join(getWorkspaceDir(), "memory");
|
|
@@ -122,11 +138,13 @@ export async function memoryV2ConsolidateJob(
|
|
|
122
138
|
}
|
|
123
139
|
|
|
124
140
|
try {
|
|
125
|
-
// Step 2: capture cutoff.
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
|
|
141
|
+
// Step 2: capture cutoff. Formatted to match `buffer.md` entry timestamps
|
|
142
|
+
// (`Mon D, h:mm AM/PM`, see `formatBufferTimestamp`) so the agent's
|
|
143
|
+
// "timestamp ≥ cutoff" check compares like-with-like at minute precision.
|
|
144
|
+
// Same-minute entries land on the next pass — conservative but loss-free.
|
|
145
|
+
// Captured here (not at enqueue time) so late-claimed rows get a fresh
|
|
146
|
+
// cutoff.
|
|
147
|
+
const cutoff = formatBufferTimestamp(new Date());
|
|
130
148
|
|
|
131
149
|
// Step 3: bail on empty buffer. Nothing for the agent to consolidate.
|
|
132
150
|
// The lock is released in finally below.
|
|
@@ -136,57 +154,45 @@ export async function memoryV2ConsolidateJob(
|
|
|
136
154
|
return { kind: "empty_buffer" };
|
|
137
155
|
}
|
|
138
156
|
|
|
139
|
-
// Step 4:
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
157
|
+
// Step 4: hand off to the centralized background-job runner. The runner
|
|
158
|
+
// bootstraps the conversation, drives `processMessage`, applies the
|
|
159
|
+
// timeout policy, classifies errors, and — because we opt out via
|
|
160
|
+
// `suppressFailureNotifications` — does NOT emit an `activity.failed`
|
|
161
|
+
// notification on transient failures. Consolidation runs on tight
|
|
162
|
+
// intervals; a network blip or model hiccup should not spam the feed.
|
|
163
|
+
// Sentry-side reporting is unchanged.
|
|
164
|
+
//
|
|
165
|
+
// The prompt body comes from `resolveConsolidationPrompt`, which honors
|
|
166
|
+
// the `memory.v2.consolidation_prompt_path` config override but bounds
|
|
167
|
+
// it to a regular file under 1 MiB before substitution so a stray path
|
|
168
|
+
// (or a `/dev/zero`-style pseudo-file) cannot exfiltrate megabytes of
|
|
169
|
+
// bytes through the wake hint.
|
|
170
|
+
const runResult = await runBackgroundJob({
|
|
171
|
+
jobName: JOB_NAME,
|
|
146
172
|
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
173
|
+
prompt: resolveConsolidationPrompt(
|
|
174
|
+
config.memory.v2.consolidation_prompt_path,
|
|
175
|
+
cutoff,
|
|
176
|
+
),
|
|
177
|
+
trustContext: { sourceChannel: "vellum", trustClass: "guardian" },
|
|
178
|
+
callSite: "mainAgent",
|
|
179
|
+
timeoutMs: CONSOLIDATION_TIMEOUT_MS,
|
|
147
180
|
origin: "memory_consolidation",
|
|
148
|
-
|
|
149
|
-
groupId: "system:background",
|
|
181
|
+
suppressFailureNotifications: true,
|
|
150
182
|
});
|
|
151
183
|
|
|
152
|
-
|
|
153
|
-
let failureReason: string | undefined;
|
|
154
|
-
try {
|
|
155
|
-
const result = await wakeAgentForOpportunity({
|
|
156
|
-
conversationId: conversation.id,
|
|
157
|
-
hint: resolveConsolidationPrompt(
|
|
158
|
-
config.memory.v2.consolidation_prompt_path,
|
|
159
|
-
cutoff,
|
|
160
|
-
),
|
|
161
|
-
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
162
|
-
trustContext: INTERNAL_GUARDIAN_TRUST_CONTEXT,
|
|
163
|
-
});
|
|
164
|
-
wakeInvoked = result.invoked;
|
|
165
|
-
failureReason = result.reason;
|
|
166
|
-
} catch (err) {
|
|
167
|
-
failureReason = err instanceof Error ? err.message : String(err);
|
|
184
|
+
if (!runResult.ok) {
|
|
168
185
|
log.error(
|
|
169
|
-
{
|
|
170
|
-
|
|
186
|
+
{
|
|
187
|
+
conversationId: runResult.conversationId,
|
|
188
|
+
errorKind: runResult.errorKind,
|
|
189
|
+
err: runResult.error?.message,
|
|
190
|
+
},
|
|
191
|
+
"consolidation run failed; follow-ups skipped",
|
|
171
192
|
);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
// timeout, exception), clean up the orphan background conversation —
|
|
176
|
-
// matches the cleanup logic in `runUpdateBulletinJobIfNeeded`. We
|
|
177
|
-
// do NOT enqueue follow-ups in this branch because no pages changed.
|
|
178
|
-
if (!wakeInvoked) {
|
|
179
|
-
try {
|
|
180
|
-
deleteConversation(conversation.id);
|
|
181
|
-
} catch (err) {
|
|
182
|
-
log.warn(
|
|
183
|
-
{ err, conversationId: conversation.id },
|
|
184
|
-
"consolidation: failed to delete orphan background conversation; continuing",
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
return failureReason !== undefined
|
|
188
|
-
? { kind: "wake_failed", reason: failureReason }
|
|
189
|
-
: { kind: "wake_failed" };
|
|
193
|
+
return runResult.error?.message !== undefined
|
|
194
|
+
? { kind: "run_failed", reason: runResult.error.message }
|
|
195
|
+
: { kind: "run_failed" };
|
|
190
196
|
}
|
|
191
197
|
|
|
192
198
|
// Step 5: enqueue follow-up jobs. Enqueueing now keeps the dispatch
|
|
@@ -208,7 +214,7 @@ export async function memoryV2ConsolidateJob(
|
|
|
208
214
|
|
|
209
215
|
log.info(
|
|
210
216
|
{
|
|
211
|
-
conversationId:
|
|
217
|
+
conversationId: runResult.conversationId,
|
|
212
218
|
cutoff,
|
|
213
219
|
followUpJobIds,
|
|
214
220
|
},
|
|
@@ -216,7 +222,7 @@ export async function memoryV2ConsolidateJob(
|
|
|
216
222
|
);
|
|
217
223
|
return {
|
|
218
224
|
kind: "invoked",
|
|
219
|
-
conversationId:
|
|
225
|
+
conversationId: runResult.conversationId,
|
|
220
226
|
cutoff,
|
|
221
227
|
followUpJobIds,
|
|
222
228
|
};
|
|
@@ -336,7 +342,7 @@ function isHolderStale(holder: string): boolean {
|
|
|
336
342
|
|
|
337
343
|
/**
|
|
338
344
|
* Idempotent unlink of the lock file. Called from the `finally` block so a
|
|
339
|
-
* crash in the
|
|
345
|
+
* crash in the run path doesn't leave the lock stranded. ENOENT is swallowed
|
|
340
346
|
* because the lock may have been released by an operator or never created
|
|
341
347
|
* (acquire failed before reaching the lock-write step).
|
|
342
348
|
*/
|