feat(channelbridge): 出站语音结论落 voice 列并挂出站 Media(M58)
- voice.Ref 增 SourceTTS 与 FallbackReason,Validate/IsZero/validSource 同步 - 出站成功:INSERT -> 补写 voice 列 -> notify(首帧即带 voice) - 出站降级:source=tts + status=failed + fallbackReason,正文原样 - 首条气泡挂出站 Media(新开条目,不复制 target.Media) - gateway historyVoice 投影 fallbackReason - 新增 outbound_voice.go 与整链 e2e 测试(含变异打红验证时序)
This commit is contained in:
1 parent
9f6243a729
commit
28afa11aeb
13 files changed
+755
-44
No files matched your search
@@ -83,7 +83,7 @@ func (b *Bridge) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
|
||||
// 把主动消息镜像进主对话上下文(design/16
|
||||
// §4.4 + §4.6.1)。否则模型看不到自己主动说了什么,
|
||||
// 主人后续回复就会显得不连贯(该消息「丢失」了历史)。
|
||||
// 它用的是普通回复那条写入口径(persistMain,相同的列、相同的时间戳语义),
|
||||
// 它用的是普通回复那条写入口径(persistMainWith,相同的列、相同的时间戳语义),
|
||||
// 作用域恒为 MainSessionID,落库的同样是**规整后**的那一份(Web 与 IM 看到的必须是
|
||||
// 同一份),因此落库行为与本切片之前逐字相同;变的只有通知的第二步(见下)。
|
||||
// turn_id 传 ""(零值):主动推送是**她单方面开口**,没有对应的入站回合,也就没有
|
||||
@@ -97,13 +97,13 @@ func (b *Bridge) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
|
||||
// id),前端按 id 去重 ⇒ 仍是一个气泡、仍只提醒一次。
|
||||
//
|
||||
// ② 只在**确实落了库**时发:`message_persisted` 的载荷要求权威 id,客户端拿不到 id
|
||||
// 会整帧丢弃 —— 发一条没有 id 的帧等于假装提醒过。落库失败本身已由 persistMain
|
||||
// 会整帧丢弃 —— 发一条没有 id 的帧等于假装提醒过。落库失败本身已由 persistMainWith
|
||||
// 记 WARN(可见,不静默)。
|
||||
row := history.Message{
|
||||
SessionID: history.MainSessionID, Role: history.RoleAssistant, Content: out.Content,
|
||||
Platform: target.platform, DeviceID: proactiveDeviceID(target), AdapterID: target.platform, Mode: modeChat,
|
||||
}
|
||||
if full := b.persistMain(ctx, row, b.notifyPersisted); full.ID != "" {
|
||||
if full := b.persistMainWith(ctx, row, b.notifyPersisted); full.ID != "" {
|
||||
b.notifyProactive(full)
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in new issue
Block a user