docs(契约): v0.89 修订 —— 白名单收窄六项 + 边界行为降为实现细节 + 补 IM 出口口径
与安卓(客户端)会话对齐后的三处修订: - 白名单八项 -> 六项(去掉 u / s):它们在她 100 条输出里 0 命中, 不值得让各端为它们返工;各端可额外容错,但契约只承诺六项 - 结构不平衡的粒度(整段降级 vs 只坏那一对保持字面)降为实现细节: 契约只承诺「不产生行内渲染 + 字符一个不丢」;这类输入极罕见, 为它让任一端返工不划算 - 新增 IM 出口口径:成对且平衡的白名单标签 -> 剥标签留文本; br -> 换行;白名单外与不平衡 -> 原样保留(逐字不丢)。 与 action / narration 的「整体剥除」语义不同(那是角色扮演标记) 大小写口径(Web 不敏感 / 安卓只认小写)留待各端自定,已与安卓协商。
This commit is contained in:
1 parent
b989f0bb0c
commit
d27c1d4e33
1 file changed
+6
-3
+6
-3
@@ -1493,12 +1493,15 @@ curl -s -X POST -H "X-API-Key: $KEY" \
|
||||
|
||||
- 🔴 **背景(实测)**:她输出的**不是 Markdown**(最近 12 条 assistant 消息里 `**` 记号 0 个、列表行 0 个),而是**有限的一小组 HTML 标签**:`<p>` 96 次、`<action>` 34 次、**`<b>` 6 次**。`<p>` / `<action>` 各端早已处理,**`<b>` 此前没有任何一端处理 ⇒ 用户直接看到裸标签**。
|
||||
- **新增渲染口径(跨端一致)**:助手消息正文里,以下**行内标签**应被渲染成对应样式,而**不是**按字面显示:
|
||||
`b` / `strong`(粗)· `i` / `em`(斜)· `code`(等宽)· `u`(下划线)· `s`(删除线)· `br`(换行,`<br>`/`<br/>`/`</br>` 按 HTML5 口径等价)。
|
||||
**标签名大小写不敏感**(`<B>` = `<b>`)。
|
||||
`b` / `strong`(粗)· `i` / `em`(斜)· `code`(等宽)· `br`(换行,`<br>`/`<br/>`/`</br>` 按 HTML5 口径等价)。
|
||||
⚠️ **同日晚修订:白名单由八项收窄为上面六项**(去掉 `u`/`s`)—— 它们在她 100 条输出里 0 命中,不值得让各端为它们返工;各端**可以**额外容错渲染别的行内标签,但**契约只承诺这六项**。
|
||||
- **🔴 三条硬口径(各端必须照此实现,否则跨端显示不一致)**:
|
||||
1. **白名单外一律按纯文本原样显示** —— `<script>` 显示成字面量 `<script>`,**字符一个不丢**;
|
||||
2. **属性一律不解析** —— `<b class=x onclick=y>` 只取标签名,**属性不得变成任何 DOM/视图属性**;
|
||||
3. **结构不平衡**(未闭合 / 落单闭标签 / 交错嵌套)⇒ **整段降级为纯文本原文**(粗粒度是有意为之:换来「字符一个不丢」可被逐字断言)。
|
||||
3. **结构不平衡**(未闭合 / 落单闭标签 / 交错嵌套)⇒ **该段不产生任何行内渲染,且字符一个不丢**。
|
||||
⚠️ **同日晚修订**:具体粒度(「整段降级为原文」还是「只让坏的那一对保持字面」)**降级为实现细节**,契约不再强制统一 —— 这类输入极罕见(安卓扫 100 条、Web 扫 12 条,均 0 例),为它让任一端返工不划算。
|
||||
- **🆕 行内标签在 IM 出口的行为(同日晚补)**:IM 渠道只收纯聊天文本 ⇒ **成对且平衡的白名单行内标签在投递前剥除标签、保留内部文本**(`<b>18:35</b>` ⇒ `18:35`),**`<br>` ⇒ 换行**;**白名单外与结构不平衡的标签一律原样保留**(它们是文本,逐字不丢)。这与既有的 `<action>`/`<narration>`「IM 出口整体剥除」**语义不同**(那两个是角色扮演标记,要丢;行内标签是排版标记,剥样式留文本)。
|
||||
- **大小写口径(各端自行决定,契约不强制)**:Web 端**不敏感**(`<B>` = `<b>`);安卓端**只认小写**(与它 `parse` 只认小写 `<p>` 同口径)。两者都能通过本契约的硬口径,**这一条留待各端自定**(已与安卓端协商)。
|
||||
- 🔴 **安全红线**:助手文本是**不可信内容**(模型生成 + 用户可诱导)⇒ **任何端都不许把整段内容当 HTML 注入**(Web 端禁 `dangerouslySetInnerHTML`,原生端禁等价手段)。正确姿势是**解析成结构化节点、交给各自的安全渲染原语**(Web:React 子节点自动转义)。Web 端已由「**全程无 `dangerouslySetInnerHTML`** + 节点类型里**没有属性位**」两条结构性保证锁住,并以「白名单外的 `script` 必须逐字原样」为测试断言。
|
||||
- **范围克制**:**不做块级**(段落仍由 §4.16 的 `<p>` 机制表达)· **不做 `<a>`**(链接有独立安全面,且她目前不用)· **不做 Markdown**(她不用)。
|
||||
- **不改既有**:`<action>` / `<narration>` 的既有行为逐字不变(Web 灰斜体、IM 出口剥除);**注记内部不参与行内渲染**(注记里写 `<b>` 仍是字面量)。
|
||||
|
||||
Reference in new issue
Block a user