@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
|
@@ -93,7 +93,6 @@ import {
|
|
|
93
93
|
memoryV2ConsolidateJob,
|
|
94
94
|
} from "./v2/consolidation-job.js";
|
|
95
95
|
import { memoryV2SweepJob } from "./v2/sweep-job.js";
|
|
96
|
-
import { spawnMemoryWorkerProcess } from "./worker-control.js";
|
|
97
96
|
|
|
98
97
|
const log = getLogger("memory-jobs-worker");
|
|
99
98
|
|
|
@@ -162,64 +161,7 @@ export interface MemoryJobsWorker {
|
|
|
162
161
|
stop(): void;
|
|
163
162
|
}
|
|
164
163
|
|
|
165
|
-
/**
|
|
166
|
-
* Start the memory jobs worker using the configured implementation.
|
|
167
|
-
*
|
|
168
|
-
* `memory.worker.enabled` selects between two implementations:
|
|
169
|
-
* - enabled: spawn the worker as a separate OS process (the same path as
|
|
170
|
-
* `assistant memory worker start`), keeping long-running jobs off the
|
|
171
|
-
* caller's event loop.
|
|
172
|
-
* - disabled (default): run the worker in-process on the caller's event
|
|
173
|
-
* loop.
|
|
174
|
-
*
|
|
175
|
-
* The flag is read here so callers don't branch on it themselves. It only
|
|
176
|
-
* governs which implementation starts; shutdown stops whichever worker is
|
|
177
|
-
* actually running (see daemon/shutdown-handlers.ts), so the handle returned
|
|
178
|
-
* for the out-of-process implementation has a no-op `stop()`.
|
|
179
|
-
*
|
|
180
|
-
* This dispatcher must not be used as the standalone worker process's entry —
|
|
181
|
-
* that would recurse and fork-bomb. `worker-process.ts` calls
|
|
182
|
-
* {@link startInProcessMemoryJobsWorker} directly.
|
|
183
|
-
*/
|
|
184
164
|
export function startMemoryJobsWorker(): MemoryJobsWorker {
|
|
185
|
-
if (getConfig().memory.worker?.enabled === true) {
|
|
186
|
-
void spawnMemoryWorkerProcess()
|
|
187
|
-
.then(({ pid, alreadyRunning }) =>
|
|
188
|
-
log.info(
|
|
189
|
-
{ pid, alreadyRunning },
|
|
190
|
-
alreadyRunning
|
|
191
|
-
? "Memory worker process already running — reusing it"
|
|
192
|
-
: "Memory worker process started",
|
|
193
|
-
),
|
|
194
|
-
)
|
|
195
|
-
.catch((err) =>
|
|
196
|
-
log.warn(
|
|
197
|
-
{ err },
|
|
198
|
-
"Failed to start memory worker process — memory jobs will not be processed",
|
|
199
|
-
),
|
|
200
|
-
);
|
|
201
|
-
return {
|
|
202
|
-
async runOnce(): Promise<number> {
|
|
203
|
-
return 0;
|
|
204
|
-
},
|
|
205
|
-
// No-op: shutdown always stops the worker process via the live-state
|
|
206
|
-
// PID probe in daemon/shutdown-handlers.ts, since it can't know whether
|
|
207
|
-
// the process was started here or out of band (e.g. `assistant memory
|
|
208
|
-
// worker start`) after boot.
|
|
209
|
-
stop(): void {},
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return startInProcessMemoryJobsWorker();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Run the memory jobs worker in-process on the caller's event loop: poll for
|
|
218
|
-
* claimable jobs with adaptive backoff until {@link MemoryJobsWorker.stop} is
|
|
219
|
-
* called. This is the worker loop itself — used directly by the daemon (when
|
|
220
|
-
* `memory.worker.enabled` is off) and by the standalone worker process.
|
|
221
|
-
*/
|
|
222
|
-
export function startInProcessMemoryJobsWorker(): MemoryJobsWorker {
|
|
223
165
|
const recovered = resetRunningJobsToPending();
|
|
224
166
|
if (recovered > 0) {
|
|
225
167
|
log.info({ recovered }, "Recovered stale running memory jobs");
|
|
@@ -94,21 +94,14 @@ export type CompactionAgentLogRow = LogMetaRow & {
|
|
|
94
94
|
* can either stringify it directly (daemon-path `recordRequestLog`) or
|
|
95
95
|
* store it on a pending-log queue that stringifies later (wake-path
|
|
96
96
|
* `PendingLog.rawResponse`), without double-encoding.
|
|
97
|
-
*
|
|
98
|
-
* When the provider captured the verbatim upstream body, it is attached as a
|
|
99
|
-
* top-level `rawResponse` sibling so the inspector's Raw tab can show the
|
|
100
|
-
* actual provider payload (parsed JSON, or the raw string for non-JSON error
|
|
101
|
-
* pages) — matching the success path, where Raw shows the real provider JSON.
|
|
102
97
|
*/
|
|
103
98
|
export function buildProviderErrorResponsePayload(err: Error): {
|
|
104
99
|
error: Record<string, unknown>;
|
|
105
|
-
rawResponse?: unknown;
|
|
106
100
|
} {
|
|
107
101
|
const payload: Record<string, unknown> = {
|
|
108
102
|
name: err.name,
|
|
109
103
|
message: err.message,
|
|
110
104
|
};
|
|
111
|
-
let rawResponse: unknown;
|
|
112
105
|
if (err instanceof ProviderError) {
|
|
113
106
|
payload.code = err.code;
|
|
114
107
|
payload.provider = err.provider;
|
|
@@ -118,28 +111,10 @@ export function buildProviderErrorResponsePayload(err: Error): {
|
|
|
118
111
|
if (err.retryAfterMs !== undefined) {
|
|
119
112
|
payload.retryAfterMs = err.retryAfterMs;
|
|
120
113
|
}
|
|
121
|
-
if (err.apiErrorCode !== undefined) payload.apiErrorCode = err.apiErrorCode;
|
|
122
|
-
if (err.apiErrorType !== undefined) payload.apiErrorType = err.apiErrorType;
|
|
123
|
-
if (err.apiErrorParam !== undefined)
|
|
124
|
-
payload.apiErrorParam = err.apiErrorParam;
|
|
125
|
-
if (err.requestId !== undefined) payload.requestId = err.requestId;
|
|
126
|
-
if (err.rawBody !== undefined) rawResponse = parseRawBody(err.rawBody);
|
|
127
114
|
} else if (err instanceof AssistantError) {
|
|
128
115
|
payload.code = err.code;
|
|
129
116
|
}
|
|
130
|
-
return
|
|
131
|
-
? { error: payload, rawResponse }
|
|
132
|
-
: { error: payload };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/** Parse a captured upstream body as JSON, falling back to the raw string for
|
|
136
|
-
* non-JSON error pages (HTML, plain text) or a truncated/invalid prefix. */
|
|
137
|
-
function parseRawBody(rawBody: string): unknown {
|
|
138
|
-
try {
|
|
139
|
-
return JSON.parse(rawBody);
|
|
140
|
-
} catch {
|
|
141
|
-
return rawBody;
|
|
142
|
-
}
|
|
117
|
+
return { error: payload };
|
|
143
118
|
}
|
|
144
119
|
|
|
145
120
|
export function recordRequestLog(
|
|
@@ -525,32 +525,7 @@ export function getUsageTotals(
|
|
|
525
525
|
};
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
-
/**
|
|
529
|
-
* Width of the SQL pre-aggregation bucket used by the time-series read paths,
|
|
530
|
-
* in milliseconds. The series/daily endpoints bucket events into local-day or
|
|
531
|
-
* local-hour buckets in JavaScript (SQLite's `strftime` is UTC-only and can't
|
|
532
|
-
* honor an IANA timezone). To avoid materializing one JS object per usage event
|
|
533
|
-
* — which on a 90-day window can mean hundreds of thousands of rows on the
|
|
534
|
-
* daemon's main thread — we first roll events up in SQL into fixed UTC buckets,
|
|
535
|
-
* then feed those far-fewer rows into the same JS bucketing logic.
|
|
536
|
-
*
|
|
537
|
-
* 15 minutes is the finest quantum every real-world IANA UTC offset divides
|
|
538
|
-
* into (whole-hour offsets, plus the :30 and :45 zones like Asia/Kolkata and
|
|
539
|
-
* Asia/Kathmandu). Because every local-day and local-hour boundary therefore
|
|
540
|
-
* lands on a 15-minute UTC boundary, no pre-aggregation bucket can straddle a
|
|
541
|
-
* local bucket boundary — so rolling up to 15-minute UTC buckets and then
|
|
542
|
-
* re-bucketing in local time is exactly equal to bucketing each raw event.
|
|
543
|
-
* DST fall-back hours stay distinct because their instants fall in different
|
|
544
|
-
* 15-minute UTC buckets (and the JS layer disambiguates them by UTC offset).
|
|
545
|
-
*/
|
|
546
|
-
const USAGE_PREAGG_BUCKET_MS = 15 * 60 * 1000;
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Fetch usage rows for a time range, pre-aggregated into {@link
|
|
550
|
-
* USAGE_PREAGG_BUCKET_MS} UTC buckets, for in-memory local-time bucketing. Each
|
|
551
|
-
* returned row's `created_at` is its UTC bucket start, which the JS bucketing
|
|
552
|
-
* maps to the same local bucket every raw event in that window would map to.
|
|
553
|
-
*/
|
|
528
|
+
/** Fetch raw events in a time range for in-memory bucketing. */
|
|
554
529
|
function fetchRawBucketRows(
|
|
555
530
|
range: UsageTimeRange,
|
|
556
531
|
filter?: UsageAggregationFilter,
|
|
@@ -559,14 +534,13 @@ function fetchRawBucketRows(
|
|
|
559
534
|
return rawAll<UsageEventBucketRow>(
|
|
560
535
|
/*sql*/ `
|
|
561
536
|
SELECT
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
537
|
+
created_at,
|
|
538
|
+
input_tokens,
|
|
539
|
+
output_tokens,
|
|
540
|
+
estimated_cost_usd,
|
|
541
|
+
llm_call_count
|
|
567
542
|
FROM llm_usage_events
|
|
568
543
|
WHERE ${where.sql}
|
|
569
|
-
GROUP BY (created_at / ${USAGE_PREAGG_BUCKET_MS})
|
|
570
544
|
ORDER BY created_at ASC
|
|
571
545
|
`,
|
|
572
546
|
...where.params,
|
|
@@ -855,18 +829,17 @@ export function getUsageGroupedSeries(
|
|
|
855
829
|
WHERE ${where.sql}
|
|
856
830
|
)
|
|
857
831
|
SELECT
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
schedule_usage.group_key
|
|
864
|
-
|
|
832
|
+
schedule_usage.created_at,
|
|
833
|
+
schedule_usage.input_tokens,
|
|
834
|
+
schedule_usage.output_tokens,
|
|
835
|
+
schedule_usage.estimated_cost_usd,
|
|
836
|
+
schedule_usage.llm_call_count,
|
|
837
|
+
schedule_usage.group_key,
|
|
838
|
+
schedule_group_jobs.name AS group_label
|
|
865
839
|
FROM schedule_usage
|
|
866
840
|
LEFT JOIN cron_jobs schedule_group_jobs
|
|
867
841
|
ON schedule_group_jobs.id = schedule_usage.group_key
|
|
868
|
-
|
|
869
|
-
ORDER BY created_at ASC
|
|
842
|
+
ORDER BY schedule_usage.created_at ASC
|
|
870
843
|
`,
|
|
871
844
|
...groupKeySubquery.params,
|
|
872
845
|
...where.params,
|
|
@@ -877,16 +850,15 @@ export function getUsageGroupedSeries(
|
|
|
877
850
|
rows = rawAll<UsageGroupedBucketRow>(
|
|
878
851
|
/*sql*/ `
|
|
879
852
|
SELECT
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
853
|
+
e.created_at,
|
|
854
|
+
e.input_tokens,
|
|
855
|
+
e.output_tokens,
|
|
856
|
+
e.estimated_cost_usd,
|
|
857
|
+
e.llm_call_count,
|
|
885
858
|
e.${column} AS group_key
|
|
886
859
|
FROM llm_usage_events e
|
|
887
860
|
WHERE ${where.sql}
|
|
888
|
-
|
|
889
|
-
ORDER BY created_at ASC
|
|
861
|
+
ORDER BY e.created_at ASC
|
|
890
862
|
`,
|
|
891
863
|
...where.params,
|
|
892
864
|
);
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
} from "../channels/types.js";
|
|
45
45
|
import type { AssistantConfig } from "../config/types.js";
|
|
46
46
|
import { extractTurnContextTimestamp } from "../context/compactor.js";
|
|
47
|
+
import { findConversation } from "../daemon/conversation-registry.js";
|
|
47
48
|
import {
|
|
48
49
|
formatLocalTimestamp,
|
|
49
50
|
resolveTurnTimezoneContext,
|
|
@@ -62,7 +63,6 @@ import {
|
|
|
62
63
|
forkConversationForRetrospective,
|
|
63
64
|
getConversation,
|
|
64
65
|
getMessagesAfter,
|
|
65
|
-
isConversationProcessing,
|
|
66
66
|
resolveOverrideProfile,
|
|
67
67
|
} from "./conversation-crud.js";
|
|
68
68
|
import {
|
|
@@ -145,15 +145,14 @@ export async function runForkBasedRetrospective(
|
|
|
145
145
|
|
|
146
146
|
// Forking mid-turn would capture a half-finished display turn — incremental
|
|
147
147
|
// checkpoint persistence writes complete tool turns to the DB while the
|
|
148
|
-
// agent loop is still running.
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
// nothing is lost. Returning (not throwing) keeps the jobs-worker from
|
|
148
|
+
// agent loop is still running. Peek the in-memory registry only (an
|
|
149
|
+
// unloaded conversation is by definition not processing); never load the
|
|
150
|
+
// conversation just to check. Bump `lastRunAt` so the cooldown gate
|
|
151
|
+
// applies, leave `lastProcessedMessageId` untouched so the next
|
|
152
|
+
// interval/message-count trigger re-processes the same messages — nothing
|
|
153
|
+
// is lost. Returning (not throwing) keeps the jobs-worker from
|
|
155
154
|
// retry-with-backoff.
|
|
156
|
-
if (
|
|
155
|
+
if (findConversation(sourceConversationId)?.isProcessing()) {
|
|
157
156
|
bumpRetrospectiveLastRunAt(sourceConversationId, Date.now());
|
|
158
157
|
log.info(
|
|
159
158
|
{ sourceConversationId },
|
|
@@ -1,86 +1,6 @@
|
|
|
1
|
-
import { getLogger } from "../../util/logger.js";
|
|
2
|
-
import { getDbPath } from "../../util/platform.js";
|
|
3
|
-
import { runAsyncSqlite } from "../db-async-query.js";
|
|
4
1
|
import type { DrizzleDb } from "../db-connection.js";
|
|
5
2
|
import { getSqliteFrom } from "../db-connection.js";
|
|
6
3
|
|
|
7
|
-
const log = getLogger("db-init");
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Checkpoint key holding the highest `messages.rowid` already swept by this
|
|
11
|
-
* migration. Persisted after every window so an interrupted run resumes from
|
|
12
|
-
* where it left off instead of restarting the whole table scan. The value is a
|
|
13
|
-
* plain integer string — deliberately not `started`/`rolling_back`, so
|
|
14
|
-
* `recoverCrashedMigrations` never mistakes it for a stalled step and clears
|
|
15
|
-
* it, and not `step:`-prefixed, so `validateMigrationState` ignores it.
|
|
16
|
-
*/
|
|
17
|
-
const WATERMARK_KEY = "migration_209_strip_thinking_watermark";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Number of `rowid` values swept per `runAsyncSqlite` dispatch. Each window is
|
|
21
|
-
* one off-thread subprocess transaction, so the size bounds both the WAL growth
|
|
22
|
-
* per statement and how long a single write lock is held, while keeping the
|
|
23
|
-
* number of subprocess spawns low on a large table.
|
|
24
|
-
*/
|
|
25
|
-
const ROWID_WINDOW = 100_000;
|
|
26
|
-
|
|
27
|
-
/** SQL predicate: this `json_each` element is an internal reasoning block. */
|
|
28
|
-
const IS_THINKING = `json_extract(value, '$.type') IN ('thinking', 'redacted_thinking')`;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* SQL predicate: this `json_each` element is kept. `IS NOT` (not `!=`) so a
|
|
32
|
-
* block with a NULL/absent `type` is preserved, matching the JS filter the
|
|
33
|
-
* original migration used (`b.type !== 'thinking'`).
|
|
34
|
-
*/
|
|
35
|
-
const IS_KEPT = `json_extract(value, '$.type') IS NOT 'thinking' AND json_extract(value, '$.type') IS NOT 'redacted_thinking'`;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Build the two set-based UPDATEs that sweep one rowid window `(lo, hi]`.
|
|
39
|
-
*
|
|
40
|
-
* - Statement A strips thinking/redacted_thinking blocks from rows that retain
|
|
41
|
-
* at least one kept block, rebuilding the content array in place. `json(value)`
|
|
42
|
-
* re-embeds each surviving element as JSON rather than a quoted string.
|
|
43
|
-
* - Statement B replaces all-thinking rows (no kept block survives) with the
|
|
44
|
-
* null-byte placeholder sentinel so the message isn't left empty. `char(0)`
|
|
45
|
-
* is evaluated inside SQLite, so the literal NUL is produced in the database
|
|
46
|
-
* and never written into the SQL piped to the sqlite3 CLI.
|
|
47
|
-
*
|
|
48
|
-
* Both are gated by a cheap `content LIKE '%thinking%'` substring prefilter
|
|
49
|
-
* (covers both `thinking` and `redacted_thinking`) so the expensive `json_each`
|
|
50
|
-
* work only runs for rows that could possibly contain a reasoning block. The
|
|
51
|
-
* two statements touch disjoint row sets (A requires a kept block, B requires
|
|
52
|
-
* none), so their order within the window is immaterial.
|
|
53
|
-
*/
|
|
54
|
-
function windowSql(lo: number, hi: number): string {
|
|
55
|
-
const scope = `role = 'assistant'
|
|
56
|
-
AND rowid > ${lo} AND rowid <= ${hi}
|
|
57
|
-
AND content LIKE '%thinking%'
|
|
58
|
-
AND json_valid(content)
|
|
59
|
-
AND json_type(content) = 'array'`;
|
|
60
|
-
|
|
61
|
-
const stripMixed = /*sql*/ `
|
|
62
|
-
UPDATE messages
|
|
63
|
-
SET content = (
|
|
64
|
-
SELECT json_group_array(json(value))
|
|
65
|
-
FROM json_each(messages.content)
|
|
66
|
-
WHERE ${IS_KEPT}
|
|
67
|
-
)
|
|
68
|
-
WHERE ${scope}
|
|
69
|
-
AND EXISTS (SELECT 1 FROM json_each(messages.content) WHERE ${IS_THINKING})
|
|
70
|
-
AND EXISTS (SELECT 1 FROM json_each(messages.content) WHERE ${IS_KEPT});`;
|
|
71
|
-
|
|
72
|
-
const placeholderOnly = /*sql*/ `
|
|
73
|
-
UPDATE messages
|
|
74
|
-
SET content = json_array(
|
|
75
|
-
json_object('type', 'text', 'text', char(0) || '__PLACEHOLDER__[internal blocks omitted]')
|
|
76
|
-
)
|
|
77
|
-
WHERE ${scope}
|
|
78
|
-
AND EXISTS (SELECT 1 FROM json_each(messages.content) WHERE ${IS_THINKING})
|
|
79
|
-
AND NOT EXISTS (SELECT 1 FROM json_each(messages.content) WHERE ${IS_KEPT});`;
|
|
80
|
-
|
|
81
|
-
return `${stripMixed}\n${placeholderOnly}`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
4
|
/**
|
|
85
5
|
* Strip thinking and redacted_thinking blocks from all assistant messages.
|
|
86
6
|
*
|
|
@@ -91,62 +11,68 @@ function windowSql(lo: number, hi: number): string {
|
|
|
91
11
|
* provider no longer needs to strip, enabling append-only conversation
|
|
92
12
|
* history and stable prefix caching.
|
|
93
13
|
*
|
|
94
|
-
*
|
|
95
|
-
* {@link runAsyncSqlite} a rowid window at a time. On a host with the `sqlite3`
|
|
96
|
-
* CLI each window executes in a subprocess, leaving the daemon's event loop
|
|
97
|
-
* free to answer `/healthz` while a multi-GB table is rewritten — the original
|
|
98
|
-
* synchronous in-process loop blocked the loop for minutes and tripped the
|
|
99
|
-
* startup probe into a restart loop. Progress is checkpointed per window, so an
|
|
100
|
-
* interrupted run resumes instead of rescanning from the start.
|
|
101
|
-
*
|
|
102
|
-
* Idempotent — safe to re-run. Already-cleaned rows no longer contain a
|
|
103
|
-
* thinking block, so the substring prefilter skips them.
|
|
14
|
+
* Idempotent — safe to re-run.
|
|
104
15
|
*/
|
|
105
|
-
export
|
|
16
|
+
export function migrateStripThinkingFromConsolidated(
|
|
106
17
|
database: DrizzleDb,
|
|
107
|
-
):
|
|
18
|
+
): void {
|
|
108
19
|
const raw = getSqliteFrom(database);
|
|
109
|
-
const dbPath = getDbPath();
|
|
110
|
-
|
|
111
|
-
const maxRow = (
|
|
112
|
-
raw.query(`SELECT MAX(rowid) AS m FROM messages`).get() as {
|
|
113
|
-
m: number | null;
|
|
114
|
-
}
|
|
115
|
-
).m;
|
|
116
|
-
if (maxRow == null) return; // empty table — nothing to sweep
|
|
117
20
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
21
|
+
const BATCH_SIZE = 100;
|
|
22
|
+
let lastRowid = 0;
|
|
23
|
+
|
|
24
|
+
for (;;) {
|
|
25
|
+
const rows = raw
|
|
26
|
+
.query(
|
|
27
|
+
`SELECT rowid, id, content FROM messages
|
|
28
|
+
WHERE role = 'assistant'
|
|
29
|
+
AND rowid > ?
|
|
30
|
+
ORDER BY rowid
|
|
31
|
+
LIMIT ?`,
|
|
32
|
+
)
|
|
33
|
+
.all(lastRowid, BATCH_SIZE) as Array<{
|
|
34
|
+
rowid: number;
|
|
35
|
+
id: string;
|
|
36
|
+
content: string;
|
|
37
|
+
}>;
|
|
38
|
+
|
|
39
|
+
if (rows.length === 0) break;
|
|
40
|
+
|
|
41
|
+
for (const row of rows) {
|
|
42
|
+
lastRowid = row.rowid;
|
|
43
|
+
|
|
44
|
+
let blocks: Array<{ type: string }>;
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(row.content);
|
|
47
|
+
if (!Array.isArray(parsed)) continue;
|
|
48
|
+
blocks = parsed;
|
|
49
|
+
} catch {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const hasThinking = blocks.some(
|
|
54
|
+
(b) => b.type === "thinking" || b.type === "redacted_thinking",
|
|
55
|
+
);
|
|
56
|
+
if (!hasThinking) continue;
|
|
129
57
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// Leave the watermark at the last completed window; throwing reports the
|
|
133
|
-
// step failed so the runner retries it (from the watermark) next boot
|
|
134
|
-
// rather than checkpointing it as done.
|
|
135
|
-
throw new Error(
|
|
136
|
-
`strip-thinking window (${lo}, ${hi}] failed: ${res.error}`,
|
|
58
|
+
const stripped = blocks.filter(
|
|
59
|
+
(b) => b.type !== "thinking" && b.type !== "redacted_thinking",
|
|
137
60
|
);
|
|
138
|
-
}
|
|
139
61
|
|
|
140
|
-
|
|
141
|
-
|
|
62
|
+
// Preserve at least one block so the message isn't empty.
|
|
63
|
+
const finalContent =
|
|
64
|
+
stripped.length > 0
|
|
65
|
+
? stripped
|
|
66
|
+
: [
|
|
67
|
+
{
|
|
68
|
+
type: "text" as const,
|
|
69
|
+
text: "\x00__PLACEHOLDER__[internal blocks omitted]",
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
raw
|
|
74
|
+
.query(`UPDATE messages SET content = ? WHERE id = ?`)
|
|
75
|
+
.run(JSON.stringify(finalContent), row.id);
|
|
76
|
+
}
|
|
142
77
|
}
|
|
143
|
-
|
|
144
|
-
// Bound WAL growth left by the windowed rewrites, then drop the watermark so
|
|
145
|
-
// a future re-run (e.g. after a rollback) starts clean.
|
|
146
|
-
await runAsyncSqlite(`PRAGMA wal_checkpoint(TRUNCATE);`, { dbPath });
|
|
147
|
-
raw.query(`DELETE FROM memory_checkpoints WHERE key = ?`).run(WATERMARK_KEY);
|
|
148
|
-
|
|
149
|
-
log.info(
|
|
150
|
-
"Migration 209: stripped thinking blocks from consolidated messages",
|
|
151
|
-
);
|
|
152
78
|
}
|
|
@@ -54,7 +54,7 @@ describe("runMigrationSteps — checkpointing", () => {
|
|
|
54
54
|
|
|
55
55
|
test("records step completions in the shared memory_checkpoints ledger", async () => {
|
|
56
56
|
/**
|
|
57
|
-
* Step bookkeeping lives in the same memory_checkpoints table the
|
|
57
|
+
* Step bookkeeping lives in the same memory_checkpoints table the registry
|
|
58
58
|
* uses, under the `step:` namespace — one ledger for all applied state.
|
|
59
59
|
*/
|
|
60
60
|
|
|
@@ -110,7 +110,7 @@ describe("runMigrationSteps — checkpointing", () => {
|
|
|
110
110
|
* before the loop so a migration interrupted mid-flight re-runs this boot.
|
|
111
111
|
*/
|
|
112
112
|
|
|
113
|
-
// GIVEN a database with a stalled
|
|
113
|
+
// GIVEN a database with a stalled registry checkpoint left by a crash
|
|
114
114
|
const db = createTestDb();
|
|
115
115
|
const raw = getSqliteFrom(db);
|
|
116
116
|
raw.run(
|