fix(agent): 审批暂停 - 暂停后不再接受新的模型步骤 (#675)

运行时在工具进入审批时调用 session.abort(),但中止是异步生效的,SDK 可能抢在它生效前再开一轮并请求 /model。服务端照常入队:多计一次费,返回的新工具调用顶掉待审批的调用,保存时以「approval does not match current call」的检查点校验失败,整轮中断,用户还没来得及审批。

三处防护:运行时在暂停后不再发模型请求;服务端在等审批期间拒绝模型步骤(不入队、不改状态);已因审批暂停的会话收尾报错不再判运行失败,由审批结论接管。
This commit is contained in:
jiabx authored and GitHub committed 2026-10-05 13:56:07 +08:00
1 parent 222820f331
commit 00bad0589f
4 files changed
+128

No files matched your search

@@ -161,6 +161,9 @@ func (s *Service) broadcastCloudAgentPiContextPressure(userID, runID string, usa
// cloudAgentModelStepRetries 是单步模型调用首次失败后的最大重试次数。
const cloudAgentModelStepRetries = 3
// errCloudAgentAwaitingApproval 运行正在等用户审批,本步模型请求被拒绝(未入队、未计费)。
var errCloudAgentAwaitingApproval = errors.New("run is waiting for approval")
// errCloudAgentTruncatedToolArguments 标记"模型返回的工具参数不是完整 JSON":
// 调用未执行,可以带纠偏上下文重做同一步。
var errCloudAgentTruncatedToolArguments = errors.New("truncated tool arguments")
@@ -186,6 +189,12 @@ func (s *Service) runCloudAgentModelStep(ctx context.Context, userID, runID stri
if cloudAgentRunTerminal(run.Status) {
return nil, false, fmt.Errorf("run already terminated")
}
// 等审批期间不接受新的模型步骤。运行时在审批暂停后中止会话是异步的,
// 可能抢在中止生效前再请求一步;放它过去会多计一次费,返回的新工具调用
// 还会顶掉待审批的调用。这里不入队、不改状态,审批结论照常接管运行。
if run.Status == "waiting_approval" && state.Approval != nil {
return nil, false, errCloudAgentAwaitingApproval
}
if cloudAgentStepBudgetExhausted(&state) {
// 最终回答之后的插话续步会在这里撞上限;若确实停在最终回答边界,
// 按完成收尾而不是把整轮判失败(见 settleCloudAgentPiFinalAnswer)。