fix(core): persist state on call cancellation - #2820
Conversation
3a7d8c5 to
e1ca130
Compare
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
guslegend0510
left a comment
There was a problem hiding this comment.
审查发现了两个会影响取消状态正确性的真实问题,不适合直接批准
| !(block instanceof ToolUseBlock toolUse) | ||
| || toolUse.getState() | ||
| != ToolCallState.PENDING | ||
| || !pendingIds.contains(toolUse.getId())) |
There was a problem hiding this comment.
[P1] ALLOWED 工具调用未被清理
acting 在执行工具前会把调用改为 ALLOWED,因此工具执行中取消或 acting 后置失败时,这里的 PENDING 条件会保留一个没有 tool_result 的 tool_use。默认 pending recovery 关闭,下一轮普通调用会失败,空消息恢复还可能重复执行工具。应清理本轮无结果的 PENDING/ALLOWED,并保留 ASKING。
There was a problem hiding this comment.
已在 21df397 修复:异常保存时会清理本轮无结果的 PENDING 和 ALLOWED tool call,并保留可恢复的 ASKING。新增测试分别覆盖 pre-acting PENDING、工具执行中取消后的 ALLOWED、post-acting failure 后的 ALLOWED,以及 ASKING 保留。
| .ifPresent(ae -> scope.externalEventEmitter = ae); | ||
| } | ||
| return scope.doCallInner(msgs) | ||
| .doOnCancel(() -> saveStateAfterCancellation(scope)) |
There was a problem hiding this comment.
[P1] 取消前同步保存会阻塞并竞态双写
doOnCancel 回调先同步持久化、随后才向上游传播 cancel,阻塞式状态库会延迟模型和工具停止,并允许 live state 在保存时继续变化;取消发生在正常异步保存期间时还会启动第二次 persistState,造成 loadedVersion/CAS 竞态。应统一为单一的取消终止保存流程,在上游取消后保存稳定快照。
There was a problem hiding this comment.
已在 21df397 修复:三条执行路径统一通过 doFinally(CANCEL) 处理,cancel 会先传播给上游模型/工具,之后才修复并保存状态。hook 只包裹 doCallInner;正常异步保存开始后 inner 已结束,因此取消不会启动第二次保存。新增测试验证工具先收到 cancel、StateStore 后保存,以及正常保存期间取消不会双写。
e1ca130 to
21df397
Compare
AgentScope-Java Version
2.0.3-SNAPSHOT
Description
背景
#2799 已在模型调用报错时保存安全的对话状态,但 Reactor cancellation 不会进入异常处理,因此取消普通或 structured-output 调用时,本轮用户输入仍可能丢失。
另外,如果 reasoning 已经提交了 tool call,而 acting 或 middleware 在写入 tool result 前报错,直接保存会留下没有结果的
PENDINGtool call。本 PR 是 #2713 基于 #2799 的精简后续,只补充上述两个场景。
改动
PENDING/ALLOWEDtool call,保留可恢复的ASKING。测试
mvn -pl agentscope-core -Dtest=ReActAgentCallFailurePersistenceTest testmvn -pl agentscope-core test2302 tests passed,8 skipped。
Checklist
mvn spotless:applymvn test)