@vellumai/assistant 0.7.1 → 0.7.3
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 +48 -50
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/memory.md +5 -2
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +1020 -40
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +384 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +157 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
- package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +62 -2
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +461 -147
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
- package/src/__tests__/config-watcher.test.ts +142 -71
- package/src/__tests__/context-search-agent-runner.test.ts +61 -3
- package/src/__tests__/context-search-conversations-source.test.ts +0 -24
- package/src/__tests__/context-search-fanout.test.ts +0 -1
- package/src/__tests__/context-search-memory-source.test.ts +3 -7
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop.test.ts +454 -5
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +43 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-store.test.ts +0 -18
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +12 -12
- package/src/__tests__/cu-unified-flow.test.ts +351 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/date-context.test.ts +164 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/disk-pressure-guard.test.ts +262 -0
- package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
- package/src/__tests__/disk-pressure-policy.test.ts +241 -0
- package/src/__tests__/disk-pressure-routes.test.ts +379 -0
- package/src/__tests__/disk-pressure-tools.test.ts +277 -0
- package/src/__tests__/disk-usage.test.ts +150 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/events-client-registration.test.ts +52 -0
- package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
- package/src/__tests__/file-write-tool.test.ts +4 -10
- package/src/__tests__/filing-service.test.ts +3 -4
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +968 -2
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +772 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +439 -47
- package/src/__tests__/host-bash-routes.test.ts +459 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +248 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
- package/src/__tests__/host-file-proxy.test.ts +301 -45
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
- package/src/__tests__/http-user-message-parity.test.ts +108 -1
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +18 -6
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/onboarding-persona-write.test.ts +308 -0
- package/src/__tests__/openai-provider.test.ts +45 -8
- package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/platform-callback-registration.test.ts +21 -4
- package/src/__tests__/platform.test.ts +2 -1
- package/src/__tests__/playbook-execution.test.ts +0 -43
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/relay-server.test.ts +15 -4
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +2 -2
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
- package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
- package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/approvals/guardian-decision-primitive.ts +13 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -17
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/app-bundler.ts +51 -3
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +137 -25
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +71 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +303 -7
- package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
- package/src/cli/commands/oauth/connect.ts +127 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +16 -25
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +6 -2
- package/src/config/assistant-feature-flags.ts +79 -12
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -20
- package/src/config/feature-flag-registry.json +47 -135
- package/src/config/loader.ts +197 -104
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +64 -1
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +7 -10
- package/src/config/schemas/memory-lifecycle.ts +90 -24
- package/src/config/schemas/memory-v2.ts +121 -13
- package/src/config/schemas/platform.ts +49 -3
- package/src/config/schemas/services.ts +29 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -55
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +89 -60
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
- package/src/daemon/conversation-agent-loop.ts +202 -61
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +9 -4
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-runtime-assembly.ts +28 -2
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +305 -4
- package/src/daemon/conversation-tool-setup.ts +66 -62
- package/src/daemon/conversation.ts +38 -24
- package/src/daemon/date-context.ts +71 -22
- package/src/daemon/disk-pressure-background-gate.ts +73 -0
- package/src/daemon/disk-pressure-guard.ts +343 -0
- package/src/daemon/disk-pressure-policy.ts +163 -0
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -2
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +389 -0
- package/src/daemon/host-bash-proxy.ts +117 -82
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +127 -86
- package/src/daemon/host-file-proxy.ts +129 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +338 -129
- package/src/daemon/lifecycle.ts +194 -145
- package/src/daemon/meet-host-supervisor.ts +4 -4
- package/src/daemon/meet-manifest-loader.ts +0 -1
- package/src/daemon/memory-v2-startup.ts +14 -4
- package/src/daemon/message-protocol.ts +6 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +15 -8
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/documents/document-store.ts +85 -0
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/filing/filing-service.ts +30 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
- package/src/heartbeat/heartbeat-run-store.ts +249 -0
- package/src/heartbeat/heartbeat-service.ts +459 -54
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-scheduler.ts +18 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +70 -3
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/gateway-client.ts +37 -3
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +5 -7
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/media/image-service.ts +1 -7
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/admin.ts +5 -9
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +51 -9
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +22 -9
- package/src/memory/context-search/sources/memory.ts +0 -1
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +5 -13
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
- package/src/memory/graph/conversation-graph-memory.ts +43 -78
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +10 -67
- package/src/memory/graph/graph-search.ts +9 -20
- package/src/memory/graph/retriever.test.ts +6 -0
- package/src/memory/graph/retriever.ts +34 -10
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/indexer.ts +54 -45
- package/src/memory/job-handlers/backfill.ts +2 -11
- package/src/memory/job-handlers/cleanup.ts +43 -0
- package/src/memory/job-handlers/embedding.ts +6 -8
- package/src/memory/job-handlers/summarization.ts +2 -7
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +114 -22
- package/src/memory/jobs-worker.ts +193 -106
- package/src/memory/memory-v2-activation-log-store.ts +33 -15
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +49 -32
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +13 -67
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +387 -344
- package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
- package/src/memory/v2/__tests__/injection.test.ts +181 -169
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +154 -188
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +76 -2
- package/src/memory/v2/activation.ts +213 -239
- package/src/memory/v2/consolidation-job.ts +65 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +123 -103
- package/src/memory/v2/prompts/consolidation.ts +348 -92
- package/src/memory/v2/qdrant.ts +198 -1
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +113 -77
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +91 -53
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +28 -5
- package/src/memory/v2/types.ts +10 -10
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/copy-composer.ts +13 -0
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/notifications/signal.ts +4 -0
- package/src/oauth/AGENTS.md +3 -1
- package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
- package/src/oauth/connect-orchestrator.ts +6 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/plugins/defaults/injectors.ts +35 -2
- package/src/plugins/defaults/memory-retrieval.ts +5 -6
- package/src/plugins/types.ts +7 -0
- package/src/proactive-artifact/aux-message-injector.ts +74 -0
- package/src/proactive-artifact/decision.test.ts +226 -0
- package/src/proactive-artifact/decision.ts +165 -0
- package/src/proactive-artifact/index.ts +7 -0
- package/src/proactive-artifact/job.test.ts +867 -0
- package/src/proactive-artifact/job.ts +352 -0
- package/src/proactive-artifact/message-copy.ts +41 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +23 -24
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/__tests__/retry-callsite.test.ts +222 -1
- package/src/providers/model-intents.ts +7 -0
- package/src/providers/openrouter/client.ts +8 -0
- package/src/providers/retry.ts +50 -0
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +1 -0
- package/src/runtime/__tests__/agent-wake.test.ts +456 -3
- package/src/runtime/agent-wake.ts +238 -100
- package/src/runtime/assistant-event-hub.ts +151 -99
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +32 -0
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/guardian-reply-router.ts +10 -0
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +43 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +21 -2
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +65 -39
- package/src/runtime/routes/debug-bash-routes.ts +163 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +169 -0
- package/src/runtime/routes/documents-routes.ts +32 -75
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +38 -0
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +56 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +66 -9
- package/src/runtime/routes/host-file-routes.ts +54 -5
- package/src/runtime/routes/host-transfer-routes.ts +122 -19
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +21 -180
- package/src/runtime/routes/inbound-message-handler.ts +78 -21
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +14 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.test.ts +41 -15
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +474 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +83 -39
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +10 -16
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/index.ts +1 -7
- package/src/subagent/manager.ts +1 -15
- package/src/tasks/task-runner.ts +0 -1
- package/src/tasks/task-store.ts +0 -3
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/background-tool-registry.ts +17 -3
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +68 -0
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +68 -0
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +78 -3
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +68 -0
- package/src/tools/host-terminal/host-shell.ts +66 -1
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +12 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +32 -11
- package/src/tools/types.ts +28 -2
- package/src/tts/provider-catalog.ts +3 -5
- package/src/usage/pricing.ts +1 -1
- package/src/util/disk-usage.ts +138 -0
- package/src/util/platform.ts +21 -11
- package/src/util/process-liveness.ts +26 -0
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/heartbeat-service.ts +19 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
- package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -395
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/bash.ts +0 -198
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -12,18 +12,35 @@ export interface MemoryV2ConceptRowRecord {
|
|
|
12
12
|
simUser: number;
|
|
13
13
|
simAssistant: number;
|
|
14
14
|
simNow: number;
|
|
15
|
+
/**
|
|
16
|
+
* Cross-encoder rerank delta in raw rerank space (`alpha · r_norm_u`)
|
|
17
|
+
* for the user channel. Zero when rerank is disabled or the slug fell
|
|
18
|
+
* outside the unified top-K-by-pre-rerank-A_o window. Applied
|
|
19
|
+
* additively to A_o weighted by `c_user` — `simUser` itself is the
|
|
20
|
+
* raw fused score and never carries the boost. Stored as a JSON field,
|
|
21
|
+
* so older log rows pre-date this addition and decode with `undefined`;
|
|
22
|
+
* readers should fall back to 0.
|
|
23
|
+
*/
|
|
24
|
+
simUserRerankBoost: number;
|
|
25
|
+
/**
|
|
26
|
+
* Cross-encoder rerank delta for the assistant channel. Same semantics
|
|
27
|
+
* as `simUserRerankBoost`, weighted by `c_assistant` when applied to
|
|
28
|
+
* A_o. The NOW channel intentionally bypasses rerank, so there is no
|
|
29
|
+
* `simNowRerankBoost`.
|
|
30
|
+
*/
|
|
31
|
+
simAssistantRerankBoost: number;
|
|
32
|
+
/**
|
|
33
|
+
* True when rerank ran and this slug landed in the unified
|
|
34
|
+
* top-K-by-pre-rerank-A_o pool. Distinguishes "cross-encoder evaluated
|
|
35
|
+
* this and chose 0" from "rerank skipped this slug" so the inspector
|
|
36
|
+
* can keep the rerank rows visible at `+0.000` instead of silently
|
|
37
|
+
* dropping them. Older log rows pre-date this field and decode with
|
|
38
|
+
* `undefined`; readers should fall back to `false`.
|
|
39
|
+
*/
|
|
40
|
+
inRerankPool: boolean;
|
|
15
41
|
spreadContribution: number;
|
|
16
42
|
source: "prior_state" | "ann_top50" | "both";
|
|
17
|
-
status: "in_context" | "injected" | "not_injected";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface MemoryV2SkillRowRecord {
|
|
21
|
-
id: string;
|
|
22
|
-
activation: number;
|
|
23
|
-
simUser: number;
|
|
24
|
-
simAssistant: number;
|
|
25
|
-
simNow: number;
|
|
26
|
-
status: "injected" | "not_injected";
|
|
43
|
+
status: "in_context" | "injected" | "not_injected" | "page_missing";
|
|
27
44
|
}
|
|
28
45
|
|
|
29
46
|
export interface MemoryV2ConfigSnapshot {
|
|
@@ -34,7 +51,6 @@ export interface MemoryV2ConfigSnapshot {
|
|
|
34
51
|
k: number;
|
|
35
52
|
hops: number;
|
|
36
53
|
top_k: number;
|
|
37
|
-
top_k_skills: number;
|
|
38
54
|
epsilon: number;
|
|
39
55
|
}
|
|
40
56
|
|
|
@@ -43,7 +59,6 @@ export interface RecordMemoryV2ActivationLogParams {
|
|
|
43
59
|
turn: number;
|
|
44
60
|
mode: "context-load" | "per-turn";
|
|
45
61
|
concepts: MemoryV2ConceptRowRecord[];
|
|
46
|
-
skills: MemoryV2SkillRowRecord[];
|
|
47
62
|
config: MemoryV2ConfigSnapshot;
|
|
48
63
|
}
|
|
49
64
|
|
|
@@ -51,6 +66,11 @@ export function recordMemoryV2ActivationLog(
|
|
|
51
66
|
params: RecordMemoryV2ActivationLogParams,
|
|
52
67
|
): void {
|
|
53
68
|
const db = getDb();
|
|
69
|
+
// Skills now live as concept rows under `slug: "skills/<id>"`, so the
|
|
70
|
+
// separate `skills_json` column is always written empty. The column itself
|
|
71
|
+
// remains in the schema for backwards-compat with prior log rows; the
|
|
72
|
+
// reader drops it. A future migration can DROP the column once those rows
|
|
73
|
+
// age out of relevance.
|
|
54
74
|
db.insert(memoryV2ActivationLogs)
|
|
55
75
|
.values({
|
|
56
76
|
id: uuid(),
|
|
@@ -59,7 +79,7 @@ export function recordMemoryV2ActivationLog(
|
|
|
59
79
|
turn: params.turn,
|
|
60
80
|
mode: params.mode,
|
|
61
81
|
conceptsJson: JSON.stringify(params.concepts),
|
|
62
|
-
skillsJson:
|
|
82
|
+
skillsJson: "[]",
|
|
63
83
|
configJson: JSON.stringify(params.config),
|
|
64
84
|
createdAt: Date.now(),
|
|
65
85
|
})
|
|
@@ -87,7 +107,6 @@ export interface MemoryV2ActivationLog {
|
|
|
87
107
|
turn: number;
|
|
88
108
|
mode: "context-load" | "per-turn";
|
|
89
109
|
concepts: MemoryV2ConceptRowRecord[];
|
|
90
|
-
skills: MemoryV2SkillRowRecord[];
|
|
91
110
|
config: MemoryV2ConfigSnapshot;
|
|
92
111
|
}
|
|
93
112
|
|
|
@@ -109,7 +128,6 @@ export function getMemoryV2ActivationLogByMessageIds(
|
|
|
109
128
|
turn: row.turn,
|
|
110
129
|
mode: row.mode as "context-load" | "per-turn",
|
|
111
130
|
concepts: JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[],
|
|
112
|
-
skills: JSON.parse(row.skillsJson) as MemoryV2SkillRowRecord[],
|
|
113
131
|
config: JSON.parse(row.configJson) as MemoryV2ConfigSnapshot,
|
|
114
132
|
};
|
|
115
133
|
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { MemoryV2ConceptRowRecord } from "./memory-v2-activation-log-store.js";
|
|
2
|
+
import { rawAll, rawGet } from "./raw-query.js";
|
|
3
|
+
import { listPages } from "./v2/page-store.js";
|
|
4
|
+
|
|
5
|
+
type ConceptStatus = MemoryV2ConceptRowRecord["status"];
|
|
6
|
+
|
|
7
|
+
export type ConceptFrequencyCounts = Record<ConceptStatus, number>;
|
|
8
|
+
|
|
9
|
+
export interface ConceptFrequencyRow {
|
|
10
|
+
slug: string;
|
|
11
|
+
counts: ConceptFrequencyCounts;
|
|
12
|
+
totalEvaluations: number;
|
|
13
|
+
lastInjectedAt: number | null;
|
|
14
|
+
/** Whether the slug currently has a markdown page on disk. */
|
|
15
|
+
onDisk: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ConceptFrequencyResponse {
|
|
19
|
+
filters: {
|
|
20
|
+
conversationId: string | null;
|
|
21
|
+
sinceMs: number | null;
|
|
22
|
+
};
|
|
23
|
+
totals: {
|
|
24
|
+
/** Activation log rows scanned (turns of evaluation in the window). */
|
|
25
|
+
logCount: number;
|
|
26
|
+
/** Sum of per-row concept evaluations across all log rows in the window. */
|
|
27
|
+
conceptOccurrences: number;
|
|
28
|
+
};
|
|
29
|
+
/** Per-slug aggregates, sorted by `totalEvaluations` desc, then slug asc. */
|
|
30
|
+
concepts: ConceptFrequencyRow[];
|
|
31
|
+
/**
|
|
32
|
+
* Slugs present on disk that never appeared in any activation log row in
|
|
33
|
+
* the window — i.e. retrieval never even scored them as a candidate.
|
|
34
|
+
*/
|
|
35
|
+
neverEvaluatedSlugs: string[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface GetConceptFrequencyFilters {
|
|
39
|
+
conversationId?: string;
|
|
40
|
+
sinceMs?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface AggRow {
|
|
44
|
+
slug: string | null;
|
|
45
|
+
status: ConceptStatus | string | null;
|
|
46
|
+
count: number;
|
|
47
|
+
last_seen: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const ZERO_COUNTS: ConceptFrequencyCounts = {
|
|
51
|
+
injected: 0,
|
|
52
|
+
in_context: 0,
|
|
53
|
+
not_injected: 0,
|
|
54
|
+
page_missing: 0,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
interface CountRow {
|
|
58
|
+
count: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function getConceptFrequencySummary(
|
|
62
|
+
workspaceDir: string,
|
|
63
|
+
filters: GetConceptFrequencyFilters = {},
|
|
64
|
+
): Promise<ConceptFrequencyResponse> {
|
|
65
|
+
const conversationId = filters.conversationId ?? null;
|
|
66
|
+
const sinceMs = filters.sinceMs ?? null;
|
|
67
|
+
|
|
68
|
+
// Kick off the on-disk page walk in parallel with the (synchronous) SQL
|
|
69
|
+
// queries below — listPages does fs.readdir, rawAll/rawGet are sync.
|
|
70
|
+
const onDiskSlugsPromise = listPages(workspaceDir);
|
|
71
|
+
|
|
72
|
+
const aggRows = rawAll<AggRow>(
|
|
73
|
+
`SELECT
|
|
74
|
+
json_extract(c.value, '$.slug') AS slug,
|
|
75
|
+
json_extract(c.value, '$.status') AS status,
|
|
76
|
+
COUNT(*) AS count,
|
|
77
|
+
MAX(l.created_at) AS last_seen
|
|
78
|
+
FROM memory_v2_activation_logs l, json_each(l.concepts_json) c
|
|
79
|
+
WHERE (? IS NULL OR l.conversation_id = ?)
|
|
80
|
+
AND (? IS NULL OR l.created_at >= ?)
|
|
81
|
+
GROUP BY slug, status`,
|
|
82
|
+
conversationId,
|
|
83
|
+
conversationId,
|
|
84
|
+
sinceMs,
|
|
85
|
+
sinceMs,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const logCountRow = rawGet<CountRow>(
|
|
89
|
+
`SELECT COUNT(*) AS count
|
|
90
|
+
FROM memory_v2_activation_logs
|
|
91
|
+
WHERE (? IS NULL OR conversation_id = ?)
|
|
92
|
+
AND (? IS NULL OR created_at >= ?)`,
|
|
93
|
+
conversationId,
|
|
94
|
+
conversationId,
|
|
95
|
+
sinceMs,
|
|
96
|
+
sinceMs,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const bySlug = new Map<string, ConceptFrequencyRow>();
|
|
100
|
+
let conceptOccurrences = 0;
|
|
101
|
+
|
|
102
|
+
for (const row of aggRows) {
|
|
103
|
+
if (!row.slug) continue;
|
|
104
|
+
let entry = bySlug.get(row.slug);
|
|
105
|
+
if (!entry) {
|
|
106
|
+
entry = {
|
|
107
|
+
slug: row.slug,
|
|
108
|
+
counts: { ...ZERO_COUNTS },
|
|
109
|
+
totalEvaluations: 0,
|
|
110
|
+
lastInjectedAt: null,
|
|
111
|
+
onDisk: false,
|
|
112
|
+
};
|
|
113
|
+
bySlug.set(row.slug, entry);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
switch (row.status) {
|
|
117
|
+
case "injected":
|
|
118
|
+
entry.counts.injected += row.count;
|
|
119
|
+
entry.lastInjectedAt =
|
|
120
|
+
entry.lastInjectedAt === null
|
|
121
|
+
? row.last_seen
|
|
122
|
+
: Math.max(entry.lastInjectedAt, row.last_seen);
|
|
123
|
+
break;
|
|
124
|
+
case "in_context":
|
|
125
|
+
entry.counts.in_context += row.count;
|
|
126
|
+
break;
|
|
127
|
+
case "not_injected":
|
|
128
|
+
entry.counts.not_injected += row.count;
|
|
129
|
+
break;
|
|
130
|
+
case "page_missing":
|
|
131
|
+
entry.counts.page_missing += row.count;
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
// Forward-compat: unknown status values are ignored, not summed into
|
|
135
|
+
// totalEvaluations. The activation pipeline produces a closed enum.
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
entry.totalEvaluations += row.count;
|
|
139
|
+
conceptOccurrences += row.count;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const onDiskSlugs = new Set(await onDiskSlugsPromise);
|
|
143
|
+
for (const entry of bySlug.values()) {
|
|
144
|
+
entry.onDisk = onDiskSlugs.has(entry.slug);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const neverEvaluatedSlugs: string[] = [];
|
|
148
|
+
for (const slug of onDiskSlugs) {
|
|
149
|
+
if (!bySlug.has(slug)) neverEvaluatedSlugs.push(slug);
|
|
150
|
+
}
|
|
151
|
+
neverEvaluatedSlugs.sort();
|
|
152
|
+
|
|
153
|
+
const concepts = [...bySlug.values()].sort((a, b) => {
|
|
154
|
+
if (b.totalEvaluations !== a.totalEvaluations) {
|
|
155
|
+
return b.totalEvaluations - a.totalEvaluations;
|
|
156
|
+
}
|
|
157
|
+
return a.slug.localeCompare(b.slug);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
filters: { conversationId, sinceMs },
|
|
162
|
+
totals: {
|
|
163
|
+
logCount: logCountRow?.count ?? 0,
|
|
164
|
+
conceptOccurrences,
|
|
165
|
+
},
|
|
166
|
+
concepts,
|
|
167
|
+
neverEvaluatedSlugs,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { tableHasColumn } from "./schema-introspection.js";
|
|
4
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
5
|
+
|
|
6
|
+
const CHECKPOINT_KEY = "migration_heartbeat_runs_v1";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create the heartbeat_runs table for tracking heartbeat execution lifecycle.
|
|
10
|
+
*
|
|
11
|
+
* Each row represents one scheduled heartbeat tick, tracking its progression
|
|
12
|
+
* through the status lifecycle: pending -> running -> ok/error/timeout, or
|
|
13
|
+
* pending -> skipped/missed/superseded.
|
|
14
|
+
*/
|
|
15
|
+
export function migrateHeartbeatRuns(database: DrizzleDb): void {
|
|
16
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
17
|
+
if (tableHasColumn(database, "heartbeat_runs", "id")) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const raw = getSqliteFrom(database);
|
|
21
|
+
raw.exec(/*sql*/ `
|
|
22
|
+
CREATE TABLE IF NOT EXISTS heartbeat_runs (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
scheduled_for INTEGER NOT NULL,
|
|
25
|
+
started_at INTEGER,
|
|
26
|
+
finished_at INTEGER,
|
|
27
|
+
duration_ms INTEGER,
|
|
28
|
+
status TEXT NOT NULL,
|
|
29
|
+
skip_reason TEXT,
|
|
30
|
+
error TEXT,
|
|
31
|
+
conversation_id TEXT,
|
|
32
|
+
created_at INTEGER NOT NULL
|
|
33
|
+
)
|
|
34
|
+
`);
|
|
35
|
+
raw.exec(/*sql*/ `
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_heartbeat_runs_scheduled_for
|
|
37
|
+
ON heartbeat_runs (scheduled_for)
|
|
38
|
+
`);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function downHeartbeatRuns(database: DrizzleDb): void {
|
|
43
|
+
const raw = getSqliteFrom(database);
|
|
44
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS heartbeat_runs`);
|
|
45
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
export function migrateScheduleRetryPolicy(database: DrizzleDb): void {
|
|
5
|
+
const raw = getSqliteFrom(database);
|
|
6
|
+
try {
|
|
7
|
+
raw.exec(
|
|
8
|
+
`ALTER TABLE cron_jobs ADD COLUMN max_retries INTEGER NOT NULL DEFAULT 3`,
|
|
9
|
+
);
|
|
10
|
+
} catch {
|
|
11
|
+
/* Column already exists */
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
raw.exec(
|
|
15
|
+
`ALTER TABLE cron_jobs ADD COLUMN retry_backoff_ms INTEGER NOT NULL DEFAULT 60000`,
|
|
16
|
+
);
|
|
17
|
+
} catch {
|
|
18
|
+
/* Column already exists */
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
4
|
+
|
|
5
|
+
const CHECKPOINT_KEY = "migration_trace_events_created_at_index_v1";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Add an index on `trace_events.created_at` so the periodic prune job
|
|
9
|
+
* can locate expired rows without a full table scan.
|
|
10
|
+
*/
|
|
11
|
+
export function migrateTraceEventsCreatedAtIndex(database: DrizzleDb): void {
|
|
12
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
13
|
+
const raw = getSqliteFrom(database);
|
|
14
|
+
raw.exec(
|
|
15
|
+
`CREATE INDEX IF NOT EXISTS idx_trace_events_created_at ON trace_events(created_at)`,
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -195,6 +195,12 @@ export {
|
|
|
195
195
|
downToolInvocationsMatchedRuleId,
|
|
196
196
|
migrateToolInvocationsMatchedRuleId,
|
|
197
197
|
} from "./236-tool-invocations-matched-rule-id.js";
|
|
198
|
+
export {
|
|
199
|
+
downHeartbeatRuns,
|
|
200
|
+
migrateHeartbeatRuns,
|
|
201
|
+
} from "./237-heartbeat-runs.js";
|
|
202
|
+
export { migrateScheduleRetryPolicy } from "./238-schedule-retry-policy.js";
|
|
203
|
+
export { migrateTraceEventsCreatedAtIndex } from "./239-trace-events-created-at-index.js";
|
|
198
204
|
export {
|
|
199
205
|
MIGRATION_REGISTRY,
|
|
200
206
|
type MigrationRegistryEntry,
|
|
@@ -47,6 +47,7 @@ import { downActivationState } from "./232-activation-state.js";
|
|
|
47
47
|
import { downMemoryV2ActivationLogs } from "./234-memory-v2-activation-logs.js";
|
|
48
48
|
import { downSlackCompactionWatermark } from "./235-slack-compaction-watermark.js";
|
|
49
49
|
import { downToolInvocationsMatchedRuleId } from "./236-tool-invocations-matched-rule-id.js";
|
|
50
|
+
import { downHeartbeatRuns } from "./237-heartbeat-runs.js";
|
|
50
51
|
|
|
51
52
|
export interface MigrationRegistryEntry {
|
|
52
53
|
/** The checkpoint key written to memory_checkpoints on completion. */
|
|
@@ -404,6 +405,13 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
|
|
|
404
405
|
"Add matched_trust_rule_id column to tool_invocations for trust rule audit and rule editor UI",
|
|
405
406
|
down: downToolInvocationsMatchedRuleId,
|
|
406
407
|
},
|
|
408
|
+
{
|
|
409
|
+
key: "migration_heartbeat_runs_v1",
|
|
410
|
+
version: 47,
|
|
411
|
+
description:
|
|
412
|
+
"Create heartbeat_runs table for tracking heartbeat execution lifecycle with CAS state transitions",
|
|
413
|
+
down: downHeartbeatRuns,
|
|
414
|
+
},
|
|
407
415
|
];
|
|
408
416
|
|
|
409
417
|
export function getMaxMigrationVersion(): number {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import { makeMockLogger } from "../../__tests__/helpers/mock-logger.js";
|
|
4
|
+
import { _setOverridesForTesting } from "../../config/assistant-feature-flags.js";
|
|
5
|
+
|
|
6
|
+
// This test exercises the v1 PKB search path. The `memory-v2-enabled` flag
|
|
7
|
+
// (registry default `true`) makes pkb-search short-circuit to keep traffic
|
|
8
|
+
// off the legacy collection — disable it so the v1 path stays under test.
|
|
9
|
+
_setOverridesForTesting({ "memory-v2-enabled": false });
|
|
4
10
|
|
|
5
11
|
mock.module("../../util/logger.js", () => ({
|
|
6
12
|
getLogger: () => makeMockLogger(),
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// PKB — Qdrant hybrid search for indexed PKB markdown files
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
|
+
import { getConfig } from "../../config/loader.js";
|
|
5
6
|
import { getLogger } from "../../util/logger.js";
|
|
7
|
+
import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
|
|
6
8
|
import {
|
|
7
9
|
isQdrantBreakerOpen,
|
|
8
10
|
withQdrantBreaker,
|
|
@@ -40,6 +42,11 @@ export async function searchPkbFiles(
|
|
|
40
42
|
limit: number,
|
|
41
43
|
scopeIds?: string[],
|
|
42
44
|
): Promise<PkbSearchResult[]> {
|
|
45
|
+
// v2 owns the read path when both gates are on; v2 absorbs PKB as a read
|
|
46
|
+
// source, so PKB hint search short-circuits to keep traffic off the v1
|
|
47
|
+
// collection (avoiding OOM-crash risk from a corrupted sparse segment).
|
|
48
|
+
if (isMemoryV2ReadActive(getConfig())) return [];
|
|
49
|
+
|
|
43
50
|
if (isQdrantBreakerOpen()) {
|
|
44
51
|
log.warn("Qdrant circuit breaker open, skipping PKB search");
|
|
45
52
|
return [];
|
|
@@ -73,19 +73,31 @@ export interface QdrantSearchResult {
|
|
|
73
73
|
payload: QdrantPointPayload;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Strip a trailing `:sparse-v<digits>` segment from a sentinel string.
|
|
78
|
+
*
|
|
79
|
+
* Legacy v1 sentinels (pre-decouple) included the sparse encoder version in
|
|
80
|
+
* the embedding-model identity. The suffix is no longer written, but stored
|
|
81
|
+
* sentinels written by older daemons may still carry it — strip it before
|
|
82
|
+
* comparing identities so existing collections aren't unnecessarily rebuilt.
|
|
83
|
+
*/
|
|
84
|
+
export function stripLegacySparseSuffix(sentinel: string): string {
|
|
85
|
+
return sentinel.replace(/:sparse-v\d+$/, "");
|
|
86
|
+
}
|
|
87
|
+
|
|
76
88
|
let _instance: VellumQdrantClient | null = null;
|
|
77
89
|
|
|
78
90
|
export function getQdrantClient(): VellumQdrantClient {
|
|
79
91
|
if (!_instance) {
|
|
80
92
|
throw new Error(
|
|
81
|
-
"Qdrant client not initialized. Call initQdrantClient() first."
|
|
93
|
+
"Qdrant client not initialized. Call initQdrantClient() first.",
|
|
82
94
|
);
|
|
83
95
|
}
|
|
84
96
|
return _instance;
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
export function initQdrantClient(
|
|
88
|
-
config: QdrantClientConfig
|
|
100
|
+
config: QdrantClientConfig,
|
|
89
101
|
): VellumQdrantClient {
|
|
90
102
|
_instance = new VellumQdrantClient(config);
|
|
91
103
|
return _instance;
|
|
@@ -140,12 +152,28 @@ export class VellumQdrantClient {
|
|
|
140
152
|
const dimMismatch =
|
|
141
153
|
currentSize != null && currentSize !== this.vectorSize;
|
|
142
154
|
|
|
143
|
-
// Check model identity via a sentinel point that stores the embedding model
|
|
155
|
+
// Check model identity via a sentinel point that stores the embedding model.
|
|
156
|
+
//
|
|
157
|
+
// Legacy sentinels included a ":sparse-v<N>" suffix that conflated the
|
|
158
|
+
// sparse encoder version with the dense model identity. Sparse vectors
|
|
159
|
+
// are upserted in place and never require collection recreation, so a
|
|
160
|
+
// stored value matching the current dense identity after stripping any
|
|
161
|
+
// legacy sparse suffix is treated as compatible. Compatible-but-legacy
|
|
162
|
+
// sentinels are rewritten to the new format below to clean up gradually.
|
|
144
163
|
let modelMismatch = false;
|
|
164
|
+
let needsSentinelRewrite = false;
|
|
145
165
|
if (this.embeddingModel) {
|
|
146
166
|
const sentinel = await this.readSentinel();
|
|
147
|
-
if (sentinel
|
|
148
|
-
|
|
167
|
+
if (sentinel) {
|
|
168
|
+
const normalizedStored = stripLegacySparseSuffix(sentinel);
|
|
169
|
+
const normalizedCurrent = stripLegacySparseSuffix(
|
|
170
|
+
this.embeddingModel,
|
|
171
|
+
);
|
|
172
|
+
if (normalizedStored !== normalizedCurrent) {
|
|
173
|
+
modelMismatch = true;
|
|
174
|
+
} else if (sentinel !== this.embeddingModel) {
|
|
175
|
+
needsSentinelRewrite = true;
|
|
176
|
+
}
|
|
149
177
|
}
|
|
150
178
|
}
|
|
151
179
|
|
|
@@ -156,7 +184,7 @@ export class VellumQdrantClient {
|
|
|
156
184
|
currentSize,
|
|
157
185
|
expectedSize: this.vectorSize,
|
|
158
186
|
},
|
|
159
|
-
"Qdrant collection uses unnamed vectors (legacy) — deleting and recreating with named vectors. Embeddings will be re-indexed."
|
|
187
|
+
"Qdrant collection uses unnamed vectors (legacy) — deleting and recreating with named vectors. Embeddings will be re-indexed.",
|
|
160
188
|
);
|
|
161
189
|
await this.client.deleteCollection(this.collection);
|
|
162
190
|
migrated = true;
|
|
@@ -169,7 +197,7 @@ export class VellumQdrantClient {
|
|
|
169
197
|
expectedSize: this.vectorSize,
|
|
170
198
|
modelMismatch,
|
|
171
199
|
},
|
|
172
|
-
"Qdrant collection incompatible (dimension or model change) — deleting and recreating. Embeddings will be regenerated on demand."
|
|
200
|
+
"Qdrant collection incompatible (dimension or model change) — deleting and recreating. Embeddings will be regenerated on demand.",
|
|
173
201
|
);
|
|
174
202
|
await this.client.deleteCollection(this.collection);
|
|
175
203
|
migrated = true;
|
|
@@ -178,12 +206,15 @@ export class VellumQdrantClient {
|
|
|
178
206
|
if (await this.ensurePayloadIndexesSafe()) {
|
|
179
207
|
this.collectionReady = true;
|
|
180
208
|
}
|
|
209
|
+
if (needsSentinelRewrite && this.embeddingModel) {
|
|
210
|
+
await this.writeSentinel(this.embeddingModel);
|
|
211
|
+
}
|
|
181
212
|
return { migrated: false };
|
|
182
213
|
}
|
|
183
214
|
} catch (err) {
|
|
184
215
|
log.warn(
|
|
185
216
|
{ err },
|
|
186
|
-
"Failed to verify collection compatibility, assuming compatible"
|
|
217
|
+
"Failed to verify collection compatibility, assuming compatible",
|
|
187
218
|
);
|
|
188
219
|
if (await this.ensurePayloadIndexesSafe()) {
|
|
189
220
|
this.collectionReady = true;
|
|
@@ -197,7 +228,7 @@ export class VellumQdrantClient {
|
|
|
197
228
|
|
|
198
229
|
log.info(
|
|
199
230
|
{ collection: this.collection, vectorSize: this.vectorSize },
|
|
200
|
-
"Creating Qdrant collection with named vectors (dense + sparse)"
|
|
231
|
+
"Creating Qdrant collection with named vectors (dense + sparse)",
|
|
201
232
|
);
|
|
202
233
|
|
|
203
234
|
try {
|
|
@@ -253,7 +284,7 @@ export class VellumQdrantClient {
|
|
|
253
284
|
this.collectionReady = true;
|
|
254
285
|
log.info(
|
|
255
286
|
{ collection: this.collection },
|
|
256
|
-
"Qdrant collection created with payload indexes"
|
|
287
|
+
"Qdrant collection created with payload indexes",
|
|
257
288
|
);
|
|
258
289
|
}
|
|
259
290
|
|
|
@@ -265,7 +296,7 @@ export class VellumQdrantClient {
|
|
|
265
296
|
targetId: string,
|
|
266
297
|
vector: number[],
|
|
267
298
|
payload: Omit<QdrantPointPayload, "target_type" | "target_id">,
|
|
268
|
-
sparseVector?: QdrantSparseVector
|
|
299
|
+
sparseVector?: QdrantSparseVector,
|
|
269
300
|
): Promise<string> {
|
|
270
301
|
await this.ensureCollection();
|
|
271
302
|
|
|
@@ -320,7 +351,7 @@ export class VellumQdrantClient {
|
|
|
320
351
|
async search(
|
|
321
352
|
vector: number[],
|
|
322
353
|
limit: number,
|
|
323
|
-
filter?: Record<string, unknown
|
|
354
|
+
filter?: Record<string, unknown>,
|
|
324
355
|
): Promise<QdrantSearchResult[]> {
|
|
325
356
|
await this.ensureCollection();
|
|
326
357
|
|
|
@@ -348,7 +379,7 @@ export class VellumQdrantClient {
|
|
|
348
379
|
return results.map((result) => ({
|
|
349
380
|
id: typeof result.id === "string" ? result.id : String(result.id),
|
|
350
381
|
score: result.score,
|
|
351
|
-
payload:
|
|
382
|
+
payload: result.payload as unknown as QdrantPointPayload,
|
|
352
383
|
}));
|
|
353
384
|
}
|
|
354
385
|
|
|
@@ -357,7 +388,6 @@ export class VellumQdrantClient {
|
|
|
357
388
|
limit: number,
|
|
358
389
|
targetTypes: Array<"segment" | "item" | "summary" | "media">,
|
|
359
390
|
excludeMessageIds?: string[],
|
|
360
|
-
scopeIds?: string[]
|
|
361
391
|
): Promise<QdrantSearchResult[]> {
|
|
362
392
|
const mustConditions: Array<Record<string, unknown>> = [
|
|
363
393
|
{
|
|
@@ -384,18 +414,6 @@ export class VellumQdrantClient {
|
|
|
384
414
|
});
|
|
385
415
|
}
|
|
386
416
|
|
|
387
|
-
// Scope filtering: accept points whose memory_scope_id matches one of the
|
|
388
|
-
// allowed scopes, OR points that lack the field entirely (legacy data).
|
|
389
|
-
// Post-query DB filtering remains as defense-in-depth for legacy points.
|
|
390
|
-
if (scopeIds && scopeIds.length > 0) {
|
|
391
|
-
mustConditions.push({
|
|
392
|
-
should: [
|
|
393
|
-
{ key: "memory_scope_id", match: { any: scopeIds } },
|
|
394
|
-
{ is_empty: { key: "memory_scope_id" } },
|
|
395
|
-
],
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
|
|
399
417
|
const mustNotConditions: Array<Record<string, unknown>> = [
|
|
400
418
|
{ key: "_meta", match: { value: true } },
|
|
401
419
|
];
|
|
@@ -434,7 +452,7 @@ export class VellumQdrantClient {
|
|
|
434
452
|
const queryParams = {
|
|
435
453
|
prefetch: [
|
|
436
454
|
{
|
|
437
|
-
query:
|
|
455
|
+
query: denseVector as unknown as number[],
|
|
438
456
|
using: "dense",
|
|
439
457
|
limit: effectivePrefetchLimit,
|
|
440
458
|
},
|
|
@@ -469,7 +487,7 @@ export class VellumQdrantClient {
|
|
|
469
487
|
return (results.points ?? []).map((point) => ({
|
|
470
488
|
id: typeof point.id === "string" ? point.id : String(point.id),
|
|
471
489
|
score: point.score ?? 0,
|
|
472
|
-
payload:
|
|
490
|
+
payload: point.payload as unknown as QdrantPointPayload,
|
|
473
491
|
}));
|
|
474
492
|
}
|
|
475
493
|
|
|
@@ -594,7 +612,7 @@ export class VellumQdrantClient {
|
|
|
594
612
|
} catch (err) {
|
|
595
613
|
log.warn(
|
|
596
614
|
{ err, collection: this.collection },
|
|
597
|
-
"Failed to delete Qdrant collection"
|
|
615
|
+
"Failed to delete Qdrant collection",
|
|
598
616
|
);
|
|
599
617
|
return false;
|
|
600
618
|
}
|
|
@@ -762,8 +780,7 @@ export class VellumQdrantClient {
|
|
|
762
780
|
...(offset !== undefined ? { offset } : {}),
|
|
763
781
|
});
|
|
764
782
|
for (const point of result.points) {
|
|
765
|
-
const id =
|
|
766
|
-
typeof point.id === "string" ? point.id : String(point.id);
|
|
783
|
+
const id = typeof point.id === "string" ? point.id : String(point.id);
|
|
767
784
|
const payload = (point.payload ?? {}) as Record<string, unknown>;
|
|
768
785
|
out.push({ id, payload });
|
|
769
786
|
}
|
|
@@ -788,7 +805,7 @@ export class VellumQdrantClient {
|
|
|
788
805
|
|
|
789
806
|
private async findByTarget(
|
|
790
807
|
targetType: string,
|
|
791
|
-
targetId: string
|
|
808
|
+
targetId: string,
|
|
792
809
|
): Promise<string | null> {
|
|
793
810
|
try {
|
|
794
811
|
const results = await this.client.scroll(this.collection, {
|