Files
social-app/docs/plans/2026-03-03-interrupt-resume-fixes-design.md
T

96 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent Interrupt/Resume 遗留问题修复设计
## 1. 目标
本次修复一次性完成以下三项遗留问题:
1. `state_snapshot` 并发一致性问题(并发 resume 竞争)
2. `expires_at` 过期未强校验问题
3. `state_snapshot` 缺少强类型与版本化问题
## 2. 设计决策
采用方案 2(严格重构):
- `state_snapshot` 仅接受新结构,不再兼容旧结构
- 统一快照版本为 `version = 2`
- 使用强类型模型约束快照结构与状态迁移
- resume 入口引入行级锁语义,避免并发双写
## 3. 状态快照模型
`state_snapshot` 顶层结构:
```json
{
"version": 2,
"pending_tool_call": {
"interrupt_id": "int-1",
"tool_name": "srv.transfer_funds",
"tool_args": {"to": "u2", "amount": 100},
"status": "PENDING_APPROVAL",
"expires_at": "2026-03-03T12:00:00Z",
"decision": null,
"result": null,
"updated_at": "2026-03-03T11:59:00Z"
},
"run_context": {
"thread_id": "t1",
"run_id": "r1"
}
}
```
说明:
- `version` 必须为 2,否则拒绝处理
- `pending_tool_call` 字段缺失或类型错误,按无效快照处理
- `run_context` 仅保留 interrupt/resume 必需字段
## 4. 状态机约束
仅允许以下迁移:
- `PENDING_APPROVAL -> APPROVED_EXECUTING -> EXECUTED`
- `PENDING_APPROVAL -> REJECTED`
- `PENDING_APPROVAL -> EXPIRED`
非法状态迁移必须返回错误,不做隐式修复。
## 5. 并发与过期语义
- resume 前先对目标 session 加锁再读取快照
- 同一 `interrupt_id` 并发 resume 只能有一个请求成功
-`expires_at < now(UTC)`,先迁移为 `EXPIRED`,再返回 410
## 6. 错误语义(RFC7807
- `409 Conflict`: run/interrupt 不匹配,或并发冲突导致状态已消费
- `410 Gone`: 挂起调用已过期
- `422 Unprocessable Entity`: `state_snapshot` 非法或版本不匹配
- `404 Not Found`: 目标 session/run 不存在
## 7. 测试策略
采用 TDD,先写失败测试后实现:
- 快照版本校验(`version != 2`
- 快照结构校验(必填字段/类型)
- 并发 resume 幂等竞争(仅一个成功)
- 过期校验(返回 410 + 状态置 EXPIRED
- 合法状态迁移路径覆盖
## 8. 验证命令
- `uv run pytest backend/tests/unit/v1/agent -v`
- `uv run pytest backend/tests/integration/v1/agent/test_chat_routes.py -v`
- `uv run pytest backend/tests/integration/v1/agent/test_interrupt_resume_flow.py -v`
- `cd backend && uv run ruff check src/v1/agent`
- `cd backend && uv run basedpyright src/v1/agent`
## 9. 风险与回滚
- 风险:旧快照不再兼容,可能触发运行时拒绝
- 处置:通过明确 422 错误暴露不合规数据,结合日志定位并人工修复数据
- 回滚:回退本次变更并恢复旧快照解析逻辑(仅在紧急故障时)