mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-27 15:13:37 +08:00
docs(release): include #79 in v0.5.20 notes
PR #79 (suppress consecutive identical retry errors) merged after the v0.5.20 release commit but before the tag was pushed. The released build will contain its code, so the notes need to mention it. Title broadened to cover both retry-link denoise changes (#78 + #79). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
d9b16a86c3
commit
37ffca0ec0
@ -1,6 +1,6 @@
|
||||
# v0.5.20
|
||||
|
||||
> 子代理限流器从单门改双门:cap 放宽 + 连续 FAIL 流式阻断,正常多步工作不再被误杀。
|
||||
> 重试链路两处去噪:子代理限流器从单门改双门,正常多步工作不再被误杀;HTTP 重试期间相同错误不再每次都堆到对话气泡。
|
||||
|
||||
## 修复
|
||||
|
||||
@ -11,22 +11,36 @@
|
||||
- 错误文案区分 `cappedReason: 'total' | 'streak' | 'none'`,用户能看到具体哪个门触发。
|
||||
- 环境变量出口保留:`CLAUDE_CODE_AGENT_LIMIT_<TYPE>=N` 调高 total cap、`CLAUDE_CODE_AGENT_LIMITER_OFF=1` 整体禁用。
|
||||
|
||||
- **HTTP 重试期间相同错误不再刷屏对话**(#79)。原 `withRetry` 默认 `maxRetries=10`,每次失败只要错误是 `APIError` 就把 `SystemAPIErrorMessage` yield 到对话流。一次 flaky 上游恢复需要 2-3 次重试时,对话气泡里就会堆出 2-3 条一模一样的错误(用户原话「100% 显示出来」)。本版加同错误去重门控:
|
||||
- **首次出现的错误 key**:立即 yield(携带新信息)。
|
||||
- **连续相同错误**:沉默到累计 ≥ 3 次(默认)才再 yield。
|
||||
- **任何 429 rate-limit**:始终 yield —— wait-time 信息是它存在的意义。
|
||||
- **错误 key**:用 `Error.name + APIError.status + Error.message` 拼接,401 与 503 即使 message 相同也不会折叠。
|
||||
- **State 是 generator 闭包局部变量**,跨 withRetry 调用不泄露;persistent 模式 heartbeat 复用一次性算定的结果,避免长 persistent 等待重复增计数。
|
||||
- 环境变量 `CLAUDE_CODE_RETRY_REPORT_AFTER=N` 可调阈值(默认 3)。
|
||||
- 效果:一段 3 次相同错误的重试现在显示 2 个气泡而非 3 个;更长 streak 压缩更明显,但用户始终能看到通话还在重试。
|
||||
|
||||
## 测试
|
||||
|
||||
- `src/tools/AgentTool/invocationLimiter.test.ts`:28 cases / 153 expects 全过。
|
||||
- 14 个原测试按新 cap=12 适配
|
||||
- 5 个 streak 行为新测试:3 FAIL trip / PASS clears / UNKNOWN soft-PASS / per-agent-type 隔离 / 12 PASS 触 total cap not streak
|
||||
- 9 个 parseVerdict 测试:empty / 标准 VERDICT 行 / FAIL 同义词 / APPROVE / 专家技能同义词 / 无 verdict / markdown 容忍 / 长 input tail
|
||||
- 验证子代理独立 PASS,含 8 个对抗性场景:5 PR PASS 序列、verifier loop 模拟、PASS 中断 streak、跨 type 隔离、真实子代理输出、UNKNOWN soft-PASS、orphan FAIL、12 PASS 后 total cap。
|
||||
- `src/services/api/withRetry.test.ts`:4 cases,3 个新测试覆盖 same-error 抑制、新 key 立即 yield、env override 提高阈值。
|
||||
- 两个 PR 各自的 verification 子代理均独立 PASS,含状态隔离、heartbeat 放大、UNKNOWN soft-PASS 攻击面、throw/abort 场景 streak 残留等对抗性 probe。
|
||||
|
||||
## 设计审查
|
||||
|
||||
- **UNKNOWN 当 soft-PASS 的攻击面**:恶意子代理可省略 VERDICT 行避开 streak,但 total cap=12 仍兜底;且子代理 prompt 由调用方完全控制,不是普通输入面。
|
||||
- **throw / abort 场景的 streak 状态**:`noteInvocation` 已增计数但 `noteOutcome` 不跑——streak 保持原值不偏移,下次调用基于既有 streak 起步,PASS 仍能清零。
|
||||
- **接入点对称性**:`AgentTool.tsx` 中 `noteOutcome` 与 `noteInvocation` 用完全相同的 guard `(!toolUseContext.agentId && isBuiltInAgent(selectedAgent) && !isLimiterDisabled())`,避免 streak/total 计数不同步。
|
||||
- **UNKNOWN 当 soft-PASS 的攻击面**(#78):恶意子代理可省略 VERDICT 行避开 streak,但 total cap=12 仍兜底;且子代理 prompt 由调用方完全控制,不是普通输入面。
|
||||
- **throw / abort 场景的 streak 状态**(#78):`noteInvocation` 已增计数但 `noteOutcome` 不跑——streak 保持原值不偏移,下次调用基于既有 streak 起步,PASS 仍能清零。
|
||||
- **接入点对称性**(#78):`AgentTool.tsx` 中 `noteOutcome` 与 `noteInvocation` 用完全相同的 guard `(!toolUseContext.agentId && isBuiltInAgent(selectedAgent) && !isLimiterDisabled())`,避免 streak/total 计数不同步。
|
||||
- **非 APIError 不进对话流**(#79):`Stream ended without receiving any events` 这类普通 Error 仍走外层 `CannotRetryError` 路径,本 PR 不扩大 `SystemAPIErrorMessage` 的类型契约(它要求 `error: APIError`)。改契约会扩散到所有消费者,超出本 PR 范围。
|
||||
|
||||
## 范围
|
||||
|
||||
- `src/tools/AgentTool/invocationLimiter.ts`:核心改造,加 streak 状态、noteOutcome、parseVerdict、双门判定。
|
||||
- `src/tools/AgentTool/AgentTool.tsx`:completed 分支加 `noteOutcome` 调用。
|
||||
- `src/tools/AgentTool/invocationLimiter.test.ts`:14→28 测试。
|
||||
- `src/services/api/withRetry.ts`:加 `DEFAULT_RETRY_REPORT_THRESHOLD` / `errorIdentityKey` / `shouldReportRetry`,2 处 yield 改 guard。
|
||||
- `src/services/api/withRetry.test.ts`:1→4 测试。
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user