Skip to content

fix(agui): dedupe resume tool results already present in messages - #2955

Merged
jujn merged 2 commits into
agentscope-ai:mainfrom
resomi:fix/agui-dedupe-resume-tool-results
Sep 5, 2026
Merged

jujn merged 2 commits into
agentscope-ai:mainfrom
resomi:fix/agui-dedupe-resume-tool-results

Conversation

@resomi

@resomi resomi commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.0.3-SNAPSHOT (main)

Description

Background

CopilotKit v2 useInterrupt.resolve() for reason: "tool_call" interrupts attaches:

  • messages: role:"tool" result (for UI / history)
  • resume[]: protocol resume payload

AgentScope schema-only HITL (registerSchema → TOOL_SUSPENDED → interrupt) uses reason: "tool_call". AguiMessageConverter.toMsgList previously converted both into the same ToolResultBlock id → ReActAgent Duplicate tool result ID.

Related CopilotKit issue #6201 does not remove dual-send for tool_call interrupts.

Changes

  • AguiMessageConverter.toMsgList: skip ordinary tool resumes whose toolCallId already has a ToolResultBlock from messages (messages win; no payload comparison).
  • Permission-confirm resumes (agentscope.interruptKind=permission_confirm) still always append USER ConfirmResult.
  • Unit tests for dual-path dedupe + permission-confirm keep behavior.

How to test

mvn -pl agentscope-extensions/agentscope-extensions-protocol/agentscope-extensions-agui \
  -Dtest=AguiMessageConverterTest#testCopilotKitDualPathSkipsDuplicateToolResultFromResume+testPermissionConfirmResumeKeptWhenToolMessageAlreadyPresent \
  test

Optional E2E: agentscope-copilotkit agent default, schema-only requestHumanApproval, resume with tool message + resume[] — should continue without Duplicate tool result ID.

Checklist

  • Code has been formatted with mvn spotless:apply
  • Focused unit tests are passing
  • Javadoc comments are complete and follow project conventions
  • Code is ready for review

Fixes #2954

CopilotKit useInterrupt.resolve() sends both a role=tool message and
resume[] for tool_call interrupts. Skip converting ordinary resumes that
would duplicate an existing ToolResultBlock id so ReActAgent does not
throw Duplicate tool result ID. Permission-confirm resumes still emit
ConfirmResult.
@CLAassistant

CLAassistant commented Sep 3, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.33333% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...cope/core/agui/converter/AguiMessageConverter.java 73.33% 1 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@oss-maintainer oss-maintainer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. This PR records ToolResultBlock IDs produced from incoming AG-UI messages and skips ordinary resume results when the ID already exists, while retaining permission-confirm results. I verified the converter call path, the ReActAgent duplicate-result validation, and null-list handling; the focused new tests and the full 48-test AguiMessageConverterTest suite pass, so the change is localized, correct, and adequately covered.


Automated review by github-manager-bot

@jujn
jujn merged commit 9073c43 into agentscope-ai:main Sep 5, 2026
6 checks passed
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.

[Bug]: AguiMessageConverter duplicates ToolResultBlock when CopilotKit sends tool message + resume

4 participants