@vellumai/assistant 0.7.2 → 0.8.0
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 +45 -29
- package/Dockerfile +1 -0
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docs/architecture/memory.md +5 -2
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/openapi.yaml +470 -25
- package/package.json +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/app-control-flow.test.ts +21 -11
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/assistant-event.test.ts +0 -10
- package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
- package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +4 -2
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
- package/src/__tests__/config-loader-backfill.test.ts +379 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
- package/src/__tests__/config-watcher.test.ts +140 -69
- 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 +6 -33
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +12 -7
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +457 -8
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-process-callsite.test.ts +38 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -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 +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/credentials-cli.test.ts +7 -0
- package/src/__tests__/cu-unified-flow.test.ts +176 -10
- package/src/__tests__/date-context.test.ts +164 -2
- 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__/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 +2 -20
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +260 -11
- package/src/__tests__/host-app-control-proxy.test.ts +195 -25
- package/src/__tests__/host-bash-proxy.test.ts +227 -34
- package/src/__tests__/host-bash-routes.test.ts +178 -13
- package/src/__tests__/host-cu-proxy.test.ts +210 -3
- package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
- package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
- package/src/__tests__/host-file-proxy.test.ts +268 -6
- package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
- package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
- package/src/__tests__/http-user-message-parity.test.ts +107 -1
- package/src/__tests__/injector-chain.test.ts +36 -16
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/oauth-cli.test.ts +121 -0
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- 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__/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 -27
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/relay-server.test.ts +60 -5
- package/src/__tests__/runtime-events-sse.test.ts +4 -8
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-tool.test.ts +44 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/twilio-validation.test.ts +2 -2
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- 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-069-seed-onboarding-threads.test.ts +120 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-request-resolvers.ts +3 -32
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +7 -1
- package/src/calls/voice-session-bridge.ts +1 -1
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/contacts.ts +64 -25
- package/src/cli/commands/credentials.ts +56 -0
- package/src/cli/commands/memory-v2.ts +11 -10
- package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
- package/src/cli/commands/oauth/connect.ts +124 -40
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
- package/src/cli/commands/platform/index.ts +16 -7
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/program.ts +4 -2
- package/src/config/assistant-feature-flags.ts +13 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
- 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/env.ts +0 -8
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +199 -27
- package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +13 -0
- package/src/config/schemas/memory-v2.ts +76 -12
- package/src/config/schemas/platform.ts +43 -3
- package/src/config/schemas/services.ts +28 -0
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -25
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/config-watcher.ts +85 -57
- package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
- package/src/daemon/conversation-agent-loop.ts +183 -43
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +22 -10
- package/src/daemon/conversation-process.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +26 -0
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +211 -29
- package/src/daemon/conversation-tool-setup.ts +66 -19
- package/src/daemon/conversation.ts +18 -23
- 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/handlers/shared.ts +26 -1
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +137 -41
- package/src/daemon/host-bash-proxy.ts +47 -22
- package/src/daemon/host-browser-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +50 -4
- package/src/daemon/host-file-proxy.ts +44 -8
- package/src/daemon/host-transfer-proxy.ts +97 -6
- package/src/daemon/lifecycle.ts +167 -101
- 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 +66 -15
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +4 -0
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/messages.ts +22 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/tool-setup-types.ts +2 -2
- package/src/documents/document-store.ts +119 -0
- package/src/filing/filing-service.ts +29 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
- package/src/heartbeat/heartbeat-run-store.ts +13 -0
- package/src/heartbeat/heartbeat-service.ts +205 -31
- package/src/home/feed-scheduler.ts +18 -0
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/assistant-server.ts +149 -38
- package/src/ipc/gateway-client.ts +37 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/protocol.ts +5 -7
- 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-worker-v2-schedule.test.ts +34 -51
- 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/admin.ts +5 -9
- package/src/memory/context-search/agent-runner.ts +19 -2
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +1 -16
- package/src/memory/context-search/sources/memory.ts +2 -3
- package/src/memory/context-search/sources/pkb.ts +2 -3
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +4 -12
- package/src/memory/db-init.ts +2 -0
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/conversation-graph-memory.ts +72 -61
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +11 -67
- package/src/memory/graph/graph-search.ts +4 -24
- package/src/memory/graph/retriever.test.ts +12 -1
- package/src/memory/graph/retriever.ts +10 -15
- package/src/memory/graph/tool-handlers.ts +3 -4
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/indexer.ts +53 -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 +116 -0
- package/src/memory/jobs/embed-concept-page.ts +223 -87
- package/src/memory/jobs-store.ts +48 -0
- package/src/memory/jobs-worker.ts +85 -43
- package/src/memory/memory-v2-activation-log-store.ts +32 -14
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +7 -0
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/qdrant-client.ts +3 -13
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/search/semantic.ts +10 -72
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +346 -255
- package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
- package/src/memory/v2/__tests__/injection.test.ts +297 -190
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +113 -196
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/static-context.test.ts +77 -14
- package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
- package/src/memory/v2/activation.ts +149 -156
- package/src/memory/v2/consolidation-job.ts +69 -20
- package/src/memory/v2/injection.ts +75 -68
- package/src/memory/v2/page-store.ts +39 -0
- package/src/memory/v2/prompts/consolidation.ts +41 -1
- package/src/memory/v2/qdrant.ts +306 -46
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +77 -110
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +82 -59
- package/src/memory/v2/static-context.ts +26 -8
- package/src/memory/v2/sweep-job.ts +5 -6
- package/src/memory/v2/types.ts +17 -10
- package/src/notifications/copy-composer.ts +47 -0
- package/src/notifications/decision-engine.ts +46 -0
- 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 +2 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugins/defaults/injectors.ts +36 -4
- 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 +914 -0
- package/src/proactive-artifact/job.ts +366 -0
- package/src/proactive-artifact/message-copy.ts +58 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +21 -7
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -28
- 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/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 +36 -6
- package/src/runtime/assistant-event.ts +0 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/route-policy.ts +15 -1
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/pending-interactions.ts +27 -15
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/approval-routes.ts +7 -3
- package/src/runtime/routes/client-routes.ts +20 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +44 -1
- package/src/runtime/routes/conversation-routes.ts +35 -26
- package/src/runtime/routes/debug-bash-routes.ts +165 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +6 -2
- package/src/runtime/routes/documents-routes.ts +2 -75
- package/src/runtime/routes/events-routes.ts +41 -9
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/host-bash-routes.ts +23 -3
- package/src/runtime/routes/host-cu-routes.ts +33 -6
- package/src/runtime/routes/host-file-routes.ts +32 -6
- package/src/runtime/routes/host-transfer-routes.ts +79 -16
- package/src/runtime/routes/identity-routes.ts +7 -138
- package/src/runtime/routes/inbound-message-handler.ts +77 -12
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/memory-item-routes.test.ts +37 -17
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +136 -17
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/scheduler.ts +20 -1
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/skills/include-graph.ts +35 -13
- package/src/skills/remote-skill-policy.ts +4 -10
- 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/tools/background-tool-registry.ts +17 -3
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +43 -1
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +43 -1
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +56 -11
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +43 -1
- package/src/tools/host-terminal/host-shell.ts +13 -6
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +14 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/permission-checker.ts +15 -0
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +31 -6
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +43 -3
- package/src/tts/provider-catalog.ts +3 -5
- 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/heartbeat-service.ts +19 -0
- 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 +14 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/registry.ts +14 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -404
- package/src/signals/bash.ts +0 -198
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
const MIB = 1024 * 1024;
|
|
4
|
+
const GIB = 1024 * MIB;
|
|
5
|
+
|
|
6
|
+
let existingPaths = new Set<string>();
|
|
7
|
+
const workspaceDir = "/workspace";
|
|
8
|
+
let minikubeStorageSize: string | undefined;
|
|
9
|
+
let statfsResult = {
|
|
10
|
+
bsize: 4096,
|
|
11
|
+
blocks: 0,
|
|
12
|
+
bavail: 0,
|
|
13
|
+
};
|
|
14
|
+
let spawnResult: {
|
|
15
|
+
status: number | null;
|
|
16
|
+
stdout: string;
|
|
17
|
+
} = {
|
|
18
|
+
status: 0,
|
|
19
|
+
stdout: "",
|
|
20
|
+
};
|
|
21
|
+
let spawnCalls: Array<{ command: string; args: string[] }> = [];
|
|
22
|
+
|
|
23
|
+
mock.module("node:fs", () => ({
|
|
24
|
+
existsSync: (path: string) => existingPaths.has(path),
|
|
25
|
+
statfsSync: () => statfsResult,
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
mock.module("node:child_process", () => ({
|
|
29
|
+
spawnSync: (command: string, args: string[]) => {
|
|
30
|
+
spawnCalls.push({ command, args });
|
|
31
|
+
return spawnResult;
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
mock.module("../config/env-registry.js", () => ({
|
|
36
|
+
getMinikubeStorageSize: () => minikubeStorageSize,
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
mock.module("../util/platform.js", () => ({
|
|
40
|
+
getWorkspaceDir: () => workspaceDir,
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const { __resetDiskUsageCacheForTests, getDiskUsageInfo, parseK8sMemoryBytes } =
|
|
44
|
+
await import("../util/disk-usage.js");
|
|
45
|
+
|
|
46
|
+
function statfsFor(totalBytes: number, freeBytes: number) {
|
|
47
|
+
return {
|
|
48
|
+
bsize: MIB,
|
|
49
|
+
blocks: totalBytes / MIB,
|
|
50
|
+
bavail: freeBytes / MIB,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
describe("disk usage sampler", () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
existingPaths = new Set([workspaceDir]);
|
|
57
|
+
minikubeStorageSize = undefined;
|
|
58
|
+
statfsResult = statfsFor(100 * MIB, 25 * MIB);
|
|
59
|
+
spawnResult = { status: 0, stdout: "" };
|
|
60
|
+
spawnCalls = [];
|
|
61
|
+
__resetDiskUsageCacheForTests();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("reports regular statfs usage", () => {
|
|
65
|
+
const usage = getDiskUsageInfo();
|
|
66
|
+
|
|
67
|
+
expect(usage).toEqual({
|
|
68
|
+
path: "/workspace",
|
|
69
|
+
totalMb: 100,
|
|
70
|
+
usedMb: 75,
|
|
71
|
+
freeMb: 25,
|
|
72
|
+
});
|
|
73
|
+
expect(spawnCalls).toHaveLength(0);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("falls back to root when the workspace path does not exist", () => {
|
|
77
|
+
existingPaths = new Set();
|
|
78
|
+
|
|
79
|
+
const usage = getDiskUsageInfo();
|
|
80
|
+
|
|
81
|
+
expect(usage?.path).toBe("/");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("uses PVC capacity and du usage when host filesystem is larger", () => {
|
|
85
|
+
minikubeStorageSize = "1Gi";
|
|
86
|
+
statfsResult = statfsFor(10 * GIB, 8 * GIB);
|
|
87
|
+
spawnResult = {
|
|
88
|
+
status: 0,
|
|
89
|
+
stdout: `${100 * MIB}\t/workspace\n`,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const usage = getDiskUsageInfo();
|
|
93
|
+
|
|
94
|
+
expect(usage).toEqual({
|
|
95
|
+
path: "/workspace",
|
|
96
|
+
totalMb: 1024,
|
|
97
|
+
usedMb: 100,
|
|
98
|
+
freeMb: 924,
|
|
99
|
+
});
|
|
100
|
+
expect(spawnCalls).toEqual([
|
|
101
|
+
{ command: "du", args: ["-sb", "/workspace"] },
|
|
102
|
+
]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("includes /data in PVC du usage when it exists separately", () => {
|
|
106
|
+
existingPaths = new Set([workspaceDir, "/data"]);
|
|
107
|
+
minikubeStorageSize = "1Gi";
|
|
108
|
+
statfsResult = statfsFor(10 * GIB, 8 * GIB);
|
|
109
|
+
spawnResult = {
|
|
110
|
+
status: 0,
|
|
111
|
+
stdout: `${100 * MIB}\t/workspace\n${20 * MIB}\t/data\n`,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const usage = getDiskUsageInfo();
|
|
115
|
+
|
|
116
|
+
expect(usage?.usedMb).toBe(120);
|
|
117
|
+
expect(spawnCalls).toEqual([
|
|
118
|
+
{ command: "du", args: ["-sb", "/workspace", "/data"] },
|
|
119
|
+
]);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("returns null for malformed Kubernetes memory strings", () => {
|
|
123
|
+
expect(parseK8sMemoryBytes("")).toBeNull();
|
|
124
|
+
expect(parseK8sMemoryBytes("abc")).toBeNull();
|
|
125
|
+
expect(parseK8sMemoryBytes("12Zi")).toBeNull();
|
|
126
|
+
expect(parseK8sMemoryBytes("-1Gi")).toBeNull();
|
|
127
|
+
expect(parseK8sMemoryBytes("0Gi")).toBeNull();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("falls back to statfs when du fails in PVC mode", () => {
|
|
131
|
+
minikubeStorageSize = "1Gi";
|
|
132
|
+
statfsResult = statfsFor(10 * GIB, 8 * GIB);
|
|
133
|
+
spawnResult = {
|
|
134
|
+
status: 1,
|
|
135
|
+
stdout: "",
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const usage = getDiskUsageInfo();
|
|
139
|
+
|
|
140
|
+
expect(usage).toEqual({
|
|
141
|
+
path: "/workspace",
|
|
142
|
+
totalMb: 10240,
|
|
143
|
+
usedMb: 2048,
|
|
144
|
+
freeMb: 8192,
|
|
145
|
+
});
|
|
146
|
+
expect(spawnCalls).toEqual([
|
|
147
|
+
{ command: "du", args: ["-sb", "/workspace"] },
|
|
148
|
+
]);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -395,6 +395,58 @@ describe("events client registration", () => {
|
|
|
395
395
|
ac2.abort();
|
|
396
396
|
});
|
|
397
397
|
|
|
398
|
+
// ── actorPrincipalId capture ──────────────────────────────────────────────
|
|
399
|
+
|
|
400
|
+
test("captures actorPrincipalId from x-vellum-actor-principal-id header", () => {
|
|
401
|
+
const ac = new AbortController();
|
|
402
|
+
const hub = new AssistantEventHub();
|
|
403
|
+
|
|
404
|
+
handleSubscribeAssistantEvents(
|
|
405
|
+
{
|
|
406
|
+
headers: {
|
|
407
|
+
"x-vellum-client-id": "principal-client-001",
|
|
408
|
+
"x-vellum-interface-id": "macos",
|
|
409
|
+
"x-vellum-actor-principal-id": "user-A",
|
|
410
|
+
},
|
|
411
|
+
abortSignal: ac.signal,
|
|
412
|
+
},
|
|
413
|
+
{ hub },
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
const entry = hub.getClientById("principal-client-001");
|
|
417
|
+
expect(entry?.actorPrincipalId).toBe("user-A");
|
|
418
|
+
expect(hub.getActorPrincipalIdForClient("principal-client-001")).toBe(
|
|
419
|
+
"user-A",
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
ac.abort();
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test("registers client with undefined actorPrincipalId when header is absent", () => {
|
|
426
|
+
const ac = new AbortController();
|
|
427
|
+
const hub = new AssistantEventHub();
|
|
428
|
+
|
|
429
|
+
handleSubscribeAssistantEvents(
|
|
430
|
+
{
|
|
431
|
+
headers: {
|
|
432
|
+
"x-vellum-client-id": "principal-client-002",
|
|
433
|
+
"x-vellum-interface-id": "macos",
|
|
434
|
+
},
|
|
435
|
+
abortSignal: ac.signal,
|
|
436
|
+
},
|
|
437
|
+
{ hub },
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
const entry = hub.getClientById("principal-client-002");
|
|
441
|
+
expect(entry).toBeDefined();
|
|
442
|
+
expect(entry?.actorPrincipalId).toBeUndefined();
|
|
443
|
+
expect(
|
|
444
|
+
hub.getActorPrincipalIdForClient("principal-client-002"),
|
|
445
|
+
).toBeUndefined();
|
|
446
|
+
|
|
447
|
+
ac.abort();
|
|
448
|
+
});
|
|
449
|
+
|
|
398
450
|
// ── disposeClient (force disconnect) ──────────────────────────────────────
|
|
399
451
|
|
|
400
452
|
test("disposeClient removes all subscribers for the clientId", () => {
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for the SSE registration dev-bypass actor principal
|
|
3
|
+
* translation.
|
|
4
|
+
*
|
|
5
|
+
* In `DISABLE_HTTP_AUTH=true` (platform-managed) deployments the synthetic
|
|
6
|
+
* dev-bypass `AuthContext` injects `actorPrincipalId="dev-bypass"` for every
|
|
7
|
+
* request. Tool-side trust resolution still resolves to the real local
|
|
8
|
+
* guardian's principalId via `resolveLocalTrustContext`. Without translation,
|
|
9
|
+
* `ClientEntry.actorPrincipalId === "dev-bypass"` and
|
|
10
|
+
* `ToolContext.sourceActorPrincipalId === "<real-guardian>"` mismatch, so the
|
|
11
|
+
* same-user check in HostBashProxy / HostFileProxy / HostCuProxy /
|
|
12
|
+
* conversation-surfaces rejects every targeted host proxy invocation and the
|
|
13
|
+
* auto-resolve path silently falls through to untargeted broadcast.
|
|
14
|
+
*
|
|
15
|
+
* The events-routes handler translates `"dev-bypass"` to the real guardian's
|
|
16
|
+
* principalId at registration time so both sides agree. This keeps targeted
|
|
17
|
+
* host proxy execution working on Docker / platform-managed deployments.
|
|
18
|
+
*/
|
|
19
|
+
import { afterAll, describe, expect, mock, test } from "bun:test";
|
|
20
|
+
|
|
21
|
+
// ── Module mocks (must be set up before importing the route) ──────────────
|
|
22
|
+
|
|
23
|
+
let fakeHttpAuthDisabled = false;
|
|
24
|
+
let fakeGuardianPrincipalId: string | undefined = undefined;
|
|
25
|
+
|
|
26
|
+
mock.module("../config/env.js", () => ({
|
|
27
|
+
isHttpAuthDisabled: () => fakeHttpAuthDisabled,
|
|
28
|
+
hasUngatedHttpAuthDisabled: () => false,
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
mock.module("../runtime/local-actor-identity.js", () => ({
|
|
32
|
+
findLocalGuardianPrincipalId: () => fakeGuardianPrincipalId,
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
mock.module("../util/logger.js", () => ({
|
|
36
|
+
getLogger: () =>
|
|
37
|
+
new Proxy({} as Record<string, unknown>, {
|
|
38
|
+
get: () => () => {},
|
|
39
|
+
}),
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
// ── Real imports (after mocks) ────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
import { AssistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
45
|
+
import { handleSubscribeAssistantEvents } from "../runtime/routes/events-routes.js";
|
|
46
|
+
|
|
47
|
+
afterAll(() => {
|
|
48
|
+
mock.restore();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("events SSE registration — dev-bypass actor translation", () => {
|
|
52
|
+
test("translates 'dev-bypass' to the real guardian principalId when auth is disabled", () => {
|
|
53
|
+
fakeHttpAuthDisabled = true;
|
|
54
|
+
fakeGuardianPrincipalId = "guardian-real-id";
|
|
55
|
+
|
|
56
|
+
const ac = new AbortController();
|
|
57
|
+
const hub = new AssistantEventHub();
|
|
58
|
+
|
|
59
|
+
handleSubscribeAssistantEvents(
|
|
60
|
+
{
|
|
61
|
+
headers: {
|
|
62
|
+
"x-vellum-client-id": "devbypass-client-001",
|
|
63
|
+
"x-vellum-interface-id": "macos",
|
|
64
|
+
"x-vellum-actor-principal-id": "dev-bypass",
|
|
65
|
+
},
|
|
66
|
+
abortSignal: ac.signal,
|
|
67
|
+
},
|
|
68
|
+
{ hub },
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const entry = hub.getClientById("devbypass-client-001");
|
|
72
|
+
expect(entry?.actorPrincipalId).toBe("guardian-real-id");
|
|
73
|
+
expect(hub.getActorPrincipalIdForClient("devbypass-client-001")).toBe(
|
|
74
|
+
"guardian-real-id",
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
ac.abort();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("registers without principalId when dev-bypass is set but no guardian is bound", () => {
|
|
81
|
+
fakeHttpAuthDisabled = true;
|
|
82
|
+
fakeGuardianPrincipalId = undefined;
|
|
83
|
+
|
|
84
|
+
const ac = new AbortController();
|
|
85
|
+
const hub = new AssistantEventHub();
|
|
86
|
+
|
|
87
|
+
handleSubscribeAssistantEvents(
|
|
88
|
+
{
|
|
89
|
+
headers: {
|
|
90
|
+
"x-vellum-client-id": "devbypass-client-002",
|
|
91
|
+
"x-vellum-interface-id": "macos",
|
|
92
|
+
"x-vellum-actor-principal-id": "dev-bypass",
|
|
93
|
+
},
|
|
94
|
+
abortSignal: ac.signal,
|
|
95
|
+
},
|
|
96
|
+
{ hub },
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const entry = hub.getClientById("devbypass-client-002");
|
|
100
|
+
expect(entry).toBeDefined();
|
|
101
|
+
expect(entry?.actorPrincipalId).toBeUndefined();
|
|
102
|
+
|
|
103
|
+
ac.abort();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("does NOT translate when auth is enabled (production mode)", () => {
|
|
107
|
+
// Defense in depth: make sure we never silently rewrite a real
|
|
108
|
+
// principalId that legitimately happens to be the literal "dev-bypass"
|
|
109
|
+
// string in a non-dev-bypass deployment. The translation is gated on
|
|
110
|
+
// isHttpAuthDisabled() === true.
|
|
111
|
+
fakeHttpAuthDisabled = false;
|
|
112
|
+
fakeGuardianPrincipalId = "guardian-real-id";
|
|
113
|
+
|
|
114
|
+
const ac = new AbortController();
|
|
115
|
+
const hub = new AssistantEventHub();
|
|
116
|
+
|
|
117
|
+
handleSubscribeAssistantEvents(
|
|
118
|
+
{
|
|
119
|
+
headers: {
|
|
120
|
+
"x-vellum-client-id": "prod-client-003",
|
|
121
|
+
"x-vellum-interface-id": "macos",
|
|
122
|
+
"x-vellum-actor-principal-id": "dev-bypass",
|
|
123
|
+
},
|
|
124
|
+
abortSignal: ac.signal,
|
|
125
|
+
},
|
|
126
|
+
{ hub },
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const entry = hub.getClientById("prod-client-003");
|
|
130
|
+
expect(entry?.actorPrincipalId).toBe("dev-bypass");
|
|
131
|
+
|
|
132
|
+
ac.abort();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("passes through non-dev-bypass principalId verbatim in dev-bypass mode", () => {
|
|
136
|
+
// Edge case: a service-token connection that happens to be made while
|
|
137
|
+
// the daemon runs in DISABLE_HTTP_AUTH=true mode should still register
|
|
138
|
+
// with its own principalId, not the guardian's.
|
|
139
|
+
fakeHttpAuthDisabled = true;
|
|
140
|
+
fakeGuardianPrincipalId = "guardian-real-id";
|
|
141
|
+
|
|
142
|
+
const ac = new AbortController();
|
|
143
|
+
const hub = new AssistantEventHub();
|
|
144
|
+
|
|
145
|
+
handleSubscribeAssistantEvents(
|
|
146
|
+
{
|
|
147
|
+
headers: {
|
|
148
|
+
"x-vellum-client-id": "service-client-004",
|
|
149
|
+
"x-vellum-interface-id": "macos",
|
|
150
|
+
"x-vellum-actor-principal-id": "service-account-A",
|
|
151
|
+
},
|
|
152
|
+
abortSignal: ac.signal,
|
|
153
|
+
},
|
|
154
|
+
{ hub },
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const entry = hub.getClientById("service-client-004");
|
|
158
|
+
expect(entry?.actorPrincipalId).toBe("service-account-A");
|
|
159
|
+
|
|
160
|
+
ac.abort();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
@@ -197,26 +197,20 @@ describe("file_write tool PKB re-index hook", () => {
|
|
|
197
197
|
});
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
-
test("always uses PKB_WORKSPACE_SCOPE
|
|
200
|
+
test("always uses PKB_WORKSPACE_SCOPE", async () => {
|
|
201
201
|
const workingDir = makeTempDir();
|
|
202
202
|
setWorkspaceDir(workingDir);
|
|
203
203
|
mkdirSync(join(workingDir, "pkb"), { recursive: true });
|
|
204
204
|
|
|
205
|
-
const ctx: ToolContext = {
|
|
206
|
-
...makeContext(workingDir),
|
|
207
|
-
memoryScopeId: "subagent:abc123",
|
|
208
|
-
};
|
|
209
|
-
|
|
210
205
|
const result = await fileWriteTool.execute(
|
|
211
206
|
{ path: "pkb/private.md", content: "secret\n" },
|
|
212
|
-
|
|
207
|
+
makeContext(workingDir),
|
|
213
208
|
);
|
|
214
209
|
|
|
215
210
|
expect(result.isError).toBe(false);
|
|
216
211
|
expect(enqueueCalls).toHaveLength(1);
|
|
217
|
-
// PKB files are workspace-level —
|
|
218
|
-
//
|
|
219
|
-
// other's Qdrant points via target_id upsert deduplication.
|
|
212
|
+
// PKB files are workspace-level — points are keyed by PKB_WORKSPACE_SCOPE
|
|
213
|
+
// so all conversations share one PKB index.
|
|
220
214
|
expect(enqueueCalls[0]?.memoryScopeId).toBe(PKB_WORKSPACE_SCOPE);
|
|
221
215
|
});
|
|
222
216
|
|
|
@@ -34,9 +34,6 @@ mock.module("../config/loader.js", () => ({
|
|
|
34
34
|
invalidateConfigCache: () => {},
|
|
35
35
|
}));
|
|
36
36
|
|
|
37
|
-
const { _setOverridesForTesting } =
|
|
38
|
-
await import("../config/assistant-feature-flags.js");
|
|
39
|
-
|
|
40
37
|
// Mock conversation store
|
|
41
38
|
const createdConversations: Array<{ title: string; conversationType: string }> =
|
|
42
39
|
[];
|
|
@@ -128,7 +125,6 @@ describe("FilingService", () => {
|
|
|
128
125
|
} catch {
|
|
129
126
|
// best-effort
|
|
130
127
|
}
|
|
131
|
-
_setOverridesForTesting({});
|
|
132
128
|
});
|
|
133
129
|
|
|
134
130
|
beforeEach(() => {
|
|
@@ -331,8 +327,7 @@ describe("FilingService", () => {
|
|
|
331
327
|
});
|
|
332
328
|
|
|
333
329
|
describe("memory v2 gate", () => {
|
|
334
|
-
test("start() does not schedule timers when v2
|
|
335
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
330
|
+
test("start() does not schedule timers when memory.v2.enabled is true", () => {
|
|
336
331
|
mockConfig.memory.v2.enabled = true;
|
|
337
332
|
|
|
338
333
|
const service = createService();
|
|
@@ -342,8 +337,7 @@ describe("FilingService", () => {
|
|
|
342
337
|
expect(service.nextCompactionAt).toBeNull();
|
|
343
338
|
});
|
|
344
339
|
|
|
345
|
-
test("start() schedules timers when
|
|
346
|
-
_setOverridesForTesting({ "memory-v2-enabled": true });
|
|
340
|
+
test("start() schedules timers when memory.v2.enabled is false (v1 filing runs)", () => {
|
|
347
341
|
mockConfig.memory.v2.enabled = false;
|
|
348
342
|
|
|
349
343
|
const service = createService();
|
|
@@ -353,18 +347,6 @@ describe("FilingService", () => {
|
|
|
353
347
|
expect(service.nextCompactionAt).not.toBeNull();
|
|
354
348
|
service.stop();
|
|
355
349
|
});
|
|
356
|
-
|
|
357
|
-
test("start() schedules timers when only the config is on", () => {
|
|
358
|
-
_setOverridesForTesting({ "memory-v2-enabled": false });
|
|
359
|
-
mockConfig.memory.v2.enabled = true;
|
|
360
|
-
|
|
361
|
-
const service = createService();
|
|
362
|
-
service.start();
|
|
363
|
-
|
|
364
|
-
expect(service.nextRunAt).not.toBeNull();
|
|
365
|
-
expect(service.nextCompactionAt).not.toBeNull();
|
|
366
|
-
service.stop();
|
|
367
|
-
});
|
|
368
350
|
});
|
|
369
351
|
|
|
370
352
|
describe("llm.callSites.filingAgent resolution", () => {
|
|
@@ -5,17 +5,16 @@
|
|
|
5
5
|
* One representative call site (the `installSkill` bundled branch) is
|
|
6
6
|
* exercised — all 5 sites share the same delegation to
|
|
7
7
|
* `maybeSeedMemoryV2Skills`, so a single suite covers behavior. Validates:
|
|
8
|
-
* -
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* - config.memory.v2.enabled off → helper still invoked, seed short-circuits
|
|
8
|
+
* - config on → helper invoked after seedSkillGraphNodes and the seed
|
|
9
|
+
* observed (callOrder picks up "v2")
|
|
10
|
+
* - config off → helper still invoked, but the seed short-circuits
|
|
12
11
|
*
|
|
13
12
|
* The handler delegates to `maybeSeedMemoryV2Skills` from
|
|
14
13
|
* `daemon/memory-v2-startup.ts`. We mock that module directly so the test
|
|
15
14
|
* does not have to drain the dynamic-import microtask chain. The helper's
|
|
16
|
-
* gate semantics
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* gate semantics are covered by `lifecycle-memory-v2-seed.test.ts`; here
|
|
16
|
+
* we only verify that the handler invokes the helper synchronously with
|
|
17
|
+
* the live config.
|
|
19
18
|
*/
|
|
20
19
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
21
20
|
|
|
@@ -23,7 +22,7 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
23
22
|
// Programmable test state
|
|
24
23
|
// ---------------------------------------------------------------------------
|
|
25
24
|
|
|
26
|
-
const flagsState = {
|
|
25
|
+
const flagsState = { configV2Enabled: true };
|
|
27
26
|
|
|
28
27
|
const callOrder: string[] = [];
|
|
29
28
|
|
|
@@ -55,10 +54,7 @@ mock.module("../config/skills.js", () => ({
|
|
|
55
54
|
}));
|
|
56
55
|
|
|
57
56
|
mock.module("../config/assistant-feature-flags.js", () => ({
|
|
58
|
-
isAssistantFeatureFlagEnabled: (
|
|
59
|
-
if (key === "memory-v2-enabled") return flagsState.flagEnabled;
|
|
60
|
-
return true;
|
|
61
|
-
},
|
|
57
|
+
isAssistantFeatureFlagEnabled: () => true,
|
|
62
58
|
}));
|
|
63
59
|
|
|
64
60
|
// Stub both `getConfig` and `loadConfig`. `loadConfig` is reached by code
|
|
@@ -220,18 +216,17 @@ const { installSkill } = await import("../daemon/handlers/skills.js");
|
|
|
220
216
|
|
|
221
217
|
describe("v2 skill re-seed gating in skill handlers", () => {
|
|
222
218
|
beforeEach(() => {
|
|
223
|
-
flagsState.flagEnabled = true;
|
|
224
219
|
flagsState.configV2Enabled = true;
|
|
225
220
|
callOrder.length = 0;
|
|
226
221
|
mockSeedSkillGraphNodes.mockClear();
|
|
227
222
|
mockMaybeSeedMemoryV2Skills.mockClear();
|
|
228
223
|
mockMaybeSeedMemoryV2Skills.mockImplementation((config) => {
|
|
229
|
-
if (!
|
|
224
|
+
if (!config.memory.v2.enabled) return;
|
|
230
225
|
callOrder.push("v2");
|
|
231
226
|
});
|
|
232
227
|
});
|
|
233
228
|
|
|
234
|
-
test("
|
|
229
|
+
test("config on → maybeSeedMemoryV2Skills invoked after seedSkillGraphNodes", async () => {
|
|
235
230
|
const result = await installSkill({ slug: "bundled-skill" });
|
|
236
231
|
|
|
237
232
|
expect(result.success).toBe(true);
|
|
@@ -240,17 +235,6 @@ describe("v2 skill re-seed gating in skill handlers", () => {
|
|
|
240
235
|
expect(callOrder).toEqual(["v1", "v2"]);
|
|
241
236
|
});
|
|
242
237
|
|
|
243
|
-
test("flag off → seed mock observes the disabled flag and skips", async () => {
|
|
244
|
-
flagsState.flagEnabled = false;
|
|
245
|
-
|
|
246
|
-
const result = await installSkill({ slug: "bundled-skill" });
|
|
247
|
-
|
|
248
|
-
expect(result.success).toBe(true);
|
|
249
|
-
expect(mockSeedSkillGraphNodes).toHaveBeenCalledTimes(1);
|
|
250
|
-
expect(mockMaybeSeedMemoryV2Skills).toHaveBeenCalledTimes(1);
|
|
251
|
-
expect(callOrder).toEqual(["v1"]);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
238
|
test("config.memory.v2.enabled off → seed mock observes config and skips", async () => {
|
|
255
239
|
flagsState.configV2Enabled = false;
|
|
256
240
|
|