agentscope-ai / agentscope-ai/agentscope-java

[Bug]:ToolResultEvictionMiddleware does not evict

Đang mở
#1,695 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ả

# Bug: ToolResultEvictionMiddleware does not evict — `doOnComplete` fires before tool results are written to context

## Problem

`ToolResultEvictionMiddleware` never evicts oversized tool results. The `evictAddedToolResults()` callback always finds zero new messages and exits immediately.

## Root Cause

The `onActing` middleware hook wraps only `actingStream()`, which emits streaming events (`ToolResultEndEvent`, etc.) but does **not** write results to `AgentState.contextMutable()`.

Tool result messages are written to context in `notifyPostActingHook()` — which is called in `acting()`'s outer `.flatMap()`, **after** the middleware chain has already completed.

Execution order:

```
actingStream() Flux completes
→ doOnComplete(() -> evictAddedToolResults()) fires ← eviction runs HERE
→ contextMutable()[sizeBefore..end] is EMPTY ← nothing to evict
→ (outer flatMap) notifyPostActingHook() ← results written HERE (too late)
→ state.contextMutable().add(resultMsg)
```

Relevant lines in `ReActAgent.java`:
- **2129–2138**: middleware chain wraps only `actingCore = actingStream()`
- **2173–2174**: `notifyPostActingHook()` called outside the middleware chain
- **2728–2729**: `state.contextMutable().add(resultMsg)` — actual write point

## Fix Suggestion

Bring `notifyPostActingHook()` inside the middleware-wrapped scope so that tool results are in `contextMutable()` before the `onActing` Flux completes.

**Option A (minimal):** Extend `actingCore` to include the post-acting context write, then remove the duplicate call from the outer `flatMap`:

```java
Function> actingCore = ai ->
actingStream(ai.toolCalls(), replyId, resultHolder)
.thenMany(
Mono.defer(() -> Flux.fromIterable(resultHolder.get())
.concatMap(this::notifyPostActingHook)
.then(Mono.empty())));
```

**Option B (alternative):** Move eviction to the `onReasoning` hook's pre-step — check `contextMutable()` for oversized TOOL messages at the start of each reasoning round, before building the prompt. This avoids restructuring `actingCore` entirely.

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.