package server import ( "fmt" "strings" "chat-agent-system/internal/chat" "chat-agent-system/internal/coordinator" ) // prepareChatTurn 允许「只上传文档、不写文字」。落库文字由文件名合成,原始空串不会进入模型。 func prepareChatTurn(message string, atts []TurnAttachment) (stored string, attachmentOnly bool, reject string) { atts = normalizeTurnAttachments(atts) message = strings.TrimSpace(message) if message == "" && len(atts) == 0 { return "", false, "message cannot be empty" } if message == "" { return attachmentOnlyStoredMessage(atts), true, "" } return message, false, "" } func normalizeTurnAttachments(atts []TurnAttachment) []TurnAttachment { if len(atts) == 0 { return nil } out := make([]TurnAttachment, 0, len(atts)) for _, att := range atts { att.Filename = strings.TrimSpace(att.Filename) att.DocID = strings.TrimSpace(att.DocID) att.ParseState = strings.TrimSpace(att.ParseState) if att.Filename == "" && att.DocID == "" && att.AssetID == 0 { continue } if att.Filename == "" { att.Filename = "未命名文档" } out = append(out, att) } if len(out) == 0 { return nil } return out } func attachmentOnlyStoredMessage(atts []TurnAttachment) string { names := make([]string, 0, len(atts)) for _, att := range atts { names = append(names, "《"+strings.Trim(att.Filename, "《》")+"》") } return "已上传文档:" + strings.Join(names, "、") } func turnAttachmentHashKey(atts []TurnAttachment) string { atts = normalizeTurnAttachments(atts) if len(atts) == 0 { return "" } parts := make([]string, 0, len(atts)) for _, att := range atts { parts = append(parts, fmt.Sprintf("%s|%s|%d|%s", att.Filename, att.DocID, att.AssetID, att.ParseState)) } return strings.Join(parts, ";") } func (s *Server) bindTurnAttachments(sess *chat.Session, atts []TurnAttachment, attachmentOnly bool) { if sess == nil || sess.UserCtx == nil { return } atts = normalizeTurnAttachments(atts) refs := make([]coordinator.TurnAttachmentRef, 0, len(atts)) for _, att := range atts { refs = append(refs, coordinator.TurnAttachmentRef{ Filename: att.Filename, DocID: att.DocID, AssetID: att.AssetID, ParseState: att.ParseState, }) } sess.UserCtx.PendingTurnAttachments = refs sess.UserCtx.AttachmentOnlyTurn = attachmentOnly && len(refs) > 0 }