FindChatAgent picks the best workspace agent for a chat session from the provided candidates. It applies these rules in order: 1. Filter to root agents only (ParentID is null). 2. Sort stably and deterministically by DisplayOrder ASC, then Name ASC (case-insensitive), then Name ASC, then ID ASC. 3.
( agents []database.WorkspaceAgent, )
| 32 | // actionable message. |
| 33 | // 6. If no root agents exist at all, return an error. |
| 34 | func FindChatAgent( |
| 35 | agents []database.WorkspaceAgent, |
| 36 | ) (database.WorkspaceAgent, error) { |
| 37 | rootAgents := make([]database.WorkspaceAgent, 0, len(agents)) |
| 38 | matchingAgents := make([]database.WorkspaceAgent, 0, 1) |
| 39 | for _, agent := range agents { |
| 40 | if agent.ParentID.Valid { |
| 41 | continue |
| 42 | } |
| 43 | rootAgents = append(rootAgents, agent) |
| 44 | if IsChatAgent(agent.Name) { |
| 45 | matchingAgents = append(matchingAgents, agent) |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | if len(rootAgents) == 0 { |
| 50 | return database.WorkspaceAgent{}, xerrors.New( |
| 51 | "no eligible workspace agents found", |
| 52 | ) |
| 53 | } |
| 54 | |
| 55 | compareAgents := func(a, b database.WorkspaceAgent) int { |
| 56 | if order := cmp.Compare(a.DisplayOrder, b.DisplayOrder); order != 0 { |
| 57 | return order |
| 58 | } |
| 59 | if order := cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)); order != 0 { |
| 60 | return order |
| 61 | } |
| 62 | if order := cmp.Compare(a.Name, b.Name); order != 0 { |
| 63 | return order |
| 64 | } |
| 65 | return cmp.Compare(a.ID.String(), b.ID.String()) |
| 66 | } |
| 67 | slices.SortStableFunc(rootAgents, compareAgents) |
| 68 | slices.SortStableFunc(matchingAgents, compareAgents) |
| 69 | |
| 70 | switch len(matchingAgents) { |
| 71 | case 0: |
| 72 | return rootAgents[0], nil |
| 73 | case 1: |
| 74 | return matchingAgents[0], nil |
| 75 | default: |
| 76 | names := make([]string, 0, len(matchingAgents)) |
| 77 | for _, agent := range matchingAgents { |
| 78 | names = append(names, agent.Name) |
| 79 | } |
| 80 | return database.WorkspaceAgent{}, xerrors.Errorf( |
| 81 | "multiple agents match the chat suffix %q: %s; only one agent should use this suffix", |
| 82 | Suffix, |
| 83 | strings.Join(names, ", "), |
| 84 | ) |
| 85 | } |
| 86 | } |