/**
* 从 LLM 生成的原始文本里抠出可运行的 HTML 文档。
*
* gemma 大多数时候会乖乖只吐 HTML,但偶尔会:
* - 用 ```html ... ``` 围栏包起来
* - 在前面/后面加一两句寒暄
* 这里尽量稳地把中间那坨 HTML 提出来。提不出来就返回空串(让调用方报错)。
*/
export function extractHtml(raw: string): string {
if (!raw) return ''
let s = raw.trim()
// 1. 优先取 markdown 代码围栏里的内容
const fence = s.match(/```(?:html|HTML)?\s*\n([\s\S]*?)```/)
if (fence && fence[1].trim()) {
s = fence[1].trim()
} else if (s.startsWith('```')) {
// 围栏没闭合(流式被截断 / 只有开头)—— 去掉开头那行围栏
s = s.replace(/^```[a-zA-Z]*\s*\n?/, '').replace(/```\s*$/, '').trim()
}
// 2. 从第一个 |]/i)
if (startMatch && startMatch.index !== undefined && startMatch.index > 0) {
s = s.slice(startMatch.index)
}
// 3. 截到最后一个 结束(丢掉后面的寒暄)
const endIdx = s.toLowerCase().lastIndexOf('