agentscope-ai / agentscope-ai/agentscope-java

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

Đang mở
#1,406 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
area/core/agent bug
Ngôn ngữ chính
Java
Star
5.6k
Fork
1.3k
Merge trung bình
4 ngày 12 giờ
Pull request đã merge (30 ngày)
77

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.