voice-call: log assistant speech as bot transcript in realtime calls

call.speaking events already carry a text field (used by Telnyx) but the
manager was discarding it. Wire it through addTranscriptEntry so any
call.speaking event with non-empty text records a speaker:"bot" entry.

In the realtime handler, emit call.speaking for assistant turns when the
transcript is final, mirroring the existing user call.speech path. This
restores speaker:"bot" entries in calls.jsonl for realtime calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Forrest Blount 2026-03-12 21:56:17 +00:00
parent ea4b9a4463
commit 6c6c6388bd
2 changed files with 14 additions and 1 deletions

View File

@ -204,6 +204,9 @@ export function processEvent(ctx: EventContext, event: NormalizedEvent): void {
break;
case "call.speaking":
if (event.text) {
addTranscriptEntry(call, "bot", event.text);
}
transitionState(call, "speaking");
break;

View File

@ -233,7 +233,6 @@ export class RealtimeCallHandler {
onTranscript: (role, text, isFinal) => {
if (isFinal) {
// Emit user speech through the manager for transcript persistence
if (role === "user") {
const event: NormalizedEvent = {
id: `realtime-speech-${callSid}-${Date.now()}`,
@ -245,6 +244,17 @@ export class RealtimeCallHandler {
isFinal: true,
};
this.manager.processEvent(event);
} else if (role === "assistant") {
// Log assistant turns via call.speaking so they appear as speaker:"bot"
// in the transcript (same mechanism Telnyx uses for TTS speech).
this.manager.processEvent({
id: `realtime-bot-${callSid}-${Date.now()}`,
type: "call.speaking",
callId,
providerCallId: callSid,
timestamp: Date.now(),
text,
});
}
}
},