Skip to content

Commit b5ce75a

Browse files
fix: #2940 emit RealtimeHistoryUpdated on transcript_delta
When RealtimeSession received a RealtimeModelTranscriptDeltaEvent, it accumulated transcript text into self._history but only forwarded the raw model event. Subscribers that follow the documented history_added / history_updated pattern never observed the live transcript update. Emit RealtimeHistoryUpdated after the history mutation, matching the input_audio_transcription_completed branch, and update the session test that asserted transcript_delta was an ignored event.
1 parent f2fb9ff commit b5ce75a

2 files changed

Lines changed: 29 additions & 11 deletions

File tree

src/agents/realtime/session.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ async def on_event(self, event: RealtimeModelEvent) -> None:
313313
content=[AssistantAudio(transcript=self._item_transcripts[item_id])],
314314
),
315315
)
316+
await self._put_event(
317+
RealtimeHistoryUpdated(info=self._event_info, history=self._history)
318+
)
316319

317320
# Check if we should run guardrails based on debounce threshold
318321
current_length = len(self._item_transcripts[item_id])

tests/realtime/test_session.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -565,16 +565,9 @@ async def test_item_deleted_event_removes_item(self, mock_model, mock_agent):
565565

566566
@pytest.mark.asyncio
567567
async def test_ignored_events_only_generate_raw_events(self, mock_model, mock_agent):
568-
"""Test that ignored events (transcript_delta, connection_status, other) only generate raw
569-
events"""
568+
"""Test that ignored events (connection_status, other) only generate raw events."""
570569
session = RealtimeSession(mock_model, mock_agent, None)
571570

572-
# Test transcript delta (should be ignored per TODO comment)
573-
transcript_event = RealtimeModelTranscriptDeltaEvent(
574-
item_id="item_1", delta="hello", response_id="resp_1"
575-
)
576-
await session.on_event(transcript_event)
577-
578571
# Test connection status (should be ignored)
579572
connection_event = RealtimeModelConnectionStatusEvent(status="connected")
580573
await session.on_event(connection_event)
@@ -583,13 +576,35 @@ async def test_ignored_events_only_generate_raw_events(self, mock_model, mock_ag
583576
other_event = RealtimeModelOtherEvent(data={"custom": "data"})
584577
await session.on_event(other_event)
585578

586-
# Should only have 3 raw events (no transformed events)
587-
assert session._event_queue.qsize() == 3
579+
# Should only have 2 raw events (no transformed events)
580+
assert session._event_queue.qsize() == 2
588581

589-
for _ in range(3):
582+
for _ in range(2):
590583
event = await session._event_queue.get()
591584
assert isinstance(event, RealtimeRawModelEvent)
592585

586+
@pytest.mark.asyncio
587+
async def test_transcript_delta_emits_history_updated(self, mock_model, mock_agent):
588+
"""transcript_delta updates the live history and must emit RealtimeHistoryUpdated
589+
so subscribers following history_added/history_updated stay in sync (issue #2940)."""
590+
session = RealtimeSession(mock_model, mock_agent, None)
591+
592+
transcript_event = RealtimeModelTranscriptDeltaEvent(
593+
item_id="item_1", delta="hello", response_id="resp_1"
594+
)
595+
await session.on_event(transcript_event)
596+
597+
# Expect a raw event plus a history_updated event.
598+
assert session._event_queue.qsize() == 2
599+
600+
events = [await session._event_queue.get() for _ in range(2)]
601+
assert any(isinstance(e, RealtimeRawModelEvent) for e in events)
602+
history_updated = next(
603+
(e for e in events if isinstance(e, RealtimeHistoryUpdated)), None
604+
)
605+
assert history_updated is not None
606+
assert history_updated.history == session._history
607+
593608
@pytest.mark.asyncio
594609
async def test_function_call_event_triggers_tool_handling(self, mock_model, mock_agent):
595610
"""Test that function_call events trigger tool call handling synchronously when disabled"""

0 commit comments

Comments
 (0)