@lawpath-tech/openclaw 2026.2.21-18 → 2026.2.21-20
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/dist/{agents-C9ij96eI.js → agents-C83RLKX2.js} +4 -4
- package/dist/{agents.config-PFAfbBID.js → agents.config-BVjazvnK.js} +1 -1
- package/dist/{agents.config-CBvMKGLh.js → agents.config-dnXbFv5H.js} +1 -1
- package/dist/{audio-preflight-CODznzqu.js → audio-preflight-Da7vejCH.js} +4 -4
- package/dist/{auth-choice-DH2T1E9c.js → auth-choice-BJNaxS-L.js} +1 -1
- package/dist/{auth-choice-CLiY8PdF.js → auth-choice-Hb6530su.js} +1 -1
- package/dist/{banner-CqQBBjKH.js → banner-dFAx4eE_.js} +1 -1
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +1 -1
- package/dist/bundled/session-memory/handler.js +1 -1
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-options-e7Z9Smf2.js → channel-options--M8F-DHl.js} +1 -1
- package/dist/{channel-options-CLS27y1A.js → channel-options-D0Qjq83D.js} +1 -1
- package/dist/{channel-web-DHMbpU2p.js → channel-web-D8hSmcPF.js} +1 -1
- package/dist/{channels-cli-BDHLWbaU.js → channels-cli-6uwOEBM-.js} +4 -4
- package/dist/{channels-cli-CDwQerVi.js → channels-cli-BtZHPcBX.js} +4 -4
- package/dist/{chrome-lRUqqgSD.js → chrome-CZuniMYN.js} +7 -7
- package/dist/{cli-BGJFLB0I.js → cli-CIImVBCM.js} +1 -1
- package/dist/{cli-C1nypCKP.js → cli-CijjdR37.js} +1 -1
- package/dist/{command-registry-pGuORBuB.js → command-registry-BtDC5Ll-.js} +9 -9
- package/dist/{completion-cli-Bf-Ojq_a.js → completion-cli-Bw5nZmTm.js} +2 -2
- package/dist/{completion-cli-C79-bpAx.js → completion-cli-CI6LWHg3.js} +1 -1
- package/dist/{config-cli-DLdH6zIF.js → config-cli-CgjgjWri.js} +1 -1
- package/dist/{config-cli-BcNHb4_E.js → config-cli-Dc0TQ1yE.js} +1 -1
- package/dist/{configure-BSt9S0yk.js → configure-CGqsSqXB.js} +3 -3
- package/dist/{configure-h1d7nrgR.js → configure-GUYUjx8A.js} +3 -3
- package/dist/{deliver-B2d2N8OJ.js → deliver-0ThKlzQo.js} +1 -1
- package/dist/{doctor-completion-BB1f594d.js → doctor-completion-DgPc1rDZ.js} +1 -1
- package/dist/{doctor-completion-deY10x7w.js → doctor-completion-DipoVPSi.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/extensionAPI.js +6 -6
- package/dist/{gateway-cli-IziQis2t.js → gateway-cli-Ds3oN72Y.js} +8 -8
- package/dist/{gateway-cli-B-XwzYp2.js → gateway-cli-DuMINk2B.js} +8 -8
- package/dist/{health-DMrTgW8V.js → health-DQjqH1zU.js} +1 -1
- package/dist/{health-UmuJyu1Q.js → health-Dg0bAIKS.js} +1 -1
- package/dist/{hooks-cli-BparoMpt.js → hooks-cli-CEtCwdza.js} +2 -2
- package/dist/{hooks-cli-B6WCYLyG.js → hooks-cli-Cac2Ru8r.js} +2 -2
- package/dist/{image--DDZnw-F.js → image-88q3KE-C.js} +1 -1
- package/dist/index.js +6 -6
- package/dist/llm-slug-generator.js +1 -1
- package/dist/{models-nhERae29.js → models-DnhANpnd.js} +2 -2
- package/dist/{models-cli-bfKNgoHD.js → models-cli-03noBf8W.js} +3 -3
- package/dist/{models-cli-BnbeEOCU.js → models-cli-CaP_rt4y.js} +2 -2
- package/dist/{onboard-D_VxXTXD.js → onboard-BMc-yUv5.js} +2 -2
- package/dist/{onboard-C3pJ0NU-.js → onboard-BZg2c27h.js} +2 -2
- package/dist/{onboard-channels-CyeyvIfw.js → onboard-channels-Lt2gG1e2.js} +1 -1
- package/dist/{onboard-channels-YvwszRaQ.js → onboard-channels-O6KvizE3.js} +1 -1
- package/dist/{onboarding-0zwx3Yv7.js → onboarding-CTgBlanm.js} +3 -3
- package/dist/{onboarding-D0_Q5m2W.js → onboarding-G28sv5Ms.js} +3 -3
- package/dist/{onboarding.finalize-CYb0_Q0z.js → onboarding.finalize-Cpt9Ymcn.js} +5 -5
- package/dist/{onboarding.finalize-CVeI23_g.js → onboarding.finalize-D2sylHDB.js} +6 -6
- package/dist/{pi-embedded-Qfuh9XzI.js → pi-embedded-Dz24QZz9.js} +82 -3
- package/dist/{pi-embedded-CwQsXrVT.js → pi-embedded-ZvazjIyF.js} +96 -17
- package/dist/{pi-embedded-helpers-Cd0S0WfR.js → pi-embedded-helpers-B0Kht0I2.js} +4 -4
- package/dist/{plugin-registry-83ThmVHf.js → plugin-registry-1pF4_jNl.js} +1 -1
- package/dist/{plugin-registry-D57lc9ob.js → plugin-registry-CHOacv01.js} +1 -1
- package/dist/plugin-sdk/{channel-web-XYtgc8aq.js → channel-web-BHNS_E7F.js} +1 -1
- package/dist/plugin-sdk/index.js +2 -2
- package/dist/plugin-sdk/plugins/runtime/types.d.ts +2 -0
- package/dist/plugin-sdk/{reply-BSOpvBX4.js → reply-DEepmBkT.js} +82 -3
- package/dist/plugin-sdk/tts/tts-core.d.ts +15 -0
- package/dist/plugin-sdk/tts/tts.d.ts +16 -0
- package/dist/plugin-sdk/{web-DiLYLsml.js → web-DBo-6RyH.js} +2 -2
- package/dist/{plugins-cli-BymsOcmR.js → plugins-cli-CflNTqmB.js} +2 -2
- package/dist/{plugins-cli-DOWA2F0z.js → plugins-cli-DW0TLzrq.js} +2 -2
- package/dist/{program-T05XIetU.js → program-DUkjf6lq.js} +7 -7
- package/dist/{program-context-CDmctW1L.js → program-context-C0-LzXoV.js} +17 -17
- package/dist/{prompt-select-styled-cR4-U64b.js → prompt-select-styled-CQUE1vow.js} +4 -4
- package/dist/{prompt-select-styled-BbzQhWF7.js → prompt-select-styled-CWNxdPrL.js} +4 -4
- package/dist/{provider-auth-helpers-BbnDoytN.js → provider-auth-helpers-D39L7fZC.js} +1 -1
- package/dist/{provider-auth-helpers-C4RNIRyy.js → provider-auth-helpers-bYUBBkmL.js} +1 -1
- package/dist/{push-apns-Dli4pG4y.js → push-apns-DGIqfAg5.js} +1 -1
- package/dist/{push-apns-DUeNpqyF.js → push-apns-Qfohz-Hs.js} +1 -1
- package/dist/{pw-ai-C-kqYO4L.js → pw-ai-S3cpSYOy.js} +1 -1
- package/dist/{register.agent-aY_6enDc.js → register.agent-BEM0_4uG.js} +5 -5
- package/dist/{register.agent-DNAtU5WP.js → register.agent-WQgVmACk.js} +6 -6
- package/dist/{register.configure-CwlwOMZ3.js → register.configure-CCpFmFPt.js} +6 -6
- package/dist/{register.configure-C_n9kIWJ.js → register.configure-CdW3aECy.js} +6 -6
- package/dist/{register.maintenance-DC40nnCm.js → register.maintenance-B8RZLSOe.js} +8 -8
- package/dist/{register.maintenance-Dddndcoo.js → register.maintenance-CM3QEdFz.js} +7 -7
- package/dist/{register.message-DiR6desB.js → register.message-BRLYHuVS.js} +2 -2
- package/dist/{register.message-CpEf0b15.js → register.message-XYm9NyDT.js} +2 -2
- package/dist/{register.onboard-bOeA39xj.js → register.onboard-BzAJbRpP.js} +4 -4
- package/dist/{register.onboard-VzVmqpEA.js → register.onboard-EwGHFUsd.js} +4 -4
- package/dist/{register.setup-CNLQzxl8.js → register.setup-33shhZje.js} +4 -4
- package/dist/{register.setup-D6iO5Xqa.js → register.setup-DpdZyiMv.js} +4 -4
- package/dist/{register.status-health-sessions-CoiaeduR.js → register.status-health-sessions-C8-iqepo.js} +3 -3
- package/dist/{register.status-health-sessions-BtJeTZnN.js → register.status-health-sessions-CK4f2nj_.js} +3 -3
- package/dist/{register.subclis-CFTYYdAQ.js → register.subclis-Mn68G5tp.js} +9 -9
- package/dist/{reply-Bv-RvRzs.js → reply-DuVUTFfT.js} +82 -3
- package/dist/{run-main-EzFOCEdp.js → run-main-CNB3qjRM.js} +14 -14
- package/dist/{runner-Dq-qfrq7.js → runner-a43IsYad.js} +1 -1
- package/dist/{server-node-events-B9TqPvCI.js → server-node-events-B3o3P600.js} +2 -2
- package/dist/{server-node-events-syk21TN6.js → server-node-events-BPFwUGbS.js} +2 -2
- package/dist/{session-dirs-BAcQuXpY.js → session-dirs-Cw2efkey.js} +1 -1
- package/dist/{session-dirs-t0YpmrIL.js → session-dirs-DsU4kvIK.js} +1 -1
- package/dist/{status-keCWmejk.js → status-BSJIuIlN.js} +1 -1
- package/dist/{status-05251w21.js → status-BhHpKHQP.js} +2 -2
- package/dist/{status-BqDiXxwL.js → status-C2PvVLaW.js} +1 -1
- package/dist/{status-B8UVm7P3.js → status-CLKmcFCC.js} +2 -2
- package/dist/{subagent-registry-Lm4ps45z.js → subagent-registry-Da0a_Vka.js} +82 -3
- package/dist/{update-cli-BTF6TXGD.js → update-cli-BW3q5tFm.js} +7 -7
- package/dist/{update-cli-aW6jVJIJ.js → update-cli-D4EUMrX6.js} +8 -8
- package/dist/{web-BYZfljIx.js → web-BTbIFuWM.js} +2 -2
- package/dist/{web-BjxYv-hA.js → web-C7TQSVU0.js} +1 -1
- package/dist/{web-DPHo2cWX.js → web-CVSol55V.js} +6 -6
- package/dist/{web-BZ5kM4yO.js → web-Y49Dumye.js} +1 -1
- package/extensions/voice-call/src/providers/twilio.ts +31 -13
- package/extensions/voice-call/src/response-generator.ts +26 -5
- package/extensions/voice-call/src/telephony-audio.ts +54 -0
- package/extensions/voice-call/src/telephony-tts.ts +40 -2
- package/extensions/voice-call/src/webhook.ts +9 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { g as resolveStateDir, u as resolveGatewayPort } from "./paths-B4BZAPZh.js";
|
|
2
2
|
import { B as theme, h as pathExists } from "./utils-BlC2Fskb.js";
|
|
3
3
|
import "./thinking-EAliFiVK.js";
|
|
4
|
-
import { K as trimLogTail } from "./reply-
|
|
4
|
+
import { K as trimLogTail } from "./reply-DuVUTFfT.js";
|
|
5
5
|
import { t as resolveOpenClawPackageRoot } from "./openclaw-root-CQJwyH9q.js";
|
|
6
6
|
import "./registry-Dygi7Azw.js";
|
|
7
7
|
import { f as defaultRuntime } from "./subsystem-8bY95KEB.js";
|
|
@@ -106,7 +106,7 @@ import { c as resolveGatewayLaunchAgentLabel, d as resolveGatewaySystemdServiceN
|
|
|
106
106
|
import "./channel-selection-ZfFyXtQ1.js";
|
|
107
107
|
import "./pi-tools.policy-DZSlTC8Z.js";
|
|
108
108
|
import { r as parseSemver } from "./runtime-guard-BYGIYhEa.js";
|
|
109
|
-
import "./program-context-
|
|
109
|
+
import "./program-context-C0-LzXoV.js";
|
|
110
110
|
import "./catalog-C7TxlaHu.js";
|
|
111
111
|
import "./skills-status-CcVQgk7_.js";
|
|
112
112
|
import { n as inheritOptionFromParent } from "./command-options-BtDai3oC.js";
|
|
@@ -117,7 +117,7 @@ import "./npm-registry-spec-DVXqd4Pf.js";
|
|
|
117
117
|
import "./skill-scanner-CMBwwxis.js";
|
|
118
118
|
import "./installs-B9skpWIo.js";
|
|
119
119
|
import "./channels-status-issues-BD8w_e2b.js";
|
|
120
|
-
import { r as installCompletion } from "./completion-cli-
|
|
120
|
+
import { r as installCompletion } from "./completion-cli-CI6LWHg3.js";
|
|
121
121
|
import "./daemon-runtime-CcJb-H5N.js";
|
|
122
122
|
import "./systemd-Dq5fANx0.js";
|
|
123
123
|
import { t as resolveGatewayService } from "./service-CJGWS46r.js";
|
|
@@ -126,19 +126,19 @@ import "./systemd-hints-Bjz2gm-v.js";
|
|
|
126
126
|
import { a as terminateStaleGatewayPids, i as renderRestartDiagnostics, o as waitForGatewayHealthyRestart, r as runDaemonRestart, s as runDaemonInstall } from "./daemon-cli-D8yeYXMW.js";
|
|
127
127
|
import "./diagnostics-CSOaBA1c.js";
|
|
128
128
|
import { t as renderTable } from "./table-i7J9YlN5.js";
|
|
129
|
-
import "./health-
|
|
129
|
+
import "./health-DQjqH1zU.js";
|
|
130
130
|
import "./control-ui-assets-d_j0Pdnj.js";
|
|
131
131
|
import { a as resolveNpmChannelTag, c as DEFAULT_PACKAGE_CHANNEL, d as formatUpdateChannelLabel, g as resolveUpdateChannelDisplay, h as resolveEffectiveUpdateChannel, m as normalizeUpdateChannel, n as compareSemverStrings, r as fetchNpmTagVersion, s as DEFAULT_GIT_CHANNEL, t as checkUpdateStatus, u as channelToNpmTag } from "./update-check-B-fJT8wY.js";
|
|
132
132
|
import "./dm-policy-shared-Dhee-_og.js";
|
|
133
133
|
import { i as resolveUpdateAvailability, n as formatUpdateOneLiner, t as formatUpdateAvailableHint } from "./status.update-CCXdXTvr.js";
|
|
134
|
-
import { a as detectGlobalInstallManagerForRoot, c as readPackageName, i as detectGlobalInstallManagerByPresence, l as readPackageVersion, n as runGatewayUpdate, o as globalInstallArgs, r as cleanupGlobalRenameDirs, s as resolveGlobalPackageRoot } from "./session-dirs-
|
|
134
|
+
import { a as detectGlobalInstallManagerForRoot, c as readPackageName, i as detectGlobalInstallManagerByPresence, l as readPackageVersion, n as runGatewayUpdate, o as globalInstallArgs, r as cleanupGlobalRenameDirs, s as resolveGlobalPackageRoot } from "./session-dirs-Cw2efkey.js";
|
|
135
135
|
import "./logging-DNqMaj3H.js";
|
|
136
136
|
import { n as updateNpmInstalledPlugins, t as syncPluginsForUpdateChannel } from "./update-BS8h2lwA.js";
|
|
137
137
|
import "./doctor-config-flow-BMdUHcYg.js";
|
|
138
138
|
import "./systemd-linger-zXWRcQMp.js";
|
|
139
139
|
import "./health-format-D6i_RyWd.js";
|
|
140
|
-
import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-
|
|
141
|
-
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-
|
|
140
|
+
import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-CWNxdPrL.js";
|
|
141
|
+
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-DgPc1rDZ.js";
|
|
142
142
|
import os from "node:os";
|
|
143
143
|
import path from "node:path";
|
|
144
144
|
import fs from "node:fs/promises";
|
|
@@ -16,7 +16,7 @@ import "./client-B5QR5Bi9.js";
|
|
|
16
16
|
import "./call-D6ajQjvV.js";
|
|
17
17
|
import "./message-channel-CVHJDItx.js";
|
|
18
18
|
import "./pairing-token-Byh6drgn.js";
|
|
19
|
-
import { bt as trimLogTail } from "./subagent-registry-
|
|
19
|
+
import { bt as trimLogTail } from "./subagent-registry-Da0a_Vka.js";
|
|
20
20
|
import "./sessions-BJnLP6OJ.js";
|
|
21
21
|
import "./tokens-ANnYrShl.js";
|
|
22
22
|
import "./plugins-DStDwRz0.js";
|
|
@@ -111,10 +111,10 @@ import "./npm-registry-spec-DkaZNHAW.js";
|
|
|
111
111
|
import "./skill-scanner-Cb7mXGIR.js";
|
|
112
112
|
import "./installs-DDy4Ij7L.js";
|
|
113
113
|
import "./channels-status-issues-DsKlgViM.js";
|
|
114
|
-
import "./register.subclis-
|
|
115
|
-
import "./command-registry-
|
|
114
|
+
import "./register.subclis-Mn68G5tp.js";
|
|
115
|
+
import "./command-registry-BtDC5Ll-.js";
|
|
116
116
|
import "./program-context-5q-A0wbP.js";
|
|
117
|
-
import { r as installCompletion } from "./completion-cli-
|
|
117
|
+
import { r as installCompletion } from "./completion-cli-Bw5nZmTm.js";
|
|
118
118
|
import "./daemon-runtime-Rig_aj9Q.js";
|
|
119
119
|
import { r as parseSemver } from "./runtime-guard-Cs_ClFhP.js";
|
|
120
120
|
import "./systemd-BrybH4HV.js";
|
|
@@ -124,19 +124,19 @@ import "./systemd-hints-C73_IlRM.js";
|
|
|
124
124
|
import { a as terminateStaleGatewayPids, i as renderRestartDiagnostics, o as waitForGatewayHealthyRestart, r as runDaemonRestart, s as runDaemonInstall } from "./daemon-cli-C-NToqLz.js";
|
|
125
125
|
import "./diagnostics-CqEodocN.js";
|
|
126
126
|
import { t as renderTable } from "./table-C9BoE_4p.js";
|
|
127
|
-
import "./health-
|
|
127
|
+
import "./health-Dg0bAIKS.js";
|
|
128
128
|
import "./control-ui-assets-Yp3N6NZ_.js";
|
|
129
129
|
import { a as resolveNpmChannelTag, c as DEFAULT_PACKAGE_CHANNEL, d as formatUpdateChannelLabel, g as resolveUpdateChannelDisplay, h as resolveEffectiveUpdateChannel, m as normalizeUpdateChannel, n as compareSemverStrings, r as fetchNpmTagVersion, s as DEFAULT_GIT_CHANNEL, t as checkUpdateStatus, u as channelToNpmTag } from "./update-check-DfBZVR4k.js";
|
|
130
130
|
import "./dm-policy-shared-Do8DPXRK.js";
|
|
131
131
|
import { i as resolveUpdateAvailability, n as formatUpdateOneLiner, t as formatUpdateAvailableHint } from "./status.update-BL8rMB1W.js";
|
|
132
|
-
import { a as detectGlobalInstallManagerForRoot, c as readPackageName, i as detectGlobalInstallManagerByPresence, l as readPackageVersion, n as runGatewayUpdate, o as globalInstallArgs, r as cleanupGlobalRenameDirs, s as resolveGlobalPackageRoot } from "./session-dirs-
|
|
132
|
+
import { a as detectGlobalInstallManagerForRoot, c as readPackageName, i as detectGlobalInstallManagerByPresence, l as readPackageVersion, n as runGatewayUpdate, o as globalInstallArgs, r as cleanupGlobalRenameDirs, s as resolveGlobalPackageRoot } from "./session-dirs-DsU4kvIK.js";
|
|
133
133
|
import "./logging-PVQxLC6I.js";
|
|
134
134
|
import { n as updateNpmInstalledPlugins, t as syncPluginsForUpdateChannel } from "./update-ChO83Ek6.js";
|
|
135
135
|
import "./doctor-config-flow-B_6xrNyC.js";
|
|
136
136
|
import "./systemd-linger-B8oXYjfA.js";
|
|
137
137
|
import "./health-format-DkjSgkDx.js";
|
|
138
|
-
import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-
|
|
139
|
-
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-
|
|
138
|
+
import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-CQUE1vow.js";
|
|
139
|
+
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-DipoVPSi.js";
|
|
140
140
|
import { spawn, spawnSync } from "node:child_process";
|
|
141
141
|
import os from "node:os";
|
|
142
142
|
import path from "node:path";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./paths-B4BZAPZh.js";
|
|
2
2
|
import "./utils-BlC2Fskb.js";
|
|
3
3
|
import "./thinking-EAliFiVK.js";
|
|
4
|
-
import "./reply-
|
|
4
|
+
import "./reply-DuVUTFfT.js";
|
|
5
5
|
import "./registry-Dygi7Azw.js";
|
|
6
6
|
import "./subsystem-8bY95KEB.js";
|
|
7
7
|
import "./exec-BmMB8-Xs.js";
|
|
@@ -101,7 +101,7 @@ import "./control-service-D8pPAw9I.js";
|
|
|
101
101
|
import "./stagger-B6VQyn1F.js";
|
|
102
102
|
import "./channel-selection-ZfFyXtQ1.js";
|
|
103
103
|
import "./pi-tools.policy-DZSlTC8Z.js";
|
|
104
|
-
import { n as monitorWebInbox, t as monitorWebChannel } from "./channel-web-
|
|
104
|
+
import { n as monitorWebInbox, t as monitorWebChannel } from "./channel-web-D8hSmcPF.js";
|
|
105
105
|
import { n as sendMessageWhatsApp } from "./outbound-ZEBWBkDi.js";
|
|
106
106
|
import { i as waitForWaConnection, t as createWaSocket } from "./session-DD2Ku-SR.js";
|
|
107
107
|
import { t as loginWeb } from "./login-DN07rdvL.js";
|
|
@@ -15,7 +15,7 @@ import "./client-B5QR5Bi9.js";
|
|
|
15
15
|
import "./call-D6ajQjvV.js";
|
|
16
16
|
import "./message-channel-CVHJDItx.js";
|
|
17
17
|
import "./pairing-token-Byh6drgn.js";
|
|
18
|
-
import { $t as parseActivationCommand, B as dispatchReplyWithBufferedBlockDispatcher, Bn as shouldComputeCommandAuthorized, F as resolveMentionGating, Fn as resolveInboundDebounceMs, G as createDedupeCache, I as DEFAULT_GROUP_HISTORY_LIMIT, In as formatInboundEnvelope, K as getReplyFromConfig, L as buildHistoryContextFromEntries, Ln as resolveEnvelopeFormatOptions, P as buildPairingReply, Pn as createInboundDebouncer, Qt as normalizeGroupActivation, R as recordPendingHistoryEntryIfEnabled, S as sleepWithAbort, Un as buildMentionRegexes, Wn as normalizeMentionText, bn as enqueueSystemEvent, x as computeBackoff, z as shouldAckReactionForWhatsApp, zn as hasControlCommand } from "./subagent-registry-
|
|
18
|
+
import { $t as parseActivationCommand, B as dispatchReplyWithBufferedBlockDispatcher, Bn as shouldComputeCommandAuthorized, F as resolveMentionGating, Fn as resolveInboundDebounceMs, G as createDedupeCache, I as DEFAULT_GROUP_HISTORY_LIMIT, In as formatInboundEnvelope, K as getReplyFromConfig, L as buildHistoryContextFromEntries, Ln as resolveEnvelopeFormatOptions, P as buildPairingReply, Pn as createInboundDebouncer, Qt as normalizeGroupActivation, R as recordPendingHistoryEntryIfEnabled, S as sleepWithAbort, Un as buildMentionRegexes, Wn as normalizeMentionText, bn as enqueueSystemEvent, x as computeBackoff, z as shouldAckReactionForWhatsApp, zn as hasControlCommand } from "./subagent-registry-Da0a_Vka.js";
|
|
19
19
|
import { B as resolveGroupSessionKey, c as recordSessionMetaFromInbound, o as loadSessionStore, s as readSessionUpdatedAt, u as updateLastRoute } from "./sessions-BJnLP6OJ.js";
|
|
20
20
|
import "./tokens-ANnYrShl.js";
|
|
21
21
|
import "./plugins-DStDwRz0.js";
|
|
@@ -8,13 +8,13 @@ import { c as resolveIdentityNamePrefix, l as resolveMessagePrefix, t as createR
|
|
|
8
8
|
import "./github-copilot-token-ttqQRqMA.js";
|
|
9
9
|
import { r as formatCliCommand } from "./env-DulyEJtM.js";
|
|
10
10
|
import "./tokens-DnMmat9I.js";
|
|
11
|
-
import { C as shouldComputeCommandAuthorized, S as hasControlCommand, T as normalizeMentionText, _ as enqueueSystemEvent, a as resolveMentionGating, b as formatInboundEnvelope, c as recordPendingHistoryEntryIfEnabled, f as createDedupeCache, g as formatDurationPrecise, h as parseActivationCommand, i as buildPairingReply, l as shouldAckReactionForWhatsApp, m as normalizeGroupActivation, n as computeBackoff, o as DEFAULT_GROUP_HISTORY_LIMIT, p as getReplyFromConfig, r as sleepWithAbort, s as buildHistoryContextFromEntries, u as dispatchReplyWithBufferedBlockDispatcher, v as createInboundDebouncer, w as buildMentionRegexes, x as resolveEnvelopeFormatOptions, y as resolveInboundDebounceMs } from "./pi-embedded-
|
|
11
|
+
import { C as shouldComputeCommandAuthorized, S as hasControlCommand, T as normalizeMentionText, _ as enqueueSystemEvent, a as resolveMentionGating, b as formatInboundEnvelope, c as recordPendingHistoryEntryIfEnabled, f as createDedupeCache, g as formatDurationPrecise, h as parseActivationCommand, i as buildPairingReply, l as shouldAckReactionForWhatsApp, m as normalizeGroupActivation, n as computeBackoff, o as DEFAULT_GROUP_HISTORY_LIMIT, p as getReplyFromConfig, r as sleepWithAbort, s as buildHistoryContextFromEntries, u as dispatchReplyWithBufferedBlockDispatcher, v as createInboundDebouncer, w as buildMentionRegexes, x as resolveEnvelopeFormatOptions, y as resolveInboundDebounceMs } from "./pi-embedded-ZvazjIyF.js";
|
|
12
12
|
import "./plugins-B90TBXkV.js";
|
|
13
13
|
import { i as logWebSelfId, l as readWebSelfId, n as WA_WEB_AUTH_DIR, p as webAuthExists, r as getWebAuthAgeMs, s as pickWebChannel, t as resolveWhatsAppAccount } from "./accounts-Cxza2UXO.js";
|
|
14
14
|
import "./bindings-q3EHMdG1.js";
|
|
15
15
|
import "./send-Chks8Sx_.js";
|
|
16
16
|
import "./send-D4cCHXzJ.js";
|
|
17
|
-
import "./deliver-
|
|
17
|
+
import "./deliver-0ThKlzQo.js";
|
|
18
18
|
import "./diagnostic-DzmNBZt3.js";
|
|
19
19
|
import "./diagnostic-session-state-C1vRJs5w.js";
|
|
20
20
|
import "./accounts-sr0G5UOe.js";
|
|
@@ -22,10 +22,10 @@ import { G as formatLocationText, J as readChannelAllowFromStore, K as toLocatio
|
|
|
22
22
|
import "./image-ops-BfqdVNxh.js";
|
|
23
23
|
import "./pi-model-discovery-j5tVLINv.js";
|
|
24
24
|
import "./message-channel-DNOtJsL1.js";
|
|
25
|
-
import { Ct as resolveGroupSessionKey, H as loadSessionStore, K as updateLastRoute, U as readSessionUpdatedAt, W as recordSessionMetaFromInbound } from "./pi-embedded-helpers-
|
|
25
|
+
import { Ct as resolveGroupSessionKey, H as loadSessionStore, K as updateLastRoute, U as readSessionUpdatedAt, W as recordSessionMetaFromInbound } from "./pi-embedded-helpers-B0Kht0I2.js";
|
|
26
26
|
import { n as loadConfig } from "./config-KL7847B1.js";
|
|
27
27
|
import "./manifest-registry-sze5OW-s.js";
|
|
28
|
-
import "./chrome-
|
|
28
|
+
import "./chrome-CZuniMYN.js";
|
|
29
29
|
import "./skills-DGNBryo1.js";
|
|
30
30
|
import "./redact-1NGYV_8p.js";
|
|
31
31
|
import "./errors-CPfngF0S.js";
|
|
@@ -35,7 +35,7 @@ import { h as resolveChannelGroupRequireMention, m as resolveChannelGroupPolicy
|
|
|
35
35
|
import "./accounts-DAZL5b5o.js";
|
|
36
36
|
import { s as resolveStorePath } from "./paths-5iQF9bSz.js";
|
|
37
37
|
import "./tool-images-TQiVqsOc.js";
|
|
38
|
-
import "./image
|
|
38
|
+
import "./image-88q3KE-C.js";
|
|
39
39
|
import "./manager-CsXJuzK4.js";
|
|
40
40
|
import "./gemini-auth-BF6ZCNOV.js";
|
|
41
41
|
import "./sqlite-CmTvWxxq.js";
|
|
@@ -49,7 +49,7 @@ import "./render-B1VqYyvo.js";
|
|
|
49
49
|
import "./commands-registry-DEXQtgBS.js";
|
|
50
50
|
import "./skill-commands-CGvIAIiQ.js";
|
|
51
51
|
import { t as finalizeInboundContext } from "./inbound-context-QOi5vzUt.js";
|
|
52
|
-
import { p as registerUnhandledRejectionHandler } from "./runner-
|
|
52
|
+
import { p as registerUnhandledRejectionHandler } from "./runner-a43IsYad.js";
|
|
53
53
|
import "./fetch-BMa0enEg.js";
|
|
54
54
|
import { n as recordChannelActivity } from "./channel-activity-7fb2OxTV.js";
|
|
55
55
|
import { t as convertMarkdownTables } from "./tables-Ds9lRo34.js";
|
|
@@ -5,7 +5,7 @@ import "./agent-scope-DSUeV7-g.js";
|
|
|
5
5
|
import { r as defaultRuntime, t as createSubsystemLogger } from "./subsystem-BF9jT_Nw.js";
|
|
6
6
|
import "./workspace-DYx5Dxtw.js";
|
|
7
7
|
import "./tokens-B-c56SkM.js";
|
|
8
|
-
import { C as resolveEnvelopeFormatOptions, D as normalizeMentionText, E as buildMentionRegexes, S as formatInboundEnvelope, T as shouldComputeCommandAuthorized, _ as parseActivationCommand, b as createInboundDebouncer, c as DEFAULT_GROUP_HISTORY_LIMIT, d as shouldAckReactionForWhatsApp, f as dispatchReplyWithBufferedBlockDispatcher, g as normalizeGroupActivation, h as getReplyFromConfig, l as buildHistoryContextFromEntries, m as createDedupeCache, n as computeBackoff, o as buildPairingReply, r as sleepWithAbort, s as resolveMentionGating, u as recordPendingHistoryEntryIfEnabled, v as formatDurationPrecise, w as hasControlCommand, x as resolveInboundDebounceMs, y as enqueueSystemEvent } from "./pi-embedded-
|
|
8
|
+
import { C as resolveEnvelopeFormatOptions, D as normalizeMentionText, E as buildMentionRegexes, S as formatInboundEnvelope, T as shouldComputeCommandAuthorized, _ as parseActivationCommand, b as createInboundDebouncer, c as DEFAULT_GROUP_HISTORY_LIMIT, d as shouldAckReactionForWhatsApp, f as dispatchReplyWithBufferedBlockDispatcher, g as normalizeGroupActivation, h as getReplyFromConfig, l as buildHistoryContextFromEntries, m as createDedupeCache, n as computeBackoff, o as buildPairingReply, r as sleepWithAbort, s as resolveMentionGating, u as recordPendingHistoryEntryIfEnabled, v as formatDurationPrecise, w as hasControlCommand, x as resolveInboundDebounceMs, y as enqueueSystemEvent } from "./pi-embedded-Dz24QZz9.js";
|
|
9
9
|
import "./plugins-DIrNa311.js";
|
|
10
10
|
import { i as logWebSelfId, l as readWebSelfId, n as WA_WEB_AUTH_DIR, p as webAuthExists, r as getWebAuthAgeMs, s as pickWebChannel, t as resolveWhatsAppAccount } from "./accounts-C8m4ADkw.js";
|
|
11
11
|
import "./boolean-B8-BqKGQ.js";
|
|
@@ -565,30 +565,48 @@ export class TwilioProvider implements VoiceCallProvider {
|
|
|
565
565
|
throw new Error("TTS provider and media stream handler required");
|
|
566
566
|
}
|
|
567
567
|
|
|
568
|
-
|
|
569
|
-
const CHUNK_SIZE = 160;
|
|
568
|
+
const CHUNK_SIZE = 160; // 20ms at 8kHz mu-law
|
|
570
569
|
const CHUNK_DELAY_MS = 20;
|
|
571
|
-
|
|
572
570
|
const handler = this.mediaStreamHandler;
|
|
573
571
|
const ttsProvider = this.ttsProvider;
|
|
572
|
+
|
|
574
573
|
await handler.queueTts(streamSid, async (signal) => {
|
|
575
|
-
//
|
|
574
|
+
// Try streaming TTS first (sends audio as chunks arrive from API)
|
|
575
|
+
if (ttsProvider.synthesizeForTelephonyStream) {
|
|
576
|
+
try {
|
|
577
|
+
let framesEmitted = 0;
|
|
578
|
+
const stream = ttsProvider.synthesizeForTelephonyStream(text);
|
|
579
|
+
for await (const muLawChunk of stream) {
|
|
580
|
+
if (signal.aborted) break;
|
|
581
|
+
for (const chunk of chunkAudio(muLawChunk, CHUNK_SIZE)) {
|
|
582
|
+
if (signal.aborted) break;
|
|
583
|
+
handler.sendAudio(streamSid, chunk);
|
|
584
|
+
framesEmitted++;
|
|
585
|
+
await new Promise((resolve) => setTimeout(resolve, CHUNK_DELAY_MS));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (!signal.aborted && framesEmitted > 0) {
|
|
589
|
+
handler.sendMark(streamSid, `tts-${Date.now()}`);
|
|
590
|
+
}
|
|
591
|
+
return;
|
|
592
|
+
} catch (err) {
|
|
593
|
+
console.warn(
|
|
594
|
+
`[voice-call] Streaming TTS failed, falling back to buffered:`,
|
|
595
|
+
err instanceof Error ? err.message : err,
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Fallback: buffered TTS (full audio generated before sending)
|
|
576
601
|
const muLawAudio = await ttsProvider.synthesizeForTelephony(text);
|
|
577
602
|
for (const chunk of chunkAudio(muLawAudio, CHUNK_SIZE)) {
|
|
578
|
-
if (signal.aborted)
|
|
579
|
-
break;
|
|
580
|
-
}
|
|
603
|
+
if (signal.aborted) break;
|
|
581
604
|
handler.sendAudio(streamSid, chunk);
|
|
582
|
-
|
|
583
|
-
// Pace the audio to match real-time playback
|
|
584
605
|
await new Promise((resolve) => setTimeout(resolve, CHUNK_DELAY_MS));
|
|
585
|
-
if (signal.aborted)
|
|
586
|
-
break;
|
|
587
|
-
}
|
|
606
|
+
if (signal.aborted) break;
|
|
588
607
|
}
|
|
589
608
|
|
|
590
609
|
if (!signal.aborted) {
|
|
591
|
-
// Send a mark to track when audio finishes
|
|
592
610
|
handler.sendMark(streamSid, `tts-${Date.now()}`);
|
|
593
611
|
}
|
|
594
612
|
});
|
|
@@ -59,9 +59,9 @@ export async function generateVoiceResponse(
|
|
|
59
59
|
}
|
|
60
60
|
const cfg = coreConfig;
|
|
61
61
|
|
|
62
|
-
// Build voice-specific session key
|
|
63
|
-
|
|
64
|
-
const sessionKey = `voice:${
|
|
62
|
+
// Build voice-specific session key per call (not per phone number)
|
|
63
|
+
// so conversation history doesn't leak between separate calls
|
|
64
|
+
const sessionKey = `voice:${callId}`;
|
|
65
65
|
const agentId = "main";
|
|
66
66
|
|
|
67
67
|
// Resolve paths
|
|
@@ -123,8 +123,9 @@ export async function generateVoiceResponse(
|
|
|
123
123
|
|
|
124
124
|
try {
|
|
125
125
|
console.log(
|
|
126
|
-
`[voice-call] Running embedded agent: model=${modelRef} timeout=${timeoutMs}ms session=${sessionId}`,
|
|
126
|
+
`[voice-call] Running embedded agent: model=${modelRef} provider=${provider} timeout=${timeoutMs}ms session=${sessionId} sessionFile=${sessionFile} workspaceDir=${workspaceDir} agentDir=${agentDir}`,
|
|
127
127
|
);
|
|
128
|
+
const startMs = Date.now();
|
|
128
129
|
const result = await deps.runEmbeddedPiAgent({
|
|
129
130
|
sessionId,
|
|
130
131
|
sessionKey,
|
|
@@ -143,10 +144,24 @@ export async function generateVoiceResponse(
|
|
|
143
144
|
extraSystemPrompt,
|
|
144
145
|
agentDir,
|
|
145
146
|
});
|
|
147
|
+
const elapsedMs = Date.now() - startMs;
|
|
146
148
|
console.log(
|
|
147
|
-
`[voice-call] Embedded agent returned: payloads=${result.payloads?.length ?? 0} aborted=${result.meta?.aborted ?? false}`,
|
|
149
|
+
`[voice-call] Embedded agent returned in ${elapsedMs}ms: payloads=${result.payloads?.length ?? 0} aborted=${result.meta?.aborted ?? false} error=${result.meta?.error ?? "none"} stopReason=${result.meta?.agentMeta?.stopReason ?? "unknown"}`,
|
|
148
150
|
);
|
|
149
151
|
|
|
152
|
+
// Log all payloads for debugging
|
|
153
|
+
if (result.payloads && result.payloads.length > 0) {
|
|
154
|
+
for (const [i, p] of result.payloads.entries()) {
|
|
155
|
+
console.log(
|
|
156
|
+
`[voice-call] payload[${i}]: text=${JSON.stringify(p.text?.slice(0, 200))} isError=${p.isError ?? false}`,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
console.warn(`[voice-call] Embedded agent returned ZERO payloads`);
|
|
161
|
+
// Log the full meta for diagnosis
|
|
162
|
+
console.warn(`[voice-call] meta: ${JSON.stringify(result.meta ?? {})}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
150
165
|
// Extract text from payloads
|
|
151
166
|
const texts = (result.payloads ?? [])
|
|
152
167
|
.filter((p) => p.text && !p.isError)
|
|
@@ -159,6 +174,12 @@ export async function generateVoiceResponse(
|
|
|
159
174
|
return { text: null, error: "Response generation was aborted" };
|
|
160
175
|
}
|
|
161
176
|
|
|
177
|
+
if (!text) {
|
|
178
|
+
console.warn(
|
|
179
|
+
`[voice-call] No usable text extracted from ${result.payloads?.length ?? 0} payloads`,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
162
183
|
return { text };
|
|
163
184
|
} catch (err) {
|
|
164
185
|
console.error(`[voice-call] Response generation failed:`, err);
|
|
@@ -67,6 +67,60 @@ export function chunkAudio(audio: Buffer, chunkSize = 160): Generator<Buffer, vo
|
|
|
67
67
|
})();
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Stateful incremental PCM-to-mulaw converter for streaming.
|
|
72
|
+
* Handles odd-byte chunk boundaries between calls.
|
|
73
|
+
*/
|
|
74
|
+
export type PcmToMulawStreamState = {
|
|
75
|
+
oddByte: number | null;
|
|
76
|
+
srcPosCarry: number;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export function createPcmToMulawStreamState(): PcmToMulawStreamState {
|
|
80
|
+
return { oddByte: null, srcPosCarry: 0 };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function convertPcmChunkToMulaw8k(
|
|
84
|
+
chunk: Buffer,
|
|
85
|
+
inputSampleRate: number,
|
|
86
|
+
state: PcmToMulawStreamState,
|
|
87
|
+
): Buffer {
|
|
88
|
+
let data = chunk;
|
|
89
|
+
if (state.oddByte !== null) {
|
|
90
|
+
data = Buffer.concat([Buffer.from([state.oddByte]), chunk]);
|
|
91
|
+
state.oddByte = null;
|
|
92
|
+
}
|
|
93
|
+
if (data.length % 2 !== 0) {
|
|
94
|
+
state.oddByte = data[data.length - 1]!;
|
|
95
|
+
data = data.subarray(0, data.length - 1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (data.length === 0) return Buffer.alloc(0);
|
|
99
|
+
|
|
100
|
+
const inputSamples = data.length / 2;
|
|
101
|
+
const ratio = inputSampleRate / TELEPHONY_SAMPLE_RATE;
|
|
102
|
+
const outputSamples: number[] = [];
|
|
103
|
+
|
|
104
|
+
let srcPos = state.srcPosCarry;
|
|
105
|
+
while (srcPos < inputSamples) {
|
|
106
|
+
const srcIndex = Math.floor(srcPos);
|
|
107
|
+
const frac = srcPos - srcIndex;
|
|
108
|
+
const s0 = data.readInt16LE(srcIndex * 2);
|
|
109
|
+
const s1Index = Math.min(srcIndex + 1, inputSamples - 1);
|
|
110
|
+
const s1 = data.readInt16LE(s1Index * 2);
|
|
111
|
+
const sample = Math.round(s0 + frac * (s1 - s0));
|
|
112
|
+
outputSamples.push(linearToMulaw(clamp16(sample)));
|
|
113
|
+
srcPos += ratio;
|
|
114
|
+
}
|
|
115
|
+
state.srcPosCarry = srcPos - inputSamples;
|
|
116
|
+
|
|
117
|
+
const output = Buffer.alloc(outputSamples.length);
|
|
118
|
+
for (let i = 0; i < outputSamples.length; i++) {
|
|
119
|
+
output[i] = outputSamples[i]!;
|
|
120
|
+
}
|
|
121
|
+
return output;
|
|
122
|
+
}
|
|
123
|
+
|
|
70
124
|
function linearToMulaw(sample: number): number {
|
|
71
125
|
const BIAS = 132;
|
|
72
126
|
const CLIP = 32635;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
1
2
|
import type { VoiceCallTtsConfig } from "./config.js";
|
|
2
3
|
import type { CoreConfig } from "./core-bridge.js";
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
convertPcmToMulaw8k,
|
|
6
|
+
convertPcmChunkToMulaw8k,
|
|
7
|
+
createPcmToMulawStreamState,
|
|
8
|
+
} from "./telephony-audio.js";
|
|
4
9
|
|
|
5
10
|
export type TelephonyTtsRuntime = {
|
|
6
11
|
textToSpeechTelephony: (params: {
|
|
@@ -14,10 +19,18 @@ export type TelephonyTtsRuntime = {
|
|
|
14
19
|
provider?: string;
|
|
15
20
|
error?: string;
|
|
16
21
|
}>;
|
|
22
|
+
textToSpeechTelephonyStream?: (params: { text: string; cfg: CoreConfig }) => Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
stream?: ReadableStream<Uint8Array>;
|
|
25
|
+
sampleRate?: number;
|
|
26
|
+
cleanup?: () => void;
|
|
27
|
+
error?: string;
|
|
28
|
+
}>;
|
|
17
29
|
};
|
|
18
30
|
|
|
19
31
|
export type TelephonyTtsProvider = {
|
|
20
32
|
synthesizeForTelephony: (text: string) => Promise<Buffer>;
|
|
33
|
+
synthesizeForTelephonyStream?: (text: string) => AsyncGenerator<Buffer, void, unknown>;
|
|
21
34
|
};
|
|
22
35
|
|
|
23
36
|
const BLOCKED_MERGE_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
@@ -30,7 +43,7 @@ export function createTelephonyTtsProvider(params: {
|
|
|
30
43
|
const { coreConfig, ttsOverride, runtime } = params;
|
|
31
44
|
const mergedConfig = applyTtsOverride(coreConfig, ttsOverride);
|
|
32
45
|
|
|
33
|
-
|
|
46
|
+
const provider: TelephonyTtsProvider = {
|
|
34
47
|
synthesizeForTelephony: async (text: string) => {
|
|
35
48
|
const result = await runtime.textToSpeechTelephony({
|
|
36
49
|
text,
|
|
@@ -44,6 +57,31 @@ export function createTelephonyTtsProvider(params: {
|
|
|
44
57
|
return convertPcmToMulaw8k(result.audioBuffer, result.sampleRate);
|
|
45
58
|
},
|
|
46
59
|
};
|
|
60
|
+
|
|
61
|
+
if (runtime.textToSpeechTelephonyStream) {
|
|
62
|
+
const streamFn = runtime.textToSpeechTelephonyStream;
|
|
63
|
+
provider.synthesizeForTelephonyStream = async function* (text: string) {
|
|
64
|
+
const result = await streamFn({ text, cfg: mergedConfig });
|
|
65
|
+
if (!result.success || !result.stream || !result.sampleRate) {
|
|
66
|
+
throw new Error(result.error ?? "TTS streaming failed");
|
|
67
|
+
}
|
|
68
|
+
const state = createPcmToMulawStreamState();
|
|
69
|
+
const reader = result.stream.getReader();
|
|
70
|
+
try {
|
|
71
|
+
while (true) {
|
|
72
|
+
const { done, value } = await reader.read();
|
|
73
|
+
if (done) break;
|
|
74
|
+
const mulaw = convertPcmChunkToMulaw8k(Buffer.from(value), result.sampleRate, state);
|
|
75
|
+
if (mulaw.length > 0) yield mulaw;
|
|
76
|
+
}
|
|
77
|
+
} finally {
|
|
78
|
+
reader.releaseLock();
|
|
79
|
+
result.cleanup?.();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return provider;
|
|
47
85
|
}
|
|
48
86
|
|
|
49
87
|
function applyTtsOverride(coreConfig: CoreConfig, override?: VoiceCallTtsConfig): CoreConfig {
|
|
@@ -398,15 +398,24 @@ export class VoiceCallWebhookServer {
|
|
|
398
398
|
|
|
399
399
|
if (result.error) {
|
|
400
400
|
console.error(`[voice-call] Response generation error: ${result.error}`);
|
|
401
|
+
await this.manager.speak(callId, "Sorry, I hit a snag there. Could you try again?");
|
|
401
402
|
return;
|
|
402
403
|
}
|
|
403
404
|
|
|
404
405
|
if (result.text) {
|
|
405
406
|
console.log(`[voice-call] AI response: "${result.text}"`);
|
|
406
407
|
await this.manager.speak(callId, result.text);
|
|
408
|
+
} else {
|
|
409
|
+
console.warn(`[voice-call] Empty response for call ${callId} — speaking fallback`);
|
|
410
|
+
await this.manager.speak(callId, "Hmm, I didn't quite get that. Could you say that again?");
|
|
407
411
|
}
|
|
408
412
|
} catch (err) {
|
|
409
413
|
console.error(`[voice-call] Auto-response error:`, err);
|
|
414
|
+
try {
|
|
415
|
+
await this.manager.speak(callId, "Sorry, something went wrong. Give me a moment.");
|
|
416
|
+
} catch {
|
|
417
|
+
// best-effort
|
|
418
|
+
}
|
|
410
419
|
}
|
|
411
420
|
}
|
|
412
421
|
}
|
package/package.json
CHANGED