agentscope-ai / agentscope-ai/agentscope-java

Core: publish AllToolsDeniedEvent and persist the ALL_TOOLS_DENIED terminal reason

未關閉
#2,141 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
area/core enhancement
主要語言
Java
星號
5.6k
分支
1.4k
平均合併
3 天 23 小時
30 天內合併 PR
77

描述

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

貢獻指南

開啟貢獻指南

研究方向

Trace the middleware chain for `AllToolsDeniedEvent`, `RequestStopEvent`, and `AgentResultEvent` to confirm where terminal events should be emitted into `streamEvents()`. Then inspect state-store write/readback for `(userId, sessionId)` terminal data to persist `ALL_TOOLS_DENIED` and verify resume logic does not re-emit or re-run denied tools. Run existing stream-events and resume/state tests (or add focused ones) and check one deterministic terminal transition, no all-denied on partial approval, and stable readback semantics.

由索引模型根據 Issue 內容生成。

評估

技術堆疊
java
領域
backend, backend-api-design
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
冷清
描述清晰度
基本清楚
新手友好度
44/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。