fix: preserve remote task success after recoverable tool errors

Align remote ACP tool recovery with local runtime behavior when the model responds after a tool failure and completes normally. Preserve original errors and derive recovery state from committed remote events so reconnecting safely replays partial terminal events.

Validation: 461 focused tests, typecheck, lint, and shared Linux Host recovery scenarios passed. Full-suite validation has two pre-existing heartbeat migration fixture failures involving the pinned column.

Release note: 修复远端 Agent 在读取等工具失败后已正常回复,任务仍被误判为失败的问题,并修复断线重连时的工具状态恢复。
This commit is contained in:
mesalogo
2026-09-16 12:49:17 +08:00
parent eaf71ce16f
commit 6c045bfe2e
8 changed files with 465 additions and 14 deletions
+11 -2
View File
@@ -1919,17 +1919,24 @@ export function registerIpcHandlers(
const recoveredAssistantMessage = conversation.messages.find(
(message) => message.id === task.currentAssistantMessageId
)
const activityStates = assistantDatabase.getRemoteTaskActivityStates(task.taskId)
const recoveredTools =
recoveredAssistantMessage?.tools?.filter(
(tool): tool is typeof tool & { callId: string } =>
Boolean(tool.callId)
) ?? []
).map(tool => ({
...tool,
state: activityStates.tools.get(tool.callId) ?? tool.state
})) ?? []
const recoveredSubagents =
recoveredAssistantMessage?.subagents?.filter(
(subagent) =>
subagent.routingMode === 'native' &&
subagent.runtimeCallId
) ?? []
).map(subagent => ({
...subagent,
...activityStates.subagents.get(subagent.childTaskId)
})) ?? []
const toolStates = new Map(
recoveredTools.map((tool) => [tool.callId, tool])
)
@@ -1982,6 +1989,8 @@ export function registerIpcHandlers(
remoteSemanticAfterSequence: highestCommitted,
remoteRecoveryOnly: true,
remoteRecoveredTools: recoveredTools,
remoteHasResponseTextAfterToolFailure:
assistantDatabase.hasRemoteResponseTextAfterToolFailure(task.taskId),
remoteRecoveredSubagents: recoveredSubagents
}
let recoveryMetricSettings: