@vellumai/assistant 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -0
- package/Dockerfile +5 -4
- package/README.md +2 -2
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +23 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +148 -127
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +628 -10
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +19 -3
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +303 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +334 -86
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +22 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds `status` (NOT NULL DEFAULT 'active') and `label` (nullable) columns
|
|
5
|
+
* to the `provider_connections` table.
|
|
6
|
+
*
|
|
7
|
+
* Idempotent: reads PRAGMA table_info before each ALTER so re-running on a
|
|
8
|
+
* database that already has the columns is a no-op.
|
|
9
|
+
*/
|
|
10
|
+
export function migrateProviderConnectionStatusLabel(database: DrizzleDb): void {
|
|
11
|
+
const raw = getSqliteFrom(database);
|
|
12
|
+
|
|
13
|
+
const columns = raw.query(`PRAGMA table_info(provider_connections)`).all() as Array<{ name: string }>;
|
|
14
|
+
const columnNames = new Set(columns.map((c) => c.name));
|
|
15
|
+
|
|
16
|
+
if (!columnNames.has("status")) {
|
|
17
|
+
raw.exec(`ALTER TABLE provider_connections ADD COLUMN status TEXT NOT NULL DEFAULT 'active'`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!columnNames.has("label")) {
|
|
21
|
+
raw.exec(`ALTER TABLE provider_connections ADD COLUMN label TEXT`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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_memory_retrospective_state_v1";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create the memory_retrospective_state table.
|
|
9
|
+
*
|
|
10
|
+
* One row per source conversation tracks two independent pointers used by
|
|
11
|
+
* the memory-retrospective background job:
|
|
12
|
+
*
|
|
13
|
+
* - `last_processed_message_id`: advances ONLY when a retrospective run
|
|
14
|
+
* completes successfully (wake invoked + returned without error). On any
|
|
15
|
+
* failure path this stays unchanged so the next run reprocesses the same
|
|
16
|
+
* messages — the load-bearing correctness invariant.
|
|
17
|
+
* - `last_run_at`: advances on EVERY job end (success or failure). Drives
|
|
18
|
+
* the per-conversation cooldown gate in the trigger-check helper so a
|
|
19
|
+
* failing job can't loop in tight retries across trigger types.
|
|
20
|
+
*
|
|
21
|
+
* The foreign key cascades so the state row dies with its source
|
|
22
|
+
* conversation. Without the cascade, deleted conversations would leak rows.
|
|
23
|
+
*/
|
|
24
|
+
export function migrateMemoryRetrospectiveState(database: DrizzleDb): void {
|
|
25
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
26
|
+
const raw = getSqliteFrom(database);
|
|
27
|
+
|
|
28
|
+
raw.exec(/*sql*/ `
|
|
29
|
+
CREATE TABLE IF NOT EXISTS memory_retrospective_state (
|
|
30
|
+
conversation_id TEXT PRIMARY KEY REFERENCES conversations(id) ON DELETE CASCADE,
|
|
31
|
+
last_processed_message_id TEXT NOT NULL,
|
|
32
|
+
last_run_at INTEGER NOT NULL
|
|
33
|
+
)
|
|
34
|
+
`);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One-shot backfill: set `label = name` for any `provider_connections` row
|
|
5
|
+
* whose `label` is NULL (or empty after trim). Migration 244 added the
|
|
6
|
+
* `label` column as nullable with no default, so every row that existed
|
|
7
|
+
* pre-244 (and any row created against an older client that didn't yet
|
|
8
|
+
* write a label) ended up with NULL.
|
|
9
|
+
*
|
|
10
|
+
* Why this matters for users: in 0.8.x the editor modal renders Display
|
|
11
|
+
* Name from `label` and shows the empty-state placeholder ("e.g. My
|
|
12
|
+
* OpenAI") whenever it's null. Users who created connections before the
|
|
13
|
+
* label field existed open the editor and see what looks like an empty
|
|
14
|
+
* field, then conclude their data was wiped during the upgrade.
|
|
15
|
+
*
|
|
16
|
+
* The fix is to give every pre-feature row a sensible default — its own
|
|
17
|
+
* connection name. The list view already falls back to `name` when label
|
|
18
|
+
* is empty (see ProvidersSheet.swift `connectionRow`), so this brings the
|
|
19
|
+
* editor into agreement with what's already on screen.
|
|
20
|
+
*
|
|
21
|
+
* Idempotency: guarded by `memory_checkpoints` so a second boot won't
|
|
22
|
+
* re-clobber a label the user has intentionally cleared after the
|
|
23
|
+
* backfill ran. New rows created post-backfill follow the normal
|
|
24
|
+
* label-is-optional contract.
|
|
25
|
+
*/
|
|
26
|
+
export function migrateBackfillProviderConnectionLabel(database: DrizzleDb): void {
|
|
27
|
+
const raw = getSqliteFrom(database);
|
|
28
|
+
const checkpointKey = "backfill_provider_connection_label";
|
|
29
|
+
|
|
30
|
+
const checkpoint = raw
|
|
31
|
+
.query(`SELECT 1 FROM memory_checkpoints WHERE key = ?`)
|
|
32
|
+
.get(checkpointKey);
|
|
33
|
+
if (checkpoint) return;
|
|
34
|
+
|
|
35
|
+
// Guard: skip if the table doesn't exist yet (first-boot edge case where
|
|
36
|
+
// migration 243 hasn't run, e.g. fresh install ordering test harness).
|
|
37
|
+
const tableExists = raw
|
|
38
|
+
.query(
|
|
39
|
+
`SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_connections'`,
|
|
40
|
+
)
|
|
41
|
+
.get();
|
|
42
|
+
if (!tableExists) {
|
|
43
|
+
raw
|
|
44
|
+
.query(
|
|
45
|
+
`INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
|
|
46
|
+
)
|
|
47
|
+
.run(checkpointKey, Date.now());
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Guard: also skip if the label column hasn't been added yet (migration
|
|
52
|
+
// 244 hasn't run). Treat as no-op + don't checkpoint, so the backfill
|
|
53
|
+
// runs the next time it gets a chance against a populated schema.
|
|
54
|
+
const columns = raw
|
|
55
|
+
.query(`PRAGMA table_info(provider_connections)`)
|
|
56
|
+
.all() as Array<{ name: string }>;
|
|
57
|
+
if (!columns.some((c) => c.name === "label")) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
raw.exec("BEGIN");
|
|
63
|
+
|
|
64
|
+
raw.exec(/*sql*/ `
|
|
65
|
+
UPDATE provider_connections
|
|
66
|
+
SET label = name
|
|
67
|
+
WHERE label IS NULL OR TRIM(label) = ''
|
|
68
|
+
`);
|
|
69
|
+
|
|
70
|
+
raw
|
|
71
|
+
.query(
|
|
72
|
+
`INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
|
|
73
|
+
)
|
|
74
|
+
.run(checkpointKey, Date.now());
|
|
75
|
+
|
|
76
|
+
raw.exec("COMMIT");
|
|
77
|
+
} catch (err) {
|
|
78
|
+
raw.exec("ROLLBACK");
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Database } from "bun:sqlite";
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
|
|
4
|
+
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
5
|
+
|
|
6
|
+
import { getSqliteFrom } from "../../db-connection.js";
|
|
7
|
+
import * as schema from "../../schema.js";
|
|
8
|
+
import { migrateCreateProviderConnections } from "../243-provider-connections.js";
|
|
9
|
+
import { migrateProviderConnectionStatusLabel } from "../244-provider-connection-status-label.js";
|
|
10
|
+
|
|
11
|
+
interface ColumnRow {
|
|
12
|
+
name: string;
|
|
13
|
+
type: string;
|
|
14
|
+
notnull: number;
|
|
15
|
+
dflt_value: string | null;
|
|
16
|
+
pk: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function createTestDb() {
|
|
20
|
+
const sqlite = new Database(":memory:");
|
|
21
|
+
sqlite.exec("PRAGMA journal_mode=WAL");
|
|
22
|
+
sqlite.exec("PRAGMA foreign_keys = ON");
|
|
23
|
+
return drizzle(sqlite, { schema });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
describe("migration 244 — provider_connection status + label", () => {
|
|
27
|
+
test("adds status (NOT NULL DEFAULT active) and label (nullable) columns", () => {
|
|
28
|
+
const db = createTestDb();
|
|
29
|
+
const raw = getSqliteFrom(db);
|
|
30
|
+
|
|
31
|
+
// Bootstrap provider_connections table via migration 243.
|
|
32
|
+
migrateCreateProviderConnections(db);
|
|
33
|
+
|
|
34
|
+
// Verify the new columns are absent before migration 244.
|
|
35
|
+
const colsBefore = raw.query(`PRAGMA table_info(provider_connections)`).all() as ColumnRow[];
|
|
36
|
+
const namesBefore = colsBefore.map((c) => c.name);
|
|
37
|
+
expect(namesBefore).not.toContain("status");
|
|
38
|
+
expect(namesBefore).not.toContain("label");
|
|
39
|
+
|
|
40
|
+
migrateProviderConnectionStatusLabel(db);
|
|
41
|
+
|
|
42
|
+
const cols = raw.query(`PRAGMA table_info(provider_connections)`).all() as ColumnRow[];
|
|
43
|
+
const colMap = Object.fromEntries(cols.map((c) => [c.name, c]));
|
|
44
|
+
|
|
45
|
+
// status: NOT NULL, default 'active'
|
|
46
|
+
expect(colMap["status"]).toBeDefined();
|
|
47
|
+
expect(colMap["status"].notnull).toBe(1);
|
|
48
|
+
expect(colMap["status"].dflt_value).toBe("'active'");
|
|
49
|
+
|
|
50
|
+
// label: nullable
|
|
51
|
+
expect(colMap["label"]).toBeDefined();
|
|
52
|
+
expect(colMap["label"].notnull).toBe(0);
|
|
53
|
+
expect(colMap["label"].dflt_value).toBeNull();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("is idempotent — running twice does not throw", () => {
|
|
57
|
+
const db = createTestDb();
|
|
58
|
+
migrateCreateProviderConnections(db);
|
|
59
|
+
migrateProviderConnectionStatusLabel(db);
|
|
60
|
+
expect(() => migrateProviderConnectionStatusLabel(db)).not.toThrow();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("existing rows get status=active from column default", () => {
|
|
64
|
+
const db = createTestDb();
|
|
65
|
+
const raw = getSqliteFrom(db);
|
|
66
|
+
|
|
67
|
+
// Seed a row before adding the status column.
|
|
68
|
+
migrateCreateProviderConnections(db);
|
|
69
|
+
|
|
70
|
+
// Verify canonical connections got the default.
|
|
71
|
+
migrateProviderConnectionStatusLabel(db);
|
|
72
|
+
|
|
73
|
+
const rows = raw.query(`SELECT name, status, label FROM provider_connections`).all() as Array<{
|
|
74
|
+
name: string;
|
|
75
|
+
status: string;
|
|
76
|
+
label: string | null;
|
|
77
|
+
}>;
|
|
78
|
+
expect(rows.length).toBeGreaterThan(0);
|
|
79
|
+
for (const row of rows) {
|
|
80
|
+
expect(row.status).toBe("active");
|
|
81
|
+
expect(row.label).toBeNull();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Database } from "bun:sqlite";
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
|
|
4
|
+
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
5
|
+
|
|
6
|
+
import { getSqliteFrom } from "../../db-connection.js";
|
|
7
|
+
import * as schema from "../../schema.js";
|
|
8
|
+
import { migrateMemoryRetrospectiveState } from "../245-memory-retrospective-state.js";
|
|
9
|
+
|
|
10
|
+
interface ColumnRow {
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
notnull: number;
|
|
14
|
+
dflt_value: string | null;
|
|
15
|
+
pk: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ForeignKeyRow {
|
|
19
|
+
id: number;
|
|
20
|
+
seq: number;
|
|
21
|
+
table: string;
|
|
22
|
+
from: string;
|
|
23
|
+
to: string;
|
|
24
|
+
on_update: string;
|
|
25
|
+
on_delete: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function createTestDb() {
|
|
29
|
+
const sqlite = new Database(":memory:");
|
|
30
|
+
sqlite.exec("PRAGMA journal_mode=WAL");
|
|
31
|
+
sqlite.exec("PRAGMA foreign_keys = ON");
|
|
32
|
+
// `withCrashRecovery` (used by the migration) reads/writes a
|
|
33
|
+
// `memory_checkpoints` table. Seed a minimal version so the migration's
|
|
34
|
+
// structural setup can be exercised without booting the entire
|
|
35
|
+
// db-init pipeline.
|
|
36
|
+
sqlite.exec(`
|
|
37
|
+
CREATE TABLE memory_checkpoints (
|
|
38
|
+
key TEXT PRIMARY KEY,
|
|
39
|
+
value TEXT NOT NULL,
|
|
40
|
+
updated_at INTEGER NOT NULL
|
|
41
|
+
)
|
|
42
|
+
`);
|
|
43
|
+
// The state table FK references `conversations(id)`, so the test DB needs
|
|
44
|
+
// that table to exist before we can apply the FK. Use a minimal table —
|
|
45
|
+
// we're only checking the migration's structural output, not exercising
|
|
46
|
+
// cascade behavior end-to-end.
|
|
47
|
+
sqlite.exec(`
|
|
48
|
+
CREATE TABLE conversations (
|
|
49
|
+
id TEXT PRIMARY KEY,
|
|
50
|
+
created_at INTEGER NOT NULL
|
|
51
|
+
)
|
|
52
|
+
`);
|
|
53
|
+
return drizzle(sqlite, { schema });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe("migration 245 — memory_retrospective_state", () => {
|
|
57
|
+
test("creates the table with the expected columns and primary key", () => {
|
|
58
|
+
const db = createTestDb();
|
|
59
|
+
const raw = getSqliteFrom(db);
|
|
60
|
+
|
|
61
|
+
migrateMemoryRetrospectiveState(db);
|
|
62
|
+
|
|
63
|
+
const cols = raw
|
|
64
|
+
.query(`PRAGMA table_info(memory_retrospective_state)`)
|
|
65
|
+
.all() as ColumnRow[];
|
|
66
|
+
const colMap = Object.fromEntries(cols.map((c) => [c.name, c]));
|
|
67
|
+
|
|
68
|
+
expect(colMap["conversation_id"]).toBeDefined();
|
|
69
|
+
expect(colMap["conversation_id"].pk).toBe(1);
|
|
70
|
+
|
|
71
|
+
expect(colMap["last_processed_message_id"]).toBeDefined();
|
|
72
|
+
expect(colMap["last_processed_message_id"].notnull).toBe(1);
|
|
73
|
+
|
|
74
|
+
expect(colMap["last_run_at"]).toBeDefined();
|
|
75
|
+
expect(colMap["last_run_at"].notnull).toBe(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("FK on conversation_id is ON DELETE CASCADE", () => {
|
|
79
|
+
const db = createTestDb();
|
|
80
|
+
const raw = getSqliteFrom(db);
|
|
81
|
+
|
|
82
|
+
migrateMemoryRetrospectiveState(db);
|
|
83
|
+
|
|
84
|
+
const fks = raw
|
|
85
|
+
.query(`PRAGMA foreign_key_list(memory_retrospective_state)`)
|
|
86
|
+
.all() as ForeignKeyRow[];
|
|
87
|
+
|
|
88
|
+
expect(fks).toHaveLength(1);
|
|
89
|
+
expect(fks[0]!.from).toBe("conversation_id");
|
|
90
|
+
expect(fks[0]!.table).toBe("conversations");
|
|
91
|
+
expect(fks[0]!.to).toBe("id");
|
|
92
|
+
expect(fks[0]!.on_delete).toBe("CASCADE");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("is idempotent — running twice does not throw", () => {
|
|
96
|
+
const db = createTestDb();
|
|
97
|
+
|
|
98
|
+
migrateMemoryRetrospectiveState(db);
|
|
99
|
+
expect(() => migrateMemoryRetrospectiveState(db)).not.toThrow();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("deleting a conversation cascades to its state row", () => {
|
|
103
|
+
const db = createTestDb();
|
|
104
|
+
const raw = getSqliteFrom(db);
|
|
105
|
+
|
|
106
|
+
migrateMemoryRetrospectiveState(db);
|
|
107
|
+
|
|
108
|
+
raw.exec(`INSERT INTO conversations (id, created_at) VALUES ('c1', 0)`);
|
|
109
|
+
raw.exec(
|
|
110
|
+
`INSERT INTO memory_retrospective_state (conversation_id, last_processed_message_id, last_run_at) VALUES ('c1', 'm1', 1000)`,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const before = raw
|
|
114
|
+
.query(`SELECT COUNT(*) AS c FROM memory_retrospective_state`)
|
|
115
|
+
.get() as { c: number };
|
|
116
|
+
expect(before.c).toBe(1);
|
|
117
|
+
|
|
118
|
+
raw.exec(`DELETE FROM conversations WHERE id = 'c1'`);
|
|
119
|
+
|
|
120
|
+
const after = raw
|
|
121
|
+
.query(`SELECT COUNT(*) AS c FROM memory_retrospective_state`)
|
|
122
|
+
.get() as { c: number };
|
|
123
|
+
expect(after.c).toBe(0);
|
|
124
|
+
});
|
|
125
|
+
});
|