agentscope-ai / agentscope-ai/agentscope

[Bug]: Mid-stream failures can leave orphan tool_calls and brick sessions

未关闭
#1,888 4 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Python
星标
31.5k
派生
3.5k
平均合并
1 天 23 小时
30 天内合并 PR
95

描述

### Describe the bug

In AgentScope Python 2.0.2, a chat run can fail after an assistant tool call has been appended to `AgentState.context`, but before the matching `ToolResultBlock` is recorded and persisted.

The persisted session can then contain an assistant message with `tool_calls` but no matching tool result. On the next turn, OpenAI-compatible providers reject the conversation history with an error like:

```text
An assistant message with "tool_calls" must be followed by tool messages responding to each "tool_call_id"
```

After that, every retry of the same session can fail again, so the session is effectively bricked until the stored context is manually repaired or deleted.

### Expected behavior

If a run is interrupted or crashes while a tool call is pending, AgentScope should persist a valid recovery state before the exception escapes. For example, the pending tool call could be closed with an interrupted/error `ToolResultBlock`, so the next run does not send invalid tool-call history to the model provider.

### Actual behavior

A mid-stream failure can leave an orphan tool call in persisted session state. The next run reuses that invalid context and fails at provider validation before the agent can recover naturally.

### Related issues / prior art

This appears related to earlier Python reports of provider-side tool-call validation errors:

- https://github.com/agentscope-ai/agentscope/issues/772
- https://github.com/agentscope-ai/agentscope/issues/815
- https://github.com/agentscope-ai/agentscope/issues/1711

The Java implementation also had a very similar pending-tool-call recovery problem:

- https://github.com/agentscope-ai/agentscope-java/issues/951
- https://github.com/agentscope-ai/agentscope-java/pull/956

The Java fix added a `PendingToolRecoveryHook` that synthesizes error tool results for pending tool calls. Python may need an equivalent recovery point in the app/chat service or agent middleware layer.

### Suggested fix

Add a Python-side recovery mechanism for persisted agent state:

1. Before a run, scan `AgentState.context` for assistant tool calls that do not have matching tool results, and synthesize interrupted/error `ToolResultBlock`s.
2. During a run, wrap the streaming/chat execution path in `try` / `finally` or equivalent middleware so pending tool calls are repaired and persisted when an exception occurs.
3. Add regression tests that simulate a failure after a tool call is emitted but before its tool result is persisted, then verify the next run does not fail with provider validation errors.

This would avoid downstream applications needing to monkey-patch private `ChatService` internals to keep sessions recoverable.

### Environment

- AgentScope Python: 2.0.2
- Python: 3.12
- Storage: persisted app session state
- Providers: OpenAI-compatible tool-call validation

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。