Agent/core/think-parse.ts
2026-08-06 22:17:39 +08:00

81 lines
2.3 KiB
TypeScript

// @ts-nocheck
export function createThinkSplitter(enabled) {
let buf = '';
let inThink = false;
function drain(final = false) {
let thinking = '';
let content = '';
while (buf.length > 0) {
if (inThink) {
const endIdx = buf.indexOf('</think>');
if (endIdx === -1) {
const hold = holdPartialClose(buf);
if (!final && hold > 0) {
const safe = buf.slice(0, buf.length - hold);
if (enabled) thinking += safe;
buf = buf.slice(buf.length - hold);
break;
}
if (enabled) thinking += buf;
buf = '';
break;
}
if (enabled) thinking += buf.slice(0, endIdx);
buf = buf.slice(endIdx + '</think>'.length);
inThink = false;
continue;
}
const startIdx = buf.indexOf('<think>');
if (startIdx === -1) {
const hold = holdPartialOpen(buf);
if (!final && hold > 0) {
content += buf.slice(0, buf.length - hold);
buf = buf.slice(buf.length - hold);
break;
}
content += buf;
buf = '';
break;
}
content += buf.slice(0, startIdx);
buf = buf.slice(startIdx + '<think>'.length);
inThink = true;
}
return { thinking, content };
}
return {
push(chunk) {
if (!chunk) return { thinking: '', content: '' };
buf += chunk;
return drain(false);
},
flush() {
return drain(true);
},
};
}
function holdPartialOpen(s) {
const m = s.match(/<t(?:h(?:i(?:n(?:k(?:>)?)?)?)?)?$/);
return m ? m[0].length : 0;
}
function holdPartialClose(s) {
const m = s.match(/<\/?(?:t(?:h(?:i(?:n(?:k)?)?)?)?)?$/);
return m ? m[0].length : 0;
}
export function stripThinkTags(text) {
return String(text || '')
.replace(/<think>[\s\S]*?<\/think>/g, '')
.replace(/<think>[\s\S]*$/g, '')
.replace(/<\/think>/g, '');
}