// 助手文本的**行内白名单标签**解析(主人 2026-10-07 需求「基本渲染支持」)。 // // 背景:昔涟产出的是**少量 HTML 标签**而不是 Markdown —— 段落用 `

`(契约 §4.16, // 由 `splitParagraphs` 处理),动作/旁白用 ``/``(由 `splitBubble` // 处理,Web 渲染为气泡外的灰斜体注记),**行内**则偶发 `` 之类强调标签。 // 后两类此前没有处理 ⇒ `18:35` 会把字面量 `<b>` 直接显示给用户。 // // 🔴 **`
` 有两种身份,由调用方的 `lineBreaks` 决定**(主人 2026-10-07 口径 // 「对消息内的 `
` 始终处理为多条消息隔断」+ 2026-10-07 晚「非聊天模式按照应当有的 // 专业卡片和格式来显示」): // · **chat 模式(默认,`lineBreaks` 关)**:`
` 是**气泡/消息分隔符**,与 `

` 同级, // 由 `components/chat.tsx` 的 `splitParagraphs`(气泡切分层)切掉;到这里它已不存在。 // 万一有 `
` 走到本模块(注记文本等不切气泡的路径),按**白名单外**处理 ⇒ 逐字原样, // 绝不在这里伪造一个「气泡内换行」。 // · **非 chat 的单卡正文(`lineBreaks` 开)**:工作 / 代码 / 文档 / 首页 / 视觉 / 语音 / // 智能体 / 设置这些界面**没有「多条气泡」的概念** ⇒ `
` 只**换行**、不切分,解析成 // `{kind:"break"}`(渲染为真 `
` 元素,不依赖父容器的 `white-space`)。 // // 🔴 安全口径(本模块存在的理由):产物是**不可信文本**(模型生成 + 用户可诱导), // 因此**绝不**把它当 HTML 注入(无 `innerHTML` / `dangerouslySetInnerHTML`)。 // 这里的做法是**解析成结构化节点**(`InlineNode[]`),交给 React 元素渲染 —— React // 对文本节点默认转义,天然安全。规则: // ① 只认**行内**白名单元素(六项:`b` / `strong` / `i` / `em` / `code` / `u`),块级一律 // 不支持(段落仍由 §4.16 的 `

` 机制表达); // ② **属性一律丢弃**(`` 只取标签名 `b`,属性绝不进 DOM); // ③ 白名单外标签**逐字原样**当文本(`