agentscope-ai / agentscope-ai/agentscope-java
[Bug]: PendingToolRecoveryHook skips recovery when input contains unrelated ToolResultBlock IDs
- Linguagem predominante
- Java
- Estrelas
- 5.6k
- Forks
- 1.3k
- Merge médio
- 4d 12h
- PRs com merge (30d)
- 77
Descrição
# 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:
```java
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
1. Enable pending tool recovery:
```java
ReActAgent agent = ReActAgent.builder()
// other builder config
.enablePendingToolRecovery(true)
.build();
```
2. Let the agent memory contain a pending tool call, for example pending ID `tool_call_1`.
3. 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`.
4. `PendingToolRecoveryHook` sees that a `ToolResultBlock` exists and returns without patching `tool_call_1`.
5. `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 `ToolResultBlock`s 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`:
```text
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`:
```java
m.hasContentBlocks(ToolResultBlock.class)
```
but it does not check whether those `ToolResultBlock` IDs are related to the pending tool calls found by:
```java
Set pendingIds = findPendingToolUseIds(memory);
```
This can cause pending tool recovery to be skipped incorrectly.
Guia de contribuição
Avaliação
Esta issue ainda não foi avaliada.