Files
Cyrene_v2/internal/runtime/transcript/documents.go
T
AskaEth 9b903a89bc
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
feat(runtime): IM 主人私聊补历史转录(与 Web 主会话同源:抽共享 transcript 包 + OwnerEnvFor 单入口)
2026-10-05 11:36:18 +08:00

52 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package transcript
import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/history"
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
)
// DocumentPathPrefix 是文档读取的版本化路径前缀。转录还原出的文档部件必须与网关读侧
// (`GET /api/v1/documents/{name}`)指向同一个 URL,否则续接的回合会把模型指到一个取不到的
// 地址。它是这个契约字符串的**唯一字面量**:网关的 `documentFilePrefix` 直接取自这里。
const DocumentPathPrefix = "/api/v1/documents/"
// documentParts 把已存 document 列里的**全部**引用还原为该回合的文档部件(design/24 §9.5)。
// 部件只交给 RoleUser 回合(§2.3-③):文档在任何别的角色上都会让编码器 fail-loud,而一行
// 坏数据不该把整个会话卡死。
//
// 列里是引用数组(一个回合最多 5 个附件),因此这里逐条还原、保持部件顺序 —— 少还原一条,
// 那个附件就会在发起它的回合之后的所有回合里消失,与「清单恒在」的承诺自相矛盾。
//
// 列被写坏(或附件落在非用户行上)时**不静默**:打一条带来源的 WARN 并省掉该部件,回合照常
// 继续 —— 附件凭空消失正是这条清单要修的缺陷,因此必须留下痕迹。日志只带消息 id 与错误,
// 绝不带正文。
func documentParts(role model.Role, h history.Message) []model.Content {
if h.Document == "" {
return nil
}
if role != model.RoleUser {
transcriptLog().Warn("transcript document on non-user row", "message", h.ID, "role", h.Role)
return nil
}
refs, err := history.DecodeDocuments(h.Document)
if err != nil {
transcriptLog().Warn("transcript document decode", "message", h.ID, "err", err)
return nil
}
parts := make([]model.Content, 0, len(refs))
for _, ref := range refs {
if ref.Name == "" {
transcriptLog().Warn("transcript document without name", "message", h.ID)
continue
}
doc := model.Document{
Name: ref.Name,
MIME: ref.MIME,
URL: DocumentPathPrefix + ref.Name,
Size: ref.Size,
}
parts = append(parts, model.DocumentMessage(model.RoleUser, "", doc).Content...)
}
return parts
}