fix(gateway,channelbridge,turnreply): p 标签半包写入侧规整(修「整条塌成一段」)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

裁定(已发安卓):**能修**,走**写入侧规整** —— 不指望模型输出、不动客户端。
- 新增 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:
AskaEth committed 2026-10-05 10:56:39 +08:00
1 parent d532eb3fcd
commit 5de708a560
17 files changed
+721 -46

No files matched your search

@@ -207,12 +207,16 @@ func assertNothingDelivered(t *testing.T, ad *fakeAdapter, hist *captureHistory)
}
// TestTurnReply_NormalReplyPassedThroughVerbatim 是必测③:正常回合(有正文)
// 的出站与落库内容与模型正文**逐字相同**,绝不掺进兜底文案。
// 的出站内容与模型正文**逐字相同**(段落标记由 IM 出口按既有行为剥除),落库则是
// 同一条正文的**规范形态**(每段一个 <p>,写入侧规整,见
// turnreply_paragraph_test.go)——两者都不掺进兜底文案。
func TestTurnReply_NormalReplyPassedThroughVerbatim(t *testing.T) {
t.Parallel()
const want = "你好,我在。今天想聊点什么?"
chat := &stubChatter{res: &loop.Result{Text: want, Mood: "平静"}}
const reply = "你好,我在。今天想聊点什么?"
// 规范形态:单段正文也会被包上 <p>,因此落库内容与模型原文相差的只有包裹。
const canonical = "<p>" + reply + "</p>"
chat := &stubChatter{res: &loop.Result{Text: reply, Mood: "平静"}}
b, ad, hist := replyTurnBridge(t, chat)
b.process(context.Background(), directMessage())
@@ -220,10 +224,10 @@ func TestTurnReply_NormalReplyPassedThroughVerbatim(t *testing.T) {
if len(ad.sends) != 1 {
t.Fatalf("出站消息 = %d 条, want 1", len(ad.sends))
}
if got := ad.sends[0].Content; got != want {
t.Fatalf("出站文案 = %q, want 逐字等于模型正文", got)
if got := ad.sends[0].Content; got != reply {
t.Fatalf("出站文案 = %q, want 逐字等于模型正文(段落标记不投给 IM)", got)
}
rec := assertAssistantReply(t, hist, want)
rec := assertAssistantReply(t, hist, canonical)
if rec.Mood != "平静" {
t.Fatalf("assistant mood = %q, want 平静(真实结果的心情照旧带到消息上)", rec.Mood)
}