fix(agent): 审批恢复 - 补齐被审批暂停跳过的并行工具调用结果 (#670)

模型一步里发出多个工具调用、排在前面的进入用户审批时,运行时中止本轮,后面的调用既没执行也没有结果;批准后恢复运行,历史里留着有调用没结果的条目,整轮以「工具调用缺少结果」失败。转换前给这些调用补一条「未执行」结果:历史恢复合法,模型也知道那一步没做过,需要时会重新调用。

后端重启后恢复运行等场景下会被直接采用的服务端规范历史同样可能留着这类条目,一并补齐。
This commit is contained in:
jiabx
2026-10-05 13:28:14 +08:00
committed by GitHub
parent faef652125
commit 907a3eb3fb
3 changed files with 286 additions and 0 deletions

View File

@@ -350,6 +350,10 @@ func (s *Service) adoptCloudAgentPiModelStep(userID, runID, taskID string) (adop
func cloudAgentPiCanonicalForModelRequest(messages []map[string]any, existing canonicalAgentRequest) (canonicalAgentRequest, error) {
compactionSummaryRequest := cloudAgentPiCompactionSummaryRequest(messages)
if !compactionSummaryRequest {
// 审批暂停会留下没有结果的并行工具调用,先补齐再转换(见 cloud_agent_pi_unanswered_calls.go)。
messages = repairRuntimeUnansweredCalls(messages)
}
tools, systemPrompt := existing.Tools, existing.SystemPrompt
if compactionSummaryRequest {
tools, systemPrompt = nil, ""
@@ -365,11 +369,13 @@ func cloudAgentPiCanonicalForModelRequest(messages []map[string]any, existing ca
if len(existing.Messages) == 0 {
return canonicalAgentRequest{}, err
}
existing.Messages = repairCanonicalUnansweredCalls(existing.Messages)
return existing, nil
}
// A projected Pi transcript containing a compaction summary is authoritative,
// even though it is shorter than the server's pre-compaction canonical history.
if !cloudAgentPiHasCompactionSummary(messages) && len(existing.Messages) > len(messages) {
existing.Messages = repairCanonicalUnansweredCalls(existing.Messages)
return existing, nil
}
canonical.PromptCacheKey = existing.PromptCacheKey