Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions python/packages/ag-ui/agent_framework_ag_ui/_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ def _handle_text_content(self, content: TextContent) -> list[BaseEvent]:
logger.info(f" Suppressed summary length={len(self.suppressed_summary)}")
return events

# Skip empty text chunks to avoid emitting
# TextMessageContentEvent with an empty `delta` which fails
# Pydantic validation (AG-UI requires non-empty strings).
if not content.text:
logger.info(" SKIPPING TextContent: empty chunk")
return events

if not self.current_message_id:
self.current_message_id = generate_event_id()
start_event = TextMessageStartEvent(
Expand Down
31 changes: 31 additions & 0 deletions python/packages/ag-ui/tests/test_events_comprehensive.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,37 @@ async def test_skip_text_content_for_structured_outputs():
assert len(events) == 0


async def test_skip_text_content_for_empty_text():
"""Test streaming TextContent with empty chunks."""
from agent_framework_ag_ui._events import AgentFrameworkEventBridge

bridge = AgentFrameworkEventBridge(run_id="test_run", thread_id="test_thread")

update1 = AgentRunResponseUpdate(contents=[TextContent(text="Hello ")])
update2 = AgentRunResponseUpdate(contents=[TextContent(text="")]) # Empty chunk
update3 = AgentRunResponseUpdate(contents=[TextContent(text="world")])

events1 = await bridge.from_agent_run_update(update1)
events2 = await bridge.from_agent_run_update(update2)
events3 = await bridge.from_agent_run_update(update3)

# First update: START + CONTENT
assert len(events1) == 2
assert events1[0].type == "TEXT_MESSAGE_START"
assert events1[1].delta == "Hello "

# Second update: should skip empty chunk, no events
assert len(events2) == 0

# Third update: just CONTENT (same message)
assert len(events3) == 1
assert events3[0].type == "TEXT_MESSAGE_CONTENT"
assert events3[0].delta == "world"

# Both content events should have same message_id
assert events1[1].message_id == events3[0].message_id


async def test_tool_call_with_name():
"""Test FunctionCallContent with name emits ToolCallStartEvent."""
from agent_framework_ag_ui._events import AgentFrameworkEventBridge
Expand Down
Loading