Skip to content

Commit 3f50792

Browse files
committed
fix: sync partial transcripts to chat when turn ends
Previously, chat messages were lost when only STTPartialTranscriptEvent events were received and no final STTTranscriptEvent arrived before the turn ended. The transcript was sent to the LLM but never synced to chat. This fix moves chat sync from the STTTranscriptEvent handler to _on_turn_event, ensuring the accumulated transcript (from partials or finals) is always recorded in chat when a turn completes.
1 parent 210b64d commit 3f50792

File tree

1 file changed

+29
-19
lines changed
  • agents-core/vision_agents/core/agents

1 file changed

+29
-19
lines changed

agents-core/vision_agents/core/agents/agents.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -339,25 +339,9 @@ async def on_stt_transcript_event_create_response(
339339
async def on_error(event: STTErrorEvent):
340340
self.logger.error("stt error event %s", event)
341341

342-
@self.events.subscribe
343-
async def on_stt_transcript_event_sync_conversation(event: STTTranscriptEvent):
344-
if self.conversation is None:
345-
return
346-
347-
user_id = event.user_id()
348-
if user_id is None:
349-
raise ValueError("missing user_id")
350-
351-
with self.span("agent.on_stt_transcript_event_sync_conversation"):
352-
await self.conversation.upsert_message(
353-
message_id=str(uuid.uuid4()),
354-
role="user",
355-
user_id=user_id,
356-
content=event.text or "",
357-
completed=True,
358-
replace=True, # Replace any partial transcripts
359-
original=event,
360-
)
342+
# Note: STTTranscriptEvent chat sync is handled in _on_turn_event to ensure
343+
# partial transcripts are also synced when no final transcript arrives.
344+
# See _sync_user_transcript_to_chat() for the implementation.
361345

362346
@self.events.subscribe
363347
async def on_realtime_user_speech_transcription(
@@ -461,6 +445,27 @@ async def simple_audio_response(
461445
if _is_audio_llm(self.llm):
462446
await self.llm.simple_audio_response(pcm, participant)
463447

448+
async def _sync_user_transcript_to_chat(
449+
self, transcript: str, user_id: str
450+
) -> None:
451+
"""Sync user transcript to chat conversation.
452+
453+
Called when a turn ends to ensure the user's message is recorded in chat,
454+
whether it came from final STTTranscriptEvent or only partial transcripts.
455+
"""
456+
if self.conversation is None or not transcript:
457+
return
458+
459+
with self.span("agent._sync_user_transcript_to_chat"):
460+
await self.conversation.upsert_message(
461+
message_id=str(uuid.uuid4()),
462+
role="user",
463+
user_id=user_id,
464+
content=transcript,
465+
completed=True,
466+
replace=True,
467+
)
468+
464469
def subscribe(self, function):
465470
"""Subscribe a callback to the agent-wide event bus.
466471
@@ -1098,6 +1103,11 @@ async def _on_turn_event(self, event: TurnStartedEvent | TurnEndedEvent) -> None
10981103
buffer.reset()
10991104

11001105
if transcript.strip():
1106+
# Sync user transcript to chat (handles both final and partial-only cases)
1107+
await self._sync_user_transcript_to_chat(
1108+
transcript, event.participant.user_id
1109+
)
1110+
11011111
# cancel the old task if the text changed in the meantime
11021112

11031113
if (

0 commit comments

Comments
 (0)