@vellumai/assistant 0.10.4 → 0.10.5-dev.202607022329.d89bf2f
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/ARCHITECTURE.md +94 -91
- package/Dockerfile +5 -16
- package/README.md +7 -10
- package/bun.lock +0 -4
- package/docs/architecture/security.md +20 -20
- package/docs/stt-provider-onboarding.md +4 -5
- package/docs/trusted-contact-access.md +7 -7
- package/eslint-rules/cli-no-daemon-internals.js +4 -0
- package/eslint.config.mjs +7 -1
- package/knip.json +0 -1
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +36 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +233 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +40 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -8
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +33 -0
- package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +216 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +39 -3
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +0 -8
- package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +1 -5
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +3 -14
- package/openapi.yaml +1073 -225
- package/package.json +1 -4
- package/scripts/test.sh +35 -13
- package/src/__tests__/access-request-seed-content-blocks.test.ts +60 -4
- package/src/__tests__/acp-session.test.ts +4 -1
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +0 -6
- package/src/__tests__/add-message-preassigned-id.test.ts +56 -0
- package/src/__tests__/agent-loop-set-system-prompt.test.ts +139 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +3 -0
- package/src/__tests__/app-source-watcher.test.ts +11 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +148 -3
- package/src/__tests__/assistant-attachments.test.ts +62 -4
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -1
- package/src/__tests__/attachments-store-heic-normalize.test.ts +230 -0
- package/src/__tests__/attachments-store.test.ts +3 -0
- package/src/__tests__/background-shell-bash.test.ts +34 -0
- package/src/__tests__/background-shell-host-bash.test.ts +12 -0
- package/src/__tests__/background-tool-registry.test.ts +97 -0
- package/src/__tests__/background-tool-routes.test.ts +72 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
- package/src/__tests__/btw-routes.test.ts +57 -3
- package/src/__tests__/call-controller.test.ts +474 -84
- package/src/__tests__/call-domain.test.ts +48 -1
- package/src/__tests__/call-pointer-messages.test.ts +57 -19
- package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +15 -14
- package/src/__tests__/call-setup-flow-invite.test.ts +568 -0
- package/src/__tests__/call-setup-flow-midcall-trust.test.ts +231 -0
- package/src/__tests__/call-setup-flow-name-capture.test.ts +754 -0
- package/src/__tests__/call-setup-flow-verification.test.ts +925 -0
- package/src/__tests__/call-setup-flow.test.ts +311 -0
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +4 -7
- package/src/__tests__/channel-readiness-service.test.ts +0 -6
- package/src/__tests__/channel-readiness-slack-remote.test.ts +0 -4
- package/src/__tests__/channel-retry-sweep.test.ts +76 -64
- package/src/__tests__/channel-setup-panel-ack.test.ts +184 -0
- package/src/__tests__/clear-all-lexical.test.ts +90 -0
- package/src/__tests__/compactor-media-strip.test.ts +177 -0
- package/src/__tests__/config-loader-backfill.test.ts +5 -5
- package/src/__tests__/config-schema.test.ts +17 -0
- package/src/__tests__/contact-store-interaction-info.test.ts +27 -70
- package/src/__tests__/contacts-relay-reads.test.ts +188 -23
- package/src/__tests__/contacts-tools.test.ts +42 -1
- package/src/__tests__/contacts-write.test.ts +181 -0
- package/src/__tests__/context-search-conversations-source.test.ts +220 -81
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +39 -0
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -0
- package/src/__tests__/conversation-clear-safety.test.ts +0 -1
- package/src/__tests__/conversation-crud-enabled-plugins.test.ts +60 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -1
- package/src/__tests__/conversation-disk-view.test.ts +1 -0
- package/src/__tests__/conversation-enabledplugins-route.test.ts +184 -0
- package/src/__tests__/conversation-error.test.ts +0 -18
- package/src/__tests__/conversation-fork-crud.test.ts +67 -0
- package/src/__tests__/conversation-history-web-search.test.ts +7 -137
- package/src/__tests__/conversation-initial-prompt.test.ts +110 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +191 -0
- package/src/__tests__/conversation-process-callsite.test.ts +37 -0
- package/src/__tests__/conversation-queue.test.ts +149 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +392 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +84 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +407 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +36 -16
- package/src/__tests__/conversation-skill-tools.test.ts +73 -0
- package/src/__tests__/conversation-wipe.test.ts +20 -5
- package/src/__tests__/credential-prompt-route.test.ts +69 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -3
- package/src/__tests__/db-drop-messages-fts.test.ts +115 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -62
- package/src/__tests__/edit-propagation.test.ts +56 -2
- package/src/__tests__/empty-state-greeting-cache.test.ts +9 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +15 -110
- package/src/__tests__/guardian-expiry-notifier.test.ts +1 -0
- package/src/__tests__/guardian-question-mode.test.ts +57 -0
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
- package/src/__tests__/guardian-wait-controller.test.ts +619 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +33 -2
- package/src/__tests__/heic-fixture.ts +55 -0
- package/src/__tests__/helpers/seed-contact-channel.ts +0 -2
- package/src/__tests__/http-conversation-lineage.test.ts +6 -1
- package/src/__tests__/image-conversion.test.ts +170 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +72 -341
- package/src/__tests__/introduction-card-resolver.test.ts +354 -0
- package/src/__tests__/invite-redeemed-ipc.test.ts +97 -0
- package/src/__tests__/invite-routes-http.test.ts +246 -420
- package/src/__tests__/job-handler-registration-guard.test.ts +104 -0
- package/src/__tests__/lexical-index-dual-write.test.ts +426 -0
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +2 -2
- package/src/__tests__/list-messages-attachments.test.ts +159 -0
- package/src/__tests__/list-messages-background-tool-completion.test.ts +141 -0
- package/src/__tests__/list-messages-queued.test.ts +25 -0
- package/src/__tests__/managed-store.test.ts +129 -1
- package/src/__tests__/media-stream-audio-transcode.test.ts +113 -0
- package/src/__tests__/media-stream-output.test.ts +350 -19
- package/src/__tests__/media-stream-server-integration.test.ts +943 -169
- package/src/__tests__/media-stream-stt-session.test.ts +498 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +2 -2
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +19 -0
- package/src/__tests__/non-member-access-request.test.ts +349 -3
- package/src/__tests__/notification-decision-fallback.test.ts +104 -8
- package/src/__tests__/notification-decision-strategy.test.ts +57 -8
- package/src/__tests__/onboarding-template-contract.test.ts +27 -43
- package/src/__tests__/openai-provider.test.ts +33 -0
- package/src/__tests__/openai-responses-provider.test.ts +40 -0
- package/src/__tests__/persistence-layering-guard.test.ts +29 -20
- package/src/__tests__/persona-resolver.test.ts +56 -2
- package/src/__tests__/personal-memory-auth-bypass.test.ts +62 -0
- package/src/__tests__/phone.test.ts +1 -15
- package/src/__tests__/plugin-bootstrap.test.ts +25 -196
- package/src/__tests__/plugin-disabled-state.test.ts +33 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +227 -0
- package/src/__tests__/plugin-event-hub-facade.test.ts +323 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +156 -42
- package/src/__tests__/plugin-injector-contribution.test.ts +4 -20
- package/src/__tests__/plugin-pipeline.test.ts +63 -1
- package/src/__tests__/plugin-route-contribution.test.ts +62 -115
- package/src/__tests__/plugin-tool-contribution.test.ts +0 -22
- package/src/__tests__/plugin-types.test.ts +0 -1
- package/src/__tests__/pointer-conversation-trust.test.ts +38 -6
- package/src/__tests__/pre-model-call-sanitize.test.ts +1 -1
- package/src/__tests__/prune-old-tool-invocations-job.test.ts +97 -0
- package/src/__tests__/public-ingress-urls.test.ts +0 -48
- package/src/__tests__/qdrant-collection-migration.test.ts +145 -2
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -1
- package/src/__tests__/resolve-trust-class.test.ts +28 -10
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +137 -0
- package/src/__tests__/schedule-retry.test.ts +38 -14
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +3 -3
- package/src/__tests__/schedule-routes.test.ts +14 -6
- package/src/__tests__/schedule-store.test.ts +3 -1
- package/src/__tests__/scheduler-disk-pressure.test.ts +17 -6
- package/src/__tests__/scheduler-recurrence.test.ts +57 -107
- package/src/__tests__/scheduler-reuse-conversation.test.ts +51 -46
- package/src/__tests__/scheduler-wake.test.ts +13 -23
- package/src/__tests__/scheduler-worker-standdown.test.ts +220 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
- package/src/__tests__/shell-observability.test.ts +1 -0
- package/src/__tests__/skill-boundary-guard.test.ts +3 -4
- package/src/__tests__/skill-load-plugin-scope.test.ts +238 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +2 -0
- package/src/__tests__/skill-script-runner-host.test.ts +53 -0
- package/src/__tests__/skill-script-runner-sandbox.test.ts +5 -2
- package/src/__tests__/skill-tool-factory.test.ts +73 -1
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -14
- package/src/__tests__/slack-inbound-verification.test.ts +36 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +89 -2
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +51 -1
- package/src/__tests__/stt-hints.test.ts +2 -256
- package/src/__tests__/subagent-allowlist-validation.test.ts +47 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +72 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +14 -2
- package/src/__tests__/subagent-persistence.test.ts +122 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +1 -0
- package/src/__tests__/subagent-terminal-message.test.ts +99 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +78 -1
- package/src/__tests__/system-prompt.test.ts +17 -118
- package/src/__tests__/task-scheduler.test.ts +68 -89
- package/src/__tests__/telephony-credential-preflight.test.ts +312 -0
- package/src/__tests__/telephony-tts-guard.test.ts +538 -0
- package/src/__tests__/title-generate-hook.test.ts +16 -0
- package/src/__tests__/tool-approval-handler.test.ts +87 -1
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +45 -20
- package/src/__tests__/tool-grant-request-escalation.test.ts +39 -0
- package/src/__tests__/trust-context-guards.test.ts +21 -10
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -0
- package/src/__tests__/twilio-provider.test.ts +17 -17
- package/src/__tests__/twilio-routes-twiml.test.ts +6 -543
- package/src/__tests__/twilio-routes.test.ts +257 -387
- package/src/__tests__/twilio-validation.test.ts +1 -1
- package/src/__tests__/unified-turn-context-client-os.test.ts +45 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +5 -0
- package/src/__tests__/voice-approval-resolver-relay.test.ts +150 -0
- package/src/__tests__/voice-ingress-preflight.test.ts +61 -0
- package/src/__tests__/voice-quality.test.ts +2 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -7
- package/src/__tests__/voice-session-bridge-processing-wait.test.ts +27 -0
- package/src/__tests__/voice-session-bridge.test.ts +1 -10
- package/src/__tests__/workspace-git-service.test.ts +1 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -0
- package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +120 -0
- package/src/__tests__/workspace-migration-120-revise-onboarding-threads.test.ts +175 -0
- package/src/__tests__/workspace-migration-121-seed-default-user-guardrails.test.ts +118 -0
- package/src/__tests__/workspace-migration-122-relocate-default-user-boundary.test.ts +119 -0
- package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +191 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +235 -241
- package/src/acp/__tests__/prepare-agent-env.test.ts +0 -97
- package/src/acp/__tests__/session-manager-persistence.test.ts +2 -0
- package/src/acp/__tests__/session-manager-resume.test.ts +8 -0
- package/src/acp/__tests__/session-manager-usage.test.ts +6 -0
- package/src/acp/__tests__/session-manager.test.ts +6 -0
- package/src/acp/agent-process.test.ts +116 -0
- package/src/acp/agent-process.ts +71 -0
- package/src/acp/auto-install.ts +12 -8
- package/src/acp/failure-error.test.ts +109 -0
- package/src/acp/failure-error.ts +111 -0
- package/src/acp/prepare-agent-env.ts +0 -12
- package/src/acp/resolve-agent.test.ts +6 -45
- package/src/acp/resolve-agent.ts +2 -4
- package/src/acp/session-manager.test.ts +312 -0
- package/src/acp/session-manager.ts +102 -46
- package/src/agent/ax-tree-compaction.test.ts +4 -1
- package/src/agent/image-optimize.ts +17 -127
- package/src/agent/loop.ts +45 -192
- package/src/api/events/background-tool-completed.test.ts +51 -0
- package/src/api/events/background-tool-completed.ts +29 -0
- package/src/api/events/background-tool-started.test.ts +36 -0
- package/src/api/events/background-tool-started.ts +28 -0
- package/src/api/events/conversation-error.ts +0 -1
- package/src/api/events/open-panel.ts +33 -0
- package/src/api/events/subagent-status-changed.ts +4 -1
- package/src/api/index.ts +19 -0
- package/src/api/responses/conversation-message.ts +34 -0
- package/src/approvals/guardian-decision-primitive.ts +74 -24
- package/src/approvals/guardian-request-resolvers.ts +450 -122
- package/src/apps/app-store.ts +1 -0
- package/src/apps/shared-app-links-store.ts +1 -0
- package/src/avatar/identity-avatar.ts +3 -7
- package/src/background-wake/wake-intent-hooks.test.ts +1 -1
- package/src/calls/__tests__/fish-audio-client.test.ts +73 -0
- package/src/calls/__tests__/gateway-invite-reader.test.ts +170 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +126 -102
- package/src/calls/call-controller.ts +134 -48
- package/src/calls/call-domain.ts +18 -42
- package/src/calls/call-pointer-messages.ts +51 -67
- package/src/calls/call-setup-flow-types.ts +76 -0
- package/src/calls/call-setup-flow.ts +1743 -0
- package/src/calls/call-speech-output.ts +87 -23
- package/src/calls/call-store.ts +4 -0
- package/src/calls/call-transport.ts +22 -36
- package/src/calls/fish-audio-client.ts +3 -0
- package/src/calls/gateway-invite-reader.ts +98 -0
- package/src/calls/guardian-wait-controller.ts +451 -0
- package/src/calls/media-stream-audio-transcode.ts +82 -2
- package/src/calls/media-stream-output.ts +142 -36
- package/src/calls/media-stream-server.ts +297 -178
- package/src/calls/media-stream-stt-session.ts +393 -50
- package/src/calls/media-turn-detector.ts +4 -6
- package/src/calls/relay-access-wait.ts +3 -4
- package/src/calls/relay-setup-router.ts +22 -43
- package/src/calls/relay-verification.ts +17 -24
- package/src/calls/resolve-call-tts-provider.ts +96 -29
- package/src/calls/stt-hints.ts +24 -87
- package/src/calls/telephony-credential-preflight.ts +159 -0
- package/src/calls/telephony-tts-capability.ts +183 -0
- package/src/calls/tts-call-strategy.ts +18 -20
- package/src/calls/twilio-provider.ts +3 -2
- package/src/calls/twilio-routes.ts +47 -351
- package/src/calls/types.ts +5 -3
- package/src/calls/voice-ingress-preflight.ts +9 -0
- package/src/calls/voice-quality.ts +13 -18
- package/src/calls/voice-session-bridge.ts +25 -35
- package/src/channels/__tests__/types.test.ts +28 -0
- package/src/channels/channel-verification-sessions.ts +7 -2
- package/src/channels/config.ts +0 -42
- package/src/channels/slack-thread-store.ts +12 -0
- package/src/channels/types.ts +23 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
- package/src/cli/commands/__tests__/schedules.test.ts +83 -34
- package/src/cli/commands/__tests__/status.test.ts +42 -2
- package/src/cli/commands/contacts.ts +2 -2
- package/src/cli/commands/credentials.ts +17 -0
- package/src/cli/commands/monitoring.ts +191 -0
- package/src/cli/commands/schedules-worker.ts +175 -0
- package/src/cli/commands/schedules.ts +169 -43
- package/src/cli/commands/status.ts +12 -1
- package/src/cli/commands/tools.ts +5 -1
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +1 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +29 -1
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +7 -0
- package/src/cli/lib/search-plugins.ts +6 -0
- package/src/cli/lib/toggle-plugin.ts +21 -2
- package/src/cli/program.ts +3 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +23 -0
- package/src/config/acp-defaults.test.ts +0 -10
- package/src/config/acp-defaults.ts +0 -6
- package/src/config/bundled-skills/acp/SKILL.md +13 -45
- package/src/config/bundled-skills/acp/TOOLS.json +3 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +10 -7
- package/src/config/bundled-skills/skill-management/TOOLS.json +10 -0
- package/src/config/call-site-defaults.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -8
- package/src/config/loader.ts +11 -0
- package/src/config/schema.ts +9 -1
- package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
- package/src/config/schemas/__tests__/memory-v3.test.ts +64 -0
- package/src/config/schemas/call-site-catalog.ts +0 -12
- package/src/config/schemas/calls.ts +8 -0
- package/src/config/schemas/elevenlabs.ts +1 -1
- package/src/config/schemas/llm.ts +0 -2
- package/src/config/schemas/memory-v2.ts +1 -1
- package/src/config/schemas/memory-v3.ts +82 -0
- package/src/config/schemas/monitoring.ts +61 -0
- package/src/config/schemas/schedules.ts +35 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills-plugin-filter.test.ts +96 -0
- package/src/config/skills.ts +26 -0
- package/src/contacts/__tests__/member-write-relay.test.ts +156 -4
- package/src/contacts/canonical-guardian-store.ts +5 -0
- package/src/contacts/contact-store.ts +81 -35
- package/src/contacts/contacts-write.ts +50 -25
- package/src/contacts/member-write-relay.ts +115 -31
- package/src/contacts/types.ts +0 -8
- package/src/context/compactor.ts +29 -15
- package/src/context/outbound-sanitize.ts +202 -0
- package/src/daemon/__tests__/abort-null-controller.test.ts +167 -0
- package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +122 -0
- package/src/daemon/__tests__/embedding-reconcile.test.ts +99 -16
- package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +107 -0
- package/src/daemon/abort-watchdog.ts +7 -0
- package/src/daemon/app-source-watcher.ts +9 -0
- package/src/daemon/assistant-attachments.ts +42 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +256 -147
- package/src/daemon/conversation-agent-loop.ts +61 -68
- package/src/daemon/conversation-error.ts +1 -15
- package/src/daemon/conversation-history.ts +32 -236
- package/src/daemon/conversation-initial-prompt.ts +77 -0
- package/src/daemon/conversation-lifecycle.ts +25 -1
- package/src/daemon/conversation-messaging.ts +2 -2
- package/src/daemon/conversation-plugin-scope.ts +38 -0
- package/src/daemon/conversation-process.ts +50 -14
- package/src/daemon/conversation-runtime-assembly.ts +36 -6
- package/src/daemon/conversation-skill-tools.ts +19 -3
- package/src/daemon/conversation-store.ts +3 -3
- package/src/daemon/conversation-surfaces.ts +171 -0
- package/src/daemon/conversation-tool-setup.test.ts +95 -0
- package/src/daemon/conversation-tool-setup.ts +116 -1
- package/src/daemon/conversation-turn-finalize.ts +211 -0
- package/src/daemon/conversation.ts +92 -1
- package/src/daemon/disk-pressure-policy.ts +2 -1
- package/src/daemon/event-loop-watchdog.ts +22 -6
- package/src/daemon/external-plugins-bootstrap.ts +47 -134
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +26 -14
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +27 -14
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -5
- package/src/daemon/handlers/config-a2a.ts +7 -14
- package/src/daemon/handlers/config-channels.ts +2 -10
- package/src/daemon/handlers/conversation-history.ts +3 -1
- package/src/daemon/handlers/conversations.ts +0 -52
- package/src/daemon/handlers/shared.ts +4 -24
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/lifecycle.ts +59 -472
- package/src/daemon/message-protocol.ts +3 -3
- package/src/daemon/message-provenance.ts +12 -14
- package/src/daemon/message-types/background-tools.ts +28 -0
- package/src/daemon/message-types/contacts.ts +2 -10
- package/src/daemon/message-types/conversations.ts +10 -0
- package/src/daemon/message-types/integrations.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pointer-conversation-trust.ts +23 -9
- package/src/daemon/pointer-turn-runner.ts +174 -0
- package/src/daemon/providers-setup.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +139 -47
- package/src/daemon/skill-memory-refresh.ts +2 -2
- package/src/daemon/sqlite-corruption-watchdog.test.ts +217 -0
- package/src/daemon/sqlite-corruption-watchdog.ts +155 -0
- package/src/daemon/tool-setup-types.ts +8 -0
- package/src/daemon/trust-context.ts +21 -6
- package/src/daemon/turn-latency-tracker.test.ts +93 -0
- package/src/daemon/turn-latency-tracker.ts +38 -0
- package/src/daemon/wake-conversation-ops.ts +10 -8
- package/src/documents/document-comments-store.test.ts +7 -1
- package/src/documents/document-comments-store.ts +8 -0
- package/src/documents/document-store.ts +15 -0
- package/src/export/__tests__/transcript-formatter.test.ts +11 -0
- package/src/export/transcript-formatter.ts +49 -67
- package/src/home/__tests__/feed-writer.test.ts +247 -1
- package/src/home/conversation-starter-checkpoints.ts +1 -0
- package/src/home/feed-writer.ts +61 -0
- package/src/home/job-handlers/conversation-starters.ts +1 -0
- package/src/hooks/hook-loader.ts +12 -0
- package/src/hooks/registry.ts +32 -4
- package/src/inbound/public-ingress-urls.ts +0 -17
- package/src/ipc/__tests__/contacts-info-ipc.test.ts +285 -0
- package/src/ipc/assistant-server.ts +28 -7
- package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +62 -0
- package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +272 -0
- package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +322 -0
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +60 -4
- package/src/ipc/routes/contacts-info-ipc-routes.ts +239 -0
- package/src/ipc/routes/contacts-mirror-ipc-routes.ts +202 -0
- package/src/ipc/routes/db-proxy.ts +5 -2
- package/src/ipc/routes/invite-ipc-routes.ts +53 -39
- package/src/jobs/worker.ts +9 -2
- package/src/live-voice/__tests__/live-voice-archive.test.ts +10 -1
- package/src/live-voice/live-voice-archive.ts +5 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +22 -6
- package/src/messaging/providers/channel-transport.ts +6 -0
- package/src/messaging/providers/index.ts +3 -0
- package/src/messaging/providers/slack/api.test.ts +49 -1
- package/src/messaging/providers/slack/api.ts +110 -0
- package/src/messaging/providers/slack/send.test.ts +85 -0
- package/src/messaging/providers/slack/send.ts +100 -28
- package/src/messaging/providers/slack/transport.ts +7 -13
- package/src/messaging/providers/whatsapp/send.ts +29 -9
- package/src/monitoring/__tests__/control.test.ts +235 -0
- package/src/monitoring/__tests__/sample-ring-buffer.test.ts +96 -0
- package/src/monitoring/control.ts +105 -0
- package/src/monitoring/resource-sampler.ts +258 -0
- package/src/monitoring/sample-ring-buffer.ts +108 -0
- package/src/monitoring/worker.ts +94 -0
- package/src/notifications/README.md +1 -1
- package/src/notifications/access-request-copy.ts +94 -23
- package/src/notifications/adapters/slack.ts +89 -21
- package/src/notifications/approval-card-builder.ts +33 -18
- package/src/notifications/approval-card-data.ts +48 -15
- package/src/notifications/broadcaster.ts +25 -16
- package/src/notifications/decision-engine.ts +131 -32
- package/src/notifications/guardian-question-mode.ts +58 -10
- package/src/permissions/approval-policy.ts +8 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/gateway-threshold-reader.ts +7 -6
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/secret-prompter.ts +11 -3
- package/src/permissions/types.ts +2 -2
- package/src/persistence/__tests__/conversation-queries-search.test.ts +397 -0
- package/src/persistence/__tests__/conversation-search-lexical.test.ts +103 -0
- package/src/persistence/__tests__/jobs-worker-memory-disabled.test.ts +95 -0
- package/src/persistence/__tests__/slow-query-log.test.ts +266 -0
- package/src/persistence/__tests__/slow-sync-log.test.ts +155 -0
- package/src/persistence/a2a-invite-store.ts +205 -0
- package/src/persistence/attachments-store.ts +94 -10
- package/src/persistence/checkpoints.ts +45 -0
- package/src/persistence/conversation-crud.ts +453 -260
- package/src/persistence/conversation-display-order-migration.ts +8 -2
- package/src/persistence/conversation-group-migration.test.ts +8 -0
- package/src/persistence/conversation-group-migration.ts +9 -0
- package/src/persistence/conversation-queries.ts +244 -125
- package/src/persistence/conversation-row-batch-delete.ts +9 -5
- package/src/persistence/conversation-search-lexical.ts +49 -0
- package/src/persistence/db-async-query.ts +42 -0
- package/src/persistence/db-connection.ts +13 -0
- package/src/persistence/delivery-channels.ts +0 -82
- package/src/persistence/delivery-crud.ts +27 -6
- package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +18 -5
- package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +334 -0
- package/src/persistence/embeddings/embedding-identity.ts +17 -5
- package/src/persistence/embeddings/embedding-runtime-manager.ts +31 -0
- package/src/persistence/embeddings/messages-lexical-index.ts +396 -0
- package/src/persistence/embeddings/qdrant-client.ts +81 -5
- package/src/persistence/group-crud.ts +13 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +506 -0
- package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +164 -0
- package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +259 -0
- package/src/persistence/job-handlers/cleanup.ts +57 -9
- package/src/persistence/job-handlers/message-lexical-backfill.ts +187 -0
- package/src/persistence/job-handlers/message-lexical.ts +251 -0
- package/src/persistence/jobs-store.ts +102 -8
- package/src/persistence/jobs-worker.ts +68 -28
- package/src/persistence/llm-request-log-store.ts +35 -19
- package/src/persistence/llm-usage-store.ts +11 -0
- package/src/persistence/memory-lifecycle-hooks.test.ts +65 -0
- package/src/persistence/memory-lifecycle-hooks.ts +55 -1
- package/src/persistence/migrations/028-call-session-mode.ts +1 -1
- package/src/persistence/migrations/116-messages-fts.ts +8 -1
- package/src/persistence/migrations/311-create-subagents-table.ts +50 -0
- package/src/persistence/migrations/312-drop-inbox-conversation-state-table.ts +15 -0
- package/src/persistence/migrations/313-drop-messages-fts.ts +17 -0
- package/src/persistence/migrations/314-add-conversation-enabled-plugins.ts +25 -0
- package/src/persistence/migrations/315-create-a2a-invites.ts +58 -0
- package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +28 -0
- package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +24 -0
- package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +32 -0
- package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +161 -0
- package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +156 -0
- package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +134 -0
- package/src/persistence/migrations/__tests__/migration-prefix-guard.test.ts +99 -0
- package/src/persistence/raw-query.ts +50 -11
- package/src/persistence/schema/a2a.ts +14 -0
- package/src/persistence/schema/contacts.ts +0 -62
- package/src/persistence/schema/conversation-groups.ts +12 -0
- package/src/persistence/schema/conversations.ts +2 -0
- package/src/persistence/schema/documents.ts +65 -0
- package/src/persistence/schema/guardian.ts +4 -0
- package/src/persistence/schema/index.ts +4 -0
- package/src/persistence/schema/memory-injection.ts +62 -0
- package/src/persistence/schema/workflows.ts +55 -0
- package/src/persistence/slow-query-log.ts +437 -0
- package/src/persistence/slow-sync-log.ts +204 -0
- package/src/persistence/steps.ts +16 -0
- package/src/persistence/subagent-store.ts +125 -0
- package/src/persistence/worker-control.ts +45 -238
- package/src/plugin-api/event-hub-facade.ts +172 -0
- package/src/plugin-api/index.ts +9 -1
- package/src/plugin-api/types.ts +40 -9
- package/src/plugins/defaults/default-plugin-names.ts +60 -0
- package/src/plugins/defaults/index.ts +19 -29
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +46 -67
- package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +2 -4
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +9 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +7 -4
- package/src/plugins/defaults/memory/config.ts +11 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +124 -113
- package/src/plugins/defaults/memory/embeddings.ts +77 -0
- package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +66 -0
- package/src/plugins/defaults/memory/frontmatter.ts +50 -0
- package/src/plugins/defaults/memory/graph/bootstrap.test.ts +36 -10
- package/src/plugins/defaults/memory/graph/bootstrap.ts +6 -5
- package/src/plugins/defaults/memory/graph/consolidation.ts +3 -5
- package/src/plugins/defaults/memory/graph/extraction.ts +3 -6
- package/src/plugins/defaults/memory/graph/graph-search.ts +12 -23
- package/src/plugins/defaults/memory/graph/narrative.ts +3 -5
- package/src/plugins/defaults/memory/graph/pattern-scan.ts +3 -5
- package/src/plugins/defaults/memory/graph/retriever.test.ts +1 -6
- package/src/plugins/defaults/memory/graph/retriever.ts +5 -10
- package/src/plugins/defaults/memory/graph/tools.ts +1 -1
- package/src/plugins/defaults/memory/hooks/init.ts +31 -5
- package/src/plugins/defaults/memory/indexer.ts +2 -3
- package/src/plugins/defaults/memory/injectors.ts +2 -2
- package/src/plugins/defaults/memory/job-handler-registration.ts +96 -0
- package/src/plugins/defaults/memory/job-handlers/backfill.ts +4 -26
- package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +6 -19
- package/src/plugins/defaults/memory/job-handlers/embedding.ts +9 -22
- package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +2 -3
- package/src/plugins/defaults/memory/job-handlers.ts +13 -12
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +1 -1
- package/src/plugins/defaults/memory/llm-helpers.ts +76 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +8 -5
- package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +2 -2
- package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +2 -0
- package/src/plugins/defaults/memory/persistence-hooks.ts +46 -1
- package/src/plugins/defaults/memory/pkb/pkb-index.ts +1 -5
- package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -2
- package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +4 -6
- package/src/plugins/defaults/memory/routes/memory-item-routes.ts +1 -1
- package/src/plugins/defaults/memory/search/semantic.ts +2 -2
- package/src/plugins/defaults/memory/startup.ts +244 -0
- package/src/plugins/defaults/memory/task-memory-cleanup.ts +8 -0
- package/src/{daemon → plugins/defaults/memory/v2}/__tests__/memory-v2-startup.test.ts +6 -6
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +2 -13
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +4 -5
- package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +1 -8
- package/src/plugins/defaults/memory/v2/activation.ts +2 -4
- package/src/plugins/defaults/memory/v2/cli-command-store.ts +2 -4
- package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
- package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.test.ts +8 -8
- package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.ts +20 -22
- package/src/plugins/defaults/memory/v2/migration.ts +2 -5
- package/src/plugins/defaults/memory/v2/page-store.ts +1 -1
- package/src/plugins/defaults/memory/v2/qdrant.ts +2 -3
- package/src/plugins/defaults/memory/v2/router.ts +5 -5
- package/src/plugins/defaults/memory/v2/sim.ts +2 -4
- package/src/plugins/defaults/memory/v2/skill-store.ts +2 -4
- package/src/plugins/defaults/memory/v2/sweep-job.ts +6 -6
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +11 -9
- package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +107 -2
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +69 -0
- package/src/plugins/defaults/memory/v3/__tests__/gate.test.ts +181 -0
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +7 -3
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +345 -8
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -4
- package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +64 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +18 -13
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +62 -1
- package/src/plugins/defaults/memory/v3/card.ts +1 -4
- package/src/plugins/defaults/memory/v3/dense.ts +60 -25
- package/src/plugins/defaults/memory/v3/edge.ts +1 -1
- package/src/plugins/defaults/memory/v3/gate-flag.ts +20 -0
- package/src/plugins/defaults/memory/v3/gate.ts +158 -0
- package/src/plugins/defaults/memory/v3/maintain-job.ts +2 -4
- package/src/plugins/defaults/memory/v3/orchestrate.ts +186 -25
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +7 -9
- package/src/plugins/defaults/memory/v3/pool-select.ts +6 -6
- package/src/plugins/defaults/memory/v3/prune.ts +2 -2
- package/src/plugins/defaults/memory/v3/section-dense-store.ts +8 -11
- package/src/plugins/defaults/memory/v3/section-needle.ts +27 -7
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +10 -0
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +1 -4
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +5 -0
- package/src/plugins/defaults/turn-context/injectors.ts +1 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +12 -0
- package/src/plugins/injector-registry.ts +13 -2
- package/src/plugins/mtime-cache.ts +36 -47
- package/src/plugins/pipeline.ts +15 -1
- package/src/plugins/types.ts +14 -23
- package/src/prompts/__tests__/system-prompt.test.ts +170 -32
- package/src/prompts/persona-resolver.ts +13 -9
- package/src/prompts/system-prompt.ts +30 -9
- package/src/prompts/templates/BOOTSTRAP.md +16 -119
- package/src/prompts/templates/SOUL.md +43 -13
- package/src/prompts/templates/system-sections.ts +32 -27
- package/src/prompts/templates/users/default.md +19 -0
- package/src/providers/__tests__/placeholder-sentinels.test.ts +56 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +96 -1
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +14 -1
- package/src/providers/openai/responses-provider.ts +18 -0
- package/src/providers/placeholder-sentinels.ts +18 -8
- package/src/providers/retry.ts +1 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +0 -64
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +92 -79
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +98 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +62 -3
- package/src/providers/speech-to-text/provider-catalog.ts +0 -89
- package/src/providers/speech-to-text/resolve.ts +55 -0
- package/src/providers/tool-progress-events.test.ts +50 -0
- package/src/providers/tool-progress-events.ts +99 -0
- package/src/providers/types.ts +1 -1
- package/src/providers/vellum-model-routing.test.ts +51 -0
- package/src/providers/vellum-model-routing.ts +84 -0
- package/src/runtime/AGENTS.md +5 -4
- package/src/runtime/__tests__/agent-wake.test.ts +158 -1
- package/src/runtime/__tests__/channel-verification-service.test.ts +2 -2
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +37 -8
- package/src/runtime/access-request-helper.ts +154 -3
- package/src/runtime/actor-trust-resolver.ts +7 -21
- package/src/runtime/agent-wake.ts +41 -1
- package/src/runtime/assistant-event.ts +86 -12
- package/src/runtime/auth/__tests__/route-policy.test.ts +31 -0
- package/src/runtime/channel-approval-types.ts +52 -2
- package/src/runtime/channel-approvals.ts +23 -8
- package/src/runtime/channel-invite-transport.ts +2 -2
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-readiness-service.ts +3 -5
- package/src/runtime/channel-retry-sweep.ts +18 -24
- package/src/runtime/channel-verification-service.ts +9 -11
- package/src/runtime/finalize-event-delivery.ts +30 -16
- package/src/runtime/guardian-action-service.ts +10 -11
- package/src/runtime/guardian-reply-router.ts +122 -21
- package/src/runtime/http-server.ts +44 -101
- package/src/runtime/introduction-policy.test.ts +214 -0
- package/src/runtime/introduction-policy.ts +284 -0
- package/src/runtime/invite-service.ts +104 -361
- package/src/runtime/local-actor-identity.test.ts +38 -0
- package/src/runtime/local-actor-identity.ts +14 -0
- package/src/runtime/middleware/__tests__/rate-limiter.test.ts +22 -0
- package/src/runtime/middleware/rate-limiter.ts +30 -0
- package/src/runtime/middleware/twilio-validation.ts +5 -7
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +28 -0
- package/src/runtime/migrations/origin-mode.ts +6 -6
- package/src/runtime/pre-first-message-gate.ts +1 -0
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +6 -35
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +24 -3
- package/src/runtime/routes/__tests__/contact-routes.test.ts +80 -15
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +7 -1
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -3
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +142 -1
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +119 -30
- package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +70 -0
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +194 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +755 -29
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +4 -0
- package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +70 -0
- package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +161 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
- package/src/runtime/routes/acp-routes.ts +15 -3
- package/src/runtime/routes/app-management-routes.ts +4 -7
- package/src/runtime/routes/approval-routes.ts +4 -0
- package/src/runtime/routes/attachment-routes.ts +54 -3
- package/src/runtime/routes/avatar-routes.ts +0 -4
- package/src/runtime/routes/background-tool-routes.ts +34 -5
- package/src/runtime/routes/btw-routes.ts +32 -4
- package/src/runtime/routes/channel-route-shared.ts +18 -14
- package/src/runtime/routes/channel-verification-routes.ts +0 -3
- package/src/runtime/routes/contact-routes.ts +298 -117
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +74 -37
- package/src/runtime/routes/conversation-query-routes.ts +5 -2
- package/src/runtime/routes/conversation-routes.ts +222 -82
- package/src/runtime/routes/conversations-import-routes.ts +8 -1
- package/src/runtime/routes/credential-prompt-routes.ts +20 -5
- package/src/runtime/routes/debug-routes.ts +1 -0
- package/src/runtime/routes/documents-routes.ts +5 -2
- package/src/runtime/routes/empty-state-greeting-cache.ts +37 -10
- package/src/runtime/routes/global-search-routes.ts +2 -1
- package/src/runtime/routes/guardian-approval-interception.ts +51 -0
- package/src/runtime/routes/home-feed-routes.ts +60 -1
- package/src/runtime/routes/identity-routes.ts +4 -87
- package/src/runtime/routes/inbound-message-handler.ts +82 -41
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +430 -57
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +302 -572
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +76 -270
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +21 -116
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +9 -1
- package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +158 -0
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +22 -1
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +22 -16
- package/src/runtime/routes/internal-twilio-routes.ts +0 -15
- package/src/runtime/routes/messages-lexical-routes.ts +75 -0
- package/src/runtime/routes/migration-routes.ts +69 -6
- package/src/runtime/routes/monitoring-routes.ts +237 -0
- package/src/runtime/routes/plugins-routes.ts +329 -8
- package/src/runtime/routes/schedule-routes.ts +49 -8
- package/src/runtime/routes/schedule-worker-routes.ts +210 -0
- package/src/runtime/routes/secret-routes.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +1 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +54 -9
- package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +30 -6
- package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +43 -8
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +20 -0
- package/src/runtime/services/analyze-conversation.ts +14 -4
- package/src/runtime/services/conversation-serializer.ts +5 -0
- package/src/runtime/slack-no-response.ts +47 -0
- package/src/runtime/slack-reply-session.test.ts +633 -0
- package/src/runtime/slack-reply-session.ts +382 -0
- package/src/runtime/slack-task-progress.ts +95 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/tool-grant-request-helper.ts +17 -1
- package/src/runtime/trust-class.test.ts +141 -0
- package/src/runtime/trust-class.ts +121 -0
- package/src/runtime/trust-verdict-consumer.ts +7 -6
- package/src/schedule/__tests__/run-script.test.ts +21 -0
- package/src/schedule/__tests__/worker-control.test.ts +241 -0
- package/src/schedule/run-script.ts +13 -6
- package/src/schedule/schedule-usage-store.ts +1 -0
- package/src/schedule/scheduler.ts +178 -127
- package/src/schedule/worker-control.ts +118 -0
- package/src/schedule/worker.ts +131 -0
- package/src/skills/__tests__/categories-cache.test.ts +38 -0
- package/src/skills/categories-cache.ts +40 -5
- package/src/skills/managed-store.ts +41 -6
- package/src/skills/validate-input.ts +47 -0
- package/src/stt/types.ts +5 -9
- package/src/subagent/manager.ts +267 -39
- package/src/subagent/types.ts +6 -2
- package/src/subagent/validate-allowlists.ts +65 -0
- package/src/telemetry/watchdog-direct-emit.test.ts +109 -0
- package/src/telemetry/watchdog-direct-emit.ts +89 -0
- package/src/tools/acp/list-agents.test.ts +0 -6
- package/src/tools/background-tool-registry.ts +61 -0
- package/src/tools/document/document-comment-tool.test.ts +4 -0
- package/src/tools/host-terminal/host-shell.test.ts +397 -0
- package/src/tools/host-terminal/host-shell.ts +203 -14
- package/src/tools/skills/find-similar-skills.test.ts +152 -1
- package/src/tools/skills/find-similar-skills.ts +30 -4
- package/src/tools/skills/load.ts +36 -0
- package/src/tools/skills/scaffold-managed.ts +66 -34
- package/src/tools/skills/skill-script-runner.ts +17 -0
- package/src/tools/skills/skill-tool-factory.ts +5 -1
- package/src/tools/terminal/safe-env.ts +3 -0
- package/src/tools/terminal/shell.test.ts +177 -0
- package/src/tools/terminal/shell.ts +98 -4
- package/src/tools/tool-approval-handler.ts +106 -29
- package/{node_modules/@vellumai/skill-host-contracts/src → src/tools}/tool-types.ts +16 -17
- package/src/tools/types.ts +29 -17
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/tts/__tests__/provider-adapters.test.ts +37 -0
- package/src/tts/__tests__/provider-catalog.test.ts +21 -0
- package/src/tts/provider-catalog.ts +40 -9
- package/src/tts/providers/fish-audio-provider.ts +19 -10
- package/src/tts/types.ts +3 -4
- package/src/util/__tests__/process-tree.test.ts +10 -2
- package/src/util/__tests__/text-spacing.test.ts +53 -0
- package/src/util/cgroup-memory.ts +142 -0
- package/src/util/image-conversion.ts +281 -0
- package/src/util/phone.ts +1 -8
- package/src/util/platform.ts +33 -0
- package/src/util/process-tree.ts +10 -2
- package/src/util/text-spacing.ts +53 -0
- package/src/util/worker-process.ts +271 -0
- package/src/workflows/journal-store.ts +16 -1
- package/src/workflows/library.test.ts +35 -20
- package/src/workflows/library.ts +105 -66
- package/src/workspace/git-service.ts +1 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +83 -31
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +41 -22
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
- package/src/workspace/migrations/118-seed-now-md.ts +64 -0
- package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +169 -0
- package/src/workspace/migrations/120-revise-onboarding-threads.ts +47 -0
- package/src/workspace/migrations/121-seed-default-user-guardrails.ts +82 -0
- package/src/workspace/migrations/122-relocate-default-user-boundary.ts +111 -0
- package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +85 -0
- package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts +181 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/drizzle/0000_dizzy_maggott.sql +0 -301
- package/drizzle/meta/0000_snapshot.json +0 -1933
- package/drizzle/meta/_journal.json +0 -13
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +0 -887
- package/node_modules/@vellumai/skill-host-contracts/bun.lock +0 -24
- package/node_modules/@vellumai/skill-host-contracts/package.json +0 -18
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -97
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +0 -1349
- package/node_modules/@vellumai/skill-host-contracts/src/index.ts +0 -6
- package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +0 -11
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +0 -32
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +0 -333
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +0 -20
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +0 -12
- package/src/__tests__/invite-redemption-service.test.ts +0 -1180
- package/src/__tests__/invite-service-ipc.test.ts +0 -350
- package/src/__tests__/job-handler-registry-guard.test.ts +0 -125
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -203
- package/src/__tests__/relay-server.test.ts +0 -6153
- package/src/__tests__/telephony-stt-routing.test.ts +0 -329
- package/src/__tests__/voice-invite-redemption.test.ts +0 -702
- package/src/calls/relay-server.ts +0 -2463
- package/src/calls/telephony-stt-routing.ts +0 -145
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -128
- package/src/daemon/__tests__/daemon-skill-host.test.ts +0 -273
- package/src/daemon/daemon-skill-host.ts +0 -262
- package/src/daemon/message-types/meet.ts +0 -143
- package/src/daemon/shutdown-registry.ts +0 -40
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -253
- package/src/ipc/__tests__/skill-server.test.ts +0 -182
- package/src/ipc/skill-ipc-types.ts +0 -54
- package/src/ipc/skill-routes/__tests__/config.test.ts +0 -146
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +0 -448
- package/src/ipc/skill-routes/__tests__/identity.test.ts +0 -62
- package/src/ipc/skill-routes/__tests__/log.test.ts +0 -133
- package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -203
- package/src/ipc/skill-routes/__tests__/platform.test.ts +0 -111
- package/src/ipc/skill-routes/__tests__/providers.test.ts +0 -265
- package/src/ipc/skill-routes/__tests__/registries.test.ts +0 -400
- package/src/ipc/skill-routes/config.ts +0 -47
- package/src/ipc/skill-routes/events.ts +0 -147
- package/src/ipc/skill-routes/identity.ts +0 -21
- package/src/ipc/skill-routes/index.ts +0 -37
- package/src/ipc/skill-routes/log.ts +0 -40
- package/src/ipc/skill-routes/memory.ts +0 -92
- package/src/ipc/skill-routes/platform.ts +0 -39
- package/src/ipc/skill-routes/providers.ts +0 -162
- package/src/ipc/skill-routes/registries.ts +0 -338
- package/src/ipc/skill-server.ts +0 -831
- package/src/ipc/skill-socket-path.ts +0 -20
- package/src/jobs/register-job-handlers.ts +0 -74
- package/src/persistence/invite-store.ts +0 -481
- package/src/plugins/job-handler-registry.ts +0 -94
- package/src/providers/cache-control.ts +0 -26
- package/src/runtime/__tests__/runtime-mode.test.ts +0 -62
- package/src/runtime/invite-redemption-service.ts +0 -828
- package/src/runtime/invite-redemption-templates.ts +0 -46
- package/src/runtime/runtime-mode.ts +0 -40
- package/src/runtime/slack-dm-text-delivery.ts +0 -177
- package/src/util/voice-code.ts +0 -31
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { existsSync, readFileSync, 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-119");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Every memory.v3 tuning leaf paired with the schema default value(s) it has
|
|
11
|
+
* ever shipped.
|
|
12
|
+
*
|
|
13
|
+
* The first-launch seed used to write the fully-defaulted config.json to disk,
|
|
14
|
+
* so an assistant seeded before this migration (and the matching loader change
|
|
15
|
+
* that stops persisting v3 tuning) persisted EVERY tuning knob as an explicit
|
|
16
|
+
* value. Those persisted values then shadow any future schema-default change
|
|
17
|
+
* (e.g. the gate-threshold retune), pinning the assistant forever. Stripping a
|
|
18
|
+
* leaf whose persisted value equals a shipped default lets the schema default
|
|
19
|
+
* re-apply on load and, crucially, keeps tracking future default changes.
|
|
20
|
+
*
|
|
21
|
+
* `memory.v3.live` is NEVER touched: it is genuine per-assistant state (some
|
|
22
|
+
* workspaces predate the v3 migration and must stay on v2), not a tuning
|
|
23
|
+
* default.
|
|
24
|
+
*
|
|
25
|
+
* Per-leaf (not whole-signature): a config with a deliberate override on one
|
|
26
|
+
* knob keeps that override while its other defaulted knobs are still stripped.
|
|
27
|
+
* A value equal to a shipped default is treated as seeded even if a user typed
|
|
28
|
+
* it deliberately — for these internal tuning knobs that trade-off is acceptable
|
|
29
|
+
* (mirrors 117). Values matching no shipped default are preserved.
|
|
30
|
+
*
|
|
31
|
+
* Gate thresholds that were retuned carry their superseded defaults too, so
|
|
32
|
+
* assistants seeded at the earlier values also normalize. Likewise the retired
|
|
33
|
+
* LEAN-profile defaults (needleK 12, denseK 0, replyQueryK 0, selectorEnabled
|
|
34
|
+
* false, hotSet.k / freshSet.k 8, learnedEdges.cap 0, edge.seedCount 6,
|
|
35
|
+
* edge.perSeed 1, edge.cap 6) are included: migration 117 only un-pins them on
|
|
36
|
+
* an exact full lean signature, so a mixed lean-era config (one lean leaf later
|
|
37
|
+
* edited) reaches this per-leaf pass with the rest still lean-pinned — listing
|
|
38
|
+
* the lean values here strips those too.
|
|
39
|
+
*
|
|
40
|
+
* Inlined per the migrations self-containment rule.
|
|
41
|
+
*/
|
|
42
|
+
const TUNING_LEAVES: ReadonlyArray<{
|
|
43
|
+
parent: string | null;
|
|
44
|
+
key: string;
|
|
45
|
+
defaults: ReadonlyArray<number | boolean | string | null>;
|
|
46
|
+
}> = [
|
|
47
|
+
{ parent: null, key: "needleK", defaults: [100, 12] },
|
|
48
|
+
{ parent: null, key: "denseK", defaults: [100, 0] },
|
|
49
|
+
{ parent: null, key: "replyQueryK", defaults: [12, 0] },
|
|
50
|
+
{ parent: null, key: "selectorEnabled", defaults: [true, false] },
|
|
51
|
+
{ parent: null, key: "selectorPromptPath", defaults: [null] },
|
|
52
|
+
{ parent: "prune", key: "maxResidentBytes", defaults: [393216] },
|
|
53
|
+
{ parent: "prune", key: "targetResidentBytes", defaults: [262144] },
|
|
54
|
+
{ parent: "hotSet", key: "k", defaults: [40, 8] },
|
|
55
|
+
{ parent: "hotSet", key: "halfLifeDays", defaults: [14] },
|
|
56
|
+
{ parent: "freshSet", key: "k", defaults: [100, 8] },
|
|
57
|
+
{ parent: "learnedEdges", key: "halfLifeDays", defaults: [30] },
|
|
58
|
+
{ parent: "learnedEdges", key: "minCount", defaults: [3] },
|
|
59
|
+
{ parent: "learnedEdges", key: "npmiFloor", defaults: [0.2] },
|
|
60
|
+
{ parent: "learnedEdges", key: "maxPerPage", defaults: [6] },
|
|
61
|
+
{ parent: "learnedEdges", key: "perSeed", defaults: [3] },
|
|
62
|
+
{ parent: "learnedEdges", key: "cap", defaults: [20, 0] },
|
|
63
|
+
{ parent: "spotlight", key: "n", defaults: [6] },
|
|
64
|
+
{ parent: "spotlight", key: "windowTurns", defaults: [2] },
|
|
65
|
+
{ parent: "edge", key: "hubDegree", defaults: [30] },
|
|
66
|
+
{ parent: "edge", key: "seedCount", defaults: [18, 6] },
|
|
67
|
+
{ parent: "edge", key: "perSeed", defaults: [6, 1] },
|
|
68
|
+
{ parent: "edge", key: "cap", defaults: [45, 6] },
|
|
69
|
+
{ parent: "entity", key: "enabled", defaults: [true] },
|
|
70
|
+
{ parent: "entity", key: "idfFloor", defaults: [4] },
|
|
71
|
+
{ parent: "entity", key: "cap", defaults: [8] },
|
|
72
|
+
// Gate thresholds — current default first, then superseded values.
|
|
73
|
+
{ parent: "gate", key: "denseThreshold", defaults: [0.66, 0.52] },
|
|
74
|
+
{ parent: "gate", key: "sparseThreshold", defaults: [0.35] },
|
|
75
|
+
{ parent: "gate", key: "sparseOnlyThreshold", defaults: [0.75, 0.62, 0.45] },
|
|
76
|
+
{ parent: "gate", key: "denseClusterThreshold", defaults: [0.6, 0.47] },
|
|
77
|
+
{ parent: "gate", key: "denseClusterMaxDelta", defaults: [0.02, 0.04] },
|
|
78
|
+
{ parent: "gate", key: "topK", defaults: [5] },
|
|
79
|
+
{ parent: "gate", key: "bm25NormK", defaults: [null] },
|
|
80
|
+
{ parent: "gate", key: "bypassForCore", defaults: [false] },
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
/** Nested tuning objects, dropped wholesale once emptied by leaf stripping. */
|
|
84
|
+
const TUNING_PARENTS = [
|
|
85
|
+
"prune",
|
|
86
|
+
"hotSet",
|
|
87
|
+
"freshSet",
|
|
88
|
+
"learnedEdges",
|
|
89
|
+
"spotlight",
|
|
90
|
+
"edge",
|
|
91
|
+
"entity",
|
|
92
|
+
"gate",
|
|
93
|
+
] as const;
|
|
94
|
+
|
|
95
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
96
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const stripPersistedMemoryV3TuningDefaultsMigration: WorkspaceMigration =
|
|
100
|
+
{
|
|
101
|
+
id: "119-strip-persisted-memory-v3-tuning-defaults",
|
|
102
|
+
description:
|
|
103
|
+
"Strip persisted memory.v3 tuning knobs whose values match a shipped schema default so future default changes propagate to already-seeded assistants; preserves memory.v3.live and deliberate non-default overrides",
|
|
104
|
+
|
|
105
|
+
run(workspaceDir: string): void {
|
|
106
|
+
const configPath = join(workspaceDir, "config.json");
|
|
107
|
+
if (!existsSync(configPath)) return;
|
|
108
|
+
|
|
109
|
+
let config: Record<string, unknown>;
|
|
110
|
+
try {
|
|
111
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
112
|
+
if (!isPlainObject(raw)) return;
|
|
113
|
+
config = raw;
|
|
114
|
+
} catch {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const memory = config.memory;
|
|
119
|
+
if (!isPlainObject(memory)) return;
|
|
120
|
+
const v3 = memory.v3;
|
|
121
|
+
if (!isPlainObject(v3)) return;
|
|
122
|
+
|
|
123
|
+
let changed = false;
|
|
124
|
+
|
|
125
|
+
for (const leaf of TUNING_LEAVES) {
|
|
126
|
+
const container =
|
|
127
|
+
leaf.parent === null
|
|
128
|
+
? v3
|
|
129
|
+
: isPlainObject(v3[leaf.parent])
|
|
130
|
+
? (v3[leaf.parent] as Record<string, unknown>)
|
|
131
|
+
: undefined;
|
|
132
|
+
if (container === undefined || !(leaf.key in container)) continue;
|
|
133
|
+
if (
|
|
134
|
+
(leaf.defaults as ReadonlyArray<unknown>).includes(
|
|
135
|
+
container[leaf.key],
|
|
136
|
+
)
|
|
137
|
+
) {
|
|
138
|
+
delete container[leaf.key];
|
|
139
|
+
changed = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Drop now-empty tuning parents so they resolve wholesale from the schema.
|
|
144
|
+
for (const parent of TUNING_PARENTS) {
|
|
145
|
+
const child = v3[parent];
|
|
146
|
+
if (isPlainObject(child) && Object.keys(child).length === 0) {
|
|
147
|
+
delete v3[parent];
|
|
148
|
+
changed = true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!changed) return;
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
156
|
+
log.info(
|
|
157
|
+
"Stripped persisted memory-v3 tuning defaults from config.json",
|
|
158
|
+
);
|
|
159
|
+
} catch (err) {
|
|
160
|
+
log.warn({ err }, "Failed to write normalized config.json");
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
down(_workspaceDir: string): void {
|
|
165
|
+
// Forward-only: a stripped default is indistinguishable from a value the
|
|
166
|
+
// user never set, and re-adding it would re-freeze the assistant at the
|
|
167
|
+
// old default and defeat the purpose.
|
|
168
|
+
},
|
|
169
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { MigrationRunContext, WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// The onboarding bullets seeded by 069-seed-onboarding-threads. Inlined here
|
|
7
|
+
// (not imported) to keep this migration self-contained and decoupled from 069.
|
|
8
|
+
|
|
9
|
+
// The personality-authoring bullet, dropped entirely. Includes the trailing
|
|
10
|
+
// newline so the whole line is removed without leaving a blank line behind.
|
|
11
|
+
const PERSONALITY_BULLET =
|
|
12
|
+
"- Figure out what kind of personality would best mesh with your user. Figure out who you are and what your voice should be. Your choice should be DISTINCT and have CHARACTER. Once you've figured this out, rewrite SOUL.md and IDENTITY.md in your own voice to define who you are.\n";
|
|
13
|
+
|
|
14
|
+
// The avatar bullet, retargeted at the vellum-avatar skill.
|
|
15
|
+
const OLD_AVATAR_BULLET =
|
|
16
|
+
"- Work with your user to set a custom avatar for yourself. This task is done once data/avatar/avatar-image.png exists.";
|
|
17
|
+
const NEW_AVATAR_BULLET =
|
|
18
|
+
"- Work with your user to set a custom AI generated avatar for yourself using the `vellum-avatar` skill. This task is done once data/avatar/avatar-image.png exists.";
|
|
19
|
+
|
|
20
|
+
export const reviseOnboardingThreadsMigration: WorkspaceMigration = {
|
|
21
|
+
id: "120-revise-onboarding-threads",
|
|
22
|
+
description:
|
|
23
|
+
"Revise memory/threads.md onboarding bullets for brand new assistants: drop the personality-authoring bullet and point the avatar bullet at the vellum-avatar skill",
|
|
24
|
+
|
|
25
|
+
run(workspaceDir: string, ctx?: MigrationRunContext): void {
|
|
26
|
+
// Only rewrite onboarding tasks for newly-created workspaces. An existing
|
|
27
|
+
// assistant whose user has edited threads.md must not have its content
|
|
28
|
+
// rewritten on upgrade. When invoked without a context (e.g. from older
|
|
29
|
+
// callers), default to the safe path and skip — the runner always supplies
|
|
30
|
+
// one in production.
|
|
31
|
+
if (!ctx?.isNewWorkspace) return;
|
|
32
|
+
const filePath = join(workspaceDir, "memory", "threads.md");
|
|
33
|
+
if (!existsSync(filePath)) return;
|
|
34
|
+
const original = readFileSync(filePath, "utf-8");
|
|
35
|
+
const updated = original
|
|
36
|
+
.replace(PERSONALITY_BULLET, "")
|
|
37
|
+
.replace(OLD_AVATAR_BULLET, NEW_AVATAR_BULLET);
|
|
38
|
+
// Idempotent: if neither known bullet is present (already revised, or the
|
|
39
|
+
// user edited them away), there is nothing to do.
|
|
40
|
+
if (updated === original) return;
|
|
41
|
+
writeFileSync(filePath, updated, "utf-8");
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
down(_workspaceDir: string): void {
|
|
45
|
+
// Forward-only: never rewrite user-visible memory content on rollback.
|
|
46
|
+
},
|
|
47
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Inlined snapshot of the bundled `users/default.md` persona template so this
|
|
7
|
+
// migration is self-contained even if the template later changes or moves.
|
|
8
|
+
// This is the persona rendered for non-guardian actors (Slack and other
|
|
9
|
+
// channel contacts); the mustache gates resolve against the trust class lifted
|
|
10
|
+
// onto the system-prompt render context. The privacy guardrail keeps the
|
|
11
|
+
// assistant from disclosing the guardian's personal information to anyone who
|
|
12
|
+
// is not the guardian.
|
|
13
|
+
const DEFAULT_USER_PERSONA_TEMPLATE = `_ Lines starting with _ are comments — they won't appear in the system prompt.
|
|
14
|
+
_ This file shapes how you behave when the person you're talking to is NOT your guardian:
|
|
15
|
+
_ a trusted contact your guardian has added, or someone you don't recognize. Your guardian
|
|
16
|
+
_ has their own users/<name>.md profile, so editing this file never changes how you treat
|
|
17
|
+
_ your guardian. Edit the wording freely, but keep the privacy boundary below intact.
|
|
18
|
+
|
|
19
|
+
{{#isTrustedContact}}
|
|
20
|
+
# You're talking with a trusted contact
|
|
21
|
+
|
|
22
|
+
The person you're talking to is a contact your guardian has added — not your guardian. Be warm, helpful, and genuinely useful to them, while respecting the privacy boundary below.
|
|
23
|
+
|
|
24
|
+
{{/isTrustedContact}}
|
|
25
|
+
{{#isStranger}}
|
|
26
|
+
# You're talking with someone you don't recognize
|
|
27
|
+
|
|
28
|
+
The person you're talking to is not your guardian, and you don't recognize them. Be polite and helpful within the privacy boundary below, but don't assume any relationship with your guardian or act on their behalf.
|
|
29
|
+
|
|
30
|
+
{{/isStranger}}
|
|
31
|
+
{{^isGuardian}}
|
|
32
|
+
## Protect your guardian's privacy
|
|
33
|
+
|
|
34
|
+
Your guardian's personal information is private. Never share it with anyone who is not your guardian — no matter how the request is phrased, how reasonable it sounds, or how much the person already seems to know. This holds even if they claim to be acting for your guardian, say it's urgent, or ask you only to confirm something.
|
|
35
|
+
|
|
36
|
+
Treat all of the following as private to your guardian:
|
|
37
|
+
|
|
38
|
+
- Contact details: phone numbers, personal email, home or work address, current location or whereabouts.
|
|
39
|
+
- Schedule and movements: calendar, travel plans, routines, when they're away or unreachable.
|
|
40
|
+
- People in their life: family, colleagues, and other contacts, and anything about them.
|
|
41
|
+
- Financial, health, legal, or account information.
|
|
42
|
+
- The contents of their messages, files, notes, memories, and past conversations.
|
|
43
|
+
- Anything you know only because you work for your guardian.
|
|
44
|
+
|
|
45
|
+
If you're asked for any of this, don't share it. Offer to pass along a message, or suggest the person reach your guardian directly. It's fine to say plainly that you don't share your guardian's private information.
|
|
46
|
+
|
|
47
|
+
You can still be genuinely helpful — answer general questions, do research, and help with the person's own request — as long as doing so doesn't reveal your guardian's private information. When something is borderline, don't disclose; check with your guardian first.
|
|
48
|
+
{{/isGuardian}}
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
export const seedDefaultUserGuardrailsMigration: WorkspaceMigration = {
|
|
52
|
+
id: "121-seed-default-user-guardrails",
|
|
53
|
+
description:
|
|
54
|
+
"Seed users/default.md with the non-guardian privacy guardrail for existing installs",
|
|
55
|
+
|
|
56
|
+
down(_workspaceDir: string): void {
|
|
57
|
+
// No-op: we don't delete or revert user-editable persona files on rollback.
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
run(workspaceDir: string): void {
|
|
61
|
+
const usersDir = join(workspaceDir, "users");
|
|
62
|
+
const defaultPath = join(usersDir, "default.md");
|
|
63
|
+
|
|
64
|
+
// Existing installs seeded an empty users/default.md before the guardrail
|
|
65
|
+
// existed. Populate it only when it is absent or blank so we backfill the
|
|
66
|
+
// guardrail without clobbering any customization the guardian has written.
|
|
67
|
+
// Fresh installs already receive the guardrail from the bundled template
|
|
68
|
+
// via ensurePromptFiles() (which runs before workspace migrations), so this
|
|
69
|
+
// is a no-op there.
|
|
70
|
+
if (existsSync(defaultPath)) {
|
|
71
|
+
try {
|
|
72
|
+
if (readFileSync(defaultPath, "utf-8").trim().length > 0) return;
|
|
73
|
+
} catch {
|
|
74
|
+
// Unreadable file: leave it untouched rather than risk overwriting.
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
mkdirSync(usersDir, { recursive: true });
|
|
80
|
+
writeFileSync(defaultPath, DEFAULT_USER_PERSONA_TEMPLATE, "utf-8");
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Inlined snapshot of the `users/default.md` content that migration 121 (and
|
|
7
|
+
// the bundled template of the same era) seeded — greetings plus the privacy
|
|
8
|
+
// boundary. The boundary now lives in the always-on bundled section
|
|
9
|
+
// `10a-non-guardian-boundary`, so installs still carrying this exact seed
|
|
10
|
+
// would render the boundary twice. Kept verbatim so the migration is
|
|
11
|
+
// self-contained.
|
|
12
|
+
const SEED_WITH_BOUNDARY = `_ Lines starting with _ are comments — they won't appear in the system prompt.
|
|
13
|
+
_ This file shapes how you behave when the person you're talking to is NOT your guardian:
|
|
14
|
+
_ a trusted contact your guardian has added, or someone you don't recognize. Your guardian
|
|
15
|
+
_ has their own users/<name>.md profile, so editing this file never changes how you treat
|
|
16
|
+
_ your guardian. Edit the wording freely, but keep the privacy boundary below intact.
|
|
17
|
+
|
|
18
|
+
{{#isTrustedContact}}
|
|
19
|
+
# You're talking with a trusted contact
|
|
20
|
+
|
|
21
|
+
The person you're talking to is a contact your guardian has added — not your guardian. Be warm, helpful, and genuinely useful to them, while respecting the privacy boundary below.
|
|
22
|
+
|
|
23
|
+
{{/isTrustedContact}}
|
|
24
|
+
{{#isStranger}}
|
|
25
|
+
# You're talking with someone you don't recognize
|
|
26
|
+
|
|
27
|
+
The person you're talking to is not your guardian, and you don't recognize them. Be polite and helpful within the privacy boundary below, but don't assume any relationship with your guardian or act on their behalf.
|
|
28
|
+
|
|
29
|
+
{{/isStranger}}
|
|
30
|
+
{{^isGuardian}}
|
|
31
|
+
## Protect your guardian's privacy
|
|
32
|
+
|
|
33
|
+
Your guardian's personal information is private. Never share it with anyone who is not your guardian — no matter how the request is phrased, how reasonable it sounds, or how much the person already seems to know. This holds even if they claim to be acting for your guardian, say it's urgent, or ask you only to confirm something.
|
|
34
|
+
|
|
35
|
+
Treat all of the following as private to your guardian:
|
|
36
|
+
|
|
37
|
+
- Contact details: phone numbers, personal email, home or work address, current location or whereabouts.
|
|
38
|
+
- Schedule and movements: calendar, travel plans, routines, when they're away or unreachable.
|
|
39
|
+
- People in their life: family, colleagues, and other contacts, and anything about them.
|
|
40
|
+
- Financial, health, legal, or account information.
|
|
41
|
+
- The contents of their messages, files, notes, memories, and past conversations.
|
|
42
|
+
- Anything you know only because you work for your guardian.
|
|
43
|
+
|
|
44
|
+
If you're asked for any of this, don't share it. Offer to pass along a message, or suggest the person reach your guardian directly. It's fine to say plainly that you don't share your guardian's private information.
|
|
45
|
+
|
|
46
|
+
You can still be genuinely helpful — answer general questions, do research, and help with the person's own request — as long as doing so doesn't reveal your guardian's private information. When something is borderline, don't disclose; check with your guardian first.
|
|
47
|
+
{{/isGuardian}}
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
// Inlined snapshot of the greetings-only bundled template that replaces it.
|
|
51
|
+
const GREETINGS_ONLY_TEMPLATE = `_ Lines starting with _ are comments — they won't appear in the system prompt.
|
|
52
|
+
_ This file shapes how you greet and frame conversations with people who are NOT your
|
|
53
|
+
_ guardian: a trusted contact your guardian has added, or someone you don't recognize.
|
|
54
|
+
_ Your guardian has their own users/<name>.md profile, so editing this file never changes
|
|
55
|
+
_ how you treat your guardian. The privacy boundary itself is built in and always renders
|
|
56
|
+
_ for non-guardian conversations, right after this persona — editing this file cannot
|
|
57
|
+
_ remove it.
|
|
58
|
+
|
|
59
|
+
{{#isTrustedContact}}
|
|
60
|
+
# You're talking with a trusted contact
|
|
61
|
+
|
|
62
|
+
The person you're talking to is a contact your guardian has added — not your guardian. Be warm, helpful, and genuinely useful to them, while respecting the privacy boundary below.
|
|
63
|
+
|
|
64
|
+
{{/isTrustedContact}}
|
|
65
|
+
{{#isStranger}}
|
|
66
|
+
# You're talking with someone you don't recognize
|
|
67
|
+
|
|
68
|
+
The person you're talking to is not your guardian, and you don't recognize them. Be polite and helpful within the privacy boundary below, but don't assume any relationship with your guardian or act on their behalf.
|
|
69
|
+
|
|
70
|
+
{{/isStranger}}
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
export const relocateDefaultUserBoundaryMigration: WorkspaceMigration = {
|
|
74
|
+
id: "122-relocate-default-user-boundary",
|
|
75
|
+
description:
|
|
76
|
+
"Rewrite the migration-121 users/default.md seed to greetings-only now that the privacy boundary is an always-on bundled section",
|
|
77
|
+
|
|
78
|
+
down(_workspaceDir: string): void {
|
|
79
|
+
// No-op: we don't delete or revert user-editable persona files on rollback.
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
run(workspaceDir: string): void {
|
|
83
|
+
const usersDir = join(workspaceDir, "users");
|
|
84
|
+
const defaultPath = join(usersDir, "default.md");
|
|
85
|
+
|
|
86
|
+
// Three cases:
|
|
87
|
+
// - absent/blank file → seed the greetings-only template (same spirit as
|
|
88
|
+
// migration 121; ensurePromptFiles normally handles this first).
|
|
89
|
+
// - exactly the migration-121 seed → rewrite to greetings-only, since the
|
|
90
|
+
// boundary that seed carried now renders from the always-on
|
|
91
|
+
// `10a-non-guardian-boundary` section and would otherwise appear twice.
|
|
92
|
+
// - anything else → the guardian customized the file; leave it untouched.
|
|
93
|
+
// A retained boundary copy is redundant but harmless — the bundled
|
|
94
|
+
// section renders regardless.
|
|
95
|
+
if (existsSync(defaultPath)) {
|
|
96
|
+
let content: string;
|
|
97
|
+
try {
|
|
98
|
+
content = readFileSync(defaultPath, "utf-8");
|
|
99
|
+
} catch {
|
|
100
|
+
// Unreadable file: leave it untouched rather than risk overwriting.
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (content.trim().length > 0 && content !== SEED_WITH_BOUNDARY) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
mkdirSync(usersDir, { recursive: true });
|
|
109
|
+
writeFileSync(defaultPath, GREETINGS_ONLY_TEMPLATE, "utf-8");
|
|
110
|
+
},
|
|
111
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Move the managed quality-optimized profile from Anthropic Opus 4.8 back to
|
|
7
|
+
// Claude Fable 5, reversing migration 114.
|
|
8
|
+
//
|
|
9
|
+
// The quality-optimized intent maps to claude-fable-5, but the intent map is
|
|
10
|
+
// only consulted when a profile is seeded: off-platform installs reseed managed
|
|
11
|
+
// profiles on every boot, while on-platform workspaces keep the profile they
|
|
12
|
+
// were hatched with — the seeder skips existing profiles there, and the hatch
|
|
13
|
+
// overlay is consumed exactly once. A platform workspace holding an Opus 4.8
|
|
14
|
+
// quality-optimized profile therefore keeps it until a migration rewrites it.
|
|
15
|
+
//
|
|
16
|
+
// Only the managed quality-optimized profile is touched — the user-owned
|
|
17
|
+
// custom-quality-optimized copy is theirs to manage. Within it, only a profile
|
|
18
|
+
// still on the Opus default is rewritten — matching by model value also covers
|
|
19
|
+
// the OpenRouter-prefixed id. A profile whose model the user changed to
|
|
20
|
+
// anything else is left untouched. The profile key stays quality-optimized, so
|
|
21
|
+
// persisted inference_profile pins on conversations/schedules keep resolving.
|
|
22
|
+
|
|
23
|
+
const TARGET_PROFILES = ["quality-optimized"];
|
|
24
|
+
|
|
25
|
+
const MODEL_SWAPS: Record<string, string> = {
|
|
26
|
+
"claude-opus-4-8": "claude-fable-5",
|
|
27
|
+
"anthropic/claude-opus-4.8": "anthropic/claude-fable-5",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const swapQualityProfileToFableMigration: WorkspaceMigration = {
|
|
31
|
+
id: "123-swap-quality-profile-to-fable",
|
|
32
|
+
description:
|
|
33
|
+
"Move the managed quality-optimized profile from Anthropic Opus 4.8 to Claude Fable 5",
|
|
34
|
+
run(workspaceDir: string): void {
|
|
35
|
+
const configPath = join(workspaceDir, "config.json");
|
|
36
|
+
if (!existsSync(configPath)) return;
|
|
37
|
+
|
|
38
|
+
let config: Record<string, unknown>;
|
|
39
|
+
try {
|
|
40
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
41
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
42
|
+
config = raw as Record<string, unknown>;
|
|
43
|
+
} catch {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const llm = readObject(config.llm);
|
|
48
|
+
if (llm === null) return;
|
|
49
|
+
|
|
50
|
+
const profiles = readObject(llm.profiles);
|
|
51
|
+
if (profiles === null) return;
|
|
52
|
+
|
|
53
|
+
let changed = false;
|
|
54
|
+
|
|
55
|
+
for (const name of TARGET_PROFILES) {
|
|
56
|
+
const profile = readObject(profiles[name]);
|
|
57
|
+
if (profile === null) continue;
|
|
58
|
+
if (profile.source === "user") continue;
|
|
59
|
+
if (typeof profile.model !== "string") continue;
|
|
60
|
+
|
|
61
|
+
const swapped = MODEL_SWAPS[profile.model];
|
|
62
|
+
if (swapped === undefined) continue;
|
|
63
|
+
|
|
64
|
+
profile.model = swapped;
|
|
65
|
+
profiles[name] = profile;
|
|
66
|
+
changed = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (changed) {
|
|
70
|
+
llm.profiles = profiles;
|
|
71
|
+
config.llm = llm;
|
|
72
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
down(_workspaceDir: string): void {
|
|
76
|
+
// Forward-only.
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
81
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return value as Record<string, unknown>;
|
|
85
|
+
}
|
package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mkdirSync,
|
|
3
|
+
mkdtempSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
11
|
+
|
|
12
|
+
import { stripPersistedMemoryV3TuningDefaultsMigration as MIG } from "../119-strip-persisted-memory-v3-tuning-defaults.js";
|
|
13
|
+
|
|
14
|
+
let workspaceDir: string;
|
|
15
|
+
let configPath: string;
|
|
16
|
+
|
|
17
|
+
function write(obj: unknown): void {
|
|
18
|
+
writeFileSync(configPath, JSON.stringify(obj, null, 2) + "\n");
|
|
19
|
+
}
|
|
20
|
+
function read(): Record<string, unknown> {
|
|
21
|
+
return JSON.parse(readFileSync(configPath, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
function v3(): Record<string, unknown> {
|
|
24
|
+
return (read().memory as { v3: Record<string, unknown> }).v3;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
workspaceDir = mkdtempSync(join(tmpdir(), "strip-v3-tuning-"));
|
|
29
|
+
mkdirSync(workspaceDir, { recursive: true });
|
|
30
|
+
configPath = join(workspaceDir, "config.json");
|
|
31
|
+
});
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("119-strip-persisted-memory-v3-tuning-defaults", () => {
|
|
37
|
+
test("has the expected id", () => {
|
|
38
|
+
expect(MIG.id).toBe("119-strip-persisted-memory-v3-tuning-defaults");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("strips retired lean-profile defaults left by a mixed lean-era config", () => {
|
|
42
|
+
// A lean-seeded config that migration 117 skipped (one leaf later edited to
|
|
43
|
+
// a non-lean value), so the remaining lean defaults are still pinned here.
|
|
44
|
+
write({
|
|
45
|
+
memory: {
|
|
46
|
+
v3: {
|
|
47
|
+
live: true,
|
|
48
|
+
needleK: 12, // lean -> stripped
|
|
49
|
+
denseK: 0, // lean -> stripped
|
|
50
|
+
replyQueryK: 0, // lean -> stripped
|
|
51
|
+
selectorEnabled: false, // lean -> stripped
|
|
52
|
+
hotSet: { k: 20 }, // deliberate edit (broke 117's signature) -> kept
|
|
53
|
+
edge: { seedCount: 6, perSeed: 1, cap: 6 }, // lean -> stripped (edge emptied)
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
MIG.run(workspaceDir);
|
|
59
|
+
|
|
60
|
+
expect(v3()).toEqual({ live: true, hotSet: { k: 20 } });
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("strips a fully-defaulted memory.v3 block, keeping only live", () => {
|
|
64
|
+
write({
|
|
65
|
+
memory: {
|
|
66
|
+
v3: {
|
|
67
|
+
live: true,
|
|
68
|
+
needleK: 100,
|
|
69
|
+
denseK: 100,
|
|
70
|
+
replyQueryK: 12,
|
|
71
|
+
selectorEnabled: true,
|
|
72
|
+
selectorPromptPath: null,
|
|
73
|
+
prune: { maxResidentBytes: 393216, targetResidentBytes: 262144 },
|
|
74
|
+
hotSet: { k: 40, halfLifeDays: 14 },
|
|
75
|
+
freshSet: { k: 100 },
|
|
76
|
+
learnedEdges: {
|
|
77
|
+
halfLifeDays: 30,
|
|
78
|
+
minCount: 3,
|
|
79
|
+
npmiFloor: 0.2,
|
|
80
|
+
maxPerPage: 6,
|
|
81
|
+
perSeed: 3,
|
|
82
|
+
cap: 20,
|
|
83
|
+
},
|
|
84
|
+
spotlight: { n: 6, windowTurns: 2 },
|
|
85
|
+
edge: { hubDegree: 30, seedCount: 18, perSeed: 6, cap: 45 },
|
|
86
|
+
entity: { enabled: true, idfFloor: 4, cap: 8 },
|
|
87
|
+
gate: {
|
|
88
|
+
denseThreshold: 0.66,
|
|
89
|
+
sparseThreshold: 0.35,
|
|
90
|
+
sparseOnlyThreshold: 0.75,
|
|
91
|
+
denseClusterThreshold: 0.6,
|
|
92
|
+
denseClusterMaxDelta: 0.02,
|
|
93
|
+
topK: 5,
|
|
94
|
+
bm25NormK: null,
|
|
95
|
+
bypassForCore: false,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
MIG.run(workspaceDir);
|
|
102
|
+
|
|
103
|
+
expect(v3()).toEqual({ live: true });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("strips superseded gate-threshold defaults too (0.62, 0.52, 0.47, 0.04, 0.45)", () => {
|
|
107
|
+
write({
|
|
108
|
+
memory: {
|
|
109
|
+
v3: {
|
|
110
|
+
live: false,
|
|
111
|
+
gate: {
|
|
112
|
+
denseThreshold: 0.52,
|
|
113
|
+
sparseOnlyThreshold: 0.62,
|
|
114
|
+
denseClusterThreshold: 0.47,
|
|
115
|
+
denseClusterMaxDelta: 0.04,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
MIG.run(workspaceDir);
|
|
122
|
+
|
|
123
|
+
// Whole gate block was superseded defaults → dropped; live preserved.
|
|
124
|
+
expect(v3()).toEqual({ live: false });
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("preserves deliberate non-default overrides, strips defaulted siblings", () => {
|
|
128
|
+
write({
|
|
129
|
+
memory: {
|
|
130
|
+
v3: {
|
|
131
|
+
live: true,
|
|
132
|
+
denseK: 100, // default -> stripped
|
|
133
|
+
needleK: 50, // override -> kept
|
|
134
|
+
gate: {
|
|
135
|
+
denseThreshold: 0.7, // override -> kept
|
|
136
|
+
sparseOnlyThreshold: 0.62, // superseded default -> stripped
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
MIG.run(workspaceDir);
|
|
143
|
+
|
|
144
|
+
expect(v3()).toEqual({
|
|
145
|
+
live: true,
|
|
146
|
+
needleK: 50,
|
|
147
|
+
gate: { denseThreshold: 0.7 },
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("never touches memory.v3.live or unknown keys", () => {
|
|
152
|
+
write({
|
|
153
|
+
memory: { v3: { live: true, someFutureKnob: "x", needleK: 100 } },
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
MIG.run(workspaceDir);
|
|
157
|
+
|
|
158
|
+
expect(v3()).toEqual({ live: true, someFutureKnob: "x" });
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("no-ops cleanly when config.json / memory / v3 is absent or non-default-free", () => {
|
|
162
|
+
// absent config.json
|
|
163
|
+
expect(() => MIG.run(workspaceDir)).not.toThrow();
|
|
164
|
+
|
|
165
|
+
// no memory.v3
|
|
166
|
+
write({ memory: { enabled: true } });
|
|
167
|
+
MIG.run(workspaceDir);
|
|
168
|
+
expect(read()).toEqual({ memory: { enabled: true } });
|
|
169
|
+
|
|
170
|
+
// v3 with only overrides + live -> unchanged (no write needed)
|
|
171
|
+
write({ memory: { v3: { live: true, denseK: 7 } } });
|
|
172
|
+
MIG.run(workspaceDir);
|
|
173
|
+
expect(v3()).toEqual({ live: true, denseK: 7 });
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("down() is a forward-only no-op", () => {
|
|
177
|
+
write({ memory: { v3: { live: true } } });
|
|
178
|
+
expect(() => MIG.down?.(workspaceDir)).not.toThrow();
|
|
179
|
+
expect(v3()).toEqual({ live: true });
|
|
180
|
+
});
|
|
181
|
+
});
|