@vellumai/assistant 0.10.12 → 0.11.0-staging.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/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +264 -14
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +33 -2
- package/src/__tests__/app-conversation-ids.test.ts +204 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-group-tools.test.ts +279 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-lineage.test.ts +235 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/platform-callback-registration.test.ts +10 -10
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/resolve-app-id.test.ts +32 -0
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +26 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +587 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +482 -2
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/api/responses/subagent-detail.ts +13 -0
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/apps/app-store.ts +95 -4
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +178 -65
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/commands/webhooks.help.ts +9 -4
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
- package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/bundled-skills/schedule/SKILL.md +2 -0
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -38
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-lineage.ts +76 -0
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +8 -14
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +32 -16
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +1288 -439
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +298 -15
- package/src/permissions/checker.ts +102 -36
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +269 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/conversation-parent.ts +27 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +9 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/prompts/sections.ts +4 -16
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/subagents-routes.ts +35 -8
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/webhook-routes.ts +89 -30
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/apps/resolve-app-id.ts +15 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/conversation-groups/group_create.ts +63 -0
- package/src/tools/conversation-groups/group_list.ts +20 -0
- package/src/tools/conversation-groups/group_shared.ts +52 -0
- package/src/tools/conversation-groups/move_to_group.ts +106 -0
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/util/platform.ts +15 -0
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/tsconfig.plugin-api.json +1 -1
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -26,6 +26,24 @@ describe("redactLogString", () => {
|
|
|
26
26
|
expect(redactLogString(input)).toBe(input);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
test("redacts a whole PEM private-key block — body and footer, not just the header", () => {
|
|
30
|
+
// Synthetic fake PEM material only — never a real key. `redactLogString`
|
|
31
|
+
// replaces the matched span in place, so the match must cover
|
|
32
|
+
// header→body→footer or the base64 body and END footer leak into logs.
|
|
33
|
+
const fakeBody =
|
|
34
|
+
"MIIFAKEfakefakefakefakefakefakefakefakefake\n" +
|
|
35
|
+
"FAKEfakefakefakefakefakefakefakefakefake==";
|
|
36
|
+
const block = `-----BEGIN RSA PRIVATE KEY-----\n${fakeBody}\n-----END RSA PRIVATE KEY-----`;
|
|
37
|
+
const result = redactLogString(`error dumping key: ${block} <eol>`);
|
|
38
|
+
expect(result).toContain("[REDACTED]");
|
|
39
|
+
expect(result).not.toContain("MIIFAKE");
|
|
40
|
+
expect(result).not.toContain("FAKEfake");
|
|
41
|
+
expect(result).not.toContain("-----BEGIN");
|
|
42
|
+
expect(result).not.toContain("-----END");
|
|
43
|
+
expect(result).toContain("error dumping key:");
|
|
44
|
+
expect(result).toContain("<eol>");
|
|
45
|
+
});
|
|
46
|
+
|
|
29
47
|
describe("plugin-declared patterns", () => {
|
|
30
48
|
// Synthetic token mirroring the incident's shape (never a real credential).
|
|
31
49
|
const pluginKey = "virlo_tkn_Qm7pW2xLbV9sKjR4tNcY8dZh3Fg";
|
|
@@ -1298,3 +1298,30 @@ describe("code-owned default profiles — echoes over stale on-disk bodies", ()
|
|
|
1298
1298
|
expectNothingCommitted();
|
|
1299
1299
|
});
|
|
1300
1300
|
});
|
|
1301
|
+
|
|
1302
|
+
// ---------------------------------------------------------------------------
|
|
1303
|
+
// PATCH /v1/config — legacy service-mode scrub
|
|
1304
|
+
// ---------------------------------------------------------------------------
|
|
1305
|
+
|
|
1306
|
+
describe("PATCH /v1/config — provider-only services scrub legacy mode", () => {
|
|
1307
|
+
test("a paired provider+mode write persists without the mode key", async () => {
|
|
1308
|
+
// Web clients pair provider writes with `mode` so their saves stay valid
|
|
1309
|
+
// on daemons whose schemas still carry it; the raw config must not
|
|
1310
|
+
// resurrect the removed field on every save.
|
|
1311
|
+
await patchRoute.handler({
|
|
1312
|
+
body: {
|
|
1313
|
+
services: {
|
|
1314
|
+
"image-generation": { provider: "vellum", mode: "managed" },
|
|
1315
|
+
"web-search": { provider: "vellum", mode: "managed" },
|
|
1316
|
+
},
|
|
1317
|
+
},
|
|
1318
|
+
} as never);
|
|
1319
|
+
|
|
1320
|
+
const raw = committedRaw() as Record<
|
|
1321
|
+
string,
|
|
1322
|
+
Record<string, Record<string, unknown>>
|
|
1323
|
+
>;
|
|
1324
|
+
expect(raw.services["image-generation"]).toEqual({ provider: "vellum" });
|
|
1325
|
+
expect(raw.services["web-search"]).toEqual({ provider: "vellum" });
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
@@ -25,7 +25,7 @@ mock.module("../persistence/embeddings/embedding-backend.js", () => ({
|
|
|
25
25
|
generateSparseEmbedding: () => ({ indices: [1], values: [1] }),
|
|
26
26
|
}));
|
|
27
27
|
|
|
28
|
-
mock.module("../plugins/defaults/memory/
|
|
28
|
+
mock.module("../plugins/defaults/memory/substrate/qdrant.js", () => ({
|
|
29
29
|
upsertConceptPageEmbedding: async (params: { slug: string }) => {
|
|
30
30
|
seedUpsertSlugs.push(params.slug);
|
|
31
31
|
},
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
_resetSkillStoreForTests,
|
|
42
42
|
getSkillCapability,
|
|
43
43
|
seedV2SkillEntries,
|
|
44
|
-
} from "../plugins/defaults/memory/
|
|
44
|
+
} from "../plugins/defaults/memory/substrate/skill-store.js";
|
|
45
45
|
import { executeDeleteManagedSkill } from "../tools/skills/delete-managed.js";
|
|
46
46
|
import { skillLoadTool } from "../tools/skills/load.js";
|
|
47
47
|
import { executeScaffoldManagedSkill } from "../tools/skills/scaffold-managed.js";
|
|
@@ -24,13 +24,13 @@ let lastGenerateCredentials: unknown = null;
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Seed the image-generation service entry in the real workspace config.
|
|
27
|
-
* Omitted fields fall back to the schema defaults (`
|
|
28
|
-
*
|
|
27
|
+
* Omitted fields fall back to the schema defaults (`provider: "gemini"`,
|
|
28
|
+
* model `gemini-3.1-flash-image-preview`).
|
|
29
29
|
*/
|
|
30
30
|
function seedImageGenService(
|
|
31
31
|
overrides: {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
provider?: "vellum" | "gemini" | "openai";
|
|
33
|
+
model?: string;
|
|
34
34
|
} = {},
|
|
35
35
|
): void {
|
|
36
36
|
setConfig("services", { "image-generation": overrides });
|
|
@@ -151,8 +151,8 @@ describe("image-studio skill script wrapper", () => {
|
|
|
151
151
|
expect(result.content).toContain("No Gemini API key");
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
-
test("
|
|
155
|
-
seedImageGenService({
|
|
154
|
+
test("provider vellum uses managed proxy credentials", async () => {
|
|
155
|
+
seedImageGenService({ provider: "vellum" });
|
|
156
156
|
mockManagedBaseUrl = "https://platform.example.com/v1/runtime-proxy/gemini";
|
|
157
157
|
mockManagedProxyContext = {
|
|
158
158
|
enabled: true,
|
|
@@ -172,8 +172,59 @@ describe("image-studio skill script wrapper", () => {
|
|
|
172
172
|
});
|
|
173
173
|
});
|
|
174
174
|
|
|
175
|
-
test("
|
|
176
|
-
seedImageGenService({
|
|
175
|
+
test("provider vellum routes managed to the gemini proxy for gemini models", async () => {
|
|
176
|
+
seedImageGenService({ provider: "vellum" });
|
|
177
|
+
mockManagedProxyContext = {
|
|
178
|
+
enabled: true,
|
|
179
|
+
platformBaseUrl: "https://platform.example.com",
|
|
180
|
+
assistantApiKey: "managed-key-123",
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const result = await run({ prompt: "a hippo" }, fakeContext);
|
|
184
|
+
|
|
185
|
+
expect(result.isError).toBe(false);
|
|
186
|
+
expect(lastGenerateProvider).toBe("gemini");
|
|
187
|
+
expect(lastGenerateCredentials).toEqual({
|
|
188
|
+
type: "managed-proxy",
|
|
189
|
+
assistantApiKey: "managed-key-123",
|
|
190
|
+
baseUrl: "https://platform.example.com/v1/runtime-proxy/gemini",
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("provider vellum routes a gpt model to the openai proxy", async () => {
|
|
195
|
+
seedImageGenService({ provider: "vellum", model: "gpt-image-2" });
|
|
196
|
+
mockManagedProxyContext = {
|
|
197
|
+
enabled: true,
|
|
198
|
+
platformBaseUrl: "https://platform.example.com",
|
|
199
|
+
assistantApiKey: "managed-key-123",
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const result = await run({ prompt: "a hippo" }, fakeContext);
|
|
203
|
+
|
|
204
|
+
expect(result.isError).toBe(false);
|
|
205
|
+
expect(lastGenerateProvider).toBe("openai");
|
|
206
|
+
expect(lastGenerateCredentials).toEqual({
|
|
207
|
+
type: "managed-proxy",
|
|
208
|
+
assistantApiKey: "managed-key-123",
|
|
209
|
+
baseUrl: "https://platform.example.com/v1/runtime-proxy/openai",
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test("provider vellum with no platform is a hard error, not a BYOK fallback", async () => {
|
|
214
|
+
// Billing rule: an explicit vellum choice never silently spends a stored
|
|
215
|
+
// provider key.
|
|
216
|
+
seedImageGenService({ provider: "vellum" });
|
|
217
|
+
mockGeminiKey = "gemini-key-should-not-be-used";
|
|
218
|
+
|
|
219
|
+
const result = await run({ prompt: "a hippo" }, fakeContext);
|
|
220
|
+
|
|
221
|
+
expect(result.isError).toBe(true);
|
|
222
|
+
expect(result.content).toContain("Managed proxy is not available");
|
|
223
|
+
expect(lastGenerateProvider).toBeNull();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test("provider vellum returns error when managed proxy is unavailable", async () => {
|
|
227
|
+
seedImageGenService({ provider: "vellum" });
|
|
177
228
|
mockGeminiKey = "direct-key"; // should be ignored in managed mode
|
|
178
229
|
mockManagedBaseUrl = undefined;
|
|
179
230
|
|
|
@@ -184,7 +235,7 @@ describe("image-studio skill script wrapper", () => {
|
|
|
184
235
|
});
|
|
185
236
|
|
|
186
237
|
test("your-own mode uses direct API key", async () => {
|
|
187
|
-
seedImageGenService({
|
|
238
|
+
seedImageGenService({ provider: "gemini" });
|
|
188
239
|
mockGeminiKey = "direct-key";
|
|
189
240
|
mockManagedBaseUrl = "https://platform.example.com/v1/runtime-proxy/gemini";
|
|
190
241
|
mockManagedProxyContext = {
|
|
@@ -365,8 +416,8 @@ describe("image-studio skill script wrapper", () => {
|
|
|
365
416
|
);
|
|
366
417
|
});
|
|
367
418
|
|
|
368
|
-
test("
|
|
369
|
-
seedImageGenService({
|
|
419
|
+
test("provider vellum credential error includes guidance not to change service config", async () => {
|
|
420
|
+
seedImageGenService({ provider: "vellum" });
|
|
370
421
|
mockManagedBaseUrl = undefined;
|
|
371
422
|
|
|
372
423
|
const result = await run({ prompt: "a cat" }, fakeContext);
|
|
@@ -27,7 +27,7 @@ mock.module("../prompts/persona-resolver.js", () => ({
|
|
|
27
27
|
const { buildCoreIdentityContext } =
|
|
28
28
|
await import("../prompts/system-prompt.js");
|
|
29
29
|
const { buildIdentityContext } =
|
|
30
|
-
await import("../plugins/defaults/memory/identity-context.js");
|
|
30
|
+
await import("../plugins/defaults/memory/v1/identity-context.js");
|
|
31
31
|
|
|
32
32
|
// ── Workspace fixtures ─────────────────────────────────────────────────
|
|
33
33
|
|
|
@@ -40,8 +40,13 @@ setDefaultTimeout(30_000);
|
|
|
40
40
|
// claimed jobs without lane awareness and ran them through a single
|
|
41
41
|
// workerConcurrency-sized pool — would pin its slots on the first claimed
|
|
42
42
|
// slow jobs and force the fast jobs to queue behind a 200ms LLM call.
|
|
43
|
+
// `memory.v2.enabled` is off so v1 is the active memory tier: the slow-lane
|
|
44
|
+
// job here is `graph_consolidate`, whose handler completes v1 graph rows as
|
|
45
|
+
// a no-op while concept-page memory is active — this test needs it to
|
|
46
|
+
// genuinely run.
|
|
43
47
|
// Everything else (including `memory.enabled: true`) is the schema default.
|
|
44
48
|
setConfig("memory", {
|
|
49
|
+
v2: { enabled: false },
|
|
45
50
|
jobs: {
|
|
46
51
|
slowLlmConcurrency: 1,
|
|
47
52
|
fastConcurrency: 5,
|
|
@@ -63,7 +68,7 @@ const completions: CompletionRecord[] = [];
|
|
|
63
68
|
// job completes before any slow job — a single 200ms window is plenty.
|
|
64
69
|
const SLOW_DELAY_MS = 200;
|
|
65
70
|
|
|
66
|
-
mock.module("../plugins/defaults/memory/graph/consolidation.js", () => ({
|
|
71
|
+
mock.module("../plugins/defaults/memory/v1/graph/consolidation.js", () => ({
|
|
67
72
|
runConsolidation: async (
|
|
68
73
|
scopeId: string,
|
|
69
74
|
): Promise<{
|
|
@@ -95,6 +100,9 @@ mock.module("../plugins/defaults/memory/v2/backfill-jobs.js", () => ({
|
|
|
95
100
|
return 0;
|
|
96
101
|
},
|
|
97
102
|
memoryV2MigrateJob: async (): Promise<void> => {},
|
|
103
|
+
}));
|
|
104
|
+
|
|
105
|
+
mock.module("../plugins/defaults/memory/substrate/reembed-job.js", () => ({
|
|
98
106
|
memoryV2ReembedJob: async (): Promise<void> => {},
|
|
99
107
|
}));
|
|
100
108
|
|
|
@@ -66,9 +66,9 @@ mock.module("../runtime/assistant-event-hub.js", () => ({
|
|
|
66
66
|
|
|
67
67
|
import type { UserPromptSubmitContext } from "@vellumai/plugin-api";
|
|
68
68
|
|
|
69
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
69
70
|
import type { AssistantConfig } from "../config/schema.js";
|
|
70
71
|
import type { Conversation } from "../daemon/conversation.js";
|
|
71
|
-
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
72
72
|
import type { QdrantSparseVector } from "../persistence/embeddings/qdrant-client.js";
|
|
73
73
|
import type { ConversationGraphMemory } from "../plugins/defaults/memory/graph/conversation-graph-memory.js";
|
|
74
74
|
import userPromptSubmitMemoryRetrieval from "../plugins/defaults/memory/hooks/user-prompt-submit.js";
|
|
@@ -337,7 +337,7 @@ describe("user-prompt-submit hook (memory retrieval)", () => {
|
|
|
337
337
|
expect(logEntry.reason).toBe("graph:none");
|
|
338
338
|
// The `memory_recalled` summary publishes through the shared broadcast hub.
|
|
339
339
|
expect(broadcastMessageMock).toHaveBeenCalledTimes(1);
|
|
340
|
-
const emitted = broadcastMessageMock.mock.calls[0]?.[0] as
|
|
340
|
+
const emitted = broadcastMessageMock.mock.calls[0]?.[0] as AssistantEvent;
|
|
341
341
|
expect(emitted.type).toBe("memory_recalled");
|
|
342
342
|
});
|
|
343
343
|
|
|
@@ -449,7 +449,7 @@ describe("user-prompt-submit hook (memory retrieval)", () => {
|
|
|
449
449
|
_msgs: Message[],
|
|
450
450
|
_cfg: AssistantConfig,
|
|
451
451
|
_signal: AbortSignal,
|
|
452
|
-
_onEvent: (msg:
|
|
452
|
+
_onEvent: (msg: AssistantEvent) => void,
|
|
453
453
|
) => Promise.reject(new Error("retrieval failed")),
|
|
454
454
|
);
|
|
455
455
|
const graphMemory = {
|
|
@@ -472,7 +472,7 @@ describe("user-prompt-submit hook (memory retrieval)", () => {
|
|
|
472
472
|
_msgs: Message[],
|
|
473
473
|
_cfg: AssistantConfig,
|
|
474
474
|
signal: AbortSignal,
|
|
475
|
-
_onEvent: (msg:
|
|
475
|
+
_onEvent: (msg: AssistantEvent) => void,
|
|
476
476
|
) => {
|
|
477
477
|
capturedSignal = signal;
|
|
478
478
|
return {
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import type { ConversationCandidateSet } from "../notifications/conversation-candidates.js";
|
|
20
20
|
import { composeFallbackCopy } from "../notifications/copy-composer.js";
|
|
21
21
|
import {
|
|
22
|
-
|
|
22
|
+
enforceGuardianRequestConversationAffinity,
|
|
23
23
|
validateConversationActions,
|
|
24
24
|
} from "../notifications/decision-engine.js";
|
|
25
25
|
import {
|
|
@@ -945,9 +945,9 @@ describe("notification decision strategy", () => {
|
|
|
945
945
|
});
|
|
946
946
|
});
|
|
947
947
|
|
|
948
|
-
// -- Guardian
|
|
948
|
+
// -- Guardian request conversation affinity enforcement -----------------------------
|
|
949
949
|
|
|
950
|
-
describe("guardian
|
|
950
|
+
describe("guardian request conversation affinity enforcement", () => {
|
|
951
951
|
function makeDecision(
|
|
952
952
|
overrides?: Partial<NotificationDecision>,
|
|
953
953
|
): NotificationDecision {
|
|
@@ -979,7 +979,10 @@ describe("notification decision strategy", () => {
|
|
|
979
979
|
},
|
|
980
980
|
});
|
|
981
981
|
|
|
982
|
-
const result =
|
|
982
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
983
|
+
decision,
|
|
984
|
+
signal,
|
|
985
|
+
);
|
|
983
986
|
expect(result.conversationActions?.vellum).toEqual({
|
|
984
987
|
action: "start_new",
|
|
985
988
|
});
|
|
@@ -1004,7 +1007,10 @@ describe("notification decision strategy", () => {
|
|
|
1004
1007
|
conversationAffinityHint: { vellum: "conv-123" },
|
|
1005
1008
|
});
|
|
1006
1009
|
|
|
1007
|
-
const result =
|
|
1010
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
1011
|
+
decision,
|
|
1012
|
+
signal,
|
|
1013
|
+
);
|
|
1008
1014
|
// Should remain unchanged — the affinity hint takes precedence
|
|
1009
1015
|
expect(result.conversationActions?.vellum).toEqual({
|
|
1010
1016
|
action: "reuse_existing",
|
|
@@ -1023,15 +1029,22 @@ describe("notification decision strategy", () => {
|
|
|
1023
1029
|
contextPayload: { message: "Take out the trash" },
|
|
1024
1030
|
});
|
|
1025
1031
|
|
|
1026
|
-
const result =
|
|
1032
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
1033
|
+
decision,
|
|
1034
|
+
signal,
|
|
1035
|
+
);
|
|
1027
1036
|
expect(result.conversationActions?.vellum).toEqual({
|
|
1028
1037
|
action: "reuse_existing",
|
|
1029
1038
|
conversationId: "conv-456",
|
|
1030
1039
|
});
|
|
1031
1040
|
});
|
|
1032
1041
|
|
|
1033
|
-
test("guardian.question without callSessionId
|
|
1034
|
-
const decision = makeDecision(
|
|
1042
|
+
test("guardian.question without callSessionId and no hint still forces start_new", () => {
|
|
1043
|
+
const decision = makeDecision({
|
|
1044
|
+
conversationActions: {
|
|
1045
|
+
vellum: { action: "reuse_existing", conversationId: "conv-catchall" },
|
|
1046
|
+
},
|
|
1047
|
+
});
|
|
1035
1048
|
const signal = makeSignal({
|
|
1036
1049
|
sourceEventName: "guardian.question",
|
|
1037
1050
|
contextPayload: {
|
|
@@ -1043,9 +1056,100 @@ describe("notification decision strategy", () => {
|
|
|
1043
1056
|
},
|
|
1044
1057
|
});
|
|
1045
1058
|
|
|
1046
|
-
const result =
|
|
1047
|
-
|
|
1048
|
-
|
|
1059
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
1060
|
+
decision,
|
|
1061
|
+
signal,
|
|
1062
|
+
);
|
|
1063
|
+
// Un-pinned guardian requests must never reuse an LLM-chosen conversation
|
|
1064
|
+
expect(result.conversationActions?.vellum).toEqual({
|
|
1065
|
+
action: "start_new",
|
|
1066
|
+
});
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
test("ingress.access_request without hint forces start_new over LLM reuse", () => {
|
|
1070
|
+
const decision = makeDecision({
|
|
1071
|
+
conversationActions: {
|
|
1072
|
+
vellum: { action: "reuse_existing", conversationId: "conv-catchall" },
|
|
1073
|
+
},
|
|
1074
|
+
});
|
|
1075
|
+
const signal = makeSignal({
|
|
1076
|
+
sourceEventName: "ingress.access_request",
|
|
1077
|
+
contextPayload: {
|
|
1078
|
+
requestId: "access-req-1",
|
|
1079
|
+
senderIdentifier: "Alice",
|
|
1080
|
+
},
|
|
1081
|
+
});
|
|
1082
|
+
|
|
1083
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
1084
|
+
decision,
|
|
1085
|
+
signal,
|
|
1086
|
+
);
|
|
1087
|
+
expect(result.conversationActions?.vellum).toEqual({
|
|
1088
|
+
action: "start_new",
|
|
1089
|
+
});
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
test("ingress.access_request with affinity hint is left to affinity enforcement", () => {
|
|
1093
|
+
const decision = makeDecision({
|
|
1094
|
+
conversationActions: {
|
|
1095
|
+
vellum: { action: "reuse_existing", conversationId: "conv-origin" },
|
|
1096
|
+
},
|
|
1097
|
+
});
|
|
1098
|
+
const signal = makeSignal({
|
|
1099
|
+
sourceEventName: "ingress.access_request",
|
|
1100
|
+
contextPayload: {
|
|
1101
|
+
requestId: "access-req-2",
|
|
1102
|
+
senderIdentifier: "Bob",
|
|
1103
|
+
},
|
|
1104
|
+
conversationAffinityHint: { vellum: "conv-origin" },
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
1108
|
+
decision,
|
|
1109
|
+
signal,
|
|
1110
|
+
);
|
|
1111
|
+
expect(result.conversationActions?.vellum).toEqual({
|
|
1112
|
+
action: "reuse_existing",
|
|
1113
|
+
conversationId: "conv-origin",
|
|
1114
|
+
});
|
|
1115
|
+
});
|
|
1116
|
+
|
|
1117
|
+
test("two unrelated un-pinned guardian requests never share a reuse target", () => {
|
|
1118
|
+
// Simulates the LUM-2870 catch-all: the LLM offers the same recent
|
|
1119
|
+
// guardian conversation as a reuse candidate for two unrelated
|
|
1120
|
+
// requests. The guard must force each to start its own conversation.
|
|
1121
|
+
const llmDecisionForRequest = () =>
|
|
1122
|
+
makeDecision({
|
|
1123
|
+
conversationActions: {
|
|
1124
|
+
vellum: {
|
|
1125
|
+
action: "reuse_existing",
|
|
1126
|
+
conversationId: "conv-catchall",
|
|
1127
|
+
},
|
|
1128
|
+
},
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
const accessRequest = makeSignal({
|
|
1132
|
+
sourceEventName: "ingress.access_request",
|
|
1133
|
+
contextPayload: { requestId: "access-req-3" },
|
|
1134
|
+
});
|
|
1135
|
+
const toolGrant = makeSignal({
|
|
1136
|
+
sourceEventName: "guardian.question",
|
|
1137
|
+
contextPayload: {
|
|
1138
|
+
requestId: "tool-grant-9",
|
|
1139
|
+
requestKind: "tool_grant_request",
|
|
1140
|
+
toolName: "host_bash",
|
|
1141
|
+
},
|
|
1142
|
+
});
|
|
1143
|
+
|
|
1144
|
+
for (const signal of [accessRequest, toolGrant]) {
|
|
1145
|
+
const result = enforceGuardianRequestConversationAffinity(
|
|
1146
|
+
llmDecisionForRequest(),
|
|
1147
|
+
signal,
|
|
1148
|
+
);
|
|
1149
|
+
expect(result.conversationActions?.vellum).toEqual({
|
|
1150
|
+
action: "start_new",
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1049
1153
|
});
|
|
1050
1154
|
});
|
|
1051
1155
|
});
|
|
@@ -98,7 +98,7 @@ mock.module("../notifications/conversation-pairing.js", () => ({
|
|
|
98
98
|
},
|
|
99
99
|
}));
|
|
100
100
|
|
|
101
|
-
import type {
|
|
101
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
102
102
|
import { VellumAdapter } from "../notifications/adapters/macos.js";
|
|
103
103
|
import { NotificationBroadcaster } from "../notifications/broadcaster.js";
|
|
104
104
|
import type { NotificationSignal } from "../notifications/signal.js";
|
|
@@ -179,7 +179,7 @@ describe("notification deep-link metadata", () => {
|
|
|
179
179
|
|
|
180
180
|
describe("VellumAdapter", () => {
|
|
181
181
|
test("broadcasts notification_intent with deepLinkMetadata from payload", async () => {
|
|
182
|
-
const messages:
|
|
182
|
+
const messages: AssistantEvent[] = [];
|
|
183
183
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
184
184
|
|
|
185
185
|
await adapter.send(
|
|
@@ -207,7 +207,7 @@ describe("notification deep-link metadata", () => {
|
|
|
207
207
|
});
|
|
208
208
|
|
|
209
209
|
test("broadcasts notification_intent without deepLinkMetadata when absent", async () => {
|
|
210
|
-
const messages:
|
|
210
|
+
const messages: AssistantEvent[] = [];
|
|
211
211
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
212
212
|
|
|
213
213
|
await adapter.send(
|
|
@@ -226,7 +226,7 @@ describe("notification deep-link metadata", () => {
|
|
|
226
226
|
});
|
|
227
227
|
|
|
228
228
|
test("includes conversationId in deepLinkMetadata for navigation", async () => {
|
|
229
|
-
const messages:
|
|
229
|
+
const messages: AssistantEvent[] = [];
|
|
230
230
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
231
231
|
|
|
232
232
|
const conversationId = "conv-deep-link-test";
|
|
@@ -279,7 +279,7 @@ describe("notification deep-link metadata", () => {
|
|
|
279
279
|
});
|
|
280
280
|
|
|
281
281
|
test("sourceEventName is included in the event payload", async () => {
|
|
282
|
-
const messages:
|
|
282
|
+
const messages: AssistantEvent[] = [];
|
|
283
283
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
284
284
|
|
|
285
285
|
await adapter.send(
|
|
@@ -296,7 +296,7 @@ describe("notification deep-link metadata", () => {
|
|
|
296
296
|
});
|
|
297
297
|
|
|
298
298
|
test("deepLinkMetadata with conversationId enables client-side navigation", async () => {
|
|
299
|
-
const messages:
|
|
299
|
+
const messages: AssistantEvent[] = [];
|
|
300
300
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
301
301
|
|
|
302
302
|
// Simulate a notification that should deep-link to a specific conversation
|
|
@@ -320,7 +320,7 @@ describe("notification deep-link metadata", () => {
|
|
|
320
320
|
});
|
|
321
321
|
|
|
322
322
|
test("deep-link payload includes messageId when present", async () => {
|
|
323
|
-
const messages:
|
|
323
|
+
const messages: AssistantEvent[] = [];
|
|
324
324
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
325
325
|
|
|
326
326
|
await adapter.send(
|
|
@@ -341,7 +341,7 @@ describe("notification deep-link metadata", () => {
|
|
|
341
341
|
// ── Deep-link conversationId present regardless of reuse/new ──────
|
|
342
342
|
|
|
343
343
|
test("deep-link payload includes conversationId for a newly created conversation", async () => {
|
|
344
|
-
const messages:
|
|
344
|
+
const messages: AssistantEvent[] = [];
|
|
345
345
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
346
346
|
|
|
347
347
|
// Simulates the broadcaster merging pairing.conversationId into deep-link
|
|
@@ -362,7 +362,7 @@ describe("notification deep-link metadata", () => {
|
|
|
362
362
|
});
|
|
363
363
|
|
|
364
364
|
test("deep-link payload includes conversationId for a reused conversation", async () => {
|
|
365
|
-
const messages:
|
|
365
|
+
const messages: AssistantEvent[] = [];
|
|
366
366
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
367
367
|
|
|
368
368
|
// Simulates the broadcaster merging pairing.conversationId into deep-link
|
|
@@ -388,7 +388,7 @@ describe("notification deep-link metadata", () => {
|
|
|
388
388
|
// ── Reused conversation deep-link stability regressions ─────────────────
|
|
389
389
|
|
|
390
390
|
test("reused conversation preserves the same conversationId across follow-up notifications", async () => {
|
|
391
|
-
const messages:
|
|
391
|
+
const messages: AssistantEvent[] = [];
|
|
392
392
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
393
393
|
|
|
394
394
|
const stableConversationId = "conv-bound-telegram-dest-001";
|
|
@@ -438,7 +438,7 @@ describe("notification deep-link metadata", () => {
|
|
|
438
438
|
});
|
|
439
439
|
|
|
440
440
|
test("reused conversation deep-link messageId changes per delivery for scroll targeting", async () => {
|
|
441
|
-
const messages:
|
|
441
|
+
const messages: AssistantEvent[] = [];
|
|
442
442
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
443
443
|
|
|
444
444
|
const conversationId = "conv-reused-scroll-test";
|
|
@@ -475,7 +475,7 @@ describe("notification deep-link metadata", () => {
|
|
|
475
475
|
});
|
|
476
476
|
|
|
477
477
|
test("deep-link metadata is stable when conversation is reused via binding-key continuation", async () => {
|
|
478
|
-
const messages:
|
|
478
|
+
const messages: AssistantEvent[] = [];
|
|
479
479
|
const adapter = new VellumAdapter((msg) => messages.push(msg));
|
|
480
480
|
|
|
481
481
|
// Simulates the binding-key continuation path: multiple notifications
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
4
4
|
import { VellumAdapter } from "../notifications/adapters/macos.js";
|
|
5
5
|
import type {
|
|
6
6
|
ChannelDeliveryPayload,
|
|
@@ -30,9 +30,9 @@ function makeDestination(
|
|
|
30
30
|
|
|
31
31
|
function captureBroadcast(): {
|
|
32
32
|
adapter: VellumAdapter;
|
|
33
|
-
sent:
|
|
33
|
+
sent: AssistantEvent[];
|
|
34
34
|
} {
|
|
35
|
-
const sent:
|
|
35
|
+
const sent: AssistantEvent[] = [];
|
|
36
36
|
const adapter = new VellumAdapter((msg) => sent.push(msg));
|
|
37
37
|
return { adapter, sent };
|
|
38
38
|
}
|
|
@@ -48,7 +48,7 @@ describe("VellumAdapter silent flag", () => {
|
|
|
48
48
|
expect(result.success).toBe(true);
|
|
49
49
|
expect(sent).toHaveLength(1);
|
|
50
50
|
const intent = sent[0] as Extract<
|
|
51
|
-
|
|
51
|
+
AssistantEvent,
|
|
52
52
|
{ type: "notification_intent" }
|
|
53
53
|
>;
|
|
54
54
|
expect(intent.type).toBe("notification_intent");
|
|
@@ -60,7 +60,7 @@ describe("VellumAdapter silent flag", () => {
|
|
|
60
60
|
await adapter.send(makePayload({ urgency: "medium" }), makeDestination());
|
|
61
61
|
|
|
62
62
|
const intent = sent[0] as Extract<
|
|
63
|
-
|
|
63
|
+
AssistantEvent,
|
|
64
64
|
{ type: "notification_intent" }
|
|
65
65
|
>;
|
|
66
66
|
expect(intent.silent).toBe(true);
|
|
@@ -71,7 +71,7 @@ describe("VellumAdapter silent flag", () => {
|
|
|
71
71
|
await adapter.send(makePayload({ urgency: "high" }), makeDestination());
|
|
72
72
|
|
|
73
73
|
const intent = sent[0] as Extract<
|
|
74
|
-
|
|
74
|
+
AssistantEvent,
|
|
75
75
|
{ type: "notification_intent" }
|
|
76
76
|
>;
|
|
77
77
|
expect(intent.silent).toBe(false);
|
|
@@ -82,7 +82,7 @@ describe("VellumAdapter silent flag", () => {
|
|
|
82
82
|
await adapter.send(makePayload({ urgency: "critical" }), makeDestination());
|
|
83
83
|
|
|
84
84
|
const intent = sent[0] as Extract<
|
|
85
|
-
|
|
85
|
+
AssistantEvent,
|
|
86
86
|
{ type: "notification_intent" }
|
|
87
87
|
>;
|
|
88
88
|
expect(intent.silent).toBe(false);
|
|
@@ -101,7 +101,7 @@ describe("VellumAdapter silent flag", () => {
|
|
|
101
101
|
);
|
|
102
102
|
|
|
103
103
|
const intent = sent[0] as Extract<
|
|
104
|
-
|
|
104
|
+
AssistantEvent,
|
|
105
105
|
{ type: "notification_intent" }
|
|
106
106
|
>;
|
|
107
107
|
expect(intent.deliveryId).toBe("delivery-xyz");
|