mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-02-19 10:14:21 -05:00
Merge pull request #1993 from ksylvan/kayvna/abacus-models-dynamic-list
Add dynamic Abacus RouteLLM model list and update fallback static list
This commit is contained in:
7
cmd/generate_changelog/incoming/1993.txt
Normal file
7
cmd/generate_changelog/incoming/1993.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
### PR [#1993](https://github.com/danielmiessler/Fabric/pull/1993) by [ksylvan](https://github.com/ksylvan): Add dynamic Abacus RouteLLM model list and update fallback static list
|
||||
|
||||
- Add dynamic model fetching from Abacus RouteLLM API with `fetchAbacusModels()` function and fallback to static list on failure
|
||||
- Add GPT-5 Codex variants (5, 5.1, 5.1-max, 5.2) and GPT-5.2-chat-latest to static model list
|
||||
- Add claude-opus-4-6, gemini-3-flash-preview, kimi-k2.5, glm-4.7, and glm-5 to static models
|
||||
- Rename `qwen/qwen3-Max` to lowercase `qwen3-max` for consistency
|
||||
- Handle `static:abacus` as special case in `ListModels` routing logic
|
||||
@@ -2,13 +2,18 @@ package openai_compatible
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/danielmiessler/fabric/internal/plugins/ai/openai"
|
||||
)
|
||||
|
||||
const abacusRouteLLMModelsURL = "https://routellm.abacus.ai/api/v0/_listRouteLLMModels"
|
||||
|
||||
// ProviderConfig defines the configuration for an OpenAI-compatible API provider
|
||||
type ProviderConfig struct {
|
||||
Name string
|
||||
@@ -41,6 +46,14 @@ func NewClient(providerConfig ProviderConfig) *Client {
|
||||
func (c *Client) ListModels() ([]string, error) {
|
||||
// If a custom models URL is provided, handle it
|
||||
if c.modelsURL != "" {
|
||||
if c.modelsURL == "static:abacus" {
|
||||
models, err := c.fetchAbacusModels()
|
||||
if err == nil && len(models) > 0 {
|
||||
return models, nil
|
||||
}
|
||||
return c.getStaticModels(c.modelsURL)
|
||||
}
|
||||
|
||||
// Check for static model list
|
||||
if strings.HasPrefix(c.modelsURL, "static:") {
|
||||
return c.getStaticModels(c.modelsURL)
|
||||
@@ -60,6 +73,47 @@ func (c *Client) ListModels() ([]string, error) {
|
||||
return c.DirectlyGetModels(context.Background())
|
||||
}
|
||||
|
||||
func (c *Client) fetchAbacusModels() ([]string, error) {
|
||||
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, abacusRouteLLMModelsURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
if c.Client.ApiKey.Value != "" {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Client.ApiKey.Value))
|
||||
}
|
||||
|
||||
httpClient := &http.Client{Timeout: 10 * time.Second}
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("abacus models endpoint returned status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Result []struct {
|
||||
Name string `json:"name"`
|
||||
} `json:"result"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
models := make([]string, 0, len(response.Result))
|
||||
for _, item := range response.Result {
|
||||
if item.Name != "" {
|
||||
models = append(models, item.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return models, nil
|
||||
}
|
||||
|
||||
// NeedsRawMode overrides the parent implementation to handle provider-specific raw mode requirements
|
||||
func (c *Client) NeedsRawMode(modelName string) bool {
|
||||
// MiniMax models require raw mode for proper message formatting
|
||||
@@ -88,8 +142,14 @@ func (c *Client) getStaticModels(modelsKey string) ([]string, error) {
|
||||
"gpt-5",
|
||||
"gpt-5-mini",
|
||||
"gpt-5-nano",
|
||||
"gpt-5-codex",
|
||||
"gpt-5.1",
|
||||
"gpt-5.1-codex",
|
||||
"gpt-5.1-codex-max",
|
||||
"gpt-5.1-chat-latest",
|
||||
"gpt-5.2",
|
||||
"gpt-5.2-chat-latest",
|
||||
"gpt-5.2-codex",
|
||||
"openai/gpt-oss-120b",
|
||||
"claude-3-7-sonnet-20250219",
|
||||
"claude-sonnet-4-20250514",
|
||||
@@ -98,6 +158,7 @@ func (c *Client) getStaticModels(modelsKey string) ([]string, error) {
|
||||
"claude-sonnet-4-5-20250929",
|
||||
"claude-haiku-4-5-20251001",
|
||||
"claude-opus-4-5-20251101",
|
||||
"claude-opus-4-6",
|
||||
"meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8",
|
||||
"meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
|
||||
"meta-llama/Meta-Llama-3.1-70B-Instruct",
|
||||
@@ -108,24 +169,28 @@ func (c *Client) getStaticModels(modelsKey string) ([]string, error) {
|
||||
"gemini-2.5-pro",
|
||||
"gemini-2.5-flash",
|
||||
"gemini-3-pro-preview",
|
||||
"gemini-3-flash-preview",
|
||||
"qwen-2.5-coder-32b",
|
||||
"Qwen/Qwen2.5-72B-Instruct",
|
||||
"Qwen/QwQ-32B",
|
||||
"Qwen/Qwen3-235B-A22B-Instruct-2507",
|
||||
"Qwen/Qwen3-32B",
|
||||
"qwen/qwen3-coder-480b-a35b-instruct",
|
||||
"qwen/qwen3-Max",
|
||||
"qwen3-max",
|
||||
"grok-4-0709",
|
||||
"grok-4-fast-non-reasoning",
|
||||
"grok-4-1-fast-non-reasoning",
|
||||
"grok-code-fast-1",
|
||||
"kimi-k2-turbo-preview",
|
||||
"kimi-k2.5",
|
||||
"deepseek/deepseek-v3.1",
|
||||
"deepseek-ai/DeepSeek-V3.1-Terminus",
|
||||
"deepseek-ai/DeepSeek-R1",
|
||||
"deepseek-ai/DeepSeek-V3.2",
|
||||
"zai-org/glm-4.5",
|
||||
"zai-org/glm-4.6",
|
||||
"zai-org/glm-4.7",
|
||||
"zai-org/glm-5",
|
||||
}, nil
|
||||
case "static:minimax":
|
||||
return []string{
|
||||
|
||||
Reference in New Issue
Block a user