@vellumai/assistant 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +32 -49
- 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/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 +39 -1
- 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/skill-host-contracts/src/assistant-event.ts +9 -0
- 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 +565 -12
- 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 +374 -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 +109 -2
- package/src/__tests__/assistant-event.test.ts +10 -0
- package/src/__tests__/assistant-events-sse-hardening.test.ts +7 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -7
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- 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-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-readiness-service.test.ts +59 -1
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +90 -155
- 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-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +2 -2
- 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-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-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-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -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 +5 -12
- package/src/__tests__/cu-unified-flow.test.ts +185 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- 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-service.test.ts +718 -1
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +602 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +246 -47
- package/src/__tests__/host-bash-routes.test.ts +294 -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 +41 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
- package/src/__tests__/host-file-proxy.test.ts +37 -43
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +262 -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 +583 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- 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__/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-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/prechat-onboarding-contract.test.ts +3 -1
- 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__/public-ingress-urls.test.ts +97 -0
- 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 +10 -6
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- 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__/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-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- 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/bundler/app-bundler.ts +51 -3
- 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 -1
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +73 -0
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +15 -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 +296 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +0 -18
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +67 -10
- 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/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- 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 -12
- package/src/config/feature-flag-registry.json +21 -133
- package/src/config/loader.ts +73 -99
- 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 +7 -4
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/heartbeat.ts +63 -0
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +5 -10
- package/src/config/schemas/memory-lifecycle.ts +77 -24
- package/src/config/schemas/memory-v2.ts +48 -4
- package/src/config/schemas/platform.ts +6 -0
- package/src/config/schemas/services.ts +1 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/contacts/contact-store.ts +0 -30
- 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 +126 -5
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +4 -3
- package/src/daemon/conversation-agent-loop-handlers.ts +21 -3
- package/src/daemon/conversation-agent-loop.ts +32 -28
- package/src/daemon/conversation-lifecycle.ts +8 -1
- package/src/daemon/conversation-process.ts +16 -11
- package/src/daemon/conversation-runtime-assembly.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +125 -4
- package/src/daemon/conversation-tool-setup.ts +16 -55
- package/src/daemon/conversation.ts +21 -2
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +293 -0
- package/src/daemon/host-bash-proxy.ts +84 -74
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +81 -86
- package/src/daemon/host-file-proxy.ts +93 -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 +247 -129
- package/src/daemon/lifecycle.ts +115 -117
- package/src/daemon/message-protocol.ts +3 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +11 -8
- 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/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- 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/events/tool-audit-listener.ts +2 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +15 -7
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
- package/src/heartbeat/heartbeat-run-store.ts +236 -0
- package/src/heartbeat/heartbeat-service.ts +280 -49
- 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/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/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +14 -1
- package/src/ipc/cli-client.ts +32 -1
- package/src/live-voice/live-voice-metrics.ts +10 -10
- 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/memory/__tests__/jobs-store-job-classes.test.ts +24 -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/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 +32 -7
- package/src/memory/context-search/sources/memory-v2.ts +17 -5
- package/src/memory/conversation-crud.ts +1 -1
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +4 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -4
- package/src/memory/graph/conversation-graph-memory.ts +1 -24
- package/src/memory/graph/graph-search.ts +8 -0
- package/src/memory/graph/retriever.ts +28 -0
- package/src/memory/graph/tools.ts +1 -1
- 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 +66 -22
- package/src/memory/jobs-worker.ts +112 -63
- package/src/memory/memory-v2-activation-log-store.ts +1 -1
- 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/index.ts +5 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +50 -20
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +7 -0
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/v2/__tests__/activation.test.ts +77 -95
- package/src/memory/v2/__tests__/injection.test.ts +43 -21
- package/src/memory/v2/__tests__/sim.test.ts +166 -6
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +0 -1
- package/src/memory/v2/activation.ts +69 -88
- package/src/memory/v2/consolidation-job.ts +3 -5
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +86 -53
- package/src/memory/v2/prompts/consolidation.ts +312 -91
- package/src/memory/v2/qdrant.ts +99 -1
- package/src/memory/v2/sim.ts +126 -16
- package/src/memory/v2/skill-qdrant.ts +12 -3
- package/src/memory/v2/skill-store.ts +16 -1
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +6 -5
- 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/guardian-question-mode.ts +5 -5
- package/src/oauth/connect-orchestrator.ts +4 -0
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- 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/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/system-prompt.ts +3 -18
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/runtime/assistant-event-hub.ts +118 -96
- package/src/runtime/assistant-event.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +19 -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/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- 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 +35 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- 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 +1 -0
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +30 -13
- package/src/runtime/routes/document-pdf-renderer.ts +165 -0
- package/src/runtime/routes/documents-routes.ts +30 -0
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +12 -6
- 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 +36 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +44 -14
- package/src/runtime/routes/host-file-routes.ts +33 -10
- package/src/runtime/routes/host-transfer-routes.ts +64 -24
- 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 +15 -43
- package/src/runtime/routes/inbound-message-handler.ts +1 -9
- 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/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +441 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- 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/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 +63 -38
- package/src/security/oauth-callback-registry.ts +8 -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 +5 -5
- 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/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/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.ts +26 -0
- package/src/tools/host-filesystem/read.ts +26 -0
- package/src/tools/host-filesystem/transfer.ts +31 -1
- package/src/tools/host-filesystem/write.ts +26 -0
- package/src/tools/host-terminal/host-shell.ts +58 -0
- 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/tool-approval-handler.ts +1 -5
- package/src/tools/types.ts +4 -0
- package/src/usage/pricing.ts +1 -1
- package/src/workspace/hatched-date.ts +86 -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/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/utils.ts +21 -0
- 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/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/mcp-reload.ts +0 -18
|
@@ -36,6 +36,10 @@ import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
|
36
36
|
import type {
|
|
37
37
|
MemoryV2BackfillOp,
|
|
38
38
|
MemoryV2BackfillResult,
|
|
39
|
+
MemoryV2ExplainSimilarityResult,
|
|
40
|
+
MemoryV2ExplainSimilarityStats,
|
|
41
|
+
MemoryV2FitAnisotropyResult,
|
|
42
|
+
MemoryV2RebuildCorpusStatsResult,
|
|
39
43
|
MemoryV2ReembedSkillsResult,
|
|
40
44
|
MemoryV2ValidateResult,
|
|
41
45
|
} from "../../runtime/routes/memory-v2-routes.js";
|
|
@@ -73,6 +77,74 @@ async function runBackfillOp(
|
|
|
73
77
|
log.info(`Queued ${op} job: ${result.result!.jobId}`);
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
/** Format a number for table output. */
|
|
81
|
+
function fmt(n: number | null, decimals: number): string {
|
|
82
|
+
if (n === null) return "—";
|
|
83
|
+
return n.toFixed(decimals);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Render the per-channel breakdown table + stats for the explain command. */
|
|
87
|
+
function printExplainResult(result: MemoryV2ExplainSimilarityResult): void {
|
|
88
|
+
log.info(
|
|
89
|
+
`dense_weight=${result.config.dense_weight} sparse_weight=${result.config.sparse_weight}`,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
for (const channel of result.channels) {
|
|
93
|
+
log.info("");
|
|
94
|
+
log.info(`── channel: ${channel.channel} ──`);
|
|
95
|
+
log.info(`text: ${channel.textPreview}`);
|
|
96
|
+
log.info(
|
|
97
|
+
`maxSparse (used for normalization): ${channel.maxSparse.toFixed(4)}`,
|
|
98
|
+
);
|
|
99
|
+
log.info(
|
|
100
|
+
`effective: dw=${channel.effectiveDenseWeight.toFixed(3)} sw=${channel.effectiveSparseWeight.toFixed(3)} (sparseSpread=${channel.sparseSpread.toFixed(3)})`,
|
|
101
|
+
);
|
|
102
|
+
log.info("");
|
|
103
|
+
log.info(
|
|
104
|
+
"slug".padEnd(48) +
|
|
105
|
+
"dense".padStart(10) +
|
|
106
|
+
"sparseRaw".padStart(12) +
|
|
107
|
+
"sparseNorm".padStart(12) +
|
|
108
|
+
"fused".padStart(10),
|
|
109
|
+
);
|
|
110
|
+
log.info("─".repeat(92));
|
|
111
|
+
for (const row of channel.rows) {
|
|
112
|
+
const slugCol =
|
|
113
|
+
row.slug.length > 47 ? `${row.slug.slice(0, 46)}…` : row.slug;
|
|
114
|
+
log.info(
|
|
115
|
+
slugCol.padEnd(48) +
|
|
116
|
+
fmt(row.denseScore, 4).padStart(10) +
|
|
117
|
+
fmt(row.sparseRaw, 4).padStart(12) +
|
|
118
|
+
fmt(row.sparseNorm, 4).padStart(12) +
|
|
119
|
+
fmt(row.fused, 4).padStart(10),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
log.info("");
|
|
123
|
+
log.info("Stats (per channel):");
|
|
124
|
+
log.info(` ${formatStatLine("dense ", channel.stats.dense)}`);
|
|
125
|
+
log.info(` ${formatStatLine("sparseRaw ", channel.stats.sparseRaw)}`);
|
|
126
|
+
log.info(` ${formatStatLine("sparseNorm ", channel.stats.sparseNorm)}`);
|
|
127
|
+
log.info(` ${formatStatLine("fused ", channel.stats.fused)}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function formatStatLine(
|
|
132
|
+
label: string,
|
|
133
|
+
stats: MemoryV2ExplainSimilarityStats,
|
|
134
|
+
): string {
|
|
135
|
+
if (stats.count === 0) {
|
|
136
|
+
return `${label} n=0`;
|
|
137
|
+
}
|
|
138
|
+
const range = stats.max - stats.min;
|
|
139
|
+
return (
|
|
140
|
+
`${label} n=${String(stats.count).padStart(3)}` +
|
|
141
|
+
` range=[${stats.min.toFixed(4)}, ${stats.max.toFixed(4)}]` +
|
|
142
|
+
` (Δ=${range.toFixed(4)})` +
|
|
143
|
+
` mean=${stats.mean.toFixed(4)}` +
|
|
144
|
+
` std=${stats.stddev.toFixed(4)}`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
76
148
|
// ---------------------------------------------------------------------------
|
|
77
149
|
// Registration
|
|
78
150
|
// ---------------------------------------------------------------------------
|
|
@@ -119,13 +191,18 @@ Subcommands fall into three groups:
|
|
|
119
191
|
validate Print a diagnostic report of orphan outgoing-edge
|
|
120
192
|
targets, oversized pages, and parse failures.
|
|
121
193
|
|
|
194
|
+
Calibration:
|
|
195
|
+
fit-anisotropy Fit Mu & Viswanath's all-but-the-top correction so
|
|
196
|
+
embedding cosines stop clustering in a narrow band.
|
|
197
|
+
|
|
122
198
|
Examples:
|
|
123
199
|
$ assistant memory v2 validate
|
|
124
200
|
$ assistant memory v2 migrate
|
|
125
201
|
$ assistant memory v2 migrate --force
|
|
126
202
|
$ assistant memory v2 reembed
|
|
127
203
|
$ assistant memory v2 reembed-skills
|
|
128
|
-
$ assistant memory v2 activation
|
|
204
|
+
$ assistant memory v2 activation
|
|
205
|
+
$ assistant memory v2 fit-anisotropy`,
|
|
129
206
|
);
|
|
130
207
|
|
|
131
208
|
// ── migrate ───────────────────────────────────────────────────────────
|
|
@@ -241,6 +318,224 @@ Examples:
|
|
|
241
318
|
await runBackfillOp("activation-recompute");
|
|
242
319
|
});
|
|
243
320
|
|
|
321
|
+
// ── explain ───────────────────────────────────────────────────────────
|
|
322
|
+
|
|
323
|
+
v2.command("explain")
|
|
324
|
+
.description(
|
|
325
|
+
"Diagnose dense vs sparse score distributions for a query (read-only)",
|
|
326
|
+
)
|
|
327
|
+
.requiredOption(
|
|
328
|
+
"--text <text>",
|
|
329
|
+
"Query text to embed and score against the concept-page collection (the user channel).",
|
|
330
|
+
)
|
|
331
|
+
.option(
|
|
332
|
+
"--assistant-text <text>",
|
|
333
|
+
"Optional second query text — scored independently as the assistant channel.",
|
|
334
|
+
)
|
|
335
|
+
.option(
|
|
336
|
+
"--now-text <text>",
|
|
337
|
+
"Optional third query text — scored independently as the now channel.",
|
|
338
|
+
)
|
|
339
|
+
.option(
|
|
340
|
+
"--top <n>",
|
|
341
|
+
"Number of top hits to fetch per channel (default 25)",
|
|
342
|
+
"25",
|
|
343
|
+
)
|
|
344
|
+
.addHelpText(
|
|
345
|
+
"after",
|
|
346
|
+
`
|
|
347
|
+
Embeds the supplied text(s), runs the hybrid dense + sparse query against
|
|
348
|
+
the v2 concept-page Qdrant collection, and prints per-slug raw dense, raw
|
|
349
|
+
sparse, normalized sparse, and fused scores plus per-channel summary
|
|
350
|
+
statistics (range, mean, stddev). Use this to identify whether dense
|
|
351
|
+
embedding compression (anisotropy) or per-batch sparse normalization is
|
|
352
|
+
the dominant cause of score compression at the head of the activation
|
|
353
|
+
distribution.
|
|
354
|
+
|
|
355
|
+
Read-only: does not mutate Qdrant, the workspace, or the activation log.
|
|
356
|
+
|
|
357
|
+
Interpretation:
|
|
358
|
+
Dense range < 0.1 AND sparseNorm range > 0.5 → embedding anisotropy
|
|
359
|
+
Dense range > 0.2 AND sparseNorm range < 0.1 → sparse max-normalization
|
|
360
|
+
Both compressed → both contribute
|
|
361
|
+
Both wide → channel mixing is the cause
|
|
362
|
+
|
|
363
|
+
Examples:
|
|
364
|
+
$ assistant memory v2 explain --text "what's bothering me"
|
|
365
|
+
$ assistant memory v2 explain --text "..." --top 50
|
|
366
|
+
$ assistant memory v2 explain --text "..." --assistant-text "..." --now-text "..."`,
|
|
367
|
+
)
|
|
368
|
+
.action(
|
|
369
|
+
async (opts: {
|
|
370
|
+
text: string;
|
|
371
|
+
assistantText?: string;
|
|
372
|
+
nowText?: string;
|
|
373
|
+
top: string;
|
|
374
|
+
}) => {
|
|
375
|
+
const top = Number.parseInt(opts.top, 10);
|
|
376
|
+
if (!Number.isFinite(top) || top < 1) {
|
|
377
|
+
log.error("--top must be a positive integer");
|
|
378
|
+
process.exitCode = 1;
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const result = await cliIpcCall<MemoryV2ExplainSimilarityResult>(
|
|
383
|
+
"memory_v2_explain_similarity",
|
|
384
|
+
{
|
|
385
|
+
body: {
|
|
386
|
+
userText: opts.text,
|
|
387
|
+
assistantText: opts.assistantText,
|
|
388
|
+
nowText: opts.nowText,
|
|
389
|
+
top,
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
if (!result.ok) {
|
|
395
|
+
log.error(result.error ?? "Failed to run similarity diagnostic");
|
|
396
|
+
process.exitCode = 1;
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
printExplainResult(result.result!);
|
|
401
|
+
},
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
// ── rebuild-corpus-stats ──────────────────────────────────────────────
|
|
405
|
+
|
|
406
|
+
v2.command("rebuild-corpus-stats")
|
|
407
|
+
.description(
|
|
408
|
+
"Rebuild the BM25 corpus stats (DF table + avg doc length) used by the sparse channel",
|
|
409
|
+
)
|
|
410
|
+
.addHelpText(
|
|
411
|
+
"after",
|
|
412
|
+
`
|
|
413
|
+
Walks every concept page on disk and recomputes the document-frequency
|
|
414
|
+
table and average document length used to weight BM25 sparse vectors.
|
|
415
|
+
Atomic swap — the previous stats stay live until the new ones are ready.
|
|
416
|
+
|
|
417
|
+
Run after bulk content imports, after manually editing many pages, or to
|
|
418
|
+
recover from a startup rebuild that errored.
|
|
419
|
+
|
|
420
|
+
Note: this only refreshes the in-memory stats used to *construct* new
|
|
421
|
+
document-side sparse vectors. Existing sparse vectors stored in Qdrant
|
|
422
|
+
are not refreshed by this command — pair with 'assistant memory v2
|
|
423
|
+
reembed' if document-side weights need updating.
|
|
424
|
+
|
|
425
|
+
Examples:
|
|
426
|
+
$ assistant memory v2 rebuild-corpus-stats`,
|
|
427
|
+
)
|
|
428
|
+
.action(async () => {
|
|
429
|
+
const result = await cliIpcCall<MemoryV2RebuildCorpusStatsResult>(
|
|
430
|
+
"memory_v2_rebuild_corpus_stats",
|
|
431
|
+
{ body: {} },
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
if (!result.ok) {
|
|
435
|
+
log.error(result.error ?? "Failed to rebuild corpus stats");
|
|
436
|
+
process.exitCode = 1;
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const r = result.result!;
|
|
441
|
+
log.info(`Rebuilt BM25 corpus stats: ${r.totalDocs} docs.`);
|
|
442
|
+
log.info(` avg doc length: ${r.avgDl.toFixed(2)} tokens`);
|
|
443
|
+
log.info(` vocabulary buckets: ${r.vocabularyBuckets.toLocaleString()}`);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// ── fit-anisotropy ────────────────────────────────────────────────────
|
|
447
|
+
|
|
448
|
+
v2.command("fit-anisotropy")
|
|
449
|
+
.description(
|
|
450
|
+
"Fit the embedding anisotropy correction (Mu & Viswanath 'all-but-the-top')",
|
|
451
|
+
)
|
|
452
|
+
.option(
|
|
453
|
+
"--k <n>",
|
|
454
|
+
"Number of leading principal components to project out (default 1; raise to 2-3 only if PC2/PC3 also explain >5% variance)",
|
|
455
|
+
"1",
|
|
456
|
+
)
|
|
457
|
+
.option(
|
|
458
|
+
"--sample <n>",
|
|
459
|
+
"Maximum stored dense vectors to pull for the fit (default 5000)",
|
|
460
|
+
"5000",
|
|
461
|
+
)
|
|
462
|
+
.addHelpText(
|
|
463
|
+
"after",
|
|
464
|
+
`
|
|
465
|
+
Modern transformer embeddings (Gemini in particular) are anisotropic — every
|
|
466
|
+
vector lives in a narrow cone of the embedding space, which compresses cosine
|
|
467
|
+
similarities into a tight band (typically 0.4-0.7) and lets a few dominant
|
|
468
|
+
directions drown out semantic signal.
|
|
469
|
+
|
|
470
|
+
This command samples stored dense vectors from the concept-page Qdrant
|
|
471
|
+
collection, fits a corpus mean + top-k principal components, and persists the
|
|
472
|
+
calibration. Subsequent embeds and queries apply the correction automatically:
|
|
473
|
+
|
|
474
|
+
vec' = vec - mean
|
|
475
|
+
for each pc_i: vec' = vec' - (vec' · pc_i) pc_i
|
|
476
|
+
vec' = vec' / ||vec'||
|
|
477
|
+
|
|
478
|
+
After fitting, run 'assistant memory v2 reembed' to re-process every stored
|
|
479
|
+
concept page through the new calibration. Until then, queries are corrected
|
|
480
|
+
but stored vectors are not — the score range stays the same and retrieval may
|
|
481
|
+
degrade. The calibration is keyed by (provider, model, dim), so changing
|
|
482
|
+
embedding model invalidates it.
|
|
483
|
+
|
|
484
|
+
Recommended k:
|
|
485
|
+
k=1 safest default. Removes the dominant common direction.
|
|
486
|
+
k=2-3 only when explained-variance ratios show PC2/PC3 each above ~5%.
|
|
487
|
+
k>3 not justified without a labeled retrieval eval set.
|
|
488
|
+
|
|
489
|
+
Examples:
|
|
490
|
+
$ assistant memory v2 fit-anisotropy
|
|
491
|
+
$ assistant memory v2 fit-anisotropy --k 2
|
|
492
|
+
$ assistant memory v2 fit-anisotropy --sample 10000`,
|
|
493
|
+
)
|
|
494
|
+
.action(async (opts: { k: string; sample: string }) => {
|
|
495
|
+
const k = Number.parseInt(opts.k, 10);
|
|
496
|
+
const sample = Number.parseInt(opts.sample, 10);
|
|
497
|
+
if (!Number.isFinite(k) || k < 1) {
|
|
498
|
+
log.error("--k must be a positive integer");
|
|
499
|
+
process.exitCode = 1;
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (!Number.isFinite(sample) || sample < 1) {
|
|
503
|
+
log.error("--sample must be a positive integer");
|
|
504
|
+
process.exitCode = 1;
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const result = await cliIpcCall<MemoryV2FitAnisotropyResult>(
|
|
509
|
+
"memory_v2_fit_anisotropy",
|
|
510
|
+
{ body: { k, sample } },
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
if (!result.ok) {
|
|
514
|
+
log.error(result.error ?? "Failed to fit anisotropy calibration");
|
|
515
|
+
process.exitCode = 1;
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const r = result.result!;
|
|
520
|
+
log.info(
|
|
521
|
+
`Fit anisotropy calibration: ${r.provider}/${r.model} (dim=${r.dim})`,
|
|
522
|
+
);
|
|
523
|
+
log.info(` samples: ${r.sampleCount}`);
|
|
524
|
+
log.info(` total variance: ${r.totalVariance.toFixed(6)}`);
|
|
525
|
+
log.info(" explained variance per component:");
|
|
526
|
+
for (let i = 0; i < r.componentVariance.length; i++) {
|
|
527
|
+
const ratio = (r.explainedVarianceRatio[i] * 100).toFixed(2);
|
|
528
|
+
log.info(
|
|
529
|
+
` PC${i + 1}: ${r.componentVariance[i].toFixed(6)} (${ratio}%)`,
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
log.info(` written to: ${r.path}`);
|
|
533
|
+
log.info("");
|
|
534
|
+
log.info(
|
|
535
|
+
"Next step: run 'assistant memory v2 reembed' so every stored concept page is re-written under the new calibration. Until then, query-side correction operates on stored vectors that were embedded without it.",
|
|
536
|
+
);
|
|
537
|
+
});
|
|
538
|
+
|
|
244
539
|
// ── validate ──────────────────────────────────────────────────────────
|
|
245
540
|
|
|
246
541
|
v2.command("validate")
|
|
@@ -88,13 +88,11 @@ mock.module("../../../../config/loader.js", () => ({
|
|
|
88
88
|
}),
|
|
89
89
|
loadConfig: () => ({}),
|
|
90
90
|
invalidateConfigCache: () => {},
|
|
91
|
-
saveConfig: () => {},
|
|
92
91
|
loadRawConfig: () => ({}),
|
|
93
92
|
saveRawConfig: () => {},
|
|
94
93
|
getNestedValue: () => undefined,
|
|
95
94
|
setNestedValue: () => {},
|
|
96
95
|
applyNestedDefaults: (config: unknown) => config,
|
|
97
|
-
deepMergeMissing: () => false,
|
|
98
96
|
deepMergeOverwrite: () => {},
|
|
99
97
|
mergeDefaultWorkspaceConfig: () => {},
|
|
100
98
|
}));
|
|
@@ -109,13 +109,11 @@ mock.module("../../../../config/loader.js", () => ({
|
|
|
109
109
|
}),
|
|
110
110
|
loadConfig: () => ({}),
|
|
111
111
|
invalidateConfigCache: () => {},
|
|
112
|
-
saveConfig: () => {},
|
|
113
112
|
loadRawConfig: () => ({}),
|
|
114
113
|
saveRawConfig: () => {},
|
|
115
114
|
getNestedValue: () => undefined,
|
|
116
115
|
setNestedValue: () => {},
|
|
117
116
|
applyNestedDefaults: (config: unknown) => config,
|
|
118
|
-
deepMergeMissing: () => false,
|
|
119
117
|
deepMergeOverwrite: () => {},
|
|
120
118
|
mergeDefaultWorkspaceConfig: () => {},
|
|
121
119
|
}));
|
|
@@ -75,6 +75,8 @@ mock.module("../../../../util/logger.js", () => ({
|
|
|
75
75
|
LOG_FILE_PATTERN: /^assistant-(\d{4}-\d{2}-\d{2})\.log$/,
|
|
76
76
|
}));
|
|
77
77
|
|
|
78
|
+
// Also mock the CLI logger singleton so log.info calls do not write to stdout.
|
|
79
|
+
|
|
78
80
|
mock.module("../../../../config/loader.js", () => ({
|
|
79
81
|
API_KEY_PROVIDERS: [] as const,
|
|
80
82
|
getConfig: () => ({
|
|
@@ -89,13 +91,11 @@ mock.module("../../../../config/loader.js", () => ({
|
|
|
89
91
|
}),
|
|
90
92
|
loadConfig: () => ({}),
|
|
91
93
|
invalidateConfigCache: () => {},
|
|
92
|
-
saveConfig: () => {},
|
|
93
94
|
loadRawConfig: () => ({}),
|
|
94
95
|
saveRawConfig: () => {},
|
|
95
96
|
getNestedValue: () => undefined,
|
|
96
97
|
setNestedValue: () => {},
|
|
97
98
|
applyNestedDefaults: (config: unknown) => config,
|
|
98
|
-
deepMergeMissing: () => false,
|
|
99
99
|
deepMergeOverwrite: () => {},
|
|
100
100
|
mergeDefaultWorkspaceConfig: () => {},
|
|
101
101
|
}));
|
|
@@ -166,14 +166,15 @@ describe("assistant platform status", () => {
|
|
|
166
166
|
process.exitCode = 0;
|
|
167
167
|
});
|
|
168
168
|
|
|
169
|
-
test("
|
|
169
|
+
test("platform pod returns full status from context", async () => {
|
|
170
170
|
/**
|
|
171
|
-
* When the assistant
|
|
172
|
-
*
|
|
173
|
-
*
|
|
171
|
+
* When the assistant is running as a platform-managed pod, the status
|
|
172
|
+
* command reports all fields from the registration context plus
|
|
173
|
+
* organizationId and userId from the keychain. The connected field
|
|
174
|
+
* is absent — platform status does not expose it.
|
|
174
175
|
*/
|
|
175
176
|
|
|
176
|
-
// GIVEN a containerized
|
|
177
|
+
// GIVEN a containerized platform environment
|
|
177
178
|
mockResolvePlatformCallbackRegistrationContext = async () => ({
|
|
178
179
|
isPlatform: true,
|
|
179
180
|
platformBaseUrl: "https://platform.vellum.ai",
|
|
@@ -184,12 +185,9 @@ describe("assistant platform status", () => {
|
|
|
184
185
|
enabled: true,
|
|
185
186
|
});
|
|
186
187
|
|
|
187
|
-
// AND stored
|
|
188
|
+
// AND credentials are stored in the keychain
|
|
188
189
|
mockGetSecureKeyAsync = async (account: string) => {
|
|
189
|
-
if (account === "credential/vellum/
|
|
190
|
-
return "https://platform.vellum.ai";
|
|
191
|
-
if (account === "credential/vellum/assistant_api_key")
|
|
192
|
-
return "sk-test-key";
|
|
190
|
+
if (account === "credential/vellum/webhook_secret") return "wh-secret";
|
|
193
191
|
if (account === "credential/vellum/platform_organization_id")
|
|
194
192
|
return "org-456";
|
|
195
193
|
if (account === "credential/vellum/platform_user_id") return "user-789";
|
|
@@ -213,8 +211,8 @@ describe("assistant platform status", () => {
|
|
|
213
211
|
expect(parsed.assistantId).toBe("asst-abc-123");
|
|
214
212
|
expect(parsed.hasInternalApiKey).toBe(true);
|
|
215
213
|
expect(parsed.hasAssistantApiKey).toBe(true);
|
|
214
|
+
expect(parsed.hasWebhookSecret).toBe(true);
|
|
216
215
|
expect(parsed.available).toBe(true);
|
|
217
|
-
expect(parsed.connected).toBe(true);
|
|
218
216
|
expect(parsed.organizationId).toBe("org-456");
|
|
219
217
|
expect(parsed.userId).toBe("user-789");
|
|
220
218
|
});
|
|
@@ -243,7 +241,7 @@ describe("assistant platform status", () => {
|
|
|
243
241
|
// THEN the command succeeds
|
|
244
242
|
expect(exitCode).toBe(0);
|
|
245
243
|
|
|
246
|
-
//
|
|
247
|
-
expect(stdout.trim()).
|
|
244
|
+
// Plain-text mode logs via log.info — verify writeOutput (JSON) was NOT called
|
|
245
|
+
expect(() => JSON.parse(stdout.trim())).toThrow();
|
|
248
246
|
});
|
|
249
247
|
});
|
|
@@ -95,17 +95,18 @@ Examples:
|
|
|
95
95
|
|
|
96
96
|
const failedKeys: string[] = [];
|
|
97
97
|
for (const key of keysToDelete) {
|
|
98
|
-
const
|
|
98
|
+
const delResult = await deleteSecureKeyViaDaemon(
|
|
99
99
|
"credential",
|
|
100
100
|
`${key.service}:${key.field}`,
|
|
101
101
|
);
|
|
102
|
-
if (result === "error") {
|
|
103
|
-
|
|
102
|
+
if (delResult.result === "error") {
|
|
103
|
+
const detail = delResult.error ? `: ${delResult.error}` : "";
|
|
104
|
+
failedKeys.push(`${key.service}:${key.field}${detail}`);
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
if (failedKeys.length > 0) {
|
|
108
|
-
writeError(`Failed to delete credentials: ${failedKeys.join("
|
|
109
|
+
writeError(`Failed to delete credentials: ${failedKeys.join("; ")}`);
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
112
|
|
|
@@ -68,7 +68,6 @@ Fields:
|
|
|
68
68
|
hasWebhookSecret Whether a stored webhook secret is available (needed
|
|
69
69
|
for email and other inbound webhook channels)
|
|
70
70
|
available Whether callback registration prerequisites are satisfied
|
|
71
|
-
connected Whether platform credentials are stored (boolean)
|
|
72
71
|
organizationId The platform organization ID (from stored credentials)
|
|
73
72
|
userId The platform user ID (from stored credentials)
|
|
74
73
|
|
|
@@ -80,19 +79,6 @@ Examples:
|
|
|
80
79
|
try {
|
|
81
80
|
const context = await resolvePlatformCallbackRegistrationContext();
|
|
82
81
|
|
|
83
|
-
const storedBaseUrl =
|
|
84
|
-
(await getSecureKeyAsync(
|
|
85
|
-
credentialKey(
|
|
86
|
-
CREDENTIAL_KEYS.baseUrl.service,
|
|
87
|
-
CREDENTIAL_KEYS.baseUrl.field,
|
|
88
|
-
),
|
|
89
|
-
)) ?? "";
|
|
90
|
-
const hasStoredApiKey = !!(await getSecureKeyAsync(
|
|
91
|
-
credentialKey(
|
|
92
|
-
CREDENTIAL_KEYS.apiKey.service,
|
|
93
|
-
CREDENTIAL_KEYS.apiKey.field,
|
|
94
|
-
),
|
|
95
|
-
));
|
|
96
82
|
const organizationId =
|
|
97
83
|
(
|
|
98
84
|
await getSecureKeyAsync(
|
|
@@ -116,8 +102,6 @@ Examples:
|
|
|
116
102
|
credentialKey("vellum", "webhook_secret"),
|
|
117
103
|
));
|
|
118
104
|
|
|
119
|
-
const connected = !!storedBaseUrl && hasStoredApiKey;
|
|
120
|
-
|
|
121
105
|
const result = {
|
|
122
106
|
isPlatform: context.isPlatform,
|
|
123
107
|
baseUrl: context.platformBaseUrl,
|
|
@@ -126,7 +110,6 @@ Examples:
|
|
|
126
110
|
hasAssistantApiKey: context.hasAssistantApiKey,
|
|
127
111
|
hasWebhookSecret,
|
|
128
112
|
available: context.enabled,
|
|
129
|
-
connected,
|
|
130
113
|
organizationId: organizationId || null,
|
|
131
114
|
userId: userId || null,
|
|
132
115
|
};
|
|
@@ -149,7 +132,6 @@ Examples:
|
|
|
149
132
|
log.info(
|
|
150
133
|
`Callback registration available: ${result.available ? "yes" : "no"}`,
|
|
151
134
|
);
|
|
152
|
-
log.info(`Connected: ${connected}`);
|
|
153
135
|
log.info(`Organization ID: ${organizationId || "(not set)"}`);
|
|
154
136
|
log.info(`User ID: ${userId || "(not set)"}`);
|
|
155
137
|
}
|