fix(agui): emit AG-UI interrupt for permission-type HITL tool confirmation (#2437) - #2495
Open
wzq-xzwj wants to merge 1 commit into
Open
fix(agui): emit AG-UI interrupt for permission-type HITL tool confirmation (#2437)#2495wzq-xzwj wants to merge 1 commit into
wzq-xzwj wants to merge 1 commit into
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…ation (agentscope-ai#2437) The AG-UI adapter only handled suspend-type HITL (ToolSuspendException / frontend tools, GenerateReason.TOOL_SUSPENDED). Permission-type HITL -- where a non-readonly tool under DEFAULT permission mode makes ReActAgent emit RequireUserConfirmEvent + RequestStopEvent(PERMISSION_ASKING) -- was dropped: RequireUserConfirmEvent fell through to the RAW fallback and no Interrupt reached RUN_FINISHED, so the frontend could never confirm/deny. Building on the converter-registry architecture introduced by agentscope-ai#2306: - Add PermissionConfirmEventConverter that maps RequireUserConfirmEvent to one AG-UI Interrupt per pending ToolUseBlock (reason "tool_confirmation"), carrying toolName/toolInput/toolContent/replyId metadata, and register it in AgentEventConverterRegistry. Interrupt id keeps the "replyId:toolCallId" format so resume can recover the tool call id. - AguiResumeCoordinator now tracks "tool_confirmation" interrupts alongside "tool_call" ones and exposes them via a new resume-interrupts runtime key. - AguiAgentAdapter forwards the resume interrupts to the message converter. - AguiMessageConverter builds a ConfirmResult (approved/denied) from the resume payload for confirmation interrupts, reconstructing the ToolUseBlock with non-null JSON content to avoid the tool-input validation NPE on resume; non-confirmation resumes keep the existing ToolResultBlock path. - Add unit tests covering resolved/cancelled/explicit-false confirmations and the non-confirmation fallback.
wzq-xzwj
force-pushed
the
fix/2437-permission-hitl-interrupt
branch
from
July 30, 2026 10:50
abd07d3 to
f3ece2c
Compare
Contributor
Author
|
@jujn 麻烦帮忙审核一下哈,多谢 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & Why
Fixes #2437.
The AG-UI adapter only surfaced suspend-type HITL (tools that throw
ToolSuspendException/ frontend tools, i.e.GenerateReason.TOOL_SUSPENDED). The permission-type HITL path was dropped:DEFAULTpermission mode, a non-readonly tool makesReActAgentemitRequireUserConfirmEvent+RequestStopEvent(PERMISSION_ASKING).RequireUserConfirmEventhad no converter, so it fell through to theRAWfallback and noInterruptreachedRUN_FINISHED.This builds directly on the converter-registry architecture introduced in #2306, extending it to the confirmation path rather than changing its design.
Changes
PermissionConfirmEventConverter(new) — mapsRequireUserConfirmEventto one AG-UIInterruptper pendingToolUseBlock, with reasontool_confirmationandtoolName/toolInput/toolContent/replyIdmetadata. Registered inAgentEventConverterRegistry. The interrupt id keeps thereplyId:toolCallIdformat so resume can recover the tool call id (consistent withAgentLifecycleEventConverter).AguiResumeCoordinator— trackstool_confirmationinterrupts alongsidetool_call, exposing them through a new resume-interrupts runtime-context key.AguiAgentAdapter— forwards the resume interrupts to the message converter.AguiMessageConverter— for confirmation interrupts, builds aConfirmResult(approved/denied) from the resume payload and reconstructs theToolUseBlockwith non-null JSON content (viaJsonUtils.resolveToolCallArgsJson) to avoid the tool-input validation failure (argument "content" is null) on resume. Non-confirmation resumes keep the existingToolResultBlockpath.Tests
approved:falseconfirmations and the non-confirmation fallback.agentscope-extensions-aguimodule suite: 435 tests, 0 failures, 0 errors.Notes
reason.