@vellumai/assistant 0.10.12 → 0.11.0-staging.1
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 +246 -10
- 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__/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-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- 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__/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__/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 +6 -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 +583 -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-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 +399 -0
- 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/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +158 -4
- 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 +156 -58
- 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/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/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -30
- 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-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 +4 -4
- 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 +13 -13
- 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-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 +218 -422
- 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 +650 -333
- 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 +85 -9
- package/src/permissions/checker.ts +17 -22
- 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 +236 -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/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/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +7 -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/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/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/upgrade-broadcast-routes.ts +4 -5
- 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__/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/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/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/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/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
|
@@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
2
2
|
|
|
3
3
|
import type { SessionNotification } from "@agentclientprotocol/sdk";
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { AssistantEvent } from "../../api/index.js";
|
|
6
6
|
import { VellumAcpClientHandler } from "../client-handler.js";
|
|
7
7
|
|
|
8
8
|
const ACP_SESSION_ID = "acp-session-abc";
|
|
@@ -10,9 +10,9 @@ const PARENT_CONVERSATION_ID = "conv-xyz";
|
|
|
10
10
|
|
|
11
11
|
function makeHandler(): {
|
|
12
12
|
handler: VellumAcpClientHandler;
|
|
13
|
-
sent:
|
|
13
|
+
sent: AssistantEvent[];
|
|
14
14
|
} {
|
|
15
|
-
const sent:
|
|
15
|
+
const sent: AssistantEvent[] = [];
|
|
16
16
|
const handler = new VellumAcpClientHandler(
|
|
17
17
|
ACP_SESSION_ID,
|
|
18
18
|
(msg) => {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
12
12
|
|
|
13
13
|
import type { AcpSessionUpdateEvent } from "../../api/events/acp-session-update.js";
|
|
14
|
-
import type {
|
|
14
|
+
import type { AssistantEvent } from "../../api/index.js";
|
|
15
15
|
import { getSqlite } from "../../persistence/db-connection.js";
|
|
16
16
|
import { initializeDb } from "../../persistence/db-init.js";
|
|
17
17
|
import { VellumAcpClientHandler } from "../client-handler.js";
|
|
@@ -47,8 +47,8 @@ function buildSessionWithFakeProcess(opts: {
|
|
|
47
47
|
emitUpdate: (update: AcpSessionUpdateEvent) => void;
|
|
48
48
|
} {
|
|
49
49
|
const manager = new AcpSessionManager(1);
|
|
50
|
-
const sent:
|
|
51
|
-
const sendToVellum = (msg:
|
|
50
|
+
const sent: AssistantEvent[] = [];
|
|
51
|
+
const sendToVellum = (msg: AssistantEvent) => sent.push(msg);
|
|
52
52
|
|
|
53
53
|
type PromptResolution = {
|
|
54
54
|
stopReason: string;
|
|
@@ -81,7 +81,7 @@ function buildSessionWithFakeProcess(opts: {
|
|
|
81
81
|
).eventBuffers;
|
|
82
82
|
eventBuffers.set(opts.id, []);
|
|
83
83
|
|
|
84
|
-
const wrappedSend = (msg:
|
|
84
|
+
const wrappedSend = (msg: AssistantEvent) => {
|
|
85
85
|
if (msg.type === "acp_session_update") {
|
|
86
86
|
(
|
|
87
87
|
manager as unknown as {
|
|
@@ -464,7 +464,7 @@ describe("AcpSessionManager — terminal persistence", () => {
|
|
|
464
464
|
|
|
465
465
|
test("emits acp_session_usage and persists input/output tokens from PromptResponse.usage", async () => {
|
|
466
466
|
const id = "session-io-usage-1";
|
|
467
|
-
const sent:
|
|
467
|
+
const sent: AssistantEvent[] = [];
|
|
468
468
|
const handles = buildSessionWithFakeProcess({
|
|
469
469
|
id,
|
|
470
470
|
agentId: "agent-io",
|
|
@@ -478,11 +478,11 @@ describe("AcpSessionManager — terminal persistence", () => {
|
|
|
478
478
|
// Capture the usage event emitted at turn end.
|
|
479
479
|
const captureSend = (
|
|
480
480
|
handles.manager as unknown as {
|
|
481
|
-
sessions: Map<string, { sendToVellum: (m:
|
|
481
|
+
sessions: Map<string, { sendToVellum: (m: AssistantEvent) => void }>;
|
|
482
482
|
}
|
|
483
483
|
).sessions.get(id);
|
|
484
484
|
const originalSend = captureSend!.sendToVellum;
|
|
485
|
-
captureSend!.sendToVellum = (msg:
|
|
485
|
+
captureSend!.sendToVellum = (msg: AssistantEvent) => {
|
|
486
486
|
sent.push(msg);
|
|
487
487
|
originalSend(msg);
|
|
488
488
|
};
|
|
@@ -515,7 +515,7 @@ describe("AcpSessionManager — terminal persistence", () => {
|
|
|
515
515
|
|
|
516
516
|
test("does not emit usage or write token columns when PromptResponse carries no usage", async () => {
|
|
517
517
|
const id = "session-io-no-usage-1";
|
|
518
|
-
const sent:
|
|
518
|
+
const sent: AssistantEvent[] = [];
|
|
519
519
|
const handles = buildSessionWithFakeProcess({
|
|
520
520
|
id,
|
|
521
521
|
agentId: "agent-io-none",
|
|
@@ -525,11 +525,11 @@ describe("AcpSessionManager — terminal persistence", () => {
|
|
|
525
525
|
|
|
526
526
|
const entry = (
|
|
527
527
|
handles.manager as unknown as {
|
|
528
|
-
sessions: Map<string, { sendToVellum: (m:
|
|
528
|
+
sessions: Map<string, { sendToVellum: (m: AssistantEvent) => void }>;
|
|
529
529
|
}
|
|
530
530
|
).sessions.get(id);
|
|
531
531
|
const originalSend = entry!.sendToVellum;
|
|
532
|
-
entry!.sendToVellum = (msg:
|
|
532
|
+
entry!.sendToVellum = (msg: AssistantEvent) => {
|
|
533
533
|
sent.push(msg);
|
|
534
534
|
originalSend(msg);
|
|
535
535
|
};
|
|
@@ -208,7 +208,7 @@ const BUN_BIN = "/usr/local/bin/bun";
|
|
|
208
208
|
const BUN_ADD_KEY = `${BUN_BIN} add`;
|
|
209
209
|
|
|
210
210
|
import type { AcpSessionUpdateEvent } from "../../api/events/acp-session-update.js";
|
|
211
|
-
import type {
|
|
211
|
+
import type { AssistantEvent } from "../../api/index.js";
|
|
212
212
|
import { getSqlite } from "../../persistence/db-connection.js";
|
|
213
213
|
import { initializeDb } from "../../persistence/db-init.js";
|
|
214
214
|
import type { AcpSessionState } from "../types.js";
|
|
@@ -292,7 +292,7 @@ describe("AcpSessionManager.resumeFromHistory", () => {
|
|
|
292
292
|
});
|
|
293
293
|
|
|
294
294
|
const manager = new AcpSessionManager(4);
|
|
295
|
-
const sent:
|
|
295
|
+
const sent: AssistantEvent[] = [];
|
|
296
296
|
await manager.resumeFromHistory("resume-1", (msg) => sent.push(msg));
|
|
297
297
|
|
|
298
298
|
const fake = fakeInstances[0]!;
|
|
@@ -355,7 +355,7 @@ describe("AcpSessionManager.resumeFromHistory", () => {
|
|
|
355
355
|
});
|
|
356
356
|
|
|
357
357
|
const manager = new AcpSessionManager(4);
|
|
358
|
-
const sent:
|
|
358
|
+
const sent: AssistantEvent[] = [];
|
|
359
359
|
await manager.resumeFromHistory("resume-seq-1", (msg) => sent.push(msg));
|
|
360
360
|
|
|
361
361
|
const fake = fakeInstances[0]!;
|
|
@@ -716,7 +716,7 @@ describe("AcpSessionManager.resumeFromHistory", () => {
|
|
|
716
716
|
insertHistoryRow({ id: "race-1" });
|
|
717
717
|
|
|
718
718
|
const manager = new AcpSessionManager(4);
|
|
719
|
-
const sent:
|
|
719
|
+
const sent: AssistantEvent[] = [];
|
|
720
720
|
const [a, b] = await Promise.allSettled([
|
|
721
721
|
manager.resumeFromHistory("race-1", (msg) => sent.push(msg)),
|
|
722
722
|
manager.resumeFromHistory("race-1", (msg) => sent.push(msg)),
|
|
@@ -862,7 +862,7 @@ describe("AcpSessionManager.steerOrResume", () => {
|
|
|
862
862
|
insertHistoryRow({ id: "sor-resume-1" });
|
|
863
863
|
|
|
864
864
|
const manager = new AcpSessionManager(4);
|
|
865
|
-
const sent:
|
|
865
|
+
const sent: AssistantEvent[] = [];
|
|
866
866
|
const result = await manager.steerOrResume(
|
|
867
867
|
"sor-resume-1",
|
|
868
868
|
"continue the work",
|
|
@@ -904,7 +904,7 @@ describe("AcpSessionManager.steerOrResume", () => {
|
|
|
904
904
|
insertHistoryRow({ id: "sor-race-1" });
|
|
905
905
|
|
|
906
906
|
const manager = new AcpSessionManager(4);
|
|
907
|
-
const sent:
|
|
907
|
+
const sent: AssistantEvent[] = [];
|
|
908
908
|
const [a, b] = await Promise.all([
|
|
909
909
|
manager.steerOrResume("sor-race-1", "first instruction", (msg) =>
|
|
910
910
|
sent.push(msg),
|
|
@@ -943,7 +943,7 @@ describe("AcpSessionManager.steerOrResume", () => {
|
|
|
943
943
|
});
|
|
944
944
|
|
|
945
945
|
const manager = new AcpSessionManager(4);
|
|
946
|
-
const sent:
|
|
946
|
+
const sent: AssistantEvent[] = [];
|
|
947
947
|
const first = manager.steerOrResume(
|
|
948
948
|
"sor-init-1",
|
|
949
949
|
"first instruction",
|
|
@@ -32,7 +32,7 @@ import type {
|
|
|
32
32
|
} from "@agentclientprotocol/sdk";
|
|
33
33
|
|
|
34
34
|
import type { AcpSessionUpdateEvent } from "../api/events/acp-session-update.js";
|
|
35
|
-
import type {
|
|
35
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
36
36
|
import { redactJsonStringLeaves } from "../security/redact-json.js";
|
|
37
37
|
import { redactSensitiveFields } from "../security/redaction.js";
|
|
38
38
|
import { redactSecrets } from "../security/secret-scanner.js";
|
|
@@ -72,7 +72,7 @@ interface TerminalState {
|
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Vellum's ACP Client handler. Receives events from an ACP agent and
|
|
75
|
-
* forwards them as
|
|
75
|
+
* forwards them as AssistantEvent objects to connected Vellum clients.
|
|
76
76
|
*/
|
|
77
77
|
export class VellumAcpClientHandler implements Client {
|
|
78
78
|
private terminals = new Map<string, TerminalState>();
|
|
@@ -101,7 +101,7 @@ export class VellumAcpClientHandler implements Client {
|
|
|
101
101
|
|
|
102
102
|
constructor(
|
|
103
103
|
private readonly acpSessionId: string,
|
|
104
|
-
private readonly sendToVellum: (msg:
|
|
104
|
+
private readonly sendToVellum: (msg: AssistantEvent) => void,
|
|
105
105
|
private readonly parentConversationId: string,
|
|
106
106
|
) {}
|
|
107
107
|
|
|
@@ -9,8 +9,8 @@ import { basename } from "node:path";
|
|
|
9
9
|
import { eq, inArray } from "drizzle-orm";
|
|
10
10
|
|
|
11
11
|
import type { AcpSessionUpdateEvent } from "../api/events/acp-session-update.js";
|
|
12
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
12
13
|
import { findConversation } from "../daemon/conversation-registry.js";
|
|
13
|
-
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
14
14
|
import { getDb } from "../persistence/db-connection.js";
|
|
15
15
|
import { acpSessionHistory } from "../persistence/schema/index.js";
|
|
16
16
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
@@ -69,7 +69,7 @@ interface SessionEntry {
|
|
|
69
69
|
state: AcpSessionState;
|
|
70
70
|
clientHandler: VellumAcpClientHandler;
|
|
71
71
|
/** Wrapped sender that also appends to the ring buffer. */
|
|
72
|
-
sendToVellum: (msg:
|
|
72
|
+
sendToVellum: (msg: AssistantEvent) => void;
|
|
73
73
|
currentPrompt: Promise<unknown> | null;
|
|
74
74
|
parentConversationId: string;
|
|
75
75
|
cwd: string;
|
|
@@ -195,7 +195,7 @@ export class AcpSessionManager {
|
|
|
195
195
|
task: string,
|
|
196
196
|
cwd: string,
|
|
197
197
|
parentConversationId: string,
|
|
198
|
-
sendToVellum: (msg:
|
|
198
|
+
sendToVellum: (msg: AssistantEvent) => void,
|
|
199
199
|
parentToolUseId?: string,
|
|
200
200
|
): Promise<{ acpSessionId: string; protocolSessionId: string }> {
|
|
201
201
|
this.assertCapacity();
|
|
@@ -275,7 +275,7 @@ export class AcpSessionManager {
|
|
|
275
275
|
parentConversationId: string;
|
|
276
276
|
cwd: string;
|
|
277
277
|
startedAt: number;
|
|
278
|
-
sendToVellum: (msg:
|
|
278
|
+
sendToVellum: (msg: AssistantEvent) => void;
|
|
279
279
|
parentToolUseId?: string;
|
|
280
280
|
task?: string;
|
|
281
281
|
}): SessionEntry {
|
|
@@ -287,7 +287,7 @@ export class AcpSessionManager {
|
|
|
287
287
|
// Wrap the sender so every emitted message is mirrored into the buffer
|
|
288
288
|
// when it's an `acp_session_update`. The wrapper preserves the original
|
|
289
289
|
// call semantics: it forwards every message unchanged.
|
|
290
|
-
const wrappedSend = (msg:
|
|
290
|
+
const wrappedSend = (msg: AssistantEvent) => {
|
|
291
291
|
if (msg.type === "acp_session_update") {
|
|
292
292
|
this.appendToBuffer(acpSessionId, msg);
|
|
293
293
|
} else if (msg.type === "acp_session_usage") {
|
|
@@ -383,7 +383,7 @@ export class AcpSessionManager {
|
|
|
383
383
|
*/
|
|
384
384
|
async resumeFromHistory(
|
|
385
385
|
acpSessionId: string,
|
|
386
|
-
sendToVellum: (msg:
|
|
386
|
+
sendToVellum: (msg: AssistantEvent) => void,
|
|
387
387
|
): Promise<void> {
|
|
388
388
|
if (
|
|
389
389
|
this.sessions.has(acpSessionId) ||
|
|
@@ -448,7 +448,7 @@ export class AcpSessionManager {
|
|
|
448
448
|
private async performResume(
|
|
449
449
|
acpSessionId: string,
|
|
450
450
|
row: ResumableHistoryRow,
|
|
451
|
-
sendToVellum: (msg:
|
|
451
|
+
sendToVellum: (msg: AssistantEvent) => void,
|
|
452
452
|
): Promise<void> {
|
|
453
453
|
// Resolve the adapter, silently auto-installing a missing allowlisted
|
|
454
454
|
// binary via the same sandboxed `bun` path as spawn (see
|
|
@@ -658,7 +658,7 @@ export class AcpSessionManager {
|
|
|
658
658
|
async steerOrResume(
|
|
659
659
|
acpSessionId: string,
|
|
660
660
|
instruction: string,
|
|
661
|
-
sendToVellum: (msg:
|
|
661
|
+
sendToVellum: (msg: AssistantEvent) => void,
|
|
662
662
|
): Promise<{ resumed: boolean }> {
|
|
663
663
|
try {
|
|
664
664
|
await this.steer(acpSessionId, instruction);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `subagent_event` SSE event.
|
|
3
3
|
*
|
|
4
|
-
* Server → client envelope wrapping any inner `
|
|
4
|
+
* Server → client envelope wrapping any inner `AssistantEvent`
|
|
5
5
|
* emitted by a subagent's conversation. The daemon's subagent
|
|
6
6
|
* manager rebroadcasts the subagent's own stream through the
|
|
7
7
|
* parent conversation's `sendToClient`, tagged with the subagent's
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* to route inner events to the appropriate inline subagent surface.
|
|
10
10
|
*
|
|
11
11
|
* The inner `event` is opaque on the wire — it is itself a fully
|
|
12
|
-
* structured `
|
|
12
|
+
* structured `AssistantEvent` (any member of the canonical event
|
|
13
13
|
* union) and re-validating it here would duplicate work and
|
|
14
14
|
* tightly couple subagent canonicalization to every other event
|
|
15
15
|
* schema. Clients re-parse `event` through the same event parser
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Wire contract for the memory v2 activation log surfaced in the
|
|
3
3
|
* inspector's Memory tab. Mirrors the return value of
|
|
4
4
|
* `getMemoryV2ActivationLogByMessageIds` in
|
|
5
|
-
* `assistant/src/memory/
|
|
5
|
+
* `assistant/src/plugins/defaults/memory/v2/activation-log-store.ts`.
|
|
6
6
|
*
|
|
7
7
|
* Canonical wire-contract source. Assistant code imports the types
|
|
8
8
|
* directly from this file via relative paths; external consumers
|
|
@@ -20,7 +20,7 @@ import { z } from "zod";
|
|
|
20
20
|
/**
|
|
21
21
|
* One concept row in the V2 activation log. Mirrors
|
|
22
22
|
* `MemoryV2ConceptRowRecord` from
|
|
23
|
-
* `assistant/src/memory/
|
|
23
|
+
* `assistant/src/plugins/defaults/memory/v2/activation-log-store.ts`.
|
|
24
24
|
*
|
|
25
25
|
* `source` and `status` are open-ended strings on the wire — the
|
|
26
26
|
* daemon emits known values like `prior_state`, `ann_top50`, `both`
|
package/src/approvals/AGENTS.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Approvals & Guardian Rules
|
|
2
2
|
|
|
3
|
+
The end-to-end lifecycle of interactive guardian requests (approvals, questions) — promotion, notification cards, reply routing, resolution — is mapped in [docs/guardian-request-flow.md](../../docs/guardian-request-flow.md). Read it before extending any decision or card-delivery path.
|
|
4
|
+
|
|
3
5
|
## Approval Flow Resilience
|
|
4
6
|
|
|
5
7
|
- **Rich delivery failures must degrade gracefully.** If delivering a rich approval prompt (e.g., Telegram inline buttons) fails, fall back to plain text with instructions (e.g., `Reply "yes" to approve`) — never auto-deny.
|
|
@@ -26,6 +26,7 @@ import { getGuardianRequestOrNull } from "../channels/gateway-guardian-requests.
|
|
|
26
26
|
import { findContactChannel } from "../contacts/contact-store.js";
|
|
27
27
|
import { findConversation } from "../daemon/conversation-registry.js";
|
|
28
28
|
import { emitNotificationSignal } from "../notifications/emit-signal.js";
|
|
29
|
+
import { parseQuestionAnswerActionId } from "../notifications/guardian-question-mode.js";
|
|
29
30
|
import {
|
|
30
31
|
isNotificationSourceChannel,
|
|
31
32
|
type NotificationSourceChannel,
|
|
@@ -34,6 +35,7 @@ import type {
|
|
|
34
35
|
TrustedContactDecisionPayload,
|
|
35
36
|
TrustedContactVerificationSentPayload,
|
|
36
37
|
} from "../notifications/trusted-contact-payloads.js";
|
|
38
|
+
import type { QuestionBatchSubmission } from "../permissions/question-prompter.js";
|
|
37
39
|
import type { UserDecision } from "../permissions/types.js";
|
|
38
40
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
39
41
|
import {
|
|
@@ -48,6 +50,10 @@ import {
|
|
|
48
50
|
resolveTrustBinding,
|
|
49
51
|
} from "../runtime/introduction-policy.js";
|
|
50
52
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
53
|
+
import {
|
|
54
|
+
readBatchMetadata,
|
|
55
|
+
resolvePendingQuestion,
|
|
56
|
+
} from "../runtime/question-resolution.js";
|
|
51
57
|
import { TC_GRANT_WAIT_MAX_MS } from "../tools/tool-approval-handler.js";
|
|
52
58
|
import { getLogger } from "../util/logger.js";
|
|
53
59
|
import { resolveDeliverCallbackUrlForChannel } from "./guardian-channel-delivery.js";
|
|
@@ -409,11 +415,16 @@ const pendingInteractionResolver: GuardianRequestResolver = {
|
|
|
409
415
|
};
|
|
410
416
|
|
|
411
417
|
/**
|
|
412
|
-
* Resolves `pending_question` requests
|
|
418
|
+
* Resolves `pending_question` requests. Two variants share the kind,
|
|
419
|
+
* distinguished by provenance fields:
|
|
420
|
+
*
|
|
421
|
+
* - Voice-call questions carry a `callSessionId` (+ `pendingQuestionId`);
|
|
422
|
+
* the answer is delivered to the live call session via `answerCall`.
|
|
423
|
+
* - `ask_question` prompts carry neither — the request id IS the pending
|
|
424
|
+
* `question` interaction's requestId (mirroring `tool_approval` rows), and
|
|
425
|
+
* the answer resolves that interaction so the parked tool call returns.
|
|
413
426
|
*
|
|
414
|
-
*
|
|
415
|
-
* are present and delivers the answer to the live call session. An
|
|
416
|
-
* `answerCall` failure surfaces as `resolverFailed` — the committed decision
|
|
427
|
+
* Side-effect failures surface as `resolverFailed` — the committed decision
|
|
417
428
|
* stands (no reopen).
|
|
418
429
|
*/
|
|
419
430
|
const pendingQuestionResolver: GuardianRequestResolver = {
|
|
@@ -423,10 +434,7 @@ const pendingQuestionResolver: GuardianRequestResolver = {
|
|
|
423
434
|
const { request, decision, actor: _actor } = ctx;
|
|
424
435
|
|
|
425
436
|
if (!request.callSessionId) {
|
|
426
|
-
return
|
|
427
|
-
ok: false,
|
|
428
|
-
reason: "pending_question request missing callSessionId",
|
|
429
|
-
};
|
|
437
|
+
return resolveAskQuestionInteraction(request, decision);
|
|
430
438
|
}
|
|
431
439
|
|
|
432
440
|
if (!request.pendingQuestionId) {
|
|
@@ -487,6 +495,100 @@ const pendingQuestionResolver: GuardianRequestResolver = {
|
|
|
487
495
|
},
|
|
488
496
|
};
|
|
489
497
|
|
|
498
|
+
/**
|
|
499
|
+
* Resolve an `ask_question` pending interaction from a guardian decision.
|
|
500
|
+
*
|
|
501
|
+
* The decision's `userText` carries either an answer-option token
|
|
502
|
+
* (`answer_<idx>` / `answer_skip`, from a tapped card button — see
|
|
503
|
+
* {@link parseQuestionAnswerActionId}) or the guardian's free-typed answer.
|
|
504
|
+
* A reject decision with no text is an explicit skip. Submission validation
|
|
505
|
+
* and the prompter hand-off go through the shared
|
|
506
|
+
* {@link resolvePendingQuestion}, the same core `/v1/question-response` uses,
|
|
507
|
+
* so an app-card answer and a channel answer resolve identically.
|
|
508
|
+
*/
|
|
509
|
+
async function resolveAskQuestionInteraction(
|
|
510
|
+
request: GuardianRequestWire,
|
|
511
|
+
decision: ResolverDecision,
|
|
512
|
+
): Promise<ResolverResult> {
|
|
513
|
+
const interaction = pendingInteractions.get(request.id);
|
|
514
|
+
if (!interaction || interaction.kind !== "question") {
|
|
515
|
+
// The parked prompt is gone (answered elsewhere, timed out, or the daemon
|
|
516
|
+
// restarted). The committed decision stands; there is just nothing left to
|
|
517
|
+
// resume.
|
|
518
|
+
return { ok: false, reason: "no_pending_question_interaction" };
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const { orderedIds, optionsById } = readBatchMetadata(interaction);
|
|
522
|
+
if (orderedIds.length !== 1) {
|
|
523
|
+
// Channel cards are only created for single-question batches (the
|
|
524
|
+
// promotion gate enforces it); a multi-question interaction cannot be
|
|
525
|
+
// answered by one decision.
|
|
526
|
+
return { ok: false, reason: "question_batch_not_single" };
|
|
527
|
+
}
|
|
528
|
+
const questionId = orderedIds[0]!;
|
|
529
|
+
|
|
530
|
+
let submission: QuestionBatchSubmission;
|
|
531
|
+
const answerSelection = decision.userText
|
|
532
|
+
? parseQuestionAnswerActionId(decision.userText.trim())
|
|
533
|
+
: null;
|
|
534
|
+
if (answerSelection?.kind === "skip") {
|
|
535
|
+
submission = { questionId, kind: "skip" };
|
|
536
|
+
} else if (answerSelection?.kind === "option") {
|
|
537
|
+
const optionId = (optionsById[questionId] ?? [])[answerSelection.index];
|
|
538
|
+
if (!optionId) {
|
|
539
|
+
return { ok: false, reason: "question_option_index_out_of_range" };
|
|
540
|
+
}
|
|
541
|
+
submission = { questionId, kind: "option", optionId };
|
|
542
|
+
} else if (decision.userText && decision.userText.trim().length > 0) {
|
|
543
|
+
submission = {
|
|
544
|
+
questionId,
|
|
545
|
+
kind: "free_text",
|
|
546
|
+
text: decision.userText.trim(),
|
|
547
|
+
};
|
|
548
|
+
} else if (DENYING_ACTION_SET.has(decision.action)) {
|
|
549
|
+
submission = { questionId, kind: "skip" };
|
|
550
|
+
} else {
|
|
551
|
+
// Bare approval with no text (e.g. "CODE approve") — affirm without
|
|
552
|
+
// inventing content; the model reads the affirmation in context.
|
|
553
|
+
submission = { questionId, kind: "free_text", text: "Yes" };
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const outcome = resolvePendingQuestion(request.id, {
|
|
557
|
+
kind: "submit",
|
|
558
|
+
submissions: [submission],
|
|
559
|
+
});
|
|
560
|
+
if (outcome.status !== "resolved") {
|
|
561
|
+
log.warn(
|
|
562
|
+
{
|
|
563
|
+
event: "resolver_ask_question_not_resolved",
|
|
564
|
+
requestId: request.id,
|
|
565
|
+
outcome: outcome.status,
|
|
566
|
+
...(outcome.status === "invalid" ? { message: outcome.message } : {}),
|
|
567
|
+
},
|
|
568
|
+
"Ask-question resolver: pending interaction did not resolve",
|
|
569
|
+
);
|
|
570
|
+
return {
|
|
571
|
+
ok: false,
|
|
572
|
+
reason:
|
|
573
|
+
outcome.status === "invalid"
|
|
574
|
+
? "question_submission_invalid"
|
|
575
|
+
: "no_pending_question_interaction",
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
log.info(
|
|
580
|
+
{
|
|
581
|
+
event: "resolver_ask_question_applied",
|
|
582
|
+
requestId: request.id,
|
|
583
|
+
action: decision.action,
|
|
584
|
+
submissionKind: submission.kind,
|
|
585
|
+
conversationId: outcome.conversationId,
|
|
586
|
+
},
|
|
587
|
+
"Ask-question resolver: pending interaction resolved",
|
|
588
|
+
);
|
|
589
|
+
return { ok: true, applied: true };
|
|
590
|
+
}
|
|
591
|
+
|
|
490
592
|
/**
|
|
491
593
|
* The four introduction-card outcomes for an access request. The generic
|
|
492
594
|
* decision pair maps onto them: `approve_once` → `verify_code` (handshake),
|
|
@@ -658,9 +760,9 @@ async function deliverRequesterNotice(params: {
|
|
|
658
760
|
}
|
|
659
761
|
|
|
660
762
|
/**
|
|
661
|
-
* Emit the guardian-facing denial lifecycle
|
|
763
|
+
* Emit the guardian-facing denial lifecycle signal and, unless suppressed,
|
|
662
764
|
* deliver the "declined" notice to the requester. Both the `leave_unverified`
|
|
663
|
-
* and `block` outcomes call this for the lifecycle
|
|
765
|
+
* and `block` outcomes call this for the lifecycle signal, but the requester
|
|
664
766
|
* notice is delivered only for `block` (in denied mode) — `leave_unverified`
|
|
665
767
|
* always passes `suppressRequesterNotice: true`, staying a silent park at
|
|
666
768
|
* `unverified`. The notice text is a plain decline that does not reveal whether
|
|
@@ -712,6 +814,12 @@ async function notifyRequesterOfDenial(params: {
|
|
|
712
814
|
});
|
|
713
815
|
}
|
|
714
816
|
|
|
817
|
+
// Exactly one signal per denial: the payload's `decision: "denied"`
|
|
818
|
+
// carries the verdict, and the pipeline can only dedupe within a single
|
|
819
|
+
// event stream — a second event name would materialize a second
|
|
820
|
+
// conversation for the same decision. The approve path holds the same
|
|
821
|
+
// one-signal invariant via `verification_sent` standing in for
|
|
822
|
+
// `guardian_decision`.
|
|
715
823
|
if (channelDeliveryContext) {
|
|
716
824
|
void emitNotificationSignal({
|
|
717
825
|
sourceEventName: "ingress.trusted_contact.guardian_decision",
|
|
@@ -726,20 +834,6 @@ async function notifyRequesterOfDenial(params: {
|
|
|
726
834
|
contextPayload: deniedPayload,
|
|
727
835
|
dedupeKey: `trusted-contact:guardian-decision:${requestId}`,
|
|
728
836
|
});
|
|
729
|
-
|
|
730
|
-
void emitNotificationSignal({
|
|
731
|
-
sourceEventName: "ingress.trusted_contact.denied",
|
|
732
|
-
sourceChannel: channel,
|
|
733
|
-
sourceContextId: conversationId ?? "",
|
|
734
|
-
attentionHints: {
|
|
735
|
-
requiresAction: false,
|
|
736
|
-
urgency: "low",
|
|
737
|
-
isAsyncBackground: false,
|
|
738
|
-
visibleInSourceNow: false,
|
|
739
|
-
},
|
|
740
|
-
contextPayload: deniedPayload,
|
|
741
|
-
dedupeKey: `trusted-contact:denied:${requestId}`,
|
|
742
|
-
});
|
|
743
837
|
}
|
|
744
838
|
}
|
|
745
839
|
|
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
couldBeControlMarker,
|
|
5
5
|
ESCALATE_VERDICT_TOKEN,
|
|
6
6
|
HOLD_VERDICT_TOKEN,
|
|
7
|
+
isIncompleteControlMarkerTail,
|
|
8
|
+
MINIMIZE_ROOM_MARKER,
|
|
7
9
|
stripInternalSpeechMarkers,
|
|
8
10
|
} from "../voice-control-protocol.js";
|
|
9
11
|
|
|
@@ -46,3 +48,58 @@ describe("front-door verdict tokens", () => {
|
|
|
46
48
|
);
|
|
47
49
|
});
|
|
48
50
|
});
|
|
51
|
+
|
|
52
|
+
describe("minimize-room marker", () => {
|
|
53
|
+
test("marker constant is the expected bracketed form", () => {
|
|
54
|
+
expect(MINIMIZE_ROOM_MARKER).toBe("[-1]");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("stripInternalSpeechMarkers removes the marker so it is never spoken", () => {
|
|
58
|
+
expect(
|
|
59
|
+
stripInternalSpeechMarkers("Done [-1] here").replace(/\s+/g, " "),
|
|
60
|
+
).toBe("Done here");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("couldBeControlMarker holds the marker and its streaming prefixes", () => {
|
|
64
|
+
for (const text of ["[", "[-", "[-1", "[-1]", "[-1] trailing"]) {
|
|
65
|
+
expect(couldBeControlMarker(text)).toBe(true);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("a bracket prefix that disproves the marker is not held", () => {
|
|
70
|
+
expect(couldBeControlMarker("[- something else")).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("isIncompleteControlMarkerTail", () => {
|
|
75
|
+
test("strict prefixes of any marker are incomplete", () => {
|
|
76
|
+
for (const tail of ["[", "[-", "[-1", "[END_CAL", "[ASK_GUARDIAN_APPRO"]) {
|
|
77
|
+
expect(isIncompleteControlMarkerTail(tail)).toBe(true);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("complete literal markers are not held", () => {
|
|
82
|
+
for (const tail of ["[-1]", "[END_CALL]", "[0] answer", "[-1] look here"]) {
|
|
83
|
+
expect(isIncompleteControlMarkerTail(tail)).toBe(false);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("guardian-approval is judged by the balanced parser, not the first bracket", () => {
|
|
88
|
+
const streaming =
|
|
89
|
+
'[ASK_GUARDIAN_APPROVAL: {"question": "ok]?", "options": ["a", "b"';
|
|
90
|
+
expect(isIncompleteControlMarkerTail(streaming)).toBe(true);
|
|
91
|
+
expect(isIncompleteControlMarkerTail(`${streaming}]}]`)).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("colon-style markers terminate at their first bracket", () => {
|
|
95
|
+
expect(isIncompleteControlMarkerTail("[ASK_GUARDIAN: may I")).toBe(true);
|
|
96
|
+
expect(isIncompleteControlMarkerTail("[ASK_GUARDIAN: may I?]")).toBe(false);
|
|
97
|
+
expect(isIncompleteControlMarkerTail("[USER_ANSWERED: yes")).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("non-marker bracket text is not held", () => {
|
|
101
|
+
for (const tail of ["[- something else", "[sic]", '["a", "b"]']) {
|
|
102
|
+
expect(isIncompleteControlMarkerTail(tail)).toBe(false);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|