@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
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Memory retrospective — periodic trigger check.
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// Called from post-turn hooks (after each agent turn completes). Decides
|
|
6
|
+
// whether to enqueue a retrospective for this conversation based on:
|
|
7
|
+
//
|
|
8
|
+
// 1. Cooldown gate: never within `minCooldownMs` of the last attempt
|
|
9
|
+
// (success or failure). Prevents tight retry loops across trigger
|
|
10
|
+
// types.
|
|
11
|
+
// 2. Interval threshold: time since last attempt >= `timeThresholdMs`.
|
|
12
|
+
// 3. Message count threshold: new messages since `lastProcessedMessageId`
|
|
13
|
+
// >= `messageThreshold`.
|
|
14
|
+
//
|
|
15
|
+
// First-run case (no state row) skips the cooldown — `lastRunAt = 0` so the
|
|
16
|
+
// gap is effectively `Infinity`. The interval threshold trips immediately;
|
|
17
|
+
// the message-count threshold trips once enough messages accumulate.
|
|
18
|
+
|
|
19
|
+
import type { AssistantConfig } from "../config/types.js";
|
|
20
|
+
import { getLogger } from "../util/logger.js";
|
|
21
|
+
import { countMessagesAfter } from "./conversation-crud.js";
|
|
22
|
+
import { enqueueMemoryRetrospectiveIfEnabled } from "./memory-retrospective-enqueue.js";
|
|
23
|
+
import { getRetrospectiveState } from "./memory-retrospective-state.js";
|
|
24
|
+
|
|
25
|
+
const log = getLogger("memory-retrospective-trigger-check");
|
|
26
|
+
|
|
27
|
+
export type RetrospectiveTrigger = "interval" | "message_count";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the trigger kind that fired, or `null` if no threshold tripped.
|
|
31
|
+
* Exported separately from `maybeEnqueueRetrospective` so tests can assert on
|
|
32
|
+
* the decision without observing side effects.
|
|
33
|
+
*/
|
|
34
|
+
export function shouldEnqueueRetrospective(args: {
|
|
35
|
+
state: { lastProcessedMessageId: string; lastRunAt: number } | null;
|
|
36
|
+
newMessageCount: number;
|
|
37
|
+
now: number;
|
|
38
|
+
timeThresholdMs: number;
|
|
39
|
+
messageThreshold: number;
|
|
40
|
+
minCooldownMs: number;
|
|
41
|
+
}): RetrospectiveTrigger | null {
|
|
42
|
+
const {
|
|
43
|
+
state,
|
|
44
|
+
newMessageCount,
|
|
45
|
+
now,
|
|
46
|
+
timeThresholdMs,
|
|
47
|
+
messageThreshold,
|
|
48
|
+
minCooldownMs,
|
|
49
|
+
} = args;
|
|
50
|
+
|
|
51
|
+
if (state && now - state.lastRunAt < minCooldownMs) return null;
|
|
52
|
+
|
|
53
|
+
if (state && now - state.lastRunAt >= timeThresholdMs) return "interval";
|
|
54
|
+
if (!state) return "interval";
|
|
55
|
+
|
|
56
|
+
if (newMessageCount >= messageThreshold) return "message_count";
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Post-turn hook entry point. Looks up state, counts new messages, evaluates
|
|
62
|
+
* thresholds, and enqueues if appropriate. Best-effort — any thrown error is
|
|
63
|
+
* caught and logged so the agent turn cleanup path doesn't fail.
|
|
64
|
+
*/
|
|
65
|
+
export function maybeEnqueueRetrospective(
|
|
66
|
+
conversationId: string,
|
|
67
|
+
config: AssistantConfig,
|
|
68
|
+
): void {
|
|
69
|
+
try {
|
|
70
|
+
const state = getRetrospectiveState(conversationId);
|
|
71
|
+
const newMessageCount = countMessagesAfter(
|
|
72
|
+
conversationId,
|
|
73
|
+
state?.lastProcessedMessageId ?? null,
|
|
74
|
+
);
|
|
75
|
+
if (newMessageCount === 0) return;
|
|
76
|
+
|
|
77
|
+
const trigger = shouldEnqueueRetrospective({
|
|
78
|
+
state,
|
|
79
|
+
newMessageCount,
|
|
80
|
+
now: Date.now(),
|
|
81
|
+
timeThresholdMs: config.memory.retrospective.timeThresholdMs,
|
|
82
|
+
messageThreshold: config.memory.retrospective.messageThreshold,
|
|
83
|
+
minCooldownMs: config.memory.retrospective.minCooldownMs,
|
|
84
|
+
});
|
|
85
|
+
if (!trigger) return;
|
|
86
|
+
|
|
87
|
+
enqueueMemoryRetrospectiveIfEnabled({ conversationId, trigger });
|
|
88
|
+
} catch (err) {
|
|
89
|
+
log.warn({ err, conversationId }, "trigger-check failed; skipping enqueue");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -39,8 +39,43 @@ export interface MemoryV2ConceptRowRecord {
|
|
|
39
39
|
*/
|
|
40
40
|
inRerankPool: boolean;
|
|
41
41
|
spreadContribution: number;
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Provenance of this concept row.
|
|
44
|
+
* - `prior_state` — carried over from prior turn's activation state.
|
|
45
|
+
* - `ann_top50` — entered via ANN top-K candidate pool.
|
|
46
|
+
* - `both` — present in both prior state and ANN pool.
|
|
47
|
+
* - `router` — selected by the Sonnet router (memory-v2 router
|
|
48
|
+
* mode). Router-mode rows zero out all activation values
|
|
49
|
+
* (`finalActivation`, `ownActivation`, `priorActivation`, channel
|
|
50
|
+
* similarities, rerank boosts, `spreadContribution`) because the
|
|
51
|
+
* router does not compute spreading-activation scores.
|
|
52
|
+
* - `carry_over` — router-mode row representing a slug carried over
|
|
53
|
+
* from `priorEverInjected` that the router did NOT re-pick on this
|
|
54
|
+
* turn. The cached attachment from a prior turn is still present
|
|
55
|
+
* on a prior user message; emitting `source: "router"` for these
|
|
56
|
+
* rows would overcount router selections in inspector queries.
|
|
57
|
+
* Same zeroed activation values as `router`.
|
|
58
|
+
*/
|
|
59
|
+
source: "prior_state" | "ann_top50" | "both" | "router" | "carry_over";
|
|
60
|
+
/**
|
|
61
|
+
* Per-turn outcome for this slug:
|
|
62
|
+
* - `in_context` — already injected on a prior turn; cached attachment
|
|
63
|
+
* remains visible without re-rendering.
|
|
64
|
+
* - `injected` — freshly rendered into this turn's user message.
|
|
65
|
+
* - `not_injected`— a candidate that didn't make `slugsToRender`.
|
|
66
|
+
* - `page_missing`— would-have-been-injected, but `readPage` returned
|
|
67
|
+
* null (file vanished between selection and render — stale Qdrant
|
|
68
|
+
* or edge-index entry).
|
|
69
|
+
* - `corrupt` — would-have-been-injected, but `readPage` threw
|
|
70
|
+
* (e.g. malformed frontmatter). Other slugs in the same batch
|
|
71
|
+
* rendered normally.
|
|
72
|
+
*/
|
|
73
|
+
status:
|
|
74
|
+
| "in_context"
|
|
75
|
+
| "injected"
|
|
76
|
+
| "not_injected"
|
|
77
|
+
| "page_missing"
|
|
78
|
+
| "corrupt";
|
|
44
79
|
}
|
|
45
80
|
|
|
46
81
|
export interface MemoryV2ConfigSnapshot {
|
|
@@ -57,7 +92,16 @@ export interface MemoryV2ConfigSnapshot {
|
|
|
57
92
|
export interface RecordMemoryV2ActivationLogParams {
|
|
58
93
|
conversationId: string;
|
|
59
94
|
turn: number;
|
|
60
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Call-site mode: `context-load` for fresh / post-compaction loads,
|
|
97
|
+
* `per-turn` for normal append injections, `errored` when `injectMemoryV2Block`
|
|
98
|
+
* threw before completing — telemetry is still written so silent failures
|
|
99
|
+
* are observable in the database, with whatever `concepts` rows had been
|
|
100
|
+
* built so far (possibly empty). `router` indicates the Sonnet
|
|
101
|
+
* router selected the per-turn page set; router-mode rows carry zeroed
|
|
102
|
+
* activation values and `source: "router"` on every concept row.
|
|
103
|
+
*/
|
|
104
|
+
mode: "context-load" | "per-turn" | "errored" | "router";
|
|
61
105
|
concepts: MemoryV2ConceptRowRecord[];
|
|
62
106
|
config: MemoryV2ConfigSnapshot;
|
|
63
107
|
}
|
|
@@ -105,7 +149,7 @@ export function backfillMemoryV2ActivationMessageId(
|
|
|
105
149
|
export interface MemoryV2ActivationLog {
|
|
106
150
|
conversationId: string;
|
|
107
151
|
turn: number;
|
|
108
|
-
mode: "context-load" | "per-turn";
|
|
152
|
+
mode: "context-load" | "per-turn" | "errored" | "router";
|
|
109
153
|
concepts: MemoryV2ConceptRowRecord[];
|
|
110
154
|
config: MemoryV2ConfigSnapshot;
|
|
111
155
|
}
|
|
@@ -126,7 +170,7 @@ export function getMemoryV2ActivationLogByMessageIds(
|
|
|
126
170
|
return {
|
|
127
171
|
conversationId: row.conversationId,
|
|
128
172
|
turn: row.turn,
|
|
129
|
-
mode: row.mode as "context-load" | "per-turn",
|
|
173
|
+
mode: row.mode as "context-load" | "per-turn" | "errored" | "router",
|
|
130
174
|
concepts: JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[],
|
|
131
175
|
config: JSON.parse(row.configJson) as MemoryV2ConfigSnapshot,
|
|
132
176
|
};
|
|
@@ -52,6 +52,7 @@ const ZERO_COUNTS: ConceptFrequencyCounts = {
|
|
|
52
52
|
in_context: 0,
|
|
53
53
|
not_injected: 0,
|
|
54
54
|
page_missing: 0,
|
|
55
|
+
corrupt: 0,
|
|
55
56
|
};
|
|
56
57
|
|
|
57
58
|
interface CountRow {
|
|
@@ -130,6 +131,9 @@ export async function getConceptFrequencySummary(
|
|
|
130
131
|
case "page_missing":
|
|
131
132
|
entry.counts.page_missing += row.count;
|
|
132
133
|
break;
|
|
134
|
+
case "corrupt":
|
|
135
|
+
entry.counts.corrupt += row.count;
|
|
136
|
+
break;
|
|
133
137
|
default:
|
|
134
138
|
// Forward-compat: unknown status values are ignored, not summed into
|
|
135
139
|
// totalEvaluations. The activation pipeline produces a closed enum.
|
|
@@ -121,7 +121,6 @@ export function extractMediaBlockMeta(
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
|
|
125
124
|
function stableJson(value: unknown): string {
|
|
126
125
|
try {
|
|
127
126
|
return JSON.stringify(value);
|
|
@@ -129,3 +128,41 @@ function stableJson(value: unknown): string {
|
|
|
129
128
|
return "<unserializable />";
|
|
130
129
|
}
|
|
131
130
|
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Coerce stored message content into a single human-readable text string,
|
|
134
|
+
* dropping non-text blocks (images, tool calls, tool results, thinking,
|
|
135
|
+
* …). Used by call sites that want only the spoken text — sweep-model
|
|
136
|
+
* context, RAG backfill, bookmark previews. For richer renderings that
|
|
137
|
+
* include tool metadata, use {@link extractTextFromStoredMessageContent}
|
|
138
|
+
* instead.
|
|
139
|
+
*
|
|
140
|
+
* Handles the two on-disk shapes:
|
|
141
|
+
* - Modern rows: JSON-serialized `ContentBlock[]`
|
|
142
|
+
* - Legacy rows: plain string
|
|
143
|
+
*
|
|
144
|
+
* Parse failures fall back to returning the raw input trimmed (the
|
|
145
|
+
* legacy-string path).
|
|
146
|
+
*/
|
|
147
|
+
export function stringifyMessageContent(stored: string): string {
|
|
148
|
+
let parsed: unknown;
|
|
149
|
+
try {
|
|
150
|
+
parsed = JSON.parse(stored);
|
|
151
|
+
} catch {
|
|
152
|
+
return stored.trim();
|
|
153
|
+
}
|
|
154
|
+
if (typeof parsed === "string") return parsed.trim();
|
|
155
|
+
if (!Array.isArray(parsed)) return "";
|
|
156
|
+
const parts: string[] = [];
|
|
157
|
+
for (const block of parsed) {
|
|
158
|
+
if (
|
|
159
|
+
block &&
|
|
160
|
+
typeof block === "object" &&
|
|
161
|
+
(block as { type?: string }).type === "text" &&
|
|
162
|
+
typeof (block as { text?: unknown }).text === "string"
|
|
163
|
+
) {
|
|
164
|
+
parts.push((block as { text: string }).text);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return parts.join("\n").trim();
|
|
168
|
+
}
|
|
@@ -8,8 +8,13 @@ export function migrateAddConversationInferenceProfile(
|
|
|
8
8
|
const columns = raw.query(`PRAGMA table_info(conversations)`).all() as Array<{
|
|
9
9
|
name: string;
|
|
10
10
|
}>;
|
|
11
|
+
// Skip if either the original camelCase column or the renamed snake_case
|
|
12
|
+
// column from migration 228 is already present. Without the snake_case
|
|
13
|
+
// check, this migration would re-add the camelCase column on every boot
|
|
14
|
+
// after 228 runs, leaving both columns permanently.
|
|
11
15
|
const hasColumn = columns.some(
|
|
12
|
-
(column) =>
|
|
16
|
+
(column) =>
|
|
17
|
+
column.name === "inferenceProfile" || column.name === "inference_profile",
|
|
13
18
|
);
|
|
14
19
|
if (hasColumn) {
|
|
15
20
|
return;
|
|
@@ -6,19 +6,32 @@ import { tableHasColumn } from "./schema-introspection.js";
|
|
|
6
6
|
* by migration 227) to `inference_profile` so it matches the snake_case
|
|
7
7
|
* convention used by every other column on the table.
|
|
8
8
|
*
|
|
9
|
-
* Idempotent:
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Idempotent and self-healing:
|
|
10
|
+
* - both columns present → drop the camelCase one (heals instances that
|
|
11
|
+
* already booted twice with the original buggy migration 227, where 227
|
|
12
|
+
* re-added the camelCase column after this migration renamed it).
|
|
13
|
+
* - camelCase column present, snake_case absent → rename it.
|
|
14
|
+
* - snake_case column present, camelCase absent → no-op.
|
|
15
|
+
* - neither column present → no-op.
|
|
14
16
|
*/
|
|
15
17
|
export function migrateRenameInferenceProfileSnakeCase(
|
|
16
18
|
database: DrizzleDb,
|
|
17
19
|
): void {
|
|
18
|
-
|
|
20
|
+
const hasSnake = tableHasColumn(
|
|
21
|
+
database,
|
|
22
|
+
"conversations",
|
|
23
|
+
"inference_profile",
|
|
24
|
+
);
|
|
25
|
+
const hasCamel = tableHasColumn(
|
|
26
|
+
database,
|
|
27
|
+
"conversations",
|
|
28
|
+
"inferenceProfile",
|
|
29
|
+
);
|
|
30
|
+
if (hasSnake && hasCamel) {
|
|
31
|
+
database.run(`ALTER TABLE conversations DROP COLUMN inferenceProfile`);
|
|
19
32
|
return;
|
|
20
33
|
}
|
|
21
|
-
if (!
|
|
34
|
+
if (!hasCamel) {
|
|
22
35
|
return;
|
|
23
36
|
}
|
|
24
37
|
database.run(
|
|
@@ -615,7 +615,8 @@ function seedGuardianAndApprovalRows(raw: Database, now: number): void {
|
|
|
615
615
|
created_at,
|
|
616
616
|
updated_at
|
|
617
617
|
) VALUES
|
|
618
|
-
('call-standard-guardian', 'conv-standard', 'test-provider', '+15550100', '+15550101', 'initiated', ${now}, ${now})
|
|
618
|
+
('call-standard-guardian', 'conv-standard', 'test-provider', '+15550100', '+15550101', 'initiated', ${now}, ${now}),
|
|
619
|
+
('call-private-guardian', 'conv-private', 'test-provider', '+15550102', '+15550103', 'initiated', ${now}, ${now});
|
|
619
620
|
|
|
620
621
|
INSERT INTO call_pending_questions (
|
|
621
622
|
id,
|
|
@@ -708,6 +709,23 @@ function seedGuardianAndApprovalRows(raw: Database, now: number): void {
|
|
|
708
709
|
('scoped-grant-standard', 'request_id', 'canonical-request-standard', NULL, NULL, 'vellum', 'vellum', 'conv-standard', 'active', ${now + 60000}, ${now}, ${now}),
|
|
709
710
|
('scoped-grant-unscoped', 'tool_signature', NULL, 'test_tool', 'digest-123', 'vellum', 'vellum', NULL, 'active', ${now + 60000}, ${now}, ${now});
|
|
710
711
|
|
|
712
|
+
INSERT INTO scoped_approval_grants (
|
|
713
|
+
id,
|
|
714
|
+
scope_mode,
|
|
715
|
+
request_id,
|
|
716
|
+
tool_name,
|
|
717
|
+
input_digest,
|
|
718
|
+
request_channel,
|
|
719
|
+
decision_channel,
|
|
720
|
+
conversation_id,
|
|
721
|
+
call_session_id,
|
|
722
|
+
status,
|
|
723
|
+
expires_at,
|
|
724
|
+
created_at,
|
|
725
|
+
updated_at
|
|
726
|
+
) VALUES
|
|
727
|
+
('scoped-grant-private-call-only', 'tool_signature', NULL, 'test_tool', 'digest-456', 'vellum', 'vellum', NULL, 'call-private-guardian', 'active', ${now + 60000}, ${now}, ${now});
|
|
728
|
+
|
|
711
729
|
INSERT INTO channel_guardian_approval_requests (
|
|
712
730
|
id,
|
|
713
731
|
run_id,
|
|
@@ -1034,6 +1052,13 @@ describe("migrateDeletePrivateConversations", () => {
|
|
|
1034
1052
|
expect(
|
|
1035
1053
|
countWhere(raw, "scoped_approval_grants", `id = 'scoped-grant-unscoped'`),
|
|
1036
1054
|
).toBe(1);
|
|
1055
|
+
expect(
|
|
1056
|
+
countWhere(
|
|
1057
|
+
raw,
|
|
1058
|
+
"scoped_approval_grants",
|
|
1059
|
+
`id = 'scoped-grant-private-call-only'`,
|
|
1060
|
+
),
|
|
1061
|
+
).toBe(0);
|
|
1037
1062
|
expect(
|
|
1038
1063
|
countWhere(
|
|
1039
1064
|
raw,
|
|
@@ -1084,4 +1109,48 @@ describe("migrateDeletePrivateConversations", () => {
|
|
|
1084
1109
|
),
|
|
1085
1110
|
).toBe(1);
|
|
1086
1111
|
});
|
|
1112
|
+
|
|
1113
|
+
test("removes orphan attachments left by prior runs that deleted private messages", () => {
|
|
1114
|
+
const db = createTestDb();
|
|
1115
|
+
const raw = getSqliteFrom(db);
|
|
1116
|
+
const now = Date.now();
|
|
1117
|
+
|
|
1118
|
+
bootstrapTables(raw);
|
|
1119
|
+
seedConversation(raw, "conv-standard", "standard");
|
|
1120
|
+
raw.exec(/*sql*/ `
|
|
1121
|
+
INSERT INTO attachments (
|
|
1122
|
+
id,
|
|
1123
|
+
original_filename,
|
|
1124
|
+
mime_type,
|
|
1125
|
+
size_bytes,
|
|
1126
|
+
kind,
|
|
1127
|
+
data_base64,
|
|
1128
|
+
created_at
|
|
1129
|
+
) VALUES (
|
|
1130
|
+
'orphan-private-attachment',
|
|
1131
|
+
'leaked.txt',
|
|
1132
|
+
'text/plain',
|
|
1133
|
+
1,
|
|
1134
|
+
'text',
|
|
1135
|
+
'eA==',
|
|
1136
|
+
${now}
|
|
1137
|
+
);
|
|
1138
|
+
`);
|
|
1139
|
+
|
|
1140
|
+
expect(
|
|
1141
|
+
countWhere(raw, "attachments", `id = 'orphan-private-attachment'`),
|
|
1142
|
+
).toBe(1);
|
|
1143
|
+
expect(
|
|
1144
|
+
countWhere(raw, "attachments", `id = 'conv-standard-attachment'`),
|
|
1145
|
+
).toBe(1);
|
|
1146
|
+
|
|
1147
|
+
migrateDeletePrivateConversations(db);
|
|
1148
|
+
|
|
1149
|
+
expect(
|
|
1150
|
+
countWhere(raw, "attachments", `id = 'orphan-private-attachment'`),
|
|
1151
|
+
).toBe(0);
|
|
1152
|
+
expect(
|
|
1153
|
+
countWhere(raw, "attachments", `id = 'conv-standard-attachment'`),
|
|
1154
|
+
).toBe(1);
|
|
1155
|
+
});
|
|
1087
1156
|
});
|
|
@@ -47,6 +47,10 @@ export function migrateDeletePrivateConversations(database: DrizzleDb): void {
|
|
|
47
47
|
database.run(/*sql*/ `
|
|
48
48
|
DELETE FROM scoped_approval_grants
|
|
49
49
|
WHERE conversation_id IN (${PRIVATE_CONVERSATION_IDS})
|
|
50
|
+
OR call_session_id IN (
|
|
51
|
+
SELECT id FROM call_sessions
|
|
52
|
+
WHERE conversation_id IN (${PRIVATE_CONVERSATION_IDS})
|
|
53
|
+
)
|
|
50
54
|
`);
|
|
51
55
|
database.run(/*sql*/ `
|
|
52
56
|
DELETE FROM guardian_action_deliveries
|
|
@@ -193,6 +197,14 @@ export function migrateDeletePrivateConversations(database: DrizzleDb): void {
|
|
|
193
197
|
DELETE FROM messages
|
|
194
198
|
WHERE conversation_id IN (${PRIVATE_CONVERSATION_IDS})
|
|
195
199
|
`);
|
|
200
|
+
database.run(/*sql*/ `
|
|
201
|
+
DELETE FROM attachments
|
|
202
|
+
WHERE NOT EXISTS (
|
|
203
|
+
SELECT 1
|
|
204
|
+
FROM message_attachments ma
|
|
205
|
+
WHERE ma.attachment_id = attachments.id
|
|
206
|
+
)
|
|
207
|
+
`);
|
|
196
208
|
database.run(/*sql*/ `
|
|
197
209
|
DELETE FROM memory_summaries
|
|
198
210
|
WHERE scope_id LIKE 'private:%'
|
|
@@ -12,6 +12,7 @@ interface GraphNodeEventDateRow {
|
|
|
12
12
|
id: string;
|
|
13
13
|
created: number;
|
|
14
14
|
event_date: number;
|
|
15
|
+
content: string;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
interface EventDateRepair {
|
|
@@ -37,9 +38,14 @@ function replaceUtcYear(epochMs: number, year: number): number {
|
|
|
37
38
|
);
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
function contentMentionsYear(content: string, year: number): boolean {
|
|
42
|
+
return new RegExp(`\\b${year}\\b`).test(content);
|
|
43
|
+
}
|
|
44
|
+
|
|
40
45
|
export function repairMemoryGraphEventDate(
|
|
41
46
|
createdMs: number,
|
|
42
47
|
eventDateMs: number,
|
|
48
|
+
content: string,
|
|
43
49
|
): number | null {
|
|
44
50
|
if (!Number.isFinite(createdMs) || !Number.isFinite(eventDateMs)) {
|
|
45
51
|
return null;
|
|
@@ -50,6 +56,10 @@ export function repairMemoryGraphEventDate(
|
|
|
50
56
|
if (createdYear !== REPAIR_CREATED_YEAR) return null;
|
|
51
57
|
if (!CORRUPT_EVENT_YEARS.includes(eventYear as 2024 | 2025)) return null;
|
|
52
58
|
|
|
59
|
+
// If the memory's prose explicitly mentions the prior year, the date is
|
|
60
|
+
// user-anchored history — not the partial-date inference bug — so leave it.
|
|
61
|
+
if (contentMentionsYear(content, eventYear)) return null;
|
|
62
|
+
|
|
53
63
|
const corrected = replaceUtcYear(eventDateMs, createdYear);
|
|
54
64
|
if (corrected === eventDateMs) return null;
|
|
55
65
|
|
|
@@ -71,7 +81,7 @@ export function migrate231RepairMemoryGraphEventDates(
|
|
|
71
81
|
const rows = raw
|
|
72
82
|
.query(
|
|
73
83
|
/*sql*/ `
|
|
74
|
-
SELECT id, created, event_date
|
|
84
|
+
SELECT id, created, event_date, content
|
|
75
85
|
FROM memory_graph_nodes
|
|
76
86
|
WHERE event_date IS NOT NULL
|
|
77
87
|
AND CAST(strftime('%Y', created / 1000, 'unixepoch') AS INTEGER) = ?
|
|
@@ -85,7 +95,11 @@ export function migrate231RepairMemoryGraphEventDates(
|
|
|
85
95
|
|
|
86
96
|
const repairs: EventDateRepair[] = [];
|
|
87
97
|
for (const row of rows) {
|
|
88
|
-
const corrected = repairMemoryGraphEventDate(
|
|
98
|
+
const corrected = repairMemoryGraphEventDate(
|
|
99
|
+
row.created,
|
|
100
|
+
row.event_date,
|
|
101
|
+
row.content ?? "",
|
|
102
|
+
);
|
|
89
103
|
if (corrected == null) continue;
|
|
90
104
|
repairs.push({
|
|
91
105
|
id: row.id,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
export function migrateConversationInferenceProfileSession(
|
|
5
|
+
database: DrizzleDb,
|
|
6
|
+
): void {
|
|
7
|
+
const raw = getSqliteFrom(database);
|
|
8
|
+
try {
|
|
9
|
+
raw.exec(
|
|
10
|
+
`ALTER TABLE conversations ADD COLUMN inference_profile_session_id TEXT DEFAULT NULL`,
|
|
11
|
+
);
|
|
12
|
+
} catch {
|
|
13
|
+
// Column already exists — nothing to do.
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
raw.exec(
|
|
17
|
+
`ALTER TABLE conversations ADD COLUMN inference_profile_expires_at INTEGER DEFAULT NULL`,
|
|
18
|
+
);
|
|
19
|
+
} catch {
|
|
20
|
+
// Column already exists — nothing to do.
|
|
21
|
+
}
|
|
22
|
+
raw.exec(
|
|
23
|
+
`CREATE INDEX IF NOT EXISTS idx_conversations_inference_profile_expires_at ON conversations (inference_profile_expires_at) WHERE inference_profile_expires_at IS NOT NULL`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Rebuild activation_state to add a foreign key on conversation_id with
|
|
5
|
+
* ON DELETE CASCADE so rows are cleaned up when their conversation is
|
|
6
|
+
* deleted, matching the pattern of conversation_graph_memory_state and
|
|
7
|
+
* every other conversation-keyed table. SQLite doesn't support
|
|
8
|
+
* ALTER TABLE ADD CONSTRAINT, so we rebuild the table; the INSERT...SELECT
|
|
9
|
+
* filters out any orphan rows already accumulated under the prior schema.
|
|
10
|
+
*/
|
|
11
|
+
export function migrateActivationStateFkCascade(database: DrizzleDb): void {
|
|
12
|
+
const raw = getSqliteFrom(database);
|
|
13
|
+
const row = raw
|
|
14
|
+
.query(
|
|
15
|
+
`SELECT sql FROM sqlite_master WHERE type='table' AND name='activation_state'`,
|
|
16
|
+
)
|
|
17
|
+
.get() as { sql: string } | null;
|
|
18
|
+
if (!row) return;
|
|
19
|
+
if (row.sql.includes("ON DELETE CASCADE")) return;
|
|
20
|
+
|
|
21
|
+
raw.exec("PRAGMA foreign_keys = OFF");
|
|
22
|
+
try {
|
|
23
|
+
raw.exec(/*sql*/ `
|
|
24
|
+
BEGIN;
|
|
25
|
+
CREATE TABLE activation_state_new (
|
|
26
|
+
conversation_id TEXT PRIMARY KEY REFERENCES conversations(id) ON DELETE CASCADE,
|
|
27
|
+
message_id TEXT NOT NULL,
|
|
28
|
+
state_json TEXT NOT NULL,
|
|
29
|
+
ever_injected_json TEXT NOT NULL DEFAULT '[]',
|
|
30
|
+
current_turn INTEGER NOT NULL DEFAULT 0,
|
|
31
|
+
updated_at INTEGER NOT NULL
|
|
32
|
+
);
|
|
33
|
+
INSERT INTO activation_state_new
|
|
34
|
+
SELECT a.* FROM activation_state a
|
|
35
|
+
WHERE EXISTS (SELECT 1 FROM conversations c WHERE c.id = a.conversation_id);
|
|
36
|
+
DROP TABLE activation_state;
|
|
37
|
+
ALTER TABLE activation_state_new RENAME TO activation_state;
|
|
38
|
+
COMMIT;
|
|
39
|
+
`);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
try {
|
|
42
|
+
raw.exec("ROLLBACK");
|
|
43
|
+
} catch {
|
|
44
|
+
/* no active transaction */
|
|
45
|
+
}
|
|
46
|
+
throw e;
|
|
47
|
+
} finally {
|
|
48
|
+
raw.exec("PRAGMA foreign_keys = ON");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
4
|
+
|
|
5
|
+
const CHECKPOINT_KEY = "migration_message_bookmarks_v1";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create the message_bookmarks table for user-saved message bookmarks.
|
|
9
|
+
*
|
|
10
|
+
* Both foreign keys cascade so bookmarks are cleaned up automatically when
|
|
11
|
+
* their parent message or conversation is deleted. A unique index on
|
|
12
|
+
* message_id keeps the create-bookmark code path idempotent (a message can
|
|
13
|
+
* be bookmarked at most once at a time).
|
|
14
|
+
*/
|
|
15
|
+
export function migrateMessageBookmarks(database: DrizzleDb): void {
|
|
16
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
17
|
+
const raw = getSqliteFrom(database);
|
|
18
|
+
|
|
19
|
+
raw.exec(/*sql*/ `
|
|
20
|
+
CREATE TABLE IF NOT EXISTS message_bookmarks (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
|
|
23
|
+
conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
|
|
24
|
+
created_at INTEGER NOT NULL
|
|
25
|
+
)
|
|
26
|
+
`);
|
|
27
|
+
|
|
28
|
+
raw.exec(/*sql*/ `
|
|
29
|
+
CREATE UNIQUE INDEX IF NOT EXISTS message_bookmarks_message_id_uniq
|
|
30
|
+
ON message_bookmarks (message_id)
|
|
31
|
+
`);
|
|
32
|
+
|
|
33
|
+
raw.exec(/*sql*/ `
|
|
34
|
+
CREATE INDEX IF NOT EXISTS message_bookmarks_created_at_idx
|
|
35
|
+
ON message_bookmarks (created_at)
|
|
36
|
+
`);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates the `provider_connections` table and seeds the three canonical
|
|
5
|
+
* connections that every installation ships with.
|
|
6
|
+
*
|
|
7
|
+
* Canonical connections:
|
|
8
|
+
* - anthropic-managed → provider=anthropic, auth={type:platform}
|
|
9
|
+
* - openai-managed → provider=openai, auth={type:platform}
|
|
10
|
+
* - gemini-managed → provider=gemini, auth={type:platform}
|
|
11
|
+
*
|
|
12
|
+
* Idempotent: checks sqlite_master for the table before running DDL;
|
|
13
|
+
* canonical rows are inserted with INSERT OR IGNORE.
|
|
14
|
+
*/
|
|
15
|
+
export function migrateCreateProviderConnections(database: DrizzleDb): void {
|
|
16
|
+
const raw = getSqliteFrom(database);
|
|
17
|
+
|
|
18
|
+
const tableExists = raw
|
|
19
|
+
.query(
|
|
20
|
+
`SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_connections'`,
|
|
21
|
+
)
|
|
22
|
+
.get();
|
|
23
|
+
|
|
24
|
+
if (!tableExists) {
|
|
25
|
+
try {
|
|
26
|
+
raw.exec("BEGIN");
|
|
27
|
+
|
|
28
|
+
raw.exec(/*sql*/ `
|
|
29
|
+
CREATE TABLE provider_connections (
|
|
30
|
+
name TEXT PRIMARY KEY,
|
|
31
|
+
provider TEXT NOT NULL,
|
|
32
|
+
auth TEXT NOT NULL,
|
|
33
|
+
created_at INTEGER NOT NULL,
|
|
34
|
+
updated_at INTEGER NOT NULL
|
|
35
|
+
)
|
|
36
|
+
`);
|
|
37
|
+
|
|
38
|
+
raw.exec(/*sql*/ `
|
|
39
|
+
CREATE INDEX idx_provider_connections_provider
|
|
40
|
+
ON provider_connections(provider)
|
|
41
|
+
`);
|
|
42
|
+
|
|
43
|
+
raw.exec("COMMIT");
|
|
44
|
+
} catch (e) {
|
|
45
|
+
try {
|
|
46
|
+
raw.exec("ROLLBACK");
|
|
47
|
+
} catch {
|
|
48
|
+
/* no active transaction */
|
|
49
|
+
}
|
|
50
|
+
throw e;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Seed canonical connections — idempotent via INSERT OR IGNORE.
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const canonicals = [
|
|
57
|
+
{ name: "anthropic-managed", provider: "anthropic", auth: JSON.stringify({ type: "platform" }) },
|
|
58
|
+
{ name: "openai-managed", provider: "openai", auth: JSON.stringify({ type: "platform" }) },
|
|
59
|
+
{ name: "gemini-managed", provider: "gemini", auth: JSON.stringify({ type: "platform" }) },
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
for (const { name, provider, auth } of canonicals) {
|
|
63
|
+
raw.run(
|
|
64
|
+
`INSERT OR IGNORE INTO provider_connections (name, provider, auth, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`,
|
|
65
|
+
[name, provider, auth, now, now],
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|