Skip to content

Commit 1df846b

Browse files
author
sunwg2
committed
fix(hook): skip auto-patch only when ToolResultBlock IDs match pending tool calls
1 parent 13a7167 commit 1df846b

1 file changed

Lines changed: 31 additions & 6 deletions

File tree

agentscope-core/src/main/java/io/agentscope/core/hook/PendingToolRecoveryHook.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@
4747
* <p><b>Behavior:</b>
4848
* <ul>
4949
* <li>Only activates when the agent is a {@link ReActAgent}</li>
50-
* <li>Only patches when pending tool calls exist AND user input does not contain
51-
* {@link ToolResultBlock}s (i.e., user is not providing results themselves)</li>
50+
* <li>Only patches when pending tool calls exist AND user input does not contain any
51+
* {@link ToolResultBlock} whose ID matches a current pending tool call ID</li>
52+
* <li>If the input contains {@link ToolResultBlock}s but none of their IDs match the current
53+
* pending IDs (i.e., stale or unrelated results), a warning is logged and the input is
54+
* passed through unmodified — {@link ReActAgent}'s {@code doCall} will then reject the
55+
* invalid IDs with an {@link IllegalStateException}</li>
5256
* <li>Generated error results are added to memory as TOOL-role messages</li>
5357
* </ul>
5458
*
@@ -107,10 +111,31 @@ private Mono<PreCallEvent> handlePreCall(PreCallEvent event) {
107111
return Mono.just(event);
108112
}
109113

110-
boolean userProvidedResults =
111-
inputMessages.stream().anyMatch(m -> m.hasContentBlocks(ToolResultBlock.class));
112-
if (userProvidedResults) {
113-
return Mono.just(event);
114+
// Collect all ToolResultBlock IDs present in the input messages
115+
Set<String> providedResultIds =
116+
inputMessages.stream()
117+
.flatMap(m -> m.getContentBlocks(ToolResultBlock.class).stream())
118+
.map(ToolResultBlock::getId)
119+
.collect(Collectors.toSet());
120+
121+
if (!providedResultIds.isEmpty()) {
122+
// Check whether any provided ID actually matches a current pending tool call.
123+
// Only treat input as user-provided results when the IDs are relevant;
124+
// stale or unrelated IDs should not suppress auto-recovery.
125+
if (providedResultIds.stream().anyMatch(pendingIds::contains)) {
126+
// User provided at least one relevant result — skip auto-patch and let
127+
// doCall's validateAndAddToolResults handle strict ID validation
128+
return Mono.just(event);
129+
}
130+
// Input contains ToolResultBlocks, but none of their IDs match the current
131+
// pending tool call IDs (stale / unrelated results). Log a warning and
132+
// proceed with auto-patch; doCall will reject the invalid IDs with
133+
// an IllegalStateException, which is the correct strict-mode behavior.
134+
log.warn(
135+
"Input contains ToolResultBlock(s) with IDs {} that do not match"
136+
+ " pending tool call IDs {}. Proceeding with auto-patch.",
137+
providedResultIds,
138+
pendingIds);
114139
}
115140

116141
// Auto-patch: generate error tool results for orphaned pending tool calls

0 commit comments

Comments
 (0)