🐛 fix(sdk): engine 执行循环九项修复——运行锁 TOCTOU、缓存计价、压缩边界 uuid 回填 - #435
Merged
Conversation
Owner
Author
Code Review九项逐项核对完毕,全部真实落地、方向正确、无 P0/P1/P2,CI 6/6 绿,可合。 亮点核验
非阻塞 P3 记录
BEHIND,merge main 过 gate 后即可合。 |
protectedUserMessage 的命中条件(boundaryStart ≤ idx < firstKeptIndex) 决定它必然同时落在 messagesToSummarize ∪ turnPrefixMessages 的序列化 区间内,摘要生成后再原样插回,同一请求文本出现两份。 prepareCompaction 在返回前按引用把该消息从两个序列化区间剔除; 插回逻辑与 checkpoint 语义保持原样,split-turn 与非 split-turn 一并覆盖。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
estimateCost 只计 input/output,cache read(约 0.1x 输入价)与 cache write(约 1.25x 输入价)无计价路径,totalCost 长期低估, maxBudgetUsd 预算熔断因此失真。 签名扩展两个可选 cache 字段:read 按 0.1x、write 按 1.25x 折算; 未传字段行为不变。引擎侧接线随引擎批次提交。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
启动让并发 query 双双穿过守卫、fork 出双引擎写坏同一会话。入口改 同步置位 runLocked 布尔并在外层 finally 复位(拆出 runSinglePromptLocked), 单标志闭合窗口;锁随首个 next() 的同步前缀即生效。 按旧 uuid 键查 fileCheckpointState 必 miss。重建时按同角色消息自队尾 对齐回填原 uuid(toSessionMessage 增加可选 uuid 参数):compaction 在 队首插入合成摘要消息,只有尾部消息与前列表一一对应,checkpoint 键不动。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#361 续写预算耗尽后再遇 max_tokens 且无 tool_use,落入 completedNaturally 以 success 收尾掩盖截断。置 maxTokensExhausted 标志,终态映射 error_max_output_tokens(subtype 联合新增字面量, 含 string 向后兼容),errors 附说明;#304 占位结构沿用 main 既有实现。 #353 prompt-too-long 守卫要求 !compacted,而 compacted 成功后整个 run 不复位,tool 循环二次超窗直接终止 run。守卫改 consecutiveFailures < 3:成功复位 0 允许再触发,失败自增自带熔断。 #359 pendingLspDiagnostics.splice(0) 破坏性取走后仅注入瞬态 apiMessages,prompt-too-long 压缩重建请求时诊断永久丢失。改非破坏 读取,请求成功后才清空,压缩重试下一轮自然重新注入。 #360 非流式路径 api_retry 事件缓冲至 withRetry 整体返回后才补发, 最长约 30s×3 假死。onRetry 改经既有 onAsyncEvent 通道即时投递, 缓冲数组仅作无宿主回调时的兜底。 另接 #352:recordProviderUsage 将归一化 cache 读写字段透传 estimateCost,totalCost/modelUsage/billingUsage 反映缓存计价。 rebase 注记:#358(repeat guard 交替击穿)与 #304 占位已由 main 208c818/515d6ad10 先行落地且语义更严,本次保留 main 实现; 原 #358 放行用例与 main 的 stall-guard 取舍相悖,随本提交移除。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
review 返工:队尾对齐未区分合成消息。当 previous 同角色条目数多于 重建后历史(长会话压缩的常态),队尾配对会把被摘要吞掉的最近真实 用户消息的 uuid 偷给合成摘要条目——fileCheckpointState 不随压缩 清理时,宿主对摘要条目 rewindFiles 会静默恢复无关旧轮次的文件快照。 配对前剔除 content 含 _meta.contextBlock === 'compaction' 的消息, 强制其拿 fresh uuid;补 previous > new 方向的回归测试(原测试只覆盖 了反方向)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
上一轮 rebase 解决 agent.test.ts 双方新增冲突时遗留了一行 >>>>>>> 标记未删,随本提交移除,无其它改动。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
Code Review九项逐项核对完毕,全部真实落地且各有行为钉死测试,可合。merge-tree 实测与 main 零冲突(仅 BEHIND,main 唯一触碰点 c0cc273 新增 亮点验证
P3(不阻塞)
结论可合,走 PR 正常合并即可。 |
CavinHuang
force-pushed
the
fix/sdk-engine-loop
branch
from
August 22, 2026 12:47
9be2dcc to
56ebfea
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
修复 sdk 全量 review 提出的 9 个 issue(engine 执行循环域),每个 commit 独立可跑绿。
注:#304(max_tokens 占位 tool_result)已由 main 侧 515d6ad 上游修复,本分支在其上叠加 #361 耗尽标志。
验证
bun run typecheck六 workspace 全绿Closes #358, closes #352, closes #353, closes #357, closes #359, closes #360, closes #361, closes #363, closes #365
🤖 Generated with Claude Code