@vellumai/assistant 0.10.7 → 0.10.8-dev.202607102228.5945895
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 +3 -1
- package/ARCHITECTURE.md +9 -9
- package/README.md +1 -1
- package/docs/architecture/memory.md +1 -3
- package/docs/credential-execution-service.md +9 -96
- package/docs/runbook-trusted-contacts.md +132 -93
- package/docs/trusted-contact-access.md +125 -115
- 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 -269
- package/eslint.config.mjs +4 -4
- package/knip.json +2 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -2
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/attachment-naming.test.ts +104 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +0 -2
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/attachment-naming.ts +118 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +3 -5
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +2 -4
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/rpc.ts +4 -447
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/attachment-naming.test.ts +104 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +0 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/attachment-naming.ts +118 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +3 -5
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +2 -4
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/rpc.ts +4 -447
- package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +0 -18
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +40 -6
- package/node_modules/@vellumai/gateway-client/src/channel-permission-contract.ts +13 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +24 -2
- package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +146 -16
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +22 -4
- package/node_modules/@vellumai/service-contracts/package.json +1 -2
- package/node_modules/@vellumai/service-contracts/src/__tests__/attachment-naming.test.ts +104 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +0 -2
- package/node_modules/@vellumai/service-contracts/src/attachment-naming.ts +118 -0
- package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +3 -5
- package/node_modules/@vellumai/service-contracts/src/index.ts +2 -4
- package/node_modules/@vellumai/service-contracts/src/rpc.ts +4 -447
- package/openapi.yaml +1648 -676
- package/package.json +4 -5
- package/scripts/build-test-fixtures.ts +105 -0
- package/scripts/memory-inspect.ts +2 -8
- package/scripts/test.ts +597 -0
- package/src/__tests__/access-request-card-view.test.ts +38 -0
- package/src/__tests__/activation-early-marking.test.ts +1 -8
- package/src/__tests__/actor-token-service.test.ts +1 -22
- package/src/__tests__/add-message-preassigned-id.test.ts +1 -1
- package/src/__tests__/agent-image-optimize.test.ts +104 -1
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +0 -5
- package/src/__tests__/agent-loop-compaction-events.test.ts +1 -1
- package/src/__tests__/agent-loop-compaction-strip.test.ts +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +1 -1
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +0 -6
- package/src/__tests__/agent-loop-override-profile.test.ts +66 -5
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +1 -9
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +1 -1
- package/src/__tests__/agent-loop-set-system-prompt.test.ts +1 -7
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +21 -1
- package/src/__tests__/annotate-activity-metadata.test.ts +4 -10
- package/src/__tests__/annotate-risk-options.test.ts +4 -10
- package/src/__tests__/anthropic-error-formatting.test.ts +193 -2
- package/src/__tests__/anthropic-gateway-shared.test.ts +140 -0
- package/src/__tests__/anthropic-provider.test.ts +58 -0
- package/src/__tests__/app-bundler.test.ts +0 -8
- package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -8
- package/src/__tests__/app-routes-csp.test.ts +0 -8
- package/src/__tests__/approval-cascade.test.ts +0 -21
- 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 +1 -16
- package/src/__tests__/assistant-attachment-directive.test.ts +1 -0
- package/src/__tests__/assistant-attachments.test.ts +211 -0
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +0 -7
- package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -7
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/attachment-stored-path-annotation.test.ts +0 -7
- package/src/__tests__/attachment-upload-trusted-source.test.ts +0 -7
- package/src/__tests__/attachments-store-heic-normalize.test.ts +0 -7
- package/src/__tests__/attachments-store.test.ts +43 -8
- package/src/__tests__/attachments.test.ts +77 -0
- package/src/__tests__/audit-log-rotation.test.ts +1 -9
- package/src/__tests__/auth-fallback-events-store.test.ts +0 -7
- package/src/__tests__/available-skills.test.ts +266 -0
- package/src/__tests__/avatar-generator.test.ts +0 -9
- package/src/__tests__/background-shell-host-bash.test.ts +0 -7
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/browser-fill-credential.test.ts +0 -7
- package/src/__tests__/browser-manager.test.ts +1 -8
- package/src/__tests__/btw-routes.test.ts +0 -7
- package/src/__tests__/build-persisted-content.test.ts +0 -8
- package/src/__tests__/call-constants.test.ts +1 -1
- package/src/__tests__/call-controller.test.ts +783 -34
- package/src/__tests__/call-conversation-messages.test.ts +2 -9
- package/src/__tests__/call-domain.test.ts +7 -24
- 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 +1 -8
- package/src/__tests__/call-routes-http.test.ts +0 -7
- package/src/__tests__/call-setup-flow-invite.test.ts +1 -1
- package/src/__tests__/call-setup-flow-midcall-trust.test.ts +76 -97
- package/src/__tests__/call-setup-flow-name-capture.test.ts +1 -1
- package/src/__tests__/call-setup-flow-verification.test.ts +1 -1
- package/src/__tests__/call-setup-flow.test.ts +2 -2
- package/src/__tests__/call-site-routing-provider.test.ts +1 -5
- package/src/__tests__/call-state.test.ts +1 -8
- package/src/__tests__/call-store.test.ts +1 -8
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -7
- package/src/__tests__/canonical-guardian-store.test.ts +1 -8
- 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 +0 -7
- package/src/__tests__/channel-approvals.test.ts +0 -7
- package/src/__tests__/channel-delivery-store.test.ts +0 -7
- package/src/__tests__/channel-guardian.test.ts +29 -16
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +0 -7
- package/src/__tests__/channel-reply-delivery.test.ts +18 -5
- package/src/__tests__/channel-retry-sweep.test.ts +0 -7
- 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__/client-os-metadata-persistence.test.ts +0 -5
- package/src/__tests__/compaction-direct.test.ts +47 -0
- package/src/__tests__/compaction-events.test.ts +14 -29
- package/src/__tests__/compaction-ledger-store.test.ts +1 -7
- package/src/__tests__/compaction-summary-head-persisted-count.test.ts +417 -0
- package/src/__tests__/compaction-trail-store.test.ts +2 -8
- package/src/__tests__/compaction.benchmark.test.ts +0 -5
- package/src/__tests__/compactor-call-site-logging.test.ts +0 -21
- package/src/__tests__/compactor-fixed-boundary.test.ts +334 -0
- package/src/__tests__/compactor-low-watermark-cut.test.ts +8 -23
- 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 +21 -25
- package/src/__tests__/config-get-vision-flag.test.ts +0 -6
- package/src/__tests__/config-loader-backfill.test.ts +332 -316
- package/src/__tests__/config-loader-platform-defaults.test.ts +0 -21
- package/src/__tests__/config-loader-validation-reset-notice.test.ts +183 -0
- package/src/__tests__/config-schema.test.ts +85 -30
- package/src/__tests__/config-set-route.test.ts +0 -6
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +12 -24
- package/src/__tests__/config-watcher-skill-reseed.test.ts +1 -8
- package/src/__tests__/config-watcher.test.ts +22 -12
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -9
- package/src/__tests__/contact-store-interaction-info.test.ts +1 -8
- package/src/__tests__/contact-store-user-file.test.ts +1 -14
- package/src/__tests__/contacts-tools.test.ts +0 -7
- package/src/__tests__/contacts-write.test.ts +1 -8
- package/src/__tests__/context-search-memory-source.test.ts +0 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -6
- package/src/__tests__/context-window-manager-compact-retry.test.ts +118 -21
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +0 -21
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -5
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -12
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +5 -12
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +45 -21
- package/src/__tests__/conversation-agent-loop.test.ts +192 -70
- package/src/__tests__/conversation-app-control-instantiation.test.ts +20 -8
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -9
- package/src/__tests__/conversation-attachments.test.ts +1 -7
- 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 +0 -7
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -21
- 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 +0 -7
- package/src/__tests__/conversation-disk-view.test.ts +0 -7
- package/src/__tests__/conversation-enabledplugins-route.test.ts +2 -8
- package/src/__tests__/conversation-error.test.ts +299 -3
- package/src/__tests__/conversation-fork-crud.test.ts +52 -37
- package/src/__tests__/conversation-fork-retrospective.test.ts +486 -7
- package/src/__tests__/conversation-fork-route.test.ts +0 -7
- package/src/__tests__/conversation-history-web-search.test.ts +39 -17
- package/src/__tests__/conversation-inference-profile-list.test.ts +0 -6
- package/src/__tests__/conversation-inference-profile-route.test.ts +0 -5
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -2
- package/src/__tests__/conversation-initial-prompt.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +0 -7
- package/src/__tests__/conversation-lifecycle.test.ts +108 -62
- package/src/__tests__/conversation-list-source.test.ts +0 -7
- package/src/__tests__/conversation-load-history-repair.test.ts +39 -53
- package/src/__tests__/conversation-load-history-stripped.test.ts +12 -19
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +10 -15
- package/src/__tests__/conversation-message-id-uuidv7.test.ts +73 -0
- package/src/__tests__/conversation-pairing.test.ts +0 -7
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -5
- package/src/__tests__/conversation-process-callsite.test.ts +14 -7
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -5
- package/src/__tests__/conversation-queue.test.ts +91 -21
- package/src/__tests__/conversation-routes-disk-view.test.ts +0 -11
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +3 -11
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +3 -11
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +3 -11
- package/src/__tests__/conversation-routes-slash-commands.test.ts +24 -13
- package/src/__tests__/conversation-runtime-assembly.test.ts +37 -9
- package/src/__tests__/conversation-skill-tools.test.ts +31 -15
- package/src/__tests__/conversation-slash-commands.test.ts +5 -4
- package/src/__tests__/conversation-slash-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -5
- package/src/__tests__/conversation-speed-override.test.ts +13 -23
- package/src/__tests__/conversation-starter-routes.test.ts +0 -7
- package/src/__tests__/conversation-store.test.ts +9 -22
- package/src/__tests__/conversation-summarize-route.test.ts +445 -0
- package/src/__tests__/conversation-summarize-up-to.test.ts +711 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +0 -8
- 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 -19
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +4 -8
- package/src/__tests__/conversation-unread-route.test.ts +0 -7
- package/src/__tests__/conversation-usage.test.ts +10 -8
- package/src/__tests__/conversation-wait-for-idle.test.ts +391 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -5
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -5
- package/src/__tests__/conversations-import-system-filter.test.ts +0 -7
- 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-execution-api-key-propagation.test.ts +0 -40
- package/src/__tests__/credential-execution-client.test.ts +3 -38
- package/src/__tests__/credential-execution-managed-contract.test.ts +10 -106
- package/src/__tests__/credential-health-service.test.ts +0 -9
- package/src/__tests__/credential-metadata-store.test.ts +0 -8
- package/src/__tests__/credential-prompt-route.test.ts +80 -9
- package/src/__tests__/credential-request-route.test.ts +76 -0
- package/src/__tests__/credential-resolve.test.ts +0 -8
- package/src/__tests__/credential-security-invariants.test.ts +3 -10
- package/src/__tests__/credential-token-resolver.test.ts +0 -9
- package/src/__tests__/custom-profile-ensure.test.ts +232 -0
- 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-processing-resume-attempts-migration.test.ts +116 -0
- package/src/__tests__/db-readiness-http-gate.test.ts +0 -7
- package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +1 -7
- package/src/__tests__/default-provider-ensure.test.ts +343 -0
- 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-tools.test.ts +0 -4
- 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 +202 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +174 -0
- package/src/__tests__/edit-propagation.test.ts +1 -8
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +0 -8
- package/src/__tests__/emit-signal-routing-intent.test.ts +175 -7
- package/src/__tests__/encrypted-store.test.ts +0 -9
- package/src/__tests__/ensure-conversation-exists.test.ts +85 -0
- package/src/__tests__/events-client-registration.test.ts +0 -7
- package/src/__tests__/events-dev-bypass-actor.test.ts +2 -9
- package/src/__tests__/events-tail-route.test.ts +172 -0
- package/src/__tests__/file-write-tool.test.ts +9 -13
- package/src/__tests__/followup-tools.test.ts +0 -7
- package/src/__tests__/gateway-flag-listener.test.ts +2 -23
- package/src/__tests__/gemini-inline-media.test.ts +2 -2
- package/src/__tests__/gemini-provider.test.ts +140 -1
- package/src/__tests__/get-skill-detail-audit.test.ts +89 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +0 -9
- 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 +0 -8
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -9
- package/src/__tests__/guardian-dispatch.test.ts +0 -7
- package/src/__tests__/guardian-expiry-notifier.test.ts +1 -9
- package/src/__tests__/guardian-outbound-http.test.ts +0 -7
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +1 -8
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -8
- package/src/__tests__/guardian-routing-state.test.ts +1 -9
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +4 -5
- 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 +91 -13
- 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 +0 -9
- package/src/__tests__/helpers/set-config.ts +40 -0
- package/src/__tests__/host-bash-proxy.test.ts +3 -3
- package/src/__tests__/host-browser-proxy.test.ts +15 -20
- package/src/__tests__/host-cu-routes-targeted.test.ts +0 -1
- package/src/__tests__/host-shell-tool.test.ts +5 -69
- package/src/__tests__/http-conversation-lineage.test.ts +0 -7
- package/src/__tests__/http-user-message-parity.test.ts +0 -7
- 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 +296 -0
- 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 +1 -8
- package/src/__tests__/inference-profile-reaper.test.ts +1 -7
- package/src/__tests__/inference-profile-session-handler.test.ts +0 -6
- package/src/__tests__/inference-profile-session-ipc.test.ts +0 -6
- package/src/__tests__/ingress-url-consistency.test.ts +1 -23
- package/src/__tests__/injection-block.test.ts +0 -1
- package/src/__tests__/injector-chain.test.ts +17 -0
- package/src/__tests__/injector-config-validation-reset-notice.test.ts +121 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +8 -0
- package/src/__tests__/injector-registry-order-guard.test.ts +1 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -7
- package/src/__tests__/inline-skill-load-permissions.test.ts +29 -31
- package/src/__tests__/internal-telemetry-routes.test.ts +72 -7
- package/src/__tests__/interrupted-turn-reconciler.test.ts +126 -0
- package/src/__tests__/introduction-card-resolver.test.ts +0 -9
- package/src/__tests__/invite-redeemed-ipc.test.ts +0 -7
- package/src/__tests__/invite-routes-http.test.ts +46 -11
- package/src/__tests__/job-handler-registration-guard.test.ts +1 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +0 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +0 -7
- package/src/__tests__/lexical-index-dual-write.test.ts +2 -8
- package/src/__tests__/list-messages-attachments.test.ts +0 -7
- package/src/__tests__/list-messages-background-tool-completion.test.ts +0 -7
- package/src/__tests__/list-messages-client-message-id.test.ts +0 -7
- package/src/__tests__/list-messages-hidden-metadata.test.ts +0 -7
- package/src/__tests__/list-messages-page-latest.test.ts +0 -7
- package/src/__tests__/list-messages-queued.test.ts +9 -10
- package/src/__tests__/list-messages-tool-merge.test.ts +0 -7
- package/src/__tests__/llm-catalog-parity.test.ts +20 -0
- package/src/__tests__/llm-context-resolution.test.ts +26 -1
- package/src/__tests__/llm-context-route-provider.test.ts +1 -8
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +9 -16
- package/src/__tests__/llm-request-log-call-site.test.ts +5 -12
- package/src/__tests__/llm-request-log-clickhouse-routing.test.ts +117 -0
- package/src/__tests__/llm-request-log-clickhouse-writer-guards.test.ts +115 -0
- package/src/__tests__/llm-request-log-disabled-writes.test.ts +72 -0
- package/src/__tests__/llm-request-log-sink-clickhouse.test.ts +211 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +1 -22
- package/src/__tests__/llm-request-log-source-factory.test.ts +0 -21
- package/src/__tests__/llm-request-log-turn-query.test.ts +0 -7
- package/src/__tests__/llm-resolver-override-or-default.test.ts +563 -0
- package/src/__tests__/llm-resolver.test.ts +167 -6
- 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 +240 -6
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -7
- package/src/__tests__/managed-store.test.ts +1 -16
- package/src/__tests__/mcp-auth-routes.test.ts +1 -8
- package/src/__tests__/mcp-config-secret-boundary.test.ts +17 -5
- package/src/__tests__/media-generate-image.test.ts +20 -7
- package/src/__tests__/media-stream-output.test.ts +755 -71
- package/src/__tests__/media-stream-server-integration.test.ts +290 -60
- package/src/__tests__/media-stream-stt-session.test.ts +26 -13
- package/src/__tests__/memory-config-file-parity.test.ts +187 -0
- package/src/__tests__/memory-identity-context-parity.test.ts +103 -0
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +8 -7
- package/src/__tests__/memory-jobs-worker-cleanup-cadence.test.ts +296 -0
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +0 -7
- package/src/__tests__/memory-recall-log-store.test.ts +0 -7
- package/src/__tests__/memory-upsert-concurrency.test.ts +0 -7
- package/src/__tests__/message-queue.test.ts +40 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +1 -8
- package/src/__tests__/messaging-send-tool.test.ts +0 -7
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -7
- package/src/__tests__/migration-export-http.test.ts +10 -12
- package/src/__tests__/migration-export-streaming.test.ts +0 -7
- package/src/__tests__/migration-export-to-gcs.test.ts +60 -7
- package/src/__tests__/migration-import-commit-http.test.ts +11 -12
- package/src/__tests__/migration-import-from-gcs.test.ts +0 -7
- package/src/__tests__/migration-import-from-url.test.ts +0 -7
- package/src/__tests__/migration-import-preflight-http.test.ts +10 -11
- package/src/__tests__/migration-jobs-status.test.ts +8 -11
- package/src/__tests__/migration-validate-http.test.ts +2 -8
- package/src/__tests__/model-intents.test.ts +18 -0
- package/src/__tests__/mtime-cache.test.ts +102 -9
- package/src/__tests__/non-member-access-request.test.ts +145 -7
- package/src/__tests__/notification-broadcaster.test.ts +0 -7
- package/src/__tests__/notification-candidate-guardian-context.test.ts +1 -8
- 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 +415 -11
- package/src/__tests__/notification-guardian-path.test.ts +0 -7
- 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 -1
- package/src/__tests__/oauth-connect-orchestrator.test.ts +0 -8
- package/src/__tests__/oauth-connect-routes.test.ts +19 -18
- package/src/__tests__/oauth-provider-profiles.test.ts +0 -7
- package/src/__tests__/oauth-provider-visibility.test.ts +0 -7
- package/src/__tests__/oauth-store.test.ts +0 -7
- package/src/__tests__/openai-provider.test.ts +11 -0
- package/src/__tests__/openrouter-provider-only.test.ts +16 -5
- package/src/__tests__/openrouter-token-estimation.test.ts +2 -2
- package/src/__tests__/outbound-slack-persistence.test.ts +9 -7
- package/src/__tests__/outlook-email-watcher.test.ts +0 -9
- package/src/__tests__/path-policy.test.ts +0 -7
- package/src/__tests__/pending-interactions-resolved-event.test.ts +26 -4
- package/src/__tests__/persist-media-references.test.ts +112 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +9 -4
- package/src/__tests__/persist-unsendable-image.test.ts +39 -7
- package/src/__tests__/persist-user-message-set-processing-failure.test.ts +41 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +7 -7
- package/src/__tests__/persona-resolver.test.ts +1 -1
- package/src/__tests__/personal-memory-auth-bypass.test.ts +2 -4
- package/src/__tests__/platform-bash-auto-approve.test.ts +20 -10
- 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 +2 -33
- package/src/__tests__/playbook-tools.test.ts +0 -7
- package/src/__tests__/plugin-api-model-profiles.test.ts +25 -4
- package/src/__tests__/plugin-effective-enabled-set.test.ts +29 -29
- package/src/__tests__/plugin-hook-pipeline-hardening.test.ts +249 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +13 -25
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +316 -0
- package/src/__tests__/plugin-types.test.ts +1 -1
- package/src/__tests__/pointer-conversation-trust.test.ts +2 -4
- package/src/__tests__/pricing.test.ts +85 -2
- package/src/__tests__/process-message-background-slack.test.ts +4 -5
- package/src/__tests__/process-message-display-content.test.ts +102 -10
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -5
- package/src/__tests__/provider-commit-message-generator.test.ts +15 -8
- package/src/__tests__/provider-error-scenarios.test.ts +68 -5
- package/src/__tests__/provider-platform-proxy-integration.test.ts +17 -2
- package/src/__tests__/provider-registry-ollama.test.ts +14 -1
- package/src/__tests__/provider-send-message-override-profile.test.ts +13 -5
- package/src/__tests__/provider-streaming.benchmark.test.ts +1 -6
- package/src/__tests__/provider-usage-tracking.test.ts +9 -6
- package/src/__tests__/proxy-approval-callback.test.ts +0 -6
- package/src/__tests__/prune-old-conversations-job.test.ts +1 -9
- 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__/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 +0 -7
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +0 -11
- package/src/__tests__/registry.test.ts +39 -12
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +270 -0
- package/src/__tests__/require-fresh-approval.test.ts +47 -182
- package/src/__tests__/resolve-trust-class.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +9 -5
- package/src/__tests__/retry-thinking-adaptive-only.test.ts +19 -5
- package/src/__tests__/retry-thinking-tool-choice.test.ts +65 -5
- package/src/__tests__/retry-verbosity-normalization.test.ts +9 -5
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -7
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +0 -7
- package/src/__tests__/runtime-events-sse-parity.test.ts +0 -7
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +0 -7
- package/src/__tests__/runtime-events-sse.test.ts +0 -7
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +131 -9
- package/src/__tests__/schedule-retry.test.ts +0 -8
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +0 -7
- package/src/__tests__/schedule-routes.test.ts +0 -7
- package/src/__tests__/schedule-store.test.ts +0 -8
- package/src/__tests__/schedule-tools.test.ts +0 -7
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -10
- package/src/__tests__/scheduler-recurrence.test.ts +19 -96
- package/src/__tests__/scheduler-reuse-conversation.test.ts +75 -88
- package/src/__tests__/scheduler-wake.test.ts +12 -60
- package/src/__tests__/scheduler-worker-standdown.test.ts +0 -8
- package/src/__tests__/scoped-approval-grants.test.ts +1 -9
- package/src/__tests__/scoped-grant-security-matrix.test.ts +1 -9
- package/src/__tests__/secret-allowlist.test.ts +1 -8
- package/src/__tests__/secret-ingress-channel.test.ts +0 -7
- package/src/__tests__/secret-ingress-cli.test.ts +0 -7
- package/src/__tests__/secret-ingress-http.test.ts +3 -11
- package/src/__tests__/secret-patterns.test.ts +27 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +35 -9
- package/src/__tests__/secret-response-routing.test.ts +1 -1
- package/src/__tests__/secret-routes-platform-proxy.test.ts +0 -7
- package/src/__tests__/secure-keys-managed-failover.test.ts +0 -7
- package/src/__tests__/secure-keys.test.ts +142 -33
- package/src/__tests__/send-endpoint-busy.test.ts +0 -19
- package/src/__tests__/sequence-store.test.ts +0 -9
- package/src/__tests__/server-history-render.test.ts +61 -8
- package/src/__tests__/service-contracts-import-guard.test.ts +4 -9
- package/src/__tests__/set-permission-mode.test.ts +0 -7
- package/src/__tests__/settings-routes.test.ts +0 -7
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -7
- package/src/__tests__/skill-projection-feature-flag.test.ts +35 -17
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -7
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -7
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -7
- package/src/__tests__/slack-channels-routes.test.ts +34 -16
- package/src/__tests__/slack-inbound-verification.test.ts +0 -7
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +0 -8
- package/src/__tests__/slack-users-routes.test.ts +148 -0
- package/src/__tests__/slim-skill-category.test.ts +0 -7
- package/src/__tests__/stale-approval-dedup.test.ts +0 -7
- package/src/__tests__/subagent-call-site-routing.test.ts +45 -11
- package/src/__tests__/subagent-detail.test.ts +2 -1
- package/src/__tests__/subagent-fork-prompt-role.test.ts +0 -5
- package/src/__tests__/subagent-fork-spawn.test.ts +0 -37
- package/src/__tests__/subagent-spawn-and-await.test.ts +0 -5
- package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -7
- package/src/__tests__/subagent-tools.test.ts +77 -36
- package/src/__tests__/suggestion-routes.test.ts +28 -42
- package/src/__tests__/summarize-boundary.test.ts +169 -0
- package/src/__tests__/task-compiler.test.ts +0 -7
- package/src/__tests__/task-management-tools.test.ts +0 -7
- package/src/__tests__/task-memory-cleanup.test.ts +0 -18
- package/src/__tests__/task-scheduler.test.ts +40 -9
- package/src/__tests__/telegram-bot-username-resolution.test.ts +0 -8
- package/src/__tests__/telephony-tts-guard.test.ts +118 -26
- package/src/__tests__/test-preload.ts +11 -1
- package/src/__tests__/thread-backfill.test.ts +2 -8
- package/src/__tests__/token-manager.test.ts +0 -9
- package/src/__tests__/tool-approval-handler.test.ts +57 -88
- package/src/__tests__/{tool-audit-listener.test.ts → tool-audit.test.ts} +230 -255
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +5 -33
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -8
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +308 -411
- package/src/__tests__/tool-executor.test.ts +37 -26
- package/src/__tests__/tool-grant-request-escalation.test.ts +17 -31
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -8
- package/src/__tests__/tool-profiler.test.ts +139 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -8
- package/src/__tests__/tool-start-timestamp.test.ts +4 -10
- package/src/__tests__/tools-get-route.test.ts +75 -3
- package/src/__tests__/trust-context-guards.test.ts +1 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +9 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -7
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -7
- package/src/__tests__/trusted-contact-verification.test.ts +6 -139
- package/src/__tests__/turn-boundary-resolution.test.ts +0 -7
- package/src/__tests__/turn-events-store.test.ts +51 -7
- package/src/__tests__/turn-outcome-read.test.ts +75 -0
- package/src/__tests__/twilio-config.test.ts +0 -7
- package/src/__tests__/twilio-provider.test.ts +0 -7
- package/src/__tests__/twilio-routes-twiml.test.ts +1 -8
- package/src/__tests__/twilio-routes.test.ts +12 -5
- package/src/__tests__/twilio-validation.test.ts +0 -7
- package/src/__tests__/usage-attribution.test.ts +91 -1
- package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -7
- package/src/__tests__/usage-routes.test.ts +1 -8
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +0 -7
- package/src/__tests__/vercel-ai-gateway-provider.test.ts +283 -0
- package/src/__tests__/vercel-config.test.ts +0 -7
- package/src/__tests__/verification-control-plane-policy.test.ts +60 -31
- package/src/__tests__/voice-approval-resolver-relay.test.ts +3 -9
- package/src/__tests__/voice-config-update.test.ts +1 -22
- package/src/__tests__/voice-guardian-cold-cache-warm.test.ts +8 -17
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -10
- package/src/__tests__/voice-session-bridge-processing-wait.test.ts +0 -7
- package/src/__tests__/voice-session-bridge.test.ts +116 -68
- package/src/__tests__/workspace-git-service.test.ts +207 -2
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +0 -8
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +0 -8
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +0 -8
- package/src/__tests__/workspace-migration-126-strip-managed-profile-bodies.test.ts +192 -0
- package/src/__tests__/workspace-migration-127-backfill-default-provider.test.ts +277 -0
- package/src/__tests__/workspace-migration-128-repair-stale-openrouter-grok-model-ids.test.ts +135 -0
- package/src/__tests__/workspace-migration-129-remove-analyze-conversation-config.test.ts +190 -0
- package/src/__tests__/workspace-tool-loader.test.ts +5 -1
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -10
- 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/attachments.ts +57 -0
- package/src/agent/image-optimize.ts +80 -0
- package/src/agent/loop-exclusive-tool.test.ts +28 -5
- package/src/agent/loop.ts +25 -63
- package/src/api/responses/conversation-message.ts +9 -15
- package/src/approvals/guardian-expiry-notifier.ts +6 -0
- package/src/approvals/guardian-request-resolvers.ts +42 -21
- package/src/background-wake/wake-intent-hooks.test.ts +2 -10
- package/src/browser/operation-meta.ts +493 -0
- package/src/browser/operations.ts +2 -477
- package/src/calls/__tests__/call-setup-router.test.ts +341 -321
- package/src/calls/__tests__/channel-admission-reader.test.ts +50 -24
- package/src/calls/__tests__/fish-audio-client.test.ts +35 -11
- package/src/calls/__tests__/inbound-trust-reader.test.ts +157 -34
- package/src/calls/__tests__/tts-text-sanitizer.test.ts +22 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +884 -0
- package/src/calls/access-request-wait.ts +3 -1
- package/src/calls/audio-store.ts +6 -6
- package/src/calls/call-constants.ts +1 -1
- package/src/calls/call-controller.ts +242 -64
- package/src/calls/call-setup-flow-types.ts +2 -2
- package/src/calls/call-setup-flow.ts +19 -57
- package/src/calls/call-setup-router.ts +63 -39
- package/src/calls/call-speech-output.ts +39 -39
- package/src/calls/call-transport.ts +17 -5
- package/src/calls/channel-admission-reader.ts +38 -28
- package/src/calls/fish-audio-client.ts +24 -52
- package/src/calls/gateway-invite-reader.ts +15 -19
- package/src/calls/inbound-trust-reader.ts +74 -25
- package/src/calls/media-stream-audio-transcode.ts +1 -1
- package/src/calls/media-stream-output.ts +482 -64
- package/src/calls/media-stream-server.ts +156 -83
- package/src/calls/media-stream-stt-session.ts +1 -0
- package/src/calls/resolve-call-tts-provider.ts +60 -17
- package/src/calls/telephony-tts-capability.ts +13 -13
- package/src/calls/tts-text-sanitizer.ts +5 -3
- package/src/calls/unresolved-caller-trust.ts +36 -0
- package/src/calls/voice-session-bridge.ts +397 -52
- package/src/channels/__tests__/gateway-invites.test.ts +257 -0
- package/src/channels/gateway-invites.ts +142 -0
- package/src/channels/gateway-verification-sessions.ts +4 -8
- package/src/cli/AGENTS.md +60 -51
- package/src/cli/commands/__tests__/inference-models.test.ts +86 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +254 -0
- package/src/cli/commands/__tests__/inference-providers.test.ts +171 -0
- package/src/cli/commands/__tests__/schedules.test.ts +133 -1
- package/src/cli/commands/__tests__/usage.test.ts +131 -0
- package/src/cli/commands/attachment.help.ts +100 -0
- package/src/cli/commands/attachment.ts +92 -157
- package/src/cli/commands/audit.help.ts +40 -0
- package/src/cli/commands/audit.ts +66 -86
- package/src/cli/commands/auth.help.ts +46 -0
- package/src/cli/commands/auth.ts +10 -43
- package/src/cli/commands/avatar.help.ts +236 -0
- package/src/cli/commands/avatar.ts +66 -250
- package/src/cli/commands/backup.help.ts +190 -0
- package/src/cli/commands/backup.ts +109 -276
- package/src/cli/commands/bash.help.ts +45 -0
- package/src/cli/commands/bash.ts +55 -75
- package/src/cli/commands/browser.help.ts +196 -0
- package/src/cli/commands/browser.ts +241 -352
- package/src/cli/commands/config.ts +166 -164
- package/src/cli/commands/contacts.ts +13 -22
- package/src/cli/commands/credentials.ts +38 -28
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +19 -10
- package/src/cli/commands/db/repair.ts +20 -8
- package/src/cli/commands/default-action.ts +8 -3
- package/src/cli/commands/domain.ts +36 -22
- package/src/cli/commands/email.ts +77 -36
- package/src/cli/commands/inference-callsites.ts +158 -0
- package/src/cli/commands/inference-models.ts +84 -0
- package/src/cli/commands/inference-profiles.ts +371 -0
- package/src/cli/commands/inference-providers-default.ts +89 -0
- package/src/cli/commands/inference-providers.ts +117 -24
- package/src/cli/commands/inference.ts +6 -0
- package/src/cli/commands/keys.ts +27 -38
- package/src/cli/commands/memory/index.ts +8 -0
- package/src/cli/commands/memory/memory-retrospective.ts +7 -5
- package/src/cli/commands/memory/memory-v2-compare-render.ts +2 -2
- package/src/cli/commands/memory/nodes.ts +301 -0
- 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 +12 -6
- package/src/cli/commands/oauth/token.ts +1 -26
- package/src/cli/commands/plugins.ts +210 -116
- package/src/cli/commands/schedules.ts +17 -2
- package/src/cli/commands/tools-run.ts +4 -4
- package/src/cli/commands/tools.ts +23 -7
- package/src/cli/commands/ui.ts +2 -3
- package/src/cli/commands/usage.ts +59 -21
- package/src/cli/index.help.ts +31 -0
- package/src/cli/lib/__tests__/cli-output.test.ts +20 -0
- package/src/cli/lib/__tests__/diff-plugin.test.ts +2 -5
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -1
- package/src/cli/lib/__tests__/install-from-github.test.ts +37 -5
- package/src/cli/lib/__tests__/install-from-platform.test.ts +497 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +36 -0
- package/src/cli/lib/__tests__/plugin-artifact.test.ts +54 -1
- package/src/cli/lib/__tests__/plugin-details.test.ts +137 -1
- package/src/cli/lib/__tests__/plugin-icon-file.test.ts +142 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +1 -1
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +1 -1
- package/src/cli/lib/__tests__/search-plugins.test.ts +1 -1
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +82 -21
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +1 -1
- package/src/cli/lib/cli-command-help.ts +119 -0
- package/src/cli/lib/cli-output.ts +55 -0
- package/src/cli/lib/diff-plugin.ts +2 -2
- package/src/cli/lib/fetch-like.ts +11 -0
- package/src/cli/lib/inspect-plugin.ts +2 -2
- package/src/cli/lib/install-from-github.ts +61 -15
- package/src/cli/lib/install-from-platform.ts +618 -0
- package/src/cli/lib/list-installed-plugins.ts +39 -5
- package/src/cli/lib/plugin-artifact.ts +30 -0
- package/src/cli/lib/plugin-constants.ts +27 -0
- package/src/cli/lib/plugin-details.ts +51 -11
- package/src/cli/lib/plugin-icon-file.ts +101 -0
- package/src/cli/lib/plugin-marketplace.ts +1 -4
- package/src/cli/lib/plugin-pin-history.ts +27 -12
- package/src/cli/lib/publish-plugin.ts +3 -3
- package/src/cli/lib/search-plugins.ts +2 -6
- package/src/cli/lib/uninstall-plugin.ts +24 -2
- package/src/cli/lib/upgrade-plugin.ts +8 -22
- package/src/cli/program.ts +0 -2
- package/src/cli.ts +22 -13
- package/src/config/__tests__/default-profile-catalog.test.ts +384 -0
- package/src/config/__tests__/default-provider.test.ts +245 -0
- package/src/config/__tests__/deployment-context-defaults.test.ts +0 -21
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -21
- package/src/config/__tests__/loader-last-known-good.test.ts +208 -0
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +145 -0
- package/src/config/__tests__/profile-materialization.test.ts +297 -0
- package/src/config/__tests__/seed-default-provider.test.ts +210 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +27 -34
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +9 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +0 -6
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +0 -3
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +0 -3
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +1 -3
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +0 -4
- package/src/config/bundled-skills/schedule/SKILL.md +17 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +0 -7
- package/src/config/call-site-defaults.ts +5 -2
- package/src/config/default-profile-catalog.ts +481 -0
- package/src/config/default-profile-names.ts +44 -0
- package/src/config/default-provider-resolution.ts +33 -0
- package/src/config/default-provider.ts +38 -0
- package/src/config/env-registry.ts +2 -0
- package/src/config/env.ts +0 -6
- package/src/config/feature-flag-registry.json +42 -50
- package/src/config/inference-profile-validation.ts +5 -4
- package/src/config/llm-resolver.ts +447 -24
- package/src/config/loader.ts +345 -10
- package/src/config/profile-materialization.ts +151 -0
- package/src/config/schema.ts +2 -52
- package/src/config/schemas/__tests__/live-voice.test.ts +108 -0
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +33 -5
- package/src/config/schemas/call-site-catalog.ts +0 -6
- package/src/config/schemas/calls.ts +9 -0
- package/src/config/schemas/conversations.ts +1 -1
- package/src/config/schemas/live-voice.ts +77 -0
- package/src/config/schemas/llm-request-logs.ts +78 -27
- package/src/config/schemas/llm.ts +53 -2
- package/src/config/schemas/memory-lifecycle.ts +0 -6
- package/src/config/schemas/memory.ts +57 -1
- package/src/config/seed-inference-profiles.ts +100 -289
- package/src/config/sync-gated-profiles.ts +17 -23
- package/src/contacts/canonical-guardian-store.ts +6 -0
- package/src/contacts/contact-store.ts +272 -51
- package/src/contacts/contacts-write.ts +0 -22
- package/src/contacts/guardian-contact-reader.ts +3 -2
- package/src/contacts/member-write-relay.ts +2 -19
- package/src/contacts/types.ts +2 -1
- package/src/context/compactor.ts +230 -38
- package/src/context/image-dimensions.ts +25 -3
- package/src/context/token-estimator.ts +11 -7
- package/src/conversations/__tests__/message-consolidation.test.ts +6 -5
- package/src/conversations/job-handlers/summarization.ts +0 -2
- package/src/conversations/message-consolidation.ts +34 -112
- package/src/credential-execution/executable-discovery.ts +16 -144
- package/src/credential-execution/process-manager.test.ts +1 -112
- package/src/credential-execution/process-manager.ts +13 -379
- package/src/credential-execution/prompted-credential.ts +1 -1
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
- package/src/daemon/__tests__/inference-profile-notification.test.ts +0 -8
- package/src/daemon/__tests__/inflight-message-content.test.ts +219 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +0 -8
- package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +0 -6
- package/src/daemon/__tests__/web-search-status-text.test.ts +0 -8
- package/src/daemon/approval-generators.ts +17 -11
- package/src/daemon/assistant-attachments.ts +86 -87
- package/src/daemon/config-watcher.ts +67 -21
- package/src/daemon/conversation-agent-loop-handlers.ts +146 -50
- package/src/daemon/conversation-agent-loop.ts +136 -34
- package/src/daemon/conversation-error.ts +291 -109
- package/src/daemon/conversation-history.ts +6 -12
- package/src/daemon/conversation-initial-prompt.ts +1 -1
- package/src/daemon/conversation-launch.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +5 -22
- package/src/daemon/conversation-media-retry.ts +3 -2
- package/src/daemon/conversation-messaging.ts +296 -66
- package/src/daemon/conversation-notifiers.ts +1 -1
- package/src/daemon/conversation-process.ts +162 -12
- package/src/daemon/conversation-queue-manager.ts +12 -0
- package/src/daemon/conversation-runtime-assembly.ts +197 -53
- package/src/daemon/conversation-skill-tools.ts +27 -9
- package/src/daemon/conversation-slash.ts +2 -4
- package/src/daemon/conversation-store.ts +11 -13
- package/src/daemon/conversation-surfaces.ts +145 -176
- package/src/daemon/conversation-tool-setup.ts +18 -12
- package/src/daemon/conversation-turn-finalize.ts +18 -1
- package/src/daemon/conversation.ts +265 -85
- package/src/daemon/disk-pressure-policy.ts +1 -1
- package/src/daemon/event-loop-watchdog.test.ts +1 -6
- package/src/daemon/event-loop-watchdog.ts +2 -20
- 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/config-a2a.ts +0 -3
- package/src/daemon/handlers/conversation-history.ts +6 -4
- package/src/daemon/handlers/shared.ts +224 -79
- package/src/daemon/handlers/skills.ts +8 -0
- package/src/daemon/inflight-message-content.ts +228 -0
- package/src/daemon/interrupted-turn-reconciler.ts +134 -0
- package/src/daemon/lifecycle.ts +120 -64
- package/src/daemon/main.ts +1 -5
- package/src/daemon/message-types/conversations.ts +2 -0
- package/src/daemon/message-types/host-bash.ts +1 -1
- package/src/daemon/message-types/skills.ts +6 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/orphan-reaper.test.ts +1 -6
- package/src/daemon/persist-media-references.ts +151 -0
- package/src/daemon/pointer-conversation-trust.ts +2 -4
- package/src/daemon/process-message.ts +82 -8
- package/src/daemon/providers-setup.ts +1 -4
- package/src/daemon/shutdown-handlers.ts +0 -4
- package/src/daemon/sqlite-corruption-watchdog.test.ts +0 -13
- package/src/daemon/sqlite-corruption-watchdog.ts +2 -15
- package/src/daemon/summarize-boundary.ts +62 -0
- package/src/daemon/tool-setup-types.ts +1 -1
- package/src/daemon/trust-context-types.ts +61 -0
- package/src/daemon/trust-context.ts +5 -55
- package/src/daemon/wake-conversation-ops.ts +4 -1
- package/src/documents/document-comments-store.test.ts +1 -7
- package/src/export/__tests__/transcript-formatter.test.ts +13 -8
- package/src/export/formatter.ts +8 -17
- package/src/export/transcript-formatter.ts +13 -40
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +0 -9
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -2
- package/src/home/__tests__/home-content-refresh.test.ts +0 -7
- package/src/home/__tests__/suggested-prompts.test.ts +4 -12
- package/src/home/conversation-starter-checkpoints.ts +9 -5
- package/src/home/job-handlers/conversation-starters.ts +24 -54
- package/src/home/suggested-prompts-cache.ts +91 -0
- package/src/home/suggested-prompts.ts +4 -77
- package/src/hooks/__tests__/hook-live-reload.test.ts +62 -48
- package/src/hooks/hook-loader.ts +215 -194
- package/src/hooks/types.ts +2 -2
- package/src/ipc/__tests__/contacts-info-ipc.test.ts +66 -11
- package/src/ipc/assistant-server.ts +14 -34
- package/src/ipc/gateway-flag-listener.ts +14 -25
- package/src/ipc/gateway-validated-call.ts +32 -0
- package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +149 -17
- package/src/ipc/routes/__tests__/contacts-mirror-merge-contact.test.ts +197 -0
- package/src/ipc/routes/__tests__/contacts-mirror-upsert-full.test.ts +368 -0
- 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/__tests__/memory-v2-backfill.test.ts +5 -7
- package/src/ipc/routes/contacts-info-ipc-routes.ts +5 -2
- package/src/ipc/routes/contacts-mirror-ipc-routes.ts +78 -1
- package/src/ipc/routes/db-proxy.ts +9 -15
- 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 +275 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +124 -0
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +67 -0
- package/src/live-voice/__tests__/live-voice-session-preflight.test.ts +156 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +464 -19
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +350 -4
- package/src/live-voice/__tests__/live-voice-tts.test.ts +186 -10
- package/src/live-voice/__tests__/live-voice-vad.test.ts +372 -10
- package/src/live-voice/__tests__/protocol.test.ts +2 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +61 -9
- package/src/live-voice/live-voice-credential-preflight.ts +205 -0
- package/src/live-voice/live-voice-metrics.ts +44 -0
- package/src/live-voice/live-voice-session-manager.ts +19 -0
- package/src/live-voice/live-voice-session.ts +1015 -276
- package/src/live-voice/live-voice-tts.ts +50 -4
- package/src/live-voice/protocol.ts +8 -0
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +3 -7
- package/src/messaging/channel-binding-schema.ts +15 -7
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +0 -9
- package/src/messaging/providers/slack/__tests__/download.test.ts +1 -8
- package/src/messaging/providers/slack/binding-metadata.test.ts +63 -0
- package/src/messaging/providers/slack/binding-metadata.ts +6 -0
- package/src/messaging/providers/slack/conversation-utils.ts +7 -4
- package/src/messaging/providers/slack/send.test.ts +0 -7
- package/src/messaging/providers/slack/types.ts +2 -0
- 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__/resource-sampler.test.ts +2 -4
- package/src/monitoring/__tests__/stall-capture.test.ts +1 -1
- package/src/monitoring/process-memory.ts +6 -1
- package/src/monitoring/resource-sample-types.ts +71 -0
- package/src/monitoring/resource-sampler.ts +7 -69
- package/src/monitoring/stall-capture.ts +1 -1
- package/src/notifications/__tests__/broadcaster.test.ts +100 -9
- 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/access-request-copy.ts +33 -1
- package/src/notifications/adapters/slack.ts +7 -2
- package/src/notifications/approval-card-data.ts +4 -2
- package/src/notifications/broadcaster.ts +118 -67
- package/src/notifications/copy-composer.ts +6 -2
- package/src/notifications/emit-signal.ts +23 -1
- package/src/notifications/signal.ts +5 -4
- package/src/notifications/types.ts +1 -1
- package/src/notifications/urgency.ts +5 -0
- package/src/oauth/byo-connection.test.ts +1 -10
- package/src/oauth/connect-orchestrator.ts +1 -1
- package/src/oauth/connection-resolver.test.ts +140 -7
- package/src/oauth/connection-resolver.ts +48 -12
- package/src/oauth/oauth-store.ts +4 -11
- package/src/onboarding/__tests__/onboarding-events-store.test.ts +0 -8
- package/src/permissions/approval-policy.test.ts +0 -314
- package/src/permissions/approval-policy.ts +38 -90
- package/src/permissions/checker.test.ts +3 -14
- package/src/permissions/checker.ts +95 -19
- package/src/permissions/confirmation-canonical-request.ts +118 -0
- package/src/permissions/gateway-threshold-reader.test.ts +0 -8
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/permissions/prompter.ts +16 -3
- package/src/permissions/secret-prompt-types.ts +34 -0
- package/src/permissions/secret-prompter.ts +21 -19
- package/src/permissions/types.ts +0 -14
- package/src/persistence/__tests__/bulk-write-gate.test.ts +159 -0
- package/src/persistence/__tests__/conversation-queries-search.test.ts +0 -7
- package/src/persistence/__tests__/immediate-transaction-guard.test.ts +70 -0
- package/src/persistence/__tests__/message-content-file.test.ts +259 -0
- package/src/persistence/__tests__/slow-query-log.test.ts +125 -0
- package/src/persistence/attachments-store.ts +90 -26
- package/src/persistence/auto-analysis-constants.ts +4 -13
- package/src/persistence/bulk-write-gate.ts +82 -0
- package/src/persistence/cleanup-schedule-state.ts +51 -21
- package/src/persistence/conversation-bootstrap.ts +3 -3
- package/src/persistence/conversation-crud.ts +382 -105
- package/src/persistence/conversation-disk-view.ts +32 -15
- package/src/persistence/conversation-group-migration.test.ts +1 -8
- package/src/persistence/conversation-key-store.ts +0 -2
- package/src/persistence/conversation-plugin-facade.ts +190 -0
- package/src/persistence/conversation-row-batch-delete.ts +16 -1
- package/src/persistence/conversation-title-service.ts +59 -22
- package/src/persistence/conversation-types.ts +19 -4
- package/src/persistence/db-async-query.ts +18 -9
- package/src/persistence/db-connection.ts +20 -4
- package/src/persistence/db-init.ts +16 -173
- package/src/persistence/db-maintenance.ts +78 -6
- package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +0 -7
- package/src/persistence/embeddings/plugin-facade.ts +37 -0
- package/src/persistence/embeddings/qdrant-client.ts +2 -18
- package/src/persistence/fork-message-copy.ts +18 -4
- 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/message-lexical-backfill.ts +8 -5
- package/src/persistence/job-handlers/message-lexical.ts +2 -2
- package/src/persistence/jobs-store.ts +48 -85
- package/src/persistence/llm-request-log-sink-clickhouse.ts +325 -0
- package/src/persistence/llm-request-log-store.ts +213 -100
- package/src/persistence/llm-request-log-writer-types.ts +80 -0
- package/src/persistence/message-content-file.ts +301 -0
- package/src/persistence/message-content.ts +33 -72
- package/src/persistence/migrations/321-canonical-guardian-request-trigger.ts +27 -0
- package/src/persistence/migrations/322-add-processing-resume-attempts.ts +31 -0
- package/src/persistence/migrations/323-delete-non-default-memory-scopes.test.ts +148 -0
- package/src/persistence/migrations/323-delete-non-default-memory-scopes.ts +35 -0
- package/src/persistence/migrations/324-message-finalized-column.ts +26 -0
- 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/__tests__/297-move-llm-request-logs.test.ts +2 -2
- package/src/persistence/migrations/__tests__/327-create-flush-checkpoints.test.ts +124 -0
- package/src/persistence/schema/conversations.ts +25 -1
- package/src/persistence/schema/guardian.ts +5 -0
- package/src/persistence/schema/infrastructure.ts +33 -0
- package/src/persistence/schema/memory-core.ts +17 -28
- package/src/persistence/schema/memory-graph.ts +0 -4
- package/src/persistence/schema/memory-injection.ts +3 -1
- package/src/persistence/schema/tasks.ts +0 -1
- package/src/persistence/slow-query-log.ts +58 -21
- package/src/persistence/steps.ts +14 -0
- package/src/platform/consent-cache.test.ts +0 -7
- package/src/platform/managed-speech.test.ts +218 -0
- package/src/platform/managed-speech.ts +195 -0
- package/src/playbooks/playbook-compiler.ts +2 -10
- package/src/plugin-api/index.ts +79 -0
- package/src/plugin-api/model-profiles.test.ts +31 -3
- package/src/plugin-api/model-profiles.ts +3 -1
- package/src/plugin-api/types.ts +12 -3
- package/src/plugin-api/vision-support.ts +4 -3
- package/src/plugins/AGENTS.md +19 -0
- package/src/plugins/__tests__/plugin-state-boundary-guard.test.ts +65 -0
- package/src/plugins/defaults/compaction/compact.ts +13 -0
- package/src/plugins/defaults/compaction/window-manager.ts +207 -43
- package/src/plugins/defaults/image-fallback/__tests__/caption-cache-persistence.test.ts +216 -0
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +281 -2
- package/src/plugins/defaults/image-fallback/__tests__/vision-recovery.test.ts +268 -0
- package/src/plugins/defaults/image-fallback/hooks/conversation-deleted.ts +27 -0
- package/src/plugins/defaults/image-fallback/hooks/init.ts +16 -0
- package/src/plugins/defaults/image-fallback/hooks/post-compact.ts +52 -0
- package/src/plugins/defaults/image-fallback/hooks/post-model-call.ts +80 -0
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +7 -4
- package/src/plugins/defaults/image-fallback/hooks/shutdown.ts +14 -0
- package/src/plugins/defaults/image-fallback/hooks/stop.ts +23 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +12 -12
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +73 -15
- package/src/plugins/defaults/image-fallback/src/caption-cache.ts +206 -20
- package/src/plugins/defaults/image-fallback/src/recovery-state.ts +49 -0
- package/src/plugins/defaults/image-fallback/src/vision-caption.ts +11 -3
- package/src/plugins/defaults/image-fallback/src/vision-error.ts +19 -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 +97 -61
- package/src/plugins/defaults/index.ts +29 -5
- package/src/plugins/defaults/injector-order.ts +1 -0
- 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 +0 -6
- package/src/plugins/defaults/memory/__tests__/db-maintenance.test.ts +105 -11
- 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 +0 -6
- package/src/plugins/defaults/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -70
- package/src/plugins/defaults/memory/__tests__/jobs-worker-memory-disabled.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/jobs-worker-pkb-schedule.test.ts +7 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +0 -5
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +7 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +186 -19
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +926 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +136 -82
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +0 -6
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +217 -2
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +0 -7
- package/src/plugins/defaults/memory/__tests__/table-relocation.test.ts +49 -0
- package/src/plugins/defaults/memory/activation-session-store.ts +1 -1
- package/src/plugins/defaults/memory/anisotropy.ts +1 -1
- package/src/plugins/defaults/memory/config.ts +155 -6
- package/src/plugins/defaults/memory/context-search/agent-protocol.ts +1 -1
- package/src/plugins/defaults/memory/context-search/search.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +26 -23
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +1 -1
- package/src/plugins/defaults/memory/embeddings.ts +8 -40
- package/src/plugins/defaults/memory/filing-jobs.ts +1 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +8 -4
- package/src/plugins/defaults/memory/frontmatter.ts +1 -1
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +4 -25
- package/src/plugins/defaults/memory/graph/bootstrap.ts +13 -19
- package/src/plugins/defaults/memory/graph/capability-seed.ts +62 -33
- package/src/plugins/defaults/memory/graph/consolidation.ts +8 -15
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +12 -4
- package/src/plugins/defaults/memory/graph/decay.ts +5 -10
- package/src/plugins/defaults/memory/graph/extraction-job.ts +2 -3
- package/src/plugins/defaults/memory/graph/extraction.test.ts +1 -9
- package/src/plugins/defaults/memory/graph/extraction.ts +149 -64
- package/src/plugins/defaults/memory/graph/graph-search.test.ts +0 -6
- package/src/plugins/defaults/memory/graph/graph-search.ts +33 -15
- package/src/plugins/defaults/memory/graph/image-ref-utils.ts +7 -3
- package/src/plugins/defaults/memory/graph/injection.test.ts +0 -1
- package/src/plugins/defaults/memory/graph/injection.ts +1 -1
- package/src/plugins/defaults/memory/graph/narrative.ts +2 -4
- package/src/plugins/defaults/memory/graph/pattern-scan.ts +2 -5
- package/src/plugins/defaults/memory/graph/retriever.test.ts +27 -28
- package/src/plugins/defaults/memory/graph/retriever.ts +89 -42
- package/src/plugins/defaults/memory/graph/scoring.test.ts +0 -1
- package/src/plugins/defaults/memory/graph/store.test.ts +6 -58
- package/src/plugins/defaults/memory/graph/store.ts +5 -43
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +318 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +244 -8
- package/src/plugins/defaults/memory/graph/tools.ts +1 -1
- package/src/plugins/defaults/memory/graph/types.ts +0 -3
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +130 -0
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +303 -0
- package/src/plugins/defaults/memory/graph-topology/flag.ts +14 -0
- package/src/plugins/defaults/memory/graph-topology/types.ts +84 -0
- package/src/plugins/defaults/memory/hooks/init.ts +1 -1
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +10 -10
- package/src/plugins/defaults/memory/host-utils.ts +80 -0
- package/src/plugins/defaults/memory/identity-context.ts +39 -0
- package/src/plugins/defaults/memory/indexer.ts +18 -54
- package/src/plugins/defaults/memory/injectors.ts +5 -8
- package/src/plugins/defaults/memory/job-handler-registration.ts +0 -4
- package/src/plugins/defaults/memory/job-handlers/backfill.ts +10 -8
- package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +0 -8
- package/src/plugins/defaults/memory/job-handlers/embedding.ts +31 -17
- package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +13 -6
- package/src/plugins/defaults/memory/job-handlers.ts +10 -9
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +0 -7
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +3 -3
- package/src/plugins/defaults/memory/jobs/embed-pkb-file.test.ts +41 -28
- package/src/plugins/defaults/memory/jobs/embed-pkb-file.ts +10 -5
- package/src/plugins/defaults/memory/jobs-worker.ts +161 -50
- package/src/plugins/defaults/memory/logging.ts +17 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +143 -0
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +19 -7
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +5 -6
- package/src/plugins/defaults/memory/memory-retrospective-fork-boundary.ts +57 -20
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +220 -79
- package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +448 -0
- package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +52 -39
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +14 -10
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +8 -3
- package/src/plugins/defaults/memory/message-media.ts +80 -0
- package/src/plugins/defaults/memory/paths.ts +48 -0
- package/src/plugins/defaults/memory/pkb/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/pkb/context.ts +2 -2
- package/src/plugins/defaults/memory/pkb/pkb-index.test.ts +25 -44
- package/src/plugins/defaults/memory/pkb/pkb-index.ts +24 -25
- package/src/plugins/defaults/memory/pkb/pkb-reconcile.test.ts +46 -34
- package/src/plugins/defaults/memory/pkb/pkb-reconcile.ts +4 -9
- package/src/plugins/defaults/memory/pkb/pkb-search.test.ts +5 -17
- package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -9
- package/src/plugins/defaults/memory/pkb/types.ts +1 -12
- package/src/plugins/defaults/memory/pkb-schedule.ts +2 -2
- package/src/plugins/defaults/memory/rerank-local.ts +3 -4
- package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +9 -17
- package/src/plugins/defaults/memory/routes/memory-eval-routes.ts +2 -2
- package/src/plugins/defaults/memory/routes/memory-graph-routes.ts +71 -0
- package/src/plugins/defaults/memory/routes/memory-item-routes.test.ts +149 -9
- package/src/plugins/defaults/memory/routes/memory-item-routes.ts +147 -12
- package/src/plugins/defaults/memory/routes/memory-v2-routes.ts +7 -11
- package/src/plugins/defaults/memory/routes/memory-v3-routes.ts +1 -1
- package/src/plugins/defaults/memory/startup.ts +3 -4
- package/src/plugins/defaults/memory/task-memory-cleanup.ts +1 -1
- package/src/plugins/defaults/memory/tools.test.ts +1 -9
- package/src/plugins/defaults/memory/tools.ts +0 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +0 -6
- package/src/plugins/defaults/memory/v2/__tests__/cli-command-store.test.ts +6 -6
- package/src/plugins/defaults/memory/v2/__tests__/consolidation-job.test.ts +48 -6
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/injection-events.test.ts +61 -69
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +0 -6
- package/src/plugins/defaults/memory/v2/__tests__/page-index.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/prompts-consolidation.test.ts +28 -0
- package/src/plugins/defaults/memory/v2/__tests__/qdrant.test.ts +3 -6
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +3 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +16 -27
- package/src/plugins/defaults/memory/v2/__tests__/sim.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/__tests__/skill-content.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/skill-store.test.ts +56 -22
- package/src/plugins/defaults/memory/v2/__tests__/static-context.test.ts +9 -6
- package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +6 -6
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +31 -16
- package/src/plugins/defaults/memory/v2/cli-command-content.ts +78 -0
- package/src/plugins/defaults/memory/v2/cli-command-store.ts +32 -11
- package/src/plugins/defaults/memory/v2/consolidation-job.ts +45 -5
- package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/harness-types.ts +12 -0
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -8
- package/src/plugins/defaults/memory/v2/harness/router-retriever.ts +1 -8
- package/src/plugins/defaults/memory/v2/harness/trace.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection-events.ts +34 -15
- package/src/plugins/defaults/memory/v2/injection.ts +3 -4
- package/src/plugins/defaults/memory/v2/memory-v2-startup.test.ts +0 -5
- package/src/plugins/defaults/memory/v2/memory-v2-startup.ts +2 -2
- package/src/plugins/defaults/memory/v2/migration.ts +1 -1
- package/src/plugins/defaults/memory/v2/page-index.ts +1 -1
- package/src/plugins/defaults/memory/v2/prompts/consolidation.ts +6 -2
- package/src/plugins/defaults/memory/v2/prompts/router.ts +1 -1
- package/src/plugins/defaults/memory/v2/qdrant.ts +2 -2
- package/src/plugins/defaults/memory/v2/reranker.ts +2 -2
- package/src/plugins/defaults/memory/v2/router.ts +10 -20
- package/src/plugins/defaults/memory/v2/skill-content.ts +23 -4
- package/src/plugins/defaults/memory/v2/skill-store.ts +44 -43
- package/src/plugins/defaults/memory/v2/static-context.ts +7 -12
- package/src/plugins/defaults/memory/v2/sweep-job.ts +24 -13
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +19 -0
- package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +0 -5
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +17 -0
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +14 -4
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +23 -17
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +20 -6
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +2 -0
- package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +0 -5
- package/src/plugins/defaults/memory/v3/candidate-match.ts +20 -11
- package/src/plugins/defaults/memory/v3/dense.ts +1 -1
- package/src/plugins/defaults/memory/v3/injector.ts +1 -1
- package/src/plugins/defaults/memory/v3/learned-edges.test.ts +14 -0
- package/src/plugins/defaults/memory/v3/learned-edges.ts +6 -1
- package/src/plugins/defaults/memory/v3/maintain-job.ts +39 -31
- package/src/plugins/defaults/memory/v3/orchestrate.ts +1 -1
- package/src/plugins/defaults/memory/v3/page-content.ts +1 -1
- package/src/plugins/defaults/memory/v3/pool-select.ts +2 -3
- package/src/plugins/defaults/memory/v3/prune.test.ts +10 -0
- package/src/plugins/defaults/memory/v3/prune.ts +1 -1
- package/src/plugins/defaults/memory/v3/section-dense-store.ts +1 -1
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +1 -1
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +47 -25
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +31 -11
- package/src/plugins/defaults/memory/worker.ts +2 -2
- package/src/plugins/defaults/workspace/injectors.ts +116 -5
- package/src/plugins/mtime-cache.ts +207 -105
- package/src/plugins/pipeline.ts +195 -5
- package/src/plugins/surface-import.ts +52 -14
- package/src/plugins/types.ts +10 -15
- package/src/prompts/persona-resolver.ts +1 -1
- package/src/prompts/system-prompt.ts +2 -4
- package/src/prompts/templates/system-sections.ts +12 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +0 -5
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +1 -21
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +12 -6
- package/src/providers/__tests__/preflight-resolved-config.test.ts +189 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +21 -3
- package/src/providers/__tests__/retry-callsite.test.ts +207 -8
- package/src/providers/__tests__/satellite-connection-routing.test.ts +12 -6
- package/src/providers/__tests__/vellum-mismatch-routing.test.ts +0 -5
- package/src/providers/anthropic/client.ts +109 -7
- package/src/providers/anthropic-gateway-shared.ts +63 -0
- package/src/providers/call-site-routing.ts +1 -0
- package/src/providers/connection-resolution.ts +192 -6
- package/src/providers/content-block-schema.ts +149 -0
- package/src/providers/gemini/client.ts +84 -22
- package/src/providers/gemini/inline-media.ts +2 -3
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +5 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +1 -15
- package/src/providers/inference/adapter-factory.ts +13 -0
- package/src/providers/inference/connection-availability.ts +193 -0
- package/src/providers/inference/connections.ts +6 -10
- package/src/providers/media-resolve.ts +193 -0
- package/src/providers/model-catalog.ts +337 -17
- package/src/providers/model-intents.ts +6 -0
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +98 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
- package/src/providers/openai/api-error-normalization.ts +61 -0
- package/src/providers/openai/chat-completions-provider.ts +73 -10
- package/src/providers/openai/responses-provider.ts +10 -3
- package/src/providers/openrouter/client.ts +6 -39
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/provider-availability.ts +23 -1
- package/src/providers/provider-send-message.ts +19 -3
- package/src/providers/registry.ts +5 -1
- package/src/providers/retry.ts +91 -29
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +31 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +393 -1
- package/src/providers/speech-to-text/deepgram-realtime.ts +213 -13
- package/src/providers/speech-to-text/resolve.ts +33 -5
- package/src/providers/types.ts +69 -24
- package/src/providers/vellum-model-routing.ts +11 -0
- package/src/providers/vercel-ai-gateway/client.ts +142 -0
- package/src/runtime/__tests__/actor-trust-resolver.test.ts +132 -0
- package/src/runtime/__tests__/agent-wake.test.ts +232 -16
- package/src/runtime/__tests__/background-job-runner.test.ts +71 -2
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +5 -15
- package/src/runtime/__tests__/local-principal-trust.test.ts +0 -6
- package/src/runtime/__tests__/member-verdict-cache.test.ts +2 -15
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +91 -30
- package/src/runtime/access-request-helper.ts +75 -3
- package/src/runtime/actor-trust-resolver.ts +33 -108
- package/src/runtime/agent-wake.ts +45 -25
- package/src/runtime/assistant-event-hub.ts +0 -105
- 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/background-job-runner.ts +57 -2
- package/src/runtime/capabilities.ts +3 -3
- package/src/runtime/channel-reply-delivery.ts +38 -19
- package/src/runtime/channel-retry-sweep.ts +1 -1
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -3
- package/src/runtime/effective-capabilities.test.ts +0 -36
- package/src/runtime/effective-capabilities.ts +8 -23
- package/src/runtime/guardian-vellum-migration.ts +12 -16
- package/src/runtime/http-router-types.ts +119 -0
- package/src/runtime/http-router.ts +2 -115
- package/src/runtime/http-server.ts +11 -2
- package/src/runtime/http-types.ts +1 -1
- package/src/runtime/introduction-policy.ts +89 -0
- package/src/runtime/local-actor-identity.ts +4 -50
- package/src/runtime/local-principal-trust.ts +1 -1
- package/src/runtime/member-verdict-cache.ts +0 -0
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +51 -1
- package/src/runtime/migrations/__tests__/origin-mode.test.ts +62 -0
- package/src/runtime/migrations/gcs-signed-url.ts +21 -7
- package/src/runtime/migrations/origin-mode.ts +16 -11
- package/src/runtime/pending-interactions.ts +8 -3
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/backup-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +0 -16
- package/src/runtime/routes/__tests__/client-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +4 -5
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +8 -8
- package/src/runtime/routes/__tests__/contact-routes.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 +31 -9
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +0 -8
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +260 -11
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +499 -0
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/inference-callsites-routes.test.ts +54 -0
- package/src/runtime/routes/__tests__/inference-models-routes.test.ts +54 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +403 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +219 -6
- package/src/runtime/routes/__tests__/inference-routes-registration.test.ts +42 -0
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +70 -15
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +182 -38
- 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__/stt-routes.test.ts +0 -9
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/task-routes.test.ts +2 -2
- package/src/runtime/routes/__tests__/theme-routes.test.ts +66 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +0 -7
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +1 -9
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +0 -7
- package/src/runtime/routes/acp-routes.ts +20 -14
- package/src/runtime/routes/approval-routes.ts +21 -2
- package/src/runtime/routes/canned-message-complete.ts +82 -0
- package/src/runtime/routes/channel-metadata.ts +49 -0
- package/src/runtime/routes/contact-routes.ts +75 -43
- package/src/runtime/routes/conversation-attention-routes.ts +1 -1
- package/src/runtime/routes/conversation-cli-routes.ts +2 -2
- package/src/runtime/routes/conversation-compaction-routes.ts +5 -0
- package/src/runtime/routes/conversation-management-routes.ts +147 -2
- package/src/runtime/routes/conversation-query-routes.ts +378 -43
- package/src/runtime/routes/conversation-routes.ts +89 -181
- package/src/runtime/routes/conversation-starter-routes.ts +12 -23
- package/src/runtime/routes/credential-prompt-routes.ts +48 -4
- package/src/runtime/routes/credential-request-routes.ts +85 -0
- package/src/runtime/routes/credential-routes.ts +40 -5
- package/src/runtime/routes/default-provider-routes.ts +132 -0
- package/src/runtime/routes/errors.ts +17 -0
- package/src/runtime/routes/events-routes.ts +158 -39
- package/src/runtime/routes/guardian-approval-interception.ts +1 -1
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/inbound-message-handler.ts +61 -6
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +58 -26
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +73 -87
- package/src/runtime/routes/inbound-stages/admission-policy.ts +2 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +1 -8
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -2
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -5
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -1
- package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +0 -5
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +0 -9
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -9
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +302 -0
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +27 -37
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +1 -1
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -9
- package/src/runtime/routes/index.ts +16 -4
- package/src/runtime/routes/inference-callsites-routes.ts +211 -0
- package/src/runtime/routes/inference-models-routes.ts +104 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +2 -1
- package/src/runtime/routes/inference-profiles-routes.ts +717 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +38 -1
- package/src/runtime/routes/inference-send-routes.ts +2 -1
- package/src/runtime/routes/integrations/slack/channels.ts +26 -4
- package/src/runtime/routes/integrations/slack/users.ts +78 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +44 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +2 -1
- package/src/runtime/routes/llm-request-logs-access.ts +19 -0
- package/src/runtime/routes/migration-routes.ts +94 -47
- package/src/runtime/routes/monitoring-routes.ts +1 -1
- package/src/runtime/routes/notification-routes.ts +1 -1
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +0 -7
- package/src/runtime/routes/plugins-routes.ts +169 -16
- package/src/runtime/routes/schedule-routes.ts +38 -1
- package/src/runtime/routes/secret-routes.ts +0 -7
- package/src/runtime/routes/settings-routes.ts +160 -22
- package/src/runtime/routes/skills-routes.ts +6 -0
- package/src/runtime/routes/subagents-routes.ts +17 -18
- package/src/runtime/routes/surface-action-routes.ts +4 -2
- package/src/runtime/routes/theme-routes.ts +36 -0
- package/src/runtime/routes/types.ts +2 -1
- package/src/runtime/routes/workflow-routes.ts +1 -1
- package/src/runtime/services/__tests__/auto-analysis-guard.test.ts +2 -16
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
- package/src/runtime/services/auto-analysis-guard.ts +5 -5
- package/src/runtime/services/conversation-serializer.ts +2 -3
- package/src/runtime/sync/resource-sync-events.ts +4 -0
- package/src/runtime/trust-context-resolver.ts +9 -9
- package/src/runtime/trust-verdict-consumer.ts +46 -5
- package/src/schedule/scheduler.ts +61 -18
- 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/__tests__/secret-normalize.test.ts +96 -0
- package/src/security/secret-normalize.ts +41 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/security/secure-keys.ts +222 -49
- package/src/sequence/engine.ts +15 -6
- package/src/signals/user-message.ts +3 -1
- package/src/skills/available-skills.ts +134 -0
- package/src/skills/install-meta.ts +8 -0
- package/src/skills/managed-store.ts +10 -0
- package/src/stt/types.ts +33 -2
- package/src/subagent/manager.ts +5 -6
- package/src/tasks/SPEC.md +10 -17
- package/src/tasks/tool-sanitizer.ts +3 -1
- package/src/telemetry/__tests__/config-setting-events-store.test.ts +126 -0
- package/src/telemetry/__tests__/flush-checkpoints.test.ts +56 -0
- package/src/telemetry/__tests__/watchdog-events-store.test.ts +0 -8
- package/src/telemetry/config-setting-events-store.ts +97 -0
- package/src/telemetry/flush-checkpoints.ts +70 -0
- package/src/telemetry/skill-loaded-events-store.test.ts +0 -8
- package/src/telemetry/telemetry-event-sources.ts +571 -0
- package/src/telemetry/tool-audit.ts +285 -0
- package/src/telemetry/tool-executed-events-store.test.ts +19 -27
- package/src/telemetry/tool-executed-events-store.ts +5 -5
- package/src/telemetry/turn-events-store.ts +36 -0
- package/src/telemetry/turn-outcome.ts +116 -0
- package/src/telemetry/turn-trace-store.test.ts +156 -8
- package/src/telemetry/turn-trace-store.ts +53 -4
- package/src/telemetry/types.ts +91 -2
- package/src/telemetry/usage-telemetry-reporter.test.ts +373 -119
- package/src/telemetry/usage-telemetry-reporter.ts +110 -675
- package/src/telemetry/watchdog-direct-emit.test.ts +0 -5
- package/src/theme/workspace-theme.test.ts +269 -0
- package/src/theme/workspace-theme.ts +304 -0
- package/src/tools/AGENTS.md +0 -26
- package/src/tools/acp/spawn.test.ts +0 -7
- package/src/tools/browser/browser-execution.ts +99 -75
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1 -11
- 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/execution-target.test.ts +31 -0
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/executor.ts +63 -275
- package/src/tools/filesystem/write.ts +0 -2
- package/src/tools/host-terminal/host-shell.test.ts +0 -7
- package/src/tools/host-terminal/host-shell.ts +6 -49
- package/src/tools/permission-checker.ts +33 -81
- package/src/tools/registry.ts +261 -166
- package/src/tools/run-standalone.ts +6 -13
- package/src/tools/side-effects.ts +0 -1
- package/src/tools/skills/find-similar-skills.test.ts +5 -9
- package/src/tools/skills/scaffold-managed.ts +31 -4
- package/src/tools/skills/skill-script-runner.ts +17 -31
- package/src/tools/skills/skill-tool-factory.ts +2 -6
- package/src/tools/subagent/read.ts +6 -4
- package/src/tools/subagent/spawn.ts +28 -29
- package/src/tools/terminal/safe-env.ts +8 -3
- package/src/tools/terminal/shell.test.ts +0 -6
- package/src/tools/terminal/shell.ts +1 -50
- package/src/tools/tool-approval-handler.ts +99 -166
- package/src/tools/tool-defaults.ts +2 -6
- package/src/tools/tool-manifest.ts +0 -49
- package/src/{events/tool-profiling-listener.ts → tools/tool-profiler.ts} +64 -32
- package/src/tools/tool-types.ts +4 -95
- package/src/tools/types.ts +27 -140
- package/src/tools/workflows/manage-workflows.ts +2 -1
- package/src/tools/workflows/run-workflow.test.ts +6 -1
- package/src/tools/workflows/run-workflow.ts +2 -4
- package/src/tools/workspace-tools/loader.ts +26 -14
- package/src/tts/__tests__/pcm-chunk-aligner.test.ts +48 -0
- package/src/tts/__tests__/pcm-sample-rates.test.ts +59 -0
- package/src/tts/__tests__/provider-adapters.test.ts +891 -22
- package/src/tts/__tests__/provider-catalog.test.ts +43 -10
- package/src/tts/__tests__/speakable-segments.test.ts +427 -0
- package/src/tts/__tests__/synthesis-stream.test.ts +5 -1
- package/src/tts/pcm-chunk-aligner.ts +29 -0
- package/src/tts/pcm-sample-rates.ts +47 -0
- package/src/tts/provider-definition.ts +6 -7
- package/src/tts/providers/__tests__/xai-tts-socket.test.ts +406 -0
- package/src/tts/providers/deepgram-provider.ts +160 -102
- package/src/tts/providers/elevenlabs-provider.ts +182 -105
- package/src/tts/providers/fish-audio-provider.ts +72 -105
- package/src/tts/providers/xai-provider.ts +131 -22
- package/src/tts/providers/xai-tts-socket.ts +311 -0
- package/src/tts/speakable-segments.ts +188 -0
- package/src/tts/stream-read.ts +136 -0
- package/src/tts/synthesis-stream.ts +9 -5
- package/src/tts/synthesize-text.ts +15 -5
- package/src/tts/types.ts +21 -0
- package/src/usage/attribution.ts +43 -9
- package/src/util/errors.ts +26 -0
- package/src/util/image-conversion.ts +23 -5
- package/src/util/logger.ts +67 -68
- package/src/util/platform.ts +19 -60
- package/src/util/pricing.ts +14 -11
- package/src/util/process-tree.ts +25 -13
- package/src/util/provider-error-patterns.ts +21 -0
- package/src/util/sqlite-query-label.ts +51 -0
- package/src/util/sqlite-retry.ts +14 -2
- package/src/util/unicode.ts +1 -1
- package/src/watcher/__tests__/engine-auth-notify.test.ts +316 -0
- package/src/watcher/engine.ts +87 -2
- package/src/workflows/capabilities.test.ts +2 -32
- package/src/workflows/capabilities.ts +18 -25
- package/src/workflows/engine-integration.test.ts +1 -7
- package/src/workflows/engine.test.ts +2 -10
- package/src/workflows/engine.ts +1 -1
- package/src/workflows/fanout-load.test.ts +1 -1
- package/src/workflows/journal-store.test.ts +1 -9
- package/src/workflows/leaf-runner.test.ts +0 -6
- package/src/workflows/leaf-runner.ts +4 -5
- package/src/workflows/library.test.ts +1 -9
- package/src/workflows/run-manager.test.ts +2 -10
- package/src/workflows/run-manager.ts +2 -4
- package/src/workspace/adaptive-thinking-repair.ts +1 -1
- package/src/workspace/custom-profile-ensure.ts +133 -0
- package/src/workspace/default-provider-ensure.ts +162 -0
- package/src/workspace/git-service.ts +160 -15
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +0 -1
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +1 -1
- package/src/workspace/migrations/126-strip-managed-profile-bodies.ts +92 -0
- package/src/workspace/migrations/127-backfill-default-provider.ts +176 -0
- package/src/workspace/migrations/128-repair-stale-openrouter-grok-model-ids.ts +112 -0
- package/src/workspace/migrations/129-remove-analyze-conversation-config.ts +59 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/grants.test.ts +0 -686
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/grants.ts +0 -184
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/rendering.ts +0 -135
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/grants.test.ts +0 -686
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/grants.ts +0 -184
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/rendering.ts +0 -135
- package/node_modules/@vellumai/service-contracts/src/__tests__/grants.test.ts +0 -686
- package/node_modules/@vellumai/service-contracts/src/grants.ts +0 -184
- package/node_modules/@vellumai/service-contracts/src/rendering.ts +0 -135
- package/scripts/generate-bundled-tool-registry.ts +0 -223
- package/scripts/test.sh +0 -494
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +0 -255
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +0 -137
- package/src/__tests__/auto-analysis-end-to-end.test.ts +0 -621
- package/src/__tests__/auto-analysis-prompt.test.ts +0 -50
- package/src/__tests__/config-analysis.test.ts +0 -83
- package/src/__tests__/conversation-analysis-routes.test.ts +0 -156
- package/src/__tests__/credential-execution-admin-cli.test.ts +0 -504
- package/src/__tests__/credential-execution-approval-bridge.test.ts +0 -297
- package/src/__tests__/credential-execution-feature-gates.test.ts +0 -185
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -120
- package/src/__tests__/credential-execution-tools.test.ts +0 -289
- package/src/__tests__/db-proxy-transaction.test.ts +0 -206
- package/src/__tests__/event-bus.test.ts +0 -222
- package/src/__tests__/reaction-intercept-cold-cache-warm.test.ts +0 -141
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -157
- package/src/__tests__/skill-memory.test.ts +0 -85
- package/src/__tests__/skill-runtime-path.test.ts +0 -63
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -216
- package/src/__tests__/tool-metrics-listener.test.ts +0 -194
- package/src/__tests__/tool-profiling-listener.test.ts +0 -219
- package/src/cli/commands/credential-execution.ts +0 -362
- package/src/config/__tests__/bundled-tool-registry-guard.test.ts +0 -120
- package/src/config/bundled-tool-registry.ts +0 -281
- package/src/config/schemas/analysis.ts +0 -32
- package/src/credential-execution/approval-bridge.ts +0 -320
- package/src/credential-execution/feature-gates.ts +0 -61
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +0 -449
- package/src/events/bus.ts +0 -177
- package/src/events/domain-events.ts +0 -68
- package/src/events/tool-audit-listener.ts +0 -184
- package/src/events/tool-domain-event-publisher.ts +0 -90
- package/src/events/tool-metrics-listener.ts +0 -134
- package/src/events/tool-permission-telemetry-listener.ts +0 -44
- package/src/instrument.ts +0 -213
- package/src/ipc/routes/db-proxy-transaction.ts +0 -151
- package/src/plugins/defaults/memory/__tests__/find-analysis-conversation.test.ts +0 -197
- package/src/runtime/routes/conversation-analysis-routes.ts +0 -75
- package/src/runtime/routes/work-items-routes.test.ts +0 -74
- package/src/runtime/routes/work-items-routes.ts +0 -881
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +0 -477
- package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +0 -386
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +0 -53
- package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +0 -213
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +0 -41
- package/src/runtime/services/analyze-conversation.ts +0 -332
- package/src/runtime/services/auto-analysis-enqueue.ts +0 -130
- package/src/runtime/services/auto-analysis-prompt.ts +0 -55
- package/src/runtime/services/conversation-analyze-job.ts +0 -53
- package/src/skills/skill-memory.ts +0 -44
- package/src/tools/credential-execution/make-authenticated-request.ts +0 -198
- package/src/tools/credential-execution/manage-secure-command-tool.ts +0 -371
- package/src/tools/credential-execution/run-authenticated-command.ts +0 -261
- package/src/tools/flag-gated-tools.test.ts +0 -76
- package/src/util/sentry-log-stream.ts +0 -51
|
@@ -7,14 +7,17 @@
|
|
|
7
7
|
*
|
|
8
8
|
* The media-stream transport operates on raw audio frames:
|
|
9
9
|
*
|
|
10
|
-
* - `sendTextToken()` — Accumulates text tokens
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* media frames
|
|
14
|
-
* end-of-turn mark
|
|
10
|
+
* - `sendTextToken()` — Accumulates text tokens, extracts complete
|
|
11
|
+
* speakable segments as they form, and synthesizes each segment via
|
|
12
|
+
* the configured TTS provider, transcoding the resulting audio to
|
|
13
|
+
* mu-law 8 kHz media frames for Twilio. On `last: true` the remaining
|
|
14
|
+
* text is flushed as a final segment followed by an end-of-turn mark.
|
|
15
|
+
* An empty token with `last: true` sends only the mark.
|
|
15
16
|
*
|
|
16
17
|
* - `sendPlayUrl()` — Fetches audio from the given URL, transcodes it
|
|
17
|
-
* to mu-law 8 kHz, and streams the resulting frames to Twilio.
|
|
18
|
+
* to mu-law 8 kHz, and streams the resulting frames to Twilio. WAV
|
|
19
|
+
* and raw-PCM bodies are transcoded incrementally as they download,
|
|
20
|
+
* so playback starts before the response completes.
|
|
18
21
|
*
|
|
19
22
|
* - `endSession()` — Closes the underlying WebSocket, which triggers
|
|
20
23
|
* Twilio to tear down the media stream and (eventually) the call.
|
|
@@ -28,14 +31,20 @@
|
|
|
28
31
|
*
|
|
29
32
|
* - `clearAudio()` — Clears any queued outbound audio (barge-in),
|
|
30
33
|
* flushes the internal playback queue, and aborts in-flight synthesis.
|
|
34
|
+
* Also exposed to the call controller as `cancelPendingSpeech()` so an
|
|
35
|
+
* aborted turn's queued speech never plays over the next turn.
|
|
31
36
|
*/
|
|
32
37
|
|
|
33
38
|
import type { ServerWebSocket } from "bun";
|
|
34
39
|
|
|
40
|
+
import { extractSpeakableSegments } from "../tts/speakable-segments.js";
|
|
41
|
+
import { synthesizeAndEmit } from "../tts/synthesis-stream.js";
|
|
35
42
|
import { getLogger } from "../util/logger.js";
|
|
43
|
+
import type { CallAudioFormat } from "./audio-store.js";
|
|
36
44
|
import type { CallTransport } from "./call-transport.js";
|
|
37
45
|
import {
|
|
38
46
|
chunkMulawToBase64Frames,
|
|
47
|
+
MULAW_FRAME_SIZE,
|
|
39
48
|
pcm16ToMulaw,
|
|
40
49
|
resamplePcm16,
|
|
41
50
|
} from "./media-stream-audio-transcode.js";
|
|
@@ -44,12 +53,43 @@ import type {
|
|
|
44
53
|
MediaStreamSendMarkCommand,
|
|
45
54
|
MediaStreamSendMediaCommand,
|
|
46
55
|
} from "./media-stream-protocol.js";
|
|
56
|
+
import { resolveCallTtsProvider } from "./resolve-call-tts-provider.js";
|
|
47
57
|
|
|
48
58
|
const log = getLogger("media-stream-output");
|
|
49
59
|
|
|
50
60
|
/** Twilio media streams consume 8 kHz mono mu-law. */
|
|
51
61
|
const TELEPHONY_SAMPLE_RATE_HZ = 8000;
|
|
52
62
|
|
|
63
|
+
/**
|
|
64
|
+
* PCM sample rate requested from streaming-capable providers. Deterministic
|
|
65
|
+
* across providers (ElevenLabs maps the hint to `pcm_16000`; fish-audio
|
|
66
|
+
* honours it directly), so the incremental transcode can hard-wire its
|
|
67
|
+
* downsample ratio to the telephony rate.
|
|
68
|
+
*/
|
|
69
|
+
const STREAMING_PCM_SAMPLE_RATE_HZ = 16_000;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Size of the canonical WAV header: RIFF descriptor + 16-byte PCM fmt
|
|
73
|
+
* chunk + data chunk header.
|
|
74
|
+
*/
|
|
75
|
+
const WAV_HEADER_BYTES = 44;
|
|
76
|
+
|
|
77
|
+
/** WAV files always start with the ASCII magic "RIFF" (0x52494646). */
|
|
78
|
+
function hasRiffMagic(audio: Buffer): boolean {
|
|
79
|
+
return (
|
|
80
|
+
audio.length >= 4 &&
|
|
81
|
+
audio[0] === 0x52 && // R
|
|
82
|
+
audio[1] === 0x49 && // I
|
|
83
|
+
audio[2] === 0x46 && // F
|
|
84
|
+
audio[3] === 0x46 // F
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Wrap a Uint8Array's memory as a Buffer without copying. */
|
|
89
|
+
function viewToBuffer(view: Uint8Array): Buffer {
|
|
90
|
+
return Buffer.from(view.buffer, view.byteOffset, view.byteLength);
|
|
91
|
+
}
|
|
92
|
+
|
|
53
93
|
/**
|
|
54
94
|
* Keep every `factor`-th 16-bit LE sample. Cheap decimation (no anti-alias
|
|
55
95
|
* filter) for rates that are integer multiples of the telephony rate; also
|
|
@@ -66,6 +106,169 @@ function decimatePcm16(pcm: Buffer, factor: number): Buffer {
|
|
|
66
106
|
return out;
|
|
67
107
|
}
|
|
68
108
|
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// Incremental PCM16 → mu-law frame encoding
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Incrementally converts 16-bit LE PCM chunks — at an integer multiple of
|
|
115
|
+
* the telephony rate — into base64 mu-law frames, emitting each frame as
|
|
116
|
+
* soon as it fills.
|
|
117
|
+
*
|
|
118
|
+
* Chunk boundaries can split a 16-bit sample or a decimation group; the
|
|
119
|
+
* unprocessable tail (less than one output sample's worth of bytes)
|
|
120
|
+
* carries into the next chunk so sample alignment and decimation phase
|
|
121
|
+
* stay stable across chunks. Mu-law bytes short of a whole 20 ms frame
|
|
122
|
+
* are carried likewise.
|
|
123
|
+
*/
|
|
124
|
+
class IncrementalMulawFrameEncoder {
|
|
125
|
+
/** PCM tail below one output sample, awaiting the next chunk. */
|
|
126
|
+
private pcmCarry: Buffer | undefined;
|
|
127
|
+
|
|
128
|
+
/** Mu-law bytes short of a whole frame, awaiting the next chunk. */
|
|
129
|
+
private mulawCarry: Buffer = Buffer.alloc(0);
|
|
130
|
+
|
|
131
|
+
/** Bytes per output sample: 2 input bytes per sample × decimation factor. */
|
|
132
|
+
private readonly pcmAlignBytes: number;
|
|
133
|
+
|
|
134
|
+
constructor(
|
|
135
|
+
private readonly decimationFactor: number,
|
|
136
|
+
private readonly emitFrames: (frames: string[]) => void,
|
|
137
|
+
) {
|
|
138
|
+
this.pcmAlignBytes = 2 * decimationFactor;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Bytes currently held back waiting for sample alignment. */
|
|
142
|
+
get pcmCarryBytes(): number {
|
|
143
|
+
return this.pcmCarry?.length ?? 0;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Transcode a PCM16 LE chunk, emitting every frame that fills. */
|
|
147
|
+
push(chunk: Buffer): void {
|
|
148
|
+
const combined = this.pcmCarry
|
|
149
|
+
? Buffer.concat([this.pcmCarry, chunk])
|
|
150
|
+
: chunk;
|
|
151
|
+
const usableBytes =
|
|
152
|
+
combined.length - (combined.length % this.pcmAlignBytes);
|
|
153
|
+
this.pcmCarry =
|
|
154
|
+
usableBytes < combined.length
|
|
155
|
+
? combined.subarray(usableBytes)
|
|
156
|
+
: undefined;
|
|
157
|
+
if (usableBytes === 0) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const pcm8k = decimatePcm16(
|
|
161
|
+
combined.subarray(0, usableBytes),
|
|
162
|
+
this.decimationFactor,
|
|
163
|
+
);
|
|
164
|
+
this.sendMulaw(pcm16ToMulaw(pcm8k), false);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Emit the final partial frame — the whole-buffer path sends a short
|
|
169
|
+
* trailing frame the same way.
|
|
170
|
+
*/
|
|
171
|
+
flush(): void {
|
|
172
|
+
this.sendMulaw(Buffer.alloc(0), true);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private sendMulaw(mulaw: Buffer, flushPartialFrame: boolean): void {
|
|
176
|
+
this.mulawCarry =
|
|
177
|
+
this.mulawCarry.length > 0
|
|
178
|
+
? Buffer.concat([this.mulawCarry, mulaw])
|
|
179
|
+
: mulaw;
|
|
180
|
+
const sendableBytes = flushPartialFrame
|
|
181
|
+
? this.mulawCarry.length
|
|
182
|
+
: this.mulawCarry.length - (this.mulawCarry.length % MULAW_FRAME_SIZE);
|
|
183
|
+
if (sendableBytes === 0) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const frames = chunkMulawToBase64Frames(
|
|
187
|
+
this.mulawCarry.subarray(0, sendableBytes),
|
|
188
|
+
);
|
|
189
|
+
this.mulawCarry = this.mulawCarry.subarray(sendableBytes);
|
|
190
|
+
this.emitFrames(frames);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Outcome of an incremental body transcode attempt. */
|
|
195
|
+
type BodyStreamResult =
|
|
196
|
+
| { outcome: "streamed" }
|
|
197
|
+
| { outcome: "aborted" }
|
|
198
|
+
| { outcome: "fallback"; buffered: Buffer };
|
|
199
|
+
|
|
200
|
+
type HeaderSniffDecision =
|
|
201
|
+
| { kind: "need-more-bytes" }
|
|
202
|
+
| { kind: "fallback" }
|
|
203
|
+
| { kind: "stream"; decimationFactor: number; payloadOffset: number };
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Decide from a body's leading bytes whether it can be transcoded
|
|
207
|
+
* incrementally — and with which decimation factor — or must fall back
|
|
208
|
+
* to the whole-buffer path.
|
|
209
|
+
*
|
|
210
|
+
* Sniffs the actual bytes rather than trusting the declared format,
|
|
211
|
+
* mirroring `audioBufferToFrames`: a RIFF header wins over the declared
|
|
212
|
+
* content type. Only inputs the incremental encoder transcodes exactly
|
|
213
|
+
* like the whole-buffer path are streamed: canonical-header PCM16 mono
|
|
214
|
+
* WAV at an integer multiple of the telephony rate, or headerless raw
|
|
215
|
+
* PCM (assumed 16 kHz). Anything else — RIFF layouts with extra chunks,
|
|
216
|
+
* stereo, non-16-bit samples, fractional rates (44.1 kHz needs an
|
|
217
|
+
* interpolating resample), compressed bytes under a WAV content type —
|
|
218
|
+
* falls back.
|
|
219
|
+
*/
|
|
220
|
+
function sniffStreamableHeader(
|
|
221
|
+
pending: Buffer,
|
|
222
|
+
format: "wav" | "pcm",
|
|
223
|
+
): HeaderSniffDecision {
|
|
224
|
+
if (pending.length < 4) {
|
|
225
|
+
return { kind: "need-more-bytes" };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!hasRiffMagic(pending)) {
|
|
229
|
+
// Headerless raw PCM streams at the assumed 16 kHz (matching the
|
|
230
|
+
// whole-buffer path). WAV-declared bytes without a RIFF header need
|
|
231
|
+
// the whole-buffer path's compressed-format sniffing.
|
|
232
|
+
return format === "pcm"
|
|
233
|
+
? {
|
|
234
|
+
kind: "stream",
|
|
235
|
+
decimationFactor:
|
|
236
|
+
STREAMING_PCM_SAMPLE_RATE_HZ / TELEPHONY_SAMPLE_RATE_HZ,
|
|
237
|
+
payloadOffset: 0,
|
|
238
|
+
}
|
|
239
|
+
: { kind: "fallback" };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (pending.length < WAV_HEADER_BYTES) {
|
|
243
|
+
return { kind: "need-more-bytes" };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Only the canonical 44-byte layout is streamed: fmt chunk at fixed
|
|
247
|
+
// offsets, PCM16 mono, "data" chunk immediately after.
|
|
248
|
+
const isCanonicalPcm16Mono =
|
|
249
|
+
pending.toString("ascii", 8, 16) === "WAVEfmt " &&
|
|
250
|
+
pending.readUInt32LE(16) === 16 && // fmt chunk size (plain PCM)
|
|
251
|
+
pending.readUInt16LE(20) === 1 && // format tag: PCM
|
|
252
|
+
pending.readUInt16LE(22) === 1 && // mono
|
|
253
|
+
pending.readUInt16LE(34) === 16 && // 16 bits per sample
|
|
254
|
+
pending.toString("ascii", 36, 40) === "data";
|
|
255
|
+
const sampleRate = pending.readUInt32LE(24);
|
|
256
|
+
|
|
257
|
+
if (
|
|
258
|
+
!isCanonicalPcm16Mono ||
|
|
259
|
+
sampleRate <= 0 ||
|
|
260
|
+
sampleRate % TELEPHONY_SAMPLE_RATE_HZ !== 0
|
|
261
|
+
) {
|
|
262
|
+
return { kind: "fallback" };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
kind: "stream",
|
|
267
|
+
decimationFactor: sampleRate / TELEPHONY_SAMPLE_RATE_HZ,
|
|
268
|
+
payloadOffset: WAV_HEADER_BYTES,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
69
272
|
// ---------------------------------------------------------------------------
|
|
70
273
|
// Connection state
|
|
71
274
|
// ---------------------------------------------------------------------------
|
|
@@ -96,9 +299,21 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
96
299
|
private ws: ServerWebSocket<unknown>;
|
|
97
300
|
private state: MediaStreamOutputState = "connected";
|
|
98
301
|
|
|
99
|
-
/**
|
|
302
|
+
/**
|
|
303
|
+
* Text accumulated from sendTextToken calls that has not yet formed a
|
|
304
|
+
* complete speakable segment.
|
|
305
|
+
*/
|
|
100
306
|
private textBuffer = "";
|
|
101
307
|
|
|
308
|
+
/**
|
|
309
|
+
* True once the current turn's first speakable segment has been queued
|
|
310
|
+
* for synthesis. Gates eager segmentation: each turn's opening clause
|
|
311
|
+
* flushes early so speech onset does not wait for a full sentence.
|
|
312
|
+
* Cleared when a turn completes (`last: true`) or its pending text is
|
|
313
|
+
* discarded, so the next turn's first segment is eager again.
|
|
314
|
+
*/
|
|
315
|
+
private turnSegmentEnqueued = false;
|
|
316
|
+
|
|
102
317
|
/** FIFO queue of playback items awaiting delivery. */
|
|
103
318
|
private playbackQueue: PlaybackItem[] = [];
|
|
104
319
|
|
|
@@ -121,10 +336,10 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
121
336
|
private audioStartCallback: (() => void) | null = null;
|
|
122
337
|
|
|
123
338
|
/**
|
|
124
|
-
* The media-stream transport requires
|
|
339
|
+
* The media-stream transport requires raw PCM audio because its
|
|
125
340
|
* mu-law transcoder cannot decode compressed formats (mp3, opus).
|
|
126
341
|
*/
|
|
127
|
-
readonly
|
|
342
|
+
readonly requiresPcmAudio = true;
|
|
128
343
|
|
|
129
344
|
constructor(ws: ServerWebSocket<unknown>, streamSid: string) {
|
|
130
345
|
this.ws = ws;
|
|
@@ -134,30 +349,39 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
134
349
|
// ── CallTransport interface ─────────────────────────────────────────
|
|
135
350
|
|
|
136
351
|
/**
|
|
137
|
-
* Accumulate text tokens for TTS synthesis.
|
|
138
|
-
*
|
|
352
|
+
* Accumulate text tokens for TTS synthesis. Each complete speakable
|
|
353
|
+
* segment (sentence or newline-bounded line) is queued for synthesis
|
|
354
|
+
* as soon as it forms, so speech starts before the turn completes.
|
|
355
|
+
* When `last` is true, the remaining text is force-flushed as a final
|
|
356
|
+
* segment.
|
|
139
357
|
*
|
|
140
358
|
* An empty token with `last: true` signals end-of-turn without TTS:
|
|
141
359
|
* a mark is sent so the session transitions from "assistant speaking"
|
|
142
360
|
* to "caller speaking".
|
|
143
361
|
*/
|
|
144
362
|
sendTextToken(token: string, last: boolean): void {
|
|
145
|
-
if (this.state === "closed")
|
|
363
|
+
if (this.state === "closed") {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
146
366
|
|
|
147
367
|
this.textBuffer += token;
|
|
148
368
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
369
|
+
const { segments, remainder } = extractSpeakableSegments(
|
|
370
|
+
this.textBuffer,
|
|
371
|
+
last,
|
|
372
|
+
{ eager: !this.turnSegmentEnqueued },
|
|
373
|
+
);
|
|
374
|
+
this.textBuffer = remainder;
|
|
375
|
+
for (const segment of segments) {
|
|
376
|
+
this.enqueuePlayback({ type: "synthesize", text: segment });
|
|
377
|
+
this.turnSegmentEnqueued = true;
|
|
378
|
+
}
|
|
157
379
|
|
|
380
|
+
if (last) {
|
|
158
381
|
// Always send an end-of-turn mark so the media-stream server
|
|
159
382
|
// can detect turn boundaries.
|
|
160
383
|
this.enqueuePlayback({ type: "mark", name: "end-of-turn" });
|
|
384
|
+
this.turnSegmentEnqueued = false;
|
|
161
385
|
}
|
|
162
386
|
}
|
|
163
387
|
|
|
@@ -169,7 +393,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
169
393
|
* PCM, and re-encode as mu-law frames for Twilio.
|
|
170
394
|
*/
|
|
171
395
|
sendPlayUrl(url: string): void {
|
|
172
|
-
if (this.state === "closed")
|
|
396
|
+
if (this.state === "closed") {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
173
399
|
this.enqueuePlayback({ type: "fetch-url", url });
|
|
174
400
|
}
|
|
175
401
|
|
|
@@ -189,6 +415,17 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
189
415
|
*/
|
|
190
416
|
discardPendingText(): void {
|
|
191
417
|
this.textBuffer = "";
|
|
418
|
+
this.turnSegmentEnqueued = false;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Cancel queued and in-flight speech playback, including audio Twilio
|
|
423
|
+
* has already buffered. The call controller invokes this when it
|
|
424
|
+
* aborts an in-flight turn so speech the aborted turn queued for
|
|
425
|
+
* synthesis never plays over the next turn.
|
|
426
|
+
*/
|
|
427
|
+
cancelPendingSpeech(): void {
|
|
428
|
+
this.clearAudio();
|
|
192
429
|
}
|
|
193
430
|
|
|
194
431
|
/**
|
|
@@ -197,7 +434,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
197
434
|
* closes.
|
|
198
435
|
*/
|
|
199
436
|
endSession(reason?: string): void {
|
|
200
|
-
if (this.state === "closed")
|
|
437
|
+
if (this.state === "closed") {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
201
440
|
this.state = "closed";
|
|
202
441
|
|
|
203
442
|
// Cancel any in-flight playback
|
|
@@ -224,7 +463,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
224
463
|
* Send a base64-encoded audio frame to Twilio for playback.
|
|
225
464
|
*/
|
|
226
465
|
sendAudioPayload(base64Payload: string): void {
|
|
227
|
-
if (this.state === "closed")
|
|
466
|
+
if (this.state === "closed") {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
228
469
|
|
|
229
470
|
const command: MediaStreamSendMediaCommand = {
|
|
230
471
|
event: "media",
|
|
@@ -249,7 +490,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
249
490
|
* back a `mark` event when the caller reaches this point in playback.
|
|
250
491
|
*/
|
|
251
492
|
sendMark(name: string): void {
|
|
252
|
-
if (this.state === "closed")
|
|
493
|
+
if (this.state === "closed") {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
253
496
|
|
|
254
497
|
const command: MediaStreamSendMarkCommand = {
|
|
255
498
|
event: "mark",
|
|
@@ -283,7 +526,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
283
526
|
* when it actually aborts the turn.
|
|
284
527
|
*/
|
|
285
528
|
clearAudio(): void {
|
|
286
|
-
if (this.state === "closed")
|
|
529
|
+
if (this.state === "closed") {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
287
532
|
|
|
288
533
|
// Flush our internal playback queue and abort in-flight work.
|
|
289
534
|
this.flushPlaybackQueue();
|
|
@@ -303,7 +548,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
303
548
|
* (initial greeting, setup handoff prompt) survives to play after.
|
|
304
549
|
*/
|
|
305
550
|
clearBufferedAudio(): void {
|
|
306
|
-
if (this.state === "closed")
|
|
551
|
+
if (this.state === "closed") {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
307
554
|
this.sendClearCommand();
|
|
308
555
|
}
|
|
309
556
|
|
|
@@ -397,7 +644,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
397
644
|
* before sending.
|
|
398
645
|
*/
|
|
399
646
|
private async drainPlaybackQueue(): Promise<void> {
|
|
400
|
-
if (this.draining)
|
|
647
|
+
if (this.draining) {
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
401
650
|
this.draining = true;
|
|
402
651
|
|
|
403
652
|
try {
|
|
@@ -425,7 +674,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
425
674
|
|
|
426
675
|
// If the playback version changed (clearAudio was called), stop
|
|
427
676
|
// processing stale items.
|
|
428
|
-
if (version !== this.playbackVersion)
|
|
677
|
+
if (version !== this.playbackVersion) {
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
429
680
|
}
|
|
430
681
|
} finally {
|
|
431
682
|
this.draining = false;
|
|
@@ -443,7 +694,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
443
694
|
* the one-shot audio-start signal before the first frame goes out.
|
|
444
695
|
*/
|
|
445
696
|
private sendFrames(frames: string[]): void {
|
|
446
|
-
if (frames.length === 0)
|
|
697
|
+
if (frames.length === 0) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
447
700
|
const audioStartCallback = this.audioStartCallback;
|
|
448
701
|
if (audioStartCallback) {
|
|
449
702
|
this.audioStartCallback = null;
|
|
@@ -456,7 +709,10 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
456
709
|
|
|
457
710
|
/**
|
|
458
711
|
* Synthesize text via the TTS provider and send resulting audio as
|
|
459
|
-
* mu-law frames.
|
|
712
|
+
* mu-law frames. PCM-capable providers are transcoded incrementally —
|
|
713
|
+
* each streamed chunk becomes frames as it arrives — while other
|
|
714
|
+
* providers accumulate into the whole-buffer conversion path. Falls
|
|
715
|
+
* back to a silent frame if synthesis fails.
|
|
460
716
|
*/
|
|
461
717
|
private async processSynthesizeItem(
|
|
462
718
|
text: string,
|
|
@@ -466,13 +722,11 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
466
722
|
this.activePlaybackAbort = abortController;
|
|
467
723
|
|
|
468
724
|
try {
|
|
469
|
-
|
|
470
|
-
await import("./resolve-call-tts-provider.js");
|
|
471
|
-
// Request WAV so audioBufferToFrames gets PCM it can transcode
|
|
725
|
+
// Request PCM so audioBufferToFrames gets raw PCM it can transcode
|
|
472
726
|
// to mu-law. Compressed formats (mp3, opus) would be sent as raw
|
|
473
727
|
// bytes and produce garbled audio.
|
|
474
728
|
const { provider, audioFormat } = await resolveCallTtsProvider({
|
|
475
|
-
|
|
729
|
+
requiresPcmAudio: true,
|
|
476
730
|
});
|
|
477
731
|
if (!provider) {
|
|
478
732
|
log.warn(
|
|
@@ -482,27 +736,83 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
482
736
|
return;
|
|
483
737
|
}
|
|
484
738
|
|
|
485
|
-
if (version !== this.playbackVersion || this.isClosed())
|
|
739
|
+
if (version !== this.playbackVersion || this.isClosed()) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
const isCurrent = (): boolean =>
|
|
744
|
+
version === this.playbackVersion && !this.isClosed();
|
|
745
|
+
|
|
746
|
+
// PCM-capable providers honour `outputFormat: "pcm"` at the requested
|
|
747
|
+
// sample rate, so their chunks can be transcoded to mu-law frames as
|
|
748
|
+
// they arrive. Other providers accumulate below and go through the
|
|
749
|
+
// whole-buffer content-type sniffing path.
|
|
750
|
+
const streamsPcm = provider.capabilities.supportedFormats.includes("pcm");
|
|
751
|
+
const bufferedChunks: Buffer[] = [];
|
|
752
|
+
|
|
753
|
+
const encoder = streamsPcm
|
|
754
|
+
? new IncrementalMulawFrameEncoder(
|
|
755
|
+
STREAMING_PCM_SAMPLE_RATE_HZ / TELEPHONY_SAMPLE_RATE_HZ,
|
|
756
|
+
(frames) => this.sendFrames(frames),
|
|
757
|
+
)
|
|
758
|
+
: null;
|
|
486
759
|
|
|
487
760
|
// Synthesize the text. Request PCM output so the media-stream
|
|
488
761
|
// transport receives raw samples it can transcode to mu-law.
|
|
489
762
|
// Providers that support it (e.g. ElevenLabs pcm_16000) will
|
|
490
763
|
// return raw PCM; others fall back to their default format and
|
|
491
764
|
// the content-type sniffing below handles the mismatch.
|
|
492
|
-
const result = await
|
|
765
|
+
const result = await synthesizeAndEmit({
|
|
766
|
+
provider,
|
|
493
767
|
text,
|
|
494
768
|
useCase: "phone-call",
|
|
495
769
|
outputFormat: "pcm",
|
|
770
|
+
sampleRateHz: STREAMING_PCM_SAMPLE_RATE_HZ,
|
|
496
771
|
signal: abortController.signal,
|
|
772
|
+
isCurrent,
|
|
773
|
+
onChunk: (chunk) => {
|
|
774
|
+
if (!encoder) {
|
|
775
|
+
bufferedChunks.push(chunk.audio);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
if (!isCurrent()) {
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
encoder.push(chunk.audio);
|
|
782
|
+
},
|
|
497
783
|
});
|
|
498
784
|
|
|
499
|
-
if (
|
|
785
|
+
if (!isCurrent()) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
if (encoder) {
|
|
790
|
+
if (encoder.pcmCarryBytes > 0) {
|
|
791
|
+
// A sub-sample tail is malformed provider output; decimation
|
|
792
|
+
// would drop it anyway.
|
|
793
|
+
log.debug(
|
|
794
|
+
{ streamSid: this.streamSid, carryBytes: encoder.pcmCarryBytes },
|
|
795
|
+
"Dropping sub-sample tail from PCM16 TTS stream",
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
// Flush the final partial frame — the whole-buffer path sends a
|
|
799
|
+
// short trailing frame the same way.
|
|
800
|
+
encoder.flush();
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// A stopped stream means partial audio; never send a truncated buffer.
|
|
805
|
+
if (result.stopped) {
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
500
808
|
|
|
501
809
|
// Derive the format from the provider's actual content type rather
|
|
502
810
|
// than the declared audioFormat. The declared format may not match
|
|
503
|
-
// reality (e.g.
|
|
504
|
-
//
|
|
505
|
-
|
|
811
|
+
// reality (e.g. requiresPcmAudio requests PCM but the provider
|
|
812
|
+
// returns mp3). For unknown content types, fall back to the declared
|
|
813
|
+
// format (PCM on this path — the bytes were requested as raw PCM,
|
|
814
|
+
// and audioBufferToFrames sniffs magic bytes as a safety net).
|
|
815
|
+
const actualFormat: CallAudioFormat =
|
|
506
816
|
result.contentType.includes("wav") ||
|
|
507
817
|
result.contentType.includes("x-wav")
|
|
508
818
|
? "wav"
|
|
@@ -515,8 +825,13 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
515
825
|
result.contentType.includes("x-raw")
|
|
516
826
|
? "pcm"
|
|
517
827
|
: audioFormat; // fall back to declared format for unknown types
|
|
518
|
-
const frames = this.audioBufferToFrames(
|
|
519
|
-
|
|
828
|
+
const frames = this.audioBufferToFrames(
|
|
829
|
+
Buffer.concat(bufferedChunks),
|
|
830
|
+
actualFormat,
|
|
831
|
+
);
|
|
832
|
+
if (!isCurrent()) {
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
520
835
|
|
|
521
836
|
this.sendFrames(frames);
|
|
522
837
|
} catch (err) {
|
|
@@ -541,6 +856,13 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
541
856
|
/**
|
|
542
857
|
* Fetch audio from a URL (typically the audio store), transcode to
|
|
543
858
|
* mu-law frames, and send to Twilio.
|
|
859
|
+
*
|
|
860
|
+
* WAV and raw-PCM bodies are transcoded incrementally — the first frame
|
|
861
|
+
* goes out as soon as enough bytes arrive, which matters for
|
|
862
|
+
* synthesized-play segments whose store entry fills only as fast as the
|
|
863
|
+
* provider synthesizes. Compressed and unknown formats (and bodies the
|
|
864
|
+
* incremental encoder cannot transcode exactly) buffer the whole
|
|
865
|
+
* response and use the buffered conversion path.
|
|
544
866
|
*/
|
|
545
867
|
private async processFetchUrlItem(
|
|
546
868
|
url: string,
|
|
@@ -559,13 +881,13 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
559
881
|
return;
|
|
560
882
|
}
|
|
561
883
|
|
|
562
|
-
if (version !== this.playbackVersion || this.isClosed())
|
|
884
|
+
if (version !== this.playbackVersion || this.isClosed()) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
563
887
|
|
|
564
|
-
const buffer = Buffer.from(await response.arrayBuffer());
|
|
565
|
-
if (version !== this.playbackVersion || this.isClosed()) return;
|
|
566
888
|
|
|
567
889
|
const contentType = response.headers.get("content-type") ?? "audio/mpeg";
|
|
568
|
-
const format:
|
|
890
|
+
const format: CallAudioFormat = contentType.includes("wav")
|
|
569
891
|
? "wav"
|
|
570
892
|
: contentType.includes("opus")
|
|
571
893
|
? "opus"
|
|
@@ -573,9 +895,28 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
573
895
|
? "pcm"
|
|
574
896
|
: "mp3";
|
|
575
897
|
|
|
576
|
-
|
|
898
|
+
let buffer: Buffer;
|
|
899
|
+
if ((format === "wav" || format === "pcm") && response.body) {
|
|
900
|
+
const result = await this.streamBodyToFrames(
|
|
901
|
+
response.body,
|
|
902
|
+
format,
|
|
903
|
+
version,
|
|
904
|
+
abortController.signal,
|
|
905
|
+
);
|
|
906
|
+
if (result.outcome !== "fallback") return;
|
|
907
|
+
// The body could not be transcoded incrementally and was drained
|
|
908
|
+
// instead; transcode it through the whole-buffer path.
|
|
909
|
+
buffer = result.buffered;
|
|
910
|
+
} else {
|
|
911
|
+
buffer = Buffer.from(await response.arrayBuffer());
|
|
912
|
+
}
|
|
577
913
|
if (version !== this.playbackVersion || this.isClosed()) return;
|
|
578
914
|
|
|
915
|
+
const frames = this.audioBufferToFrames(buffer, format);
|
|
916
|
+
if (version !== this.playbackVersion || this.isClosed()) {
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
|
|
579
920
|
this.sendFrames(frames);
|
|
580
921
|
} catch (err) {
|
|
581
922
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
@@ -596,14 +937,90 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
596
937
|
}
|
|
597
938
|
}
|
|
598
939
|
|
|
940
|
+
/**
|
|
941
|
+
* Incrementally read a WAV or raw-PCM response body, sending mu-law
|
|
942
|
+
* frames as they fill so playback starts before the body completes.
|
|
943
|
+
*
|
|
944
|
+
* Streams only what {@link sniffStreamableHeader} accepts; on any other
|
|
945
|
+
* input the remaining body is drained and returned so the caller can
|
|
946
|
+
* run the whole-buffer path, keeping output byte-identical to the
|
|
947
|
+
* buffered transcode in every case.
|
|
948
|
+
*
|
|
949
|
+
* Aborting `signal` (clearAudio / cancelPendingSpeech) cancels the
|
|
950
|
+
* reader, which settles an in-flight read so the loop exits promptly.
|
|
951
|
+
*/
|
|
952
|
+
private async streamBodyToFrames(
|
|
953
|
+
body: ReadableStream<Uint8Array>,
|
|
954
|
+
format: "wav" | "pcm",
|
|
955
|
+
version: number,
|
|
956
|
+
signal: AbortSignal,
|
|
957
|
+
): Promise<BodyStreamResult> {
|
|
958
|
+
const reader = body.getReader();
|
|
959
|
+
const onAbort = (): void => {
|
|
960
|
+
reader.cancel().catch(() => {});
|
|
961
|
+
};
|
|
962
|
+
signal.addEventListener("abort", onAbort);
|
|
963
|
+
const isCurrent = (): boolean =>
|
|
964
|
+
version === this.playbackVersion && !this.isClosed() && !signal.aborted;
|
|
965
|
+
|
|
966
|
+
try {
|
|
967
|
+
let encoder: IncrementalMulawFrameEncoder | null = null;
|
|
968
|
+
// Bytes accumulated while sniffing the header, before streaming starts.
|
|
969
|
+
let pending: Buffer = Buffer.alloc(0);
|
|
970
|
+
|
|
971
|
+
for (;;) {
|
|
972
|
+
const { done, value } = await reader.read();
|
|
973
|
+
if (!isCurrent()) return { outcome: "aborted" };
|
|
974
|
+
if (done || !value) break;
|
|
975
|
+
let chunk = viewToBuffer(value);
|
|
976
|
+
|
|
977
|
+
if (!encoder) {
|
|
978
|
+
pending =
|
|
979
|
+
pending.length > 0 ? Buffer.concat([pending, chunk]) : chunk;
|
|
980
|
+
const decision = sniffStreamableHeader(pending, format);
|
|
981
|
+
if (decision.kind === "need-more-bytes") continue;
|
|
982
|
+
if (decision.kind === "fallback") {
|
|
983
|
+
const rest: Buffer[] = [pending];
|
|
984
|
+
for (;;) {
|
|
985
|
+
const next = await reader.read();
|
|
986
|
+
if (!isCurrent()) return { outcome: "aborted" };
|
|
987
|
+
if (next.done || !next.value) break;
|
|
988
|
+
rest.push(viewToBuffer(next.value));
|
|
989
|
+
}
|
|
990
|
+
return { outcome: "fallback", buffered: Buffer.concat(rest) };
|
|
991
|
+
}
|
|
992
|
+
encoder = new IncrementalMulawFrameEncoder(
|
|
993
|
+
decision.decimationFactor,
|
|
994
|
+
(frames) => this.sendFrames(frames),
|
|
995
|
+
);
|
|
996
|
+
chunk = pending.subarray(decision.payloadOffset);
|
|
997
|
+
if (chunk.length === 0) continue;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
encoder.push(chunk);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
if (!encoder) {
|
|
1004
|
+
// The body ended before the header could be sniffed; the
|
|
1005
|
+
// whole-buffer path handles undersized buffers.
|
|
1006
|
+
return { outcome: "fallback", buffered: pending };
|
|
1007
|
+
}
|
|
1008
|
+
encoder.flush();
|
|
1009
|
+
return { outcome: "streamed" };
|
|
1010
|
+
} finally {
|
|
1011
|
+
signal.removeEventListener("abort", onAbort);
|
|
1012
|
+
reader.releaseLock();
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
599
1016
|
/**
|
|
600
1017
|
* Convert an audio buffer (from TTS synthesis or URL fetch) into
|
|
601
1018
|
* base64-encoded mu-law frames.
|
|
602
1019
|
*
|
|
603
1020
|
* Rather than trusting the declared `format` parameter (which may not
|
|
604
|
-
* match the actual bytes — e.g.
|
|
605
|
-
*
|
|
606
|
-
* real format:
|
|
1021
|
+
* match the actual bytes — e.g. the declared format may be pcm while
|
|
1022
|
+
* the provider returned mp3), this method **sniffs the magic bytes**
|
|
1023
|
+
* to detect the real format:
|
|
607
1024
|
*
|
|
608
1025
|
* - **WAV** (`RIFF` header, bytes `0x52 0x49 0x46 0x46`): extracts
|
|
609
1026
|
* raw PCM data from the WAV container, converts it to 8 kHz using the
|
|
@@ -617,16 +1034,10 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
617
1034
|
*/
|
|
618
1035
|
private audioBufferToFrames(
|
|
619
1036
|
audio: Buffer,
|
|
620
|
-
format:
|
|
1037
|
+
format: CallAudioFormat,
|
|
621
1038
|
): string[] {
|
|
622
1039
|
// Sniff the actual bytes rather than trusting the declared format.
|
|
623
|
-
|
|
624
|
-
const isWav =
|
|
625
|
-
audio.length >= 44 &&
|
|
626
|
-
audio[0] === 0x52 && // R
|
|
627
|
-
audio[1] === 0x49 && // I
|
|
628
|
-
audio[2] === 0x46 && // F
|
|
629
|
-
audio[3] === 0x46; // F
|
|
1040
|
+
const isWav = audio.length >= WAV_HEADER_BYTES && hasRiffMagic(audio);
|
|
630
1041
|
|
|
631
1042
|
if (isWav) {
|
|
632
1043
|
// Extract raw PCM from the WAV container, honoring the fmt-chunk
|
|
@@ -635,8 +1046,10 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
635
1046
|
const channels = audio.readUInt16LE(22);
|
|
636
1047
|
const sampleRate = audio.readUInt32LE(24);
|
|
637
1048
|
const bitsPerSample = audio.readUInt16LE(34);
|
|
638
|
-
let pcmData: Buffer = audio.subarray(
|
|
639
|
-
if (pcmData.length < 2)
|
|
1049
|
+
let pcmData: Buffer = audio.subarray(WAV_HEADER_BYTES);
|
|
1050
|
+
if (pcmData.length < 2) {
|
|
1051
|
+
return [];
|
|
1052
|
+
}
|
|
640
1053
|
|
|
641
1054
|
if (bitsPerSample !== 16 || channels > 2 || channels === 0) {
|
|
642
1055
|
// Limitation: only 16-bit mono/stereo PCM is decoded here.
|
|
@@ -657,8 +1070,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
657
1070
|
|
|
658
1071
|
// When the declared format is "wav" but the RIFF check failed, the
|
|
659
1072
|
// bytes might be either:
|
|
660
|
-
// (a) Raw PCM
|
|
661
|
-
//
|
|
1073
|
+
// (a) Raw PCM served under a wav content-type (declared "wav" only
|
|
1074
|
+
// arrives via content-type sniffing; some providers label raw
|
|
1075
|
+
// PCM streams audio/wav)
|
|
662
1076
|
// (b) Compressed audio (mp3/opus) from a provider that ignores
|
|
663
1077
|
// outputFormat (e.g. Fish Audio defaults to mp3)
|
|
664
1078
|
//
|
|
@@ -701,7 +1115,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
701
1115
|
// ElevenLabs pcm_16000 produces 16-bit signed LE at 16 kHz. Twilio
|
|
702
1116
|
// needs 8 kHz mu-law, so we downsample by taking every other sample.
|
|
703
1117
|
if (format === "pcm" || format === "wav") {
|
|
704
|
-
if (audio.length < 2)
|
|
1118
|
+
if (audio.length < 2) {
|
|
1119
|
+
return [];
|
|
1120
|
+
}
|
|
705
1121
|
// Headerless PCM carries no declared rate; assume the 16 kHz that
|
|
706
1122
|
// ElevenLabs pcm_16000 produces and downsample to 8 kHz.
|
|
707
1123
|
const downsampled = decimatePcm16(audio, 2);
|
|
@@ -750,7 +1166,9 @@ export class MediaStreamOutput implements CallTransport {
|
|
|
750
1166
|
* assumption with a warning.
|
|
751
1167
|
*/
|
|
752
1168
|
private pcm16ToTelephonyRate(pcm: Buffer, sampleRate: number): Buffer {
|
|
753
|
-
if (sampleRate === TELEPHONY_SAMPLE_RATE_HZ)
|
|
1169
|
+
if (sampleRate === TELEPHONY_SAMPLE_RATE_HZ) {
|
|
1170
|
+
return pcm;
|
|
1171
|
+
}
|
|
754
1172
|
if (!Number.isFinite(sampleRate) || sampleRate <= 0) {
|
|
755
1173
|
log.warn(
|
|
756
1174
|
{ streamSid: this.streamSid, sampleRate },
|