Skip to content

fix(core): emit ExternalExecutionResultEvent when external tool results resume - #2605

Merged
zouyx merged 2 commits into
mainfrom
emit-external-execution-result-event
Aug 8, 2026
Merged

zouyx merged 2 commits into
mainfrom
emit-external-execution-result-event

Conversation

@jujn

@jujn jujn commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fix the external tool execution resume loop by emitting ExternalExecutionResultEvent when externally executed ToolResultBlocks are provided back to ReActAgent.

The agent now persists the replyId from RequireExternalExecutionEvent on the pending assistant message, restores that correlation when matching tool results are accepted in a later call(), emits ExternalExecutionResultEvent with the same replyId, and then continues reasoning.

This also simplifies the confirmation resume path by combining confirmation validation and acceptance into validateAndAcceptConfirmResults.

Changes

  • Add metadata for correlating external execution requests with later result events.
  • Emit ExternalExecutionResultEvent after accepted external tool results are added to context.
  • Reuse the pending-request reply id helper for both user confirmation and external execution flows.
  • Add coverage for the full external execution resume flow:
    • RequireExternalExecutionEvent
    • external ToolResultBlock resume
    • correlated ExternalExecutionResultEvent
    • continued model reasoning
  • Update v2 English and Chinese docs for external tool execution and event reference.

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

Copilot AI review requested due to automatic review settings August 7, 2026 13:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes the external-tool resume loop by persisting a correlation replyId for external-execution pauses and emitting a correlated ExternalExecutionResultEvent when externally executed ToolResultBlocks are accepted on a later call(). It also refactors the permission-HITL resume path to validate + accept confirmations in a single helper and updates v2 docs accordingly. The PR title follows the conventional commit format.

Changes:

  • Persist pending-request replyId metadata on the paused assistant message for both confirmation HITL and external execution, and restore it during resume.
  • Emit ExternalExecutionResultEvent (correlated by replyId) after accepting resumed external tool results, then continue reasoning.
  • Add a test covering the full external execution resume flow and update v2 English/Chinese docs for the revised event semantics.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/v2/zh/docs/building-blocks/tool.md Updates external-execution description to reflect resume via ToolResultBlock and correlated ExternalExecutionResultEvent.
docs/v2/zh/docs/building-blocks/message-and-event.md Documents RequireExternalExecutionEvent/ExternalExecutionResultEvent fields and correlation behavior.
docs/v2/zh/docs/building-blocks/agent.md Updates external-execution resume walkthrough to mention correlated result event emission before reasoning continues.
docs/v2/en/docs/building-blocks/tool.md Same as zh: clarifies resume and correlated event emission semantics.
docs/v2/en/docs/building-blocks/message-and-event.md Same as zh: documents methods and correlation for external execution events.
docs/v2/en/docs/building-blocks/agent.md Same as zh: updates the resume walkthrough for correlated ExternalExecutionResultEvent.
agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java Adds correlation metadata helpers, refactors confirm-resume validation/acceptance, and emits ExternalExecutionResultEvent on external-result resume.
agentscope-core/src/main/java/io/agentscope/core/message/Msg.java Adds metadata key for external-execution pause replyId correlation.
agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentNewLoopReplyTest.java Adds coverage for external execution resume emitting a correlated ExternalExecutionResultEvent and continuing model reasoning.
Suppressed comments (1)

agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java:2235

  • validateAndAddToolResults only clears the external-execution replyId metadata when replyId is non-empty. If the metadata key exists but the value is missing/invalid, the key will remain on the assistant message and can cause stale correlation on later turns. Clear the metadata key after accepting results regardless, and only guard event emission.
            String replyId =
                    resolvePendingRequestReplyId(Msg.METADATA_EXTERNAL_EXECUTION_REQUEST_REPLY_ID);
            if (!replyId.isEmpty()) {
                publishEvent(new ExternalExecutionResultEvent(replyId, results));
                clearPendingRequestReplyId(Msg.METADATA_EXTERNAL_EXECUTION_REQUEST_REPLY_ID);

Comment on lines +1866 to +1870
String replyId = resolvePendingRequestReplyId(Msg.METADATA_CONFIRM_REQUEST_REPLY_ID);
if (!replyId.isEmpty()) {
publishEvent(new UserConfirmResultEvent(replyId, normalized));
clearPendingRequestReplyId(Msg.METADATA_CONFIRM_REQUEST_REPLY_ID);
}
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.21053% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...e/src/main/java/io/agentscope/core/ReActAgent.java 84.21% 0 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!


state.contextMutable().addAll(msgs);
String replyId =
resolvePendingRequestReplyId(Msg.METADATA_EXTERNAL_EXECUTION_REQUEST_REPLY_ID);

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.

我看 resolvePendingRequestReplyId 找最后一条 Msg,但上面有 addAll 过一次,会不会找到上面 add 进去的 msg?
这是对的吗?如果是对的,为啥不在 addAll 之前滤出来?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

这里应该是顺序无关的吧。state.contextMutable().addAll(msgs) 的 msgs 来自用户;resolvePendingRequestReplyId 找的是最后一条 Assistant 消息。

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.

方法没有控制只有user,可能未来会有bug?

@zouyx zouyx self-assigned this Aug 7, 2026

@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.

Summary

This PR modifies 9 files with 369 lines of diff.

Observations

  • Files changed: 9
  • Test coverage: ✅ Tests included
  • CLA: ✅ Signed

Suggestions

  • Please ensure all public API changes are backward compatible
  • Consider adding unit tests for new logic paths

Automated review by github-manager-bot

@jujn
jujn requested a review from zouyx August 8, 2026 05:14
@zouyx
zouyx merged commit 3fb4d0e into main Aug 8, 2026
6 checks passed
@jujn
jujn deleted the emit-external-execution-result-event branch August 8, 2026 11:04
wzl521 pushed a commit to wzl521/agentscope-java that referenced this pull request Aug 12, 2026
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.

4 participants