Skip to content

fix(agui): Fix duplicate TextMessageEnd emission (#562)#586

Merged
AlbumenJ merged 4 commits intoagentscope-ai:mainfrom
fishl3j:fix-agui-duplicate-text-message-end
Jan 22, 2026
Merged

fix(agui): Fix duplicate TextMessageEnd emission (#562)#586
AlbumenJ merged 4 commits intoagentscope-ai:mainfrom
fishl3j:fix-agui-duplicate-text-message-end

Conversation

@fishl3j
Copy link
Contributor

@fishl3j fishl3j commented Jan 16, 2026

Background: Fix Duplicate AguiEvent.TextMessageEnd Issue

Problem Description

When using AGUI protocol to request a ReActAgent with SKILL and TOOL capabilities, the AguiAgentAdapter was emitting duplicate AguiEvent.TextMessageEnd events, causing incorrect event closure in the AGUI event stream.

Root Cause

The issue occurs in the convertEvent method of AguiAgentAdapter when processing REASONING events that contain both TextBlock and ToolUseBlock content blocks:

  1. First emission path: When processing a ToolUseBlock ,checks if there's an active text message and attempts to end it before starting the tool call (lines 162-169).

  2. Second emission path: When processing a TextBlock in the last event (event.isLast() == true), the code emits TextMessageEnd to close the text message (lines 152-158).

  3. The bug: If a message contains both text content and tool usage, and the text block is processed as the last event, the TextMessageEnd is emitted. However, when the subsequent ToolUseBlock is processed, the code doesn't check if the message has already been ended, leading to a duplicate TextMessageEnd event.

Impact

  • Issue: #562 - AGUI方式下请求使用Skill的ReActAgent,返回的AguiEvent存在闭合错误
  • Version affected: 1.0.8-SNAPSHOT
  • Symptoms:
    • Duplicate TextMessageEnd events in the AGUI event stream
    • Incorrect event closure state
    • Potential issues with AGUI clients expecting proper event sequencing

Solution

Added a guard check using state.hasEndedMessage(messageId) before emitting TextMessageEnd events. This ensures that:

  1. The message end event is only emitted once per message
  2. The state tracking correctly reflects whether a message has been closed
  3. The event stream maintains proper sequencing and closure semantics

Code Changes

The fix adds a conditional check before emitting TextMessageEnd:

if (!state.hasEndedMessage(messageId)) {
    events.add(
        new AguiEvent.TextMessageEnd(
            state.threadId, state.runId, messageId));
    state.endMessage(messageId);
}

This prevents duplicate emissions while maintaining the existing logic for properly closing messages when tool calls are encountered.

@fishl3j fishl3j requested a review from a team January 16, 2026 07:09
@cla-assistant
Copy link

cla-assistant bot commented Jan 16, 2026

CLA assistant check
All committers have signed the CLA.

@fishl3j fishl3j force-pushed the fix-agui-duplicate-text-message-end branch from 9beab1b to 0ec149a Compare January 16, 2026 07:11
@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

This test covers the new code path at lines 153-158 in AguiAgentAdapter
that checks if a message has already been ended before emitting
TextMessageEnd event. This fixes the patch coverage issue for commit
9beab1b.
Copy link
Collaborator

@AlbumenJ AlbumenJ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Please resolve conflicts

THX

…text-message-end

# Conflicts:
#	agentscope-extensions/agentscope-extensions-agui/src/test/java/io/agentscope/core/agui/adapter/AguiAgentAdapterTest.java
@fishl3j fishl3j requested a review from AlbumenJ January 21, 2026 05:04
@AlbumenJ AlbumenJ merged commit a80cc9b into agentscope-ai:main Jan 22, 2026
5 checks passed
Alexxigang pushed a commit to Alexxigang/agentscope-java that referenced this pull request Jan 25, 2026
…gentscope-ai#586)

# Background: Fix Duplicate AguiEvent.TextMessageEnd Issue

## Problem Description

When using AGUI protocol to request a ReActAgent with SKILL and TOOL
capabilities, the `AguiAgentAdapter` was emitting duplicate
`AguiEvent.TextMessageEnd` events, causing incorrect event closure in
the AGUI event stream.

## Root Cause

The issue occurs in the `convertEvent` method of `AguiAgentAdapter` when
processing `REASONING` events that contain both `TextBlock` and
`ToolUseBlock` content blocks:

1. **First emission path**: When processing a `ToolUseBlock` ,checks if
there's an active text message and attempts to end it before starting
the tool call (lines 162-169).

2. **Second emission path**: When processing a `TextBlock` in the last
event (`event.isLast() == true`), the code emits `TextMessageEnd` to
close the text message (lines 152-158).

3. **The bug**: If a message contains both text content and tool usage,
and the text block is processed as the last event, the `TextMessageEnd`
is emitted. However, when the subsequent `ToolUseBlock` is processed,
the code doesn't check if the message has already been ended, leading to
a duplicate `TextMessageEnd` event.

## Impact

- **Issue**:
[agentscope-ai#562](agentscope-ai#562) -
AGUI方式下请求使用Skill的ReActAgent,返回的AguiEvent存在闭合错误
- **Version affected**: 1.0.8-SNAPSHOT
- **Symptoms**: 
  - Duplicate `TextMessageEnd` events in the AGUI event stream
  - Incorrect event closure state
  - Potential issues with AGUI clients expecting proper event sequencing

## Solution

Added a guard check using `state.hasEndedMessage(messageId)` before
emitting `TextMessageEnd` events. This ensures that:

1. The message end event is only emitted once per message
2. The state tracking correctly reflects whether a message has been
closed
3. The event stream maintains proper sequencing and closure semantics

## Code Changes

The fix adds a conditional check before emitting `TextMessageEnd`:

```java
if (!state.hasEndedMessage(messageId)) {
    events.add(
        new AguiEvent.TextMessageEnd(
            state.threadId, state.runId, messageId));
    state.endMessage(messageId);
}
```

This prevents duplicate emissions while maintaining the existing logic
for properly closing messages when tool calls are encountered.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants