@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
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
channelSupportsGuardianQuestionCards,
|
|
5
|
+
channelSupportsInlineOptions,
|
|
6
|
+
conversationSupportsGuardianQuestionCards,
|
|
7
|
+
} from "../channel-ui-capability.js";
|
|
8
|
+
|
|
9
|
+
// Single source of truth for which channels' adapters can render inline
|
|
10
|
+
// tappable options. `resolveChannelCapabilities` populates
|
|
11
|
+
// `ChannelCapabilities.supportsInlineOptions` from this, and the approval
|
|
12
|
+
// delivery path reads it directly (retiring the old RICH_APPROVAL_CHANNELS set).
|
|
13
|
+
describe("channelSupportsInlineOptions", () => {
|
|
14
|
+
test("true for channels with an inline-button adapter", () => {
|
|
15
|
+
expect(channelSupportsInlineOptions("telegram")).toBe(true);
|
|
16
|
+
expect(channelSupportsInlineOptions("whatsapp")).toBe(true);
|
|
17
|
+
expect(channelSupportsInlineOptions("slack")).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("false for the app and text/voice-only channels", () => {
|
|
21
|
+
expect(channelSupportsInlineOptions("vellum")).toBe(false);
|
|
22
|
+
expect(channelSupportsInlineOptions("phone")).toBe(false);
|
|
23
|
+
expect(channelSupportsInlineOptions("email")).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("false for unknown and empty channel ids", () => {
|
|
27
|
+
expect(channelSupportsInlineOptions("")).toBe(false);
|
|
28
|
+
expect(channelSupportsInlineOptions("mystery")).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Strict subset of the inline-options channels: only channels with a
|
|
33
|
+
// notification adapter that renders card actions can receive a parked
|
|
34
|
+
// ask_question as a guardian-request card. WhatsApp renders approval buttons
|
|
35
|
+
// on direct sends but has no notification adapter, so it must stay false —
|
|
36
|
+
// parking a question for it would hang the turn with no card ever delivered.
|
|
37
|
+
describe("channelSupportsGuardianQuestionCards", () => {
|
|
38
|
+
test("true only for channels with a card-rendering notification adapter", () => {
|
|
39
|
+
expect(channelSupportsGuardianQuestionCards("telegram")).toBe(true);
|
|
40
|
+
expect(channelSupportsGuardianQuestionCards("slack")).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("false for whatsapp (approval buttons but no notification adapter)", () => {
|
|
44
|
+
expect(channelSupportsGuardianQuestionCards("whatsapp")).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("false for the app, voice, unknown, and empty ids", () => {
|
|
48
|
+
expect(channelSupportsGuardianQuestionCards("vellum")).toBe(false);
|
|
49
|
+
expect(channelSupportsGuardianQuestionCards("phone")).toBe(false);
|
|
50
|
+
expect(channelSupportsGuardianQuestionCards("")).toBe(false);
|
|
51
|
+
expect(channelSupportsGuardianQuestionCards("mystery")).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe("conversationSupportsGuardianQuestionCards", () => {
|
|
56
|
+
test("reads the channel from per-turn capabilities, then the structural fallback", () => {
|
|
57
|
+
expect(
|
|
58
|
+
conversationSupportsGuardianQuestionCards({
|
|
59
|
+
currentTurnChannelCapabilities: {
|
|
60
|
+
supportsDynamicUi: false,
|
|
61
|
+
channel: "telegram",
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
).toBe(true);
|
|
65
|
+
expect(
|
|
66
|
+
conversationSupportsGuardianQuestionCards({
|
|
67
|
+
channelCapabilities: { supportsDynamicUi: false, channel: "slack" },
|
|
68
|
+
}),
|
|
69
|
+
).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("false when the channel is card-less or unknown", () => {
|
|
73
|
+
expect(
|
|
74
|
+
conversationSupportsGuardianQuestionCards({
|
|
75
|
+
channelCapabilities: { supportsDynamicUi: false, channel: "whatsapp" },
|
|
76
|
+
}),
|
|
77
|
+
).toBe(false);
|
|
78
|
+
expect(
|
|
79
|
+
conversationSupportsGuardianQuestionCards({
|
|
80
|
+
channelCapabilities: { supportsDynamicUi: true },
|
|
81
|
+
}),
|
|
82
|
+
).toBe(false);
|
|
83
|
+
expect(conversationSupportsGuardianQuestionCards({})).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -126,7 +126,7 @@ const { createSurfaceMutex, handleSurfaceAction } =
|
|
|
126
126
|
type SurfaceConversationContext =
|
|
127
127
|
import("../conversation-surfaces.js").SurfaceConversationContext;
|
|
128
128
|
type TrustContext = import("../trust-context-types.js").TrustContext;
|
|
129
|
-
type
|
|
129
|
+
type AssistantEvent = import("../../api/index.js").AssistantEvent;
|
|
130
130
|
type SurfaceType = import("../message-protocol.js").SurfaceType;
|
|
131
131
|
|
|
132
132
|
// ── Harness reset helper ───────────────────────────────────────────
|
|
@@ -145,7 +145,7 @@ function resetProcessHarness(): void {
|
|
|
145
145
|
// ── Surface-context harness ────────────────────────────────────────
|
|
146
146
|
|
|
147
147
|
interface HarnessContext extends SurfaceConversationContext {
|
|
148
|
-
sent:
|
|
148
|
+
sent: AssistantEvent[];
|
|
149
149
|
enqueueCalls: Array<{ content: string }>;
|
|
150
150
|
processCalls: Array<{ content: string }>;
|
|
151
151
|
}
|
|
@@ -153,7 +153,7 @@ interface HarnessContext extends SurfaceConversationContext {
|
|
|
153
153
|
function makeContext(
|
|
154
154
|
overrides?: Partial<SurfaceConversationContext>,
|
|
155
155
|
): HarnessContext {
|
|
156
|
-
const sent:
|
|
156
|
+
const sent: AssistantEvent[] = [];
|
|
157
157
|
const enqueueCalls: Array<{ content: string }> = [];
|
|
158
158
|
const processCalls: Array<{ content: string }> = [];
|
|
159
159
|
|
|
@@ -24,7 +24,7 @@ const realMemoryV3Gate = {
|
|
|
24
24
|
...(await import("../../config/memory-v3-gate.js")),
|
|
25
25
|
};
|
|
26
26
|
const realV2Qdrant = {
|
|
27
|
-
...(await import("../../plugins/defaults/memory/
|
|
27
|
+
...(await import("../../plugins/defaults/memory/substrate/qdrant.js")),
|
|
28
28
|
};
|
|
29
29
|
const realSectionDenseStore = {
|
|
30
30
|
...(await import("../../plugins/defaults/memory/v3/section-dense-store.js")),
|
|
@@ -86,7 +86,7 @@ function makeDeps(opts: {
|
|
|
86
86
|
: { provider: "gemini" as const, model: "m", dim: opts.probeDim },
|
|
87
87
|
),
|
|
88
88
|
readConceptPageCollectionDim: mock(async () => {
|
|
89
|
-
if (opts.committedDimError) throw opts.committedDimError;
|
|
89
|
+
if (opts.committedDimError) {throw opts.committedDimError;}
|
|
90
90
|
return opts.committedDim ?? null;
|
|
91
91
|
}),
|
|
92
92
|
decideEmbeddingReconcile: mock(() => opts.decision),
|
|
@@ -360,7 +360,7 @@ async function withDefaultDepsMocks(opts: {
|
|
|
360
360
|
realMemoryV3Gate.isMemoryV3Live,
|
|
361
361
|
),
|
|
362
362
|
}));
|
|
363
|
-
mock.module("../../plugins/defaults/memory/
|
|
363
|
+
mock.module("../../plugins/defaults/memory/substrate/qdrant.js", () => ({
|
|
364
364
|
...realV2Qdrant,
|
|
365
365
|
ensureConceptPageCollection: delegate(
|
|
366
366
|
spies.ensureConceptPageCollection,
|
|
@@ -42,12 +42,9 @@ mock.module("../../plugins/defaults/memory/memory-recall-log-store.js", () => ({
|
|
|
42
42
|
backfillMemoryRecallLogMessageId: () => {},
|
|
43
43
|
}));
|
|
44
44
|
|
|
45
|
-
mock.module(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
backfillMemoryV2ActivationMessageId: () => {},
|
|
49
|
-
}),
|
|
50
|
-
);
|
|
45
|
+
mock.module("../../plugins/defaults/memory/v2/activation-log-store.js", () => ({
|
|
46
|
+
backfillMemoryV2ActivationMessageId: () => {},
|
|
47
|
+
}));
|
|
51
48
|
|
|
52
49
|
// ── Imports (after mocks) ────────────────────────────────────────────────────
|
|
53
50
|
import type { AgentEvent } from "../../agent/loop.js";
|
|
@@ -29,6 +29,7 @@ mock.module("../../persistence/llm-request-log-store.js", () => ({
|
|
|
29
29
|
}));
|
|
30
30
|
|
|
31
31
|
// ── Imports (after mocks) ─────────────────────────────────────────────────────
|
|
32
|
+
import type { AssistantEvent } from "../../api/index.js";
|
|
32
33
|
import { WEB_SEARCH_BACKEND_FAILURE_MESSAGE } from "../../tools/network/web-search-error.js";
|
|
33
34
|
import type {
|
|
34
35
|
EventHandlerDeps,
|
|
@@ -38,17 +39,16 @@ import {
|
|
|
38
39
|
createEventHandlerState,
|
|
39
40
|
dispatchAgentEvent,
|
|
40
41
|
} from "../conversation-agent-loop-handlers.js";
|
|
41
|
-
import type { ServerMessage } from "../message-protocol.js";
|
|
42
42
|
|
|
43
|
-
type ToolResultEvent = Extract<
|
|
43
|
+
type ToolResultEvent = Extract<AssistantEvent, { type: "tool_result" }>;
|
|
44
44
|
|
|
45
45
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
46
46
|
|
|
47
47
|
function createCollectorDeps(providerName = "anthropic"): {
|
|
48
48
|
deps: EventHandlerDeps;
|
|
49
|
-
events:
|
|
49
|
+
events: AssistantEvent[];
|
|
50
50
|
} {
|
|
51
|
-
const events:
|
|
51
|
+
const events: AssistantEvent[] = [];
|
|
52
52
|
const deps = {
|
|
53
53
|
ctx: {
|
|
54
54
|
conversationId: "conv-native-meta",
|
|
@@ -58,7 +58,7 @@ function createCollectorDeps(providerName = "anthropic"): {
|
|
|
58
58
|
markWorkspaceTopLevelDirty: () => {},
|
|
59
59
|
currentTurnSurfaces: [],
|
|
60
60
|
} as unknown as EventHandlerDeps["ctx"],
|
|
61
|
-
onEvent: (msg:
|
|
61
|
+
onEvent: (msg: AssistantEvent) => events.push(msg),
|
|
62
62
|
reqId: "req-native-meta",
|
|
63
63
|
isFirstMessage: false,
|
|
64
64
|
shouldGenerateTitle: false,
|
|
@@ -20,6 +20,7 @@ mock.module("../../persistence/llm-request-log-store.js", () => ({
|
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
22
|
// ── Imports (after mocks) ─────────────────────────────────────────────────────
|
|
23
|
+
import type { AssistantEvent } from "../../api/index.js";
|
|
23
24
|
import type {
|
|
24
25
|
EventHandlerDeps,
|
|
25
26
|
EventHandlerState,
|
|
@@ -30,7 +31,6 @@ import {
|
|
|
30
31
|
formatFetchStatusText,
|
|
31
32
|
formatSearchStatusText,
|
|
32
33
|
} from "../conversation-agent-loop-handlers.js";
|
|
33
|
-
import type { ServerMessage } from "../message-protocol.js";
|
|
34
34
|
|
|
35
35
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
36
36
|
|
|
@@ -68,7 +68,7 @@ function createCollectorDeps(): {
|
|
|
68
68
|
markWorkspaceTopLevelDirty: () => {},
|
|
69
69
|
currentTurnSurfaces: [],
|
|
70
70
|
} as unknown as EventHandlerDeps["ctx"],
|
|
71
|
-
onEvent: (_msg:
|
|
71
|
+
onEvent: (_msg: AssistantEvent) => {},
|
|
72
72
|
reqId: "req-status-text",
|
|
73
73
|
isFirstMessage: false,
|
|
74
74
|
shouldGenerateTitle: false,
|
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
export interface DynamicUiCapabilityView {
|
|
9
9
|
readonly currentTurnChannelCapabilities?: {
|
|
10
10
|
readonly supportsDynamicUi: boolean;
|
|
11
|
+
readonly channel?: string;
|
|
12
|
+
};
|
|
13
|
+
readonly channelCapabilities?: {
|
|
14
|
+
readonly supportsDynamicUi: boolean;
|
|
15
|
+
readonly channel?: string;
|
|
11
16
|
};
|
|
12
|
-
readonly channelCapabilities?: { readonly supportsDynamicUi: boolean };
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
/**
|
|
@@ -30,3 +34,68 @@ export function conversationSupportsDynamicUi(
|
|
|
30
34
|
conversation.channelCapabilities;
|
|
31
35
|
return caps?.supportsDynamicUi !== false;
|
|
32
36
|
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Channels whose adapter can render inline tappable options — approval buttons
|
|
40
|
+
* today, question option pickers next. Single source of truth: `resolveChannelCapabilities`
|
|
41
|
+
* populates `ChannelCapabilities.supportsInlineOptions` from this, and the approval
|
|
42
|
+
* delivery path reads it directly, so no feature re-hardcodes its own channel set.
|
|
43
|
+
*
|
|
44
|
+
* Distinct from `supportsDynamicUi` (which gates the app's dynamic-UI surfaces): a
|
|
45
|
+
* text-only channel like Telegram renders inline buttons yet has no dynamic UI.
|
|
46
|
+
*/
|
|
47
|
+
const INLINE_OPTIONS_CHANNELS: ReadonlySet<string> = new Set([
|
|
48
|
+
"telegram",
|
|
49
|
+
"whatsapp",
|
|
50
|
+
"slack",
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Whether a channel's adapter can render inline tappable options. Pure
|
|
55
|
+
* set-membership on the canonical channel id (no normalization).
|
|
56
|
+
*/
|
|
57
|
+
export function channelSupportsInlineOptions(channel: string): boolean {
|
|
58
|
+
return INLINE_OPTIONS_CHANNELS.has(channel);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Channels where a parked `ask_question` can be delivered as a guardian-request
|
|
63
|
+
* card with tappable answer options — i.e. channels with a notification
|
|
64
|
+
* adapter that renders card actions (`notifications/adapters/`). A strict
|
|
65
|
+
* subset of {@link INLINE_OPTIONS_CHANNELS}: WhatsApp renders approval buttons
|
|
66
|
+
* on direct sends but has no notification adapter yet, so parking a question
|
|
67
|
+
* for it would hang the turn with no card ever delivered.
|
|
68
|
+
*
|
|
69
|
+
* Gates BOTH the `ask_question` park decision (tool context) and the
|
|
70
|
+
* guardian-request promotion, so the two can never disagree. Onboarding a
|
|
71
|
+
* channel = add its notification adapter, then add it here.
|
|
72
|
+
*/
|
|
73
|
+
const GUARDIAN_QUESTION_CARD_CHANNELS: ReadonlySet<string> = new Set([
|
|
74
|
+
"telegram",
|
|
75
|
+
"slack",
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Whether a parked question can be delivered to this channel as a
|
|
80
|
+
* guardian-request card. Pure set-membership on the canonical channel id.
|
|
81
|
+
*/
|
|
82
|
+
export function channelSupportsGuardianQuestionCards(channel: string): boolean {
|
|
83
|
+
return GUARDIAN_QUESTION_CARD_CHANNELS.has(channel);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Whether the conversation's current-turn channel can receive a parked
|
|
88
|
+
* question as a guardian-request card. Opt-in per channel: defaults to
|
|
89
|
+
* `false` when the channel is unknown. Prefers the per-turn capabilities,
|
|
90
|
+
* falling back to the structural channel capabilities.
|
|
91
|
+
*/
|
|
92
|
+
export function conversationSupportsGuardianQuestionCards(
|
|
93
|
+
conversation: DynamicUiCapabilityView,
|
|
94
|
+
): boolean {
|
|
95
|
+
const caps =
|
|
96
|
+
conversation.currentTurnChannelCapabilities ??
|
|
97
|
+
conversation.channelCapabilities;
|
|
98
|
+
return caps?.channel
|
|
99
|
+
? channelSupportsGuardianQuestionCards(caps.channel)
|
|
100
|
+
: false;
|
|
101
|
+
}
|
|
@@ -11,6 +11,7 @@ import type pino from "pino";
|
|
|
11
11
|
import { v4 as uuid } from "uuid";
|
|
12
12
|
|
|
13
13
|
import type { AgentEvent } from "../agent/loop.js";
|
|
14
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
14
15
|
import type {
|
|
15
16
|
TurnChannelContext,
|
|
16
17
|
TurnInterfaceContext,
|
|
@@ -54,7 +55,7 @@ import { endSection, markSection } from "../persistence/slow-sync-log.js";
|
|
|
54
55
|
import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
|
|
55
56
|
import { indexMessageNow } from "../plugins/defaults/memory/indexer.js";
|
|
56
57
|
import { backfillMemoryRecallLogMessageId } from "../plugins/defaults/memory/memory-recall-log-store.js";
|
|
57
|
-
import { backfillMemoryV2ActivationMessageId } from "../plugins/defaults/memory/
|
|
58
|
+
import { backfillMemoryV2ActivationMessageId } from "../plugins/defaults/memory/v2/activation-log-store.js";
|
|
58
59
|
import { backfillMemoryV3SelectionMessageId } from "../plugins/defaults/memory/v3/shadow-plugin.js";
|
|
59
60
|
import { resolveMediaSourceData } from "../providers/media-resolve.js";
|
|
60
61
|
import type {
|
|
@@ -131,7 +132,6 @@ import {
|
|
|
131
132
|
} from "./inflight-message-content.js";
|
|
132
133
|
import type {
|
|
133
134
|
CardSurfaceData,
|
|
134
|
-
ServerMessage,
|
|
135
135
|
SurfaceAction,
|
|
136
136
|
UiSurfaceShow,
|
|
137
137
|
} from "./message-protocol.js";
|
|
@@ -511,7 +511,7 @@ export interface EventHandlerState {
|
|
|
511
511
|
/** Immutable context shared across event handlers within a single agent loop run. */
|
|
512
512
|
export interface EventHandlerDeps {
|
|
513
513
|
readonly ctx: Conversation;
|
|
514
|
-
readonly onEvent: (msg:
|
|
514
|
+
readonly onEvent: (msg: AssistantEvent) => void;
|
|
515
515
|
readonly reqId: string;
|
|
516
516
|
readonly isFirstMessage: boolean;
|
|
517
517
|
/** Whether the conversation title is replaceable — controls firstAssistantText accumulation for title generation. */
|
|
@@ -3309,7 +3309,7 @@ export async function dispatchAgentEvent(
|
|
|
3309
3309
|
case "compaction_circuit_open":
|
|
3310
3310
|
case "compaction_circuit_closed":
|
|
3311
3311
|
// Circuit-breaker transitions are already in wire-contract shape
|
|
3312
|
-
// (a subset of
|
|
3312
|
+
// (a subset of AssistantEvent), so forward them to the client sink
|
|
3313
3313
|
// unchanged. They drive the client's "auto-compaction paused"
|
|
3314
3314
|
// banner.
|
|
3315
3315
|
deps.onEvent(event);
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
CheckpointDecision,
|
|
16
16
|
} from "../agent/loop.js";
|
|
17
17
|
import { createAssistantMessage } from "../agent/message-types.js";
|
|
18
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
18
19
|
import type {
|
|
19
20
|
ChannelId,
|
|
20
21
|
InterfaceId,
|
|
@@ -116,7 +117,7 @@ import {
|
|
|
116
117
|
registerInflightTurn,
|
|
117
118
|
unregisterInflightTurn,
|
|
118
119
|
} from "./inflight-turn-registry.js";
|
|
119
|
-
import type {
|
|
120
|
+
import type { UsageStats } from "./message-protocol.js";
|
|
120
121
|
import type { TrustContext } from "./trust-context-types.js";
|
|
121
122
|
import { resolveTurnCallSite } from "./turn-call-site.js";
|
|
122
123
|
import { runWithLatencySubSpans } from "./turn-latency-sub-spans.js";
|
|
@@ -240,7 +241,7 @@ export async function runAgentLoopImpl(
|
|
|
240
241
|
ctx: Conversation,
|
|
241
242
|
content: string,
|
|
242
243
|
userMessageId: string,
|
|
243
|
-
onEvent: (msg:
|
|
244
|
+
onEvent: (msg: AssistantEvent) => void,
|
|
244
245
|
options?: {
|
|
245
246
|
isInteractive?: boolean;
|
|
246
247
|
isUserMessage?: boolean;
|
|
@@ -1669,7 +1670,13 @@ export async function runAgentLoopImpl(
|
|
|
1669
1670
|
// the API, enabling stable prefix caching across turns. Compaction
|
|
1670
1671
|
// consolidates when it summarizes old messages (cache miss is expected).
|
|
1671
1672
|
|
|
1672
|
-
|
|
1673
|
+
// kickDrainQueue never rejects — a drain failure here would otherwise be
|
|
1674
|
+
// an unhandled rejection that strands the queue with nothing left to
|
|
1675
|
+
// re-trigger it.
|
|
1676
|
+
void ctx.kickDrainQueue(
|
|
1677
|
+
yieldedForHandoff ? "checkpoint_handoff" : "loop_complete",
|
|
1678
|
+
"agent_loop_finally",
|
|
1679
|
+
);
|
|
1673
1680
|
}
|
|
1674
1681
|
}
|
|
1675
1682
|
|
|
@@ -1680,7 +1687,7 @@ function emitUsage(
|
|
|
1680
1687
|
inputTokens: number,
|
|
1681
1688
|
outputTokens: number,
|
|
1682
1689
|
model: string,
|
|
1683
|
-
onEvent: (msg:
|
|
1690
|
+
onEvent: (msg: AssistantEvent) => void,
|
|
1684
1691
|
actor: UsageActor,
|
|
1685
1692
|
requestId: string | null = null,
|
|
1686
1693
|
cacheCreationInputTokens = 0,
|
|
@@ -1769,7 +1776,7 @@ export async function applyCompactionResult(
|
|
|
1769
1776
|
summaryCallSite?: LLMCallSite;
|
|
1770
1777
|
summaryOverrideProfile?: string | null;
|
|
1771
1778
|
},
|
|
1772
|
-
onEvent: (msg:
|
|
1779
|
+
onEvent: (msg: AssistantEvent) => void,
|
|
1773
1780
|
reqId: string | null,
|
|
1774
1781
|
options: {
|
|
1775
1782
|
slackContextCompactionWatermarkTs?: string | null;
|
|
@@ -7,6 +7,7 @@ const log = getLogger("conversation-evictor");
|
|
|
7
7
|
/** Minimal interface a conversation must satisfy to be evictable. */
|
|
8
8
|
export interface EvictableConversation {
|
|
9
9
|
isProcessing(): boolean;
|
|
10
|
+
hasQueuedMessages(): boolean;
|
|
10
11
|
dispose(): void;
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -63,7 +64,12 @@ export class ConversationEvictor {
|
|
|
63
64
|
options?.sweepIntervalMs ?? DEFAULT_SWEEP_INTERVAL_MS;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Abort any in-flight subagents belonging to a conversation as it's evicted.
|
|
69
|
+
* Terminal subagent metadata is left readable — an evicted conversation is
|
|
70
|
+
* resumable from the database, and its next turn may still `subagent_read` a
|
|
71
|
+
* completed child's result.
|
|
72
|
+
*/
|
|
67
73
|
onEvict(conversationId: string): void {
|
|
68
74
|
getSubagentManager().abortAllForParent(conversationId);
|
|
69
75
|
}
|
|
@@ -125,10 +131,19 @@ export class ConversationEvictor {
|
|
|
125
131
|
};
|
|
126
132
|
|
|
127
133
|
// Phase 1: TTL eviction — remove conversations idle longer than ttlMs.
|
|
134
|
+
// A conversation with queued messages is not idle: the queue drains via an
|
|
135
|
+
// async dispatch after the current turn's `finally`, so `isProcessing()`
|
|
136
|
+
// can read false while a queued turn (e.g. a subagent completion wake) is
|
|
137
|
+
// still pending. Disposing in that gap would silently drop the queued
|
|
138
|
+
// messages.
|
|
128
139
|
for (const [id, conversation] of this.conversations) {
|
|
129
140
|
const lastAccessTime = this.lastAccess.get(id) ?? 0;
|
|
130
141
|
if (now - lastAccessTime < this.ttlMs) continue;
|
|
131
|
-
if (
|
|
142
|
+
if (
|
|
143
|
+
conversation.isProcessing() ||
|
|
144
|
+
conversation.hasQueuedMessages() ||
|
|
145
|
+
this.shouldProtect(id)
|
|
146
|
+
) {
|
|
132
147
|
result.skipped++;
|
|
133
148
|
continue;
|
|
134
149
|
}
|
|
@@ -202,8 +217,15 @@ export class ConversationEvictor {
|
|
|
202
217
|
private idleConversationsByLru(): Array<[string, EvictableConversation]> {
|
|
203
218
|
const idle: Array<[string, EvictableConversation, number]> = [];
|
|
204
219
|
for (const [id, conversation] of this.conversations) {
|
|
205
|
-
if (conversation.isProcessing())
|
|
206
|
-
|
|
220
|
+
if (conversation.isProcessing()) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (conversation.hasQueuedMessages()) {
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (this.shouldProtect(id)) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
207
229
|
idle.push([id, conversation, this.lastAccess.get(id) ?? 0]);
|
|
208
230
|
}
|
|
209
231
|
idle.sort((a, b) => a[2] - b[2]);
|
|
@@ -11,8 +11,7 @@ import { randomUUID } from "node:crypto";
|
|
|
11
11
|
|
|
12
12
|
import { updateConversationTitle } from "../persistence/conversation-crud.js";
|
|
13
13
|
import { getOrCreateConversation as getOrCreateConversationKey } from "../persistence/conversation-key-store.js";
|
|
14
|
-
import {
|
|
15
|
-
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
14
|
+
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
16
15
|
import { getLogger } from "../util/logger.js";
|
|
17
16
|
import { getOrCreateConversation } from "./conversation-store.js";
|
|
18
17
|
import { processMessageInBackground } from "./process-message.js";
|
|
@@ -72,19 +71,17 @@ export async function launchConversation(
|
|
|
72
71
|
updateConversationTitle(conversationId, params.title, 0);
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
type: "open_conversation",
|
|
79
|
-
conversationId,
|
|
80
|
-
...(params.title ? { title: params.title } : {}),
|
|
81
|
-
...(params.anchorMessageId
|
|
82
|
-
? { anchorMessageId: params.anchorMessageId }
|
|
83
|
-
: {}),
|
|
84
|
-
...(params.focus !== undefined ? { focus: params.focus } : {}),
|
|
85
|
-
},
|
|
74
|
+
broadcastMessage(
|
|
75
|
+
{
|
|
76
|
+
type: "open_conversation",
|
|
86
77
|
conversationId,
|
|
87
|
-
|
|
78
|
+
...(params.title ? { title: params.title } : {}),
|
|
79
|
+
...(params.anchorMessageId
|
|
80
|
+
? { anchorMessageId: params.anchorMessageId }
|
|
81
|
+
: {}),
|
|
82
|
+
...(params.focus !== undefined ? { focus: params.focus } : {}),
|
|
83
|
+
},
|
|
84
|
+
conversationId,
|
|
88
85
|
);
|
|
89
86
|
|
|
90
87
|
processMessageInBackground(conversationId, params.seedPrompt, {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../agent/attachments.js";
|
|
17
17
|
import { optimizeImageForTransport } from "../agent/image-optimize.js";
|
|
18
18
|
import { createUserMessage } from "../agent/message-types.js";
|
|
19
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
19
20
|
import type {
|
|
20
21
|
TurnChannelContext,
|
|
21
22
|
TurnInterfaceContext,
|
|
@@ -64,7 +65,6 @@ import { withSqliteRetry } from "../util/sqlite-retry.js";
|
|
|
64
65
|
import type { MessageQueue } from "./conversation-queue-manager.js";
|
|
65
66
|
import type { SlackInboundMessageMetadata } from "./handlers/shared.js";
|
|
66
67
|
import type {
|
|
67
|
-
ServerMessage,
|
|
68
68
|
UserMessageAttachment,
|
|
69
69
|
} from "./message-protocol.js";
|
|
70
70
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
@@ -187,10 +187,10 @@ function resolveIngressSecretTarget(
|
|
|
187
187
|
for (const detectedType of detectedTypes) {
|
|
188
188
|
const normalizedType = normalizeIngressSecretTypeLabel(detectedType);
|
|
189
189
|
const mapped = INGRESS_SECRET_TARGETS[normalizedType];
|
|
190
|
-
if (!mapped) continue;
|
|
190
|
+
if (!mapped) {continue;}
|
|
191
191
|
mappedTargets.set(`${mapped.service}:${mapped.field}`, mapped);
|
|
192
192
|
}
|
|
193
|
-
if (mappedTargets.size === 1) return mappedTargets.values().next().value!;
|
|
193
|
+
if (mappedTargets.size === 1) {return mappedTargets.values().next().value!;}
|
|
194
194
|
|
|
195
195
|
return {
|
|
196
196
|
service: "detected",
|
|
@@ -275,7 +275,7 @@ function computeReferenceImageDimensions(
|
|
|
275
275
|
mediaType: string,
|
|
276
276
|
): { width: number; height: number } | null {
|
|
277
277
|
const bytes = getAttachmentContent(attachmentId);
|
|
278
|
-
if (!bytes) return null;
|
|
278
|
+
if (!bytes) {return null;}
|
|
279
279
|
const optimized = optimizeImageForTransport(
|
|
280
280
|
bytes.toString("base64"),
|
|
281
281
|
mediaType,
|
|
@@ -330,7 +330,7 @@ function materializeUserAttachment(
|
|
|
330
330
|
);
|
|
331
331
|
return stored ? { kind: "stored", stored } : { kind: "transient" };
|
|
332
332
|
}
|
|
333
|
-
if (!a.data) return { kind: "rejected" };
|
|
333
|
+
if (!a.data) {return { kind: "rejected" };}
|
|
334
334
|
const validation = validateAttachmentUpload(a.filename, a.mimeType);
|
|
335
335
|
if (!validation.ok) {
|
|
336
336
|
log.warn(
|
|
@@ -395,7 +395,7 @@ function referenceBlockForAttachment(
|
|
|
395
395
|
function inlineBlockForAttachment(
|
|
396
396
|
a: MessageAttachmentInput,
|
|
397
397
|
): ContentBlock | null {
|
|
398
|
-
if (!a.data) return null;
|
|
398
|
+
if (!a.data) {return null;}
|
|
399
399
|
return attachmentsToContentBlocks([a])[0] ?? null;
|
|
400
400
|
}
|
|
401
401
|
|
|
@@ -431,7 +431,7 @@ function prepareUserAttachmentReferences(
|
|
|
431
431
|
});
|
|
432
432
|
continue;
|
|
433
433
|
}
|
|
434
|
-
if (outcome.kind === "rejected") continue;
|
|
434
|
+
if (outcome.kind === "rejected") {continue;}
|
|
435
435
|
// transient: keep the upload by inlining its bytes (dropped only when the
|
|
436
436
|
// recoverable failure left us with no bytes to inline).
|
|
437
437
|
const inline = inlineBlockForAttachment(a);
|
|
@@ -450,24 +450,24 @@ function prepareUserAttachmentReferences(
|
|
|
450
450
|
function extractTurnChannelContext(
|
|
451
451
|
metadata?: Record<string, unknown>,
|
|
452
452
|
): TurnChannelContext | null {
|
|
453
|
-
if (!metadata) return null;
|
|
453
|
+
if (!metadata) {return null;}
|
|
454
454
|
const userMessageChannel = parseChannelId(metadata.userMessageChannel);
|
|
455
455
|
const assistantMessageChannel = parseChannelId(
|
|
456
456
|
metadata.assistantMessageChannel,
|
|
457
457
|
);
|
|
458
|
-
if (!userMessageChannel || !assistantMessageChannel) return null;
|
|
458
|
+
if (!userMessageChannel || !assistantMessageChannel) {return null;}
|
|
459
459
|
return { userMessageChannel, assistantMessageChannel };
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
function extractTurnInterfaceContext(
|
|
463
463
|
metadata?: Record<string, unknown>,
|
|
464
464
|
): TurnInterfaceContext | null {
|
|
465
|
-
if (!metadata) return null;
|
|
465
|
+
if (!metadata) {return null;}
|
|
466
466
|
const userMessageInterface = parseInterfaceId(metadata.userMessageInterface);
|
|
467
467
|
const assistantMessageInterface = parseInterfaceId(
|
|
468
468
|
metadata.assistantMessageInterface,
|
|
469
469
|
);
|
|
470
|
-
if (!userMessageInterface || !assistantMessageInterface) return null;
|
|
470
|
+
if (!userMessageInterface || !assistantMessageInterface) {return null;}
|
|
471
471
|
return { userMessageInterface, assistantMessageInterface };
|
|
472
472
|
}
|
|
473
473
|
|
|
@@ -530,7 +530,7 @@ export function buildSlackMetaForPersistence(params: {
|
|
|
530
530
|
export interface EnqueueMessageOptions {
|
|
531
531
|
content: string;
|
|
532
532
|
attachments?: UserMessageAttachment[];
|
|
533
|
-
onEvent?: (msg:
|
|
533
|
+
onEvent?: (msg: AssistantEvent) => void;
|
|
534
534
|
requestId?: string;
|
|
535
535
|
activeSurfaceId?: string;
|
|
536
536
|
currentPage?: string;
|
|
@@ -890,7 +890,7 @@ export async function persistQueuedMessageBody(
|
|
|
890
890
|
// though the store anchor was lost, then persist the corrected content.
|
|
891
891
|
let repairedBlocks: ContentBlock[] | null = null;
|
|
892
892
|
preparedAttachments.forEach((p, idx) => {
|
|
893
|
-
if (!p.link) return;
|
|
893
|
+
if (!p.link) {return;}
|
|
894
894
|
try {
|
|
895
895
|
const scopedAttachmentId = linkAttachmentToMessage(
|
|
896
896
|
persistedUserMessage.id,
|
|
@@ -982,7 +982,7 @@ export function redirectToSecurePrompt(
|
|
|
982
982
|
conversationId,
|
|
983
983
|
)
|
|
984
984
|
.then(async (result): Promise<void> => {
|
|
985
|
-
if (!result.value) return;
|
|
985
|
+
if (!result.value) {return;}
|
|
986
986
|
|
|
987
987
|
const { setSecureKeyAsync } = await import("../security/secure-keys.js");
|
|
988
988
|
const { upsertCredentialMetadata } =
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createAssistantMessage } from "../agent/message-types.js";
|
|
11
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
11
12
|
import { buildCallCompletionMessage } from "../calls/call-conversation-messages.js";
|
|
12
13
|
import {
|
|
13
14
|
registerCallCompletionNotifier,
|
|
@@ -23,7 +24,6 @@ import {
|
|
|
23
24
|
provenanceFromTrustContext,
|
|
24
25
|
} from "../persistence/conversation-crud.js";
|
|
25
26
|
import type { Message } from "../providers/types.js";
|
|
26
|
-
import type { ServerMessage } from "./message-protocol.js";
|
|
27
27
|
import type { TrustContext } from "./trust-context-types.js";
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -31,7 +31,7 @@ import type { TrustContext } from "./trust-context-types.js";
|
|
|
31
31
|
* invocation time. Properties are read lazily from this reference.
|
|
32
32
|
*/
|
|
33
33
|
export interface NotifierConversationContext {
|
|
34
|
-
sendToClient: (msg:
|
|
34
|
+
sendToClient: (msg: AssistantEvent) => void;
|
|
35
35
|
messages: Message[];
|
|
36
36
|
trustContext?: TrustContext;
|
|
37
37
|
}
|