@vellumai/assistant 0.11.2 → 0.11.3-dev.202608080427.92f668a
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/ARCHITECTURE.md +69 -9
- package/docs/flux-turn-detection-spike.md +243 -0
- package/docs/stt-provider-onboarding.md +3 -1
- package/docs/trusted-contact-access.md +9 -5
- package/docs/vellum-doctor.md +195 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +50 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +19 -2
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/__tests__/cloud-assistant-hub-url.test.ts +38 -0
- package/node_modules/@vellumai/environments/src/__tests__/install-layout.test.ts +98 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +5 -5
- package/node_modules/@vellumai/environments/src/index.ts +17 -6
- package/node_modules/@vellumai/environments/src/install-layout.ts +49 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +29 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +50 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +91 -6
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.test.ts +36 -0
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.ts +142 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +2 -0
- package/node_modules/@vellumai/ipc-server-utils/src/listen-options.ts +3 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +15 -1
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +17 -2
- package/node_modules/@vellumai/service-contracts/src/channels.ts +50 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +16 -2
- package/openapi.yaml +619 -47
- package/package.json +1 -1
- package/scripts/voice-ttft-spike.ts +3 -3
- package/src/__tests__/agent-image-optimize.test.ts +4 -4
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +113 -66
- package/src/__tests__/agent-loop-override-profile.test.ts +38 -48
- package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +166 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/answered-question-persistence.test.ts +240 -0
- package/src/__tests__/anthropic-provider.test.ts +165 -30
- package/src/__tests__/app-control-flow.test.ts +9 -8
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +16 -12
- package/src/__tests__/attachments-store.test.ts +130 -68
- package/src/__tests__/attachments.test.ts +36 -36
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/call-controller.test.ts +120 -0
- package/src/__tests__/call-start-guardian-guard.test.ts +18 -4
- package/src/__tests__/canned-reply-release.test.ts +86 -0
- package/src/__tests__/channel-availability-routes.test.ts +14 -1
- package/src/__tests__/channel-guardian.test.ts +59 -29
- package/src/__tests__/channel-readiness-telegram-remote.test.ts +154 -0
- package/src/__tests__/channel-setup-panel-ack.test.ts +6 -5
- package/src/__tests__/client-os-metadata-persistence.test.ts +103 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/config-loader-backfill.test.ts +19 -0
- package/src/__tests__/config-schema.test.ts +150 -7
- package/src/__tests__/consult-deadline.test.ts +65 -0
- package/src/__tests__/conversation-agent-loop.test.ts +438 -2
- package/src/__tests__/conversation-disk-view-integration.test.ts +5 -1
- package/src/__tests__/conversation-disk-view.test.ts +4 -4
- package/src/__tests__/conversation-error.test.ts +22 -3
- package/src/__tests__/conversation-fork-crud.test.ts +5 -1
- package/src/__tests__/conversation-fork-referential.test.ts +352 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +5 -1
- package/src/__tests__/conversation-group-tools.test.ts +32 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +27 -1
- package/src/__tests__/conversation-initial-prompt.test.ts +51 -22
- package/src/__tests__/conversation-key-store-bootstrap-cleanup.test.ts +119 -0
- package/src/__tests__/conversation-key-store-origin.test.ts +105 -0
- package/src/__tests__/conversation-list-recency-ordering.test.ts +104 -0
- package/src/__tests__/conversation-origin-at-creation.test.ts +153 -0
- package/src/__tests__/conversation-origin-channel-filter.test.ts +95 -0
- package/src/__tests__/conversation-placement-promotion.test.ts +172 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +123 -0
- package/src/__tests__/conversation-queue.test.ts +433 -1
- package/src/__tests__/conversation-retry-route.test.ts +3 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +64 -1
- package/src/__tests__/conversation-store-ephemeral.test.ts +4 -0
- package/src/__tests__/conversation-store.test.ts +26 -10
- package/src/__tests__/conversation-summarize-route.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +15 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-app-control.test.ts +12 -11
- package/src/__tests__/conversation-surfaces-app-open.test.ts +11 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +5 -4
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +967 -0
- package/src/__tests__/conversation-surfaces-persisted-info.test.ts +312 -0
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -8
- package/src/__tests__/conversation-surfaces-standalone.test.ts +21 -11
- package/src/__tests__/conversation-surfaces-state-update.test.ts +7 -11
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -6
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +11 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -6
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +70 -7
- package/src/__tests__/conversation-wait-for-idle.test.ts +6 -11
- package/src/__tests__/credential-prompt-route.test.ts +54 -7
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +89 -28
- package/src/__tests__/custom-group-listing-visibility.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +366 -0
- package/src/__tests__/discord-requester-notice-privacy.test.ts +87 -0
- package/src/__tests__/disk-pressure-guard.test.ts +55 -55
- package/src/__tests__/disk-pressure-routes.test.ts +10 -10
- package/src/__tests__/disk-pressure-tools.test.ts +2 -2
- package/src/__tests__/disk-usage.test.ts +35 -20
- package/src/__tests__/document-sync-tags.test.ts +379 -0
- package/src/__tests__/document-update-default-surface.test.ts +28 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +2 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -4
- package/src/__tests__/ensure-conversation-exists.test.ts +8 -5
- package/src/__tests__/events-dev-bypass-actor.test.ts +294 -1
- package/src/__tests__/evict-conversations-for-reload.test.ts +90 -0
- package/src/__tests__/file-list-tool.test.ts +12 -10
- package/src/__tests__/file-ops-service.test.ts +151 -44
- package/src/__tests__/file-read-container-boundary.test.ts +137 -0
- package/src/__tests__/file-read-tool.test.ts +21 -9
- package/src/__tests__/file-url-path-guard.test.ts +83 -0
- package/src/__tests__/filesystem-tools.test.ts +82 -66
- package/src/__tests__/guardian-outbound-http.test.ts +8 -8
- package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +14 -1
- package/src/__tests__/helpers/hub-clients.ts +42 -0
- package/src/__tests__/helpers/mock-conversation.ts +46 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +61 -57
- package/src/__tests__/history-repair.test.ts +112 -12
- package/src/__tests__/host-bash-proxy.test.ts +10 -5
- package/src/__tests__/host-bash-routes.test.ts +67 -0
- package/src/__tests__/host-browser-proxy.test.ts +2 -2
- package/src/__tests__/host-cu-proxy.test.ts +3 -7
- package/src/__tests__/host-file-proxy.test.ts +3 -7
- package/src/__tests__/host-file-read-tool.test.ts +5 -1
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +6 -4
- package/src/__tests__/http-conversation-lineage.test.ts +2 -5
- package/src/__tests__/http-user-message-parity.test.ts +44 -0
- package/src/__tests__/identity-routes.test.ts +13 -13
- package/src/__tests__/image-conversion.test.ts +29 -26
- package/src/__tests__/image-source-path-reinject.test.ts +2 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +95 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +25 -0
- package/src/__tests__/introduction-card-resolver.test.ts +6 -1
- package/src/__tests__/list-messages-attachments.test.ts +56 -32
- package/src/__tests__/list-messages-background-tool-completion.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +2 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +16 -16
- package/src/__tests__/list-messages-page-latest.test.ts +61 -61
- package/src/__tests__/list-messages-provider-error.test.ts +6 -6
- package/src/__tests__/list-messages-queued.test.ts +49 -6
- package/src/__tests__/list-messages-system-card.test.ts +4 -4
- package/src/__tests__/list-messages-tool-merge.test.ts +9 -9
- package/src/__tests__/llm-resolver-override-or-default.test.ts +141 -0
- package/src/__tests__/llm-usage-store.test.ts +55 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +45 -0
- package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
- package/src/__tests__/media-stream-output.test.ts +175 -0
- package/src/__tests__/media-stream-server-integration.test.ts +36 -0
- package/src/__tests__/media-stream-stt-session.test.ts +67 -0
- package/src/__tests__/migration-export-http.test.ts +1 -1
- package/src/__tests__/migration-import-commit-http.test.ts +1 -1
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -1
- package/src/__tests__/migration-validate-http.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +65 -3
- package/src/__tests__/notification-platform-adapter.test.ts +104 -0
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +4 -2
- package/src/__tests__/oauth-provider-seed-logos.test.ts +65 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +17 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +5 -2
- package/src/__tests__/path-policy.test.ts +164 -1
- package/src/__tests__/persist-media-references.test.ts +2 -2
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +5 -5
- package/src/__tests__/persist-unsendable-image.test.ts +23 -23
- package/src/__tests__/persona-resolver.test.ts +154 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +170 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +6 -0
- package/src/__tests__/processing-flag-persist-failure.test.ts +15 -10
- package/src/__tests__/profile-availability-incomplete.test.ts +113 -0
- package/src/__tests__/profiler-routes.test.ts +13 -13
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +593 -0
- package/src/__tests__/proxy-approval-callback.test.ts +3 -3
- package/src/__tests__/queued-message-cancel-and-steer.test.ts +189 -0
- package/src/__tests__/queued-message-steer-actor-scoping.test.ts +164 -0
- package/src/__tests__/resolve-trust-class.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +174 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +15 -7
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +166 -0
- package/src/__tests__/schedule-routes.test.ts +730 -8
- package/src/__tests__/schedule-store.test.ts +540 -0
- package/src/__tests__/schedule-tools.test.ts +103 -0
- package/src/__tests__/scheduler-wake.test.ts +5 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +29 -1
- package/src/__tests__/secure-keys.test.ts +91 -0
- package/src/__tests__/server-history-render.test.ts +97 -7
- package/src/__tests__/size-guard.test.ts +8 -8
- package/src/__tests__/skill-docs-sync-guard.test.ts +3 -2
- package/src/__tests__/skill-tool-factory.test.ts +247 -0
- package/src/__tests__/skills-install-staging.test.ts +15 -6
- package/src/__tests__/skills.test.ts +32 -0
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +103 -0
- package/src/__tests__/slack-inbound-verification.test.ts +4 -1
- package/src/__tests__/slack-mention-binding-invariance.test.ts +103 -0
- package/src/__tests__/slack-mention-provider-leak-audit.test.ts +135 -0
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/steer-on-enqueue-question.test.ts +3 -2
- package/src/__tests__/stt-language-catalog-parity.test.ts +38 -0
- package/src/__tests__/subagent-allowlist-validation.test.ts +26 -4
- package/src/__tests__/subagent-cron-run-attribution.test.ts +301 -0
- package/src/__tests__/subagent-disposal.test.ts +10 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +10 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +85 -11
- package/src/__tests__/subagent-fork-spawn.test.ts +15 -7
- package/src/__tests__/subagent-manager-notify.test.ts +148 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/subagent-persistence.test.ts +141 -0
- package/src/__tests__/subagent-role-registry.test.ts +172 -63
- package/src/__tests__/subagent-role-resolution.test.ts +88 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +48 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +111 -10
- package/src/__tests__/subagent-terminal-message.test.ts +88 -1
- package/src/__tests__/subagent-tool-gate-mode.test.ts +225 -10
- package/src/__tests__/subagent-tools.test.ts +1901 -108
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +124 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +298 -0
- package/src/__tests__/system-prompt.test.ts +82 -7
- package/src/__tests__/tool-grant-request-escalation.test.ts +40 -1
- package/src/__tests__/tool-result-spool.test.ts +74 -18
- package/src/__tests__/tool-side-effects-documents.test.ts +174 -0
- package/src/__tests__/tool-side-effects-hook-failures.test.ts +129 -0
- package/src/__tests__/tools-audio-read.test.ts +10 -10
- package/src/__tests__/tools-get-route.test.ts +85 -12
- package/src/__tests__/tools-list-cli.test.ts +171 -0
- package/src/__tests__/top-level-renderer.test.ts +54 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +68 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -1
- package/src/__tests__/turn-tail-chain.test.ts +135 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +6 -4
- package/src/__tests__/ui-visual-surface.test.ts +5 -4
- package/src/__tests__/ui-work-result-surface.test.ts +5 -4
- package/src/__tests__/unified-turn-context-visible-app.test.ts +7 -8
- package/src/__tests__/usage-routes.test.ts +62 -0
- package/src/__tests__/verification-outbound-delivery.test.ts +176 -0
- package/src/__tests__/visible-app-context.test.ts +20 -4
- package/src/__tests__/web-search-history.test.ts +96 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +6 -6
- package/src/__tests__/workspace-migration-140-repair-seed-pinned-memory-v3-live.test.ts +330 -0
- package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +150 -0
- package/src/acp/failure-error.ts +3 -5
- package/src/agent/attachments.ts +26 -24
- package/src/agent/history-repair/history-repair.ts +27 -26
- package/src/agent/image-optimize.ts +6 -6
- package/src/agent/loop.ts +40 -22
- package/src/agent/message-types.ts +3 -3
- package/src/api/constants/document-tools.ts +55 -0
- package/src/api/events/question-answered.ts +53 -0
- package/src/api/events/tool-result.ts +7 -0
- package/src/api/index.ts +13 -0
- package/src/api/responses/conversation-message.ts +11 -0
- package/src/api/surfaces-oauth-connect.test.ts +96 -0
- package/src/api/surfaces.ts +36 -8
- package/src/approvals/guardian-channel-delivery.ts +83 -0
- package/src/approvals/guardian-expiry-notifier.ts +13 -11
- package/src/approvals/guardian-request-resolvers.ts +222 -135
- package/src/calls/__tests__/tts-text-sanitizer.test.ts +13 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +131 -12
- package/src/calls/__tests__/voice-triage-escalate.test.ts +106 -0
- package/src/calls/call-controller.ts +30 -2
- package/src/calls/call-speech-output.ts +12 -4
- package/src/calls/call-transport.ts +18 -1
- package/src/calls/media-stream-output.ts +53 -5
- package/src/calls/media-stream-server.ts +21 -1
- package/src/calls/media-stream-stt-session.ts +49 -0
- package/src/calls/telephony-synthesis-language.ts +84 -0
- package/src/calls/tts-text-sanitizer.ts +12 -5
- package/src/calls/voice-session-bridge.ts +86 -17
- package/src/calls/voice-triage-escalate.ts +54 -7
- package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
- package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
- package/src/channels/config.ts +20 -2
- package/src/channels/gateway-verification-sessions.ts +7 -2
- package/src/channels/plugin-channel-declarations.ts +108 -0
- package/src/channels/types.ts +37 -1
- package/src/cli/AGENTS.md +5 -2
- package/src/cli/commands/__tests__/cache.test.ts +7 -4
- package/src/cli/commands/__tests__/cli-test-harness.ts +82 -0
- package/src/cli/commands/__tests__/conversations-wake.test.ts +51 -6
- package/src/cli/commands/__tests__/inference-models.test.ts +14 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +44 -1
- package/src/cli/commands/__tests__/inference-providers.test.ts +7 -0
- package/src/cli/commands/__tests__/plugins.test.ts +692 -0
- package/src/cli/commands/__tests__/schedules.test.ts +136 -37
- package/src/cli/commands/conversations.ts +7 -3
- package/src/cli/commands/credentials.help.ts +7 -0
- package/src/cli/commands/inference-profiles.ts +9 -3
- package/src/cli/commands/inference.help.ts +16 -2
- package/src/cli/commands/mcp.help.ts +17 -6
- package/src/cli/commands/mcp.ts +9 -0
- package/src/cli/commands/memory/memory-retrospective.ts +18 -0
- package/src/cli/commands/notifications.ts +3 -6
- package/src/cli/commands/oauth/connect-surface-guidance.test.ts +16 -0
- package/src/cli/commands/oauth/connect-surface-guidance.ts +25 -7
- package/src/cli/commands/oauth/connect.test.ts +26 -1
- package/src/cli/commands/oauth/connect.ts +4 -1
- package/src/cli/commands/oauth/index.help.ts +3 -1
- package/src/cli/commands/oauth/providers.ts +3 -0
- package/src/cli/commands/plugins.help.ts +25 -2
- package/src/cli/commands/plugins.ts +289 -10
- package/src/cli/commands/schedules.help.ts +14 -12
- package/src/cli/commands/schedules.ts +19 -5
- package/src/cli/commands/stt.help.ts +27 -2
- package/src/cli/commands/tools.help.ts +4 -2
- package/src/cli/commands/tools.ts +38 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +79 -0
- package/src/cli/lib/__tests__/install-from-platform.test.ts +47 -1
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +86 -7
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +161 -0
- package/src/cli/lib/install-from-github.ts +61 -0
- package/src/cli/lib/install-from-platform.ts +13 -2
- package/src/cli/lib/plugin-surfaces.ts +124 -4
- package/src/cli/lib/upgrade-plugin.ts +60 -0
- package/src/cli.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +11 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +73 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +40 -0
- package/src/config/__tests__/plugin-updates-schema.test.ts +43 -0
- package/src/config/__tests__/profile-tool-support.test.ts +131 -0
- package/src/config/bundled-skills/AGENTS.md +1 -1
- package/src/config/bundled-skills/acp/SKILL.md +6 -7
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +3 -3
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +15 -15
- package/src/config/bundled-skills/schedule/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +53 -22
- package/src/config/bundled-skills/subagent/TOOLS.json +14 -13
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
- package/src/config/bundled-skills/visualize/SKILL.md +1 -1
- package/src/config/call-site-defaults.ts +4 -5
- package/src/config/default-profile-catalog.ts +9 -5
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +45 -15
- package/src/config/loader.ts +75 -1
- package/src/config/profile-tool-support.ts +110 -0
- package/src/config/sanitize-for-transfer.ts +11 -0
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/live-voice.test.ts +142 -4
- package/src/config/schemas/__tests__/stt.test.ts +20 -5
- package/src/config/schemas/call-site-catalog.ts +4 -4
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/channels.ts +13 -0
- package/src/config/schemas/live-voice.ts +82 -23
- package/src/config/schemas/llm.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +25 -0
- package/src/config/schemas/plugin-updates.ts +59 -0
- package/src/config/schemas/services.ts +8 -4
- package/src/config/schemas/stt.ts +18 -5
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/schemas/tts.ts +63 -0
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +16 -0
- package/src/contacts/guardian-delivery-reader.ts +29 -2
- package/src/context/compactor.ts +4 -4
- package/src/context/post-turn-tool-result-truncation.ts +32 -16
- package/src/context/strip-injections.ts +42 -0
- package/src/context/tool-result-spool.ts +32 -18
- package/src/credential-execution/ces-runtime.ts +3 -0
- package/src/credential-execution/client.ts +22 -1
- package/src/credential-execution/process-manager.test.ts +99 -0
- package/src/credential-execution/process-manager.ts +62 -16
- package/src/daemon/__tests__/abort-null-controller.test.ts +141 -5
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +8 -12
- package/src/daemon/__tests__/install-assistant-command.test.ts +234 -0
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +2 -4
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +20 -29
- package/src/daemon/channel-ui-capability.ts +4 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +117 -61
- package/src/daemon/conversation-agent-loop.ts +318 -148
- package/src/daemon/conversation-attachments.ts +1 -1
- package/src/daemon/conversation-error.ts +8 -1
- package/src/daemon/conversation-initial-prompt.ts +16 -38
- package/src/daemon/conversation-lifecycle.ts +154 -32
- package/src/daemon/conversation-messaging.ts +106 -43
- package/src/daemon/conversation-process.ts +131 -33
- package/src/daemon/conversation-queue-manager.ts +10 -0
- package/src/daemon/conversation-runtime-assembly.ts +9 -4
- package/src/daemon/conversation-store.ts +52 -3
- package/src/daemon/conversation-surface-state.ts +9 -0
- package/src/daemon/conversation-surfaces.ts +403 -210
- package/src/daemon/conversation-tool-setup.ts +56 -7
- package/src/daemon/conversation-turn-finalize.ts +134 -89
- package/src/daemon/conversation.ts +111 -27
- package/src/daemon/disk-pressure-guard-lifecycle.ts +2 -2
- package/src/daemon/disk-pressure-guard.ts +3 -3
- package/src/daemon/doordash-steps.ts +5 -5
- package/src/daemon/external-plugins-bootstrap.ts +7 -1
- package/src/daemon/handlers/config-channels.ts +48 -5
- package/src/daemon/handlers/conversation-history.ts +1 -1
- package/src/daemon/handlers/conversations.ts +62 -17
- package/src/daemon/handlers/shared.ts +12 -0
- package/src/daemon/handlers/skills.ts +11 -1
- package/src/daemon/identity-helpers.ts +38 -10
- package/src/daemon/install-assistant-command.ts +322 -0
- package/src/daemon/lifecycle.ts +14 -3
- package/src/daemon/message-types/conversations.ts +6 -7
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/persist-media-references.ts +23 -14
- package/src/daemon/process-message.ts +6 -6
- package/src/daemon/tool-setup-types.ts +19 -122
- package/src/daemon/tool-side-effects.ts +17 -94
- package/src/daemon/trust-context-types.ts +39 -0
- package/src/daemon/trust-context.ts +14 -6
- package/src/daemon/turn-tail-chain.ts +73 -0
- package/src/daemon/web-search-history.ts +47 -33
- package/src/heartbeat/heartbeat-service.ts +6 -6
- package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
- package/src/inbound/oauth-callback-url.ts +61 -0
- package/src/ipc/__tests__/socket-path.test.ts +21 -0
- package/src/ipc/assistant-server.ts +17 -10
- package/src/ipc/cli-client.ts +10 -1
- package/src/ipc/routes/__tests__/documents-sync-ipc-routes.test.ts +56 -0
- package/src/ipc/routes/documents-sync-ipc-routes.ts +42 -0
- package/src/ipc/socket-cleanup.ts +9 -7
- package/src/ipc/socket-path.ts +4 -96
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
- package/src/live-voice/__tests__/live-voice-archive.test.ts +16 -16
- package/src/live-voice/__tests__/live-voice-attach-image.test.ts +209 -0
- package/src/live-voice/__tests__/live-voice-connection.test.ts +20 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +932 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +12 -5
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
- package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +179 -146
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +324 -2
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +131 -2
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
- package/src/live-voice/__tests__/live-voice-tts.test.ts +148 -2
- package/src/live-voice/__tests__/live-voice-vad.test.ts +313 -32
- package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
- package/src/live-voice/__tests__/progress-phrases.test.ts +167 -0
- package/src/live-voice/__tests__/protocol.test.ts +52 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +3 -0
- package/src/live-voice/live-voice-archive.ts +13 -13
- package/src/live-voice/live-voice-connection.ts +7 -1
- package/src/live-voice/live-voice-metrics.ts +57 -32
- package/src/live-voice/live-voice-photo.ts +168 -0
- package/src/live-voice/live-voice-session.ts +1137 -351
- package/src/live-voice/live-voice-tts.ts +18 -2
- package/src/live-voice/progress-narration.ts +277 -0
- package/src/live-voice/progress-phrases.ts +105 -2
- package/src/live-voice/protocol.ts +110 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +196 -0
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
- package/src/mcp/client.ts +14 -7
- package/src/mcp/mcp-auth-orchestrator.ts +13 -22
- package/src/mcp/mcp-oauth-provider.ts +195 -240
- package/src/messaging/providers/__tests__/callback-routing.test.ts +5 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +66 -4
- package/src/messaging/providers/callback-routing.ts +1 -0
- package/src/messaging/providers/discord/api.ts +312 -0
- package/src/messaging/providers/discord/dm-delivery.test.ts +204 -0
- package/src/messaging/providers/discord/render.test.ts +204 -0
- package/src/messaging/providers/discord/render.ts +195 -0
- package/src/messaging/providers/discord/send.test.ts +179 -0
- package/src/messaging/providers/discord/send.ts +212 -0
- package/src/messaging/providers/discord/transport.ts +81 -0
- package/src/messaging/providers/index.ts +3 -1
- package/src/messaging/providers/retry-policy.test.ts +247 -0
- package/src/messaging/providers/retry-policy.ts +206 -0
- package/src/messaging/providers/slack/mention-source.test.ts +285 -0
- package/src/messaging/providers/slack/mention-source.ts +287 -0
- package/src/messaging/providers/telegram-bot/api.ts +47 -130
- package/src/messaging/providers/whatsapp/api.ts +47 -136
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +4 -1
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +495 -0
- package/src/monitoring/db-integrity-sample.ts +6 -1
- package/src/monitoring/plugin-auto-update.ts +463 -0
- package/src/monitoring/resource-sampler.ts +21 -5
- package/src/monitoring/worker.ts +13 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +375 -2
- package/src/notifications/__tests__/broadcaster.test.ts +37 -1
- package/src/notifications/__tests__/copy-composer.test.ts +165 -0
- package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +205 -0
- package/src/notifications/__tests__/notification-utils.test.ts +249 -0
- package/src/notifications/adapters/platform.ts +31 -2
- package/src/notifications/assistant-reply-producer.ts +79 -32
- package/src/notifications/broadcaster.ts +30 -10
- package/src/notifications/copy-composer.ts +69 -0
- package/src/notifications/emit-signal.ts +82 -15
- package/src/notifications/events-store.ts +10 -2
- package/src/notifications/home-feed-side-effect.ts +6 -3
- package/src/notifications/notification-utils.ts +173 -5
- package/src/notifications/signal.ts +13 -0
- package/src/oauth/AGENTS.md +4 -2
- package/src/oauth/byo-connection.ts +6 -1
- package/src/oauth/credential-token-resolver.ts +3 -10
- package/src/oauth/manual-token-connection.ts +29 -64
- package/src/oauth/manual-token-providers.ts +62 -0
- package/src/oauth/provider-serializer.ts +13 -0
- package/src/oauth/seed-providers.ts +62 -11
- package/src/onboarding/onboarding-events-store.ts +91 -1
- package/src/permissions/question-prompter.test.ts +4 -0
- package/src/permissions/question-prompter.ts +21 -4
- package/src/persistence/__tests__/conversation-lineage.test.ts +248 -0
- package/src/persistence/attachments-store.ts +15 -15
- package/src/persistence/conversation-attention-store.ts +30 -10
- package/src/persistence/conversation-bootstrap.ts +17 -0
- package/src/persistence/conversation-crud.ts +363 -97
- package/src/persistence/conversation-group-migration.ts +1 -1
- package/src/persistence/conversation-key-store.ts +38 -10
- package/src/persistence/conversation-lineage.ts +226 -0
- package/src/persistence/conversation-plugin-facade.ts +28 -3
- package/src/persistence/conversation-queries.ts +207 -33
- package/src/persistence/conversation-types.ts +107 -1
- package/src/persistence/jobs-store.ts +32 -8
- package/src/persistence/llm-usage-store.ts +22 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +168 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +76 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.test.ts +187 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.ts +93 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.test.ts +229 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.ts +127 -0
- package/src/persistence/migrations/364-add-schedule-source-key.test.ts +120 -0
- package/src/persistence/migrations/364-add-schedule-source-key.ts +43 -0
- package/src/persistence/migrations/365-add-conversation-fork-strategy.ts +27 -0
- package/src/persistence/schema/conversations.ts +32 -0
- package/src/persistence/schema/infrastructure.ts +3 -0
- package/src/persistence/steps.ts +30 -0
- package/src/persistence/subagent-store.ts +148 -6
- package/src/platform/managed-speech.test.ts +20 -0
- package/src/platform/managed-speech.ts +9 -0
- package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
- package/src/plugin-api/index.ts +28 -5
- package/src/plugin-api/webhook-url.ts +151 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
- package/src/plugins/__tests__/mcp-servers.test.ts +370 -0
- package/src/plugins/__tests__/source-fingerprint.test.ts +5 -1
- package/src/plugins/collect-source-versions.ts +4 -27
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +5 -5
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +4 -2
- package/src/plugins/defaults/image-recovery/recover.ts +67 -57
- package/src/plugins/defaults/index.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +64 -18
- package/src/plugins/defaults/memory/__tests__/jobs-worker-outcome-contract.test.ts +242 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-retrospective-sweep.test.ts +24 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +48 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +511 -19
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +39 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +493 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +5 -4
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -1
- package/src/plugins/defaults/memory/job-handlers.ts +87 -5
- package/src/plugins/defaults/memory/jobs-worker.ts +60 -6
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +11 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +29 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +342 -60
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +23 -3
- package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +9 -4
- package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +7 -0
- package/src/plugins/defaults/memory/v1/graph/injection.ts +1 -1
- package/src/plugins/defaults/memory/v2/router.ts +8 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +1 -2
- package/src/plugins/external-plugin-loader.ts +64 -8
- package/src/plugins/installed-plugin-dirs.ts +101 -0
- package/src/plugins/mcp-servers.ts +343 -0
- package/src/plugins/mtime-cache.ts +34 -22
- package/src/plugins/types.ts +69 -8
- package/src/prompts/persona-resolver.ts +6 -2
- package/src/prompts/system-prompt.ts +72 -17
- package/src/providers/__tests__/inference.test.ts +40 -0
- package/src/providers/__tests__/preflight-resolved-config.test.ts +58 -1
- package/src/providers/__tests__/retry-callsite.test.ts +72 -2
- package/src/providers/__tests__/vellum-connection-routing.test.ts +42 -11
- package/src/providers/anthropic/client.ts +112 -95
- package/src/providers/connection-resolution.ts +35 -1
- package/src/providers/gemini/client.ts +5 -5
- package/src/providers/inference/adapter-factory.ts +16 -10
- package/src/providers/inference/auth.ts +16 -0
- package/src/providers/inference/connection-availability.ts +164 -12
- package/src/providers/inference/connections.ts +25 -1
- package/src/providers/media-resolve.ts +21 -11
- package/src/providers/model-catalog.ts +15 -0
- package/src/providers/openai/chat-completions-provider.ts +4 -4
- package/src/providers/openai/responses-provider.ts +12 -25
- package/src/providers/registry.ts +9 -4
- package/src/providers/retry.ts +25 -0
- package/src/providers/server-tool-pairing.ts +134 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +620 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +472 -12
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +719 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +283 -1
- package/src/providers/speech-to-text/deepgram-realtime.ts +117 -3
- package/src/providers/speech-to-text/deepgram.ts +1 -0
- package/src/providers/speech-to-text/provider-catalog.ts +137 -8
- package/src/providers/speech-to-text/resolve.ts +105 -12
- package/src/providers/speech-to-text/vellum-managed.ts +7 -1
- package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +3 -1
- package/src/providers/types.ts +26 -6
- package/src/providers/vellum-model-routing.ts +6 -7
- package/src/runtime/AGENTS.md +2 -0
- package/src/runtime/__tests__/agent-wake.test.ts +16 -16
- package/src/runtime/__tests__/background-job-runner.test.ts +0 -144
- package/src/runtime/__tests__/desktop-presence.test.ts +162 -0
- package/src/runtime/__tests__/local-actor-identity-force-refresh.test.ts +104 -0
- package/src/runtime/agent-wake.ts +63 -24
- package/src/runtime/assistant-event-hub.ts +110 -12
- package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -0
- package/src/runtime/auth/__tests__/scopes.test.ts +20 -0
- package/src/runtime/auth/same-actor.ts +56 -8
- package/src/runtime/auth/scopes.ts +12 -0
- package/src/runtime/auth/types.ts +2 -0
- package/src/runtime/background-job-runner.ts +5 -27
- package/src/runtime/channel-readiness-service.ts +59 -3
- package/src/runtime/channel-readiness-types.ts +18 -0
- package/src/runtime/desktop-presence.ts +69 -0
- package/src/runtime/http-server.ts +12 -0
- package/src/runtime/local-actor-identity.ts +29 -14
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/client-routes.test.ts +186 -14
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +547 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +162 -7
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +340 -3
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +28 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +217 -1
- package/src/runtime/routes/__tests__/question-routes.test.ts +64 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +20 -0
- package/src/runtime/routes/__tests__/skill-history-route.test.ts +116 -0
- package/src/runtime/routes/__tests__/sse-actor-principal-heal.test.ts +165 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +2 -0
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +60 -2
- package/src/runtime/routes/archive-utils.ts +16 -12
- package/src/runtime/routes/attachment-routes.ts +13 -6
- package/src/runtime/routes/canned-reply-release.ts +54 -0
- package/src/runtime/routes/channel-availability-routes.ts +32 -14
- package/src/runtime/routes/channel-verification-routes.ts +2 -27
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +5 -0
- package/src/runtime/routes/client-routes.ts +114 -2
- package/src/runtime/routes/conversation-cli-routes.ts +10 -12
- package/src/runtime/routes/conversation-list-routes.ts +59 -10
- package/src/runtime/routes/conversation-management-routes.ts +47 -18
- package/src/runtime/routes/conversation-query-routes.ts +32 -53
- package/src/runtime/routes/conversation-routes.ts +360 -293
- package/src/runtime/routes/credential-prompt-routes.ts +20 -2
- package/src/runtime/routes/debug-routes.ts +4 -1
- package/src/runtime/routes/default-provider-routes.ts +7 -11
- package/src/runtime/routes/documents-routes.ts +44 -1
- package/src/runtime/routes/events-routes.ts +29 -1
- package/src/runtime/routes/host-app-control-routes.ts +2 -0
- package/src/runtime/routes/host-bash-routes.ts +2 -0
- package/src/runtime/routes/host-browser-routes.ts +2 -0
- package/src/runtime/routes/host-cu-routes.ts +2 -0
- package/src/runtime/routes/host-file-routes.ts +2 -0
- package/src/runtime/routes/host-transfer-routes.ts +4 -0
- package/src/runtime/routes/identity-routes.ts +6 -6
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +14 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +14 -11
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -17
- package/src/runtime/routes/inference-profile-availability-guard.ts +171 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +26 -2
- package/src/runtime/routes/inference-profile-session-routes.ts +2 -1
- package/src/runtime/routes/inference-profiles-routes.ts +152 -73
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -16
- package/src/runtime/routes/llm-call-sites-routes.ts +13 -0
- package/src/runtime/routes/log-export-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +141 -57
- package/src/runtime/routes/notification-routes.ts +0 -14
- package/src/runtime/routes/oauth-providers.ts +1 -0
- package/src/runtime/routes/plugins-routes.ts +127 -4
- package/src/runtime/routes/profiler-routes.ts +4 -2
- package/src/runtime/routes/question-routes.ts +28 -10
- package/src/runtime/routes/retrospective-routes.ts +9 -3
- package/src/runtime/routes/schedule-routes.ts +210 -12
- package/src/runtime/routes/secret-routes.ts +40 -23
- package/src/runtime/routes/settings-routes.ts +41 -13
- package/src/runtime/routes/skills-routes.ts +79 -0
- package/src/runtime/routes/sse-actor-principal-heal.ts +113 -0
- package/src/runtime/routes/stt-routes.ts +31 -25
- package/src/runtime/routes/ui-snapshot-routes.ts +1 -0
- package/src/runtime/routes/wake-conversation-routes.ts +23 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +24 -9
- package/src/runtime/sync/documents-sidecar-publish.test.ts +101 -0
- package/src/runtime/sync/resource-sync-events.ts +79 -1
- package/src/runtime/sync/worker-daemon-notify.test.ts +34 -0
- package/src/runtime/sync/worker-daemon-notify.ts +44 -6
- package/src/runtime/verification-outbound-actions.ts +250 -222
- package/src/runtime/verification-templates.ts +41 -30
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +614 -0
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1066 -0
- package/src/schedule/inference-profile.ts +64 -3
- package/src/schedule/plugin-schedule-declarations.ts +518 -0
- package/src/schedule/plugin-schedule-reconciler.ts +605 -0
- package/src/schedule/plugin-schedules-gate.ts +23 -0
- package/src/schedule/schedule-store.ts +520 -26
- package/src/schedule/scheduler.ts +38 -0
- package/src/security/credential-backend.ts +51 -4
- package/src/security/encrypted-store.ts +64 -42
- package/src/security/oauth2.ts +6 -22
- package/src/security/secure-keys.ts +55 -7
- package/src/skills/catalog-install.ts +20 -7
- package/src/skills/inline-command-runner.ts +2 -7
- package/src/skills/skill-history.test.ts +269 -0
- package/src/skills/skill-history.ts +250 -0
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
- package/src/stt/__tests__/language-metadata.test.ts +85 -0
- package/src/stt/__tests__/speech-energy.test.ts +79 -0
- package/src/stt/__tests__/types.test.ts +94 -0
- package/src/stt/daemon-batch-transcriber.ts +18 -6
- package/src/stt/language-metadata.ts +65 -0
- package/src/stt/speech-energy.ts +115 -12
- package/src/stt/stt-stream-session.ts +8 -4
- package/src/stt/types.ts +119 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +25 -0
- package/src/subagent/consult-prompt.ts +3 -1
- package/src/subagent/consult-transcript.ts +1 -1
- package/src/subagent/manager.ts +304 -44
- package/src/subagent/progress-events.ts +35 -0
- package/src/subagent/role-resolution.ts +88 -0
- package/src/subagent/types.ts +303 -67
- package/src/subagent/validate-allowlists.ts +3 -4
- package/src/telegram/__tests__/webhook-health.test.ts +73 -1
- package/src/telegram/webhook-health.ts +101 -3
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +2 -0
- package/src/telemetry/activation-funnel.ts +6 -1
- package/src/telemetry/live-voice-funnel.ts +75 -0
- package/src/telemetry/telemetry-event-sources.ts +6 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +2 -0
- package/src/telemetry/types.ts +23 -4
- package/src/telemetry/usage-telemetry-reporter.test.ts +4 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +118 -3
- package/src/tools/ask-question/ask-question-tool.ts +56 -2
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/calls/call-start.ts +8 -5
- package/src/tools/conversation-groups/move_to_group.ts +10 -12
- package/src/tools/document/document-tool.ts +11 -4
- package/src/tools/execution-timeout.ts +9 -2
- package/src/tools/executor.ts +7 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +7 -13
- package/src/tools/filesystem/search.ts +23 -21
- package/src/tools/filesystem/write.ts +4 -1
- package/src/tools/host-filesystem/edit.ts +7 -2
- package/src/tools/host-filesystem/read.ts +21 -8
- package/src/tools/host-filesystem/write.ts +10 -2
- package/src/tools/host-terminal/host-shell.ts +2 -2
- package/src/tools/mcp/mcp-tool-factory.ts +25 -1
- package/src/tools/permission-checker.ts +8 -3
- package/src/tools/schedule/delete.ts +13 -1
- package/src/tools/schedule/list.ts +14 -3
- package/src/tools/schedule/update.ts +56 -33
- package/src/tools/shared/filesystem/audio-read.ts +6 -4
- package/src/tools/shared/filesystem/file-ops-service.ts +176 -116
- package/src/tools/shared/filesystem/image-read.ts +12 -12
- package/src/tools/shared/filesystem/path-policy.ts +70 -5
- package/src/tools/shared/filesystem/size-guard.ts +6 -6
- package/src/tools/shared/input-misuse.ts +72 -0
- package/src/tools/skills/scaffold-managed.ts +82 -0
- package/src/tools/skills/skill-tool-factory.ts +14 -1
- package/src/tools/subagent/consult-deadline.ts +12 -7
- package/src/tools/subagent/message.ts +3 -1
- package/src/tools/subagent/read.ts +66 -4
- package/src/tools/subagent/spawn.ts +500 -78
- package/src/tools/tool-approval-handler.ts +45 -4
- package/src/tools/types.ts +22 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
- package/src/tools/ui-surface/visual-validation.ts +2 -0
- package/src/tts/__tests__/provider-adapters.test.ts +147 -0
- package/src/tts/__tests__/speakable-segments.test.ts +470 -0
- package/src/tts/language-voices.ts +23 -0
- package/src/tts/providers/deepgram-provider.ts +3 -1
- package/src/tts/providers/elevenlabs-provider.ts +73 -1
- package/src/tts/providers/xai-provider.ts +28 -2
- package/src/tts/speakable-segments.ts +293 -23
- package/src/tts/synthesis-stream.ts +7 -0
- package/src/tts/types.ts +7 -0
- package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
- package/src/usage/subagent-attribution.ts +108 -0
- package/src/util/__tests__/language-subtag.test.ts +54 -0
- package/src/util/__tests__/sqlite-retry.test.ts +112 -0
- package/src/util/abort-reasons.ts +16 -0
- package/src/util/ansi.ts +44 -0
- package/src/util/disk-usage.ts +17 -13
- package/src/util/image-conversion.ts +20 -13
- package/src/util/language-subtag.ts +43 -0
- package/src/util/schedule-source-key.ts +23 -0
- package/src/util/unicode.ts +1 -1
- package/src/util/worker-process.ts +7 -1
- package/src/workspace/git-service.ts +33 -9
- package/src/workspace/migrations/140-repair-seed-pinned-memory-v3-live.ts +260 -0
- package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +111 -0
- package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +116 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/top-level-renderer.ts +15 -2
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -357
- package/src/daemon/install-symlink.ts +0 -207
- package/src/live-voice/__tests__/front-decision.test.ts +0 -525
- package/src/live-voice/front-decision.ts +0 -429
- package/src/notifications/deferred-emit.ts +0 -147
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
VoiceTurnCallbacks,
|
|
6
6
|
VoiceTurnOptions,
|
|
7
7
|
} from "../../calls/voice-session-bridge.js";
|
|
8
|
+
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
8
9
|
import type {
|
|
9
10
|
LiveVoiceFrontModelConfig,
|
|
10
11
|
LiveVoiceProgressConfig,
|
|
@@ -13,10 +14,6 @@ import type {
|
|
|
13
14
|
StreamingTranscriber,
|
|
14
15
|
SttStreamServerEvent,
|
|
15
16
|
} from "../../stt/types.js";
|
|
16
|
-
import type {
|
|
17
|
-
VoiceFrontDecider,
|
|
18
|
-
VoiceProgressTextInput,
|
|
19
|
-
} from "../front-decision.js";
|
|
20
17
|
import {
|
|
21
18
|
LiveVoiceSession,
|
|
22
19
|
type LiveVoiceTtsStreamer,
|
|
@@ -24,9 +21,14 @@ import {
|
|
|
24
21
|
} from "../live-voice-session.js";
|
|
25
22
|
import type { LiveVoiceSessionFactoryContext } from "../live-voice-session-manager.js";
|
|
26
23
|
import type { LiveVoiceTtsOptions } from "../live-voice-tts.js";
|
|
24
|
+
import type {
|
|
25
|
+
VoiceProgressNarrator,
|
|
26
|
+
VoiceProgressTextInput,
|
|
27
|
+
} from "../progress-narration.js";
|
|
27
28
|
import {
|
|
28
29
|
pickProgressPhrase,
|
|
29
30
|
PROGRESS_FALLBACK_PHRASES,
|
|
31
|
+
PROGRESS_FALLBACK_PHRASES_BY_LANGUAGE,
|
|
30
32
|
} from "../progress-phrases.js";
|
|
31
33
|
import {
|
|
32
34
|
createLiveVoiceServerFrameSequencer,
|
|
@@ -44,16 +46,7 @@ const START_FRAME = {
|
|
|
44
46
|
},
|
|
45
47
|
} as const satisfies LiveVoiceClientStartFrame;
|
|
46
48
|
|
|
47
|
-
// Generous enough that the slow-first-delta ack never fires during a test;
|
|
48
|
-
// the immediate tool-start ack still speaks and is asserted where relevant.
|
|
49
|
-
const GENEROUS_ACK_TIMEOUT_MS = 60_000;
|
|
50
|
-
|
|
51
49
|
const GENERATED_NARRATION = "Progress text.";
|
|
52
|
-
// Acks are front-model-phrased; narrations fall back to a static phrase.
|
|
53
|
-
// Both pass through the same TTS sanitizer, and each fresh session's
|
|
54
|
-
// narration phrase counter starts at 0.
|
|
55
|
-
const GENERATED_TOOL_ACK = "Let me look that up.";
|
|
56
|
-
const EXPECTED_TOOL_ACK = sanitizeForTts(GENERATED_TOOL_ACK).trim();
|
|
57
50
|
const EXPECTED_PROGRESS_FALLBACK = sanitizeForTts(pickProgressPhrase(0)).trim();
|
|
58
51
|
|
|
59
52
|
class MockStreamingTranscriber implements StreamingTranscriber {
|
|
@@ -61,6 +54,13 @@ class MockStreamingTranscriber implements StreamingTranscriber {
|
|
|
61
54
|
readonly boundaryId = "daemon-streaming" as const;
|
|
62
55
|
private onEvent: ((event: SttStreamServerEvent) => void) | null = null;
|
|
63
56
|
|
|
57
|
+
constructor(
|
|
58
|
+
private readonly stopEvents: SttStreamServerEvent[] = [
|
|
59
|
+
{ type: "final", text: "hello" },
|
|
60
|
+
{ type: "closed" },
|
|
61
|
+
],
|
|
62
|
+
) {}
|
|
63
|
+
|
|
64
64
|
async start(onEvent: (event: SttStreamServerEvent) => void): Promise<void> {
|
|
65
65
|
this.onEvent = onEvent;
|
|
66
66
|
}
|
|
@@ -68,8 +68,9 @@ class MockStreamingTranscriber implements StreamingTranscriber {
|
|
|
68
68
|
sendAudio(): void {}
|
|
69
69
|
|
|
70
70
|
stop(): void {
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
for (const event of this.stopEvents) {
|
|
72
|
+
this.onEvent?.(event);
|
|
73
|
+
}
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -113,10 +114,13 @@ function createRecordingTtsStreamer(
|
|
|
113
114
|
): {
|
|
114
115
|
streamTtsAudio: LiveVoiceTtsStreamer;
|
|
115
116
|
ttsTexts: string[];
|
|
117
|
+
ttsCalls: LiveVoiceTtsOptions[];
|
|
116
118
|
} {
|
|
117
119
|
const ttsTexts: string[] = [];
|
|
120
|
+
const ttsCalls: LiveVoiceTtsOptions[] = [];
|
|
118
121
|
const streamTtsAudio = mock(async (options: LiveVoiceTtsOptions) => {
|
|
119
122
|
ttsTexts.push(options.text);
|
|
123
|
+
ttsCalls.push(options);
|
|
120
124
|
await gateTtsText?.(options.text);
|
|
121
125
|
return {
|
|
122
126
|
provider: "fish-audio" as const,
|
|
@@ -126,14 +130,13 @@ function createRecordingTtsStreamer(
|
|
|
126
130
|
bytes: Buffer.byteLength(options.text),
|
|
127
131
|
};
|
|
128
132
|
});
|
|
129
|
-
return { streamTtsAudio, ttsTexts };
|
|
133
|
+
return { streamTtsAudio, ttsTexts, ttsCalls };
|
|
130
134
|
}
|
|
131
135
|
|
|
132
|
-
function
|
|
133
|
-
generateProgressText:
|
|
134
|
-
):
|
|
136
|
+
function makeProgressNarrator(
|
|
137
|
+
generateProgressText: VoiceProgressNarrator["generateProgressText"],
|
|
138
|
+
): VoiceProgressNarrator {
|
|
135
139
|
return {
|
|
136
|
-
generateAckText: async () => GENERATED_TOOL_ACK,
|
|
137
140
|
generateProgressText,
|
|
138
141
|
};
|
|
139
142
|
}
|
|
@@ -143,7 +146,6 @@ function progressConfig(
|
|
|
143
146
|
): Partial<LiveVoiceFrontModelConfig> {
|
|
144
147
|
const idleIntervalMs = overrides.idleIntervalMs ?? 60_000;
|
|
145
148
|
return {
|
|
146
|
-
ackFirstDeltaTimeoutMs: GENEROUS_ACK_TIMEOUT_MS,
|
|
147
149
|
progress: {
|
|
148
150
|
enabled: true,
|
|
149
151
|
opsThreshold: 3,
|
|
@@ -162,26 +164,31 @@ function progressConfig(
|
|
|
162
164
|
|
|
163
165
|
function createProgressHarness(options: {
|
|
164
166
|
frontModelConfig: Partial<LiveVoiceFrontModelConfig>;
|
|
165
|
-
|
|
167
|
+
progressNarrator: VoiceProgressNarrator;
|
|
166
168
|
emitMetrics?: boolean;
|
|
167
169
|
gateTtsText?: (text: string) => Promise<void> | null;
|
|
170
|
+
// Events the transcriber flushes at utterance release; defaults to a plain
|
|
171
|
+
// untagged "hello" final.
|
|
172
|
+
sttStopEvents?: SttStreamServerEvent[];
|
|
168
173
|
}) {
|
|
169
174
|
const { startVoiceTurn, getCallbacks } = createCapturingTurnStarter();
|
|
170
|
-
const { streamTtsAudio, ttsTexts } = createRecordingTtsStreamer(
|
|
175
|
+
const { streamTtsAudio, ttsTexts, ttsCalls } = createRecordingTtsStreamer(
|
|
171
176
|
options.gateTtsText,
|
|
172
177
|
);
|
|
173
178
|
const { context, frames } = createContext();
|
|
174
179
|
const session = new LiveVoiceSession(context, {
|
|
175
|
-
resolveTranscriber: mock(
|
|
180
|
+
resolveTranscriber: mock(
|
|
181
|
+
async () => new MockStreamingTranscriber(options.sttStopEvents),
|
|
182
|
+
),
|
|
176
183
|
startVoiceTurn,
|
|
177
184
|
streamTtsAudio,
|
|
178
185
|
frontModelConfig: options.frontModelConfig,
|
|
179
|
-
|
|
186
|
+
progressNarrator: options.progressNarrator,
|
|
180
187
|
createTurnId: () => "live-turn-1",
|
|
181
188
|
emitMetrics: options.emitMetrics ?? false,
|
|
182
189
|
});
|
|
183
190
|
|
|
184
|
-
return { frames, session, getCallbacks, ttsTexts };
|
|
191
|
+
return { frames, session, getCallbacks, ttsTexts, ttsCalls };
|
|
185
192
|
}
|
|
186
193
|
|
|
187
194
|
async function startReleasedTurn(
|
|
@@ -263,7 +270,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
263
270
|
);
|
|
264
271
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
265
272
|
frontModelConfig: progressConfig({ idleIntervalMs: 40 }),
|
|
266
|
-
|
|
273
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
267
274
|
});
|
|
268
275
|
await startReleasedTurn(session, getCallbacks);
|
|
269
276
|
|
|
@@ -289,22 +296,18 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
289
296
|
});
|
|
290
297
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
291
298
|
frontModelConfig: progressConfig({ opsThreshold: 3, minGapMs: 10 }),
|
|
292
|
-
|
|
299
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
293
300
|
});
|
|
294
301
|
|
|
295
302
|
await startReleasedTurn(session, getCallbacks);
|
|
296
303
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
297
|
-
await waitFor(() => ttsTexts.length === 1);
|
|
298
|
-
expect(ttsTexts).toEqual([EXPECTED_TOOL_ACK]);
|
|
299
304
|
|
|
300
305
|
emitToolResult(getCallbacks, "web_search", "tool-1", "found 3 results");
|
|
301
306
|
emitToolStart(getCallbacks, "file_read", "tool-2");
|
|
302
307
|
emitToolResult(getCallbacks, "file_read", "tool-2", "file contents");
|
|
303
|
-
// Let the ack's minGapMs spacing elapse before the threshold-crossing op.
|
|
304
|
-
await sleep(30);
|
|
305
308
|
emitToolStart(getCallbacks, "web_search", "tool-3");
|
|
306
|
-
await waitFor(() => ttsTexts.length ===
|
|
307
|
-
expect(ttsTexts).toEqual([
|
|
309
|
+
await waitFor(() => ttsTexts.length === 1);
|
|
310
|
+
expect(ttsTexts).toEqual([GENERATED_NARRATION]);
|
|
308
311
|
expect(generateProgressText).toHaveBeenCalledTimes(1);
|
|
309
312
|
expect(inputs[0]).toMatchObject({
|
|
310
313
|
transcriptSoFar: "hello",
|
|
@@ -320,7 +323,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
320
323
|
// below the threshold: still exactly one narration.
|
|
321
324
|
emitToolResult(getCallbacks, "web_search", "tool-3");
|
|
322
325
|
await sleep(30);
|
|
323
|
-
expect(ttsTexts).toEqual([
|
|
326
|
+
expect(ttsTexts).toEqual([GENERATED_NARRATION]);
|
|
324
327
|
expect(generateProgressText).toHaveBeenCalledTimes(1);
|
|
325
328
|
|
|
326
329
|
emitMessageComplete(getCallbacks);
|
|
@@ -336,12 +339,11 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
336
339
|
});
|
|
337
340
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
338
341
|
frontModelConfig: progressConfig({ opsThreshold: 3, minGapMs: 10 }),
|
|
339
|
-
|
|
342
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
340
343
|
});
|
|
341
344
|
|
|
342
345
|
await startReleasedTurn(session, getCallbacks);
|
|
343
346
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
344
|
-
await waitFor(() => ttsTexts.length === 1);
|
|
345
347
|
|
|
346
348
|
// Name-only result: no toolUseId to correlate by.
|
|
347
349
|
getCallbacks()?.tool_result?.({
|
|
@@ -349,11 +351,9 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
349
351
|
resultPreview: "found it",
|
|
350
352
|
});
|
|
351
353
|
emitToolStart(getCallbacks, "file_read", "tool-2");
|
|
352
|
-
// Let the ack's minGapMs spacing elapse before the threshold-crossing op.
|
|
353
|
-
await sleep(30);
|
|
354
354
|
emitToolStart(getCallbacks, "bash", "tool-3");
|
|
355
|
-
await waitFor(() => ttsTexts.length ===
|
|
356
|
-
expect(ttsTexts).toEqual([
|
|
355
|
+
await waitFor(() => ttsTexts.length === 1);
|
|
356
|
+
expect(ttsTexts).toEqual([GENERATED_NARRATION]);
|
|
357
357
|
|
|
358
358
|
// The name fallback completed the web_search op: it reports as completed
|
|
359
359
|
// (with its preview) rather than lingering incomplete.
|
|
@@ -365,7 +365,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
365
365
|
emitMessageComplete(getCallbacks);
|
|
366
366
|
});
|
|
367
367
|
|
|
368
|
-
test("completedOps reach the
|
|
368
|
+
test("completedOps reach the narrator in completion order, not start order", async () => {
|
|
369
369
|
const inputs: VoiceProgressTextInput[] = [];
|
|
370
370
|
const generateProgressText = mock(async (input: VoiceProgressTextInput) => {
|
|
371
371
|
inputs.push(input);
|
|
@@ -373,21 +373,20 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
373
373
|
});
|
|
374
374
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
375
375
|
frontModelConfig: progressConfig({ opsThreshold: 3, minGapMs: 10 }),
|
|
376
|
-
|
|
376
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
377
377
|
});
|
|
378
378
|
|
|
379
379
|
await startReleasedTurn(session, getCallbacks);
|
|
380
380
|
// Two parallel tools start in one order…
|
|
381
381
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
382
|
-
await waitFor(() => ttsTexts.length === 1);
|
|
383
382
|
emitToolStart(getCallbacks, "file_read", "tool-2");
|
|
384
|
-
//
|
|
385
|
-
// timestamps
|
|
383
|
+
// They complete in the other order. The sleep separates their completion
|
|
384
|
+
// timestamps on the millisecond clock.
|
|
386
385
|
emitToolResult(getCallbacks, "file_read", "tool-2", "file contents");
|
|
387
386
|
await sleep(30);
|
|
388
387
|
emitToolResult(getCallbacks, "web_search", "tool-1", "found 3 results");
|
|
389
388
|
emitToolStart(getCallbacks, "bash", "tool-3");
|
|
390
|
-
await waitFor(() => ttsTexts.length ===
|
|
389
|
+
await waitFor(() => ttsTexts.length === 1);
|
|
391
390
|
|
|
392
391
|
expect(inputs[0]?.completedOps).toEqual([
|
|
393
392
|
{ toolName: "file_read", resultPreview: "file contents" },
|
|
@@ -397,7 +396,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
397
396
|
emitMessageComplete(getCallbacks);
|
|
398
397
|
});
|
|
399
398
|
|
|
400
|
-
test("idle trigger: dead air narrates with
|
|
399
|
+
test("idle trigger: dead air narrates with generated text, audio-only", async () => {
|
|
401
400
|
const inputs: VoiceProgressTextInput[] = [];
|
|
402
401
|
const generateProgressText = mock(async (input: VoiceProgressTextInput) => {
|
|
403
402
|
inputs.push(input);
|
|
@@ -408,7 +407,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
408
407
|
idleIntervalMs: 40,
|
|
409
408
|
minGapMs: 60_000,
|
|
410
409
|
}),
|
|
411
|
-
|
|
410
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
412
411
|
});
|
|
413
412
|
|
|
414
413
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -429,14 +428,14 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
429
428
|
emitMessageComplete(getCallbacks);
|
|
430
429
|
});
|
|
431
430
|
|
|
432
|
-
test("idle trigger with a null
|
|
431
|
+
test("idle trigger with a null narrator result speaks the static fallback", async () => {
|
|
433
432
|
const generateProgressText = mock(async () => null);
|
|
434
433
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
435
434
|
frontModelConfig: progressConfig({
|
|
436
435
|
idleIntervalMs: 40,
|
|
437
436
|
minGapMs: 60_000,
|
|
438
437
|
}),
|
|
439
|
-
|
|
438
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
440
439
|
});
|
|
441
440
|
|
|
442
441
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -449,11 +448,17 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
449
448
|
|
|
450
449
|
test("no-ops idle fallback stays neutral: no phrase claims tool activity", async () => {
|
|
451
450
|
// List invariant: the fallback can speak on a slow turn with zero tool
|
|
452
|
-
// activity, so no phrase may claim tools or tasks are running.
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
451
|
+
// activity, so no phrase may claim tools or tasks are running. Every
|
|
452
|
+
// language's list carries the invariant; the regex names the English
|
|
453
|
+
// activity words, which no list may borrow.
|
|
454
|
+
for (const phrases of Object.values(
|
|
455
|
+
PROGRESS_FALLBACK_PHRASES_BY_LANGUAGE,
|
|
456
|
+
)) {
|
|
457
|
+
for (const phrase of phrases) {
|
|
458
|
+
expect(phrase.toLowerCase()).not.toMatch(
|
|
459
|
+
/\b(run|runs|running|tool|tools|thing|things|task|tasks|check|checking|look|looking|search|searching)\b/,
|
|
460
|
+
);
|
|
461
|
+
}
|
|
457
462
|
}
|
|
458
463
|
|
|
459
464
|
// Behavior: a slow turn with no tool events falls back to that list.
|
|
@@ -463,7 +468,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
463
468
|
idleIntervalMs: 40,
|
|
464
469
|
minGapMs: 60_000,
|
|
465
470
|
}),
|
|
466
|
-
|
|
471
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
467
472
|
});
|
|
468
473
|
|
|
469
474
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -475,104 +480,135 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
475
480
|
emitMessageComplete(getCallbacks);
|
|
476
481
|
});
|
|
477
482
|
|
|
478
|
-
test("
|
|
479
|
-
const
|
|
483
|
+
test("a Hindi turn's idle fallback speaks the Hindi phrase and hints the narrator", async () => {
|
|
484
|
+
const inputs: VoiceProgressTextInput[] = [];
|
|
485
|
+
const generateProgressText = mock(async (input: VoiceProgressTextInput) => {
|
|
486
|
+
inputs.push(input);
|
|
487
|
+
return null;
|
|
488
|
+
});
|
|
480
489
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
481
490
|
frontModelConfig: progressConfig({
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
minGapMs: 10,
|
|
491
|
+
idleIntervalMs: 40,
|
|
492
|
+
minGapMs: 60_000,
|
|
485
493
|
}),
|
|
486
|
-
|
|
494
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
495
|
+
sttStopEvents: [
|
|
496
|
+
{ type: "final", text: "नमस्ते", languages: ["hi"] },
|
|
497
|
+
{ type: "closed" },
|
|
498
|
+
],
|
|
487
499
|
});
|
|
488
500
|
|
|
489
501
|
await startReleasedTurn(session, getCallbacks);
|
|
490
|
-
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
491
502
|
await waitFor(() => ttsTexts.length === 1);
|
|
492
|
-
expect(ttsTexts).toEqual([EXPECTED_TOOL_ACK]);
|
|
493
|
-
|
|
494
|
-
// Past the ack gap, the ops trigger fires but generation returns null:
|
|
495
|
-
// nothing speaks and no update is consumed.
|
|
496
|
-
await sleep(30);
|
|
497
|
-
emitToolResult(getCallbacks, "web_search", "tool-1");
|
|
498
|
-
await waitFor(() => generateProgressText.mock.calls.length === 1);
|
|
499
|
-
await sleep(10);
|
|
500
|
-
expect(ttsTexts).toEqual([EXPECTED_TOOL_ACK]);
|
|
501
503
|
|
|
502
|
-
// The
|
|
503
|
-
// the
|
|
504
|
-
|
|
505
|
-
|
|
504
|
+
// The static fallback rotates through the caller's language's list, not
|
|
505
|
+
// the English default, and the narrator was told the language too.
|
|
506
|
+
expect(pickProgressPhrase(0, "hi")).toBe(
|
|
507
|
+
PROGRESS_FALLBACK_PHRASES_BY_LANGUAGE.hi![0]!,
|
|
508
|
+
);
|
|
509
|
+
expect(ttsTexts).toEqual([
|
|
510
|
+
sanitizeForTts(pickProgressPhrase(0, "hi")).trim(),
|
|
511
|
+
]);
|
|
512
|
+
expect(inputs[0]?.languageHint).toBe("hi");
|
|
506
513
|
|
|
507
514
|
emitMessageComplete(getCallbacks);
|
|
508
515
|
});
|
|
509
516
|
|
|
510
|
-
test("
|
|
511
|
-
|
|
517
|
+
test("an out-of-roster pinned turn speaks the English fallback with an 'en' hint while model speech keeps the pin", async () => {
|
|
518
|
+
// "ar" is an accepted monolingual services.stt.language pin but has no
|
|
519
|
+
// entry in the localized phrase tables, so the idle fallback is English
|
|
520
|
+
// text. The filler segment must carry an "en" hint rather than the
|
|
521
|
+
// turn's "ar" (an enforcing TTS provider would otherwise render English
|
|
522
|
+
// words as Arabic). Model speech stays on the turn's language.
|
|
523
|
+
const originalRaw = loadRawConfig();
|
|
524
|
+
const rawServices = (originalRaw.services ?? {}) as Record<string, unknown>;
|
|
525
|
+
saveRawConfig({
|
|
526
|
+
...originalRaw,
|
|
527
|
+
services: {
|
|
528
|
+
...rawServices,
|
|
529
|
+
stt: {
|
|
530
|
+
...((rawServices.stt ?? {}) as Record<string, unknown>),
|
|
531
|
+
provider: "deepgram",
|
|
532
|
+
language: "ar",
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
const generateProgressText = mock(async () => null);
|
|
537
|
+
const { session, getCallbacks, ttsTexts, ttsCalls } = createProgressHarness(
|
|
538
|
+
{
|
|
539
|
+
frontModelConfig: progressConfig({
|
|
540
|
+
idleIntervalMs: 40,
|
|
541
|
+
minGapMs: 60_000,
|
|
542
|
+
}),
|
|
543
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
544
|
+
},
|
|
545
|
+
);
|
|
546
|
+
|
|
547
|
+
try {
|
|
548
|
+
await startReleasedTurn(session, getCallbacks);
|
|
549
|
+
await waitFor(() => ttsTexts.length === 1);
|
|
550
|
+
|
|
551
|
+
expect(ttsTexts[0]).toBe(EXPECTED_PROGRESS_FALLBACK);
|
|
552
|
+
expect(ttsCalls[0]?.language).toBe("en");
|
|
553
|
+
|
|
554
|
+
emitTextDelta(getCallbacks, "Okay.");
|
|
555
|
+
emitMessageComplete(getCallbacks);
|
|
556
|
+
await waitFor(() => ttsCalls.length >= 2);
|
|
557
|
+
|
|
558
|
+
expect(ttsCalls[1]?.text).toBe("Okay.");
|
|
559
|
+
expect(ttsCalls[1]?.language).toBe("ar");
|
|
560
|
+
} finally {
|
|
561
|
+
await session.close("websocket_close");
|
|
562
|
+
saveRawConfig(originalRaw);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
test("with no detected language the narrator gets no hint and fallback stays English", async () => {
|
|
567
|
+
const inputs: VoiceProgressTextInput[] = [];
|
|
568
|
+
const progressNarrator: VoiceProgressNarrator = {
|
|
569
|
+
generateProgressText: async (input) => {
|
|
570
|
+
inputs.push(input);
|
|
571
|
+
return null;
|
|
572
|
+
},
|
|
573
|
+
};
|
|
512
574
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
513
|
-
frontModelConfig: progressConfig({
|
|
514
|
-
|
|
575
|
+
frontModelConfig: progressConfig({ idleIntervalMs: 40, minGapMs: 10 }),
|
|
576
|
+
progressNarrator,
|
|
515
577
|
});
|
|
516
578
|
|
|
517
579
|
await startReleasedTurn(session, getCallbacks);
|
|
518
580
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
519
581
|
await waitFor(() => ttsTexts.length === 1);
|
|
520
|
-
// Threshold already met, but the just-spoken ack holds the floor.
|
|
521
|
-
emitToolResult(getCallbacks, "web_search", "tool-1");
|
|
522
|
-
await sleep(30);
|
|
523
|
-
expect(ttsTexts).toEqual([EXPECTED_TOOL_ACK]);
|
|
524
|
-
expect(generateProgressText).not.toHaveBeenCalled();
|
|
525
582
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
expect(ttsTexts).toEqual([
|
|
530
|
-
expect(generateProgressText).toHaveBeenCalledTimes(1);
|
|
583
|
+
// Language unknown: the input has no languageHint key and the static
|
|
584
|
+
// fallback comes from the English list.
|
|
585
|
+
expect(inputs[0]).not.toHaveProperty("languageHint");
|
|
586
|
+
expect(ttsTexts).toEqual([EXPECTED_PROGRESS_FALLBACK]);
|
|
531
587
|
|
|
532
588
|
emitMessageComplete(getCallbacks);
|
|
533
589
|
});
|
|
534
590
|
|
|
535
|
-
test("
|
|
536
|
-
const
|
|
537
|
-
const generateAckText = mock(() => ackGeneration.promise);
|
|
538
|
-
const generateProgressText = mock(async () => GENERATED_NARRATION);
|
|
539
|
-
const frontDecider: VoiceFrontDecider = {
|
|
540
|
-
generateAckText,
|
|
541
|
-
generateProgressText,
|
|
542
|
-
};
|
|
591
|
+
test("ops trigger with a null narrator result stays silent and keeps the update budget", async () => {
|
|
592
|
+
const generateProgressText = mock(async () => null);
|
|
543
593
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
544
|
-
frontModelConfig: progressConfig({
|
|
545
|
-
|
|
594
|
+
frontModelConfig: progressConfig({
|
|
595
|
+
opsThreshold: 1,
|
|
596
|
+
idleIntervalMs: 120,
|
|
597
|
+
minGapMs: 10,
|
|
598
|
+
}),
|
|
599
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
546
600
|
});
|
|
547
601
|
|
|
548
602
|
await startReleasedTurn(session, getCallbacks);
|
|
549
|
-
// The tool start speaks a generated ack (generation still pending) and
|
|
550
|
-
// simultaneously crosses the ops threshold; the entry guard must stand
|
|
551
|
-
// down instead of launching a narration generation whose result the
|
|
552
|
-
// post-await re-check would only discard.
|
|
553
603
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
554
|
-
await
|
|
555
|
-
|
|
604
|
+
await waitFor(() => generateProgressText.mock.calls.length === 1);
|
|
605
|
+
await sleep(10);
|
|
556
606
|
expect(ttsTexts).toEqual([]);
|
|
557
607
|
|
|
558
|
-
|
|
608
|
+
// The idle trigger still has the full budget: its own null falls back to
|
|
609
|
+
// the static phrase.
|
|
559
610
|
await waitFor(() => ttsTexts.length === 1);
|
|
560
|
-
expect(ttsTexts).toEqual([
|
|
561
|
-
|
|
562
|
-
// Inside the ack's minGapMs window nothing else speaks even as tool
|
|
563
|
-
// activity continues.
|
|
564
|
-
emitToolResult(getCallbacks, "web_search", "tool-1");
|
|
565
|
-
await sleep(30);
|
|
566
|
-
expect(generateProgressText).not.toHaveBeenCalled();
|
|
567
|
-
expect(ttsTexts).toEqual(["Generated ack."]);
|
|
568
|
-
|
|
569
|
-
// The stand-down preserved the update budget: once the gap elapses, the
|
|
570
|
-
// next ops trigger narrates normally.
|
|
571
|
-
await sleep(150);
|
|
572
|
-
emitToolStart(getCallbacks, "file_read", "tool-2");
|
|
573
|
-
await waitFor(() => ttsTexts.length === 2);
|
|
574
|
-
expect(ttsTexts).toEqual(["Generated ack.", GENERATED_NARRATION]);
|
|
575
|
-
expect(generateProgressText).toHaveBeenCalledTimes(1);
|
|
611
|
+
expect(ttsTexts).toEqual([EXPECTED_PROGRESS_FALLBACK]);
|
|
576
612
|
|
|
577
613
|
emitMessageComplete(getCallbacks);
|
|
578
614
|
});
|
|
@@ -585,7 +621,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
585
621
|
});
|
|
586
622
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
587
623
|
frontModelConfig: progressConfig({ idleIntervalMs: 30, minGapMs: 1 }),
|
|
588
|
-
|
|
624
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
589
625
|
});
|
|
590
626
|
|
|
591
627
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -619,7 +655,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
619
655
|
idleIntervalMs: 40,
|
|
620
656
|
minGapMs: 10,
|
|
621
657
|
}),
|
|
622
|
-
|
|
658
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
623
659
|
});
|
|
624
660
|
|
|
625
661
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -651,7 +687,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
651
687
|
idleIntervalMs: 40,
|
|
652
688
|
minGapMs: 60_000,
|
|
653
689
|
}),
|
|
654
|
-
|
|
690
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
655
691
|
gateTtsText: (text) => (text === "Hello there." ? ttsGate.promise : null),
|
|
656
692
|
});
|
|
657
693
|
|
|
@@ -676,7 +712,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
676
712
|
const generateProgressText = mock(() => generation.promise);
|
|
677
713
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
678
714
|
frontModelConfig: progressConfig({ idleIntervalMs: 40 }),
|
|
679
|
-
|
|
715
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
680
716
|
});
|
|
681
717
|
|
|
682
718
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -697,7 +733,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
697
733
|
idleIntervalMs: 40,
|
|
698
734
|
minGapMs: 60_000,
|
|
699
735
|
}),
|
|
700
|
-
|
|
736
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
701
737
|
emitMetrics: true,
|
|
702
738
|
});
|
|
703
739
|
|
|
@@ -722,7 +758,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
722
758
|
});
|
|
723
759
|
});
|
|
724
760
|
|
|
725
|
-
test("progress.enabled false: zero narrations and zero
|
|
761
|
+
test("progress.enabled false: zero narrations and zero narrator calls", async () => {
|
|
726
762
|
const generateProgressText = mock(async () => GENERATED_NARRATION);
|
|
727
763
|
const { session, getCallbacks, ttsTexts } = createProgressHarness({
|
|
728
764
|
frontModelConfig: progressConfig({
|
|
@@ -731,7 +767,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
731
767
|
idleIntervalMs: 30,
|
|
732
768
|
minGapMs: 1,
|
|
733
769
|
}),
|
|
734
|
-
|
|
770
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
735
771
|
});
|
|
736
772
|
|
|
737
773
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -741,8 +777,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
741
777
|
emitToolResult(getCallbacks, "file_read", "tool-2");
|
|
742
778
|
await sleep(100);
|
|
743
779
|
|
|
744
|
-
|
|
745
|
-
expect(ttsTexts).toEqual([EXPECTED_TOOL_ACK]);
|
|
780
|
+
expect(ttsTexts).toEqual([]);
|
|
746
781
|
expect(generateProgressText).not.toHaveBeenCalled();
|
|
747
782
|
|
|
748
783
|
emitMessageComplete(getCallbacks);
|
|
@@ -755,7 +790,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
755
790
|
idleIntervalMs: 20,
|
|
756
791
|
maxSilenceMs: 150,
|
|
757
792
|
}),
|
|
758
|
-
|
|
793
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
759
794
|
});
|
|
760
795
|
|
|
761
796
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -782,7 +817,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
782
817
|
idleIntervalMs: 20,
|
|
783
818
|
maxSilenceMs: 600_000,
|
|
784
819
|
}),
|
|
785
|
-
|
|
820
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
786
821
|
});
|
|
787
822
|
|
|
788
823
|
await startReleasedTurn(session, getCallbacks);
|
|
@@ -791,14 +826,14 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
791
826
|
|
|
792
827
|
// A tool starting is news: the next tick narrates it.
|
|
793
828
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
794
|
-
await waitFor(() => ttsTexts.length ===
|
|
795
|
-
expect(ttsTexts).toEqual([
|
|
829
|
+
await waitFor(() => ttsTexts.length === 1);
|
|
830
|
+
expect(ttsTexts).toEqual([GENERATED_NARRATION]);
|
|
796
831
|
|
|
797
832
|
// Nothing has happened since, so the ticks that follow stay quiet
|
|
798
833
|
// instead of repeating the same update on a clock.
|
|
799
834
|
await sleep(80);
|
|
800
835
|
expect(generateProgressText).toHaveBeenCalledTimes(1);
|
|
801
|
-
expect(ttsTexts).toEqual([
|
|
836
|
+
expect(ttsTexts).toEqual([GENERATED_NARRATION]);
|
|
802
837
|
|
|
803
838
|
emitMessageComplete(getCallbacks);
|
|
804
839
|
});
|
|
@@ -817,17 +852,16 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
817
852
|
idleIntervalMs: 60_000,
|
|
818
853
|
longOpMs: 25,
|
|
819
854
|
}),
|
|
820
|
-
|
|
855
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
821
856
|
});
|
|
822
857
|
|
|
823
858
|
await startReleasedTurn(session, getCallbacks);
|
|
824
859
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
825
|
-
await waitFor(() => ttsTexts.length === 1);
|
|
826
860
|
await sleep(40);
|
|
827
861
|
|
|
828
862
|
emitToolResult(getCallbacks, "web_search", "tool-1");
|
|
829
|
-
await waitFor(() => ttsTexts.length ===
|
|
830
|
-
expect(ttsTexts).toEqual([
|
|
863
|
+
await waitFor(() => ttsTexts.length === 1);
|
|
864
|
+
expect(ttsTexts).toEqual([GENERATED_NARRATION]);
|
|
831
865
|
expect(inputs[0]?.completedOps).toEqual([
|
|
832
866
|
{ toolName: "web_search", resultPreview: "ok" },
|
|
833
867
|
]);
|
|
@@ -843,18 +877,17 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
843
877
|
idleIntervalMs: 60_000,
|
|
844
878
|
longOpMs: 60_000,
|
|
845
879
|
}),
|
|
846
|
-
|
|
880
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
847
881
|
});
|
|
848
882
|
|
|
849
883
|
await startReleasedTurn(session, getCallbacks);
|
|
850
884
|
emitToolStart(getCallbacks, "web_search", "tool-1");
|
|
851
|
-
await waitFor(() => ttsTexts.length === 1);
|
|
852
885
|
emitToolResult(getCallbacks, "web_search", "tool-1");
|
|
853
886
|
await sleep(60);
|
|
854
887
|
|
|
855
888
|
// Narrating every quick lookup is the chatter the cadence avoids.
|
|
856
889
|
expect(generateProgressText).not.toHaveBeenCalled();
|
|
857
|
-
expect(ttsTexts).toEqual([
|
|
890
|
+
expect(ttsTexts).toEqual([]);
|
|
858
891
|
|
|
859
892
|
emitMessageComplete(getCallbacks);
|
|
860
893
|
});
|
|
@@ -874,7 +907,7 @@ describe("LiveVoiceSession progress narration", () => {
|
|
|
874
907
|
idleIntervalMs: 20,
|
|
875
908
|
maxSilenceMs: 600_000,
|
|
876
909
|
}),
|
|
877
|
-
|
|
910
|
+
progressNarrator: makeProgressNarrator(generateProgressText),
|
|
878
911
|
});
|
|
879
912
|
|
|
880
913
|
await startReleasedTurn(session, getCallbacks);
|