← back to Butlr
twilio: Stream track=both_tracks so listener hears Butlr's voice too
83398b4e9626751701acadd2f29818e13e9a9d32 · 2026-05-13 07:36:46 -0700 · SteveStudio2
inbound_track only captured the business side — the listener heard
the IVR and rep but Butlr's own TTS responses were silent. AI and rep
speak in alternation, not overlap, so there's no echo to avoid by
splitting tracks. Switch to both_tracks. Bonus: Steve can now verify
the consent announcement actually played at call start.
Exposed by Steve testing the post-prompt-fix AAA + Capital One calls
2026-05-13 — he reported "nothing is talking back" while logs showed
the AI was correctly responding "No" / "I don't know" / etc.
Files touched
M routes/twilio-webhooks.js
Diff
commit 83398b4e9626751701acadd2f29818e13e9a9d32
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 07:36:46 2026 -0700
twilio: Stream track=both_tracks so listener hears Butlr's voice too
inbound_track only captured the business side — the listener heard
the IVR and rep but Butlr's own TTS responses were silent. AI and rep
speak in alternation, not overlap, so there's no echo to avoid by
splitting tracks. Switch to both_tracks. Bonus: Steve can now verify
the consent announcement actually played at call start.
Exposed by Steve testing the post-prompt-fix AAA + Capital One calls
2026-05-13 — he reported "nothing is talking back" while logs showed
the AI was correctly responding "No" / "I don't know" / etc.
---
routes/twilio-webhooks.js | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/routes/twilio-webhooks.js b/routes/twilio-webhooks.js
index 3d2def5..c5ecaa8 100644
--- a/routes/twilio-webhooks.js
+++ b/routes/twilio-webhooks.js
@@ -73,9 +73,12 @@ function turnsFor(callId) {
// chain stays in one execution context for the whole call. The Stream
// stays alive until call hangs up.
function streamStartXml(callId, wsBase) {
- // track="inbound_track" → business voice only (default both_tracks would
- // mix Butlr's outbound TTS into the listener feed, causing echo).
- return `<Start><Stream url="${wsBase}/stream/${callId}" track="inbound_track"/></Start>`;
+ // track="both_tracks" → Steve's listen page hears BOTH sides (the IVR/rep
+ // AND Butlr's TTS responses). Earlier "inbound_track only" was wrong: AI
+ // and rep speak in alternation, not overlap, so there's no echo to worry
+ // about. The cost is the listener also hears the consent announce; that's
+ // fine — it's a feature (Steve gets to verify the announce played).
+ return `<Start><Stream url="${wsBase}/stream/${callId}" track="both_tracks"/></Start>`;
}
// ── /twilio/twiml/:call_id (initial TwiML when Twilio dials a business)
@@ -262,11 +265,19 @@ You will hear text from the other end of the line. Identify what KIND of input i
Input: "What's the name on the account?"
Output: It's ${customerName}.
+8. INPUT-ASK from an automated system ("enter your account number", "say your member number", "enter your 10-digit phone number on your keypad") AND we don't have that info in the data above → SPEAK a transfer request, NEVER press a random digit:
+ Input: "Please enter the 10-digit phone number on the account."
+ Output: I'm sorry, I don't have that handy. Could you transfer me to a representative please?
+ Input: "Say or enter your account number."
+ Output: I don't have the account number. Could I speak with a representative please?
+
═══ HARD RULES ═══
- NEVER greet a rep by a name they didn't just say. If no name was given, just "Hi".
- NEVER press a digit that wasn't explicitly offered in the menu.
+- NEVER press # / * / 0 just to get past an input-ask. SPEAK a transfer request instead.
- NEVER claim "goal achieved" without an explicit answer from the rep.
- NEVER reply with "One moment please" or "I'm checking on that".
+- If asked to enter / say / provide info that isn't listed in your data above, SPEAK case 8 — do NOT press anything.
- Empty input → wait. Don't hangup. Don't speak filler.
- If the IVR repeats itself, press 0 on the SECOND repeat.
- Keep ANY prose reply under 20 words.
← d68c3bf ai-agent: fix 3 bugs exposed by AAA call PSmRTAJ5
·
back to Butlr
·
call-quality-report: one-shot 7-check report card for any ca bf42377 →