@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
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Static fallbacks for an idle-triggered progress narration whose LLM
|
|
2
|
+
// phrasing failed — the one case where prolonged silence is actively harmful.
|
|
3
|
+
// The idle trigger can fire on a slow turn with zero tool activity, so every
|
|
4
|
+
// phrase stays strictly neutral: no claims about running tools or tasks.
|
|
5
|
+
// Persona-neutral, no domain content, ≤ 8 words.
|
|
6
|
+
// Exported so tests can assert the neutrality invariant against the list.
|
|
7
|
+
export const PROGRESS_FALLBACK_PHRASES: readonly string[] = [
|
|
8
|
+
"Still on it — one moment.",
|
|
9
|
+
"Still thinking this through.",
|
|
10
|
+
"Almost there — thanks for waiting.",
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
// Deterministic rotation through the phrase list: callers hold a nonnegative
|
|
14
|
+
// monotonic counter, so consecutive picks vary while tests stay reproducible.
|
|
15
|
+
export function pickProgressPhrase(counter: number): string {
|
|
16
|
+
return PROGRESS_FALLBACK_PHRASES[counter % PROGRESS_FALLBACK_PHRASES.length];
|
|
17
|
+
}
|
|
@@ -22,6 +22,7 @@ const _LIVE_VOICE_SERVER_FRAME_TYPES = [
|
|
|
22
22
|
"tts_audio",
|
|
23
23
|
"tts_done",
|
|
24
24
|
"turn_cancelled",
|
|
25
|
+
"minimize_room",
|
|
25
26
|
"metrics",
|
|
26
27
|
"archived",
|
|
27
28
|
"error",
|
|
@@ -242,6 +243,18 @@ export interface LiveVoiceTurnCancelledServerFrame extends LiveVoiceServerFrameB
|
|
|
242
243
|
readonly turnId: string;
|
|
243
244
|
}
|
|
244
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Assistant-requested room minimize: the just-completed turn asked (via the
|
|
248
|
+
* inline [-1] control marker) for the client to dismiss the full-screen
|
|
249
|
+
* voice room so the user can see the screen behind it. Sent only after the
|
|
250
|
+
* turn's TTS has fully drained, at most once per turn. Advisory — clients
|
|
251
|
+
* without a room (pop-outs, older clients) ignore it.
|
|
252
|
+
*/
|
|
253
|
+
export interface LiveVoiceMinimizeRoomServerFrame extends LiveVoiceServerFrameBase {
|
|
254
|
+
readonly type: "minimize_room";
|
|
255
|
+
readonly turnId: string;
|
|
256
|
+
}
|
|
257
|
+
|
|
245
258
|
export interface LiveVoiceMetricsServerFrame extends LiveVoiceServerFrameBase {
|
|
246
259
|
readonly type: "metrics";
|
|
247
260
|
readonly event?: string;
|
|
@@ -312,6 +325,7 @@ export type LiveVoiceServerFrame =
|
|
|
312
325
|
| LiveVoiceTtsAudioServerFrame
|
|
313
326
|
| LiveVoiceTtsDoneServerFrame
|
|
314
327
|
| LiveVoiceTurnCancelledServerFrame
|
|
328
|
+
| LiveVoiceMinimizeRoomServerFrame
|
|
315
329
|
| LiveVoiceMetricsServerFrame
|
|
316
330
|
| LiveVoiceArchivedServerFrame
|
|
317
331
|
| LiveVoiceErrorServerFrame;
|
|
@@ -331,6 +345,7 @@ export type LiveVoiceServerFramePayload =
|
|
|
331
345
|
| WithoutSeq<LiveVoiceTtsAudioServerFrame>
|
|
332
346
|
| WithoutSeq<LiveVoiceTtsDoneServerFrame>
|
|
333
347
|
| WithoutSeq<LiveVoiceTurnCancelledServerFrame>
|
|
348
|
+
| WithoutSeq<LiveVoiceMinimizeRoomServerFrame>
|
|
334
349
|
| WithoutSeq<LiveVoiceMetricsServerFrame>
|
|
335
350
|
| WithoutSeq<LiveVoiceArchivedServerFrame>
|
|
336
351
|
| WithoutSeq<LiveVoiceErrorServerFrame>;
|
|
@@ -12,7 +12,10 @@ import { join } from "node:path";
|
|
|
12
12
|
import { getAppDirPath } from "../apps/app-store.js";
|
|
13
13
|
import { getConfig } from "../config/loader.js";
|
|
14
14
|
import { getLogger } from "../util/logger.js";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
resolveImageGenCredentials,
|
|
17
|
+
resolveImageGenRouting,
|
|
18
|
+
} from "./image-credentials.js";
|
|
16
19
|
import { generateImage, mapImageGenError } from "./image-service.js";
|
|
17
20
|
|
|
18
21
|
const log = getLogger("app-icon-generator");
|
|
@@ -31,9 +34,10 @@ export async function generateAppIcon(
|
|
|
31
34
|
): Promise<void> {
|
|
32
35
|
const config = getConfig();
|
|
33
36
|
const svc = config.services["image-generation"];
|
|
37
|
+
const { backendProvider, managed } = resolveImageGenRouting(svc);
|
|
34
38
|
const { credentials, errorHint } = await resolveImageGenCredentials({
|
|
35
|
-
provider:
|
|
36
|
-
|
|
39
|
+
provider: backendProvider,
|
|
40
|
+
managed,
|
|
37
41
|
});
|
|
38
42
|
if (!credentials) {
|
|
39
43
|
log.debug(
|
|
@@ -64,9 +68,12 @@ export async function generateAppIcon(
|
|
|
64
68
|
"- Modern aesthetic similar to Apple's design language";
|
|
65
69
|
|
|
66
70
|
try {
|
|
67
|
-
log.info(
|
|
71
|
+
log.info(
|
|
72
|
+
{ appId, appName, provider: backendProvider },
|
|
73
|
+
"Generating app icon",
|
|
74
|
+
);
|
|
68
75
|
|
|
69
|
-
const result = await generateImage(
|
|
76
|
+
const result = await generateImage(backendProvider, credentials, {
|
|
70
77
|
prompt,
|
|
71
78
|
mode: "generate",
|
|
72
79
|
model: svc.model,
|
|
@@ -74,7 +81,7 @@ export async function generateAppIcon(
|
|
|
74
81
|
|
|
75
82
|
if (result.images.length === 0) {
|
|
76
83
|
log.warn(
|
|
77
|
-
{ appId, provider:
|
|
84
|
+
{ appId, provider: backendProvider },
|
|
78
85
|
"Provider returned no image for app icon",
|
|
79
86
|
);
|
|
80
87
|
return;
|
|
@@ -88,9 +95,9 @@ export async function generateAppIcon(
|
|
|
88
95
|
|
|
89
96
|
log.info({ appId, iconPath }, "App icon saved");
|
|
90
97
|
} catch (error) {
|
|
91
|
-
const message = mapImageGenError(
|
|
98
|
+
const message = mapImageGenError(backendProvider, error);
|
|
92
99
|
log.warn(
|
|
93
|
-
{ appId, provider:
|
|
100
|
+
{ appId, provider: backendProvider, error: message },
|
|
94
101
|
"App icon generation failed — skipping",
|
|
95
102
|
);
|
|
96
103
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
2
|
import { ConfigError, ProviderError } from "../util/errors.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
resolveImageGenCredentials,
|
|
5
|
+
resolveImageGenRouting,
|
|
6
|
+
} from "./image-credentials.js";
|
|
4
7
|
import { generateImage, mapImageGenError } from "./image-service.js";
|
|
5
8
|
|
|
6
9
|
export async function generateAvatar(
|
|
@@ -9,9 +12,10 @@ export async function generateAvatar(
|
|
|
9
12
|
const config = getConfig();
|
|
10
13
|
const svc = config.services["image-generation"];
|
|
11
14
|
|
|
15
|
+
const { backendProvider, managed } = resolveImageGenRouting(svc);
|
|
12
16
|
const { credentials, errorHint } = await resolveImageGenCredentials({
|
|
13
|
-
provider:
|
|
14
|
-
|
|
17
|
+
provider: backendProvider,
|
|
18
|
+
managed,
|
|
15
19
|
});
|
|
16
20
|
|
|
17
21
|
if (!credentials) {
|
|
@@ -20,7 +24,7 @@ export async function generateAvatar(
|
|
|
20
24
|
|
|
21
25
|
let result;
|
|
22
26
|
try {
|
|
23
|
-
result = await generateImage(
|
|
27
|
+
result = await generateImage(backendProvider, credentials, {
|
|
24
28
|
prompt,
|
|
25
29
|
mode: "generate",
|
|
26
30
|
model: svc.model,
|
|
@@ -30,7 +34,7 @@ export async function generateAvatar(
|
|
|
30
34
|
// (e.g. avatar-generator) don't need provider context to surface a
|
|
31
35
|
// useful error.
|
|
32
36
|
throw new ProviderError(
|
|
33
|
-
mapImageGenError(
|
|
37
|
+
mapImageGenError(backendProvider, error),
|
|
34
38
|
svc.provider,
|
|
35
39
|
);
|
|
36
40
|
}
|
|
@@ -12,24 +12,57 @@ import { PLATFORM_PROVIDER_META } from "../providers/platform-proxy/constants.js
|
|
|
12
12
|
import { resolveManagedProxyContext } from "../providers/platform-proxy/context.js";
|
|
13
13
|
import { getProviderKeyAsync } from "../security/secure-keys.js";
|
|
14
14
|
import type { ImageGenCredentials, ImageGenProvider } from "./types.js";
|
|
15
|
+
import { providerForImageModelPrefix, providerForModel } from "./types.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Resolve which backend serves an image request and whether it runs managed.
|
|
19
|
+
*
|
|
20
|
+
* `vellum` is unconditionally managed and carries no backend of its own: the
|
|
21
|
+
* backend derives from the model prefix (`gpt-*`/`dall-e-*` proxy OpenAI,
|
|
22
|
+
* anything else proxies Gemini), so one managed provider spans both runtime
|
|
23
|
+
* proxies. Managed routing never falls back to a stored BYOK key, and a BYOK
|
|
24
|
+
* provider never falls back to the proxy — billing follows the explicit
|
|
25
|
+
* provider choice. Other providers use the caller's key, with an explicit
|
|
26
|
+
* model override re-routing to the model's backend.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveImageGenRouting(
|
|
29
|
+
svc: { provider: string; model: string },
|
|
30
|
+
modelOverride?: unknown,
|
|
31
|
+
): { backendProvider: ImageGenProvider; managed: boolean } {
|
|
32
|
+
const managed = svc.provider === "vellum";
|
|
33
|
+
if (svc.provider === "vellum") {
|
|
34
|
+
const model =
|
|
35
|
+
typeof modelOverride === "string" && modelOverride
|
|
36
|
+
? modelOverride
|
|
37
|
+
: svc.model;
|
|
38
|
+
return { backendProvider: providerForImageModelPrefix(model), managed };
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
backendProvider: providerForModel(
|
|
42
|
+
modelOverride,
|
|
43
|
+
svc.provider as ImageGenProvider,
|
|
44
|
+
),
|
|
45
|
+
managed,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
15
48
|
|
|
16
49
|
/**
|
|
17
50
|
* Resolve credentials for an image-generation request.
|
|
18
51
|
*
|
|
19
|
-
* - `
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* -
|
|
23
|
-
*
|
|
24
|
-
*
|
|
52
|
+
* - `managed`: returns managed-proxy credentials when the platform URL and
|
|
53
|
+
* assistant API key are both configured, otherwise a hint telling the
|
|
54
|
+
* user to log in.
|
|
55
|
+
* - otherwise: returns direct credentials when the provider API key is
|
|
56
|
+
* present in secure storage (or the env-var fallback), otherwise a
|
|
57
|
+
* provider-aware hint pointing at Settings.
|
|
25
58
|
*/
|
|
26
59
|
export async function resolveImageGenCredentials(opts: {
|
|
27
60
|
provider: ImageGenProvider;
|
|
28
|
-
|
|
61
|
+
managed: boolean;
|
|
29
62
|
}): Promise<{ credentials?: ImageGenCredentials; errorHint?: string }> {
|
|
30
|
-
const { provider,
|
|
63
|
+
const { provider, managed } = opts;
|
|
31
64
|
|
|
32
|
-
if (
|
|
65
|
+
if (managed) {
|
|
33
66
|
// Resolve platform URL + assistant API key from a single snapshot so
|
|
34
67
|
// baseUrl and assistantApiKey can't diverge if the credential is cleared
|
|
35
68
|
// between lookups.
|
|
@@ -55,7 +88,6 @@ export async function resolveImageGenCredentials(opts: {
|
|
|
55
88
|
};
|
|
56
89
|
}
|
|
57
90
|
|
|
58
|
-
// mode === "your-own"
|
|
59
91
|
const apiKey = await getProviderKeyAsync(provider);
|
|
60
92
|
if (apiKey) {
|
|
61
93
|
return { credentials: { type: "direct", apiKey } };
|
|
@@ -63,17 +63,5 @@ export function mapImageGenError(
|
|
|
63
63
|
* - `gemini-*` → `gemini`
|
|
64
64
|
* - anything else (or `undefined`) → the provided `fallback`
|
|
65
65
|
*/
|
|
66
|
-
export function providerForModel(
|
|
67
|
-
model: unknown,
|
|
68
|
-
fallback: ImageGenProvider,
|
|
69
|
-
): ImageGenProvider {
|
|
70
|
-
// `model` originates from an LLM tool call's `input.model`, which is a
|
|
71
|
-
// `Record<string, unknown>` without runtime validation — so a non-string
|
|
72
|
-
// value (e.g. `{"model": 123}`) must not crash `.startsWith`.
|
|
73
|
-
if (typeof model !== "string" || !model) return fallback;
|
|
74
|
-
if (model.startsWith("gpt-") || model.startsWith("dall-e-")) return "openai";
|
|
75
|
-
if (model.startsWith("gemini-")) return "gemini";
|
|
76
|
-
return fallback;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
66
|
export type { ImageGenCredentials } from "./types.js";
|
|
67
|
+
export { providerForModel } from "./types.js";
|
package/src/media/types.ts
CHANGED
|
@@ -34,8 +34,7 @@ export const MAX_VARIANTS = 4;
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Derive the image-generation provider from a model identifier by prefix.
|
|
37
|
-
*
|
|
38
|
-
* `image-service.ts`; prefixes must stay in sync with that function.
|
|
37
|
+
* Sibling of {@link providerForModel} below; prefixes must stay in sync.
|
|
39
38
|
* Unknown models fall through to "gemini".
|
|
40
39
|
*/
|
|
41
40
|
export function providerForImageModelPrefix(model: string): ImageGenProvider {
|
|
@@ -45,6 +44,28 @@ export function providerForImageModelPrefix(model: string): ImageGenProvider {
|
|
|
45
44
|
return "gemini";
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Like {@link providerForImageModelPrefix}, but for untrusted caller input:
|
|
49
|
+
* a non-string or empty `model` (e.g. an LLM tool call's raw `input.model`)
|
|
50
|
+
* and unknown prefixes fall back to the provided provider instead of gemini.
|
|
51
|
+
* Prefixes must stay in sync with providerForImageModelPrefix.
|
|
52
|
+
*/
|
|
53
|
+
export function providerForModel(
|
|
54
|
+
model: unknown,
|
|
55
|
+
fallback: ImageGenProvider,
|
|
56
|
+
): ImageGenProvider {
|
|
57
|
+
if (typeof model !== "string" || !model) {
|
|
58
|
+
return fallback;
|
|
59
|
+
}
|
|
60
|
+
if (model.startsWith("gpt-") || model.startsWith("dall-e-")) {
|
|
61
|
+
return "openai";
|
|
62
|
+
}
|
|
63
|
+
if (model.startsWith("gemini-")) {
|
|
64
|
+
return "gemini";
|
|
65
|
+
}
|
|
66
|
+
return fallback;
|
|
67
|
+
}
|
|
68
|
+
|
|
48
69
|
/**
|
|
49
70
|
* Message fragments that indicate a provider billing / insufficient-credits
|
|
50
71
|
* failure. Used by the per-provider error mappers to detect a non-retryable
|
|
@@ -74,7 +95,9 @@ export function isImageProviderBillingError(args: {
|
|
|
74
95
|
status?: number;
|
|
75
96
|
message?: string;
|
|
76
97
|
}): boolean {
|
|
77
|
-
if (args.status === 402)
|
|
98
|
+
if (args.status === 402) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
78
101
|
const message = args.message ?? "";
|
|
79
102
|
return BILLING_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));
|
|
80
103
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
All notification producers **MUST** go through `emitNotificationSignal()` in `notifications/emit-signal.ts`. Do not bypass the pipeline by broadcasting events directly -- the pipeline handles event persistence, deduplication, decision routing, and delivery audit.
|
|
4
4
|
|
|
5
|
+
Guardian-request cards (approvals, questions) ride this pipeline end to end -- the full lifecycle map is [docs/guardian-request-flow.md](../../docs/guardian-request-flow.md). Card actions (`actions[]`) are built **once, centrally** in the broadcaster's context resolvers (`resolveApprovalContext` / `resolveQuestionOptionsContext`); channel adapters render only. Adding buttons for a new request kind = a broadcaster context branch, never adapter parsing.
|
|
6
|
+
|
|
5
7
|
When a notification flow creates a server-side conversation (e.g. guardian question conversations, task run conversations), the conversation and initial message **MUST** be persisted before the conversation-created event is emitted. This ensures the macOS/iOS client can immediately fetch the conversation contents when it receives the event.
|
|
6
8
|
|
|
7
9
|
Guardian-request producers (access requests, tool approvals, tool-grant escalations, voice questions, trusted-contact confirmations) **MUST** record approval-card deliveries through `recordApprovalCardDelivery` / `recordGuardianRequestDeliveries` in `guardian-delivery-recorder.ts` -- never by calling the gateway client's `createGuardianRequestDelivery` directly. That sink is the single place the card-to-request addressing convention lives (conversation id for the in-app card; chat + channel-native `ts` for channel cards), so the path that writes a delivery row cannot drift from the paths that read it back to withdraw a card or resolve an emoji reaction -- the drift that previously fanned this logic into four divergent copies. (Tests may seed delivery rows directly for fixtures.)
|
|
@@ -292,3 +292,98 @@ describe("NotificationBroadcaster platform deep-link from contextPayload", () =>
|
|
|
292
292
|
expect(sends[0]?.payload.deepLinkTarget).toBeUndefined();
|
|
293
293
|
});
|
|
294
294
|
});
|
|
295
|
+
|
|
296
|
+
// The card context is built once per broadcast (adapters render only); an
|
|
297
|
+
// answer-mode pending_question with structured options renders them as
|
|
298
|
+
// tappable card actions in the answer-token scheme the reply router
|
|
299
|
+
// recognizes.
|
|
300
|
+
describe("NotificationBroadcaster question option actions", () => {
|
|
301
|
+
function questionSignal(payload: Record<string, unknown>) {
|
|
302
|
+
return makeSignal({
|
|
303
|
+
sourceEventName: "guardian.question",
|
|
304
|
+
contextPayload: payload,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const decisionForPlatform = () =>
|
|
309
|
+
makeDecision({
|
|
310
|
+
selectedChannels: ["platform"],
|
|
311
|
+
renderedCopy: { platform: { title: "Question", body: "Which fruit?" } },
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test("renders pending_question options as answer-token actions plus Skip", async () => {
|
|
315
|
+
const { adapter, sends } = makeCapturingAdapter("platform");
|
|
316
|
+
const broadcaster = new NotificationBroadcaster([adapter]);
|
|
317
|
+
|
|
318
|
+
await broadcaster.broadcastDecision(
|
|
319
|
+
questionSignal({
|
|
320
|
+
requestKind: "pending_question",
|
|
321
|
+
requestId: "req-q1",
|
|
322
|
+
requestCode: "abc123",
|
|
323
|
+
questionText: "Which fruit?",
|
|
324
|
+
options: [
|
|
325
|
+
{ id: "apple", label: "Apple" },
|
|
326
|
+
{ id: "banana", label: "Banana" },
|
|
327
|
+
],
|
|
328
|
+
}),
|
|
329
|
+
decisionForPlatform(),
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
expect(sends.length).toBe(1);
|
|
333
|
+
const approval = sends[0]?.payload.approvalContext;
|
|
334
|
+
expect(approval?.requestId).toBe("req-q1");
|
|
335
|
+
expect(approval?.actions).toEqual([
|
|
336
|
+
{ id: "answer_0", label: "Apple" },
|
|
337
|
+
{ id: "answer_1", label: "Banana" },
|
|
338
|
+
{ id: "answer_skip", label: "Skip" },
|
|
339
|
+
]);
|
|
340
|
+
// The plain-text fallback keeps the answer-mode request-code instruction.
|
|
341
|
+
expect(approval?.plainTextFallback).toContain("ABC123");
|
|
342
|
+
expect(approval?.plainTextFallback).toContain("your answer");
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test("an option-less pending_question (voice) carries no card actions", async () => {
|
|
346
|
+
const { adapter, sends } = makeCapturingAdapter("platform");
|
|
347
|
+
const broadcaster = new NotificationBroadcaster([adapter]);
|
|
348
|
+
|
|
349
|
+
await broadcaster.broadcastDecision(
|
|
350
|
+
questionSignal({
|
|
351
|
+
requestKind: "pending_question",
|
|
352
|
+
requestId: "req-v1",
|
|
353
|
+
requestCode: "def456",
|
|
354
|
+
questionText: "What time works?",
|
|
355
|
+
callSessionId: "call-1",
|
|
356
|
+
activeGuardianRequestCount: 1,
|
|
357
|
+
}),
|
|
358
|
+
decisionForPlatform(),
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
expect(sends.length).toBe(1);
|
|
362
|
+
// Answer-mode without options renders as plain text with request-code
|
|
363
|
+
// instructions — no approve/reject pair is ever attached to a question.
|
|
364
|
+
expect(sends[0]?.payload.approvalContext).toBeUndefined();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
test("tool_approval payloads keep the approve/reject action pair", async () => {
|
|
368
|
+
const { adapter, sends } = makeCapturingAdapter("platform");
|
|
369
|
+
const broadcaster = new NotificationBroadcaster([adapter]);
|
|
370
|
+
|
|
371
|
+
await broadcaster.broadcastDecision(
|
|
372
|
+
questionSignal({
|
|
373
|
+
requestKind: "tool_approval",
|
|
374
|
+
requestId: "req-t1",
|
|
375
|
+
requestCode: "ghi789",
|
|
376
|
+
questionText: "Approve tool: bash",
|
|
377
|
+
toolName: "bash",
|
|
378
|
+
}),
|
|
379
|
+
decisionForPlatform(),
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
expect(sends.length).toBe(1);
|
|
383
|
+
const approval = sends[0]?.payload.approvalContext;
|
|
384
|
+
expect(approval?.actions?.map((a) => a.id)).toEqual([
|
|
385
|
+
"approve_once",
|
|
386
|
+
"reject",
|
|
387
|
+
]);
|
|
388
|
+
});
|
|
389
|
+
});
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* does not match their own identity.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import type { AssistantEvent } from "../../api/index.js";
|
|
21
22
|
import type { InterfaceId } from "../../channels/types.js";
|
|
22
|
-
import type { ServerMessage } from "../../daemon/message-protocol.js";
|
|
23
23
|
import { getLogger } from "../../util/logger.js";
|
|
24
24
|
import type {
|
|
25
25
|
ChannelAdapter,
|
|
@@ -44,7 +44,7 @@ export interface BroadcastFnOptions {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export type BroadcastFn = (
|
|
47
|
-
msg:
|
|
47
|
+
msg: AssistantEvent,
|
|
48
48
|
conversationId?: string,
|
|
49
49
|
options?: BroadcastFnOptions,
|
|
50
50
|
) => void;
|
|
@@ -107,7 +107,7 @@ export class VellumAdapter implements ChannelAdapter {
|
|
|
107
107
|
deepLinkMetadata: payload.deepLinkTarget,
|
|
108
108
|
targetGuardianPrincipalId,
|
|
109
109
|
silent,
|
|
110
|
-
} as
|
|
110
|
+
} as AssistantEvent);
|
|
111
111
|
|
|
112
112
|
log.info(
|
|
113
113
|
{
|
|
@@ -30,8 +30,12 @@ import {
|
|
|
30
30
|
} from "./deliveries-store.js";
|
|
31
31
|
import { resolveDestinations } from "./destination-resolver.js";
|
|
32
32
|
import {
|
|
33
|
+
buildQuestionOptionActionId,
|
|
33
34
|
buildToolApprovalSourceView,
|
|
35
|
+
parseGuardianQuestionPayload,
|
|
34
36
|
parseInteractiveApprovalPayload,
|
|
37
|
+
QUESTION_SKIP_ACTION_ID,
|
|
38
|
+
resolveGuardianInstructionModeFromPayload,
|
|
35
39
|
type ToolApprovalSourceView,
|
|
36
40
|
} from "./guardian-question-mode.js";
|
|
37
41
|
import { nonEmpty } from "./notification-utils.js";
|
|
@@ -94,6 +98,16 @@ function resolveApprovalContext(
|
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
if (signal.sourceEventName === "guardian.question") {
|
|
101
|
+
// Answer-mode question with structured options (an ask_question prompt):
|
|
102
|
+
// render the options as card actions so every channel adapter shows
|
|
103
|
+
// tappable choices. Built here — once per broadcast — so adapters stay
|
|
104
|
+
// rendering-only; the reply router recognizes the action ids as answer
|
|
105
|
+
// selections (see parseQuestionAnswerActionId).
|
|
106
|
+
const questionContext = resolveQuestionOptionsContext(payload);
|
|
107
|
+
if (questionContext) {
|
|
108
|
+
return questionContext;
|
|
109
|
+
}
|
|
110
|
+
|
|
97
111
|
const parsed = parseInteractiveApprovalPayload(payload);
|
|
98
112
|
if (!parsed) {
|
|
99
113
|
return undefined;
|
|
@@ -137,6 +151,49 @@ function resolveApprovalContext(
|
|
|
137
151
|
return undefined;
|
|
138
152
|
}
|
|
139
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Card actions for an answer-mode `pending_question` payload carrying
|
|
156
|
+
* structured options: one action per option plus Skip, ids in the
|
|
157
|
+
* answer-selection scheme. Returns `undefined` for approval-mode payloads,
|
|
158
|
+
* option-less questions (voice questions answer by free text), and anything
|
|
159
|
+
* that fails strict parsing — those fall through to the approval/plain-text
|
|
160
|
+
* paths.
|
|
161
|
+
*/
|
|
162
|
+
function resolveQuestionOptionsContext(
|
|
163
|
+
payload: Record<string, unknown>,
|
|
164
|
+
): ResolvedApprovalContext | undefined {
|
|
165
|
+
const parsed = parseGuardianQuestionPayload(payload);
|
|
166
|
+
if (!parsed || parsed.requestKind !== "pending_question") {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
if (resolveGuardianInstructionModeFromPayload(parsed).mode !== "answer") {
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
const options = parsed.options;
|
|
173
|
+
if (!options || options.length === 0) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const requestId = nonEmpty(parsed.requestId);
|
|
177
|
+
if (!requestId) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const code = parsed.requestCode?.toUpperCase() ?? requestId;
|
|
182
|
+
return {
|
|
183
|
+
approval: {
|
|
184
|
+
requestId,
|
|
185
|
+
actions: [
|
|
186
|
+
...options.map((option, index) => ({
|
|
187
|
+
id: buildQuestionOptionActionId(index),
|
|
188
|
+
label: option.label,
|
|
189
|
+
})),
|
|
190
|
+
{ id: QUESTION_SKIP_ACTION_ID, label: "Skip" },
|
|
191
|
+
],
|
|
192
|
+
plainTextFallback: `Reply "${code} <your answer>".`,
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
140
197
|
/** Callback invoked immediately when a vellum notification conversation is created. */
|
|
141
198
|
export interface ConversationCreatedInfo {
|
|
142
199
|
conversationId: string;
|
|
@@ -222,21 +222,6 @@ const TEMPLATES: Partial<Record<NotificationSourceEventName, CopyTemplate>> = {
|
|
|
222
222
|
};
|
|
223
223
|
},
|
|
224
224
|
|
|
225
|
-
"ingress.trusted_contact.denied": (payload) => {
|
|
226
|
-
const parsed = parseTrustedContactDecisionPayload(payload);
|
|
227
|
-
const requesterLabel = formatTrustedContactActor(
|
|
228
|
-
parsed?.requesterDisplayName,
|
|
229
|
-
parsed?.requesterExternalUserId,
|
|
230
|
-
parsed?.sourceChannel,
|
|
231
|
-
"Someone",
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
title: "Trusted Contact Denied",
|
|
236
|
-
body: `A trusted contact request from ${requesterLabel} has been denied.`,
|
|
237
|
-
};
|
|
238
|
-
},
|
|
239
|
-
|
|
240
225
|
"watcher.notification": (payload) => ({
|
|
241
226
|
title: str(payload.title, "Watcher Notification"),
|
|
242
227
|
body: str(payload.body, "A watcher event occurred"),
|
|
@@ -974,7 +974,7 @@ export async function evaluateSignal(
|
|
|
974
974
|
decision = enforceGuardianRequestCode(decision, signal);
|
|
975
975
|
decision = enforceToolApprovalSeedBlocks(decision, signal);
|
|
976
976
|
decision = enforceAccessRequestInstructions(decision, signal);
|
|
977
|
-
decision =
|
|
977
|
+
decision = enforceGuardianRequestConversationAffinity(decision, signal);
|
|
978
978
|
decision = enforceConversationAffinity(
|
|
979
979
|
decision,
|
|
980
980
|
signal.conversationAffinityHint,
|
|
@@ -992,7 +992,7 @@ export async function evaluateSignal(
|
|
|
992
992
|
decision = enforceGuardianRequestCode(decision, signal);
|
|
993
993
|
decision = enforceToolApprovalSeedBlocks(decision, signal);
|
|
994
994
|
decision = enforceAccessRequestInstructions(decision, signal);
|
|
995
|
-
decision =
|
|
995
|
+
decision = enforceGuardianRequestConversationAffinity(decision, signal);
|
|
996
996
|
decision = enforceConversationAffinity(
|
|
997
997
|
decision,
|
|
998
998
|
signal.conversationAffinityHint,
|
|
@@ -1022,7 +1022,7 @@ export async function evaluateSignal(
|
|
|
1022
1022
|
decision = enforceGuardianRequestCode(decision, signal);
|
|
1023
1023
|
decision = enforceToolApprovalSeedBlocks(decision, signal);
|
|
1024
1024
|
decision = enforceAccessRequestInstructions(decision, signal);
|
|
1025
|
-
decision =
|
|
1025
|
+
decision = enforceGuardianRequestConversationAffinity(decision, signal);
|
|
1026
1026
|
decision = enforceConversationAffinity(
|
|
1027
1027
|
decision,
|
|
1028
1028
|
signal.conversationAffinityHint,
|
|
@@ -1258,33 +1258,32 @@ export function enforceRoutingIntent(
|
|
|
1258
1258
|
return decision;
|
|
1259
1259
|
}
|
|
1260
1260
|
|
|
1261
|
-
// ── Guardian
|
|
1261
|
+
// ── Guardian request conversation affinity ───────────────────────────────
|
|
1262
1262
|
|
|
1263
1263
|
/**
|
|
1264
|
-
* Force a new vellum conversation for
|
|
1264
|
+
* Force a new vellum conversation for guardian-request signals that carry no
|
|
1265
|
+
* vellum affinity hint.
|
|
1265
1266
|
*
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1268
|
-
*
|
|
1269
|
-
*
|
|
1270
|
-
* call
|
|
1271
|
-
*
|
|
1267
|
+
* Guardian cards (tool approvals, tool grants, access requests, voice and
|
|
1268
|
+
* ask_question prompts) are pinned to their originating conversation by the
|
|
1269
|
+
* producer via `conversationAffinityHint`. When no pin exists — e.g. an
|
|
1270
|
+
* access request from a sender with no prior conversation, or the first
|
|
1271
|
+
* question in a phone call — the card must open its own conversation:
|
|
1272
|
+
* leaving the choice to the LLM lets unrelated requests accumulate in
|
|
1273
|
+
* whichever guardian conversation is most recent. For hinted signals,
|
|
1274
|
+
* enforceConversationAffinity applies the pin — this guard is a no-op.
|
|
1272
1275
|
*/
|
|
1273
|
-
export function
|
|
1276
|
+
export function enforceGuardianRequestConversationAffinity(
|
|
1274
1277
|
decision: NotificationDecision,
|
|
1275
1278
|
signal: NotificationSignal,
|
|
1276
1279
|
): NotificationDecision {
|
|
1277
|
-
if (
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
const callSessionId = signal.contextPayload?.callSessionId;
|
|
1282
|
-
if (typeof callSessionId !== "string" || callSessionId.trim().length === 0) {
|
|
1280
|
+
if (
|
|
1281
|
+
signal.sourceEventName !== "guardian.question" &&
|
|
1282
|
+
signal.sourceEventName !== "ingress.access_request"
|
|
1283
|
+
) {
|
|
1283
1284
|
return decision;
|
|
1284
1285
|
}
|
|
1285
1286
|
|
|
1286
|
-
// If an affinity hint already exists for vellum, the second+ dispatch
|
|
1287
|
-
// will be handled by enforceConversationAffinity — nothing to do here.
|
|
1288
1287
|
if (signal.conversationAffinityHint?.vellum) {
|
|
1289
1288
|
return decision;
|
|
1290
1289
|
}
|
|
@@ -1299,8 +1298,8 @@ export function enforceGuardianCallConversationAffinity(
|
|
|
1299
1298
|
enforced.conversationActions = conversationActions;
|
|
1300
1299
|
|
|
1301
1300
|
log.info(
|
|
1302
|
-
{
|
|
1303
|
-
"Guardian
|
|
1301
|
+
{ sourceEventName: signal.sourceEventName },
|
|
1302
|
+
"Guardian request conversation affinity: no vellum pin — forcing start_new",
|
|
1304
1303
|
);
|
|
1305
1304
|
|
|
1306
1305
|
return enforced;
|