Show custom provider model catalogs

This commit is contained in:
rcourtman
2026-06-29 23:19:13 +01:00
parent dcf23fb2ca
commit d8de95b91f
2 changed files with 79 additions and 15 deletions
+30
View File
@@ -307,6 +307,17 @@ func (c *OpenAIClient) isOpenRouter() bool {
return c.Name() == "openrouter" || strings.Contains(c.baseURL, "openrouter.ai")
}
func (c *OpenAIClient) usesOfficialOpenAIEndpoint() bool {
if c.Name() != "openai" {
return false
}
u, err := url.Parse(c.baseURL)
if err != nil || u.Host == "" {
return true
}
return strings.EqualFold(u.Hostname(), "api.openai.com")
}
// isDeepSeekReasoner returns true if using DeepSeek's reasoning model
func (c *OpenAIClient) isDeepSeekReasoner() bool {
return c.isDeepSeek() && strings.Contains(c.model, "reasoner")
@@ -1240,6 +1251,25 @@ func (c *OpenAIClient) ListModels(ctx context.Context) ([]ModelInfo, error) {
continue
}
if !c.usesOfficialOpenAIEndpoint() {
modelName := strings.TrimSpace(m.Name)
if modelName == "" {
modelName = m.ID
}
description := strings.TrimSpace(m.Description)
if description == "" && strings.TrimSpace(m.OwnedBy) != "" {
description = strings.TrimSpace(m.OwnedBy)
}
models = append(models, ModelInfo{
ID: m.ID,
Name: modelName,
Description: description,
CreatedAt: m.Created,
Notable: cache.IsNotable(c.Name(), m.ID, m.Created),
})
continue
}
// Filter to only chat-capable models
if strings.Contains(m.ID, "gpt") || strings.Contains(m.ID, "o1") ||
strings.Contains(m.ID, "o3") || strings.Contains(m.ID, "o4") ||
+49 -15
View File
@@ -945,21 +945,24 @@ func TestNewOpenAIClient_StripsOpenRouterPrefix(t *testing.T) {
}
func TestOpenAIClient_ListModels(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"data": []map[string]interface{}{
{"id": "gpt-4", "object": "model", "created": 1234567890, "owned_by": "openai"},
{"id": "gpt-3.5-turbo", "object": "model", "created": 1234567890, "owned_by": "openai"},
{"id": "claude-3", "object": "model", "created": 1234567890, "owned_by": "anthropic"},
},
})
}))
defer server.Close()
client := NewOpenAIClient("sk-test", "gpt-4", server.URL, 0)
client := NewOpenAIClient("sk-test", "gpt-4", "https://api.openai.com/v1", 0)
client.client = &http.Client{
Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) {
assert.Equal(t, "https://api.openai.com/v1/models", r.URL.String())
return &http.Response{
StatusCode: http.StatusOK,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(strings.NewReader(`{
"data": [
{"id": "gpt-4", "object": "model", "created": 1234567890, "owned_by": "openai"},
{"id": "gpt-3.5-turbo", "object": "model", "created": 1234567890, "owned_by": "openai"},
{"id": "claude-3", "object": "model", "created": 1234567890, "owned_by": "anthropic"}
]
}`)),
Request: r,
}, nil
}),
}
models, err := client.ListModels(context.Background())
require.NoError(t, err)
@@ -969,6 +972,37 @@ func TestOpenAIClient_ListModels(t *testing.T) {
assert.Equal(t, "gpt-3.5-turbo", models[1].ID)
}
func TestOpenAIClient_ListModels_CustomBaseURLReturnsCatalog(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/v1/models", r.URL.Path)
assert.Equal(t, "Bearer sk-test", r.Header.Get("Authorization"))
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"data": []map[string]interface{}{
{"id": "qwen2.5-coder:32b", "name": "Qwen Coder 32B", "description": "local coding model", "created": 1234567890},
{"id": "llama3.3:70b", "object": "model", "created": 1234567891, "owned_by": "custom-lab"},
{"id": "gpt-4-compatible", "object": "model", "created": 1234567892},
},
})
}))
defer server.Close()
client := NewOpenAIClient("sk-test", "qwen2.5-coder:32b", server.URL, 0)
models, err := client.ListModels(context.Background())
require.NoError(t, err)
require.Len(t, models, 3)
assert.Equal(t, "qwen2.5-coder:32b", models[0].ID)
assert.Equal(t, "Qwen Coder 32B", models[0].Name)
assert.Equal(t, "local coding model", models[0].Description)
assert.Equal(t, "llama3.3:70b", models[1].ID)
assert.Equal(t, "custom-lab", models[1].Description)
assert.Equal(t, "gpt-4-compatible", models[2].ID)
}
func TestOpenAIClient_ListModels_OpenRouterReturnsCatalog(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/api/v1/models", r.URL.Path)