package tools import ( "context" "strings" "isphere-ai-bridge/internal/isphere" "isphere-ai-bridge/internal/msglib" ) type DisplayEntitySource interface { DisplayEntities(ctx context.Context, opts msglib.DisplayEntitiesOptions) ([]msglib.DisplayEntity, error) } func displayEntityQueryLimit(limit int) int { if limit <= 0 { return msglib.DefaultDisplayEntityLimit } if limit > msglib.MaxDisplayEntityLimit { return msglib.MaxDisplayEntityLimit } return limit } func contactsFromDisplayEntities(entities []msglib.DisplayEntity) []isphere.Contact { contacts := make([]isphere.Contact, 0, len(entities)) for _, entity := range entities { id := strings.TrimSpace(entity.JID) name := strings.TrimSpace(entity.DisplayName) if id == "" { id = name } if name == "" { name = id } if id == "" { continue } contacts = append(contacts, isphere.Contact{ ContactID: id, DisplayName: name, Account: strings.TrimSpace(entity.JID), Source: "msglib_readonly", Confidence: entity.Confidence, RawRef: "msglib:" + entity.SourceTable, }) } return contacts } func groupsFromDisplayEntities(entities []msglib.DisplayEntity) []isphere.Group { groups := make([]isphere.Group, 0, len(entities)) for _, entity := range entities { id := strings.TrimSpace(entity.JID) name := strings.TrimSpace(entity.DisplayName) if id == "" { id = name } if name == "" { name = id } if id == "" { continue } groups = append(groups, isphere.Group{ GroupID: id, DisplayName: name, Source: "msglib_readonly", Confidence: entity.Confidence, RawRef: "msglib:" + entity.SourceTable, }) } return groups } func mergeContacts(primary []isphere.Contact, fallback []isphere.Contact, limit int) isphere.SearchContactsResult { seen := map[string]bool{} contacts := make([]isphere.Contact, 0, len(primary)+len(fallback)) for _, contact := range append(primary, fallback...) { id := strings.TrimSpace(contact.ContactID) if id == "" || seen[strings.ToLower(id)] { continue } seen[strings.ToLower(id)] = true contacts = append(contacts, contact) if limit > 0 && len(contacts) >= limit { break } } return isphere.SearchContactsResult{Contacts: contacts} } func mergeGroups(primary []isphere.Group, fallback []isphere.Group, limit int) isphere.SearchGroupsResult { seen := map[string]bool{} groups := make([]isphere.Group, 0, len(primary)+len(fallback)) for _, group := range append(primary, fallback...) { id := strings.TrimSpace(group.GroupID) if id == "" || seen[strings.ToLower(id)] { continue } seen[strings.ToLower(id)] = true groups = append(groups, group) if limit > 0 && len(groups) >= limit { break } } return isphere.SearchGroupsResult{Groups: groups} }