Files
SuperBizAgent-java/openspec/changes/archive/2026-07-21-single-react-tool-invocation-store/proposal.md
T

46 lines
3.7 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.
## Why
阶段 1 已冻结 Agent-facing Tool Contract,阶段 2 已提供 RunContext、预算、取消和 Tool Call Key 基础,但当前 `ToolInvocationRecorder` 仍把截断 preview 写入 JPA、依赖 ThreadLocal,并没有同一条记录中的 `request/raw_response/agent_result`、生命周期或当前 Run 所有权。RAG、日志和 MySQL 投影若各自保存调用,会重新复制状态机并让 EvidenceGuard 无法证明引用来自当前 Run。
## What Changes
- 新增统一 `ToolBoundary`,在每个 Tool 调用前执行 JSON Schema/只读/Run/预算/Tool Call ID 门禁,执行后统一处理 raw、投影、状态和错误。
- 新增 `CanonicalInvocationStore` 抽象与 Redis 实现,按阶段 2 Key Factory 保存一条完整 JSON 调用记录:`request`、`raw_response`、`agent_result`、`status`、`evidence_status`、时间和错误信息。
- `PROJECTING -> READY/ERROR` 生命周期和独立 EvidenceStatus 在 store 中集中执行;READY 才允许 `EVIDENCE_FOUND/NO_EVIDENCE`,ERROR 不可引用。
- 创建时设置 TTL,读取不刷新;更新只使用当前剩余 TTL,不延长生命周期;单记录、Agent projection 和单 Run 容量超限显式返回 `RESULT_TOO_LARGE`,不静默截断 raw。
- 拒绝缺失/非法/重复 Tool Call ID、跨 Run 引用、不可解析 JSON、非只读请求和已超预算调用;不生成第二套 ID。
- 使用 Fake Tool/Projector/In-memory Store 覆盖成功、no-evidence、projection error、execution error、duplicate/cross-run、TTL、容量和 raw oversize。
- 本阶段不实现 RAG/log/MySQL specific projector,不修改旧 `ToolInvocationRecorder`、JPA entity、Controller、ChatService 或公开协议。
## Capabilities
### New Capabilities
- `canonical-tool-invocation-store`: 提供统一 ToolBoundary、canonical invocation 生命周期、Run 所有权、容量/TTL 和可引用状态边界,供后续 RAG/log/MySQL 投影复用。
### Modified Capabilities
- None. 旧 JPA audit 记录继续服务旧链路;新 store 先作为零消费者 Harness foundation。
## Context Constraints
- canonical store 只能由 Harness/ToolBoundary 访问,Agent 不获得 Redis client/key/raw record。
- Redis key 固定由阶段 2 `ToolCallKeyFactory` 生成:`prefix:runId:toolCallId`。
- 同一调用的完整 request/raw/agent projection 必须在同一记录;raw 不能只保存 preview,也不能未经 projector 返回 Agent。
- 创建 TTL 默认配置由 caller 提供且必须大于 0;读取与更新不得续期。
- `PROJECTING` 时 evidence_status 只能是内部暂态 ERROR/unknown;只有 READY 才能成为 `EVIDENCE_FOUND` 或 `NO_EVIDENCE`。
- `NO_EVIDENCE` 仅作为结果语义,不可被 boundary 自动升级为成功事实或重试。
## Interface Impact
- 等级:L2(内部 Harness/Tool boundary)。新增接口会被阶段 3B/3C 直接消费,旧调用方不变。
- 不改变 JPA `tool_invocation`、数据库 Schema、旧审计 preview 或公开 HTTP/SSE。
- Redis 是新增运行时依赖使用既有 `RedisTemplate<String,Object>` bean;真实连接验证留给阶段 7,focused tests 使用 fake/mocks。
## Risks
- Redis JSON value 更新需要读取剩余 TTL 后再写回,存在并发更新窗口;当前单 Tool Call 只有 boundary 状态机写入,后续若并发 projector 必须升级 Lua/CAS。
- canonical raw 可包含敏感内容;本 Issue 保留阶段 0 已确认的 Harness-only ACL/TTL 约束,持久化脱敏和 durable audit 留给后续阶段。
- ToolBoundary 同时负责预算、store 状态和 projector 错误,若异常分类不清会产生错误状态;每个边界分支都有 Fake tests。
- 当前旧 recorder 继续运行,新旧两条 audit 链短期并存;proposal 明确禁止把旧 JPA 记录当 canonical evidence。