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
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/history"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/turnreply"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/user"
|
||||
)
|
||||
|
||||
@@ -54,6 +55,10 @@ func (b *Bridge) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
|
||||
out := msg
|
||||
out.Platform = target.platform
|
||||
out.ChannelType = adapter.ChannelDirect
|
||||
// 主动推送的文本与回合回复走**同一份**段落包裹规整(同一函数、同一口径):
|
||||
// 半包 <p> 的推送在 Web 历史里同样会塌成一整段,在 IM 侧同样只会得到
|
||||
// 一个气泡(splitBubbles 只认完整 <p> 块)。
|
||||
out.Content = turnreply.NormalizeParagraphs(msg.Content)
|
||||
// 主人的账号 id 在每个适配器上都作私聊对端:telegram/qq 读
|
||||
// ChannelID,kook/weixin 读 SenderID(ChannelID 作回退)。两者
|
||||
// 都设置,无论适配器偏好哪个字段,私聊消息都可投达,
|
||||
@@ -63,17 +68,18 @@ func (b *Bridge) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
|
||||
// 推送经共享的 IM 气泡派发器出口,因此多段主动消息
|
||||
// 会被拆成气泡、角色扮演/旁白被剥离,并采用
|
||||
// 与回复相同的 0.5-2s 间隔——WeChat 主动推送不再作为
|
||||
// 一整条未拆分消息发送。
|
||||
// 一整条未拆分消息发送。切分吃的是**规整后**的同一份文本。
|
||||
if err := b.sendIMBubbles(ctx, out, func(ctx context.Context, msg adapter.UnifiedMessage) error {
|
||||
return ad.SendProactive(ctx, msg)
|
||||
}, msg.Content); err != nil {
|
||||
}, out.Content); err != nil {
|
||||
return fmt.Errorf("channelbridge: send proactive via %q: %w", target.platform, err)
|
||||
}
|
||||
// 把主动消息镜像进主对话上下文(design/16
|
||||
// §4.4 + §4.6.1)。否则模型看不到自己主动说了什么,
|
||||
// 主人后续回复就会显得不连贯(该消息「丢失」了历史)。
|
||||
// 它与主人私聊 IM 回复走同一条镜像路径,作用域为 MainSessionID。
|
||||
b.persistToMain(ctx, history.RoleAssistant, msg.Content, "", "", target.platform,
|
||||
// 它与主人私聊 IM 回复走同一条镜像路径,作用域为 MainSessionID,
|
||||
// 落库的同样是规整后的那一份(Web 与 IM 看到的必须是同一份)。
|
||||
b.persistToMain(ctx, history.RoleAssistant, out.Content, "", "", target.platform,
|
||||
fmt.Sprintf("%s:%s:%s", target.platform, target.accountID, target.accountID),
|
||||
target.platform)
|
||||
return nil
|
||||
|
||||
Reference in new issue
Block a user