@vellumai/assistant 0.10.12 → 0.11.0-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +264 -14
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +33 -2
- package/src/__tests__/app-conversation-ids.test.ts +204 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-group-tools.test.ts +279 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-lineage.test.ts +235 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/platform-callback-registration.test.ts +10 -10
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/resolve-app-id.test.ts +32 -0
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +26 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +587 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +482 -2
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/api/responses/subagent-detail.ts +13 -0
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/apps/app-store.ts +95 -4
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +178 -65
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/commands/webhooks.help.ts +9 -4
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
- package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/bundled-skills/schedule/SKILL.md +2 -0
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -38
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-lineage.ts +76 -0
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +8 -14
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +32 -16
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +1288 -439
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +298 -15
- package/src/permissions/checker.ts +102 -36
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +269 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/conversation-parent.ts +27 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +9 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/prompts/sections.ts +4 -16
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/subagents-routes.ts +35 -8
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/webhook-routes.ts +89 -30
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/apps/resolve-app-id.ts +15 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/conversation-groups/group_create.ts +63 -0
- package/src/tools/conversation-groups/group_list.ts +20 -0
- package/src/tools/conversation-groups/group_shared.ts +52 -0
- package/src/tools/conversation-groups/move_to_group.ts +106 -0
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/util/platform.ts +15 -0
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/tsconfig.plugin-api.json +1 -1
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { isInviteCodeRedemptionEnabled } from "@vellumai/gateway-client";
|
|
2
|
-
import {
|
|
3
|
-
normalizePublicBaseUrl,
|
|
4
|
-
resolveTwilioPublicBaseUrl,
|
|
5
|
-
} from "@vellumai/service-contracts/twilio-ingress";
|
|
2
|
+
import { z } from "zod";
|
|
6
3
|
|
|
7
4
|
import { resolveTwilioPhoneNumber } from "../calls/twilio-config.js";
|
|
8
5
|
import { hasTwilioCredentials } from "../calls/twilio-rest.js";
|
|
9
|
-
import { getIsPlatform } from "../config/env-registry.js";
|
|
10
6
|
import { getNestedValue, loadRawConfig } from "../config/loader.js";
|
|
7
|
+
import { hasWebhookRoutingConfigured } from "../config/webhook-routing.js";
|
|
11
8
|
import { credentialKey } from "../security/credential-key.js";
|
|
12
9
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
13
10
|
import { resolveWhatsAppDisplayNumber } from "./channel-invite-transports/whatsapp.js";
|
|
@@ -23,39 +20,95 @@ import type {
|
|
|
23
20
|
/** Remote check results are cached for 5 minutes before being considered stale. */
|
|
24
21
|
export const REMOTE_TTL_MS = 5 * 60 * 1000;
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Bot scopes the Slack manifest requests that the app cannot work without.
|
|
25
|
+
*
|
|
26
|
+
* Slack's install flow can return a token carrying a fraction of the manifest's
|
|
27
|
+
* scopes while `auth.test` still succeeds — a live install produced 2 of 18, and
|
|
28
|
+
* the first real API call failed with `missing_scope`. `auth.test` passing is
|
|
29
|
+
* therefore not evidence the install is usable; the granted set has to be read
|
|
30
|
+
* off the `x-oauth-scopes` response header and compared.
|
|
31
|
+
*
|
|
32
|
+
* Mirrors the non-optional half of `oauth_config.scopes.bot` in
|
|
33
|
+
* `skills/slack-app-setup/scripts/build-manifest.ts` (and its copy in
|
|
34
|
+
* `clients/web/src/utils/slack-manifest.ts`). Scopes the manifest marks
|
|
35
|
+
* declinable are deliberately absent: a workspace may refuse those at the
|
|
36
|
+
* consent screen, and flagging that choice as a fault would be noise.
|
|
37
|
+
*/
|
|
38
|
+
const SLACK_REQUIRED_BOT_SCOPES = [
|
|
39
|
+
"app_mentions:read",
|
|
40
|
+
"assistant:write",
|
|
41
|
+
"channels:history",
|
|
42
|
+
"channels:read",
|
|
43
|
+
"chat:write",
|
|
44
|
+
"groups:history",
|
|
45
|
+
"groups:read",
|
|
46
|
+
"im:history",
|
|
47
|
+
"im:read",
|
|
48
|
+
"im:write",
|
|
49
|
+
"mpim:history",
|
|
50
|
+
"mpim:read",
|
|
51
|
+
"users:read",
|
|
52
|
+
] as const;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Shape of a Slack `auth.test` response.
|
|
56
|
+
*
|
|
57
|
+
* Validated rather than cast: this crosses a runtime boundary, so a `ok` that
|
|
58
|
+
* arrives as a string would slip past a cast and make `!data.ok` decide on the
|
|
59
|
+
* wrong value. Unknown keys are ignored — Slack adds fields over time and a
|
|
60
|
+
* new one is not a reason to report the integration broken.
|
|
61
|
+
*/
|
|
62
|
+
const AuthTestResponseSchema = z.object({
|
|
63
|
+
ok: z.boolean(),
|
|
64
|
+
error: z.string().optional(),
|
|
65
|
+
team_id: z.string().optional(),
|
|
66
|
+
team: z.string().optional(),
|
|
67
|
+
user: z.string().optional(),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/** Slack returns `x-oauth-scopes` as a comma-separated list on every response. */
|
|
71
|
+
function parseGrantedScopes(raw: string | null): string[] | null {
|
|
72
|
+
if (raw === null) {
|
|
73
|
+
return null;
|
|
39
74
|
}
|
|
75
|
+
const scopes = raw
|
|
76
|
+
.split(",")
|
|
77
|
+
.map((scope) => scope.trim())
|
|
78
|
+
.filter(Boolean);
|
|
79
|
+
return scopes.length > 0 ? scopes : null;
|
|
40
80
|
}
|
|
41
81
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Compare what Slack granted against what the app needs.
|
|
84
|
+
*
|
|
85
|
+
* Passes when the header is unreadable: a check that cannot see the grant must
|
|
86
|
+
* not report a fault it has no evidence for. Reinstalling re-grants the scopes
|
|
87
|
+
* to the same token, so recovery needs no new credentials — but Slack forces an
|
|
88
|
+
* app "update" prompt first, and skipping it leaves the scopes unchanged.
|
|
89
|
+
*/
|
|
90
|
+
function scopeGrantCheck(rawHeader: string | null): ReadinessCheckResult {
|
|
91
|
+
const granted = parseGrantedScopes(rawHeader);
|
|
92
|
+
if (granted === null) {
|
|
93
|
+
return check(
|
|
94
|
+
"scopes_granted",
|
|
95
|
+
true,
|
|
96
|
+
"Slack did not report granted scopes — skipped",
|
|
97
|
+
"Slack did not report granted scopes — skipped",
|
|
98
|
+
);
|
|
52
99
|
}
|
|
53
100
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
101
|
+
const grantedSet = new Set(granted);
|
|
102
|
+
const missing = SLACK_REQUIRED_BOT_SCOPES.filter(
|
|
103
|
+
(scope) => !grantedSet.has(scope),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return check(
|
|
107
|
+
"scopes_granted",
|
|
108
|
+
missing.length === 0,
|
|
109
|
+
`Bot token carries all ${SLACK_REQUIRED_BOT_SCOPES.length} required scopes`,
|
|
110
|
+
`Bot token is missing ${missing.length} of ${SLACK_REQUIRED_BOT_SCOPES.length} required scopes (${missing.join(", ")}) — open the app at https://api.slack.com/apps, accept the update prompt, then OAuth & Permissions → Reinstall to Workspace`,
|
|
111
|
+
);
|
|
59
112
|
}
|
|
60
113
|
|
|
61
114
|
// ── Shared check helpers ────────────────────────────────────────────────────
|
|
@@ -298,13 +351,18 @@ const slackProbe: ChannelProbe = {
|
|
|
298
351
|
method: "POST",
|
|
299
352
|
headers: { Authorization: `Bearer ${botToken}` },
|
|
300
353
|
});
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
354
|
+
const parsed = AuthTestResponseSchema.safeParse(await res.json());
|
|
355
|
+
if (!parsed.success) {
|
|
356
|
+
return [
|
|
357
|
+
check(
|
|
358
|
+
"auth_test",
|
|
359
|
+
false,
|
|
360
|
+
"Slack auth.test ok",
|
|
361
|
+
`Slack auth.test returned an unexpected response shape: ${parsed.error.issues.map((i) => i.path.join(".") || "(root)").join(", ")}`,
|
|
362
|
+
),
|
|
363
|
+
];
|
|
364
|
+
}
|
|
365
|
+
const data = parsed.data;
|
|
308
366
|
if (!data.ok) {
|
|
309
367
|
return [
|
|
310
368
|
check(
|
|
@@ -334,6 +392,7 @@ const slackProbe: ChannelProbe = {
|
|
|
334
392
|
"Stored workspace matches bot token",
|
|
335
393
|
`Stored workspace ${storedTeamId} does not match bot token's workspace ${data.team_id ?? "unknown"} — run 'assistant channels slack reconnect' to refresh metadata`,
|
|
336
394
|
),
|
|
395
|
+
scopeGrantCheck(res.headers.get("x-oauth-scopes")),
|
|
337
396
|
];
|
|
338
397
|
} catch (err) {
|
|
339
398
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Periodic retry sweep for failed channel inbound events.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
5
6
|
import {
|
|
6
7
|
type ChannelId,
|
|
7
8
|
isChannelId,
|
|
@@ -12,7 +13,6 @@ import { isConversationBusyError } from "../daemon/conversation-messaging.js";
|
|
|
12
13
|
import { findConversation } from "../daemon/conversation-registry.js";
|
|
13
14
|
import { getDiskPressureStatus } from "../daemon/disk-pressure-guard.js";
|
|
14
15
|
import { classifyDiskPressureTurnPolicy } from "../daemon/disk-pressure-policy.js";
|
|
15
|
-
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
16
16
|
import type { TrustContext } from "../daemon/trust-context-types.js";
|
|
17
17
|
import { updateDeliveredSegmentCount } from "../persistence/delivery-channels.js";
|
|
18
18
|
import {
|
|
@@ -156,12 +156,22 @@ function parseStoredSlackInbound(
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
|
-
* Fallback
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* `
|
|
163
|
-
*
|
|
164
|
-
*
|
|
159
|
+
* Fallback when the payload carries no captured `slackInbound`: reconstruct
|
|
160
|
+
* what we can from the fields the payload has always carried, so the event
|
|
161
|
+
* still dedups on replay. `channelTs` mirrors the live
|
|
162
|
+
* `sourceMessageId ?? externalMessageId` derivation.
|
|
163
|
+
*
|
|
164
|
+
* Two kinds of event land here, not just one. Payloads stored before the
|
|
165
|
+
* capture existed are the obvious case and drain quickly. The durable case is
|
|
166
|
+
* a crash between `storePayload` (which runs at the top of the handler) and
|
|
167
|
+
* `storeInboundSlackMetadata` (which runs on dispatch, after the awaited Slack
|
|
168
|
+
* backfills) — `recoverOrphanedChannelEvents` promotes that orphan onto the
|
|
169
|
+
* sweep and it arrives here with a full `sourceMetadata` but no `slackInbound`.
|
|
170
|
+
*
|
|
171
|
+
* So anything the live path reads off `sourceMetadata` and renders into the
|
|
172
|
+
* turn has to be recovered here too, or crash recovery replays an impoverished
|
|
173
|
+
* turn. slackMeta is still partial (the rest is presentation, reconstructible
|
|
174
|
+
* from the row), but the turn-shaping fields are not optional.
|
|
165
175
|
*/
|
|
166
176
|
function buildReplaySlackInbound(params: {
|
|
167
177
|
sourceChannel: ChannelId;
|
|
@@ -179,7 +189,14 @@ function buildReplaySlackInbound(params: {
|
|
|
179
189
|
if (!channelTs) {
|
|
180
190
|
return undefined;
|
|
181
191
|
}
|
|
182
|
-
|
|
192
|
+
const appContext = params.sourceMetadata?.appContext;
|
|
193
|
+
return {
|
|
194
|
+
channelId: params.externalChatId,
|
|
195
|
+
channelTs,
|
|
196
|
+
...(Array.isArray(appContext?.entities) && appContext.entities.length > 0
|
|
197
|
+
? { appContext }
|
|
198
|
+
: {}),
|
|
199
|
+
};
|
|
183
200
|
}
|
|
184
201
|
|
|
185
202
|
/**
|
|
@@ -368,7 +385,7 @@ export async function sweepFailedEvents(
|
|
|
368
385
|
? payload.slackStreamMessageTs
|
|
369
386
|
: undefined;
|
|
370
387
|
let replyMessageId: string | undefined;
|
|
371
|
-
const observeAgentEvent = (msg:
|
|
388
|
+
const observeAgentEvent = (msg: AssistantEvent): void => {
|
|
372
389
|
if (
|
|
373
390
|
msg.type === "message_complete" &&
|
|
374
391
|
(msg.source === undefined || msg.source === "main") &&
|
|
@@ -401,12 +418,6 @@ export async function sweepFailedEvents(
|
|
|
401
418
|
// `slackInbound` when present (identical idempotency key + full slackMeta),
|
|
402
419
|
// else the reconstructed fallback — so a replay of an already-persisted turn
|
|
403
420
|
// dedups instead of running a second agent loop.
|
|
404
|
-
const prepared = prepareChannelInboundContent({
|
|
405
|
-
trimmedContent: content,
|
|
406
|
-
trustClass: trustContext.trustClass,
|
|
407
|
-
sourceChannel,
|
|
408
|
-
requesterIdentifier: trustContext.requesterIdentifier,
|
|
409
|
-
});
|
|
410
421
|
const replaySlackInbound =
|
|
411
422
|
parseStoredSlackInbound(payload.slackInbound) ??
|
|
412
423
|
buildReplaySlackInbound({
|
|
@@ -415,6 +426,18 @@ export async function sweepFailedEvents(
|
|
|
415
426
|
sourceMetadata,
|
|
416
427
|
externalMessageId,
|
|
417
428
|
});
|
|
429
|
+
// The captured `slackInbound` carries the sender's Slack `app_context`, so
|
|
430
|
+
// the replayed turn is prepared with the same context block the live turn
|
|
431
|
+
// rendered. Payloads predating the capture simply have none.
|
|
432
|
+
const prepared = prepareChannelInboundContent({
|
|
433
|
+
trimmedContent: content,
|
|
434
|
+
trustClass: trustContext.trustClass,
|
|
435
|
+
sourceChannel,
|
|
436
|
+
requesterIdentifier: trustContext.requesterIdentifier,
|
|
437
|
+
...(replaySlackInbound?.appContext
|
|
438
|
+
? { slackAppContext: replaySlackInbound.appContext }
|
|
439
|
+
: {}),
|
|
440
|
+
});
|
|
418
441
|
|
|
419
442
|
// Shared replay options. The idempotency-bearing `slackInbound` is added
|
|
420
443
|
// only on the first attempt; the incomplete-turn re-run below omits it so it
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
recordApprovalCardDelivery,
|
|
20
20
|
recordGuardianRequestDeliveries,
|
|
21
21
|
} from "../notifications/guardian-delivery-recorder.js";
|
|
22
|
+
import { buildVellumCardAffinity } from "../notifications/vellum-card-affinity.js";
|
|
22
23
|
import { canonicalizeInboundIdentity } from "../util/canonicalize-identity.js";
|
|
23
24
|
import { getLogger } from "../util/logger.js";
|
|
24
25
|
import { resolveApprovalSourceReference } from "./approval-source-link.js";
|
|
@@ -166,6 +167,9 @@ export async function bridgeConfirmationRequestToGuardian(
|
|
|
166
167
|
sourceChannel,
|
|
167
168
|
sourceContextId: conversationId,
|
|
168
169
|
requiresConversation: true,
|
|
170
|
+
// Pin the in-app (vellum) card to the conversation the confirmation was
|
|
171
|
+
// emitted in, so the guardian decides it in context.
|
|
172
|
+
...(buildVellumCardAffinity(conversationId) ?? {}),
|
|
169
173
|
attentionHints: {
|
|
170
174
|
requiresAction: true,
|
|
171
175
|
urgency: "high",
|
|
@@ -46,6 +46,8 @@ import {
|
|
|
46
46
|
buildGuardianDisambiguationExample,
|
|
47
47
|
buildGuardianDisambiguationLabel,
|
|
48
48
|
buildGuardianInvalidActionReply,
|
|
49
|
+
parseQuestionAnswerActionId,
|
|
50
|
+
QUESTION_SKIP_ACTION_ID,
|
|
49
51
|
resolveGuardianInstructionModeForRequest,
|
|
50
52
|
} from "../notifications/guardian-question-mode.js";
|
|
51
53
|
import { getLogger } from "../util/logger.js";
|
|
@@ -58,6 +60,7 @@ import type {
|
|
|
58
60
|
ApprovalConversationContext,
|
|
59
61
|
ApprovalConversationGenerator,
|
|
60
62
|
} from "./http-types.js";
|
|
63
|
+
import * as pendingInteractions from "./pending-interactions.js";
|
|
61
64
|
import { parseReactionCallbackData } from "./routes/channel-route-shared.js";
|
|
62
65
|
|
|
63
66
|
const log = getLogger("guardian-reply-router");
|
|
@@ -181,6 +184,38 @@ function parseCallbackAction(data: string): ParsedCallback | null {
|
|
|
181
184
|
return { requestId, action };
|
|
182
185
|
}
|
|
183
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Parse an `apr:<requestId>:<token>` callback whose token is an answer-option
|
|
189
|
+
* selection rather than an approval action. Same wire prefix as approval
|
|
190
|
+
* buttons — question cards are ordinary guardian-request cards — but the
|
|
191
|
+
* token is validated against the answer scheme by the caller, which also
|
|
192
|
+
* confirms the target request is answer-mode before applying anything.
|
|
193
|
+
*/
|
|
194
|
+
function parseAnswerCallback(
|
|
195
|
+
data: string,
|
|
196
|
+
): { requestId: string; token: string } | null {
|
|
197
|
+
const parts = data.split(":");
|
|
198
|
+
if (parts.length !== 3 || parts[0] !== "apr") {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
const [, requestId, token] = parts;
|
|
202
|
+
if (!requestId || !token) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return { requestId, token };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Whether the parked `question` interaction behind an ask_question guardian
|
|
210
|
+
* request is still live. An answer path must not commit a decision against a
|
|
211
|
+
* request whose interaction is gone (answered on another surface, timed out,
|
|
212
|
+
* superseded) — there is nothing left to resolve, and the message/tap should
|
|
213
|
+
* take the stale path instead.
|
|
214
|
+
*/
|
|
215
|
+
function hasLiveQuestionInteraction(requestId: string): boolean {
|
|
216
|
+
return pendingInteractions.get(requestId)?.kind === "question";
|
|
217
|
+
}
|
|
218
|
+
|
|
184
219
|
// ---------------------------------------------------------------------------
|
|
185
220
|
// Request code parser
|
|
186
221
|
// ---------------------------------------------------------------------------
|
|
@@ -392,6 +427,40 @@ export async function routeGuardianReply(
|
|
|
392
427
|
emissionContext,
|
|
393
428
|
);
|
|
394
429
|
}
|
|
430
|
+
|
|
431
|
+
// Answer-option tap on a question card: the action token is an answer
|
|
432
|
+
// selection (`answer_<idx>` / `answer_skip`), not an approval action, so
|
|
433
|
+
// `parseCallbackAction` rejects it above. Accept it only when the target
|
|
434
|
+
// request actually resolves to answer mode — an answer token aimed at an
|
|
435
|
+
// approval-mode request is never treated as a decision — and the parked
|
|
436
|
+
// interaction is still live, so a tap on a stale card (answered elsewhere,
|
|
437
|
+
// timed out) falls through to the stale-callback handling instead of
|
|
438
|
+
// committing a decision that can no longer resolve anything. The token
|
|
439
|
+
// rides as `userText`; the question resolver maps it to the selected
|
|
440
|
+
// option.
|
|
441
|
+
const answerTap = parseAnswerCallback(callbackData);
|
|
442
|
+
if (answerTap) {
|
|
443
|
+
const request = await getGuardianRequestOrNull(answerTap.requestId);
|
|
444
|
+
if (
|
|
445
|
+
request &&
|
|
446
|
+
resolveRequestInstructionMode(request) === "answer" &&
|
|
447
|
+
parseQuestionAnswerActionId(answerTap.token) &&
|
|
448
|
+
!request.callSessionId &&
|
|
449
|
+
hasLiveQuestionInteraction(request.id)
|
|
450
|
+
) {
|
|
451
|
+
return applyDecision(
|
|
452
|
+
request.id,
|
|
453
|
+
answerTap.token === QUESTION_SKIP_ACTION_ID
|
|
454
|
+
? "reject"
|
|
455
|
+
: "approve_once",
|
|
456
|
+
actor,
|
|
457
|
+
answerTap.token,
|
|
458
|
+
channelDeliveryContext,
|
|
459
|
+
emissionContext,
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
return notConsumed();
|
|
463
|
+
}
|
|
395
464
|
}
|
|
396
465
|
|
|
397
466
|
// ── 2. Request code parsing (6-char alphanumeric prefix) ──
|
|
@@ -544,6 +613,45 @@ export async function routeGuardianReply(
|
|
|
544
613
|
}
|
|
545
614
|
}
|
|
546
615
|
|
|
616
|
+
// ── 2.55. Bare-text answer to a single pending question ──
|
|
617
|
+
// When exactly one pending request is answer-mode (an ask_question), an
|
|
618
|
+
// unprefixed guardian reply IS the answer — "3pm works" must not require a
|
|
619
|
+
// request code, fall into approve/reject inference, or leak through to a
|
|
620
|
+
// normal agent turn (which would defer behind the parked question's
|
|
621
|
+
// processing lock and hang until the prompt timeout). Multiple pending
|
|
622
|
+
// requests keep the disambiguation flow below, which already prints
|
|
623
|
+
// per-mode reply examples.
|
|
624
|
+
//
|
|
625
|
+
// Deliberately narrow — this branch consumes ordinary prose, so it only
|
|
626
|
+
// fires when the message is unambiguously the answer:
|
|
627
|
+
// - same conversation the question was asked in (`sourceConversationId`)
|
|
628
|
+
// — under the identity-fallback scope a guardian's pending requests are
|
|
629
|
+
// visible cross-chat, and prose typed in an unrelated chat must never
|
|
630
|
+
// resolve a question elsewhere. Explicit codes/callbacks stay cross-chat.
|
|
631
|
+
// - the parked interaction is still live — after an app-card answer or a
|
|
632
|
+
// prompt timeout the request row can briefly outlive the interaction,
|
|
633
|
+
// and matching it would swallow the message into a decision that can no
|
|
634
|
+
// longer resolve anything. (Voice questions carry no such interaction
|
|
635
|
+
// and keep their existing code/NL answer paths.)
|
|
636
|
+
if (messageText.length > 0 && pendingRequests.length === 1) {
|
|
637
|
+
const soleRequest = pendingRequests[0];
|
|
638
|
+
if (
|
|
639
|
+
resolveRequestInstructionMode(soleRequest) === "answer" &&
|
|
640
|
+
!soleRequest.callSessionId &&
|
|
641
|
+
soleRequest.sourceConversationId === conversationId &&
|
|
642
|
+
hasLiveQuestionInteraction(soleRequest.id)
|
|
643
|
+
) {
|
|
644
|
+
return applyDecision(
|
|
645
|
+
soleRequest.id,
|
|
646
|
+
"approve_once",
|
|
647
|
+
actor,
|
|
648
|
+
messageText,
|
|
649
|
+
channelDeliveryContext,
|
|
650
|
+
emissionContext,
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
547
655
|
// ── 2.6. Deterministic plain-text decisions for known pending targets ──
|
|
548
656
|
// Desktop sessions intentionally do not enable NL classification; when the
|
|
549
657
|
// caller has exactly one known pending request and sends an explicit
|
|
@@ -37,6 +37,10 @@ import {
|
|
|
37
37
|
activeSttStreamSessions,
|
|
38
38
|
SttStreamSession,
|
|
39
39
|
} from "../stt/stt-stream-session.js";
|
|
40
|
+
import {
|
|
41
|
+
startTelegramWebhookHealthSweep,
|
|
42
|
+
stopTelegramWebhookHealthSweep,
|
|
43
|
+
} from "../telegram/webhook-health.js";
|
|
40
44
|
import { getLogger } from "../util/logger.js";
|
|
41
45
|
import { authenticateRequest } from "./auth/middleware.js";
|
|
42
46
|
import { parseSub } from "./auth/subject.js";
|
|
@@ -504,11 +508,15 @@ export class RuntimeHttpServer {
|
|
|
504
508
|
|
|
505
509
|
startInferenceProfileSessionReaper();
|
|
506
510
|
log.info("Inference profile session reaper started");
|
|
511
|
+
|
|
512
|
+
startTelegramWebhookHealthSweep();
|
|
513
|
+
log.info("Telegram webhook health sweep started");
|
|
507
514
|
}
|
|
508
515
|
|
|
509
516
|
async stop(): Promise<void> {
|
|
510
517
|
stopGuardianExpirySweep();
|
|
511
518
|
stopInferenceProfileSessionReaper();
|
|
519
|
+
stopTelegramWebhookHealthSweep();
|
|
512
520
|
if (this.retrySweepTimer) {
|
|
513
521
|
clearInterval(this.retrySweepTimer);
|
|
514
522
|
this.retrySweepTimer = null;
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
// Re-export so route modules (background-dispatch, etc.) can pull the type
|
|
17
17
|
// from the runtime barrel without reaching into daemon internals.
|
|
18
18
|
export type { SlackInboundMessageMetadata };
|
|
19
|
-
import type {
|
|
19
|
+
import type { AssistantEvent } from "../api/index.js";
|
|
20
20
|
import type { AssistantEventHub } from "./assistant-event-hub.js";
|
|
21
21
|
|
|
22
22
|
export type {
|
|
@@ -84,7 +84,7 @@ export interface RuntimeMessageConversationOptions {
|
|
|
84
84
|
*/
|
|
85
85
|
displayContent?: string;
|
|
86
86
|
/** Optional callback to receive real-time agent loop events (text deltas, tool starts, etc.). */
|
|
87
|
-
onEvent?: (msg:
|
|
87
|
+
onEvent?: (msg: AssistantEvent) => void;
|
|
88
88
|
/**
|
|
89
89
|
* Optional LLM call-site identifier. Channel ingress and other inbound paths
|
|
90
90
|
* may pass this so the daemon's per-call provider config picks up the right
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-role signal: whether this OS process is the main assistant daemon or
|
|
3
|
+
* something else (a sidecar worker — the resource monitor, memory jobs worker,
|
|
4
|
+
* schedule worker, route host — the CLI, a test, …).
|
|
5
|
+
*
|
|
6
|
+
* The daemon owns the singletons real clients connect to — the event hub and
|
|
7
|
+
* its SSE fan-out chief among them. Any other process runs its own disjoint
|
|
8
|
+
* copies, so anything it publishes locally reaches no client; such code routes
|
|
9
|
+
* to the live daemon over IPC when {@link isMainDaemonProcess} is false.
|
|
10
|
+
*
|
|
11
|
+
* Only the daemon knows it is the daemon: its entrypoint calls
|
|
12
|
+
* {@link markCurrentProcessAsMainDaemon} once at startup. Every other process
|
|
13
|
+
* (which never runs that entrypoint) is a non-daemon by default — no per-worker
|
|
14
|
+
* bookkeeping to keep in sync.
|
|
15
|
+
*
|
|
16
|
+
* State lives on the shared `globalThis.vellumAssistant.mainDaemonProcess` slot
|
|
17
|
+
* (like the other process-scoped singletons, and typed once by the ambient
|
|
18
|
+
* `VellumAssistantNamespace` in `src/vellum-assistant-namespace.d.ts`) so the
|
|
19
|
+
* test preload can default a test process to "main daemon" — a test runs daemon
|
|
20
|
+
* code in-process and expects local hub delivery — without importing this
|
|
21
|
+
* module.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
function ns(): VellumAssistantNamespace {
|
|
25
|
+
return (globalThis.vellumAssistant ??= {});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Mark the current process as the main assistant daemon. Called once, early in
|
|
30
|
+
* the daemon entrypoint (`runDaemon`), before anything can publish an event.
|
|
31
|
+
*/
|
|
32
|
+
export function markCurrentProcessAsMainDaemon(): void {
|
|
33
|
+
ns().mainDaemonProcess = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Whether this is the main assistant daemon process. False everywhere the
|
|
38
|
+
* daemon entrypoint did not run — sidecar workers, the route host, the CLI.
|
|
39
|
+
*/
|
|
40
|
+
export function isMainDaemonProcess(): boolean {
|
|
41
|
+
return ns().mainDaemonProcess === true;
|
|
42
|
+
}
|