@vellumai/assistant 0.10.8 → 0.10.9-dev.202607152225.ec6fdbf
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 +4 -0
- package/ARCHITECTURE.md +52 -88
- package/README.md +14 -35
- package/docs/activation-funnel-telemetry.md +20 -18
- package/docs/architecture/scheduling.md +0 -86
- package/docs/runbook-trusted-contacts.md +19 -19
- package/docs/trusted-contact-access.md +70 -69
- package/docs/workspace-tools.md +4 -2
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +62 -360
- package/eslint-rules/cli-no-daemon-internals.js +91 -275
- package/eslint.config.mjs +4 -4
- 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__/redacted-credential.test.ts +200 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/redacted-credential.ts +226 -0
- 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__/redacted-credential.test.ts +200 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/redacted-credential.ts +226 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-request-contract.test.ts +575 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-request-contract.ts +687 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +82 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +200 -0
- package/node_modules/@vellumai/service-contracts/src/redacted-credential.ts +226 -0
- package/openapi.yaml +353 -742
- package/package.json +2 -2
- package/scripts/build-test-fixtures.ts +3 -2
- package/scripts/test.ts +2 -7
- package/src/__tests__/activation-early-marking.test.ts +1 -8
- package/src/__tests__/actor-token-service.test.ts +0 -7
- package/src/__tests__/add-message-preassigned-id.test.ts +1 -1
- package/src/__tests__/add-message-skip-indexing.test.ts +164 -0
- package/src/__tests__/agent-image-optimize.test.ts +104 -1
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +5 -15
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +0 -6
- package/src/__tests__/agent-loop-override-profile.test.ts +48 -50
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +4 -17
- package/src/__tests__/agent-loop-set-system-prompt.test.ts +3 -14
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -4
- package/src/__tests__/agent-wake-override-profile.test.ts +40 -71
- package/src/__tests__/always-loaded-tools-guard.test.ts +4 -7
- package/src/__tests__/annotate-activity-metadata.test.ts +4 -31
- package/src/__tests__/annotate-risk-options.test.ts +4 -31
- package/src/__tests__/anthropic-provider.test.ts +11 -0
- package/src/__tests__/app-asset-bytes.test.ts +72 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +0 -1
- package/src/__tests__/app-bundler.test.ts +4 -20
- package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -8
- package/src/__tests__/app-executors.test.ts +2 -49
- package/src/__tests__/app-routes-csp.test.ts +126 -157
- package/src/__tests__/approval-cascade.test.ts +0 -82
- package/src/__tests__/approval-interception-trust-gates.test.ts +0 -7
- package/src/__tests__/approval-primitive.test.ts +1 -9
- package/src/__tests__/approval-routes-http.test.ts +5 -63
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +1 -19
- package/src/__tests__/assistant-events-sse-hardening.test.ts +4 -21
- package/src/__tests__/attachment-stored-path-annotation.test.ts +1 -19
- package/src/__tests__/attachment-upload-trusted-source.test.ts +0 -13
- package/src/__tests__/attachments-store-heic-normalize.test.ts +0 -13
- package/src/__tests__/attachments-store.test.ts +5 -19
- package/src/__tests__/audit-log-rotation.test.ts +1 -9
- package/src/__tests__/auth-fallback-events-store.test.ts +43 -59
- package/src/__tests__/available-skills.test.ts +7 -15
- package/src/__tests__/avatar-e2e.test.ts +0 -19
- package/src/__tests__/avatar-generator.test.ts +0 -9
- package/src/__tests__/background-shell-bash.test.ts +0 -20
- package/src/__tests__/background-shell-host-bash.test.ts +0 -34
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -43
- package/src/__tests__/browser-fill-credential.test.ts +0 -7
- package/src/__tests__/browser-manager.test.ts +1 -8
- package/src/__tests__/browser-skill-endstate.test.ts +1 -5
- package/src/__tests__/btw-routes.test.ts +7 -30
- package/src/__tests__/build-persisted-content.test.ts +96 -29
- package/src/__tests__/bundle-scanner.test.ts +27 -1
- package/src/__tests__/call-controller.test.ts +96 -149
- package/src/__tests__/call-conversation-messages.test.ts +2 -9
- package/src/__tests__/call-domain.test.ts +21 -56
- package/src/__tests__/call-pointer-message-composer.test.ts +0 -8
- package/src/__tests__/call-pointer-messages.test.ts +1 -8
- package/src/__tests__/call-recovery.test.ts +4 -11
- package/src/__tests__/call-routes-http.test.ts +12 -47
- package/src/__tests__/call-site-routing-provider.test.ts +5 -16
- package/src/__tests__/call-start-guardian-guard.test.ts +0 -10
- package/src/__tests__/call-state.test.ts +1 -8
- package/src/__tests__/call-store.test.ts +4 -11
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -32
- package/src/__tests__/catalog-cache.test.ts +0 -8
- package/src/__tests__/catalog-files.test.ts +0 -8
- package/src/__tests__/catalog-install-normalize.test.ts +0 -7
- package/src/__tests__/ces-rpc-credential-backend.test.ts +0 -7
- package/src/__tests__/channel-approval-routes.test.ts +23 -34
- package/src/__tests__/channel-approvals.test.ts +0 -7
- package/src/__tests__/channel-delivery-store.test.ts +6 -17
- package/src/__tests__/channel-guardian.test.ts +0 -7
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +15 -20
- package/src/__tests__/channel-readiness-routes.test.ts +41 -67
- package/src/__tests__/channel-readiness-service.test.ts +13 -45
- package/src/__tests__/channel-readiness-slack-remote.test.ts +5 -22
- package/src/__tests__/channel-reply-delivery.test.ts +18 -5
- package/src/__tests__/channel-retry-sweep.test.ts +0 -7
- package/src/__tests__/chat-credential-redaction.test.ts +1395 -0
- package/src/__tests__/chat-reveal-guard-priming.test.ts +791 -0
- package/src/__tests__/checker.test.ts +0 -24
- package/src/__tests__/clawhub-files.test.ts +0 -8
- package/src/__tests__/clawhub.test.ts +0 -7
- package/src/__tests__/clear-all-lexical.test.ts +0 -6
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -0
- package/src/__tests__/client-os-metadata-persistence.test.ts +0 -5
- package/src/__tests__/compaction-events.test.ts +26 -99
- package/src/__tests__/compaction-ledger-store.test.ts +1 -7
- package/src/__tests__/compaction-summary-head-persisted-count.test.ts +0 -27
- package/src/__tests__/compaction-trail-store.test.ts +1 -19
- package/src/__tests__/compaction.benchmark.test.ts +2 -6
- package/src/__tests__/compactor-call-site-logging.test.ts +0 -21
- package/src/__tests__/compactor-fixed-boundary.test.ts +0 -21
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -10
- package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -21
- package/src/__tests__/compactor-media-strip.test.ts +0 -21
- package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -21
- package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -21
- package/src/__tests__/compactor-web-search-strip.test.ts +0 -21
- package/src/__tests__/config-get-vision-flag.test.ts +24 -53
- package/src/__tests__/config-loader-backfill.test.ts +9 -25
- package/src/__tests__/config-loader-platform-defaults.test.ts +0 -21
- package/src/__tests__/config-schema-cmd.test.ts +10 -11
- package/src/__tests__/config-schema.test.ts +221 -275
- package/src/__tests__/config-set-route.test.ts +32 -62
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +44 -83
- package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -16
- package/src/__tests__/config-watcher.test.ts +2 -17
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +57 -63
- package/src/__tests__/contact-store-interaction-info.test.ts +1 -8
- package/src/__tests__/contact-store-user-file.test.ts +1 -8
- package/src/__tests__/contacts-tools.test.ts +21 -26
- package/src/__tests__/contacts-write.test.ts +1 -8
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -6
- package/src/__tests__/context-window-manager-compact-retry.test.ts +0 -27
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +0 -21
- package/src/__tests__/conversation-abort-tool-results.test.ts +9 -90
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +5 -41
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +16 -54
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +14 -79
- package/src/__tests__/conversation-agent-loop.test.ts +213 -136
- package/src/__tests__/conversation-app-control-instantiation.test.ts +10 -16
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -43
- package/src/__tests__/conversation-attachments.test.ts +0 -17
- package/src/__tests__/conversation-attention-store.test.ts +1 -9
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -8
- package/src/__tests__/conversation-clear-safety.test.ts +20 -20
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -82
- package/src/__tests__/conversation-crud-enabled-plugins.test.ts +1 -7
- package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -7
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -7
- package/src/__tests__/conversation-disk-view-integration.test.ts +1 -26
- package/src/__tests__/conversation-disk-view.test.ts +1 -26
- package/src/__tests__/conversation-enabledplugins-route.test.ts +3 -21
- package/src/__tests__/conversation-error.test.ts +21 -7
- package/src/__tests__/conversation-fork-crud.test.ts +35 -44
- package/src/__tests__/conversation-fork-retrospective.test.ts +9 -24
- package/src/__tests__/conversation-fork-route.test.ts +0 -32
- package/src/__tests__/conversation-history-web-search.test.ts +20 -17
- package/src/__tests__/conversation-inference-profile-list.test.ts +0 -17
- package/src/__tests__/conversation-inference-profile-route.test.ts +2 -24
- package/src/__tests__/conversation-init.benchmark.test.ts +3 -56
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -33
- package/src/__tests__/conversation-lifecycle.test.ts +63 -103
- package/src/__tests__/conversation-list-source.test.ts +0 -18
- package/src/__tests__/conversation-load-history-repair.test.ts +39 -91
- package/src/__tests__/conversation-load-history-stripped.test.ts +12 -57
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +10 -20
- package/src/__tests__/conversation-message-id-uuidv7.test.ts +1 -18
- package/src/__tests__/conversation-pairing.test.ts +0 -7
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -9
- package/src/__tests__/conversation-process-callsite.test.ts +15 -97
- package/src/__tests__/conversation-provider-retry-repair.test.ts +3 -84
- package/src/__tests__/conversation-queue.test.ts +12 -108
- package/src/__tests__/conversation-routes-disk-view.test.ts +8 -60
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +5 -63
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +13 -22
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +5 -64
- package/src/__tests__/conversation-routes-slash-commands.test.ts +19 -87
- package/src/__tests__/conversation-runtime-assembly.test.ts +34 -37
- package/src/__tests__/conversation-seed-composer.test.ts +3 -3
- package/src/__tests__/conversation-skill-tools.test.ts +19 -32
- package/src/__tests__/conversation-slash-queue.test.ts +3 -90
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -87
- package/src/__tests__/conversation-speed-override.test.ts +19 -94
- package/src/__tests__/conversation-starter-routes.test.ts +0 -7
- package/src/__tests__/conversation-store.test.ts +72 -66
- package/src/__tests__/conversation-summarize-route.test.ts +0 -11
- package/src/__tests__/conversation-summarize-up-to.test.ts +4 -89
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +131 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +36 -36
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +4 -2
- package/src/__tests__/conversation-title-service.test.ts +0 -7
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +0 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +37 -60
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +17 -17
- package/src/__tests__/conversation-unread-route.test.ts +0 -7
- package/src/__tests__/conversation-usage.test.ts +21 -71
- package/src/__tests__/conversation-wait-for-idle.test.ts +0 -82
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -45
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -88
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -88
- package/src/__tests__/conversations-defer-cli.test.ts +3 -0
- package/src/__tests__/conversations-import-system-filter.test.ts +0 -17
- package/src/__tests__/credential-broker-browser-fill.test.ts +0 -9
- package/src/__tests__/credential-broker-server-use.test.ts +0 -9
- package/src/__tests__/credential-health-service.test.ts +14 -31
- package/src/__tests__/credential-metadata-store.test.ts +0 -8
- package/src/__tests__/credential-prompt-route.test.ts +9 -15
- package/src/__tests__/credential-resolve.test.ts +0 -8
- package/src/__tests__/credential-routes.test.ts +250 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -8
- package/src/__tests__/credential-token-resolver.test.ts +0 -9
- package/src/__tests__/cross-provider-web-search.test.ts +12 -18
- package/src/__tests__/daemon-assistant-events.test.ts +1 -9
- package/src/__tests__/daemon-credential-client.test.ts +0 -7
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +1 -8
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +1 -7
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +0 -8
- package/src/__tests__/db-readiness-http-gate.test.ts +0 -18
- package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +1 -7
- package/src/__tests__/db-test-helpers.ts +10 -3
- package/src/__tests__/delete-managed-skill-tool.test.ts +0 -7
- package/src/__tests__/delete-propagation.test.ts +0 -7
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -7
- package/src/__tests__/device-id.test.ts +1 -9
- package/src/__tests__/disk-pressure-guard.test.ts +0 -4
- package/src/__tests__/disk-pressure-routes.test.ts +0 -4
- package/src/__tests__/disk-pressure-tools.test.ts +4 -42
- package/src/__tests__/dm-backfill.test.ts +0 -7
- package/src/__tests__/dm-persistence.test.ts +0 -5
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +1 -8
- package/src/__tests__/drain-requeue-on-contention.test.ts +1 -8
- package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -43
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -27
- package/src/__tests__/edit-propagation.test.ts +1 -8
- package/src/__tests__/email-invite-adapter.test.ts +8 -33
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +0 -8
- package/src/__tests__/emit-event-signal.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +0 -7
- package/src/__tests__/empty-state-greeting-cache.test.ts +9 -9
- package/src/__tests__/encrypted-store.test.ts +0 -9
- package/src/__tests__/ensure-conversation-exists.test.ts +1 -18
- package/src/__tests__/events-client-registration.test.ts +1 -19
- package/src/__tests__/events-dev-bypass-actor.test.ts +0 -7
- package/src/__tests__/events-tail-route.test.ts +1 -8
- package/src/__tests__/file-list-tool.test.ts +22 -15
- package/src/__tests__/followup-tools.test.ts +1 -16
- package/src/__tests__/gateway-only-enforcement.test.ts +3 -44
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -7
- package/src/__tests__/google-calendar-watcher.test.ts +175 -0
- package/src/__tests__/guardian-action-sweep.test.ts +0 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +0 -7
- package/src/__tests__/guardian-card-withdrawal.test.ts +60 -64
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +172 -135
- package/src/__tests__/guardian-dispatch.test.ts +58 -157
- package/src/__tests__/guardian-expiry-notifier.test.ts +56 -48
- package/src/__tests__/guardian-gateway-sim.ts +626 -0
- package/src/__tests__/guardian-outbound-http.test.ts +0 -7
- package/src/__tests__/guardian-routing-invariants.test.ts +229 -220
- package/src/__tests__/guardian-routing-state.test.ts +2 -9
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -17
- package/src/__tests__/guardian-wait-controller.test.ts +44 -43
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +26 -91
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +18 -103
- package/src/__tests__/headless-browser-interactions.test.ts +0 -7
- package/src/__tests__/headless-browser-mode.test.ts +0 -9
- package/src/__tests__/headless-browser-navigate.test.ts +0 -7
- package/src/__tests__/headless-browser-read-tools.test.ts +0 -7
- package/src/__tests__/headless-browser-snapshot.test.ts +0 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +9 -38
- package/src/__tests__/heartbeat-service.test.ts +83 -106
- package/src/__tests__/helpers/channel-test-adapter.ts +10 -0
- package/src/__tests__/helpers/gateway-guardian-requests-store-bridge.ts +155 -0
- package/src/__tests__/helpers/set-config.ts +40 -0
- package/src/__tests__/host-bash-proxy.test.ts +18 -34
- package/src/__tests__/host-browser-proxy.test.ts +15 -20
- package/src/__tests__/host-shell-tool.test.ts +2 -34
- package/src/__tests__/http-conversation-lineage.test.ts +3 -19
- package/src/__tests__/http-user-message-parity.test.ts +3 -95
- package/src/__tests__/identity-routes.test.ts +1 -9
- package/src/__tests__/image-recovery-hook.test.ts +36 -0
- package/src/__tests__/inbound-admitted-introduction-nudge.test.ts +6 -12
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +0 -5
- package/src/__tests__/inbound-trust-verdict.test.ts +2 -8
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +52 -8
- package/src/__tests__/inference-profile-reaper.test.ts +1 -7
- package/src/__tests__/inference-profile-session-handler.test.ts +4 -30
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -20
- package/src/__tests__/ingress-url-consistency.test.ts +1 -23
- package/src/__tests__/injector-background-turn.test.ts +10 -24
- package/src/__tests__/injector-chain.test.ts +4 -13
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +19 -17
- package/src/__tests__/inline-command-runner.test.ts +0 -34
- package/src/__tests__/inline-skill-load-permissions.test.ts +1 -30
- package/src/__tests__/install-skill-routing.test.ts +7 -6
- package/src/__tests__/integration-status.test.ts +25 -17
- package/src/__tests__/intent-routing.test.ts +1 -50
- package/src/__tests__/internal-telemetry-routes.test.ts +41 -22
- package/src/__tests__/interrupted-turn-reconciler.test.ts +1 -8
- package/src/__tests__/introduction-card-resolver.test.ts +108 -117
- package/src/__tests__/invite-redeemed-ipc.test.ts +0 -7
- package/src/__tests__/invite-routes-http.test.ts +12 -23
- package/src/__tests__/jobs-store-has-pending-job.test.ts +59 -0
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +1 -14
- package/src/__tests__/jobs-store-skill-card-upsert.test.ts +191 -0
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +1 -14
- package/src/__tests__/lexical-index-dual-write.test.ts +0 -6
- package/src/__tests__/list-all-apps.test.ts +200 -0
- package/src/__tests__/list-messages-attachments.test.ts +11 -20
- package/src/__tests__/list-messages-background-tool-completion.test.ts +6 -18
- package/src/__tests__/list-messages-client-message-id.test.ts +4 -16
- package/src/__tests__/list-messages-hidden-metadata.test.ts +6 -18
- package/src/__tests__/list-messages-page-latest.test.ts +3 -19
- package/src/__tests__/list-messages-queued.test.ts +1 -18
- package/src/__tests__/list-messages-tool-merge.test.ts +7 -18
- package/src/__tests__/llm-context-resolution.test.ts +32 -56
- package/src/__tests__/llm-context-route-provider.test.ts +1 -8
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +1 -19
- package/src/__tests__/llm-request-log-call-site.test.ts +1 -19
- package/src/__tests__/llm-request-log-clickhouse-routing.test.ts +114 -0
- package/src/__tests__/llm-request-log-clickhouse-writer-guards.test.ts +108 -0
- package/src/__tests__/llm-request-log-disabled-writes.test.ts +11 -30
- package/src/__tests__/llm-request-log-sink-clickhouse.test.ts +205 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +1 -22
- package/src/__tests__/llm-request-log-source-factory.test.ts +23 -69
- package/src/__tests__/llm-request-log-turn-query.test.ts +1 -19
- package/src/__tests__/llm-resolver-override-or-default.test.ts +3 -52
- package/src/__tests__/llm-resolver.test.ts +342 -602
- package/src/__tests__/llm-schema.test.ts +79 -37
- package/src/__tests__/llm-usage-store.test.ts +1 -7
- package/src/__tests__/log-export-routes.test.ts +0 -7
- package/src/__tests__/log-export-workspace.test.ts +0 -7
- package/src/__tests__/managed-profile-guard.test.ts +125 -137
- package/src/__tests__/managed-skill-lifecycle.test.ts +6 -50
- package/src/__tests__/managed-speech-defaults.test.ts +138 -0
- package/src/__tests__/managed-store.test.ts +1 -16
- package/src/__tests__/mcp-auth-routes.test.ts +15 -26
- package/src/__tests__/mcp-config-secret-boundary.test.ts +49 -91
- package/src/__tests__/mcp-health-check.test.ts +14 -20
- package/src/__tests__/media-generate-image.test.ts +25 -32
- package/src/__tests__/media-stream-output.test.ts +0 -9
- package/src/__tests__/media-stream-server-integration.test.ts +19 -27
- package/src/__tests__/media-stream-stt-session.test.ts +16 -29
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +6 -19
- package/src/__tests__/memory-jobs-worker-cleanup-cadence.test.ts +33 -12
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +10 -29
- package/src/__tests__/memory-recall-log-store.test.ts +1 -19
- package/src/__tests__/memory-retrieval-hook.test.ts +0 -3
- package/src/__tests__/memory-upsert-concurrency.test.ts +12 -35
- package/src/__tests__/memory-v2-static-injector.test.ts +5 -17
- package/src/__tests__/messages-after-tiebreaker.test.ts +1 -7
- package/src/__tests__/messaging-send-tool.test.ts +67 -7
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -18
- package/src/__tests__/migration-export-http.test.ts +10 -23
- package/src/__tests__/migration-export-streaming.test.ts +0 -18
- package/src/__tests__/migration-export-to-gcs.test.ts +0 -19
- package/src/__tests__/migration-import-commit-http.test.ts +11 -23
- package/src/__tests__/migration-import-from-gcs.test.ts +0 -19
- package/src/__tests__/migration-import-from-url.test.ts +0 -19
- package/src/__tests__/migration-import-preflight-http.test.ts +10 -22
- package/src/__tests__/migration-jobs-status.test.ts +8 -23
- package/src/__tests__/migration-validate-http.test.ts +2 -19
- package/src/__tests__/mtime-cache.test.ts +116 -2
- package/src/__tests__/native-web-search.test.ts +0 -21
- package/src/__tests__/non-member-access-request.test.ts +102 -93
- package/src/__tests__/notification-broadcaster.test.ts +32 -21
- package/src/__tests__/notification-candidate-guardian-context.test.ts +36 -34
- package/src/__tests__/notification-decision-fallback.test.ts +0 -7
- package/src/__tests__/notification-decision-identity.test.ts +0 -7
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -7
- package/src/__tests__/notification-deep-link.test.ts +0 -7
- package/src/__tests__/notification-guardian-path.test.ts +48 -93
- package/src/__tests__/notification-platform-adapter.test.ts +0 -7
- package/src/__tests__/notification-routing-intent.test.ts +1 -9
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -9
- package/src/__tests__/notification-telegram-adapter.test.ts +0 -7
- package/src/__tests__/oauth-cli.test.ts +0 -19
- package/src/__tests__/oauth-commands-routes.test.ts +28 -43
- package/src/__tests__/oauth-connect-orchestrator.test.ts +17 -26
- package/src/__tests__/oauth-connect-routes.test.ts +19 -18
- package/src/__tests__/oauth-provider-profiles.test.ts +3 -9
- package/src/__tests__/oauth-provider-visibility.test.ts +0 -7
- package/src/__tests__/oauth-store.test.ts +0 -7
- package/src/__tests__/oauth2-gateway-transport.test.ts +41 -43
- package/src/__tests__/openai-responses-prompt-cache.test.ts +355 -0
- package/src/__tests__/openai-responses-provider.test.ts +98 -9
- package/src/__tests__/openrouter-responses-transport.test.ts +170 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +13 -46
- package/src/__tests__/outlook-email-watcher.test.ts +0 -9
- package/src/__tests__/outlook-messaging-provider.test.ts +71 -0
- package/src/__tests__/path-policy.test.ts +0 -7
- package/src/__tests__/persist-media-references.test.ts +1 -6
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +6 -3
- package/src/__tests__/persist-unsendable-image.test.ts +39 -7
- package/src/__tests__/persistence-secret-redaction.test.ts +7 -28
- package/src/__tests__/platform-bash-auto-approve.test.ts +0 -46
- package/src/__tests__/platform-callback-registration.test.ts +10 -9
- package/src/__tests__/platform-proxy-context.test.ts +0 -8
- package/src/__tests__/playbook-execution.test.ts +0 -14
- package/src/__tests__/playbook-tools.test.ts +0 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +12 -35
- package/src/__tests__/plugin-app-serve-routes.test.ts +315 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -3
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -2
- package/src/__tests__/plugin-types.test.ts +0 -7
- package/src/__tests__/prechat-onboarding-contract.test.ts +0 -27
- package/src/__tests__/pricing.test.ts +45 -0
- package/src/__tests__/process-message-background-slack.test.ts +7 -21
- package/src/__tests__/process-message-display-content.test.ts +37 -6
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -44
- package/src/__tests__/provider-commit-message-generator.test.ts +57 -63
- package/src/__tests__/provider-error-scenarios.test.ts +5 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +21 -57
- package/src/__tests__/provider-registry-ollama.test.ts +8 -18
- package/src/__tests__/provider-send-message-override-profile.test.ts +28 -39
- package/src/__tests__/provider-streaming.benchmark.test.ts +1 -6
- package/src/__tests__/provider-usage-tracking.test.ts +13 -35
- package/src/__tests__/proxy-approval-callback.test.ts +0 -16
- package/src/__tests__/prune-old-conversations-job.test.ts +29 -21
- package/src/__tests__/prune-old-tool-invocations-job.test.ts +1 -9
- package/src/__tests__/public-ingress-urls.test.ts +1 -24
- package/src/__tests__/published-app-updater.test.ts +22 -16
- package/src/__tests__/qdrant-collection-migration.test.ts +0 -7
- package/src/__tests__/qdrant-manager.test.ts +0 -8
- package/src/__tests__/ratelimit.test.ts +1 -8
- package/src/__tests__/reaction-persistence.test.ts +18 -24
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +0 -14
- package/src/__tests__/recording-handler.test.ts +0 -27
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +4 -16
- package/src/__tests__/require-fresh-approval.test.ts +0 -45
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +24 -36
- package/src/__tests__/retry-prompt-cache-key.test.ts +123 -0
- package/src/__tests__/retry-thinking-adaptive-only.test.ts +45 -61
- package/src/__tests__/retry-thinking-tool-choice.test.ts +60 -80
- package/src/__tests__/retry-verbosity-normalization.test.ts +27 -37
- package/src/__tests__/reveal-success-registry.test.ts +123 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +113 -0
- package/src/__tests__/{scheduler-worker-standdown.test.ts → run-due-schedules.test.ts} +5 -77
- package/src/__tests__/runtime-attachment-metadata.test.ts +5 -18
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +1 -19
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -20
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -19
- package/src/__tests__/runtime-events-sse.test.ts +1 -20
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +306 -5
- package/src/__tests__/schedule-retry.test.ts +22 -23
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +18 -42
- package/src/__tests__/schedule-routes.test.ts +2 -150
- package/src/__tests__/schedule-store.test.ts +0 -8
- package/src/__tests__/schedule-tools.test.ts +1 -16
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -26
- package/src/__tests__/scheduler-recurrence.test.ts +43 -76
- package/src/__tests__/scheduler-reuse-conversation.test.ts +19 -35
- package/src/__tests__/scheduler-wake.test.ts +8 -24
- package/src/__tests__/scoped-approval-grants.test.ts +1 -9
- package/src/__tests__/scoped-grant-security-matrix.test.ts +1 -9
- package/src/__tests__/search-skills-unified.test.ts +0 -6
- package/src/__tests__/secret-allowlist.test.ts +1 -8
- package/src/__tests__/secret-fixtures.ts +9 -0
- package/src/__tests__/secret-ingress-channel.test.ts +4 -32
- package/src/__tests__/secret-ingress-cli.test.ts +3 -37
- package/src/__tests__/secret-ingress-http.test.ts +15 -78
- package/src/__tests__/secret-ingress.test.ts +14 -31
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +4 -10
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -9
- package/src/__tests__/secret-routes-platform-proxy.test.ts +3 -40
- package/src/__tests__/secure-keys-managed-failover.test.ts +0 -7
- package/src/__tests__/secure-keys.test.ts +0 -9
- package/src/__tests__/send-endpoint-busy.test.ts +47 -91
- package/src/__tests__/sequence-store.test.ts +0 -9
- package/src/__tests__/server-history-render.test.ts +29 -8
- package/src/__tests__/set-permission-mode.test.ts +8 -16
- package/src/__tests__/settings-routes.test.ts +0 -7
- package/src/__tests__/shell-credential-ref.test.ts +0 -18
- package/src/__tests__/shell-observability.test.ts +0 -21
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -34
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -27
- package/src/__tests__/skill-load-inline-command.test.ts +0 -25
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -25
- package/src/__tests__/skill-load-plugin-scope.test.ts +0 -24
- package/src/__tests__/skill-projection-feature-flag.test.ts +14 -33
- package/src/__tests__/skill-projection.benchmark.test.ts +14 -19
- package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -39
- package/src/__tests__/skills-file-content-endpoint.test.ts +0 -7
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -14
- package/src/__tests__/slack-channel-config.test.ts +24 -79
- package/src/__tests__/slack-inbound-verification.test.ts +5 -13
- package/src/__tests__/{slack-reaction-canonical-approval.test.ts → slack-reaction-guardian-approval.test.ts} +18 -74
- package/src/__tests__/slack-share-routes.test.ts +0 -1
- package/src/__tests__/slim-skill-category.test.ts +0 -14
- package/src/__tests__/stale-approval-dedup.test.ts +0 -7
- package/src/__tests__/subagent-call-site-routing.test.ts +72 -111
- package/src/__tests__/subagent-detail.test.ts +1 -1
- package/src/__tests__/subagent-fork-prompt-role.test.ts +0 -12
- package/src/__tests__/subagent-notify-parent.test.ts +4 -6
- package/src/__tests__/subagent-spawn-and-await.test.ts +0 -18
- package/src/__tests__/subagent-tool-filtering.test.ts +21 -31
- package/src/__tests__/subagent-tool-gate-mode.test.ts +6 -32
- package/src/__tests__/subagent-tools.test.ts +92 -67
- package/src/__tests__/suggestion-routes.test.ts +28 -42
- package/src/__tests__/summarize-boundary.test.ts +2 -1
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -25
- package/src/__tests__/system-prompt.test.ts +0 -33
- package/src/__tests__/task-memory-cleanup.test.ts +18 -192
- package/src/__tests__/telegram-bot-username-resolution.test.ts +24 -48
- package/src/__tests__/telegram-config.test.ts +0 -8
- package/src/__tests__/telemetry-routes.test.ts +100 -0
- package/src/__tests__/telephony-credential-preflight.test.ts +7 -11
- package/src/__tests__/telephony-tts-guard.test.ts +38 -21
- package/src/__tests__/terminal-tools.test.ts +0 -21
- package/src/__tests__/thread-backfill.test.ts +0 -7
- package/src/__tests__/title-generate-hook.test.ts +11 -10
- package/src/__tests__/token-manager.test.ts +0 -9
- package/src/__tests__/tool-approval-handler.test.ts +0 -8
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +5 -33
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +3 -23
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -48
- package/src/__tests__/tool-executor.test.ts +3 -49
- package/src/__tests__/tool-grant-request-escalation.test.ts +51 -153
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -29
- package/src/__tests__/tool-profiler.test.ts +72 -1
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -29
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -1
- package/src/__tests__/tool-start-timestamp.test.ts +4 -31
- package/src/__tests__/tools-get-route.test.ts +2 -1
- package/src/__tests__/trust-context-guards.test.ts +19 -7
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +75 -79
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +14 -18
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -7
- package/src/__tests__/trusted-contact-verification.test.ts +1 -9
- package/src/__tests__/turn-boundary-resolution.test.ts +1 -19
- package/src/__tests__/turn-events-store.test.ts +1 -7
- package/src/__tests__/turn-outcome-read.test.ts +1 -7
- package/src/__tests__/twilio-config.test.ts +11 -28
- package/src/__tests__/twilio-provider.test.ts +2 -13
- package/src/__tests__/twilio-routes-twiml.test.ts +1 -8
- package/src/__tests__/twilio-routes.test.ts +52 -103
- package/src/__tests__/twilio-validation.test.ts +5 -22
- package/src/__tests__/ui-file-upload-surface.test.ts +6 -9
- package/src/__tests__/usage-attribution.test.ts +25 -56
- package/src/__tests__/usage-cache-backfill-migration.test.ts +8 -15
- package/src/__tests__/usage-routes.test.ts +1 -8
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +0 -18
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -24
- package/src/__tests__/vercel-config.test.ts +0 -7
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -45
- package/src/__tests__/voice-approval-resolver-relay.test.ts +106 -75
- package/src/__tests__/voice-config-update.test.ts +114 -21
- package/src/__tests__/voice-ingress-preflight.test.ts +16 -15
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -30
- package/src/__tests__/voice-session-bridge-processing-wait.test.ts +1 -17
- package/src/__tests__/voice-session-bridge.test.ts +14 -46
- package/src/__tests__/web-search-backend-failure.test.ts +0 -21
- package/src/__tests__/whatsapp-invite-adapter.test.ts +11 -30
- package/src/__tests__/workspace-git-service.test.ts +801 -2
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -26
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -26
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +1 -26
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -9
- package/src/a2a/__tests__/task-store.test.ts +0 -9
- package/src/acp/__tests__/session-manager-persistence.test.ts +1 -8
- package/src/acp/__tests__/session-manager-resume.test.ts +0 -7
- package/src/acp/__tests__/session-manager-startup.test.ts +1 -8
- package/src/agent/image-optimize.ts +80 -0
- package/src/agent/loop.ts +20 -5
- package/src/api/events/open-conversation.test.ts +64 -0
- package/src/api/events/open-conversation.ts +33 -0
- package/src/api/index.ts +6 -0
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/guardian-card-withdrawal.ts +26 -19
- package/src/approvals/guardian-decision-primitive.ts +172 -102
- package/src/approvals/guardian-expiry-notifier.ts +20 -19
- package/src/approvals/guardian-request-resolvers.ts +305 -275
- package/src/apps/app-store.ts +320 -15
- package/src/background-wake/background-wake-routes.test.ts +2 -3
- package/src/background-wake/next-wake.test.ts +23 -20
- package/src/background-wake/wake-intent-hooks.test.ts +0 -10
- package/src/bundler/app-bundler.ts +34 -48
- package/src/bundler/app-compiler.ts +39 -4
- package/src/bundler/bundle-scanner.ts +13 -0
- package/src/bundler/manifest.ts +1 -1
- package/src/calls/__tests__/call-setup-router.test.ts +84 -88
- package/src/calls/__tests__/fish-audio-client.test.ts +6 -11
- package/src/calls/__tests__/voice-control-protocol.test.ts +47 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +151 -16
- package/src/calls/__tests__/voice-triage-escalate.test.ts +128 -0
- package/src/calls/access-request-wait.ts +35 -35
- package/src/calls/call-controller.ts +48 -45
- package/src/calls/call-setup-flow.ts +2 -2
- package/src/calls/call-setup-router.ts +1 -24
- package/src/calls/guardian-dispatch.ts +47 -30
- package/src/calls/guardian-wait-controller.ts +31 -18
- package/src/calls/media-turn-detector.ts +11 -1
- package/src/calls/telephony-credential-preflight.ts +19 -1
- package/src/calls/telephony-tts-capability.ts +18 -1
- package/src/calls/voice-control-protocol.ts +12 -0
- package/src/calls/voice-session-bridge.ts +110 -15
- package/src/calls/voice-triage-escalate.ts +136 -0
- package/src/channels/__tests__/gateway-guardian-requests.test.ts +669 -0
- package/src/channels/gateway-guardian-requests.ts +410 -0
- package/src/channels/types.ts +10 -5
- package/src/cli/AGENTS.md +77 -51
- package/src/cli/__tests__/cli-command-help-coverage.test.ts +29 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +23 -24
- package/src/cli/commands/__tests__/gateway.test.ts +55 -0
- package/src/cli/commands/__tests__/inference-models.test.ts +3 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +3 -0
- package/src/cli/commands/__tests__/inference-providers.test.ts +3 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +0 -10
- package/src/cli/commands/__tests__/inference-session.test.ts +4 -11
- package/src/cli/commands/__tests__/ui.test.ts +2 -2
- package/src/cli/commands/apps.help.ts +46 -0
- package/src/cli/commands/apps.ts +51 -0
- package/src/cli/commands/avatar.help.ts +229 -0
- package/src/cli/commands/avatar.ts +58 -250
- package/src/cli/commands/backup.help.ts +183 -0
- package/src/cli/commands/backup.ts +107 -276
- package/src/cli/commands/bash.help.ts +38 -0
- package/src/cli/commands/bash.ts +51 -75
- package/src/cli/commands/browser.help.ts +193 -0
- package/src/cli/commands/browser.ts +234 -347
- package/src/cli/commands/cache.help.ts +123 -0
- package/src/cli/commands/cache.ts +72 -166
- package/src/cli/commands/changelog.help.ts +59 -0
- package/src/cli/commands/changelog.ts +29 -61
- package/src/cli/commands/channel-verification-sessions.help.ts +178 -0
- package/src/cli/commands/channel-verification-sessions.ts +71 -226
- package/src/cli/commands/channels/index.help.ts +67 -0
- package/src/cli/commands/channels/index.ts +55 -105
- package/src/cli/commands/clients.help.ts +72 -0
- package/src/cli/commands/clients.ts +100 -153
- package/src/cli/commands/completions.help.ts +33 -0
- package/src/cli/commands/completions.ts +43 -66
- package/src/cli/commands/config.help.ts +126 -0
- package/src/cli/commands/config.ts +59 -174
- package/src/cli/commands/contacts.help.ts +327 -0
- package/src/cli/commands/contacts.ts +318 -603
- package/src/cli/commands/conversations-defer.ts +141 -202
- package/src/cli/commands/conversations-import.ts +80 -113
- package/src/cli/commands/conversations.help.ts +364 -0
- package/src/cli/commands/conversations.ts +143 -328
- package/src/cli/commands/credentials.help.ts +290 -0
- package/src/cli/commands/credentials.ts +271 -487
- package/src/cli/commands/db/index.help.ts +27 -0
- package/src/cli/commands/db/index.ts +7 -3
- package/src/cli/commands/db/refresh.ts +131 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +19 -9
- package/src/cli/commands/db/repair.ts +41 -43
- package/src/cli/commands/db/status.ts +79 -83
- package/src/cli/commands/domain.help.ts +34 -0
- package/src/cli/commands/domain.ts +10 -15
- package/src/cli/commands/email.help.ts +176 -0
- package/src/cli/commands/email.ts +323 -412
- package/src/cli/commands/gateway.help.ts +115 -0
- package/src/cli/commands/gateway.ts +105 -123
- package/src/cli/commands/image-generation.help.ts +72 -0
- package/src/cli/commands/image-generation.ts +13 -62
- package/src/cli/commands/inference-callsites.ts +34 -49
- package/src/cli/commands/inference-models.ts +6 -21
- package/src/cli/commands/inference-profiles.ts +95 -156
- package/src/cli/commands/inference-providers-default.ts +27 -42
- package/src/cli/commands/inference-providers.ts +25 -87
- package/src/cli/commands/inference-session.ts +189 -249
- package/src/cli/commands/inference.help.ts +485 -0
- package/src/cli/commands/inference.ts +104 -165
- package/src/cli/commands/keys.help.ts +46 -0
- package/src/cli/commands/keys.ts +37 -71
- package/src/cli/commands/mcp.help.ts +167 -0
- package/src/cli/commands/mcp.ts +123 -267
- package/src/cli/commands/memory/__tests__/memory-items.test.ts +4 -0
- package/src/cli/commands/memory/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +4 -0
- package/src/cli/commands/memory/__tests__/worker.test.ts +12 -5
- package/src/cli/commands/memory/index.help.ts +814 -0
- package/src/cli/commands/memory/index.ts +5 -27
- package/src/cli/commands/memory/items.ts +257 -404
- package/src/cli/commands/memory/memory-retrospective.ts +31 -71
- package/src/cli/commands/memory/memory-v2-compare-render.ts +2 -2
- package/src/cli/commands/memory/memory-v2.ts +435 -646
- package/src/cli/commands/memory/memory-v3.ts +158 -283
- package/src/cli/commands/memory/nodes.ts +154 -249
- package/src/cli/commands/memory/worker.ts +83 -128
- package/src/cli/commands/monitoring.help.ts +57 -0
- package/src/cli/commands/monitoring.ts +17 -41
- package/src/cli/commands/notifications.help.ts +293 -0
- package/src/cli/commands/notifications.ts +420 -657
- package/src/cli/commands/oauth/apps.ts +182 -315
- package/src/cli/commands/oauth/connect.ts +4 -35
- package/src/cli/commands/oauth/disconnect.ts +44 -71
- package/src/cli/commands/oauth/index.help.ts +855 -0
- package/src/cli/commands/oauth/index.ts +5 -31
- package/src/cli/commands/oauth/mode.ts +5 -28
- package/src/cli/commands/oauth/ping.ts +44 -66
- package/src/cli/commands/oauth/providers.ts +413 -772
- package/src/cli/commands/oauth/request.ts +6 -35
- package/src/cli/commands/oauth/shared.ts +1 -1
- package/src/cli/commands/oauth/status.test.ts +6 -6
- package/src/cli/commands/oauth/status.ts +45 -62
- package/src/cli/commands/oauth/token.ts +32 -71
- package/src/cli/commands/pending.help.ts +26 -0
- package/src/cli/commands/pending.ts +77 -78
- package/src/cli/commands/platform/__tests__/connect.test.ts +3 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +4 -4
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -90
- package/src/cli/commands/platform/connect.ts +10 -21
- package/src/cli/commands/platform/disconnect.ts +11 -26
- package/src/cli/commands/platform/index.help.ts +187 -0
- package/src/cli/commands/platform/index.ts +22 -169
- package/src/cli/commands/plugins.help.ts +247 -0
- package/src/cli/commands/plugins.ts +356 -437
- package/src/cli/commands/ps.help.ts +26 -0
- package/src/cli/commands/ps.ts +5 -17
- package/src/cli/commands/routes.help.ts +72 -0
- package/src/cli/commands/routes.ts +78 -125
- package/src/cli/commands/schedules-worker.ts +70 -138
- package/src/cli/commands/schedules.help.ts +514 -0
- package/src/cli/commands/schedules.ts +494 -871
- package/src/cli/commands/sequence.help.ts +183 -0
- package/src/cli/commands/sequence.ts +181 -343
- package/src/cli/commands/skills.help.ts +159 -0
- package/src/cli/commands/skills.ts +230 -368
- package/src/cli/commands/status.help.ts +32 -0
- package/src/cli/commands/status.ts +38 -3
- package/src/cli/commands/stt.help.ts +52 -0
- package/src/cli/commands/stt.ts +9 -47
- package/src/cli/commands/telemetry.help.ts +14 -0
- package/src/cli/commands/telemetry.ts +19 -17
- package/src/cli/commands/tools-run.ts +30 -45
- package/src/cli/commands/tools.help.ts +81 -0
- package/src/cli/commands/tools.ts +43 -83
- package/src/cli/commands/trust.help.ts +43 -0
- package/src/cli/commands/trust.ts +82 -109
- package/src/cli/commands/tts.help.ts +88 -0
- package/src/cli/commands/tts.ts +116 -188
- package/src/cli/commands/ui.help.ts +213 -0
- package/src/cli/commands/ui.ts +363 -380
- package/src/cli/commands/usage.help.ts +147 -0
- package/src/cli/commands/usage.ts +87 -206
- package/src/cli/commands/watchers.help.ts +211 -0
- package/src/cli/commands/watchers.ts +261 -417
- package/src/cli/commands/webhooks.help.ts +95 -0
- package/src/cli/commands/webhooks.ts +44 -115
- package/src/cli/index.help.ts +91 -0
- package/src/cli/lib/__tests__/global-json-option.test.ts +97 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +144 -4
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +96 -132
- package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +65 -0
- package/src/cli/lib/__tests__/plugin-catalog-platform.test.ts +167 -0
- package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +197 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +349 -240
- package/src/cli/lib/__tests__/plugin-fingerprint.test.ts +31 -0
- package/src/cli/lib/__tests__/plugin-icon-file.test.ts +50 -1
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +94 -0
- package/src/cli/lib/__tests__/plugins-install-offline.test.ts +147 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +193 -309
- package/src/cli/lib/bundled-marketplace.json +439 -0
- package/src/cli/lib/cli-command-help.ts +83 -10
- package/src/cli/lib/global-json-option.ts +41 -0
- package/src/cli/lib/install-from-github.ts +69 -2
- package/src/cli/lib/plugin-catalog-cache.ts +22 -50
- package/src/cli/lib/plugin-catalog-local.ts +71 -0
- package/src/cli/lib/plugin-catalog-platform.ts +117 -0
- package/src/cli/lib/plugin-catalog-resolve.ts +72 -0
- package/src/cli/lib/plugin-details.ts +100 -34
- package/src/cli/lib/plugin-fingerprint.ts +18 -7
- package/src/cli/lib/plugin-icon-file.ts +38 -26
- package/src/cli/lib/plugin-marketplace.ts +15 -2
- package/src/cli/lib/publish-plugin.ts +3 -3
- package/src/cli/lib/search-plugins.ts +48 -111
- package/src/cli/program.ts +7 -0
- package/src/cli.ts +22 -13
- package/src/config/__tests__/default-profile-catalog.test.ts +8 -12
- package/src/config/__tests__/default-provider.test.ts +0 -21
- package/src/config/__tests__/deployment-context-defaults.test.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-bundled.test.ts +2 -2
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -21
- package/src/config/__tests__/loader-last-known-good.test.ts +0 -21
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +0 -21
- package/src/config/__tests__/platform-rehydration.test.ts +125 -0
- package/src/config/__tests__/profile-materialization.test.ts +1 -88
- package/src/config/__tests__/seed-default-provider.test.ts +0 -21
- package/src/config/__tests__/sync-gated-profiles.test.ts +0 -21
- package/src/config/bundled-skills/app-builder/SKILL.md +24 -1
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +30 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -1
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +4 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +28 -20
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +7 -7
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/schedule/SKILL.md +0 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/TOOLS.json +5 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +84 -10
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +0 -7
- package/src/config/call-site-defaults.ts +3 -3
- package/src/config/feature-flag-registry.json +15 -63
- package/src/config/llm-resolver.ts +88 -475
- package/src/config/managed-speech-defaults.ts +115 -0
- package/src/config/platform-rehydration.ts +76 -0
- package/src/config/profile-materialization.ts +11 -11
- package/src/config/schema.ts +93 -129
- package/src/config/schemas/__tests__/live-voice.test.ts +24 -6
- package/src/config/schemas/__tests__/stt.test.ts +37 -0
- package/src/config/schemas/live-voice.ts +10 -4
- package/src/config/schemas/llm.ts +51 -15
- package/src/config/schemas/memory-lifecycle.ts +1 -13
- package/src/config/schemas/memory-retrospective.ts +8 -0
- package/src/config/schemas/memory.ts +0 -4
- package/src/config/schemas/stt.ts +33 -6
- package/src/config/schemas/tts.ts +53 -6
- package/src/config/schemas/workspace-git.ts +8 -0
- package/src/contacts/contact-store.ts +3 -58
- package/src/contacts/types.ts +1 -1
- package/src/conversations/__tests__/message-consolidation.test.ts +6 -5
- package/src/conversations/message-consolidation.ts +34 -112
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +64 -7
- package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +3 -7
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +8 -6
- package/src/daemon/__tests__/embedding-reconcile.test.ts +0 -11
- package/src/daemon/__tests__/inference-profile-notification.test.ts +5 -11
- package/src/daemon/__tests__/inflight-message-content.test.ts +219 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -27
- package/src/daemon/__tests__/route-conversation-post.test.ts +158 -0
- package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +0 -6
- package/src/daemon/__tests__/web-search-status-text.test.ts +0 -29
- package/src/daemon/app-source-watcher.ts +17 -23
- package/src/daemon/chat-credential-redaction.ts +1365 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +742 -77
- package/src/daemon/conversation-agent-loop.ts +10 -17
- package/src/daemon/conversation-error.ts +53 -16
- package/src/daemon/conversation-history.ts +6 -12
- package/src/daemon/conversation-messaging.ts +13 -1
- package/src/daemon/conversation-process.ts +16 -11
- package/src/daemon/conversation-runtime-assembly.ts +148 -52
- package/src/daemon/conversation-surfaces.ts +217 -100
- package/src/daemon/conversation-tool-setup.ts +59 -112
- package/src/daemon/conversation-turn-finalize.ts +18 -0
- package/src/daemon/conversation.ts +35 -66
- package/src/daemon/event-loop-watchdog.test.ts +1 -6
- package/src/daemon/external-plugins-bootstrap.ts +20 -74
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +0 -7
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -8
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -8
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -8
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -8
- package/src/daemon/handlers/conversation-history.ts +6 -4
- package/src/daemon/handlers/conversations.ts +19 -9
- package/src/daemon/handlers/shared.ts +24 -1
- package/src/daemon/inflight-message-content.ts +228 -0
- package/src/daemon/lifecycle.ts +21 -31
- package/src/daemon/message-protocol.ts +2 -7
- package/src/daemon/message-provenance.ts +17 -8
- package/src/daemon/message-types/conversations.ts +6 -17
- package/src/daemon/message-types/host-ui-snapshot.ts +44 -0
- package/src/daemon/message-types/inbox.ts +3 -46
- package/src/daemon/orphan-reaper.test.ts +1 -6
- package/src/daemon/process-message.ts +9 -0
- package/src/daemon/providers-setup.ts +5 -75
- package/src/daemon/route-conversation-post.ts +158 -0
- package/src/daemon/shutdown-handlers.ts +11 -17
- package/src/daemon/sqlite-corruption-watchdog.test.ts +0 -6
- package/src/documents/document-comments-store.test.ts +1 -7
- package/src/export/__tests__/transcript-formatter.test.ts +8 -8
- package/src/export/formatter.ts +8 -17
- package/src/export/transcript-formatter.ts +4 -1
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +0 -9
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +29 -57
- package/src/home/__tests__/home-content-refresh.test.ts +0 -7
- package/src/home/__tests__/suggested-prompts.test.ts +0 -11
- package/src/ipc/__tests__/contacts-info-ipc.test.ts +12 -10
- package/src/ipc/__tests__/email-ipc.test.ts +90 -0
- package/src/ipc/assistant-server.ts +10 -22
- package/src/ipc/routes/__tests__/guardian-label-ipc-routes.test.ts +74 -0
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +0 -7
- package/src/ipc/routes/guardian-label-ipc-routes.ts +42 -0
- package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -8
- package/src/live-voice/__tests__/live-voice-credential-preflight.test.ts +89 -49
- package/src/live-voice/__tests__/live-voice-integration.test.ts +116 -2
- package/src/live-voice/__tests__/live-voice-resume-registry.test.ts +58 -0
- package/src/live-voice/__tests__/live-voice-resume-turn.test.ts +280 -0
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +337 -0
- package/src/live-voice/__tests__/live-voice-tts.test.ts +0 -4
- package/src/live-voice/__tests__/live-voice-vad.test.ts +432 -12
- package/src/live-voice/__tests__/protocol.test.ts +122 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -41
- package/src/live-voice/live-voice-credential-preflight.ts +27 -3
- package/src/live-voice/live-voice-resume-registry.ts +54 -0
- package/src/live-voice/live-voice-session.ts +602 -61
- package/src/live-voice/protocol.ts +143 -1
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +3 -7
- package/src/messaging/provider-types.ts +9 -0
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +0 -9
- package/src/messaging/providers/outlook/adapter.ts +17 -2
- package/src/messaging/providers/outlook/client.ts +11 -2
- package/src/messaging/providers/outlook/types.ts +9 -0
- package/src/messaging/providers/slack/__tests__/download.test.ts +1 -8
- package/src/messaging/providers/slack/binding-metadata.test.ts +23 -21
- package/src/messaging/providers/slack/send.test.ts +0 -7
- package/src/messaging/providers/slack/withdraw.test.ts +0 -6
- package/src/messaging/providers/telegram-bot/send.test.ts +0 -7
- package/src/monitoring/__tests__/plugin-source-watch.test.ts +40 -1
- package/src/monitoring/plugin-source-watch.ts +56 -62
- package/src/monitoring/recovery/__tests__/inflight-content.test.ts +166 -0
- package/src/monitoring/recovery/inflight-content.ts +260 -0
- package/src/monitoring/recovery/run-recovery.ts +72 -0
- package/src/monitoring/worker.ts +68 -7
- package/src/notifications/AGENTS.md +1 -1
- package/src/notifications/README.md +4 -4
- package/src/notifications/__tests__/broadcaster.test.ts +4 -17
- package/src/notifications/__tests__/connected-channels.test.ts +11 -8
- package/src/notifications/__tests__/decision-engine.test.ts +0 -7
- package/src/notifications/__tests__/destination-resolver.test.ts +18 -12
- package/src/notifications/__tests__/deterministic-checks.test.ts +1 -9
- package/src/notifications/adapters/macos.ts +3 -5
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/broadcaster.ts +13 -4
- package/src/notifications/conversation-candidates.ts +21 -28
- package/src/notifications/copy-composer.ts +0 -6
- package/src/notifications/decision-engine.ts +1 -1
- package/src/notifications/{canonical-delivery-recorder.ts → guardian-delivery-recorder.ts} +47 -33
- package/src/notifications/home-feed-side-effect.ts +0 -2
- package/src/notifications/signal.ts +0 -4
- package/src/oauth/byo-connection.test.ts +0 -9
- package/src/oauth/connection-resolver.test.ts +18 -46
- package/src/oauth/seed-providers.ts +6 -0
- package/src/onboarding/__tests__/onboarding-events-store.test.ts +122 -44
- package/src/onboarding/onboarding-events-store.ts +67 -115
- package/src/onboarding/onboarding-research-events-store.test.ts +222 -0
- package/src/onboarding/onboarding-research-events-store.ts +92 -0
- package/src/permissions/checker.test.ts +10 -24
- package/src/permissions/confirmation-guardian-request.test.ts +94 -0
- package/src/permissions/{confirmation-canonical-request.ts → confirmation-guardian-request.ts} +44 -29
- package/src/permissions/gateway-threshold-reader.test.ts +0 -8
- package/src/permissions/prompter.ts +6 -4
- package/src/permissions/question-prompter.test.ts +7 -14
- package/src/persistence/__tests__/bulk-write-gate.test.ts +1 -7
- package/src/persistence/__tests__/conversation-queries-search.test.ts +0 -7
- package/src/persistence/__tests__/main-db-readonly-probe.ts +80 -0
- package/src/persistence/__tests__/main-db-readonly.test.ts +35 -0
- package/src/persistence/__tests__/message-content-file.test.ts +161 -52
- package/src/persistence/__tests__/raw-query-telemetry.test.ts +74 -0
- package/src/persistence/conversation-crud.ts +175 -45
- package/src/persistence/conversation-disk-view.ts +32 -15
- package/src/persistence/conversation-group-migration.test.ts +1 -8
- package/src/persistence/conversation-title-service.ts +59 -22
- package/src/persistence/db-connection.ts +46 -1
- package/src/persistence/db-singleton.ts +7 -1
- package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +3 -7
- package/src/persistence/embeddings/messages-lexical-index.ts +11 -0
- package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +0 -7
- package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +0 -6
- package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +0 -7
- package/src/persistence/job-handlers/cleanup.ts +30 -16
- package/src/persistence/job-handlers/message-lexical-backfill.ts +8 -5
- package/src/persistence/job-handlers/message-lexical.ts +2 -2
- package/src/persistence/jobs-store.ts +123 -17
- package/src/persistence/lifecycle-events-store.test.ts +84 -0
- package/src/persistence/lifecycle-events-store.ts +27 -52
- package/src/persistence/llm-request-log-sink-clickhouse.ts +325 -0
- package/src/persistence/llm-request-log-store.ts +185 -106
- package/src/persistence/llm-request-log-writer-types.ts +80 -0
- package/src/persistence/llm-usage-store.ts +5 -2
- package/src/persistence/message-content-file.ts +182 -71
- package/src/persistence/message-content.ts +18 -10
- package/src/persistence/migrations/305-drop-contact-acl-columns.ts +3 -2
- package/src/persistence/migrations/325-create-config-setting-events.ts +40 -0
- package/src/persistence/migrations/326-move-injection-events-to-memory-db.ts +104 -0
- package/src/persistence/migrations/327-create-flush-checkpoints.ts +86 -0
- package/src/persistence/migrations/328-drop-memory-v3-learned-edge-tables.ts +16 -0
- package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.test.ts +179 -0
- package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.ts +119 -0
- package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.test.ts +197 -0
- package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.ts +108 -0
- package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.test.ts +159 -0
- package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.ts +97 -0
- package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.test.ts +219 -0
- package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.ts +128 -0
- package/src/persistence/migrations/333-create-telemetry-events-table.test.ts +66 -0
- package/src/persistence/migrations/333-create-telemetry-events-table.ts +43 -0
- package/src/persistence/migrations/334-backfill-telemetry-events-outbox.test.ts +584 -0
- package/src/persistence/migrations/334-backfill-telemetry-events-outbox.ts +386 -0
- package/src/persistence/migrations/335-collapse-memory-embed-backlog.test.ts +181 -0
- package/src/persistence/migrations/335-collapse-memory-embed-backlog.ts +177 -0
- package/src/persistence/migrations/__tests__/327-create-flush-checkpoints.test.ts +124 -0
- package/src/persistence/raw-query.ts +27 -1
- package/src/persistence/schema/calls.ts +0 -23
- package/src/persistence/schema/conversation-starters.ts +31 -0
- package/src/persistence/schema/conversations.ts +3 -3
- package/src/persistence/schema/guardian.ts +0 -150
- package/src/persistence/schema/index.ts +1 -0
- package/src/persistence/schema/infrastructure.ts +25 -72
- package/src/persistence/schema/memory-core.ts +0 -25
- package/src/persistence/schema/memory-injection.ts +3 -1
- package/src/persistence/schema/tasks.ts +1 -60
- package/src/persistence/steps.ts +22 -0
- package/src/platform/client.test.ts +110 -0
- package/src/platform/client.ts +24 -4
- package/src/platform/consent-cache.test.ts +5 -18
- package/src/platform/consent-cache.ts +8 -6
- package/src/platform/managed-speech.test.ts +218 -0
- package/src/platform/managed-speech.ts +204 -0
- package/src/plugin-api/conversation-turn.ts +250 -0
- package/src/plugin-api/index.ts +21 -0
- package/src/plugin-api/model-profiles.test.ts +29 -28
- package/src/plugin-api/vision-support.test.ts +25 -38
- package/src/plugin-api/vision-support.ts +26 -17
- package/src/plugins/AGENTS.md +8 -0
- package/src/plugins/__tests__/source-fingerprint.test.ts +41 -0
- package/src/plugins/collect-source-versions.ts +77 -0
- package/src/plugins/defaults/image-recovery/detect.ts +32 -10
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +20 -18
- package/src/plugins/defaults/image-recovery/recover.ts +86 -59
- package/src/plugins/defaults/memory/__tests__/activation-session-store.test.ts +1 -8
- package/src/plugins/defaults/memory/__tests__/clear-stale-processing-flags.test.ts +1 -8
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +1 -8
- package/src/plugins/defaults/memory/__tests__/conversation-row-batch-delete.test.ts +7 -18
- package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +22 -18
- package/src/plugins/defaults/memory/__tests__/embedding-cache.test.ts +0 -6
- package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -8
- package/src/plugins/defaults/memory/__tests__/fork-message-copy.test.ts +7 -18
- package/src/plugins/defaults/memory/__tests__/jobs-store-enqueue-gate.test.ts +29 -39
- package/src/plugins/defaults/memory/__tests__/jobs-worker-memory-disabled.test.ts +11 -26
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +3 -22
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +215 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +114 -16
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +180 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +153 -519
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +6 -17
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -19
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +0 -18
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +8 -7
- package/src/plugins/defaults/memory/__tests__/table-relocation.test.ts +49 -0
- package/src/{persistence → plugins/defaults/memory}/__tests__/worker-control.test.ts +8 -10
- package/src/plugins/defaults/memory/graph/capability-seed.ts +4 -6
- package/src/plugins/defaults/memory/graph/extraction.ts +5 -1
- package/src/plugins/defaults/memory/graph/graph-search.test.ts +2 -8
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +0 -6
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +2 -2
- package/src/plugins/defaults/memory/graph/tools.ts +47 -13
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +81 -2
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +67 -32
- package/src/plugins/defaults/memory/hooks/shutdown.ts +8 -11
- package/src/plugins/defaults/memory/indexer.ts +2 -1
- package/src/plugins/defaults/memory/job-handlers/backfill.ts +8 -5
- package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +0 -7
- package/src/plugins/defaults/memory/job-handlers/embedding.ts +2 -2
- package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +7 -2
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +73 -8
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +5 -3
- package/src/plugins/defaults/memory/jobs/embed-pkb-file.test.ts +0 -13
- package/src/plugins/defaults/memory/jobs-worker.ts +139 -107
- package/src/plugins/defaults/memory/memory-db.ts +27 -0
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +4 -4
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +56 -180
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +216 -0
- package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +122 -202
- package/src/plugins/defaults/memory/message-media.ts +2 -2
- package/src/plugins/defaults/memory/paths.ts +3 -2
- package/src/plugins/defaults/memory/pkb/pkb-index.test.ts +0 -12
- package/src/plugins/defaults/memory/pkb/pkb-reconcile.test.ts +0 -9
- package/src/plugins/defaults/memory/pkb/pkb-search.test.ts +0 -6
- package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +15 -92
- package/src/plugins/defaults/memory/routes/__tests__/memory-worker-routes.test.ts +201 -0
- package/src/plugins/defaults/memory/routes/memory-item-routes.test.ts +7 -21
- package/src/plugins/defaults/memory/routes/memory-v2-routes.ts +3 -8
- package/src/plugins/defaults/memory/routes/memory-worker-routes.ts +162 -0
- package/src/plugins/defaults/memory/startup.ts +6 -7
- package/src/plugins/defaults/memory/task-memory-cleanup.ts +11 -22
- package/src/plugins/defaults/memory/tools.test.ts +40 -8
- package/src/plugins/defaults/memory/tools.ts +12 -2
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +0 -19
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +63 -40
- package/src/plugins/defaults/memory/v2/__tests__/cli-command-store.test.ts +61 -130
- package/src/plugins/defaults/memory/v2/__tests__/consolidation-job.test.ts +406 -10
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -10
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -10
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -10
- package/src/plugins/defaults/memory/v2/__tests__/injection-events.test.ts +61 -69
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +0 -19
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +11 -10
- package/src/plugins/defaults/memory/v2/__tests__/page-index.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/qdrant.test.ts +6 -22
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +3 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +7 -20
- package/src/plugins/defaults/memory/v2/__tests__/sim.test.ts +0 -24
- package/src/plugins/defaults/memory/v2/__tests__/skill-content.test.ts +17 -11
- package/src/plugins/defaults/memory/v2/__tests__/skill-store.test.ts +0 -16
- package/src/plugins/defaults/memory/v2/__tests__/static-context.test.ts +0 -10
- package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +0 -6
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +5 -2
- package/src/plugins/defaults/memory/v2/cli-command-content.ts +43 -12
- package/src/plugins/defaults/memory/v2/cli-command-store.ts +34 -50
- package/src/plugins/defaults/memory/v2/consolidation-job.ts +216 -10
- package/src/plugins/defaults/memory/v2/harness/router-retriever.ts +1 -8
- package/src/plugins/defaults/memory/v2/injection-events.ts +16 -14
- package/src/plugins/defaults/memory/v2/injection.ts +1 -2
- package/src/plugins/defaults/memory/v2/memory-v2-startup.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/migration.ts +55 -24
- package/src/plugins/defaults/memory/v2/prompts/consolidation.ts +4 -0
- package/src/plugins/defaults/memory/v2/router.ts +4 -14
- package/src/plugins/defaults/memory/v2/sweep-job.ts +1 -0
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +10 -22
- package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +0 -5
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +18 -20
- package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +0 -5
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +5 -9
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +51 -31
- package/src/plugins/defaults/memory/v3/prune.test.ts +3 -11
- package/src/{persistence → plugins/defaults/memory}/worker-control.ts +12 -21
- package/src/plugins/defaults/memory/worker.ts +19 -2
- package/src/plugins/mtime-cache.ts +166 -70
- package/src/plugins/plugin-tree-walk.ts +41 -4
- package/src/plugins/source-fingerprint.ts +9 -3
- package/src/plugins/surface-import.ts +28 -0
- package/src/plugins/types.ts +9 -23
- package/src/prompts/__tests__/system-prompt.test.ts +0 -28
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +0 -28
- package/src/providers/__tests__/connection-model-compat.test.ts +6 -19
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +1 -21
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +9 -26
- package/src/providers/__tests__/registry-native-web-search.test.ts +4 -10
- package/src/providers/__tests__/retry-callsite.test.ts +240 -235
- package/src/providers/__tests__/satellite-connection-routing.test.ts +11 -36
- package/src/providers/__tests__/vellum-mismatch-routing.test.ts +0 -5
- package/src/providers/anthropic/client.ts +9 -3
- package/src/providers/call-site-routing.ts +7 -3
- package/src/providers/connection-resolution.ts +9 -11
- package/src/providers/content-block-schema.ts +149 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +7 -11
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +1 -15
- package/src/providers/inference/auth.ts +23 -0
- package/src/providers/inference/backfill.ts +25 -9
- package/src/providers/model-catalog.ts +213 -5
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +54 -0
- package/src/providers/openai/chat-completions-provider.ts +13 -2
- package/src/providers/openai/responses-provider.ts +232 -5
- package/src/providers/openrouter/client.ts +53 -0
- package/src/providers/retry.ts +25 -2
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +13 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +211 -74
- package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +408 -0
- package/src/providers/speech-to-text/__tests__/vellum-managed.test.ts +121 -0
- package/src/providers/speech-to-text/__tests__/vellum-speech-relay-connection.test.ts +126 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +167 -37
- package/src/providers/speech-to-text/incremental-batch-stream.ts +413 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +16 -363
- package/src/providers/speech-to-text/provider-catalog.ts +26 -1
- package/src/providers/speech-to-text/resolve.ts +74 -13
- package/src/providers/speech-to-text/vellum-managed-realtime.ts +309 -0
- package/src/providers/speech-to-text/vellum-managed.ts +71 -0
- package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +174 -0
- package/src/providers/types.ts +23 -4
- package/src/providers/vellum-model-routing.test.ts +26 -0
- package/src/providers/vellum-model-routing.ts +30 -0
- package/src/runtime/AGENTS.md +1 -1
- package/src/runtime/__tests__/actor-trust-resolver.test.ts +2 -8
- package/src/runtime/__tests__/agent-wake.test.ts +100 -27
- package/src/runtime/__tests__/background-job-runner.test.ts +22 -0
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -5
- package/src/runtime/__tests__/member-verdict-cache.test.ts +2 -9
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +22 -5
- package/src/runtime/access-request-helper.ts +84 -60
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/agent-wake.ts +75 -26
- package/src/runtime/assistant-event-hub.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +1 -10
- package/src/runtime/auth/__tests__/route-policy.test.ts +0 -7
- package/src/runtime/auth/__tests__/token-service.test.ts +1 -8
- package/src/runtime/auth/same-actor.ts +2 -1
- package/src/runtime/background-job-runner.ts +22 -0
- package/src/runtime/channel-approval-types.ts +1 -1
- package/src/runtime/channel-reply-delivery.ts +38 -19
- package/src/runtime/confirmation-request-guardian-bridge.ts +45 -39
- package/src/runtime/for-chat-mint-registry.ts +118 -0
- package/src/runtime/guardian-action-service.ts +32 -27
- package/src/runtime/guardian-decision-types.ts +2 -2
- package/src/runtime/guardian-reply-router.ts +80 -98
- package/src/runtime/http-server.ts +61 -41
- package/src/runtime/introduction-policy.ts +2 -2
- package/src/runtime/local-actor-identity.ts +19 -7
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/reveal-nonce.ts +49 -0
- package/src/runtime/reveal-success-registry.ts +306 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/backup-routes.test.ts +195 -125
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/client-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +1 -19
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +1 -8
- package/src/runtime/routes/__tests__/contact-routes-merge-relay.test.ts +186 -0
- package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +2 -3
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +5 -27
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +12 -30
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +59 -56
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +53 -73
- package/src/runtime/routes/__tests__/gateway-status-routes.test.ts +84 -0
- package/src/runtime/routes/__tests__/inference-callsites-routes.test.ts +2 -10
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +58 -90
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +161 -93
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +6 -1
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +0 -8
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +218 -64
- package/src/runtime/routes/__tests__/question-routes.test.ts +2 -4
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -8
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +2 -1
- package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +16 -56
- package/src/runtime/routes/__tests__/stt-routes.test.ts +0 -9
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -0
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +354 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +0 -11
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +163 -10
- package/src/runtime/routes/__tests__/user-routes-cli.test.ts +154 -0
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +0 -7
- package/src/runtime/routes/acp-routes.ts +21 -9
- package/src/runtime/routes/app-management-routes.ts +231 -60
- package/src/runtime/routes/app-routes.ts +130 -83
- package/src/runtime/routes/auth-routes.ts +3 -1
- package/src/runtime/routes/background-wake-routes.ts +0 -1
- package/src/runtime/routes/cache-routes.ts +3 -3
- package/src/runtime/routes/call-routes.ts +5 -1
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-prompt-routes.ts +11 -5
- package/src/runtime/routes/contact-routes.ts +34 -42
- package/src/runtime/routes/conversation-attention-routes.ts +1 -1
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +4 -4
- package/src/runtime/routes/conversation-routes.ts +111 -72
- package/src/runtime/routes/credential-routes.ts +116 -3
- package/src/runtime/routes/email-routes.ts +17 -1
- package/src/runtime/routes/events-routes.ts +1 -0
- package/src/runtime/routes/gateway-status-routes.ts +69 -0
- package/src/runtime/routes/guardian-action-routes.ts +18 -16
- package/src/runtime/routes/guardian-approval-interception.ts +6 -4
- package/src/runtime/routes/guardian-approval-prompt.ts +7 -5
- package/src/runtime/routes/guardian-expiry-sweep.ts +130 -0
- package/src/runtime/routes/inbound-message-handler.ts +9 -33
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +9 -9
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +24 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -7
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -5
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +6 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -1
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +0 -9
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +4 -1
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +3 -12
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +16 -14
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +8 -2
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +15 -7
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -9
- package/src/runtime/routes/index.ts +5 -5
- package/src/runtime/routes/inference-provider-connection-routes.ts +73 -24
- package/src/runtime/routes/inference-send-routes.ts +1 -1
- package/src/runtime/routes/internal-telemetry-routes.ts +11 -2
- package/src/runtime/routes/oauth-connect-routes.ts +27 -7
- package/src/runtime/routes/platform-routes.ts +4 -14
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +0 -4
- package/src/runtime/routes/playground/__tests__/guard.test.ts +0 -4
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +0 -14
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +0 -21
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +0 -4
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +16 -18
- package/src/runtime/routes/playground/__tests__/state.test.ts +0 -14
- package/src/runtime/routes/playground/seed-conversation.ts +5 -4
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -2
- package/src/runtime/routes/plugins-routes.ts +163 -25
- package/src/runtime/routes/profiler-routes.ts +2 -5
- package/src/runtime/routes/publish-routes.ts +15 -18
- package/src/runtime/routes/question-routes.ts +8 -4
- package/src/runtime/routes/schedule-routes.ts +20 -78
- package/src/runtime/routes/schedule-worker-routes.ts +16 -84
- package/src/runtime/routes/secret-routes.ts +14 -0
- package/src/runtime/routes/settings-routes.ts +21 -25
- package/src/runtime/routes/subagents-routes.ts +17 -18
- package/src/runtime/routes/surface-action-routes.ts +18 -39
- package/src/runtime/routes/surface-content-routes.ts +59 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +148 -4
- package/src/runtime/routes/telemetry-routes.ts +74 -1
- package/src/runtime/routes/tts-routes.ts +9 -5
- package/src/runtime/routes/ui-snapshot-routes.test.ts +219 -0
- package/src/runtime/routes/ui-snapshot-routes.ts +313 -0
- package/src/runtime/routes/user-route-dispatcher.ts +52 -53
- package/src/runtime/routes/user-route-resolution.ts +141 -0
- package/src/runtime/routes/user-routes-cli.ts +56 -35
- package/src/runtime/routes/user-routes.ts +9 -2
- package/src/runtime/routes/vellum-actor-trust.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-guard.test.ts +1 -8
- package/src/runtime/tool-grant-request-helper.ts +34 -30
- package/src/runtime/trust-verdict-consumer.ts +4 -6
- package/src/schedule/__tests__/worker-control.test.ts +3 -3
- package/src/schedule/schedule-store.ts +0 -41
- package/src/schedule/scheduler.ts +38 -257
- package/src/schedule/worker-control.ts +11 -21
- package/src/schedule/worker.ts +18 -5
- package/src/security/__tests__/oauth2-device-code.test.ts +12 -60
- package/src/security/__tests__/provider-key-env-fallback.test.ts +0 -10
- package/src/security/auth-fallback-events-store.ts +34 -72
- package/src/security/secret-scanner.ts +26 -1
- package/src/sequence/engine.ts +15 -6
- package/src/services/published-app-updater.ts +6 -11
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +24 -4
- package/src/stt/daemon-batch-transcriber.ts +33 -2
- package/src/stt/stt-stream-session.ts +17 -11
- package/src/stt/types.ts +2 -1
- package/src/subagent/manager.ts +4 -3
- package/src/telemetry/AGENTS.md +44 -0
- package/src/telemetry/__tests__/config-setting-events-store.test.ts +63 -0
- package/src/telemetry/__tests__/config-setting-snapshot.test.ts +107 -0
- package/src/telemetry/__tests__/flush-checkpoints.test.ts +56 -0
- package/src/telemetry/__tests__/outbox-test-harness.ts +83 -0
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +258 -0
- package/src/telemetry/__tests__/watchdog-events-store.test.ts +32 -122
- package/src/telemetry/config-setting-events-store.ts +40 -0
- package/src/telemetry/config-setting-snapshot.ts +135 -0
- package/src/telemetry/flush-checkpoints.ts +70 -0
- package/src/telemetry/skill-loaded-events-store.test.ts +54 -113
- package/src/telemetry/skill-loaded-events-store.ts +21 -77
- package/src/telemetry/telemetry-event-sources.test.ts +211 -0
- package/src/telemetry/telemetry-event-sources.ts +582 -0
- package/src/telemetry/telemetry-events-outbox.test.ts +330 -0
- package/src/telemetry/telemetry-events-outbox.ts +204 -0
- package/src/telemetry/telemetry-main-db.ts +48 -0
- package/src/telemetry/telemetry-wire-source.json +4 -0
- package/src/telemetry/telemetry-wire-validation.test.ts +157 -0
- package/src/telemetry/telemetry-wire-validation.ts +125 -0
- package/src/telemetry/telemetry-wire.generated.ts +433 -0
- package/src/telemetry/tool-executed-events-store.test.ts +0 -8
- package/src/telemetry/tool-executed-events-store.ts +2 -2
- package/src/telemetry/turn-trace-store.test.ts +86 -7
- package/src/telemetry/turn-trace-store.ts +29 -1
- package/src/telemetry/types.test.ts +38 -0
- package/src/telemetry/types.ts +302 -87
- package/src/telemetry/usage-telemetry-reporter.test.ts +921 -364
- package/src/telemetry/usage-telemetry-reporter.ts +235 -722
- package/src/telemetry/watchdog-direct-emit.test.ts +0 -5
- package/src/telemetry/watchdog-direct-emit.ts +7 -1
- package/src/telemetry/watchdog-events-store.ts +11 -70
- package/src/tools/acp/spawn.test.ts +0 -7
- package/src/tools/apps/definitions.ts +1 -7
- package/src/tools/apps/executors.ts +11 -36
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +11 -24
- package/src/tools/browser/__tests__/browser-status.test.ts +47 -33
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1 -11
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +75 -58
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +0 -10
- package/src/tools/browser/network-recorder.test.ts +0 -11
- package/src/tools/document/document-comment-tool.test.ts +1 -7
- package/src/tools/host-terminal/host-shell.test.ts +0 -32
- package/src/tools/host-terminal/host-shell.ts +6 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +13 -15
- package/src/tools/network/__tests__/web-search-metadata.test.ts +15 -18
- package/src/tools/network/__tests__/web-search.test.ts +39 -50
- package/src/tools/registry.ts +148 -196
- package/src/tools/skills/find-similar-skills.test.ts +0 -7
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/skills/scaffold-managed.ts +105 -12
- package/src/tools/subagent/read.ts +6 -4
- package/src/tools/subagent/spawn.ts +20 -29
- package/src/tools/terminal/safe-env.ts +7 -2
- package/src/tools/terminal/shell.test.ts +4 -8
- package/src/tools/terminal/shell.ts +5 -2
- package/src/tools/tool-approval-handler.ts +39 -23
- package/src/tools/tool-input-summary.ts +2 -1
- package/src/tools/tool-manifest.ts +20 -6
- package/src/tools/tool-profiler.ts +37 -6
- package/src/tools/ui-surface/definitions.ts +1 -7
- package/src/tools/workflows/run-workflow.test.ts +8 -22
- package/src/tts/__tests__/provider-adapters.test.ts +28 -22
- package/src/tts/__tests__/provider-resolution.test.ts +26 -0
- package/src/tts/__tests__/synthesis-stream.test.ts +6 -6
- package/src/tts/__tests__/vellum-provider.test.ts +251 -0
- package/src/tts/provider-catalog.ts +6 -0
- package/src/tts/providers/__tests__/vellum-tts-socket.test.ts +266 -0
- package/src/tts/providers/vellum-provider.ts +220 -0
- package/src/tts/providers/vellum-tts-socket.ts +377 -0
- package/src/tts/synthesize-text.ts +15 -5
- package/src/tts/tts-config-resolver.ts +2 -7
- package/src/tts/types.ts +1 -0
- package/src/usage/attribution.ts +20 -114
- package/src/util/abort-reasons.ts +1 -3
- package/src/util/image-conversion.ts +23 -5
- package/src/util/logger.ts +8 -3
- package/src/{config/bundled-skills/messaging/tools/gmail-mime-helpers.ts → util/mime-type.ts} +4 -1
- package/src/util/platform.ts +0 -60
- package/src/util/pricing.ts +10 -1
- package/src/util/telemetry-db-path.ts +9 -7
- package/src/watcher/__tests__/telemetry.test.ts +41 -11
- package/src/watcher/providers/google-calendar.ts +81 -49
- package/src/watcher/telemetry.ts +22 -5
- package/src/workflows/engine-integration.test.ts +0 -6
- package/src/workflows/engine.test.ts +1 -9
- package/src/workflows/journal-store.test.ts +1 -9
- package/src/workflows/leaf-runner.test.ts +17 -50
- package/src/workflows/library.test.ts +1 -9
- package/src/workflows/run-manager.test.ts +1 -9
- package/src/workspace/git-service.ts +932 -37
- package/src/workspace/provider-commit-message-generator.ts +6 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +0 -450
- package/src/__tests__/canonical-guardian-store.test.ts +0 -928
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -140
- package/src/__tests__/plugin-route-contribution.test.ts +0 -245
- package/src/__tests__/skill-runtime-path.test.ts +0 -63
- package/src/__tests__/task-compiler.test.ts +0 -317
- package/src/__tests__/task-management-tools.test.ts +0 -1128
- package/src/__tests__/task-scheduler.test.ts +0 -786
- package/src/config/schemas/schedules.ts +0 -35
- package/src/contacts/canonical-guardian-store.ts +0 -902
- package/src/daemon/message-types/work-items.ts +0 -243
- package/src/runtime/routes/__tests__/memory-worker-routes.test.ts +0 -306
- package/src/runtime/routes/__tests__/task-routes.test.ts +0 -644
- package/src/runtime/routes/assets/vellum-design-system.css +0 -1959
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +0 -129
- package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +0 -158
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +0 -187
- package/src/runtime/routes/memory-worker-routes.ts +0 -227
- package/src/runtime/routes/task-routes.ts +0 -380
- package/src/runtime/routes/work-items-routes.test.ts +0 -75
- package/src/runtime/routes/work-items-routes.ts +0 -881
- package/src/runtime/skill-route-registry.ts +0 -131
- package/src/tasks/SPEC.md +0 -132
- package/src/tasks/task-compiler.ts +0 -194
- package/src/tasks/task-runner.ts +0 -119
- package/src/tasks/task-scheduler.ts +0 -22
- package/src/tasks/task-store.ts +0 -153
- package/src/tasks/tool-sanitizer.ts +0 -38
- package/src/tools/apps/registry.ts +0 -16
- package/src/tools/system/register.ts +0 -9
- package/src/tools/tasks/task-delete.ts +0 -121
- package/src/tools/tasks/task-list.ts +0 -56
- package/src/tools/tasks/task-run.ts +0 -122
- package/src/tools/tasks/task-save.ts +0 -64
- package/src/tools/tasks/work-item-enqueue.ts +0 -300
- package/src/tools/tasks/work-item-list.ts +0 -65
- package/src/tools/tasks/work-item-remove.ts +0 -94
- package/src/tools/tasks/work-item-run.ts +0 -99
- package/src/tools/tasks/work-item-update.ts +0 -166
- package/src/tools/ui-surface/registry.ts +0 -14
- package/src/work-items/resolve-required-tools.test.ts +0 -37
- package/src/work-items/resolve-required-tools.ts +0 -26
- package/src/work-items/work-item-runner.ts +0 -187
- package/src/work-items/work-item-store.ts +0 -416
|
@@ -6,11 +6,27 @@ import {
|
|
|
6
6
|
type TurnDetectorConfig,
|
|
7
7
|
} from "../calls/media-turn-detector.js";
|
|
8
8
|
import { sanitizeForTts } from "../calls/tts-text-sanitizer.js";
|
|
9
|
+
import {
|
|
10
|
+
couldBeControlMarker,
|
|
11
|
+
ESCALATE_MARKER,
|
|
12
|
+
stripInternalSpeechMarkers,
|
|
13
|
+
} from "../calls/voice-control-protocol.js";
|
|
9
14
|
import type {
|
|
10
15
|
VoiceTurnHandle,
|
|
11
16
|
VoiceTurnOptions,
|
|
12
17
|
} from "../calls/voice-session-bridge.js";
|
|
18
|
+
import {
|
|
19
|
+
ESCALATION_CONTINUATION_CONTENT,
|
|
20
|
+
ESCALATION_PROFILE,
|
|
21
|
+
FALLBACK_ESCALATION_BRIDGE,
|
|
22
|
+
FRONT_DOOR_PROFILE,
|
|
23
|
+
isVoiceTriageEscalateEnabled,
|
|
24
|
+
needsFallbackBridge,
|
|
25
|
+
type VoiceRoutingLeg,
|
|
26
|
+
} from "../calls/voice-triage-escalate.js";
|
|
27
|
+
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
13
28
|
import { getConfig } from "../config/loader.js";
|
|
29
|
+
import type { TrustContext } from "../daemon/trust-context-types.js";
|
|
14
30
|
import { ensureConversationExists } from "../persistence/conversation-crud.js";
|
|
15
31
|
import {
|
|
16
32
|
listProviderIds,
|
|
@@ -38,6 +54,12 @@ import {
|
|
|
38
54
|
type LiveVoiceMetricsEvent,
|
|
39
55
|
type LiveVoiceTurnSeedMarks,
|
|
40
56
|
} from "./live-voice-metrics.js";
|
|
57
|
+
import {
|
|
58
|
+
registerVoiceResumeHandler,
|
|
59
|
+
unregisterVoiceResumeHandler,
|
|
60
|
+
type VoiceResumeHandler,
|
|
61
|
+
type VoiceResumeOptions,
|
|
62
|
+
} from "./live-voice-resume-registry.js";
|
|
41
63
|
import {
|
|
42
64
|
type LiveVoiceSession as LiveVoiceSessionContract,
|
|
43
65
|
type LiveVoiceSessionCloseReason,
|
|
@@ -51,6 +73,7 @@ import type {
|
|
|
51
73
|
} from "./live-voice-tts.js";
|
|
52
74
|
import {
|
|
53
75
|
type LiveVoiceClientFrame,
|
|
76
|
+
type LiveVoiceClientUpdateConfigFrame,
|
|
54
77
|
LiveVoiceProtocolErrorCode,
|
|
55
78
|
type LiveVoiceServerFramePayload,
|
|
56
79
|
} from "./protocol.js";
|
|
@@ -77,10 +100,12 @@ const SERVER_VAD_PRE_ROLL_MAX_CHUNKS = 25;
|
|
|
77
100
|
// provider keeps its own, longer, finalize fallback).
|
|
78
101
|
const FINALIZE_GRACE_MS = 1_000;
|
|
79
102
|
// Consecutive speech (ms) required before speech during assistant playback
|
|
80
|
-
// flushes it (speech_started) and cancels the turn, so a cough
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
|
|
103
|
+
// flushes it (speech_started) and cancels the turn, so a cough, a filler word,
|
|
104
|
+
// or the assistant's own TTS bleeding through imperfect browser echo
|
|
105
|
+
// cancellation cannot kill a reply mid-sentence. Mirrors the
|
|
106
|
+
// liveVoice.vad.bargeInMinSpeechMs schema default; 0 disables the guard for
|
|
107
|
+
// instant barge-in.
|
|
108
|
+
const DEFAULT_BARGE_IN_MIN_SPEECH_MS = 250;
|
|
84
109
|
// At most this many TTS segment jobs are open (provider stream started,
|
|
85
110
|
// frames not yet fully emitted) per turn: the emitting job plus one
|
|
86
111
|
// prefetching job. The prefetch buffers its chunks in memory until promoted;
|
|
@@ -244,10 +269,20 @@ interface ActiveAssistantTurn {
|
|
|
244
269
|
handle: VoiceTurnHandle | null;
|
|
245
270
|
assistantCompleted: boolean;
|
|
246
271
|
ttsDone: boolean;
|
|
247
|
-
// A tts_audio frame actually went out to the client — the
|
|
248
|
-
//
|
|
272
|
+
// A tts_audio frame actually went out to the client — latches on the first
|
|
273
|
+
// forwarded chunk so the firstTtsAudio metric is marked exactly once per turn.
|
|
249
274
|
ttsAudioStarted: boolean;
|
|
250
275
|
finalized: boolean;
|
|
276
|
+
// When this turn started from a barge-in, the interrupted request's
|
|
277
|
+
// transcript. Appended to the turn's control prompt (both legs) so the model
|
|
278
|
+
// merges it with this turn's utterance instead of treating that utterance as
|
|
279
|
+
// a fresh follow-up. Null for an ordinary (non-barge-in) turn.
|
|
280
|
+
interruptedRequest: string | null;
|
|
281
|
+
// Triage-and-escalate (Voice Mode): the front-door leg emitted [ESCALATE]
|
|
282
|
+
// and the strong "escalated" leg has taken over this same turn. Guards the
|
|
283
|
+
// front-door leg's trailing completion from finalizing the turn, and makes
|
|
284
|
+
// the hand-off idempotent.
|
|
285
|
+
escalationHandedOff: boolean;
|
|
251
286
|
ttsBuffer: string;
|
|
252
287
|
// A non-empty speakable segment reached the TTS queue — gates the eager
|
|
253
288
|
// first-segment flush that trades clause quality for speech onset.
|
|
@@ -264,6 +299,21 @@ interface ActiveAssistantTurn {
|
|
|
264
299
|
assistantAudioSampleRate?: number;
|
|
265
300
|
}
|
|
266
301
|
|
|
302
|
+
// Base control prompt for every live-voice turn. When a turn starts from a
|
|
303
|
+
// barge-in, the interruption merge note is appended to it (see
|
|
304
|
+
// buildInterruptionMergeNote) so the model reconciles the interrupted request
|
|
305
|
+
// with the new utterance.
|
|
306
|
+
const LIVE_VOICE_CONTROL_PROMPT =
|
|
307
|
+
"You are speaking in a local live voice session. Keep replies brief and conversational.";
|
|
308
|
+
|
|
309
|
+
// System-level guidance appended to a barge-in turn's control prompt so the
|
|
310
|
+
// model treats the new utterance as a continuation of the request it was cut
|
|
311
|
+
// off answering, rather than a fresh follow-up. Reaches the model only; it is
|
|
312
|
+
// not a user message and never renders as a transcript bubble.
|
|
313
|
+
function buildInterruptionMergeNote(interruptedRequest: string): string {
|
|
314
|
+
return `The user interrupted your previous, unfinished reply. Their earlier request was: "${interruptedRequest}". Treat their current message as a continuation of that request and address both together, or stay silent if they only want you to stop.`;
|
|
315
|
+
}
|
|
316
|
+
|
|
267
317
|
export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
268
318
|
private readonly context: LiveVoiceSessionFactoryContext;
|
|
269
319
|
private readonly resolveTranscriber: LiveVoiceStreamingTranscriberResolver;
|
|
@@ -285,7 +335,9 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
285
335
|
// Energy gate for server-VAD speech classification; undefined defers to
|
|
286
336
|
// DEFAULT_SPEECH_ENERGY_THRESHOLD.
|
|
287
337
|
private readonly speechEnergyThreshold: number | undefined;
|
|
288
|
-
|
|
338
|
+
// Mutable so a mid-session `update_config` frame can retune "interrupt
|
|
339
|
+
// sensitivity" live (see applyConfigUpdate).
|
|
340
|
+
private bargeInMinSpeechMs: number;
|
|
289
341
|
// Sustained-speech barge-in guard, armed at speech onset while the
|
|
290
342
|
// assistant turn is audibly speaking: consecutive speech-chunk duration
|
|
291
343
|
// accumulates until it reaches bargeInMinSpeechMs, then the deferred
|
|
@@ -305,6 +357,11 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
305
357
|
// the chunk's PCM duration; zeroed whenever the client flushes playback
|
|
306
358
|
// (speech_started, turn_cancelled, interrupt, close).
|
|
307
359
|
private assistantPlaybackTailUntilMs = 0;
|
|
360
|
+
// Set when barge-in cancels an in-flight turn: the interrupted request's
|
|
361
|
+
// transcript, carried into the next turn so the model merges the two.
|
|
362
|
+
// Consumed (and cleared) when that turn launches; cleared if the barge-in
|
|
363
|
+
// utterance is discarded, so it can never attach to a later, unrelated turn.
|
|
364
|
+
private pendingInterruptedRequest: string | null = null;
|
|
308
365
|
private readonly maxPendingAudioBytes: number;
|
|
309
366
|
// Set on VAD speech onset; consumed when the first speech chunk is routed
|
|
310
367
|
// to an utterance so the metric lands on the right turn.
|
|
@@ -341,6 +398,15 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
341
398
|
/** The cycle whose grace timer is armed (only the newest release has one). */
|
|
342
399
|
private finalizeGraceCycle: UtteranceCycle | null = null;
|
|
343
400
|
private readonly finalizeGraceMs: number;
|
|
401
|
+
// Registered in the registry so the HTTP surface-action path can resume a
|
|
402
|
+
// yielded interactive surface as a SPOKEN turn on this session (JARVIS-1287).
|
|
403
|
+
private readonly voiceResumeHandler: VoiceResumeHandler;
|
|
404
|
+
// A resume requested while an assistant turn was still in flight; dispatched
|
|
405
|
+
// once the active turn settles (see flushPendingResume).
|
|
406
|
+
private pendingResume: {
|
|
407
|
+
content: string;
|
|
408
|
+
opts?: VoiceResumeOptions;
|
|
409
|
+
} | null = null;
|
|
344
410
|
|
|
345
411
|
constructor(
|
|
346
412
|
context: LiveVoiceSessionFactoryContext,
|
|
@@ -358,6 +424,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
358
424
|
this.createTurnId = options.createTurnId ?? randomUUID;
|
|
359
425
|
this.conversationId =
|
|
360
426
|
context.startFrame.conversationId ?? context.sessionId;
|
|
427
|
+
this.voiceResumeHandler = {
|
|
428
|
+
resumeWithText: (content, opts) => this.resumeWithText(content, opts),
|
|
429
|
+
};
|
|
430
|
+
registerVoiceResumeHandler(this.conversationId, this.voiceResumeHandler);
|
|
361
431
|
this.metricsClock = options.metricsClock ?? Date.now;
|
|
362
432
|
this.metrics = new LiveVoiceMetricsCollector({
|
|
363
433
|
sessionId: context.sessionId,
|
|
@@ -365,12 +435,23 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
365
435
|
...(options.metricsClock ? { clock: options.metricsClock } : {}),
|
|
366
436
|
});
|
|
367
437
|
this.speechEnergyThreshold = options.speechEnergyThreshold;
|
|
438
|
+
// Precedence for the two sensitivity knobs: per-session start-frame
|
|
439
|
+
// override (the client's user setting) > daemon `liveVoice.vad` config
|
|
440
|
+
// (seeded into `options` by the factory) > in-code default.
|
|
368
441
|
this.bargeInMinSpeechMs =
|
|
369
|
-
|
|
442
|
+
context.startFrame.bargeInMinSpeechMs ??
|
|
443
|
+
options.bargeInMinSpeechMs ??
|
|
444
|
+
DEFAULT_BARGE_IN_MIN_SPEECH_MS;
|
|
370
445
|
this.finalizeGraceMs = options.finalizeGraceMs ?? FINALIZE_GRACE_MS;
|
|
446
|
+
const turnDetectorConfig: TurnDetectorConfig = {
|
|
447
|
+
...(options.turnDetectorConfig ?? {}),
|
|
448
|
+
...(context.startFrame.silenceThresholdMs !== undefined
|
|
449
|
+
? { silenceThresholdMs: context.startFrame.silenceThresholdMs }
|
|
450
|
+
: {}),
|
|
451
|
+
};
|
|
371
452
|
this.turnDetector =
|
|
372
453
|
context.startFrame.turnDetection === "server_vad"
|
|
373
|
-
? new MediaTurnDetector(
|
|
454
|
+
? new MediaTurnDetector(turnDetectorConfig, {
|
|
374
455
|
onTurnStart: () => this.handleVadSpeechStart(),
|
|
375
456
|
onTurnEnd: (reason) => this.handleVadUtteranceEnd(reason),
|
|
376
457
|
})
|
|
@@ -440,6 +521,25 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
440
521
|
return;
|
|
441
522
|
case "start":
|
|
442
523
|
return;
|
|
524
|
+
case "update_config":
|
|
525
|
+
this.applyConfigUpdate(frame);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Apply a mid-session `update_config` frame: retune the live turn detector's
|
|
532
|
+
* pause ("pause before reply") and/or the barge-in guard ("interrupt
|
|
533
|
+
* sensitivity") without reconnecting. Each field is optional and independent;
|
|
534
|
+
* changes take effect from the next utterance. A no-op on manual (non-
|
|
535
|
+
* server_vad) sessions, which have no turn detector.
|
|
536
|
+
*/
|
|
537
|
+
private applyConfigUpdate(frame: LiveVoiceClientUpdateConfigFrame): void {
|
|
538
|
+
if (frame.silenceThresholdMs !== undefined) {
|
|
539
|
+
this.turnDetector?.setSilenceThresholdMs(frame.silenceThresholdMs);
|
|
540
|
+
}
|
|
541
|
+
if (frame.bargeInMinSpeechMs !== undefined) {
|
|
542
|
+
this.bargeInMinSpeechMs = frame.bargeInMinSpeechMs;
|
|
443
543
|
}
|
|
444
544
|
}
|
|
445
545
|
|
|
@@ -454,6 +554,7 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
454
554
|
|
|
455
555
|
const shouldEmitSessionEndMetrics = this.state !== "failed";
|
|
456
556
|
this.state = "closed";
|
|
557
|
+
unregisterVoiceResumeHandler(this.conversationId, this.voiceResumeHandler);
|
|
457
558
|
this.turnDetector?.dispose();
|
|
458
559
|
this.stopSessionTranscriber();
|
|
459
560
|
await this.cancelAssistantTurn("session_closed");
|
|
@@ -622,6 +723,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
622
723
|
return;
|
|
623
724
|
}
|
|
624
725
|
|
|
726
|
+
// A resume deferred behind the finished turn takes the freed slot before a
|
|
727
|
+
// fresh utterance is armed (no-op when there's nothing pending).
|
|
728
|
+
this.flushPendingResume();
|
|
729
|
+
|
|
625
730
|
const current = this.currentUtterance;
|
|
626
731
|
if (current && !current.completed) {
|
|
627
732
|
// server_vad armed the next utterance during the finished turn; it may
|
|
@@ -846,12 +951,14 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
846
951
|
}
|
|
847
952
|
|
|
848
953
|
// VAD speech onset. Contract: speech_started tells the client to flush
|
|
849
|
-
// tail playback immediately; barge-in then cancels
|
|
850
|
-
//
|
|
851
|
-
//
|
|
852
|
-
//
|
|
853
|
-
//
|
|
854
|
-
//
|
|
954
|
+
// tail playback immediately; barge-in then cancels any in-flight,
|
|
955
|
+
// non-finalized turn — including a pre-TTS "thinking" turn whose reply is
|
|
956
|
+
// still being generated, so a user can cut in before the assistant starts
|
|
957
|
+
// talking (JARVIS-1266). Speaking over a thinking or audibly speaking turn
|
|
958
|
+
// is deferred behind the same sustained-speech guard, so a cough or noise
|
|
959
|
+
// blip cannot kill an unspoken reply or clip a spoken one; sustained speech
|
|
960
|
+
// aborts the turn. Onset while listening keeps the instant speech_started
|
|
961
|
+
// (turn-taking latency is untouched).
|
|
855
962
|
private handleVadSpeechStart(): void {
|
|
856
963
|
if (this.isClosed || this.state === "failed") {
|
|
857
964
|
return;
|
|
@@ -860,25 +967,27 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
860
967
|
this.vadSpeechStartPending = true;
|
|
861
968
|
|
|
862
969
|
const turn = this.activeAssistantTurn;
|
|
863
|
-
|
|
864
|
-
|
|
970
|
+
// Any in-flight, non-finalized turn is interruptible, whether it is still
|
|
971
|
+
// "thinking" (pre-TTS) or audibly speaking, so a user can cut in before the
|
|
972
|
+
// assistant starts talking.
|
|
973
|
+
const bargeableTurn = turn && !turn.finalized ? turn : null;
|
|
865
974
|
// The client can still be draining audible playback after tts_done
|
|
866
975
|
// (the turn is already cleared server-side) — that tail deserves the
|
|
867
976
|
// same guard, or a noise blip clips the reply's last words.
|
|
868
977
|
const drainingPlayback = Date.now() < this.assistantPlaybackTailUntilMs;
|
|
869
978
|
|
|
870
|
-
if ((
|
|
979
|
+
if ((bargeableTurn || drainingPlayback) && this.bargeInMinSpeechMs > 0) {
|
|
871
980
|
// Onset audio keeps flowing into the cycle/pre-roll while the guard
|
|
872
981
|
// accumulates (trackBargeInGuard), so no speech is lost either way.
|
|
873
|
-
this.pendingBargeIn = { turn:
|
|
982
|
+
this.pendingBargeIn = { turn: bargeableTurn, speechMs: 0 };
|
|
874
983
|
return;
|
|
875
984
|
}
|
|
876
985
|
|
|
877
986
|
this.pendingBargeIn = null;
|
|
878
987
|
this.assistantPlaybackTailUntilMs = 0;
|
|
879
988
|
void this.sendFrame({ type: "speech_started" });
|
|
880
|
-
if (
|
|
881
|
-
this.bargeIn(
|
|
989
|
+
if (bargeableTurn) {
|
|
990
|
+
this.bargeIn(bargeableTurn);
|
|
882
991
|
}
|
|
883
992
|
}
|
|
884
993
|
|
|
@@ -917,6 +1026,13 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
917
1026
|
// do not collide with it in the collector. turn_cancelled flushes
|
|
918
1027
|
// client playback, so the drain estimate resets with it.
|
|
919
1028
|
this.assistantPlaybackTailUntilMs = 0;
|
|
1029
|
+
// Carry the interrupted request into the next turn so it merges with the
|
|
1030
|
+
// barge-in utterance rather than being answered as a fresh follow-up.
|
|
1031
|
+
const interruptedRequest = turn.utterance.finalTranscriptSegments
|
|
1032
|
+
.join(" ")
|
|
1033
|
+
.trim();
|
|
1034
|
+
this.pendingInterruptedRequest =
|
|
1035
|
+
interruptedRequest.length > 0 ? interruptedRequest : null;
|
|
920
1036
|
turn.abortController.abort();
|
|
921
1037
|
this.metrics.markBargeIn(turn.turnId);
|
|
922
1038
|
void (async () => {
|
|
@@ -1363,6 +1479,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1363
1479
|
this.assistantPlaybackTailUntilMs = 0;
|
|
1364
1480
|
this.takeVadPreRoll();
|
|
1365
1481
|
this.vadPendingTurnEnd = null;
|
|
1482
|
+
// A client interrupt is a hard reset: any barge-in merge context waiting for
|
|
1483
|
+
// the next turn is now stale (the interrupted utterance may be discarded
|
|
1484
|
+
// without ever reaching finalizePendingUtterance).
|
|
1485
|
+
this.pendingInterruptedRequest = null;
|
|
1366
1486
|
const utterance = this.currentUtterance;
|
|
1367
1487
|
this.stopSessionTranscriber();
|
|
1368
1488
|
if (utterance) {
|
|
@@ -1435,12 +1555,34 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1435
1555
|
return;
|
|
1436
1556
|
}
|
|
1437
1557
|
|
|
1558
|
+
// Consume any pending barge-in merge context for this turn (one barge-in
|
|
1559
|
+
// feeds exactly the next launched turn).
|
|
1560
|
+
const interruptedRequest = this.pendingInterruptedRequest;
|
|
1561
|
+
this.pendingInterruptedRequest = null;
|
|
1562
|
+
await this.launchAssistantTurn(utterance, content, { interruptedRequest });
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
// Build the ActiveAssistantTurn for a released utterance and drive its model
|
|
1566
|
+
// leg. Shared by the STT path (startAssistantTurnIfReady) and the spoken
|
|
1567
|
+
// surface-resume path (startResumeTurn) so both run identical turn machinery.
|
|
1568
|
+
private async launchAssistantTurn(
|
|
1569
|
+
utterance: UtteranceCycle,
|
|
1570
|
+
content: string,
|
|
1571
|
+
opts?: {
|
|
1572
|
+
// Only set on the surface-resume path; the STT path leaves it undefined
|
|
1573
|
+
// so no active-surface context is injected into an ordinary spoken turn.
|
|
1574
|
+
activeSurfaceId?: string;
|
|
1575
|
+
// Set on a barge-in follow-up turn: the interrupted request's transcript,
|
|
1576
|
+
// appended to the turn's control prompt so the model merges the two.
|
|
1577
|
+
interruptedRequest?: string | null;
|
|
1578
|
+
},
|
|
1579
|
+
): Promise<void> {
|
|
1438
1580
|
utterance.assistantTurnStarted = true;
|
|
1439
1581
|
const token = Symbol("live-voice-assistant-turn");
|
|
1440
1582
|
const turnId = this.ensureTurnId(utterance);
|
|
1441
1583
|
this.startMetricsTurnIfNeeded(utterance, turnId);
|
|
1442
1584
|
const abortController = new AbortController();
|
|
1443
|
-
|
|
1585
|
+
const activeTurn: ActiveAssistantTurn = {
|
|
1444
1586
|
token,
|
|
1445
1587
|
turnId,
|
|
1446
1588
|
utterance,
|
|
@@ -1450,6 +1592,8 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1450
1592
|
ttsDone: false,
|
|
1451
1593
|
ttsAudioStarted: false,
|
|
1452
1594
|
finalized: false,
|
|
1595
|
+
interruptedRequest: opts?.interruptedRequest ?? null,
|
|
1596
|
+
escalationHandedOff: false,
|
|
1453
1597
|
ttsBuffer: "",
|
|
1454
1598
|
ttsSegmentEnqueued: false,
|
|
1455
1599
|
ttsJobs: [],
|
|
@@ -1458,12 +1602,234 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1458
1602
|
assistantAudioChunks: [],
|
|
1459
1603
|
assistantAudioMimeType: "audio/pcm",
|
|
1460
1604
|
};
|
|
1605
|
+
this.activeAssistantTurn = activeTurn;
|
|
1461
1606
|
|
|
1462
1607
|
await this.sendFrame({ type: "thinking", turnId });
|
|
1463
1608
|
if (!this.isActiveAssistantTurn(token)) {
|
|
1464
1609
|
return;
|
|
1465
1610
|
}
|
|
1466
1611
|
|
|
1612
|
+
// Triage-and-escalate (Voice Mode): active only when BOTH the voice-mode
|
|
1613
|
+
// surface flag and the voice-triage-escalate routing flag are on. A
|
|
1614
|
+
// live-voice session already implies voice-mode client-side; the explicit
|
|
1615
|
+
// check keeps the "gated behind both flags" contract true server-side.
|
|
1616
|
+
const cfg = getConfig();
|
|
1617
|
+
const escalateEnabled =
|
|
1618
|
+
isAssistantFeatureFlagEnabled("voice-mode", cfg) &&
|
|
1619
|
+
isVoiceTriageEscalateEnabled(cfg);
|
|
1620
|
+
|
|
1621
|
+
// Front-door leg: with routing on, a fast profile fronts the turn and may
|
|
1622
|
+
// hand off to the strong profile on [ESCALATE]; with it off, a single leg
|
|
1623
|
+
// runs on the call-site default — byte-for-byte the prior behavior.
|
|
1624
|
+
await this.startAssistantLeg(
|
|
1625
|
+
activeTurn,
|
|
1626
|
+
escalateEnabled
|
|
1627
|
+
? {
|
|
1628
|
+
content,
|
|
1629
|
+
overrideProfile: FRONT_DOOR_PROFILE,
|
|
1630
|
+
routingLeg: "front-door",
|
|
1631
|
+
frontDoor: true,
|
|
1632
|
+
...(opts?.activeSurfaceId !== undefined
|
|
1633
|
+
? { activeSurfaceId: opts.activeSurfaceId }
|
|
1634
|
+
: {}),
|
|
1635
|
+
}
|
|
1636
|
+
: {
|
|
1637
|
+
content,
|
|
1638
|
+
...(opts?.activeSurfaceId !== undefined
|
|
1639
|
+
? { activeSurfaceId: opts.activeSurfaceId }
|
|
1640
|
+
: {}),
|
|
1641
|
+
},
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
/**
|
|
1646
|
+
* Resume a yielded interactive surface as a SPOKEN turn. The HTTP surface-
|
|
1647
|
+
* action path calls this (via the resume registry) once the user completes a
|
|
1648
|
+
* surface the voice turn raised, so the follow-up reply is synthesized to
|
|
1649
|
+
* audio through this session's TTS pipeline instead of running silently
|
|
1650
|
+
* through the text pipeline (JARVIS-1287).
|
|
1651
|
+
*
|
|
1652
|
+
* If a turn is still in flight the resume is deferred (pendingResume) and
|
|
1653
|
+
* dispatched once that turn settles — never rejected with CONVERSATION_BUSY.
|
|
1654
|
+
*/
|
|
1655
|
+
resumeWithText(content: string, opts?: VoiceResumeOptions): void {
|
|
1656
|
+
const trimmed = content.trim();
|
|
1657
|
+
if (
|
|
1658
|
+
this.isClosed ||
|
|
1659
|
+
this.state === "failed" ||
|
|
1660
|
+
!this.startVoiceTurn ||
|
|
1661
|
+
trimmed.length === 0
|
|
1662
|
+
) {
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
if (this.activeAssistantTurn) {
|
|
1666
|
+
this.pendingResume = { content: trimmed, opts };
|
|
1667
|
+
return;
|
|
1668
|
+
}
|
|
1669
|
+
void this.startResumeTurn(trimmed, opts).catch((err) => {
|
|
1670
|
+
log.error(
|
|
1671
|
+
{ err, conversationId: this.conversationId },
|
|
1672
|
+
"live-voice resume turn failed",
|
|
1673
|
+
);
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
private async startResumeTurn(
|
|
1678
|
+
content: string,
|
|
1679
|
+
opts?: VoiceResumeOptions,
|
|
1680
|
+
): Promise<void> {
|
|
1681
|
+
if (this.isClosed || this.state === "failed" || !this.startVoiceTurn) {
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
if (this.activeAssistantTurn) {
|
|
1685
|
+
this.pendingResume = { content, opts };
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
// A synthetic utterance carrying only the resume text: it is not
|
|
1689
|
+
// this.currentUtterance (which holds the server-VAD armed next utterance),
|
|
1690
|
+
// so the armed transcriber is untouched. finalizeAssistantTurn works on
|
|
1691
|
+
// turn.utterance and tolerates the empty audio buffers.
|
|
1692
|
+
const utterance: UtteranceCycle = {
|
|
1693
|
+
phase: "transcriber_closed",
|
|
1694
|
+
released: true,
|
|
1695
|
+
assistantTurnStarted: false,
|
|
1696
|
+
completed: false,
|
|
1697
|
+
finalizeRequested: false,
|
|
1698
|
+
transcriber: null,
|
|
1699
|
+
pendingAudioChunks: [],
|
|
1700
|
+
pendingAudioBytes: 0,
|
|
1701
|
+
finalTranscriptSegments: [content],
|
|
1702
|
+
turnId: null,
|
|
1703
|
+
userMessageId: null,
|
|
1704
|
+
userAudioChunks: [],
|
|
1705
|
+
metricsTurnStarted: false,
|
|
1706
|
+
metricsTurnFinished: false,
|
|
1707
|
+
stashedMetricsMarks: {
|
|
1708
|
+
firstAudioAtMs: null,
|
|
1709
|
+
firstPartialAtMs: null,
|
|
1710
|
+
speechStartAtMs: null,
|
|
1711
|
+
utteranceEndAtMs: null,
|
|
1712
|
+
finalTranscriptAtMs: null,
|
|
1713
|
+
},
|
|
1714
|
+
};
|
|
1715
|
+
await this.launchAssistantTurn(utterance, content, {
|
|
1716
|
+
activeSurfaceId: opts?.activeSurfaceId,
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
// Dispatch a resume deferred behind an in-flight turn, once that turn has
|
|
1721
|
+
// settled. Null out pendingResume before dispatch so a re-entrant settle
|
|
1722
|
+
// cannot double-fire the same resume.
|
|
1723
|
+
private flushPendingResume(): void {
|
|
1724
|
+
const deferred = this.pendingResume;
|
|
1725
|
+
this.pendingResume = null;
|
|
1726
|
+
if (
|
|
1727
|
+
deferred &&
|
|
1728
|
+
!this.activeAssistantTurn &&
|
|
1729
|
+
!this.isClosed &&
|
|
1730
|
+
this.state !== "failed"
|
|
1731
|
+
) {
|
|
1732
|
+
void this.startResumeTurn(deferred.content, deferred.opts).catch(
|
|
1733
|
+
(err) => {
|
|
1734
|
+
log.error(
|
|
1735
|
+
{ err, conversationId: this.conversationId },
|
|
1736
|
+
"live-voice deferred resume turn failed",
|
|
1737
|
+
);
|
|
1738
|
+
},
|
|
1739
|
+
);
|
|
1740
|
+
} else if (deferred) {
|
|
1741
|
+
// Could not dispatch now (turn still active / session gone); keep it for
|
|
1742
|
+
// the next settle point rather than dropping it.
|
|
1743
|
+
this.pendingResume = deferred;
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
/**
|
|
1748
|
+
* Drive one model leg of an assistant turn through the session bridge,
|
|
1749
|
+
* streaming its deltas to the live-voice client and TTS. Returns once the
|
|
1750
|
+
* leg's turn handle is acquired (or the start fails) — turn completion stays
|
|
1751
|
+
* callback-driven via message_complete, exactly as the single-leg path did.
|
|
1752
|
+
*
|
|
1753
|
+
* A turn runs one leg normally. Under triage-and-escalate the front-door leg
|
|
1754
|
+
* (`frontDoor: true`) may emit [ESCALATE]; the marker and everything after it
|
|
1755
|
+
* are held back from the live-voice transcript and TTS here at the source,
|
|
1756
|
+
* and `escalateTurn` starts a second "escalated" leg that shares this same
|
|
1757
|
+
* ActiveAssistantTurn. (The shared conversation-hub broadcast and persisted
|
|
1758
|
+
* assistant message still carry the raw marker — see issue #37850.)
|
|
1759
|
+
*/
|
|
1760
|
+
private async startAssistantLeg(
|
|
1761
|
+
activeTurn: ActiveAssistantTurn,
|
|
1762
|
+
leg: {
|
|
1763
|
+
content: string;
|
|
1764
|
+
overrideProfile?: string;
|
|
1765
|
+
routingLeg?: VoiceRoutingLeg;
|
|
1766
|
+
frontDoor?: boolean;
|
|
1767
|
+
// Present only on the primary surface-resume leg — never on the escalated
|
|
1768
|
+
// continuation leg, so the active-surface context stays turn-scoped.
|
|
1769
|
+
activeSurfaceId?: string;
|
|
1770
|
+
},
|
|
1771
|
+
): Promise<void> {
|
|
1772
|
+
if (!this.startVoiceTurn) {
|
|
1773
|
+
return;
|
|
1774
|
+
}
|
|
1775
|
+
const { token, utterance, turnId } = activeTurn;
|
|
1776
|
+
|
|
1777
|
+
// Front-door marker gate. `rawText` accumulates this leg's full stream (for
|
|
1778
|
+
// marker detection and the fallback-bridge decision); `frontDoorEmitted`
|
|
1779
|
+
// tracks how much of it has been forwarded, so a trailing partial marker
|
|
1780
|
+
// held back on one delta is released once a later delta disproves it.
|
|
1781
|
+
let rawText = "";
|
|
1782
|
+
let frontDoorEmitted = 0;
|
|
1783
|
+
|
|
1784
|
+
const emitFrontDoor = (chunk: string): void => {
|
|
1785
|
+
if (chunk.length === 0) {
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
this.markFirstAssistantDelta(utterance, turnId);
|
|
1789
|
+
// Same send-time abort gate as the default-leg delta path: a front-door
|
|
1790
|
+
// delta queued behind a backed-up outbound frame must not be written
|
|
1791
|
+
// once barge-in aborts the turn. Escalation aborts the front-door handle,
|
|
1792
|
+
// not this turn's controller, so legitimate front-door text still sends.
|
|
1793
|
+
void this.sendFrame(
|
|
1794
|
+
{ type: "assistant_text_delta", text: chunk },
|
|
1795
|
+
() => !activeTurn.abortController.signal.aborted && !this.isClosed,
|
|
1796
|
+
);
|
|
1797
|
+
this.bufferAssistantTextForTts(token, chunk);
|
|
1798
|
+
};
|
|
1799
|
+
|
|
1800
|
+
// Forward the marker-free, non-partial-marker prefix that has not been
|
|
1801
|
+
// emitted yet. Returns true once the complete [ESCALATE] marker arrives.
|
|
1802
|
+
const flushFrontDoor = (): boolean => {
|
|
1803
|
+
const markerIdx = rawText.indexOf(ESCALATE_MARKER, frontDoorEmitted);
|
|
1804
|
+
if (markerIdx !== -1) {
|
|
1805
|
+
emitFrontDoor(
|
|
1806
|
+
stripInternalSpeechMarkers(
|
|
1807
|
+
rawText.slice(frontDoorEmitted, markerIdx),
|
|
1808
|
+
),
|
|
1809
|
+
);
|
|
1810
|
+
// Suppress the marker and anything the model streams after it.
|
|
1811
|
+
frontDoorEmitted = rawText.length;
|
|
1812
|
+
return true;
|
|
1813
|
+
}
|
|
1814
|
+
let safeEnd = rawText.length;
|
|
1815
|
+
const lastOpen = rawText.lastIndexOf("[");
|
|
1816
|
+
if (lastOpen >= frontDoorEmitted) {
|
|
1817
|
+
const tail = rawText.slice(lastOpen);
|
|
1818
|
+
// Hold back a trailing "[…" that could still become a control marker;
|
|
1819
|
+
// a real partial that never completes is simply never spoken.
|
|
1820
|
+
if (!tail.includes("]") && couldBeControlMarker(tail)) {
|
|
1821
|
+
safeEnd = lastOpen;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
if (safeEnd > frontDoorEmitted) {
|
|
1825
|
+
emitFrontDoor(
|
|
1826
|
+
stripInternalSpeechMarkers(rawText.slice(frontDoorEmitted, safeEnd)),
|
|
1827
|
+
);
|
|
1828
|
+
frontDoorEmitted = safeEnd;
|
|
1829
|
+
}
|
|
1830
|
+
return false;
|
|
1831
|
+
};
|
|
1832
|
+
|
|
1467
1833
|
try {
|
|
1468
1834
|
const handle = await this.startVoiceTurn({
|
|
1469
1835
|
conversationId: this.conversationId,
|
|
@@ -1472,67 +1838,106 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1472
1838
|
assistantMessageChannel: "vellum",
|
|
1473
1839
|
userMessageInterface: "macos",
|
|
1474
1840
|
assistantMessageInterface: "macos",
|
|
1475
|
-
voiceControlPrompt:
|
|
1476
|
-
|
|
1841
|
+
voiceControlPrompt: activeTurn.interruptedRequest
|
|
1842
|
+
? `${LIVE_VOICE_CONTROL_PROMPT}\n\n${buildInterruptionMergeNote(
|
|
1843
|
+
activeTurn.interruptedRequest,
|
|
1844
|
+
)}`
|
|
1845
|
+
: LIVE_VOICE_CONTROL_PROMPT,
|
|
1477
1846
|
approvalMode: "local-live-voice",
|
|
1478
|
-
content,
|
|
1847
|
+
content: leg.content,
|
|
1479
1848
|
isInbound: true,
|
|
1480
|
-
signal: abortController.signal,
|
|
1849
|
+
signal: activeTurn.abortController.signal,
|
|
1850
|
+
...(leg.overrideProfile != null
|
|
1851
|
+
? { overrideProfile: leg.overrideProfile }
|
|
1852
|
+
: {}),
|
|
1853
|
+
...(leg.routingLeg != null ? { routingLeg: leg.routingLeg } : {}),
|
|
1854
|
+
...(leg.activeSurfaceId != null
|
|
1855
|
+
? { activeSurfaceId: leg.activeSurfaceId }
|
|
1856
|
+
: {}),
|
|
1481
1857
|
callbacks: {
|
|
1482
1858
|
assistant_text_delta: (msg) => {
|
|
1483
1859
|
if (!this.isForwardingAssistantText(token)) {
|
|
1484
1860
|
return;
|
|
1485
1861
|
}
|
|
1862
|
+
if (leg.frontDoor) {
|
|
1863
|
+
rawText += msg.text;
|
|
1864
|
+
if (activeTurn.escalationHandedOff) {
|
|
1865
|
+
return;
|
|
1866
|
+
}
|
|
1867
|
+
if (flushFrontDoor()) {
|
|
1868
|
+
this.escalateTurn(activeTurn, rawText);
|
|
1869
|
+
}
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1486
1872
|
this.markFirstAssistantDelta(utterance, turnId);
|
|
1487
|
-
void this.sendFrame(
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1873
|
+
void this.sendFrame(
|
|
1874
|
+
{
|
|
1875
|
+
type: "assistant_text_delta",
|
|
1876
|
+
text: msg.text,
|
|
1877
|
+
},
|
|
1878
|
+
// Re-check at send time (mirrors the tts_audio path): a delta
|
|
1879
|
+
// already queued behind a backed-up outbound frame must not be
|
|
1880
|
+
// written once barge-in has aborted the turn, or the cancelled
|
|
1881
|
+
// reply's text leaks ahead of turn_cancelled. Key off this turn's
|
|
1882
|
+
// own abort signal — a normal message_complete finalizes and
|
|
1883
|
+
// clears activeAssistantTurn while trailing deltas may still be
|
|
1884
|
+
// draining, so an activeAssistantTurn-based guard would drop them.
|
|
1885
|
+
() =>
|
|
1886
|
+
!activeTurn.abortController.signal.aborted && !this.isClosed,
|
|
1887
|
+
);
|
|
1491
1888
|
this.bufferAssistantTextForTts(token, msg.text);
|
|
1492
1889
|
},
|
|
1493
1890
|
message_complete: (msg) => {
|
|
1494
|
-
const
|
|
1891
|
+
const current = this.activeAssistantTurn;
|
|
1495
1892
|
if (
|
|
1496
|
-
|
|
1497
|
-
|
|
1893
|
+
current?.token !== token ||
|
|
1894
|
+
current.assistantCompleted ||
|
|
1498
1895
|
// A barged-in turn finalizes through cancelAssistantTurn.
|
|
1499
|
-
|
|
1896
|
+
current.abortController.signal.aborted ||
|
|
1500
1897
|
this.isClosed
|
|
1501
1898
|
) {
|
|
1502
1899
|
return;
|
|
1503
1900
|
}
|
|
1504
|
-
|
|
1901
|
+
// A front-door leg that handed off is finished; the escalated leg
|
|
1902
|
+
// drives completion. The front-door leg's own trailing completion
|
|
1903
|
+
// (including the generation_cancelled from its abort) is a no-op.
|
|
1904
|
+
if (leg.frontDoor && current.escalationHandedOff) {
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
current.assistantCompleted = true;
|
|
1505
1908
|
if (msg.type === "generation_cancelled") {
|
|
1506
1909
|
void this.finalizeAssistantTurn(
|
|
1507
|
-
|
|
1910
|
+
current,
|
|
1508
1911
|
"cancelled",
|
|
1509
1912
|
"generation_cancelled",
|
|
1510
1913
|
);
|
|
1511
1914
|
return;
|
|
1512
1915
|
}
|
|
1513
|
-
|
|
1916
|
+
current.assistantMessageId = msg.messageId ?? null;
|
|
1514
1917
|
this.completeTtsForTurn(token);
|
|
1515
1918
|
},
|
|
1516
1919
|
persisted_user_message_id: (messageId) => {
|
|
1517
|
-
const
|
|
1518
|
-
|
|
1920
|
+
const current = this.activeAssistantTurn;
|
|
1921
|
+
// Only the first leg's user row is the real caller utterance; the
|
|
1922
|
+
// escalated leg persists a hidden synthetic continuation prompt.
|
|
1923
|
+
if (current?.token !== token || leg.routingLeg === "escalated") {
|
|
1519
1924
|
return;
|
|
1520
1925
|
}
|
|
1521
|
-
|
|
1926
|
+
current.utterance.userMessageId = messageId;
|
|
1522
1927
|
},
|
|
1523
1928
|
persisted_assistant_message_id: (messageId) => {
|
|
1524
|
-
const
|
|
1525
|
-
if (
|
|
1929
|
+
const current = this.activeAssistantTurn;
|
|
1930
|
+
if (current?.token !== token) {
|
|
1526
1931
|
return;
|
|
1527
1932
|
}
|
|
1528
|
-
|
|
1933
|
+
current.assistantMessageId = messageId;
|
|
1529
1934
|
},
|
|
1530
1935
|
},
|
|
1531
1936
|
onError: (message) => {
|
|
1532
|
-
const
|
|
1937
|
+
const current = this.activeAssistantTurn;
|
|
1533
1938
|
if (
|
|
1534
1939
|
!this.isActiveAssistantTurn(token) ||
|
|
1535
|
-
|
|
1940
|
+
current?.assistantCompleted
|
|
1536
1941
|
) {
|
|
1537
1942
|
return;
|
|
1538
1943
|
}
|
|
@@ -1551,17 +1956,23 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1551
1956
|
},
|
|
1552
1957
|
});
|
|
1553
1958
|
|
|
1554
|
-
const
|
|
1555
|
-
if (
|
|
1959
|
+
const current = this.activeAssistantTurn;
|
|
1960
|
+
if (current?.token !== token) {
|
|
1556
1961
|
handle.abort();
|
|
1557
1962
|
return;
|
|
1558
1963
|
}
|
|
1559
|
-
if (
|
|
1964
|
+
if (current.finalized) {
|
|
1560
1965
|
this.activeAssistantTurn = null;
|
|
1561
1966
|
return;
|
|
1562
1967
|
}
|
|
1968
|
+
// The front-door leg may have handed off before its handle resolved;
|
|
1969
|
+
// abort it rather than exposing it as the turn's live handle.
|
|
1970
|
+
if (leg.frontDoor && current.escalationHandedOff) {
|
|
1971
|
+
handle.abort();
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1563
1974
|
|
|
1564
|
-
|
|
1975
|
+
current.handle = handle;
|
|
1565
1976
|
} catch (err) {
|
|
1566
1977
|
if (!this.isActiveAssistantTurn(token)) {
|
|
1567
1978
|
return;
|
|
@@ -1580,6 +1991,47 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1580
1991
|
}
|
|
1581
1992
|
}
|
|
1582
1993
|
|
|
1994
|
+
/**
|
|
1995
|
+
* Hand the turn from the front-door leg to the strong "escalated" leg after
|
|
1996
|
+
* [ESCALATE]. Speaks a holding phrase (the front-door leg's own pre-marker
|
|
1997
|
+
* text, or a canned fallback when that was too short) and force-flushes it so
|
|
1998
|
+
* it plays during the strong-model call, then starts the escalated leg on the
|
|
1999
|
+
* same ActiveAssistantTurn. Idempotent.
|
|
2000
|
+
*/
|
|
2001
|
+
private escalateTurn(
|
|
2002
|
+
activeTurn: ActiveAssistantTurn,
|
|
2003
|
+
frontDoorText: string,
|
|
2004
|
+
): void {
|
|
2005
|
+
if (activeTurn.escalationHandedOff || activeTurn.finalized) {
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
activeTurn.escalationHandedOff = true;
|
|
2009
|
+
// Abort the front-door leg so a model that keeps generating past the marker
|
|
2010
|
+
// adds no latency before the escalated leg starts.
|
|
2011
|
+
activeTurn.handle?.abort();
|
|
2012
|
+
activeTurn.handle = null;
|
|
2013
|
+
|
|
2014
|
+
// Speak a bridge so the strong-model call has no dead air. Fall back to a
|
|
2015
|
+
// canned phrase only when the front-door leg spoke too little before the
|
|
2016
|
+
// marker (measured pre-marker, so suppressed post-marker text can't count).
|
|
2017
|
+
if (needsFallbackBridge(frontDoorText)) {
|
|
2018
|
+
this.bufferAssistantTextForTts(
|
|
2019
|
+
activeTurn.token,
|
|
2020
|
+
`${FALLBACK_ESCALATION_BRIDGE} `,
|
|
2021
|
+
);
|
|
2022
|
+
}
|
|
2023
|
+
// Force-flush now: on the TTS path an unpunctuated bridge would otherwise
|
|
2024
|
+
// sit buffered until a sentence boundary and leave the caller in silence
|
|
2025
|
+
// during the escalated model's call.
|
|
2026
|
+
this.flushTtsBuffer(activeTurn.token, true);
|
|
2027
|
+
|
|
2028
|
+
void this.startAssistantLeg(activeTurn, {
|
|
2029
|
+
content: ESCALATION_CONTINUATION_CONTENT,
|
|
2030
|
+
overrideProfile: ESCALATION_PROFILE,
|
|
2031
|
+
routingLeg: "escalated",
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
|
|
1583
2035
|
private async cancelAssistantTurn(reason: string): Promise<void> {
|
|
1584
2036
|
const turn = this.activeAssistantTurn;
|
|
1585
2037
|
this.activeAssistantTurn = null;
|
|
@@ -1605,7 +2057,14 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1605
2057
|
private isActiveAssistantTurn(token: symbol): boolean {
|
|
1606
2058
|
const activeTurn = this.activeAssistantTurn;
|
|
1607
2059
|
return (
|
|
1608
|
-
activeTurn?.token === token &&
|
|
2060
|
+
activeTurn?.token === token &&
|
|
2061
|
+
!activeTurn.finalized &&
|
|
2062
|
+
// Barge-in aborts synchronously but finalizes through an async
|
|
2063
|
+
// cancelAssistantTurn chain; the abort makes the turn dead at once so a
|
|
2064
|
+
// rejected startVoiceTurn or a trailing onError in that window does not
|
|
2065
|
+
// treat it as live (and emit a stray error frame or double-finalize).
|
|
2066
|
+
!activeTurn.abortController.signal.aborted &&
|
|
2067
|
+
!this.isClosed
|
|
1609
2068
|
);
|
|
1610
2069
|
}
|
|
1611
2070
|
|
|
@@ -1615,6 +2074,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1615
2074
|
activeTurn?.token === token &&
|
|
1616
2075
|
!activeTurn.assistantCompleted &&
|
|
1617
2076
|
!activeTurn.finalized &&
|
|
2077
|
+
// Fence a late first assistant_text_delta once barge-in aborts a pre-TTS
|
|
2078
|
+
// turn, before its async teardown finalizes — mirrors isForwardingTts so
|
|
2079
|
+
// no cancelled-turn text leaks after turn_cancelled.
|
|
2080
|
+
!activeTurn.abortController.signal.aborted &&
|
|
1618
2081
|
!this.isClosed
|
|
1619
2082
|
);
|
|
1620
2083
|
}
|
|
@@ -1688,6 +2151,14 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1688
2151
|
}
|
|
1689
2152
|
}
|
|
1690
2153
|
|
|
2154
|
+
// Now that the active turn is actually cleared, dispatch a resume that
|
|
2155
|
+
// arrived mid-turn. `finalizeAssistantTurn` runs its own flush too, but
|
|
2156
|
+
// this path finalizes with `clearActive: false`, so at that point the
|
|
2157
|
+
// slot was still taken and the flush re-stashed. `scheduleRearmAfterTurn`
|
|
2158
|
+
// below no-ops in manual (no-`turnDetector`) sessions, so without this
|
|
2159
|
+
// flush the deferred resume would never start there (JARVIS-1287).
|
|
2160
|
+
this.flushPendingResume();
|
|
2161
|
+
|
|
1691
2162
|
// Re-arm only after the terminal tts_done frame so a slow or failing
|
|
1692
2163
|
// next transcriber cannot block or precede turn completion. A
|
|
1693
2164
|
// cancelled turn re-arms through cancelAssistantTurn instead.
|
|
@@ -1879,9 +2350,13 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1879
2350
|
if (activeTurn?.token !== token) {
|
|
1880
2351
|
return;
|
|
1881
2352
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
)
|
|
2353
|
+
// Only retain the assistant TTS audio when it will be archived (see
|
|
2354
|
+
// collectUserAudio); the mime/sample-rate are cheap and left unconditional.
|
|
2355
|
+
if (this.archiveAudio) {
|
|
2356
|
+
activeTurn.assistantAudioChunks.push(
|
|
2357
|
+
Buffer.from(chunk.dataBase64, "base64"),
|
|
2358
|
+
);
|
|
2359
|
+
}
|
|
1885
2360
|
activeTurn.assistantAudioMimeType = chunk.contentType;
|
|
1886
2361
|
activeTurn.assistantAudioSampleRate = chunk.sampleRate;
|
|
1887
2362
|
job.frames = job.frames.then(async () => {
|
|
@@ -1894,10 +2369,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1894
2369
|
},
|
|
1895
2370
|
() => this.isForwardingTts(token),
|
|
1896
2371
|
);
|
|
1897
|
-
//
|
|
1898
|
-
//
|
|
1899
|
-
//
|
|
1900
|
-
// from
|
|
2372
|
+
// Skip a frame that wasn't actually written — a backed-up outbound
|
|
2373
|
+
// queue hasn't reached the client, so it must not extend the
|
|
2374
|
+
// playback-tail estimate or latch first-audio state. Token match keeps
|
|
2375
|
+
// a stale turn's late send from latching a newer turn.
|
|
1901
2376
|
if (!sent) {
|
|
1902
2377
|
return;
|
|
1903
2378
|
}
|
|
@@ -1921,7 +2396,12 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
1921
2396
|
}
|
|
1922
2397
|
|
|
1923
2398
|
private collectUserAudio(utterance: UtteranceCycle, chunk: Buffer): void {
|
|
1924
|
-
|
|
2399
|
+
// Only retain the raw audio when it will actually be archived — otherwise
|
|
2400
|
+
// buffering a whole turn's PCM is dead memory. The first-audio metric is
|
|
2401
|
+
// independent of archiving, so it stays unconditional.
|
|
2402
|
+
if (this.archiveAudio) {
|
|
2403
|
+
utterance.userAudioChunks.push(Buffer.from(chunk));
|
|
2404
|
+
}
|
|
1925
2405
|
this.markUtteranceMetric(utterance, "firstAudioAtMs", (turnId) =>
|
|
1926
2406
|
this.metrics.markFirstAudio(turnId),
|
|
1927
2407
|
);
|
|
@@ -2036,6 +2516,13 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
2036
2516
|
utterance: UtteranceCycle,
|
|
2037
2517
|
reason: string,
|
|
2038
2518
|
): Promise<void> {
|
|
2519
|
+
// An utterance that finalizes here never became a turn (empty transcript,
|
|
2520
|
+
// client interrupt, transcriber close, error), so it ends the window a
|
|
2521
|
+
// barge-in's merge context was waiting to attach to. Drop that context so
|
|
2522
|
+
// it can't leak into a later, unrelated turn. The barged turn itself
|
|
2523
|
+
// finalizes through finalizeAssistantTurn, not here, so this never clears a
|
|
2524
|
+
// request that the barge-in follow-up turn is still about to consume.
|
|
2525
|
+
this.pendingInterruptedRequest = null;
|
|
2039
2526
|
utterance.completed = true;
|
|
2040
2527
|
const turnId = utterance.turnId;
|
|
2041
2528
|
if (!turnId) {
|
|
@@ -2089,6 +2576,11 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
|
|
|
2089
2576
|
if (options.rearm ?? true) {
|
|
2090
2577
|
this.scheduleRearmAfterTurn();
|
|
2091
2578
|
}
|
|
2579
|
+
|
|
2580
|
+
// A surface-resume that arrived mid-turn waits here: the just-cleared
|
|
2581
|
+
// active turn frees the slot, so dispatch it now. rearmAfterTurn also
|
|
2582
|
+
// flushes (covers the manual path where scheduleRearmAfterTurn no-ops).
|
|
2583
|
+
this.flushPendingResume();
|
|
2092
2584
|
}
|
|
2093
2585
|
|
|
2094
2586
|
private async archiveBufferedAudio(input: {
|
|
@@ -2316,7 +2808,8 @@ export function createLiveVoiceSession(
|
|
|
2316
2808
|
// unchanged. Optional-chained
|
|
2317
2809
|
// because hand-built test configs may predate the liveVoice namespace;
|
|
2318
2810
|
// absent config falls through to the in-code defaults.
|
|
2319
|
-
const
|
|
2811
|
+
const liveVoiceConfig = getConfig().liveVoice;
|
|
2812
|
+
const vadConfig = liveVoiceConfig?.vad;
|
|
2320
2813
|
return new LiveVoiceSession(context, {
|
|
2321
2814
|
...options,
|
|
2322
2815
|
turnDetectorConfig:
|
|
@@ -2340,9 +2833,16 @@ export function createLiveVoiceSession(
|
|
|
2340
2833
|
options.streamTtsAudio === undefined
|
|
2341
2834
|
? defaultStreamLiveVoiceTtsAudio
|
|
2342
2835
|
: options.streamTtsAudio,
|
|
2836
|
+
// Off by default (see the `liveVoice.archiveAudio` schema): voice turns
|
|
2837
|
+
// persist only their transcribed text, so the recorded audio never lands
|
|
2838
|
+
// as an attachment on the conversation messages. Enable via config for
|
|
2839
|
+
// playback/debugging. An explicit option (incl. `null`) always wins — the
|
|
2840
|
+
// test seam and any future caller override.
|
|
2343
2841
|
archiveAudio:
|
|
2344
2842
|
options.archiveAudio === undefined
|
|
2345
|
-
?
|
|
2843
|
+
? liveVoiceConfig?.archiveAudio
|
|
2844
|
+
? defaultArchiveLiveVoiceAudio
|
|
2845
|
+
: null
|
|
2346
2846
|
: options.archiveAudio,
|
|
2347
2847
|
emitMetrics: options.emitMetrics ?? true,
|
|
2348
2848
|
});
|
|
@@ -2383,8 +2883,49 @@ async function defaultStartVoiceTurn(
|
|
|
2383
2883
|
options.conversationId,
|
|
2384
2884
|
);
|
|
2385
2885
|
}
|
|
2886
|
+
// Stamp the turn with the guardian's trust context — the same resolution the
|
|
2887
|
+
// text-send route runs for a local vellum principal. A local live-voice
|
|
2888
|
+
// session only exists for the guardian's own authenticated client (the
|
|
2889
|
+
// gateway pins the `/v1/live-voice` upgrade to the bound guardian), but the
|
|
2890
|
+
// live-voice ingress bypasses the send-message route, so without this stamp
|
|
2891
|
+
// the turn resolved to the fail-closed `unknown` trust class and every
|
|
2892
|
+
// sensitive tool was denied. Resolution stays fail-closed: a gateway miss /
|
|
2893
|
+
// missing binding leaves the context unset (`unknown`), never a blind grant.
|
|
2894
|
+
const trustContext = await resolveLocalLiveVoiceTrustContext(
|
|
2895
|
+
options.conversationId,
|
|
2896
|
+
);
|
|
2386
2897
|
const { startVoiceTurn } = await import("../calls/voice-session-bridge.js");
|
|
2387
|
-
return startVoiceTurn(
|
|
2898
|
+
return startVoiceTurn({
|
|
2899
|
+
...options,
|
|
2900
|
+
...(trustContext ? { trustContext } : {}),
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
/**
|
|
2905
|
+
* Resolve the local guardian's {@link TrustContext} for a live-voice turn, or
|
|
2906
|
+
* `undefined` when it cannot be established (no vellum guardian binding, or
|
|
2907
|
+
* the gateway is unreachable) — the turn then runs under the fail-closed
|
|
2908
|
+
* `unknown` capability set, exactly as an unstamped turn does.
|
|
2909
|
+
*/
|
|
2910
|
+
async function resolveLocalLiveVoiceTrustContext(
|
|
2911
|
+
conversationId: string,
|
|
2912
|
+
): Promise<TrustContext | undefined> {
|
|
2913
|
+
const { findLocalGuardianPrincipalId } =
|
|
2914
|
+
await import("../runtime/local-actor-identity.js");
|
|
2915
|
+
const { resolveLocalPrincipalTrustContext } =
|
|
2916
|
+
await import("../runtime/local-principal-trust.js");
|
|
2917
|
+
const guardianPrincipalId = await findLocalGuardianPrincipalId();
|
|
2918
|
+
if (!guardianPrincipalId) {
|
|
2919
|
+
return undefined;
|
|
2920
|
+
}
|
|
2921
|
+
const trustContext = await resolveLocalPrincipalTrustContext({
|
|
2922
|
+
actorPrincipalId: guardianPrincipalId,
|
|
2923
|
+
sourceChannel: "vellum",
|
|
2924
|
+
conversationExternalId: conversationId,
|
|
2925
|
+
});
|
|
2926
|
+
// Only stamp a positive guardian resolution; the resolver's own
|
|
2927
|
+
// fail-closed `unknown` carries no more information than no stamp.
|
|
2928
|
+
return trustContext.trustClass === "guardian" ? trustContext : undefined;
|
|
2388
2929
|
}
|
|
2389
2930
|
|
|
2390
2931
|
async function defaultStreamLiveVoiceTtsAudio(
|