package isphere import ( "context" "fmt" "strings" "isphere-ai-bridge/internal/msglib" ) type MsgLibMessageLister interface { ListMessages(ctx context.Context, opts msglib.ListMessagesOptions) (msglib.ListMessagesResult, error) } type MsgLibMessageSource struct { Lister MsgLibMessageLister IncludeBody bool IncludeAttachmentMetadata bool } func (s MsgLibMessageSource) ReceiveMessages(ctx context.Context, query ReceiveMessagesQuery) (ReceiveMessagesResult, error) { if s.Lister == nil { return ReceiveMessagesResult{}, fmt.Errorf("msglib message source requires a lister") } result, err := s.Lister.ListMessages(ctx, msglib.ListMessagesOptions{ ConversationID: query.ConversationID, ConversationType: "auto", Query: query.Query, Since: query.Since, Limit: query.Limit, IncludeBody: s.IncludeBody, IncludeAttachmentMetadata: s.IncludeAttachmentMetadata, }) if err != nil { return ReceiveMessagesResult{}, err } if !result.ReadOnly { return ReceiveMessagesResult{}, fmt.Errorf("msglib list_messages did not report read_only=true") } if result.RawRowsReturned { return ReceiveMessagesResult{}, fmt.Errorf("msglib list_messages returned raw rows") } if result.FilePathsReturned { return ReceiveMessagesResult{}, fmt.Errorf("msglib list_messages returned file path values") } messages := make([]Message, 0, len(result.Messages)) for _, item := range result.Messages { messages = append(messages, msgLibListMessageToReceiveMessage(item)) } return ReceiveMessagesResult{Messages: messages}, nil } func msgLibListMessageToReceiveMessage(item msglib.ListMessage) Message { return Message{ ID: firstNonEmpty(item.ID, item.MessageID), ConversationID: item.ConversationID, ConversationType: item.ConversationType, SenderID: item.SenderID, ReceiverID: item.ReceiverID, Text: firstNonEmpty(item.ContentText, item.Text), Timestamp: firstNonEmpty(item.Timestamp, item.CreatedAt), Subject: item.Subject, Read: item.Read, Source: firstNonEmpty(item.Source, "local_readonly"), RawRef: item.RawRef, Attachments: msgLibAttachmentsToReceiveAttachments(item.Attachments), } } func msgLibAttachmentsToReceiveAttachments(items []msglib.ListMessageAttachment) []MessageAttachment { if len(items) == 0 { return nil } attachments := make([]MessageAttachment, 0, len(items)) for _, item := range items { attachment := MessageAttachment{ FileID: item.FileID, FileName: item.FileName, DownloadRef: item.DownloadRef, } if item.SizeBytes > 0 { size := item.SizeBytes attachment.SizeBytes = &size } attachments = append(attachments, attachment) } return attachments } func firstNonEmpty(values ...string) string { for _, value := range values { if strings.TrimSpace(value) != "" { return value } } return "" }