Repository navigation
fix(twilio): mark a cut-off reply where playback stopped, and not after a timeout - #1474
Conversation
…er a timeout Addresses the review on SciSharp#1467. - Text goes out faster than it is spoken, so what was sent when the caller cut in is more than they heard. The interrupt's utteranceUntilInterrupt says where playback stopped; the history mark now cuts there when it is the start of what went out, and where the sending stopped otherwise. - An interrupt once the stream was already dropped (the turn timed out and the apology is playing) or the session ended no longer marks the orphaned turn's reply as cut in on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Summary by QodoMark Twilio replies at the playback cutoff, not after a timeout
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
There was a problem hiding this comment.
🟡 Changes recommended
An empty interruption prefix is treated as a missing playback boundary, leaving fully sent replies unmarked as unheard in conversation history even when the caller heard none of the reply.
1 open issue
What changed in this PR
This follow-up to #1467 refines how Twilio interruptions are recorded in conversation history, using playback progress rather than only the text sent.
Changes:
- Use
utteranceUntilInterruptto locate the cut-off point, with a logged fallback to the sent text. - Prevent interrupts from marking replies after the stream was dropped or the session ended.
- Reset playback-boundary tracking for each turn and update the documentation.
| File | Description |
|---|---|
src/Plugins/BotSharp.Plugin.Twilio/Services/ConversationRelaySession.cs |
Tracks playback boundaries and tightens interruption handling for history updates. |
Review effort: Balanced
Twilio reports an empty utteranceUntilInterrupt when the caller cut in before any of the reply played. That was taken as no boundary at all, so a reply fully sent was kept unmarked. Only a missing one falls back to the sent text now; an empty one marks all of the reply as unheard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
reviewed |

Follow-up to #1467, addressing its two review findings.
The problems
FailAsyncdrops the stream and plays the apology, but_isProcessingand_streamedThisTurnstay set. A caller talking over the apology set_cutInMidReply, and the orphaned turn's reply was stored as one the caller interrupted.What this does
interrupthandler readsutteranceUntilInterrupt, where Twilio says playback stopped.MarkWhatTheCallerCutOffcuts there when it is the start of what went out, and where the sending stopped otherwise (field missing, or the cut-in landed on something else, such as a filler); that fallback is logged.A side effect of (1): a reply fully sent but not yet stored when the caller cuts in used to be left unmarked (nothing unsent), and is now marked where playback stopped.
Note
Twilio's docs show
utteranceUntilInterruptonly in an example (a partial sentence), without a formal definition. The cut relies on it being the part played before the interruption; if it is not, the fallback keeps today's behaviour.Testing
Covered downstream, where the relay session runs against a fake WebSocket:
utteranceUntilInterruptmatching the sent text stores only the heard part plus the mark;The first and third fail on current master and pass with this change. There is no test project here that covers the Twilio plugin.
🤖 Generated with Claude Code