fix(gateway,channelbridge,turnreply): p 标签半包写入侧规整(修「整条塌成一段」)
裁定(已发安卓):**能修**,走**写入侧规整** —— 不指望模型输出、不动客户端。 - 新增 internal/runtime/turnreply/paragraph.go 的 NormalizeParagraphs: 把未被 <p> 包裹的段落补上 <p>(按空行分段;<action>/<narration> 段也包进 <p>, 与正确形态 <p><action>…</action>…</p> 一致) - **幂等**守门断言:已完全包裹的文本逐字不变(防二次加工) - 落点覆盖 Web 与 IM 两条落库路径(gateway/session_turn_reply.go、channelbridge/turnreply.go、 proactive.go)⇒ 两边共用同一份规整文本 ⇒ **历史一次性变好、两个客户端零改动**、渲染口径不分叉 (测试与变异详见切片报告)
This commit is contained in:
1 parent
d532eb3fcd
commit
5de708a560
17 files changed
+721
-46
No files matched your search
@@ -53,8 +53,10 @@ func (o *Orchestrator) turnIsCurrent(sessionID string, gen uint64) bool {
|
||||
// persistTurnReply 是本回合助手回复的**唯一落库入口**(completeTurn 的收尾第一
|
||||
// 步)。两条分支:
|
||||
//
|
||||
// - 有真实文本:逐字落库,行为与加入本保证之前完全一致(被取消/陈旧代次的
|
||||
// 回合也照旧落 —— 内容是真的,与「不静默」无关);
|
||||
// - 有真实文本:逐字落库(**唯一例外**是幂等的段落包裹规整,见
|
||||
// turnreply.NormalizeParagraphs:只给未被 `<p>` 包裹的段落补上包裹,已规范的
|
||||
// 文本一字不改;且**只在 chat 模式**做,见正文注释),行为与加入本保证之前完全
|
||||
// 一致(被取消/陈旧代次的回合也照旧落 —— 内容是真的,与「不静默」无关);
|
||||
// - 没有可见文本(空回复 / 轮次用尽 / 内部报错 / 只剩安全网的内部文案):只有
|
||||
// 「归本代次且不是被取消」才补一条诚实说明;其余情形返回原样、什么都不写。
|
||||
//
|
||||
@@ -74,7 +76,20 @@ func (o *Orchestrator) persistTurnReply(sessionID string, gen uint64, res *loop.
|
||||
}
|
||||
text := turnreply.Text(res)
|
||||
if res != nil && res.Text == text {
|
||||
// 真实文本:逐字落库,行为与加入本保证之前完全一致。
|
||||
// 真实文本:除段落包裹规整外逐字落库。规整是**幂等的写入侧加法**(只给
|
||||
// 未被 <p> 包裹的段落补上包裹,已规范的文本一字不改),它就地改写
|
||||
// res.Text,因此落库内容、WS `message_persisted`、REST reply、续跑尾部
|
||||
// 与语音拿到的是**同一份**文本。客户端的解析规则是「只要存在完整 <p> 块
|
||||
// 就不再按空行回退切分」,半包的回复恰好在那一侧整条塌成一段;同一条
|
||||
// 判据在 IM 侧(splitBubbles)也成立,两边必须吃同一份文本。
|
||||
//
|
||||
// **只在 chat 模式规整**:拆气泡这条判据只属于 chat 气泡;其余 mode
|
||||
// (code/home/work/docs…)的消息在客户端是**按原样整体渲染**的
|
||||
// (design/07 §2),往里塞 <p> 只会在那些形态里露出野生标签。IM 永远是
|
||||
// chat(channelbridge 的 modeChat),因此这条闸门不会让 Web 与 IM 分叉。
|
||||
if modeOrDefault(mode) == modeChat {
|
||||
res.Text = turnreply.NormalizeParagraphs(res.Text)
|
||||
}
|
||||
o.persistAssistantReply(sessionID, res, deviceID, mode, personaID, turnID)
|
||||
return res
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user