classifyProviderRow evaluates a single ai_providers row for routing. seenHost is mutated to track the first provider that claimed each hostname so later duplicates can be flagged as errors.
(row database.AIProvider, seenHost map[string]string)
| 117 | // seenHost is mutated to track the first provider that claimed each |
| 118 | // hostname so later duplicates can be flagged as errors. |
| 119 | func classifyProviderRow(row database.AIProvider, seenHost map[string]string) aibridgeproxyd.ReloadedProvider { |
| 120 | out := aibridgeproxyd.ReloadedProvider{ |
| 121 | ProviderOutcome: aibridged.ProviderOutcome{ |
| 122 | Name: row.Name, |
| 123 | Type: string(row.Type), |
| 124 | }, |
| 125 | } |
| 126 | if !row.Enabled { |
| 127 | out.Status = aibridged.ProviderStatusDisabled |
| 128 | return out |
| 129 | } |
| 130 | if strings.TrimSpace(row.BaseUrl) == "" { |
| 131 | out.Status = aibridged.ProviderStatusError |
| 132 | out.Err = xerrors.New("base url is empty") |
| 133 | return out |
| 134 | } |
| 135 | u, err := url.Parse(row.BaseUrl) |
| 136 | if err != nil { |
| 137 | out.Status = aibridged.ProviderStatusError |
| 138 | out.Err = xerrors.Errorf("invalid base url %q: %w", row.BaseUrl, err) |
| 139 | return out |
| 140 | } |
| 141 | host := strings.ToLower(u.Hostname()) |
| 142 | if host == "" { |
| 143 | out.Status = aibridged.ProviderStatusError |
| 144 | out.Err = xerrors.Errorf("base url %q has no hostname", row.BaseUrl) |
| 145 | return out |
| 146 | } |
| 147 | if claimedBy, taken := seenHost[host]; taken { |
| 148 | out.Status = aibridged.ProviderStatusError |
| 149 | out.Err = xerrors.Errorf("hostname %q already claimed by provider %q", host, claimedBy) |
| 150 | return out |
| 151 | } |
| 152 | seenHost[host] = row.Name |
| 153 | out.Host = host |
| 154 | out.Status = aibridged.ProviderStatusEnabled |
| 155 | return out |
| 156 | } |