agentscope-ai / agentscope-ai/agentscope-java

[Bug]: PendingToolRecoveryHook skips recovery when input contains unrelated ToolResultBlock IDs

Offen
#1,406 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
area/core/agent bug
Vorherrschende Sprache
Java
Sterne
5.6k
Forks
1.3k
Ø Merge
4 T. 12 Std.
Gemergte PRs (30 T.)
77

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.