@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.2
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/bun.lock +0 -20
- package/docs/workspace-tools.md +33 -42
- package/eslint-rules/cli-no-daemon-internals.js +0 -6
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
- package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
- package/node_modules/@vellumai/service-contracts/package.json +0 -1
- package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
- package/openapi.yaml +0 -155
- package/package.json +1 -4
- package/scripts/test.sh +15 -36
- package/src/__tests__/actor-token-service.test.ts +14 -36
- package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
- package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
- package/src/__tests__/annotate-risk-options.test.ts +0 -2
- package/src/__tests__/approval-cascade.test.ts +0 -2
- package/src/__tests__/assistant-attachments.test.ts +0 -42
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -2
- package/src/__tests__/build-persisted-content.test.ts +0 -2
- package/src/__tests__/call-controller.test.ts +0 -19
- package/src/__tests__/channel-guardian.test.ts +58 -94
- package/src/__tests__/channel-reply-delivery.test.ts +0 -2
- package/src/__tests__/compaction-events.test.ts +0 -2
- package/src/__tests__/compaction.benchmark.test.ts +0 -2
- package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
- package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
- package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
- package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
- package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
- package/src/__tests__/config-loader-backfill.test.ts +10 -123
- package/src/__tests__/config-schema.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
- package/src/__tests__/contacts-relay-reads.test.ts +15 -13
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +0 -134
- package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
- package/src/__tests__/conversation-history-web-search.test.ts +0 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
- package/src/__tests__/conversation-pairing.test.ts +0 -2
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
- package/src/__tests__/conversation-process-callsite.test.ts +0 -2
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
- package/src/__tests__/conversation-queue.test.ts +0 -91
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
- package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
- package/src/__tests__/conversation-slash-queue.test.ts +0 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
- package/src/__tests__/conversation-speed-override.test.ts +0 -2
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
- package/src/__tests__/conversation-title-service.test.ts +0 -2
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/db-migration-rollback.test.ts +171 -205
- package/src/__tests__/db-test-helpers.ts +4 -5
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
- package/src/__tests__/disk-pressure-guard.test.ts +0 -41
- package/src/__tests__/dm-persistence.test.ts +0 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
- package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
- package/src/__tests__/exploration-drift-hook.test.ts +2 -3
- package/src/__tests__/filing-service.test.ts +0 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
- package/src/__tests__/guardian-dispatch.test.ts +1 -95
- package/src/__tests__/guardian-outbound-http.test.ts +0 -13
- package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
- package/src/__tests__/heartbeat-service.test.ts +0 -2
- package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
- package/src/__tests__/host-app-control-routes.test.ts +30 -24
- package/src/__tests__/host-bash-routes.test.ts +41 -31
- package/src/__tests__/host-browser-routes.test.ts +32 -26
- package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
- package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
- package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
- package/src/__tests__/http-user-message-parity.test.ts +8 -290
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
- package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/invite-redemption-service.test.ts +0 -198
- package/src/__tests__/llm-context-normalization.test.ts +0 -105
- package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
- package/src/__tests__/llm-usage-store.test.ts +0 -25
- package/src/__tests__/mcp-health-check.test.ts +1 -2
- package/src/__tests__/media-stream-server-integration.test.ts +0 -127
- package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
- package/src/__tests__/messaging-send-tool.test.ts +0 -2
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +5 -146
- package/src/__tests__/native-web-search.test.ts +0 -2
- package/src/__tests__/non-member-access-request.test.ts +17 -189
- package/src/__tests__/notification-broadcaster.test.ts +0 -4
- package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
- package/src/__tests__/notification-deep-link.test.ts +0 -6
- package/src/__tests__/notification-guardian-path.test.ts +0 -19
- package/src/__tests__/openai-provider.test.ts +12 -22
- package/src/__tests__/openai-responses-provider.test.ts +2 -12
- package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
- package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
- package/src/__tests__/plugin-bootstrap.test.ts +73 -3
- package/src/__tests__/plugin-route-contribution.test.ts +17 -4
- package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
- package/src/__tests__/plugin-types.test.ts +2 -0
- package/src/__tests__/process-message-background-slack.test.ts +0 -2
- package/src/__tests__/process-message-display-content.test.ts +0 -2
- package/src/__tests__/provider-error-scenarios.test.ts +4 -5
- package/src/__tests__/provider-usage-tracking.test.ts +0 -39
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
- package/src/__tests__/registry.test.ts +1 -4
- package/src/__tests__/relay-server.test.ts +25 -694
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -14
- package/src/__tests__/send-endpoint-busy.test.ts +8 -30
- package/src/__tests__/skills.test.ts +0 -44
- package/src/__tests__/slack-inbound-verification.test.ts +2 -47
- package/src/__tests__/stt-hints.test.ts +13 -44
- package/src/__tests__/subagent-detail.test.ts +0 -27
- package/src/__tests__/subagent-disposal.test.ts +0 -65
- package/src/__tests__/subagent-notify-parent.test.ts +0 -2
- package/src/__tests__/subagent-role-registry.test.ts +2 -7
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
- package/src/__tests__/subagent-tools.test.ts +0 -2
- package/src/__tests__/suggestion-routes.test.ts +0 -2
- package/src/__tests__/title-generate-hook.test.ts +0 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
- package/src/__tests__/tool-executor.test.ts +11 -16
- package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
- package/src/__tests__/tool-start-timestamp.test.ts +0 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
- package/src/__tests__/twilio-routes.test.ts +0 -96
- package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +0 -33
- package/src/__tests__/web-search-backend-failure.test.ts +0 -2
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
- package/src/__tests__/workspace-tool-loader.test.ts +2 -195
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +0 -56
- package/src/api/index.ts +1 -19
- package/src/api/responses/llm-request-log-entry.ts +0 -29
- package/src/api/responses/subagent-detail.ts +0 -17
- package/src/api/surfaces.ts +3 -39
- package/src/approvals/guardian-request-resolvers.ts +11 -1
- package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +8 -10
- package/src/calls/inbound-trust-reader.ts +1 -17
- package/src/calls/media-stream-server.ts +0 -21
- package/src/calls/relay-server.ts +50 -167
- package/src/calls/relay-setup-router.ts +7 -37
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +12 -9
- package/src/calls/twilio-routes.ts +4 -14
- package/src/channels/types.ts +20 -10
- package/src/cli/commands/__tests__/cache.test.ts +1 -8
- package/src/cli/commands/cache.ts +181 -194
- package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
- package/src/cli/commands/db/status.ts +1 -37
- package/src/cli/commands/mcp.ts +218 -252
- package/src/cli/commands/memory/index.ts +0 -2
- package/src/cli/commands/plugins.ts +3 -75
- package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
- package/src/cli/lib/list-installed-plugins.ts +1 -179
- package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
- package/src/config/bundled-skills/subagent/SKILL.md +1 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +5 -38
- package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
- package/src/config/schemas/memory-lifecycle.ts +0 -12
- package/src/config/schemas/memory-v3.ts +0 -7
- package/src/config/schemas/memory.ts +0 -4
- package/src/config/schemas/timeouts.ts +0 -8
- package/src/config/seed-inference-profiles.ts +11 -21
- package/src/config/skills.ts +5 -27
- package/src/config/sync-gated-profiles.ts +13 -12
- package/src/contacts/contacts-write.ts +0 -3
- package/src/daemon/assistant-attachments.ts +4 -27
- package/src/daemon/conversation-agent-loop.ts +0 -28
- package/src/daemon/conversation-process.ts +16 -35
- package/src/daemon/conversation-surfaces.ts +38 -111
- package/src/daemon/conversation-tool-setup.ts +16 -50
- package/src/daemon/conversation.ts +1 -13
- package/src/daemon/disk-pressure-guard.ts +2 -12
- package/src/daemon/event-loop-watchdog.ts +1 -28
- package/src/daemon/external-plugins-bootstrap.ts +34 -4
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
- package/src/daemon/handlers/config-a2a.ts +14 -6
- package/src/daemon/handlers/config-channels.ts +22 -78
- package/src/daemon/handlers/conversations.ts +0 -77
- package/src/daemon/lifecycle.ts +0 -4
- package/src/daemon/mcp-reload-service.ts +0 -10
- package/src/daemon/memory-v2-startup.test.ts +0 -72
- package/src/daemon/memory-v2-startup.ts +19 -87
- package/src/daemon/message-types/conversations.ts +0 -2
- package/src/daemon/message-types/surfaces.ts +12 -12
- package/src/daemon/server.ts +4 -0
- package/src/daemon/shutdown-handlers.ts +0 -20
- package/src/daemon/tool-setup-types.ts +0 -9
- package/src/daemon/workspace-tools-watcher.ts +328 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/client.ts +1 -15
- package/src/mcp/mcp-auth-orchestrator.ts +1 -6
- package/src/mcp/mcp-oauth-provider.ts +8 -19
- package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
- package/src/memory/conversation-crud.ts +0 -38
- package/src/memory/db-connection.ts +3 -22
- package/src/memory/db-init.ts +502 -36
- package/src/memory/db-singleton.ts +4 -6
- package/src/memory/jobs-worker.ts +0 -58
- package/src/memory/llm-request-log-store.ts +1 -26
- package/src/memory/llm-usage-store.ts +20 -48
- package/src/memory/memory-retrospective-job.ts +8 -9
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/registry.ts +573 -0
- package/src/memory/migrations/run-migrations.ts +6 -90
- package/src/memory/migrations/validate-migration-state.ts +66 -101
- package/src/memory/schema/conversations.ts +0 -9
- package/src/memory/schema/infrastructure.ts +0 -20
- package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
- package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
- package/src/memory/v2/cli-command-store.ts +38 -75
- package/src/memory/v2/prompts/consolidation.ts +82 -13
- package/src/memory/v2/prompts/router.ts +93 -21
- package/src/memory/v2/skill-store.ts +31 -68
- package/src/notifications/__tests__/broadcaster.test.ts +8 -16
- package/src/notifications/__tests__/decision-engine.test.ts +9 -78
- package/src/notifications/broadcaster.ts +1 -8
- package/src/notifications/decision-engine.ts +7 -15
- package/src/notifications/destination-resolver.ts +24 -68
- package/src/notifications/emit-signal.ts +14 -39
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +4 -7
- package/src/plugin-api/index.ts +6 -6
- package/src/plugin-api/types.ts +5 -3
- package/src/plugin-api/vision-support.test.ts +4 -28
- package/src/plugin-api/vision-support.ts +31 -66
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
- package/src/plugins/defaults/advisor/consult.ts +6 -110
- package/src/plugins/defaults/advisor/steering.ts +2 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
- package/src/plugins/mtime-cache.ts +291 -76
- package/src/plugins/pipeline.ts +13 -111
- package/src/plugins/types.ts +2 -0
- package/src/providers/anthropic/client.ts +0 -5
- package/src/providers/call-site-routing.ts +0 -4
- package/src/providers/model-catalog.ts +0 -16
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/chat-completions-provider.ts +83 -37
- package/src/providers/openai/responses-provider.ts +46 -50
- package/src/providers/openrouter/client.ts +0 -5
- package/src/providers/provider-send-message.ts +0 -4
- package/src/providers/ratelimit.ts +0 -4
- package/src/providers/retry.ts +0 -4
- package/src/providers/types.ts +0 -9
- package/src/providers/usage-tracking.ts +0 -4
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
- package/src/runtime/access-request-helper.ts +39 -19
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +2 -9
- package/src/runtime/auth/require-bound-guardian.ts +11 -21
- package/src/runtime/channel-verification-service.ts +31 -56
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +7 -66
- package/src/runtime/invite-redemption-service.ts +187 -198
- package/src/runtime/local-actor-identity.ts +11 -76
- package/src/runtime/pending-interactions.ts +1 -11
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +32 -8
- package/src/runtime/routes/conversation-cli-routes.ts +5 -4
- package/src/runtime/routes/conversation-list-routes.ts +7 -4
- package/src/runtime/routes/conversation-query-routes.ts +0 -72
- package/src/runtime/routes/conversation-routes.ts +85 -84
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -3
- package/src/runtime/routes/guardian-action-routes.ts +5 -4
- package/src/runtime/routes/host-app-control-routes.ts +4 -5
- package/src/runtime/routes/host-bash-routes.ts +4 -5
- package/src/runtime/routes/host-browser-routes.ts +11 -9
- package/src/runtime/routes/host-cu-routes.ts +4 -5
- package/src/runtime/routes/host-file-routes.ts +4 -5
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +2 -3
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
- package/src/runtime/routes/index.ts +0 -2
- package/src/runtime/routes/llm-context-normalization.ts +0 -83
- package/src/runtime/routes/mcp-auth-routes.ts +19 -171
- package/src/runtime/routes/migration-rollback-routes.ts +3 -4
- package/src/runtime/routes/migration-routes.ts +1 -4
- package/src/runtime/routes/subagents-routes.ts +0 -5
- package/src/runtime/routes/surface-action-routes.ts +56 -42
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
- package/src/runtime/services/conversation-serializer.ts +9 -7
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +9 -85
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +0 -16
- package/src/subagent/manager.ts +0 -9
- package/src/subagent/types.ts +3 -3
- package/src/telemetry/types.ts +1 -34
- package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
- package/src/telemetry/usage-telemetry-reporter.ts +3 -87
- package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
- package/src/tools/ask-question/ask-question-tool.ts +0 -13
- package/src/tools/executor.ts +4 -4
- package/src/tools/registry.ts +0 -18
- package/src/tools/shared/filesystem/path-policy.ts +5 -12
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +2 -9
- package/src/tools/tool-manifest.ts +0 -3
- package/src/tools/types.ts +2 -17
- package/src/tools/workspace-tools/loader.ts +244 -348
- package/src/util/errors.ts +1 -26
- package/src/util/platform.ts +0 -5
- package/src/workflows/library.test.ts +0 -140
- package/src/workflows/library.ts +28 -82
- package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
- package/src/workspace/migrations/registry.ts +0 -2
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
- package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
- package/src/__tests__/code-search-tool.test.ts +0 -585
- package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
- package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
- package/src/__tests__/plugin-pipeline.test.ts +0 -96
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
- package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
- package/src/agent/loop-exclusive-tool.test.ts +0 -150
- package/src/api/constants/sse-replay.ts +0 -41
- package/src/api/events/conversation-notice.ts +0 -26
- package/src/approvals/guardian-channel-delivery.ts +0 -30
- package/src/approvals/guardian-expiry-notifier.ts +0 -148
- package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
- package/src/cli/commands/memory/worker.ts +0 -175
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
- package/src/config/prune-seeded-callsite-defaults.ts +0 -110
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
- package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
- package/src/contacts/guardian-delivery-reader.ts +0 -223
- package/src/contacts/member-write-relay.ts +0 -189
- package/src/daemon/conversation-notices.ts +0 -60
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
- package/src/hooks/hook-loader.ts +0 -341
- package/src/mcp/mcp-header-store.ts +0 -134
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
- package/src/memory/__tests__/prompt-override.test.ts +0 -192
- package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
- package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
- package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
- package/src/memory/prompt-override.ts +0 -129
- package/src/memory/steps.ts +0 -573
- package/src/memory/watchdog-events-store.ts +0 -87
- package/src/memory/worker-control.ts +0 -118
- package/src/memory/worker-process.ts +0 -72
- package/src/notifications/__tests__/connected-channels.test.ts +0 -114
- package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
- package/src/onboarding/checkin-event.test.ts +0 -222
- package/src/onboarding/checkin-event.ts +0 -321
- package/src/onboarding/schedule-checkin.ts +0 -190
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
- package/src/plugins/defaults/advisor/context-pack.ts +0 -288
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
- package/src/plugins/surface-import.ts +0 -121
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
- package/src/providers/openai/api-error-normalization.ts +0 -270
- package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
- package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
- package/src/runtime/anchored-guardian.test.ts +0 -156
- package/src/runtime/anchored-guardian.ts +0 -135
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
- package/src/runtime/local-principal-trust.ts +0 -52
- package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
- package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
- package/src/tools/filesystem/search.ts +0 -543
- package/src/util/telemetry-db-path.ts +0 -24
- package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
|
@@ -4,45 +4,10 @@ import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
|
4
4
|
|
|
5
5
|
const log = getLogger("db-init");
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Rollback metadata for a migration step that can be reversed.
|
|
9
|
-
*
|
|
10
|
-
* A single step may carry multiple rollback entries (e.g. migration 162 has
|
|
11
|
-
* two: one for the timestamp conversion and one for the table rebuild). Each
|
|
12
|
-
* entry has its own monotonic version number for rollback ordering and its
|
|
13
|
-
* own `down()` function.
|
|
14
|
-
*/
|
|
15
|
-
export interface RollbackEntry {
|
|
16
|
-
/** Monotonic version used for rollback ordering. */
|
|
17
|
-
version: number;
|
|
18
|
-
/** Human-readable description for diagnostics. */
|
|
19
|
-
description: string;
|
|
20
|
-
/** Reverse the migration. Must be idempotent — safe to re-run. */
|
|
21
|
-
down: (database: DrizzleDb) => void;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Object form of a migration step, carrying optional rollback metadata and
|
|
26
|
-
* dependency declarations inline — no separate registry needed.
|
|
27
|
-
*/
|
|
28
|
-
export interface MigrationStepObject {
|
|
29
|
-
/** Step name — used for `step:*` checkpoint key, logging, and skip logic. */
|
|
30
|
-
name: string;
|
|
31
|
-
/** Forward migration body. */
|
|
32
|
-
run: (database: DrizzleDb) => void | Promise<void>;
|
|
33
|
-
/** Step names that must complete before this step runs. */
|
|
34
|
-
dependsOn?: string[];
|
|
35
|
-
/** Rollback entries — present if this step has down() function(s). */
|
|
36
|
-
rollback?: RollbackEntry[];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
7
|
/**
|
|
40
8
|
* A single forward migration step, identified for checkpointing and logging by
|
|
41
9
|
* its `.name`. Anonymous steps (empty `.name`) cannot be tracked and always run.
|
|
42
10
|
*
|
|
43
|
-
* Bare function steps are identified by `Function.name`. Object-form steps
|
|
44
|
-
* carry an explicit `name` plus optional `rollback` and `dependsOn` metadata.
|
|
45
|
-
*
|
|
46
11
|
* A step may be synchronous or return a promise. The runner awaits an async
|
|
47
12
|
* step to completion before checkpointing it and moving on, so ordering is
|
|
48
13
|
* preserved exactly as for sync steps: step N+1 never starts — and is never
|
|
@@ -51,56 +16,7 @@ export interface MigrationStepObject {
|
|
|
51
16
|
* thread between batches while still guaranteeing later migrations observe its
|
|
52
17
|
* completed result.
|
|
53
18
|
*/
|
|
54
|
-
export type MigrationStep =
|
|
55
|
-
| MigrationStepObject
|
|
56
|
-
| ((database: DrizzleDb) => void | Promise<void>);
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Normalize a {@link MigrationStep} (which may be a bare function or an object)
|
|
60
|
-
* into its object form so callers don't need to type-narrow.
|
|
61
|
-
*/
|
|
62
|
-
export function normalizeStep(step: MigrationStep): MigrationStepObject {
|
|
63
|
-
if (typeof step === "function") {
|
|
64
|
-
return { name: step.name, run: step };
|
|
65
|
-
}
|
|
66
|
-
return step;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Extract the step name from either form of {@link MigrationStep}.
|
|
71
|
-
*/
|
|
72
|
-
export function getStepName(step: MigrationStep): string {
|
|
73
|
-
return typeof step === "function" ? step.name : step.name;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Get the maximum rollback version across all steps that carry rollback
|
|
78
|
-
* metadata. Returns 0 if no steps have rollback entries.
|
|
79
|
-
*/
|
|
80
|
-
export function getMaxRollbackVersion(steps: MigrationStep[]): number {
|
|
81
|
-
let max = 0;
|
|
82
|
-
for (const step of steps) {
|
|
83
|
-
if (typeof step === "function") continue;
|
|
84
|
-
if (!step.rollback) continue;
|
|
85
|
-
for (const entry of step.rollback) {
|
|
86
|
-
if (entry.version > max) max = entry.version;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return max;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Collect all step names that appear in the steps array (both bare-function
|
|
94
|
-
* and object-form). Used by {@link validateMigrationState} to detect
|
|
95
|
-
* checkpoints from a newer daemon version.
|
|
96
|
-
*/
|
|
97
|
-
export function getKnownStepNames(steps: MigrationStep[]): Set<string> {
|
|
98
|
-
const names = new Set<string>();
|
|
99
|
-
for (const step of steps) {
|
|
100
|
-
names.add(getStepName(step));
|
|
101
|
-
}
|
|
102
|
-
return names;
|
|
103
|
-
}
|
|
19
|
+
export type MigrationStep = (database: DrizzleDb) => void | Promise<void>;
|
|
104
20
|
|
|
105
21
|
export interface MigrationRunResult {
|
|
106
22
|
/** Steps that ran and completed successfully this boot. */
|
|
@@ -114,8 +30,9 @@ export interface MigrationRunResult {
|
|
|
114
30
|
/**
|
|
115
31
|
* Prefix under which forward-step completions are recorded in the shared
|
|
116
32
|
* `memory_checkpoints` ledger. A distinct namespace keeps step bookkeeping from
|
|
117
|
-
* colliding with
|
|
118
|
-
* `drop_*`)
|
|
33
|
+
* colliding with registry checkpoint keys (`migration_*`, `backfill_*`,
|
|
34
|
+
* `drop_*`) and is deliberately chosen so `validateMigrationState` does not
|
|
35
|
+
* mistake a step record for an unknown registry migration.
|
|
119
36
|
*/
|
|
120
37
|
export const STEP_CHECKPOINT_PREFIX = "step:";
|
|
121
38
|
|
|
@@ -244,8 +161,7 @@ export async function runMigrationSteps(
|
|
|
244
161
|
const ran: string[] = [];
|
|
245
162
|
|
|
246
163
|
for (const step of steps) {
|
|
247
|
-
const
|
|
248
|
-
const name = obj.name;
|
|
164
|
+
const name = step.name;
|
|
249
165
|
const checkpointable = name !== "";
|
|
250
166
|
|
|
251
167
|
if (checkpointable && applied.has(name)) {
|
|
@@ -259,7 +175,7 @@ export async function runMigrationSteps(
|
|
|
259
175
|
markStarted.run(`${STEP_CHECKPOINT_PREFIX}${name}`, Date.now());
|
|
260
176
|
}
|
|
261
177
|
log.info({ migration: name }, `Starting migration: ${name}`);
|
|
262
|
-
const result =
|
|
178
|
+
const result = step(database);
|
|
263
179
|
if (result instanceof Promise) {
|
|
264
180
|
await result;
|
|
265
181
|
}
|
|
@@ -3,25 +3,17 @@ import { getLogger } from "../../util/logger.js";
|
|
|
3
3
|
import { getDbPath } from "../../util/platform.js";
|
|
4
4
|
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
type
|
|
8
|
-
|
|
6
|
+
MIGRATION_REGISTRY,
|
|
7
|
+
type MigrationValidationResult,
|
|
8
|
+
} from "./registry.js";
|
|
9
|
+
import {
|
|
9
10
|
STEP_CHECKPOINT_PREFIX,
|
|
10
11
|
} from "./run-migrations.js";
|
|
11
12
|
|
|
12
13
|
const log = getLogger("memory-db");
|
|
13
14
|
|
|
14
|
-
export interface MigrationValidationResult {
|
|
15
|
-
/** Keys of migrations whose checkpoint has value 'started' — started but never completed. */
|
|
16
|
-
crashed: string[];
|
|
17
|
-
/** Pairs where a completed migration's declared prerequisite is missing from checkpoints. */
|
|
18
|
-
dependencyViolations: Array<{ migration: string; missingDependency: string }>;
|
|
19
|
-
/** Checkpoint keys present in the database but absent from the known step names — likely from a newer version. */
|
|
20
|
-
unknownCheckpoints: string[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
15
|
/**
|
|
24
|
-
* Validate the applied migration state against the
|
|
16
|
+
* Validate the applied migration state against the registry at startup.
|
|
25
17
|
*
|
|
26
18
|
* Logs a prominent error when a migration started but never completed (crash
|
|
27
19
|
* detected) — startup continues so the migration can be retried.
|
|
@@ -33,15 +25,9 @@ export interface MigrationValidationResult {
|
|
|
33
25
|
*
|
|
34
26
|
* Call this AFTER all DDL and migration functions have run so that the final
|
|
35
27
|
* state is inspected.
|
|
36
|
-
*
|
|
37
|
-
* @param database The Drizzle database instance.
|
|
38
|
-
* @param steps The full ordered migration step array (same one passed to
|
|
39
|
-
* `runMigrationSteps`). Used to determine known step names for unknown-checkpoint
|
|
40
|
-
* detection and to check `dependsOn` declarations.
|
|
41
28
|
*/
|
|
42
29
|
export function validateMigrationState(
|
|
43
30
|
database: DrizzleDb,
|
|
44
|
-
steps: MigrationStep[],
|
|
45
31
|
): MigrationValidationResult {
|
|
46
32
|
const raw = getSqliteFrom(database);
|
|
47
33
|
|
|
@@ -78,6 +64,8 @@ export function validateMigrationState(
|
|
|
78
64
|
}
|
|
79
65
|
|
|
80
66
|
// Build a set of completed step names from `step:*` checkpoints with value '1'.
|
|
67
|
+
// The step runner writes these — `migration_*` registry keys are no longer
|
|
68
|
+
// written by migration functions (Phase 2 removed withCrashRecovery).
|
|
81
69
|
const completedStepNames = new Set(
|
|
82
70
|
rows
|
|
83
71
|
.filter(
|
|
@@ -87,24 +75,32 @@ export function validateMigrationState(
|
|
|
87
75
|
.map((r) => r.key.slice(STEP_CHECKPOINT_PREFIX.length)),
|
|
88
76
|
);
|
|
89
77
|
|
|
90
|
-
//
|
|
91
|
-
//
|
|
78
|
+
// Map registry entries to their step names to determine which migrations
|
|
79
|
+
// are completed. Multiple registry entries can share the same step name
|
|
80
|
+
// (e.g., 162's two entries both map to migrateGuardianTimestampsEpochMs).
|
|
81
|
+
const completed = new Set<string>();
|
|
82
|
+
for (const entry of MIGRATION_REGISTRY) {
|
|
83
|
+
if (completedStepNames.has(entry.stepName)) {
|
|
84
|
+
completed.add(entry.key);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
92
88
|
const dependencyViolations: Array<{
|
|
93
89
|
migration: string;
|
|
94
90
|
missingDependency: string;
|
|
95
91
|
}> = [];
|
|
96
92
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (!
|
|
100
|
-
// Only check
|
|
93
|
+
// Validate dependency ordering.
|
|
94
|
+
for (const entry of MIGRATION_REGISTRY) {
|
|
95
|
+
if (!entry.dependsOn || entry.dependsOn.length === 0) continue;
|
|
96
|
+
// Only check entries that have been completed — unapplied or in-progress
|
|
101
97
|
// migrations have not had a chance to violate their prerequisites yet.
|
|
102
|
-
if (!
|
|
98
|
+
if (!completed.has(entry.key)) continue;
|
|
103
99
|
|
|
104
|
-
for (const dep of
|
|
105
|
-
if (!
|
|
100
|
+
for (const dep of entry.dependsOn) {
|
|
101
|
+
if (!completed.has(dep)) {
|
|
106
102
|
dependencyViolations.push({
|
|
107
|
-
migration:
|
|
103
|
+
migration: entry.key,
|
|
108
104
|
missingDependency: dep,
|
|
109
105
|
});
|
|
110
106
|
}
|
|
@@ -125,11 +121,10 @@ export function validateMigrationState(
|
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
// Detect step checkpoints that exist in the database but have no
|
|
128
|
-
// corresponding entry
|
|
129
|
-
|
|
130
|
-
const knownStepNames = new Set(steps.map((s) => getStepName(s)));
|
|
124
|
+
// corresponding registry entry — these are from a newer version of the daemon.
|
|
125
|
+
const registryStepNames = new Set(MIGRATION_REGISTRY.map((e) => e.stepName));
|
|
131
126
|
const unknownCheckpoints = [...completedStepNames].filter(
|
|
132
|
-
(name) => !
|
|
127
|
+
(name) => !registryStepNames.has(name),
|
|
133
128
|
);
|
|
134
129
|
|
|
135
130
|
if (unknownCheckpoints.length > 0) {
|
|
@@ -145,26 +140,23 @@ export function validateMigrationState(
|
|
|
145
140
|
/**
|
|
146
141
|
* Roll back all completed memory (database) migrations with version > targetVersion.
|
|
147
142
|
*
|
|
148
|
-
* Iterates eligible
|
|
149
|
-
*
|
|
150
|
-
* 1. Marks the step checkpoint as `"rolling_back"` for crash recovery.
|
|
143
|
+
* Iterates eligible migrations in reverse version order. For each:
|
|
144
|
+
* 1. Marks the checkpoint as `"rolling_back"` for crash recovery.
|
|
151
145
|
* 2. Calls `entry.down(database)` — each down() manages its own transactions.
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* A single step may carry multiple rollback entries (e.g. migration 162 has
|
|
155
|
-
* two). All entries with version > target are rolled back in reverse version
|
|
156
|
-
* order. The step checkpoint is only deleted after the last rollback entry
|
|
157
|
-
* for that step completes.
|
|
146
|
+
* (`down` is required on `MigrationRegistryEntry` at the type level.)
|
|
147
|
+
* 3. Deletes the checkpoint from `memory_checkpoints`.
|
|
158
148
|
*
|
|
159
149
|
* **Usage**: Pass the target version number you want to roll back *to*. All
|
|
160
|
-
*
|
|
161
|
-
* reversed. For example, `rollbackMemoryMigration(db, 5
|
|
162
|
-
*
|
|
150
|
+
* migrations with a higher version number that have been applied will be
|
|
151
|
+
* reversed. For example, `rollbackMemoryMigration(db, 5)` rolls back all
|
|
152
|
+
* applied migrations with version > 5.
|
|
163
153
|
*
|
|
164
|
-
* **Checkpoint state**: Each rolled-back
|
|
165
|
-
* from `memory_checkpoints
|
|
166
|
-
*
|
|
167
|
-
* `recoverCrashedMigrations` on the next startup.
|
|
154
|
+
* **Checkpoint state**: Each rolled-back migration's checkpoint is deleted
|
|
155
|
+
* from `memory_checkpoints`. If the process crashes mid-rollback, the
|
|
156
|
+
* `"rolling_back"` marker is detected and cleared by
|
|
157
|
+
* `recoverCrashedMigrations` on the next startup. The forward-step checkpoints
|
|
158
|
+
* recorded by the migration runner (the `step:` namespace) for the rolled-back
|
|
159
|
+
* entries are also discarded so a later upgrade re-applies them.
|
|
168
160
|
*
|
|
169
161
|
* **Warning — data loss**: Some down() migrations may not fully restore the
|
|
170
162
|
* original state (e.g., DROP TABLE migrations recreate the table but cannot
|
|
@@ -176,15 +168,13 @@ export function validateMigrationState(
|
|
|
176
168
|
* query failures, or data corruption.
|
|
177
169
|
*
|
|
178
170
|
* @param database The Drizzle database instance.
|
|
179
|
-
* @param targetVersion Roll back to this version (exclusive — all
|
|
180
|
-
*
|
|
181
|
-
* @
|
|
182
|
-
* @returns The list of rolled-back step names.
|
|
171
|
+
* @param targetVersion Roll back to this version (exclusive — all migrations
|
|
172
|
+
* with version > targetVersion are reversed).
|
|
173
|
+
* @returns The list of rolled-back migration keys.
|
|
183
174
|
*/
|
|
184
175
|
export function rollbackMemoryMigration(
|
|
185
176
|
database: DrizzleDb,
|
|
186
177
|
targetVersion: number,
|
|
187
|
-
steps: MigrationStep[],
|
|
188
178
|
): string[] {
|
|
189
179
|
const raw = getSqliteFrom(database);
|
|
190
180
|
|
|
@@ -208,66 +198,41 @@ export function rollbackMemoryMigration(
|
|
|
208
198
|
.map((r) => r.key.slice(STEP_CHECKPOINT_PREFIX.length)),
|
|
209
199
|
);
|
|
210
200
|
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const toRollback: RollbackItem[] = [];
|
|
222
|
-
for (const step of steps) {
|
|
223
|
-
const obj = normalizeStep(step);
|
|
224
|
-
if (!obj.rollback) continue;
|
|
225
|
-
if (!completedStepNames.has(obj.name)) continue;
|
|
201
|
+
// Find registry entries with version > targetVersion whose step is completed.
|
|
202
|
+
// Deduplicate by stepName — multiple registry entries can share the same step
|
|
203
|
+
// (e.g., 162's two entries), and we only need to clear the step checkpoint once.
|
|
204
|
+
const toRollback = MIGRATION_REGISTRY.filter(
|
|
205
|
+
(entry) =>
|
|
206
|
+
entry.version > targetVersion &&
|
|
207
|
+
completedStepNames.has(entry.stepName),
|
|
208
|
+
).sort((a, b) => b.version - a.version); // reverse version order
|
|
226
209
|
|
|
227
|
-
for (const entry of obj.rollback) {
|
|
228
|
-
if (entry.version > targetVersion) {
|
|
229
|
-
toRollback.push({
|
|
230
|
-
stepName: obj.name,
|
|
231
|
-
version: entry.version,
|
|
232
|
-
description: entry.description,
|
|
233
|
-
down: entry.down,
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Sort in reverse version order — children (higher version) before parents.
|
|
240
|
-
toRollback.sort((a, b) => b.version - a.version);
|
|
241
|
-
|
|
242
|
-
// Group by stepName so we only delete the checkpoint after all rollback
|
|
243
|
-
// entries for that step have been executed.
|
|
244
|
-
const stepNamesToRollback = new Set(toRollback.map((r) => r.stepName));
|
|
245
210
|
const rolledBack: string[] = [];
|
|
246
211
|
|
|
247
|
-
for (const
|
|
248
|
-
const stepKey = `${STEP_CHECKPOINT_PREFIX}${
|
|
212
|
+
for (const entry of toRollback) {
|
|
213
|
+
const stepKey = `${STEP_CHECKPOINT_PREFIX}${entry.stepName}`;
|
|
249
214
|
|
|
250
|
-
// Mark as rolling_back for crash recovery
|
|
215
|
+
// Mark as rolling_back for crash recovery — if the process crashes here,
|
|
216
|
+
// recoverCrashedMigrations will clear this checkpoint on next startup.
|
|
251
217
|
raw
|
|
252
218
|
.query(
|
|
253
219
|
`INSERT OR REPLACE INTO memory_checkpoints (key, value, updated_at) VALUES (?, 'rolling_back', ?)`,
|
|
254
220
|
)
|
|
255
221
|
.run(stepKey, Date.now());
|
|
256
222
|
|
|
257
|
-
// Execute the down migration.
|
|
258
|
-
|
|
223
|
+
// Execute the down migration — let it manage its own transaction lifecycle.
|
|
224
|
+
// Many down() functions call BEGIN/COMMIT internally or use PRAGMA statements
|
|
225
|
+
// that are no-ops inside a transaction.
|
|
226
|
+
entry.down(database);
|
|
227
|
+
|
|
228
|
+
// Delete the step checkpoint after down() succeeds.
|
|
229
|
+
raw.query(`DELETE FROM memory_checkpoints WHERE key = ?`).run(stepKey);
|
|
259
230
|
|
|
260
231
|
log.info(
|
|
261
|
-
{
|
|
262
|
-
`Rolled back migration "${
|
|
232
|
+
{ key: entry.key, version: entry.version },
|
|
233
|
+
`Rolled back migration "${entry.key}" (version ${entry.version})`,
|
|
263
234
|
);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
// After all down() calls succeed, delete checkpoints for the rolled-back steps.
|
|
267
|
-
for (const stepName of stepNamesToRollback) {
|
|
268
|
-
const stepKey = `${STEP_CHECKPOINT_PREFIX}${stepName}`;
|
|
269
|
-
raw.query(`DELETE FROM memory_checkpoints WHERE key = ?`).run(stepKey);
|
|
270
|
-
rolledBack.push(stepName);
|
|
235
|
+
rolledBack.push(entry.key);
|
|
271
236
|
}
|
|
272
237
|
|
|
273
238
|
return rolledBack;
|
|
@@ -52,15 +52,6 @@ export const conversations = sqliteTable(
|
|
|
52
52
|
inferenceProfileSessionId: text("inference_profile_session_id"),
|
|
53
53
|
inferenceProfileExpiresAt: integer("inference_profile_expires_at"),
|
|
54
54
|
lastNotifiedInferenceProfile: text("last_notified_inference_profile"),
|
|
55
|
-
/**
|
|
56
|
-
* Epoch-ms timestamp set when the agent loop starts a turn for this
|
|
57
|
-
* conversation, cleared (NULL) when the turn ends. NULL means not
|
|
58
|
-
* processing. This is the cross-process source of truth for processing
|
|
59
|
-
* state — the in-memory `Conversation._processing` flag is the hot-path
|
|
60
|
-
* read for resident conversations, but CLI-side and other out-of-process
|
|
61
|
-
* callers read this column directly.
|
|
62
|
-
*/
|
|
63
|
-
processingStartedAt: integer("processing_started_at"),
|
|
64
55
|
},
|
|
65
56
|
(table) => [
|
|
66
57
|
index("idx_conversations_updated_at").on(table.updatedAt),
|
|
@@ -337,26 +337,6 @@ export const skillLoadedEvents = sqliteTable(
|
|
|
337
337
|
],
|
|
338
338
|
);
|
|
339
339
|
|
|
340
|
-
// One row per `watchdog` telemetry event, emitted when a daemon watchdog
|
|
341
|
-
// check fires (event-loop block, stream-idle stall, restart, ...) — see
|
|
342
|
-
// watchdog-events-store.ts for the data contract. Flushed by the usage
|
|
343
|
-
// telemetry reporter. `value` is a REAL (BQ FLOAT) so the daemon need not
|
|
344
|
-
// distinguish int vs float; the platform serializer coerces ints to float.
|
|
345
|
-
// `detail` is a JSON bag stored as text and forwarded verbatim.
|
|
346
|
-
export const watchdogEvents = sqliteTable(
|
|
347
|
-
"watchdog_events",
|
|
348
|
-
{
|
|
349
|
-
id: text("id").primaryKey(),
|
|
350
|
-
createdAt: integer("created_at").notNull(),
|
|
351
|
-
checkName: text("check_name").notNull(),
|
|
352
|
-
value: real("value"),
|
|
353
|
-
detail: text("detail"),
|
|
354
|
-
},
|
|
355
|
-
(table) => [
|
|
356
|
-
index("idx_watchdog_events_created_at_id").on(table.createdAt, table.id),
|
|
357
|
-
],
|
|
358
|
-
);
|
|
359
|
-
|
|
360
340
|
export const traceEvents = sqliteTable(
|
|
361
341
|
"trace_events",
|
|
362
342
|
{
|
|
@@ -371,31 +371,6 @@ describe("seedV2CliCommandEntries", () => {
|
|
|
371
371
|
).rejects.toThrow("backend exploded");
|
|
372
372
|
});
|
|
373
373
|
|
|
374
|
-
test("populates the cache from the Commander tree on the first seed even when the embedding backend is unavailable (cold-start needle resilience)", async () => {
|
|
375
|
-
// Cold-start race: the startup seed runs before the managed embedding
|
|
376
|
-
// credential is provisioned, so the first `embedWithBackend` throws. The
|
|
377
|
-
// in-memory cache (read by the v3 needle lane and the page index) must
|
|
378
|
-
// still populate from the local Commander tree so CLI commands are
|
|
379
|
-
// discoverable from first boot; only the dense Qdrant upsert is deferred.
|
|
380
|
-
state.commands = [
|
|
381
|
-
{ name: "config", description: "Manage configuration", helpText: "..." },
|
|
382
|
-
];
|
|
383
|
-
state.embedThrows = new Error(
|
|
384
|
-
'Embedding backend "gemini" is not configured',
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
await expect(seedV2CliCommandEntries()).resolves.toBeUndefined();
|
|
388
|
-
|
|
389
|
-
const entry = getCliCommandCapability("config");
|
|
390
|
-
expect(entry).not.toBeNull();
|
|
391
|
-
expect(entry?.id).toBe("config");
|
|
392
|
-
expect(listCliCommandEntries().map((e) => e.id)).toEqual(["config"]);
|
|
393
|
-
|
|
394
|
-
// No dense vectors were produced, so the Qdrant write is skipped entirely.
|
|
395
|
-
expect(state.upsertCalls).toHaveLength(0);
|
|
396
|
-
expect(state.pruneCalls).toHaveLength(0);
|
|
397
|
-
});
|
|
398
|
-
|
|
399
374
|
test("skips stale in-flight seed results when a newer refresh is requested", async () => {
|
|
400
375
|
state.commands = [
|
|
401
376
|
{ name: "config", description: "Manage configuration", helpText: "..." },
|
|
@@ -619,86 +619,6 @@ Write a local article draft.
|
|
|
619
619
|
expect(after).toEqual(before);
|
|
620
620
|
});
|
|
621
621
|
|
|
622
|
-
test("populates the cache from the local catalog on the first seed even when the embedding backend is unavailable (cold-start needle resilience)", async () => {
|
|
623
|
-
// Regression: on a brand-new managed assistant the startup seed runs before
|
|
624
|
-
// the platform provisions the managed embedding credential, so the very
|
|
625
|
-
// first `embedWithBackend` throws. The in-memory cache (which the v3 needle
|
|
626
|
-
// lane and the page index read) must still populate from the local catalog
|
|
627
|
-
// so skills are discoverable from first boot; only the dense Qdrant upsert
|
|
628
|
-
// is deferred until the backend recovers.
|
|
629
|
-
const skillA = makeSummary({
|
|
630
|
-
id: "example-skill-a",
|
|
631
|
-
displayName: "Skill A",
|
|
632
|
-
});
|
|
633
|
-
state.catalog = [skillA];
|
|
634
|
-
state.resolved = [{ summary: skillA, state: "enabled" }];
|
|
635
|
-
// No prior successful seed — the backend is unconfigured from the start.
|
|
636
|
-
state.embedThrows = new Error(
|
|
637
|
-
'Embedding backend "gemini" is not configured',
|
|
638
|
-
);
|
|
639
|
-
|
|
640
|
-
// Best-effort callers (the startup seed) must resolve.
|
|
641
|
-
await expect(seedV2SkillEntries()).resolves.toBeUndefined();
|
|
642
|
-
|
|
643
|
-
// The needle-lane cache is populated despite the dense-embed failure.
|
|
644
|
-
const entry = getSkillCapability("example-skill-a");
|
|
645
|
-
expect(entry).not.toBeNull();
|
|
646
|
-
expect(entry?.id).toBe("example-skill-a");
|
|
647
|
-
expect(entry?.content).toContain("Skill A");
|
|
648
|
-
expect(listSkillEntries().map((e) => e.id)).toEqual(["example-skill-a"]);
|
|
649
|
-
|
|
650
|
-
// No dense vectors were produced, so the Qdrant write is skipped entirely.
|
|
651
|
-
expect(state.upsertCalls).toHaveLength(0);
|
|
652
|
-
expect(state.pruneCalls).toHaveLength(0);
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
test("surfaces the dense-embed failure to throwOnError callers while still populating the needle cache", async () => {
|
|
656
|
-
// The managed-credential reseed and the operator reembed route pass
|
|
657
|
-
// `throwOnError` so they learn the dense lane didn't complete and the
|
|
658
|
-
// retry/maintain machinery backfills it — but the needle cache is fixed
|
|
659
|
-
// regardless before the error propagates.
|
|
660
|
-
const skillA = makeSummary({ id: "example-skill-a" });
|
|
661
|
-
state.catalog = [skillA];
|
|
662
|
-
state.resolved = [{ summary: skillA, state: "enabled" }];
|
|
663
|
-
state.embedThrows = new Error("backend down");
|
|
664
|
-
|
|
665
|
-
await expect(seedV2SkillEntries({ throwOnError: true })).rejects.toThrow(
|
|
666
|
-
"backend down",
|
|
667
|
-
);
|
|
668
|
-
|
|
669
|
-
expect(getSkillCapability("example-skill-a")).not.toBeNull();
|
|
670
|
-
expect(state.upsertCalls).toHaveLength(0);
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
test("drops a locally-disabled installed skill even when the catalog is unavailable (local state is authoritative)", async () => {
|
|
674
|
-
// Regression: the local resolution is authoritative, so a skill that is
|
|
675
|
-
// still installed but explicitly disabled must NOT be kept alive by remote-
|
|
676
|
-
// catalog uncertainty — `getSkillCapability` and the page index must drop it.
|
|
677
|
-
const skillA = makeSummary({ id: "example-skill-a" });
|
|
678
|
-
state.catalog = [skillA];
|
|
679
|
-
state.resolved = [{ summary: skillA, state: "enabled" }];
|
|
680
|
-
state.fullCatalog = [
|
|
681
|
-
{ id: "example-skill-a", name: "example-skill-a", description: "A" },
|
|
682
|
-
];
|
|
683
|
-
state.embedReturn = [[0.1, 0.2, 0.3]];
|
|
684
|
-
|
|
685
|
-
// First run: skillA enabled and cached.
|
|
686
|
-
await seedV2SkillEntries();
|
|
687
|
-
expect(getSkillCapability("example-skill-a")).not.toBeNull();
|
|
688
|
-
|
|
689
|
-
// Second run: skillA is still locally installed but now disabled; the remote
|
|
690
|
-
// catalog is unavailable. It stays in `installedIds`, so the carry-forward
|
|
691
|
-
// must skip it and the cache drops it.
|
|
692
|
-
state.resolved = [{ summary: skillA, state: "disabled" }];
|
|
693
|
-
state.fullCatalog = [];
|
|
694
|
-
state.fullCatalogThrows = new Error("catalog fetch failed");
|
|
695
|
-
|
|
696
|
-
await seedV2SkillEntries();
|
|
697
|
-
|
|
698
|
-
expect(getSkillCapability("example-skill-a")).toBeNull();
|
|
699
|
-
expect(listSkillEntries()).toEqual([]);
|
|
700
|
-
});
|
|
701
|
-
|
|
702
622
|
test("no enabled skills yields empty cache and no prune when catalog is empty", async () => {
|
|
703
623
|
state.catalog = [];
|
|
704
624
|
state.resolved = [];
|