@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
|
@@ -88,8 +88,8 @@ describe("attachmentsToReferenceBlocks", () => {
|
|
|
88
88
|
// ---------------------------------------------------------------------------
|
|
89
89
|
|
|
90
90
|
describe("attachmentsToContentBlocks", () => {
|
|
91
|
-
test("creates image content block for image/jpeg", () => {
|
|
92
|
-
const blocks = attachmentsToContentBlocks([
|
|
91
|
+
test("creates image content block for image/jpeg", async () => {
|
|
92
|
+
const blocks = await attachmentsToContentBlocks([
|
|
93
93
|
{ filename: "photo.jpg", mimeType: "image/jpeg", data: "base64data" },
|
|
94
94
|
]);
|
|
95
95
|
|
|
@@ -104,8 +104,8 @@ describe("attachmentsToContentBlocks", () => {
|
|
|
104
104
|
expect(block.source.data).toBe("base64data");
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
-
test("creates image content block for image/png", () => {
|
|
108
|
-
const blocks = attachmentsToContentBlocks([
|
|
107
|
+
test("creates image content block for image/png", async () => {
|
|
108
|
+
const blocks = await attachmentsToContentBlocks([
|
|
109
109
|
{ filename: "screenshot.png", mimeType: "image/png", data: "pngdata" },
|
|
110
110
|
]);
|
|
111
111
|
|
|
@@ -113,8 +113,8 @@ describe("attachmentsToContentBlocks", () => {
|
|
|
113
113
|
expect(blocks[0].type).toBe("image");
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
test("creates image content block for image/webp", () => {
|
|
117
|
-
const blocks = attachmentsToContentBlocks([
|
|
116
|
+
test("creates image content block for image/webp", async () => {
|
|
117
|
+
const blocks = await attachmentsToContentBlocks([
|
|
118
118
|
{ filename: "sticker.webp", mimeType: "image/webp", data: "webpdata" },
|
|
119
119
|
]);
|
|
120
120
|
|
|
@@ -122,8 +122,8 @@ describe("attachmentsToContentBlocks", () => {
|
|
|
122
122
|
expect(blocks[0].type).toBe("image");
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
test("creates file content block for non-image mime types", () => {
|
|
126
|
-
const blocks = attachmentsToContentBlocks([
|
|
125
|
+
test("creates file content block for non-image mime types", async () => {
|
|
126
|
+
const blocks = await attachmentsToContentBlocks([
|
|
127
127
|
{ filename: "doc.pdf", mimeType: "application/pdf", data: "pdfdata" },
|
|
128
128
|
]);
|
|
129
129
|
|
|
@@ -137,8 +137,8 @@ describe("attachmentsToContentBlocks", () => {
|
|
|
137
137
|
expect(block.source.media_type).toBe("application/pdf");
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
test("handles multiple attachments including mixed types", () => {
|
|
141
|
-
const blocks = attachmentsToContentBlocks([
|
|
140
|
+
test("handles multiple attachments including mixed types", async () => {
|
|
141
|
+
const blocks = await attachmentsToContentBlocks([
|
|
142
142
|
{ filename: "photo.jpg", mimeType: "image/jpeg", data: "imgdata" },
|
|
143
143
|
{ filename: "notes.txt", mimeType: "text/plain", data: "txtdata" },
|
|
144
144
|
]);
|
|
@@ -148,8 +148,8 @@ describe("attachmentsToContentBlocks", () => {
|
|
|
148
148
|
expect(blocks[1].type).toBe("file");
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
-
test("returns empty array for no attachments", () => {
|
|
152
|
-
const blocks = attachmentsToContentBlocks([]);
|
|
151
|
+
test("returns empty array for no attachments", async () => {
|
|
152
|
+
const blocks = await attachmentsToContentBlocks([]);
|
|
153
153
|
expect(blocks).toHaveLength(0);
|
|
154
154
|
});
|
|
155
155
|
});
|
|
@@ -159,8 +159,8 @@ describe("attachmentsToContentBlocks", () => {
|
|
|
159
159
|
// ---------------------------------------------------------------------------
|
|
160
160
|
|
|
161
161
|
describe("createUserMessage with image attachments", () => {
|
|
162
|
-
test("includes both text and image blocks", () => {
|
|
163
|
-
const msg = createUserMessage("what is this?", [
|
|
162
|
+
test("includes both text and image blocks", async () => {
|
|
163
|
+
const msg = await createUserMessage("what is this?", [
|
|
164
164
|
{ filename: "photo.jpg", mimeType: "image/jpeg", data: "base64img" },
|
|
165
165
|
]);
|
|
166
166
|
|
|
@@ -173,8 +173,8 @@ describe("createUserMessage with image attachments", () => {
|
|
|
173
173
|
expect(msg.content[1].type).toBe("image");
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
test("includes only image block when text is empty", () => {
|
|
177
|
-
const msg = createUserMessage("", [
|
|
176
|
+
test("includes only image block when text is empty", async () => {
|
|
177
|
+
const msg = await createUserMessage("", [
|
|
178
178
|
{ filename: "photo.jpg", mimeType: "image/jpeg", data: "base64img" },
|
|
179
179
|
]);
|
|
180
180
|
|
|
@@ -183,8 +183,8 @@ describe("createUserMessage with image attachments", () => {
|
|
|
183
183
|
expect(msg.content[0].type).toBe("image");
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
-
test("includes only image block when text is whitespace", () => {
|
|
187
|
-
const msg = createUserMessage(" ", [
|
|
186
|
+
test("includes only image block when text is whitespace", async () => {
|
|
187
|
+
const msg = await createUserMessage(" ", [
|
|
188
188
|
{ filename: "photo.jpg", mimeType: "image/jpeg", data: "base64img" },
|
|
189
189
|
]);
|
|
190
190
|
|
|
@@ -193,8 +193,8 @@ describe("createUserMessage with image attachments", () => {
|
|
|
193
193
|
expect(msg.content[0].type).toBe("image");
|
|
194
194
|
});
|
|
195
195
|
|
|
196
|
-
test("includes multiple image blocks", () => {
|
|
197
|
-
const msg = createUserMessage("compare these", [
|
|
196
|
+
test("includes multiple image blocks", async () => {
|
|
197
|
+
const msg = await createUserMessage("compare these", [
|
|
198
198
|
{ filename: "a.jpg", mimeType: "image/jpeg", data: "img1" },
|
|
199
199
|
{ filename: "b.png", mimeType: "image/png", data: "img2" },
|
|
200
200
|
]);
|
|
@@ -206,9 +206,9 @@ describe("createUserMessage with image attachments", () => {
|
|
|
206
206
|
expect(msg.content[2].type).toBe("image");
|
|
207
207
|
});
|
|
208
208
|
|
|
209
|
-
test("preserves base64 data in image content block", () => {
|
|
209
|
+
test("preserves base64 data in image content block", async () => {
|
|
210
210
|
const base64 = "dGVzdC1pbWFnZS1kYXRh";
|
|
211
|
-
const msg = createUserMessage("test", [
|
|
211
|
+
const msg = await createUserMessage("test", [
|
|
212
212
|
{ filename: "photo.jpg", mimeType: "image/jpeg", data: base64 },
|
|
213
213
|
]);
|
|
214
214
|
|
|
@@ -227,7 +227,7 @@ describe("createUserMessage with image attachments", () => {
|
|
|
227
227
|
// ---------------------------------------------------------------------------
|
|
228
228
|
|
|
229
229
|
describe("enrichMessageWithSourcePaths", () => {
|
|
230
|
-
test("appends a source path annotation for images with filePath", () => {
|
|
230
|
+
test("appends a source path annotation for images with filePath", async () => {
|
|
231
231
|
const attachments = [
|
|
232
232
|
{
|
|
233
233
|
filename: "photo.jpg",
|
|
@@ -236,7 +236,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
236
236
|
filePath: "/Users/me/Desktop/photo.jpg",
|
|
237
237
|
},
|
|
238
238
|
];
|
|
239
|
-
const original = createUserMessage("what is this?", attachments);
|
|
239
|
+
const original = await createUserMessage("what is this?", attachments);
|
|
240
240
|
const enriched = enrichMessageWithSourcePaths(original, attachments);
|
|
241
241
|
|
|
242
242
|
expect(enriched).not.toBe(original);
|
|
@@ -249,7 +249,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
249
249
|
);
|
|
250
250
|
});
|
|
251
251
|
|
|
252
|
-
test("returns the original message (same reference) when no images have filePath", () => {
|
|
252
|
+
test("returns the original message (same reference) when no images have filePath", async () => {
|
|
253
253
|
const attachments = [
|
|
254
254
|
{
|
|
255
255
|
filename: "photo.jpg",
|
|
@@ -257,13 +257,13 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
257
257
|
data: "base64img",
|
|
258
258
|
},
|
|
259
259
|
];
|
|
260
|
-
const original = createUserMessage("what is this?", attachments);
|
|
260
|
+
const original = await createUserMessage("what is this?", attachments);
|
|
261
261
|
const result = enrichMessageWithSourcePaths(original, attachments);
|
|
262
262
|
|
|
263
263
|
expect(result).toBe(original);
|
|
264
264
|
});
|
|
265
265
|
|
|
266
|
-
test("skips non-image attachments with filePath", () => {
|
|
266
|
+
test("skips non-image attachments with filePath", async () => {
|
|
267
267
|
const attachments = [
|
|
268
268
|
{
|
|
269
269
|
filename: "doc.pdf",
|
|
@@ -272,14 +272,14 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
272
272
|
filePath: "/Users/me/Documents/doc.pdf",
|
|
273
273
|
},
|
|
274
274
|
];
|
|
275
|
-
const original = createUserMessage("review this", attachments);
|
|
275
|
+
const original = await createUserMessage("review this", attachments);
|
|
276
276
|
const result = enrichMessageWithSourcePaths(original, attachments);
|
|
277
277
|
|
|
278
278
|
// Non-image attachments are not annotated, so we get back the same ref
|
|
279
279
|
expect(result).toBe(original);
|
|
280
280
|
});
|
|
281
281
|
|
|
282
|
-
test("handles multiple images with file paths", () => {
|
|
282
|
+
test("handles multiple images with file paths", async () => {
|
|
283
283
|
const attachments = [
|
|
284
284
|
{
|
|
285
285
|
filename: "a.jpg",
|
|
@@ -294,7 +294,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
294
294
|
filePath: "/path/to/b.png",
|
|
295
295
|
},
|
|
296
296
|
];
|
|
297
|
-
const original = createUserMessage("compare", attachments);
|
|
297
|
+
const original = await createUserMessage("compare", attachments);
|
|
298
298
|
const enriched = enrichMessageWithSourcePaths(original, attachments);
|
|
299
299
|
|
|
300
300
|
expect(enriched).not.toBe(original);
|
|
@@ -307,7 +307,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
307
307
|
);
|
|
308
308
|
});
|
|
309
309
|
|
|
310
|
-
test("only annotates images that have filePath, skips those without", () => {
|
|
310
|
+
test("only annotates images that have filePath, skips those without", async () => {
|
|
311
311
|
const attachments = [
|
|
312
312
|
{
|
|
313
313
|
filename: "a.jpg",
|
|
@@ -322,7 +322,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
322
322
|
// no filePath — e.g. pasted screenshot
|
|
323
323
|
},
|
|
324
324
|
];
|
|
325
|
-
const original = createUserMessage("compare", attachments);
|
|
325
|
+
const original = await createUserMessage("compare", attachments);
|
|
326
326
|
const enriched = enrichMessageWithSourcePaths(original, attachments);
|
|
327
327
|
|
|
328
328
|
expect(enriched).not.toBe(original);
|
|
@@ -332,7 +332,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
332
332
|
expect(annotation.text).toBe("[Attached image source: /path/to/a.jpg]");
|
|
333
333
|
});
|
|
334
334
|
|
|
335
|
-
test("annotates non-image attachments that have storedPath", () => {
|
|
335
|
+
test("annotates non-image attachments that have storedPath", async () => {
|
|
336
336
|
const attachments = [
|
|
337
337
|
{
|
|
338
338
|
filename: "report.pdf",
|
|
@@ -342,7 +342,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
342
342
|
storedPath: "/conv/attachments/report-2.pdf",
|
|
343
343
|
},
|
|
344
344
|
];
|
|
345
|
-
const original = createUserMessage("review my edits", attachments);
|
|
345
|
+
const original = await createUserMessage("review my edits", attachments);
|
|
346
346
|
const enriched = enrichMessageWithSourcePaths(original, attachments);
|
|
347
347
|
|
|
348
348
|
expect(enriched).not.toBe(original);
|
|
@@ -355,7 +355,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
355
355
|
);
|
|
356
356
|
});
|
|
357
357
|
|
|
358
|
-
test("emits image source lines before stored path lines in one block", () => {
|
|
358
|
+
test("emits image source lines before stored path lines in one block", async () => {
|
|
359
359
|
const attachments = [
|
|
360
360
|
{
|
|
361
361
|
filename: "data.csv",
|
|
@@ -371,7 +371,7 @@ describe("enrichMessageWithSourcePaths", () => {
|
|
|
371
371
|
storedPath: "/conv/attachments/photo.jpg",
|
|
372
372
|
},
|
|
373
373
|
];
|
|
374
|
-
const original = createUserMessage("compare", attachments);
|
|
374
|
+
const original = await createUserMessage("compare", attachments);
|
|
375
375
|
const enriched = enrichMessageWithSourcePaths(original, attachments);
|
|
376
376
|
|
|
377
377
|
const annotation = enriched.content.at(-1) as {
|
|
@@ -61,7 +61,7 @@ mock.module("../persistence/conversation-crud.js", () => ({
|
|
|
61
61
|
getConversationPersistedSeq: () => null,
|
|
62
62
|
addMessage: mock(() => ({ id: "msg-1" })),
|
|
63
63
|
archiveConversation: mock(() => true),
|
|
64
|
-
|
|
64
|
+
batchSetConversationPlacement: mock(() => {}),
|
|
65
65
|
createConversation: (opts: { conversationType: string }) => {
|
|
66
66
|
createdConversations.push(opts);
|
|
67
67
|
return { id: "conv-1", ...opts };
|
|
@@ -377,6 +377,8 @@ function setupController(
|
|
|
377
377
|
requiresPcmAudio?: boolean;
|
|
378
378
|
/** Simulate a transport that gates teardown on playback drain. */
|
|
379
379
|
awaitPlaybackDrained?: () => Promise<void>;
|
|
380
|
+
/** Synthesis-language resolver, as the media-stream server wires it. */
|
|
381
|
+
resolveSynthesisLanguage?: () => string | undefined;
|
|
380
382
|
},
|
|
381
383
|
) {
|
|
382
384
|
ensureConversation("conv-ctrl-test");
|
|
@@ -400,6 +402,7 @@ function setupController(
|
|
|
400
402
|
const controller = new CallController(session.id, transport, task ?? null, {
|
|
401
403
|
assistantId: opts?.assistantId,
|
|
402
404
|
trustContext: opts?.trustContext,
|
|
405
|
+
resolveSynthesisLanguage: opts?.resolveSynthesisLanguage,
|
|
403
406
|
});
|
|
404
407
|
return { session, relay: transport, controller };
|
|
405
408
|
}
|
|
@@ -3470,6 +3473,123 @@ describe("call-controller", () => {
|
|
|
3470
3473
|
controller.destroy();
|
|
3471
3474
|
});
|
|
3472
3475
|
|
|
3476
|
+
test("synthesized provider: the resolved language rides every segment's synthesis request", async () => {
|
|
3477
|
+
const requestLanguages: Array<string | undefined> = [];
|
|
3478
|
+
registerFishAudioSegmentRecorder({
|
|
3479
|
+
onSynthesizeStream: async (_text, request) => {
|
|
3480
|
+
requestLanguages.push(request.language);
|
|
3481
|
+
},
|
|
3482
|
+
});
|
|
3483
|
+
mockStartVoiceTurn.mockImplementation(
|
|
3484
|
+
createMockVoiceTurn(["Hola desde aqui. ", "Segunda frase."]),
|
|
3485
|
+
);
|
|
3486
|
+
const { controller } = setupController(undefined, {
|
|
3487
|
+
resolveSynthesisLanguage: () => "es",
|
|
3488
|
+
});
|
|
3489
|
+
|
|
3490
|
+
await controller.handleCallerUtterance("Hola");
|
|
3491
|
+
|
|
3492
|
+
expect(requestLanguages).toEqual(["es", "es"]);
|
|
3493
|
+
|
|
3494
|
+
controller.destroy();
|
|
3495
|
+
});
|
|
3496
|
+
|
|
3497
|
+
test("synthesized provider: no language on the request when nothing resolves", async () => {
|
|
3498
|
+
const requestLanguages: Array<string | undefined> = [];
|
|
3499
|
+
registerFishAudioSegmentRecorder({
|
|
3500
|
+
onSynthesizeStream: async (_text, request) => {
|
|
3501
|
+
requestLanguages.push(request.language);
|
|
3502
|
+
},
|
|
3503
|
+
});
|
|
3504
|
+
mockStartVoiceTurn.mockImplementation(
|
|
3505
|
+
createMockVoiceTurn(["Hello from here."]),
|
|
3506
|
+
);
|
|
3507
|
+
// Default resolver + default config (multilingual STT pin): no hint.
|
|
3508
|
+
const { controller } = setupController();
|
|
3509
|
+
|
|
3510
|
+
await controller.handleCallerUtterance("Hi");
|
|
3511
|
+
|
|
3512
|
+
expect(requestLanguages).toEqual([undefined]);
|
|
3513
|
+
|
|
3514
|
+
controller.destroy();
|
|
3515
|
+
});
|
|
3516
|
+
|
|
3517
|
+
function registerDeepgramRequestRecorder(): {
|
|
3518
|
+
requests: Array<{ voiceId?: string; language?: string }>;
|
|
3519
|
+
} {
|
|
3520
|
+
const cfg = loadConfig();
|
|
3521
|
+
cfg.services.tts.provider = "deepgram";
|
|
3522
|
+
|
|
3523
|
+
_resetTtsProviderOverridesForTests();
|
|
3524
|
+
const requests: Array<{ voiceId?: string; language?: string }> = [];
|
|
3525
|
+
const deepgramRecorder: TtsProvider = {
|
|
3526
|
+
id: "deepgram",
|
|
3527
|
+
capabilities: {
|
|
3528
|
+
supportsStreaming: false,
|
|
3529
|
+
supportedFormats: ["mp3", "wav", "opus"],
|
|
3530
|
+
},
|
|
3531
|
+
async synthesize(request) {
|
|
3532
|
+
requests.push({
|
|
3533
|
+
voiceId: request.voiceId,
|
|
3534
|
+
language: request.language,
|
|
3535
|
+
});
|
|
3536
|
+
return { audio: Buffer.from("audio"), contentType: "audio/mpeg" };
|
|
3537
|
+
},
|
|
3538
|
+
};
|
|
3539
|
+
_setTtsProviderForTests(deepgramRecorder);
|
|
3540
|
+
return { requests };
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3543
|
+
test("synthesized provider: a configured languageVoices entry for the call language rides the request as voiceId", async () => {
|
|
3544
|
+
const cfg = loadConfig();
|
|
3545
|
+
cfg.services.tts.providers.deepgram.languageVoices = {
|
|
3546
|
+
hi: "aura-2-hindi-voice",
|
|
3547
|
+
};
|
|
3548
|
+
try {
|
|
3549
|
+
const { requests } = registerDeepgramRequestRecorder();
|
|
3550
|
+
mockStartVoiceTurn.mockImplementation(
|
|
3551
|
+
createMockVoiceTurn(["Namaste doston."]),
|
|
3552
|
+
);
|
|
3553
|
+
const { controller } = setupController(undefined, {
|
|
3554
|
+
resolveSynthesisLanguage: () => "hi",
|
|
3555
|
+
});
|
|
3556
|
+
|
|
3557
|
+
await controller.handleCallerUtterance("Namaste");
|
|
3558
|
+
|
|
3559
|
+
expect(requests).toEqual([
|
|
3560
|
+
{ voiceId: "aura-2-hindi-voice", language: "hi" },
|
|
3561
|
+
]);
|
|
3562
|
+
|
|
3563
|
+
controller.destroy();
|
|
3564
|
+
} finally {
|
|
3565
|
+
delete cfg.services.tts.providers.deepgram.languageVoices;
|
|
3566
|
+
}
|
|
3567
|
+
});
|
|
3568
|
+
|
|
3569
|
+
test("synthesized provider: no voiceId when languageVoices has no entry for the call language", async () => {
|
|
3570
|
+
const cfg = loadConfig();
|
|
3571
|
+
cfg.services.tts.providers.deepgram.languageVoices = {
|
|
3572
|
+
hi: "aura-2-hindi-voice",
|
|
3573
|
+
};
|
|
3574
|
+
try {
|
|
3575
|
+
const { requests } = registerDeepgramRequestRecorder();
|
|
3576
|
+
mockStartVoiceTurn.mockImplementation(
|
|
3577
|
+
createMockVoiceTurn(["Hola desde aqui."]),
|
|
3578
|
+
);
|
|
3579
|
+
const { controller } = setupController(undefined, {
|
|
3580
|
+
resolveSynthesisLanguage: () => "es",
|
|
3581
|
+
});
|
|
3582
|
+
|
|
3583
|
+
await controller.handleCallerUtterance("Hola");
|
|
3584
|
+
|
|
3585
|
+
expect(requests).toEqual([{ voiceId: undefined, language: "es" }]);
|
|
3586
|
+
|
|
3587
|
+
controller.destroy();
|
|
3588
|
+
} finally {
|
|
3589
|
+
delete cfg.services.tts.providers.deepgram.languageVoices;
|
|
3590
|
+
}
|
|
3591
|
+
});
|
|
3592
|
+
|
|
3473
3593
|
test("synthesized provider: segments synthesize serially in order even when the first is slow", async () => {
|
|
3474
3594
|
const events: string[] = [];
|
|
3475
3595
|
registerFishAudioSegmentRecorder({
|
|
@@ -40,10 +40,24 @@ const realGatewaySessionsModule = {
|
|
|
40
40
|
};
|
|
41
41
|
mock.module("../channels/gateway-verification-sessions.js", () => ({
|
|
42
42
|
...realGatewaySessionsModule,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// Honours the caller's filter: the guard asks for the number it is about
|
|
44
|
+
// to dial, so a session for a different number must read as absent.
|
|
45
|
+
findActiveSession: async (
|
|
46
|
+
channel: string,
|
|
47
|
+
filter?: { expectedExternalUserId?: string },
|
|
48
|
+
) => {
|
|
49
|
+
if (!findActiveSessionMockActive) {
|
|
50
|
+
return realGatewaySessionsModule.findActiveSession(channel, filter);
|
|
51
|
+
}
|
|
52
|
+
const wanted = filter?.expectedExternalUserId;
|
|
53
|
+
if (
|
|
54
|
+
wanted !== undefined &&
|
|
55
|
+
activeVoiceSession?.expectedPhoneE164 !== wanted
|
|
56
|
+
) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return activeVoiceSession;
|
|
60
|
+
},
|
|
47
61
|
}));
|
|
48
62
|
|
|
49
63
|
const { executeCallStart } = await import("../tools/calls/call-start.js");
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The canned-reply routes (canned first greeting, unknown slash command) hold
|
|
3
|
+
* the processing lock themselves and release it from a deferred callback that
|
|
4
|
+
* also publishes their client event burst. That release is the only one those
|
|
5
|
+
* turns get: no agent loop runs, so a throw escaping the burst would latch the
|
|
6
|
+
* conversation "processing" for the life of the daemon and queue every later
|
|
7
|
+
* send behind an idle conversation.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, expect, test } from "bun:test";
|
|
10
|
+
|
|
11
|
+
import type { QueueDrainReason } from "../daemon/conversation-queue-manager.js";
|
|
12
|
+
import { scheduleCannedReplyRelease } from "../runtime/routes/canned-reply-release.js";
|
|
13
|
+
|
|
14
|
+
function makeConversation() {
|
|
15
|
+
let processing = true;
|
|
16
|
+
const drainOrigins: string[] = [];
|
|
17
|
+
return {
|
|
18
|
+
isProcessing: () => processing,
|
|
19
|
+
drainOrigins,
|
|
20
|
+
target: {
|
|
21
|
+
setProcessing: (value: boolean) => {
|
|
22
|
+
processing = value;
|
|
23
|
+
},
|
|
24
|
+
kickDrainQueue: (_reason?: QueueDrainReason, origin?: string) => {
|
|
25
|
+
drainOrigins.push(origin ?? "");
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Let the scheduled `setTimeout(..., 0)` callback run. */
|
|
33
|
+
function nextTick(): Promise<void> {
|
|
34
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe("scheduleCannedReplyRelease", () => {
|
|
38
|
+
test("releases and drains after the deferred event burst", async () => {
|
|
39
|
+
const conversation = makeConversation();
|
|
40
|
+
const order: string[] = [];
|
|
41
|
+
|
|
42
|
+
scheduleCannedReplyRelease({
|
|
43
|
+
conversation: {
|
|
44
|
+
setProcessing: (value: boolean) => {
|
|
45
|
+
order.push("release");
|
|
46
|
+
conversation.target.setProcessing(value);
|
|
47
|
+
},
|
|
48
|
+
kickDrainQueue: conversation.target.kickDrainQueue,
|
|
49
|
+
},
|
|
50
|
+
origin: "canned_greeting",
|
|
51
|
+
emit: () => {
|
|
52
|
+
order.push("emit");
|
|
53
|
+
},
|
|
54
|
+
afterRelease: () => {
|
|
55
|
+
order.push("after");
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Nothing runs synchronously: the HTTP response has to reach the client
|
|
60
|
+
// before its events do.
|
|
61
|
+
expect(order).toEqual([]);
|
|
62
|
+
|
|
63
|
+
await nextTick();
|
|
64
|
+
|
|
65
|
+
expect(order).toEqual(["emit", "release", "after"]);
|
|
66
|
+
expect(conversation.isProcessing()).toBe(false);
|
|
67
|
+
expect(conversation.drainOrigins).toEqual(["canned_greeting"]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("still releases and drains when a broadcast throws", async () => {
|
|
71
|
+
const conversation = makeConversation();
|
|
72
|
+
|
|
73
|
+
scheduleCannedReplyRelease({
|
|
74
|
+
conversation: conversation.target,
|
|
75
|
+
origin: "slash_command",
|
|
76
|
+
emit: () => {
|
|
77
|
+
throw new Error("broadcast exploded");
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await nextTick();
|
|
82
|
+
|
|
83
|
+
expect(conversation.isProcessing()).toBe(false);
|
|
84
|
+
expect(conversation.drainOrigins).toEqual(["slash_command"]);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -57,6 +57,8 @@ const handler = ROUTES[0]!.handler;
|
|
|
57
57
|
|
|
58
58
|
interface ChannelEntry {
|
|
59
59
|
id: string;
|
|
60
|
+
/** `default` here, `plugin:<name>` for a channel a plugin brings. */
|
|
61
|
+
source: string;
|
|
60
62
|
label: string;
|
|
61
63
|
subtitle: string;
|
|
62
64
|
icon: string;
|
|
@@ -173,10 +175,21 @@ describe("channels/available", () => {
|
|
|
173
175
|
for (const channel of result.channels) {
|
|
174
176
|
const expected = (CHANNEL_METADATA as any)[channel.id];
|
|
175
177
|
expect(expected).toBeDefined();
|
|
176
|
-
|
|
178
|
+
// Plus `source`, which the metadata does not carry: it says who
|
|
179
|
+
// contributes the row, and every row here comes from the assistant.
|
|
180
|
+
expect(channel).toEqual({ ...expected, source: "default" });
|
|
177
181
|
}
|
|
178
182
|
});
|
|
179
183
|
|
|
184
|
+
test("marks every channel the assistant ships as its own", async () => {
|
|
185
|
+
// The base list is what a client compares a plugin-contributed row
|
|
186
|
+
// against, so the marker has to be present rather than implied by an
|
|
187
|
+
// absent field.
|
|
188
|
+
const result = (await handler({})) as HandlerResult;
|
|
189
|
+
|
|
190
|
+
expect(result.channels.every((c) => c.source === "default")).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
|
|
180
193
|
test("email metadata: not verification-capable, mail icon", async () => {
|
|
181
194
|
mockEmailAddressesResponse = {
|
|
182
195
|
ok: true,
|