Document U3 r0.6 route-scoped terminal evidence #95

Merged
weichen merged 51 commits from feature/fast-slow-u2-u3-plan into main 2026-10-19 09:26:55 +00:00
Showing only changes of commit 0827b81026 - Show all commits
@@ -138,11 +138,11 @@
### Task 4:材料子代理的最终答复预留(Backend)
**Files:** Create `modules/backend/internal/runtime/material_final_reserve.go`、`material_final_reserve_test.go`;modify `sub_loop.go`;replay the existing `run_budget_stream_test.go` unchanged。一般子代理、前台、生产模型路由和 `budgetedStream` 的已返回 Usage 守卫不扩大。
**Files:** Create `modules/backend/internal/runtime/material_final_reserve.go`、`material_final_reserve_test.go`;modify `sub_loop.go`、`usage_n3_test.go`;replay the existing `run_budget_stream_test.go` unchanged。一般子代理、前台、生产模型路由和 `budgetedStream` 的已返回 Usage 守卫不扩大。
**Interfaces:** `type materialBudgetState struct { Limit, Used, LastPrompt, OutputCap, SavedCheckpoints, Responses int; UsageKnown bool }` 与 `materialFinalDecision(s materialBudgetState) (finalOnly, stop bool)` 只处理 `agent.sub.material`。`Responses=0` 是尚未产生调用的初态;已有响应但 Usage 未知则 fail-closed。增长余量 `margin=max(1024, LastPrompt/4)`;最终预留 `reserve=LastPrompt+OutputCap+margin`,再做一次检查点的估算成本也取同一值。`Limit-Used <= LastPrompt+margin` 时停止;否则 `SavedCheckpoints>=2` 或 `Limit-Used <= 2*reserve` 时进入 final-only。首个响应前不套用该估算。这样保留一次最终请求的空间,且一次成果后发现下一次发布会挤占预留时优先收尾,明确这是部分结论而非第二项。final-only 不再向 provider 声明 `publish_work_checkpoint`,并添加系统拥有的简短最终答复指令;若剩余额度不容纳预计最终 prompt,则不发新请求,保留已保存卡和真实失败状态。它不保证在途请求不越过总目标。
- [ ] **Step 1: 写 RED。** `material_final_reserve_test.go` 用假 stream 顺序返回用量,断言“初始零响应允许首个请求”“两个合法检查点→下一次仅最终答复”“只有一个检查点且额度临界→真实部分最终答复”“额度不足→0 次额外 provider 请求”“已有响应而 Usage 缺失→停止”“非材料子代理保持原行为”。故意让假 provider 在 final-only 中仍请求隐藏的检查点,断言 `runTool` 拒绝、设置本次执行的停止标记,下一轮在 provider 前停止且没有持久发布。测试检查 provider 请求里的工具声明和系统提醒,而非只检查内部布尔值。
- [ ] **Step 1: 写 RED。** `material_final_reserve_test.go` 用假 stream 顺序返回用量,断言“初始零响应允许首个请求”“两个合法检查点→下一次仅最终答复”“只有一个检查点且额度临界→真实部分最终答复”“额度不足→0 次额外 provider 请求”“已有响应而全部 Usage 缺失→停止”“非材料子代理保持原行为”。`usage_n3_test.go` 补一条 `TotalTokens=0` 但 prompt/completion 有值时按两者之和入账的回归,与现有 `budgetedStream` 口径一致。故意让假 provider 在 final-only 中仍请求隐藏的检查点,断言 `runTool` 拒绝、设置本次执行的停止标记,下一轮在 provider 前停止且没有持久发布。测试检查 provider 请求里的工具声明和系统提醒,而非只检查内部布尔值。
```go
func TestMaterialFinalReserveAfterTwoCheckpoints(t *testing.T) {
@@ -153,7 +153,7 @@
}
```
- [ ] **Step 2: 运行 RED。** `cd modules/backend && go test ./internal/runtime -run 'TestMaterialFinalReserve|TestRunBudgetStreamStopsReportedTokenExhaustion' -count=1`;期望当前两检查点之后仍继续暴露发布工具或临界余额耗尽。
- [ ] **Step 3: 实现调度。** `subRun.runTool` 仅在检查点真实成功时增加 `savedCheckpoints`,在 final-only 阶段拒绝模型凭旧记忆仍提交的检查点并设置停止标记;`wrapped` 下一次调用先检查此标记,直接返回错误而不接触 provider;`onEvent(message_end)` 用返回 Usage 更新 `Used/LastPrompt/Responses/UsageKnown`。在 `SubLLMRunner.Execute` 的 `wrapped` 调用前计算决策;final-only 只改当前请求的工具声明和系统提示,不写回历史、不提高 `MaxTokens` 或单次输出上限。预算不能证明可用时保留原失败/部分投影,不伪造正文。
- [ ] **Step 3: 实现调度。** `subRun.runTool` 仅在检查点真实成功时增加 `savedCheckpoints`,在 final-only 阶段拒绝模型凭旧记忆仍提交的检查点并设置停止标记;`wrapped` 下一次调用先检查此标记,直接返回错误而不接触 provider;`onEvent(message_end)` 用返回 Usage 更新 `Used/LastPrompt/Responses/UsageKnown`。`TotalTokens=0` 时仅在 prompt+completion 大于零才采用其和;三项均为零才标 Usage 未知并阻断后续请求。该回退也修复子 run 的 `AddUsage` 记账,不修改前台或 `budgetedStream`。在 `SubLLMRunner.Execute` 的 `wrapped` 调用前计算决策;final-only 只改当前请求的工具声明和系统提示,不写回历史、不提高 `MaxTokens` 或单次输出上限。预算不能证明可用时保留原失败/部分投影,不伪造正文。
```go
if st.finalOnlyRejected {