@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,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
|
+
});
|
|
@@ -0,0 +1,192 @@
|
|
|
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
|
+
import { migrateBackfillProviderConnectionLabel } from "../246-backfill-provider-connection-label.js";
|
|
11
|
+
|
|
12
|
+
interface ConnectionRow {
|
|
13
|
+
name: string;
|
|
14
|
+
label: string | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function createTestDb() {
|
|
18
|
+
const sqlite = new Database(":memory:");
|
|
19
|
+
sqlite.exec("PRAGMA journal_mode=WAL");
|
|
20
|
+
sqlite.exec("PRAGMA foreign_keys = ON");
|
|
21
|
+
return drizzle(sqlite, { schema });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// Ensure the `memory_checkpoints` table exists in test DBs — it's normally
|
|
25
|
+
/// provisioned by earlier infra migrations that the test harness doesn't
|
|
26
|
+
/// pull in. Schema mirrors what other backfill migrations expect.
|
|
27
|
+
function ensureCheckpointsTable(db: ReturnType<typeof createTestDb>): void {
|
|
28
|
+
const raw = getSqliteFrom(db);
|
|
29
|
+
raw.exec(`
|
|
30
|
+
CREATE TABLE IF NOT EXISTS memory_checkpoints (
|
|
31
|
+
key TEXT PRIMARY KEY,
|
|
32
|
+
value TEXT,
|
|
33
|
+
updated_at INTEGER
|
|
34
|
+
)
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// Bring the test DB up to the state right before migration 246 runs:
|
|
39
|
+
/// provider_connections table present + status/label columns added.
|
|
40
|
+
function prepareSchemaThroughMigration244(
|
|
41
|
+
db: ReturnType<typeof createTestDb>,
|
|
42
|
+
): void {
|
|
43
|
+
migrateCreateProviderConnections(db);
|
|
44
|
+
migrateProviderConnectionStatusLabel(db);
|
|
45
|
+
ensureCheckpointsTable(db);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe("migration 246 — backfill provider_connection label", () => {
|
|
49
|
+
test("sets label = name for rows where label is NULL", () => {
|
|
50
|
+
const db = createTestDb();
|
|
51
|
+
const raw = getSqliteFrom(db);
|
|
52
|
+
prepareSchemaThroughMigration244(db);
|
|
53
|
+
|
|
54
|
+
// Insert a row with label = NULL (simulating a pre-244 connection).
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
raw
|
|
57
|
+
.query(
|
|
58
|
+
`INSERT INTO provider_connections (name, provider, auth, status, label, created_at, updated_at) VALUES (?, ?, ?, 'active', NULL, ?, ?)`,
|
|
59
|
+
)
|
|
60
|
+
.run("anthropic-personal", "anthropic", JSON.stringify({ type: "api_key", credential: "credential/anthropic/api_key" }), now, now);
|
|
61
|
+
|
|
62
|
+
migrateBackfillProviderConnectionLabel(db);
|
|
63
|
+
|
|
64
|
+
const row = raw
|
|
65
|
+
.query(`SELECT name, label FROM provider_connections WHERE name = ?`)
|
|
66
|
+
.get("anthropic-personal") as ConnectionRow;
|
|
67
|
+
expect(row.label).toBe("anthropic-personal");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("sets label = name for rows where label is empty/whitespace", () => {
|
|
71
|
+
const db = createTestDb();
|
|
72
|
+
const raw = getSqliteFrom(db);
|
|
73
|
+
prepareSchemaThroughMigration244(db);
|
|
74
|
+
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
raw
|
|
77
|
+
.query(
|
|
78
|
+
`INSERT INTO provider_connections (name, provider, auth, status, label, created_at, updated_at) VALUES (?, ?, ?, 'active', ?, ?, ?)`,
|
|
79
|
+
)
|
|
80
|
+
.run("openai-empty", "openai", JSON.stringify({ type: "api_key", credential: "credential/openai/api_key" }), "", now, now);
|
|
81
|
+
raw
|
|
82
|
+
.query(
|
|
83
|
+
`INSERT INTO provider_connections (name, provider, auth, status, label, created_at, updated_at) VALUES (?, ?, ?, 'active', ?, ?, ?)`,
|
|
84
|
+
)
|
|
85
|
+
.run("openai-whitespace", "openai", JSON.stringify({ type: "api_key", credential: "credential/openai/api_key" }), " ", now, now);
|
|
86
|
+
|
|
87
|
+
migrateBackfillProviderConnectionLabel(db);
|
|
88
|
+
|
|
89
|
+
const empty = raw
|
|
90
|
+
.query(`SELECT label FROM provider_connections WHERE name = ?`)
|
|
91
|
+
.get("openai-empty") as ConnectionRow;
|
|
92
|
+
const whitespace = raw
|
|
93
|
+
.query(`SELECT label FROM provider_connections WHERE name = ?`)
|
|
94
|
+
.get("openai-whitespace") as ConnectionRow;
|
|
95
|
+
expect(empty.label).toBe("openai-empty");
|
|
96
|
+
expect(whitespace.label).toBe("openai-whitespace");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("does NOT overwrite rows where the user has set a non-empty label", () => {
|
|
100
|
+
const db = createTestDb();
|
|
101
|
+
const raw = getSqliteFrom(db);
|
|
102
|
+
prepareSchemaThroughMigration244(db);
|
|
103
|
+
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
raw
|
|
106
|
+
.query(
|
|
107
|
+
`INSERT INTO provider_connections (name, provider, auth, status, label, created_at, updated_at) VALUES (?, ?, ?, 'active', ?, ?, ?)`,
|
|
108
|
+
)
|
|
109
|
+
.run("anthropic-work", "anthropic", JSON.stringify({ type: "api_key", credential: "credential/anthropic/api_key" }), "Anthropic — Work", now, now);
|
|
110
|
+
|
|
111
|
+
migrateBackfillProviderConnectionLabel(db);
|
|
112
|
+
|
|
113
|
+
const row = raw
|
|
114
|
+
.query(`SELECT label FROM provider_connections WHERE name = ?`)
|
|
115
|
+
.get("anthropic-work") as ConnectionRow;
|
|
116
|
+
expect(row.label).toBe("Anthropic — Work");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("is idempotent — second run does not re-clobber a later user-cleared label", () => {
|
|
120
|
+
const db = createTestDb();
|
|
121
|
+
const raw = getSqliteFrom(db);
|
|
122
|
+
prepareSchemaThroughMigration244(db);
|
|
123
|
+
|
|
124
|
+
const now = Date.now();
|
|
125
|
+
raw
|
|
126
|
+
.query(
|
|
127
|
+
`INSERT INTO provider_connections (name, provider, auth, status, label, created_at, updated_at) VALUES (?, ?, ?, 'active', NULL, ?, ?)`,
|
|
128
|
+
)
|
|
129
|
+
.run("anthropic-personal", "anthropic", JSON.stringify({ type: "api_key", credential: "credential/anthropic/api_key" }), now, now);
|
|
130
|
+
|
|
131
|
+
// First run: backfills NULL → "anthropic-personal".
|
|
132
|
+
migrateBackfillProviderConnectionLabel(db);
|
|
133
|
+
expect(
|
|
134
|
+
(raw.query(`SELECT label FROM provider_connections WHERE name = ?`).get("anthropic-personal") as ConnectionRow).label,
|
|
135
|
+
).toBe("anthropic-personal");
|
|
136
|
+
|
|
137
|
+
// User clears the label after the backfill ran.
|
|
138
|
+
raw.query(`UPDATE provider_connections SET label = NULL WHERE name = ?`).run("anthropic-personal");
|
|
139
|
+
|
|
140
|
+
// Second run: should NOT re-clobber the user's deliberate clear, because
|
|
141
|
+
// the checkpoint was set on the first successful run.
|
|
142
|
+
migrateBackfillProviderConnectionLabel(db);
|
|
143
|
+
expect(
|
|
144
|
+
(raw.query(`SELECT label FROM provider_connections WHERE name = ?`).get("anthropic-personal") as ConnectionRow).label,
|
|
145
|
+
).toBeNull();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("checkpoint is set after a successful run", () => {
|
|
149
|
+
const db = createTestDb();
|
|
150
|
+
const raw = getSqliteFrom(db);
|
|
151
|
+
prepareSchemaThroughMigration244(db);
|
|
152
|
+
|
|
153
|
+
migrateBackfillProviderConnectionLabel(db);
|
|
154
|
+
|
|
155
|
+
const checkpoint = raw
|
|
156
|
+
.query(`SELECT key FROM memory_checkpoints WHERE key = ?`)
|
|
157
|
+
.get("backfill_provider_connection_label") as { key: string } | null;
|
|
158
|
+
expect(checkpoint).not.toBeNull();
|
|
159
|
+
expect(checkpoint?.key).toBe("backfill_provider_connection_label");
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("no-op when provider_connections table is absent (first-boot edge)", () => {
|
|
163
|
+
const db = createTestDb();
|
|
164
|
+
ensureCheckpointsTable(db);
|
|
165
|
+
|
|
166
|
+
// Don't run 243/244 — the table doesn't exist yet.
|
|
167
|
+
expect(() => migrateBackfillProviderConnectionLabel(db)).not.toThrow();
|
|
168
|
+
|
|
169
|
+
// Checkpoint should still get set so we don't retry forever.
|
|
170
|
+
const raw = getSqliteFrom(db);
|
|
171
|
+
const checkpoint = raw
|
|
172
|
+
.query(`SELECT key FROM memory_checkpoints WHERE key = ?`)
|
|
173
|
+
.get("backfill_provider_connection_label");
|
|
174
|
+
expect(checkpoint).not.toBeNull();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("no-op when label column is absent (244 hasn't run yet) — no checkpoint set", () => {
|
|
178
|
+
const db = createTestDb();
|
|
179
|
+
const raw = getSqliteFrom(db);
|
|
180
|
+
migrateCreateProviderConnections(db); // 243 only, NOT 244
|
|
181
|
+
ensureCheckpointsTable(db);
|
|
182
|
+
|
|
183
|
+
expect(() => migrateBackfillProviderConnectionLabel(db)).not.toThrow();
|
|
184
|
+
|
|
185
|
+
// Crucially: no checkpoint should be set, so the backfill can run later
|
|
186
|
+
// once 244 has provisioned the column.
|
|
187
|
+
const checkpoint = raw
|
|
188
|
+
.query(`SELECT key FROM memory_checkpoints WHERE key = ?`)
|
|
189
|
+
.get("backfill_provider_connection_label");
|
|
190
|
+
expect(checkpoint).toBeNull();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -201,6 +201,13 @@ export {
|
|
|
201
201
|
} from "./237-heartbeat-runs.js";
|
|
202
202
|
export { migrateScheduleRetryPolicy } from "./238-schedule-retry-policy.js";
|
|
203
203
|
export { migrateTraceEventsCreatedAtIndex } from "./239-trace-events-created-at-index.js";
|
|
204
|
+
export { migrateConversationInferenceProfileSession } from "./240-conversation-inference-profile-session.js";
|
|
205
|
+
export { migrateActivationStateFkCascade } from "./241-activation-state-fk-cascade.js";
|
|
206
|
+
export { migrateMessageBookmarks } from "./242-message-bookmarks.js";
|
|
207
|
+
export { migrateCreateProviderConnections } from "./243-provider-connections.js";
|
|
208
|
+
export { migrateProviderConnectionStatusLabel } from "./244-provider-connection-status-label.js";
|
|
209
|
+
export { migrateMemoryRetrospectiveState } from "./245-memory-retrospective-state.js";
|
|
210
|
+
export { migrateBackfillProviderConnectionLabel } from "./246-backfill-provider-connection-label.js";
|
|
204
211
|
export {
|
|
205
212
|
MIGRATION_REGISTRY,
|
|
206
213
|
type MigrationRegistryEntry,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import { makeMockLogger } from "../../__tests__/helpers/mock-logger.js";
|
|
4
|
-
import { _setOverridesForTesting } from "../../config/assistant-feature-flags.js";
|
|
5
4
|
|
|
6
|
-
// This test exercises the v1 PKB search path.
|
|
7
|
-
// (
|
|
8
|
-
//
|
|
9
|
-
|
|
5
|
+
// This test exercises the v1 PKB search path. `config.memory.v2.enabled`
|
|
6
|
+
// (default `true`) makes pkb-search short-circuit to keep traffic off the
|
|
7
|
+
// legacy collection — force it off so the v1 path stays under test.
|
|
8
|
+
mock.module("../../config/loader.js", () => ({
|
|
9
|
+
getConfig: () => ({ memory: { v2: { enabled: false } } }),
|
|
10
|
+
}));
|
|
10
11
|
|
|
11
12
|
mock.module("../../util/logger.js", () => ({
|
|
12
13
|
getLogger: () => makeMockLogger(),
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { getConfig } from "../../config/loader.js";
|
|
6
6
|
import { getLogger } from "../../util/logger.js";
|
|
7
|
-
import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
|
|
8
7
|
import {
|
|
9
8
|
isQdrantBreakerOpen,
|
|
10
9
|
withQdrantBreaker,
|
|
@@ -42,10 +41,10 @@ export async function searchPkbFiles(
|
|
|
42
41
|
limit: number,
|
|
43
42
|
scopeIds?: string[],
|
|
44
43
|
): Promise<PkbSearchResult[]> {
|
|
45
|
-
// v2 owns the read path when
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
if (
|
|
44
|
+
// v2 owns the read path when enabled; v2 absorbs PKB as a read source,
|
|
45
|
+
// so PKB hint search short-circuits to keep traffic off the v1 collection
|
|
46
|
+
// (avoiding OOM-crash risk from a corrupted sparse segment).
|
|
47
|
+
if (getConfig().memory.v2.enabled) return [];
|
|
49
48
|
|
|
50
49
|
if (isQdrantBreakerOpen()) {
|
|
51
50
|
log.warn("Qdrant circuit breaker open, skipping PKB search");
|
|
@@ -36,6 +36,21 @@ export function getActivePublishedPageByAppId(
|
|
|
36
36
|
return row ?? null;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export function insertPublishedPage(record: {
|
|
40
|
+
id: string;
|
|
41
|
+
deploymentId: string;
|
|
42
|
+
publicUrl: string;
|
|
43
|
+
pageTitle: string | null;
|
|
44
|
+
htmlHash: string;
|
|
45
|
+
publishedAt: number;
|
|
46
|
+
status: string;
|
|
47
|
+
appId: string | null;
|
|
48
|
+
projectSlug: string | null;
|
|
49
|
+
}): void {
|
|
50
|
+
const db = getDb();
|
|
51
|
+
db.insert(publishedPages).values(record).run();
|
|
52
|
+
}
|
|
53
|
+
|
|
39
54
|
export function updatePublishedPage(
|
|
40
55
|
id: string,
|
|
41
56
|
updates: {
|
|
@@ -44,6 +59,7 @@ export function updatePublishedPage(
|
|
|
44
59
|
htmlHash?: string;
|
|
45
60
|
publishedAt?: number;
|
|
46
61
|
appId?: string;
|
|
62
|
+
status?: string;
|
|
47
63
|
},
|
|
48
64
|
): void {
|
|
49
65
|
const db = getDb();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
index,
|
|
3
|
+
integer,
|
|
4
|
+
sqliteTable,
|
|
5
|
+
text,
|
|
6
|
+
uniqueIndex,
|
|
7
|
+
} from "drizzle-orm/sqlite-core";
|
|
8
|
+
|
|
9
|
+
import { conversations, messages } from "./conversations.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* User-saved bookmarks for individual messages. Surfaced in the macOS app
|
|
13
|
+
* Settings → Bookmarks tab and on the message hover overflow menu, behind the
|
|
14
|
+
* `bookmarks` client feature flag.
|
|
15
|
+
*
|
|
16
|
+
* Both foreign keys CASCADE so bookmarks disappear automatically when their
|
|
17
|
+
* parent message or conversation is deleted. A unique index on `message_id`
|
|
18
|
+
* keeps the create-bookmark path idempotent.
|
|
19
|
+
*/
|
|
20
|
+
export const messageBookmarks = sqliteTable(
|
|
21
|
+
"message_bookmarks",
|
|
22
|
+
{
|
|
23
|
+
id: text("id").primaryKey(),
|
|
24
|
+
messageId: text("message_id")
|
|
25
|
+
.notNull()
|
|
26
|
+
.references(() => messages.id, { onDelete: "cascade" }),
|
|
27
|
+
conversationId: text("conversation_id")
|
|
28
|
+
.notNull()
|
|
29
|
+
.references(() => conversations.id, { onDelete: "cascade" }),
|
|
30
|
+
createdAt: integer("created_at").notNull(),
|
|
31
|
+
},
|
|
32
|
+
(table) => [
|
|
33
|
+
uniqueIndex("message_bookmarks_message_id_uniq").on(table.messageId),
|
|
34
|
+
index("message_bookmarks_created_at_idx").on(table.createdAt),
|
|
35
|
+
],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export type MessageBookmarkRow = typeof messageBookmarks.$inferSelect;
|