agentscope-ai / agentscope-ai/agentscope-java

[Bug]:ToolResultEvictionMiddleware does not evict

Offen
#1,695 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

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

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