{"version":3,"file":"thinking-tags.d.ts","sourceRoot":"","sources":["../../src/utils/thinking-tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,KAAK,gBAAgB,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AA2CpD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAiBvF;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAG1F;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9D","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai/compat\";\n\ntype AssistantContent = AssistantMessage[\"content\"];\ntype AssistantContentPart = AssistantContent[number];\n\nconst THINK_OPEN = \"<think>\";\nconst THINK_CLOSE = \"</think>\";\n\nfunction splitTextByThinkingTags(text: string): Array<{ type: \"text\"; text: string } | { type: \"thinking\"; thinking: string }> {\n\tconst parts: Array<{ type: \"text\"; text: string } | { type: \"thinking\"; thinking: string }> = [];\n\tlet index = 0;\n\tlet inThinking = false;\n\n\twhile (index < text.length) {\n\t\tconst nextOpen = text.indexOf(THINK_OPEN, index);\n\t\tconst nextClose = text.indexOf(THINK_CLOSE, index);\n\n\t\tif (!inThinking) {\n\t\t\tif (nextOpen === -1) {\n\t\t\t\tparts.push({ type: \"text\", text: text.slice(index) });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (nextOpen > index) parts.push({ type: \"text\", text: text.slice(index, nextOpen) });\n\t\t\tindex = nextOpen + THINK_OPEN.length;\n\t\t\tinThinking = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nextClose === -1) {\n\t\t\tparts.push({ type: \"thinking\", thinking: text.slice(index) });\n\t\t\tbreak;\n\t\t}\n\t\tparts.push({ type: \"thinking\", thinking: text.slice(index, nextClose) });\n\t\tindex = nextClose + THINK_CLOSE.length;\n\t\tinThinking = false;\n\t}\n\n\treturn parts.filter((part) => part.type === \"text\" ? part.text.length > 0 : part.thinking.length > 0);\n}\n\nfunction shouldNormalizeText(text: string): boolean {\n\tif (!text.includes(THINK_OPEN)) return false;\n\treturn text.trimStart().startsWith(THINK_OPEN) || text.includes(THINK_CLOSE);\n}\n\nexport function normalizeThinkingTagContent(content: AssistantContent): AssistantContent {\n\tlet changed = false;\n\tconst normalized: AssistantContentPart[] = [];\n\n\tfor (const part of content) {\n\t\tif (part.type !== \"text\" || !shouldNormalizeText(part.text)) {\n\t\t\tnormalized.push(part);\n\t\t\tcontinue;\n\t\t}\n\n\t\tchanged = true;\n\t\tfor (const split of splitTextByThinkingTags(part.text)) {\n\t\t\tnormalized.push(split as AssistantContentPart);\n\t\t}\n\t}\n\n\treturn changed ? normalized : content;\n}\n\nexport function normalizeAssistantThinkingTags(message: AssistantMessage): AssistantMessage {\n\tconst content = normalizeThinkingTagContent(message.content);\n\treturn content === message.content ? message : { ...message, content };\n}\n\nexport function stripThinkingTagsFromText(text: string): string {\n\tif (!shouldNormalizeText(text)) return text;\n\treturn splitTextByThinkingTags(text)\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n"]}