feat(gateway): 消息mode落库(A3) — 持久化真实写入渲染模式
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- POST /api/v1/chat 与 ws.chat 上行新增可选 mode(行为模式 design/01 §3/design/16 §5.1)
- Web路径经ctx透传本轮mode到编排器持久化(persistUserMessages/persistAssistantReply),缺省回落chat
- pendingMsg记录mode,恢复/续接路径沿用发起轮次mode
- IM路径(persistToMain/persistIsolated)恒为chat
- 新增/扩充测试:REST/WS/orchestrator/channelbridge 覆盖mode写入
- Docs/api-client.md v0.20 同步mode字段
This commit is contained in:
AskaEth committed 2026-09-08 21:05:50 +08:00
1 parent fe5dbcddba
commit b686d5fec8
9 files changed
+199 -41

No files matched your search

+6 -2
View File
@@ -14,6 +14,10 @@ import (
// without a refresh. Kept separate from channelbridge.go so the bridge's inbound
// pipeline file stays under the module size bound.
// modeChat is the behavior mode written for every IM-persisted message: IM carries
// chat text alone (design/02 §1 单向回流), so no other mode ever applies there.
const modeChat = "chat"
// SetOnPersisted wires (or replaces) the transport hook called after an
// owner-private message is persisted into the main web session. The gateway is
// built after the bridge in the composition root, so the hook is attached post-New
@@ -60,7 +64,7 @@ func (b *Bridge) persistToMain(ctx context.Context, role, content, platform, dev
return
}
full, err := b.history.AppendFull(ctx, history.Message{
SessionID: history.MainSessionID, Role: role, Content: content, Platform: platform, DeviceID: deviceID, AdapterID: adapterID,
SessionID: history.MainSessionID, Role: role, Content: content, Platform: platform, DeviceID: deviceID, AdapterID: adapterID, Mode: modeChat,
})
if err != nil {
b.log.Warn("persist main session", "err", err, "role", role, "platform", platform, "device_id", deviceID, "adapter", adapterID)
@@ -85,7 +89,7 @@ func (b *Bridge) persistIsolated(ctx context.Context, role, content, deviceID st
}
full, err := b.history.AppendFull(ctx, history.Message{
SessionID: sess.SessionID, Role: role, Content: content, Platform: platform,
DeviceID: deviceID, SenderName: senderName, AdapterID: adapterID,
DeviceID: deviceID, SenderName: senderName, AdapterID: adapterID, Mode: modeChat,
})
if err != nil {
b.log.Warn("persist isolated session", "err", err, "role", role,