@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
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
// Memory v2 — Skill catalog → embedded skill entries
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// catalog state. Including uninstalled catalog skills ensures their activation
|
|
11
|
-
// hints are discoverable by intent so the model can auto-install them.
|
|
5
|
+
// Enumerate the enabled-skill catalog AND uninstalled catalog skills, render
|
|
6
|
+
// each skill's prose statement via `buildSkillContent`, embed dense + sparse,
|
|
7
|
+
// and upsert into `memory_v2_concept_pages` under the slug `skills/<id>`.
|
|
8
|
+
// Including uninstalled catalog skills ensures their activation hints are
|
|
9
|
+
// discoverable by intent so the model can auto-install them.
|
|
12
10
|
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
11
|
+
// Skills share the concept-page collection rather than living in a dedicated
|
|
12
|
+
// one so the per-turn activation pipeline scores them against the same
|
|
13
|
+
// candidate ANN as concept pages, with the same decay and spread machinery.
|
|
14
|
+
// The render path branches on the `skills/` slug prefix to surface them as
|
|
15
|
+
// the `### Skills You Can Use` subsection.
|
|
16
|
+
//
|
|
17
|
+
// Skill entries are kept in a small in-process cache so the render path can
|
|
18
|
+
// fetch a `SkillEntry` synchronously by id without round-tripping to Qdrant.
|
|
19
|
+
// The cache is replaced atomically at the end of a successful seed run; on
|
|
20
|
+
// error the prior cache stays intact (skills are best-effort).
|
|
17
21
|
|
|
18
22
|
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
19
23
|
import { getConfig } from "../../config/loader.js";
|
|
@@ -25,19 +29,36 @@ import {
|
|
|
25
29
|
fromSkillSummary,
|
|
26
30
|
} from "../../skills/skill-memory.js";
|
|
27
31
|
import { getLogger } from "../../util/logger.js";
|
|
32
|
+
import { applyCorrectionIfCalibrated } from "../anisotropy.js";
|
|
28
33
|
import {
|
|
29
34
|
embedWithBackend,
|
|
30
35
|
generateSparseEmbedding,
|
|
31
36
|
} from "../embedding-backend.js";
|
|
37
|
+
import {
|
|
38
|
+
pruneSlugsWithPrefixExcept,
|
|
39
|
+
upsertConceptPageEmbedding,
|
|
40
|
+
} from "./qdrant.js";
|
|
32
41
|
import {
|
|
33
42
|
augmentMcpSetupDescription,
|
|
34
43
|
buildSkillContent,
|
|
35
44
|
} from "./skill-content.js";
|
|
36
|
-
import { pruneSkillsExcept, upsertSkillEmbedding } from "./skill-qdrant.js";
|
|
37
45
|
import type { SkillEntry } from "./types.js";
|
|
38
46
|
|
|
39
47
|
const log = getLogger("memory-v2-skill-store");
|
|
40
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Slug prefix under which skill embeddings are indexed in
|
|
51
|
+
* `memory_v2_concept_pages`. Concept-page slugs must match
|
|
52
|
+
* `[a-z0-9][a-z0-9-]*(/...)*`, and `skills` matches that pattern, so the
|
|
53
|
+
* prefix coexists with hand-authored concept pages without escape work.
|
|
54
|
+
*/
|
|
55
|
+
export const SKILL_SLUG_PREFIX = "skills/";
|
|
56
|
+
|
|
57
|
+
/** Compose the unified-collection slug for a skill id. */
|
|
58
|
+
export function skillSlugFor(id: string): string {
|
|
59
|
+
return `${SKILL_SLUG_PREFIX}${id}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
41
62
|
/**
|
|
42
63
|
* Module-level cache of rendered skill entries keyed by skill id. `null` until
|
|
43
64
|
* the first successful seed run completes; replaced atomically on each
|
|
@@ -46,30 +67,27 @@ const log = getLogger("memory-v2-skill-store");
|
|
|
46
67
|
let entries: Map<string, SkillEntry> | null = null;
|
|
47
68
|
|
|
48
69
|
/**
|
|
49
|
-
* Seed (or re-seed)
|
|
50
|
-
*
|
|
51
|
-
*
|
|
70
|
+
* Seed (or re-seed) skill embeddings into the unified concept-page collection.
|
|
71
|
+
* Idempotent: safe to call repeatedly. Best-effort: never throws — any
|
|
72
|
+
* failure leaves the prior `entries` cache in place and logs a warning.
|
|
52
73
|
*
|
|
53
74
|
* Steps:
|
|
54
|
-
* 1. Enumerate the local skill catalog and resolve each skill's enabled
|
|
55
|
-
* (`resolveSkillStates`).
|
|
56
|
-
* 2. Build a `
|
|
57
|
-
*
|
|
58
|
-
*
|
|
75
|
+
* 1. Enumerate the local skill catalog and resolve each skill's enabled
|
|
76
|
+
* state (`resolveSkillStates`).
|
|
77
|
+
* 2. Build a `SkillEntry` per enabled skill, applying the mcp-setup
|
|
78
|
+
* augmentation and the prose-style content render (`buildSkillContent`,
|
|
79
|
+
* capped at 500 chars).
|
|
59
80
|
* 3. Defense-in-depth feature-flag filter: drop any skill whose declared
|
|
60
|
-
* `metadata.vellum.feature-flag` is currently disabled.
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* 3b. Fetch the full remote catalog and seed any uninstalled skills so their
|
|
65
|
-
* activation hints are discoverable by semantic search. Best-effort: if
|
|
66
|
-
* the catalog fetch fails, only installed skills are seeded.
|
|
81
|
+
* `metadata.vellum.feature-flag` is currently disabled.
|
|
82
|
+
* 3b. Fetch the full remote catalog and seed any uninstalled skills so
|
|
83
|
+
* their activation hints are discoverable by semantic search. Best-effort:
|
|
84
|
+
* if the catalog fetch fails, only installed skills are seeded.
|
|
67
85
|
* 4. Embed all `content` strings in a single dense `embedWithBackend` call,
|
|
68
86
|
* and a per-skill synchronous `generateSparseEmbedding`.
|
|
69
|
-
* 5. Upsert one Qdrant point per skill via `
|
|
70
|
-
* deterministically on id
|
|
71
|
-
* 6. Call `
|
|
72
|
-
* points from prior catalog state (e.g. uninstalled skills).
|
|
87
|
+
* 5. Upsert one Qdrant point per skill via `upsertConceptPageEmbedding`
|
|
88
|
+
* keyed deterministically on slug `skills/<id>`.
|
|
89
|
+
* 6. Call `pruneSlugsWithPrefixExcept(SKILL_SLUG_PREFIX, ...)` to drop any
|
|
90
|
+
* stale points from prior catalog state (e.g. uninstalled skills).
|
|
73
91
|
* 7. Replace the module-level `entries` cache with the freshly built map.
|
|
74
92
|
*/
|
|
75
93
|
export async function seedV2SkillEntries(): Promise<void> {
|
|
@@ -82,8 +100,7 @@ export async function seedV2SkillEntries(): Promise<void> {
|
|
|
82
100
|
// Track every locally-installed skill id (regardless of enabled/disabled
|
|
83
101
|
// state) so the catalog-seeding loop below treats them all as "installed"
|
|
84
102
|
// and never re-seeds a disabled skill from `getCatalog()` as if it were
|
|
85
|
-
// uninstalled.
|
|
86
|
-
// keys off `loadSkillCatalog()` (the installed set) for the same reason.
|
|
103
|
+
// uninstalled.
|
|
87
104
|
const installedIds = new Set<string>(catalog.map((s) => s.id));
|
|
88
105
|
|
|
89
106
|
// Build the input list, applying the mcp-setup description augmentation
|
|
@@ -99,8 +116,8 @@ export async function seedV2SkillEntries(): Promise<void> {
|
|
|
99
116
|
}
|
|
100
117
|
|
|
101
118
|
// Seed uninstalled catalog skills so their activation hints are
|
|
102
|
-
// discoverable by intent
|
|
103
|
-
//
|
|
119
|
+
// discoverable by intent. Track whether the catalog was available so we
|
|
120
|
+
// can guard pruning below.
|
|
104
121
|
let catalogAvailable = false;
|
|
105
122
|
try {
|
|
106
123
|
const fullCatalog = await getCatalog();
|
|
@@ -122,31 +139,41 @@ export async function seedV2SkillEntries(): Promise<void> {
|
|
|
122
139
|
|
|
123
140
|
// Embed all content strings in one batched call. Sparse vectors are
|
|
124
141
|
// computed in-process (no network).
|
|
125
|
-
const
|
|
142
|
+
const embedded = await embedWithBackend(
|
|
126
143
|
config,
|
|
127
144
|
seeds.map((s) => s.content),
|
|
128
145
|
);
|
|
146
|
+
const denseVectors = await Promise.all(
|
|
147
|
+
embedded.vectors.map((v) =>
|
|
148
|
+
applyCorrectionIfCalibrated(v, embedded.provider, embedded.model),
|
|
149
|
+
),
|
|
150
|
+
);
|
|
129
151
|
|
|
130
152
|
const now = Date.now();
|
|
131
153
|
const nextEntries = new Map<string, SkillEntry>();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
154
|
+
await Promise.all(
|
|
155
|
+
seeds.map((seed, i) =>
|
|
156
|
+
upsertConceptPageEmbedding({
|
|
157
|
+
slug: skillSlugFor(seed.id),
|
|
158
|
+
dense: denseVectors[i],
|
|
159
|
+
sparse: generateSparseEmbedding(seed.content),
|
|
160
|
+
updatedAt: now,
|
|
161
|
+
}),
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
for (const seed of seeds) {
|
|
140
165
|
nextEntries.set(seed.id, seed);
|
|
141
166
|
}
|
|
142
167
|
|
|
143
|
-
// Prune stale
|
|
144
|
-
// network failure or cold cache), we cannot enumerate which
|
|
145
|
-
// catalog skills should exist, so skip pruning entirely to
|
|
146
|
-
// aggressively removing previously-seeded catalog skill embeddings.
|
|
147
|
-
// Mirrors v1's safeguard in capability-seed.ts (lines 124–143).
|
|
168
|
+
// Prune stale skill slugs. When the catalog is unavailable (empty array
|
|
169
|
+
// from network failure or cold cache), we cannot enumerate which
|
|
170
|
+
// uninstalled catalog skills should exist, so skip pruning entirely to
|
|
171
|
+
// avoid aggressively removing previously-seeded catalog skill embeddings.
|
|
148
172
|
if (catalogAvailable) {
|
|
149
|
-
await
|
|
173
|
+
await pruneSlugsWithPrefixExcept(
|
|
174
|
+
SKILL_SLUG_PREFIX,
|
|
175
|
+
seeds.map((s) => s.id),
|
|
176
|
+
);
|
|
150
177
|
} else {
|
|
151
178
|
log.info(
|
|
152
179
|
"Catalog unavailable — skipping skill pruning to preserve prior catalog embeddings",
|
|
@@ -163,13 +190,24 @@ export async function seedV2SkillEntries(): Promise<void> {
|
|
|
163
190
|
/**
|
|
164
191
|
* Synchronous lookup of a previously-seeded `SkillEntry` by skill id. Returns
|
|
165
192
|
* `null` when the cache has not yet been populated, when the id is unknown,
|
|
166
|
-
* or when a prior seed run dropped the id (e.g. the skill was disabled).
|
|
167
|
-
*
|
|
193
|
+
* or when a prior seed run dropped the id (e.g. the skill was disabled).
|
|
194
|
+
*
|
|
195
|
+
* Accepts either a bare skill id (`example-skill`) or its unified-collection
|
|
196
|
+
* slug (`skills/example-skill`) so render-side callers can pass through what
|
|
197
|
+
* they have without a manual prefix strip.
|
|
168
198
|
*/
|
|
169
|
-
export function getSkillCapability(
|
|
199
|
+
export function getSkillCapability(idOrSlug: string): SkillEntry | null {
|
|
200
|
+
const id = idOrSlug.startsWith(SKILL_SLUG_PREFIX)
|
|
201
|
+
? idOrSlug.slice(SKILL_SLUG_PREFIX.length)
|
|
202
|
+
: idOrSlug;
|
|
170
203
|
return entries?.get(id) ?? null;
|
|
171
204
|
}
|
|
172
205
|
|
|
206
|
+
/** True iff the slug refers to a skill entry in the unified collection. */
|
|
207
|
+
export function isSkillSlug(slug: string): boolean {
|
|
208
|
+
return slug.startsWith(SKILL_SLUG_PREFIX);
|
|
209
|
+
}
|
|
210
|
+
|
|
173
211
|
/** @internal Test-only: clear the module-level cache. */
|
|
174
212
|
export function _resetSkillStoreForTests(): void {
|
|
175
213
|
entries = null;
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Memory v2 — BM25 sparse channel
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// Replaces the legacy TF-only sparse embedding (`generateSparseEmbedding` in
|
|
6
|
+
// `../embedding-backend.ts`) with a real Okapi BM25 implementation. Common
|
|
7
|
+
// words like "i", "am", "the" no longer dominate sparse matching the way they
|
|
8
|
+
// did when every token was weighted equally.
|
|
9
|
+
//
|
|
10
|
+
// BM25 score for document `d` and query `q`:
|
|
11
|
+
//
|
|
12
|
+
// score(d, q) = Σ_t∈q IDF(t) · TF_sat(d, t)
|
|
13
|
+
// TF_sat(d, t) = tf(d, t) · (k1 + 1)
|
|
14
|
+
// / (tf(d, t) + k1 · (1 - b + b · |d| / avg_dl))
|
|
15
|
+
// IDF(t) = log( (N - df(t) + 0.5) / (df(t) + 0.5) + 1 )
|
|
16
|
+
//
|
|
17
|
+
// `+1` inside the IDF log keeps the result non-negative even when df(t) > N/2,
|
|
18
|
+
// matching the variant Lucene uses for `BM25Similarity`.
|
|
19
|
+
//
|
|
20
|
+
// **Asymmetric encoding**: documents carry the full BM25 weight per token
|
|
21
|
+
// (IDF · TF_sat baked into the stored vector), and queries carry binary
|
|
22
|
+
// occurrence per token. Qdrant's sparse dot product then reduces to the BM25
|
|
23
|
+
// score directly. Putting BM25 on the doc side means the weights need
|
|
24
|
+
// recomputing whenever the corpus DF or avg_dl changes — operators trigger
|
|
25
|
+
// that with `assistant memory v2 reembed` after major content shifts.
|
|
26
|
+
|
|
27
|
+
import { readFile } from "node:fs/promises";
|
|
28
|
+
|
|
29
|
+
import type { SparseEmbedding } from "../embedding-types.js";
|
|
30
|
+
import {
|
|
31
|
+
SPARSE_VOCAB_SIZE,
|
|
32
|
+
tokenHash,
|
|
33
|
+
tokenizeStemmed,
|
|
34
|
+
} from "../sparse-tokenize.js";
|
|
35
|
+
import { listPages } from "./page-store.js";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Aggregate corpus statistics used to weight a BM25 document vector. Held in
|
|
39
|
+
* memory after a startup walk over `memory/concepts/`.
|
|
40
|
+
*/
|
|
41
|
+
export interface CorpusStats {
|
|
42
|
+
/** Total document count over which DF was accumulated. */
|
|
43
|
+
totalDocs: number;
|
|
44
|
+
/** hashedTokenIndex (in `[0, SPARSE_VOCAB_SIZE)`) → distinct-doc count. */
|
|
45
|
+
df: Map<number, number>;
|
|
46
|
+
/** Average document length in tokens, post-tokenize. */
|
|
47
|
+
avgDl: number;
|
|
48
|
+
/** Wall-clock millis at build time — used by diagnostics, not the formula. */
|
|
49
|
+
builtAt: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** BM25 hyperparameters. Standard Lucene/Elasticsearch defaults. */
|
|
53
|
+
export interface Bm25Params {
|
|
54
|
+
/** TF saturation curve. ~1.2 is standard. */
|
|
55
|
+
k1: number;
|
|
56
|
+
/** Length normalization. 0 = none, 1 = full. ~0.75 is standard. */
|
|
57
|
+
b: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let _conceptPageStats: CorpusStats | null = null;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Latest in-memory corpus stats for `memory/concepts/`, or `null` if a build
|
|
64
|
+
* has not yet completed. Callers must handle `null` and fall back to legacy
|
|
65
|
+
* TF-only behavior so the daemon remains usable during the brief startup
|
|
66
|
+
* window before {@link rebuildConceptPageCorpusStats} finishes.
|
|
67
|
+
*/
|
|
68
|
+
export function getConceptPageCorpusStats(): CorpusStats | null {
|
|
69
|
+
return _conceptPageStats;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Walk every concept page on disk, accumulate document frequency per hashed
|
|
74
|
+
* token bucket, and average document length. Atomically swaps the result into
|
|
75
|
+
* the module-level cache when the walk succeeds. On error the previous stats
|
|
76
|
+
* stay live.
|
|
77
|
+
*
|
|
78
|
+
* Reads bodies via `readPage`-equivalent direct file reads to avoid paying for
|
|
79
|
+
* frontmatter parsing on every page (we only need the body for sparse).
|
|
80
|
+
*/
|
|
81
|
+
export async function rebuildConceptPageCorpusStats(
|
|
82
|
+
workspaceDir: string,
|
|
83
|
+
): Promise<void> {
|
|
84
|
+
const slugs = await listPages(workspaceDir);
|
|
85
|
+
if (slugs.length === 0) {
|
|
86
|
+
_conceptPageStats = {
|
|
87
|
+
totalDocs: 0,
|
|
88
|
+
df: new Map(),
|
|
89
|
+
avgDl: 0,
|
|
90
|
+
builtAt: Date.now(),
|
|
91
|
+
};
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const df = new Map<number, number>();
|
|
96
|
+
let totalTokens = 0;
|
|
97
|
+
let docsCounted = 0;
|
|
98
|
+
|
|
99
|
+
for (const slug of slugs) {
|
|
100
|
+
const body = await readPageBodyForStats(workspaceDir, slug);
|
|
101
|
+
if (body === null) continue;
|
|
102
|
+
const tokens = tokenizeStemmed(body);
|
|
103
|
+
if (tokens.length === 0) continue;
|
|
104
|
+
totalTokens += tokens.length;
|
|
105
|
+
docsCounted += 1;
|
|
106
|
+
const seen = new Set<number>();
|
|
107
|
+
for (const token of tokens) {
|
|
108
|
+
const idx = tokenHash(token, SPARSE_VOCAB_SIZE);
|
|
109
|
+
if (seen.has(idx)) continue;
|
|
110
|
+
seen.add(idx);
|
|
111
|
+
df.set(idx, (df.get(idx) ?? 0) + 1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_conceptPageStats = {
|
|
116
|
+
totalDocs: docsCounted,
|
|
117
|
+
df,
|
|
118
|
+
avgDl: docsCounted > 0 ? totalTokens / docsCounted : 0,
|
|
119
|
+
builtAt: Date.now(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Read just the body of a page for stats accumulation. Skips the YAML
|
|
125
|
+
* frontmatter without invoking the schema-validating `readPage` parser, since
|
|
126
|
+
* any parse failure surfaced there would abort the whole rebuild — and we
|
|
127
|
+
* only need the prose half for tokenization.
|
|
128
|
+
*/
|
|
129
|
+
async function readPageBodyForStats(
|
|
130
|
+
workspaceDir: string,
|
|
131
|
+
slug: string,
|
|
132
|
+
): Promise<string | null> {
|
|
133
|
+
const path = `${workspaceDir}/memory/concepts/${slug}.md`;
|
|
134
|
+
let raw: string;
|
|
135
|
+
try {
|
|
136
|
+
raw = await readFile(path, "utf-8");
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
// Strip a leading `---\n...\n---\n` block if present; otherwise return raw.
|
|
141
|
+
if (raw.startsWith("---")) {
|
|
142
|
+
const closing = raw.indexOf("\n---", 3);
|
|
143
|
+
if (closing !== -1) {
|
|
144
|
+
const after = raw.indexOf("\n", closing + 4);
|
|
145
|
+
if (after !== -1) return raw.slice(after + 1);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return raw;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Compute the BM25 IDF weight for a hashed token bucket. Returns `0` when the
|
|
153
|
+
* token's df equals the corpus size (a token in every document carries no
|
|
154
|
+
* discriminating power).
|
|
155
|
+
*/
|
|
156
|
+
function computeIdf(stats: CorpusStats, hashIdx: number): number {
|
|
157
|
+
const df = stats.df.get(hashIdx) ?? 0;
|
|
158
|
+
const numerator = stats.totalDocs - df + 0.5;
|
|
159
|
+
const denominator = df + 0.5;
|
|
160
|
+
return Math.log(numerator / denominator + 1);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Document-side BM25-weighted sparse vector. Each emitted value is
|
|
165
|
+
* `IDF(t) · TF_sat(d, t)` so the dot product against a binary query vector
|
|
166
|
+
* (see {@link generateBm25QueryEmbedding}) yields the BM25 score.
|
|
167
|
+
*
|
|
168
|
+
* Returns an empty embedding for empty input or when the corpus is empty
|
|
169
|
+
* (every IDF would be zero anyway).
|
|
170
|
+
*/
|
|
171
|
+
export function generateBm25DocEmbedding(
|
|
172
|
+
text: string,
|
|
173
|
+
stats: CorpusStats,
|
|
174
|
+
params: Bm25Params,
|
|
175
|
+
): SparseEmbedding {
|
|
176
|
+
const tokens = tokenizeStemmed(text);
|
|
177
|
+
if (tokens.length === 0 || stats.totalDocs === 0) {
|
|
178
|
+
return { indices: [], values: [] };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Per-document term frequencies, keyed by hashed bucket.
|
|
182
|
+
const tf = new Map<number, number>();
|
|
183
|
+
for (const token of tokens) {
|
|
184
|
+
const idx = tokenHash(token, SPARSE_VOCAB_SIZE);
|
|
185
|
+
tf.set(idx, (tf.get(idx) ?? 0) + 1);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const docLen = tokens.length;
|
|
189
|
+
// avg_dl can be 0 only when totalDocs is 0, which we already short-circuited.
|
|
190
|
+
const lengthFactor = 1 - params.b + (params.b * docLen) / stats.avgDl;
|
|
191
|
+
const indices: number[] = [];
|
|
192
|
+
const values: number[] = [];
|
|
193
|
+
|
|
194
|
+
for (const [idx, freq] of tf) {
|
|
195
|
+
const idf = computeIdf(stats, idx);
|
|
196
|
+
if (idf === 0) continue; // Skip tokens that contribute nothing to scores.
|
|
197
|
+
const saturated =
|
|
198
|
+
(freq * (params.k1 + 1)) / (freq + params.k1 * lengthFactor);
|
|
199
|
+
const weight = idf * saturated;
|
|
200
|
+
if (weight === 0) continue;
|
|
201
|
+
indices.push(idx);
|
|
202
|
+
values.push(weight);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return { indices, values };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Query-side sparse vector — binary occurrence per distinct query token. The
|
|
210
|
+
* dot product `Σ_t v_q(t) · v_d(t)` against a BM25-weighted document vector
|
|
211
|
+
* is exactly the BM25 score, since `v_q(t) = 1` for tokens in the query and
|
|
212
|
+
* `0` otherwise.
|
|
213
|
+
*
|
|
214
|
+
* Stateless — does not need corpus stats, so callers can use this on every
|
|
215
|
+
* turn without coordinating with {@link rebuildConceptPageCorpusStats}.
|
|
216
|
+
*/
|
|
217
|
+
export function generateBm25QueryEmbedding(text: string): SparseEmbedding {
|
|
218
|
+
const tokens = tokenizeStemmed(text);
|
|
219
|
+
if (tokens.length === 0) {
|
|
220
|
+
return { indices: [], values: [] };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const seen = new Set<number>();
|
|
224
|
+
const indices: number[] = [];
|
|
225
|
+
const values: number[] = [];
|
|
226
|
+
for (const token of tokens) {
|
|
227
|
+
const idx = tokenHash(token, SPARSE_VOCAB_SIZE);
|
|
228
|
+
if (seen.has(idx)) continue;
|
|
229
|
+
seen.add(idx);
|
|
230
|
+
indices.push(idx);
|
|
231
|
+
values.push(1);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return { indices, values };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** @internal Test-only: reset module-level singletons. */
|
|
238
|
+
export function _resetCorpusStatsForTests(): void {
|
|
239
|
+
_conceptPageStats = null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** @internal Test-only: install a fixture stats table without disk I/O. */
|
|
243
|
+
export function _setCorpusStatsForTests(stats: CorpusStats | null): void {
|
|
244
|
+
_conceptPageStats = stats;
|
|
245
|
+
}
|
|
@@ -6,16 +6,18 @@
|
|
|
6
6
|
// and returns a concatenated, header-wrapped block ready to splice into the
|
|
7
7
|
// current user message via the injector chain.
|
|
8
8
|
//
|
|
9
|
-
// Pairs with the v2 per-turn activation block (`
|
|
10
|
-
// `conversation-graph-memory.ts
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// Both land on the user message so
|
|
9
|
+
// Pairs with the v2 per-turn activation block (`maybeRouteV2Injection` in
|
|
10
|
+
// `conversation-graph-memory.ts`, which threads through `injectTextBlock`)
|
|
11
|
+
// — that block carries activated concept pages selected by the activation
|
|
12
|
+
// pipeline; this static block carries the always-relevant aggregate views
|
|
13
|
+
// written by consolidation and the user. Both land on the user message so
|
|
14
|
+
// the system prompt stays cache-stable.
|
|
14
15
|
//
|
|
15
16
|
// Refresh cadence is owned by the caller: the agent loop only passes the
|
|
16
17
|
// content through when `mode === "full"` (first turn / post-compaction),
|
|
17
18
|
// matching the existing PKB auto-inject pattern.
|
|
18
19
|
|
|
20
|
+
import type { ChannelId } from "../../channels/types.js";
|
|
19
21
|
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
20
22
|
import { loadConfig } from "../../config/loader.js";
|
|
21
23
|
import { readPromptFile } from "../../prompts/system-prompt.js";
|
|
@@ -60,3 +62,24 @@ export function readMemoryV2StaticContent(): string | null {
|
|
|
60
62
|
}
|
|
61
63
|
return sections.length > 0 ? sections.join("\n\n") : null;
|
|
62
64
|
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Static memory holds the user's aggregate personal pages
|
|
68
|
+
* (essentials/threads/recent/buffer). Block injection when a non-guardian
|
|
69
|
+
* actor reaches the assistant over a remote channel — otherwise the model
|
|
70
|
+
* can be prompt-injected into reciting private memory. Internal flows
|
|
71
|
+
* (`sourceChannel: "vellum"`) and turns with no trust context pass through
|
|
72
|
+
* unchanged; this gate exists only to keep remote untrusted actors out.
|
|
73
|
+
*/
|
|
74
|
+
export function shouldLoadMemoryV2Static(args: {
|
|
75
|
+
shouldInjectNowAndPkb: boolean;
|
|
76
|
+
sourceChannel: ChannelId | undefined;
|
|
77
|
+
isTrustedActor: boolean;
|
|
78
|
+
}): boolean {
|
|
79
|
+
if (!args.shouldInjectNowAndPkb) return false;
|
|
80
|
+
const isRemoteUntrustedActor =
|
|
81
|
+
args.sourceChannel !== undefined &&
|
|
82
|
+
args.sourceChannel !== "vellum" &&
|
|
83
|
+
!args.isTrustedActor;
|
|
84
|
+
return !isRemoteUntrustedActor;
|
|
85
|
+
}
|
package/src/memory/v2/types.ts
CHANGED
|
@@ -85,20 +85,20 @@ export const ActivationStateSchema = z.object({
|
|
|
85
85
|
export type ActivationState = z.infer<typeof ActivationStateSchema>;
|
|
86
86
|
|
|
87
87
|
// ---------------------------------------------------------------------------
|
|
88
|
-
// Skill
|
|
88
|
+
// Skill entries (synthetic concept-collection rows, not on-disk pages)
|
|
89
89
|
// ---------------------------------------------------------------------------
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Per-skill capability snapshot held in-process and embedded into the
|
|
93
|
-
* `
|
|
94
|
-
* `buildSkillContent` string — already capped at
|
|
95
|
-
* already containing the skill's display name — and
|
|
96
|
-
* what we render verbatim in `### Skills You Can Use`.
|
|
92
|
+
* Per-skill capability snapshot held in-process and embedded into the unified
|
|
93
|
+
* `memory_v2_concept_pages` Qdrant collection under the slug `skills/<id>`.
|
|
94
|
+
* `content` is the rendered `buildSkillContent` string — already capped at
|
|
95
|
+
* 500 chars upstream and already containing the skill's display name — and
|
|
96
|
+
* is what we embed and what we render verbatim in `### Skills You Can Use`.
|
|
97
97
|
*
|
|
98
|
-
* Plain interface (no Zod) because skill data does not cross a
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
98
|
+
* Plain interface (no Zod) because skill data does not cross a serialization
|
|
99
|
+
* boundary: it is built in-process by `seedV2SkillEntries` and read in-process
|
|
100
|
+
* by `renderInjectionBlock`. The Qdrant payload is not parsed back through
|
|
101
|
+
* this type.
|
|
102
102
|
*/
|
|
103
103
|
export interface SkillEntry {
|
|
104
104
|
id: string;
|
|
@@ -95,52 +95,3 @@ export interface GmailModifyRequest {
|
|
|
95
95
|
|
|
96
96
|
/** Message format for GET requests */
|
|
97
97
|
export type GmailMessageFormat = "minimal" | "full" | "raw" | "metadata";
|
|
98
|
-
|
|
99
|
-
/** Attachment data from the Gmail API */
|
|
100
|
-
export interface GmailAttachment {
|
|
101
|
-
size: number;
|
|
102
|
-
data: string; // base64url-encoded
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/** Gmail filter criteria */
|
|
106
|
-
export interface GmailFilterCriteria {
|
|
107
|
-
from?: string;
|
|
108
|
-
to?: string;
|
|
109
|
-
subject?: string;
|
|
110
|
-
query?: string;
|
|
111
|
-
hasAttachment?: boolean;
|
|
112
|
-
excludeChats?: boolean;
|
|
113
|
-
size?: number;
|
|
114
|
-
sizeComparison?: "larger" | "smaller";
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** Gmail filter action */
|
|
118
|
-
export interface GmailFilterAction {
|
|
119
|
-
addLabelIds?: string[];
|
|
120
|
-
removeLabelIds?: string[];
|
|
121
|
-
forward?: string;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** Gmail filter */
|
|
125
|
-
export interface GmailFilter {
|
|
126
|
-
id: string;
|
|
127
|
-
criteria: GmailFilterCriteria;
|
|
128
|
-
action: GmailFilterAction;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** Gmail filters list response */
|
|
132
|
-
export interface GmailFiltersListResponse {
|
|
133
|
-
filter?: GmailFilter[];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/** Gmail vacation auto-reply settings */
|
|
137
|
-
export interface GmailVacationSettings {
|
|
138
|
-
enableAutoReply: boolean;
|
|
139
|
-
responseSubject?: string;
|
|
140
|
-
responseBodyPlainText?: string;
|
|
141
|
-
responseBodyHtml?: string;
|
|
142
|
-
restrictToContacts?: boolean;
|
|
143
|
-
restrictToDomain?: boolean;
|
|
144
|
-
startTime?: string; // epoch ms as string
|
|
145
|
-
endTime?: string; // epoch ms as string
|
|
146
|
-
}
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from "@vellumai/slack-text";
|
|
12
12
|
|
|
13
13
|
import { findContactChannel } from "../../../contacts/contact-store.js";
|
|
14
|
-
import { upsertContactChannel } from "../../../contacts/contacts-write.js";
|
|
15
14
|
import type { OAuthConnection } from "../../../oauth/connection.js";
|
|
16
15
|
import { resolveOAuthConnection } from "../../../oauth/connection-resolver.js";
|
|
17
16
|
import { isProviderConnected } from "../../../oauth/oauth-store.js";
|
|
@@ -163,18 +162,6 @@ async function resolveUserName(
|
|
|
163
162
|
resp.user.real_name ||
|
|
164
163
|
resp.user.name;
|
|
165
164
|
userNameCache.set(userId, name);
|
|
166
|
-
|
|
167
|
-
// Persist to contacts for future sessions
|
|
168
|
-
try {
|
|
169
|
-
upsertContactChannel({
|
|
170
|
-
sourceChannel: "slack",
|
|
171
|
-
externalUserId: userId,
|
|
172
|
-
displayName: name,
|
|
173
|
-
});
|
|
174
|
-
} catch {
|
|
175
|
-
// Non-fatal — caching failure shouldn't break messaging
|
|
176
|
-
}
|
|
177
|
-
|
|
178
165
|
return name;
|
|
179
166
|
} catch {
|
|
180
167
|
return userId;
|
|
@@ -433,24 +420,7 @@ export const slackProvider: MessagingProvider = {
|
|
|
433
420
|
const dmUserId = conv.metadata.dmUserId as string;
|
|
434
421
|
conv.name = await resolveUserName(auth, dmUserId);
|
|
435
422
|
|
|
436
|
-
|
|
437
|
-
try {
|
|
438
|
-
const existing = findContactChannel({
|
|
439
|
-
channelType: "slack",
|
|
440
|
-
externalUserId: dmUserId,
|
|
441
|
-
});
|
|
442
|
-
if (existing && !existing.channel.externalChatId) {
|
|
443
|
-
upsertContactChannel({
|
|
444
|
-
contactId: existing.contact.id,
|
|
445
|
-
sourceChannel: "slack",
|
|
446
|
-
externalUserId: dmUserId,
|
|
447
|
-
externalChatId: conv.id,
|
|
448
|
-
displayName: conv.name,
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
} catch {
|
|
452
|
-
// Non-fatal
|
|
453
|
-
}
|
|
423
|
+
|
|
454
424
|
}
|
|
455
425
|
}
|
|
456
426
|
|