fix(autofix-pr): extractBetween 支持 latest tag 截断时回溯到更早完整对
如果远端 agent 重试时写了完整 <autofix-result> 后又开了一个被截断的 第二个 tag, 旧实现只看 lastIndexOf(open) 然后找不到 close 就返回 null, 导致前面那个完整结果被丢弃。改为从尾向首遍历所有 open tag, 返回第一个 能配对的 open/close 对。 附带: - docs/features/remote-agent-completion-analysis.md: 9 处裸 fenced block 补 language tag (text/http), 修复 markdownlint MD040 警告 - 同文件: 两处"三选项" → "三个选项" 符合中文量词习惯
This commit is contained in:
parent
873f0a03ac
commit
ae7f3e2232
|
|
@ -89,6 +89,16 @@ describe('extractAutofixResultFromLog', () => {
|
||||||
expect(extractAutofixResultFromLog(log)).toBeNull()
|
expect(extractAutofixResultFromLog(log)).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('returns earlier complete tag when latest open tag is truncated within the same block', () => {
|
||||||
|
// Retry scenario: a full result was emitted, then a second result tag
|
||||||
|
// started but got cut off. We should surface the earlier complete pair
|
||||||
|
// rather than dropping the whole block.
|
||||||
|
const complete = sampleTag('earlier complete result')
|
||||||
|
const truncated = `<${AUTOFIX_RESULT_TAG}>\n<summary>truncated retry...`
|
||||||
|
const log = [assistantTextMessage(`${complete}\n${truncated}`)]
|
||||||
|
expect(extractAutofixResultFromLog(log)).toBe(complete)
|
||||||
|
})
|
||||||
|
|
||||||
test('walks backwards so hook stdout from later in log wins over earlier assistant text', () => {
|
test('walks backwards so hook stdout from later in log wins over earlier assistant text', () => {
|
||||||
const earlier = sampleTag('via assistant first')
|
const earlier = sampleTag('via assistant first')
|
||||||
const later = sampleTag('via hook later')
|
const later = sampleTag('via hook later')
|
||||||
|
|
|
||||||
|
|
@ -71,14 +71,22 @@ export function extractAutofixResultFromLog(log: SDKMessage[]): string | null {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Walks open tags from latest to earliest, returning the first complete
|
||||||
|
// open/close pair. Guards against a truncated final tag shadowing an
|
||||||
|
// earlier complete pair within the same text block (e.g., a retry wrote a
|
||||||
|
// full result, then the model started a second tag that got cut off).
|
||||||
function extractBetween(
|
function extractBetween(
|
||||||
text: string,
|
text: string,
|
||||||
open: string,
|
open: string,
|
||||||
close: string,
|
close: string,
|
||||||
): string | null {
|
): string | null {
|
||||||
const start = text.lastIndexOf(open)
|
let searchFrom = text.length
|
||||||
|
while (searchFrom >= 0) {
|
||||||
|
const start = text.lastIndexOf(open, searchFrom)
|
||||||
if (start === -1) return null
|
if (start === -1) return null
|
||||||
const end = text.indexOf(close, start + open.length)
|
const end = text.indexOf(close, start + open.length)
|
||||||
if (end === -1) return null
|
if (end !== -1) return text.slice(start, end + close.length)
|
||||||
return text.slice(start, end + close.length)
|
searchFrom = start - 1
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user