/**
* 去除深度思考模型输出的 ... 标签及其内容
*
* 1. stripThink(text) — 用于非流式,直接去除完整文本中的 块
* 2. createThinkStreamFilter() — 用于流式,返回有状态的过滤器,逐 chunk 过滤
*/
/**
* 非流式:去除完整文本中的 ...
*/
export function stripThink(text: string): string {
return text.replace(/[\s\S]*?<\/think>/g, "").trim();
}
/**
* 流式:创建一个有状态的 chunk 过滤器
*
* 用法:
* ```ts
* const filter = createThinkStreamFilter();
* for await (const chunk of textStream) {
* const filtered = filter.push(chunk);
* if (filtered) msg.send(filtered);
* }
* ```
*/
export function createThinkStreamFilter() {
let insideThink = false;
let buffer = "";
return {
/**
* 输入一个 chunk,返回过滤后需要输出的文本(可能为空字符串)
*/
push(chunk: string): string {
let output = "";
let i = 0;
while (i < chunk.length) {
if (insideThink) {
// 正在 内部,寻找
const closeIdx = chunk.indexOf("", i);
if (closeIdx !== -1) {
// 找到闭合标签,跳过标签内容
insideThink = false;
i = closeIdx + "".length;
} else {
// 整个剩余 chunk 都在 think 内,全部丢弃
break;
}
} else {
// 不在 内部
const openIdx = chunk.indexOf("", i);
if (openIdx !== -1) {
// 找到开启标签,输出标签之前的内容
output += buffer + chunk.slice(i, openIdx);
buffer = "";
insideThink = true;
i = openIdx + "".length;
} else {
// 没有发现 ,但可能 chunk 末尾是不完整的 "" 的不完整前缀
* 如 "<", "