diff --git a/lib/client.js b/lib/client.js index d38147c..4efa22a 100644 --- a/lib/client.js +++ b/lib/client.js @@ -160,32 +160,49 @@ window.__ModuleLoader__.load({ } function extractDiffs(block) { - // PTC 模式:从 argsRaw 动态构建 diffs - // callId 包含 ':code:' 表示这是 run_code 的子调用 - if (typeof block.callId === 'string' && block.callId.includes(':code:')) { - // RunningToolCall 的 argsRaw 在 block 上,ToolResultNode 的 argsRaw 在 block.call 上 - const argsRaw = block.call ? block.call.argsRaw : block.argsRaw - const name = block.call ? block.call.name : block.name - if (name === 'edit' || name === 'write') { - try { - const args = JSON.parse(argsRaw) - if (args && typeof args === 'object') { - const filePath = args.file_path - if (typeof filePath === 'string' && filePath !== '') { - if (name === 'write' && typeof args.content === 'string') { - return narrowDiffs([{ path: filePath, oldText: null, newText: args.content }]) - } - if (name === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string') { - return narrowDiffs([{ path: filePath, oldText: args.old_string || null, newText: args.new_string }]) - } + const done = 'kind' in block + // PTC 子调用标记:新版 DSH 用 parentCallId;旧版 callId 含 ':code:',双兼容 + const subCall = block.parentCallId !== void 0 || + (typeof block.callId === 'string' && block.callId.includes(':code:')) + + // settled 且非错误:取真实应用的 diff,新版 DSH 存放在 block.meta.diffs。 + // 结构与内置 diffCardModel/appliedDiffs 同构,支持多 hunk。 + if (done && !subCall && !block.isError) { + const meta = block.meta + if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) { + const diffs = meta.diffs + if (Array.isArray(diffs) && diffs.length > 0) { + const n = narrowDiffs(diffs) + if (n !== null) return n + } + } + } + + // 子调用 / running / 兜底:没有真实 diff,改为从参数意图推断。 + // running 的 argsRaw/name 在 block 顶层,settled 的挪到 block.call 上,两处兼容。 + // settled 失败同样不显示意图 diff,与内置 diffCardModel 一致。 + if (done && !subCall && block.isError) return null + const argsRaw = (block.call ? block.call.argsRaw : block.argsRaw) ?? '' + const name = block.call ? block.call.name : block.name + if (name === 'edit' || name === 'write') { + try { + const args = JSON.parse(argsRaw) + if (args && typeof args === 'object') { + const filePath = args.file_path + if (typeof filePath === 'string' && filePath !== '') { + if (name === 'write' && typeof args.content === 'string') { + return narrowDiffs([{ path: filePath, oldText: null, newText: args.content }]) + } + if (name === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string') { + return narrowDiffs([{ path: filePath, oldText: args.old_string || null, newText: args.new_string }]) } } - } catch {} - } + } + } catch {} } - - // 标准模式:从 callView 或 resultView 提取 diffs - if (!('kind' in block)) { + + // 旧版 DSH 在 0.1.x 重构前没有以上字段,回退从 callView/resultView 读 diff。 + if (!done) { const call = block.callView && block.callView.card === 'diff' ? block.callView : null return call ? narrowDiffs(call.diffs) : null }