@vellumai/assistant 0.10.12 → 0.11.0-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +246 -10
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +583 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +399 -0
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +158 -4
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +156 -58
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -30
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +4 -4
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +13 -13
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +218 -422
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +650 -333
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +85 -9
- package/src/permissions/checker.ts +17 -22
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +236 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +7 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { getLogger } from "../../util/logger.js";
|
|
5
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
6
|
+
|
|
7
|
+
const log = getLogger("workspace-migration-135");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Marks the two optional `memory.v2` keys that ship with no schema default
|
|
11
|
+
* (`min_sparse_spread`, `full_sparse_spread`) — for those, raw presence IS
|
|
12
|
+
* user intent, so they copy on presence alone.
|
|
13
|
+
*/
|
|
14
|
+
const NO_DEFAULT: unique symbol = Symbol("no-default");
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The fifteen substrate tunables shared between the historical `memory.v2`
|
|
18
|
+
* namespace and the new `memory.substrate` namespace, each paired with the
|
|
19
|
+
* shipped `memory.v2` schema default (from `config/schemas/memory-v2.ts`).
|
|
20
|
+
* `memory.v2.k` and `memory.v2.hops` were renamed to `spread_k` /
|
|
21
|
+
* `spread_hops` on the substrate side; every other key keeps its name.
|
|
22
|
+
*
|
|
23
|
+
* The defaults matter because raw presence in config.json is NOT user intent:
|
|
24
|
+
* the config loader serializes the fully-parsed configuration for
|
|
25
|
+
* normally-created workspaces, so defaulted `memory.v2` leaves are persisted
|
|
26
|
+
* for most existing assistants. Copying those seeded values would populate
|
|
27
|
+
* the override-only `memory.substrate` namespace with today's defaults and
|
|
28
|
+
* permanently pin those assistants when substrate defaults are later retuned
|
|
29
|
+
* — the same default-pinning problem migration 119 solves for `memory.v3`
|
|
30
|
+
* tuning, distinguished the same way (value-vs-shipped-default comparison,
|
|
31
|
+
* table inlined per the migrations self-containment rule).
|
|
32
|
+
*/
|
|
33
|
+
const SUBSTRATE_KEY_PAIRS: ReadonlyArray<{
|
|
34
|
+
v2Key: string;
|
|
35
|
+
substrateKey: string;
|
|
36
|
+
shippedDefault: number | boolean | string | null | typeof NO_DEFAULT;
|
|
37
|
+
/**
|
|
38
|
+
* Additional values the loader has seeded as this key's default in earlier
|
|
39
|
+
* releases (multi-default keys, mirroring migration 119). A persisted value
|
|
40
|
+
* matching any of them is seeded, not a user override.
|
|
41
|
+
*/
|
|
42
|
+
priorDefaults?: ReadonlyArray<number | boolean | string | null>;
|
|
43
|
+
}> = [
|
|
44
|
+
{
|
|
45
|
+
v2Key: "sweep_enabled",
|
|
46
|
+
substrateKey: "sweep_enabled",
|
|
47
|
+
shippedDefault: false,
|
|
48
|
+
},
|
|
49
|
+
{ v2Key: "dense_weight", substrateKey: "dense_weight", shippedDefault: 0.85 },
|
|
50
|
+
{
|
|
51
|
+
v2Key: "sparse_weight",
|
|
52
|
+
substrateKey: "sparse_weight",
|
|
53
|
+
shippedDefault: 0.15,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
v2Key: "min_sparse_spread",
|
|
57
|
+
substrateKey: "min_sparse_spread",
|
|
58
|
+
shippedDefault: NO_DEFAULT,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
v2Key: "full_sparse_spread",
|
|
62
|
+
substrateKey: "full_sparse_spread",
|
|
63
|
+
shippedDefault: NO_DEFAULT,
|
|
64
|
+
},
|
|
65
|
+
{ v2Key: "bm25_k1", substrateKey: "bm25_k1", shippedDefault: 1.2 },
|
|
66
|
+
{
|
|
67
|
+
v2Key: "bm25_b",
|
|
68
|
+
substrateKey: "bm25_b",
|
|
69
|
+
shippedDefault: 0.4,
|
|
70
|
+
// Workspaces seeded before migration 075 carry the earlier 0.75 default.
|
|
71
|
+
priorDefaults: [0.75],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
v2Key: "consolidation_interval_hours",
|
|
75
|
+
substrateKey: "consolidation_interval_hours",
|
|
76
|
+
shippedDefault: 8,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
v2Key: "consolidation_max_buffer_lines",
|
|
80
|
+
substrateKey: "consolidation_max_buffer_lines",
|
|
81
|
+
shippedDefault: 100,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
v2Key: "consolidation_max_entries_per_run",
|
|
85
|
+
substrateKey: "consolidation_max_entries_per_run",
|
|
86
|
+
shippedDefault: 150,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
v2Key: "max_page_chars",
|
|
90
|
+
substrateKey: "max_page_chars",
|
|
91
|
+
shippedDefault: 5000,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
v2Key: "consolidation_prompt_path",
|
|
95
|
+
substrateKey: "consolidation_prompt_path",
|
|
96
|
+
shippedDefault: null,
|
|
97
|
+
},
|
|
98
|
+
{ v2Key: "k", substrateKey: "spread_k", shippedDefault: 0.5 },
|
|
99
|
+
{ v2Key: "hops", substrateKey: "spread_hops", shippedDefault: 2 },
|
|
100
|
+
{
|
|
101
|
+
v2Key: "ann_candidate_limit",
|
|
102
|
+
substrateKey: "ann_candidate_limit",
|
|
103
|
+
shippedDefault: null,
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
108
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Copy user-overridden substrate tunables from `memory.v2` to
|
|
113
|
+
* `memory.substrate` so the substrate namespace carries the user's tuned
|
|
114
|
+
* values itself, independent of the runtime resolver's substrate→v2 fallback.
|
|
115
|
+
*
|
|
116
|
+
* Value-based, not presence-based: a key is copied only when it is present
|
|
117
|
+
* under `memory.v2`, absent under `memory.substrate`, AND its value differs
|
|
118
|
+
* from the shipped v2 schema default. The config loader persists the
|
|
119
|
+
* fully-parsed configuration for normally-created workspaces, so a defaulted
|
|
120
|
+
* `memory.v2` leaf in config.json is seeded, not user intent — copying it
|
|
121
|
+
* would pin the assistant to today's value when substrate defaults are later
|
|
122
|
+
* retuned (migration 119's rationale). A persisted value equal to its shipped
|
|
123
|
+
* default is treated as seeded even if a user typed it deliberately — the
|
|
124
|
+
* acceptable trade-off 119 already makes — so `memory.substrate` stays an
|
|
125
|
+
* override-only surface. The two no-default keys (`min_sparse_spread`,
|
|
126
|
+
* `full_sparse_spread`) copy on presence alone.
|
|
127
|
+
*
|
|
128
|
+
* That rule is narrower than "explicitly present", and the gap is deliberate:
|
|
129
|
+
* a value equal to a shipped default never copies, even when the user typed it
|
|
130
|
+
* on purpose. For every key whose shipped default is the current one that costs
|
|
131
|
+
* nothing — `memory.substrate` plus the shipped defaults resolve to exactly
|
|
132
|
+
* what the resolver's fallback produces. `bm25_b`'s retired `0.75` is the sole
|
|
133
|
+
* exception: it is skipped as seeded yet differs from today's `0.4`, so on a
|
|
134
|
+
* workspace carrying it the value survives only through the resolver's
|
|
135
|
+
* `memory.v2` fallback. That is the one case where dropping the fallback would
|
|
136
|
+
* change behavior — see the equivalence proof in this migration's test.
|
|
137
|
+
*
|
|
138
|
+
* `memory.v2.*` is never modified — the v2 injection engine still reads it.
|
|
139
|
+
* An already-present `memory.substrate` key is never clobbered. `memory.substrate` is only
|
|
140
|
+
* written at all when at least one key copies, so a fresh config never gains
|
|
141
|
+
* an empty object.
|
|
142
|
+
*
|
|
143
|
+
* Weight-pair safety: copying cannot create an invalid config. The v2
|
|
144
|
+
* schema's own refinement validates `dense_weight + sparse_weight` on the
|
|
145
|
+
* PERSISTED values (absent leaves resolve to defaults before the check), so a
|
|
146
|
+
* valid config carrying a non-default weight necessarily carries its
|
|
147
|
+
* non-default twin — both differ from their defaults, both copy, and the
|
|
148
|
+
* copied substrate pair is exactly the pair v2 already accepted.
|
|
149
|
+
*/
|
|
150
|
+
export const copySubstrateTunablesMigration: WorkspaceMigration = {
|
|
151
|
+
id: "135-copy-substrate-tunables",
|
|
152
|
+
description:
|
|
153
|
+
"Copy memory.v2 substrate tunables that differ from their shipped defaults to memory.substrate (k→spread_k, hops→spread_hops) without touching memory.v2, clobbering existing memory.substrate values, or pinning loader-seeded defaults",
|
|
154
|
+
// run() only ever adds missing memory.substrate keys and never clobbers
|
|
155
|
+
// present ones, so retrying after a failed write attempt is safe.
|
|
156
|
+
retryFailedCheckpoint: true,
|
|
157
|
+
|
|
158
|
+
run(workspaceDir: string): void {
|
|
159
|
+
const configPath = join(workspaceDir, "config.json");
|
|
160
|
+
if (!existsSync(configPath)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// A filesystem read failure propagates so the failed checkpoint retries
|
|
165
|
+
// on the next boot; only malformed JSON is a permanent no-op (the config
|
|
166
|
+
// loader owns surfacing that error).
|
|
167
|
+
const rawText = readFileSync(configPath, "utf-8");
|
|
168
|
+
let config: Record<string, unknown>;
|
|
169
|
+
try {
|
|
170
|
+
const raw = JSON.parse(rawText);
|
|
171
|
+
if (!isPlainObject(raw)) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
config = raw;
|
|
175
|
+
} catch {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const memory = config.memory;
|
|
180
|
+
if (!isPlainObject(memory)) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const v2 = memory.v2;
|
|
184
|
+
if (!isPlainObject(v2)) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// A malformed (non-object) persisted memory.substrate is left alone — the
|
|
188
|
+
// config loader surfaces that error; this migration must not clobber it.
|
|
189
|
+
if (memory.substrate !== undefined && !isPlainObject(memory.substrate)) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Staged separately so memory.substrate is only attached when a key
|
|
194
|
+
// actually copies — never introduce an empty object.
|
|
195
|
+
const substrate: Record<string, unknown> = isPlainObject(memory.substrate)
|
|
196
|
+
? memory.substrate
|
|
197
|
+
: {};
|
|
198
|
+
|
|
199
|
+
let copied = false;
|
|
200
|
+
for (const {
|
|
201
|
+
v2Key,
|
|
202
|
+
substrateKey,
|
|
203
|
+
shippedDefault,
|
|
204
|
+
priorDefaults,
|
|
205
|
+
} of SUBSTRATE_KEY_PAIRS) {
|
|
206
|
+
if (!(v2Key in v2) || substrateKey in substrate) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
// A persisted value equal to a shipped default (current or from an
|
|
210
|
+
// earlier release) is loader-seeded, not a user override — skip it so
|
|
211
|
+
// the substrate namespace stays override-only. Strict equality
|
|
212
|
+
// suffices: every tunable value is a primitive or null.
|
|
213
|
+
const value = v2[v2Key];
|
|
214
|
+
if (shippedDefault !== NO_DEFAULT && value === shippedDefault) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (priorDefaults?.some((seeded) => seeded === value)) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
substrate[substrateKey] = v2[v2Key];
|
|
221
|
+
copied = true;
|
|
222
|
+
}
|
|
223
|
+
if (!copied) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
memory.substrate = substrate;
|
|
227
|
+
|
|
228
|
+
// Write-then-rename keeps the migration rerunnable: a crash mid-write
|
|
229
|
+
// must not leave a truncated config.json that a retry reads as malformed
|
|
230
|
+
// and "completes" past, stranding the user's v2 overrides. A write or
|
|
231
|
+
// rename failure propagates to the runner, which checkpoints this
|
|
232
|
+
// migration as failed and (via retryFailedCheckpoint) retries it on the
|
|
233
|
+
// next boot instead of recording it as completed.
|
|
234
|
+
const tmpPath = `${configPath}.tmp`;
|
|
235
|
+
writeFileSync(tmpPath, JSON.stringify(config, null, 2) + "\n");
|
|
236
|
+
renameSync(tmpPath, configPath);
|
|
237
|
+
log.info(
|
|
238
|
+
"Copied non-default memory.v2 substrate tunables to memory.substrate",
|
|
239
|
+
);
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
down(_workspaceDir: string): void {
|
|
243
|
+
// Forward-only: a copied value is indistinguishable from one the user set
|
|
244
|
+
// under memory.substrate directly, so removal could destroy deliberate
|
|
245
|
+
// overrides. The copy is also behavior-preserving, so there is nothing to
|
|
246
|
+
// unwind.
|
|
247
|
+
},
|
|
248
|
+
};
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import {
|
|
2
|
+
chmodSync,
|
|
3
|
+
existsSync,
|
|
4
|
+
mkdtempSync,
|
|
5
|
+
readFileSync,
|
|
6
|
+
rmSync,
|
|
7
|
+
writeFileSync,
|
|
8
|
+
} from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
12
|
+
|
|
13
|
+
import { MemoryConfigSchema } from "../../../config/schemas/memory.js";
|
|
14
|
+
import { MemoryV2ConfigSchema } from "../../../config/schemas/memory-v2.js";
|
|
15
|
+
import {
|
|
16
|
+
resolveSubstrateTuning,
|
|
17
|
+
type SubstrateTuning,
|
|
18
|
+
} from "../../../plugins/defaults/memory/substrate/tuning.js";
|
|
19
|
+
import { copySubstrateTunablesMigration as MIG } from "../135-copy-substrate-tunables.js";
|
|
20
|
+
|
|
21
|
+
let workspaceDir: string;
|
|
22
|
+
let configPath: string;
|
|
23
|
+
|
|
24
|
+
/** The shipped `memory.v2` defaults, i.e. the effective value of an unset key. */
|
|
25
|
+
const V2_SCHEMA_DEFAULTS = MemoryV2ConfigSchema.parse({});
|
|
26
|
+
|
|
27
|
+
function pick<T>(
|
|
28
|
+
substrate: Record<string, unknown>,
|
|
29
|
+
key: string,
|
|
30
|
+
fallback: T,
|
|
31
|
+
): T {
|
|
32
|
+
// Presence, not truthiness: `resolveSubstrateTuning` falls back only on
|
|
33
|
+
// `undefined`, so an explicit `null` counts as set.
|
|
34
|
+
return key in substrate ? (substrate[key] as T) : fallback;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* `resolveSubstrateTuning` with the `memory.v2` fallback stripped: every
|
|
39
|
+
* tunable resolves from `memory.substrate` alone, or from the shipped v2
|
|
40
|
+
* schema default when the substrate key is absent.
|
|
41
|
+
*
|
|
42
|
+
* Migration 135's whole purpose is to make this resolver agree with the real
|
|
43
|
+
* one on a migrated workspace — that agreement is what lets the fallback be
|
|
44
|
+
* removed later without changing anyone's behavior.
|
|
45
|
+
*/
|
|
46
|
+
function resolveSubstrateOnly(
|
|
47
|
+
substrate: Record<string, unknown>,
|
|
48
|
+
): SubstrateTuning {
|
|
49
|
+
const d = V2_SCHEMA_DEFAULTS;
|
|
50
|
+
return {
|
|
51
|
+
sweep_enabled: pick(substrate, "sweep_enabled", d.sweep_enabled),
|
|
52
|
+
dense_weight: pick(substrate, "dense_weight", d.dense_weight),
|
|
53
|
+
sparse_weight: pick(substrate, "sparse_weight", d.sparse_weight),
|
|
54
|
+
min_sparse_spread: pick(
|
|
55
|
+
substrate,
|
|
56
|
+
"min_sparse_spread",
|
|
57
|
+
d.min_sparse_spread,
|
|
58
|
+
),
|
|
59
|
+
full_sparse_spread: pick(
|
|
60
|
+
substrate,
|
|
61
|
+
"full_sparse_spread",
|
|
62
|
+
d.full_sparse_spread,
|
|
63
|
+
),
|
|
64
|
+
bm25_k1: pick(substrate, "bm25_k1", d.bm25_k1),
|
|
65
|
+
bm25_b: pick(substrate, "bm25_b", d.bm25_b),
|
|
66
|
+
consolidation_interval_hours: pick(
|
|
67
|
+
substrate,
|
|
68
|
+
"consolidation_interval_hours",
|
|
69
|
+
d.consolidation_interval_hours,
|
|
70
|
+
),
|
|
71
|
+
consolidation_max_buffer_lines: pick(
|
|
72
|
+
substrate,
|
|
73
|
+
"consolidation_max_buffer_lines",
|
|
74
|
+
d.consolidation_max_buffer_lines,
|
|
75
|
+
),
|
|
76
|
+
consolidation_max_entries_per_run: pick(
|
|
77
|
+
substrate,
|
|
78
|
+
"consolidation_max_entries_per_run",
|
|
79
|
+
d.consolidation_max_entries_per_run,
|
|
80
|
+
),
|
|
81
|
+
max_page_chars: pick(substrate, "max_page_chars", d.max_page_chars),
|
|
82
|
+
consolidation_prompt_path: pick(
|
|
83
|
+
substrate,
|
|
84
|
+
"consolidation_prompt_path",
|
|
85
|
+
d.consolidation_prompt_path,
|
|
86
|
+
),
|
|
87
|
+
spread_k: pick(substrate, "spread_k", d.k),
|
|
88
|
+
spread_hops: pick(substrate, "spread_hops", d.hops),
|
|
89
|
+
ann_candidate_limit: pick(
|
|
90
|
+
substrate,
|
|
91
|
+
"ann_candidate_limit",
|
|
92
|
+
d.ann_candidate_limit,
|
|
93
|
+
),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function write(obj: unknown): void {
|
|
98
|
+
writeFileSync(configPath, JSON.stringify(obj, null, 2) + "\n");
|
|
99
|
+
}
|
|
100
|
+
function readRaw(): string {
|
|
101
|
+
return readFileSync(configPath, "utf-8");
|
|
102
|
+
}
|
|
103
|
+
function read(): Record<string, unknown> {
|
|
104
|
+
return JSON.parse(readRaw());
|
|
105
|
+
}
|
|
106
|
+
function memory(): Record<string, unknown> {
|
|
107
|
+
return read().memory as Record<string, unknown>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
beforeEach(() => {
|
|
111
|
+
workspaceDir = mkdtempSync(join(tmpdir(), "copy-substrate-tunables-"));
|
|
112
|
+
configPath = join(workspaceDir, "config.json");
|
|
113
|
+
});
|
|
114
|
+
afterEach(() => {
|
|
115
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe("135-copy-substrate-tunables", () => {
|
|
119
|
+
test("has the expected id", () => {
|
|
120
|
+
expect(MIG.id).toBe("135-copy-substrate-tunables");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("no-ops when config.json is absent, unparseable, or has no memory config", () => {
|
|
124
|
+
// Absent config.json.
|
|
125
|
+
expect(() => MIG.run(workspaceDir)).not.toThrow();
|
|
126
|
+
|
|
127
|
+
// Unparseable config.json is left byte-for-byte alone.
|
|
128
|
+
writeFileSync(configPath, "{not json");
|
|
129
|
+
MIG.run(workspaceDir);
|
|
130
|
+
expect(readRaw()).toBe("{not json");
|
|
131
|
+
|
|
132
|
+
// No memory config — fresh-workspace shape.
|
|
133
|
+
write({ llm: { provider: "anthropic" } });
|
|
134
|
+
const before = readRaw();
|
|
135
|
+
MIG.run(workspaceDir);
|
|
136
|
+
expect(readRaw()).toBe(before);
|
|
137
|
+
|
|
138
|
+
// memory present but no v2 subtree.
|
|
139
|
+
write({ memory: { enabled: true } });
|
|
140
|
+
const beforeNoV2 = readRaw();
|
|
141
|
+
MIG.run(workspaceDir);
|
|
142
|
+
expect(readRaw()).toBe(beforeNoV2);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("never introduces memory.substrate when memory.v2 sets no substrate tunables", () => {
|
|
146
|
+
write({ memory: { v2: { enabled: true, hybrid_min_score: 0.02 } } });
|
|
147
|
+
const before = readRaw();
|
|
148
|
+
|
|
149
|
+
MIG.run(workspaceDir);
|
|
150
|
+
|
|
151
|
+
// Nothing copied → no write at all, so no empty substrate object appears.
|
|
152
|
+
expect(readRaw()).toBe(before);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("copies an explicit memory.v2.consolidation_interval_hours, leaving memory.v2 untouched", () => {
|
|
156
|
+
write({
|
|
157
|
+
memory: {
|
|
158
|
+
v2: { enabled: true, consolidation_interval_hours: 6 },
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
MIG.run(workspaceDir);
|
|
163
|
+
|
|
164
|
+
expect(memory()).toEqual({
|
|
165
|
+
v2: { enabled: true, consolidation_interval_hours: 6 },
|
|
166
|
+
substrate: { consolidation_interval_hours: 6 },
|
|
167
|
+
});
|
|
168
|
+
// Temp-then-rename persistence leaves no temp file behind on success.
|
|
169
|
+
expect(existsSync(configPath + ".tmp")).toBe(false);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Root bypasses file permission checks, so chmod cannot make the workspace
|
|
173
|
+
// read-only — skip rather than assert a failure path that cannot be
|
|
174
|
+
// exercised.
|
|
175
|
+
test.skipIf(process.getuid?.() === 0)(
|
|
176
|
+
"throws on a write failure, leaving config.json byte-for-byte intact (retryable via failed checkpoint)",
|
|
177
|
+
() => {
|
|
178
|
+
write({ memory: { v2: { bm25_b: 0.6 } } });
|
|
179
|
+
const before = readRaw();
|
|
180
|
+
|
|
181
|
+
// A read-only workspace dir blocks creation of the config.json.tmp
|
|
182
|
+
// staging file, standing in for any persistence failure.
|
|
183
|
+
chmodSync(workspaceDir, 0o555);
|
|
184
|
+
try {
|
|
185
|
+
expect(() => MIG.run(workspaceDir)).toThrow();
|
|
186
|
+
} finally {
|
|
187
|
+
chmodSync(workspaceDir, 0o755);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// The failure surfaces to the runner (failed checkpoint, not completed)
|
|
191
|
+
// and the migration opts into retrying that checkpoint on the next boot.
|
|
192
|
+
expect(MIG.retryFailedCheckpoint).toBe(true);
|
|
193
|
+
// config.json is untouched — the failed write targeted the temp file.
|
|
194
|
+
expect(readRaw()).toBe(before);
|
|
195
|
+
expect(existsSync(configPath + ".tmp")).toBe(false);
|
|
196
|
+
|
|
197
|
+
// The retry succeeds once the workspace is writable again.
|
|
198
|
+
MIG.run(workspaceDir);
|
|
199
|
+
expect(memory().substrate).toEqual({ bm25_b: 0.6 });
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// Root bypasses file permission checks, so chmod 0o000 cannot make the
|
|
204
|
+
// file unreadable — skip rather than assert a failure path that cannot be
|
|
205
|
+
// exercised.
|
|
206
|
+
test.skipIf(process.getuid?.() === 0)(
|
|
207
|
+
"throws on a filesystem read failure so the failed checkpoint retries; malformed JSON stays a no-op",
|
|
208
|
+
() => {
|
|
209
|
+
write({ memory: { v2: { bm25_b: 0.6 } } });
|
|
210
|
+
|
|
211
|
+
// An unreadable config.json is a transient fs failure, not malformed
|
|
212
|
+
// content — it must surface to the runner instead of completing.
|
|
213
|
+
chmodSync(configPath, 0o000);
|
|
214
|
+
try {
|
|
215
|
+
expect(() => MIG.run(workspaceDir)).toThrow();
|
|
216
|
+
} finally {
|
|
217
|
+
chmodSync(configPath, 0o644);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// The retry succeeds once the file is readable again.
|
|
221
|
+
MIG.run(workspaceDir);
|
|
222
|
+
expect(memory().substrate).toEqual({ bm25_b: 0.6 });
|
|
223
|
+
},
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
test("renames k→spread_k and hops→spread_hops; a tuned bm25_b lands on the substrate key", () => {
|
|
227
|
+
write({
|
|
228
|
+
memory: {
|
|
229
|
+
v2: { k: 0.4, hops: 3, bm25_b: 0.6 },
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
MIG.run(workspaceDir);
|
|
234
|
+
|
|
235
|
+
expect(memory().substrate).toEqual({
|
|
236
|
+
spread_k: 0.4,
|
|
237
|
+
spread_hops: 3,
|
|
238
|
+
bm25_b: 0.6,
|
|
239
|
+
});
|
|
240
|
+
expect(memory().v2).toEqual({ k: 0.4, hops: 3, bm25_b: 0.6 });
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test("a migrated workspace resolves identically with the v2 fallback stripped", () => {
|
|
244
|
+
// A normally-created workspace: loader-seeded defaults alongside real user
|
|
245
|
+
// overrides, including the two no-default spread keys and the nullable
|
|
246
|
+
// keys on both sides of the copy rule.
|
|
247
|
+
write({
|
|
248
|
+
memory: {
|
|
249
|
+
v2: {
|
|
250
|
+
enabled: true,
|
|
251
|
+
// Seeded defaults — the migration must leave these behind.
|
|
252
|
+
sweep_enabled: false,
|
|
253
|
+
dense_weight: 0.85,
|
|
254
|
+
sparse_weight: 0.15,
|
|
255
|
+
bm25_k1: 1.2,
|
|
256
|
+
consolidation_max_entries_per_run: 150,
|
|
257
|
+
consolidation_prompt_path: null,
|
|
258
|
+
hops: 2,
|
|
259
|
+
// User overrides — the migration must carry these across.
|
|
260
|
+
bm25_b: 0.6,
|
|
261
|
+
consolidation_interval_hours: 6,
|
|
262
|
+
consolidation_max_buffer_lines: null,
|
|
263
|
+
max_page_chars: 9000,
|
|
264
|
+
k: 0.4,
|
|
265
|
+
ann_candidate_limit: 500,
|
|
266
|
+
min_sparse_spread: 0.05,
|
|
267
|
+
full_sparse_spread: 0.3,
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
MIG.run(workspaceDir);
|
|
273
|
+
|
|
274
|
+
const parsed = MemoryConfigSchema.parse(memory());
|
|
275
|
+
const withFallback = resolveSubstrateTuning(parsed);
|
|
276
|
+
const substrateOnly = resolveSubstrateOnly(
|
|
277
|
+
memory().substrate as Record<string, unknown>,
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// The load-bearing claim: after the copy, the substrate namespace plus the
|
|
281
|
+
// shipped defaults reproduce the resolver's substrate→v2 fallback exactly.
|
|
282
|
+
expect(substrateOnly).toEqual(withFallback);
|
|
283
|
+
// Anchored against the operator's actual intent, so the equality above
|
|
284
|
+
// cannot pass by both sides being wrong in the same way.
|
|
285
|
+
expect(withFallback.consolidation_interval_hours).toBe(6);
|
|
286
|
+
expect(withFallback.consolidation_max_buffer_lines).toBeNull();
|
|
287
|
+
expect(withFallback.spread_k).toBe(0.4);
|
|
288
|
+
expect(withFallback.spread_hops).toBe(2);
|
|
289
|
+
expect(withFallback.min_sparse_spread).toBe(0.05);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("bm25_b at the historical 0.75 default is the one value the copy rule cannot carry", () => {
|
|
293
|
+
// The skip list treats 0.75 as loader-seeded, so it never reaches
|
|
294
|
+
// memory.substrate and only the fallback keeps it in effect. Recorded here
|
|
295
|
+
// because it is the single case where dropping the fallback would change
|
|
296
|
+
// behavior.
|
|
297
|
+
write({ memory: { v2: { bm25_b: 0.75 } } });
|
|
298
|
+
|
|
299
|
+
MIG.run(workspaceDir);
|
|
300
|
+
|
|
301
|
+
const parsed = MemoryConfigSchema.parse(memory());
|
|
302
|
+
expect(resolveSubstrateTuning(parsed).bm25_b).toBe(0.75);
|
|
303
|
+
expect(resolveSubstrateOnly({}).bm25_b).toBe(0.4);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
test("never clobbers an already-set memory.substrate key, but still copies its unset siblings", () => {
|
|
307
|
+
write({
|
|
308
|
+
memory: {
|
|
309
|
+
v2: { bm25_b: 0.6, max_page_chars: 9000 },
|
|
310
|
+
substrate: { bm25_b: 0.3 },
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
MIG.run(workspaceDir);
|
|
315
|
+
|
|
316
|
+
expect(memory().substrate).toEqual({ bm25_b: 0.3, max_page_chars: 9000 });
|
|
317
|
+
expect(memory().v2).toEqual({ bm25_b: 0.6, max_page_chars: 9000 });
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test("skips loader-seeded values equal to the shipped defaults, including null-default keys", () => {
|
|
321
|
+
// The config loader persists the fully-parsed config for normally-created
|
|
322
|
+
// workspaces, so every defaulted v2 leaf is present in config.json. None
|
|
323
|
+
// of these are user intent — the migration must not pin them into the
|
|
324
|
+
// override-only substrate namespace.
|
|
325
|
+
write({
|
|
326
|
+
memory: {
|
|
327
|
+
v2: {
|
|
328
|
+
enabled: true,
|
|
329
|
+
sweep_enabled: false,
|
|
330
|
+
dense_weight: 0.85,
|
|
331
|
+
sparse_weight: 0.15,
|
|
332
|
+
bm25_k1: 1.2,
|
|
333
|
+
bm25_b: 0.4,
|
|
334
|
+
consolidation_interval_hours: 8,
|
|
335
|
+
consolidation_max_buffer_lines: 100,
|
|
336
|
+
consolidation_max_entries_per_run: 150,
|
|
337
|
+
max_page_chars: 5000,
|
|
338
|
+
consolidation_prompt_path: null,
|
|
339
|
+
k: 0.5,
|
|
340
|
+
hops: 2,
|
|
341
|
+
ann_candidate_limit: null,
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
const before = readRaw();
|
|
346
|
+
|
|
347
|
+
MIG.run(workspaceDir);
|
|
348
|
+
|
|
349
|
+
// Nothing differs from a shipped default → no copy, no write at all.
|
|
350
|
+
expect(readRaw()).toBe(before);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
test("copies non-default values on nullable keys but skips their seeded null defaults", () => {
|
|
354
|
+
write({
|
|
355
|
+
memory: {
|
|
356
|
+
v2: {
|
|
357
|
+
ann_candidate_limit: 500,
|
|
358
|
+
consolidation_prompt_path: null,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
MIG.run(workspaceDir);
|
|
364
|
+
|
|
365
|
+
// 500 differs from the shipped null default and copies; the seeded null
|
|
366
|
+
// equals its default and stays out of the substrate namespace.
|
|
367
|
+
expect(memory().substrate).toEqual({ ann_candidate_limit: 500 });
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
test("skips bm25_b values seeded by the earlier 0.75 default (multi-default key)", () => {
|
|
371
|
+
write({
|
|
372
|
+
memory: {
|
|
373
|
+
v2: { bm25_b: 0.75, bm25_k1: 1.5 },
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
MIG.run(workspaceDir);
|
|
378
|
+
|
|
379
|
+
// 0.75 matches the pre-migration-075 shipped default and is seeded, not a
|
|
380
|
+
// user override; the tuned bm25_k1 still copies.
|
|
381
|
+
expect(memory().substrate).toEqual({ bm25_k1: 1.5 });
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
test("copies the no-default spread keys on presence alone", () => {
|
|
385
|
+
// min_sparse_spread / full_sparse_spread ship with no schema default, so
|
|
386
|
+
// the loader never seeds them — raw presence IS user intent.
|
|
387
|
+
write({
|
|
388
|
+
memory: {
|
|
389
|
+
v2: { min_sparse_spread: 0.05, full_sparse_spread: 0.3 },
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
MIG.run(workspaceDir);
|
|
394
|
+
|
|
395
|
+
expect(memory().substrate).toEqual({
|
|
396
|
+
min_sparse_spread: 0.05,
|
|
397
|
+
full_sparse_spread: 0.3,
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
test("a tuned weight pair copies whole and still parses after migration (resolved-pair weight check)", () => {
|
|
402
|
+
// The v2 refinement validates dense_weight + sparse_weight on the
|
|
403
|
+
// persisted values, so a valid config with a non-default dense_weight
|
|
404
|
+
// necessarily persists its non-default twin — both copy, and the copied
|
|
405
|
+
// substrate pair is exactly the pair v2 already accepted.
|
|
406
|
+
write({ memory: { v2: { dense_weight: 0.9, sparse_weight: 0.1 } } });
|
|
407
|
+
|
|
408
|
+
MIG.run(workspaceDir);
|
|
409
|
+
|
|
410
|
+
expect(memory().substrate).toEqual({
|
|
411
|
+
dense_weight: 0.9,
|
|
412
|
+
sparse_weight: 0.1,
|
|
413
|
+
});
|
|
414
|
+
expect(() => MemoryConfigSchema.parse(memory())).not.toThrow();
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
test("is idempotent — a second run leaves the file byte-for-byte unchanged", () => {
|
|
418
|
+
write({
|
|
419
|
+
memory: {
|
|
420
|
+
v2: { bm25_b: 0.6, k: 0.4, ann_candidate_limit: 500 },
|
|
421
|
+
substrate: { sweep_enabled: true },
|
|
422
|
+
},
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
MIG.run(workspaceDir);
|
|
426
|
+
const afterFirst = readRaw();
|
|
427
|
+
MIG.run(workspaceDir);
|
|
428
|
+
|
|
429
|
+
expect(readRaw()).toBe(afterFirst);
|
|
430
|
+
expect(memory().substrate).toEqual({
|
|
431
|
+
sweep_enabled: true,
|
|
432
|
+
bm25_b: 0.6,
|
|
433
|
+
spread_k: 0.4,
|
|
434
|
+
ann_candidate_limit: 500,
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
test("down() is a forward-only no-op", () => {
|
|
439
|
+
write({ memory: { v2: { bm25_b: 0.6 }, substrate: { bm25_b: 0.6 } } });
|
|
440
|
+
const before = readRaw();
|
|
441
|
+
|
|
442
|
+
expect(() => MIG.down(workspaceDir)).not.toThrow();
|
|
443
|
+
|
|
444
|
+
expect(readRaw()).toBe(before);
|
|
445
|
+
});
|
|
446
|
+
});
|
|
@@ -6,8 +6,8 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
|
6
6
|
import {
|
|
7
7
|
readPage,
|
|
8
8
|
writePage,
|
|
9
|
-
} from "../../../plugins/defaults/memory/
|
|
10
|
-
import type { ConceptPageFrontmatter } from "../../../plugins/defaults/memory/
|
|
9
|
+
} from "../../../plugins/defaults/memory/substrate/page-store.js";
|
|
10
|
+
import type { ConceptPageFrontmatter } from "../../../plugins/defaults/memory/substrate/types.js";
|
|
11
11
|
import { backfillV3LeavesMigration } from "../092-backfill-v3-leaves.js";
|
|
12
12
|
|
|
13
13
|
describe("092 backfill v3 leaves", () => {
|