feat(channels): IM 入站图片接线(纯图片不再被丢 / data URI 进模型视图 / 诚实提示 / 来源白名单)

This commit is contained in:
AskaEth committed 2026-10-05 11:22:26 +08:00
1 parent 0cbc9ff886
commit b73a1276c6
18 files changed
+1224 -121

No files matched your search

+10 -5
View File
@@ -64,17 +64,20 @@ func (b *Bridge) notifyPersisted(msg history.Message) {
// 形状即 history.EncodeDocuments 的产物;没有附件时传 ""(那一列因此为
// 空,读侧 `documents` 键随之省略)。IM 入站的附件与 Web 上传共用这一列,
// 客户端两侧读到的附件芯片才是同一个东西。
// image 是这条消息携带的图片(data: URI 或 http(s) URL),写进 DTO 的 `image`
// 字段(design/16 §4.4);没有图片时传 ""。它**不是** document 列的一部分:
// 图片走视觉链路,文档走抽取,两者是两条路(design/24 §4.2 末的明确分野)。
//
// 它返回刚落库的完整消息(未装配历史存储、或写库失败时是零值),
// 使调用方能在回合结束后按 id 把文档抽取结论补进同一列
// (inbound_documents_persist.go 的两段式)。未装配历史存储时为空操作,
// 因此桥接器在没有存储的情况下行为不变。
func (b *Bridge) persistToMain(ctx context.Context, role, content, mood, document, platform, deviceID, adapterID string) history.Message {
func (b *Bridge) persistToMain(ctx context.Context, role, content, mood, document, image, platform, deviceID, adapterID string) history.Message {
if b.history == nil {
return history.Message{}
}
full, err := b.history.AppendFull(ctx, history.Message{
SessionID: history.MainSessionID, Role: role, Content: content, Mood: mood, Document: document, Platform: platform, DeviceID: deviceID, AdapterID: adapterID, Mode: modeChat,
SessionID: history.MainSessionID, Role: role, Content: content, Mood: mood, Document: document, Image: image, 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)
@@ -93,17 +96,19 @@ func (b *Bridge) persistToMain(ctx context.Context, role, content, mood, documen
// 消息才镜像到 Web);它只交给传输钩子,让
// gateway 广播 `channel_persisted` 事件、IM 适配器日志页无需刷新
// 即可追加。document 是该消息携带的文档引用数组(design/24 §2.4),
// 与 persistToMain 同一列、同一形状;没有附件时传 ""。
// 与 persistToMain 同一列、同一形状;没有附件时传 ""。image 是该消息携带的图片
// (data: URI 或 http(s) URL),同样与 persistToMain 同一列(DTO 的 `image` 字段);
// 没有图片时传 ""。
//
// 它返回刚落库的完整消息(未装配历史存储、或写库失败时是零值),
// 供调用方在回合结束后补回文档抽取结论。未装配历史存储时为空操作,
// 因此桥接器在没有存储的情况下行为不变。
func (b *Bridge) persistIsolated(ctx context.Context, role, content, document, deviceID string, sess session.Session, platform, senderName, adapterID string) history.Message {
func (b *Bridge) persistIsolated(ctx context.Context, role, content, document, image, deviceID string, sess session.Session, platform, senderName, adapterID string) history.Message {
if b.history == nil {
return history.Message{}
}
full, err := b.history.AppendFull(ctx, history.Message{
SessionID: sess.SessionID, Role: role, Content: content, Document: document, Platform: platform,
SessionID: sess.SessionID, Role: role, Content: content, Document: document, Image: image, Platform: platform,
DeviceID: deviceID, SenderName: senderName, AdapterID: adapterID, Mode: modeChat,
})
if err != nil {