PendingToolRecoveryHook skips recovery when input contains unrelated ToolResultBlock IDs
Describe the bug
PendingToolRecoveryHook treats any incoming ToolResultBlock as user-provided tool results, without checking whether the tool result IDs match the current pending tool call IDs.
In PendingToolRecoveryHook.handlePreCall, the current logic only checks whether any ToolResultBlock exists:
boolean userProvidedResults =
inputMessages.stream().anyMatch(m -> m.hasContentBlocks(ToolResultBlock.class));
if (userProvidedResults) {
return Mono.just(event);
}
This means that if the input contains a ToolResultBlock with an unrelated, stale, or invalid ID, the hook skips auto-recovery even though the actual pending tool calls are still unresolved.
Later, ReActAgent#doCall validates the provided tool result IDs against pendingIds and may throw an exception, instead of letting PendingToolRecoveryHook recover the real pending calls.
To Reproduce
- Enable pending tool recovery:
ReActAgent agent = ReActAgent.builder()
// other builder config
.enablePendingToolRecovery(true)
.build();
-
Let the agent memory contain a pending tool call, for example pending ID tool_call_1.
-
Call the agent with an input message that contains a ToolResultBlock, but its ID does not match the pending tool call ID, for example tool_call_old.
-
PendingToolRecoveryHook sees that a ToolResultBlock exists and returns without patching tool_call_1.
-
ReActAgent#doCall then validates the result IDs and fails because tool_call_old is not in pendingIds.
Expected behavior
PendingToolRecoveryHook should check the IDs of incoming ToolResultBlocks against pendingIds.
It should only treat input tool results as user-provided results for the current pending calls when their IDs match the current pending tool call IDs.
For example, the hook could collect provided result IDs and compare them with pendingIds before deciding whether to skip auto-recovery.
Error messages
Possible error from ReActAgent#doCall / validateAndAddToolResults:
Invalid tool result IDs: [tool_call_old]. Expected: [tool_call_1]
Environment
- AgentScope-Java Version: [please fill in]
- Java Version: [please fill in]
- OS: Windows
Additional context
The current implementation checks only for the existence of ToolResultBlock:
m.hasContentBlocks(ToolResultBlock.class)
but it does not check whether those ToolResultBlock IDs are related to the pending tool calls found by:
Set<String> pendingIds = findPendingToolUseIds(memory);
This can cause pending tool recovery to be skipped incorrectly.
PendingToolRecoveryHook skips recovery when input contains unrelated ToolResultBlock IDs
Describe the bug
PendingToolRecoveryHooktreats any incomingToolResultBlockas user-provided tool results, without checking whether the tool result IDs match the current pending tool call IDs.In
PendingToolRecoveryHook.handlePreCall, the current logic only checks whether anyToolResultBlockexists:This means that if the input contains a
ToolResultBlockwith an unrelated, stale, or invalid ID, the hook skips auto-recovery even though the actual pending tool calls are still unresolved.Later,
ReActAgent#doCallvalidates the provided tool result IDs againstpendingIdsand may throw an exception, instead of lettingPendingToolRecoveryHookrecover the real pending calls.To Reproduce
Let the agent memory contain a pending tool call, for example pending ID
tool_call_1.Call the agent with an input message that contains a
ToolResultBlock, but its ID does not match the pending tool call ID, for exampletool_call_old.PendingToolRecoveryHooksees that aToolResultBlockexists and returns without patchingtool_call_1.ReActAgent#doCallthen validates the result IDs and fails becausetool_call_oldis not inpendingIds.Expected behavior
PendingToolRecoveryHookshould check the IDs of incomingToolResultBlocks againstpendingIds.It should only treat input tool results as user-provided results for the current pending calls when their IDs match the current pending tool call IDs.
For example, the hook could collect provided result IDs and compare them with
pendingIdsbefore deciding whether to skip auto-recovery.Error messages
Possible error from
ReActAgent#doCall/validateAndAddToolResults:Environment
Additional context
The current implementation checks only for the existence of
ToolResultBlock:but it does not check whether those
ToolResultBlockIDs are related to the pending tool calls found by:This can cause pending tool recovery to be skipped incorrectly.