@vellumai/assistant 0.12.1-staging.1 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +0 -4
- package/ARCHITECTURE.md +12 -11
- package/docs/architecture/turn-actor.md +8 -15
- package/openapi.yaml +1 -291
- package/package.json +1 -1
- package/src/__tests__/always-loaded-tools-guard.test.ts +10 -18
- package/src/__tests__/app-compiler.test.ts +0 -6
- package/src/__tests__/app-control-tool-schemas.test.ts +2 -5
- package/src/__tests__/app-dir-path-guard.test.ts +3 -1
- package/src/__tests__/app-source-watcher.test.ts +218 -0
- package/src/{calls/__tests__ → __tests__}/call-controller.test.ts +82 -503
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +2 -5
- package/src/__tests__/computer-use-tools.test.ts +5 -17
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +29 -28
- package/src/__tests__/config-watcher-skill-reseed.test.ts +359 -0
- package/src/__tests__/config-watcher.test.ts +8 -23
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +0 -26
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -4
- package/src/__tests__/conversation-queue.test.ts +207 -48
- package/src/__tests__/conversation-retry-discard.test.ts +1 -54
- package/src/__tests__/conversation-skill-tools.test.ts +0 -27
- package/src/__tests__/conversation-surfaces-app-control.test.ts +3 -8
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -67
- package/src/__tests__/conversation-title-service.test.ts +10 -14
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +5 -3
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -51
- package/src/__tests__/credential-record-retire.test.ts +1 -171
- package/src/__tests__/credential-routes.test.ts +3 -212
- package/src/__tests__/credential-security-invariants.test.ts +1 -2
- package/src/__tests__/cu-unified-flow.test.ts +2 -8
- package/src/__tests__/drain-kick-guard.test.ts +2 -0
- package/src/__tests__/drain-requeue-on-contention.test.ts +6 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/host-bash-proxy.test.ts +45 -26
- package/src/__tests__/host-browser-proxy.test.ts +17 -6
- package/src/__tests__/host-file-proxy-targeted.test.ts +0 -23
- package/src/__tests__/host-file-proxy.test.ts +23 -11
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +9 -30
- package/src/__tests__/llm-catalog-parity.test.ts +0 -25
- package/src/__tests__/mcp-auth-routes.test.ts +9 -6
- package/src/__tests__/mcp-config-secret-boundary.test.ts +136 -78
- package/src/__tests__/mcp-health-check.test.ts +11 -8
- package/src/__tests__/mcp-list-plugin-servers.test.ts +10 -8
- package/src/{calls/__tests__ → __tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{calls/__tests__ → __tests__}/media-stream-output.test.ts +8 -37
- package/src/{calls/__tests__ → __tests__}/media-stream-parser.test.ts +1 -1
- package/src/{calls/__tests__ → __tests__}/media-stream-server-integration.test.ts +57 -150
- package/src/{calls/__tests__ → __tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{calls/__tests__ → __tests__}/media-turn-detector.test.ts +1 -1
- package/src/__tests__/messages-after-tiebreaker.test.ts +0 -91
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +548 -355
- package/src/__tests__/model-intents.test.ts +0 -3
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-client-verify-credential.test.ts +0 -2
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -13
- package/src/__tests__/script-proxy-certs.test.ts +0 -35
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/speaker-identification.test.ts +56 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +3 -19
- package/src/__tests__/subagent-tools.test.ts +2 -3
- package/src/__tests__/telephony-tts-guard.test.ts +3 -38
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -4
- package/src/{calls/__tests__/voice-session-bridge-turn-flow.test.ts → __tests__/voice-session-bridge.test.ts} +12 -20
- package/src/__tests__/watch-retro-tool-availability.test.ts +17 -8
- package/src/__tests__/workspace-git-service.test.ts +0 -26
- package/src/acp/__tests__/agent-process.test.ts +4 -258
- package/src/acp/__tests__/auth-required.test.ts +0 -96
- package/src/acp/__tests__/client-handler.test.ts +2 -90
- package/src/acp/__tests__/session-manager-persistence.test.ts +1 -5
- package/src/acp/__tests__/session-manager-resume.test.ts +6 -270
- package/src/acp/__tests__/session-manager-usage.test.ts +2 -4
- package/src/acp/__tests__/session-manager.test.ts +4 -895
- package/src/acp/agent-process.test.ts +1 -4
- package/src/acp/agent-process.ts +9 -94
- package/src/acp/auth-required.ts +1 -50
- package/src/acp/auto-install.test.ts +7 -9
- package/src/acp/client-handler.ts +3 -16
- package/src/acp/resolve-agent.test.ts +6 -220
- package/src/acp/resolve-agent.ts +23 -88
- package/src/acp/session-manager.test.ts +3 -196
- package/src/acp/session-manager.ts +18 -441
- package/src/acp/types.ts +5 -50
- package/src/api/events/app-files-changed.ts +3 -4
- package/src/api/index.ts +0 -6
- package/src/apps/app-store.ts +1 -1
- package/src/bundler/app-compiler.ts +0 -15
- package/src/calls/__tests__/voice-control-protocol.test.ts +25 -58
- package/src/calls/__tests__/voice-session-bridge.test.ts +1 -37
- package/src/calls/__tests__/voice-triage-escalate.test.ts +0 -105
- package/src/calls/call-constants.ts +4 -24
- package/src/calls/call-controller.ts +199 -499
- package/src/calls/call-transport.ts +0 -16
- package/src/calls/media-stream-output.ts +0 -32
- package/src/calls/media-stream-server.ts +30 -82
- package/src/calls/media-stream-stt-session.ts +0 -15
- package/src/calls/resolve-call-tts-provider.ts +2 -33
- package/src/calls/speaker-identification.ts +233 -0
- package/src/calls/tts-call-strategy.ts +5 -9
- package/src/calls/types.ts +0 -2
- package/src/calls/voice-control-protocol.ts +21 -53
- package/src/calls/voice-session-bridge.ts +46 -59
- package/src/calls/voice-triage-escalate.ts +56 -175
- package/src/cli/commands/apps.help.ts +13 -67
- package/src/cli/commands/apps.ts +0 -183
- package/src/cli/commands/channels/index.help.ts +2 -70
- package/src/cli/commands/channels/index.ts +3 -16
- package/src/cli/commands/credentials.help.ts +2 -6
- package/src/cli/commands/credentials.ts +2 -2
- package/src/cli/commands/mcp.help.ts +8 -8
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/roadmap.help.ts +1 -5
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +90 -103
- package/src/config/__tests__/default-profile-catalog.test.ts +0 -22
- package/src/config/__tests__/memory-retrospective-schema.test.ts +1 -15
- package/src/config/__tests__/platform-rehydration.test.ts +0 -93
- package/src/config/acp-defaults.test.ts +3 -13
- package/src/config/acp-defaults.ts +6 -23
- package/src/config/acp-schema.ts +2 -30
- package/src/config/bundled-skills/acp/SKILL.md +14 -22
- package/src/config/bundled-skills/acp/TOOLS.json +1 -5
- package/src/config/bundled-skills/app-builder/SKILL.md +9 -12
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +139 -67
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/screen-annotation/SKILL.md +1 -8
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +1 -4
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +12 -8
- package/src/config/memory-v3-gate.test.ts +0 -31
- package/src/config/memory-v3-gate.ts +16 -20
- package/src/config/platform-rehydration.ts +21 -75
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +158 -8
- package/src/config/schemas/calls.ts +28 -1
- package/src/config/schemas/live-voice.ts +173 -1
- package/src/config/schemas/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +0 -10
- package/src/config/schemas/skills.ts +14 -0
- package/src/credential-execution/process-manager.test.ts +19 -18
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +121 -66
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +1 -4
- package/src/daemon/app-source-watcher.ts +218 -0
- package/src/daemon/config-watcher.ts +194 -13
- package/src/daemon/conversation-process.ts +64 -35
- package/src/daemon/conversation-skill-tools.ts +31 -13
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +8 -10
- package/src/daemon/conversation-tool-setup.ts +43 -37
- package/src/daemon/conversation.ts +3 -0
- package/src/daemon/host-bash-proxy.ts +12 -8
- package/src/daemon/host-browser-proxy.ts +1 -15
- package/src/daemon/host-file-proxy.ts +10 -8
- package/src/daemon/host-transfer-proxy.ts +18 -14
- package/src/daemon/lifecycle.ts +5 -0
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/shutdown-handlers.ts +9 -1
- package/src/daemon/skill-memory-refresh.ts +0 -64
- package/src/daemon/tool-side-effects.ts +18 -7
- package/src/hooks/types.ts +0 -33
- package/src/inbound/platform-callback-registration.ts +5 -4
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +3 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/{calls → live-voice}/__tests__/progress-narration.test.ts +4 -4
- package/src/{calls → live-voice}/__tests__/progress-phrases.test.ts +1 -1
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +69 -13
- package/src/live-voice/live-voice-session.ts +693 -213
- package/src/{calls → live-voice}/progress-narration.ts +2 -2
- package/src/live-voice/protocol.ts +2 -0
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +45 -29
- package/src/mcp/startup.ts +4 -8
- package/src/messaging/provider.ts +3 -10
- package/src/messaging/providers/callback-routing.ts +0 -18
- package/src/messaging/providers/channel-transport.ts +0 -56
- package/src/messaging/providers/discord/transport.ts +0 -17
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +17 -6
- package/src/messaging/providers/slack/adapter.ts +44 -7
- package/src/messaging/providers/slack/transport.ts +0 -16
- package/src/messaging/providers/telegram-bot/adapter.ts +48 -1
- package/src/messaging/providers/telegram-bot/client.ts +26 -0
- package/src/messaging/providers/telegram-bot/transport.ts +0 -20
- package/src/messaging/providers/whatsapp/adapter.ts +48 -1
- package/src/messaging/providers/whatsapp/client.ts +29 -0
- package/src/messaging/providers/whatsapp/transport.ts +0 -18
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +0 -8
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +0 -55
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +3 -153
- package/src/notifications/assistant-reply-producer.ts +3 -8
- package/src/notifications/conversation-pairing.ts +16 -36
- package/src/notifications/delivered-post-record.ts +1 -11
- package/src/notifications/home-feed-side-effect.ts +7 -55
- package/src/outbound-proxy/certs.ts +5 -3
- package/src/permissions/checker.test.ts +6 -11
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +63 -71
- package/src/persistence/conversation-lineage.ts +4 -12
- package/src/persistence/conversation-title-service.ts +26 -9
- package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
- package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
- package/src/persistence/message-reads.ts +0 -30
- package/src/persistence/migrations/157-invite-contact-id.ts +6 -18
- package/src/persistence/schema/memory-core.ts +0 -5
- package/src/platform/client.test.ts +0 -2
- package/src/platform/client.ts +10 -2
- package/src/plugin-api/constants.ts +0 -2
- package/src/plugin-api/index.ts +0 -1
- package/src/plugin-api/types.ts +0 -2
- package/src/plugins/defaults/index.ts +0 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +0 -46
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +5 -9
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +10 -20
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +0 -219
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +0 -31
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -63
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +0 -4
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -4
- package/src/plugins/defaults/memory/hooks/init.ts +0 -10
- package/src/plugins/defaults/memory/hooks/shutdown.ts +0 -2
- package/src/plugins/defaults/memory/jobs-worker.ts +0 -13
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +60 -34
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +5 -3
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -12
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +71 -312
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +1 -2
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +3 -5
- package/src/plugins/defaults/memory/startup.ts +1 -6
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +9 -7
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +0 -89
- package/src/plugins/defaults/memory/worker.ts +0 -6
- package/src/plugins/mcp-servers.ts +75 -15
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/gemini/client.ts +23 -9
- package/src/providers/model-catalog.ts +0 -34
- package/src/providers/model-intents.ts +5 -10
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +18 -146
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +1 -83
- package/src/providers/openai/chat-completions-provider.ts +78 -192
- package/src/providers/openai/codex-models.ts +4 -0
- package/src/runtime/AGENTS.md +0 -2
- package/src/runtime/auth/same-actor.ts +3 -38
- package/src/runtime/http-server.ts +151 -160
- package/src/runtime/routes/__tests__/acp-routes.test.ts +4 -159
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -108
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +12 -16
- package/src/runtime/routes/acp-routes.test.ts +0 -15
- package/src/runtime/routes/acp-routes.ts +9 -72
- package/src/runtime/routes/app-management-routes.ts +0 -73
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +0 -40
- package/src/runtime/routes/credential-routes.ts +10 -19
- package/src/runtime/routes/diagnostics-routes.ts +3 -55
- package/src/runtime/routes/index.ts +0 -4
- package/src/runtime/routes/log-export-routes.ts +0 -2
- package/src/runtime/routes/mcp-auth-routes.ts +47 -39
- package/src/runtime/routes/migration-routes.ts +21 -8
- package/src/runtime/routes/platform-routes.ts +15 -18
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -28
- package/src/runtime/services/conversation-serializer.ts +3 -16
- package/src/runtime/sync/resource-sync-events.ts +1 -2
- package/src/schedule/worker.ts +1 -1
- package/src/security/ces-rpc-record-backend.ts +0 -7
- package/src/subagent/consult-context.ts +25 -12
- package/src/tools/acp/list-agents.test.ts +1 -3
- package/src/tools/acp/spawn.test.ts +11 -146
- package/src/tools/acp/spawn.ts +3 -21
- package/src/tools/acp/status.ts +3 -40
- package/src/tools/app-control/skill-proxy-bridge.ts +1 -2
- package/src/tools/capability-offer.test.ts +2 -22
- package/src/tools/capability-offer.ts +1 -16
- package/src/tools/computer-use/definitions.ts +2 -4
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -2
- package/src/tools/credentials/metadata-store.ts +0 -100
- package/src/tools/host-filesystem/edit.test.ts +1 -2
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +1 -2
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +1 -2
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +1 -2
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +0 -16
- package/src/tools/host-terminal/host-shell.ts +20 -4
- package/src/tools/policy-context.ts +7 -6
- package/src/tools/subagent/spawn.ts +8 -5
- package/src/tools/watch/watch-retro-report.ts +8 -0
- package/src/util/__tests__/language-subtag.test.ts +1 -23
- package/src/util/fs-watcher-error.ts +36 -0
- package/src/util/language-subtag.ts +0 -16
- package/src/util/platform.ts +0 -8
- package/src/workspace/git-service.ts +54 -5
- package/src/workspace/migrations/registry.ts +0 -6
- package/scripts/smoke-desktop-window-theme.ts +0 -186
- package/src/__tests__/git-porcelain.test.ts +0 -47
- package/src/__tests__/helpers/set-workspace-mcp.ts +0 -11
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +0 -119
- package/src/__tests__/resolve-app.test.ts +0 -135
- package/src/__tests__/source-fingerprint.test.ts +0 -184
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +0 -336
- package/src/acp/__tests__/helpers/acp-model-option.ts +0 -51
- package/src/acp/model-config.test.ts +0 -166
- package/src/acp/model-config.ts +0 -138
- package/src/api/events/acp-session-model-update.test.ts +0 -88
- package/src/api/events/acp-session-model-update.ts +0 -46
- package/src/apps/resolve-app.ts +0 -81
- package/src/apps/source-fingerprint.ts +0 -266
- package/src/calls/__tests__/barge-in-guard.test.ts +0 -81
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +0 -229
- package/src/calls/__tests__/voice-progress-cadence.test.ts +0 -274
- package/src/calls/barge-in-guard.ts +0 -118
- package/src/calls/voice-leg-coordinator.ts +0 -189
- package/src/calls/voice-progress-cadence.ts +0 -423
- package/src/cli/commands/__tests__/apps.test.ts +0 -245
- package/src/cli/commands/__tests__/roadmap.help.test.ts +0 -19
- package/src/cli/commands/channels/__tests__/send.test.ts +0 -218
- package/src/cli/commands/channels/send.ts +0 -128
- package/src/config/__tests__/platform-identity.test.ts +0 -117
- package/src/config/acp-agent-write.ts +0 -43
- package/src/config/acp-schema.test.ts +0 -81
- package/src/config/platform-identity.ts +0 -144
- package/src/config/schemas/__tests__/voice.test.ts +0 -148
- package/src/config/schemas/voice.ts +0 -150
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +0 -133
- package/src/daemon/app-change-notify.ts +0 -45
- package/src/desktop/__tests__/fake-desktop.ts +0 -119
- package/src/desktop/desktop-chrome-policy.test.ts +0 -71
- package/src/desktop/desktop-chrome-policy.ts +0 -42
- package/src/desktop/desktop-dependencies.test.ts +0 -102
- package/src/desktop/desktop-dependencies.ts +0 -306
- package/src/desktop/desktop-feature.test.ts +0 -18
- package/src/desktop/desktop-feature.ts +0 -19
- package/src/desktop/desktop-panel-config.test.ts +0 -135
- package/src/desktop/desktop-panel-config.ts +0 -149
- package/src/desktop/desktop-session-manager.test.ts +0 -627
- package/src/desktop/desktop-session-manager.ts +0 -814
- package/src/desktop/desktop-stream-bridge.test.ts +0 -395
- package/src/desktop/desktop-stream-bridge.ts +0 -214
- package/src/desktop/desktop-wallpaper.test.ts +0 -191
- package/src/desktop/desktop-wallpaper.ts +0 -113
- package/src/desktop/desktop-window-theme.ts +0 -170
- package/src/i18n/AGENTS.md +0 -22
- package/src/i18n/__tests__/i18n.test.ts +0 -108
- package/src/i18n/index.ts +0 -16
- package/src/i18n/locales.ts +0 -93
- package/src/i18n/messages.ts +0 -61
- package/src/i18n/title.ts +0 -25
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +0 -135
- package/src/mcp/spec-schema.ts +0 -111
- package/src/mcp/workspace-mcp-config.ts +0 -188
- package/src/messaging/providers/__tests__/proactive-address.test.ts +0 -95
- package/src/persistence/conversation-title-placeholders.ts +0 -23
- package/src/persistence/message-cursor.ts +0 -78
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +0 -149
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +0 -118
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +0 -83
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +0 -21
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +0 -126
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +0 -79
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +0 -28
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +0 -9
- package/src/providers/gemini-thought-signature.test.ts +0 -63
- package/src/providers/gemini-thought-signature.ts +0 -44
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +0 -613
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +0 -235
- package/src/providers/openai/google-thought-signature.ts +0 -320
- package/src/runtime/__tests__/channel-send.test.ts +0 -443
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +0 -89
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +0 -58
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +0 -72
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +0 -59
- package/src/runtime/channel-send.ts +0 -316
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +0 -205
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +0 -127
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +0 -107
- package/src/runtime/routes/channel-send-routes.ts +0 -85
- package/src/runtime/routes/desktop-setup-routes.test.ts +0 -74
- package/src/runtime/routes/desktop-setup-routes.ts +0 -35
- package/src/security/__tests__/ces-http-record-backend.test.ts +0 -137
- package/src/security/ces-http-record-backend.ts +0 -120
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +0 -60
- package/src/skills/workspace-skill-md-signature.ts +0 -50
- package/src/tools/acp/status.test.ts +0 -94
- package/src/util/ca-bundle.ts +0 -13
- package/src/workspace/git-porcelain.ts +0 -66
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +0 -258
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +0 -78
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +0 -214
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +0 -102
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +0 -199
- /package/src/{calls → live-voice}/progress-phrases.ts +0 -0
package/src/acp/types.ts
CHANGED
|
@@ -4,20 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
import type { StopReason } from "@agentclientprotocol/sdk";
|
|
6
6
|
|
|
7
|
-
import type { AcpAgentConfig as ConfiguredAcpAgent } from "../config/acp-schema.js";
|
|
8
|
-
import type { AcpModelOption } from "./model-config.js";
|
|
9
|
-
|
|
10
7
|
/**
|
|
11
|
-
*
|
|
12
|
-
* The configured half is the schema's own inferred type, so a new config leaf
|
|
13
|
-
* is declared once, in `config/acp-schema.ts`.
|
|
8
|
+
* Configuration for a single ACP agent process.
|
|
14
9
|
*/
|
|
15
|
-
export interface AcpAgentConfig
|
|
16
|
-
/**
|
|
17
|
-
* Always set on a resolved agent: the resolver fills in a bundled profile's
|
|
18
|
-
* command when the config entry omits it.
|
|
19
|
-
*/
|
|
10
|
+
export interface AcpAgentConfig {
|
|
20
11
|
command: string;
|
|
12
|
+
args: string[];
|
|
13
|
+
description?: string;
|
|
14
|
+
env?: Record<string, string>;
|
|
21
15
|
/**
|
|
22
16
|
* Identity of the Claude token `prepareAgentEnv` resolved into `env`,
|
|
23
17
|
* whichever source it came from. Recorded on the history row when Claude
|
|
@@ -57,32 +51,6 @@ export interface AcpSessionState {
|
|
|
57
51
|
authErrorCredential?: string;
|
|
58
52
|
/** Latest context-window usage gauge, from the most recent `usage_update`. */
|
|
59
53
|
latestUsage?: AcpUsageSnapshot;
|
|
60
|
-
/**
|
|
61
|
-
* Model the session is running on, as the adapter reports it. Absent while
|
|
62
|
-
* the adapter advertises no model selector, which is how the feature stays
|
|
63
|
-
* invisible for agents that cannot switch models.
|
|
64
|
-
*/
|
|
65
|
-
model?: string;
|
|
66
|
-
/** Models the adapter offers this session, flattened from its selector. */
|
|
67
|
-
availableModels?: AcpModelOption[];
|
|
68
|
-
/** Time-ordered identifier of the assistant process issuing revisions. */
|
|
69
|
-
modelRevisionEpoch?: string;
|
|
70
|
-
/** Monotonic revision within `modelRevisionEpoch`. */
|
|
71
|
-
modelRevision?: number;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Statuses a session is still live in. One list for every place that asks the
|
|
76
|
-
* question: the boot sweep over persisted rows, the in-memory liveness guard,
|
|
77
|
-
* `close()`, and the delete route's conflict guard.
|
|
78
|
-
*/
|
|
79
|
-
export const ACP_LIVE_STATUSES = ["running", "initializing"] as const;
|
|
80
|
-
|
|
81
|
-
/** Whether a status is one a session can still move from. */
|
|
82
|
-
export function isLiveAcpStatus(
|
|
83
|
-
status: AcpSessionState["status"],
|
|
84
|
-
): status is (typeof ACP_LIVE_STATUSES)[number] {
|
|
85
|
-
return ACP_LIVE_STATUSES.some((live) => live === status);
|
|
86
54
|
}
|
|
87
55
|
|
|
88
56
|
/** Context-window usage snapshot tracked from ACP `usage_update`. */
|
|
@@ -96,16 +64,3 @@ export interface AcpUsageSnapshot {
|
|
|
96
64
|
/** Cumulative output tokens across all turns, from `PromptResponse.usage`. */
|
|
97
65
|
outputTokens?: number;
|
|
98
66
|
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* The adapter answered `session/set_config_option` with an error: the value
|
|
102
|
-
* was refused. Raised only for the adapter's own answer to that request, so a
|
|
103
|
-
* closed connection, an exited process, or a failed authentication is never
|
|
104
|
-
* mistaken for a refusal.
|
|
105
|
-
*/
|
|
106
|
-
export class AcpConfigOptionRefusedError extends Error {
|
|
107
|
-
constructor(message: string) {
|
|
108
|
-
super(message);
|
|
109
|
-
this.name = "AcpConfigOptionRefusedError";
|
|
110
|
-
}
|
|
111
|
-
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `app_files_changed` SSE event.
|
|
3
3
|
*
|
|
4
|
-
* Broadcast
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `app_refresh`; file edits do not emit this on their own.
|
|
4
|
+
* Broadcast when an app's source files change on disk — emitted when a new
|
|
5
|
+
* app is created and by the app source watcher on edits — so connected
|
|
6
|
+
* clients re-read the app (refresh preview, reload the running surface).
|
|
8
7
|
*
|
|
9
8
|
* Canonical wire-contract source. Daemon code imports the type
|
|
10
9
|
* directly from this file; external consumers import via
|
package/src/api/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { z } from "zod";
|
|
|
3
3
|
import { AcpAuthRequiredEventSchema } from "./events/acp-auth-required.js";
|
|
4
4
|
import { AcpSessionCompletedEventSchema } from "./events/acp-session-completed.js";
|
|
5
5
|
import { AcpSessionErrorEventSchema } from "./events/acp-session-error.js";
|
|
6
|
-
import { AcpSessionModelUpdateEventSchema } from "./events/acp-session-model-update.js";
|
|
7
6
|
import { AcpSessionSpawnedEventSchema } from "./events/acp-session-spawned.js";
|
|
8
7
|
import { AcpSessionUpdateEventSchema } from "./events/acp-session-update.js";
|
|
9
8
|
import { AcpSessionUsageEventSchema } from "./events/acp-session-usage.js";
|
|
@@ -187,10 +186,6 @@ export {
|
|
|
187
186
|
type AcpSessionErrorEvent,
|
|
188
187
|
AcpSessionErrorEventSchema,
|
|
189
188
|
} from "./events/acp-session-error.js";
|
|
190
|
-
export {
|
|
191
|
-
type AcpSessionModelUpdateEvent,
|
|
192
|
-
AcpSessionModelUpdateEventSchema,
|
|
193
|
-
} from "./events/acp-session-model-update.js";
|
|
194
189
|
export {
|
|
195
190
|
type AcpSessionSpawnedEvent,
|
|
196
191
|
AcpSessionSpawnedEventSchema,
|
|
@@ -969,7 +964,6 @@ export const AssistantEventSchema = z.discriminatedUnion("type", [
|
|
|
969
964
|
AcpAuthRequiredEventSchema,
|
|
970
965
|
AcpSessionCompletedEventSchema,
|
|
971
966
|
AcpSessionErrorEventSchema,
|
|
972
|
-
AcpSessionModelUpdateEventSchema,
|
|
973
967
|
AcpSessionSpawnedEventSchema,
|
|
974
968
|
AcpSessionUpdateEventSchema,
|
|
975
969
|
AcpSessionUsageEventSchema,
|
package/src/apps/app-store.ts
CHANGED
|
@@ -114,7 +114,7 @@ export function resolveEffectiveAppHtmlFromDir(sourceDir: string): string {
|
|
|
114
114
|
if (isLegacySingleFileDir(sourceDir)) {
|
|
115
115
|
return UNSUPPORTED_LEGACY_APP_HTML;
|
|
116
116
|
}
|
|
117
|
-
return `<p>App compilation failed.
|
|
117
|
+
return `<p>App compilation failed. Edit a source file to trigger a rebuild.</p>`;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/**
|
|
@@ -13,10 +13,6 @@ import { existsSync, rmSync } from "node:fs";
|
|
|
13
13
|
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
14
14
|
import { delimiter, dirname, join, resolve } from "node:path";
|
|
15
15
|
|
|
16
|
-
import {
|
|
17
|
-
computeAppSourceFingerprint,
|
|
18
|
-
writeAppSourceFingerprint,
|
|
19
|
-
} from "../apps/source-fingerprint.js";
|
|
20
16
|
import { getLogger } from "../util/logger.js";
|
|
21
17
|
import { ensureCompilerTools } from "./compiler-tools.js";
|
|
22
18
|
import {
|
|
@@ -432,8 +428,6 @@ export async function runCompile(
|
|
|
432
428
|
};
|
|
433
429
|
}
|
|
434
430
|
|
|
435
|
-
const sourceFingerprint = computeAppSourceFingerprint(appDir);
|
|
436
|
-
|
|
437
431
|
// Clear stale dist/ output so removed assets (e.g. CSS) don't persist
|
|
438
432
|
if (existsSync(distDir)) {
|
|
439
433
|
rmSync(distDir, { recursive: true, force: true });
|
|
@@ -556,15 +550,6 @@ export async function runCompile(
|
|
|
556
550
|
await writeFile(join(distDir, "index.html"), html);
|
|
557
551
|
}
|
|
558
552
|
|
|
559
|
-
try {
|
|
560
|
-
writeAppSourceFingerprint(appDir, distDir, sourceFingerprint);
|
|
561
|
-
} catch (err) {
|
|
562
|
-
log.warn(
|
|
563
|
-
{ err, appDir, distDir },
|
|
564
|
-
"Failed to write source fingerprint after compile",
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
553
|
const durationMs = Math.round(performance.now() - start);
|
|
569
554
|
log.info({ durationMs }, "Build succeeded");
|
|
570
555
|
return { ok: true, errors: [], warnings: [], durationMs };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
couldBeControlMarker,
|
|
5
5
|
ESCALATE_VERDICT_TOKEN,
|
|
6
6
|
HOLD_VERDICT_TOKEN,
|
|
7
7
|
isIncompleteControlMarkerTail,
|
|
@@ -28,7 +28,21 @@ describe("front-door verdict tokens", () => {
|
|
|
28
28
|
).toBe(" one two ");
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
+
test("couldBeControlMarker holds the complete tokens (not flushed to TTS)", () => {
|
|
32
|
+
expect(couldBeControlMarker("[0]")).toBe(true);
|
|
33
|
+
expect(couldBeControlMarker("[1]")).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("couldBeControlMarker holds a partial token still streaming", () => {
|
|
37
|
+
// Any prefix of a token must be held so a streamed "[1" does not leak
|
|
38
|
+
// to the TTS engine before the full token arrives.
|
|
39
|
+
for (const partial of ["[", "[0", "[1"]) {
|
|
40
|
+
expect(couldBeControlMarker(partial)).toBe(true);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
31
44
|
test("ordinary text is not mistaken for a token", () => {
|
|
45
|
+
expect(couldBeControlMarker("Sure, one moment")).toBe(false);
|
|
32
46
|
expect(stripInternalSpeechMarkers("Sure, one moment")).toBe(
|
|
33
47
|
"Sure, one moment",
|
|
34
48
|
);
|
|
@@ -45,6 +59,16 @@ describe("minimize-room marker", () => {
|
|
|
45
59
|
stripInternalSpeechMarkers("Done [-1] here").replace(/\s+/g, " "),
|
|
46
60
|
).toBe("Done here");
|
|
47
61
|
});
|
|
62
|
+
|
|
63
|
+
test("couldBeControlMarker holds the marker and its streaming prefixes", () => {
|
|
64
|
+
for (const text of ["[", "[-", "[-1", "[-1]", "[-1] trailing"]) {
|
|
65
|
+
expect(couldBeControlMarker(text)).toBe(true);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("a bracket prefix that disproves the marker is not held", () => {
|
|
70
|
+
expect(couldBeControlMarker("[- something else")).toBe(false);
|
|
71
|
+
});
|
|
48
72
|
});
|
|
49
73
|
|
|
50
74
|
describe("isIncompleteControlMarkerTail", () => {
|
|
@@ -79,60 +103,3 @@ describe("isIncompleteControlMarkerTail", () => {
|
|
|
79
103
|
}
|
|
80
104
|
});
|
|
81
105
|
});
|
|
82
|
-
|
|
83
|
-
describe("createControlMarkerHoldback", () => {
|
|
84
|
-
function collect(): {
|
|
85
|
-
flush: ReturnType<typeof createControlMarkerHoldback>;
|
|
86
|
-
chunks: string[];
|
|
87
|
-
} {
|
|
88
|
-
const chunks: string[] = [];
|
|
89
|
-
const flush = createControlMarkerHoldback((chunk) => chunks.push(chunk));
|
|
90
|
-
return { flush, chunks };
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
test("holds a token still streaming and strips it once complete", () => {
|
|
94
|
-
const { flush, chunks } = collect();
|
|
95
|
-
flush("Sure [");
|
|
96
|
-
expect(chunks).toEqual(["Sure "]);
|
|
97
|
-
flush("Sure [1");
|
|
98
|
-
expect(chunks).toEqual(["Sure "]);
|
|
99
|
-
flush("Sure [1] one moment");
|
|
100
|
-
expect(chunks).toEqual(["Sure ", " one moment"]);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test("ordinary bracketed text flushes without stalling", () => {
|
|
104
|
-
const { flush, chunks } = collect();
|
|
105
|
-
flush("Option [A] then [note] here");
|
|
106
|
-
expect(chunks).toEqual(["Option [A] then [note] here"]);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test("a bracket prefix that disproves every marker flushes", () => {
|
|
110
|
-
const { flush, chunks } = collect();
|
|
111
|
-
flush("[- something else");
|
|
112
|
-
expect(chunks).toEqual(["[- something else"]);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
test("a guardian-approval body is held until its JSON balances", () => {
|
|
116
|
-
const { flush, chunks } = collect();
|
|
117
|
-
const streaming =
|
|
118
|
-
'Hold on. [ASK_GUARDIAN_APPROVAL: {"question": "ok]?", "options": ["a", "b"';
|
|
119
|
-
flush(streaming);
|
|
120
|
-
expect(chunks).toEqual(["Hold on. "]);
|
|
121
|
-
flush(`${streaming}]}] Thanks.`);
|
|
122
|
-
expect(chunks).toEqual(["Hold on. ", " Thanks."]);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test("force emits a held tail that never became a marker", () => {
|
|
126
|
-
const { flush, chunks } = collect();
|
|
127
|
-
flush("Score was [1");
|
|
128
|
-
expect(chunks).toEqual(["Score was "]);
|
|
129
|
-
flush("Score was [1", { force: true });
|
|
130
|
-
expect(chunks).toEqual(["Score was ", "[1"]);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("a chunk that strips to nothing is not emitted", () => {
|
|
134
|
-
const { flush, chunks } = collect();
|
|
135
|
-
flush("[END_CALL]");
|
|
136
|
-
expect(chunks).toEqual([]);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
@@ -842,42 +842,6 @@ describe("startVoiceTurn triage-and-escalate control prompt", () => {
|
|
|
842
842
|
expect(installed()).toContain(escalatedContinuationRule());
|
|
843
843
|
});
|
|
844
844
|
|
|
845
|
-
test("the auto-built phone prompt carries the front-door rule anchored to the caller's words", async () => {
|
|
846
|
-
const installed = captureInstalledPrompt();
|
|
847
|
-
await startVoiceTurn({
|
|
848
|
-
...makeTurnOptions(),
|
|
849
|
-
content: "what time is it",
|
|
850
|
-
routingLeg: "front-door",
|
|
851
|
-
});
|
|
852
|
-
expect(installed()).toContain("<voice_call_control>");
|
|
853
|
-
expect(installed()).toContain(
|
|
854
|
-
`13. ${frontDoorDecisionRule({ callerUtterance: "what time is it" })}`,
|
|
855
|
-
);
|
|
856
|
-
});
|
|
857
|
-
|
|
858
|
-
test("a phone sentinel anchors the front-door rule on its persisted form", async () => {
|
|
859
|
-
const installed = captureInstalledPrompt();
|
|
860
|
-
await startVoiceTurn({ ...makeTurnOptions(), routingLeg: "front-door" });
|
|
861
|
-
expect(installed()).toContain(
|
|
862
|
-
frontDoorDecisionRule({
|
|
863
|
-
callerUtterance: "(call connected — deliver opening greeting)",
|
|
864
|
-
}),
|
|
865
|
-
);
|
|
866
|
-
expect(installed()).not.toContain(JSON.stringify(CALL_OPENING_MARKER));
|
|
867
|
-
});
|
|
868
|
-
|
|
869
|
-
test("the auto-built phone prompt carries the escalated continuation rule", async () => {
|
|
870
|
-
const installed = captureInstalledPrompt();
|
|
871
|
-
await startVoiceTurn({
|
|
872
|
-
...makeTurnOptions(),
|
|
873
|
-
routingLeg: "escalated",
|
|
874
|
-
spokenEscalationBridge: "One moment.",
|
|
875
|
-
});
|
|
876
|
-
expect(installed()).toContain(
|
|
877
|
-
`13. ${escalatedContinuationRule("One moment.")}`,
|
|
878
|
-
);
|
|
879
|
-
});
|
|
880
|
-
|
|
881
845
|
test("leaves a caller-supplied prompt verbatim when no routing leg is set", async () => {
|
|
882
846
|
const installed = captureInstalledPrompt();
|
|
883
847
|
await startVoiceTurn({
|
|
@@ -896,7 +860,7 @@ describe("default call protocol numbered rules", () => {
|
|
|
896
860
|
const installed = captureInstalledPrompt();
|
|
897
861
|
await startVoiceTurn(makeTurnOptions());
|
|
898
862
|
expect(installed()).toContain(
|
|
899
|
-
"
|
|
863
|
+
"12. Speak the caller's language: reply in the language of the caller's most recent actual speech, and follow them if they switch languages mid-call. Synthetic user turns (parenthetical markers like the call-connected and verification-completed notices) are not caller speech and never set the language. Before the caller has spoken, such as on the opening greeting turn, use the language the Task context implies, if any; otherwise default to English.",
|
|
900
864
|
);
|
|
901
865
|
});
|
|
902
866
|
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
capEscalationBridge,
|
|
6
6
|
classifyFrontDoorLeading,
|
|
7
7
|
createFrontDoorStreamGate,
|
|
8
|
-
createFrontDoorVerdictMachine,
|
|
9
8
|
ESCALATE_VERDICT_TOKEN,
|
|
10
9
|
escalatedContinuationRule,
|
|
11
10
|
ESCALATION_CONTINUATION_CONTENT,
|
|
@@ -18,7 +17,6 @@ import {
|
|
|
18
17
|
isEscalationBridgeComplete,
|
|
19
18
|
MAX_ESCALATION_BRIDGE_CHARS,
|
|
20
19
|
needsFallbackBridge,
|
|
21
|
-
resolveSpokenEscalationBridge,
|
|
22
20
|
spokenBridgeText,
|
|
23
21
|
} from "../voice-triage-escalate.js";
|
|
24
22
|
|
|
@@ -283,34 +281,6 @@ describe("fallbackEscalationBridgeFor", () => {
|
|
|
283
281
|
});
|
|
284
282
|
});
|
|
285
283
|
|
|
286
|
-
describe("resolveSpokenEscalationBridge", () => {
|
|
287
|
-
test("a real capped bridge is spoken as the model's own speech", () => {
|
|
288
|
-
expect(resolveSpokenEscalationBridge("Let me check that.", "es")).toEqual({
|
|
289
|
-
spokenBridge: "Let me check that.",
|
|
290
|
-
usesFallback: false,
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
test("an empty or too-short bridge falls back to the localized canned phrase, audio-only", () => {
|
|
295
|
-
expect(resolveSpokenEscalationBridge("", "es")).toEqual({
|
|
296
|
-
spokenBridge: FALLBACK_ESCALATION_BRIDGE_BY_LANGUAGE.es,
|
|
297
|
-
usesFallback: true,
|
|
298
|
-
});
|
|
299
|
-
expect(resolveSpokenEscalationBridge("Ok", undefined)).toEqual({
|
|
300
|
-
spokenBridge: FALLBACK_ESCALATION_BRIDGE,
|
|
301
|
-
usesFallback: true,
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
test("a canned phrase the table lacks for the caller's language is English and says so", () => {
|
|
306
|
-
expect(resolveSpokenEscalationBridge("", "ko")).toEqual({
|
|
307
|
-
spokenBridge: FALLBACK_ESCALATION_BRIDGE,
|
|
308
|
-
usesFallback: true,
|
|
309
|
-
language: "en",
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
|
|
314
284
|
describe("capEscalationBridge", () => {
|
|
315
285
|
test("cuts just after the first sentence terminator", () => {
|
|
316
286
|
expect(
|
|
@@ -479,81 +449,6 @@ describe("live-voice escalation orchestration (end-to-end — TODO)", () => {
|
|
|
479
449
|
);
|
|
480
450
|
});
|
|
481
451
|
|
|
482
|
-
describe("createFrontDoorVerdictMachine", () => {
|
|
483
|
-
/** Feed `deltas` through a machine and return the step kinds, in order. */
|
|
484
|
-
function kinds(deltas: string[], holdEnabled = false): string[] {
|
|
485
|
-
const machine = createFrontDoorVerdictMachine(holdEnabled);
|
|
486
|
-
return deltas.map((delta) => machine.push(delta).kind);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
test("stays pending while the lead could still become a token", () => {
|
|
490
|
-
expect(kinds(["", "[", "1"])).toEqual(["pending", "pending", "pending"]);
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
test("an answer releases the held lead on the transition, then each delta", () => {
|
|
494
|
-
const machine = createFrontDoorVerdictMachine(false);
|
|
495
|
-
expect(machine.push("[")).toEqual({ kind: "pending" });
|
|
496
|
-
expect(machine.push("A] first")).toEqual({
|
|
497
|
-
kind: "answer",
|
|
498
|
-
text: "[A] first",
|
|
499
|
-
});
|
|
500
|
-
expect(machine.push(", second")).toEqual({
|
|
501
|
-
kind: "answer",
|
|
502
|
-
text: ", second",
|
|
503
|
-
});
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
test("escalate reports the capped bridge on the delta that completes it", () => {
|
|
507
|
-
const machine = createFrontDoorVerdictMachine(false);
|
|
508
|
-
expect(machine.push(`${ESCALATE_VERDICT_TOKEN} One `)).toEqual({
|
|
509
|
-
kind: "escalate",
|
|
510
|
-
bridge: null,
|
|
511
|
-
});
|
|
512
|
-
expect(machine.push("moment")).toEqual({ kind: "bridging" });
|
|
513
|
-
expect(machine.push(". Extra text past the cap")).toEqual({
|
|
514
|
-
kind: "bridge",
|
|
515
|
-
bridge: "One moment.",
|
|
516
|
-
});
|
|
517
|
-
expect(machine.push(" more")).toEqual({ kind: "done" });
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
test("a bridge that completes on the verdict delta is reported with it", () => {
|
|
521
|
-
const machine = createFrontDoorVerdictMachine(false);
|
|
522
|
-
expect(machine.push(`${ESCALATE_VERDICT_TOKEN} Let me check.`)).toEqual({
|
|
523
|
-
kind: "escalate",
|
|
524
|
-
bridge: "Let me check.",
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
test("finish hands off a bridge that never hit a terminator", () => {
|
|
529
|
-
const machine = createFrontDoorVerdictMachine(false);
|
|
530
|
-
machine.push(`${ESCALATE_VERDICT_TOKEN} Give me a second`);
|
|
531
|
-
expect(machine.finish()).toEqual({
|
|
532
|
-
kind: "bridge",
|
|
533
|
-
bridge: "Give me a second",
|
|
534
|
-
});
|
|
535
|
-
expect(machine.push("late")).toEqual({ kind: "done" });
|
|
536
|
-
});
|
|
537
|
-
|
|
538
|
-
test("finish on an answer or a pending lead is done, not a bridge", () => {
|
|
539
|
-
const answering = createFrontDoorVerdictMachine(false);
|
|
540
|
-
answering.push("Sure.");
|
|
541
|
-
expect(answering.finish()).toEqual({ kind: "done" });
|
|
542
|
-
const undecided = createFrontDoorVerdictMachine(false);
|
|
543
|
-
undecided.push("[");
|
|
544
|
-
expect(undecided.finish()).toEqual({ kind: "done" });
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
test("hold is a step only when the leg was taught the token", () => {
|
|
548
|
-
expect(kinds([HOLD_VERDICT_TOKEN], true)).toEqual(["hold"]);
|
|
549
|
-
expect(kinds([`${HOLD_VERDICT_TOKEN} trailing`], true)).toEqual(["hold"]);
|
|
550
|
-
expect(kinds([HOLD_VERDICT_TOKEN], false)).toEqual(["answer"]);
|
|
551
|
-
const held = createFrontDoorVerdictMachine(true);
|
|
552
|
-
held.push(HOLD_VERDICT_TOKEN);
|
|
553
|
-
expect(held.push("anything")).toEqual({ kind: "done" });
|
|
554
|
-
});
|
|
555
|
-
});
|
|
556
|
-
|
|
557
452
|
describe("createFrontDoorStreamGate", () => {
|
|
558
453
|
/** Feed `deltas` through a gate and return what it released, in order. */
|
|
559
454
|
function release(
|
|
@@ -69,35 +69,15 @@ export function getGuardianWaitUpdateSteadyMaxIntervalMs(): number {
|
|
|
69
69
|
return getConfig().calls.guardianWaitUpdateSteadyMaxIntervalMs;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// Fixed conversational timings. Named here, beside the config-backed limits
|
|
73
|
-
// above, so the phone path's cadence is readable in one place.
|
|
74
|
-
|
|
75
|
-
/** Caller silence after the assistant's turn before it nudges them. */
|
|
76
|
-
export const CALLER_SILENCE_NUDGE_MS = 30_000;
|
|
77
|
-
|
|
78
|
-
/** Listen window after the goodbye drains, in case the caller re-engages. */
|
|
79
|
-
export const END_CALL_LISTEN_WINDOW_MS = 2_000;
|
|
80
|
-
|
|
81
|
-
/** Max time to wait for goodbye audio to drain before forcing hangup. */
|
|
82
|
-
export const END_CALL_DRAIN_MAX_WAIT_MS = 15_000;
|
|
83
|
-
|
|
84
|
-
/** Lead before the max call duration at which the low-on-time warning is spoken. */
|
|
85
|
-
export const DURATION_WARNING_LEAD_MS = 2 * 60 * 1000;
|
|
86
|
-
|
|
87
|
-
/** Delay after the max-duration goodbye is spoken before the call is ended. */
|
|
88
|
-
export const POST_GOODBYE_HANGUP_DELAY_MS = 3_000;
|
|
89
|
-
|
|
90
|
-
/** Cap on waiting for a superseded turn's teardown before the next caller turn starts. */
|
|
91
|
-
export const BARGE_IN_TEARDOWN_WAIT_MS = 2_000;
|
|
92
|
-
|
|
93
72
|
export function getSilenceTimeoutMs(): number {
|
|
94
|
-
return
|
|
73
|
+
return 30 * 1000; // 30 seconds
|
|
95
74
|
}
|
|
96
75
|
|
|
97
76
|
export function getEndCallListenWindowMs(): number {
|
|
98
|
-
return
|
|
77
|
+
return 2 * 1000;
|
|
99
78
|
}
|
|
100
79
|
|
|
80
|
+
/** Max time to wait for goodbye audio to drain before forcing hangup. */
|
|
101
81
|
export function getEndCallDrainMaxWaitMs(): number {
|
|
102
|
-
return
|
|
82
|
+
return 15 * 1000;
|
|
103
83
|
}
|