@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
|
@@ -208,9 +208,11 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
|
|
|
208
208
|
"config/bundled-skills/image-studio/tools/media-generate-image.ts", // image generation tool API key lookup
|
|
209
209
|
"config/bundled-skills/media-processing/tools/analyze-keyframes.ts", // keyframe analysis tool API key lookup
|
|
210
210
|
"providers/registry.ts", // provider registry API key lookup for initialization
|
|
211
|
+
"providers/inference/resolve-auth.ts", // provider_connection auth resolver (api_key path reads vault, mirrors registry.ts)
|
|
211
212
|
"providers/provider-availability.ts", // provider availability API key check
|
|
212
213
|
"media/image-credentials.ts", // shared image-gen credential resolver (provider API key lookup)
|
|
213
214
|
"memory/embedding-backend.ts", // embedding backend API key lookup
|
|
215
|
+
"memory/llm-request-log-source-clickhouse.ts", // ClickHouse read source — lazy lookup of clickhouse:url + clickhouse:password + vellum:platform_assistant_id for self-scoped mirror reads
|
|
214
216
|
"daemon/providers-setup.ts", // provider initialization API key lookup
|
|
215
217
|
"workspace/migrations/006-services-config.ts", // services config migration reads provider API keys
|
|
216
218
|
"workspace/migrations/018-rekey-compound-credential-keys.ts", // re-key compound credential storage keys
|
|
@@ -220,22 +222,19 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
|
|
|
220
222
|
"daemon/lifecycle.ts", // CES client injection into secure-keys at startup
|
|
221
223
|
"daemon/daemon-skill-host.ts", // SkillHost secureKeys facet adapter (delegates to getProviderKeyAsync)
|
|
222
224
|
"runtime/routes/credential-prompt-routes.ts", // Route for secure credential prompt (stores secret via setSecureKeyAsync)
|
|
225
|
+
"runtime/routes/credential-routes.ts", // CLI credential management routes (CLI-migrated to IPC)
|
|
226
|
+
"runtime/routes/platform-routes.ts", // CLI platform connect/disconnect/status routes (CLI-migrated to IPC)
|
|
223
227
|
"ipc/skill-routes/providers.ts", // host.providers.secureKeys.getProviderKey IPC route (out-of-process SkillHost companion)
|
|
224
228
|
"daemon/external-plugins-bootstrap.ts", // reads credentials at plugin init (manifest.requiresCredential) via the CES-mediated getSecureKeyAsync path
|
|
225
229
|
"inbound/platform-callback-registration.ts", // managed credential lookup for platform base URL, assistant ID, and API key
|
|
226
230
|
"tts/providers/elevenlabs-provider.ts", // ElevenLabs TTS API key lookup
|
|
227
231
|
"tts/providers/deepgram-provider.ts", // Deepgram TTS API key lookup
|
|
228
232
|
"tts/providers/xai-provider.ts", // xAI TTS API key lookup
|
|
229
|
-
"meet/session-manager.ts", // Meet bot container provisioning (provider API key lookup for Deepgram/TTS)
|
|
230
233
|
"credential-health/credential-health-service.ts", // credential health check reads access tokens for liveness pings
|
|
231
234
|
"ipc/skill-routes/providers.ts", // skill IPC route exposes provider key lookup to hosted skills
|
|
232
|
-
"
|
|
233
|
-
"cli/commands/credentials.ts", // CLI credential management commands
|
|
235
|
+
"runtime/routes/avatar-routes.ts", // avatar generate route reads platform_base_url from credential store
|
|
234
236
|
"cli/commands/keys.ts", // CLI provider key management
|
|
235
237
|
"cli/commands/oauth/connect.ts", // CLI OAuth connect stored-secret verification
|
|
236
|
-
"cli/commands/platform/connect.ts", // CLI platform connect credential check
|
|
237
|
-
"cli/commands/platform/disconnect.ts", // CLI platform disconnect credential lookup
|
|
238
|
-
"cli/commands/platform/index.ts", // CLI platform status credential check
|
|
239
238
|
]);
|
|
240
239
|
|
|
241
240
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -13,8 +13,13 @@ let _ipcResponse: { ok: boolean; result?: unknown; error?: string } = {
|
|
|
13
13
|
error: "Could not connect to assistant daemon. Is it running?",
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
let _lastIpcCall: { method: string; params: unknown } | null = null;
|
|
17
|
+
|
|
16
18
|
mock.module("../ipc/cli-client.js", () => ({
|
|
17
|
-
cliIpcCall: async () =>
|
|
19
|
+
cliIpcCall: async (method: string, params: unknown) => {
|
|
20
|
+
_lastIpcCall = { method, params };
|
|
21
|
+
return _ipcResponse;
|
|
22
|
+
},
|
|
18
23
|
}));
|
|
19
24
|
|
|
20
25
|
mock.module("../util/logger.js", () => ({
|
|
@@ -120,4 +125,54 @@ describe("daemon credential client", () => {
|
|
|
120
125
|
expect(result.error).toBeUndefined();
|
|
121
126
|
});
|
|
122
127
|
});
|
|
128
|
+
|
|
129
|
+
// Regression: the IPC server registers route handlers by `operationId`
|
|
130
|
+
// (e.g. `secrets_add`, `secrets_delete`) and unwraps params from
|
|
131
|
+
// `{ body: ... }`. Earlier versions called `secrets/write` and
|
|
132
|
+
// `secrets/delete` with un-wrapped params, which the IPC server rejected
|
|
133
|
+
// with "Unknown method". These tests pin the wire format so it cannot
|
|
134
|
+
// silently drift again.
|
|
135
|
+
describe("IPC wire format", () => {
|
|
136
|
+
test("set uses secrets_add with body-wrapped params", async () => {
|
|
137
|
+
_ipcResponse = { ok: true, result: { success: true } };
|
|
138
|
+
_lastIpcCall = null;
|
|
139
|
+
|
|
140
|
+
await setSecureKeyViaDaemon(
|
|
141
|
+
"credential",
|
|
142
|
+
"github-app:pem",
|
|
143
|
+
"secret-pem-value",
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const captured = _lastIpcCall as {
|
|
147
|
+
method: string;
|
|
148
|
+
params: unknown;
|
|
149
|
+
} | null;
|
|
150
|
+
expect(captured).not.toBeNull();
|
|
151
|
+
expect(captured?.method).toBe("secrets_add");
|
|
152
|
+
expect(captured?.params).toEqual({
|
|
153
|
+
body: {
|
|
154
|
+
type: "credential",
|
|
155
|
+
name: "github-app:pem",
|
|
156
|
+
value: "secret-pem-value",
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("delete uses secrets_delete with body-wrapped params", async () => {
|
|
162
|
+
_ipcResponse = { ok: true, result: { success: true } };
|
|
163
|
+
_lastIpcCall = null;
|
|
164
|
+
|
|
165
|
+
await deleteSecureKeyViaDaemon("credential", "github-app:pem");
|
|
166
|
+
|
|
167
|
+
const captured = _lastIpcCall as {
|
|
168
|
+
method: string;
|
|
169
|
+
params: unknown;
|
|
170
|
+
} | null;
|
|
171
|
+
expect(captured).not.toBeNull();
|
|
172
|
+
expect(captured?.method).toBe("secrets_delete");
|
|
173
|
+
expect(captured?.params).toEqual({
|
|
174
|
+
body: { type: "credential", name: "github-app:pem" },
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
123
178
|
});
|
|
@@ -0,0 +1,132 @@
|
|
|
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 "../memory/db-connection.js";
|
|
7
|
+
import { migrateActivationState } from "../memory/migrations/232-activation-state.js";
|
|
8
|
+
import { migrateActivationStateFkCascade } from "../memory/migrations/241-activation-state-fk-cascade.js";
|
|
9
|
+
import * as schema from "../memory/schema.js";
|
|
10
|
+
|
|
11
|
+
function createTestDb() {
|
|
12
|
+
const sqlite = new Database(":memory:");
|
|
13
|
+
sqlite.exec("PRAGMA journal_mode=WAL");
|
|
14
|
+
sqlite.exec("PRAGMA foreign_keys = ON");
|
|
15
|
+
return drizzle(sqlite, { schema });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function bootstrap(raw: Database): void {
|
|
19
|
+
raw.exec(/*sql*/ `
|
|
20
|
+
CREATE TABLE IF NOT EXISTS memory_checkpoints (
|
|
21
|
+
key TEXT PRIMARY KEY,
|
|
22
|
+
value TEXT NOT NULL,
|
|
23
|
+
updated_at INTEGER NOT NULL
|
|
24
|
+
)
|
|
25
|
+
`);
|
|
26
|
+
raw.exec(/*sql*/ `
|
|
27
|
+
CREATE TABLE IF NOT EXISTS conversations (id TEXT PRIMARY KEY)
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function insertActivation(
|
|
32
|
+
raw: Database,
|
|
33
|
+
conversationId: string,
|
|
34
|
+
messageId = "msg-1",
|
|
35
|
+
): void {
|
|
36
|
+
raw
|
|
37
|
+
.query(
|
|
38
|
+
/*sql*/ `INSERT INTO activation_state (conversation_id, message_id, state_json, updated_at) VALUES (?, ?, ?, ?)`,
|
|
39
|
+
)
|
|
40
|
+
.run(conversationId, messageId, "{}", 1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe("activation_state FK cascade migration", () => {
|
|
44
|
+
test("rebuilds the table with ON DELETE CASCADE", () => {
|
|
45
|
+
const db = createTestDb();
|
|
46
|
+
const raw = getSqliteFrom(db);
|
|
47
|
+
bootstrap(raw);
|
|
48
|
+
|
|
49
|
+
migrateActivationState(db);
|
|
50
|
+
migrateActivationStateFkCascade(db);
|
|
51
|
+
|
|
52
|
+
const ddl = raw
|
|
53
|
+
.query(
|
|
54
|
+
`SELECT sql FROM sqlite_master WHERE type='table' AND name='activation_state'`,
|
|
55
|
+
)
|
|
56
|
+
.get() as { sql: string } | null;
|
|
57
|
+
expect(ddl?.sql).toContain("REFERENCES conversations(id)");
|
|
58
|
+
expect(ddl?.sql).toContain("ON DELETE CASCADE");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("deleting a conversation cascades to activation_state", () => {
|
|
62
|
+
const db = createTestDb();
|
|
63
|
+
const raw = getSqliteFrom(db);
|
|
64
|
+
bootstrap(raw);
|
|
65
|
+
|
|
66
|
+
migrateActivationState(db);
|
|
67
|
+
migrateActivationStateFkCascade(db);
|
|
68
|
+
|
|
69
|
+
raw.query(`INSERT INTO conversations (id) VALUES (?)`).run("conv-1");
|
|
70
|
+
insertActivation(raw, "conv-1");
|
|
71
|
+
|
|
72
|
+
raw.query(`DELETE FROM conversations WHERE id = ?`).run("conv-1");
|
|
73
|
+
|
|
74
|
+
const remaining = raw
|
|
75
|
+
.query(`SELECT COUNT(*) AS n FROM activation_state`)
|
|
76
|
+
.get() as { n: number };
|
|
77
|
+
expect(remaining.n).toBe(0);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("rebuild purges existing orphan rows", () => {
|
|
81
|
+
const db = createTestDb();
|
|
82
|
+
const raw = getSqliteFrom(db);
|
|
83
|
+
bootstrap(raw);
|
|
84
|
+
|
|
85
|
+
migrateActivationState(db);
|
|
86
|
+
|
|
87
|
+
raw.query(`INSERT INTO conversations (id) VALUES (?)`).run("conv-live");
|
|
88
|
+
insertActivation(raw, "conv-live");
|
|
89
|
+
insertActivation(raw, "conv-orphan");
|
|
90
|
+
|
|
91
|
+
migrateActivationStateFkCascade(db);
|
|
92
|
+
|
|
93
|
+
const rows = raw
|
|
94
|
+
.query(
|
|
95
|
+
`SELECT conversation_id FROM activation_state ORDER BY conversation_id`,
|
|
96
|
+
)
|
|
97
|
+
.all() as Array<{ conversation_id: string }>;
|
|
98
|
+
expect(rows.map((r) => r.conversation_id)).toEqual(["conv-live"]);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("is idempotent — second run is a no-op", () => {
|
|
102
|
+
const db = createTestDb();
|
|
103
|
+
const raw = getSqliteFrom(db);
|
|
104
|
+
bootstrap(raw);
|
|
105
|
+
|
|
106
|
+
migrateActivationState(db);
|
|
107
|
+
migrateActivationStateFkCascade(db);
|
|
108
|
+
expect(() => migrateActivationStateFkCascade(db)).not.toThrow();
|
|
109
|
+
|
|
110
|
+
const ddl = raw
|
|
111
|
+
.query(
|
|
112
|
+
`SELECT sql FROM sqlite_master WHERE type='table' AND name='activation_state'`,
|
|
113
|
+
)
|
|
114
|
+
.get() as { sql: string } | null;
|
|
115
|
+
expect(ddl?.sql).toContain("ON DELETE CASCADE");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("no-ops when activation_state table is absent", () => {
|
|
119
|
+
const db = createTestDb();
|
|
120
|
+
const raw = getSqliteFrom(db);
|
|
121
|
+
bootstrap(raw);
|
|
122
|
+
|
|
123
|
+
expect(() => migrateActivationStateFkCascade(db)).not.toThrow();
|
|
124
|
+
|
|
125
|
+
const tableRow = raw
|
|
126
|
+
.query(
|
|
127
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name='activation_state'`,
|
|
128
|
+
)
|
|
129
|
+
.get();
|
|
130
|
+
expect(tableRow).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
@@ -18,6 +18,7 @@ import { resetDb } from "../memory/db-connection.js";
|
|
|
18
18
|
import { getSqliteFrom } from "../memory/db-connection.js";
|
|
19
19
|
import { initializeDb } from "../memory/db-init.js";
|
|
20
20
|
import { migrateAddConversationInferenceProfile } from "../memory/migrations/227-add-conversation-inference-profile.js";
|
|
21
|
+
import { migrateRenameInferenceProfileSnakeCase } from "../memory/migrations/228-rename-inference-profile-snake-case.js";
|
|
21
22
|
import * as schema from "../memory/schema.js";
|
|
22
23
|
import { getDbPath } from "../util/platform.js";
|
|
23
24
|
|
|
@@ -208,6 +209,42 @@ describe("conversation inference profile migration", () => {
|
|
|
208
209
|
expect(row).toEqual({ inferenceProfile: "quality-optimized" });
|
|
209
210
|
});
|
|
210
211
|
|
|
212
|
+
test("replaying 227 + 228 across multiple boots does not re-add the camelCase column", () => {
|
|
213
|
+
const db = createTestDb();
|
|
214
|
+
const raw = getSqliteFrom(db);
|
|
215
|
+
|
|
216
|
+
bootstrapPreInferenceProfileConversations(raw);
|
|
217
|
+
|
|
218
|
+
// First boot: 227 adds camelCase, 228 renames to snake_case.
|
|
219
|
+
migrateAddConversationInferenceProfile(db);
|
|
220
|
+
migrateRenameInferenceProfileSnakeCase(db);
|
|
221
|
+
expect(getColumnNames(raw)).toContain("inference_profile");
|
|
222
|
+
expect(getColumnNames(raw)).not.toContain("inferenceProfile");
|
|
223
|
+
|
|
224
|
+
// Second boot: replays must not re-add the camelCase column.
|
|
225
|
+
migrateAddConversationInferenceProfile(db);
|
|
226
|
+
migrateRenameInferenceProfileSnakeCase(db);
|
|
227
|
+
expect(getColumnNames(raw)).toContain("inference_profile");
|
|
228
|
+
expect(getColumnNames(raw)).not.toContain("inferenceProfile");
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test("228 self-heals when both columns are present from the legacy bug", () => {
|
|
232
|
+
const db = createTestDb();
|
|
233
|
+
const raw = getSqliteFrom(db);
|
|
234
|
+
|
|
235
|
+
bootstrapPreInferenceProfileConversations(raw);
|
|
236
|
+
// Simulate the legacy state: both columns exist because 227 re-added the
|
|
237
|
+
// camelCase column on a boot after 228 had already renamed it.
|
|
238
|
+
raw.exec(`ALTER TABLE conversations ADD COLUMN inference_profile TEXT`);
|
|
239
|
+
raw.exec(`ALTER TABLE conversations ADD COLUMN inferenceProfile TEXT`);
|
|
240
|
+
expect(getColumnNames(raw)).toContain("inferenceProfile");
|
|
241
|
+
|
|
242
|
+
migrateRenameInferenceProfileSnakeCase(db);
|
|
243
|
+
|
|
244
|
+
expect(getColumnNames(raw)).toContain("inference_profile");
|
|
245
|
+
expect(getColumnNames(raw)).not.toContain("inferenceProfile");
|
|
246
|
+
});
|
|
247
|
+
|
|
211
248
|
test("new rows default to NULL inferenceProfile after migration", () => {
|
|
212
249
|
const db = createTestDb();
|
|
213
250
|
const raw = getSqliteFrom(db);
|
|
@@ -28,7 +28,8 @@ function bootstrapTables(raw: Database): void {
|
|
|
28
28
|
CREATE TABLE memory_graph_nodes (
|
|
29
29
|
id TEXT PRIMARY KEY,
|
|
30
30
|
created INTEGER NOT NULL,
|
|
31
|
-
event_date INTEGER
|
|
31
|
+
event_date INTEGER,
|
|
32
|
+
content TEXT NOT NULL DEFAULT ''
|
|
32
33
|
);
|
|
33
34
|
|
|
34
35
|
CREATE TABLE memory_graph_triggers (
|
|
@@ -59,16 +60,35 @@ describe("repairMemoryGraphEventDate", () => {
|
|
|
59
60
|
const created = Date.UTC(2026, 3, 26, 5, 23, 20);
|
|
60
61
|
const wrongEventDate = Date.UTC(2025, 3, 19, 2, 32, 0);
|
|
61
62
|
|
|
62
|
-
expect(
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
expect(
|
|
64
|
+
repairMemoryGraphEventDate(
|
|
65
|
+
created,
|
|
66
|
+
wrongEventDate,
|
|
67
|
+
"Talked about the trip on April 19",
|
|
68
|
+
),
|
|
69
|
+
).toBe(Date.UTC(2026, 3, 19, 2, 32, 0));
|
|
65
70
|
});
|
|
66
71
|
|
|
67
72
|
test("leaves distant historical dates alone", () => {
|
|
68
73
|
const created = Date.UTC(2026, 3, 26, 5, 23, 20);
|
|
69
74
|
const historicalEventDate = Date.UTC(2025, 10, 1, 12, 0, 0);
|
|
70
75
|
|
|
71
|
-
expect(
|
|
76
|
+
expect(
|
|
77
|
+
repairMemoryGraphEventDate(created, historicalEventDate, ""),
|
|
78
|
+
).toBeNull();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("leaves dates alone when content explicitly mentions the prior year", () => {
|
|
82
|
+
const created = Date.UTC(2026, 3, 26, 5, 23, 20);
|
|
83
|
+
const explicitHistorical = Date.UTC(2025, 3, 19, 2, 32, 0);
|
|
84
|
+
|
|
85
|
+
expect(
|
|
86
|
+
repairMemoryGraphEventDate(
|
|
87
|
+
created,
|
|
88
|
+
explicitHistorical,
|
|
89
|
+
"User flew on April 19, 2025 to visit family",
|
|
90
|
+
),
|
|
91
|
+
).toBeNull();
|
|
72
92
|
});
|
|
73
93
|
});
|
|
74
94
|
|
|
@@ -84,21 +104,23 @@ describe("migrate231RepairMemoryGraphEventDates", () => {
|
|
|
84
104
|
const distantHistoricalDate = Date.UTC(2025, 10, 1, 12, 0, 0);
|
|
85
105
|
const futureDate = Date.UTC(2027, 0, 1, 12, 0, 0);
|
|
86
106
|
|
|
87
|
-
raw
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
107
|
+
const insertNode = raw.prepare(
|
|
108
|
+
`INSERT INTO memory_graph_nodes (id, created, event_date, content) VALUES (?, ?, ?, ?)`,
|
|
109
|
+
);
|
|
110
|
+
insertNode.run("bad-node", created, wrongEventDate, "Trip on April 19");
|
|
111
|
+
insertNode.run(
|
|
112
|
+
"historical-node",
|
|
113
|
+
created,
|
|
114
|
+
distantHistoricalDate,
|
|
115
|
+
"Notes from last fall",
|
|
116
|
+
);
|
|
117
|
+
insertNode.run("future-node", created, futureDate, "New Year 2027 plans");
|
|
118
|
+
insertNode.run(
|
|
119
|
+
"explicit-year-node",
|
|
120
|
+
created,
|
|
121
|
+
wrongEventDate,
|
|
122
|
+
"User flew on April 19, 2025 to visit family",
|
|
123
|
+
);
|
|
102
124
|
raw
|
|
103
125
|
.prepare(
|
|
104
126
|
`INSERT INTO memory_graph_triggers (id, node_id, type, event_date) VALUES (?, ?, ?, ?)`,
|
|
@@ -112,5 +134,6 @@ describe("migrate231RepairMemoryGraphEventDates", () => {
|
|
|
112
134
|
expect(triggerEventDateFor(raw, "bad-trigger")).toBe(correctedEventDate);
|
|
113
135
|
expect(eventDateFor(raw, "historical-node")).toBe(distantHistoricalDate);
|
|
114
136
|
expect(eventDateFor(raw, "future-node")).toBe(futureDate);
|
|
137
|
+
expect(eventDateFor(raw, "explicit-year-node")).toBe(wrongEventDate);
|
|
115
138
|
});
|
|
116
139
|
});
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the `db_proxy_transaction` IPC handler.
|
|
3
|
+
*
|
|
4
|
+
* Verifies all-or-nothing semantics: every step commits together, any
|
|
5
|
+
* exception or `requireChanges` violation rolls the entire batch back.
|
|
6
|
+
*
|
|
7
|
+
* Uses the real DB (via `initializeDb()`); the test preload points
|
|
8
|
+
* `VELLUM_WORKSPACE_DIR` at a per-file temp dir.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { beforeEach, describe, expect, test } from "bun:test";
|
|
12
|
+
|
|
13
|
+
import { handleDbProxyTransaction } from "../ipc/routes/db-proxy-transaction.js";
|
|
14
|
+
import { getSqlite } from "../memory/db-connection.js";
|
|
15
|
+
import { initializeDb } from "../memory/db-init.js";
|
|
16
|
+
import { RouteError } from "../runtime/routes/errors.js";
|
|
17
|
+
|
|
18
|
+
initializeDb();
|
|
19
|
+
|
|
20
|
+
function resetTestTable(): void {
|
|
21
|
+
const sqlite = getSqlite();
|
|
22
|
+
sqlite.exec("DROP TABLE IF EXISTS proxy_tx_test");
|
|
23
|
+
sqlite.exec(
|
|
24
|
+
"CREATE TABLE proxy_tx_test (id INTEGER PRIMARY KEY, label TEXT NOT NULL, count INTEGER NOT NULL DEFAULT 0)",
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function rowCount(): number {
|
|
29
|
+
const result = getSqlite()
|
|
30
|
+
.prepare("SELECT COUNT(*) AS n FROM proxy_tx_test")
|
|
31
|
+
.get() as { n: number };
|
|
32
|
+
return result.n;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe("db_proxy_transaction", () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
resetTestTable();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("commits multiple inserts atomically", () => {
|
|
41
|
+
const result = handleDbProxyTransaction({
|
|
42
|
+
steps: [
|
|
43
|
+
{
|
|
44
|
+
sql: "INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)",
|
|
45
|
+
bind: [1, "alpha"],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
sql: "INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)",
|
|
49
|
+
bind: [2, "beta"],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
expect(result.ok).toBe(true);
|
|
55
|
+
if (result.ok) {
|
|
56
|
+
expect(result.results).toHaveLength(2);
|
|
57
|
+
expect(result.results[0].changes).toBe(1);
|
|
58
|
+
expect(result.results[1].changes).toBe(1);
|
|
59
|
+
}
|
|
60
|
+
expect(rowCount()).toBe(2);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("rolls back all writes when a later step throws (SQL constraint)", () => {
|
|
64
|
+
// Pre-existing row that the transaction will collide with.
|
|
65
|
+
getSqlite()
|
|
66
|
+
.prepare("INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)")
|
|
67
|
+
.run(2, "preexisting");
|
|
68
|
+
|
|
69
|
+
let caught: unknown;
|
|
70
|
+
try {
|
|
71
|
+
handleDbProxyTransaction({
|
|
72
|
+
steps: [
|
|
73
|
+
{
|
|
74
|
+
sql: "INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)",
|
|
75
|
+
bind: [1, "alpha"],
|
|
76
|
+
},
|
|
77
|
+
// Primary-key collision triggers a SqliteError mid-transaction.
|
|
78
|
+
{
|
|
79
|
+
sql: "INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)",
|
|
80
|
+
bind: [2, "beta"],
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
} catch (err) {
|
|
85
|
+
caught = err;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// The thrown error must be a RouteError carrying the underlying SQL
|
|
89
|
+
// message — without the wrapping, the IPC envelope would lose the
|
|
90
|
+
// statusCode and the gateway-side strict caller would misclassify
|
|
91
|
+
// this as a transport failure ("assistant may not be ready").
|
|
92
|
+
expect(caught).toBeInstanceOf(RouteError);
|
|
93
|
+
if (caught instanceof RouteError) {
|
|
94
|
+
expect(caught.code).toBe("DB_PROXY_TRANSACTION_FAILED");
|
|
95
|
+
expect(caught.statusCode).toBe(500);
|
|
96
|
+
// The original SQL constraint message must survive the wrap so
|
|
97
|
+
// operators can debug from the gateway logs.
|
|
98
|
+
expect(caught.message).toMatch(/UNIQUE|PRIMARY KEY|constraint/i);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// The first step's insert must NOT have committed.
|
|
102
|
+
expect(rowCount()).toBe(1);
|
|
103
|
+
const remaining = getSqlite()
|
|
104
|
+
.prepare("SELECT label FROM proxy_tx_test WHERE id = ?")
|
|
105
|
+
.get(2) as { label: string };
|
|
106
|
+
expect(remaining.label).toBe("preexisting");
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("requireChanges aborts the transaction when unmet", () => {
|
|
110
|
+
// Seed a row to update; condition will not match so changes = 0.
|
|
111
|
+
getSqlite()
|
|
112
|
+
.prepare("INSERT INTO proxy_tx_test (id, label, count) VALUES (?, ?, ?)")
|
|
113
|
+
.run(1, "active", 0);
|
|
114
|
+
|
|
115
|
+
const result = handleDbProxyTransaction({
|
|
116
|
+
steps: [
|
|
117
|
+
{
|
|
118
|
+
sql: "INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)",
|
|
119
|
+
bind: [99, "should-rollback"],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
// No row matches label='nonexistent', so changes = 0.
|
|
123
|
+
sql: "UPDATE proxy_tx_test SET count = count + 1 WHERE label = ?",
|
|
124
|
+
bind: ["nonexistent"],
|
|
125
|
+
requireChanges: 1,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(result.ok).toBe(false);
|
|
131
|
+
if (!result.ok) {
|
|
132
|
+
expect(result.reason).toBe("require_changes_failed");
|
|
133
|
+
expect(result.failedStep).toBe(1);
|
|
134
|
+
expect(result.actualChanges).toBe(0);
|
|
135
|
+
expect(result.requiredChanges).toBe(1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// The earlier insert must have rolled back.
|
|
139
|
+
expect(rowCount()).toBe(1);
|
|
140
|
+
const remaining = getSqlite()
|
|
141
|
+
.prepare("SELECT label FROM proxy_tx_test WHERE id = ?")
|
|
142
|
+
.get(1) as { label: string };
|
|
143
|
+
expect(remaining.label).toBe("active");
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("requireChanges allows the transaction to commit when met", () => {
|
|
147
|
+
getSqlite()
|
|
148
|
+
.prepare("INSERT INTO proxy_tx_test (id, label, count) VALUES (?, ?, ?)")
|
|
149
|
+
.run(1, "active", 0);
|
|
150
|
+
|
|
151
|
+
const result = handleDbProxyTransaction({
|
|
152
|
+
steps: [
|
|
153
|
+
{
|
|
154
|
+
sql: "INSERT INTO proxy_tx_test (id, label) VALUES (?, ?)",
|
|
155
|
+
bind: [2, "new"],
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
sql: "UPDATE proxy_tx_test SET count = count + 1 WHERE label = ?",
|
|
159
|
+
bind: ["active"],
|
|
160
|
+
requireChanges: 1,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
expect(result.ok).toBe(true);
|
|
166
|
+
if (result.ok) {
|
|
167
|
+
expect(result.results[1].changes).toBe(1);
|
|
168
|
+
}
|
|
169
|
+
expect(rowCount()).toBe(2);
|
|
170
|
+
const updated = getSqlite()
|
|
171
|
+
.prepare("SELECT count FROM proxy_tx_test WHERE id = ?")
|
|
172
|
+
.get(1) as { count: number };
|
|
173
|
+
expect(updated.count).toBe(1);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("rejects empty step list with a 400 RouteError", () => {
|
|
177
|
+
let caught: unknown;
|
|
178
|
+
try {
|
|
179
|
+
handleDbProxyTransaction({ steps: [] });
|
|
180
|
+
} catch (err) {
|
|
181
|
+
caught = err;
|
|
182
|
+
}
|
|
183
|
+
expect(caught).toBeInstanceOf(RouteError);
|
|
184
|
+
if (caught instanceof RouteError) {
|
|
185
|
+
expect(caught.statusCode).toBe(400);
|
|
186
|
+
expect(caught.code).toBe("INVALID_PARAMS");
|
|
187
|
+
expect(caught.message).toMatch(/at least one step/);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("returns lastInsertRowid for inserts", () => {
|
|
192
|
+
const result = handleDbProxyTransaction({
|
|
193
|
+
steps: [
|
|
194
|
+
{
|
|
195
|
+
sql: "INSERT INTO proxy_tx_test (label) VALUES (?)",
|
|
196
|
+
bind: ["solo"],
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
expect(result.ok).toBe(true);
|
|
202
|
+
if (result.ok) {
|
|
203
|
+
expect(result.results[0].lastInsertRowid).toBeGreaterThan(0);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
});
|