agentscope-ai / agentscope-ai/agentscope-java

Core: publish AllToolsDeniedEvent and persist the ALL_TOOLS_DENIED terminal reason

Abierto
#2,141 1 comentario 0 reacciones 0 asignados Ver en GitHub
area/core enhancement
Lenguaje dominante
Java
Estrellas
5.6k
Forks
1.3k
Merge medio
4 d 12 h
PR fusionados (30 d)
77

Descripción

## Problem

The 2.0 all-tools-denied hook works inside the acting middleware chain, but its externally observable and persisted terminal semantics are incomplete.

Observed against `e3a412ed2cc944e401da861c8d5e464b967724e9`:

1. An ASK tool suspends normally.
2. A follow-up `ConfirmResult(confirmed=false)` for every pending tool causes `AllToolsDeniedEvent` to pass through `MiddlewareBase.onActing(...)`.
3. Middleware can return `RequestStopEvent(reason=ALL_TOOLS_DENIED)` and the current `AgentResultEvent.result.generateReason` becomes `ALL_TOOLS_DENIED`.
4. Neither `AllToolsDeniedEvent` nor the middleware `RequestStopEvent` is published by the external `streamEvents()` result.
5. The persisted last context message still carries the previous `MODEL_STOP`, so a fresh runtime cannot read back the actual all-denied terminal reason.

## Expected contract

- `streamEvents()` should publish the typed all-denied lifecycle boundary exactly once, including the stop event if it is the mechanism that terminates the turn.
- The terminal result/state persisted for `(userId, sessionId)` should retain `ALL_TOOLS_DENIED` (or an equivalent typed terminal fact) across state-store recreation.
- Tool results/denial facts must remain consistent: denied tools execute zero times and restart must not make them pending again.
- Multiple parallel tool calls where all are denied should produce one terminal transition; partial denial should not be mislabeled all-denied.
- Product hosts should not need to synthesize the event from text or maintain a separate terminal-state store.

## Acceptance

1. `RequireUserConfirmEvent -> all ConfirmResult(false) -> AllToolsDeniedEvent -> RequestStopEvent/AgentResultEvent` is visible through `streamEvents()` in deterministic order.
2. Fresh agent/state-store readback preserves the terminal reason.
3. Repeated readback/resume does not re-emit or re-execute the denied tool calls.
4. Partial approve/deny follows the normal continuation path and does not emit all-denied.
5. Middleware observers and external subscribers see the same terminal semantics.

This is separable from a larger long-running Goal mode; it closes the typed event/persistence behavior of the existing GA hook.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.