dispatchModelsRequest sends req via client and parses the OpenAI-style model list returned. Empty IDs are skipped; duplicates are preserved (the caller — collectModels — already deduplicates by ref). The function logs and returns nil on any failure so the listing command degrades gracefully.
(ctx context.Context, req *http.Request, client *http.Client)
| 328 | // — collectModels — already deduplicates by ref). The function logs and |
| 329 | // returns nil on any failure so the listing command degrades gracefully. |
| 330 | func dispatchModelsRequest(ctx context.Context, req *http.Request, client *http.Client) []string { |
| 331 | url := req.URL.String() |
| 332 | |
| 333 | resp, err := client.Do(req) |
| 334 | if err != nil { |
| 335 | slog.WarnContext(ctx, "failed to fetch provider models", "url", url, "error", err) |
| 336 | return nil |
| 337 | } |
| 338 | defer resp.Body.Close() |
| 339 | |
| 340 | if resp.StatusCode != http.StatusOK { |
| 341 | slog.WarnContext(ctx, "provider models endpoint returned non-200", "url", url, "status", resp.StatusCode) |
| 342 | return nil |
| 343 | } |
| 344 | |
| 345 | body, err := io.ReadAll(resp.Body) |
| 346 | if err != nil { |
| 347 | slog.WarnContext(ctx, "failed to read provider models response", "url", url, "error", err) |
| 348 | return nil |
| 349 | } |
| 350 | |
| 351 | var result openAIModelsResponse |
| 352 | if err := json.Unmarshal(body, &result); err != nil { |
| 353 | slog.WarnContext(ctx, "failed to parse provider models response", "url", url, "error", err) |
| 354 | return nil |
| 355 | } |
| 356 | |
| 357 | models := make([]string, 0, len(result.Data)) |
| 358 | for _, m := range result.Data { |
| 359 | if m.ID == "" { |
| 360 | continue |
| 361 | } |
| 362 | models = append(models, m.ID) |
| 363 | } |
| 364 | return models |
| 365 | } |
| 366 | |
| 367 | func isEmbeddingModel(family, name string) bool { |
| 368 | fl := strings.ToLower(family) |
no test coverage detected