From 0703dd16027eed4757ff99128bd2dd4279a314f3 Mon Sep 17 00:00:00 2001 From: Ed Zynda Date: Wed, 25 Feb 2026 18:17:25 +0300 Subject: [PATCH] fix: eliminate escape sequence leak from spinner tea.Program instances Each spinner created a new tea.NewProgram which sent DECRQM queries for synchronized output mode 2026. When the program exited and restored cooked terminal mode, the terminal's DECRPM response leaked as visible ^[[?2026;2$y characters. Replace Bubble Tea spinner with a simple goroutine animation loop writing directly to stderr via lipgloss. --- .golangci.yml | 9 + btca.config.jsonc | 14 +- cmd/root.go | 72 +- cmd/script.go | 15 +- cmd/script_integration_test.go | 2 +- go.mod | 134 +- go.sum | 367 +- internal/agent/agent.go | 586 +- internal/agent/streaming.go | 147 - internal/auth/oauth.go | 8 +- internal/builtin/bash.go | 6 +- internal/builtin/bash_test.go | 9 +- internal/builtin/fetch.go | 6 +- internal/builtin/fetch_test.go | 9 +- internal/builtin/http.go | 121 +- internal/builtin/http_test.go | 9 +- internal/builtin/registry.go | 30 +- internal/builtin/todo_test.go | 9 +- internal/config/environment_flow_test.go | 9 +- internal/config/merger.go | 4 +- internal/config/viper_test.go | 8 +- internal/hooks/executor.go | 6 +- internal/hooks/executor_test.go | 7 +- internal/models/anthropic/anthropic.go | 283 - internal/models/gemini/gemini.go | 791 - internal/models/generate_models.go | 226 - internal/models/models_data.go | 35035 --------------------- internal/models/openai/openai.go | 249 - internal/models/providers.go | 797 +- internal/models/registry.go | 220 +- internal/session/manager.go | 70 +- internal/session/session.go | 154 +- internal/tools/connection_pool.go | 19 +- internal/tools/fantasy_adapter.go | 92 + internal/tools/mcp.go | 244 +- internal/tools/mcp_test.go | 126 +- internal/ui/callbacks.go | 41 - internal/ui/cli.go | 35 +- internal/ui/commands.go | 8 +- internal/ui/compact_renderer.go | 23 +- internal/ui/debug_logger.go | 8 +- internal/ui/progress/ollama.go | 11 +- internal/ui/spinner.go | 196 +- internal/ui/styles.go | 156 +- sdk/mcphost.go | 17 +- sdk/mcphost_test.go | 2 +- sdk/types.go | 14 +- 47 files changed, 1524 insertions(+), 38880 deletions(-) create mode 100644 .golangci.yml delete mode 100644 internal/agent/streaming.go delete mode 100644 internal/models/anthropic/anthropic.go delete mode 100644 internal/models/gemini/gemini.go delete mode 100644 internal/models/generate_models.go delete mode 100644 internal/models/models_data.go delete mode 100644 internal/models/openai/openai.go create mode 100644 internal/tools/fantasy_adapter.go delete mode 100644 internal/ui/callbacks.go diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..ed6c7f2c --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,9 @@ +version: "2" + +linters: + enable: + - modernize + +formatters: + enable: + - gofmt diff --git a/btca.config.jsonc b/btca.config.jsonc index d60c1f1c..92efbf0b 100644 --- a/btca.config.jsonc +++ b/btca.config.jsonc @@ -23,9 +23,21 @@ "type": "git", "name": "glamour", "url": "https://github.com/charmbracelet/glamour", + "branch": "v2-exp" + }, + { + "type": "git", + "name": "fantasy", + "url": "https://github.com/charmbracelet/fantasy", + "branch": "main" + }, + { + "type": "git", + "name": "catwalk", + "url": "https://github.com/charmbracelet/catwalk", "branch": "main" } ], "model": "claude-haiku-4-5", "provider": "opencode" -} \ No newline at end of file +} diff --git a/cmd/root.go b/cmd/root.go index 75cc1f63..025cd1df 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/cloudwego/eino/schema" + "charm.land/fantasy" "github.com/mark3labs/mcphost/internal/agent" "github.com/mark3labs/mcphost/internal/config" "github.com/mark3labs/mcphost/internal/hooks" @@ -608,13 +608,12 @@ func runNormalMode(ctx context.Context) error { tools := mcpAgent.GetTools() var toolNames []string for _, tool := range tools { - if info, err := tool.Info(ctx); err == nil { - toolNames = append(toolNames, info.Name) - } + info := tool.Info() + toolNames = append(toolNames, info.Name) } // Main interaction logic - var messages []*schema.Message + var messages []fantasy.Message var sessionManager *session.Manager if sessionPath != "" { _, err := os.Stat(sessionPath) @@ -637,7 +636,8 @@ func runNormalMode(ctx context.Context) error { // Convert session messages to schema messages for _, msg := range loadedSession.Messages { - messages = append(messages, msg.ConvertToSchemaMessage()) + fantasyMsg := msg.ConvertToFantasyMessage() + messages = append(messages, fantasyMsg) } // If we're also saving, use the loaded session with the session manager @@ -658,9 +658,10 @@ func runNormalMode(ctx context.Context) error { // Display all previous messages as they would have appeared for _, sessionMsg := range loadedSession.Messages { - if sessionMsg.Role == "user" { + switch sessionMsg.Role { + case "user": cli.DisplayUserMessage(sessionMsg.Content) - } else if sessionMsg.Role == "assistant" { + case "assistant": // Display tool calls if present if len(sessionMsg.ToolCalls) > 0 { for _, tc := range sessionMsg.ToolCalls { @@ -679,7 +680,7 @@ func runNormalMode(ctx context.Context) error { if sessionMsg.Content != "" { cli.DisplayAssistantMessage(sessionMsg.Content) } - } else if sessionMsg.Role == "tool" { + case "tool": // Display tool result if sessionMsg.ToolCallID != "" { if toolCall, exists := toolCallMap[sessionMsg.ToolCallID]; exists { @@ -773,7 +774,7 @@ type AgenticLoopConfig struct { } // addMessagesToHistory adds messages to the conversation history and saves to session if available -func addMessagesToHistory(messages *[]*schema.Message, sessionManager *session.Manager, cli *ui.CLI, newMessages ...*schema.Message) { +func addMessagesToHistory(messages *[]fantasy.Message, sessionManager *session.Manager, cli *ui.CLI, newMessages ...fantasy.Message) { // Add to local history *messages = append(*messages, newMessages...) @@ -790,7 +791,7 @@ func addMessagesToHistory(messages *[]*schema.Message, sessionManager *session.M } // replaceMessagesHistory replaces the conversation history and saves to session if available -func replaceMessagesHistory(messages *[]*schema.Message, sessionManager *session.Manager, cli *ui.CLI, newMessages []*schema.Message) { +func replaceMessagesHistory(messages *[]fantasy.Message, sessionManager *session.Manager, cli *ui.CLI, newMessages []fantasy.Message) { // Replace local history *messages = newMessages @@ -807,7 +808,7 @@ func replaceMessagesHistory(messages *[]*schema.Message, sessionManager *session } // runAgenticLoop handles all execution modes with a single unified loop -func runAgenticLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, messages []*schema.Message, config AgenticLoopConfig, hookExecutor *hooks.Executor) error { +func runAgenticLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, messages []fantasy.Message, config AgenticLoopConfig, hookExecutor *hooks.Executor) error { // Handle initial prompt for non-interactive modes if !config.IsInteractive && config.InitialPrompt != "" { // Execute UserPromptSubmit hooks for non-interactive mode @@ -837,7 +838,7 @@ func runAgenticLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, mes } // Create temporary messages with user input for processing (don't add to history yet) - tempMessages := append(messages, schema.UserMessage(config.InitialPrompt)) + tempMessages := append(messages, fantasy.NewUserMessage(config.InitialPrompt)) // Process the initial prompt with tool calls _, conversationMessages, err := runAgenticStep(ctx, mcpAgent, cli, tempMessages, config, hookExecutor) @@ -875,7 +876,7 @@ func runAgenticLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, mes } // runAgenticStep processes a single step of the agentic loop (handles tool calls) -func runAgenticStep(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, messages []*schema.Message, config AgenticLoopConfig, hookExecutor *hooks.Executor) (*schema.Message, []*schema.Message, error) { +func runAgenticStep(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, messages []fantasy.Message, config AgenticLoopConfig, hookExecutor *hooks.Executor) (*fantasy.Response, []fantasy.Message, error) { var currentSpinner *ui.Spinner // Start initial spinner (skip if quiet) @@ -1153,13 +1154,22 @@ func runAgenticStep(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, mes if len(messages) > 0 { // Find the last user message for i := len(messages) - 1; i >= 0; i-- { - if messages[i].Role == schema.User { - lastUserMessage = messages[i].Content + if messages[i].Role == fantasy.MessageRoleUser { + // Extract text from message parts + for _, part := range messages[i].Content { + if tp, ok := part.(fantasy.TextPart); ok { + lastUserMessage = tp.Text + break + } + } break } } } + // Get text content from response + responseText := response.Content.Text() + // Update usage tracking for ALL responses (streaming and non-streaming) if !config.Quiet && cli != nil { cli.UpdateUsageFromResponse(response, lastUserMessage) @@ -1167,15 +1177,15 @@ func runAgenticStep(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, mes // Display assistant response with model name // Skip if: quiet mode, same content already displayed, or if streaming completed the full response - streamedFullResponse := responseWasStreamed && streamingContent.String() == response.Content - if !config.Quiet && cli != nil && response.Content != lastDisplayedContent && response.Content != "" && !streamedFullResponse { - if err := cli.DisplayAssistantMessageWithModel(response.Content, config.ModelName); err != nil { + streamedFullResponse := responseWasStreamed && streamingContent.String() == responseText + if !config.Quiet && cli != nil && responseText != lastDisplayedContent && responseText != "" && !streamedFullResponse { + if err := cli.DisplayAssistantMessageWithModel(responseText, config.ModelName); err != nil { cli.DisplayError(fmt.Errorf("display error: %v", err)) return nil, nil, err } } else if config.Quiet { // In quiet mode, only output the final response content to stdout - fmt.Print(response.Content) + fmt.Print(responseText) } // Display usage information immediately after the response (for both streaming and non-streaming) @@ -1191,15 +1201,14 @@ func runAgenticStep(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, mes } // executeStopHook executes the Stop hook if a hook executor is available -func executeStopHook(hookExecutor *hooks.Executor, response *schema.Message, stopReason string, modelName string) { +func executeStopHook(hookExecutor *hooks.Executor, response *fantasy.Response, stopReason string, modelName string) { if hookExecutor != nil { // Prepare metadata var meta json.RawMessage if response != nil { - metaData := map[string]interface{}{ + metaData := map[string]any{ "model": modelName, - "role": string(response.Role), - "has_tool_calls": len(response.ToolCalls) > 0, + "has_tool_calls": len(response.Content.ToolCalls()) > 0, } if metaBytes, err := json.Marshal(metaData); err == nil { meta = json.RawMessage(metaBytes) @@ -1208,7 +1217,7 @@ func executeStopHook(hookExecutor *hooks.Executor, response *schema.Message, sto responseContent := "" if response != nil { - responseContent = response.Content + responseContent = response.Content.Text() } input := &hooks.StopInput{ @@ -1225,7 +1234,7 @@ func executeStopHook(hookExecutor *hooks.Executor, response *schema.Message, sto } // runInteractiveLoop handles the interactive portion of the agentic loop -func runInteractiveLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, messages []*schema.Message, config AgenticLoopConfig, hookExecutor *hooks.Executor) error { +func runInteractiveLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, messages []fantasy.Message, config AgenticLoopConfig, hookExecutor *hooks.Executor) error { for { // Get user input prompt, err := cli.GetPrompt() @@ -1292,7 +1301,7 @@ func runInteractiveLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, cli.DisplayUserMessage(prompt) // Create temporary messages with user input for processing - tempMessages := append(messages, schema.UserMessage(prompt)) + tempMessages := append(messages, fantasy.NewUserMessage(prompt)) // Process the user input with tool calls _, conversationMessages, err := runAgenticStep(ctx, mcpAgent, cli, tempMessages, config, hookExecutor) if err != nil { @@ -1312,7 +1321,7 @@ func runInteractiveLoop(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, } // runNonInteractiveMode handles the non-interactive mode execution -func runNonInteractiveMode(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, prompt, modelName string, messages []*schema.Message, quiet, noExit bool, mcpConfig *config.Config, sessionManager *session.Manager, hookExecutor *hooks.Executor) error { +func runNonInteractiveMode(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, prompt, modelName string, messages []fantasy.Message, quiet, noExit bool, mcpConfig *config.Config, sessionManager *session.Manager, hookExecutor *hooks.Executor) error { // Prepare data for slash commands (needed if continuing to interactive mode) var serverNames []string for name := range mcpConfig.MCPServers { @@ -1322,9 +1331,8 @@ func runNonInteractiveMode(ctx context.Context, mcpAgent *agent.Agent, cli *ui.C tools := mcpAgent.GetTools() var toolNames []string for _, tool := range tools { - if info, err := tool.Info(ctx); err == nil { - toolNames = append(toolNames, info.Name) - } + info := tool.Info() + toolNames = append(toolNames, info.Name) } // Configure and run unified agentic loop @@ -1345,7 +1353,7 @@ func runNonInteractiveMode(ctx context.Context, mcpAgent *agent.Agent, cli *ui.C } // runInteractiveMode handles the interactive mode execution -func runInteractiveMode(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, serverNames, toolNames []string, modelName string, messages []*schema.Message, sessionManager *session.Manager, hookExecutor *hooks.Executor, approveToolRun bool) error { +func runInteractiveMode(ctx context.Context, mcpAgent *agent.Agent, cli *ui.CLI, serverNames, toolNames []string, modelName string, messages []fantasy.Message, sessionManager *session.Manager, hookExecutor *hooks.Executor, approveToolRun bool) error { // Configure and run unified agentic loop config := AgenticLoopConfig{ IsInteractive: true, diff --git a/cmd/script.go b/cmd/script.go index 67e34626..027eaffa 100644 --- a/cmd/script.go +++ b/cmd/script.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/cloudwego/eino/schema" + "charm.land/fantasy" "github.com/mark3labs/mcphost/internal/agent" "github.com/mark3labs/mcphost/internal/config" "github.com/mark3labs/mcphost/internal/hooks" @@ -177,8 +177,8 @@ func parseCustomVariables(_ *cobra.Command) map[string]string { } // Parse custom variables with --args: prefix - if strings.HasPrefix(arg, "--args:") { - varName := strings.TrimPrefix(arg, "--args:") + if after, ok := strings.CutPrefix(arg, "--args:"); ok { + varName := after if varName == "" { continue // Skip malformed --args: without name } @@ -312,7 +312,7 @@ func parseScriptContent(content string, variables map[string]string) (*config.Co var promptLines []string var inFrontmatter bool var foundFrontmatter bool - var frontmatterEnd int = -1 + var frontmatterEnd = -1 for i, line := range lines { trimmed := strings.TrimSpace(line) @@ -699,13 +699,12 @@ func runScriptMode(ctx context.Context, mcpConfig *config.Config, prompt string, tools := mcpAgent.GetTools() var toolNames []string for _, tool := range tools { - if info, err := tool.Info(ctx); err == nil { - toolNames = append(toolNames, info.Name) - } + info := tool.Info() + toolNames = append(toolNames, info.Name) } // Configure and run unified agentic loop - var messages []*schema.Message + var messages []fantasy.Message config := AgenticLoopConfig{ IsInteractive: prompt == "", // If no prompt, start in interactive mode InitialPrompt: prompt, diff --git a/cmd/script_integration_test.go b/cmd/script_integration_test.go index 9d479ade..14ca6601 100644 --- a/cmd/script_integration_test.go +++ b/cmd/script_integration_test.go @@ -82,7 +82,7 @@ Working directory is ${env://WORK_DIR:-/tmp}. t.Fatal("Filesystem server not found in script config") } - allowedDirs, ok := fsServer.Options["allowed_directories"].([]interface{}) + allowedDirs, ok := fsServer.Options["allowed_directories"].([]any) if !ok { t.Fatal("allowed_directories should be an array") } diff --git a/go.mod b/go.mod index 63d19451..c21655ec 100644 --- a/go.mod +++ b/go.mod @@ -1,150 +1,129 @@ module github.com/mark3labs/mcphost -go 1.24.2 - -toolchain go1.24.5 +go 1.26.0 require ( charm.land/bubbles/v2 v2.0.0 charm.land/bubbletea/v2 v2.0.0 + charm.land/catwalk v0.22.1 + charm.land/fantasy v0.10.0 charm.land/lipgloss/v2 v2.0.0 github.com/JohannesKaufmann/html-to-markdown v1.6.0 github.com/PuerkitoBio/goquery v1.10.3 - github.com/bytedance/sonic v1.15.0 github.com/charmbracelet/fang v0.4.4 - github.com/cloudwego/eino v0.7.13 - github.com/cloudwego/eino-ext/components/model/claude v0.1.12 - github.com/cloudwego/eino-ext/components/model/ollama v0.1.8 - github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250903035842-96774a3ec845 - github.com/eino-contrib/jsonschema v1.0.3 - github.com/getkin/kin-openapi v0.131.0 github.com/mark3labs/mcp-filesystem-server v0.11.1 github.com/mark3labs/mcp-go v0.44.0-beta.2 github.com/spf13/cobra v1.10.1 github.com/spf13/viper v1.20.1 github.com/tidwall/gjson v1.18.0 - golang.org/x/term v0.37.0 - google.golang.org/genai v1.22.0 + golang.org/x/term v0.40.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go v0.121.6 // indirect - cloud.google.com/go/auth v0.16.5 // indirect + cloud.google.com/go v0.123.0 // indirect + cloud.google.com/go/auth v0.18.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.8.0 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/alecthomas/chroma/v2 v2.20.0 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect - github.com/anthropics/anthropic-sdk-go v1.10.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect - github.com/aws/aws-sdk-go-v2 v1.38.3 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 // indirect - github.com/aws/aws-sdk-go-v2/config v1.31.6 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.10 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 // indirect - github.com/aws/smithy-go v1.23.0 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.1 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.9 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.9 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.10 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect + github.com/aws/smithy-go v1.24.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect - github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charmbracelet/anthropic-sdk-go v0.0.0-20260223140439-63879b0b8dab // indirect github.com/charmbracelet/colorprofile v0.4.2 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect + github.com/charmbracelet/x/etag v0.2.0 // indirect github.com/charmbracelet/x/exp/charmtone v0.0.0-20250902204034-1cdc10c66d5b // indirect github.com/charmbracelet/x/exp/color v0.0.0-20250902204034-1cdc10c66d5b // indirect - github.com/charmbracelet/x/exp/slice v0.0.0-20250902204034-1cdc10c66d5b // indirect + github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 // indirect + github.com/charmbracelet/x/json v0.2.0 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect - github.com/cloudwego/base64x v0.1.6 // indirect - github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250826113018-8c6f6358d4bb // indirect github.com/djherbis/times v1.6.0 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/eino-contrib/ollama v0.1.0 // indirect - github.com/evanphx/json-patch v0.5.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.10 // indirect + github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.0 // indirect - github.com/go-openapi/swag/jsonname v0.24.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect - github.com/googleapis/gax-go/v2 v2.15.0 // indirect - github.com/goph/emperror v0.17.2 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.12 // indirect + github.com/googleapis/gax-go/v2 v2.17.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/invopop/jsonschema v0.13.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/kaptinlin/go-i18n v0.2.11 // indirect + github.com/kaptinlin/jsonpointer v0.4.16 // indirect + github.com/kaptinlin/jsonschema v0.7.3 // indirect + github.com/kaptinlin/messageformat-go v0.4.18 // indirect github.com/mailru/easyjson v0.9.0 // indirect - github.com/meguminnnnnnnnn/go-openai v0.0.0-20250821095446-07791bea23a0 // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/muesli/mango v0.2.0 // indirect github.com/muesli/mango-cobra v1.2.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/roff v0.1.0 // indirect - github.com/nikolalohinski/gonja v1.5.3 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/openai/openai-go/v2 v2.7.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/sagikazarmark/locafero v0.10.0 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect - github.com/spf13/afero v1.14.0 // indirect + github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.9.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/yargevad/filepathx v1.0.0 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect github.com/yuin/goldmark v1.7.13 // indirect github.com/yuin/goldmark-emoji v1.0.6 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - golang.org/x/arch v0.23.0 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/time v0.12.0 // indirect - google.golang.org/api v0.246.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect - google.golang.org/grpc v1.75.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect + go.opentelemetry.io/otel v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.40.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect + golang.org/x/time v0.14.0 // indirect + google.golang.org/api v0.267.0 // indirect + google.golang.org/genai v1.47.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect + google.golang.org/grpc v1.79.1 // indirect + google.golang.org/protobuf v1.36.11 // indirect ) require ( @@ -160,8 +139,7 @@ require ( github.com/muesli/termenv v0.16.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/pflag v1.0.10 // indirect - golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/text v0.34.0 // indirect ) diff --git a/go.sum b/go.sum index caf57807..bb6150d0 100644 --- a/go.sum +++ b/go.sum @@ -2,16 +2,28 @@ charm.land/bubbles/v2 v2.0.0 h1:tE3eK/pHjmtrDiRdoC9uGNLgpopOd8fjhEe31B/ai5s= charm.land/bubbles/v2 v2.0.0/go.mod h1:rCHoleP2XhU8um45NTuOWBPNVHxnkXKTiZqcclL/qOI= charm.land/bubbletea/v2 v2.0.0 h1:p0d6CtWyJXJ9GfzMpUUqbP/XUUhhlk06+vCKWmox1wQ= charm.land/bubbletea/v2 v2.0.0/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= +charm.land/catwalk v0.22.1 h1:i7nxxYyEzgWqDD3ifAZ8SQR/cEaPbviiBbxq+ZGhk6M= +charm.land/catwalk v0.22.1/go.mod h1:rFC/V96rIHX7VES215c/qzI1EW/Moo1ggs1Q6seTy5s= +charm.land/fantasy v0.10.0 h1:6PD+1rrsCgLIG1n+PAZp/gHiC0dltU0cvb7c8zUKyu8= +charm.land/fantasy v0.10.0/go.mod h1:KIeNQUpJTswwpY0P6HJsr3LBFgfTDb8FDpOdVQMsKqY= charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo= charm.land/lipgloss/v2 v2.0.0/go.mod h1:w6SnmsBFBmEFBodiEDurGS/sdUY/u1+v72DqUzc6J14= -cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c= -cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI= -cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= -cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= +cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= -cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/JohannesKaufmann/html-to-markdown v1.6.0 h1:04VXMiE50YYfCfLboJCLcgqF5x+rHJnb1ssNmqpLH/k= github.com/JohannesKaufmann/html-to-markdown v1.6.0/go.mod h1:NUI78lGg/a7vpEJTz/0uOcYMaibytE4BUOQS8k78yPQ= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= @@ -19,7 +31,6 @@ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6 github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk= github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo= github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y= -github.com/airbrake/gobrake v3.6.1+incompatible/go.mod h1:wM4gu3Cn0W0K7GUuVWnlXZU11AGBXMILnrdOU8Kn00o= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= @@ -29,38 +40,38 @@ github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW5 github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= -github.com/anthropics/anthropic-sdk-go v1.10.0 h1:jDKQTfC0miIEj21eMmPrNSLKTNdNa3nHZOhd4wZz1cI= -github.com/anthropics/anthropic-sdk-go v1.10.0/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aws/aws-sdk-go-v2 v1.38.3 h1:B6cV4oxnMs45fql4yRH+/Po/YU+597zgWqvDpYMturk= -github.com/aws/aws-sdk-go-v2 v1.38.3/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 h1:i8p8P4diljCr60PpJp6qZXNlgX4m2yQFpYk+9ZT+J4E= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1/go.mod h1:ddqbooRZYNoJ2dsTwOty16rM+/Aqmk/GOXrK8cg7V00= -github.com/aws/aws-sdk-go-v2/config v1.31.6 h1:a1t8fXY4GT4xjyJExz4knbuoxSCacB5hT/WgtfPyLjo= -github.com/aws/aws-sdk-go-v2/config v1.31.6/go.mod h1:5ByscNi7R+ztvOGzeUaIu49vkMk2soq5NaH5PYe33MQ= -github.com/aws/aws-sdk-go-v2/credentials v1.18.10 h1:xdJnXCouCx8Y0NncgoptztUocIYLKeQxrCgN6x9sdhg= -github.com/aws/aws-sdk-go-v2/credentials v1.18.10/go.mod h1:7tQk08ntj914F/5i9jC4+2HQTAuJirq7m1vZVIhEkWs= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 h1:wbjnrrMnKew78/juW7I2BtKQwa1qlf6EjQgS69uYY14= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6/go.mod h1:AtiqqNrDioJXuUgz3+3T0mBWN7Hro2n9wll2zRUc0ww= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 h1:uF68eJA6+S9iVr9WgX1NaRGyQ/6MdIyc4JNUo6TN1FA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6/go.mod h1:qlPeVZCGPiobx8wb1ft0GHT5l+dc6ldnwInDFaMvC7Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 h1:pa1DEC6JoI0zduhZePp3zmhWvk/xxm4NB8Hy/Tlsgos= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6/go.mod h1:gxEjPebnhWGJoaDdtDkA0JX46VRg1wcTHYe63OfX5pE= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 h1:LHS1YAIJXJ4K9zS+1d/xa9JAA9sL2QyXIQCQFQW/X08= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6/go.mod h1:c9PCiTEuh0wQID5/KqA32J+HAgZxN9tOGXKCiYJjTZI= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 h1:8OLZnVJPvjnrxEwHFg9hVUof/P4sibH+Ea4KKuqAGSg= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.1/go.mod h1:27M3BpVi0C02UiQh1w9nsBEit6pLhlaH3NHna6WUbDE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 h1:gKWSTnqudpo8dAxqBqZnDoDWCiEh/40FziUjr/mo6uA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2/go.mod h1:x7+rkNmRoEN1U13A6JE2fXne9EWyJy54o3n6d4mGaXQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 h1:YZPjhyaGzhDQEvsffDEcpycq49nl7fiGcfJTIo8BszI= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.2/go.mod h1:2dIN8qhQfv37BdUYGgEC8Q3tteM3zFxTI1MLO2O3J3c= -github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= -github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU= +github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4= +github.com/aws/aws-sdk-go-v2/config v1.32.9 h1:ktda/mtAydeObvJXlHzyGpK1xcsLaP16zfUPDGoW90A= +github.com/aws/aws-sdk-go-v2/config v1.32.9/go.mod h1:U+fCQ+9QKsLW786BCfEjYRj34VVTbPdsLP3CHSYXMOI= +github.com/aws/aws-sdk-go-v2/credentials v1.19.9 h1:sWvTKsyrMlJGEuj/WgrwilpoJ6Xa1+KhIpGdzw7mMU8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.9/go.mod h1:+J44MBhmfVY/lETFiKI+klz0Vym2aCmIjqgClMmW82w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.10 h1:+VTRawC4iVY58pS/lzpo0lnoa/SYNGF4/B/3/U5ro8Y= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.10/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 h1:0jbJeuEHlwKJ9PfXtpSFc4MF+WIWORdhN1n30ITZGFM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ= +github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0= +github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.4.0 h1:TKnLPh7IbnizJIBKFWa9mKayRUBQ9Kh1BPCk6w2PnYM= @@ -69,21 +80,12 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= -github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= -github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8= -github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY= -github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= -github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= -github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= -github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= -github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charmbracelet/anthropic-sdk-go v0.0.0-20260223140439-63879b0b8dab h1:J7XQLgl9sefgTnTGrmX3xqvp5o6MCiBzEjGv5igAlc4= +github.com/charmbracelet/anthropic-sdk-go v0.0.0-20260223140439-63879b0b8dab/go.mod h1:hqlYqR7uPKOKfnNeicUbZp0Ps0GeYFlKYtwh5HGDCx8= github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= github.com/charmbracelet/fang v0.4.4 h1:G4qKxF6or/eTPgmAolwPuRNyuci3hTUGGX1rj1YkHJY= @@ -100,14 +102,18 @@ github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= +github.com/charmbracelet/x/etag v0.2.0 h1:Euj1VkheoHfTYA9y+TCwkeXF/hN8Fb9l4LqZl79pt04= +github.com/charmbracelet/x/etag v0.2.0/go.mod h1:C1B7/bsgvzzxpfu0Rabbd+rTHJa5TmC/qgTseCf6DF0= github.com/charmbracelet/x/exp/charmtone v0.0.0-20250902204034-1cdc10c66d5b h1:U9SnQTnrxy8y3gEpxhpBS3ztHAR7IvL0CjvFHOR4sbE= github.com/charmbracelet/x/exp/charmtone v0.0.0-20250902204034-1cdc10c66d5b/go.mod h1:T9jr8CzFpjhFVHjNjKwbAD7KwBNyFnj2pntAO7F2zw0= github.com/charmbracelet/x/exp/color v0.0.0-20250902204034-1cdc10c66d5b h1:x4wRlDV7e7qM6yYS06W6wMKh6z1NeD1+DTjvOm2grzo= github.com/charmbracelet/x/exp/color v0.0.0-20250902204034-1cdc10c66d5b/go.mod h1:hk/GyTELmEgX54pBAOHcFvH8Xed53JWo/g8kJXFo/PI= github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA= github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f/go.mod h1:IfZAMTHB6XkZSeXUqriemErjAWCCzT0LwjKFYCZyw0I= -github.com/charmbracelet/x/exp/slice v0.0.0-20250902204034-1cdc10c66d5b h1:DZ2Li1O0j+wWw6AgEUDrODB7PAIKpmOy65yu1UBPYc4= -github.com/charmbracelet/x/exp/slice v0.0.0-20250902204034-1cdc10c66d5b/go.mod h1:vI5nDVMWi6veaYH+0Fmvpbe/+cv/iJfMntdh+N0+Tms= +github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 h1:DTSZxdV9qQagD4iGcAt9RgaRBZtJl01bfKgdLzUzUPI= +github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5/go.mod h1:vI5nDVMWi6veaYH+0Fmvpbe/+cv/iJfMntdh+N0+Tms= +github.com/charmbracelet/x/json v0.2.0 h1:DqB+ZGx2h+Z+1s98HOuOyli+i97wsFQIxP2ZQANTPrQ= +github.com/charmbracelet/x/json v0.2.0/go.mod h1:opFIflx2YgXgi49xVUu8gEQ21teFAxyMwvOiZhIvWNM= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= @@ -118,105 +124,78 @@ github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSE github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= -github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= -github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= -github.com/cloudwego/eino v0.7.13 h1:Ku7hY+83gGJJjf4On3UgqjC57UcA+DXe0tqAZiNDDew= -github.com/cloudwego/eino v0.7.13/go.mod h1:nA8Vacmuqv3pqKBQbTWENBLQ8MmGmPt/WqiyLeB8ohQ= -github.com/cloudwego/eino-ext/components/model/claude v0.1.12 h1:c66gFH9J5Ku2/v1f7jPwI9R4CYw5TiAlIVzsfzjsF1g= -github.com/cloudwego/eino-ext/components/model/claude v0.1.12/go.mod h1:a9oQkf4Ib+/VqjsLRdRETytt2m/C4fbcvfjPNu6nVAg= -github.com/cloudwego/eino-ext/components/model/ollama v0.1.8 h1:+BStnQlkRxWMV9jsPopLmmut2ARG88e9hDSMaDNAI/w= -github.com/cloudwego/eino-ext/components/model/ollama v0.1.8/go.mod h1:C3rf3yy2nEoXFP/CQJne4gbiu1pREKplHKmFlhuOzPE= -github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250903035842-96774a3ec845 h1:nxflfiBwWNPoKS9X4SMhmT+si7rtYv+lQzIyPJik4DM= -github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250903035842-96774a3ec845/go.mod h1:QQhCuQxuBAVWvu/YAZBhs/RsR76mUigw59Tl0kh04C8= -github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250826113018-8c6f6358d4bb h1:RMslzyijc3bi9EkqCulpS0hZupTl1y/wayR3+fVRN/c= -github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250826113018-8c6f6358d4bb/go.mod h1:fHn/6OqPPY1iLLx9wzz+MEVT5Dl9gwuZte1oLEnCoYw= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eino-contrib/jsonschema v1.0.3 h1:2Kfsm1xlMV0ssY2nuxshS4AwbLFuqmPmzIjLVJ1Fsp0= -github.com/eino-contrib/jsonschema v1.0.3/go.mod h1:cpnX4SyKjWjGC7iN2EbhxaTdLqGjCi0e9DxpLYxddD4= -github.com/eino-contrib/ollama v0.1.0 h1:z1NaMdKW6X1ftP8g5xGGR5zDRPUtuTKFq35vBQgxsN4= -github.com/eino-contrib/ollama v0.1.0/go.mod h1:mYsQ7b3DeqY8bHPuD3MZJYTqkgyL6LoemxoP/B7ZNhA= -github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= +github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= +github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= -github.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE= -github.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU= +github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.0 h1:TmMhghgNef9YXxTu1tOopo+0BGEytxA+okbry0HjZsM= -github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= -github.com/go-openapi/swag/jsonname v0.24.0 h1:2wKS9bgRV/xB8c62Qg16w4AUiIrqqiniJFtZGi3dg5k= -github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= -github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= -github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= -github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18= -github.com/goph/emperror v0.17.2/go.mod h1:+ZbQ+fUNO/6FNiUo0ujtMjhgad9Xa6fQL9KhH4LNHic= -github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= -github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/googleapis/enterprise-certificate-proxy v0.3.12 h1:Fg+zsqzYEs1ZnvmcztTYxhgCBsx3eEhEwQ1W/lHq/sQ= +github.com/googleapis/enterprise-certificate-proxy v0.3.12/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kaptinlin/go-i18n v0.2.11 h1:OayNt8mWt8nDaqAOp09/C1VG9Y5u8LpQnnxbyGARDV4= +github.com/kaptinlin/go-i18n v0.2.11/go.mod h1:pVcu9qsW5pOIOoZFJXesRYmLos1vMQrby70JPAoWmJU= +github.com/kaptinlin/jsonpointer v0.4.16 h1:Ux4w4FY+uLv+K+TxaCJtM/TpPv+1+eS6gH4Z9/uhOuA= +github.com/kaptinlin/jsonpointer v0.4.16/go.mod h1:SsfsjqnHG5zuKo1DTBzk1VknaHlL4osHw+X9kZKukpU= +github.com/kaptinlin/jsonschema v0.7.3 h1:kyIydij76ORiSxmfy0xFYy0cOx8MwG6pyyaSoQshsK4= +github.com/kaptinlin/jsonschema v0.7.3/go.mod h1:Ys6zr+W6/1330FzZEouFrAYImK+AmYt5HQVTHQQXQo8= +github.com/kaptinlin/messageformat-go v0.4.18 h1:RBlHVWgZyoxTcUgGWBsl2AcyScq/urqbLZvzgryTmSI= +github.com/kaptinlin/messageformat-go v0.4.18/go.mod h1:ntI3154RnqJgr7GaC+vZBnIExl2V3sv9selvRNNEM24= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -224,6 +203,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= @@ -232,26 +213,13 @@ github.com/mark3labs/mcp-filesystem-server v0.11.1 h1:7uKIZRMaKWfgvtDj/uLAvo0+7M github.com/mark3labs/mcp-filesystem-server v0.11.1/go.mod h1:xDqJizVYWZ5a31Mt4xuYbVku2AR/kT56H3O0SbpANoQ= github.com/mark3labs/mcp-go v0.44.0-beta.2 h1:gfUT0m77E4odfgiHkqV/E+MQVaQ06rbutW7Ln0JRkBA= github.com/mark3labs/mcp-go v0.44.0-beta.2/go.mod h1:YnJfOL382MIWDx1kMY+2zsRHU/q78dBg9aFb8W6Thdw= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= -github.com/meguminnnnnnnnn/go-openai v0.0.0-20250821095446-07791bea23a0 h1:nIohpHs1ViKR0SVgW/cbBstHjmnqFZDM9RqgX9m9Xu8= -github.com/meguminnnnnnnnn/go-openai v0.0.0-20250821095446-07791bea23a0/go.mod h1:qs96ysDmxhE4BZoU45I43zcyfnaYxU3X+aRzLko/htY= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/mango v0.2.0 h1:iNNc0c5VLQ6fsMgAqGQofByNUBH2Q2nEbD6TaI+5yyQ= @@ -266,32 +234,24 @@ github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/nikolalohinski/gonja v1.5.3 h1:GsA+EEaZDZPGJ8JtpeGN78jidhOlxeJROpqMT9fTj9c= -github.com/nikolalohinski/gonja v1.5.3/go.mod h1:RmjwxNiXAEqcq1HeK5SSMmqFJvKOfTfXhkJv6YBtPa4= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openai/openai-go/v2 v2.7.1 h1:/tfvTJhfv7hTSL8mWwc5VL4WLLSDL5yn9VqVykdu9r8= +github.com/openai/openai-go/v2 v2.7.1/go.mod h1:jrJs23apqJKKbT+pqtFgNKpRju/KP9zpUTZhz3GElQE= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/rollbar/rollbar-go v1.0.2/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.10.0 h1:FM8Cv6j2KqIhM2ZK7HZjm4mpj9NBktLgowT1aN9q5Cc= github.com/sagikazarmark/locafero v0.10.0/go.mod h1:Ieo3EUsjifvQu4NZwV5sPd4dwvu0OCgEQV7vjc9yDjw= @@ -300,19 +260,10 @@ github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvK github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f h1:Z2cODYsUxQPofhpYRMQVwWz4yUVpHF+vPi+eUdruUYI= -github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f/go.mod h1:JqzWyvTuI2X4+9wOHmKSQCYxybB/8j6Ko43qVmXDuZg= -github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= -github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= -github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= -github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= -github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= -github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= @@ -323,18 +274,8 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -349,18 +290,10 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= -github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc= -github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -369,27 +302,22 @@ github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg= -golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= @@ -397,16 +325,15 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0= -golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -418,11 +345,10 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -432,14 +358,11 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -463,8 +386,8 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -474,10 +397,10 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -487,26 +410,22 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.246.0 h1:H0ODDs5PnMZVZAEtdLMn2Ul2eQi7QNjqM2DIFp8TlTM= -google.golang.org/api v0.246.0/go.mod h1:dMVhVcylamkirHdzEBAIQWUCgqY885ivNeZYd7VAVr8= -google.golang.org/genai v1.22.0 h1:5hrEhXXWJQZa3tdPocl4vQ/0w6myEAxdNns2Kmx0f4Y= -google.golang.org/genai v1.22.0/go.mod h1:QPj5NGJw+3wEOHg+PrsWwJKvG6UC84ex5FR7qAYsN/M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 h1:pmJpJEvT846VzausCQ5d7KreSROcDqmO388w5YbnltA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE= +google.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0= +google.golang.org/genai v1.47.0 h1:iWCS7gEdO6rctOqfCYLOrZGKu2D+N42aTnCEcBvB1jo= +google.golang.org/genai v1.47.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 14141906..d7c25cb1 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -8,102 +8,114 @@ import ( "time" tea "charm.land/bubbletea/v2" - "github.com/cloudwego/eino/components/model" - "github.com/cloudwego/eino/components/tool" - "github.com/cloudwego/eino/schema" - "github.com/mark3labs/mcp-go/mcp" + "charm.land/fantasy" + "github.com/mark3labs/mcphost/internal/config" "github.com/mark3labs/mcphost/internal/models" "github.com/mark3labs/mcphost/internal/tools" ) // AgentConfig holds configuration options for creating a new Agent. -// It includes model configuration, MCP settings, and various behavioral options. type AgentConfig struct { - // ModelConfig specifies the LLM provider and model to use - ModelConfig *models.ProviderConfig - // MCPConfig contains MCP server configurations - MCPConfig *config.Config - // SystemPrompt is the initial system message for the agent - SystemPrompt string - // MaxSteps limits the number of tool calls (0 for unlimited) - MaxSteps int - // StreamingEnabled controls whether responses are streamed + ModelConfig *models.ProviderConfig + MCPConfig *config.Config + SystemPrompt string + MaxSteps int StreamingEnabled bool - // DebugLogger is an optional logger for debugging MCP communications - DebugLogger tools.DebugLogger // Optional debug logger + DebugLogger tools.DebugLogger } // ToolCallHandler is a function type for handling tool calls as they happen. -// It receives the tool name and its arguments when a tool is about to be invoked. type ToolCallHandler func(toolName, toolArgs string) // ToolExecutionHandler is a function type for handling tool execution start/end events. -// The isStarting parameter indicates whether the tool is starting (true) or finished (false). type ToolExecutionHandler func(toolName string, isStarting bool) // ToolResultHandler is a function type for handling tool results. -// It receives the tool name, arguments, result, and whether the result is an error. type ToolResultHandler func(toolName, toolArgs, result string, isError bool) // ResponseHandler is a function type for handling LLM responses. -// It receives the complete response content from the model. type ResponseHandler func(content string) // StreamingResponseHandler is a function type for handling streaming LLM responses. -// It receives content chunks as they are streamed from the model. type StreamingResponseHandler func(content string) // ToolCallContentHandler is a function type for handling content that accompanies tool calls. -// It receives any text content that the model generates alongside tool calls. type ToolCallContentHandler func(content string) // ToolApprovalHandler is a function type for handling user approval of tool calls. -// It receives the tool name and arguments, and returns true if the user approves. type ToolApprovalHandler func(toolName, toolArgs string) (bool, error) -// Agent represents an AI agent with MCP tool integration and real-time tool call display. +// Agent represents an AI agent with MCP tool integration using the fantasy library. // It manages the interaction between an LLM and various tools through the MCP protocol. type Agent struct { toolManager *tools.MCPToolManager - model model.ToolCallingChatModel + fantasyAgent fantasy.Agent + model fantasy.LanguageModel maxSteps int systemPrompt string - loadingMessage string // Message from provider loading (e.g., GPU fallback info) - providerType string // Provider type for streaming behavior - streamingEnabled bool // Whether streaming is enabled + loadingMessage string + providerType string + streamingEnabled bool +} + +// GenerateWithLoopResult contains the result and conversation history from an agent interaction. +type GenerateWithLoopResult struct { + // FinalResponse is the last message generated by the model + FinalResponse *fantasy.Response + // ConversationMessages contains all messages in the conversation including tool calls and results + ConversationMessages []fantasy.Message + // TotalUsage contains aggregate token usage across all steps + TotalUsage fantasy.Usage } // NewAgent creates a new Agent with MCP tool integration and streaming support. -// It initializes the LLM provider, loads MCP tools, and configures the agent -// based on the provided configuration. Returns an error if provider creation -// or tool loading fails. -func NewAgent(ctx context.Context, config *AgentConfig) (*Agent, error) { - // Create the LLM provider - providerResult, err := models.CreateProvider(ctx, config.ModelConfig) +func NewAgent(ctx context.Context, agentConfig *AgentConfig) (*Agent, error) { + // Create the LLM provider via fantasy + providerResult, err := models.CreateProvider(ctx, agentConfig.ModelConfig) if err != nil { return nil, fmt.Errorf("failed to create model provider: %v", err) } // Create and load MCP tools toolManager := tools.NewMCPToolManager() - - // Set the model for sampling support toolManager.SetModel(providerResult.Model) - // Set the debug logger if provided - if config.DebugLogger != nil { - toolManager.SetDebugLogger(config.DebugLogger) + if agentConfig.DebugLogger != nil { + toolManager.SetDebugLogger(agentConfig.DebugLogger) } - if err := toolManager.LoadTools(ctx, config.MCPConfig); err != nil { + if err := toolManager.LoadTools(ctx, agentConfig.MCPConfig); err != nil { return nil, fmt.Errorf("failed to load MCP tools: %v", err) } + // Build fantasy agent options + var agentOpts []fantasy.AgentOption + + if agentConfig.SystemPrompt != "" { + agentOpts = append(agentOpts, fantasy.WithSystemPrompt(agentConfig.SystemPrompt)) + } + + // Register all MCP tools with the fantasy agent + mcpTools := toolManager.GetTools() + if len(mcpTools) > 0 { + agentOpts = append(agentOpts, fantasy.WithTools(mcpTools...)) + } + + // Set max steps as stop condition + if agentConfig.MaxSteps > 0 { + agentOpts = append(agentOpts, fantasy.WithStopConditions( + fantasy.StepCountIs(agentConfig.MaxSteps), + )) + } + + // Create the fantasy agent + fantasyAgent := fantasy.NewAgent(providerResult.Model, agentOpts...) + // Determine provider type from model string providerType := "default" - if config.ModelConfig != nil && config.ModelConfig.ModelString != "" { - parts := strings.SplitN(config.ModelConfig.ModelString, ":", 2) + if agentConfig.ModelConfig != nil && agentConfig.ModelConfig.ModelString != "" { + parts := strings.SplitN(agentConfig.ModelConfig.ModelString, ":", 2) if len(parts) >= 1 { providerType = parts[0] } @@ -111,345 +123,239 @@ func NewAgent(ctx context.Context, config *AgentConfig) (*Agent, error) { return &Agent{ toolManager: toolManager, + fantasyAgent: fantasyAgent, model: providerResult.Model, - maxSteps: config.MaxSteps, // Keep 0 for infinite, handle in loop - systemPrompt: config.SystemPrompt, + maxSteps: agentConfig.MaxSteps, + systemPrompt: agentConfig.SystemPrompt, loadingMessage: providerResult.Message, providerType: providerType, - streamingEnabled: config.StreamingEnabled, + streamingEnabled: agentConfig.StreamingEnabled, }, nil } -// GenerateWithLoopResult contains the result and conversation history from an agent interaction. -// It includes both the final response and the complete message history with tool interactions. -type GenerateWithLoopResult struct { - // FinalResponse is the last message generated by the model - FinalResponse *schema.Message - // ConversationMessages contains all messages in the conversation including tool calls and results - ConversationMessages []*schema.Message // All messages in the conversation (including tool calls and results) -} - // GenerateWithLoop processes messages with a custom loop that displays tool calls in real-time. -// It handles the conversation flow, executing tools as needed and invoking callbacks for various events. -// This method does not support streaming responses; use GenerateWithLoopAndStreaming for streaming support. -func (a *Agent) GenerateWithLoop(ctx context.Context, messages []*schema.Message, - onToolCall ToolCallHandler, onToolExecution ToolExecutionHandler, onToolResult ToolResultHandler, onResponse ResponseHandler, onToolCallContent ToolCallContentHandler, onToolApproval ToolApprovalHandler, +func (a *Agent) GenerateWithLoop(ctx context.Context, messages []fantasy.Message, + onToolCall ToolCallHandler, onToolExecution ToolExecutionHandler, onToolResult ToolResultHandler, + onResponse ResponseHandler, onToolCallContent ToolCallContentHandler, onToolApproval ToolApprovalHandler, ) (*GenerateWithLoopResult, error) { - return a.GenerateWithLoopAndStreaming(ctx, messages, onToolCall, onToolExecution, onToolResult, onResponse, onToolCallContent, nil, onToolApproval) + return a.GenerateWithLoopAndStreaming(ctx, messages, onToolCall, onToolExecution, onToolResult, + onResponse, onToolCallContent, nil, onToolApproval) } -// GenerateWithLoopAndStreaming processes messages with a custom loop that displays tool calls in real-time and supports streaming callbacks. -// It handles the conversation flow, executing tools as needed and invoking callbacks for various events including streaming chunks. -// The onStreamingResponse callback is invoked for each content chunk during streaming if streaming is enabled. -func (a *Agent) GenerateWithLoopAndStreaming(ctx context.Context, messages []*schema.Message, - onToolCall ToolCallHandler, onToolExecution ToolExecutionHandler, onToolResult ToolResultHandler, onResponse ResponseHandler, onToolCallContent ToolCallContentHandler, onStreamingResponse StreamingResponseHandler, onToolApproval ToolApprovalHandler, +// GenerateWithLoopAndStreaming processes messages using the fantasy agent with streaming and callbacks. +// Fantasy handles the tool call loop internally. We map fantasy's rich callback system +// to mcphost's existing callback interface for UI integration. +func (a *Agent) GenerateWithLoopAndStreaming(ctx context.Context, messages []fantasy.Message, + onToolCall ToolCallHandler, onToolExecution ToolExecutionHandler, onToolResult ToolResultHandler, + onResponse ResponseHandler, onToolCallContent ToolCallContentHandler, + onStreamingResponse StreamingResponseHandler, onToolApproval ToolApprovalHandler, ) (*GenerateWithLoopResult, error) { - // Create a copy of messages to avoid modifying the original - workingMessages := make([]*schema.Message, len(messages)) - copy(workingMessages, messages) - // Add system prompt if provided - if a.systemPrompt != "" { - hasSystemMessage := false - if len(workingMessages) > 0 && workingMessages[0].Role == schema.System { - hasSystemMessage = true - } + // Fantasy requires the current user input as Prompt, with prior messages as history. + // Extract the last user message text as the prompt, and pass everything before it as Messages. + prompt, history := splitPromptAndHistory(messages) - if !hasSystemMessage { - systemMsg := schema.SystemMessage(a.systemPrompt) - workingMessages = append([]*schema.Message{systemMsg}, workingMessages...) - } - } + // Track current tool call info for callbacks + var currentToolName string + var currentToolArgs string - // Get available tools - availableTools := a.toolManager.GetTools() - var toolInfos []*schema.ToolInfo - toolMap := make(map[string]tool.BaseTool) + if a.streamingEnabled { + // Use fantasy's streaming agent + result, err := a.fantasyAgent.Stream(ctx, fantasy.AgentStreamCall{ + Prompt: prompt, + Messages: history, - for _, t := range availableTools { - info, err := t.Info(ctx) - if err != nil { - continue - } - if info == nil { - continue - } - toolInfos = append(toolInfos, info) - toolMap[info.Name] = t - } + // Text streaming callback + OnTextDelta: func(id, text string) error { + if onStreamingResponse != nil { + onStreamingResponse(text) + } + return nil + }, - // Main loop - for step := 0; a.maxSteps == 0 || step < a.maxSteps; step++ { - // Check if context was cancelled before making LLM call - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - } + // Tool call complete - the tool has been parsed and is about to execute + OnToolCall: func(tc fantasy.ToolCallContent) error { + currentToolName = tc.ToolName + currentToolArgs = tc.Input - // Call the LLM with cancellation support - response, err := a.generateWithCancellationAndStreaming(ctx, workingMessages, toolInfos, onStreamingResponse) + // Check approval if handler is set + if onToolApproval != nil { + approved, err := onToolApproval(tc.ToolName, tc.Input) + if err != nil { + return err + } + if !approved { + return fmt.Errorf("tool call %s rejected by user", tc.ToolName) + } + } + + // Notify about the tool call + if onToolCall != nil { + onToolCall(tc.ToolName, tc.Input) + } + + // Notify tool execution starting + if onToolExecution != nil { + onToolExecution(tc.ToolName, true) + } + + return nil + }, + + // Tool result - tool execution completed + OnToolResult: func(tr fantasy.ToolResultContent) error { + // Notify tool execution finished + if onToolExecution != nil { + onToolExecution(tr.ToolName, false) + } + + if onToolResult != nil { + // Extract result text and error status + resultText, isError := extractToolResultText(tr) + onToolResult(tr.ToolName, currentToolArgs, resultText, isError) + } + + return nil + }, + + // Step callbacks for content that accompanies tool calls + OnStepFinish: func(step fantasy.StepResult) error { + // Check if step has text content alongside tool calls + text := step.Content.Text() + toolCalls := step.Content.ToolCalls() + if text != "" && len(toolCalls) > 0 && onToolCallContent != nil { + onToolCallContent(text) + } + return nil + }, + }) if err != nil { return nil, err } - // Add response to working messages - workingMessages = append(workingMessages, response) + return convertAgentResult(result, messages), nil + } - // Check if this is a tool call or final response - if len(response.ToolCalls) > 0 { - // Display any content that accompanies the tool calls - if response.Content != "" && onToolCallContent != nil { - onToolCallContent(response.Content) - } + // Non-streaming path + result, err := a.fantasyAgent.Generate(ctx, fantasy.AgentCall{ + Prompt: prompt, + Messages: history, + }) + if err != nil { + return nil, err + } - // Handle tool calls - for _, toolCall := range response.ToolCalls { - if onToolApproval != nil { - approved, err := onToolApproval(toolCall.Function.Name, toolCall.Function.Arguments) - if err != nil { - return nil, err - } - if !approved { - rejectedMsg := fmt.Sprintf("The user did not allow tool call %s. Reason: User cancelled.", toolCall.Function.Name) - toolMessage := schema.ToolMessage(rejectedMsg, toolCall.ID) - workingMessages = append(workingMessages, toolMessage) - continue - } - } + // For non-streaming, fire the response callback with the final text + if onResponse != nil && result.Response.Content.Text() != "" { + onResponse(result.Response.Content.Text()) + } - // Notify about tool call - if onToolCall != nil { - onToolCall(toolCall.Function.Name, toolCall.Function.Arguments) - } + _ = currentToolName // satisfy compiler for non-streaming path - // Execute the tool - if selectedTool, exists := toolMap[toolCall.Function.Name]; exists { - // Notify tool execution start - if onToolExecution != nil { - onToolExecution(toolCall.Function.Name, true) - } + return convertAgentResult(result, messages), nil +} - // Sanitize arguments for common LLM junk like "}{" - arguments := toolCall.Function.Arguments - if len(arguments) > 0 && strings.Trim(arguments, " \t\n\r{}") == "" { - arguments = "{}" - } +// splitPromptAndHistory extracts the last user message as the prompt string, +// and returns everything before it as conversation history. Fantasy's agent +// requires the current turn's input as Prompt (string), with prior messages +// passed separately as Messages (history). +func splitPromptAndHistory(messages []fantasy.Message) (string, []fantasy.Message) { + if len(messages) == 0 { + return "", nil + } - output, err := selectedTool.(tool.InvokableTool).InvokableRun(ctx, arguments) - - // Notify tool execution end - if onToolExecution != nil { - onToolExecution(toolCall.Function.Name, false) - } - - if err != nil { - errorMsg := fmt.Sprintf("Tool execution error: %v", err) - toolMessage := schema.ToolMessage(errorMsg, toolCall.ID) - workingMessages = append(workingMessages, toolMessage) - - if onToolResult != nil { - onToolResult(toolCall.Function.Name, toolCall.Function.Arguments, errorMsg, true) - } - } else { - // Check if this is an MCP tool response with an error - isError := false - if output != "" { - var mcpResult mcp.CallToolResult - if err := json.Unmarshal([]byte(output), &mcpResult); err == nil && mcpResult.IsError { - isError = true - } - } - - toolMessage := schema.ToolMessage(output, toolCall.ID) - workingMessages = append(workingMessages, toolMessage) - - if onToolResult != nil { - onToolResult(toolCall.Function.Name, toolCall.Function.Arguments, output, isError) - } - } - } else { - errorMsg := fmt.Sprintf("Tool not found: %s", toolCall.Function.Name) - toolMessage := schema.ToolMessage(errorMsg, toolCall.ID) - workingMessages = append(workingMessages, toolMessage) - - if onToolResult != nil { - onToolResult(toolCall.Function.Name, toolCall.Function.Arguments, errorMsg, true) - } + // Walk backwards to find the last user message + for i := len(messages) - 1; i >= 0; i-- { + if messages[i].Role == fantasy.MessageRoleUser { + // Extract text from the user message parts + var prompt string + for _, part := range messages[i].Content { + if tp, ok := part.(fantasy.TextPart); ok { + prompt = tp.Text + break } } - } else { - // This is a final response - if onResponse != nil && response.Content != "" { - onResponse(response.Content) - } - return &GenerateWithLoopResult{ - FinalResponse: response, - ConversationMessages: workingMessages, - }, nil + // History is everything except this last user message + history := make([]fantasy.Message, 0, len(messages)-1) + history = append(history, messages[:i]...) + history = append(history, messages[i+1:]...) + return prompt, history } } - // If we reach here, we've exceeded max steps - finalResponse := schema.AssistantMessage("Maximum number of steps reached.", nil) + // No user message found — use the last message's text as prompt + last := messages[len(messages)-1] + for _, part := range last.Content { + if tp, ok := part.(fantasy.TextPart); ok { + return tp.Text, messages[:len(messages)-1] + } + } + + return "", messages +} + +// convertAgentResult converts a fantasy AgentResult to our GenerateWithLoopResult. +func convertAgentResult(result *fantasy.AgentResult, originalMessages []fantasy.Message) *GenerateWithLoopResult { + // Collect all conversation messages: original + all step messages + var allMessages []fantasy.Message + allMessages = append(allMessages, originalMessages...) + + for _, step := range result.Steps { + allMessages = append(allMessages, step.Messages...) + } + return &GenerateWithLoopResult{ - FinalResponse: finalResponse, - ConversationMessages: workingMessages, - }, nil + FinalResponse: &result.Response, + ConversationMessages: allMessages, + TotalUsage: result.TotalUsage, + } +} + +// extractToolResultText extracts the text and error status from a fantasy ToolResultContent. +func extractToolResultText(tr fantasy.ToolResultContent) (string, bool) { + if tr.Result == nil { + return "", false + } + + // Marshal the result to JSON for display + resultBytes, err := json.Marshal(tr.Result) + if err != nil { + return fmt.Sprintf("%v", tr.Result), false + } + + resultText := string(resultBytes) + + // Check if this is an error result by examining the type + if errResult, ok := tr.Result.(fantasy.ToolResultOutputContentError); ok { + return errResult.Error.Error(), true + } + + return resultText, false } // GetTools returns the list of available tools loaded in the agent. -// These tools are available for the model to use during interactions. -func (a *Agent) GetTools() []tool.BaseTool { +func (a *Agent) GetTools() []fantasy.AgentTool { return a.toolManager.GetTools() } // GetLoadingMessage returns the loading message from provider creation. -// This may contain information about GPU fallback or other provider-specific initialization details. func (a *Agent) GetLoadingMessage() string { return a.loadingMessage } // GetLoadedServerNames returns the names of successfully loaded MCP servers. -// This includes both builtin servers and external MCP server configurations. func (a *Agent) GetLoadedServerNames() []string { return a.toolManager.GetLoadedServerNames() } -// generateWithCancellationAndStreaming calls the LLM with ESC key cancellation support and streaming callbacks -func (a *Agent) generateWithCancellationAndStreaming(ctx context.Context, messages []*schema.Message, toolInfos []*schema.ToolInfo, streamingCallback StreamingResponseHandler) (*schema.Message, error) { - // Check if streaming is enabled - if !a.streamingEnabled { - // Use traditional non-streaming approach - return a.generateWithoutStreaming(ctx, messages, toolInfos) - } - - // Try streaming first if no tools are expected or if we can detect tool calls early - if len(toolInfos) == 0 { - // No tools available, use streaming directly - return a.generateWithStreamingAndCallback(ctx, messages, toolInfos, streamingCallback) - } - - // Try streaming with tool call detection - return a.generateWithStreamingFirstAndCallback(ctx, messages, toolInfos, streamingCallback) +// GetModel returns the underlying fantasy LanguageModel. +func (a *Agent) GetModel() fantasy.LanguageModel { + return a.model } -// generateWithStreamingAndCallback uses streaming for responses without tool calls with real-time callbacks -func (a *Agent) generateWithStreamingAndCallback(ctx context.Context, messages []*schema.Message, toolInfos []*schema.ToolInfo, callback StreamingResponseHandler) (*schema.Message, error) { - // Try streaming first - reader, err := a.model.Stream(ctx, messages, model.WithTools(toolInfos)) - if err != nil { - // Fallback to non-streaming if streaming fails - return a.model.Generate(ctx, messages, model.WithTools(toolInfos)) - } - - // Use streaming with callback for real-time display - response, err := StreamWithCallback(ctx, reader, func(chunk string) { - if callback != nil { - callback(chunk) - } - }) - if err != nil { - // Fallback to non-streaming on error - return a.model.Generate(ctx, messages, model.WithTools(toolInfos)) - } - - // Return the complete streamed response (with tool calls if any) - return response, nil -} - -// generateWithStreamingFirstAndCallback attempts streaming first with provider-aware tool call detection and callbacks -func (a *Agent) generateWithStreamingFirstAndCallback(ctx context.Context, messages []*schema.Message, toolInfos []*schema.ToolInfo, callback StreamingResponseHandler) (*schema.Message, error) { - // Try streaming first - reader, err := a.model.Stream(ctx, messages, model.WithTools(toolInfos)) - if err != nil { - // Fallback to non-streaming if streaming fails - return a.model.Generate(ctx, messages, model.WithTools(toolInfos)) - } - - // Use streaming with callback for real-time display - response, err := StreamWithCallback(ctx, reader, func(chunk string) { - if callback != nil { - callback(chunk) - } - }) - if err != nil { - // Fallback to non-streaming on error - return a.model.Generate(ctx, messages, model.WithTools(toolInfos)) - } - - // Return the complete streamed response (with tool calls if any) - // No need to restart - we have everything we need! - return response, nil -} - -// generateWithoutStreaming uses the traditional non-streaming approach -func (a *Agent) generateWithoutStreaming(ctx context.Context, messages []*schema.Message, toolInfos []*schema.ToolInfo) (*schema.Message, error) { - // Create a cancellable context for just this LLM call - llmCtx, cancel := context.WithCancel(ctx) - defer cancel() - - // Channel to receive the LLM result - resultChan := make(chan struct { - message *schema.Message - err error - }, 1) - - // Start ESC key listener first and wait for it to be ready - escChan := make(chan bool, 1) - stopListening := make(chan bool, 1) - escReady := make(chan bool, 1) - - go func() { - if a.listenForESC(stopListening, escReady) { - escChan <- true - } else { - escChan <- false - } - }() - - // Wait for ESC listener to be ready before starting LLM - select { - case <-escReady: - // ESC listener is ready, proceed - case <-time.After(100 * time.Millisecond): - // Timeout waiting for ESC listener, proceed anyway - case <-ctx.Done(): - close(stopListening) - return nil, ctx.Err() - } - - // Now start the LLM generation - go func() { - message, err := a.model.Generate(llmCtx, messages, model.WithTools(toolInfos)) - if err != nil { - err = fmt.Errorf("failed to generate response: %v", err) - } - resultChan <- struct { - message *schema.Message - err error - }{message, err} - }() - - // Wait for either LLM completion or ESC key - select { - case result := <-resultChan: - // Stop the ESC listener - close(stopListening) - return result.message, result.err - case escPressed := <-escChan: - if escPressed { - cancel() // Cancel the LLM context - return nil, fmt.Errorf("generation cancelled by user") - } - // ESC listener stopped normally, wait for LLM result - result := <-resultChan - return result.message, result.err - case <-ctx.Done(): - // Stop the ESC listener - close(stopListening) - return nil, ctx.Err() - } +// Close closes the agent and cleans up resources. +func (a *Agent) Close() error { + return a.toolManager.Close() } // escListenerModel is a simple Bubble Tea model for ESC key detection @@ -462,10 +368,8 @@ func (m escListenerModel) Init() tea.Cmd { } func (m escListenerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyPressMsg: + if msg, ok := msg.(tea.KeyPressMsg); ok { if msg.String() == "esc" { - // Signal ESC was pressed select { case m.escPressed <- true: default: @@ -477,7 +381,7 @@ func (m escListenerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } func (m escListenerModel) View() tea.View { - return tea.NewView("") // No visual output needed + return tea.NewView("") } // listenForESC listens for ESC key press using Bubble Tea and returns true if detected @@ -488,13 +392,10 @@ func (a *Agent) listenForESC(stopChan chan bool, readyChan chan bool) bool { escPressed: escPressed, } - // Create a Bubble Tea program p := tea.NewProgram(model, tea.WithoutRenderer()) - // Start the program in a goroutine go func() { if _, err := p.Run(); err != nil { - // Program failed, try to signal completion select { case escPressed <- false: default: @@ -502,7 +403,6 @@ func (a *Agent) listenForESC(stopChan chan bool, readyChan chan bool) bool { } }() - // Give the program a moment to initialize, then signal ready go func() { time.Sleep(10 * time.Millisecond) select { @@ -511,28 +411,18 @@ func (a *Agent) listenForESC(stopChan chan bool, readyChan chan bool) bool { } }() - // Wait for either ESC key or stop signal select { case <-stopChan: p.Kill() - // Give the program time to fully terminate time.Sleep(50 * time.Millisecond) return false case pressed := <-escPressed: p.Kill() - // Give the program time to fully terminate time.Sleep(50 * time.Millisecond) return pressed case <-time.After(30 * time.Second): - // Timeout after 30 seconds to prevent hanging p.Kill() time.Sleep(50 * time.Millisecond) return false } } - -// Close closes the agent and cleans up resources. -// It ensures all MCP connections are properly closed and resources are released. -func (a *Agent) Close() error { - return a.toolManager.Close() -} diff --git a/internal/agent/streaming.go b/internal/agent/streaming.go deleted file mode 100644 index ce6bb1de..00000000 --- a/internal/agent/streaming.go +++ /dev/null @@ -1,147 +0,0 @@ -package agent - -import ( - "context" - "io" - "strings" - - "github.com/cloudwego/eino/schema" -) - -// StreamWithCallback streams content with real-time callbacks and returns the complete response. -// It accumulates content and tool calls from the stream, invoking the callback for each content chunk. -// IMPORTANT: Tool calls are only processed after EOF is reached to ensure we have the complete -// and final tool call information. This prevents premature tool execution on partial data. -// Handles different provider streaming patterns: -// - Anthropic: Text content first, then tool calls streamed incrementally -// - OpenAI/Others: Tool calls first or alone -// - Mixed: Tool calls and content interleaved -func StreamWithCallback(ctx context.Context, reader *schema.StreamReader[*schema.Message], callback func(string)) (*schema.Message, error) { - defer reader.Close() - - var content strings.Builder - var accumulatedToolCalls map[string]*schema.ToolCall // Track tool calls by ID to handle incremental updates - var streamComplete bool - var finalResponseMeta *schema.ResponseMeta // Accumulate response metadata from all chunks - - accumulatedToolCalls = make(map[string]*schema.ToolCall) - - for { - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - } - - msg, err := reader.Recv() - if err == io.EOF { - // Stream is complete - now we can safely process tool calls - streamComplete = true - break - } - if err != nil { - return nil, err - } - - // Call callback for each chunk if provided (for real-time display) - if callback != nil && msg.Content != "" { - callback(msg.Content) - } - - // Accumulate content from all chunks - content.WriteString(msg.Content) - - // Accumulate response metadata - merge from multiple chunks for accuracy - if msg.ResponseMeta != nil { - if finalResponseMeta == nil { - // First metadata we've seen - use as base - finalResponseMeta = &schema.ResponseMeta{} - if msg.ResponseMeta.Usage != nil { - finalResponseMeta.Usage = &schema.TokenUsage{} - } - } - - // Merge metadata intelligently to handle Anthropic's streaming behavior - if msg.ResponseMeta.Usage != nil && finalResponseMeta.Usage != nil { - usage := msg.ResponseMeta.Usage - - // Take PromptTokens from first chunk that has them (usually non-zero) - if finalResponseMeta.Usage.PromptTokens == 0 && usage.PromptTokens > 0 { - finalResponseMeta.Usage.PromptTokens = usage.PromptTokens - } - - // Always take the latest CompletionTokens (accumulates over chunks) - if usage.CompletionTokens > 0 { - finalResponseMeta.Usage.CompletionTokens = usage.CompletionTokens - } - - // Calculate TotalTokens from the components - finalResponseMeta.Usage.TotalTokens = finalResponseMeta.Usage.PromptTokens + finalResponseMeta.Usage.CompletionTokens - } - - // Preserve other metadata fields from the latest chunk - if msg.ResponseMeta.FinishReason != "" { - finalResponseMeta.FinishReason = msg.ResponseMeta.FinishReason - } - } - - // Accumulate tool calls incrementally - Anthropic streams them piece by piece - // NOTE: We don't process these tool calls until EOF is reached - if len(msg.ToolCalls) > 0 { - for _, toolCall := range msg.ToolCalls { - // Use tool call ID as key, but handle cases where ID might be empty in partial chunks - key := toolCall.ID - if key == "" { - // For chunks without ID, try to find existing tool call or create a temporary key - if len(accumulatedToolCalls) == 1 { - // If we have exactly one tool call being built, assume this chunk belongs to it - for existingKey := range accumulatedToolCalls { - key = existingKey - break - } - } else { - // Create a temporary key for this tool call - key = "temp_" + toolCall.Function.Name - } - } - - existing := accumulatedToolCalls[key] - if existing == nil { - // First time seeing this tool call - accumulatedToolCalls[key] = &schema.ToolCall{ - ID: toolCall.ID, - Function: toolCall.Function, - } - } else { - // Update existing tool call with new information - // Preserve non-empty values, accumulate arguments - if toolCall.ID != "" { - existing.ID = toolCall.ID - } - if toolCall.Function.Name != "" { - existing.Function.Name = toolCall.Function.Name - } - // Accumulate arguments (they come in pieces) - existing.Function.Arguments += toolCall.Function.Arguments - } - } - } - } - - // Only process tool calls after EOF - ensures we have complete information - var finalToolCalls []schema.ToolCall - if streamComplete && len(accumulatedToolCalls) > 0 { - finalToolCalls = make([]schema.ToolCall, 0, len(accumulatedToolCalls)) - for _, toolCall := range accumulatedToolCalls { - finalToolCalls = append(finalToolCalls, *toolCall) - } - } - - // Return complete message with all content, final tool calls, and preserved metadata - return &schema.Message{ - Role: schema.Assistant, - Content: content.String(), - ToolCalls: finalToolCalls, - ResponseMeta: finalResponseMeta, // Preserve usage and other metadata from streaming - }, nil -} diff --git a/internal/auth/oauth.go b/internal/auth/oauth.go index 7d528992..dee69721 100644 --- a/internal/auth/oauth.go +++ b/internal/auth/oauth.go @@ -109,7 +109,7 @@ func (c *OAuthClient) ExchangeCode(code, verifier string) (*AnthropicCredentials parsedCode, parsedState := c.parseCodeAndState(code) // Build request body - reqBody := map[string]interface{}{ + reqBody := map[string]any{ "code": parsedCode, "grant_type": "authorization_code", "client_id": c.ClientID, @@ -131,7 +131,7 @@ func (c *OAuthClient) ExchangeCode(code, verifier string) (*AnthropicCredentials // rotated), and new expiration timestamp. Returns an error if the refresh fails or // the refresh token is invalid. func (c *OAuthClient) RefreshToken(refreshToken string) (*AnthropicCredentials, error) { - reqBody := map[string]interface{}{ + reqBody := map[string]any{ "grant_type": "refresh_token", "refresh_token": refreshToken, "client_id": c.ClientID, @@ -141,7 +141,7 @@ func (c *OAuthClient) RefreshToken(refreshToken string) (*AnthropicCredentials, } // makeTokenRequest makes a token request to the OAuth server -func (c *OAuthClient) makeTokenRequest(body map[string]interface{}) (*AnthropicCredentials, error) { +func (c *OAuthClient) makeTokenRequest(body map[string]any) (*AnthropicCredentials, error) { jsonBody, err := json.Marshal(body) if err != nil { return nil, fmt.Errorf("failed to marshal request body: %w", err) @@ -162,7 +162,7 @@ func (c *OAuthClient) makeTokenRequest(body map[string]interface{}) (*AnthropicC defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - var errorResp map[string]interface{} + var errorResp map[string]any if err := json.NewDecoder(resp.Body).Decode(&errorResp); err == nil { return nil, fmt.Errorf("token request failed: %v", errorResp) } diff --git a/internal/builtin/bash.go b/internal/builtin/bash.go index ff9ffa12..f0ee060c 100644 --- a/internal/builtin/bash.go +++ b/internal/builtin/bash.go @@ -84,11 +84,7 @@ func executeBash(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToo timeout := defaultTimeout if timeoutMs := request.GetFloat("timeout", 0); timeoutMs > 0 { timeoutDuration := time.Duration(timeoutMs) * time.Millisecond - if timeoutDuration > maxTimeout { - timeout = maxTimeout - } else { - timeout = timeoutDuration - } + timeout = min(timeoutDuration, maxTimeout) } // Check for banned commands diff --git a/internal/builtin/bash_test.go b/internal/builtin/bash_test.go index 35a972d3..9f844278 100644 --- a/internal/builtin/bash_test.go +++ b/internal/builtin/bash_test.go @@ -2,6 +2,7 @@ package builtin import ( "context" + "slices" "testing" "github.com/mark3labs/mcp-go/mcp" @@ -23,13 +24,7 @@ func TestBashServerRegistry(t *testing.T) { // Test that bash server is registered servers := registry.ListServers() - found := false - for _, name := range servers { - if name == "bash" { - found = true - break - } - } + found := slices.Contains(servers, "bash") if !found { t.Error("bash server not found in registry") diff --git a/internal/builtin/fetch.go b/internal/builtin/fetch.go index 1af3b8f3..0acbe10d 100644 --- a/internal/builtin/fetch.go +++ b/internal/builtin/fetch.go @@ -73,11 +73,7 @@ func executeFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallTo timeout := defaultFetchTimeout if timeoutSec := request.GetFloat("timeout", 0); timeoutSec > 0 { timeoutDuration := time.Duration(timeoutSec) * time.Second - if timeoutDuration > maxFetchTimeout { - timeout = maxFetchTimeout - } else { - timeout = timeoutDuration - } + timeout = min(timeoutDuration, maxFetchTimeout) } // Validate URL diff --git a/internal/builtin/fetch_test.go b/internal/builtin/fetch_test.go index 6e0aee80..4dc4732f 100644 --- a/internal/builtin/fetch_test.go +++ b/internal/builtin/fetch_test.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "net/http/httptest" + "slices" "strings" "testing" @@ -26,13 +27,7 @@ func TestFetchServerRegistry(t *testing.T) { // Test that fetch server is registered servers := registry.ListServers() - found := false - for _, name := range servers { - if name == "fetch" { - found = true - break - } - } + found := slices.Contains(servers, "fetch") if !found { t.Error("fetch server not found in registry") diff --git a/internal/builtin/http.go b/internal/builtin/http.go index 49ec01f2..4334e63b 100644 --- a/internal/builtin/http.go +++ b/internal/builtin/http.go @@ -10,13 +10,13 @@ import ( "strings" "time" - "github.com/JohannesKaufmann/html-to-markdown" + md "github.com/JohannesKaufmann/html-to-markdown" "github.com/PuerkitoBio/goquery" - "github.com/cloudwego/eino/components/model" - "github.com/cloudwego/eino/schema" + "github.com/tidwall/gjson" + + "charm.land/fantasy" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" - "github.com/tidwall/gjson" ) const ( @@ -26,15 +26,14 @@ const ( ) // httpServerModel holds the model for the HTTP server -var httpServerModel model.ToolCallingChatModel +var httpServerModel fantasy.LanguageModel // NewHTTPServer creates a new MCP server providing advanced HTTP fetching capabilities. // The server includes tools for fetching web content, summarizing pages, extracting // specific information, and filtering JSON responses. If an LLM model is provided, // AI-powered summarization and extraction tools are enabled. Returns an error if // server initialization fails. -func NewHTTPServer(llmModel model.ToolCallingChatModel) (*server.MCPServer, error) { - // Store the model globally for use in tool handlers +func NewHTTPServer(llmModel fantasy.LanguageModel) (*server.MCPServer, error) { httpServerModel = llmModel s := server.NewMCPServer("http-server", "1.0.0", server.WithToolCapabilities(true)) @@ -63,7 +62,7 @@ func NewHTTPServer(llmModel model.ToolCallingChatModel) (*server.MCPServer, erro s.AddTool(fetchTool, executeHTTPFetch) - // Only add the summarize tool if we have a model + // Only add AI-powered tools if we have a model if llmModel != nil { summarizeTool := mcp.NewTool("fetch_summarize", mcp.WithDescription(httpSummarizeDescription), @@ -114,7 +113,6 @@ func NewHTTPServer(llmModel model.ToolCallingChatModel) (*server.MCPServer, erro // executeHTTPFetch handles the fetch tool execution func executeHTTPFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - // Extract parameters urlStr, err := request.RequireString("url") if err != nil { return mcp.NewToolResultError("url parameter is required and must be a string"), nil @@ -125,32 +123,23 @@ func executeHTTPFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.Ca return mcp.NewToolResultError("format parameter is required and must be a string"), nil } - // Validate format if format != "html" && format != "markdown" { return mcp.NewToolResultError("format must be 'html' or 'markdown'"), nil } - // Get bodyOnly parameter (optional, defaults to false) bodyOnly := request.GetBool("bodyOnly", false) - // Parse timeout (optional) timeout := httpDefaultFetchTimeout if timeoutSec := request.GetFloat("timeout", 0); timeoutSec > 0 { timeoutDuration := time.Duration(timeoutSec) * time.Second - if timeoutDuration > httpMaxFetchTimeout { - timeout = httpMaxFetchTimeout - } else { - timeout = timeoutDuration - } + timeout = min(timeoutDuration, httpMaxFetchTimeout) } - // Validate URL parsedURL, err := url.Parse(urlStr) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("invalid URL: %v", err)), nil } - // Ensure URL has a scheme if parsedURL.Scheme == "" { urlStr = "https://" + urlStr parsedURL, err = url.Parse(urlStr) @@ -159,52 +148,43 @@ func executeHTTPFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.Ca } } - // Only allow HTTP and HTTPS if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { return mcp.NewToolResultError("URL must use http:// or https://"), nil } - // Create HTTP client with timeout client := &http.Client{ Timeout: timeout, } - // Create request with context req, err := http.NewRequestWithContext(ctx, "GET", urlStr, nil) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("failed to create request: %v", err)), nil } - // Set headers to mimic a real browser req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8") req.Header.Set("Accept-Language", "en-US,en;q=0.9") - // Make the request resp, err := client.Do(req) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("request failed: %v", err)), nil } defer resp.Body.Close() - // Check status code if resp.StatusCode < 200 || resp.StatusCode >= 300 { return mcp.NewToolResultError(fmt.Sprintf("request failed with status code: %d", resp.StatusCode)), nil } - // Check content length if resp.ContentLength > httpMaxResponseSize { return mcp.NewToolResultError("response too large (exceeds 5MB limit)"), nil } - // Read response body with size limit limitedReader := io.LimitReader(resp.Body, httpMaxResponseSize+1) bodyBytes, err := io.ReadAll(limitedReader) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("failed to read response: %v", err)), nil } - // Check if we exceeded the size limit if len(bodyBytes) > httpMaxResponseSize { return mcp.NewToolResultError("response too large (exceeds 5MB limit)"), nil } @@ -215,7 +195,6 @@ func executeHTTPFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.Ca contentType = "unknown" } - // Extract body content if requested if bodyOnly && strings.Contains(contentType, "text/html") { content, err = extractBodyContent(content) if err != nil { @@ -223,12 +202,10 @@ func executeHTTPFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.Ca } } - // Process content based on format var output string switch format { case "html": output = content - case "markdown": if strings.Contains(contentType, "text/html") { output, err = httpConvertHTMLToMarkdown(content) @@ -236,12 +213,10 @@ func executeHTTPFetch(ctx context.Context, request mcp.CallToolRequest) (*mcp.Ca return mcp.NewToolResultError(fmt.Sprintf("failed to convert HTML to markdown: %v", err)), nil } } else { - // Non-HTML content, wrap in code block output = "```\n" + content + "\n```" } } - // Create result with metadata title := fmt.Sprintf("%s (%s)", urlStr, contentType) result := mcp.NewToolResultText(output) result.Meta = &mcp.Meta{ @@ -263,14 +238,11 @@ func extractBodyContent(htmlContent string) (string, error) { return "", err } - // Find the body tag bodySelection := doc.Find("body") if bodySelection.Length() == 0 { - // No body tag found, return the original content return htmlContent, nil } - // Get the inner HTML of the body tag bodyHTML, err := bodySelection.Html() if err != nil { return "", err @@ -283,7 +255,6 @@ func extractBodyContent(htmlContent string) (string, error) { func httpConvertHTMLToMarkdown(htmlContent string) (string, error) { converter := md.NewConverter("", true, nil) - // Remove unwanted elements converter.Remove("script") converter.Remove("style") converter.Remove("meta") @@ -300,43 +271,39 @@ func httpConvertHTMLToMarkdown(htmlContent string) (string, error) { // executeHTTPFetchSummarize handles the fetch_summarize tool execution func executeHTTPFetchSummarize(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - // Get URL urlStr, err := request.RequireString("url") if err != nil { return mcp.NewToolResultError("url parameter is required and must be a string"), nil } - // Get optional instructions instructions := request.GetString("instructions", "Provide a concise summary of this content.") - // Fetch content as text (reuse existing logic) content, err := httpFetchAndExtractText(ctx, urlStr) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("Failed to fetch content: %v", err)), nil } - // Check if we have a model available if httpServerModel == nil { return mcp.NewToolResultError("LLM model not available for summarization"), nil } - // Create messages for the LLM - messages := []*schema.Message{ - schema.UserMessage(fmt.Sprintf("%s\n\nContent to summarize:\n%s", instructions, content)), + // Use fantasy model for summarization + call := fantasy.Call{ + Prompt: fantasy.Prompt{ + fantasy.NewUserMessage(fmt.Sprintf("%s\n\nContent to summarize:\n%s", instructions, content)), + }, } - // Generate summary using the model directly - response, err := httpServerModel.Generate(ctx, messages) + response, err := httpServerModel.Generate(ctx, call) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("Summarization failed: %v", err)), nil } - // Return summary return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", - Text: response.Content, + Text: response.Content.Text(), }, }, }, nil @@ -344,30 +311,25 @@ func executeHTTPFetchSummarize(ctx context.Context, request mcp.CallToolRequest) // executeHTTPFetchExtract handles the fetch_extract tool execution func executeHTTPFetchExtract(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - // Get URL urlStr, err := request.RequireString("url") if err != nil { return mcp.NewToolResultError("url parameter is required and must be a string"), nil } - // Get extraction instructions instructions, err := request.RequireString("instructions") if err != nil { return mcp.NewToolResultError("instructions parameter is required and must be a string"), nil } - // Fetch content as text (reuse existing logic) content, err := httpFetchAndExtractText(ctx, urlStr) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("Failed to fetch content: %v", err)), nil } - // Check if we have a model available if httpServerModel == nil { return mcp.NewToolResultError("LLM model not available for extraction"), nil } - // Create extraction prompt extractionPrompt := fmt.Sprintf(`Extract the requested information from the following web content. Extraction Instructions: %s @@ -377,23 +339,22 @@ Web Content: Please extract only the requested information. If the requested information is not found, respond with "Information not found" and explain what was searched for.`, instructions, content) - // Create messages for the LLM - messages := []*schema.Message{ - schema.UserMessage(extractionPrompt), + call := fantasy.Call{ + Prompt: fantasy.Prompt{ + fantasy.NewUserMessage(extractionPrompt), + }, } - // Generate extraction using the model directly - response, err := httpServerModel.Generate(ctx, messages) + response, err := httpServerModel.Generate(ctx, call) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("Extraction failed: %v", err)), nil } - // Return extracted data return &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", - Text: response.Content, + Text: response.Content.Text(), }, }, }, nil @@ -401,16 +362,13 @@ Please extract only the requested information. If the requested information is n // httpFetchAndExtractText fetches content from URL and extracts as text func httpFetchAndExtractText(ctx context.Context, urlStr string) (string, error) { - // Parse timeout (use default) timeout := httpDefaultFetchTimeout - // Validate URL parsedURL, err := url.Parse(urlStr) if err != nil { return "", fmt.Errorf("invalid URL: %v", err) } - // Ensure URL has a scheme if parsedURL.Scheme == "" { urlStr = "https://" + urlStr parsedURL, err = url.Parse(urlStr) @@ -419,52 +377,43 @@ func httpFetchAndExtractText(ctx context.Context, urlStr string) (string, error) } } - // Only allow HTTP and HTTPS if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { return "", fmt.Errorf("URL must use http:// or https://") } - // Create HTTP client with timeout client := &http.Client{ Timeout: timeout, } - // Create request with context req, err := http.NewRequestWithContext(ctx, "GET", urlStr, nil) if err != nil { return "", fmt.Errorf("failed to create request: %v", err) } - // Set headers to mimic a real browser req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8") req.Header.Set("Accept-Language", "en-US,en;q=0.9") - // Make the request resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("request failed: %v", err) } defer resp.Body.Close() - // Check status code if resp.StatusCode < 200 || resp.StatusCode >= 300 { return "", fmt.Errorf("request failed with status code: %d", resp.StatusCode) } - // Check content length if resp.ContentLength > httpMaxResponseSize { return "", fmt.Errorf("response too large (exceeds 5MB limit)") } - // Read response body with size limit limitedReader := io.LimitReader(resp.Body, httpMaxResponseSize+1) bodyBytes, err := io.ReadAll(limitedReader) if err != nil { return "", fmt.Errorf("failed to read response: %v", err) } - // Check if we exceeded the size limit if len(bodyBytes) > httpMaxResponseSize { return "", fmt.Errorf("response too large (exceeds 5MB limit)") } @@ -472,7 +421,6 @@ func httpFetchAndExtractText(ctx context.Context, urlStr string) (string, error) content := string(bodyBytes) contentType := resp.Header.Get("Content-Type") - // Extract text content if strings.Contains(contentType, "text/html") { return httpExtractTextFromHTML(content) } @@ -486,13 +434,10 @@ func httpExtractTextFromHTML(htmlContent string) (string, error) { return "", err } - // Remove script, style, and other non-content elements doc.Find("script, style, noscript, iframe, object, embed").Remove() - // Extract text content text := doc.Text() - // Clean up whitespace lines := strings.Split(text, "\n") var cleanLines []string for _, line := range lines { @@ -507,7 +452,6 @@ func httpExtractTextFromHTML(htmlContent string) (string, error) { // executeHTTPFetchFilteredJSON handles the fetch_filtered_json tool execution func executeHTTPFetchFilteredJSON(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - // Extract parameters urlStr, err := request.RequireString("url") if err != nil { return mcp.NewToolResultError("url parameter is required and must be a string"), nil @@ -518,24 +462,17 @@ func executeHTTPFetchFilteredJSON(ctx context.Context, request mcp.CallToolReque return mcp.NewToolResultError("path parameter is required and must be a string"), nil } - // Parse timeout (optional) timeout := httpDefaultFetchTimeout if timeoutSec := request.GetFloat("timeout", 0); timeoutSec > 0 { timeoutDuration := time.Duration(timeoutSec) * time.Second - if timeoutDuration > httpMaxFetchTimeout { - timeout = httpMaxFetchTimeout - } else { - timeout = timeoutDuration - } + timeout = min(timeoutDuration, httpMaxFetchTimeout) } - // Validate URL parsedURL, err := url.Parse(urlStr) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("invalid URL: %v", err)), nil } - // Ensure URL has a scheme if parsedURL.Scheme == "" { urlStr = "https://" + urlStr parsedURL, err = url.Parse(urlStr) @@ -544,75 +481,62 @@ func executeHTTPFetchFilteredJSON(ctx context.Context, request mcp.CallToolReque } } - // Only allow HTTP and HTTPS if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { return mcp.NewToolResultError("URL must use http:// or https://"), nil } - // Create HTTP client with timeout client := &http.Client{ Timeout: timeout, } - // Create request with context req, err := http.NewRequestWithContext(ctx, "GET", urlStr, nil) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("failed to create request: %v", err)), nil } - // Set headers to mimic a real browser and accept JSON req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") req.Header.Set("Accept", "application/json, text/plain, */*") req.Header.Set("Accept-Language", "en-US,en;q=0.9") - // Make the request resp, err := client.Do(req) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("request failed: %v", err)), nil } defer resp.Body.Close() - // Check status code if resp.StatusCode < 200 || resp.StatusCode >= 300 { return mcp.NewToolResultError(fmt.Sprintf("request failed with status code: %d", resp.StatusCode)), nil } - // Check content length if resp.ContentLength > httpMaxResponseSize { return mcp.NewToolResultError("response too large (exceeds 5MB limit)"), nil } - // Read response body with size limit limitedReader := io.LimitReader(resp.Body, httpMaxResponseSize+1) bodyBytes, err := io.ReadAll(limitedReader) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("failed to read response: %v", err)), nil } - // Check if we exceeded the size limit if len(bodyBytes) > httpMaxResponseSize { return mcp.NewToolResultError("response too large (exceeds 5MB limit)"), nil } content := string(bodyBytes) - // Validate that the content is valid JSON if !json.Valid(bodyBytes) { return mcp.NewToolResultError("response is not valid JSON"), nil } - // Apply gjson path to filter the JSON result := gjson.Get(content, path) if !result.Exists() { return mcp.NewToolResultError(fmt.Sprintf("gjson path '%s' did not match any data", path)), nil } - // Get the filtered JSON as a string var filteredJSON string if result.IsArray() || result.IsObject() { filteredJSON = result.Raw } else { - // For primitive values, wrap in quotes if it's a string if result.Type == gjson.String { filteredJSON = fmt.Sprintf(`"%s"`, result.Str) } else { @@ -620,7 +544,6 @@ func executeHTTPFetchFilteredJSON(ctx context.Context, request mcp.CallToolReque } } - // Create result with metadata contentType := resp.Header.Get("Content-Type") if contentType == "" { contentType = "application/json" diff --git a/internal/builtin/http_test.go b/internal/builtin/http_test.go index 079a2ec5..d74d8d21 100644 --- a/internal/builtin/http_test.go +++ b/internal/builtin/http_test.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "net/http/httptest" + "slices" "strings" "testing" @@ -26,13 +27,7 @@ func TestHTTPServerRegistry(t *testing.T) { // Test that HTTP server is registered servers := registry.ListServers() - found := false - for _, name := range servers { - if name == "http" { - found = true - break - } - } + found := slices.Contains(servers, "http") if !found { t.Error("http server not found in registry") diff --git a/internal/builtin/registry.go b/internal/builtin/registry.go index 1bb24a82..6657e932 100644 --- a/internal/builtin/registry.go +++ b/internal/builtin/registry.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/cloudwego/eino/components/model" + "charm.land/fantasy" "github.com/mark3labs/mcp-filesystem-server/filesystemserver" "github.com/mark3labs/mcp-go/server" ) @@ -19,7 +19,6 @@ type BuiltinServerWrapper struct { // a no-op as the server is initialized during creation. Returns an error if // initialization fails. func (w *BuiltinServerWrapper) Initialize() error { - // The server is already initialized when created return nil } @@ -33,7 +32,7 @@ func (w *BuiltinServerWrapper) GetServer() *server.MCPServer { // It provides a centralized registry for creating instances of builtin MCP servers // with their respective configurations. type Registry struct { - servers map[string]func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) + servers map[string]func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) } // NewRegistry creates a new builtin server registry with all available builtin @@ -41,10 +40,9 @@ type Registry struct { // and HTTP servers. func NewRegistry() *Registry { r := &Registry{ - servers: make(map[string]func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error)), + servers: make(map[string]func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error)), } - // Register builtin servers r.registerFilesystemServer() r.registerBashServer() r.registerTodoServer() @@ -58,7 +56,7 @@ func NewRegistry() *Registry { // parameter provides server-specific configuration, and the model parameter provides // an optional LLM for AI-powered features. Returns an error if the server name // is unknown or if creation fails. -func (r *Registry) CreateServer(name string, options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) { +func (r *Registry) CreateServer(name string, options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) { factory, exists := r.servers[name] if !exists { return nil, fmt.Errorf("unknown builtin server: %s", name) @@ -67,8 +65,7 @@ func (r *Registry) CreateServer(name string, options map[string]any, model model return factory(options, model) } -// ListServers returns a list of all available builtin server names that can be -// created using CreateServer. The order of names is not guaranteed. +// ListServers returns a list of all available builtin server names. func (r *Registry) ListServers() []string { names := make([]string, 0, len(r.servers)) for name := range r.servers { @@ -79,8 +76,7 @@ func (r *Registry) ListServers() []string { // registerFilesystemServer registers the filesystem server func (r *Registry) registerFilesystemServer() { - r.servers["fs"] = func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) { - // Extract allowed directories from options + r.servers["fs"] = func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) { var allowedDirs []string if dirs, ok := options["allowed_directories"]; ok { switch v := dirs.(type) { @@ -101,7 +97,6 @@ func (r *Registry) registerFilesystemServer() { return nil, fmt.Errorf("allowed_directories must be a string or array of strings") } } else { - // Default to current working directory if no directories specified cwd, err := os.Getwd() if err != nil { return nil, fmt.Errorf("failed to get current working directory: %v", err) @@ -109,7 +104,6 @@ func (r *Registry) registerFilesystemServer() { allowedDirs = []string{cwd} } - // Create the filesystem server server, err := filesystemserver.NewFilesystemServer(allowedDirs) if err != nil { return nil, fmt.Errorf("failed to create filesystem server: %v", err) @@ -121,8 +115,7 @@ func (r *Registry) registerFilesystemServer() { // registerBashServer registers the bash server func (r *Registry) registerBashServer() { - r.servers["bash"] = func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) { - // Create the bash server + r.servers["bash"] = func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) { server, err := NewBashServer() if err != nil { return nil, fmt.Errorf("failed to create bash server: %v", err) @@ -134,8 +127,7 @@ func (r *Registry) registerBashServer() { // registerTodoServer registers the todo server func (r *Registry) registerTodoServer() { - r.servers["todo"] = func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) { - // Create the todo server + r.servers["todo"] = func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) { server, err := NewTodoServer() if err != nil { return nil, fmt.Errorf("failed to create todo server: %v", err) @@ -147,8 +139,7 @@ func (r *Registry) registerTodoServer() { // registerFetchServer registers the fetch server func (r *Registry) registerFetchServer() { - r.servers["fetch"] = func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) { - // Create the fetch server + r.servers["fetch"] = func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) { server, err := NewFetchServer() if err != nil { return nil, fmt.Errorf("failed to create fetch server: %v", err) @@ -160,8 +151,7 @@ func (r *Registry) registerFetchServer() { // registerHTTPServer registers the HTTP server func (r *Registry) registerHTTPServer() { - r.servers["http"] = func(options map[string]any, model model.ToolCallingChatModel) (*BuiltinServerWrapper, error) { - // Create the HTTP server + r.servers["http"] = func(options map[string]any, model fantasy.LanguageModel) (*BuiltinServerWrapper, error) { server, err := NewHTTPServer(model) if err != nil { return nil, fmt.Errorf("failed to create HTTP server: %v", err) diff --git a/internal/builtin/todo_test.go b/internal/builtin/todo_test.go index c4492355..2419e4e7 100644 --- a/internal/builtin/todo_test.go +++ b/internal/builtin/todo_test.go @@ -2,6 +2,7 @@ package builtin import ( "context" + "slices" "testing" "github.com/mark3labs/mcp-go/mcp" @@ -23,13 +24,7 @@ func TestTodoServerRegistry(t *testing.T) { // Test that todo server is registered servers := registry.ListServers() - found := false - for _, name := range servers { - if name == "todo" { - found = true - break - } - } + found := slices.Contains(servers, "todo") if !found { t.Error("todo server not found in registry") diff --git a/internal/config/environment_flow_test.go b/internal/config/environment_flow_test.go index 6ea45463..5ee4b307 100644 --- a/internal/config/environment_flow_test.go +++ b/internal/config/environment_flow_test.go @@ -3,6 +3,7 @@ package config import ( "os" "path/filepath" + "slices" "strings" "testing" @@ -77,13 +78,7 @@ mcpServers: // Check command has substituted value expectedInCommand := "GITHUB_PERSONAL_ACCESS_TOKEN=ghp_test_token_123" - found := false - for _, arg := range githubServer.Command { - if arg == expectedInCommand { - found = true - break - } - } + found := slices.Contains(githubServer.Command, expectedInCommand) if !found { t.Errorf("Expected '%s' in command, got: %v", expectedInCommand, githubServer.Command) } diff --git a/internal/config/merger.go b/internal/config/merger.go index 1ada1959..67a1177f 100644 --- a/internal/config/merger.go +++ b/internal/config/merger.go @@ -51,10 +51,10 @@ func fixEnvironmentCase(config *Config) { // Check if we have mcpServers in the raw config if mcpServersRaw, ok := rawConfig["mcpservers"]; ok { - if mcpServersMap, ok := mcpServersRaw.(map[string]interface{}); ok { + if mcpServersMap, ok := mcpServersRaw.(map[string]any); ok { // Iterate through each server for serverName, serverDataRaw := range mcpServersMap { - if serverData, ok := serverDataRaw.(map[string]interface{}); ok { + if serverData, ok := serverDataRaw.(map[string]any); ok { // Check if this server has an environment field if _, hasEnv := serverData["environment"]; hasEnv { // Get the server config from our parsed config diff --git a/internal/config/viper_test.go b/internal/config/viper_test.go index f9e32a6f..59c4314c 100644 --- a/internal/config/viper_test.go +++ b/internal/config/viper_test.go @@ -24,15 +24,15 @@ mcpServers: // Test 1: Direct YAML parsing t.Run("DirectYAMLParsing", func(t *testing.T) { - var yamlData map[string]interface{} + var yamlData map[string]any err := yaml.Unmarshal([]byte(yamlContent), &yamlData) if err != nil { t.Fatalf("YAML unmarshal error: %v", err) } - servers := yamlData["mcpServers"].(map[string]interface{}) - testServer := servers["test"].(map[string]interface{}) - env := testServer["environment"].(map[string]interface{}) + servers := yamlData["mcpServers"].(map[string]any) + testServer := servers["test"].(map[string]any) + env := testServer["environment"].(map[string]any) if env["KEY1"] != "value1" { t.Errorf("Expected KEY1=value1, got %v", env["KEY1"]) diff --git a/internal/hooks/executor.go b/internal/hooks/executor.go index ab5b5047..ae8ea6fe 100644 --- a/internal/hooks/executor.go +++ b/internal/hooks/executor.go @@ -74,7 +74,7 @@ func (e *Executor) PopulateCommonFields(event HookEvent) CommonInput { // it matches hooks based on tool name patterns. Hooks are executed in parallel // with configurable timeouts. Returns a combined HookOutput from all executed // hooks, with blocking decisions taking precedence. -func (e *Executor) ExecuteHooks(ctx context.Context, event HookEvent, input interface{}) (*HookOutput, error) { +func (e *Executor) ExecuteHooks(ctx context.Context, event HookEvent, input any) (*HookOutput, error) { matchers, ok := e.config.Hooks[event] if !ok || len(matchers) == 0 { return nil, nil @@ -119,7 +119,7 @@ func (e *Executor) ExecuteHooks(ctx context.Context, event HookEvent, input inte } // executeHook runs a single hook command -func (e *Executor) executeHook(ctx context.Context, hook HookEntry, input interface{}) *hookResult { +func (e *Executor) executeHook(ctx context.Context, hook HookEntry, input any) *hookResult { // Prepare input JSON inputJSON, err := json.Marshal(input) if err != nil { @@ -187,7 +187,7 @@ func matchesPattern(pattern, toolName string) bool { } // extractToolName gets the tool name from various input types -func extractToolName(input interface{}) string { +func extractToolName(input any) string { switch v := input.(type) { case *PreToolUseInput: return v.ToolName diff --git a/internal/hooks/executor_test.go b/internal/hooks/executor_test.go index b59cbf8e..dc0ad008 100644 --- a/internal/hooks/executor_test.go +++ b/internal/hooks/executor_test.go @@ -42,7 +42,7 @@ echo '{"decision": "approve", "reason": "Approved by test"}' name string config *HookConfig event HookEvent - input interface{} + input any expected *HookOutput wantErr bool }{ @@ -87,7 +87,7 @@ echo '{"decision": "approve", "reason": "Approved by test"}' expected: &HookOutput{ Decision: "block", Reason: "Blocked by policy\n", - Continue: boolPtr(false), + Continue: new(false), }, }, { @@ -166,8 +166,9 @@ echo '{"decision": "approve", "reason": "Approved by test"}' } } +//go:fix inline func boolPtr(b bool) *bool { - return &b + return new(b) } func compareHookOutputs(a, b *HookOutput) bool { diff --git a/internal/models/anthropic/anthropic.go b/internal/models/anthropic/anthropic.go deleted file mode 100644 index 7f456913..00000000 --- a/internal/models/anthropic/anthropic.go +++ /dev/null @@ -1,283 +0,0 @@ -package anthropic - -import ( - "bytes" - "context" - "encoding/json" - "io" - "net/http" - "strings" - - einoclaude "github.com/cloudwego/eino-ext/components/model/claude" - "github.com/cloudwego/eino/components/model" - "github.com/cloudwego/eino/schema" -) - -// CustomChatModel wraps the eino-ext Claude model with custom tool schema handling. -// It provides a compatibility layer that fixes malformed JSON in tool calls and -// ensures proper schema validation for Anthropic's API requirements. -// This wrapper is necessary to handle edge cases where the underlying library -// may generate invalid JSON for empty tool inputs or missing properties. -type CustomChatModel struct { - // wrapped is the underlying eino-ext Claude model instance - wrapped *einoclaude.ChatModel -} - -// CustomRoundTripper intercepts HTTP requests to fix Anthropic function schemas. -// It acts as a middleware that modifies requests before they reach the Anthropic API, -// ensuring that tool schemas and function calls are properly formatted. -// This is particularly important for handling edge cases like empty tool inputs -// or missing schema properties that would otherwise cause API errors. -type CustomRoundTripper struct { - // wrapped is the underlying HTTP transport to use for actual requests - wrapped http.RoundTripper -} - -// NewCustomChatModel creates a new custom Anthropic chat model. -// It wraps the standard eino-ext Claude model with additional request -// preprocessing to ensure compatibility with Anthropic's API requirements. -// -// Parameters: -// - ctx: Context for the operation -// - config: Configuration for the Claude model including API key, model name, and parameters -// -// Returns: -// - *CustomChatModel: A wrapped Claude model with enhanced compatibility -// - error: Returns an error if model creation fails -// -// The custom model automatically: -// - Fixes malformed JSON in tool calls -// - Ensures tool schemas have required properties -// - Handles empty or missing input fields in function calls -func NewCustomChatModel(ctx context.Context, config *einoclaude.Config) (*CustomChatModel, error) { - // Create a custom HTTP client that intercepts requests - if config.HTTPClient == nil { - config.HTTPClient = &http.Client{} - } - - // Wrap the transport with our custom round tripper - if config.HTTPClient.Transport == nil { - config.HTTPClient.Transport = http.DefaultTransport - } - config.HTTPClient.Transport = &CustomRoundTripper{ - wrapped: config.HTTPClient.Transport, - } - - // Create the wrapped model - wrapped, err := einoclaude.NewChatModel(ctx, config) - if err != nil { - return nil, err - } - - return &CustomChatModel{ - wrapped: wrapped, - }, nil -} - -// RoundTrip implements http.RoundTripper to intercept and fix requests. -// It preprocesses outgoing requests to the Anthropic API to ensure -// they meet the API's requirements for tool schemas and function calls. -// -// Parameters: -// - req: The HTTP request to be sent to the Anthropic API -// -// Returns: -// - *http.Response: The response from the Anthropic API -// - error: Any error that occurred during the request -// -// The method performs the following fixes: -// - Ensures tool input_schema properties are not null -// - Fixes malformed JSON patterns in tool_use content -// - Validates and corrects empty or invalid function call inputs -func (rt *CustomRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - // Only process Anthropic API requests - if !strings.Contains(req.URL.Host, "anthropic.com") { - return rt.wrapped.RoundTrip(req) - } - - // Read the request body - body, err := io.ReadAll(req.Body) - if err != nil { - return nil, err - } - req.Body = io.NopCloser(bytes.NewReader(body)) - - // Apply string-based fixes BEFORE JSON parsing for malformed patterns - bodyStr := string(body) - - // Replace common malformed patterns - be more specific about context - replacements := []struct { - old string - new string - }{ - // Handle input field in tool_use objects - {`"input":,"name"`, `"input":{},"name"`}, - {`"input":,"type"`, `"input":{},"type"`}, - {`"input":}`, `"input":{}}`}, - // Handle arguments field in function calls - {`"arguments":,"name"`, `"arguments":"{}","name"`}, - {`"arguments":,"type"`, `"arguments":"{}","type"`}, - {`"arguments":}`, `"arguments":"{}"`}, - // Fallback patterns (less specific) - {`"input":,`, `"input":{}`}, - {`"arguments":,`, `"arguments":"{}"`}, - } - - for _, r := range replacements { - if strings.Contains(bodyStr, r.old) { - bodyStr = strings.ReplaceAll(bodyStr, r.old, r.new) - } - } - - // Parse the JSON request (after string fixes) - var requestData map[string]interface{} - if err := json.Unmarshal([]byte(bodyStr), &requestData); err != nil { - // Return the original request to avoid panic - req.Body = io.NopCloser(bytes.NewReader(body)) - req.ContentLength = int64(len(body)) - return rt.wrapped.RoundTrip(req) - } - - // Fix tool schemas if present - if tools, ok := requestData["tools"].([]interface{}); ok { - for _, tool := range tools { - if toolMap, ok := tool.(map[string]interface{}); ok { - if inputSchema, ok := toolMap["input_schema"].(map[string]interface{}); ok { - // Ensure properties exists and is not null - if properties, exists := inputSchema["properties"]; !exists || properties == nil { - inputSchema["properties"] = map[string]interface{}{} - } else if propertiesMap, ok := properties.(map[string]interface{}); ok { - // Ensure each property has a type - for _, propValue := range propertiesMap { - if propMap, ok := propValue.(map[string]interface{}); ok { - if _, hasType := propMap["type"]; !hasType { - propMap["type"] = "string" - } - } - } - } - } - } - } - } - - // Fix tool_use content in messages if present - if messages, ok := requestData["messages"].([]interface{}); ok { - for _, message := range messages { - if msgMap, ok := message.(map[string]interface{}); ok { - if content, ok := msgMap["content"].([]interface{}); ok { - for _, contentItem := range content { - if contentMap, ok := contentItem.(map[string]interface{}); ok { - if contentType, ok := contentMap["type"].(string); ok && contentType == "tool_use" { - // Ensure tool_use input is valid JSON - if input, exists := contentMap["input"]; exists { - // If input is nil or empty, set it to an empty object - if input == nil { - contentMap["input"] = map[string]interface{}{} - } else if inputBytes, ok := input.(json.RawMessage); ok { - if len(inputBytes) == 0 { - contentMap["input"] = map[string]interface{}{} - } else { - // Validate that it's valid JSON - var temp interface{} - if err := json.Unmarshal(inputBytes, &temp); err != nil { - contentMap["input"] = map[string]interface{}{} - } - } - } else if inputStr, ok := input.(string); ok { - // Handle string inputs that might be empty or invalid JSON - if inputStr == "" || inputStr == "{}" { - contentMap["input"] = map[string]interface{}{} - } else { - // Try to parse as JSON - var temp interface{} - if err := json.Unmarshal([]byte(inputStr), &temp); err != nil { - contentMap["input"] = map[string]interface{}{} - } - } - } - } else { - // If input field doesn't exist, add it as empty object - contentMap["input"] = map[string]interface{}{} - } - } - } - } - } - } - } - } - - // Marshal the fixed request back to JSON - fixedBody, err := json.Marshal(requestData) - if err != nil { - return nil, err - } - - // Use the fixed body from JSON marshaling - finalBodyStr := string(fixedBody) - - // Validate the final JSON - var finalCheck interface{} - if err := json.Unmarshal([]byte(finalBodyStr), &finalCheck); err != nil { - return nil, err - } - - // Create new request with fixed body - req.Body = io.NopCloser(strings.NewReader(finalBodyStr)) - req.ContentLength = int64(len(finalBodyStr)) - // Make the actual request - return rt.wrapped.RoundTrip(req) -} - -// Generate implements the model.BaseChatModel interface. -// It generates a single response from the model based on the input messages. -// -// Parameters: -// - ctx: Context for the operation, supporting cancellation and deadlines -// - input: The conversation history as a slice of messages -// - opts: Optional configuration options for the generation -// -// Returns: -// - *schema.Message: The generated response message -// - error: Any error that occurred during generation -func (m *CustomChatModel) Generate(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.Message, error) { - return m.wrapped.Generate(ctx, input, opts...) -} - -// Stream implements the model.BaseChatModel interface. -// It generates a streaming response from the model, allowing incremental -// processing of the model's output as it's generated. -// -// Parameters: -// - ctx: Context for the operation, supporting cancellation and deadlines -// - input: The conversation history as a slice of messages -// - opts: Optional configuration options for the generation -// -// Returns: -// - *schema.StreamReader[*schema.Message]: A reader for the streaming response -// - error: Any error that occurred during stream setup -func (m *CustomChatModel) Stream(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.StreamReader[*schema.Message], error) { - return m.wrapped.Stream(ctx, input, opts...) -} - -// WithTools implements the model.ToolCallingChatModel interface. -// It creates a new model instance with the specified tools available for function calling. -// The original model instance remains unchanged. -// -// Parameters: -// - tools: A slice of tool definitions that the model can use -// -// Returns: -// - model.ToolCallingChatModel: A new model instance with tools enabled -// - error: Returns an error if tool binding fails -func (m *CustomChatModel) WithTools(tools []*schema.ToolInfo) (model.ToolCallingChatModel, error) { - wrappedWithTools, err := m.wrapped.WithTools(tools) - if err != nil { - return nil, err - } - - return &CustomChatModel{ - wrapped: wrappedWithTools.(*einoclaude.ChatModel), - }, nil -} diff --git a/internal/models/gemini/gemini.go b/internal/models/gemini/gemini.go deleted file mode 100644 index a1ef7f5d..00000000 --- a/internal/models/gemini/gemini.go +++ /dev/null @@ -1,791 +0,0 @@ -package gemini - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "runtime/debug" - - "github.com/cloudwego/eino/callbacks" - "github.com/cloudwego/eino/components" - "github.com/cloudwego/eino/components/model" - "github.com/cloudwego/eino/schema" - "github.com/eino-contrib/jsonschema" - "github.com/getkin/kin-openapi/openapi3" - "google.golang.org/genai" -) - -var _ model.ToolCallingChatModel = (*ChatModel)(nil) - -// NewChatModel creates a new Gemini chat model instance. -// It initializes a Google Gemini model with the specified configuration, -// supporting both text generation and tool calling capabilities. -// -// Parameters: -// - ctx: The context for the operation (currently unused but kept for interface consistency) -// - cfg: Configuration for the Gemini model including client, model name, and parameters -// -// Returns: -// - *ChatModel: A Gemini chat model instance implementing ToolCallingChatModel -// - error: Any error that occurred during creation -// -// Example: -// -// client, _ := genai.NewClient(ctx, &genai.ClientConfig{ -// APIKey: "your-api-key", -// }) -// model, err := gemini.NewChatModel(ctx, &gemini.Config{ -// Client: client, -// Model: "gemini-pro", -// MaxTokens: &maxTokens, -// }) -func NewChatModel(_ context.Context, cfg *Config) (*ChatModel, error) { - return &ChatModel{ - cli: cfg.Client, - model: cfg.Model, - maxTokens: cfg.MaxTokens, - temperature: cfg.Temperature, - topP: cfg.TopP, - topK: cfg.TopK, - responseSchema: cfg.ResponseSchema, - enableCodeExecution: cfg.EnableCodeExecution, - safetySettings: cfg.SafetySettings, - }, nil -} - -// Config contains the configuration options for the Gemini model -type Config struct { - // Client is the Gemini API client instance - // Required for making API calls to Gemini - Client *genai.Client - - // Model specifies which Gemini model to use - // Examples: "gemini-pro", "gemini-pro-vision", "gemini-1.5-flash" - Model string - - // MaxTokens limits the maximum number of tokens in the response - // Optional. Example: maxTokens := 100 - MaxTokens *int - - // Temperature controls randomness in responses - // Range: [0.0, 1.0], where 0.0 is more focused and 1.0 is more creative - // Optional. Example: temperature := float32(0.7) - Temperature *float32 - - // TopP controls diversity via nucleus sampling - // Range: [0.0, 1.0], where 1.0 disables nucleus sampling - // Optional. Example: topP := float32(0.95) - TopP *float32 - - // TopK controls diversity by limiting the top K tokens to sample from - // Optional. Example: topK := int32(40) - TopK *int32 - - // ResponseSchema defines the structure for JSON responses - // Optional. Used when you want structured output in JSON format - ResponseSchema *jsonschema.Schema - - // EnableCodeExecution allows the model to execute code - // Warning: Be cautious with code execution in production - // Optional. Default: false - EnableCodeExecution bool - - // SafetySettings configures content filtering for different harm categories - // Controls the model's filtering behavior for potentially harmful content - // Optional. - SafetySettings []*genai.SafetySetting -} - -// options contains Gemini-specific options for model configuration. -// These are options that are specific to the Gemini API and not part -// of the common model options interface. -type options struct { - // TopK limits the number of tokens to sample from - TopK *int32 - // ResponseSchema defines the expected JSON structure for responses - ResponseSchema *jsonschema.Schema -} - -// ChatModel implements the Gemini chat model for the eino framework. -// It provides integration with Google's Gemini API, supporting both -// text generation and tool calling capabilities. -type ChatModel struct { - // cli is the Gemini API client instance - cli *genai.Client - - // model specifies which Gemini model to use - model string - // maxTokens limits the response length - maxTokens *int - // topP controls nucleus sampling - topP *float32 - // temperature controls randomness - temperature *float32 - // topK limits token sampling - topK *int32 - // responseSchema for structured JSON output - responseSchema *jsonschema.Schema - // tools converted to Gemini format - tools []*genai.Tool - // origTools stores the original tool definitions - origTools []*schema.ToolInfo - // toolChoice controls how tools are used - toolChoice *schema.ToolChoice - // enableCodeExecution allows code execution (use with caution) - enableCodeExecution bool - // safetySettings for content filtering - safetySettings []*genai.SafetySetting -} - -// Generate generates a single response from the Gemini model. -// It processes the input messages and returns a complete response. -// -// Parameters: -// - ctx: Context for the operation, supporting cancellation and callbacks -// - input: The conversation history as a slice of messages -// - opts: Optional configuration options for the generation -// -// Returns: -// - *schema.Message: The generated response message with content and metadata -// - error: Any error that occurred during generation -func (cm *ChatModel) Generate(ctx context.Context, input []*schema.Message, opts ...model.Option) (message *schema.Message, err error) { - ctx = callbacks.EnsureRunInfo(ctx, cm.GetType(), components.ComponentOfChatModel) - - config, conf, err := cm.buildGenerateConfig(opts...) - if err != nil { - return nil, err - } - - ctx = callbacks.OnStart(ctx, &model.CallbackInput{ - Messages: input, - Tools: model.GetCommonOptions(&model.Options{Tools: cm.origTools}, opts...).Tools, - Config: conf, - }) - defer func() { - if err != nil { - callbacks.OnError(ctx, err) - } - }() - - if len(input) == 0 { - return nil, fmt.Errorf("gemini input is empty") - } - - contents, err := cm.convertSchemaMessages(input) - if err != nil { - return nil, err - } - - result, err := cm.cli.Models.GenerateContent(ctx, cm.model, contents, config) - if err != nil { - return nil, fmt.Errorf("generate content failed: %w", err) - } - - message, err = cm.convertResponse(result) - if err != nil { - return nil, fmt.Errorf("convert response failed: %w", err) - } - - callbacks.OnEnd(ctx, cm.convertCallbackOutput(message, conf)) - return message, nil -} - -// Stream generates a streaming response from the Gemini model. -// It allows incremental processing of the model's output as it's generated. -// -// Parameters: -// - ctx: Context for the operation, supporting cancellation and callbacks -// - input: The conversation history as a slice of messages -// - opts: Optional configuration options for the generation -// -// Returns: -// - *schema.StreamReader[*schema.Message]: A reader for the streaming response -// - error: Any error that occurred during stream setup -func (cm *ChatModel) Stream(ctx context.Context, input []*schema.Message, opts ...model.Option) (result *schema.StreamReader[*schema.Message], err error) { - ctx = callbacks.EnsureRunInfo(ctx, cm.GetType(), components.ComponentOfChatModel) - - config, conf, err := cm.buildGenerateConfig(opts...) - if err != nil { - return nil, err - } - - ctx = callbacks.OnStart(ctx, &model.CallbackInput{ - Messages: input, - Tools: model.GetCommonOptions(&model.Options{Tools: cm.origTools}, opts...).Tools, - Config: conf, - }) - defer func() { - if err != nil { - callbacks.OnError(ctx, err) - } - }() - - if len(input) == 0 { - return nil, fmt.Errorf("gemini input is empty") - } - - contents, err := cm.convertSchemaMessages(input) - if err != nil { - return nil, err - } - - sr, sw := schema.Pipe[*model.CallbackOutput](1) - go func() { - defer func() { - panicErr := recover() - if panicErr != nil { - _ = sw.Send(nil, newPanicErr(panicErr, debug.Stack())) - } - sw.Close() - }() - - for resp, err := range cm.cli.Models.GenerateContentStream(ctx, cm.model, contents, config) { - if err != nil { - sw.Send(nil, err) - return - } - - message, err := cm.convertResponse(resp) - if err != nil { - sw.Send(nil, err) - return - } - - closed := sw.Send(cm.convertCallbackOutput(message, conf), nil) - if closed { - return - } - } - }() - - srList := sr.Copy(2) - callbacks.OnEndWithStreamOutput(ctx, srList[0]) - return schema.StreamReaderWithConvert(srList[1], func(t *model.CallbackOutput) (*schema.Message, error) { - return t.Message, nil - }), nil -} - -// WithTools creates a new model instance with the specified tools available. -// It returns a new ChatModel with tools configured for function calling. -// The original model instance remains unchanged. -// -// Parameters: -// - tools: A slice of tool definitions that the model can use -// -// Returns: -// - model.ToolCallingChatModel: A new model instance with tools enabled -// - error: Returns an error if no tools provided or conversion fails -func (cm *ChatModel) WithTools(tools []*schema.ToolInfo) (model.ToolCallingChatModel, error) { - if len(tools) == 0 { - return nil, errors.New("no tools to bind") - } - gTools, err := cm.convertToGeminiTools(tools) - if err != nil { - return nil, fmt.Errorf("convert to gemini tools failed: %w", err) - } - - tc := schema.ToolChoiceAllowed - ncm := *cm - ncm.toolChoice = &tc - ncm.tools = gTools - ncm.origTools = tools - return &ncm, nil -} - -// BindTools binds tools to the current model instance. -// Unlike WithTools, this modifies the current instance rather than -// creating a new one. Tools are set to "allowed" mode by default. -// -// Parameters: -// - tools: A slice of tool definitions to bind to the model -// -// Returns: -// - error: Returns an error if no tools provided or conversion fails -func (cm *ChatModel) BindTools(tools []*schema.ToolInfo) error { - if len(tools) == 0 { - return errors.New("no tools to bind") - } - gTools, err := cm.convertToGeminiTools(tools) - if err != nil { - return err - } - - cm.tools = gTools - cm.origTools = tools - tc := schema.ToolChoiceAllowed - cm.toolChoice = &tc - return nil -} - -// BindForcedTools binds tools to the current model instance in forced mode. -// This ensures the model will always use one of the provided tools -// rather than generating a text response. -// -// Parameters: -// - tools: A slice of tool definitions to bind to the model -// -// Returns: -// - error: Returns an error if no tools provided or conversion fails -func (cm *ChatModel) BindForcedTools(tools []*schema.ToolInfo) error { - if len(tools) == 0 { - return errors.New("no tools to bind") - } - gTools, err := cm.convertToGeminiTools(tools) - if err != nil { - return err - } - - cm.tools = gTools - cm.origTools = tools - tc := schema.ToolChoiceForced - cm.toolChoice = &tc - return nil -} - -func (cm *ChatModel) buildGenerateConfig(opts ...model.Option) (*genai.GenerateContentConfig, *model.Config, error) { - commonOptions := model.GetCommonOptions(&model.Options{ - Temperature: cm.temperature, - MaxTokens: cm.maxTokens, - TopP: cm.topP, - Tools: nil, - ToolChoice: cm.toolChoice, - }, opts...) - geminiOptions := model.GetImplSpecificOptions(&options{ - TopK: cm.topK, - ResponseSchema: cm.responseSchema, - }, opts...) - - conf := &model.Config{} - config := &genai.GenerateContentConfig{} - - // Set model - if commonOptions.Model != nil { - conf.Model = *commonOptions.Model - } else { - conf.Model = cm.model - } - - // Set temperature - if commonOptions.Temperature != nil { - conf.Temperature = *commonOptions.Temperature - config.Temperature = commonOptions.Temperature - } else if cm.temperature != nil { - conf.Temperature = *cm.temperature - config.Temperature = cm.temperature - } - - // Set max tokens - if commonOptions.MaxTokens != nil { - conf.MaxTokens = *commonOptions.MaxTokens - config.MaxOutputTokens = int32(*commonOptions.MaxTokens) - } else if cm.maxTokens != nil { - conf.MaxTokens = *cm.maxTokens - config.MaxOutputTokens = int32(*cm.maxTokens) - } - - // Set top P - if commonOptions.TopP != nil { - conf.TopP = *commonOptions.TopP - config.TopP = commonOptions.TopP - } else if cm.topP != nil { - conf.TopP = *cm.topP - config.TopP = cm.topP - } - - // Set top K - if geminiOptions.TopK != nil { - config.TopK = genai.Ptr(float32(*geminiOptions.TopK)) - } else if cm.topK != nil { - config.TopK = genai.Ptr(float32(*cm.topK)) - } - - // Set tools - tools := cm.tools - if commonOptions.Tools != nil { - var err error - tools, err = cm.convertToGeminiTools(commonOptions.Tools) - if err != nil { - return nil, nil, err - } - } - if len(tools) > 0 { - config.Tools = tools - } - - // Set tool choice - if commonOptions.ToolChoice != nil { - switch *commonOptions.ToolChoice { - case schema.ToolChoiceForbidden: - config.ToolConfig = &genai.ToolConfig{ - FunctionCallingConfig: &genai.FunctionCallingConfig{ - Mode: genai.FunctionCallingConfigModeNone, - }, - } - case schema.ToolChoiceAllowed: - config.ToolConfig = &genai.ToolConfig{ - FunctionCallingConfig: &genai.FunctionCallingConfig{ - Mode: genai.FunctionCallingConfigModeAuto, - }, - } - case schema.ToolChoiceForced: - if len(tools) == 0 { - return nil, nil, fmt.Errorf("tool choice is forced but no tools provided") - } - config.ToolConfig = &genai.ToolConfig{ - FunctionCallingConfig: &genai.FunctionCallingConfig{ - Mode: genai.FunctionCallingConfigModeAny, - }, - } - default: - return nil, nil, fmt.Errorf("tool choice=%s not supported", *commonOptions.ToolChoice) - } - } - - // Set safety settings - if len(cm.safetySettings) > 0 { - config.SafetySettings = cm.safetySettings - } - - // Set response schema for JSON mode - if geminiOptions.ResponseSchema != nil { - gSchema, err := cm.convertJSONSchema(geminiOptions.ResponseSchema) - if err != nil { - return nil, nil, fmt.Errorf("convert response schema failed: %w", err) - } - config.ResponseMIMEType = "application/json" - config.ResponseSchema = gSchema - } - - return config, conf, nil -} - -func (cm *ChatModel) convertToGeminiTools(tools []*schema.ToolInfo) ([]*genai.Tool, error) { - if len(tools) == 0 { - return nil, nil - } - - var functionDeclarations []*genai.FunctionDeclaration - for _, tool := range tools { - openSchema, err := tool.ToJSONSchema() - if err != nil { - return nil, fmt.Errorf("get open schema failed: %w", err) - } - - gSchema, err := cm.convertJSONSchema(openSchema) - if err != nil { - return nil, fmt.Errorf("convert open schema failed: %w", err) - } - - funcDecl := &genai.FunctionDeclaration{ - Name: tool.Name, - Description: tool.Desc, - Parameters: gSchema, - } - functionDeclarations = append(functionDeclarations, funcDecl) - } - - return []*genai.Tool{{FunctionDeclarations: functionDeclarations}}, nil -} - -func (cm *ChatModel) convertJSONSchema(schema *jsonschema.Schema) (*genai.Schema, error) { - if schema == nil { - return nil, nil - } - - result := &genai.Schema{ - Description: schema.Description, - } - - switch schema.Type { - case openapi3.TypeObject: - result.Type = genai.TypeObject - if schema.Properties != nil { - properties := make(map[string]*genai.Schema) - for pair := schema.Properties.Oldest(); pair != nil; pair = pair.Next() { - propSchema, err := cm.convertJSONSchema(pair.Value) - if err != nil { - return nil, err - } - properties[pair.Key] = propSchema - } - result.Properties = properties - } - if schema.Required != nil { - result.Required = schema.Required - } - case openapi3.TypeArray: - result.Type = genai.TypeArray - if schema.Items != nil { - itemSchema, err := cm.convertJSONSchema(schema.Items) - if err != nil { - return nil, err - } - result.Items = itemSchema - } - case openapi3.TypeString: - result.Type = genai.TypeString - if schema.Enum != nil { - enums := make([]string, 0, len(schema.Enum)) - for _, e := range schema.Enum { - if str, ok := e.(string); ok { - enums = append(enums, str) - } else { - return nil, fmt.Errorf("enum value must be a string, schema: %+v", schema) - } - } - result.Enum = enums - } - case openapi3.TypeNumber: - result.Type = genai.TypeNumber - case openapi3.TypeInteger: - result.Type = genai.TypeInteger - case openapi3.TypeBoolean: - result.Type = genai.TypeBoolean - default: - result.Type = genai.TypeUnspecified - } - - return result, nil -} - -func (cm *ChatModel) convertSchemaMessages(messages []*schema.Message) ([]*genai.Content, error) { - var contents []*genai.Content - for _, message := range messages { - content, err := cm.convertSchemaMessage(message) - if err != nil { - return nil, fmt.Errorf("convert schema message failed: %w", err) - } - if content != nil { - contents = append(contents, content) - } - } - return contents, nil -} - -func (cm *ChatModel) convertSchemaMessage(message *schema.Message) (*genai.Content, error) { - if message == nil { - return nil, nil - } - - var parts []*genai.Part - - // Handle tool calls - if message.ToolCalls != nil { - for _, call := range message.ToolCalls { - var args map[string]any - if err := json.Unmarshal([]byte(call.Function.Arguments), &args); err != nil { - return nil, fmt.Errorf("unmarshal tool call arguments failed: %w", err) - } - parts = append(parts, &genai.Part{ - FunctionCall: &genai.FunctionCall{ - Name: call.Function.Name, - Args: args, - }, - }) - } - } - - // Handle tool responses - if message.Role == schema.Tool { - var response map[string]any - if err := json.Unmarshal([]byte(message.Content), &response); err != nil { - // If the content is not valid JSON, treat it as a plain text error response - response = map[string]any{ - "error": message.Content, - } - } - parts = append(parts, &genai.Part{ - FunctionResponse: &genai.FunctionResponse{ - Name: message.ToolCallID, - Response: response, - }, - }) - } else { - // Handle text content - if message.Content != "" { - parts = append(parts, &genai.Part{Text: message.Content}) - } - - // Handle multi-content (images, audio, etc.) - for _, content := range message.MultiContent { - switch content.Type { - case schema.ChatMessagePartTypeText: - parts = append(parts, &genai.Part{Text: content.Text}) - case schema.ChatMessagePartTypeImageURL: - if content.ImageURL != nil { - parts = append(parts, &genai.Part{ - FileData: &genai.FileData{ - MIMEType: content.ImageURL.MIMEType, - FileURI: content.ImageURL.URI, - }, - }) - } - case schema.ChatMessagePartTypeAudioURL: - if content.AudioURL != nil { - parts = append(parts, &genai.Part{ - FileData: &genai.FileData{ - MIMEType: content.AudioURL.MIMEType, - FileURI: content.AudioURL.URI, - }, - }) - } - case schema.ChatMessagePartTypeVideoURL: - if content.VideoURL != nil { - parts = append(parts, &genai.Part{ - FileData: &genai.FileData{ - MIMEType: content.VideoURL.MIMEType, - FileURI: content.VideoURL.URI, - }, - }) - } - case schema.ChatMessagePartTypeFileURL: - if content.FileURL != nil { - parts = append(parts, &genai.Part{ - FileData: &genai.FileData{ - MIMEType: content.FileURL.MIMEType, - FileURI: content.FileURL.URI, - }, - }) - } - } - } - } - - if len(parts) == 0 { - return nil, nil - } - - return &genai.Content{ - Role: string(cm.convertRole(message.Role)), - Parts: parts, - }, nil -} - -func (cm *ChatModel) convertRole(role schema.RoleType) genai.Role { - switch role { - case schema.Assistant: - return genai.RoleModel - case schema.User: - return genai.RoleUser - case schema.Tool: - return genai.RoleUser // Tool responses are treated as user messages in the new API - default: - return genai.RoleUser - } -} - -func (cm *ChatModel) convertResponse(resp *genai.GenerateContentResponse) (*schema.Message, error) { - if len(resp.Candidates) == 0 { - return nil, fmt.Errorf("gemini result is empty") - } - - candidate := resp.Candidates[0] - message := &schema.Message{ - Role: schema.Assistant, - ResponseMeta: &schema.ResponseMeta{ - FinishReason: string(candidate.FinishReason), - }, - } - - // Handle usage metadata - if resp.UsageMetadata != nil { - message.ResponseMeta.Usage = &schema.TokenUsage{ - PromptTokens: int(resp.UsageMetadata.PromptTokenCount), - CompletionTokens: int(resp.UsageMetadata.CandidatesTokenCount), - TotalTokens: int(resp.UsageMetadata.TotalTokenCount), - } - } - - // Process content parts - var textParts []string - for _, part := range candidate.Content.Parts { - switch { - case part.Text != "": - textParts = append(textParts, part.Text) - case part.FunctionCall != nil: - args, err := json.Marshal(part.FunctionCall.Args) - if err != nil { - return nil, fmt.Errorf("marshal function call arguments failed: %w", err) - } - message.ToolCalls = append(message.ToolCalls, schema.ToolCall{ - ID: part.FunctionCall.Name, - Function: schema.FunctionCall{ - Name: part.FunctionCall.Name, - Arguments: string(args), - }, - }) - case part.ExecutableCode != nil: - textParts = append(textParts, part.ExecutableCode.Code) - case part.CodeExecutionResult != nil: - textParts = append(textParts, part.CodeExecutionResult.Output) - } - } - - // Set content - if len(textParts) == 1 { - message.Content = textParts[0] - } else if len(textParts) > 1 { - for _, text := range textParts { - message.MultiContent = append(message.MultiContent, schema.ChatMessagePart{ - Type: schema.ChatMessagePartTypeText, - Text: text, - }) - } - } - - return message, nil -} - -func (cm *ChatModel) convertCallbackOutput(message *schema.Message, conf *model.Config) *model.CallbackOutput { - callbackOutput := &model.CallbackOutput{ - Message: message, - Config: conf, - } - if message.ResponseMeta != nil && message.ResponseMeta.Usage != nil { - callbackOutput.TokenUsage = &model.TokenUsage{ - PromptTokens: message.ResponseMeta.Usage.PromptTokens, - CompletionTokens: message.ResponseMeta.Usage.CompletionTokens, - TotalTokens: message.ResponseMeta.Usage.TotalTokens, - } - } - return callbackOutput -} - -// IsCallbacksEnabled indicates whether this model supports callbacks. -// For the Gemini model, callbacks are always enabled to support -// token usage tracking and other monitoring features. -// -// Returns: -// - bool: Always returns true for Gemini models -func (cm *ChatModel) IsCallbacksEnabled() bool { - return true -} - -const typ = "Gemini" - -// GetType returns the type identifier for this model. -// This is used for logging and debugging purposes to identify -// which model implementation is being used. -// -// Returns: -// - string: Returns "Gemini" as the model type -func (cm *ChatModel) GetType() string { - return typ -} - -type panicErr struct { - info any - stack []byte -} - -func (p *panicErr) Error() string { - return fmt.Sprintf("panic error: %v, \nstack: %s", p.info, string(p.stack)) -} - -func newPanicErr(info any, stack []byte) error { - return &panicErr{ - info: info, - stack: stack, - } -} diff --git a/internal/models/generate_models.go b/internal/models/generate_models.go deleted file mode 100644 index 4b669a8e..00000000 --- a/internal/models/generate_models.go +++ /dev/null @@ -1,226 +0,0 @@ -//go:build ignore - -package main - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "text/template" - "time" -) - -// ModelInfo represents information about a specific model. -// This struct is used during code generation to parse model data -// from the models.dev API and generate the static Go code. -type ModelInfo struct { - // ID is the unique identifier for the model - ID string `json:"id"` - // Name is the human-readable name of the model - Name string `json:"name"` - // Attachment indicates whether the model supports file attachments - Attachment bool `json:"attachment"` - // Reasoning indicates whether this is a reasoning/chain-of-thought model - Reasoning bool `json:"reasoning"` - // Temperature indicates whether the model supports temperature parameter - Temperature bool `json:"temperature"` - // Cost contains the pricing information for the model - Cost Cost `json:"cost"` - // Limit contains the context and output token limits - Limit Limit `json:"limit"` -} - -// Cost represents the pricing information for a model. -// Used during code generation to parse pricing data from models.dev. -type Cost struct { - // Input is the cost per million input tokens - Input float64 `json:"input"` - // Output is the cost per million output tokens - Output float64 `json:"output"` - // CacheRead is the cost per million cached read tokens (optional) - CacheRead *float64 `json:"cache_read,omitempty"` - // CacheWrite is the cost per million cached write tokens (optional) - CacheWrite *float64 `json:"cache_write,omitempty"` -} - -// Limit represents the context and output limits for a model. -// Used during code generation to parse token limit data from models.dev. -type Limit struct { - // Context is the maximum number of input tokens - Context int `json:"context"` - // Output is the maximum number of output tokens - Output int `json:"output"` -} - -// ProviderInfo represents information about a model provider. -// Used during code generation to parse provider data from models.dev -// and generate the static provider registry. -type ProviderInfo struct { - // ID is the unique identifier for the provider - ID string `json:"id"` - // Env lists the environment variables for API credentials - Env []string `json:"env"` - // NPM is the NPM package name (for reference) - NPM string `json:"npm"` - // Name is the human-readable provider name - Name string `json:"name"` - // Models maps model IDs to their information - Models map[string]ModelInfo `json:"models"` -} - -const codeTemplate = `// Code generated by go generate; DO NOT EDIT. -// Generated at: {{.Timestamp}} - -package models - -// ModelInfo represents information about a specific model -type ModelInfo struct { - ID string - Name string - Attachment bool - Reasoning bool - Temperature bool - Cost Cost - Limit Limit -} - -// Cost represents the pricing information for a model -type Cost struct { - Input float64 - Output float64 - CacheRead *float64 - CacheWrite *float64 -} - -// Limit represents the context and output limits for a model -type Limit struct { - Context int - Output int -} - -// ProviderInfo represents information about a model provider -type ProviderInfo struct { - ID string - Env []string - NPM string - Name string - Models map[string]ModelInfo -} - -// GetModelsData returns the static models data from models.dev -func GetModelsData() map[string]ProviderInfo { - return map[string]ProviderInfo{ -{{- range $providerID, $provider := .Providers}} - "{{$providerID}}": { - ID: "{{$provider.ID}}", - Env: []string{ {{- range $i, $env := $provider.Env}}{{if $i}}, {{end}}"{{$env}}"{{end}} }, - NPM: "{{$provider.NPM}}", - Name: "{{$provider.Name}}", - Models: map[string]ModelInfo{ -{{- range $modelID, $model := $provider.Models}} - "{{$modelID}}": { - ID: "{{$model.ID}}", - Name: "{{$model.Name}}", - Attachment: {{$model.Attachment}}, - Reasoning: {{$model.Reasoning}}, - Temperature: {{$model.Temperature}}, - Cost: Cost{ - Input: {{$model.Cost.Input}}, - Output: {{$model.Cost.Output}}, - {{- if $model.Cost.CacheRead}} - CacheRead: &[]float64{{"{"}}{{$model.Cost.CacheRead}}{{"}"}}[0], - {{- else}} - CacheRead: nil, - {{- end}} - {{- if $model.Cost.CacheWrite}} - CacheWrite: &[]float64{{"{"}}{{$model.Cost.CacheWrite}}{{"}"}}[0], - {{- else}} - CacheWrite: nil, - {{- end}} - }, - Limit: Limit{ - Context: {{$model.Limit.Context}}, - Output: {{$model.Limit.Output}}, - }, - }, -{{- end}} - }, - }, -{{- end}} - } -} -` - -func main() { - fmt.Println("Fetching models data from models.dev...") - - // Fetch data from API - resp, err := http.Get("https://models.dev/api.json") - if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching data: %v\n", err) - os.Exit(1) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - fmt.Fprintf(os.Stderr, "API returned status %d\n", resp.StatusCode) - os.Exit(1) - } - - body, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Fprintf(os.Stderr, "Error reading response: %v\n", err) - os.Exit(1) - } - - // Parse JSON - var providers map[string]ProviderInfo - if err := json.Unmarshal(body, &providers); err != nil { - fmt.Fprintf(os.Stderr, "Error parsing JSON: %v\n", err) - os.Exit(1) - } - - // Fix Google provider environment variables to match our implementation - if googleProvider, exists := providers["google"]; exists { - googleProvider.Env = []string{"GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"} - providers["google"] = googleProvider - } - - // Generate Go code - tmpl, err := template.New("models").Parse(codeTemplate) - if err != nil { - fmt.Fprintf(os.Stderr, "Error parsing template: %v\n", err) - os.Exit(1) - } - - // Create output file - file, err := os.Create("models_data.go") - if err != nil { - fmt.Fprintf(os.Stderr, "Error creating output file: %v\n", err) - os.Exit(1) - } - defer file.Close() - - // Execute template - data := struct { - Providers map[string]ProviderInfo - Timestamp string - }{ - Providers: providers, - Timestamp: time.Now().Format(time.RFC3339), - } - - if err := tmpl.Execute(file, data); err != nil { - fmt.Fprintf(os.Stderr, "Error executing template: %v\n", err) - os.Exit(1) - } - - fmt.Printf("Generated models_data.go with %d providers\n", len(providers)) - - // Print summary - for providerID, provider := range providers { - fmt.Printf(" %s: %d models\n", providerID, len(provider.Models)) - } -} diff --git a/internal/models/models_data.go b/internal/models/models_data.go deleted file mode 100644 index 20320f04..00000000 --- a/internal/models/models_data.go +++ /dev/null @@ -1,35035 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// Generated at: 2026-01-09T17:30:36+03:00 - -package models - -// ModelInfo represents information about a specific model -type ModelInfo struct { - ID string - Name string - Attachment bool - Reasoning bool - Temperature bool - Cost Cost - Limit Limit -} - -// Cost represents the pricing information for a model -type Cost struct { - Input float64 - Output float64 - CacheRead *float64 - CacheWrite *float64 -} - -// Limit represents the context and output limits for a model -type Limit struct { - Context int - Output int -} - -// ProviderInfo represents information about a model provider -type ProviderInfo struct { - ID string - Env []string - NPM string - Name string - Models map[string]ModelInfo -} - -// GetModelsData returns the static models data from models.dev -func GetModelsData() map[string]ProviderInfo { - return map[string]ProviderInfo{ - "abacus": { - ID: "abacus", - Env: []string{"ABACUS_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Abacus", - Models: map[string]ModelInfo{ - "Qwen-QwQ-32B": { - ID: "Qwen-QwQ-32B", - Name: "QwQ 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "Qwen-Qwen2.5-72B-Instruct": { - ID: "Qwen-Qwen2.5-72B-Instruct", - Name: "Qwen 2.5 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.38, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "Qwen-Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen-Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen3 235B A22B Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 8192, - }, - }, - "Qwen-Qwen3-32B": { - ID: "Qwen-Qwen3-32B", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "claude-3-7-sonnet-20250219": { - ID: "claude-3-7-sonnet-20250219", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-haiku-4-5-20251001": { - ID: "claude-haiku-4-5-20251001", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-1-20250805": { - ID: "claude-opus-4-1-20250805", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-20250514": { - ID: "claude-opus-4-20250514", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5-20251101": { - ID: "claude-opus-4-5-20251101", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-20250514": { - ID: "claude-sonnet-4-20250514", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-5-20250929": { - ID: "claude-sonnet-4-5-20250929", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "deepseek-ai-DeepSeek-R1": { - ID: "deepseek-ai-DeepSeek-R1", - Name: "DeepSeek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek-ai-DeepSeek-V3.1-Terminus": { - ID: "deepseek-ai-DeepSeek-V3.1-Terminus", - Name: "DeepSeek V3.1 Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek-ai-DeepSeek-V3.2": { - ID: "deepseek-ai-DeepSeek-V3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek-deepseek-v3.1": { - ID: "deepseek-deepseek-v3.1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 1.66, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "gemini-2.0-flash-001": { - ID: "gemini-2.0-flash-001", - Name: "Gemini 2.0 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 8192, - }, - }, - "gemini-2.0-pro-exp-02-05": { - ID: "gemini-2.0-pro-exp-02-05", - Name: "Gemini 2.0 Pro Exp", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 8192, - }, - }, - "gemini-2.5-flash": { - ID: "gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-flash-preview": { - ID: "gemini-3-flash-preview", - Name: "Gemini 3 Flash Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 65000, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini": { - ID: "gpt-4.1-mini", - Name: "GPT-4.1 Mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-nano": { - ID: "gpt-4.1-nano", - Name: "GPT-4.1 Nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4o-2024-11-20": { - ID: "gpt-4o-2024-11-20", - Name: "GPT-4o (2024-11-20)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-mini": { - ID: "gpt-4o-mini", - Name: "GPT-4o Mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-chat-latest": { - ID: "gpt-5.1-chat-latest", - Name: "GPT-5.1 Chat Latest", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2": { - ID: "gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "grok-4-0709": { - ID: "grok-4-0709", - Name: "Grok 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 16384, - }, - }, - "grok-4-1-fast-non-reasoning": { - ID: "grok-4-1-fast-non-reasoning", - Name: "Grok 4.1 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 16384, - }, - }, - "grok-4-fast-non-reasoning": { - ID: "grok-4-fast-non-reasoning", - Name: "Grok 4 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 16384, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 16384, - }, - }, - "kimi-k2-turbo-preview": { - ID: "kimi-k2-turbo-preview", - Name: "Kimi K2 Turbo Preview", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8192, - }, - }, - "llama-3.3-70b-versatile": { - ID: "llama-3.3-70b-versatile", - Name: "Llama 3.3 70B Versatile", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.79, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama-Llama-4-Maverick-17B-128E-Instruct-FP8": { - ID: "meta-llama-Llama-4-Maverick-17B-128E-Instruct-FP8", - Name: "Llama 4 Maverick 17B 128E Instruct FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 32768, - }, - }, - "meta-llama-Meta-Llama-3.1-405B-Instruct-Turbo": { - ID: "meta-llama-Meta-Llama-3.1-405B-Instruct-Turbo", - Name: "Llama 3.1 405B Instruct Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3.5, - Output: 3.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta-llama-Meta-Llama-3.1-70B-Instruct": { - ID: "meta-llama-Meta-Llama-3.1-70B-Instruct", - Name: "Llama 3.1 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta-llama-Meta-Llama-3.1-8B-Instruct": { - ID: "meta-llama-Meta-Llama-3.1-8B-Instruct", - Name: "Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "o3": { - ID: "o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-mini": { - ID: "o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-pro": { - ID: "o3-pro", - Name: "o3-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 20, - Output: 80, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai-gpt-oss-120b": { - ID: "openai-gpt-oss-120b", - Name: "GPT-OSS 120B", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.44, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "qwen-2.5-coder-32b": { - ID: "qwen-2.5-coder-32b", - Name: "Qwen 2.5 Coder 32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.79, - Output: 0.79, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "qwen-qwen3-Max": { - ID: "qwen-qwen3-Max", - Name: "Qwen3 Max", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "qwen-qwen3-coder-480b-a35b-instruct": { - ID: "qwen-qwen3-coder-480b-a35b-instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "zai-org-glm-4.5": { - ID: "zai-org-glm-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "zai-org-glm-4.6": { - ID: "zai-org-glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - }, - }, - "aihubmix": { - ID: "aihubmix", - Env: []string{"AIHUBMIX_API_KEY" }, - NPM: "@aihubmix/ai-sdk-provider", - Name: "AIHubMix", - Models: map[string]ModelInfo{ - "Kimi-K2-0905": { - ID: "Kimi-K2-0905", - Name: "Kimi K2 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "claude-haiku-4-5": { - ID: "claude-haiku-4-5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.1, - Output: 5.5, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-1": { - ID: "claude-opus-4-1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 16.5, - Output: 82.5, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5": { - ID: "claude-opus-4-5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-sonnet-4-5": { - ID: "claude-sonnet-4-5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3.3, - Output: 16.5, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "coding-glm-4.7-free": { - ID: "coding-glm-4.7-free", - Name: "Coding GLM-4.7 Free", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "deepseek-v3.2": { - ID: "deepseek-v3.2", - Name: "DeepSeek-V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 64000, - }, - }, - "deepseek-v3.2-think": { - ID: "deepseek-v3.2-think", - Name: "DeepSeek-V3.2-Think", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 64000, - }, - }, - "gemini-2.5-flash": { - ID: "gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 65000, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 5, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 65000, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 65000, - }, - }, - "glm-4.7": { - ID: "glm-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1.1, - CacheRead: &[]float64{0.548}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini": { - ID: "gpt-4.1-mini", - Name: "GPT-4.1 mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-nano": { - ID: "gpt-4.1-nano", - Name: "GPT-4.1 nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4o": { - ID: "gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-2024-11-20": { - ID: "gpt-4o-2024-11-20", - Name: "GPT-4o (2024-11-20)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 20, - CacheRead: &[]float64{2.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "GPT-5-Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 6, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "GPT-5-Nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: &[]float64{0.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5-pro": { - ID: "gpt-5-pro", - Name: "GPT-5-Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 7, - Output: 28, - CacheRead: &[]float64{3.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "GPT-5.1 Codex", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-max": { - ID: "gpt-5.1-codex-max", - Name: "GPT-5.1-Codex-Max", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "GPT-5.1 Codex Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2": { - ID: "gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "minimax-m2.1": { - ID: "minimax-m2.1", - Name: "MiniMax M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "minimax-m2.1-free": { - ID: "minimax-m2.1-free", - Name: "MiniMax M2.1 Free", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "o4-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.5, - Output: 6, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 65536, - }, - }, - "qwen3-235b-a22b-instruct-2507": { - ID: "qwen3-235b-a22b-instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 1.12, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "qwen3-235b-a22b-thinking-2507": { - ID: "qwen3-235b-a22b-thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "qwen3-coder-480b-a35b-instruct": { - ID: "qwen3-coder-480b-a35b-instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.82, - Output: 3.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131000, - }, - }, - }, - }, - "alibaba": { - ID: "alibaba", - Env: []string{"DASHSCOPE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Alibaba", - Models: map[string]ModelInfo{ - "qvq-max": { - ID: "qvq-max", - Name: "QVQ Max", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 4.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen-flash": { - ID: "qwen-flash", - Name: "Qwen Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 32768, - }, - }, - "qwen-max": { - ID: "qwen-max", - Name: "Qwen Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.6, - Output: 6.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "qwen-mt-plus": { - ID: "qwen-mt-plus", - Name: "Qwen-MT Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.46, - Output: 7.37, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 8192, - }, - }, - "qwen-mt-turbo": { - ID: "qwen-mt-turbo", - Name: "Qwen-MT Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.16, - Output: 0.49, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 8192, - }, - }, - "qwen-omni-turbo": { - ID: "qwen-omni-turbo", - Name: "Qwen-Omni Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "qwen-omni-turbo-realtime": { - ID: "qwen-omni-turbo-realtime", - Name: "Qwen-Omni Turbo Realtime", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1.07, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "qwen-plus": { - ID: "qwen-plus", - Name: "Qwen Plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 32768, - }, - }, - "qwen-plus-character-ja": { - ID: "qwen-plus-character-ja", - Name: "Qwen Plus Character (Japanese)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 512, - }, - }, - "qwen-turbo": { - ID: "qwen-turbo", - Name: "Qwen Turbo", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 16384, - }, - }, - "qwen-vl-max": { - ID: "qwen-vl-max", - Name: "Qwen-VL Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 3.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen-vl-ocr": { - ID: "qwen-vl-ocr", - Name: "Qwen-VL OCR", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.72, - Output: 0.72, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 34096, - Output: 4096, - }, - }, - "qwen-vl-plus": { - ID: "qwen-vl-plus", - Name: "Qwen-VL Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.21, - Output: 0.63, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-14b-instruct": { - ID: "qwen2-5-14b-instruct", - Name: "Qwen2.5 14B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-32b-instruct": { - ID: "qwen2-5-32b-instruct", - Name: "Qwen2.5 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-72b-instruct": { - ID: "qwen2-5-72b-instruct", - Name: "Qwen2.5 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.4, - Output: 5.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-7b-instruct": { - ID: "qwen2-5-7b-instruct", - Name: "Qwen2.5 7B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.175, - Output: 0.7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-omni-7b": { - ID: "qwen2-5-omni-7b", - Name: "Qwen2.5-Omni 7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "qwen2-5-vl-72b-instruct": { - ID: "qwen2-5-vl-72b-instruct", - Name: "Qwen2.5-VL 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.8, - Output: 8.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-vl-7b-instruct": { - ID: "qwen2-5-vl-7b-instruct", - Name: "Qwen2.5-VL 7B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen3-14b": { - ID: "qwen3-14b", - Name: "Qwen3 14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen3-235b-a22b": { - ID: "qwen3-235b-a22b", - Name: "Qwen3 235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "qwen3-32b": { - ID: "qwen3-32b", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "qwen3-8b": { - ID: "qwen3-8b", - Name: "Qwen3 8B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen3-asr-flash": { - ID: "qwen3-asr-flash", - Name: "Qwen3-ASR Flash", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.035, - Output: 0.035, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 53248, - Output: 4096, - }, - }, - "qwen3-coder-30b-a3b-instruct": { - ID: "qwen3-coder-30b-a3b-instruct", - Name: "Qwen3-Coder 30B-A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.45, - Output: 2.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-coder-480b-a35b-instruct": { - ID: "qwen3-coder-480b-a35b-instruct", - Name: "Qwen3-Coder 480B-A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 7.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-coder-flash": { - ID: "qwen3-coder-flash", - Name: "Qwen3 Coder Flash", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 65536, - }, - }, - "qwen3-coder-plus": { - ID: "qwen3-coder-plus", - Name: "Qwen3 Coder Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "qwen3-livetranslate-flash-realtime": { - ID: "qwen3-livetranslate-flash-realtime", - Name: "Qwen3-LiveTranslate Flash Realtime", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 53248, - Output: 4096, - }, - }, - "qwen3-max": { - ID: "qwen3-max", - Name: "Qwen3 Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-next-80b-a3b-instruct": { - ID: "qwen3-next-80b-a3b-instruct", - Name: "Qwen3-Next 80B-A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-next-80b-a3b-thinking": { - ID: "qwen3-next-80b-a3b-thinking", - Name: "Qwen3-Next 80B-A3B (Thinking)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-omni-flash": { - ID: "qwen3-omni-flash", - Name: "Qwen3-Omni Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.43, - Output: 1.66, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 16384, - }, - }, - "qwen3-omni-flash-realtime": { - ID: "qwen3-omni-flash-realtime", - Name: "Qwen3-Omni Flash Realtime", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.52, - Output: 1.99, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 16384, - }, - }, - "qwen3-vl-235b-a22b": { - ID: "qwen3-vl-235b-a22b", - Name: "Qwen3-VL 235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-vl-30b-a3b": { - ID: "qwen3-vl-30b-a3b", - Name: "Qwen3-VL 30B-A3B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-vl-plus": { - ID: "qwen3-vl-plus", - Name: "Qwen3-VL Plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "qwq-plus": { - ID: "qwq-plus", - Name: "QwQ Plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 2.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - }, - }, - "alibaba-cn": { - ID: "alibaba-cn", - Env: []string{"DASHSCOPE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Alibaba (China)", - Models: map[string]ModelInfo{ - "deepseek-r1": { - ID: "deepseek-r1", - Name: "DeepSeek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 2.294, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "deepseek-r1-0528": { - ID: "deepseek-r1-0528", - Name: "DeepSeek R1 0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 2.294, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "deepseek-r1-distill-llama-70b": { - ID: "deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 16384, - }, - }, - "deepseek-r1-distill-llama-8b": { - ID: "deepseek-r1-distill-llama-8b", - Name: "DeepSeek R1 Distill Llama 8B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 16384, - }, - }, - "deepseek-r1-distill-qwen-1-5b": { - ID: "deepseek-r1-distill-qwen-1-5b", - Name: "DeepSeek R1 Distill Qwen 1.5B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 16384, - }, - }, - "deepseek-r1-distill-qwen-14b": { - ID: "deepseek-r1-distill-qwen-14b", - Name: "DeepSeek R1 Distill Qwen 14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.431, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 16384, - }, - }, - "deepseek-r1-distill-qwen-32b": { - ID: "deepseek-r1-distill-qwen-32b", - Name: "DeepSeek R1 Distill Qwen 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 16384, - }, - }, - "deepseek-r1-distill-qwen-7b": { - ID: "deepseek-r1-distill-qwen-7b", - Name: "DeepSeek R1 Distill Qwen 7B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.072, - Output: 0.144, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 16384, - }, - }, - "deepseek-v3": { - ID: "deepseek-v3", - Name: "DeepSeek V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 1.147, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 8192, - }, - }, - "deepseek-v3-1": { - ID: "deepseek-v3-1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 1.721, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "deepseek-v3-2-exp": { - ID: "deepseek-v3-2-exp", - Name: "DeepSeek V3.2 Exp", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.431, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "moonshot-kimi-k2-instruct": { - ID: "moonshot-kimi-k2-instruct", - Name: "Moonshot Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 2.294, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "qvq-max": { - ID: "qvq-max", - Name: "QVQ Max", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.147, - Output: 4.588, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen-deep-research": { - ID: "qwen-deep-research", - Name: "Qwen Deep Research", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 7.742, - Output: 23.367, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 32768, - }, - }, - "qwen-doc-turbo": { - ID: "qwen-doc-turbo", - Name: "Qwen Doc Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.087, - Output: 0.144, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen-flash": { - ID: "qwen-flash", - Name: "Qwen Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.022, - Output: 0.216, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 32768, - }, - }, - "qwen-long": { - ID: "qwen-long", - Name: "Qwen Long", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.072, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 10000000, - Output: 8192, - }, - }, - "qwen-math-plus": { - ID: "qwen-math-plus", - Name: "Qwen Math Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 1.721, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 3072, - }, - }, - "qwen-math-turbo": { - ID: "qwen-math-turbo", - Name: "Qwen Math Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 3072, - }, - }, - "qwen-max": { - ID: "qwen-max", - Name: "Qwen Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.345, - Output: 1.377, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen-mt-plus": { - ID: "qwen-mt-plus", - Name: "Qwen-MT Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.259, - Output: 0.775, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 8192, - }, - }, - "qwen-mt-turbo": { - ID: "qwen-mt-turbo", - Name: "Qwen-MT Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.101, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 8192, - }, - }, - "qwen-omni-turbo": { - ID: "qwen-omni-turbo", - Name: "Qwen-Omni Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.058, - Output: 0.23, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "qwen-omni-turbo-realtime": { - ID: "qwen-omni-turbo-realtime", - Name: "Qwen-Omni Turbo Realtime", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.23, - Output: 0.918, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "qwen-plus": { - ID: "qwen-plus", - Name: "Qwen Plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.115, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 32768, - }, - }, - "qwen-plus-character": { - ID: "qwen-plus-character", - Name: "Qwen Plus Character", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.115, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 4096, - }, - }, - "qwen-turbo": { - ID: "qwen-turbo", - Name: "Qwen Turbo", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.044, - Output: 0.087, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 16384, - }, - }, - "qwen-vl-max": { - ID: "qwen-vl-max", - Name: "Qwen-VL Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.23, - Output: 0.574, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen-vl-ocr": { - ID: "qwen-vl-ocr", - Name: "Qwen-VL OCR", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.717, - Output: 0.717, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 34096, - Output: 4096, - }, - }, - "qwen-vl-plus": { - ID: "qwen-vl-plus", - Name: "Qwen-VL Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.115, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-14b-instruct": { - ID: "qwen2-5-14b-instruct", - Name: "Qwen2.5 14B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.431, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-32b-instruct": { - ID: "qwen2-5-32b-instruct", - Name: "Qwen2.5 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-72b-instruct": { - ID: "qwen2-5-72b-instruct", - Name: "Qwen2.5 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 1.721, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-7b-instruct": { - ID: "qwen2-5-7b-instruct", - Name: "Qwen2.5 7B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.072, - Output: 0.144, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-coder-32b-instruct": { - ID: "qwen2-5-coder-32b-instruct", - Name: "Qwen2.5-Coder 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-coder-7b-instruct": { - ID: "qwen2-5-coder-7b-instruct", - Name: "Qwen2.5-Coder 7B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-math-72b-instruct": { - ID: "qwen2-5-math-72b-instruct", - Name: "Qwen2.5-Math 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.574, - Output: 1.721, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 3072, - }, - }, - "qwen2-5-math-7b-instruct": { - ID: "qwen2-5-math-7b-instruct", - Name: "Qwen2.5-Math 7B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 3072, - }, - }, - "qwen2-5-omni-7b": { - ID: "qwen2-5-omni-7b", - Name: "Qwen2.5-Omni 7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.087, - Output: 0.345, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "qwen2-5-vl-72b-instruct": { - ID: "qwen2-5-vl-72b-instruct", - Name: "Qwen2.5-VL 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.294, - Output: 6.881, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen2-5-vl-7b-instruct": { - ID: "qwen2-5-vl-7b-instruct", - Name: "Qwen2.5-VL 7B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.717, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen3-14b": { - ID: "qwen3-14b", - Name: "Qwen3 14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.574, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen3-235b-a22b": { - ID: "qwen3-235b-a22b", - Name: "Qwen3 235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 1.147, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "qwen3-32b": { - ID: "qwen3-32b", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 1.147, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "qwen3-8b": { - ID: "qwen3-8b", - Name: "Qwen3 8B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.072, - Output: 0.287, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen3-asr-flash": { - ID: "qwen3-asr-flash", - Name: "Qwen3-ASR Flash", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.032, - Output: 0.032, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 53248, - Output: 4096, - }, - }, - "qwen3-coder-30b-a3b-instruct": { - ID: "qwen3-coder-30b-a3b-instruct", - Name: "Qwen3-Coder 30B-A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.216, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-coder-480b-a35b-instruct": { - ID: "qwen3-coder-480b-a35b-instruct", - Name: "Qwen3-Coder 480B-A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.861, - Output: 3.441, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-coder-flash": { - ID: "qwen3-coder-flash", - Name: "Qwen3 Coder Flash", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.574, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 65536, - }, - }, - "qwen3-coder-plus": { - ID: "qwen3-coder-plus", - Name: "Qwen3 Coder Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "qwen3-max": { - ID: "qwen3-max", - Name: "Qwen3 Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.861, - Output: 3.441, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-next-80b-a3b-instruct": { - ID: "qwen3-next-80b-a3b-instruct", - Name: "Qwen3-Next 80B-A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 0.574, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-next-80b-a3b-thinking": { - ID: "qwen3-next-80b-a3b-thinking", - Name: "Qwen3-Next 80B-A3B (Thinking)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.144, - Output: 1.434, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-omni-flash": { - ID: "qwen3-omni-flash", - Name: "Qwen3-Omni Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.058, - Output: 0.23, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 16384, - }, - }, - "qwen3-omni-flash-realtime": { - ID: "qwen3-omni-flash-realtime", - Name: "Qwen3-Omni Flash Realtime", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.23, - Output: 0.918, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 16384, - }, - }, - "qwen3-vl-235b-a22b": { - ID: "qwen3-vl-235b-a22b", - Name: "Qwen3-VL 235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.286705, - Output: 1.14682, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-vl-30b-a3b": { - ID: "qwen3-vl-30b-a3b", - Name: "Qwen3-VL 30B-A3B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.108, - Output: 0.431, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-vl-plus": { - ID: "qwen3-vl-plus", - Name: "Qwen3-VL Plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.143353, - Output: 1.433525, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "qwq-32b": { - ID: "qwq-32b", - Name: "QwQ 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.287, - Output: 0.861, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwq-plus": { - ID: "qwq-plus", - Name: "QwQ Plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.23, - Output: 0.574, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "tongyi-intent-detect-v3": { - ID: "tongyi-intent-detect-v3", - Name: "Tongyi Intent Detect V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.058, - Output: 0.144, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 1024, - }, - }, - }, - }, - "amazon-bedrock": { - ID: "amazon-bedrock", - Env: []string{"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION" }, - NPM: "@ai-sdk/amazon-bedrock", - Name: "Amazon Bedrock", - Models: map[string]ModelInfo{ - "ai21.jamba-1-5-large-v1:0": { - ID: "ai21.jamba-1-5-large-v1:0", - Name: "Jamba 1.5 Large", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 4096, - }, - }, - "ai21.jamba-1-5-mini-v1:0": { - ID: "ai21.jamba-1-5-mini-v1:0", - Name: "Jamba 1.5 Mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 4096, - }, - }, - "amazon.nova-2-lite-v1:0": { - ID: "amazon.nova-2-lite-v1:0", - Name: "Nova 2 Lite", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.33, - Output: 2.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "amazon.nova-lite-v1:0": { - ID: "amazon.nova-lite-v1:0", - Name: "Nova Lite", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.24, - CacheRead: &[]float64{0.015}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 300000, - Output: 8192, - }, - }, - "amazon.nova-micro-v1:0": { - ID: "amazon.nova-micro-v1:0", - Name: "Nova Micro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.035, - Output: 0.14, - CacheRead: &[]float64{0.00875}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "amazon.nova-premier-v1:0": { - ID: "amazon.nova-premier-v1:0", - Name: "Nova Premier", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 12.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 16384, - }, - }, - "amazon.nova-pro-v1:0": { - ID: "amazon.nova-pro-v1:0", - Name: "Nova Pro", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 3.2, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 300000, - Output: 8192, - }, - }, - "amazon.titan-text-express-v1": { - ID: "amazon.titan-text-express-v1", - Name: "Titan Text G1 - Express", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "amazon.titan-text-express-v1:0:8k": { - ID: "amazon.titan-text-express-v1:0:8k", - Name: "Titan Text G1 - Express", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "anthropic.claude-3-5-haiku-20241022-v1:0": { - ID: "anthropic.claude-3-5-haiku-20241022-v1:0", - Name: "Claude Haiku 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic.claude-3-5-sonnet-20240620-v1:0": { - ID: "anthropic.claude-3-5-sonnet-20240620-v1:0", - Name: "Claude Sonnet 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic.claude-3-5-sonnet-20241022-v2:0": { - ID: "anthropic.claude-3-5-sonnet-20241022-v2:0", - Name: "Claude Sonnet 3.5 v2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic.claude-3-7-sonnet-20250219-v1:0": { - ID: "anthropic.claude-3-7-sonnet-20250219-v1:0", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic.claude-3-haiku-20240307-v1:0": { - ID: "anthropic.claude-3-haiku-20240307-v1:0", - Name: "Claude Haiku 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic.claude-3-opus-20240229-v1:0": { - ID: "anthropic.claude-3-opus-20240229-v1:0", - Name: "Claude Opus 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic.claude-3-sonnet-20240229-v1:0": { - ID: "anthropic.claude-3-sonnet-20240229-v1:0", - Name: "Claude Sonnet 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic.claude-haiku-4-5-20251001-v1:0": { - ID: "anthropic.claude-haiku-4-5-20251001-v1:0", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic.claude-instant-v1": { - ID: "anthropic.claude-instant-v1", - Name: "Claude Instant", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 2.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 100000, - Output: 4096, - }, - }, - "anthropic.claude-opus-4-1-20250805-v1:0": { - ID: "anthropic.claude-opus-4-1-20250805-v1:0", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic.claude-opus-4-20250514-v1:0": { - ID: "anthropic.claude-opus-4-20250514-v1:0", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic.claude-opus-4-5-20251101-v1:0": { - ID: "anthropic.claude-opus-4-5-20251101-v1:0", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic.claude-sonnet-4-20250514-v1:0": { - ID: "anthropic.claude-sonnet-4-20250514-v1:0", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic.claude-sonnet-4-5-20250929-v1:0": { - ID: "anthropic.claude-sonnet-4-5-20250929-v1:0", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic.claude-v2": { - ID: "anthropic.claude-v2", - Name: "Claude 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 8, - Output: 24, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 100000, - Output: 4096, - }, - }, - "anthropic.claude-v2:1": { - ID: "anthropic.claude-v2:1", - Name: "Claude 2.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 8, - Output: 24, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "cohere.command-light-text-v14": { - ID: "cohere.command-light-text-v14", - Name: "Command Light", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "cohere.command-r-plus-v1:0": { - ID: "cohere.command-r-plus-v1:0", - Name: "Command R+", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cohere.command-r-v1:0": { - ID: "cohere.command-r-v1:0", - Name: "Command R", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cohere.command-text-v14": { - ID: "cohere.command-text-v14", - Name: "Command", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "deepseek.r1-v1:0": { - ID: "deepseek.r1-v1:0", - Name: "DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "deepseek.v3-v1:0": { - ID: "deepseek.v3-v1:0", - Name: "DeepSeek-V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.58, - Output: 1.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 81920, - }, - }, - "global.anthropic.claude-opus-4-5-20251101-v1:0": { - ID: "global.anthropic.claude-opus-4-5-20251101-v1:0", - Name: "Claude Opus 4.5 (Global)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "google.gemma-3-12b-it": { - ID: "google.gemma-3-12b-it", - Name: "Google Gemma 3 12B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.049999999999999996, - Output: 0.09999999999999999, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "google.gemma-3-27b-it": { - ID: "google.gemma-3-27b-it", - Name: "Google Gemma 3 27B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.12, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 8192, - }, - }, - "google.gemma-3-4b-it": { - ID: "google.gemma-3-4b-it", - Name: "Gemma 3 4B IT", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.08, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta.llama3-1-70b-instruct-v1:0": { - ID: "meta.llama3-1-70b-instruct-v1:0", - Name: "Llama 3.1 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.72, - Output: 0.72, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta.llama3-1-8b-instruct-v1:0": { - ID: "meta.llama3-1-8b-instruct-v1:0", - Name: "Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.22, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta.llama3-2-11b-instruct-v1:0": { - ID: "meta.llama3-2-11b-instruct-v1:0", - Name: "Llama 3.2 11B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.16, - Output: 0.16, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta.llama3-2-1b-instruct-v1:0": { - ID: "meta.llama3-2-1b-instruct-v1:0", - Name: "Llama 3.2 1B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 4096, - }, - }, - "meta.llama3-2-3b-instruct-v1:0": { - ID: "meta.llama3-2-3b-instruct-v1:0", - Name: "Llama 3.2 3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 4096, - }, - }, - "meta.llama3-2-90b-instruct-v1:0": { - ID: "meta.llama3-2-90b-instruct-v1:0", - Name: "Llama 3.2 90B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.72, - Output: 0.72, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta.llama3-3-70b-instruct-v1:0": { - ID: "meta.llama3-3-70b-instruct-v1:0", - Name: "Llama 3.3 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.72, - Output: 0.72, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta.llama3-70b-instruct-v1:0": { - ID: "meta.llama3-70b-instruct-v1:0", - Name: "Llama 3 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.65, - Output: 3.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta.llama3-8b-instruct-v1:0": { - ID: "meta.llama3-8b-instruct-v1:0", - Name: "Llama 3 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta.llama4-maverick-17b-instruct-v1:0": { - ID: "meta.llama4-maverick-17b-instruct-v1:0", - Name: "Llama 4 Maverick 17B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.24, - Output: 0.97, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 16384, - }, - }, - "meta.llama4-scout-17b-instruct-v1:0": { - ID: "meta.llama4-scout-17b-instruct-v1:0", - Name: "Llama 4 Scout 17B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.66, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 3500000, - Output: 16384, - }, - }, - "minimax.minimax-m2": { - ID: "minimax.minimax-m2", - Name: "MiniMax M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204608, - Output: 128000, - }, - }, - "mistral.ministral-3-14b-instruct": { - ID: "mistral.ministral-3-14b-instruct", - Name: "Ministral 14B 3.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistral.ministral-3-8b-instruct": { - ID: "mistral.ministral-3-8b-instruct", - Name: "Ministral 3 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistral.mistral-7b-instruct-v0:2": { - ID: "mistral.mistral-7b-instruct-v0:2", - Name: "Mistral-7B-Instruct-v0.3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.11, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 127000, - }, - }, - "mistral.mistral-large-2402-v1:0": { - ID: "mistral.mistral-large-2402-v1:0", - Name: "Mistral Large (24.02)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistral.mixtral-8x7b-instruct-v0:1": { - ID: "mistral.mixtral-8x7b-instruct-v0:1", - Name: "Mixtral-8x7B-Instruct-v0.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 0.7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "mistral.voxtral-mini-3b-2507": { - ID: "mistral.voxtral-mini-3b-2507", - Name: "Voxtral Mini 3B 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistral.voxtral-small-24b-2507": { - ID: "mistral.voxtral-small-24b-2507", - Name: "Voxtral Small 24B 2507", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.35, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 8192, - }, - }, - "moonshot.kimi-k2-thinking": { - ID: "moonshot.kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "nvidia.nemotron-nano-12b-v2": { - ID: "nvidia.nemotron-nano-12b-v2", - Name: "NVIDIA Nemotron Nano 12B v2 VL BF16", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia.nemotron-nano-9b-v2": { - ID: "nvidia.nemotron-nano-9b-v2", - Name: "NVIDIA Nemotron Nano 9B v2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.23, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai.gpt-oss-120b-1:0": { - ID: "openai.gpt-oss-120b-1:0", - Name: "gpt-oss-120b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai.gpt-oss-20b-1:0": { - ID: "openai.gpt-oss-20b-1:0", - Name: "gpt-oss-20b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai.gpt-oss-safeguard-120b": { - ID: "openai.gpt-oss-safeguard-120b", - Name: "GPT OSS Safeguard 120B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai.gpt-oss-safeguard-20b": { - ID: "openai.gpt-oss-safeguard-20b", - Name: "GPT OSS Safeguard 20B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "qwen.qwen3-235b-a22b-2507-v1:0": { - ID: "qwen.qwen3-235b-a22b-2507-v1:0", - Name: "Qwen3 235B A22B 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "qwen.qwen3-32b-v1:0": { - ID: "qwen.qwen3-32b-v1:0", - Name: "Qwen3 32B (dense)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "qwen.qwen3-coder-30b-a3b-v1:0": { - ID: "qwen.qwen3-coder-30b-a3b-v1:0", - Name: "Qwen3 Coder 30B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "qwen.qwen3-coder-480b-a35b-v1:0": { - ID: "qwen.qwen3-coder-480b-a35b-v1:0", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "qwen.qwen3-next-80b-a3b": { - ID: "qwen.qwen3-next-80b-a3b", - Name: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "qwen.qwen3-vl-235b-a22b": { - ID: "qwen.qwen3-vl-235b-a22b", - Name: "Qwen/Qwen3-VL-235B-A22B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - }, - }, - "anthropic": { - ID: "anthropic", - Env: []string{"ANTHROPIC_API_KEY" }, - NPM: "@ai-sdk/anthropic", - Name: "Anthropic", - Models: map[string]ModelInfo{ - "claude-3-5-haiku-20241022": { - ID: "claude-3-5-haiku-20241022", - Name: "Claude Haiku 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3-5-haiku-latest": { - ID: "claude-3-5-haiku-latest", - Name: "Claude Haiku 3.5 (latest)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3-5-sonnet-20240620": { - ID: "claude-3-5-sonnet-20240620", - Name: "Claude Sonnet 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3-5-sonnet-20241022": { - ID: "claude-3-5-sonnet-20241022", - Name: "Claude Sonnet 3.5 v2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3-7-sonnet-20250219": { - ID: "claude-3-7-sonnet-20250219", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-3-7-sonnet-latest": { - ID: "claude-3-7-sonnet-latest", - Name: "Claude Sonnet 3.7 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-3-haiku-20240307": { - ID: "claude-3-haiku-20240307", - Name: "Claude Haiku 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.25, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "claude-3-opus-20240229": { - ID: "claude-3-opus-20240229", - Name: "Claude Opus 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "claude-3-sonnet-20240229": { - ID: "claude-3-sonnet-20240229", - Name: "Claude Sonnet 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "claude-haiku-4-5": { - ID: "claude-haiku-4-5", - Name: "Claude Haiku 4.5 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-haiku-4-5-20251001": { - ID: "claude-haiku-4-5-20251001", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-0": { - ID: "claude-opus-4-0", - Name: "Claude Opus 4 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-1": { - ID: "claude-opus-4-1", - Name: "Claude Opus 4.1 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-1-20250805": { - ID: "claude-opus-4-1-20250805", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-20250514": { - ID: "claude-opus-4-20250514", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5": { - ID: "claude-opus-4-5", - Name: "Claude Opus 4.5 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-5-20251101": { - ID: "claude-opus-4-5-20251101", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-0": { - ID: "claude-sonnet-4-0", - Name: "Claude Sonnet 4 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-20250514": { - ID: "claude-sonnet-4-20250514", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-5": { - ID: "claude-sonnet-4-5", - Name: "Claude Sonnet 4.5 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-5-20250929": { - ID: "claude-sonnet-4-5-20250929", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - }, - }, - "azure": { - ID: "azure", - Env: []string{"AZURE_RESOURCE_NAME", "AZURE_API_KEY" }, - NPM: "@ai-sdk/azure", - Name: "Azure", - Models: map[string]ModelInfo{ - "claude-haiku-4-5": { - ID: "claude-haiku-4-5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-1": { - ID: "claude-opus-4-1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5": { - ID: "claude-opus-4-5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-5": { - ID: "claude-sonnet-4-5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "codestral-2501": { - ID: "codestral-2501", - Name: "Codestral 25.01", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "codex-mini": { - ID: "codex-mini", - Name: "Codex Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.5, - Output: 6, - CacheRead: &[]float64{0.375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "cohere-command-a": { - ID: "cohere-command-a", - Name: "Command A", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8000, - }, - }, - "cohere-command-r-08-2024": { - ID: "cohere-command-r-08-2024", - Name: "Command R", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - "cohere-command-r-plus-08-2024": { - ID: "cohere-command-r-plus-08-2024", - Name: "Command R+", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - "cohere-embed-v-4-0": { - ID: "cohere-embed-v-4-0", - Name: "Embed v4", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.12, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 1536, - }, - }, - "cohere-embed-v3-english": { - ID: "cohere-embed-v3-english", - Name: "Embed v3 English", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512, - Output: 1024, - }, - }, - "cohere-embed-v3-multilingual": { - ID: "cohere-embed-v3-multilingual", - Name: "Embed v3 Multilingual", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512, - Output: 1024, - }, - }, - "deepseek-r1": { - ID: "deepseek-r1", - Name: "DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-r1-0528": { - ID: "deepseek-r1-0528", - Name: "DeepSeek-R1-0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-v3-0324": { - ID: "deepseek-v3-0324", - Name: "DeepSeek-V3-0324", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.14, - Output: 4.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek-v3.1": { - ID: "deepseek-v3.1", - Name: "DeepSeek-V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek-v3.2": { - ID: "deepseek-v3.2", - Name: "DeepSeek-V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: &[]float64{0.028}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "deepseek-v3.2-speciale": { - ID: "deepseek-v3.2-speciale", - Name: "DeepSeek-V3.2-Speciale", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-3.5-turbo-0125": { - ID: "gpt-3.5-turbo-0125", - Name: "GPT-3.5 Turbo 0125", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "gpt-3.5-turbo-0301": { - ID: "gpt-3.5-turbo-0301", - Name: "GPT-3.5 Turbo 0301", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "gpt-3.5-turbo-0613": { - ID: "gpt-3.5-turbo-0613", - Name: "GPT-3.5 Turbo 0613", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "gpt-3.5-turbo-1106": { - ID: "gpt-3.5-turbo-1106", - Name: "GPT-3.5 Turbo 1106", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "gpt-3.5-turbo-instruct": { - ID: "gpt-3.5-turbo-instruct", - Name: "GPT-3.5 Turbo Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "gpt-4": { - ID: "gpt-4", - Name: "GPT-4", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 60, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "gpt-4-32k": { - ID: "gpt-4-32k", - Name: "GPT-4 32K", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 60, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "gpt-4-turbo": { - ID: "gpt-4-turbo", - Name: "GPT-4 Turbo", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "gpt-4-turbo-vision": { - ID: "gpt-4-turbo-vision", - Name: "GPT-4 Turbo Vision", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini": { - ID: "gpt-4.1-mini", - Name: "GPT-4.1 mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-nano": { - ID: "gpt-4.1-nano", - Name: "GPT-4.1 nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4o": { - ID: "gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-mini": { - ID: "gpt-4o-mini", - Name: "GPT-4o mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5-chat": { - ID: "gpt-5-chat", - Name: "GPT-5 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5-pro": { - ID: "gpt-5-pro", - Name: "GPT-5 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 272000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5.1-chat": { - ID: "gpt-5.1-chat", - Name: "GPT-5.1 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "GPT-5.1 Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-max": { - ID: "gpt-5.1-codex-max", - Name: "GPT-5.1 Codex Max", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "GPT-5.1 Codex Mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2": { - ID: "gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2-chat": { - ID: "gpt-5.2-chat", - Name: "GPT-5.2 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "grok-3": { - ID: "grok-3", - Name: "Grok 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-mini": { - ID: "grok-3-mini", - Name: "Grok 3 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-4": { - ID: "grok-4", - Name: "Grok 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "grok-4-fast-non-reasoning": { - ID: "grok-4-fast-non-reasoning", - Name: "Grok 4 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-4-fast-reasoning": { - ID: "grok-4-fast-reasoning", - Name: "Grok 4 Fast (Reasoning)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 10000, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "llama-3.2-11b-vision-instruct": { - ID: "llama-3.2-11b-vision-instruct", - Name: "Llama-3.2-11B-Vision-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.37, - Output: 0.37, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-3.2-90b-vision-instruct": { - ID: "llama-3.2-90b-vision-instruct", - Name: "Llama-3.2-90B-Vision-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.04, - Output: 2.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-3.3-70b-instruct": { - ID: "llama-3.3-70b-instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.71, - Output: 0.71, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "llama-4-maverick-17b-128e-instruct-fp8": { - ID: "llama-4-maverick-17b-128e-instruct-fp8", - Name: "Llama 4 Maverick 17B 128E Instruct FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-4-scout-17b-16e-instruct": { - ID: "llama-4-scout-17b-16e-instruct", - Name: "Llama 4 Scout 17B 16E Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.78, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mai-ds-r1": { - ID: "mai-ds-r1", - Name: "MAI-DS-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta-llama-3-70b-instruct": { - ID: "meta-llama-3-70b-instruct", - Name: "Meta-Llama-3-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.68, - Output: 3.54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta-llama-3-8b-instruct": { - ID: "meta-llama-3-8b-instruct", - Name: "Meta-Llama-3-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.61, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta-llama-3.1-405b-instruct": { - ID: "meta-llama-3.1-405b-instruct", - Name: "Meta-Llama-3.1-405B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5.33, - Output: 16, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama-3.1-70b-instruct": { - ID: "meta-llama-3.1-70b-instruct", - Name: "Meta-Llama-3.1-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.68, - Output: 3.54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama-3.1-8b-instruct": { - ID: "meta-llama-3.1-8b-instruct", - Name: "Meta-Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.61, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "ministral-3b": { - ID: "ministral-3b", - Name: "Ministral 3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistral-large-2411": { - ID: "mistral-large-2411", - Name: "Mistral Large 24.11", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "mistral-medium-2505": { - ID: "mistral-medium-2505", - Name: "Mistral Medium 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral-nemo": { - ID: "mistral-nemo", - Name: "Mistral Nemo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral-small-2503": { - ID: "mistral-small-2503", - Name: "Mistral Small 3.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "model-router": { - ID: "model-router", - Name: "Model Router", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.14, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "o1": { - ID: "o1", - Name: "o1", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o1-mini": { - ID: "o1-mini", - Name: "o1-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "o1-preview": { - ID: "o1-preview", - Name: "o1-preview", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 16.5, - Output: 66, - CacheRead: &[]float64{8.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "o3": { - ID: "o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-mini": { - ID: "o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "phi-3-medium-128k-instruct": { - ID: "phi-3-medium-128k-instruct", - Name: "Phi-3-medium-instruct (128k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3-medium-4k-instruct": { - ID: "phi-3-medium-4k-instruct", - Name: "Phi-3-medium-instruct (4k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 1024, - }, - }, - "phi-3-mini-128k-instruct": { - ID: "phi-3-mini-128k-instruct", - Name: "Phi-3-mini-instruct (128k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3-mini-4k-instruct": { - ID: "phi-3-mini-4k-instruct", - Name: "Phi-3-mini-instruct (4k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 1024, - }, - }, - "phi-3-small-128k-instruct": { - ID: "phi-3-small-128k-instruct", - Name: "Phi-3-small-instruct (128k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3-small-8k-instruct": { - ID: "phi-3-small-8k-instruct", - Name: "Phi-3-small-instruct (8k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "phi-3.5-mini-instruct": { - ID: "phi-3.5-mini-instruct", - Name: "Phi-3.5-mini-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3.5-moe-instruct": { - ID: "phi-3.5-moe-instruct", - Name: "Phi-3.5-MoE-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.16, - Output: 0.64, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4": { - ID: "phi-4", - Name: "Phi-4", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.125, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-mini": { - ID: "phi-4-mini", - Name: "Phi-4-mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-mini-reasoning": { - ID: "phi-4-mini-reasoning", - Name: "Phi-4-mini-reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-multimodal": { - ID: "phi-4-multimodal", - Name: "Phi-4-multimodal", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.32, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-reasoning": { - ID: "phi-4-reasoning", - Name: "Phi-4-reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.125, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "phi-4-reasoning-plus": { - ID: "phi-4-reasoning-plus", - Name: "Phi-4-reasoning-plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.125, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "text-embedding-3-large": { - ID: "text-embedding-3-large", - Name: "text-embedding-3-large", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.13, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 3072, - }, - }, - "text-embedding-3-small": { - ID: "text-embedding-3-small", - Name: "text-embedding-3-small", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.02, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 1536, - }, - }, - "text-embedding-ada-002": { - ID: "text-embedding-ada-002", - Name: "text-embedding-ada-002", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 1536, - }, - }, - }, - }, - "azure-cognitive-services": { - ID: "azure-cognitive-services", - Env: []string{"AZURE_COGNITIVE_SERVICES_RESOURCE_NAME", "AZURE_COGNITIVE_SERVICES_API_KEY" }, - NPM: "@ai-sdk/azure", - Name: "Azure Cognitive Services", - Models: map[string]ModelInfo{ - "claude-haiku-4-5": { - ID: "claude-haiku-4-5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-1": { - ID: "claude-opus-4-1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5": { - ID: "claude-opus-4-5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-5": { - ID: "claude-sonnet-4-5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "codestral-2501": { - ID: "codestral-2501", - Name: "Codestral 25.01", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "codex-mini": { - ID: "codex-mini", - Name: "Codex Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.5, - Output: 6, - CacheRead: &[]float64{0.375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "cohere-command-a": { - ID: "cohere-command-a", - Name: "Command A", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8000, - }, - }, - "cohere-command-r-08-2024": { - ID: "cohere-command-r-08-2024", - Name: "Command R", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - "cohere-command-r-plus-08-2024": { - ID: "cohere-command-r-plus-08-2024", - Name: "Command R+", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - "cohere-embed-v-4-0": { - ID: "cohere-embed-v-4-0", - Name: "Embed v4", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.12, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 1536, - }, - }, - "cohere-embed-v3-english": { - ID: "cohere-embed-v3-english", - Name: "Embed v3 English", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512, - Output: 1024, - }, - }, - "cohere-embed-v3-multilingual": { - ID: "cohere-embed-v3-multilingual", - Name: "Embed v3 Multilingual", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512, - Output: 1024, - }, - }, - "deepseek-r1": { - ID: "deepseek-r1", - Name: "DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-r1-0528": { - ID: "deepseek-r1-0528", - Name: "DeepSeek-R1-0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-v3-0324": { - ID: "deepseek-v3-0324", - Name: "DeepSeek-V3-0324", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.14, - Output: 4.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek-v3.1": { - ID: "deepseek-v3.1", - Name: "DeepSeek-V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek-v3.2": { - ID: "deepseek-v3.2", - Name: "DeepSeek-V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: &[]float64{0.028}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "deepseek-v3.2-speciale": { - ID: "deepseek-v3.2-speciale", - Name: "DeepSeek-V3.2-Speciale", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-3.5-turbo-0125": { - ID: "gpt-3.5-turbo-0125", - Name: "GPT-3.5 Turbo 0125", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "gpt-3.5-turbo-0301": { - ID: "gpt-3.5-turbo-0301", - Name: "GPT-3.5 Turbo 0301", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "gpt-3.5-turbo-0613": { - ID: "gpt-3.5-turbo-0613", - Name: "GPT-3.5 Turbo 0613", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "gpt-3.5-turbo-1106": { - ID: "gpt-3.5-turbo-1106", - Name: "GPT-3.5 Turbo 1106", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "gpt-3.5-turbo-instruct": { - ID: "gpt-3.5-turbo-instruct", - Name: "GPT-3.5 Turbo Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "gpt-4": { - ID: "gpt-4", - Name: "GPT-4", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 60, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "gpt-4-32k": { - ID: "gpt-4-32k", - Name: "GPT-4 32K", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 60, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "gpt-4-turbo": { - ID: "gpt-4-turbo", - Name: "GPT-4 Turbo", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "gpt-4-turbo-vision": { - ID: "gpt-4-turbo-vision", - Name: "GPT-4 Turbo Vision", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini": { - ID: "gpt-4.1-mini", - Name: "GPT-4.1 mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-nano": { - ID: "gpt-4.1-nano", - Name: "GPT-4.1 nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4o": { - ID: "gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-mini": { - ID: "gpt-4o-mini", - Name: "GPT-4o mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5-chat": { - ID: "gpt-5-chat", - Name: "GPT-5 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5-pro": { - ID: "gpt-5-pro", - Name: "GPT-5 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 272000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 272000, - Output: 128000, - }, - }, - "gpt-5.1-chat": { - ID: "gpt-5.1-chat", - Name: "GPT-5.1 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "GPT-5.1 Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "GPT-5.1 Codex Mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2-chat": { - ID: "gpt-5.2-chat", - Name: "GPT-5.2 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "grok-3": { - ID: "grok-3", - Name: "Grok 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-mini": { - ID: "grok-3-mini", - Name: "Grok 3 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-4": { - ID: "grok-4", - Name: "Grok 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "grok-4-fast-non-reasoning": { - ID: "grok-4-fast-non-reasoning", - Name: "Grok 4 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-4-fast-reasoning": { - ID: "grok-4-fast-reasoning", - Name: "Grok 4 Fast (Reasoning)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 10000, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "llama-3.2-11b-vision-instruct": { - ID: "llama-3.2-11b-vision-instruct", - Name: "Llama-3.2-11B-Vision-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.37, - Output: 0.37, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-3.2-90b-vision-instruct": { - ID: "llama-3.2-90b-vision-instruct", - Name: "Llama-3.2-90B-Vision-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.04, - Output: 2.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-3.3-70b-instruct": { - ID: "llama-3.3-70b-instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.71, - Output: 0.71, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "llama-4-maverick-17b-128e-instruct-fp8": { - ID: "llama-4-maverick-17b-128e-instruct-fp8", - Name: "Llama 4 Maverick 17B 128E Instruct FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-4-scout-17b-16e-instruct": { - ID: "llama-4-scout-17b-16e-instruct", - Name: "Llama 4 Scout 17B 16E Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.78, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mai-ds-r1": { - ID: "mai-ds-r1", - Name: "MAI-DS-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta-llama-3-70b-instruct": { - ID: "meta-llama-3-70b-instruct", - Name: "Meta-Llama-3-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.68, - Output: 3.54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta-llama-3-8b-instruct": { - ID: "meta-llama-3-8b-instruct", - Name: "Meta-Llama-3-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.61, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta-llama-3.1-405b-instruct": { - ID: "meta-llama-3.1-405b-instruct", - Name: "Meta-Llama-3.1-405B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5.33, - Output: 16, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama-3.1-70b-instruct": { - ID: "meta-llama-3.1-70b-instruct", - Name: "Meta-Llama-3.1-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.68, - Output: 3.54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama-3.1-8b-instruct": { - ID: "meta-llama-3.1-8b-instruct", - Name: "Meta-Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.61, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "ministral-3b": { - ID: "ministral-3b", - Name: "Ministral 3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistral-large-2411": { - ID: "mistral-large-2411", - Name: "Mistral Large 24.11", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "mistral-medium-2505": { - ID: "mistral-medium-2505", - Name: "Mistral Medium 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral-nemo": { - ID: "mistral-nemo", - Name: "Mistral Nemo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral-small-2503": { - ID: "mistral-small-2503", - Name: "Mistral Small 3.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "model-router": { - ID: "model-router", - Name: "Model Router", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.14, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "o1": { - ID: "o1", - Name: "o1", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o1-mini": { - ID: "o1-mini", - Name: "o1-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "o1-preview": { - ID: "o1-preview", - Name: "o1-preview", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 16.5, - Output: 66, - CacheRead: &[]float64{8.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "o3": { - ID: "o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-mini": { - ID: "o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "phi-3-medium-128k-instruct": { - ID: "phi-3-medium-128k-instruct", - Name: "Phi-3-medium-instruct (128k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3-medium-4k-instruct": { - ID: "phi-3-medium-4k-instruct", - Name: "Phi-3-medium-instruct (4k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 1024, - }, - }, - "phi-3-mini-128k-instruct": { - ID: "phi-3-mini-128k-instruct", - Name: "Phi-3-mini-instruct (128k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3-mini-4k-instruct": { - ID: "phi-3-mini-4k-instruct", - Name: "Phi-3-mini-instruct (4k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 1024, - }, - }, - "phi-3-small-128k-instruct": { - ID: "phi-3-small-128k-instruct", - Name: "Phi-3-small-instruct (128k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3-small-8k-instruct": { - ID: "phi-3-small-8k-instruct", - Name: "Phi-3-small-instruct (8k)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "phi-3.5-mini-instruct": { - ID: "phi-3.5-mini-instruct", - Name: "Phi-3.5-mini-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-3.5-moe-instruct": { - ID: "phi-3.5-moe-instruct", - Name: "Phi-3.5-MoE-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.16, - Output: 0.64, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4": { - ID: "phi-4", - Name: "Phi-4", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.125, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-mini": { - ID: "phi-4-mini", - Name: "Phi-4-mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-mini-reasoning": { - ID: "phi-4-mini-reasoning", - Name: "Phi-4-mini-reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-multimodal": { - ID: "phi-4-multimodal", - Name: "Phi-4-multimodal", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.32, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "phi-4-reasoning": { - ID: "phi-4-reasoning", - Name: "Phi-4-reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.125, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "phi-4-reasoning-plus": { - ID: "phi-4-reasoning-plus", - Name: "Phi-4-reasoning-plus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.125, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "text-embedding-3-large": { - ID: "text-embedding-3-large", - Name: "text-embedding-3-large", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.13, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 3072, - }, - }, - "text-embedding-3-small": { - ID: "text-embedding-3-small", - Name: "text-embedding-3-small", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.02, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 1536, - }, - }, - "text-embedding-ada-002": { - ID: "text-embedding-ada-002", - Name: "text-embedding-ada-002", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 1536, - }, - }, - }, - }, - "bailing": { - ID: "bailing", - Env: []string{"BAILING_API_TOKEN" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Bailing", - Models: map[string]ModelInfo{ - "Ling-1T": { - ID: "Ling-1T", - Name: "Ling-1T", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.57, - Output: 2.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "Ring-1T": { - ID: "Ring-1T", - Name: "Ring-1T", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.57, - Output: 2.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - }, - }, - "baseten": { - ID: "baseten", - Env: []string{"BASETEN_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Baseten", - Models: map[string]ModelInfo{ - "Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.38, - Output: 1.53, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "deepseek-ai/DeepSeek-V3.2": { - ID: "deepseek-ai/DeepSeek-V3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163800, - Output: 131100, - }, - }, - "moonshotai/Kimi-K2-Instruct-0905": { - ID: "moonshotai/Kimi-K2-Instruct-0905", - Name: "Kimi K2 Instruct 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "zai-org/GLM-4.6": { - ID: "zai-org/GLM-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 200000, - }, - }, - "zai-org/GLM-4.7": { - ID: "zai-org/GLM-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "cerebras": { - ID: "cerebras", - Env: []string{"CEREBRAS_API_KEY" }, - NPM: "@ai-sdk/cerebras", - Name: "Cerebras", - Models: map[string]ModelInfo{ - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.69, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen-3-235b-a22b-instruct-2507": { - ID: "qwen-3-235b-a22b-instruct-2507", - Name: "Qwen 3 235B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 32000, - }, - }, - "zai-glm-4.6": { - ID: "zai-glm-4.6", - Name: "Z.AI GLM-4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 40960, - }, - }, - "zai-glm-4.7": { - ID: "zai-glm-4.7", - Name: "Z.AI GLM-4.7", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 40000, - }, - }, - }, - }, - "chutes": { - ID: "chutes", - Env: []string{"CHUTES_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Chutes", - Models: map[string]ModelInfo{ - "MiniMaxAI/MiniMax-M2.1-TEE": { - ID: "MiniMaxAI/MiniMax-M2.1-TEE", - Name: "MiniMax M2.1 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 65536, - }, - }, - "NousResearch/DeepHermes-3-Mistral-24B-Preview": { - ID: "NousResearch/DeepHermes-3-Mistral-24B-Preview", - Name: "DeepHermes 3 Mistral 24B Preview", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.1, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "NousResearch/Hermes-4-14B": { - ID: "NousResearch/Hermes-4-14B", - Name: "Hermes 4 14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.05, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "NousResearch/Hermes-4-405B-FP8-TEE": { - ID: "NousResearch/Hermes-4-405B-FP8-TEE", - Name: "Hermes 4 405B FP8 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "NousResearch/Hermes-4-70B": { - ID: "NousResearch/Hermes-4-70B", - Name: "Hermes 4 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.38, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "NousResearch/Hermes-4.3-36B": { - ID: "NousResearch/Hermes-4.3-36B", - Name: "Hermes 4.3 36B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.39, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 524288, - Output: 524288, - }, - }, - "OpenGVLab/InternVL3-78B-TEE": { - ID: "OpenGVLab/InternVL3-78B-TEE", - Name: "InternVL3 78B TEE", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.39, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "Qwen/Qwen2.5-72B-Instruct": { - ID: "Qwen/Qwen2.5-72B-Instruct", - Name: "Qwen2.5 72B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.52, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "Qwen/Qwen2.5-Coder-32B-Instruct": { - ID: "Qwen/Qwen2.5-Coder-32B-Instruct", - Name: "Qwen2.5 Coder 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.11, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "Qwen/Qwen2.5-VL-32B-Instruct": { - ID: "Qwen/Qwen2.5-VL-32B-Instruct", - Name: "Qwen2.5 VL 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.22, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "Qwen/Qwen2.5-VL-72B-Instruct-TEE": { - ID: "Qwen/Qwen2.5-VL-72B-Instruct-TEE", - Name: "Qwen2.5 VL 72B Instruct TEE", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "Qwen/Qwen3-14B": { - ID: "Qwen/Qwen3-14B", - Name: "Qwen3 14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.22, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "Qwen/Qwen3-235B-A22B": { - ID: "Qwen/Qwen3-235B-A22B", - Name: "Qwen3 235B A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "Qwen/Qwen3-235B-A22B-Instruct-2507-TEE": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507-TEE", - Name: "Qwen3 235B A22B Instruct 2507 TEE", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.55, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.6, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "Qwen/Qwen3-30B-A3B": { - ID: "Qwen/Qwen3-30B-A3B", - Name: "Qwen3 30B A3B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.22, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "Qwen/Qwen3-30B-A3B-Instruct-2507": { - ID: "Qwen/Qwen3-30B-A3B-Instruct-2507", - Name: "Qwen3 30B A3B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.33, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "Qwen/Qwen3-32B": { - ID: "Qwen/Qwen3-32B", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.24, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8-TEE": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8-TEE", - Name: "Qwen3 Coder 480B A35B Instruct FP8 TEE", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.95, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Instruct": { - ID: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Name: "Qwen3 Next 80B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.8, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "Qwen/Qwen3-VL-235B-A22B-Instruct": { - ID: "Qwen/Qwen3-VL-235B-A22B-Instruct", - Name: "Qwen3 VL 235B A22B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "Qwen/Qwen3Guard-Gen-0.6B": { - ID: "Qwen/Qwen3Guard-Gen-0.6B", - Name: "Qwen3Guard Gen 0.6B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.01, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "XiaomiMiMo/MiMo-V2-Flash": { - ID: "XiaomiMiMo/MiMo-V2-Flash", - Name: "MiMo V2 Flash", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.65, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "chutesai/Mistral-Small-3.1-24B-Instruct-2503": { - ID: "chutesai/Mistral-Small-3.1-24B-Instruct-2503", - Name: "Mistral Small 3.1 24B Instruct 2503", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.11, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "chutesai/Mistral-Small-3.2-24B-Instruct-2506": { - ID: "chutesai/Mistral-Small-3.2-24B-Instruct-2506", - Name: "Mistral Small 3.2 24B Instruct 2506", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.18, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek-ai/DeepSeek-R1-0528-TEE": { - ID: "deepseek-ai/DeepSeek-R1-0528-TEE", - Name: "DeepSeek R1 0528 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.75, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Llama-70B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Llama-70B", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.11, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek-ai/DeepSeek-R1-TEE": { - ID: "deepseek-ai/DeepSeek-R1-TEE", - Name: "DeepSeek R1 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-ai/DeepSeek-V3": { - ID: "deepseek-ai/DeepSeek-V3", - Name: "DeepSeek V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-ai/DeepSeek-V3-0324-TEE": { - ID: "deepseek-ai/DeepSeek-V3-0324-TEE", - Name: "DeepSeek V3 0324 TEE", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.19, - Output: 0.87, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "deepseek-ai/DeepSeek-V3.1-TEE": { - ID: "deepseek-ai/DeepSeek-V3.1-TEE", - Name: "DeepSeek V3.1 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "deepseek-ai/DeepSeek-V3.1-Terminus-TEE": { - ID: "deepseek-ai/DeepSeek-V3.1-Terminus-TEE", - Name: "DeepSeek V3.1 Terminus TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.23, - Output: 0.9, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "deepseek-ai/DeepSeek-V3.2-Speciale-TEE": { - ID: "deepseek-ai/DeepSeek-V3.2-Speciale-TEE", - Name: "DeepSeek V3.2 Speciale TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.41, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "deepseek-ai/DeepSeek-V3.2-TEE": { - ID: "deepseek-ai/DeepSeek-V3.2-TEE", - Name: "DeepSeek V3.2 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.38, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "mistralai/Devstral-2-123B-Instruct-2512": { - ID: "mistralai/Devstral-2-123B-Instruct-2512", - Name: "Devstral 2 123B Instruct 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.22, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "moonshotai/Kimi-K2-Instruct-0905": { - ID: "moonshotai/Kimi-K2-Instruct-0905", - Name: "Kimi K2 Instruct 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.39, - Output: 1.9, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "moonshotai/Kimi-K2-Thinking-TEE": { - ID: "moonshotai/Kimi-K2-Thinking-TEE", - Name: "Kimi K2 Thinking TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.75, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 65535, - }, - }, - "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16": { - ID: "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16", - Name: "NVIDIA Nemotron 3 Nano 30B A3B BF16", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.24, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "openai/gpt-oss-120b-TEE": { - ID: "openai/gpt-oss-120b-TEE", - Name: "gpt oss 120b TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.18, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "gpt oss 20b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.1, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "rednote-hilab/dots.ocr": { - ID: "rednote-hilab/dots.ocr", - Name: "dots.ocr", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.01, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "tngtech/DeepSeek-R1T-Chimera": { - ID: "tngtech/DeepSeek-R1T-Chimera", - Name: "DeepSeek R1T Chimera", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "tngtech/DeepSeek-TNG-R1T2-Chimera": { - ID: "tngtech/DeepSeek-TNG-R1T2-Chimera", - Name: "DeepSeek TNG R1T2 Chimera", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.85, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "tngtech/DeepSeek-TNG-R1T2-Chimera-TEE": { - ID: "tngtech/DeepSeek-TNG-R1T2-Chimera-TEE", - Name: "DeepSeek TNG R1T2 Chimera TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.85, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "tngtech/TNG-R1T-Chimera-TEE": { - ID: "tngtech/TNG-R1T-Chimera-TEE", - Name: "TNG R1T Chimera TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.85, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "unsloth/Mistral-Nemo-Instruct-2407": { - ID: "unsloth/Mistral-Nemo-Instruct-2407", - Name: "Mistral Nemo Instruct 2407", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.04, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "unsloth/Mistral-Small-24B-Instruct-2501": { - ID: "unsloth/Mistral-Small-24B-Instruct-2501", - Name: "Mistral Small 24B Instruct 2501", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.11, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "unsloth/gemma-3-12b-it": { - ID: "unsloth/gemma-3-12b-it", - Name: "gemma 3 12b it", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.1, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "unsloth/gemma-3-27b-it": { - ID: "unsloth/gemma-3-27b-it", - Name: "gemma 3 27b it", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.15, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 96000, - Output: 96000, - }, - }, - "unsloth/gemma-3-4b-it": { - ID: "unsloth/gemma-3-4b-it", - Name: "gemma 3 4b it", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.03, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 96000, - Output: 96000, - }, - }, - "zai-org/GLM-4.5-Air": { - ID: "zai-org/GLM-4.5-Air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.22, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "zai-org/GLM-4.5-TEE": { - ID: "zai-org/GLM-4.5-TEE", - Name: "GLM 4.5 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.55, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "zai-org/GLM-4.6-TEE": { - ID: "zai-org/GLM-4.6-TEE", - Name: "GLM 4.6 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.5, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 202752, - Output: 65536, - }, - }, - "zai-org/GLM-4.6V": { - ID: "zai-org/GLM-4.6V", - Name: "GLM 4.6V", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "zai-org/GLM-4.7-TEE": { - ID: "zai-org/GLM-4.7-TEE", - Name: "GLM 4.7 TEE", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.5, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 202752, - Output: 65535, - }, - }, - }, - }, - "cloudflare-ai-gateway": { - ID: "cloudflare-ai-gateway", - Env: []string{"CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_GATEWAY_ID" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Cloudflare AI Gateway", - Models: map[string]ModelInfo{ - "anthropic/claude-3-5-haiku": { - ID: "anthropic/claude-3-5-haiku", - Name: "Claude Haiku 3.5 (latest)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic/claude-3-haiku": { - ID: "anthropic/claude-3-haiku", - Name: "Claude Haiku 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.25, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic/claude-3-opus": { - ID: "anthropic/claude-3-opus", - Name: "Claude Opus 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic/claude-3-sonnet": { - ID: "anthropic/claude-3-sonnet", - Name: "Claude Sonnet 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic/claude-3.5-haiku": { - ID: "anthropic/claude-3.5-haiku", - Name: "Claude Haiku 3.5 (latest)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic/claude-3.5-sonnet": { - ID: "anthropic/claude-3.5-sonnet", - Name: "Claude Sonnet 3.5 v2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic/claude-haiku-4-5": { - ID: "anthropic/claude-haiku-4-5", - Name: "Claude Haiku 4.5 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-opus-4": { - ID: "anthropic/claude-opus-4", - Name: "Claude Opus 4 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4-1": { - ID: "anthropic/claude-opus-4-1", - Name: "Claude Opus 4.1 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4-5": { - ID: "anthropic/claude-opus-4-5", - Name: "Claude Opus 4.5 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4": { - ID: "anthropic/claude-sonnet-4", - Name: "Claude Sonnet 4 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4-5": { - ID: "anthropic/claude-sonnet-4-5", - Name: "Claude Sonnet 4.5 (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "openai/gpt-3.5-turbo": { - ID: "openai/gpt-3.5-turbo", - Name: "GPT-3.5-turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16385, - Output: 4096, - }, - }, - "openai/gpt-4": { - ID: "openai/gpt-4", - Name: "GPT-4", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 30, - Output: 60, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "openai/gpt-4-turbo": { - ID: "openai/gpt-4-turbo", - Name: "GPT-4 Turbo", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai/gpt-4o": { - ID: "openai/gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-4o-mini": { - ID: "openai/gpt-4o-mini", - Name: "GPT-4o mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5.1": { - ID: "openai/gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-codex": { - ID: "openai/gpt-5.1-codex", - Name: "GPT-5.1 Codex", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.2": { - ID: "openai/gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/o1": { - ID: "openai/o1", - Name: "o1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3": { - ID: "openai/o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-mini": { - ID: "openai/o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-pro": { - ID: "openai/o3-pro", - Name: "o3-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 20, - Output: 80, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o4-mini": { - ID: "openai/o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B": { - ID: "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B", - Name: "IndicTrans2 EN-Indic 1B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.34, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it": { - ID: "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it", - Name: "Gemma SEA-LION v4 27B IT", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/baai/bge-base-en-v1.5": { - ID: "workers-ai/@cf/baai/bge-base-en-v1.5", - Name: "BGE Base EN v1.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.067, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/baai/bge-large-en-v1.5": { - ID: "workers-ai/@cf/baai/bge-large-en-v1.5", - Name: "BGE Large EN v1.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/baai/bge-m3": { - ID: "workers-ai/@cf/baai/bge-m3", - Name: "BGE M3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.012, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/baai/bge-reranker-base": { - ID: "workers-ai/@cf/baai/bge-reranker-base", - Name: "BGE Reranker Base", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.0031, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/baai/bge-small-en-v1.5": { - ID: "workers-ai/@cf/baai/bge-small-en-v1.5", - Name: "BGE Small EN v1.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/deepgram/aura-2-en": { - ID: "workers-ai/@cf/deepgram/aura-2-en", - Name: "Deepgram Aura 2 (EN)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/deepgram/aura-2-es": { - ID: "workers-ai/@cf/deepgram/aura-2-es", - Name: "Deepgram Aura 2 (ES)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/deepgram/nova-3": { - ID: "workers-ai/@cf/deepgram/nova-3", - Name: "Deepgram Nova 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b": { - ID: "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", - Name: "DeepSeek R1 Distill Qwen 32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 4.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/facebook/bart-large-cnn": { - ID: "workers-ai/@cf/facebook/bart-large-cnn", - Name: "BART Large CNN", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/google/gemma-3-12b-it": { - ID: "workers-ai/@cf/google/gemma-3-12b-it", - Name: "Gemma 3 12B IT", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/huggingface/distilbert-sst-2-int8": { - ID: "workers-ai/@cf/huggingface/distilbert-sst-2-int8", - Name: "DistilBERT SST-2 INT8", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.026, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/ibm-granite/granite-4.0-h-micro": { - ID: "workers-ai/@cf/ibm-granite/granite-4.0-h-micro", - Name: "IBM Granite 4.0 H Micro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.017, - Output: 0.11, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-2-7b-chat-fp16": { - ID: "workers-ai/@cf/meta/llama-2-7b-chat-fp16", - Name: "Llama 2 7B Chat FP16", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 6.67, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3-8b-instruct": { - ID: "workers-ai/@cf/meta/llama-3-8b-instruct", - Name: "Llama 3 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.83, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3-8b-instruct-awq": { - ID: "workers-ai/@cf/meta/llama-3-8b-instruct-awq", - Name: "Llama 3 8B Instruct AWQ", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.12, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.1-8b-instruct": { - ID: "workers-ai/@cf/meta/llama-3.1-8b-instruct", - Name: "Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.8299999999999998, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq": { - ID: "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq", - Name: "Llama 3.1 8B Instruct AWQ", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.12, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8": { - ID: "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8", - Name: "Llama 3.1 8B Instruct FP8", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct": { - ID: "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct", - Name: "Llama 3.2 11B Vision Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.049, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.2-1b-instruct": { - ID: "workers-ai/@cf/meta/llama-3.2-1b-instruct", - Name: "Llama 3.2 1B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.027, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.2-3b-instruct": { - ID: "workers-ai/@cf/meta/llama-3.2-3b-instruct", - Name: "Llama 3.2 3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.051, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast": { - ID: "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast", - Name: "Llama 3.3 70B Instruct FP8 Fast", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 2.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct": { - ID: "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct", - Name: "Llama 4 Scout 17B 16E Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.85, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/llama-guard-3-8b": { - ID: "workers-ai/@cf/meta/llama-guard-3-8b", - Name: "Llama Guard 3 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.48, - Output: 0.03, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/meta/m2m100-1.2b": { - ID: "workers-ai/@cf/meta/m2m100-1.2b", - Name: "M2M100 1.2B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.34, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1": { - ID: "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1", - Name: "Mistral 7B Instruct v0.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct": { - ID: "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct", - Name: "Mistral Small 3.1 24B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/myshell-ai/melotts": { - ID: "workers-ai/@cf/myshell-ai/melotts", - Name: "MyShell MeloTTS", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/openai/gpt-oss-120b": { - ID: "workers-ai/@cf/openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/openai/gpt-oss-20b": { - ID: "workers-ai/@cf/openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/pfnet/plamo-embedding-1b": { - ID: "workers-ai/@cf/pfnet/plamo-embedding-1b", - Name: "PLaMo Embedding 1B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.019, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/pipecat-ai/smart-turn-v2": { - ID: "workers-ai/@cf/pipecat-ai/smart-turn-v2", - Name: "Pipecat Smart Turn v2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct": { - ID: "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct", - Name: "Qwen 2.5 Coder 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.66, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8": { - ID: "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8", - Name: "Qwen3 30B A3B FP8", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.051, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/qwen/qwen3-embedding-0.6b": { - ID: "workers-ai/@cf/qwen/qwen3-embedding-0.6b", - Name: "Qwen3 Embedding 0.6B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.012, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "workers-ai/@cf/qwen/qwq-32b": { - ID: "workers-ai/@cf/qwen/qwq-32b", - Name: "QwQ 32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.66, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - }, - }, - "cloudflare-workers-ai": { - ID: "cloudflare-workers-ai", - Env: []string{"CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_KEY" }, - NPM: "workers-ai-provider", - Name: "Cloudflare Workers AI", - Models: map[string]ModelInfo{ - "aura-1": { - ID: "aura-1", - Name: "@cf/deepgram/aura-1", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.015, - Output: 0.015, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "bart-large-cnn": { - ID: "bart-large-cnn", - Name: "@cf/facebook/bart-large-cnn", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "deepseek-coder-6.7b-base-awq": { - ID: "deepseek-coder-6.7b-base-awq", - Name: "@hf/thebloke/deepseek-coder-6.7b-base-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "deepseek-coder-6.7b-instruct-awq": { - ID: "deepseek-coder-6.7b-instruct-awq", - Name: "@hf/thebloke/deepseek-coder-6.7b-instruct-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "deepseek-math-7b-instruct": { - ID: "deepseek-math-7b-instruct", - Name: "@cf/deepseek-ai/deepseek-math-7b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "deepseek-r1-distill-qwen-32b": { - ID: "deepseek-r1-distill-qwen-32b", - Name: "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 4.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 80000, - Output: 80000, - }, - }, - "discolm-german-7b-v1-awq": { - ID: "discolm-german-7b-v1-awq", - Name: "@cf/thebloke/discolm-german-7b-v1-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "dreamshaper-8-lcm": { - ID: "dreamshaper-8-lcm", - Name: "@cf/lykon/dreamshaper-8-lcm", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "falcon-7b-instruct": { - ID: "falcon-7b-instruct", - Name: "@cf/tiiuae/falcon-7b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "flux-1-schnell": { - ID: "flux-1-schnell", - Name: "@cf/black-forest-labs/flux-1-schnell", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 5.3e-05, - Output: 0.00011, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2048, - Output: 0, - }, - }, - "gemma-2b-it-lora": { - ID: "gemma-2b-it-lora", - Name: "@cf/google/gemma-2b-it-lora", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "gemma-3-12b-it": { - ID: "gemma-3-12b-it", - Name: "@cf/google/gemma-3-12b-it", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 80000, - Output: 80000, - }, - }, - "gemma-7b-it": { - ID: "gemma-7b-it", - Name: "@hf/google/gemma-7b-it", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "gemma-7b-it-lora": { - ID: "gemma-7b-it-lora", - Name: "@cf/google/gemma-7b-it-lora", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 3500, - Output: 3500, - }, - }, - "gemma-sea-lion-v4-27b-it": { - ID: "gemma-sea-lion-v4-27b-it", - Name: "@cf/aisingapore/gemma-sea-lion-v4-27b-it", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 0, - }, - }, - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "@cf/openai/gpt-oss-120b", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.35, - Output: 0.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-oss-20b": { - ID: "gpt-oss-20b", - Name: "@cf/openai/gpt-oss-20b", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.2, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "granite-4.0-h-micro": { - ID: "granite-4.0-h-micro", - Name: "@cf/ibm-granite/granite-4.0-h-micro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.017, - Output: 0.11, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 0, - }, - }, - "hermes-2-pro-mistral-7b": { - ID: "hermes-2-pro-mistral-7b", - Name: "@hf/nousresearch/hermes-2-pro-mistral-7b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 24000, - Output: 24000, - }, - }, - "llama-2-13b-chat-awq": { - ID: "llama-2-13b-chat-awq", - Name: "@hf/thebloke/llama-2-13b-chat-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "llama-2-7b-chat-fp16": { - ID: "llama-2-7b-chat-fp16", - Name: "@cf/meta/llama-2-7b-chat-fp16", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 6.67, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "llama-2-7b-chat-hf-lora": { - ID: "llama-2-7b-chat-hf-lora", - Name: "@cf/meta-llama/llama-2-7b-chat-hf-lora", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama-2-7b-chat-int8": { - ID: "llama-2-7b-chat-int8", - Name: "@cf/meta/llama-2-7b-chat-int8", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.556, - Output: 6.667, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama-3-8b-instruct": { - ID: "llama-3-8b-instruct", - Name: "@cf/meta/llama-3-8b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.83, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 7968, - Output: 7968, - }, - }, - "llama-3-8b-instruct-awq": { - ID: "llama-3-8b-instruct-awq", - Name: "@cf/meta/llama-3-8b-instruct-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.12, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama-3.1-70b-instruct": { - ID: "llama-3.1-70b-instruct", - Name: "@cf/meta/llama-3.1-70b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.293, - Output: 2.253, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 24000, - Output: 24000, - }, - }, - "llama-3.1-8b-instruct": { - ID: "llama-3.1-8b-instruct", - Name: "@cf/meta/llama-3.1-8b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.83, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 7968, - Output: 7968, - }, - }, - "llama-3.1-8b-instruct-awq": { - ID: "llama-3.1-8b-instruct-awq", - Name: "@cf/meta/llama-3.1-8b-instruct-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.12, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama-3.1-8b-instruct-fast": { - ID: "llama-3.1-8b-instruct-fast", - Name: "@cf/meta/llama-3.1-8b-instruct-fast", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.045, - Output: 0.384, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "llama-3.1-8b-instruct-fp8": { - ID: "llama-3.1-8b-instruct-fp8", - Name: "@cf/meta/llama-3.1-8b-instruct-fp8", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "llama-3.2-11b-vision-instruct": { - ID: "llama-3.2-11b-vision-instruct", - Name: "@cf/meta/llama-3.2-11b-vision-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.049, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "llama-3.2-1b-instruct": { - ID: "llama-3.2-1b-instruct", - Name: "@cf/meta/llama-3.2-1b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.027, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 60000, - Output: 60000, - }, - }, - "llama-3.2-3b-instruct": { - ID: "llama-3.2-3b-instruct", - Name: "@cf/meta/llama-3.2-3b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.051, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "llama-3.3-70b-instruct-fp8-fast": { - ID: "llama-3.3-70b-instruct-fp8-fast", - Name: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 2.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 24000, - Output: 24000, - }, - }, - "llama-4-scout-17b-16e-instruct": { - ID: "llama-4-scout-17b-16e-instruct", - Name: "@cf/meta/llama-4-scout-17b-16e-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.85, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "llama-guard-3-8b": { - ID: "llama-guard-3-8b", - Name: "@cf/meta/llama-guard-3-8b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.48, - Output: 0.03, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 0, - }, - }, - "llamaguard-7b-awq": { - ID: "llamaguard-7b-awq", - Name: "@hf/thebloke/llamaguard-7b-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "llava-1.5-7b-hf": { - ID: "llava-1.5-7b-hf", - Name: "@cf/llava-hf/llava-1.5-7b-hf", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "lucid-origin": { - ID: "lucid-origin", - Name: "@cf/leonardo/lucid-origin", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.007, - Output: 0.007, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "m2m100-1.2b": { - ID: "m2m100-1.2b", - Name: "@cf/meta/m2m100-1.2b", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.34, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "melotts": { - ID: "melotts", - Name: "@cf/myshell-ai/melotts", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.0002, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "mistral-7b-instruct-v0.1": { - ID: "mistral-7b-instruct-v0.1", - Name: "@cf/mistral/mistral-7b-instruct-v0.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2824, - Output: 2824, - }, - }, - "mistral-7b-instruct-v0.1-awq": { - ID: "mistral-7b-instruct-v0.1-awq", - Name: "@hf/thebloke/mistral-7b-instruct-v0.1-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "mistral-7b-instruct-v0.2": { - ID: "mistral-7b-instruct-v0.2", - Name: "@hf/mistral/mistral-7b-instruct-v0.2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 3072, - Output: 4096, - }, - }, - "mistral-7b-instruct-v0.2-lora": { - ID: "mistral-7b-instruct-v0.2-lora", - Name: "@cf/mistral/mistral-7b-instruct-v0.2-lora", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 15000, - Output: 15000, - }, - }, - "mistral-small-3.1-24b-instruct": { - ID: "mistral-small-3.1-24b-instruct", - Name: "@cf/mistralai/mistral-small-3.1-24b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.56, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "neural-chat-7b-v3-1-awq": { - ID: "neural-chat-7b-v3-1-awq", - Name: "@hf/thebloke/neural-chat-7b-v3-1-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "nova-3": { - ID: "nova-3", - Name: "@cf/deepgram/nova-3", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.0052, - Output: 0.0052, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "openchat-3.5-0106": { - ID: "openchat-3.5-0106", - Name: "@cf/openchat/openchat-3.5-0106", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "openhermes-2.5-mistral-7b-awq": { - ID: "openhermes-2.5-mistral-7b-awq", - Name: "@hf/thebloke/openhermes-2.5-mistral-7b-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "phi-2": { - ID: "phi-2", - Name: "@cf/microsoft/phi-2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2048, - Output: 2048, - }, - }, - "phoenix-1.0": { - ID: "phoenix-1.0", - Name: "@cf/leonardo/phoenix-1.0", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.0058, - Output: 0.0058, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "qwen1.5-0.5b-chat": { - ID: "qwen1.5-0.5b-chat", - Name: "@cf/qwen/qwen1.5-0.5b-chat", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "qwen1.5-1.8b-chat": { - ID: "qwen1.5-1.8b-chat", - Name: "@cf/qwen/qwen1.5-1.8b-chat", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "qwen1.5-14b-chat-awq": { - ID: "qwen1.5-14b-chat-awq", - Name: "@cf/qwen/qwen1.5-14b-chat-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 7500, - Output: 7500, - }, - }, - "qwen1.5-7b-chat-awq": { - ID: "qwen1.5-7b-chat-awq", - Name: "@cf/qwen/qwen1.5-7b-chat-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 20000, - Output: 20000, - }, - }, - "qwen2.5-coder-32b-instruct": { - ID: "qwen2.5-coder-32b-instruct", - Name: "@cf/qwen/qwen2.5-coder-32b-instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.66, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "qwen3-30b-a3b-fp8": { - ID: "qwen3-30b-a3b-fp8", - Name: "@cf/qwen/qwen3-30b-a3b-fp8", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.051, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 0, - }, - }, - "qwq-32b": { - ID: "qwq-32b", - Name: "@cf/qwen/qwq-32b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.66, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 24000, - Output: 24000, - }, - }, - "resnet-50": { - ID: "resnet-50", - Name: "@cf/microsoft/resnet-50", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 2.5e-06, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "sqlcoder-7b-2": { - ID: "sqlcoder-7b-2", - Name: "@cf/defog/sqlcoder-7b-2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 10000, - Output: 10000, - }, - }, - "stable-diffusion-v1-5-img2img": { - ID: "stable-diffusion-v1-5-img2img", - Name: "@cf/runwayml/stable-diffusion-v1-5-img2img", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "stable-diffusion-v1-5-inpainting": { - ID: "stable-diffusion-v1-5-inpainting", - Name: "@cf/runwayml/stable-diffusion-v1-5-inpainting", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "stable-diffusion-xl-base-1.0": { - ID: "stable-diffusion-xl-base-1.0", - Name: "@cf/stabilityai/stable-diffusion-xl-base-1.0", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "stable-diffusion-xl-lightning": { - ID: "stable-diffusion-xl-lightning", - Name: "@cf/bytedance/stable-diffusion-xl-lightning", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "starling-lm-7b-beta": { - ID: "starling-lm-7b-beta", - Name: "@hf/nexusflow/starling-lm-7b-beta", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - "tinyllama-1.1b-chat-v1.0": { - ID: "tinyllama-1.1b-chat-v1.0", - Name: "@cf/tinyllama/tinyllama-1.1b-chat-v1.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2048, - Output: 2048, - }, - }, - "uform-gen2-qwen-500m": { - ID: "uform-gen2-qwen-500m", - Name: "@cf/unum/uform-gen2-qwen-500m", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "una-cybertron-7b-v2-bf16": { - ID: "una-cybertron-7b-v2-bf16", - Name: "@cf/fblgit/una-cybertron-7b-v2-bf16", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 15000, - Output: 15000, - }, - }, - "whisper": { - ID: "whisper", - Name: "@cf/openai/whisper", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.00045, - Output: 0.00045, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "whisper-large-v3-turbo": { - ID: "whisper-large-v3-turbo", - Name: "@cf/openai/whisper-large-v3-turbo", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.00051, - Output: 0.00051, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "whisper-tiny-en": { - ID: "whisper-tiny-en", - Name: "@cf/openai/whisper-tiny-en", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "zephyr-7b-beta-awq": { - ID: "zephyr-7b-beta-awq", - Name: "@hf/thebloke/zephyr-7b-beta-awq", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 4096, - }, - }, - }, - }, - "cohere": { - ID: "cohere", - Env: []string{"COHERE_API_KEY" }, - NPM: "@ai-sdk/cohere", - Name: "Cohere", - Models: map[string]ModelInfo{ - "command-a-03-2025": { - ID: "command-a-03-2025", - Name: "Command A", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8000, - }, - }, - "command-a-reasoning-08-2025": { - ID: "command-a-reasoning-08-2025", - Name: "Command A Reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "command-a-translate-08-2025": { - ID: "command-a-translate-08-2025", - Name: "Command A Translate", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8000, - Output: 8000, - }, - }, - "command-a-vision-07-2025": { - ID: "command-a-vision-07-2025", - Name: "Command A Vision", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8000, - }, - }, - "command-r-08-2024": { - ID: "command-r-08-2024", - Name: "Command R", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - "command-r-plus-08-2024": { - ID: "command-r-plus-08-2024", - Name: "Command R+", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - "command-r7b-12-2024": { - ID: "command-r7b-12-2024", - Name: "Command R7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.0375, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4000, - }, - }, - }, - }, - "cortecs": { - ID: "cortecs", - Env: []string{"CORTECS_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Cortecs", - Models: map[string]ModelInfo{ - "claude-4-5-sonnet": { - ID: "claude-4-5-sonnet", - Name: "Claude 4.5 Sonnet", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3.259, - Output: 16.296, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 200000, - }, - }, - "claude-sonnet-4": { - ID: "claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3.307, - Output: 16.536, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "deepseek-v3-0324": { - ID: "deepseek-v3-0324", - Name: "DeepSeek V3 0324", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.551, - Output: 1.654, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "devstral-2512": { - ID: "devstral-2512", - Name: "Devstral 2 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "devstral-small-2512": { - ID: "devstral-small-2512", - Name: "Devstral Small 2 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.654, - Output: 11.024, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65535, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT 4.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.354, - Output: 9.417, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "GPT Oss 120b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "intellect-3": { - ID: "intellect-3", - Name: "INTELLECT 3", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.219, - Output: 1.202, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "kimi-k2-instruct": { - ID: "kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.551, - Output: 2.646, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.656, - Output: 2.731, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "llama-3.1-405b-instruct": { - ID: "llama-3.1-405b-instruct", - Name: "Llama 3.1 405B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "nova-pro-v1": { - ID: "nova-pro-v1", - Name: "Nova Pro 1.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.016, - Output: 4.061, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 300000, - Output: 5000, - }, - }, - "qwen3-32b": { - ID: "qwen3-32b", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.099, - Output: 0.33, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "qwen3-coder-480b-a35b-instruct": { - ID: "qwen3-coder-480b-a35b-instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.441, - Output: 1.984, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "qwen3-next-80b-a3b-thinking": { - ID: "qwen3-next-80b-a3b-thinking", - Name: "Qwen3 Next 80B A3B Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.164, - Output: 1.311, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - }, - }, - "deepinfra": { - ID: "deepinfra", - Env: []string{"DEEPINFRA_API_KEY" }, - NPM: "@ai-sdk/deepinfra", - Name: "Deep Infra", - Models: map[string]ModelInfo{ - "MiniMaxAI/MiniMax-M2": { - ID: "MiniMaxAI/MiniMax-M2", - Name: "MiniMax M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.254, - Output: 1.02, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo", - Name: "Qwen3 Coder 480B A35B Instruct Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "moonshotai/Kimi-K2-Instruct": { - ID: "moonshotai/Kimi-K2-Instruct", - Name: "Kimi K2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.47, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.24, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "zai-org/GLM-4.5": { - ID: "zai-org/GLM-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "zai-org/GLM-4.7": { - ID: "zai-org/GLM-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.43, - Output: 1.75, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 16384, - }, - }, - }, - }, - "deepseek": { - ID: "deepseek", - Env: []string{"DEEPSEEK_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "DeepSeek", - Models: map[string]ModelInfo{ - "deepseek-chat": { - ID: "deepseek-chat", - Name: "DeepSeek Chat", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: &[]float64{0.028}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek-reasoner": { - ID: "deepseek-reasoner", - Name: "DeepSeek Reasoner", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: &[]float64{0.028}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - }, - }, - "fastrouter": { - ID: "fastrouter", - Env: []string{"FASTROUTER_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "FastRouter", - Models: map[string]ModelInfo{ - "anthropic/claude-opus-4.1": { - ID: "anthropic/claude-opus-4.1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-sonnet-4": { - ID: "anthropic/claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "deepseek-ai/deepseek-r1-distill-llama-70b": { - ID: "deepseek-ai/deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "google/gemini-2.5-flash": { - ID: "google/gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.0375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-pro": { - ID: "google/gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "moonshotai/kimi-k2": { - ID: "moonshotai/kimi-k2", - Name: "Kimi K2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-4.1": { - ID: "openai/gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-5": { - ID: "openai/gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-mini": { - ID: "openai/gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-nano": { - ID: "openai/gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.005}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "qwen/qwen3-coder": { - ID: "qwen/qwen3-coder", - Name: "Qwen3 Coder", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "x-ai/grok-4": { - ID: "x-ai/grok-4", - Name: "Grok 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: &[]float64{15}[0], - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - }, - }, - "fireworks-ai": { - ID: "fireworks-ai", - Env: []string{"FIREWORKS_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Fireworks AI", - Models: map[string]ModelInfo{ - "accounts/fireworks/models/deepseek-r1-0528": { - ID: "accounts/fireworks/models/deepseek-r1-0528", - Name: "Deepseek R1 05/28", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 160000, - Output: 16384, - }, - }, - "accounts/fireworks/models/deepseek-v3-0324": { - ID: "accounts/fireworks/models/deepseek-v3-0324", - Name: "Deepseek V3 03-24", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.9, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 160000, - Output: 16384, - }, - }, - "accounts/fireworks/models/deepseek-v3p1": { - ID: "accounts/fireworks/models/deepseek-v3p1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "accounts/fireworks/models/deepseek-v3p2": { - ID: "accounts/fireworks/models/deepseek-v3p2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 160000, - Output: 160000, - }, - }, - "accounts/fireworks/models/glm-4p5": { - ID: "accounts/fireworks/models/glm-4p5", - Name: "GLM 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "accounts/fireworks/models/glm-4p5-air": { - ID: "accounts/fireworks/models/glm-4p5-air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "accounts/fireworks/models/glm-4p6": { - ID: "accounts/fireworks/models/glm-4p6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 198000, - Output: 198000, - }, - }, - "accounts/fireworks/models/glm-4p7": { - ID: "accounts/fireworks/models/glm-4p7", - Name: "GLM 4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.3}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 198000, - Output: 198000, - }, - }, - "accounts/fireworks/models/gpt-oss-120b": { - ID: "accounts/fireworks/models/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "accounts/fireworks/models/gpt-oss-20b": { - ID: "accounts/fireworks/models/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "accounts/fireworks/models/kimi-k2-instruct": { - ID: "accounts/fireworks/models/kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "accounts/fireworks/models/kimi-k2-thinking": { - ID: "accounts/fireworks/models/kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "accounts/fireworks/models/minimax-m2": { - ID: "accounts/fireworks/models/minimax-m2", - Name: "MiniMax-M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 192000, - Output: 192000, - }, - }, - "accounts/fireworks/models/minimax-m2p1": { - ID: "accounts/fireworks/models/minimax-m2p1", - Name: "MiniMax-M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 200000, - }, - }, - "accounts/fireworks/models/qwen3-235b-a22b": { - ID: "accounts/fireworks/models/qwen3-235b-a22b", - Name: "Qwen3 235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "accounts/fireworks/models/qwen3-coder-480b-a35b-instruct": { - ID: "accounts/fireworks/models/qwen3-coder-480b-a35b-instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.45, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32768, - }, - }, - }, - }, - "friendli": { - ID: "friendli", - Env: []string{"FRIENDLI_TOKEN" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Friendli", - Models: map[string]ModelInfo{ - "LGAI-EXAONE/EXAONE-4.0.1-32B": { - ID: "LGAI-EXAONE/EXAONE-4.0.1-32B", - Name: "EXAONE 4.0.1 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "Qwen/Qwen3-30B-A3B": { - ID: "Qwen/Qwen3-30B-A3B", - Name: "Qwen3 30B A3B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8000, - }, - }, - "Qwen/Qwen3-32B": { - ID: "Qwen/Qwen3-32B", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8000, - }, - }, - "deepseek-ai/DeepSeek-R1-0528": { - ID: "deepseek-ai/DeepSeek-R1-0528", - Name: "DeepSeek R1 0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "meta-llama-3.1-8b-instruct": { - ID: "meta-llama-3.1-8b-instruct", - Name: "Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8000, - }, - }, - "meta-llama-3.3-70b-instruct": { - ID: "meta-llama-3.3-70b-instruct", - Name: "Llama 3.3 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "meta-llama/Llama-4-Maverick-17B-128E-Instruct": { - ID: "meta-llama/Llama-4-Maverick-17B-128E-Instruct", - Name: "Llama 4 Maverick 17B 128E Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8000, - }, - }, - "meta-llama/Llama-4-Scout-17B-16E-Instruct": { - ID: "meta-llama/Llama-4-Scout-17B-16E-Instruct", - Name: "Llama 4 Scout 17B 16E Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8000, - }, - }, - "zai-org/GLM-4.6": { - ID: "zai-org/GLM-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - }, - }, - "github-copilot": { - ID: "github-copilot", - Env: []string{"GITHUB_TOKEN" }, - NPM: "@ai-sdk/openai-compatible", - Name: "GitHub Copilot", - Models: map[string]ModelInfo{ - "claude-3.5-sonnet": { - ID: "claude-3.5-sonnet", - Name: "Claude Sonnet 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 90000, - Output: 8192, - }, - }, - "claude-3.7-sonnet": { - ID: "claude-3.7-sonnet", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 16384, - }, - }, - "claude-3.7-sonnet-thought": { - ID: "claude-3.7-sonnet-thought", - Name: "Claude Sonnet 3.7 Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 16384, - }, - }, - "claude-haiku-4.5": { - ID: "claude-haiku-4.5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16000, - }, - }, - "claude-opus-4": { - ID: "claude-opus-4", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 80000, - Output: 16000, - }, - }, - "claude-opus-4.5": { - ID: "claude-opus-4.5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16000, - }, - }, - "claude-opus-41": { - ID: "claude-opus-41", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 80000, - Output: 16000, - }, - }, - "claude-sonnet-4": { - ID: "claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16000, - }, - }, - "claude-sonnet-4.5": { - ID: "claude-sonnet-4.5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16000, - }, - }, - "gemini-2.0-flash-001": { - ID: "gemini-2.0-flash-001", - Name: "Gemini 2.0 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 8192, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "gemini-3-flash-preview": { - ID: "gemini-3-flash-preview", - Name: "Gemini 3 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o": { - ID: "gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "GPT-5-mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "GPT-5.1-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-5.1-codex-max": { - ID: "gpt-5.1-codex-max", - Name: "GPT-5.1-Codex-max", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "GPT-5.1-Codex-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 100000, - }, - }, - "gpt-5.2": { - ID: "gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "o3": { - ID: "o3", - Name: "o3 (Preview)", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "o3-mini": { - ID: "o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "o4-mini (Preview)", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "oswe-vscode-prime": { - ID: "oswe-vscode-prime", - Name: "Raptor Mini (Preview)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - }, - }, - "github-models": { - ID: "github-models", - Env: []string{"GITHUB_TOKEN" }, - NPM: "@ai-sdk/openai-compatible", - Name: "GitHub Models", - Models: map[string]ModelInfo{ - "ai21-labs/ai21-jamba-1.5-large": { - ID: "ai21-labs/ai21-jamba-1.5-large", - Name: "AI21 Jamba 1.5 Large", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 4096, - }, - }, - "ai21-labs/ai21-jamba-1.5-mini": { - ID: "ai21-labs/ai21-jamba-1.5-mini", - Name: "AI21 Jamba 1.5 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 4096, - }, - }, - "cohere/cohere-command-a": { - ID: "cohere/cohere-command-a", - Name: "Cohere Command A", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cohere/cohere-command-r": { - ID: "cohere/cohere-command-r", - Name: "Cohere Command R", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cohere/cohere-command-r-08-2024": { - ID: "cohere/cohere-command-r-08-2024", - Name: "Cohere Command R 08-2024", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cohere/cohere-command-r-plus": { - ID: "cohere/cohere-command-r-plus", - Name: "Cohere Command R+", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cohere/cohere-command-r-plus-08-2024": { - ID: "cohere/cohere-command-r-plus-08-2024", - Name: "Cohere Command R+ 08-2024", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "core42/jais-30b-chat": { - ID: "core42/jais-30b-chat", - Name: "JAIS 30b Chat", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "deepseek/deepseek-r1": { - ID: "deepseek/deepseek-r1", - Name: "DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 8192, - }, - }, - "deepseek/deepseek-r1-0528": { - ID: "deepseek/deepseek-r1-0528", - Name: "DeepSeek-R1-0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 8192, - }, - }, - "deepseek/deepseek-v3-0324": { - ID: "deepseek/deepseek-v3-0324", - Name: "DeepSeek-V3-0324", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta/llama-3.2-11b-vision-instruct": { - ID: "meta/llama-3.2-11b-vision-instruct", - Name: "Llama-3.2-11B-Vision-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta/llama-3.2-90b-vision-instruct": { - ID: "meta/llama-3.2-90b-vision-instruct", - Name: "Llama-3.2-90B-Vision-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta/llama-3.3-70b-instruct": { - ID: "meta/llama-3.3-70b-instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta/llama-4-maverick-17b-128e-instruct-fp8": { - ID: "meta/llama-4-maverick-17b-128e-instruct-fp8", - Name: "Llama 4 Maverick 17B 128E Instruct FP8", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta/llama-4-scout-17b-16e-instruct": { - ID: "meta/llama-4-scout-17b-16e-instruct", - Name: "Llama 4 Scout 17B 16E Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta/meta-llama-3-70b-instruct": { - ID: "meta/meta-llama-3-70b-instruct", - Name: "Meta-Llama-3-70B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta/meta-llama-3-8b-instruct": { - ID: "meta/meta-llama-3-8b-instruct", - Name: "Meta-Llama-3-8B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "meta/meta-llama-3.1-405b-instruct": { - ID: "meta/meta-llama-3.1-405b-instruct", - Name: "Meta-Llama-3.1-405B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta/meta-llama-3.1-70b-instruct": { - ID: "meta/meta-llama-3.1-70b-instruct", - Name: "Meta-Llama-3.1-70B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta/meta-llama-3.1-8b-instruct": { - ID: "meta/meta-llama-3.1-8b-instruct", - Name: "Meta-Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "microsoft/mai-ds-r1": { - ID: "microsoft/mai-ds-r1", - Name: "MAI-DS-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 8192, - }, - }, - "microsoft/phi-3-medium-128k-instruct": { - ID: "microsoft/phi-3-medium-128k-instruct", - Name: "Phi-3-medium instruct (128k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3-medium-4k-instruct": { - ID: "microsoft/phi-3-medium-4k-instruct", - Name: "Phi-3-medium instruct (4k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 1024, - }, - }, - "microsoft/phi-3-mini-128k-instruct": { - ID: "microsoft/phi-3-mini-128k-instruct", - Name: "Phi-3-mini instruct (128k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3-mini-4k-instruct": { - ID: "microsoft/phi-3-mini-4k-instruct", - Name: "Phi-3-mini instruct (4k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 1024, - }, - }, - "microsoft/phi-3-small-128k-instruct": { - ID: "microsoft/phi-3-small-128k-instruct", - Name: "Phi-3-small instruct (128k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3-small-8k-instruct": { - ID: "microsoft/phi-3-small-8k-instruct", - Name: "Phi-3-small instruct (8k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 2048, - }, - }, - "microsoft/phi-3.5-mini-instruct": { - ID: "microsoft/phi-3.5-mini-instruct", - Name: "Phi-3.5-mini instruct (128k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3.5-moe-instruct": { - ID: "microsoft/phi-3.5-moe-instruct", - Name: "Phi-3.5-MoE instruct (128k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3.5-vision-instruct": { - ID: "microsoft/phi-3.5-vision-instruct", - Name: "Phi-3.5-vision instruct (128k)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-4": { - ID: "microsoft/phi-4", - Name: "Phi-4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "microsoft/phi-4-mini-instruct": { - ID: "microsoft/phi-4-mini-instruct", - Name: "Phi-4-mini-instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-4-mini-reasoning": { - ID: "microsoft/phi-4-mini-reasoning", - Name: "Phi-4-mini-reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-4-multimodal-instruct": { - ID: "microsoft/phi-4-multimodal-instruct", - Name: "Phi-4-multimodal-instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-4-reasoning": { - ID: "microsoft/phi-4-reasoning", - Name: "Phi-4-Reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistral-ai/codestral-2501": { - ID: "mistral-ai/codestral-2501", - Name: "Codestral 25.01", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 8192, - }, - }, - "mistral-ai/ministral-3b": { - ID: "mistral-ai/ministral-3b", - Name: "Ministral 3B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistral-ai/mistral-large-2411": { - ID: "mistral-ai/mistral-large-2411", - Name: "Mistral Large 24.11", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "mistral-ai/mistral-medium-2505": { - ID: "mistral-ai/mistral-medium-2505", - Name: "Mistral Medium 3 (25.05)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "mistral-ai/mistral-nemo": { - ID: "mistral-ai/mistral-nemo", - Name: "Mistral Nemo", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistral-ai/mistral-small-2503": { - ID: "mistral-ai/mistral-small-2503", - Name: "Mistral Small 3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "openai/gpt-4.1": { - ID: "openai/gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-4.1-mini": { - ID: "openai/gpt-4.1-mini", - Name: "GPT-4.1-mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-4.1-nano": { - ID: "openai/gpt-4.1-nano", - Name: "GPT-4.1-nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-4o": { - ID: "openai/gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-4o-mini": { - ID: "openai/gpt-4o-mini", - Name: "GPT-4o mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/o1": { - ID: "openai/o1", - Name: "OpenAI o1", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o1-mini": { - ID: "openai/o1-mini", - Name: "OpenAI o1-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "openai/o1-preview": { - ID: "openai/o1-preview", - Name: "OpenAI o1-preview", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "openai/o3": { - ID: "openai/o3", - Name: "OpenAI o3", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-mini": { - ID: "openai/o3-mini", - Name: "OpenAI o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o4-mini": { - ID: "openai/o4-mini", - Name: "OpenAI o4-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "xai/grok-3": { - ID: "xai/grok-3", - Name: "Grok 3", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "xai/grok-3-mini": { - ID: "xai/grok-3-mini", - Name: "Grok 3 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - }, - }, - "google": { - ID: "google", - Env: []string{"GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY" }, - NPM: "@ai-sdk/google", - Name: "Google", - Models: map[string]ModelInfo{ - "gemini-1.5-flash": { - ID: "gemini-1.5-flash", - Name: "Gemini 1.5 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: &[]float64{0.01875}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 8192, - }, - }, - "gemini-1.5-flash-8b": { - ID: "gemini-1.5-flash-8b", - Name: "Gemini 1.5 Flash-8B", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.0375, - Output: 0.15, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 8192, - }, - }, - "gemini-1.5-pro": { - ID: "gemini-1.5-pro", - Name: "Gemini 1.5 Pro", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 5, - CacheRead: &[]float64{0.3125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 8192, - }, - }, - "gemini-2.0-flash": { - ID: "gemini-2.0-flash", - Name: "Gemini 2.0 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "gemini-2.0-flash-lite": { - ID: "gemini-2.0-flash-lite", - Name: "Gemini 2.0 Flash Lite", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "gemini-2.5-flash": { - ID: "gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-image": { - ID: "gemini-2.5-flash-image", - Name: "Gemini 2.5 Flash Image", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 30, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "gemini-2.5-flash-image-preview": { - ID: "gemini-2.5-flash-image-preview", - Name: "Gemini 2.5 Flash Image (Preview)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 30, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "gemini-2.5-flash-lite": { - ID: "gemini-2.5-flash-lite", - Name: "Gemini 2.5 Flash Lite", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-lite-preview-06-17": { - ID: "gemini-2.5-flash-lite-preview-06-17", - Name: "Gemini 2.5 Flash Lite Preview 06-17", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-lite-preview-09-2025": { - ID: "gemini-2.5-flash-lite-preview-09-2025", - Name: "Gemini 2.5 Flash Lite Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-04-17": { - ID: "gemini-2.5-flash-preview-04-17", - Name: "Gemini 2.5 Flash Preview 04-17", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.0375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-05-20": { - ID: "gemini-2.5-flash-preview-05-20", - Name: "Gemini 2.5 Flash Preview 05-20", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.0375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-09-2025": { - ID: "gemini-2.5-flash-preview-09-2025", - Name: "Gemini 2.5 Flash Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-tts": { - ID: "gemini-2.5-flash-preview-tts", - Name: "Gemini 2.5 Flash Preview TTS", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.5, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8000, - Output: 16000, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro-preview-05-06": { - ID: "gemini-2.5-pro-preview-05-06", - Name: "Gemini 2.5 Pro Preview 05-06", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro-preview-06-05": { - ID: "gemini-2.5-pro-preview-06-05", - Name: "Gemini 2.5 Pro Preview 06-05", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro-preview-tts": { - ID: "gemini-2.5-pro-preview-tts", - Name: "Gemini 2.5 Pro Preview TTS", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1, - Output: 20, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8000, - Output: 16000, - }, - }, - "gemini-3-flash-preview": { - ID: "gemini-3-flash-preview", - Name: "Gemini 3 Flash Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "gemini-embedding-001": { - ID: "gemini-embedding-001", - Name: "Gemini Embedding 001", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.15, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2048, - Output: 3072, - }, - }, - "gemini-flash-latest": { - ID: "gemini-flash-latest", - Name: "Gemini Flash Latest", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-flash-lite-latest": { - ID: "gemini-flash-lite-latest", - Name: "Gemini Flash-Lite Latest", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-live-2.5-flash": { - ID: "gemini-live-2.5-flash", - Name: "Gemini Live 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8000, - }, - }, - "gemini-live-2.5-flash-preview-native-audio": { - ID: "gemini-live-2.5-flash-preview-native-audio", - Name: "Gemini Live 2.5 Flash Preview Native Audio", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - }, - }, - "google-vertex": { - ID: "google-vertex", - Env: []string{"GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS" }, - NPM: "@ai-sdk/google-vertex", - Name: "Vertex", - Models: map[string]ModelInfo{ - "gemini-2.0-flash": { - ID: "gemini-2.0-flash", - Name: "Gemini 2.0 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "gemini-2.0-flash-lite": { - ID: "gemini-2.0-flash-lite", - Name: "Gemini 2.0 Flash Lite", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "gemini-2.5-flash": { - ID: "gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.383}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-lite": { - ID: "gemini-2.5-flash-lite", - Name: "Gemini 2.5 Flash Lite", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-lite-preview-06-17": { - ID: "gemini-2.5-flash-lite-preview-06-17", - Name: "Gemini 2.5 Flash Lite Preview 06-17", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 65536, - }, - }, - "gemini-2.5-flash-lite-preview-09-2025": { - ID: "gemini-2.5-flash-lite-preview-09-2025", - Name: "Gemini 2.5 Flash Lite Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-04-17": { - ID: "gemini-2.5-flash-preview-04-17", - Name: "Gemini 2.5 Flash Preview 04-17", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.0375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-05-20": { - ID: "gemini-2.5-flash-preview-05-20", - Name: "Gemini 2.5 Flash Preview 05-20", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.0375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-flash-preview-09-2025": { - ID: "gemini-2.5-flash-preview-09-2025", - Name: "Gemini 2.5 Flash Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.383}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro-preview-05-06": { - ID: "gemini-2.5-pro-preview-05-06", - Name: "Gemini 2.5 Pro Preview 05-06", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro-preview-06-05": { - ID: "gemini-2.5-pro-preview-06-05", - Name: "Gemini 2.5 Pro Preview 06-05", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-flash-preview": { - ID: "gemini-3-flash-preview", - Name: "Gemini 3 Flash Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-embedding-001": { - ID: "gemini-embedding-001", - Name: "Gemini Embedding 001", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.15, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2048, - Output: 3072, - }, - }, - "gemini-flash-latest": { - ID: "gemini-flash-latest", - Name: "Gemini Flash Latest", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.383}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-flash-lite-latest": { - ID: "gemini-flash-lite-latest", - Name: "Gemini Flash-Lite Latest", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "openai/gpt-oss-120b-maas": { - ID: "openai/gpt-oss-120b-maas", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.36, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-20b-maas": { - ID: "openai/gpt-oss-20b-maas", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - }, - }, - "google-vertex-anthropic": { - ID: "google-vertex-anthropic", - Env: []string{"GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS" }, - NPM: "@ai-sdk/google-vertex", - Name: "Vertex (Anthropic)", - Models: map[string]ModelInfo{ - "claude-3-5-haiku@20241022": { - ID: "claude-3-5-haiku@20241022", - Name: "Claude Haiku 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3-5-sonnet@20241022": { - ID: "claude-3-5-sonnet@20241022", - Name: "Claude Sonnet 3.5 v2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3-7-sonnet@20250219": { - ID: "claude-3-7-sonnet@20250219", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-haiku-4-5@20251001": { - ID: "claude-haiku-4-5@20251001", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-1@20250805": { - ID: "claude-opus-4-1@20250805", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5@20251101": { - ID: "claude-opus-4-5@20251101", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4@20250514": { - ID: "claude-opus-4@20250514", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-sonnet-4-5@20250929": { - ID: "claude-sonnet-4-5@20250929", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4@20250514": { - ID: "claude-sonnet-4@20250514", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - }, - }, - "groq": { - ID: "groq", - Env: []string{"GROQ_API_KEY" }, - NPM: "@ai-sdk/groq", - Name: "Groq", - Models: map[string]ModelInfo{ - "deepseek-r1-distill-llama-70b": { - ID: "deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.75, - Output: 0.99, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "gemma2-9b-it": { - ID: "gemma2-9b-it", - Name: "Gemma 2 9B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama-3.1-8b-instant": { - ID: "llama-3.1-8b-instant", - Name: "Llama 3.1 8B Instant", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.08, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "llama-3.3-70b-versatile": { - ID: "llama-3.3-70b-versatile", - Name: "Llama 3.3 70B Versatile", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.79, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "llama-guard-3-8b": { - ID: "llama-guard-3-8b", - Name: "Llama Guard 3 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama3-70b-8192": { - ID: "llama3-70b-8192", - Name: "Llama 3 70B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.79, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "llama3-8b-8192": { - ID: "llama3-8b-8192", - Name: "Llama 3 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.08, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "meta-llama/llama-4-maverick-17b-128e-instruct": { - ID: "meta-llama/llama-4-maverick-17b-128e-instruct", - Name: "Llama 4 Maverick 17B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "meta-llama/llama-4-scout-17b-16e-instruct": { - ID: "meta-llama/llama-4-scout-17b-16e-instruct", - Name: "Llama 4 Scout 17B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.34, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "meta-llama/llama-guard-4-12b": { - ID: "meta-llama/llama-guard-4-12b", - Name: "Llama Guard 4 12B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 1024, - }, - }, - "mistral-saba-24b": { - ID: "mistral-saba-24b", - Name: "Mistral Saba 24B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.79, - Output: 0.79, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "moonshotai/kimi-k2-instruct": { - ID: "moonshotai/kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "moonshotai/kimi-k2-instruct-0905": { - ID: "moonshotai/kimi-k2-instruct-0905", - Name: "Kimi K2 Instruct 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "qwen-qwq-32b": { - ID: "qwen-qwq-32b", - Name: "Qwen QwQ 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 0.39, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "qwen/qwen3-32b": { - ID: "qwen/qwen3-32b", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - }, - }, - "helicone": { - ID: "helicone", - Env: []string{"HELICONE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Helicone", - Models: map[string]ModelInfo{ - "chatgpt-4o-latest": { - ID: "chatgpt-4o-latest", - Name: "OpenAI ChatGPT-4o", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 20, - CacheRead: &[]float64{2.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "claude-3-haiku-20240307": { - ID: "claude-3-haiku-20240307", - Name: "Anthropic: Claude 3 Haiku", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.25, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "claude-3.5-haiku": { - ID: "claude-3.5-haiku", - Name: "Anthropic: Claude 3.5 Haiku", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7999999999999999, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3.5-sonnet-v2": { - ID: "claude-3.5-sonnet-v2", - Name: "Anthropic: Claude 3.5 Sonnet v2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.30000000000000004}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-3.7-sonnet": { - ID: "claude-3.7-sonnet", - Name: "Anthropic: Claude 3.7 Sonnet", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.30000000000000004}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-4.5-haiku": { - ID: "claude-4.5-haiku", - Name: "Anthropic: Claude 4.5 Haiku", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.09999999999999999}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-4.5-opus": { - ID: "claude-4.5-opus", - Name: "Anthropic: Claude Opus 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5000000000000001}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-4.5-sonnet": { - ID: "claude-4.5-sonnet", - Name: "Anthropic: Claude Sonnet 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.30000000000000004}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-haiku-4-5-20251001": { - ID: "claude-haiku-4-5-20251001", - Name: "Anthropic: Claude 4.5 Haiku (20251001)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.09999999999999999}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-opus-4": { - ID: "claude-opus-4", - Name: "Anthropic: Claude Opus 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-1": { - ID: "claude-opus-4-1", - Name: "Anthropic: Claude Opus 4.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-1-20250805": { - ID: "claude-opus-4-1-20250805", - Name: "Anthropic: Claude Opus 4.1 (20250805)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-sonnet-4": { - ID: "claude-sonnet-4", - Name: "Anthropic: Claude Sonnet 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.30000000000000004}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4-5-20250929": { - ID: "claude-sonnet-4-5-20250929", - Name: "Anthropic: Claude Sonnet 4.5 (20250929)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.30000000000000004}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "codex-mini-latest": { - ID: "codex-mini-latest", - Name: "OpenAI Codex Mini Latest", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.5, - Output: 6, - CacheRead: &[]float64{0.375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "deepseek-r1-distill-llama-70b": { - ID: "deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.13, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "deepseek-reasoner": { - ID: "deepseek-reasoner", - Name: "DeepSeek Reasoner", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: &[]float64{0.07}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek-tng-r1t2-chimera": { - ID: "deepseek-tng-r1t2-chimera", - Name: "DeepSeek TNG R1T2 Chimera", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 130000, - Output: 163840, - }, - }, - "deepseek-v3": { - ID: "deepseek-v3", - Name: "DeepSeek V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: &[]float64{0.07}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek-v3.1-terminus": { - ID: "deepseek-v3.1-terminus", - Name: "DeepSeek V3.1 Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: &[]float64{0.21600000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "deepseek-v3.2": { - ID: "deepseek-v3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.41, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "ernie-4.5-21b-a3b-thinking": { - ID: "ernie-4.5-21b-a3b-thinking", - Name: "Baidu Ernie 4.5 21B A3B Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8000, - }, - }, - "gemini-2.5-flash": { - ID: "gemini-2.5-flash", - Name: "Google Gemini 2.5 Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65535, - }, - }, - "gemini-2.5-flash-lite": { - ID: "gemini-2.5-flash-lite", - Name: "Google Gemini 2.5 Flash Lite", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.09999999999999999, - Output: 0.39999999999999997, - CacheRead: &[]float64{0.024999999999999998}[0], - CacheWrite: &[]float64{0.09999999999999999}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65535, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "Google Gemini 2.5 Pro", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.3125}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Google Gemini 3 Pro Preview", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.19999999999999998}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemma-3-12b-it": { - ID: "gemma-3-12b-it", - Name: "Google Gemma 3 12B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.049999999999999996, - Output: 0.09999999999999999, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "gemma2-9b-it": { - ID: "gemma2-9b-it", - Name: "Google Gemma 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.03, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "Zai GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.44999999999999996, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "OpenAI GPT-4.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini": { - ID: "gpt-4.1-mini", - Name: "OpenAI GPT-4.1 Mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.39999999999999997, - Output: 1.5999999999999999, - CacheRead: &[]float64{0.09999999999999999}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini-2025-04-14": { - ID: "gpt-4.1-mini-2025-04-14", - Name: "OpenAI GPT-4.1 Mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.39999999999999997, - Output: 1.5999999999999999, - CacheRead: &[]float64{0.09999999999999999}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-nano": { - ID: "gpt-4.1-nano", - Name: "OpenAI GPT-4.1 Nano", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09999999999999999, - Output: 0.39999999999999997, - CacheRead: &[]float64{0.024999999999999998}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4o": { - ID: "gpt-4o", - Name: "OpenAI GPT-4o", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-mini": { - ID: "gpt-4o-mini", - Name: "OpenAI GPT-4o-mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "OpenAI GPT-5", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.12500000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-chat-latest": { - ID: "gpt-5-chat-latest", - Name: "OpenAI GPT-5 Chat Latest", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.12500000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "OpenAI: GPT-5 Codex", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.12500000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "OpenAI GPT-5 Mini", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.024999999999999998}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "OpenAI GPT-5 Nano", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.049999999999999996, - Output: 0.39999999999999997, - CacheRead: &[]float64{0.005}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-pro": { - ID: "gpt-5-pro", - Name: "OpenAI: GPT-5 Pro", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "OpenAI GPT-5.1", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.12500000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-chat-latest": { - ID: "gpt-5.1-chat-latest", - Name: "OpenAI GPT-5.1 Chat", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.12500000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "OpenAI: GPT-5.1 Codex", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.12500000000000003}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "OpenAI: GPT-5.1 Codex Mini", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.024999999999999998}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "OpenAI GPT-OSS 120b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.16, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "gpt-oss-20b": { - ID: "gpt-oss-20b", - Name: "OpenAI GPT-OSS 20b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.049999999999999996, - Output: 0.19999999999999998, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "grok-3": { - ID: "grok-3", - Name: "xAI Grok 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "grok-3-mini": { - ID: "grok-3-mini", - Name: "xAI Grok 3 Mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "grok-4": { - ID: "grok-4", - Name: "xAI Grok 4", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "grok-4-1-fast-non-reasoning": { - ID: "grok-4-1-fast-non-reasoning", - Name: "xAI Grok 4.1 Fast Non-Reasoning", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.19999999999999998, - Output: 0.5, - CacheRead: &[]float64{0.049999999999999996}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-4-1-fast-reasoning": { - ID: "grok-4-1-fast-reasoning", - Name: "xAI Grok 4.1 Fast Reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.19999999999999998, - Output: 0.5, - CacheRead: &[]float64{0.049999999999999996}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 2000000, - }, - }, - "grok-4-fast-non-reasoning": { - ID: "grok-4-fast-non-reasoning", - Name: "xAI Grok 4 Fast Non-Reasoning", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.19999999999999998, - Output: 0.5, - CacheRead: &[]float64{0.049999999999999996}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 2000000, - }, - }, - "grok-4-fast-reasoning": { - ID: "grok-4-fast-reasoning", - Name: "xAI: Grok 4 Fast Reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.19999999999999998, - Output: 0.5, - CacheRead: &[]float64{0.049999999999999996}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 2000000, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "xAI Grok Code Fast 1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.19999999999999998, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 10000, - }, - }, - "hermes-2-pro-llama-3-8b": { - ID: "hermes-2-pro-llama-3-8b", - Name: "Hermes 2 Pro Llama 3 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "kimi-k2-0711": { - ID: "kimi-k2-0711", - Name: "Kimi K2 (07/11)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5700000000000001, - Output: 2.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "kimi-k2-0905": { - ID: "kimi-k2-0905", - Name: "Kimi K2 (09/05)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: &[]float64{0.39999999999999997}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.48, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 262144, - }, - }, - "llama-3.1-8b-instant": { - ID: "llama-3.1-8b-instant", - Name: "Meta Llama 3.1 8B Instant", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.049999999999999996, - Output: 0.08, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32678, - }, - }, - "llama-3.1-8b-instruct": { - ID: "llama-3.1-8b-instruct", - Name: "Meta Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.049999999999999996, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 16384, - }, - }, - "llama-3.1-8b-instruct-turbo": { - ID: "llama-3.1-8b-instruct-turbo", - Name: "Meta Llama 3.1 8B Instruct Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.03, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "llama-3.3-70b-instruct": { - ID: "llama-3.3-70b-instruct", - Name: "Meta Llama 3.3 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.39, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16400, - }, - }, - "llama-3.3-70b-versatile": { - ID: "llama-3.3-70b-versatile", - Name: "Meta Llama 3.3 70B Versatile", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.7899999999999999, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32678, - }, - }, - "llama-4-maverick": { - ID: "llama-4-maverick", - Name: "Meta Llama 4 Maverick 17B 128E", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "llama-4-scout": { - ID: "llama-4-scout", - Name: "Meta Llama 4 Scout 17B 16E", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "llama-guard-4": { - ID: "llama-guard-4", - Name: "Meta Llama Guard 4 12B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.21, - Output: 0.21, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 1024, - }, - }, - "llama-prompt-guard-2-22m": { - ID: "llama-prompt-guard-2-22m", - Name: "Meta Llama Prompt Guard 2 22M", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.01, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512, - Output: 2, - }, - }, - "llama-prompt-guard-2-86m": { - ID: "llama-prompt-guard-2-86m", - Name: "Meta Llama Prompt Guard 2 86M", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.01, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512, - Output: 2, - }, - }, - "mistral-large-2411": { - ID: "mistral-large-2411", - Name: "Mistral-Large", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "mistral-nemo": { - ID: "mistral-nemo", - Name: "Mistral Nemo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 20, - Output: 40, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16400, - }, - }, - "mistral-small": { - ID: "mistral-small", - Name: "Mistral Small", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 75, - Output: 200, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "o1": { - ID: "o1", - Name: "OpenAI: o1", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o1-mini": { - ID: "o1-mini", - Name: "OpenAI: o1-mini", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "o3": { - ID: "o3", - Name: "OpenAI o3", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-mini": { - ID: "o3-mini", - Name: "OpenAI o3 Mini", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-pro": { - ID: "o3-pro", - Name: "OpenAI o3 Pro", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 20, - Output: 80, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "OpenAI o4 Mini", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.275}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "qwen2.5-coder-7b-fast": { - ID: "qwen2.5-coder-7b-fast", - Name: "Qwen2.5 Coder 7B fast", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.09, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 8192, - }, - }, - "qwen3-235b-a22b-thinking": { - ID: "qwen3-235b-a22b-thinking", - Name: "Qwen3 235B A22B Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.9000000000000004, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 81920, - }, - }, - "qwen3-30b-a3b": { - ID: "qwen3-30b-a3b", - Name: "Qwen3 30B A3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 41000, - Output: 41000, - }, - }, - "qwen3-32b": { - ID: "qwen3-32b", - Name: "Qwen3 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 40960, - }, - }, - "qwen3-coder": { - ID: "qwen3-coder", - Name: "Qwen3 Coder 480B A35B Instruct Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.95, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "qwen3-coder-30b-a3b-instruct": { - ID: "qwen3-coder-30b-a3b-instruct", - Name: "Qwen3 Coder 30B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09999999999999999, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "qwen3-next-80b-a3b-instruct": { - ID: "qwen3-next-80b-a3b-instruct", - Name: "Qwen3 Next 80B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 16384, - }, - }, - "qwen3-vl-235b-a22b-instruct": { - ID: "qwen3-vl-235b-a22b-instruct", - Name: "Qwen3 VL 235B A22B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 16384, - }, - }, - "sonar": { - ID: "sonar", - Name: "Perplexity Sonar", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 4096, - }, - }, - "sonar-deep-research": { - ID: "sonar-deep-research", - Name: "Perplexity Sonar Deep Research", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 4096, - }, - }, - "sonar-pro": { - ID: "sonar-pro", - Name: "Perplexity Sonar Pro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "sonar-reasoning": { - ID: "sonar-reasoning", - Name: "Perplexity Sonar Reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 4096, - }, - }, - "sonar-reasoning-pro": { - ID: "sonar-reasoning-pro", - Name: "Perplexity Sonar Reasoning Pro", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 4096, - }, - }, - }, - }, - "huggingface": { - ID: "huggingface", - Env: []string{"HF_TOKEN" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Hugging Face", - Models: map[string]ModelInfo{ - "MiniMaxAI/MiniMax-M2.1": { - ID: "MiniMaxAI/MiniMax-M2.1", - Name: "MiniMax-M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3-235B-A22B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen3-Coder-480B-A35B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "Qwen/Qwen3-Embedding-4B": { - ID: "Qwen/Qwen3-Embedding-4B", - Name: "Qwen 3 Embedding 4B", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.01, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 2048, - }, - }, - "Qwen/Qwen3-Embedding-8B": { - ID: "Qwen/Qwen3-Embedding-8B", - Name: "Qwen 3 Embedding 8B", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.01, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Instruct": { - ID: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Name: "Qwen3-Next-80B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Thinking": { - ID: "Qwen/Qwen3-Next-80B-A3B-Thinking", - Name: "Qwen3-Next-80B-A3B-Thinking", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "XiaomiMiMo/MiMo-V2-Flash": { - ID: "XiaomiMiMo/MiMo-V2-Flash", - Name: "MiMo-V2-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 4096, - }, - }, - "deepseek-ai/DeepSeek-R1-0528": { - ID: "deepseek-ai/DeepSeek-R1-0528", - Name: "DeepSeek-R1-0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek-ai/DeepSeek-V3.2": { - ID: "deepseek-ai/DeepSeek-V3.2", - Name: "DeepSeek-V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "moonshotai/Kimi-K2-Instruct": { - ID: "moonshotai/Kimi-K2-Instruct", - Name: "Kimi-K2-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "moonshotai/Kimi-K2-Instruct-0905": { - ID: "moonshotai/Kimi-K2-Instruct-0905", - Name: "Kimi-K2-Instruct-0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "Kimi-K2-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "zai-org/GLM-4.7": { - ID: "zai-org/GLM-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "iflowcn": { - ID: "iflowcn", - Env: []string{"IFLOW_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "iFlow", - Models: map[string]ModelInfo{ - "deepseek-r1": { - ID: "deepseek-r1", - Name: "DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "deepseek-v3": { - ID: "deepseek-v3", - Name: "DeepSeek-V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "deepseek-v3.1": { - ID: "deepseek-v3.1", - Name: "DeepSeek-V3.1-Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek-v3.2": { - ID: "deepseek-v3.2", - Name: "DeepSeek-V3.2-Exp", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek-v3.2-chat": { - ID: "deepseek-v3.2-chat", - Name: "DeepSeek-V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 128000, - }, - }, - "kimi-k2": { - ID: "kimi-k2", - Name: "Kimi-K2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "kimi-k2-0905": { - ID: "kimi-k2-0905", - Name: "Kimi-K2-0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi-K2-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "minimax-m2": { - ID: "minimax-m2", - Name: "MiniMax-M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131100, - }, - }, - "qwen3-235b": { - ID: "qwen3-235b", - Name: "Qwen3-235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "qwen3-235b-a22b-instruct": { - ID: "qwen3-235b-a22b-instruct", - Name: "Qwen3-235B-A22B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "qwen3-235b-a22b-thinking-2507": { - ID: "qwen3-235b-a22b-thinking-2507", - Name: "Qwen3-235B-A22B-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "qwen3-32b": { - ID: "qwen3-32b", - Name: "Qwen3-32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "qwen3-coder": { - ID: "qwen3-coder", - Name: "Qwen3-Coder-480B-A35B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "qwen3-coder-plus": { - ID: "qwen3-coder-plus", - Name: "Qwen3-Coder-Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "qwen3-max": { - ID: "qwen3-max", - Name: "Qwen3-Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "qwen3-max-preview": { - ID: "qwen3-max-preview", - Name: "Qwen3-Max-Preview", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "qwen3-vl-plus": { - ID: "qwen3-vl-plus", - Name: "Qwen3-VL-Plus", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "tstars2.0": { - ID: "tstars2.0", - Name: "TStars-2.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - }, - }, - "inception": { - ID: "inception", - Env: []string{"INCEPTION_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Inception", - Models: map[string]ModelInfo{ - "mercury": { - ID: "mercury", - Name: "Mercury", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: &[]float64{0.25}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "mercury-coder": { - ID: "mercury-coder", - Name: "Mercury Coder", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: &[]float64{0.25}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - }, - }, - "inference": { - ID: "inference", - Env: []string{"INFERENCE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Inference", - Models: map[string]ModelInfo{ - "google/gemma-3": { - ID: "google/gemma-3", - Name: "Google Gemma 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 125000, - Output: 4096, - }, - }, - "meta/llama-3.1-8b-instruct": { - ID: "meta/llama-3.1-8b-instruct", - Name: "Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.025, - Output: 0.025, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "meta/llama-3.2-11b-vision-instruct": { - ID: "meta/llama-3.2-11b-vision-instruct", - Name: "Llama 3.2 11B Vision Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.055, - Output: 0.055, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "meta/llama-3.2-1b-instruct": { - ID: "meta/llama-3.2-1b-instruct", - Name: "Llama 3.2 1B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.01, - Output: 0.01, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "meta/llama-3.2-3b-instruct": { - ID: "meta/llama-3.2-3b-instruct", - Name: "Llama 3.2 3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.02, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "mistral/mistral-nemo-12b-instruct": { - ID: "mistral/mistral-nemo-12b-instruct", - Name: "Mistral Nemo 12B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.038, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "osmosis/osmosis-structure-0.6b": { - ID: "osmosis/osmosis-structure-0.6b", - Name: "Osmosis Structure 0.6B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4000, - Output: 2048, - }, - }, - "qwen/qwen-2.5-7b-vision-instruct": { - ID: "qwen/qwen-2.5-7b-vision-instruct", - Name: "Qwen 2.5 7B Vision Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 125000, - Output: 4096, - }, - }, - "qwen/qwen3-embedding-4b": { - ID: "qwen/qwen3-embedding-4b", - Name: "Qwen 3 Embedding 4B", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.01, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 2048, - }, - }, - }, - }, - "io-net": { - ID: "io-net", - Env: []string{"IOINTELLIGENCE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "IO.NET", - Models: map[string]ModelInfo{ - "Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar": { - ID: "Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar", - Name: "Qwen 3 Coder 480B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.95, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0.44}[0], - }, - Limit: Limit{ - Context: 106000, - Output: 4096, - }, - }, - "Qwen/Qwen2.5-VL-32B-Instruct": { - ID: "Qwen/Qwen2.5-VL-32B-Instruct", - Name: "Qwen 2.5 VL 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.22, - CacheRead: &[]float64{0.025}[0], - CacheWrite: &[]float64{0.1}[0], - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen 3 235B Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.6, - CacheRead: &[]float64{0.055}[0], - CacheWrite: &[]float64{0.22}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 4096, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Instruct": { - ID: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Name: "Qwen 3 Next 80B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.8, - CacheRead: &[]float64{0.05}[0], - CacheWrite: &[]float64{0.2}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 4096, - }, - }, - "deepseek-ai/DeepSeek-R1-0528": { - ID: "deepseek-ai/DeepSeek-R1-0528", - Name: "DeepSeek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8.75, - CacheRead: &[]float64{1}[0], - CacheWrite: &[]float64{4}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta-llama/Llama-3.2-90B-Vision-Instruct": { - ID: "meta-llama/Llama-3.2-90B-Vision-Instruct", - Name: "Llama 3.2 90B Vision Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 0.4, - CacheRead: &[]float64{0.175}[0], - CacheWrite: &[]float64{0.7}[0], - }, - Limit: Limit{ - Context: 16000, - Output: 4096, - }, - }, - "meta-llama/Llama-3.3-70B-Instruct": { - ID: "meta-llama/Llama-3.3-70B-Instruct", - Name: "Llama 3.3 70B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.38, - CacheRead: &[]float64{0.065}[0], - CacheWrite: &[]float64{0.26}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": { - ID: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", - Name: "Llama 4 Maverick 17B 128E Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 430000, - Output: 4096, - }, - }, - "mistralai/Devstral-Small-2505": { - ID: "mistralai/Devstral-Small-2505", - Name: "Devstral Small 2505", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.22, - CacheRead: &[]float64{0.025}[0], - CacheWrite: &[]float64{0.1}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistralai/Magistral-Small-2506": { - ID: "mistralai/Magistral-Small-2506", - Name: "Magistral Small 2506", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: &[]float64{0.25}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistralai/Mistral-Large-Instruct-2411": { - ID: "mistralai/Mistral-Large-Instruct-2411", - Name: "Mistral Large Instruct 2411", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: &[]float64{1}[0], - CacheWrite: &[]float64{4}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistralai/Mistral-Nemo-Instruct-2407": { - ID: "mistralai/Mistral-Nemo-Instruct-2407", - Name: "Mistral Nemo Instruct 2407", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.02, - Output: 0.04, - CacheRead: &[]float64{0.01}[0], - CacheWrite: &[]float64{0.04}[0], - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "moonshotai/Kimi-K2-Instruct-0905": { - ID: "moonshotai/Kimi-K2-Instruct-0905", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.39, - Output: 1.9, - CacheRead: &[]float64{0.195}[0], - CacheWrite: &[]float64{0.78}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 4096, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.25, - CacheRead: &[]float64{0.275}[0], - CacheWrite: &[]float64{1.1}[0], - }, - Limit: Limit{ - Context: 32768, - Output: 4096, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT-OSS 120B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.4, - CacheRead: &[]float64{0.02}[0], - CacheWrite: &[]float64{0.08}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 4096, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT-OSS 20B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.03, - Output: 0.14, - CacheRead: &[]float64{0.015}[0], - CacheWrite: &[]float64{0.06}[0], - }, - Limit: Limit{ - Context: 64000, - Output: 4096, - }, - }, - "zai-org/GLM-4.6": { - ID: "zai-org/GLM-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.75, - CacheRead: &[]float64{0.2}[0], - CacheWrite: &[]float64{0.8}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - }, - }, - "kimi-for-coding": { - ID: "kimi-for-coding", - Env: []string{"KIMI_API_KEY" }, - NPM: "@ai-sdk/anthropic", - Name: "Kimi For Coding", - Models: map[string]ModelInfo{ - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - }, - }, - "llama": { - ID: "llama", - Env: []string{"LLAMA_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Llama", - Models: map[string]ModelInfo{ - "cerebras-llama-4-maverick-17b-128e-instruct": { - ID: "cerebras-llama-4-maverick-17b-128e-instruct", - Name: "Cerebras-Llama-4-Maverick-17B-128E-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "cerebras-llama-4-scout-17b-16e-instruct": { - ID: "cerebras-llama-4-scout-17b-16e-instruct", - Name: "Cerebras-Llama-4-Scout-17B-16E-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "groq-llama-4-maverick-17b-128e-instruct": { - ID: "groq-llama-4-maverick-17b-128e-instruct", - Name: "Groq-Llama-4-Maverick-17B-128E-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "llama-3.3-70b-instruct": { - ID: "llama-3.3-70b-instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "llama-3.3-8b-instruct": { - ID: "llama-3.3-8b-instruct", - Name: "Llama-3.3-8B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "llama-4-maverick-17b-128e-instruct-fp8": { - ID: "llama-4-maverick-17b-128e-instruct-fp8", - Name: "Llama-4-Maverick-17B-128E-Instruct-FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "llama-4-scout-17b-16e-instruct-fp8": { - ID: "llama-4-scout-17b-16e-instruct-fp8", - Name: "Llama-4-Scout-17B-16E-Instruct-FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - }, - }, - "lmstudio": { - ID: "lmstudio", - Env: []string{"LMSTUDIO_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "LMStudio", - Models: map[string]ModelInfo{ - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen/qwen3-30b-a3b-2507": { - ID: "qwen/qwen3-30b-a3b-2507", - Name: "Qwen3 30B A3B 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "qwen/qwen3-coder-30b": { - ID: "qwen/qwen3-coder-30b", - Name: "Qwen3 Coder 30B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - }, - }, - "lucidquery": { - ID: "lucidquery", - Env: []string{"LUCIDQUERY_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "LucidQuery AI", - Models: map[string]ModelInfo{ - "lucidnova-rf1-100b": { - ID: "lucidnova-rf1-100b", - Name: "LucidNova RF1 100B", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 120000, - Output: 8000, - }, - }, - "lucidquery-nexus-coder": { - ID: "lucidquery-nexus-coder", - Name: "LucidQuery Nexus Coder", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 250000, - Output: 60000, - }, - }, - }, - }, - "minimax": { - ID: "minimax", - Env: []string{"MINIMAX_API_KEY" }, - NPM: "@ai-sdk/anthropic", - Name: "MiniMax", - Models: map[string]ModelInfo{ - "MiniMax-M2": { - ID: "MiniMax-M2", - Name: "MiniMax-M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 196608, - Output: 128000, - }, - }, - "MiniMax-M2.1": { - ID: "MiniMax-M2.1", - Name: "MiniMax-M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "minimax-cn": { - ID: "minimax-cn", - Env: []string{"MINIMAX_API_KEY" }, - NPM: "@ai-sdk/anthropic", - Name: "MiniMax (China)", - Models: map[string]ModelInfo{ - "MiniMax-M2": { - ID: "MiniMax-M2", - Name: "MiniMax-M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 196608, - Output: 128000, - }, - }, - "MiniMax-M2.1": { - ID: "MiniMax-M2.1", - Name: "MiniMax-M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "mistral": { - ID: "mistral", - Env: []string{"MISTRAL_API_KEY" }, - NPM: "@ai-sdk/mistral", - Name: "Mistral", - Models: map[string]ModelInfo{ - "codestral-latest": { - ID: "codestral-latest", - Name: "Codestral", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 4096, - }, - }, - "devstral-2512": { - ID: "devstral-2512", - Name: "Devstral 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "devstral-medium-2507": { - ID: "devstral-medium-2507", - Name: "Devstral Medium", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "devstral-medium-latest": { - ID: "devstral-medium-latest", - Name: "Devstral 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "devstral-small-2505": { - ID: "devstral-small-2505", - Name: "Devstral Small 2505", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "devstral-small-2507": { - ID: "devstral-small-2507", - Name: "Devstral Small", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "labs-devstral-small-2512": { - ID: "labs-devstral-small-2512", - Name: "Devstral Small 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "magistral-medium-latest": { - ID: "magistral-medium-latest", - Name: "Magistral Medium", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "magistral-small": { - ID: "magistral-small", - Name: "Magistral Small", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "ministral-3b-latest": { - ID: "ministral-3b-latest", - Name: "Ministral 3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "ministral-8b-latest": { - ID: "ministral-8b-latest", - Name: "Ministral 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral-embed": { - ID: "mistral-embed", - Name: "Mistral Embed", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8000, - Output: 3072, - }, - }, - "mistral-large-2411": { - ID: "mistral-large-2411", - Name: "Mistral Large 2.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "mistral-large-2512": { - ID: "mistral-large-2512", - Name: "Mistral Large 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistral-large-latest": { - ID: "mistral-large-latest", - Name: "Mistral Large", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistral-medium-2505": { - ID: "mistral-medium-2505", - Name: "Mistral Medium 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "mistral-medium-2508": { - ID: "mistral-medium-2508", - Name: "Mistral Medium 3.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistral-medium-latest": { - ID: "mistral-medium-latest", - Name: "Mistral Medium", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "mistral-nemo": { - ID: "mistral-nemo", - Name: "Mistral Nemo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral-small-2506": { - ID: "mistral-small-2506", - Name: "Mistral Small 3.2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "mistral-small-latest": { - ID: "mistral-small-latest", - Name: "Mistral Small", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "open-mistral-7b": { - ID: "open-mistral-7b", - Name: "Mistral 7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8000, - Output: 8000, - }, - }, - "open-mixtral-8x22b": { - ID: "open-mixtral-8x22b", - Name: "Mixtral 8x22B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 64000, - }, - }, - "open-mixtral-8x7b": { - ID: "open-mixtral-8x7b", - Name: "Mixtral 8x7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 0.7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "pixtral-12b": { - ID: "pixtral-12b", - Name: "Pixtral 12B", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "pixtral-large-latest": { - ID: "pixtral-large-latest", - Name: "Pixtral Large", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - }, - }, - "modelscope": { - ID: "modelscope", - Env: []string{"MODELSCOPE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "ModelScope", - Models: map[string]ModelInfo{ - "Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3-235B-A22B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-30B-A3B-Instruct-2507": { - ID: "Qwen/Qwen3-30B-A3B-Instruct-2507", - Name: "Qwen3 30B A3B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "Qwen/Qwen3-30B-A3B-Thinking-2507": { - ID: "Qwen/Qwen3-30B-A3B-Thinking-2507", - Name: "Qwen3 30B A3B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "Qwen/Qwen3-Coder-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-Coder-30B-A3B-Instruct", - Name: "Qwen3 Coder 30B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "ZhipuAI/GLM-4.5": { - ID: "ZhipuAI/GLM-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "ZhipuAI/GLM-4.6": { - ID: "ZhipuAI/GLM-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 98304, - }, - }, - }, - }, - "moonshotai": { - ID: "moonshotai", - Env: []string{"MOONSHOT_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Moonshot AI", - Models: map[string]ModelInfo{ - "kimi-k2-0711-preview": { - ID: "kimi-k2-0711-preview", - Name: "Kimi K2 0711", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "kimi-k2-0905-preview": { - ID: "kimi-k2-0905-preview", - Name: "Kimi K2 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-thinking-turbo": { - ID: "kimi-k2-thinking-turbo", - Name: "Kimi K2 Thinking Turbo", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.15, - Output: 8, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-turbo-preview": { - ID: "kimi-k2-turbo-preview", - Name: "Kimi K2 Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.4, - Output: 10, - CacheRead: &[]float64{0.6}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - }, - }, - "moonshotai-cn": { - ID: "moonshotai-cn", - Env: []string{"MOONSHOT_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Moonshot AI (China)", - Models: map[string]ModelInfo{ - "kimi-k2-0711-preview": { - ID: "kimi-k2-0711-preview", - Name: "Kimi K2 0711", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "kimi-k2-0905-preview": { - ID: "kimi-k2-0905-preview", - Name: "Kimi K2 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-thinking-turbo": { - ID: "kimi-k2-thinking-turbo", - Name: "Kimi K2 Thinking Turbo", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.15, - Output: 8, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-turbo-preview": { - ID: "kimi-k2-turbo-preview", - Name: "Kimi K2 Turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.4, - Output: 10, - CacheRead: &[]float64{0.6}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - }, - }, - "morph": { - ID: "morph", - Env: []string{"MORPH_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Morph", - Models: map[string]ModelInfo{ - "auto": { - ID: "auto", - Name: "Auto", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.85, - Output: 1.55, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "morph-v3-fast": { - ID: "morph-v3-fast", - Name: "Morph v3 Fast", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.8, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 16000, - }, - }, - "morph-v3-large": { - ID: "morph-v3-large", - Name: "Morph v3 Large", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.9, - Output: 1.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - }, - }, - "nano-gpt": { - ID: "nano-gpt", - Env: []string{"NANO_GPT_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "NanoGPT", - Models: map[string]ModelInfo{ - "deepseek/deepseek-r1": { - ID: "deepseek/deepseek-r1", - Name: "Deepseek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek/deepseek-v3.2:thinking": { - ID: "deepseek/deepseek-v3.2:thinking", - Name: "Deepseek V3.2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta-llama/llama-3.3-70b-instruct": { - ID: "meta-llama/llama-3.3-70b-instruct", - Name: "Llama 3.3 70b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "meta-llama/llama-4-maverick": { - ID: "meta-llama/llama-4-maverick", - Name: "Llama 4 Maverick", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "minimax/minimax-m2.1": { - ID: "minimax/minimax-m2.1", - Name: "Minimax M2.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistralai/devstral-2-123b-instruct-2512": { - ID: "mistralai/devstral-2-123b-instruct-2512", - Name: "Devstral 2 123b Instruct 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "mistralai/ministral-14b-instruct-2512": { - ID: "mistralai/ministral-14b-instruct-2512", - Name: "Ministral 14b Instruct 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "mistralai/mistral-large-3-675b-instruct-2512": { - ID: "mistralai/mistral-large-3-675b-instruct-2512", - Name: "Mistral Large 3 675b Instruct 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "moonshotai/kimi-k2-instruct": { - ID: "moonshotai/kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "moonshotai/kimi-k2-thinking": { - ID: "moonshotai/kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "nousresearch/hermes-4-405b:thinking": { - ID: "nousresearch/hermes-4-405b:thinking", - Name: "Hermes 4 405b Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "nvidia/llama-3_3-nemotron-super-49b-v1_5": { - ID: "nvidia/llama-3_3-nemotron-super-49b-v1_5", - Name: "Llama 3 3 Nemotron Super 49B V1 5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT Oss 120b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "qwen/qwen3-235b-a22b-thinking-2507": { - ID: "qwen/qwen3-235b-a22b-thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 8192, - }, - }, - "qwen/qwen3-coder": { - ID: "qwen/qwen3-coder", - Name: "Qwen3 Coder", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 106000, - Output: 8192, - }, - }, - "z-ai/glm-4.6": { - ID: "z-ai/glm-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "z-ai/glm-4.6:thinking": { - ID: "z-ai/glm-4.6:thinking", - Name: "GLM 4.6 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "zai-org/glm-4.5-air": { - ID: "zai-org/glm-4.5-air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "zai-org/glm-4.5-air:thinking": { - ID: "zai-org/glm-4.5-air:thinking", - Name: "GLM 4.5 Air Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "zai-org/glm-4.7": { - ID: "zai-org/glm-4.7", - Name: "GLM 4.7", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 8192, - }, - }, - "zai-org/glm-4.7:thinking": { - ID: "zai-org/glm-4.7:thinking", - Name: "GLM 4.7 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - }, - }, - "nebius": { - ID: "nebius", - Env: []string{"NEBIUS_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Nebius Token Factory", - Models: map[string]ModelInfo{ - "NousResearch/hermes-4-405b": { - ID: "NousResearch/hermes-4-405b", - Name: "Hermes-4 405B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "NousResearch/hermes-4-70b": { - ID: "NousResearch/hermes-4-70b", - Name: "Hermes 4 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "deepseek-ai/deepseek-v3": { - ID: "deepseek-ai/deepseek-v3", - Name: "DeepSeek V3", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "meta-llama/llama-3.3-70b-instruct-base": { - ID: "meta-llama/llama-3.3-70b-instruct-base", - Name: "Llama-3.3-70B-Instruct (Base)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "meta-llama/llama-3.3-70b-instruct-fast": { - ID: "meta-llama/llama-3.3-70b-instruct-fast", - Name: "Llama-3.3-70B-Instruct (Fast)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "meta-llama/llama-3_1-405b-instruct": { - ID: "meta-llama/llama-3_1-405b-instruct", - Name: "Llama 3.1 405B Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "moonshotai/kimi-k2-instruct": { - ID: "moonshotai/kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "nvidia/llama-3_1-nemotron-ultra-253b-v1": { - ID: "nvidia/llama-3_1-nemotron-ultra-253b-v1", - Name: "Llama 3.1 Nemotron Ultra 253B v1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen/qwen3-235b-a22b-instruct-2507": { - ID: "qwen/qwen3-235b-a22b-instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 8192, - }, - }, - "qwen/qwen3-235b-a22b-thinking-2507": { - ID: "qwen/qwen3-235b-a22b-thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 8192, - }, - }, - "qwen/qwen3-coder-480b-a35b-instruct": { - ID: "qwen/qwen3-coder-480b-a35b-instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "zai-org/glm-4.5": { - ID: "zai-org/glm-4.5", - Name: "GLM 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "zai-org/glm-4.5-air": { - ID: "zai-org/glm-4.5-air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - }, - }, - "nvidia": { - ID: "nvidia", - Env: []string{"NVIDIA_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Nvidia", - Models: map[string]ModelInfo{ - "black-forest-labs/flux.1-dev": { - ID: "black-forest-labs/flux.1-dev", - Name: "FLUX.1-dev", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4096, - Output: 0, - }, - }, - "deepseek-ai/deepseek-coder-6.7b-instruct": { - ID: "deepseek-ai/deepseek-coder-6.7b-instruct", - Name: "Deepseek Coder 6.7b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "deepseek-ai/deepseek-r1": { - ID: "deepseek-ai/deepseek-r1", - Name: "Deepseek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "deepseek-ai/deepseek-r1-0528": { - ID: "deepseek-ai/deepseek-r1-0528", - Name: "Deepseek R1 0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "deepseek-ai/deepseek-v3.1": { - ID: "deepseek-ai/deepseek-v3.1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek-ai/deepseek-v3.1-terminus": { - ID: "deepseek-ai/deepseek-v3.1-terminus", - Name: "DeepSeek V3.1 Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "google/codegemma-1.1-7b": { - ID: "google/codegemma-1.1-7b", - Name: "Codegemma 1.1 7b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/codegemma-7b": { - ID: "google/codegemma-7b", - Name: "Codegemma 7b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/gemma-2-27b-it": { - ID: "google/gemma-2-27b-it", - Name: "Gemma 2 27b It", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/gemma-2-2b-it": { - ID: "google/gemma-2-2b-it", - Name: "Gemma 2 2b It", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/gemma-3-12b-it": { - ID: "google/gemma-3-12b-it", - Name: "Gemma 3 12b It", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/gemma-3-1b-it": { - ID: "google/gemma-3-1b-it", - Name: "Gemma 3 1b It", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/gemma-3-27b-it": { - ID: "google/gemma-3-27b-it", - Name: "Gemma-3-27B-IT", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "google/gemma-3n-e2b-it": { - ID: "google/gemma-3n-e2b-it", - Name: "Gemma 3n E2b It", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "google/gemma-3n-e4b-it": { - ID: "google/gemma-3n-e4b-it", - Name: "Gemma 3n E4b It", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/codellama-70b": { - ID: "meta/codellama-70b", - Name: "Codellama 70b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-3.1-405b-instruct": { - ID: "meta/llama-3.1-405b-instruct", - Name: "Llama 3.1 405b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-3.1-70b-instruct": { - ID: "meta/llama-3.1-70b-instruct", - Name: "Llama 3.1 70b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-3.2-11b-vision-instruct": { - ID: "meta/llama-3.2-11b-vision-instruct", - Name: "Llama 3.2 11b Vision Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-3.2-1b-instruct": { - ID: "meta/llama-3.2-1b-instruct", - Name: "Llama 3.2 1b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-3.3-70b-instruct": { - ID: "meta/llama-3.3-70b-instruct", - Name: "Llama 3.3 70b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-4-maverick-17b-128e-instruct": { - ID: "meta/llama-4-maverick-17b-128e-instruct", - Name: "Llama 4 Maverick 17b 128e Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-4-scout-17b-16e-instruct": { - ID: "meta/llama-4-scout-17b-16e-instruct", - Name: "Llama 4 Scout 17b 16e Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama3-70b-instruct": { - ID: "meta/llama3-70b-instruct", - Name: "Llama3 70b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama3-8b-instruct": { - ID: "meta/llama3-8b-instruct", - Name: "Llama3 8b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3-medium-128k-instruct": { - ID: "microsoft/phi-3-medium-128k-instruct", - Name: "Phi 3 Medium 128k Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3-medium-4k-instruct": { - ID: "microsoft/phi-3-medium-4k-instruct", - Name: "Phi 3 Medium 4k Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4000, - Output: 4096, - }, - }, - "microsoft/phi-3-small-128k-instruct": { - ID: "microsoft/phi-3-small-128k-instruct", - Name: "Phi 3 Small 128k Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3-small-8k-instruct": { - ID: "microsoft/phi-3-small-8k-instruct", - Name: "Phi 3 Small 8k Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8000, - Output: 4096, - }, - }, - "microsoft/phi-3-vision-128k-instruct": { - ID: "microsoft/phi-3-vision-128k-instruct", - Name: "Phi 3 Vision 128k Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3.5-moe-instruct": { - ID: "microsoft/phi-3.5-moe-instruct", - Name: "Phi 3.5 Moe Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-3.5-vision-instruct": { - ID: "microsoft/phi-3.5-vision-instruct", - Name: "Phi 3.5 Vision Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "microsoft/phi-4-mini-instruct": { - ID: "microsoft/phi-4-mini-instruct", - Name: "Phi-4-Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "minimaxai/minimax-m2": { - ID: "minimaxai/minimax-m2", - Name: "MiniMax-M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "mistralai/codestral-22b-instruct-v0.1": { - ID: "mistralai/codestral-22b-instruct-v0.1", - Name: "Codestral 22b Instruct V0.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistralai/devstral-2-123b-instruct-2512": { - ID: "mistralai/devstral-2-123b-instruct-2512", - Name: "Devstral-2-123B-Instruct-2512", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistralai/mamba-codestral-7b-v0.1": { - ID: "mistralai/mamba-codestral-7b-v0.1", - Name: "Mamba Codestral 7b V0.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistralai/ministral-14b-instruct-2512": { - ID: "mistralai/ministral-14b-instruct-2512", - Name: "Ministral 3 14B Instruct 2512", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistralai/mistral-large-2-instruct": { - ID: "mistralai/mistral-large-2-instruct", - Name: "Mistral Large 2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "mistralai/mistral-large-3-675b-instruct-2512": { - ID: "mistralai/mistral-large-3-675b-instruct-2512", - Name: "Mistral Large 3 675B Instruct 2512", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistralai/mistral-small-3.1-24b-instruct-2503": { - ID: "mistralai/mistral-small-3.1-24b-instruct-2503", - Name: "Mistral Small 3.1 24b Instruct 2503", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "moonshotai/kimi-k2-instruct": { - ID: "moonshotai/kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "moonshotai/kimi-k2-instruct-0905": { - ID: "moonshotai/kimi-k2-instruct-0905", - Name: "Kimi K2 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "moonshotai/kimi-k2-thinking": { - ID: "moonshotai/kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "nvidia/cosmos-nemotron-34b": { - ID: "nvidia/cosmos-nemotron-34b", - Name: "Cosmos Nemotron 34B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "nvidia/llama-3.1-nemotron-51b-instruct": { - ID: "nvidia/llama-3.1-nemotron-51b-instruct", - Name: "Llama 3.1 Nemotron 51b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia/llama-3.1-nemotron-70b-instruct": { - ID: "nvidia/llama-3.1-nemotron-70b-instruct", - Name: "Llama 3.1 Nemotron 70b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia/llama-3.1-nemotron-ultra-253b-v1": { - ID: "nvidia/llama-3.1-nemotron-ultra-253b-v1", - Name: "Llama-3.1-Nemotron-Ultra-253B-v1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "nvidia/llama-3.3-nemotron-super-49b-v1": { - ID: "nvidia/llama-3.3-nemotron-super-49b-v1", - Name: "Llama 3.3 Nemotron Super 49b V1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia/llama-3.3-nemotron-super-49b-v1.5": { - ID: "nvidia/llama-3.3-nemotron-super-49b-v1.5", - Name: "Llama 3.3 Nemotron Super 49b V1.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia/llama-embed-nemotron-8b": { - ID: "nvidia/llama-embed-nemotron-8b", - Name: "Llama Embed Nemotron 8B", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 2048, - }, - }, - "nvidia/llama3-chatqa-1.5-70b": { - ID: "nvidia/llama3-chatqa-1.5-70b", - Name: "Llama3 Chatqa 1.5 70b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia/nemoretriever-ocr-v1": { - ID: "nvidia/nemoretriever-ocr-v1", - Name: "NeMo Retriever OCR v1", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 4096, - }, - }, - "nvidia/nemotron-3-nano-30b-a3b": { - ID: "nvidia/nemotron-3-nano-30b-a3b", - Name: "nemotron-3-nano-30b-a3b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "nvidia/nemotron-4-340b-instruct": { - ID: "nvidia/nemotron-4-340b-instruct", - Name: "Nemotron 4 340b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "nvidia/nvidia-nemotron-nano-9b-v2": { - ID: "nvidia/nvidia-nemotron-nano-9b-v2", - Name: "nvidia-nemotron-nano-9b-v2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "nvidia/parakeet-tdt-0.6b-v2": { - ID: "nvidia/parakeet-tdt-0.6b-v2", - Name: "Parakeet TDT 0.6B v2", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 4096, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT-OSS-120B", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/whisper-large-v3": { - ID: "openai/whisper-large-v3", - Name: "Whisper Large v3", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 4096, - }, - }, - "qwen/qwen2.5-coder-32b-instruct": { - ID: "qwen/qwen2.5-coder-32b-instruct", - Name: "Qwen2.5 Coder 32b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "qwen/qwen2.5-coder-7b-instruct": { - ID: "qwen/qwen2.5-coder-7b-instruct", - Name: "Qwen2.5 Coder 7b Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "qwen/qwen3-235b-a22b": { - ID: "qwen/qwen3-235b-a22b", - Name: "Qwen3-235B-A22B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "qwen/qwen3-coder-480b-a35b-instruct": { - ID: "qwen/qwen3-coder-480b-a35b-instruct", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "qwen/qwen3-next-80b-a3b-instruct": { - ID: "qwen/qwen3-next-80b-a3b-instruct", - Name: "Qwen3-Next-80B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "qwen/qwen3-next-80b-a3b-thinking": { - ID: "qwen/qwen3-next-80b-a3b-thinking", - Name: "Qwen3-Next-80B-A3B-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "qwen/qwq-32b": { - ID: "qwen/qwq-32b", - Name: "Qwq 32b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - }, - }, - "ollama-cloud": { - ID: "ollama-cloud", - Env: []string{"OLLAMA_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Ollama Cloud", - Models: map[string]ModelInfo{ - "cogito-2.1:671b-cloud": { - ID: "cogito-2.1:671b-cloud", - Name: "Cogito 2.1 671B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 160000, - Output: 8192, - }, - }, - "deepseek-v3.1:671b-cloud": { - ID: "deepseek-v3.1:671b-cloud", - Name: "DeepSeek-V3.1 671B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 160000, - Output: 8192, - }, - }, - "gemini-3-pro-preview:latest": { - ID: "gemini-3-pro-preview:latest", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "glm-4.6:cloud": { - ID: "glm-4.6:cloud", - Name: "GLM-4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "gpt-oss:120b-cloud": { - ID: "gpt-oss:120b-cloud", - Name: "GPT-OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "gpt-oss:20b-cloud": { - ID: "gpt-oss:20b-cloud", - Name: "GPT-OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "kimi-k2-thinking:cloud": { - ID: "kimi-k2-thinking:cloud", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8192, - }, - }, - "kimi-k2:1t-cloud": { - ID: "kimi-k2:1t-cloud", - Name: "Kimi K2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8192, - }, - }, - "minimax-m2:cloud": { - ID: "minimax-m2:cloud", - Name: "MiniMax M2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "qwen3-coder:480b-cloud": { - ID: "qwen3-coder:480b-cloud", - Name: "Qwen3 Coder 480B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "qwen3-vl-235b-cloud": { - ID: "qwen3-vl-235b-cloud", - Name: "Qwen3-VL 235B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "qwen3-vl-235b-instruct-cloud": { - ID: "qwen3-vl-235b-instruct-cloud", - Name: "Qwen3-VL 235B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - }, - }, - "openai": { - ID: "openai", - Env: []string{"OPENAI_API_KEY" }, - NPM: "@ai-sdk/openai", - Name: "OpenAI", - Models: map[string]ModelInfo{ - "codex-mini-latest": { - ID: "codex-mini-latest", - Name: "Codex Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.5, - Output: 6, - CacheRead: &[]float64{0.375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "gpt-3.5-turbo": { - ID: "gpt-3.5-turbo", - Name: "GPT-3.5-turbo", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16385, - Output: 4096, - }, - }, - "gpt-4": { - ID: "gpt-4", - Name: "GPT-4", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 30, - Output: 60, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "gpt-4-turbo": { - ID: "gpt-4-turbo", - Name: "GPT-4 Turbo", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "gpt-4.1": { - ID: "gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-mini": { - ID: "gpt-4.1-mini", - Name: "GPT-4.1 mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4.1-nano": { - ID: "gpt-4.1-nano", - Name: "GPT-4.1 nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "gpt-4o": { - ID: "gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-2024-05-13": { - ID: "gpt-4o-2024-05-13", - Name: "GPT-4o (2024-05-13)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "gpt-4o-2024-08-06": { - ID: "gpt-4o-2024-08-06", - Name: "GPT-4o (2024-08-06)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-2024-11-20": { - ID: "gpt-4o-2024-11-20", - Name: "GPT-4o (2024-11-20)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-4o-mini": { - ID: "gpt-4o-mini", - Name: "GPT-4o mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-chat-latest": { - ID: "gpt-5-chat-latest", - Name: "GPT-5 Chat (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-pro": { - ID: "gpt-5-pro", - Name: "GPT-5 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 272000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-chat-latest": { - ID: "gpt-5.1-chat-latest", - Name: "GPT-5.1 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "GPT-5.1 Codex", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-max": { - ID: "gpt-5.1-codex-max", - Name: "GPT-5.1 Codex Max", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "GPT-5.1 Codex mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2": { - ID: "gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2-chat-latest": { - ID: "gpt-5.2-chat-latest", - Name: "GPT-5.2 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "gpt-5.2-pro": { - ID: "gpt-5.2-pro", - Name: "GPT-5.2 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 21, - Output: 168, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "o1": { - ID: "o1", - Name: "o1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o1-mini": { - ID: "o1-mini", - Name: "o1-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 65536, - }, - }, - "o1-preview": { - ID: "o1-preview", - Name: "o1-preview", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "o1-pro": { - ID: "o1-pro", - Name: "o1-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 150, - Output: 600, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3": { - ID: "o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-deep-research": { - ID: "o3-deep-research", - Name: "o3-deep-research", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 10, - Output: 40, - CacheRead: &[]float64{2.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-mini": { - ID: "o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o3-pro": { - ID: "o3-pro", - Name: "o3-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 20, - Output: 80, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o4-mini": { - ID: "o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "o4-mini-deep-research": { - ID: "o4-mini-deep-research", - Name: "o4-mini-deep-research", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "text-embedding-3-large": { - ID: "text-embedding-3-large", - Name: "text-embedding-3-large", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.13, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 3072, - }, - }, - "text-embedding-3-small": { - ID: "text-embedding-3-small", - Name: "text-embedding-3-small", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.02, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 1536, - }, - }, - "text-embedding-ada-002": { - ID: "text-embedding-ada-002", - Name: "text-embedding-ada-002", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 1536, - }, - }, - }, - }, - "opencode": { - ID: "opencode", - Env: []string{"OPENCODE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "OpenCode Zen", - Models: map[string]ModelInfo{ - "alpha-gd4": { - ID: "alpha-gd4", - Name: "Alpha GD4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "alpha-glm-4.7": { - ID: "alpha-glm-4.7", - Name: "Alpha GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.6}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "big-pickle": { - ID: "big-pickle", - Name: "Big Pickle", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 128000, - }, - }, - "claude-3-5-haiku": { - ID: "claude-3-5-haiku", - Name: "Claude Haiku 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "claude-haiku-4-5": { - ID: "claude-haiku-4-5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-opus-4-1": { - ID: "claude-opus-4-1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "claude-opus-4-5": { - ID: "claude-opus-4-5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "claude-sonnet-4": { - ID: "claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "claude-sonnet-4-5": { - ID: "claude-sonnet-4-5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "gemini-3-flash": { - ID: "gemini-3-flash", - Name: "Gemini 3 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-3-pro": { - ID: "gemini-3-pro", - Name: "Gemini 3 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "glm-4.7-free": { - ID: "glm-4.7-free", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.07, - Output: 8.5, - CacheRead: &[]float64{0.107}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-codex": { - ID: "gpt-5-codex", - Name: "GPT-5 Codex", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.07, - Output: 8.5, - CacheRead: &[]float64{0.107}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1": { - ID: "gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.07, - Output: 8.5, - CacheRead: &[]float64{0.107}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex": { - ID: "gpt-5.1-codex", - Name: "GPT-5.1 Codex", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.07, - Output: 8.5, - CacheRead: &[]float64{0.107}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-max": { - ID: "gpt-5.1-codex-max", - Name: "GPT-5.1 Codex Max", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.1-codex-mini": { - ID: "gpt-5.1-codex-mini", - Name: "GPT-5.1 Codex Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5.2": { - ID: "gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "grok-code": { - ID: "grok-code", - Name: "Grok Code Fast 1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "kimi-k2": { - ID: "kimi-k2", - Name: "Kimi K2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2.5, - CacheRead: &[]float64{0.4}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2.5, - CacheRead: &[]float64{0.4}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "minimax-m2.1-free": { - ID: "minimax-m2.1-free", - Name: "MiniMax M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "qwen3-coder": { - ID: "qwen3-coder", - Name: "Qwen3 Coder", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.45, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - }, - }, - "openrouter": { - ID: "openrouter", - Env: []string{"OPENROUTER_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "OpenRouter", - Models: map[string]ModelInfo{ - "anthropic/claude-3.5-haiku": { - ID: "anthropic/claude-3.5-haiku", - Name: "Claude Haiku 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic/claude-3.7-sonnet": { - ID: "anthropic/claude-3.7-sonnet", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 128000, - }, - }, - "anthropic/claude-haiku-4.5": { - ID: "anthropic/claude-haiku-4.5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-opus-4": { - ID: "anthropic/claude-opus-4", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4.1": { - ID: "anthropic/claude-opus-4.1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4.5": { - ID: "anthropic/claude-opus-4.5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-sonnet-4": { - ID: "anthropic/claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4.5": { - ID: "anthropic/claude-sonnet-4.5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "cognitivecomputations/dolphin3.0-mistral-24b": { - ID: "cognitivecomputations/dolphin3.0-mistral-24b", - Name: "Dolphin3.0 Mistral 24B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "cognitivecomputations/dolphin3.0-r1-mistral-24b": { - ID: "cognitivecomputations/dolphin3.0-r1-mistral-24b", - Name: "Dolphin3.0 R1 Mistral 24B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "deepseek/deepseek-chat-v3-0324": { - ID: "deepseek/deepseek-chat-v3-0324", - Name: "DeepSeek V3 0324", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 8192, - }, - }, - "deepseek/deepseek-chat-v3.1": { - ID: "deepseek/deepseek-chat-v3.1", - Name: "DeepSeek-V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek/deepseek-r1-0528-qwen3-8b:free": { - ID: "deepseek/deepseek-r1-0528-qwen3-8b:free", - Name: "Deepseek R1 0528 Qwen3 8B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "deepseek/deepseek-r1-0528:free": { - ID: "deepseek/deepseek-r1-0528:free", - Name: "R1 0528 (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek/deepseek-r1-distill-llama-70b": { - ID: "deepseek/deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "deepseek/deepseek-r1-distill-qwen-14b": { - ID: "deepseek/deepseek-r1-distill-qwen-14b", - Name: "DeepSeek R1 Distill Qwen 14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 8192, - }, - }, - "deepseek/deepseek-r1:free": { - ID: "deepseek/deepseek-r1:free", - Name: "R1 (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek/deepseek-v3-base:free": { - ID: "deepseek/deepseek-v3-base:free", - Name: "DeepSeek V3 Base (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "deepseek/deepseek-v3.1-terminus": { - ID: "deepseek/deepseek-v3.1-terminus", - Name: "DeepSeek V3.1 Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "deepseek/deepseek-v3.1-terminus:exacto": { - ID: "deepseek/deepseek-v3.1-terminus:exacto", - Name: "DeepSeek V3.1 Terminus (exacto)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "deepseek/deepseek-v3.2": { - ID: "deepseek/deepseek-v3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "deepseek/deepseek-v3.2-speciale": { - ID: "deepseek/deepseek-v3.2-speciale", - Name: "DeepSeek V3.2 Speciale", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.41, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 65536, - }, - }, - "featherless/qwerky-72b": { - ID: "featherless/qwerky-72b", - Name: "Qwerky 72B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "google/gemini-2.0-flash-001": { - ID: "google/gemini-2.0-flash-001", - Name: "Gemini 2.0 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "google/gemini-2.0-flash-exp:free": { - ID: "google/gemini-2.0-flash-exp:free", - Name: "Gemini 2.0 Flash Experimental (free)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 1048576, - }, - }, - "google/gemini-2.5-flash": { - ID: "google/gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.0375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-flash-lite": { - ID: "google/gemini-2.5-flash-lite", - Name: "Gemini 2.5 Flash Lite", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-flash-lite-preview-09-2025": { - ID: "google/gemini-2.5-flash-lite-preview-09-2025", - Name: "Gemini 2.5 Flash Lite Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-flash-preview-09-2025": { - ID: "google/gemini-2.5-flash-preview-09-2025", - Name: "Gemini 2.5 Flash Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.031}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-pro": { - ID: "google/gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-pro-preview-05-06": { - ID: "google/gemini-2.5-pro-preview-05-06", - Name: "Gemini 2.5 Pro Preview 05-06", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-pro-preview-06-05": { - ID: "google/gemini-2.5-pro-preview-06-05", - Name: "Gemini 2.5 Pro Preview 06-05", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-flash-preview": { - ID: "google/gemini-3-flash-preview", - Name: "Gemini 3 Flash Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-pro-preview": { - ID: "google/gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1050000, - Output: 66000, - }, - }, - "google/gemma-2-9b-it:free": { - ID: "google/gemma-2-9b-it:free", - Name: "Gemma 2 9B (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "google/gemma-3-12b-it": { - ID: "google/gemma-3-12b-it", - Name: "Gemma 3 12B IT", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 96000, - Output: 8192, - }, - }, - "google/gemma-3-27b-it": { - ID: "google/gemma-3-27b-it", - Name: "Gemma 3 27B IT", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 96000, - Output: 8192, - }, - }, - "google/gemma-3n-e4b-it": { - ID: "google/gemma-3n-e4b-it", - Name: "Gemma 3n E4B IT", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "google/gemma-3n-e4b-it:free": { - ID: "google/gemma-3n-e4b-it:free", - Name: "Gemma 3n 4B (free)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "kwaipilot/kat-coder-pro:free": { - ID: "kwaipilot/kat-coder-pro:free", - Name: "Kat Coder Pro (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 65536, - }, - }, - "meta-llama/llama-3.2-11b-vision-instruct": { - ID: "meta-llama/llama-3.2-11b-vision-instruct", - Name: "Llama 3.2 11B Vision Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "meta-llama/llama-3.3-70b-instruct:free": { - ID: "meta-llama/llama-3.3-70b-instruct:free", - Name: "Llama 3.3 70B Instruct (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 65536, - }, - }, - "meta-llama/llama-4-scout:free": { - ID: "meta-llama/llama-4-scout:free", - Name: "Llama 4 Scout (free)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 64000, - }, - }, - "microsoft/mai-ds-r1:free": { - ID: "microsoft/mai-ds-r1:free", - Name: "MAI DS R1 (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "minimax/minimax-01": { - ID: "minimax/minimax-01", - Name: "MiniMax-01", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 1000000, - }, - }, - "minimax/minimax-m1": { - ID: "minimax/minimax-m1", - Name: "MiniMax M1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 40000, - }, - }, - "minimax/minimax-m2": { - ID: "minimax/minimax-m2", - Name: "MiniMax M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 1.15, - CacheRead: &[]float64{0.28}[0], - CacheWrite: &[]float64{1.15}[0], - }, - Limit: Limit{ - Context: 196600, - Output: 118000, - }, - }, - "minimax/minimax-m2.1": { - ID: "minimax/minimax-m2.1", - Name: "MiniMax M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "mistralai/codestral-2508": { - ID: "mistralai/codestral-2508", - Name: "Codestral 2508", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - "mistralai/devstral-2512": { - ID: "mistralai/devstral-2512", - Name: "Devstral 2 2512", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistralai/devstral-2512:free": { - ID: "mistralai/devstral-2512:free", - Name: "Devstral 2 2512 (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistralai/devstral-medium-2507": { - ID: "mistralai/devstral-medium-2507", - Name: "Devstral Medium", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "mistralai/devstral-small-2505": { - ID: "mistralai/devstral-small-2505", - Name: "Devstral Small", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.12, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistralai/devstral-small-2505:free": { - ID: "mistralai/devstral-small-2505:free", - Name: "Devstral Small 2505 (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "mistralai/devstral-small-2507": { - ID: "mistralai/devstral-small-2507", - Name: "Devstral Small 1.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "mistralai/mistral-7b-instruct:free": { - ID: "mistralai/mistral-7b-instruct:free", - Name: "Mistral 7B Instruct (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "mistralai/mistral-medium-3": { - ID: "mistralai/mistral-medium-3", - Name: "Mistral Medium 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "mistralai/mistral-medium-3.1": { - ID: "mistralai/mistral-medium-3.1", - Name: "Mistral Medium 3.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistralai/mistral-nemo:free": { - ID: "mistralai/mistral-nemo:free", - Name: "Mistral Nemo (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "mistralai/mistral-small-3.1-24b-instruct": { - ID: "mistralai/mistral-small-3.1-24b-instruct", - Name: "Mistral Small 3.1 24B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistralai/mistral-small-3.2-24b-instruct": { - ID: "mistralai/mistral-small-3.2-24b-instruct", - Name: "Mistral Small 3.2 24B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 96000, - Output: 8192, - }, - }, - "mistralai/mistral-small-3.2-24b-instruct:free": { - ID: "mistralai/mistral-small-3.2-24b-instruct:free", - Name: "Mistral Small 3.2 24B (free)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 96000, - Output: 96000, - }, - }, - "moonshotai/kimi-dev-72b:free": { - ID: "moonshotai/kimi-dev-72b:free", - Name: "Kimi Dev 72b (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "moonshotai/kimi-k2": { - ID: "moonshotai/kimi-k2", - Name: "Kimi K2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "moonshotai/kimi-k2-0905": { - ID: "moonshotai/kimi-k2-0905", - Name: "Kimi K2 Instruct 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "moonshotai/kimi-k2-0905:exacto": { - ID: "moonshotai/kimi-k2-0905:exacto", - Name: "Kimi K2 Instruct 0905 (exacto)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 16384, - }, - }, - "moonshotai/kimi-k2-thinking": { - ID: "moonshotai/kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "moonshotai/kimi-k2:free": { - ID: "moonshotai/kimi-k2:free", - Name: "Kimi K2 (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32800, - Output: 32800, - }, - }, - "nousresearch/deephermes-3-llama-3-8b-preview": { - ID: "nousresearch/deephermes-3-llama-3-8b-preview", - Name: "DeepHermes 3 Llama 3 8B Preview", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "nousresearch/hermes-4-405b": { - ID: "nousresearch/hermes-4-405b", - Name: "Hermes 4 405B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "nousresearch/hermes-4-70b": { - ID: "nousresearch/hermes-4-70b", - Name: "Hermes 4 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "nvidia/nemotron-nano-9b-v2": { - ID: "nvidia/nemotron-nano-9b-v2", - Name: "nvidia-nemotron-nano-9b-v2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.16, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "openai/gpt-4.1": { - ID: "openai/gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4.1-mini": { - ID: "openai/gpt-4.1-mini", - Name: "GPT-4.1 Mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4o-mini": { - ID: "openai/gpt-4o-mini", - Name: "GPT-4o-mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5": { - ID: "openai/gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-chat": { - ID: "openai/gpt-5-chat", - Name: "GPT-5 Chat (latest)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-codex": { - ID: "openai/gpt-5-codex", - Name: "GPT-5 Codex", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-image": { - ID: "openai/gpt-5-image", - Name: "GPT-5 Image", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-mini": { - ID: "openai/gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-nano": { - ID: "openai/gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-pro": { - ID: "openai/gpt-5-pro", - Name: "GPT-5 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 120, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 272000, - }, - }, - "openai/gpt-5.1": { - ID: "openai/gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-chat": { - ID: "openai/gpt-5.1-chat", - Name: "GPT-5.1 Chat", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5.1-codex": { - ID: "openai/gpt-5.1-codex", - Name: "GPT-5.1-Codex", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-codex-mini": { - ID: "openai/gpt-5.1-codex-mini", - Name: "GPT-5.1-Codex-Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 100000, - }, - }, - "openai/gpt-5.2": { - ID: "openai/gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.2-chat-latest": { - ID: "openai/gpt-5.2-chat-latest", - Name: "GPT-5.2 Chat", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.175}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5.2-pro": { - ID: "openai/gpt-5.2-pro", - Name: "GPT-5.2 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 21, - Output: 168, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.072, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-120b:exacto": { - ID: "openai/gpt-oss-120b:exacto", - Name: "GPT OSS 120B (exacto)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.24, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-safeguard-20b": { - ID: "openai/gpt-oss-safeguard-20b", - Name: "GPT OSS Safeguard 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 65536, - }, - }, - "openai/o4-mini": { - ID: "openai/o4-mini", - Name: "o4 Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openrouter/sherlock-dash-alpha": { - ID: "openrouter/sherlock-dash-alpha", - Name: "Sherlock Dash Alpha", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1840000, - Output: 0, - }, - }, - "openrouter/sherlock-think-alpha": { - ID: "openrouter/sherlock-think-alpha", - Name: "Sherlock Think Alpha", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1840000, - Output: 0, - }, - }, - "qwen/qwen-2.5-coder-32b-instruct": { - ID: "qwen/qwen-2.5-coder-32b-instruct", - Name: "Qwen2.5 Coder 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "qwen/qwen2.5-vl-32b-instruct:free": { - ID: "qwen/qwen2.5-vl-32b-instruct:free", - Name: "Qwen2.5 VL 32B Instruct (free)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 8192, - }, - }, - "qwen/qwen2.5-vl-72b-instruct": { - ID: "qwen/qwen2.5-vl-72b-instruct", - Name: "Qwen2.5 VL 72B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "qwen/qwen2.5-vl-72b-instruct:free": { - ID: "qwen/qwen2.5-vl-72b-instruct:free", - Name: "Qwen2.5 VL 72B Instruct (free)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "qwen/qwen3-14b:free": { - ID: "qwen/qwen3-14b:free", - Name: "Qwen3 14B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "qwen/qwen3-235b-a22b-07-25": { - ID: "qwen/qwen3-235b-a22b-07-25", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.85, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "qwen/qwen3-235b-a22b-07-25:free": { - ID: "qwen/qwen3-235b-a22b-07-25:free", - Name: "Qwen3 235B A22B Instruct 2507 (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "qwen/qwen3-235b-a22b-thinking-2507": { - ID: "qwen/qwen3-235b-a22b-thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.078, - Output: 0.312, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 81920, - }, - }, - "qwen/qwen3-235b-a22b:free": { - ID: "qwen/qwen3-235b-a22b:free", - Name: "Qwen3 235B A22B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "qwen/qwen3-30b-a3b-instruct-2507": { - ID: "qwen/qwen3-30b-a3b-instruct-2507", - Name: "Qwen3 30B A3B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "qwen/qwen3-30b-a3b-thinking-2507": { - ID: "qwen/qwen3-30b-a3b-thinking-2507", - Name: "Qwen3 30B A3B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "qwen/qwen3-30b-a3b:free": { - ID: "qwen/qwen3-30b-a3b:free", - Name: "Qwen3 30B A3B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "qwen/qwen3-32b:free": { - ID: "qwen/qwen3-32b:free", - Name: "Qwen3 32B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "qwen/qwen3-8b:free": { - ID: "qwen/qwen3-8b:free", - Name: "Qwen3 8B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 40960, - Output: 40960, - }, - }, - "qwen/qwen3-coder": { - ID: "qwen/qwen3-coder", - Name: "Qwen3 Coder", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "qwen/qwen3-coder-flash": { - ID: "qwen/qwen3-coder-flash", - Name: "Qwen3 Coder Flash", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 66536, - }, - }, - "qwen/qwen3-coder:exacto": { - ID: "qwen/qwen3-coder:exacto", - Name: "Qwen3 Coder (exacto)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.38, - Output: 1.53, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen/qwen3-coder:free": { - ID: "qwen/qwen3-coder:free", - Name: "Qwen3 Coder 480B A35B Instruct (free)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "qwen/qwen3-max": { - ID: "qwen/qwen3-max", - Name: "Qwen3 Max", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "qwen/qwen3-next-80b-a3b-instruct": { - ID: "qwen/qwen3-next-80b-a3b-instruct", - Name: "Qwen3 Next 80B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "qwen/qwen3-next-80b-a3b-thinking": { - ID: "qwen/qwen3-next-80b-a3b-thinking", - Name: "Qwen3 Next 80B A3B Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "qwen/qwq-32b:free": { - ID: "qwen/qwq-32b:free", - Name: "QwQ 32B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "rekaai/reka-flash-3": { - ID: "rekaai/reka-flash-3", - Name: "Reka Flash 3", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "sarvamai/sarvam-m:free": { - ID: "sarvamai/sarvam-m:free", - Name: "Sarvam-M (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "thudm/glm-z1-32b:free": { - ID: "thudm/glm-z1-32b:free", - Name: "GLM Z1 32B (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "tngtech/deepseek-r1t2-chimera:free": { - ID: "tngtech/deepseek-r1t2-chimera:free", - Name: "DeepSeek R1T2 Chimera (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 163840, - }, - }, - "x-ai/grok-3": { - ID: "x-ai/grok-3", - Name: "Grok 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: &[]float64{15}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "x-ai/grok-3-beta": { - ID: "x-ai/grok-3-beta", - Name: "Grok 3 Beta", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: &[]float64{15}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "x-ai/grok-3-mini": { - ID: "x-ai/grok-3-mini", - Name: "Grok 3 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.5}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "x-ai/grok-3-mini-beta": { - ID: "x-ai/grok-3-mini-beta", - Name: "Grok 3 Mini Beta", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.5}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "x-ai/grok-4": { - ID: "x-ai/grok-4", - Name: "Grok 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: &[]float64{15}[0], - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "x-ai/grok-4-fast": { - ID: "x-ai/grok-4-fast", - Name: "Grok 4 Fast", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: &[]float64{0.05}[0], - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "x-ai/grok-4.1-fast": { - ID: "x-ai/grok-4.1-fast", - Name: "Grok 4.1 Fast", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: &[]float64{0.05}[0], - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "x-ai/grok-code-fast-1": { - ID: "x-ai/grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 10000, - }, - }, - "z-ai/glm-4.5": { - ID: "z-ai/glm-4.5", - Name: "GLM 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 96000, - }, - }, - "z-ai/glm-4.5-air": { - ID: "z-ai/glm-4.5-air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 96000, - }, - }, - "z-ai/glm-4.5-air:free": { - ID: "z-ai/glm-4.5-air:free", - Name: "GLM 4.5 Air (free)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 96000, - }, - }, - "z-ai/glm-4.5v": { - ID: "z-ai/glm-4.5v", - Name: "GLM 4.5V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 16384, - }, - }, - "z-ai/glm-4.6": { - ID: "z-ai/glm-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 128000, - }, - }, - "z-ai/glm-4.6:exacto": { - ID: "z-ai/glm-4.6:exacto", - Name: "GLM 4.6 (exacto)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 128000, - }, - }, - "z-ai/glm-4.7": { - ID: "z-ai/glm-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "ovhcloud": { - ID: "ovhcloud", - Env: []string{"OVHCLOUD_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "OVHcloud AI Endpoints", - Models: map[string]ModelInfo{ - "deepseek-r1-distill-llama-70b": { - ID: "deepseek-r1-distill-llama-70b", - Name: "DeepSeek-R1-Distill-Llama-70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.74, - Output: 0.74, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "gpt-oss-120b", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.09, - Output: 0.47, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "gpt-oss-20b": { - ID: "gpt-oss-20b", - Name: "gpt-oss-20b", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "llama-3.1-8b-instruct": { - ID: "llama-3.1-8b-instruct", - Name: "Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.11, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "llava-next-mistral-7b": { - ID: "llava-next-mistral-7b", - Name: "llava-next-mistral-7b", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.32, - Output: 0.32, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "meta-llama-3_1-70b-instruct": { - ID: "meta-llama-3_1-70b-instruct", - Name: "Meta-Llama-3_1-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.74, - Output: 0.74, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "meta-llama-3_3-70b-instruct": { - ID: "meta-llama-3_3-70b-instruct", - Name: "Meta-Llama-3_3-70B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.74, - Output: 0.74, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "mistral-7b-instruct-v0.3": { - ID: "mistral-7b-instruct-v0.3", - Name: "Mistral-7B-Instruct-v0.3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.11, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 127000, - }, - }, - "mistral-nemo-instruct-2407": { - ID: "mistral-nemo-instruct-2407", - Name: "Mistral-Nemo-Instruct-2407", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 118000, - Output: 118000, - }, - }, - "mistral-small-3.2-24b-instruct-2506": { - ID: "mistral-small-3.2-24b-instruct-2506", - Name: "Mistral-Small-3.2-24B-Instruct-2506", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.31, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mixtral-8x7b-instruct-v0.1": { - ID: "mixtral-8x7b-instruct-v0.1", - Name: "Mixtral-8x7B-Instruct-v0.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 0.7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "qwen2.5-coder-32b-instruct": { - ID: "qwen2.5-coder-32b-instruct", - Name: "Qwen2.5-Coder-32B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.96, - Output: 0.96, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "qwen2.5-vl-72b-instruct": { - ID: "qwen2.5-vl-72b-instruct", - Name: "Qwen2.5-VL-72B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.01, - Output: 1.01, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "qwen3-32b": { - ID: "qwen3-32b", - Name: "Qwen3-32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "qwen3-coder-30b-a3b-instruct": { - ID: "qwen3-coder-30b-a3b-instruct", - Name: "Qwen3-Coder-30B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.26, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 256000, - }, - }, - }, - }, - "perplexity": { - ID: "perplexity", - Env: []string{"PERPLEXITY_API_KEY" }, - NPM: "@ai-sdk/perplexity", - Name: "Perplexity", - Models: map[string]ModelInfo{ - "sonar": { - ID: "sonar", - Name: "Sonar", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "sonar-pro": { - ID: "sonar-pro", - Name: "Sonar Pro", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "sonar-reasoning-pro": { - ID: "sonar-reasoning-pro", - Name: "Sonar Reasoning Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - }, - }, - "poe": { - ID: "poe", - Env: []string{"POE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Poe", - Models: map[string]ModelInfo{ - "anthropic/claude-haiku-3": { - ID: "anthropic/claude-haiku-3", - Name: "Claude-Haiku-3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.21, - Output: 1.1, - CacheRead: &[]float64{0.021}[0], - CacheWrite: &[]float64{0.26}[0], - }, - Limit: Limit{ - Context: 189096, - Output: 8192, - }, - }, - "anthropic/claude-haiku-3.5": { - ID: "anthropic/claude-haiku-3.5", - Name: "Claude-Haiku-3.5", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.68, - Output: 3.4, - CacheRead: &[]float64{0.068}[0], - CacheWrite: &[]float64{0.85}[0], - }, - Limit: Limit{ - Context: 189096, - Output: 8192, - }, - }, - "anthropic/claude-haiku-3.5-search": { - ID: "anthropic/claude-haiku-3.5-search", - Name: "Claude-Haiku-3.5-Search", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.68, - Output: 3.4, - CacheRead: &[]float64{0.068}[0], - CacheWrite: &[]float64{0.85}[0], - }, - Limit: Limit{ - Context: 189096, - Output: 8192, - }, - }, - "anthropic/claude-haiku-4.5": { - ID: "anthropic/claude-haiku-4.5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.85, - Output: 4.3, - CacheRead: &[]float64{0.085}[0], - CacheWrite: &[]float64{1.1}[0], - }, - Limit: Limit{ - Context: 192000, - Output: 64000, - }, - }, - "anthropic/claude-opus-3": { - ID: "anthropic/claude-opus-3", - Name: "Claude-Opus-3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 13, - Output: 64, - CacheRead: &[]float64{1.3}[0], - CacheWrite: &[]float64{16}[0], - }, - Limit: Limit{ - Context: 189096, - Output: 8192, - }, - }, - "anthropic/claude-opus-4": { - ID: "anthropic/claude-opus-4", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 13, - Output: 64, - CacheRead: &[]float64{1.3}[0], - CacheWrite: &[]float64{16}[0], - }, - Limit: Limit{ - Context: 192512, - Output: 32768, - }, - }, - "anthropic/claude-opus-4-reasoning": { - ID: "anthropic/claude-opus-4-reasoning", - Name: "Claude Opus 4 Reasoning", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 13, - Output: 64, - CacheRead: &[]float64{1.3}[0], - CacheWrite: &[]float64{16}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 32768, - }, - }, - "anthropic/claude-opus-4-search": { - ID: "anthropic/claude-opus-4-search", - Name: "Claude Opus 4 Search", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 13, - Output: 64, - CacheRead: &[]float64{1.3}[0], - CacheWrite: &[]float64{16}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 128000, - }, - }, - "anthropic/claude-opus-4.1": { - ID: "anthropic/claude-opus-4.1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 13, - Output: 64, - CacheRead: &[]float64{1.3}[0], - CacheWrite: &[]float64{16}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 32000, - }, - }, - "anthropic/claude-opus-4.5": { - ID: "anthropic/claude-opus-4.5", - Name: "claude-opus-4.5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 4.3, - Output: 21, - CacheRead: &[]float64{0.43}[0], - CacheWrite: &[]float64{5.3}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-3.5": { - ID: "anthropic/claude-sonnet-3.5", - Name: "Claude-Sonnet-3.5", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 189096, - Output: 8192, - }, - }, - "anthropic/claude-sonnet-3.5-june": { - ID: "anthropic/claude-sonnet-3.5-june", - Name: "Claude-Sonnet-3.5-June", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 189096, - Output: 8192, - }, - }, - "anthropic/claude-sonnet-3.7": { - ID: "anthropic/claude-sonnet-3.7", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 32768, - }, - }, - "anthropic/claude-sonnet-3.7-reasoning": { - ID: "anthropic/claude-sonnet-3.7-reasoning", - Name: "Claude Sonnet 3.7 Reasoning", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 128000, - }, - }, - "anthropic/claude-sonnet-3.7-search": { - ID: "anthropic/claude-sonnet-3.7-search", - Name: "Claude Sonnet 3.7 Search", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 196608, - Output: 128000, - }, - }, - "anthropic/claude-sonnet-4": { - ID: "anthropic/claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 983040, - Output: 32768, - }, - }, - "anthropic/claude-sonnet-4-reasoning": { - ID: "anthropic/claude-sonnet-4-reasoning", - Name: "Claude Sonnet 4 Reasoning", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 983040, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4-search": { - ID: "anthropic/claude-sonnet-4-search", - Name: "Claude Sonnet 4 Search", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 983040, - Output: 128000, - }, - }, - "anthropic/claude-sonnet-4.5": { - ID: "anthropic/claude-sonnet-4.5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2.6, - Output: 13, - CacheRead: &[]float64{0.26}[0], - CacheWrite: &[]float64{3.2}[0], - }, - Limit: Limit{ - Context: 983040, - Output: 32768, - }, - }, - "cerebras/gpt-oss-120b-cs": { - ID: "cerebras/gpt-oss-120b-cs", - Name: "gpt-oss-120b-cs", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "cerebras/zai-glm-4.6-cs": { - ID: "cerebras/zai-glm-4.6-cs", - Name: "zai-glm-4.6-cs", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 40000, - }, - }, - "elevenlabs/elevenlabs-music": { - ID: "elevenlabs/elevenlabs-music", - Name: "ElevenLabs-Music", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000, - Output: 0, - }, - }, - "elevenlabs/elevenlabs-v2.5-turbo": { - ID: "elevenlabs/elevenlabs-v2.5-turbo", - Name: "ElevenLabs-v2.5-Turbo", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 0, - }, - }, - "elevenlabs/elevenlabs-v3": { - ID: "elevenlabs/elevenlabs-v3", - Name: "ElevenLabs-v3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 0, - }, - }, - "google/gemini-2.0-flash": { - ID: "google/gemini-2.0-flash", - Name: "Gemini-2.0-Flash", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.1, - Output: 0.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 990000, - Output: 8192, - }, - }, - "google/gemini-2.0-flash-lite": { - ID: "google/gemini-2.0-flash-lite", - Name: "Gemini-2.0-Flash-Lite", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.052, - Output: 0.21, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 990000, - Output: 8192, - }, - }, - "google/gemini-2.5-flash": { - ID: "google/gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.21, - Output: 1.8, - CacheRead: &[]float64{0.021}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1065535, - Output: 65535, - }, - }, - "google/gemini-2.5-flash-lite": { - ID: "google/gemini-2.5-flash-lite", - Name: "Gemini 2.5 Flash Lite", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1024000, - Output: 64000, - }, - }, - "google/gemini-2.5-pro": { - ID: "google/gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.87, - Output: 7, - CacheRead: &[]float64{0.087}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1065535, - Output: 65535, - }, - }, - "google/gemini-3-flash": { - ID: "google/gemini-3-flash", - Name: "gemini-3-flash", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.4, - Output: 2.4, - CacheRead: &[]float64{0.04}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-pro": { - ID: "google/gemini-3-pro", - Name: "Gemini-3-Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.6, - Output: 9.6, - CacheRead: &[]float64{0.16}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 64000, - }, - }, - "google/gemini-deep-research": { - ID: "google/gemini-deep-research", - Name: "gemini-deep-research", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.6, - Output: 9.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 0, - }, - }, - "google/imagen-3": { - ID: "google/imagen-3", - Name: "Imagen-3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/imagen-3-fast": { - ID: "google/imagen-3-fast", - Name: "Imagen-3-Fast", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/imagen-4": { - ID: "google/imagen-4", - Name: "Imagen-4", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/imagen-4-fast": { - ID: "google/imagen-4-fast", - Name: "Imagen-4-Fast", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/imagen-4-ultra": { - ID: "google/imagen-4-ultra", - Name: "Imagen-4-Ultra", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/lyria": { - ID: "google/lyria", - Name: "Lyria", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "google/nano-banana": { - ID: "google/nano-banana", - Name: "Nano-Banana", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.21, - Output: 1.8, - CacheRead: &[]float64{0.021}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 0, - }, - }, - "google/nano-banana-pro": { - ID: "google/nano-banana-pro", - Name: "Nano-Banana-Pro", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.7, - Output: 10, - CacheRead: &[]float64{0.17}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 0, - }, - }, - "google/veo-2": { - ID: "google/veo-2", - Name: "Veo-2", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/veo-3": { - ID: "google/veo-3", - Name: "Veo-3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/veo-3-fast": { - ID: "google/veo-3-fast", - Name: "Veo-3-Fast", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/veo-3.1": { - ID: "google/veo-3.1", - Name: "Veo-3.1", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "google/veo-3.1-fast": { - ID: "google/veo-3.1-fast", - Name: "Veo-3.1-Fast", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 480, - Output: 0, - }, - }, - "ideogramai/ideogram": { - ID: "ideogramai/ideogram", - Name: "Ideogram", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 150, - Output: 0, - }, - }, - "ideogramai/ideogram-v2": { - ID: "ideogramai/ideogram-v2", - Name: "Ideogram-v2", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 150, - Output: 0, - }, - }, - "ideogramai/ideogram-v2a": { - ID: "ideogramai/ideogram-v2a", - Name: "Ideogram-v2a", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 150, - Output: 0, - }, - }, - "ideogramai/ideogram-v2a-turbo": { - ID: "ideogramai/ideogram-v2a-turbo", - Name: "Ideogram-v2a-Turbo", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 150, - Output: 0, - }, - }, - "lumalabs/dream-machine": { - ID: "lumalabs/dream-machine", - Name: "Dream-Machine", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 5000, - Output: 0, - }, - }, - "lumalabs/ray2": { - ID: "lumalabs/ray2", - Name: "Ray2", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 5000, - Output: 0, - }, - }, - "novita/glm-4.6": { - ID: "novita/glm-4.6", - Name: "GLM-4.6", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "novita/glm-4.6v": { - ID: "novita/glm-4.6v", - Name: "glm-4.6v", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 32768, - }, - }, - "novita/glm-4.7": { - ID: "novita/glm-4.7", - Name: "glm-4.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 205000, - Output: 131072, - }, - }, - "novita/kat-coder-pro": { - ID: "novita/kat-coder-pro", - Name: "kat-coder-pro", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 0, - }, - }, - "novita/kimi-k2-thinking": { - ID: "novita/kimi-k2-thinking", - Name: "kimi-k2-thinking", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 0, - }, - }, - "novita/minimax-m2.1": { - ID: "novita/minimax-m2.1", - Name: "minimax-m2.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 205000, - Output: 131072, - }, - }, - "openai/chatgpt-4o-latest": { - ID: "openai/chatgpt-4o-latest", - Name: "ChatGPT-4o-Latest", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 4.5, - Output: 14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/dall-e-3": { - ID: "openai/dall-e-3", - Name: "DALL-E-3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 800, - Output: 0, - }, - }, - "openai/gpt-3.5-turbo": { - ID: "openai/gpt-3.5-turbo", - Name: "GPT-3.5-Turbo", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.45, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16384, - Output: 2048, - }, - }, - "openai/gpt-3.5-turbo-instruct": { - ID: "openai/gpt-3.5-turbo-instruct", - Name: "GPT-3.5-Turbo-Instruct", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.4, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 3500, - Output: 1024, - }, - }, - "openai/gpt-3.5-turbo-raw": { - ID: "openai/gpt-3.5-turbo-raw", - Name: "GPT-3.5-Turbo-Raw", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.45, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4524, - Output: 2048, - }, - }, - "openai/gpt-4-classic": { - ID: "openai/gpt-4-classic", - Name: "GPT-4-Classic", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 27, - Output: 54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - "openai/gpt-4-classic-0314": { - ID: "openai/gpt-4-classic-0314", - Name: "GPT-4-Classic-0314", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 27, - Output: 54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - "openai/gpt-4-turbo": { - ID: "openai/gpt-4-turbo", - Name: "GPT-4-Turbo", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 9, - Output: 27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai/gpt-4.1": { - ID: "openai/gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.8, - Output: 7.2, - CacheRead: &[]float64{0.45}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4.1-mini": { - ID: "openai/gpt-4.1-mini", - Name: "GPT-4.1-mini", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.36, - Output: 1.4, - CacheRead: &[]float64{0.09}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4.1-nano": { - ID: "openai/gpt-4.1-nano", - Name: "GPT-4.1-nano", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.09, - Output: 0.36, - CacheRead: &[]float64{0.022}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4o": { - ID: "openai/gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/gpt-4o-aug": { - ID: "openai/gpt-4o-aug", - Name: "GPT-4o-Aug", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 2.2, - Output: 9, - CacheRead: &[]float64{1.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/gpt-4o-mini": { - ID: "openai/gpt-4o-mini", - Name: "GPT-4o-mini", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.14, - Output: 0.54, - CacheRead: &[]float64{0.068}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai/gpt-4o-mini-search": { - ID: "openai/gpt-4o-mini-search", - Name: "GPT-4o-mini-Search", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.14, - Output: 0.54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/gpt-4o-search": { - ID: "openai/gpt-4o-search", - Name: "GPT-4o-Search", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 2.2, - Output: 9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "openai/gpt-5": { - ID: "openai/gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-chat": { - ID: "openai/gpt-5-chat", - Name: "GPT-5-Chat", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5-codex": { - ID: "openai/gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-mini": { - ID: "openai/gpt-5-mini", - Name: "GPT-5-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.22, - Output: 1.8, - CacheRead: &[]float64{0.022}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-nano": { - ID: "openai/gpt-5-nano", - Name: "GPT-5-nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.045, - Output: 0.36, - CacheRead: &[]float64{0.0045}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-pro": { - ID: "openai/gpt-5-pro", - Name: "GPT-5-Pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 14, - Output: 110, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1": { - ID: "openai/gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-codex": { - ID: "openai/gpt-5.1-codex", - Name: "GPT-5.1-Codex", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-codex-max": { - ID: "openai/gpt-5.1-codex-max", - Name: "gpt-5.1-codex-max", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-codex-mini": { - ID: "openai/gpt-5.1-codex-mini", - Name: "GPT-5.1-Codex-Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.22, - Output: 1.8, - CacheRead: &[]float64{0.022}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.1-instant": { - ID: "openai/gpt-5.1-instant", - Name: "GPT-5.1-Instant", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 9, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5.2": { - ID: "openai/gpt-5.2", - Name: "gpt-5.2", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.6, - Output: 13, - CacheRead: &[]float64{0.16}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5.2-instant": { - ID: "openai/gpt-5.2-instant", - Name: "gpt-5.2-instant", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 1.6, - Output: 13, - CacheRead: &[]float64{0.16}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5.2-pro": { - ID: "openai/gpt-5.2-pro", - Name: "gpt-5.2-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 19, - Output: 150, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-image-1": { - ID: "openai/gpt-image-1", - Name: "GPT-Image-1", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 0, - }, - }, - "openai/gpt-image-1-mini": { - ID: "openai/gpt-image-1-mini", - Name: "GPT-Image-1-Mini", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "openai/gpt-image-1.5": { - ID: "openai/gpt-image-1.5", - Name: "gpt-image-1.5", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 0, - }, - }, - "openai/o1": { - ID: "openai/o1", - Name: "o1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 14, - Output: 54, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o1-pro": { - ID: "openai/o1-pro", - Name: "o1-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 140, - Output: 540, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3": { - ID: "openai/o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.8, - Output: 7.2, - CacheRead: &[]float64{0.45}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-deep-research": { - ID: "openai/o3-deep-research", - Name: "o3-deep-research", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 9, - Output: 36, - CacheRead: &[]float64{2.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-mini": { - ID: "openai/o3-mini", - Name: "o3-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.99, - Output: 4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-mini-high": { - ID: "openai/o3-mini-high", - Name: "o3-mini-high", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.99, - Output: 4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-pro": { - ID: "openai/o3-pro", - Name: "o3-pro", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 18, - Output: 72, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o4-mini": { - ID: "openai/o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.99, - Output: 4, - CacheRead: &[]float64{0.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o4-mini-deep-research": { - ID: "openai/o4-mini-deep-research", - Name: "o4-mini-deep-research", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.8, - Output: 7.2, - CacheRead: &[]float64{0.45}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/sora-2": { - ID: "openai/sora-2", - Name: "Sora-2", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "openai/sora-2-pro": { - ID: "openai/sora-2-pro", - Name: "Sora-2-Pro", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "poetools/claude-code": { - ID: "poetools/claude-code", - Name: "claude-code", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 0, - }, - }, - "runwayml/runway": { - ID: "runwayml/runway", - Name: "Runway", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256, - Output: 0, - }, - }, - "runwayml/runway-gen-4-turbo": { - ID: "runwayml/runway-gen-4-turbo", - Name: "Runway-Gen-4-Turbo", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256, - Output: 0, - }, - }, - "stabilityai/stablediffusionxl": { - ID: "stabilityai/stablediffusionxl", - Name: "StableDiffusionXL", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200, - Output: 0, - }, - }, - "topazlabs-co/topazlabs": { - ID: "topazlabs-co/topazlabs", - Name: "TopazLabs", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204, - Output: 0, - }, - }, - "trytako/tako": { - ID: "trytako/tako", - Name: "Tako", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2048, - Output: 0, - }, - }, - "xai/grok-3": { - ID: "xai/grok-3", - Name: "Grok 3", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-3-mini": { - ID: "xai/grok-3-mini", - Name: "Grok 3 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-4": { - ID: "xai/grok-4", - Name: "Grok 4", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 128000, - }, - }, - "xai/grok-4-fast-non-reasoning": { - ID: "xai/grok-4-fast-non-reasoning", - Name: "Grok-4-Fast-Non-Reasoning", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 128000, - }, - }, - "xai/grok-4-fast-reasoning": { - ID: "xai/grok-4-fast-reasoning", - Name: "Grok 4 Fast Reasoning", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 128000, - }, - }, - "xai/grok-4.1-fast-non-reasoning": { - ID: "xai/grok-4.1-fast-non-reasoning", - Name: "Grok-4.1-Fast-Non-Reasoning", - Attachment: true, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "xai/grok-4.1-fast-reasoning": { - ID: "xai/grok-4.1-fast-reasoning", - Name: "Grok-4.1-Fast-Reasoning", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "xai/grok-code-fast-1": { - ID: "xai/grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 128000, - }, - }, - }, - }, - "requesty": { - ID: "requesty", - Env: []string{"REQUESTY_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Requesty", - Models: map[string]ModelInfo{ - "anthropic/claude-3-7-sonnet": { - ID: "anthropic/claude-3-7-sonnet", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-haiku-4-5": { - ID: "anthropic/claude-haiku-4-5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 62000, - }, - }, - "anthropic/claude-opus-4": { - ID: "anthropic/claude-opus-4", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4-1": { - ID: "anthropic/claude-opus-4-1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4-5": { - ID: "anthropic/claude-opus-4-5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4": { - ID: "anthropic/claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4-5": { - ID: "anthropic/claude-sonnet-4-5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "google/gemini-2.5-flash": { - ID: "google/gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.55}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-pro": { - ID: "google/gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: &[]float64{2.375}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-flash-preview": { - ID: "google/gemini-3-flash-preview", - Name: "Gemini 3 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: &[]float64{0.05}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-pro-preview": { - ID: "google/gemini-3-pro-preview", - Name: "Gemini 3 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.2}[0], - CacheWrite: &[]float64{4.5}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "openai/gpt-4.1": { - ID: "openai/gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4.1-mini": { - ID: "openai/gpt-4.1-mini", - Name: "GPT-4.1 Mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4o-mini": { - ID: "openai/gpt-4o-mini", - Name: "GPT-4o Mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5": { - ID: "openai/gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-mini": { - ID: "openai/gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "openai/gpt-5-nano": { - ID: "openai/gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 4000, - }, - }, - "openai/o4-mini": { - ID: "openai/o4-mini", - Name: "o4 Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "xai/grok-4": { - ID: "xai/grok-4", - Name: "Grok 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: &[]float64{3}[0], - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "xai/grok-4-fast": { - ID: "xai/grok-4-fast", - Name: "Grok 4 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: &[]float64{0.2}[0], - }, - Limit: Limit{ - Context: 2000000, - Output: 64000, - }, - }, - }, - }, - "sap-ai-core": { - ID: "sap-ai-core", - Env: []string{"AICORE_SERVICE_KEY" }, - NPM: "@mymediset/sap-ai-provider", - Name: "SAP AI Core", - Models: map[string]ModelInfo{ - "anthropic--claude-3-haiku": { - ID: "anthropic--claude-3-haiku", - Name: "anthropic--claude-3-haiku", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.25, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic--claude-3-opus": { - ID: "anthropic--claude-3-opus", - Name: "anthropic--claude-3-opus", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic--claude-3-sonnet": { - ID: "anthropic--claude-3-sonnet", - Name: "anthropic--claude-3-sonnet", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic--claude-3.5-sonnet": { - ID: "anthropic--claude-3.5-sonnet", - Name: "anthropic--claude-3.5-sonnet", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic--claude-3.7-sonnet": { - ID: "anthropic--claude-3.7-sonnet", - Name: "anthropic--claude-3.7-sonnet", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic--claude-4-opus": { - ID: "anthropic--claude-4-opus", - Name: "anthropic--claude-4-opus", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic--claude-4-sonnet": { - ID: "anthropic--claude-4-sonnet", - Name: "anthropic--claude-4-sonnet", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic--claude-4.5-haiku": { - ID: "anthropic--claude-4.5-haiku", - Name: "anthropic--claude-4.5-haiku", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic--claude-4.5-sonnet": { - ID: "anthropic--claude-4.5-sonnet", - Name: "anthropic--claude-4.5-sonnet", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "gemini-2.5-flash": { - ID: "gemini-2.5-flash", - Name: "gemini-2.5-flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gemini-2.5-pro": { - ID: "gemini-2.5-pro", - Name: "gemini-2.5-pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "gpt-5": { - ID: "gpt-5", - Name: "gpt-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-mini": { - ID: "gpt-5-mini", - Name: "gpt-5-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "gpt-5-nano": { - ID: "gpt-5-nano", - Name: "gpt-5-nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - }, - }, - "scaleway": { - ID: "scaleway", - Env: []string{"SCALEWAY_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Scaleway", - Models: map[string]ModelInfo{ - "bge-multilingual-gemma2": { - ID: "bge-multilingual-gemma2", - Name: "BGE Multilingual Gemma2", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.13, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8191, - Output: 3072, - }, - }, - "deepseek-r1-distill-llama-70b": { - ID: "deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.9, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 4096, - }, - }, - "devstral-2-123b-instruct-2512": { - ID: "devstral-2-123b-instruct-2512", - Name: "Devstral 2 123B Instruct (2512)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 8192, - }, - }, - "gemma-3-27b-it": { - ID: "gemma-3-27b-it", - Name: "Gemma-3-27B-IT", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 40000, - Output: 8192, - }, - }, - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "GPT-OSS 120B", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "llama-3.1-8b-instruct": { - ID: "llama-3.1-8b-instruct", - Name: "Llama 3.1 8B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "llama-3.3-70b-instruct": { - ID: "llama-3.3-70b-instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.9, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 100000, - Output: 4096, - }, - }, - "mistral-nemo-instruct-2407": { - ID: "mistral-nemo-instruct-2407", - Name: "Mistral Nemo Instruct 2407", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "mistral-small-3.2-24b-instruct-2506": { - ID: "mistral-small-3.2-24b-instruct-2506", - Name: "Mistral Small 3.2 24B Instruct (2506)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.35, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "pixtral-12b-2409": { - ID: "pixtral-12b-2409", - Name: "Pixtral 12B 2409", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "qwen3-235b-a22b-instruct-2507": { - ID: "qwen3-235b-a22b-instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.75, - Output: 2.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 260000, - Output: 8192, - }, - }, - "qwen3-coder-30b-a3b-instruct": { - ID: "qwen3-coder-30b-a3b-instruct", - Name: "Qwen3-Coder 30B-A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "voxtral-small-24b-2507": { - ID: "voxtral-small-24b-2507", - Name: "Voxtral Small 24B 2507", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.35, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 8192, - }, - }, - "whisper-large-v3": { - ID: "whisper-large-v3", - Name: "Whisper Large v3", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.003, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 0, - Output: 4096, - }, - }, - }, - }, - "siliconflow": { - ID: "siliconflow", - Env: []string{"SILICONFLOW_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "SiliconFlow", - Models: map[string]ModelInfo{ - "ByteDance-Seed/Seed-OSS-36B-Instruct": { - ID: "ByteDance-Seed/Seed-OSS-36B-Instruct", - Name: "ByteDance-Seed/Seed-OSS-36B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.21, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "MiniMaxAI/MiniMax-M1-80k": { - ID: "MiniMaxAI/MiniMax-M1-80k", - Name: "MiniMaxAI/MiniMax-M1-80k", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "MiniMaxAI/MiniMax-M2": { - ID: "MiniMaxAI/MiniMax-M2", - Name: "MiniMaxAI/MiniMax-M2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 197000, - Output: 131000, - }, - }, - "Qwen/QwQ-32B": { - ID: "Qwen/QwQ-32B", - Name: "Qwen/QwQ-32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.58, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen2.5-14B-Instruct": { - ID: "Qwen/Qwen2.5-14B-Instruct", - Name: "Qwen/Qwen2.5-14B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-32B-Instruct": { - ID: "Qwen/Qwen2.5-32B-Instruct", - Name: "Qwen/Qwen2.5-32B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-72B-Instruct": { - ID: "Qwen/Qwen2.5-72B-Instruct", - Name: "Qwen/Qwen2.5-72B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-72B-Instruct-128K": { - ID: "Qwen/Qwen2.5-72B-Instruct-128K", - Name: "Qwen/Qwen2.5-72B-Instruct-128K", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-7B-Instruct": { - ID: "Qwen/Qwen2.5-7B-Instruct", - Name: "Qwen/Qwen2.5-7B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-Coder-32B-Instruct": { - ID: "Qwen/Qwen2.5-Coder-32B-Instruct", - Name: "Qwen/Qwen2.5-Coder-32B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-VL-32B-Instruct": { - ID: "Qwen/Qwen2.5-VL-32B-Instruct", - Name: "Qwen/Qwen2.5-VL-32B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen2.5-VL-72B-Instruct": { - ID: "Qwen/Qwen2.5-VL-72B-Instruct", - Name: "Qwen/Qwen2.5-VL-72B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-VL-7B-Instruct": { - ID: "Qwen/Qwen2.5-VL-7B-Instruct", - Name: "Qwen/Qwen2.5-VL-7B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen3-14B": { - ID: "Qwen/Qwen3-14B", - Name: "Qwen/Qwen3-14B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-235B-A22B": { - ID: "Qwen/Qwen3-235B-A22B", - Name: "Qwen/Qwen3-235B-A22B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-30B-A3B": { - ID: "Qwen/Qwen3-30B-A3B", - Name: "Qwen/Qwen3-30B-A3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-30B-A3B-Instruct-2507": { - ID: "Qwen/Qwen3-30B-A3B-Instruct-2507", - Name: "Qwen/Qwen3-30B-A3B-Instruct-2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-30B-A3B-Thinking-2507": { - ID: "Qwen/Qwen3-30B-A3B-Thinking-2507", - Name: "Qwen/Qwen3-30B-A3B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 131000, - }, - }, - "Qwen/Qwen3-32B": { - ID: "Qwen/Qwen3-32B", - Name: "Qwen/Qwen3-32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-8B": { - ID: "Qwen/Qwen3-8B", - Name: "Qwen/Qwen3-8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.06, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-Coder-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-Coder-30B-A3B-Instruct", - Name: "Qwen/Qwen3-Coder-30B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Instruct": { - ID: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Name: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Thinking": { - ID: "Qwen/Qwen3-Next-80B-A3B-Thinking", - Name: "Qwen/Qwen3-Next-80B-A3B-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Omni-30B-A3B-Captioner": { - ID: "Qwen/Qwen3-Omni-30B-A3B-Captioner", - Name: "Qwen/Qwen3-Omni-30B-A3B-Captioner", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "Qwen/Qwen3-Omni-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-Omni-30B-A3B-Instruct", - Name: "Qwen/Qwen3-Omni-30B-A3B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "Qwen/Qwen3-Omni-30B-A3B-Thinking": { - ID: "Qwen/Qwen3-Omni-30B-A3B-Thinking", - Name: "Qwen/Qwen3-Omni-30B-A3B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "Qwen/Qwen3-VL-235B-A22B-Instruct": { - ID: "Qwen/Qwen3-VL-235B-A22B-Instruct", - Name: "Qwen/Qwen3-VL-235B-A22B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-235B-A22B-Thinking": { - ID: "Qwen/Qwen3-VL-235B-A22B-Thinking", - Name: "Qwen/Qwen3-VL-235B-A22B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.45, - Output: 3.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-VL-30B-A3B-Instruct", - Name: "Qwen/Qwen3-VL-30B-A3B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-30B-A3B-Thinking": { - ID: "Qwen/Qwen3-VL-30B-A3B-Thinking", - Name: "Qwen/Qwen3-VL-30B-A3B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-32B-Instruct": { - ID: "Qwen/Qwen3-VL-32B-Instruct", - Name: "Qwen/Qwen3-VL-32B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-32B-Thinking": { - ID: "Qwen/Qwen3-VL-32B-Thinking", - Name: "Qwen/Qwen3-VL-32B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-8B-Instruct": { - ID: "Qwen/Qwen3-VL-8B-Instruct", - Name: "Qwen/Qwen3-VL-8B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-8B-Thinking": { - ID: "Qwen/Qwen3-VL-8B-Thinking", - Name: "Qwen/Qwen3-VL-8B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "THUDM/GLM-4-32B-0414": { - ID: "THUDM/GLM-4-32B-0414", - Name: "THUDM/GLM-4-32B-0414", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 33000, - }, - }, - "THUDM/GLM-4-9B-0414": { - ID: "THUDM/GLM-4-9B-0414", - Name: "THUDM/GLM-4-9B-0414", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.086, - Output: 0.086, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 33000, - }, - }, - "THUDM/GLM-4.1V-9B-Thinking": { - ID: "THUDM/GLM-4.1V-9B-Thinking", - Name: "THUDM/GLM-4.1V-9B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.035, - Output: 0.14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "THUDM/GLM-Z1-32B-0414": { - ID: "THUDM/GLM-Z1-32B-0414", - Name: "THUDM/GLM-Z1-32B-0414", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "THUDM/GLM-Z1-9B-0414": { - ID: "THUDM/GLM-Z1-9B-0414", - Name: "THUDM/GLM-Z1-9B-0414", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.086, - Output: 0.086, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "baidu/ERNIE-4.5-300B-A47B": { - ID: "baidu/ERNIE-4.5-300B-A47B", - Name: "baidu/ERNIE-4.5-300B-A47B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 1.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "deepseek-ai/DeepSeek-R1": { - ID: "deepseek-ai/DeepSeek-R1", - Name: "deepseek-ai/DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", - Name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", - Name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", - Name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 16000, - }, - }, - "deepseek-ai/DeepSeek-V3": { - ID: "deepseek-ai/DeepSeek-V3", - Name: "deepseek-ai/DeepSeek-V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-V3.1": { - ID: "deepseek-ai/DeepSeek-V3.1", - Name: "deepseek-ai/DeepSeek-V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-V3.1-Terminus": { - ID: "deepseek-ai/DeepSeek-V3.1-Terminus", - Name: "deepseek-ai/DeepSeek-V3.1-Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-V3.2-Exp": { - ID: "deepseek-ai/DeepSeek-V3.2-Exp", - Name: "deepseek-ai/DeepSeek-V3.2-Exp", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.41, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/deepseek-vl2": { - ID: "deepseek-ai/deepseek-vl2", - Name: "deepseek-ai/deepseek-vl2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4000, - Output: 4000, - }, - }, - "inclusionAI/Ling-flash-2.0": { - ID: "inclusionAI/Ling-flash-2.0", - Name: "inclusionAI/Ling-flash-2.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "inclusionAI/Ling-mini-2.0": { - ID: "inclusionAI/Ling-mini-2.0", - Name: "inclusionAI/Ling-mini-2.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "inclusionAI/Ring-flash-2.0": { - ID: "inclusionAI/Ring-flash-2.0", - Name: "inclusionAI/Ring-flash-2.0", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "meta-llama/Meta-Llama-3.1-8B-Instruct": { - ID: "meta-llama/Meta-Llama-3.1-8B-Instruct", - Name: "meta-llama/Meta-Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.06, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "moonshotai/Kimi-Dev-72B": { - ID: "moonshotai/Kimi-Dev-72B", - Name: "moonshotai/Kimi-Dev-72B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "moonshotai/Kimi-K2-Instruct": { - ID: "moonshotai/Kimi-K2-Instruct", - Name: "moonshotai/Kimi-K2-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.58, - Output: 2.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "moonshotai/Kimi-K2-Instruct-0905": { - ID: "moonshotai/Kimi-K2-Instruct-0905", - Name: "moonshotai/Kimi-K2-Instruct-0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "moonshotai/Kimi-K2-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "nex-agi/DeepSeek-V3.1-Nex-N1": { - ID: "nex-agi/DeepSeek-V3.1-Nex-N1", - Name: "nex-agi/DeepSeek-V3.1-Nex-N1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "openai/gpt-oss-120b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 8000, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "openai/gpt-oss-20b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 8000, - }, - }, - "stepfun-ai/step3": { - ID: "stepfun-ai/step3", - Name: "stepfun-ai/step3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.57, - Output: 1.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "tencent/Hunyuan-A13B-Instruct": { - ID: "tencent/Hunyuan-A13B-Instruct", - Name: "tencent/Hunyuan-A13B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "tencent/Hunyuan-MT-7B": { - ID: "tencent/Hunyuan-MT-7B", - Name: "tencent/Hunyuan-MT-7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 33000, - }, - }, - "z-ai/GLM-4.5": { - ID: "z-ai/GLM-4.5", - Name: "z-ai/GLM-4.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "z-ai/GLM-4.5-Air": { - ID: "z-ai/GLM-4.5-Air", - Name: "z-ai/GLM-4.5-Air", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.86, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "zai-org/GLM-4.5": { - ID: "zai-org/GLM-4.5", - Name: "zai-org/GLM-4.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "zai-org/GLM-4.5-Air": { - ID: "zai-org/GLM-4.5-Air", - Name: "zai-org/GLM-4.5-Air", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.86, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "zai-org/GLM-4.5V": { - ID: "zai-org/GLM-4.5V", - Name: "zai-org/GLM-4.5V", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.86, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "zai-org/GLM-4.6": { - ID: "zai-org/GLM-4.6", - Name: "zai-org/GLM-4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 205000, - Output: 205000, - }, - }, - }, - }, - "siliconflow-cn": { - ID: "siliconflow-cn", - Env: []string{"SILICONFLOW_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "SiliconFlow (China)", - Models: map[string]ModelInfo{ - "ByteDance-Seed/Seed-OSS-36B-Instruct": { - ID: "ByteDance-Seed/Seed-OSS-36B-Instruct", - Name: "ByteDance-Seed/Seed-OSS-36B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.21, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "MiniMaxAI/MiniMax-M1-80k": { - ID: "MiniMaxAI/MiniMax-M1-80k", - Name: "MiniMaxAI/MiniMax-M1-80k", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "MiniMaxAI/MiniMax-M2": { - ID: "MiniMaxAI/MiniMax-M2", - Name: "MiniMaxAI/MiniMax-M2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 197000, - Output: 131000, - }, - }, - "Qwen/QwQ-32B": { - ID: "Qwen/QwQ-32B", - Name: "Qwen/QwQ-32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.58, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen2.5-14B-Instruct": { - ID: "Qwen/Qwen2.5-14B-Instruct", - Name: "Qwen/Qwen2.5-14B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-32B-Instruct": { - ID: "Qwen/Qwen2.5-32B-Instruct", - Name: "Qwen/Qwen2.5-32B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-72B-Instruct": { - ID: "Qwen/Qwen2.5-72B-Instruct", - Name: "Qwen/Qwen2.5-72B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-72B-Instruct-128K": { - ID: "Qwen/Qwen2.5-72B-Instruct-128K", - Name: "Qwen/Qwen2.5-72B-Instruct-128K", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-7B-Instruct": { - ID: "Qwen/Qwen2.5-7B-Instruct", - Name: "Qwen/Qwen2.5-7B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-Coder-32B-Instruct": { - ID: "Qwen/Qwen2.5-Coder-32B-Instruct", - Name: "Qwen/Qwen2.5-Coder-32B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-VL-32B-Instruct": { - ID: "Qwen/Qwen2.5-VL-32B-Instruct", - Name: "Qwen/Qwen2.5-VL-32B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen2.5-VL-72B-Instruct": { - ID: "Qwen/Qwen2.5-VL-72B-Instruct", - Name: "Qwen/Qwen2.5-VL-72B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.59, - Output: 0.59, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 4000, - }, - }, - "Qwen/Qwen2.5-VL-7B-Instruct": { - ID: "Qwen/Qwen2.5-VL-7B-Instruct", - Name: "Qwen/Qwen2.5-VL-7B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "Qwen/Qwen3-14B": { - ID: "Qwen/Qwen3-14B", - Name: "Qwen/Qwen3-14B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-235B-A22B": { - ID: "Qwen/Qwen3-235B-A22B", - Name: "Qwen/Qwen3-235B-A22B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.13, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-30B-A3B": { - ID: "Qwen/Qwen3-30B-A3B", - Name: "Qwen/Qwen3-30B-A3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-30B-A3B-Instruct-2507": { - ID: "Qwen/Qwen3-30B-A3B-Instruct-2507", - Name: "Qwen/Qwen3-30B-A3B-Instruct-2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-30B-A3B-Thinking-2507": { - ID: "Qwen/Qwen3-30B-A3B-Thinking-2507", - Name: "Qwen/Qwen3-30B-A3B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.09, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 131000, - }, - }, - "Qwen/Qwen3-32B": { - ID: "Qwen/Qwen3-32B", - Name: "Qwen/Qwen3-32B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-8B": { - ID: "Qwen/Qwen3-8B", - Name: "Qwen/Qwen3-8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.06, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "Qwen/Qwen3-Coder-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-Coder-30B-A3B-Instruct", - Name: "Qwen/Qwen3-Coder-30B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Instruct": { - ID: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Name: "Qwen/Qwen3-Next-80B-A3B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 1.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Next-80B-A3B-Thinking": { - ID: "Qwen/Qwen3-Next-80B-A3B-Thinking", - Name: "Qwen/Qwen3-Next-80B-A3B-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-Omni-30B-A3B-Captioner": { - ID: "Qwen/Qwen3-Omni-30B-A3B-Captioner", - Name: "Qwen/Qwen3-Omni-30B-A3B-Captioner", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "Qwen/Qwen3-Omni-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-Omni-30B-A3B-Instruct", - Name: "Qwen/Qwen3-Omni-30B-A3B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "Qwen/Qwen3-Omni-30B-A3B-Thinking": { - ID: "Qwen/Qwen3-Omni-30B-A3B-Thinking", - Name: "Qwen/Qwen3-Omni-30B-A3B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "Qwen/Qwen3-VL-235B-A22B-Instruct": { - ID: "Qwen/Qwen3-VL-235B-A22B-Instruct", - Name: "Qwen/Qwen3-VL-235B-A22B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-235B-A22B-Thinking": { - ID: "Qwen/Qwen3-VL-235B-A22B-Thinking", - Name: "Qwen/Qwen3-VL-235B-A22B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.45, - Output: 3.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-30B-A3B-Instruct": { - ID: "Qwen/Qwen3-VL-30B-A3B-Instruct", - Name: "Qwen/Qwen3-VL-30B-A3B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-30B-A3B-Thinking": { - ID: "Qwen/Qwen3-VL-30B-A3B-Thinking", - Name: "Qwen/Qwen3-VL-30B-A3B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-32B-Instruct": { - ID: "Qwen/Qwen3-VL-32B-Instruct", - Name: "Qwen/Qwen3-VL-32B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-32B-Thinking": { - ID: "Qwen/Qwen3-VL-32B-Thinking", - Name: "Qwen/Qwen3-VL-32B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-8B-Instruct": { - ID: "Qwen/Qwen3-VL-8B-Instruct", - Name: "Qwen/Qwen3-VL-8B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "Qwen/Qwen3-VL-8B-Thinking": { - ID: "Qwen/Qwen3-VL-8B-Thinking", - Name: "Qwen/Qwen3-VL-8B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "THUDM/GLM-4-32B-0414": { - ID: "THUDM/GLM-4-32B-0414", - Name: "THUDM/GLM-4-32B-0414", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.27, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 33000, - }, - }, - "THUDM/GLM-4-9B-0414": { - ID: "THUDM/GLM-4-9B-0414", - Name: "THUDM/GLM-4-9B-0414", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.086, - Output: 0.086, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 33000, - }, - }, - "THUDM/GLM-4.1V-9B-Thinking": { - ID: "THUDM/GLM-4.1V-9B-Thinking", - Name: "THUDM/GLM-4.1V-9B-Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.035, - Output: 0.14, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "THUDM/GLM-Z1-32B-0414": { - ID: "THUDM/GLM-Z1-32B-0414", - Name: "THUDM/GLM-Z1-32B-0414", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "THUDM/GLM-Z1-9B-0414": { - ID: "THUDM/GLM-Z1-9B-0414", - Name: "THUDM/GLM-Z1-9B-0414", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.086, - Output: 0.086, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "baidu/ERNIE-4.5-300B-A47B": { - ID: "baidu/ERNIE-4.5-300B-A47B", - Name: "baidu/ERNIE-4.5-300B-A47B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 1.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "deepseek-ai/DeepSeek-R1": { - ID: "deepseek-ai/DeepSeek-R1", - Name: "deepseek-ai/DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", - Name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", - Name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.18, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B": { - ID: "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", - Name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.05, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 16000, - }, - }, - "deepseek-ai/DeepSeek-V3": { - ID: "deepseek-ai/DeepSeek-V3", - Name: "deepseek-ai/DeepSeek-V3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-V3.1": { - ID: "deepseek-ai/DeepSeek-V3.1", - Name: "deepseek-ai/DeepSeek-V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-V3.1-Terminus": { - ID: "deepseek-ai/DeepSeek-V3.1-Terminus", - Name: "deepseek-ai/DeepSeek-V3.1-Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/DeepSeek-V3.2-Exp": { - ID: "deepseek-ai/DeepSeek-V3.2-Exp", - Name: "deepseek-ai/DeepSeek-V3.2-Exp", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.41, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 164000, - Output: 164000, - }, - }, - "deepseek-ai/deepseek-vl2": { - ID: "deepseek-ai/deepseek-vl2", - Name: "deepseek-ai/deepseek-vl2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 4000, - Output: 4000, - }, - }, - "inclusionAI/Ling-flash-2.0": { - ID: "inclusionAI/Ling-flash-2.0", - Name: "inclusionAI/Ling-flash-2.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "inclusionAI/Ling-mini-2.0": { - ID: "inclusionAI/Ling-mini-2.0", - Name: "inclusionAI/Ling-mini-2.0", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.28, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "inclusionAI/Ring-flash-2.0": { - ID: "inclusionAI/Ring-flash-2.0", - Name: "inclusionAI/Ring-flash-2.0", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "meta-llama/Meta-Llama-3.1-8B-Instruct": { - ID: "meta-llama/Meta-Llama-3.1-8B-Instruct", - Name: "meta-llama/Meta-Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.06, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 4000, - }, - }, - "moonshotai/Kimi-Dev-72B": { - ID: "moonshotai/Kimi-Dev-72B", - Name: "moonshotai/Kimi-Dev-72B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.29, - Output: 1.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "moonshotai/Kimi-K2-Instruct": { - ID: "moonshotai/Kimi-K2-Instruct", - Name: "moonshotai/Kimi-K2-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.58, - Output: 2.29, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "moonshotai/Kimi-K2-Instruct-0905": { - ID: "moonshotai/Kimi-K2-Instruct-0905", - Name: "moonshotai/Kimi-K2-Instruct-0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "moonshotai/Kimi-K2-Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262000, - Output: 262000, - }, - }, - "nex-agi/DeepSeek-V3.1-Nex-N1": { - ID: "nex-agi/DeepSeek-V3.1-Nex-N1", - Name: "nex-agi/DeepSeek-V3.1-Nex-N1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "openai/gpt-oss-120b", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.45, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 8000, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "openai/gpt-oss-20b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.18, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 8000, - }, - }, - "stepfun-ai/step3": { - ID: "stepfun-ai/step3", - Name: "stepfun-ai/step3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.57, - Output: 1.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "tencent/Hunyuan-A13B-Instruct": { - ID: "tencent/Hunyuan-A13B-Instruct", - Name: "tencent/Hunyuan-A13B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "tencent/Hunyuan-MT-7B": { - ID: "tencent/Hunyuan-MT-7B", - Name: "tencent/Hunyuan-MT-7B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 33000, - Output: 33000, - }, - }, - "z-ai/GLM-4.5": { - ID: "z-ai/GLM-4.5", - Name: "z-ai/GLM-4.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "z-ai/GLM-4.5-Air": { - ID: "z-ai/GLM-4.5-Air", - Name: "z-ai/GLM-4.5-Air", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.86, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "zai-org/GLM-4.5": { - ID: "zai-org/GLM-4.5", - Name: "zai-org/GLM-4.5", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "zai-org/GLM-4.5-Air": { - ID: "zai-org/GLM-4.5-Air", - Name: "zai-org/GLM-4.5-Air", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.86, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131000, - Output: 131000, - }, - }, - "zai-org/GLM-4.5V": { - ID: "zai-org/GLM-4.5V", - Name: "zai-org/GLM-4.5V", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.86, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 66000, - }, - }, - "zai-org/GLM-4.6": { - ID: "zai-org/GLM-4.6", - Name: "zai-org/GLM-4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 205000, - Output: 205000, - }, - }, - }, - }, - "submodel": { - ID: "submodel", - Env: []string{"SUBMODEL_INSTAGEN_ACCESS_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "submodel", - Models: map[string]ModelInfo{ - "Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "deepseek-ai/DeepSeek-R1-0528": { - ID: "deepseek-ai/DeepSeek-R1-0528", - Name: "DeepSeek R1 0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 75000, - Output: 163840, - }, - }, - "deepseek-ai/DeepSeek-V3-0324": { - ID: "deepseek-ai/DeepSeek-V3-0324", - Name: "DeepSeek V3 0324", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 75000, - Output: 163840, - }, - }, - "deepseek-ai/DeepSeek-V3.1": { - ID: "deepseek-ai/DeepSeek-V3.1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 75000, - Output: 163840, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "zai-org/GLM-4.5-Air": { - ID: "zai-org/GLM-4.5-Air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "zai-org/GLM-4.5-FP8": { - ID: "zai-org/GLM-4.5-FP8", - Name: "GLM 4.5 FP8", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - }, - }, - "synthetic": { - ID: "synthetic", - Env: []string{"SYNTHETIC_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Synthetic", - Models: map[string]ModelInfo{ - "hf:MiniMaxAI/MiniMax-M2": { - ID: "hf:MiniMaxAI/MiniMax-M2", - Name: "MiniMax-M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 196608, - Output: 131000, - }, - }, - "hf:MiniMaxAI/MiniMax-M2.1": { - ID: "hf:MiniMaxAI/MiniMax-M2.1", - Name: "MiniMax-M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "hf:Qwen/Qwen2.5-Coder-32B-Instruct": { - ID: "hf:Qwen/Qwen2.5-Coder-32B-Instruct", - Name: "Qwen2.5-Coder-32B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 0.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "hf:Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "hf:Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen 3 235B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "hf:Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "hf:Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.65, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "hf:Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "hf:Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen 3 Coder 480B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - "hf:deepseek-ai/DeepSeek-R1": { - ID: "hf:deepseek-ai/DeepSeek-R1", - Name: "DeepSeek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "hf:deepseek-ai/DeepSeek-R1-0528": { - ID: "hf:deepseek-ai/DeepSeek-R1-0528", - Name: "DeepSeek R1 (0528)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "hf:deepseek-ai/DeepSeek-V3": { - ID: "hf:deepseek-ai/DeepSeek-V3", - Name: "DeepSeek V3", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 1.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "hf:deepseek-ai/DeepSeek-V3-0324": { - ID: "hf:deepseek-ai/DeepSeek-V3-0324", - Name: "DeepSeek V3 (0324)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "hf:deepseek-ai/DeepSeek-V3.1": { - ID: "hf:deepseek-ai/DeepSeek-V3.1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 1.68, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "hf:deepseek-ai/DeepSeek-V3.1-Terminus": { - ID: "hf:deepseek-ai/DeepSeek-V3.1-Terminus", - Name: "DeepSeek V3.1 Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "hf:deepseek-ai/DeepSeek-V3.2": { - ID: "hf:deepseek-ai/DeepSeek-V3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 0.4, - CacheRead: &[]float64{0.27}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 162816, - Output: 8000, - }, - }, - "hf:meta-llama/Llama-3.1-405B-Instruct": { - ID: "hf:meta-llama/Llama-3.1-405B-Instruct", - Name: "Llama-3.1-405B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "hf:meta-llama/Llama-3.1-70B-Instruct": { - ID: "hf:meta-llama/Llama-3.1-70B-Instruct", - Name: "Llama-3.1-70B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.9, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "hf:meta-llama/Llama-3.1-8B-Instruct": { - ID: "hf:meta-llama/Llama-3.1-8B-Instruct", - Name: "Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "hf:meta-llama/Llama-3.3-70B-Instruct": { - ID: "hf:meta-llama/Llama-3.3-70B-Instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.9, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "hf:meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": { - ID: "hf:meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", - Name: "Llama-4-Maverick-17B-128E-Instruct-FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 524000, - Output: 4096, - }, - }, - "hf:meta-llama/Llama-4-Scout-17B-16E-Instruct": { - ID: "hf:meta-llama/Llama-4-Scout-17B-16E-Instruct", - Name: "Llama-4-Scout-17B-16E-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 328000, - Output: 4096, - }, - }, - "hf:moonshotai/Kimi-K2-Instruct-0905": { - ID: "hf:moonshotai/Kimi-K2-Instruct-0905", - Name: "Kimi K2 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "hf:moonshotai/Kimi-K2-Thinking": { - ID: "hf:moonshotai/Kimi-K2-Thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "hf:openai/gpt-oss-120b": { - ID: "hf:openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "hf:zai-org/GLM-4.5": { - ID: "hf:zai-org/GLM-4.5", - Name: "GLM 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 96000, - }, - }, - "hf:zai-org/GLM-4.6": { - ID: "hf:zai-org/GLM-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "hf:zai-org/GLM-4.7": { - ID: "hf:zai-org/GLM-4.7", - Name: "GLM 4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.19, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - }, - }, - "togetherai": { - ID: "togetherai", - Env: []string{"TOGETHER_API_KEY" }, - NPM: "@ai-sdk/togetherai", - Name: "Together AI", - Models: map[string]ModelInfo{ - "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8", - Name: "Qwen3 Coder 480B A35B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "deepseek-ai/DeepSeek-R1": { - ID: "deepseek-ai/DeepSeek-R1", - Name: "DeepSeek R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163839, - Output: 12288, - }, - }, - "deepseek-ai/DeepSeek-V3": { - ID: "deepseek-ai/DeepSeek-V3", - Name: "DeepSeek V3", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 1.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 12288, - }, - }, - "deepseek-ai/DeepSeek-V3-1": { - ID: "deepseek-ai/DeepSeek-V3-1", - Name: "DeepSeek V3.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.7, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 12288, - }, - }, - "essentialai/Rnj-1-Instruct": { - ID: "essentialai/Rnj-1-Instruct", - Name: "Rnj-1 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 32768, - }, - }, - "meta-llama/Llama-3.3-70B-Instruct-Turbo": { - ID: "meta-llama/Llama-3.3-70B-Instruct-Turbo", - Name: "Llama 3.3 70B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.88, - Output: 0.88, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 66536, - }, - }, - "moonshotai/Kimi-K2-Instruct": { - ID: "moonshotai/Kimi-K2-Instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "moonshotai/Kimi-K2-Thinking": { - ID: "moonshotai/Kimi-K2-Thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 131072, - }, - }, - "zai-org/GLM-4.6": { - ID: "zai-org/GLM-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 32768, - }, - }, - }, - }, - "upstage": { - ID: "upstage", - Env: []string{"UPSTAGE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Upstage", - Models: map[string]ModelInfo{ - "solar-mini": { - ID: "solar-mini", - Name: "solar-mini", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 4096, - }, - }, - "solar-pro2": { - ID: "solar-pro2", - Name: "solar-pro2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 0.25, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 8192, - }, - }, - }, - }, - "v0": { - ID: "v0", - Env: []string{"V0_API_KEY" }, - NPM: "@ai-sdk/vercel", - Name: "v0", - Models: map[string]ModelInfo{ - "v0-1.0-md": { - ID: "v0-1.0-md", - Name: "v0-1.0-md", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "v0-1.5-lg": { - ID: "v0-1.5-lg", - Name: "v0-1.5-lg", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 512000, - Output: 32000, - }, - }, - "v0-1.5-md": { - ID: "v0-1.5-md", - Name: "v0-1.5-md", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - }, - }, - "venice": { - ID: "venice", - Env: []string{"VENICE_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Venice AI", - Models: map[string]ModelInfo{ - "claude-opus-45": { - ID: "claude-opus-45", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 6, - Output: 30, - CacheRead: &[]float64{0.6}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 50688, - }, - }, - "deepseek-v3.2": { - ID: "deepseek-v3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 40960, - }, - }, - "gemini-3-flash-preview": { - ID: "gemini-3-flash-preview", - Name: "Gemini 3 Flash Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 3.75, - CacheRead: &[]float64{0.07}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "gemini-3-pro-preview": { - ID: "gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 15, - CacheRead: &[]float64{0.625}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 50688, - }, - }, - "google-gemma-3-27b-it": { - ID: "google-gemma-3-27b-it", - Name: "Google Gemma 3 27B Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.12, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 50688, - }, - }, - "grok-41-fast": { - ID: "grok-41-fast", - Name: "Grok 4.1 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.25, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.87, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "hermes-3-llama-3.1-405b": { - ID: "hermes-3-llama-3.1-405b", - Name: "Hermes 3 Llama 3.1 405b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "kimi-k2-thinking": { - ID: "kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.75, - Output: 3.2, - CacheRead: &[]float64{0.375}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "llama-3.2-3b": { - ID: "llama-3.2-3b", - Name: "Llama 3.2 3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "llama-3.3-70b": { - ID: "llama-3.3-70b", - Name: "Llama 3.3 70B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "minimax-m21": { - ID: "minimax-m21", - Name: "MiniMax M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.04}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 50688, - }, - }, - "mistral-31-24b": { - ID: "mistral-31-24b", - Name: "Venice Medium", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai-gpt-52": { - ID: "openai-gpt-52", - Name: "GPT-5.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2.19, - Output: 17.5, - CacheRead: &[]float64{0.219}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "openai-gpt-oss-120b": { - ID: "openai-gpt-oss-120b", - Name: "OpenAI GPT OSS 120B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-235b-a22b-instruct-2507": { - ID: "qwen3-235b-a22b-instruct-2507", - Name: "Qwen 3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-235b-a22b-thinking-2507": { - ID: "qwen3-235b-a22b-thinking-2507", - Name: "Qwen 3 235B A22B Thinking 2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.45, - Output: 3.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "qwen3-4b": { - ID: "qwen3-4b", - Name: "Venice Small", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.05, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "qwen3-coder-480b-a35b-instruct": { - ID: "qwen3-coder-480b-a35b-instruct", - Name: "Qwen 3 Coder 480b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.75, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "qwen3-next-80b": { - ID: "qwen3-next-80b", - Name: "Qwen 3 Next 80b", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 65536, - }, - }, - "venice-uncensored": { - ID: "venice-uncensored", - Name: "Venice Uncensored 1.1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32768, - Output: 8192, - }, - }, - "zai-org-glm-4.6": { - ID: "zai-org-glm-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.85, - Output: 2.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 50688, - }, - }, - "zai-org-glm-4.6v": { - ID: "zai-org-glm-4.6v", - Name: "GLM 4.6V", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.39, - Output: 1.13, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "zai-org-glm-4.7": { - ID: "zai-org-glm-4.7", - Name: "GLM 4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.55, - Output: 2.65, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 202752, - Output: 50688, - }, - }, - }, - }, - "vercel": { - ID: "vercel", - Env: []string{"AI_GATEWAY_API_KEY" }, - NPM: "@ai-sdk/gateway", - Name: "Vercel AI Gateway", - Models: map[string]ModelInfo{ - "alibaba/qwen3-coder-plus": { - ID: "alibaba/qwen3-coder-plus", - Name: "Qwen3 Coder Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 1000000, - }, - }, - "alibaba/qwen3-max": { - ID: "alibaba/qwen3-max", - Name: "Qwen3 Max", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 32768, - }, - }, - "alibaba/qwen3-next-80b-a3b-instruct": { - ID: "alibaba/qwen3-next-80b-a3b-instruct", - Name: "Qwen3 Next 80B A3B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "alibaba/qwen3-next-80b-a3b-thinking": { - ID: "alibaba/qwen3-next-80b-a3b-thinking", - Name: "Qwen3 Next 80B A3B Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "alibaba/qwen3-vl-instruct": { - ID: "alibaba/qwen3-vl-instruct", - Name: "Qwen3 VL Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 2.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 129024, - }, - }, - "alibaba/qwen3-vl-thinking": { - ID: "alibaba/qwen3-vl-thinking", - Name: "Qwen3 VL Thinking", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.7, - Output: 8.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 129024, - }, - }, - "amazon/nova-lite": { - ID: "amazon/nova-lite", - Name: "Nova Lite", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.06, - Output: 0.24, - CacheRead: &[]float64{0.015}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 300000, - Output: 8192, - }, - }, - "amazon/nova-micro": { - ID: "amazon/nova-micro", - Name: "Nova Micro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.035, - Output: 0.14, - CacheRead: &[]float64{0.00875}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "amazon/nova-pro": { - ID: "amazon/nova-pro", - Name: "Nova Pro", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 3.2, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 300000, - Output: 8192, - }, - }, - "anthropic/claude-3-haiku": { - ID: "anthropic/claude-3-haiku", - Name: "Claude Haiku 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 1.25, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0.3}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic/claude-3-opus": { - ID: "anthropic/claude-3-opus", - Name: "Claude Opus 3", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 4096, - }, - }, - "anthropic/claude-3.5-haiku": { - ID: "anthropic/claude-3.5-haiku", - Name: "Claude Haiku 3.5", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.8, - Output: 4, - CacheRead: &[]float64{0.08}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic/claude-3.5-sonnet": { - ID: "anthropic/claude-3.5-sonnet", - Name: "Claude Sonnet 3.5 v2", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 8192, - }, - }, - "anthropic/claude-3.7-sonnet": { - ID: "anthropic/claude-3.7-sonnet", - Name: "Claude Sonnet 3.7", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-4-1-opus": { - ID: "anthropic/claude-4-1-opus", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-4-opus": { - ID: "anthropic/claude-4-opus", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-4-sonnet": { - ID: "anthropic/claude-4-sonnet", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-4.5-sonnet": { - ID: "anthropic/claude-4.5-sonnet", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-haiku-4.5": { - ID: "anthropic/claude-haiku-4.5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 1.25, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-opus-4.5": { - ID: "anthropic/claude-opus-4.5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "deepseek/deepseek-r1": { - ID: "deepseek/deepseek-r1", - Name: "DeepSeek-R1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "deepseek/deepseek-r1-distill-llama-70b": { - ID: "deepseek/deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.75, - Output: 0.99, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "deepseek/deepseek-v3.1-terminus": { - ID: "deepseek/deepseek-v3.1-terminus", - Name: "DeepSeek V3.1 Terminus", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.27, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 8192, - }, - }, - "deepseek/deepseek-v3.2-exp": { - ID: "deepseek/deepseek-v3.2-exp", - Name: "DeepSeek V3.2 Exp", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 8192, - }, - }, - "deepseek/deepseek-v3.2-exp-thinking": { - ID: "deepseek/deepseek-v3.2-exp-thinking", - Name: "DeepSeek V3.2 Exp Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 8192, - }, - }, - "google/gemini-2.0-flash": { - ID: "google/gemini-2.0-flash", - Name: "Gemini 2.0 Flash", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "google/gemini-2.0-flash-lite": { - ID: "google/gemini-2.0-flash-lite", - Name: "Gemini 2.0 Flash Lite", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.075, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 8192, - }, - }, - "google/gemini-2.5-flash": { - ID: "google/gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-flash-lite": { - ID: "google/gemini-2.5-flash-lite", - Name: "Gemini 2.5 Flash Lite", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-flash-lite-preview-09-2025": { - ID: "google/gemini-2.5-flash-lite-preview-09-2025", - Name: "Gemini 2.5 Flash Lite Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.025}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-flash-preview-09-2025": { - ID: "google/gemini-2.5-flash-preview-09-2025", - Name: "Gemini 2.5 Flash Preview 09-25", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: &[]float64{0.383}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-2.5-pro": { - ID: "google/gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-pro-preview": { - ID: "google/gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "meta/llama-3.3-70b": { - ID: "meta/llama-3.3-70b", - Name: "Llama-3.3-70B-Instruct", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-4-maverick": { - ID: "meta/llama-4-maverick", - Name: "Llama-4-Maverick-17B-128E-Instruct-FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "meta/llama-4-scout": { - ID: "meta/llama-4-scout", - Name: "Llama-4-Scout-17B-16E-Instruct-FP8", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "minimax/minimax-m2": { - ID: "minimax/minimax-m2", - Name: "MiniMax M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0.38}[0], - }, - Limit: Limit{ - Context: 205000, - Output: 131072, - }, - }, - "mistral/codestral": { - ID: "mistral/codestral", - Name: "Codestral", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 4096, - }, - }, - "mistral/magistral-medium": { - ID: "mistral/magistral-medium", - Name: "Magistral Medium", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "mistral/magistral-small": { - ID: "mistral/magistral-small", - Name: "Magistral Small", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral/ministral-3b": { - ID: "mistral/ministral-3b", - Name: "Ministral 3B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.04, - Output: 0.04, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral/ministral-8b": { - ID: "mistral/ministral-8b", - Name: "Ministral 8B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral/mistral-large": { - ID: "mistral/mistral-large", - Name: "Mistral Large", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 262144, - }, - }, - "mistral/mistral-small": { - ID: "mistral/mistral-small", - Name: "Mistral Small", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "mistral/mixtral-8x22b-instruct": { - ID: "mistral/mixtral-8x22b-instruct", - Name: "Mixtral 8x22B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 64000, - }, - }, - "mistral/pixtral-12b": { - ID: "mistral/pixtral-12b", - Name: "Pixtral 12B", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "mistral/pixtral-large": { - ID: "mistral/pixtral-large", - Name: "Pixtral Large", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 6, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 128000, - }, - }, - "moonshotai/kimi-k2": { - ID: "moonshotai/kimi-k2", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 16384, - }, - }, - "morph/morph-v3-fast": { - ID: "morph/morph-v3-fast", - Name: "Morph v3 Fast", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.8, - Output: 1.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 16000, - Output: 16000, - }, - }, - "morph/morph-v3-large": { - ID: "morph/morph-v3-large", - Name: "Morph v3 Large", - Attachment: false, - Reasoning: false, - Temperature: false, - Cost: Cost{ - Input: 0.9, - Output: 1.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 32000, - Output: 32000, - }, - }, - "openai/gpt-4-turbo": { - ID: "openai/gpt-4-turbo", - Name: "GPT-4 Turbo", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 10, - Output: 30, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "openai/gpt-4.1": { - ID: "openai/gpt-4.1", - Name: "GPT-4.1", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4.1-mini": { - ID: "openai/gpt-4.1-mini", - Name: "GPT-4.1 mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.4, - Output: 1.6, - CacheRead: &[]float64{0.1}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4.1-nano": { - ID: "openai/gpt-4.1-nano", - Name: "GPT-4.1 nano", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1047576, - Output: 32768, - }, - }, - "openai/gpt-4o": { - ID: "openai/gpt-4o", - Name: "GPT-4o", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2.5, - Output: 10, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-4o-mini": { - ID: "openai/gpt-4o-mini", - Name: "GPT-4o mini", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.15, - Output: 0.6, - CacheRead: &[]float64{0.08}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - "openai/gpt-5": { - ID: "openai/gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-codex": { - ID: "openai/gpt-5-codex", - Name: "GPT-5-Codex", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.125}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-mini": { - ID: "openai/gpt-5-mini", - Name: "GPT-5 Mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-5-nano": { - ID: "openai/gpt-5-nano", - Name: "GPT-5 Nano", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 0.05, - Output: 0.4, - CacheRead: &[]float64{0.01}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 128000, - }, - }, - "openai/gpt-oss-120b": { - ID: "openai/gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/gpt-oss-20b": { - ID: "openai/gpt-oss-20b", - Name: "GPT OSS 20B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.3, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 32768, - }, - }, - "openai/o1": { - ID: "openai/o1", - Name: "o1", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 15, - Output: 60, - CacheRead: &[]float64{7.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3": { - ID: "openai/o3", - Name: "o3", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: &[]float64{0.5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o3-mini": { - ID: "openai/o3-mini", - Name: "o3-mini", - Attachment: false, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.55}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "openai/o4-mini": { - ID: "openai/o4-mini", - Name: "o4-mini", - Attachment: true, - Reasoning: true, - Temperature: false, - Cost: Cost{ - Input: 1.1, - Output: 4.4, - CacheRead: &[]float64{0.28}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 100000, - }, - }, - "perplexity/sonar": { - ID: "perplexity/sonar", - Name: "Sonar", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 8000, - }, - }, - "perplexity/sonar-pro": { - ID: "perplexity/sonar-pro", - Name: "Sonar Pro", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 8000, - }, - }, - "perplexity/sonar-reasoning": { - ID: "perplexity/sonar-reasoning", - Name: "Sonar Reasoning", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 8000, - }, - }, - "perplexity/sonar-reasoning-pro": { - ID: "perplexity/sonar-reasoning-pro", - Name: "Sonar Reasoning Pro", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 127000, - Output: 8000, - }, - }, - "vercel/v0-1.0-md": { - ID: "vercel/v0-1.0-md", - Name: "v0-1.0-md", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "vercel/v0-1.5-md": { - ID: "vercel/v0-1.5-md", - Name: "v0-1.5-md", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32000, - }, - }, - "xai/grok-2": { - ID: "xai/grok-2", - Name: "Grok 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-2-vision": { - ID: "xai/grok-2-vision", - Name: "Grok 2 Vision", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - "xai/grok-3": { - ID: "xai/grok-3", - Name: "Grok 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-3-fast": { - ID: "xai/grok-3-fast", - Name: "Grok 3 Fast", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-3-mini": { - ID: "xai/grok-3-mini", - Name: "Grok 3 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-3-mini-fast": { - ID: "xai/grok-3-mini-fast", - Name: "Grok 3 Mini Fast", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 4, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "xai/grok-4": { - ID: "xai/grok-4", - Name: "Grok 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "xai/grok-4-fast": { - ID: "xai/grok-4-fast", - Name: "Grok 4 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "xai/grok-4-fast-non-reasoning": { - ID: "xai/grok-4-fast-non-reasoning", - Name: "Grok 4 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "xai/grok-code-fast-1": { - ID: "xai/grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 10000, - }, - }, - "zai/glm-4.5": { - ID: "zai/glm-4.5", - Name: "GLM 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 96000, - }, - }, - "zai/glm-4.5-air": { - ID: "zai/glm-4.5-air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 96000, - }, - }, - "zai/glm-4.5v": { - ID: "zai/glm-4.5v", - Name: "GLM 4.5V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 66000, - Output: 16000, - }, - }, - "zai/glm-4.6": { - ID: "zai/glm-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 96000, - }, - }, - }, - }, - "vultr": { - ID: "vultr", - Env: []string{"VULTR_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Vultr", - Models: map[string]ModelInfo{ - "deepseek-r1-distill-llama-70b": { - ID: "deepseek-r1-distill-llama-70b", - Name: "DeepSeek R1 Distill Llama 70B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 121808, - Output: 8192, - }, - }, - "deepseek-r1-distill-qwen-32b": { - ID: "deepseek-r1-distill-qwen-32b", - Name: "DeepSeek R1 Distill Qwen 32B", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 121808, - Output: 8192, - }, - }, - "gpt-oss-120b": { - ID: "gpt-oss-120b", - Name: "GPT OSS 120B", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 121808, - Output: 8192, - }, - }, - "kimi-k2-instruct": { - ID: "kimi-k2-instruct", - Name: "Kimi K2 Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 58904, - Output: 4096, - }, - }, - "qwen2.5-coder-32b-instruct": { - ID: "qwen2.5-coder-32b-instruct", - Name: "Qwen2.5 Coder 32B Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.2, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 12952, - Output: 2048, - }, - }, - }, - }, - "wandb": { - ID: "wandb", - Env: []string{"WANDB_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Weights & Biases", - Models: map[string]ModelInfo{ - "Qwen/Qwen3-235B-A22B-Instruct-2507": { - ID: "Qwen/Qwen3-235B-A22B-Instruct-2507", - Name: "Qwen3 235B A22B Instruct 2507", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-235B-A22B-Thinking-2507": { - ID: "Qwen/Qwen3-235B-A22B-Thinking-2507", - Name: "Qwen3-235B-A22B-Thinking-2507", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.1, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 131072, - }, - }, - "Qwen/Qwen3-Coder-480B-A35B-Instruct": { - ID: "Qwen/Qwen3-Coder-480B-A35B-Instruct", - Name: "Qwen3-Coder-480B-A35B-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 1.5, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 66536, - }, - }, - "deepseek-ai/DeepSeek-R1-0528": { - ID: "deepseek-ai/DeepSeek-R1-0528", - Name: "DeepSeek-R1-0528", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 5.4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 161000, - Output: 163840, - }, - }, - "deepseek-ai/DeepSeek-V3-0324": { - ID: "deepseek-ai/DeepSeek-V3-0324", - Name: "DeepSeek-V3-0324", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.14, - Output: 2.75, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 161000, - Output: 8192, - }, - }, - "meta-llama/Llama-3.1-8B-Instruct": { - ID: "meta-llama/Llama-3.1-8B-Instruct", - Name: "Meta-Llama-3.1-8B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.22, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama/Llama-3.3-70B-Instruct": { - ID: "meta-llama/Llama-3.3-70B-Instruct", - Name: "Llama-3.3-70B-Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.71, - Output: 0.71, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "meta-llama/Llama-4-Scout-17B-16E-Instruct": { - ID: "meta-llama/Llama-4-Scout-17B-16E-Instruct", - Name: "Llama 4 Scout 17B 16E Instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 0.66, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 8192, - }, - }, - "microsoft/Phi-4-mini-instruct": { - ID: "microsoft/Phi-4-mini-instruct", - Name: "Phi-4-mini-instruct", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.08, - Output: 0.35, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 4096, - }, - }, - "moonshotai/Kimi-K2-Instruct": { - ID: "moonshotai/Kimi-K2-Instruct", - Name: "Kimi-K2-Instruct", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.35, - Output: 4, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 16384, - }, - }, - }, - }, - "xai": { - ID: "xai", - Env: []string{"XAI_API_KEY" }, - NPM: "@ai-sdk/xai", - Name: "xAI", - Models: map[string]ModelInfo{ - "grok-2": { - ID: "grok-2", - Name: "Grok 2", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-2-1212": { - ID: "grok-2-1212", - Name: "Grok 2 (1212)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-2-latest": { - ID: "grok-2-latest", - Name: "Grok 2 Latest", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-2-vision": { - ID: "grok-2-vision", - Name: "Grok 2 Vision", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - "grok-2-vision-1212": { - ID: "grok-2-vision-1212", - Name: "Grok 2 Vision (1212)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - "grok-2-vision-latest": { - ID: "grok-2-vision-latest", - Name: "Grok 2 Vision Latest", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 10, - CacheRead: &[]float64{2}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - "grok-3": { - ID: "grok-3", - Name: "Grok 3", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-fast": { - ID: "grok-3-fast", - Name: "Grok 3 Fast", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-fast-latest": { - ID: "grok-3-fast-latest", - Name: "Grok 3 Fast Latest", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{1.25}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-latest": { - ID: "grok-3-latest", - Name: "Grok 3 Latest", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-mini": { - ID: "grok-3-mini", - Name: "Grok 3 Mini", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-mini-fast": { - ID: "grok-3-mini-fast", - Name: "Grok 3 Mini Fast", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 4, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-mini-fast-latest": { - ID: "grok-3-mini-fast-latest", - Name: "Grok 3 Mini Fast Latest", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 4, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-3-mini-latest": { - ID: "grok-3-mini-latest", - Name: "Grok 3 Mini Latest", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.5, - CacheRead: &[]float64{0.075}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 8192, - }, - }, - "grok-4": { - ID: "grok-4", - Name: "Grok 4", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "grok-4-1-fast": { - ID: "grok-4-1-fast", - Name: "Grok 4.1 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-4-1-fast-non-reasoning": { - ID: "grok-4-1-fast-non-reasoning", - Name: "Grok 4.1 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-4-fast": { - ID: "grok-4-fast", - Name: "Grok 4 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-4-fast-non-reasoning": { - ID: "grok-4-fast-non-reasoning", - Name: "Grok 4 Fast (Non-Reasoning)", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 30000, - }, - }, - "grok-beta": { - ID: "grok-beta", - Name: "Grok Beta", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 15, - CacheRead: &[]float64{5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 131072, - Output: 4096, - }, - }, - "grok-code-fast-1": { - ID: "grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 10000, - }, - }, - "grok-vision-beta": { - ID: "grok-vision-beta", - Name: "Grok Vision Beta", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 15, - CacheRead: &[]float64{5}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 8192, - Output: 4096, - }, - }, - }, - }, - "xiaomi": { - ID: "xiaomi", - Env: []string{"XIAOMI_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Xiaomi", - Models: map[string]ModelInfo{ - "mimo-v2-flash": { - ID: "mimo-v2-flash", - Name: "MiMo-V2-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.07, - Output: 0.21, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 32000, - }, - }, - }, - }, - "zai": { - ID: "zai", - Env: []string{"ZHIPU_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Z.AI", - Models: map[string]ModelInfo{ - "glm-4.5": { - ID: "glm-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-air": { - ID: "glm-4.5-air", - Name: "GLM-4.5-Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.1, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-flash": { - ID: "glm-4.5-flash", - Name: "GLM-4.5-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5v": { - ID: "glm-4.5v", - Name: "GLM-4.5V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 16384, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "glm-4.6v": { - ID: "glm-4.6v", - Name: "GLM-4.6V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "glm-4.7": { - ID: "glm-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "zai-coding-plan": { - ID: "zai-coding-plan", - Env: []string{"ZHIPU_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Z.AI Coding Plan", - Models: map[string]ModelInfo{ - "glm-4.5": { - ID: "glm-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-air": { - ID: "glm-4.5-air", - Name: "GLM-4.5-Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-flash": { - ID: "glm-4.5-flash", - Name: "GLM-4.5-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5v": { - ID: "glm-4.5v", - Name: "GLM-4.5V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 16384, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "glm-4.6v": { - ID: "glm-4.6v", - Name: "GLM-4.6V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "glm-4.7": { - ID: "glm-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "zenmux": { - ID: "zenmux", - Env: []string{"ZENMUX_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "ZenMux", - Models: map[string]ModelInfo{ - "anthropic/claude-haiku-4.5": { - ID: "anthropic/claude-haiku-4.5", - Name: "Claude Haiku 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-opus-4": { - ID: "anthropic/claude-opus-4", - Name: "Claude Opus 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-opus-4.1": { - ID: "anthropic/claude-opus-4.1", - Name: "Claude Opus 4.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 15, - Output: 75, - CacheRead: &[]float64{1.5}[0], - CacheWrite: &[]float64{18.75}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 32000, - }, - }, - "anthropic/claude-opus-4.5": { - ID: "anthropic/claude-opus-4.5", - Name: "Claude Opus 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 5, - Output: 25, - CacheRead: &[]float64{0.5}[0], - CacheWrite: &[]float64{6.25}[0], - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4": { - ID: "anthropic/claude-sonnet-4", - Name: "Claude Sonnet 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "anthropic/claude-sonnet-4.5": { - ID: "anthropic/claude-sonnet-4.5", - Name: "Claude Sonnet 4.5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.3}[0], - CacheWrite: &[]float64{3.75}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "baidu/ernie-5.0-thinking-preview": { - ID: "baidu/ernie-5.0-thinking-preview", - Name: "ERNIE-5.0-Thinking-Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.84, - Output: 3.37, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek/deepseek-chat": { - ID: "deepseek/deepseek-chat", - Name: "DeepSeek-V3.2 (Non-thinking Mode)", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek/deepseek-reasoner": { - ID: "deepseek/deepseek-reasoner", - Name: "DeepSeek-V3.2 (Thinking Mode)", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.42, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek/deepseek-v3.2": { - ID: "deepseek/deepseek-v3.2", - Name: "DeepSeek V3.2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 0.43, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "deepseek/deepseek-v3.2-exp": { - ID: "deepseek/deepseek-v3.2-exp", - Name: "DeepSeek-V3.2-Exp", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.22, - Output: 0.33, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 163840, - Output: 64000, - }, - }, - "google/gemini-2.5-flash": { - ID: "google/gemini-2.5-flash", - Name: "Gemini 2.5 Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 2.5, - CacheRead: &[]float64{0.07}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 64000, - }, - }, - "google/gemini-2.5-flash-lite": { - ID: "google/gemini-2.5-flash-lite", - Name: "Gemini 2.5 Flash Lite", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.1, - Output: 0.4, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 64000, - }, - }, - "google/gemini-2.5-pro": { - ID: "google/gemini-2.5-pro", - Name: "Gemini 2.5 Pro", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.31}[0], - CacheWrite: &[]float64{4.5}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 65536, - }, - }, - "google/gemini-3-flash-preview": { - ID: "google/gemini-3-flash-preview", - Name: "Gemini 3 Flash Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.5, - Output: 3, - CacheRead: &[]float64{0.05}[0], - CacheWrite: &[]float64{1}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 64000, - }, - }, - "google/gemini-3-flash-preview-free": { - ID: "google/gemini-3-flash-preview-free", - Name: "Gemini 3 Flash Preview Free", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 1048576, - Output: 64000, - }, - }, - "google/gemini-3-pro-preview": { - ID: "google/gemini-3-pro-preview", - Name: "Gemini 3 Pro Preview", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 2, - Output: 12, - CacheRead: &[]float64{0.2}[0], - CacheWrite: &[]float64{4.5}[0], - }, - Limit: Limit{ - Context: 1048576, - Output: 64000, - }, - }, - "inclusionai/ling-1t": { - ID: "inclusionai/ling-1t", - Name: "Ling-1T", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 2.24, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "inclusionai/ring-1t": { - ID: "inclusionai/ring-1t", - Name: "Ring-1T", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.56, - Output: 2.24, - CacheRead: &[]float64{0.11}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "kuaishou/kat-coder-pro-v1": { - ID: "kuaishou/kat-coder-pro-v1", - Name: "KAT-Coder-Pro-V1", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "kuaishou/kat-coder-pro-v1-free": { - ID: "kuaishou/kat-coder-pro-v1-free", - Name: "KAT-Coder-Pro-V1 Free", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "minimax/minimax-m2": { - ID: "minimax/minimax-m2", - Name: "MiniMax M2", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 64000, - }, - }, - "minimax/minimax-m2.1": { - ID: "minimax/minimax-m2.1", - Name: "MiniMax M2.1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 1.2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 204800, - Output: 64000, - }, - }, - "moonshotai/kimi-k2-0905": { - ID: "moonshotai/kimi-k2-0905", - Name: "Kimi K2 0905", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262100, - Output: 64000, - }, - }, - "moonshotai/kimi-k2-thinking": { - ID: "moonshotai/kimi-k2-thinking", - Name: "Kimi K2 Thinking", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.5, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 64000, - }, - }, - "moonshotai/kimi-k2-thinking-turbo": { - ID: "moonshotai/kimi-k2-thinking-turbo", - Name: "Kimi K2 Thinking Turbo", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.15, - Output: 8, - CacheRead: &[]float64{0.15}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 64000, - }, - }, - "openai/gpt-5": { - ID: "openai/gpt-5", - Name: "GPT-5", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 64000, - }, - }, - "openai/gpt-5-codex": { - ID: "openai/gpt-5-codex", - Name: "GPT-5 Codex", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 64000, - }, - }, - "openai/gpt-5.1": { - ID: "openai/gpt-5.1", - Name: "GPT-5.1", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 64000, - }, - }, - "openai/gpt-5.1-chat": { - ID: "openai/gpt-5.1-chat", - Name: "GPT-5.1 Chat", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "openai/gpt-5.1-codex": { - ID: "openai/gpt-5.1-codex", - Name: "GPT-5.1-Codex", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.25, - Output: 10, - CacheRead: &[]float64{0.13}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 64000, - }, - }, - "openai/gpt-5.1-codex-mini": { - ID: "openai/gpt-5.1-codex-mini", - Name: "GPT-5.1-Codex-Mini", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.25, - Output: 2, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 64000, - }, - }, - "openai/gpt-5.2": { - ID: "openai/gpt-5.2", - Name: "GPT-5.2", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 1.75, - Output: 14, - CacheRead: &[]float64{0.17}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 400000, - Output: 64000, - }, - }, - "qwen/qwen3-coder-plus": { - ID: "qwen/qwen3-coder-plus", - Name: "Qwen3-Coder-Plus", - Attachment: false, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 1, - Output: 5, - CacheRead: &[]float64{0.1}[0], - CacheWrite: &[]float64{1.25}[0], - }, - Limit: Limit{ - Context: 1000000, - Output: 64000, - }, - }, - "stepfun/step-3": { - ID: "stepfun/step-3", - Name: "Step-3", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.21, - Output: 0.57, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 65536, - Output: 64000, - }, - }, - "volcengine/doubao-seed-1.8": { - ID: "volcengine/doubao-seed-1.8", - Name: "Doubao-Seed-1.8", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.28, - CacheRead: &[]float64{0.02}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "volcengine/doubao-seed-code": { - ID: "volcengine/doubao-seed-code", - Name: "Doubao-Seed-Code", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.17, - Output: 1.12, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "x-ai/grok-4": { - ID: "x-ai/grok-4", - Name: "Grok 4", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 3, - Output: 15, - CacheRead: &[]float64{0.75}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "x-ai/grok-4-fast": { - ID: "x-ai/grok-4-fast", - Name: "Grok 4 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 64000, - }, - }, - "x-ai/grok-4.1-fast": { - ID: "x-ai/grok-4.1-fast", - Name: "Grok 4.1 Fast", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 64000, - }, - }, - "x-ai/grok-4.1-fast-non-reasoning": { - ID: "x-ai/grok-4.1-fast-non-reasoning", - Name: "Grok 4.1 Fast Non Reasoning", - Attachment: true, - Reasoning: false, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 0.5, - CacheRead: &[]float64{0.05}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 2000000, - Output: 64000, - }, - }, - "x-ai/grok-code-fast-1": { - ID: "x-ai/grok-code-fast-1", - Name: "Grok Code Fast 1", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.5, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 256000, - Output: 64000, - }, - }, - "xiaomi/mimo-v2-flash": { - ID: "xiaomi/mimo-v2-flash", - Name: "MiMo-V2-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 64000, - }, - }, - "xiaomi/mimo-v2-flash-free": { - ID: "xiaomi/mimo-v2-flash-free", - Name: "MiMo-V2-Flash Free", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 262144, - Output: 64000, - }, - }, - "z-ai/glm-4.5": { - ID: "z-ai/glm-4.5", - Name: "GLM 4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.54, - CacheRead: &[]float64{0.07}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "z-ai/glm-4.5-air": { - ID: "z-ai/glm-4.5-air", - Name: "GLM 4.5 Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.11, - Output: 0.56, - CacheRead: &[]float64{0.02}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 64000, - }, - }, - "z-ai/glm-4.6": { - ID: "z-ai/glm-4.6", - Name: "GLM 4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.35, - Output: 1.54, - CacheRead: &[]float64{0.07}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 128000, - }, - }, - "z-ai/glm-4.6v": { - ID: "z-ai/glm-4.6v", - Name: "GLM 4.6V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.14, - Output: 0.42, - CacheRead: &[]float64{0.03}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "z-ai/glm-4.6v-flash": { - ID: "z-ai/glm-4.6v-flash", - Name: "GLM 4.6V FlashX", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "z-ai/glm-4.6v-flash-free": { - ID: "z-ai/glm-4.6v-flash-free", - Name: "GLM 4.6V Flash (Free)", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - "z-ai/glm-4.7": { - ID: "z-ai/glm-4.7", - Name: "GLM 4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.28, - Output: 1.14, - CacheRead: &[]float64{0.06}[0], - CacheWrite: nil, - }, - Limit: Limit{ - Context: 200000, - Output: 64000, - }, - }, - }, - }, - "zhipuai": { - ID: "zhipuai", - Env: []string{"ZHIPU_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Zhipu AI", - Models: map[string]ModelInfo{ - "glm-4.5": { - ID: "glm-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-air": { - ID: "glm-4.5-air", - Name: "GLM-4.5-Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.2, - Output: 1.1, - CacheRead: &[]float64{0.03}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-flash": { - ID: "glm-4.5-flash", - Name: "GLM-4.5-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5v": { - ID: "glm-4.5v", - Name: "GLM-4.5V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 1.8, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 16384, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "glm-4.6v": { - ID: "glm-4.6v", - Name: "GLM-4.6V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.3, - Output: 0.9, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "glm-4.6v-flash": { - ID: "glm-4.6v-flash", - Name: "GLM-4.6V-Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "glm-4.7": { - ID: "glm-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0.6, - Output: 2.2, - CacheRead: &[]float64{0.11}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - "zhipuai-coding-plan": { - ID: "zhipuai-coding-plan", - Env: []string{"ZHIPU_API_KEY" }, - NPM: "@ai-sdk/openai-compatible", - Name: "Zhipu AI Coding Plan", - Models: map[string]ModelInfo{ - "glm-4.5": { - ID: "glm-4.5", - Name: "GLM-4.5", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-air": { - ID: "glm-4.5-air", - Name: "GLM-4.5-Air", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5-flash": { - ID: "glm-4.5-flash", - Name: "GLM-4.5-Flash", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 131072, - Output: 98304, - }, - }, - "glm-4.5v": { - ID: "glm-4.5v", - Name: "GLM-4.5V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 64000, - Output: 16384, - }, - }, - "glm-4.6": { - ID: "glm-4.6", - Name: "GLM-4.6", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - "glm-4.6v": { - ID: "glm-4.6v", - Name: "GLM-4.6V", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "glm-4.6v-flash": { - ID: "glm-4.6v-flash", - Name: "GLM-4.6V-Flash", - Attachment: true, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: nil, - CacheWrite: nil, - }, - Limit: Limit{ - Context: 128000, - Output: 32768, - }, - }, - "glm-4.7": { - ID: "glm-4.7", - Name: "GLM-4.7", - Attachment: false, - Reasoning: true, - Temperature: true, - Cost: Cost{ - Input: 0, - Output: 0, - CacheRead: &[]float64{0}[0], - CacheWrite: &[]float64{0}[0], - }, - Limit: Limit{ - Context: 204800, - Output: 131072, - }, - }, - }, - }, - } -} diff --git a/internal/models/openai/openai.go b/internal/models/openai/openai.go deleted file mode 100644 index 3f51490d..00000000 --- a/internal/models/openai/openai.go +++ /dev/null @@ -1,249 +0,0 @@ -package openai - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "strings" - - einoopenai "github.com/cloudwego/eino-ext/components/model/openai" - "github.com/cloudwego/eino/components/model" - "github.com/cloudwego/eino/schema" -) - -// CustomChatModel wraps the eino-ext OpenAI model with custom tool schema handling. -// It provides a compatibility layer that ensures proper JSON schema formatting -// for OpenAI's function calling feature. This wrapper addresses cases where -// tool schemas might have missing or empty properties that would cause API errors. -type CustomChatModel struct { - // wrapped is the underlying eino-ext OpenAI model instance - wrapped *einoopenai.ChatModel -} - -// CustomRoundTripper intercepts HTTP requests to fix OpenAI function schemas. -// It acts as middleware that modifies outgoing requests to ensure that -// function/tool schemas are properly formatted according to OpenAI's requirements. -// This is particularly important for handling edge cases where tool schemas -// might have missing or empty properties fields. -type CustomRoundTripper struct { - // wrapped is the underlying HTTP transport to use for actual requests - wrapped http.RoundTripper -} - -// NewCustomChatModel creates a new custom OpenAI chat model. -// It wraps the standard eino-ext OpenAI model with additional request -// preprocessing to ensure compatibility with OpenAI's API requirements, -// particularly for function calling and tool schemas. -// -// Parameters: -// - ctx: Context for the operation -// - config: Configuration for the OpenAI model including API key, model name, and parameters -// -// Returns: -// - *CustomChatModel: A wrapped OpenAI model with enhanced compatibility -// - error: Returns an error if model creation fails -// -// The custom model automatically: -// - Ensures function parameter schemas have properties fields -// - Fixes missing or empty properties in tool schemas -// - Maintains compatibility with OpenAI's function calling requirements -func NewCustomChatModel(ctx context.Context, config *einoopenai.ChatModelConfig) (*CustomChatModel, error) { - // Create a custom HTTP client that intercepts requests - if config.HTTPClient == nil { - config.HTTPClient = &http.Client{} - } - - // Wrap the transport to intercept requests - if config.HTTPClient.Transport == nil { - config.HTTPClient.Transport = http.DefaultTransport - } - config.HTTPClient.Transport = &CustomRoundTripper{ - wrapped: config.HTTPClient.Transport, - } - - wrapped, err := einoopenai.NewChatModel(ctx, config) - if err != nil { - return nil, err - } - - return &CustomChatModel{ - wrapped: wrapped, - }, nil -} - -// RoundTrip implements http.RoundTripper to intercept and fix OpenAI requests. -// It preprocesses outgoing requests to the OpenAI API to ensure tool/function -// schemas meet the API's requirements. -// -// Parameters: -// - req: The HTTP request to be sent to the OpenAI API -// -// Returns: -// - *http.Response: The response from the OpenAI API -// - error: Any error that occurred during the request -// -// The method performs the following fixes: -// - Ensures function parameter schemas of type "object" have a properties field -// - Adds empty properties object if missing to prevent API validation errors -func (c *CustomRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - // Only intercept OpenAI chat completions requests - if !strings.Contains(req.URL.Path, "/chat/completions") { - return c.wrapped.RoundTrip(req) - } - - // Read the request body - if req.Body == nil { - return c.wrapped.RoundTrip(req) - } - - bodyBytes, err := io.ReadAll(req.Body) - if err != nil { - return c.wrapped.RoundTrip(req) - } - req.Body.Close() - - // Parse the JSON request - var requestData map[string]interface{} - if err := json.Unmarshal(bodyBytes, &requestData); err != nil { - // If we can't parse it, just pass it through - req.Body = io.NopCloser(bytes.NewReader(bodyBytes)) - return c.wrapped.RoundTrip(req) - } - - // Fix function schemas if present - if tools, ok := requestData["tools"].([]interface{}); ok { - for _, tool := range tools { - if toolMap, ok := tool.(map[string]interface{}); ok { - if function, ok := toolMap["function"].(map[string]interface{}); ok { - if parameters, ok := function["parameters"].(map[string]interface{}); ok { - if typeVal, ok := parameters["type"].(string); ok && typeVal == "object" { - // Check if properties is missing or empty - if properties, exists := parameters["properties"]; !exists || properties == nil { - parameters["properties"] = map[string]interface{}{} - } else if propMap, ok := properties.(map[string]interface{}); ok && len(propMap) == 0 { - parameters["properties"] = map[string]interface{}{} - } - } - } - } - } - } - } - // Marshal the fixed request back to JSON - fixedBodyBytes, err := json.Marshal(requestData) - if err != nil { - // If we can't marshal it, use the original - req.Body = io.NopCloser(bytes.NewReader(bodyBytes)) - return c.wrapped.RoundTrip(req) - } - - // Create new request body with fixed data - req.Body = io.NopCloser(bytes.NewReader(fixedBodyBytes)) - req.ContentLength = int64(len(fixedBodyBytes)) - - return c.wrapped.RoundTrip(req) -} - -// Generate implements model.ChatModel interface. -// It generates a single response from the OpenAI model based on the input messages. -// -// Parameters: -// - ctx: Context for the operation, supporting cancellation and deadlines -// - in: The conversation history as a slice of messages -// - opts: Optional configuration options for the generation -// -// Returns: -// - *schema.Message: The generated response message -// - error: Any error that occurred during generation -func (c *CustomChatModel) Generate(ctx context.Context, in []*schema.Message, opts ...model.Option) (*schema.Message, error) { - return c.wrapped.Generate(ctx, in, opts...) -} - -// Stream implements model.ChatModel interface. -// It generates a streaming response from the OpenAI model, allowing -// incremental processing of the model's output as it's generated. -// -// Parameters: -// - ctx: Context for the operation, supporting cancellation and deadlines -// - in: The conversation history as a slice of messages -// - opts: Optional configuration options for the generation -// -// Returns: -// - *schema.StreamReader[*schema.Message]: A reader for the streaming response -// - error: Any error that occurred during stream setup -func (c *CustomChatModel) Stream(ctx context.Context, in []*schema.Message, opts ...model.Option) (*schema.StreamReader[*schema.Message], error) { - return c.wrapped.Stream(ctx, in, opts...) -} - -// WithTools implements model.ToolCallingChatModel interface. -// It creates a new model instance with the specified tools available for function calling. -// The original model instance remains unchanged. -// -// Parameters: -// - tools: A slice of tool definitions that the model can use -// -// Returns: -// - model.ToolCallingChatModel: A new model instance with tools enabled -// - error: Returns an error if tool binding fails -func (c *CustomChatModel) WithTools(tools []*schema.ToolInfo) (model.ToolCallingChatModel, error) { - wrappedWithTools, err := c.wrapped.WithTools(tools) - if err != nil { - return nil, err - } - - // Type assert back to *einoopenai.ChatModel - wrappedChatModel, ok := wrappedWithTools.(*einoopenai.ChatModel) - if !ok { - return nil, fmt.Errorf("unexpected type returned from WithTools") - } - - return &CustomChatModel{wrapped: wrappedChatModel}, nil -} - -// BindTools implements model.ToolCallingChatModel interface. -// It binds tools to the current model instance, modifying it in place -// rather than creating a new instance. -// -// Parameters: -// - tools: A slice of tool definitions to bind to the model -// -// Returns: -// - error: Returns an error if tool binding fails -func (c *CustomChatModel) BindTools(tools []*schema.ToolInfo) error { - return c.wrapped.BindTools(tools) -} - -// BindForcedTools implements model.ToolCallingChatModel interface. -// It binds tools to the current model instance in forced mode, -// ensuring the model will always use one of the provided tools. -// -// Parameters: -// - tools: A slice of tool definitions to bind to the model -// -// Returns: -// - error: Returns an error if tool binding fails -func (c *CustomChatModel) BindForcedTools(tools []*schema.ToolInfo) error { - return c.wrapped.BindForcedTools(tools) -} - -// GetType implements model.ChatModel interface. -// It returns the type identifier for this model implementation. -// -// Returns: -// - string: Returns "CustomOpenAI" as the model type identifier -func (c *CustomChatModel) GetType() string { - return "CustomOpenAI" -} - -// IsCallbacksEnabled implements model.ChatModel interface. -// It indicates whether this model supports callbacks for monitoring -// and tracking purposes. -// -// Returns: -// - bool: Returns the callback enabled status from the wrapped model -func (c *CustomChatModel) IsCallbacksEnabled() bool { - return c.wrapped.IsCallbacksEnabled() -} diff --git a/internal/models/providers.go b/internal/models/providers.go index 8c141fd4..feff1607 100644 --- a/internal/models/providers.go +++ b/internal/models/providers.go @@ -7,28 +7,27 @@ import ( "encoding/json" "fmt" "io" + "maps" "net/http" "os" "strings" "time" - einoclaude "github.com/cloudwego/eino-ext/components/model/claude" - "github.com/cloudwego/eino-ext/components/model/ollama" - einoopenai "github.com/cloudwego/eino-ext/components/model/openai" - "github.com/cloudwego/eino/components/model" - "github.com/mark3labs/mcphost/internal/models/anthropic" - "github.com/mark3labs/mcphost/internal/models/openai" - "github.com/mark3labs/mcphost/internal/ui/progress" - "google.golang.org/genai" + "charm.land/fantasy" + "charm.land/fantasy/providers/anthropic" + "charm.land/fantasy/providers/azure" + "charm.land/fantasy/providers/bedrock" + "charm.land/fantasy/providers/google" + "charm.land/fantasy/providers/openai" + "charm.land/fantasy/providers/openaicompat" + "charm.land/fantasy/providers/openrouter" "github.com/mark3labs/mcphost/internal/auth" - "github.com/mark3labs/mcphost/internal/models/gemini" + "github.com/mark3labs/mcphost/internal/ui/progress" ) const ( // ClaudeCodePrompt is the required system prompt for OAuth authentication. - // This prompt must be included as the first system message when using OAuth-based - // authentication with Anthropic's API to properly identify the application. ClaudeCodePrompt = "You are Claude Code, Anthropic's official CLI for Claude." ) @@ -36,120 +35,57 @@ const ( func resolveModelAlias(provider, modelName string) string { registry := GetGlobalRegistry() - // Common alias patterns for Anthropic models - using Claude 4 as the latest/default aliasMap := map[string]string{ - // Claude 4 models (latest and most capable) "claude-opus-latest": "claude-opus-4-20250514", "claude-sonnet-latest": "claude-sonnet-4-20250514", "claude-4-opus-latest": "claude-opus-4-20250514", "claude-4-sonnet-latest": "claude-sonnet-4-20250514", - // Claude 3.x models for backward compatibility "claude-3-5-haiku-latest": "claude-3-5-haiku-20241022", "claude-3-5-sonnet-latest": "claude-3-5-sonnet-20241022", "claude-3-7-sonnet-latest": "claude-3-7-sonnet-20250219", "claude-3-opus-latest": "claude-3-opus-20240229", } - // Check if it's a known alias if resolved, exists := aliasMap[modelName]; exists { - // Verify the resolved model exists in the registry if _, err := registry.ValidateModel(provider, resolved); err == nil { return resolved } } - // Return original if no alias found or resolved model doesn't exist return modelName } // ProviderConfig holds configuration for creating LLM providers. -// It contains all necessary settings to initialize and configure -// various LLM providers including API keys, model parameters, and -// provider-specific settings. type ProviderConfig struct { - // ModelString specifies the model in the format "provider:model" - // Example: "anthropic:claude-3-sonnet-20240620" or "openai:gpt-4" - ModelString string - - // SystemPrompt sets the system message/instructions for the model - SystemPrompt string - - // ProviderAPIKey is the API key for authentication with the provider - // Used for OpenAI, Anthropic, Google, and Azure providers + ModelString string + SystemPrompt string ProviderAPIKey string - - // ProviderURL is the base URL for the provider's API endpoint - // Can be used to specify custom endpoints for OpenAI, Anthropic, Ollama, or Azure - ProviderURL string - - // Model generation parameters - - // MaxTokens limits the maximum number of tokens in the response - MaxTokens int - - // Temperature controls randomness in generation (0.0 to 1.0) - // Lower values make output more focused and deterministic - Temperature *float32 - - // TopP implements nucleus sampling, controlling diversity - // Value between 0.0 and 1.0, where 1.0 considers all tokens - TopP *float32 - - // TopK limits the number of tokens to sample from - // Used by Anthropic and Google providers - TopK *int32 - - // StopSequences is a list of sequences that will stop generation - StopSequences []string - - // Ollama-specific parameters - - // NumGPU specifies the number of GPUs to use for inference - NumGPU *int32 - - // MainGPU specifies which GPU to use as the primary device - MainGPU *int32 - - // TLS configuration - - // TLSSkipVerify skips TLS certificate verification (insecure) - // Should only be used for development or with self-signed certificates - TLSSkipVerify bool + ProviderURL string + MaxTokens int + Temperature *float32 + TopP *float32 + TopK *int32 + StopSequences []string + NumGPU *int32 + MainGPU *int32 + TLSSkipVerify bool } // ProviderResult contains the result of provider creation. -// It includes both the created model instance and any informational -// messages that should be displayed to the user. type ProviderResult struct { - // Model is the created LLM provider instance that implements - // the ToolCallingChatModel interface for tool-enabled conversations - Model model.ToolCallingChatModel - + // Model is the created fantasy LanguageModel + Model fantasy.LanguageModel // Message contains optional feedback for the user - // Example: "Insufficient GPU memory, falling back to CPU inference" Message string } -// CreateProvider creates an eino ToolCallingChatModel based on the provider configuration. +// CreateProvider creates a fantasy LanguageModel based on the provider configuration. // It validates the model, checks required environment variables, and initializes -// the appropriate provider (Anthropic, OpenAI, Google, Ollama, or Azure). +// the appropriate provider. // -// Parameters: -// - ctx: Context for the operation, used for cancellation and deadlines -// - config: Provider configuration containing model details and parameters -// -// Returns: -// - *ProviderResult: Contains the created model and any informational messages -// - error: Returns an error if provider creation fails, model validation fails, -// or required credentials are missing -// -// Supported providers: -// - anthropic: Claude models with API key or OAuth authentication -// - openai: GPT models including reasoning models like o1 -// - google: Gemini models -// - ollama: Local models with automatic GPU/CPU fallback -// - azure: Azure OpenAI Service deployments +// Supported providers: anthropic, openai, google, ollama, azure, google-vertex-anthropic, +// openrouter, bedrock func CreateProvider(ctx context.Context, config *ProviderConfig) (*ProviderResult, error) { parts := strings.SplitN(config.ModelString, ":", 2) if len(parts) < 2 { @@ -160,7 +96,7 @@ func CreateProvider(ctx context.Context, config *ProviderConfig) (*ProviderResul modelName := parts[1] // Resolve model aliases before validation (for OAuth compatibility) - if provider == "anthropic" { + if provider == "anthropic" || provider == "google-vertex-anthropic" { modelName = resolveModelAlias(provider, modelName) } @@ -171,7 +107,6 @@ func CreateProvider(ctx context.Context, config *ProviderConfig) (*ProviderResul if provider != "ollama" && config.ProviderURL == "" { modelInfo, err := registry.ValidateModel(provider, modelName) if err != nil { - // Provide helpful suggestions suggestions := registry.SuggestModels(provider, modelName) if len(suggestions) > 0 { return nil, fmt.Errorf("%v. Did you mean one of: %s", err, strings.Join(suggestions, ", ")) @@ -179,12 +114,10 @@ func CreateProvider(ctx context.Context, config *ProviderConfig) (*ProviderResul return nil, err } - // Validate environment variables if err := registry.ValidateEnvironment(provider, config.ProviderAPIKey); err != nil { return nil, err } - // Validate configuration parameters against model capabilities if err := validateModelConfig(config, modelInfo); err != nil { return nil, err } @@ -192,50 +125,32 @@ func CreateProvider(ctx context.Context, config *ProviderConfig) (*ProviderResul switch provider { case "anthropic": - model, err := createAnthropicProvider(ctx, config, modelName) - if err != nil { - return nil, err - } - return &ProviderResult{Model: model, Message: ""}, nil + return createAnthropicProvider(ctx, config, modelName) case "openai": - model, err := createOpenAIProvider(ctx, config, modelName) - if err != nil { - return nil, err - } - return &ProviderResult{Model: model, Message: ""}, nil + return createOpenAIProvider(ctx, config, modelName) case "google": - model, err := createGoogleProvider(ctx, config, modelName) - if err != nil { - return nil, err - } - return &ProviderResult{Model: model, Message: ""}, nil + return createGoogleProvider(ctx, config, modelName) case "ollama": - return createOllamaProviderWithResult(ctx, config, modelName) + return createOllamaProvider(ctx, config, modelName) case "azure": - model, err := createAzureOpenAIProvider(ctx, config, modelName) - if err != nil { - return nil, err - } - return &ProviderResult{Model: model, Message: ""}, nil + return createAzureProvider(ctx, config, modelName) case "google-vertex-anthropic": - model, err := createVertexAnthropicProvider(ctx, config, modelName) - if err != nil { - return nil, err - } - return &ProviderResult{Model: model, Message: ""}, nil + return createVertexAnthropicProvider(ctx, config, modelName) + case "openrouter": + return createOpenRouterProvider(ctx, config, modelName) + case "bedrock": + return createBedrockProvider(ctx, config, modelName) default: - return nil, fmt.Errorf("unsupported provider: %s", provider) + return nil, fmt.Errorf("unsupported provider: %s. Supported: anthropic, openai, google, ollama, azure, google-vertex-anthropic, openrouter, bedrock", provider) } } // validateModelConfig validates configuration parameters against model capabilities func validateModelConfig(config *ProviderConfig, modelInfo *ModelInfo) error { - // Omit temperature if not supported by the model if config.Temperature != nil && !modelInfo.Temperature { config.Temperature = nil } - // Warn about context limits if MaxTokens is set too high if config.MaxTokens > modelInfo.Limit.Output { return fmt.Errorf("max_tokens (%d) exceeds model's output limit (%d) for %s", config.MaxTokens, modelInfo.Limit.Output, modelInfo.ID) @@ -244,179 +159,83 @@ func validateModelConfig(config *ProviderConfig, modelInfo *ModelInfo) error { return nil } -func createAzureOpenAIProvider(ctx context.Context, config *ProviderConfig, modelName string) (model.ToolCallingChatModel, error) { - apiKey := config.ProviderAPIKey - if apiKey == "" { - apiKey = os.Getenv("AZURE_OPENAI_API_KEY") - } - if apiKey == "" { - return nil, fmt.Errorf("Azure OpenAI API key not provided. Use --provider-api-key flag or AZURE_OPENAI_API_KEY environment variable") - } - - azureConfig := &einoopenai.ChatModelConfig{ - APIKey: apiKey, - Model: modelName, - ByAzure: true, // Indicate this is an Azure OpenAI model - APIVersion: "2025-01-01-preview", // Default Azure OpenAI API version - } - - if config.ProviderURL != "" { - azureConfig.BaseURL = config.ProviderURL - } else { - azureConfig.BaseURL = os.Getenv("AZURE_OPENAI_BASE_URL") - } - if azureConfig.BaseURL == "" { - return nil, fmt.Errorf("Azure OpenAI Base URL not provided. Use --provider-url flag or AZURE_OPENAI_BASE_URL environment variable") - } - - if config.MaxTokens > 0 { - azureConfig.MaxTokens = &config.MaxTokens - } - - if config.Temperature != nil { - azureConfig.Temperature = config.Temperature - } - - if config.TopP != nil { - azureConfig.TopP = config.TopP - } - - if len(config.StopSequences) > 0 { - azureConfig.Stop = config.StopSequences - } - - // Set HTTP client with TLS config if needed - if config.TLSSkipVerify { - azureConfig.HTTPClient = createHTTPClientWithTLSConfig(true) - } - - return openai.NewCustomChatModel(ctx, azureConfig) -} - -func createAnthropicProvider(ctx context.Context, config *ProviderConfig, modelName string) (model.ToolCallingChatModel, error) { +func createAnthropicProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { apiKey, source, err := auth.GetAnthropicAPIKey(config.ProviderAPIKey) if err != nil { return nil, err } - // Log the source of the API key in debug mode (without revealing the key) if os.Getenv("DEBUG") != "" || os.Getenv("MCPHOST_DEBUG") != "" { fmt.Fprintf(os.Stderr, "Using Anthropic API key from: %s\n", source) } - // Model alias resolution is handled in CreateProvider + var opts []anthropic.Option + opts = append(opts, anthropic.WithAPIKey(apiKey)) - maxTokens := config.MaxTokens - if maxTokens == 0 { - maxTokens = 4096 // Default value - } - - claudeConfig := &einoclaude.Config{ - Model: modelName, - MaxTokens: maxTokens, + if config.ProviderURL != "" { + opts = append(opts, anthropic.WithBaseURL(config.ProviderURL)) } // Handle OAuth vs API key authentication if strings.HasPrefix(source, "stored OAuth") { - // For OAuth tokens, we need to use Authorization: Bearer header - // Create a custom HTTP client that adds the proper headers - claudeConfig.HTTPClient = createOAuthHTTPClient(apiKey, config.TLSSkipVerify) - // Set a dummy API key to prevent the library from failing validation - claudeConfig.APIKey = "oauth-placeholder" - } else { - // For API keys, use the standard x-api-key header - claudeConfig.APIKey = apiKey - // Set HTTP client with TLS config if needed - if config.TLSSkipVerify { - claudeConfig.HTTPClient = createHTTPClientWithTLSConfig(true) - } + httpClient := createOAuthHTTPClient(apiKey, config.TLSSkipVerify) + opts = append(opts, anthropic.WithHTTPClient(httpClient)) + // Note: For OAuth, the API key is set as a placeholder; the transport handles auth + } else if config.TLSSkipVerify { + opts = append(opts, anthropic.WithHTTPClient(createHTTPClientWithTLSConfig(true))) } - if config.ProviderURL != "" { - claudeConfig.BaseURL = &config.ProviderURL + provider, err := anthropic.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create Anthropic provider: %w", err) } - if config.Temperature != nil { - claudeConfig.Temperature = config.Temperature + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create Anthropic model: %w", err) } - if config.TopP != nil && *config.TopP != 0.95 { - claudeConfig.TopP = config.TopP - } - - if config.TopK != nil { - claudeConfig.TopK = config.TopK - } - - if len(config.StopSequences) > 0 { - claudeConfig.StopSequences = config.StopSequences - } - - return anthropic.NewCustomChatModel(ctx, claudeConfig) + return &ProviderResult{Model: model}, nil } -func createVertexAnthropicProvider(ctx context.Context, config *ProviderConfig, modelName string) (model.ToolCallingChatModel, error) { - projectID := os.Getenv("GOOGLE_VERTEX_PROJECT") - if projectID == "" { - projectID = os.Getenv("ANTHROPIC_VERTEX_PROJECT_ID") - } - if projectID == "" { - projectID = os.Getenv("GOOGLE_CLOUD_PROJECT") - } - if projectID == "" { - projectID = os.Getenv("GCLOUD_PROJECT") - } - if projectID == "" { - projectID = os.Getenv("CLOUDSDK_CORE_PROJECT") - } +func createVertexAnthropicProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { + projectID := firstNonEmpty( + os.Getenv("GOOGLE_VERTEX_PROJECT"), + os.Getenv("ANTHROPIC_VERTEX_PROJECT_ID"), + os.Getenv("GOOGLE_CLOUD_PROJECT"), + os.Getenv("GCLOUD_PROJECT"), + os.Getenv("CLOUDSDK_CORE_PROJECT"), + ) if projectID == "" { return nil, fmt.Errorf("Google Vertex project ID not provided. Set ANTHROPIC_VERTEX_PROJECT_ID, GOOGLE_CLOUD_PROJECT, or GCLOUD_PROJECT environment variable") } - region := os.Getenv("GOOGLE_VERTEX_LOCATION") - if region == "" { - region = os.Getenv("ANTHROPIC_VERTEX_REGION") - } - if region == "" { - region = os.Getenv("CLOUD_ML_REGION") - } + region := firstNonEmpty( + os.Getenv("GOOGLE_VERTEX_LOCATION"), + os.Getenv("ANTHROPIC_VERTEX_REGION"), + os.Getenv("CLOUD_ML_REGION"), + ) if region == "" { region = "global" } - maxTokens := config.MaxTokens - if maxTokens == 0 { - maxTokens = 4096 // Default value + var opts []anthropic.Option + opts = append(opts, anthropic.WithVertex(projectID, region)) + + provider, err := anthropic.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create Vertex Anthropic provider: %w", err) } - claudeConfig := &einoclaude.Config{ - ByVertex: true, - VertexProjectID: projectID, - VertexRegion: region, - Model: modelName, - MaxTokens: maxTokens, + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create Vertex Anthropic model: %w", err) } - if config.Temperature != nil { - claudeConfig.Temperature = config.Temperature - } - - if config.TopP != nil { - claudeConfig.TopP = config.TopP - } - - if config.TopK != nil { - claudeConfig.TopK = config.TopK - } - - if len(config.StopSequences) > 0 { - claudeConfig.StopSequences = config.StopSequences - } - - return anthropic.NewCustomChatModel(ctx, claudeConfig) + return &ProviderResult{Model: model}, nil } -func createOpenAIProvider(ctx context.Context, config *ProviderConfig, modelName string) (model.ToolCallingChatModel, error) { +func createOpenAIProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { apiKey := config.ProviderAPIKey if apiKey == "" { apiKey = os.Getenv("OPENAI_API_KEY") @@ -425,131 +244,197 @@ func createOpenAIProvider(ctx context.Context, config *ProviderConfig, modelName return nil, fmt.Errorf("OpenAI API key not provided. Use --provider-api-key flag or OPENAI_API_KEY environment variable") } - openaiConfig := &einoopenai.ChatModelConfig{ - APIKey: apiKey, - Model: modelName, - } + var opts []openai.Option + opts = append(opts, openai.WithAPIKey(apiKey)) if config.ProviderURL != "" { - openaiConfig.BaseURL = config.ProviderURL + opts = append(opts, openai.WithBaseURL(config.ProviderURL)) } - // Set HTTP client with TLS config if needed if config.TLSSkipVerify { - openaiConfig.HTTPClient = createHTTPClientWithTLSConfig(true) + opts = append(opts, openai.WithHTTPClient(createHTTPClientWithTLSConfig(true))) } - // Check if this is a reasoning model to handle beta limitations (skip validation if using custom URL) - registry := GetGlobalRegistry() - isReasoningModel := false - if config.ProviderURL == "" { - if modelInfo, err := registry.ValidateModel("openai", modelName); err == nil && modelInfo.Reasoning { - isReasoningModel = true - } + provider, err := openai.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create OpenAI provider: %w", err) } - if config.MaxTokens > 0 { - if isReasoningModel { - // For reasoning models, use MaxCompletionTokens instead of MaxTokens - if openaiConfig.ExtraFields == nil { - openaiConfig.ExtraFields = make(map[string]any) - } - openaiConfig.ExtraFields["max_completion_tokens"] = config.MaxTokens - } else { - // For non-reasoning models, use MaxTokens as usual - openaiConfig.MaxTokens = &config.MaxTokens - } + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create OpenAI model: %w", err) } - // For reasoning models, skip temperature and top_p due to beta limitations - if !isReasoningModel { - if config.Temperature != nil { - openaiConfig.Temperature = config.Temperature - } - - if config.TopP != nil { - openaiConfig.TopP = config.TopP - } - } - - if len(config.StopSequences) > 0 { - openaiConfig.Stop = config.StopSequences - } - - return openai.NewCustomChatModel(ctx, openaiConfig) + return &ProviderResult{Model: model}, nil } -func createGoogleProvider(ctx context.Context, config *ProviderConfig, modelName string) (model.ToolCallingChatModel, error) { - apiKey := config.ProviderAPIKey - if apiKey == "" { - apiKey = os.Getenv("GOOGLE_API_KEY") - } - if apiKey == "" { - apiKey = os.Getenv("GEMINI_API_KEY") - } - if apiKey == "" { - apiKey = os.Getenv("GOOGLE_GENERATIVE_AI_API_KEY") - } +func createGoogleProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { + apiKey := firstNonEmpty( + config.ProviderAPIKey, + os.Getenv("GOOGLE_API_KEY"), + os.Getenv("GEMINI_API_KEY"), + os.Getenv("GOOGLE_GENERATIVE_AI_API_KEY"), + ) if apiKey == "" { return nil, fmt.Errorf("Google API key not provided. Use --provider-api-key flag or GOOGLE_API_KEY/GEMINI_API_KEY/GOOGLE_GENERATIVE_AI_API_KEY environment variable") } - clientConfig := &genai.ClientConfig{ - APIKey: apiKey, - Backend: genai.BackendGeminiAPI, - } + var opts []google.Option + opts = append(opts, google.WithGeminiAPIKey(apiKey)) - // Set HTTP client with TLS config if needed - if config.TLSSkipVerify { - clientConfig.HTTPClient = createHTTPClientWithTLSConfig(true) - } - - client, err := genai.NewClient(ctx, clientConfig) + provider, err := google.New(opts...) if err != nil { - return nil, fmt.Errorf("failed to create Google client: %v", err) + return nil, fmt.Errorf("failed to create Google provider: %w", err) } - geminiConfig := &gemini.Config{ - Client: client, - Model: modelName, + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create Google model: %w", err) } - if config.MaxTokens > 0 { - geminiConfig.MaxTokens = &config.MaxTokens + return &ProviderResult{Model: model}, nil +} + +func createAzureProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { + apiKey := config.ProviderAPIKey + if apiKey == "" { + apiKey = os.Getenv("AZURE_OPENAI_API_KEY") + } + if apiKey == "" { + return nil, fmt.Errorf("Azure OpenAI API key not provided. Use --provider-api-key flag or AZURE_OPENAI_API_KEY environment variable") } - if config.Temperature != nil { - geminiConfig.Temperature = config.Temperature + baseURL := config.ProviderURL + if baseURL == "" { + baseURL = os.Getenv("AZURE_OPENAI_BASE_URL") + } + if baseURL == "" { + return nil, fmt.Errorf("Azure OpenAI Base URL not provided. Use --provider-url flag or AZURE_OPENAI_BASE_URL environment variable") } - if config.TopP != nil { - geminiConfig.TopP = config.TopP + var opts []azure.Option + opts = append(opts, azure.WithAPIKey(apiKey)) + opts = append(opts, azure.WithBaseURL(baseURL)) + + if config.TLSSkipVerify { + opts = append(opts, azure.WithHTTPClient(createHTTPClientWithTLSConfig(true))) } - if config.TopK != nil { - geminiConfig.TopK = config.TopK + provider, err := azure.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create Azure OpenAI provider: %w", err) } - return gemini.NewChatModel(ctx, geminiConfig) + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create Azure OpenAI model: %w", err) + } + + return &ProviderResult{Model: model}, nil +} + +func createOpenRouterProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { + apiKey := config.ProviderAPIKey + if apiKey == "" { + apiKey = os.Getenv("OPENROUTER_API_KEY") + } + if apiKey == "" { + return nil, fmt.Errorf("OpenRouter API key not provided. Use --provider-api-key flag or OPENROUTER_API_KEY environment variable") + } + + var opts []openrouter.Option + opts = append(opts, openrouter.WithAPIKey(apiKey)) + + provider, err := openrouter.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create OpenRouter provider: %w", err) + } + + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create OpenRouter model: %w", err) + } + + return &ProviderResult{Model: model}, nil +} + +func createBedrockProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { + var opts []bedrock.Option + + // Bedrock uses AWS SDK default credential chain (env vars, shared config, etc.) + provider, err := bedrock.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create Bedrock provider: %w", err) + } + + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create Bedrock model: %w", err) + } + + return &ProviderResult{Model: model}, nil +} + +func createOllamaProvider(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { + baseURL := "http://localhost:11434" + if host := os.Getenv("OLLAMA_HOST"); host != "" { + baseURL = host + } + if config.ProviderURL != "" { + baseURL = config.ProviderURL + } + + // Pre-load model with GPU fallback + loadingResult, err := loadOllamaModelWithFallback(ctx, baseURL, modelName, config) + var loadingMessage string + if err != nil { + loadingMessage = "" + } else { + loadingMessage = loadingResult.Message + } + + // Use openaicompat provider pointed at Ollama's OpenAI-compatible endpoint + ollamaAPIBase := strings.TrimRight(baseURL, "/") + "/v1" + + var opts []openaicompat.Option + opts = append(opts, openaicompat.WithBaseURL(ollamaAPIBase)) + opts = append(opts, openaicompat.WithName("ollama")) + + if config.ProviderAPIKey != "" { + opts = append(opts, openaicompat.WithAPIKey(config.ProviderAPIKey)) + } else { + // Ollama doesn't require an API key, but the openaicompat provider might need one + opts = append(opts, openaicompat.WithAPIKey("ollama")) + } + + if config.TLSSkipVerify { + opts = append(opts, openaicompat.WithHTTPClient(createHTTPClientWithTLSConfig(true))) + } + + provider, err := openaicompat.New(opts...) + if err != nil { + return nil, fmt.Errorf("failed to create Ollama provider: %w", err) + } + + model, err := provider.LanguageModel(ctx, modelName) + if err != nil { + return nil, fmt.Errorf("failed to create Ollama model: %w", err) + } + + return &ProviderResult{ + Model: model, + Message: loadingMessage, + }, nil } // OllamaLoadingResult contains the result of model loading with actual settings used. -// It provides information about how the model was loaded, including any fallback -// behavior that occurred during initialization. type OllamaLoadingResult struct { - // Options contains the actual Ollama options used for loading - // May differ from requested options if fallback occurred (e.g., CPU instead of GPU) - Options *ollama.Options - - // Message describes the loading result - // Example: "Model loaded successfully on GPU" or - // "Insufficient GPU memory, falling back to CPU inference" Message string } // loadOllamaModelWithFallback loads an Ollama model with GPU settings and automatic CPU fallback -func loadOllamaModelWithFallback(ctx context.Context, baseURL, modelName string, options *ollama.Options, tlsSkipVerify bool) (*OllamaLoadingResult, error) { - client := createHTTPClientWithTLSConfig(tlsSkipVerify) +func loadOllamaModelWithFallback(ctx context.Context, baseURL, modelName string, config *ProviderConfig) (*OllamaLoadingResult, error) { + client := createHTTPClientWithTLSConfig(config.TLSSkipVerify) // Phase 1: Check if model exists locally if err := checkOllamaModelExists(client, baseURL, modelName); err != nil { @@ -559,21 +444,22 @@ func loadOllamaModelWithFallback(ctx context.Context, baseURL, modelName string, } } - // Phase 3: Load model with GPU settings + // Phase 3: Warmup the model + options := buildOllamaOptions(config) _, err := loadOllamaModelWithOptions(ctx, client, baseURL, modelName, options) if err != nil { // Phase 4: Fallback to CPU if GPU memory insufficient if isGPUMemoryError(err) { - cpuOptions := *options - cpuOptions.NumGPU = 0 + cpuOptions := make(map[string]any) + maps.Copy(cpuOptions, options) + cpuOptions["num_gpu"] = 0 - _, cpuErr := loadOllamaModelWithOptions(ctx, client, baseURL, modelName, &cpuOptions) + _, cpuErr := loadOllamaModelWithOptions(ctx, client, baseURL, modelName, cpuOptions) if cpuErr != nil { return nil, fmt.Errorf("failed to load model on GPU (%v) and CPU fallback failed (%v)", err, cpuErr) } return &OllamaLoadingResult{ - Options: &cpuOptions, Message: "Insufficient GPU memory, falling back to CPU inference", }, nil } @@ -581,12 +467,36 @@ func loadOllamaModelWithFallback(ctx context.Context, baseURL, modelName string, } return &OllamaLoadingResult{ - Options: options, Message: "Model loaded successfully on GPU", }, nil } -// checkOllamaModelExists checks if a model exists locally +func buildOllamaOptions(config *ProviderConfig) map[string]any { + options := make(map[string]any) + if config.Temperature != nil { + options["temperature"] = *config.Temperature + } + if config.TopP != nil { + options["top_p"] = *config.TopP + } + if config.TopK != nil { + options["top_k"] = int(*config.TopK) + } + if len(config.StopSequences) > 0 { + options["stop"] = config.StopSequences + } + if config.MaxTokens > 0 { + options["num_predict"] = config.MaxTokens + } + if config.NumGPU != nil { + options["num_gpu"] = int(*config.NumGPU) + } + if config.MainGPU != nil { + options["main_gpu"] = int(*config.MainGPU) + } + return options +} + func checkOllamaModelExists(client *http.Client, baseURL, modelName string) error { reqBody := map[string]string{"model": modelName} jsonBody, _ := json.Marshal(reqBody) @@ -609,21 +519,17 @@ func checkOllamaModelExists(client *http.Client, baseURL, modelName string) erro if resp.StatusCode != http.StatusOK { return fmt.Errorf("model not found locally") } - return nil } -// pullOllamaModel pulls a model from the registry func pullOllamaModel(ctx context.Context, client *http.Client, baseURL, modelName string) error { return pullOllamaModelWithProgress(ctx, client, baseURL, modelName, true) } -// pullOllamaModelWithProgress pulls a model from the registry with optional progress display func pullOllamaModelWithProgress(ctx context.Context, client *http.Client, baseURL, modelName string, showProgress bool) error { reqBody := map[string]string{"name": modelName} jsonBody, _ := json.Marshal(reqBody) - // Use a longer timeout for pulling models (5 minutes) pullCtx, cancel := context.WithTimeout(ctx, 5*time.Minute) defer cancel() @@ -644,7 +550,6 @@ func pullOllamaModelWithProgress(ctx context.Context, client *http.Client, baseU return fmt.Errorf("failed to pull model (status %d): %s", resp.StatusCode, string(body)) } - // Read the streaming response with optional progress display if showProgress { progressReader := progress.NewProgressReader(resp.Body) defer progressReader.Close() @@ -655,22 +560,20 @@ func pullOllamaModelWithProgress(ctx context.Context, client *http.Client, baseU return err } -// loadOllamaModelWithOptions loads a model with specific options using a warmup request -func loadOllamaModelWithOptions(ctx context.Context, client *http.Client, baseURL, modelName string, options *ollama.Options) (*ollama.Options, error) { - // Create a copy of options for warmup to avoid modifying the original - warmupOptions := *options - warmupOptions.NumPredict = 1 // Limit response length for warmup +func loadOllamaModelWithOptions(ctx context.Context, client *http.Client, baseURL, modelName string, options map[string]any) (map[string]any, error) { + warmupOptions := make(map[string]any) + maps.Copy(warmupOptions, options) + warmupOptions["num_predict"] = 1 - reqBody := map[string]interface{}{ + reqBody := map[string]any{ "model": modelName, "prompt": "Hello", "stream": false, - "options": &warmupOptions, + "options": warmupOptions, } jsonBody, _ := json.Marshal(reqBody) - // Use medium timeout for warmup (30 seconds) warmupCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() @@ -691,7 +594,6 @@ func loadOllamaModelWithOptions(ctx context.Context, client *http.Client, baseUR return nil, fmt.Errorf("warmup request failed (status %d): %s", resp.StatusCode, string(body)) } - // Read response to completion _, err = io.ReadAll(resp.Body) if err != nil { return nil, err @@ -700,7 +602,6 @@ func loadOllamaModelWithOptions(ctx context.Context, client *http.Client, baseUR return options, nil } -// isGPUMemoryError checks if an error indicates insufficient GPU memory func isGPUMemoryError(err error) bool { errStr := strings.ToLower(err.Error()) return strings.Contains(errStr, "out of memory") || @@ -709,114 +610,6 @@ func isGPUMemoryError(err error) bool { strings.Contains(errStr, "gpu memory") } -type bearerTransport struct { - base http.RoundTripper - token string -} - -func (t *bearerTransport) RoundTrip(req *http.Request) (*http.Response, error) { - newReq := req.Clone(req.Context()) - newReq.Header.Set("Authorization", "Bearer "+t.token) - return t.base.RoundTrip(newReq) -} - -func createOllamaProviderWithResult(ctx context.Context, config *ProviderConfig, modelName string) (*ProviderResult, error) { - baseURL := "http://localhost:11434" // Default Ollama URL - - // Check for custom Ollama host from environment - if host := os.Getenv("OLLAMA_HOST"); host != "" { - baseURL = host - } - - // Override with ProviderURL if provided - if config.ProviderURL != "" { - baseURL = config.ProviderURL - } - - // Set up options for Ollama using the ollama.Options struct - options := &ollama.Options{} - - if config.Temperature != nil { - options.Temperature = *config.Temperature - } - - if config.TopP != nil { - options.TopP = *config.TopP - } - - if config.TopK != nil { - options.TopK = int(*config.TopK) - } - - if len(config.StopSequences) > 0 { - options.Stop = config.StopSequences - } - - if config.MaxTokens > 0 { - options.NumPredict = config.MaxTokens - } - - // Set GPU configuration for Ollama - if config.NumGPU != nil { - options.NumGPU = int(*config.NumGPU) - } - - if config.MainGPU != nil { - options.MainGPU = int(*config.MainGPU) - } - - // Create a clean copy of options for the final model - finalOptions := &ollama.Options{} - *finalOptions = *options // Copy all fields - - // Try to pre-load the model with GPU settings and automatic CPU fallback - // If this fails, fall back to the original behavior - loadingResult, err := loadOllamaModelWithFallback(ctx, baseURL, modelName, options, config.TLSSkipVerify) - var loadingMessage string - - if err != nil { - // Pre-loading failed, use original options and no message - loadingMessage = "" - } else { - // Pre-loading succeeded, update GPU settings that worked - finalOptions.NumGPU = loadingResult.Options.NumGPU - finalOptions.MainGPU = loadingResult.Options.MainGPU - loadingMessage = loadingResult.Message - } - - ollamaConfig := &ollama.ChatModelConfig{ - BaseURL: baseURL, - Model: modelName, - Options: finalOptions, - } - - if config.ProviderAPIKey != "" { - transport := http.DefaultTransport - authTransport := &bearerTransport{ - base: transport, - token: config.ProviderAPIKey, - } - ollamaConfig.HTTPClient = &http.Client{ - Transport: authTransport, - } - } - - // Set HTTP client with TLS config if needed - if config.TLSSkipVerify { - ollamaConfig.HTTPClient = createHTTPClientWithTLSConfig(true) - } - - chatModel, err := ollama.NewChatModel(ctx, ollamaConfig) - if err != nil { - return nil, err - } - - return &ProviderResult{ - Model: chatModel, - Message: loadingMessage, - }, nil -} - // createHTTPClientWithTLSConfig creates an HTTP client with optional TLS skip verify func createHTTPClientWithTLSConfig(skipVerify bool) *http.Client { if !skipVerify { @@ -836,7 +629,7 @@ func createHTTPClientWithTLSConfig(skipVerify bool) *http.Client { // createOAuthHTTPClient creates an HTTP client that adds OAuth headers for Anthropic API func createOAuthHTTPClient(accessToken string, skipVerify bool) *http.Client { - var base http.RoundTripper = http.DefaultTransport + var base = http.DefaultTransport if skipVerify { base = &http.Transport{ TLSClientConfig: &tls.Config{ @@ -853,25 +646,18 @@ func createOAuthHTTPClient(accessToken string, skipVerify bool) *http.Client { } } -// oauthTransport is an HTTP transport that adds OAuth headers type oauthTransport struct { accessToken string base http.RoundTripper } func (t *oauthTransport) RoundTrip(req *http.Request) (*http.Response, error) { - // Clone the request to avoid modifying the original newReq := req.Clone(req.Context()) - - // Remove any existing x-api-key header (from the dummy API key) newReq.Header.Del("x-api-key") - - // Add OAuth headers as required by Anthropic's OAuth API newReq.Header.Set("Authorization", "Bearer "+t.accessToken) newReq.Header.Set("anthropic-beta", "oauth-2025-04-20") newReq.Header.Set("anthropic-version", "2023-06-01") - // Inject Claude Code system prompt for /v1/messages endpoint if req.Method == "POST" && strings.Contains(req.URL.Path, "/v1/messages") && req.Body != nil { body, err := io.ReadAll(req.Body) if err == nil { @@ -883,56 +669,53 @@ func (t *oauthTransport) RoundTrip(req *http.Request) (*http.Response, error) { } } - // Use the base transport to make the request return t.base.RoundTrip(newReq) } -// injectClaudeCodePrompt modifies the request body to inject Claude Code system prompt func (t *oauthTransport) injectClaudeCodePrompt(body []byte) ([]byte, error) { - var data map[string]interface{} + var data map[string]any if err := json.Unmarshal(body, &data); err != nil { - return body, nil // Return original if not JSON + return body, nil } - // Check if request has a system prompt systemRaw, hasSystem := data["system"] if !hasSystem { - // No system prompt, inject Claude Code identification data["system"] = ClaudeCodePrompt return json.Marshal(data) } switch system := systemRaw.(type) { case string: - // Handle string system prompt if system == ClaudeCodePrompt { - // Already correct, leave as-is return body, nil } - // Convert to array with Claude Code first - data["system"] = []interface{}{ - map[string]interface{}{"type": "text", "text": ClaudeCodePrompt}, - map[string]interface{}{"type": "text", "text": system}, + data["system"] = []any{ + map[string]any{"type": "text", "text": ClaudeCodePrompt}, + map[string]any{"type": "text", "text": system}, } - - case []interface{}: - // Handle array system prompt + case []any: if len(system) > 0 { - // Check if first element has correct text - if first, ok := system[0].(map[string]interface{}); ok { + if first, ok := system[0].(map[string]any); ok { if text, ok := first["text"].(string); ok && text == ClaudeCodePrompt { - // Already has Claude Code first, return as-is return body, nil } } } - // Prepend Claude Code identification - newSystem := []interface{}{ - map[string]interface{}{"type": "text", "text": ClaudeCodePrompt}, + newSystem := []any{ + map[string]any{"type": "text", "text": ClaudeCodePrompt}, } data["system"] = append(newSystem, system...) } - // Re-marshal the modified data return json.Marshal(data) } + +// firstNonEmpty returns the first non-empty string from the arguments. +func firstNonEmpty(values ...string) string { + for _, v := range values { + if v != "" { + return v + } + } + return "" +} diff --git a/internal/models/registry.go b/internal/models/registry.go index 53f67b1c..40d3d9f9 100644 --- a/internal/models/registry.go +++ b/internal/models/registry.go @@ -1,46 +1,164 @@ -//go:generate go run generate_models.go - package models import ( "fmt" "os" "strings" + + "charm.land/catwalk/pkg/embedded" ) +// ModelInfo represents information about a specific model. +type ModelInfo struct { + ID string + Name string + Attachment bool + Reasoning bool + Temperature bool + Cost Cost + Limit Limit +} + +// Cost represents the pricing information for a model. +type Cost struct { + Input float64 + Output float64 + CacheRead *float64 + CacheWrite *float64 +} + +// Limit represents the context and output limits for a model. +type Limit struct { + Context int + Output int +} + +// ProviderInfo represents information about a model provider. +type ProviderInfo struct { + ID string + Env []string + Name string + Models map[string]ModelInfo +} + +// providerEnvVars maps provider IDs to their required environment variables. +// Catwalk provides APIKey field names but we need the actual env var names. +var providerEnvVars = map[string][]string{ + "anthropic": {"ANTHROPIC_API_KEY"}, + "openai": {"OPENAI_API_KEY"}, + "google": {"GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"}, + "azure": {"AZURE_OPENAI_API_KEY"}, + "openrouter": {"OPENROUTER_API_KEY"}, + "bedrock": {"AWS_ACCESS_KEY_ID"}, + "google-vertex-anthropic": {"GOOGLE_APPLICATION_CREDENTIALS"}, + "ollama": {}, + "mistral": {"MISTRAL_API_KEY"}, + "groq": {"GROQ_API_KEY"}, + "deepseek": {"DEEPSEEK_API_KEY"}, + "xai": {"XAI_API_KEY"}, + "fireworks": {"FIREWORKS_API_KEY"}, + "together": {"TOGETHER_API_KEY"}, + "perplexity": {"PERPLEXITY_API_KEY"}, + "alibaba": {"DASHSCOPE_API_KEY"}, + "cohere": {"COHERE_API_KEY"}, +} + // ModelsRegistry provides validation and information about models. // It maintains a registry of all supported LLM providers and their models, // including capabilities, pricing, and configuration requirements. -// The registry data is generated from models.dev and provides a single -// source of truth for model validation and discovery. +// The registry data comes from the catwalk embedded database. type ModelsRegistry struct { - // providers maps provider IDs to their information and available models providers map[string]ProviderInfo } -// NewModelsRegistry creates a new models registry with static data. -// The registry is populated with model information generated from models.dev, -// providing comprehensive metadata about available models across all supported providers. -// -// Returns: -// - *ModelsRegistry: A new registry instance populated with current model data +// NewModelsRegistry creates a new models registry populated from the catwalk embedded database. func NewModelsRegistry() *ModelsRegistry { return &ModelsRegistry{ - providers: GetModelsData(), + providers: buildFromCatwalk(), + } +} + +// buildFromCatwalk converts catwalk embedded data into our internal format. +func buildFromCatwalk() map[string]ProviderInfo { + providers := make(map[string]ProviderInfo) + + for _, cp := range embedded.GetAll() { + providerID := string(cp.ID) + + modelsMap := make(map[string]ModelInfo, len(cp.Models)) + for _, cm := range cp.Models { + var cacheRead, cacheWrite *float64 + if cm.CostPer1MInCached > 0 { + v := cm.CostPer1MInCached + cacheRead = &v + } + if cm.CostPer1MOutCached > 0 { + v := cm.CostPer1MOutCached + cacheWrite = &v + } + + hasTemperature := true // most models support temperature + if cm.Options.Temperature != nil && *cm.Options.Temperature == 0 { + hasTemperature = false + } + + modelsMap[cm.ID] = ModelInfo{ + ID: cm.ID, + Name: cm.Name, + Attachment: cm.SupportsImages, + Reasoning: cm.CanReason, + Temperature: hasTemperature, + Cost: Cost{ + Input: cm.CostPer1MIn, + Output: cm.CostPer1MOut, + CacheRead: cacheRead, + CacheWrite: cacheWrite, + }, + Limit: Limit{ + Context: int(cm.ContextWindow), + Output: int(cm.DefaultMaxTokens), + }, + } + } + + envVars := providerEnvVars[providerID] + if envVars == nil { + // Derive from the catwalk APIKey field if available + if cp.APIKey != "" { + envVars = []string{cp.APIKey} + } + } + + providers[providerID] = ProviderInfo{ + ID: providerID, + Env: envVars, + Name: cp.Name, + Models: modelsMap, + } + } + + // Ensure providers that mcphost explicitly supports are always present + // even if catwalk doesn't list them (e.g. ollama, google-vertex-anthropic) + ensureProvider(providers, "ollama", "Ollama", nil) + ensureProvider(providers, "google-vertex-anthropic", "Google Vertex (Anthropic)", + providerEnvVars["google-vertex-anthropic"]) + + return providers +} + +// ensureProvider ensures a provider entry exists in the map. +func ensureProvider(providers map[string]ProviderInfo, id, name string, env []string) { + if _, exists := providers[id]; !exists { + providers[id] = ProviderInfo{ + ID: id, + Env: env, + Name: name, + Models: make(map[string]ModelInfo), + } } } // ValidateModel validates if a model exists and returns detailed information. -// It checks whether a specific model is available for a given provider and -// returns comprehensive information about the model's capabilities and limits. -// -// Parameters: -// - provider: The provider ID (e.g., "anthropic", "openai", "google") -// - modelID: The specific model ID (e.g., "claude-3-sonnet-20240620", "gpt-4") -// -// Returns: -// - *ModelInfo: Detailed information about the model including pricing, limits, and capabilities -// - error: Returns an error if the provider is unsupported or model is not found func (r *ModelsRegistry) ValidateModel(provider, modelID string) (*ModelInfo, error) { providerInfo, exists := r.providers[provider] if !exists { @@ -56,20 +174,6 @@ func (r *ModelsRegistry) ValidateModel(provider, modelID string) (*ModelInfo, er } // GetRequiredEnvVars returns the required environment variables for a provider. -// These are the environment variable names that should contain API keys or -// other authentication credentials for the specified provider. -// -// Parameters: -// - provider: The provider ID (e.g., "anthropic", "openai", "google") -// -// Returns: -// - []string: List of environment variable names the provider checks for credentials -// - error: Returns an error if the provider is unsupported -// -// Example: -// -// For "anthropic", returns ["ANTHROPIC_API_KEY"] -// For "google", returns ["GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"] func (r *ModelsRegistry) GetRequiredEnvVars(provider string) ([]string, error) { providerInfo, exists := r.providers[provider] if !exists { @@ -80,28 +184,17 @@ func (r *ModelsRegistry) GetRequiredEnvVars(provider string) ([]string, error) { } // ValidateEnvironment checks if required environment variables are set. -// It verifies that at least one of the provider's required environment variables -// contains an API key, unless an API key is explicitly provided via configuration. -// -// Parameters: -// - provider: The provider ID to validate environment for -// - apiKey: An API key provided via configuration (if empty, checks environment variables) -// -// Returns: -// - error: Returns nil if validation passes, or an error describing missing credentials func (r *ModelsRegistry) ValidateEnvironment(provider string, apiKey string) error { envVars, err := r.GetRequiredEnvVars(provider) if err != nil { return err } - // If API key is provided via config, we don't need to check env vars if apiKey != "" { return nil } // Add alternative environment variable names for google-vertex-anthropic - // These match the env vars checked by eino-claude and other tools if provider == "google-vertex-anthropic" { envVars = append(envVars, "ANTHROPIC_VERTEX_PROJECT_ID", @@ -113,7 +206,6 @@ func (r *ModelsRegistry) ValidateEnvironment(provider string, apiKey string) err ) } - // Check if at least one environment variable is set var foundVar bool for _, envVar := range envVars { if os.Getenv(envVar) != "" { @@ -131,15 +223,6 @@ func (r *ModelsRegistry) ValidateEnvironment(provider string, apiKey string) err } // SuggestModels returns similar model names when an invalid model is provided. -// It helps users discover the correct model ID by finding models that partially -// match the provided input, useful for correcting typos or finding alternatives. -// -// Parameters: -// - provider: The provider ID to search within -// - invalidModel: The invalid or misspelled model name to find suggestions for -// -// Returns: -// - []string: A list of up to 5 suggested model IDs that partially match the input func (r *ModelsRegistry) SuggestModels(provider, invalidModel string) []string { providerInfo, exists := r.providers[provider] if !exists { @@ -149,12 +232,10 @@ func (r *ModelsRegistry) SuggestModels(provider, invalidModel string) []string { var suggestions []string invalidLower := strings.ToLower(invalidModel) - // Look for models that contain parts of the invalid model name for modelID, modelInfo := range providerInfo.Models { modelIDLower := strings.ToLower(modelID) modelNameLower := strings.ToLower(modelInfo.Name) - // Check if the invalid model is a substring of existing models if strings.Contains(modelIDLower, invalidLower) || strings.Contains(modelNameLower, invalidLower) || strings.Contains(invalidLower, strings.ToLower(strings.Split(modelID, "-")[0])) { @@ -162,7 +243,6 @@ func (r *ModelsRegistry) SuggestModels(provider, invalidModel string) []string { } } - // Limit suggestions to avoid overwhelming output if len(suggestions) > 5 { suggestions = suggestions[:5] } @@ -171,11 +251,6 @@ func (r *ModelsRegistry) SuggestModels(provider, invalidModel string) []string { } // GetSupportedProviders returns a list of all supported providers. -// This includes all providers that have models registered in the system, -// such as "anthropic", "openai", "google", "alibaba", etc. -// -// Returns: -// - []string: A list of all provider IDs available in the registry func (r *ModelsRegistry) GetSupportedProviders() []string { var providers []string for providerID := range r.providers { @@ -185,15 +260,6 @@ func (r *ModelsRegistry) GetSupportedProviders() []string { } // GetModelsForProvider returns all models for a specific provider. -// This is useful for listing available models when a user wants to see -// all options for a particular provider. -// -// Parameters: -// - provider: The provider ID to get models for -// -// Returns: -// - map[string]ModelInfo: A map of model IDs to their detailed information -// - error: Returns an error if the provider is unsupported func (r *ModelsRegistry) GetModelsForProvider(provider string) (map[string]ModelInfo, error) { providerInfo, exists := r.providers[provider] if !exists { @@ -207,12 +273,6 @@ func (r *ModelsRegistry) GetModelsForProvider(provider string) (map[string]Model var globalRegistry = NewModelsRegistry() // GetGlobalRegistry returns the global models registry instance. -// This provides a singleton registry that can be accessed throughout -// the application for model validation and information retrieval. -// The registry is initialized once with data from models.dev. -// -// Returns: -// - *ModelsRegistry: The global registry instance func GetGlobalRegistry() *ModelsRegistry { return globalRegistry } diff --git a/internal/session/manager.go b/internal/session/manager.go index 82773327..6c0831e0 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -4,14 +4,12 @@ import ( "fmt" "sync" - "github.com/cloudwego/eino/schema" + "charm.land/fantasy" ) // Manager manages session state and auto-saving functionality. // It provides thread-safe operations for managing a conversation session, // including automatic persistence to disk after each modification. -// The Manager ensures that all session operations are synchronized and -// that the session file is kept up-to-date with any changes. type Manager struct { session *Session filePath string @@ -19,9 +17,6 @@ type Manager struct { } // NewManager creates a new session manager with a fresh session. -// The filePath parameter specifies where the session will be auto-saved. -// If filePath is empty, the session will not be automatically saved to disk. -// Returns a Manager instance ready to track conversation messages. func NewManager(filePath string) *Manager { return &Manager{ session: NewSession(), @@ -30,10 +25,6 @@ func NewManager(filePath string) *Manager { } // NewManagerWithSession creates a new session manager with an existing session. -// This is useful when loading a session from a file and wanting to continue -// managing it with auto-save functionality. -// The session parameter is the existing session to manage. -// The filePath parameter specifies where the session will be auto-saved. func NewManagerWithSession(session *Session, filePath string) *Manager { return &Manager{ session: session, @@ -41,17 +32,12 @@ func NewManagerWithSession(session *Session, filePath string) *Manager { } } -// AddMessage adds a message to the session and auto-saves. -// The message is converted from schema.Message format to the internal -// session Message format before being added. If a filePath was specified -// when creating the Manager, the session is automatically saved to disk. -// This operation is thread-safe. -// Returns an error if auto-saving fails, nil otherwise. -func (m *Manager) AddMessage(msg *schema.Message) error { +// AddMessage adds a fantasy message to the session and auto-saves. +func (m *Manager) AddMessage(msg fantasy.Message) error { m.mutex.Lock() defer m.mutex.Unlock() - sessionMsg := ConvertFromSchemaMessage(msg) + sessionMsg := ConvertFromFantasyMessage(msg) m.session.AddMessage(sessionMsg) if m.filePath != "" { @@ -61,17 +47,13 @@ func (m *Manager) AddMessage(msg *schema.Message) error { return nil } -// AddMessages adds multiple messages to the session and auto-saves. -// All messages are added in order and then the session is saved once. -// This is more efficient than calling AddMessage multiple times when -// adding several messages at once. The operation is thread-safe. -// Returns an error if auto-saving fails, nil otherwise. -func (m *Manager) AddMessages(msgs []*schema.Message) error { +// AddMessages adds multiple fantasy messages to the session and auto-saves. +func (m *Manager) AddMessages(msgs []fantasy.Message) error { m.mutex.Lock() defer m.mutex.Unlock() for _, msg := range msgs { - sessionMsg := ConvertFromSchemaMessage(msg) + sessionMsg := ConvertFromFantasyMessage(msg) m.session.AddMessage(sessionMsg) } @@ -83,12 +65,7 @@ func (m *Manager) AddMessages(msgs []*schema.Message) error { } // ReplaceAllMessages replaces all messages in the session with the provided messages. -// This method completely clears the existing message history and replaces it with -// the new set of messages. Useful for resetting a conversation or loading a -// different conversation context. The operation is thread-safe and triggers -// an auto-save if a filePath is configured. -// Returns an error if auto-saving fails, nil otherwise. -func (m *Manager) ReplaceAllMessages(msgs []*schema.Message) error { +func (m *Manager) ReplaceAllMessages(msgs []fantasy.Message) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -97,7 +74,7 @@ func (m *Manager) ReplaceAllMessages(msgs []*schema.Message) error { // Add all new messages for _, msg := range msgs { - sessionMsg := ConvertFromSchemaMessage(msg) + sessionMsg := ConvertFromFantasyMessage(msg) m.session.AddMessage(sessionMsg) } @@ -109,10 +86,6 @@ func (m *Manager) ReplaceAllMessages(msgs []*schema.Message) error { } // SetMetadata sets the session metadata. -// This updates the session's metadata with information about the provider, -// model, and MCPHost version. The operation is thread-safe and triggers -// an auto-save if a filePath is configured. -// Returns an error if auto-saving fails, nil otherwise. func (m *Manager) SetMetadata(metadata Metadata) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -126,33 +99,24 @@ func (m *Manager) SetMetadata(metadata Metadata) error { return nil } -// GetMessages returns all messages as a schema.Message slice. -// This method converts all stored session messages to the schema format -// used by LLM providers. The returned slice is a new allocation, so -// modifications to it won't affect the stored session. This operation -// is thread-safe for concurrent reads. -func (m *Manager) GetMessages() []*schema.Message { +// GetMessages returns all messages as fantasy.Message slice. +func (m *Manager) GetMessages() []fantasy.Message { m.mutex.RLock() defer m.mutex.RUnlock() - messages := make([]*schema.Message, len(m.session.Messages)) + messages := make([]fantasy.Message, len(m.session.Messages)) for i, msg := range m.session.Messages { - messages[i] = msg.ConvertToSchemaMessage() + messages[i] = msg.ConvertToFantasyMessage() } return messages } // GetSession returns a copy of the current session. -// The returned session is a deep copy, including all messages, so -// modifications to it won't affect the managed session. This is useful -// for safely inspecting the session state without risk of concurrent -// modification. This operation is thread-safe for concurrent reads. func (m *Manager) GetSession() *Session { m.mutex.RLock() defer m.mutex.RUnlock() - // Return a copy to prevent external modification sessionCopy := *m.session sessionCopy.Messages = make([]Message, len(m.session.Messages)) copy(sessionCopy.Messages, m.session.Messages) @@ -161,10 +125,6 @@ func (m *Manager) GetSession() *Session { } // Save manually saves the session to file. -// This forces a save operation even if no changes have been made. -// Useful for ensuring the session is persisted at specific points. -// Returns an error if no filePath was specified when creating the -// Manager, or if the save operation fails. func (m *Manager) Save() error { m.mutex.RLock() defer m.mutex.RUnlock() @@ -177,15 +137,11 @@ func (m *Manager) Save() error { } // GetFilePath returns the file path for this session. -// Returns the path where the session is being auto-saved, or an -// empty string if no auto-save path was configured. func (m *Manager) GetFilePath() string { return m.filePath } // MessageCount returns the number of messages in the session. -// This provides a quick way to check the conversation length without -// retrieving all messages. This operation is thread-safe for concurrent reads. func (m *Manager) MessageCount() int { m.mutex.RLock() defer m.mutex.RUnlock() diff --git a/internal/session/session.go b/internal/session/session.go index 580160ef..2da297fa 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -8,7 +8,7 @@ import ( "os" "time" - "github.com/cloudwego/eino/schema" + "charm.land/fantasy" ) // Session represents a complete conversation session with metadata. @@ -30,9 +30,7 @@ type Session struct { } // Metadata contains session metadata that provides context about the -// environment and configuration used during the conversation. This helps -// with debugging and understanding the session's context when reviewing -// conversation history. +// environment and configuration used during the conversation. type Metadata struct { // MCPHostVersion is the version of MCPHost used for this session MCPHostVersion string `json:"mcphost_version"` @@ -61,8 +59,6 @@ type Message struct { } // ToolCall represents a tool invocation within an assistant message. -// When the assistant decides to use a tool, it creates a ToolCall with -// the necessary information to execute that tool. type ToolCall struct { // ID is a unique identifier for this tool call, used to link results ID string `json:"id"` @@ -73,9 +69,6 @@ type ToolCall struct { } // NewSession creates a new session with default values. -// It initializes a session with version 1.0, current timestamps, -// empty message list, and empty metadata. The returned session -// is ready to receive messages and can be saved to a file. func NewSession() *Session { return &Session{ Version: "1.0", @@ -87,9 +80,6 @@ func NewSession() *Session { } // AddMessage adds a message to the session. -// If the message doesn't have an ID, one will be auto-generated. -// If the message doesn't have a timestamp, the current time will be used. -// The session's UpdatedAt timestamp is automatically updated. func (s *Session) AddMessage(msg Message) { if msg.ID == "" { msg.ID = generateMessageID() @@ -103,20 +93,12 @@ func (s *Session) AddMessage(msg Message) { } // SetMetadata sets the session metadata. -// This replaces the existing metadata with the provided metadata -// and updates the session's UpdatedAt timestamp. Use this to record -// information about the provider, model, and MCPHost version. func (s *Session) SetMetadata(metadata Metadata) { s.Metadata = metadata s.UpdatedAt = time.Now() } // SaveToFile saves the session to a JSON file. -// The session is serialized as indented JSON for readability. -// The UpdatedAt timestamp is automatically updated before saving. -// The file is created with 0644 permissions if it doesn't exist, -// or overwritten if it does exist. -// Returns an error if marshaling fails or file writing fails. func (s *Session) SaveToFile(filePath string) error { s.UpdatedAt = time.Now() @@ -129,11 +111,6 @@ func (s *Session) SaveToFile(filePath string) error { } // LoadFromFile loads a session from a JSON file. -// It reads the file at the specified path and deserializes it into -// a Session struct. This is useful for resuming previous conversations -// or reviewing session history. -// Returns the loaded session on success, or an error if the file -// cannot be read or the JSON is invalid. func LoadFromFile(filePath string) (*Session, error) { data, err := os.ReadFile(filePath) if err != nil { @@ -148,85 +125,102 @@ func LoadFromFile(filePath string) (*Session, error) { return &session, nil } -// ConvertFromSchemaMessage converts a schema.Message to a session Message. -// This function bridges between the eino schema message format and the -// session's internal message format. It preserves role, content, and -// tool-related information while adding a timestamp. -// Tool calls from assistant messages and tool call IDs from tool messages -// are properly converted and preserved. -func ConvertFromSchemaMessage(msg *schema.Message) Message { +// ConvertFromFantasyMessage converts a fantasy.Message to a session Message. +// This function bridges between the fantasy message format and the +// session's internal message format for JSON persistence. +func ConvertFromFantasyMessage(msg fantasy.Message) Message { sessionMsg := Message{ Role: string(msg.Role), - Content: msg.Content, Timestamp: time.Now(), } - // Convert tool calls if present (for assistant messages) - if len(msg.ToolCalls) > 0 { - sessionMsg.ToolCalls = make([]ToolCall, len(msg.ToolCalls)) - for i, tc := range msg.ToolCalls { - sessionMsg.ToolCalls[i] = ToolCall{ - ID: tc.ID, - Name: tc.Function.Name, - Arguments: tc.Function.Arguments, + // Extract text content and tool calls from message parts + var textParts []string + for _, part := range msg.Content { + switch p := part.(type) { + case fantasy.TextPart: + textParts = append(textParts, p.Text) + case fantasy.ToolCallPart: + sessionMsg.ToolCalls = append(sessionMsg.ToolCalls, ToolCall{ + ID: p.ToolCallID, + Name: p.ToolName, + Arguments: p.Input, + }) + case fantasy.ToolResultPart: + // Tool result messages — store the tool call ID + sessionMsg.ToolCallID = p.ToolCallID + // Marshal result for storage + if p.Output != nil { + if resultBytes, err := json.Marshal(p.Output); err == nil { + textParts = append(textParts, string(resultBytes)) + } } } } - // Handle tool result messages - extract tool call ID from ToolCallID field - if msg.Role == schema.Tool && msg.ToolCallID != "" { - sessionMsg.ToolCallID = msg.ToolCallID + // Join all text parts + for i, t := range textParts { + if i > 0 { + sessionMsg.Content += "\n" + } + sessionMsg.Content += t } return sessionMsg } -// ConvertToSchemaMessage converts a session Message to a schema.Message. +// ConvertToFantasyMessage converts a session Message to a fantasy.Message. // This method bridges between the session's internal message format and -// the eino schema message format used by the LLM providers. -// It properly handles tool calls for assistant messages and tool call IDs -// for tool result messages. Arguments are converted to string format as -// required by the schema. -func (m *Message) ConvertToSchemaMessage() *schema.Message { - msg := &schema.Message{ - Role: schema.RoleType(m.Role), - Content: m.Content, +// the fantasy message format used by the LLM providers. +func (m *Message) ConvertToFantasyMessage() fantasy.Message { + msg := fantasy.Message{ + Role: fantasy.MessageRole(m.Role), } - // Convert tool calls if present (for assistant messages) - if len(m.ToolCalls) > 0 { - msg.ToolCalls = make([]schema.ToolCall, len(m.ToolCalls)) - for i, tc := range m.ToolCalls { - // Arguments are already stored as a string, use them directly - var argsStr string - if str, ok := tc.Arguments.(string); ok { - argsStr = str - } else { - // Fallback: marshal to JSON if not a string - if argBytes, err := json.Marshal(tc.Arguments); err == nil { - argsStr = string(argBytes) - } - } - - msg.ToolCalls[i] = schema.ToolCall{ - ID: tc.ID, - Function: schema.FunctionCall{ - Name: tc.Name, - Arguments: argsStr, - }, - } + // Build content parts based on role + switch m.Role { + case "assistant": + // Add text content if present + if m.Content != "" { + msg.Content = append(msg.Content, fantasy.TextPart{Text: m.Content}) } - } + // Add tool calls if present + for _, tc := range m.ToolCalls { + var inputStr string + if str, ok := tc.Arguments.(string); ok { + inputStr = str + } else if argBytes, err := json.Marshal(tc.Arguments); err == nil { + inputStr = string(argBytes) + } - // Handle tool result messages - set the tool call ID - if m.Role == "tool" && m.ToolCallID != "" { - msg.ToolCallID = m.ToolCallID + msg.Content = append(msg.Content, fantasy.ToolCallPart{ + ToolCallID: tc.ID, + ToolName: tc.Name, + Input: inputStr, + }) + } + case "tool": + // Tool result message + msg.Role = fantasy.MessageRoleTool + var resultContent fantasy.ToolResultOutputContent + resultContent = fantasy.ToolResultOutputContentText{Text: m.Content} + + msg.Content = append(msg.Content, fantasy.ToolResultPart{ + ToolCallID: m.ToolCallID, + Output: resultContent, + }) + case "user": + msg.Content = append(msg.Content, fantasy.TextPart{Text: m.Content}) + case "system": + msg.Content = append(msg.Content, fantasy.TextPart{Text: m.Content}) + default: + msg.Content = append(msg.Content, fantasy.TextPart{Text: m.Content}) } return msg } -// generateMessageID generates a unique message ID +// generateMessageID generates a unique message ID. func generateMessageID() string { bytes := make([]byte, 8) rand.Read(bytes) diff --git a/internal/tools/connection_pool.go b/internal/tools/connection_pool.go index caab7f7d..2a3109d4 100644 --- a/internal/tools/connection_pool.go +++ b/internal/tools/connection_pool.go @@ -3,11 +3,12 @@ package tools import ( "context" "fmt" + "maps" "strings" "sync" "time" - "github.com/cloudwego/eino/components/model" + "charm.land/fantasy" "github.com/mark3labs/mcp-go/client" "github.com/mark3labs/mcp-go/client/transport" "github.com/mark3labs/mcp-go/mcp" @@ -63,7 +64,7 @@ type MCPConnectionPool struct { connections map[string]*MCPConnection config *ConnectionPoolConfig mu sync.RWMutex - model model.ToolCallingChatModel + model fantasy.LanguageModel ctx context.Context cancel context.CancelFunc debug bool @@ -75,7 +76,7 @@ type MCPConnectionPool struct { // goroutine for periodic health checks that runs until Close is called. // The model parameter is used for MCP servers that require sampling support. // Thread-safe for concurrent use immediately after creation. -func NewMCPConnectionPool(config *ConnectionPoolConfig, model model.ToolCallingChatModel, debug bool) *MCPConnectionPool { +func NewMCPConnectionPool(config *ConnectionPoolConfig, model fantasy.LanguageModel, debug bool) *MCPConnectionPool { if config == nil { config = DefaultConnectionPoolConfig() } @@ -406,7 +407,7 @@ func (p *MCPConnectionPool) initializeClient(ctx context.Context, client client. } if p.debugLogger != nil && p.debugLogger.IsDebugEnabled() { - p.debugLogger.LogDebug(fmt.Sprintf("[POOL] Initialized MCP client")) + p.debugLogger.LogDebug("[POOL] Initialized MCP client") } return nil } @@ -430,9 +431,7 @@ func (p *MCPConnectionPool) startHealthCheck() { func (p *MCPConnectionPool) checkConnectionsHealth() { p.mu.RLock() connections := make(map[string]*MCPConnection) - for k, v := range p.connections { - connections[k] = v - } + maps.Copy(connections, p.connections) p.mu.RUnlock() for serverName, conn := range connections { @@ -494,14 +493,14 @@ func (p *MCPConnectionPool) HandleConnectionError(serverName string, err error) // The returned map includes health status, last usage time, error counts, and // last error for each connection. Useful for monitoring and debugging connection // pool behavior. The returned data is a snapshot and safe for concurrent access. -func (p *MCPConnectionPool) GetConnectionStats() map[string]interface{} { +func (p *MCPConnectionPool) GetConnectionStats() map[string]any { p.mu.RLock() defer p.mu.RUnlock() - stats := make(map[string]interface{}) + stats := make(map[string]any) for serverName, conn := range p.connections { conn.mu.RLock() - stats[serverName] = map[string]interface{}{ + stats[serverName] = map[string]any{ "is_healthy": conn.isHealthy, "last_used": conn.lastUsed, "last_error": conn.lastError, diff --git a/internal/tools/fantasy_adapter.go b/internal/tools/fantasy_adapter.go new file mode 100644 index 00000000..2a2ee5fb --- /dev/null +++ b/internal/tools/fantasy_adapter.go @@ -0,0 +1,92 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + + "charm.land/fantasy" + "github.com/mark3labs/mcp-go/mcp" +) + +// mcpFantasyTool adapts an MCP tool to the fantasy.AgentTool interface. +// It bridges the MCP tool protocol with fantasy's agent tool system, handling +// name prefixing, schema conversion, connection pooling, and result marshaling. +type mcpFantasyTool struct { + toolInfo fantasy.ToolInfo + mapping *toolMapping + providerOptions fantasy.ProviderOptions +} + +// Info returns the fantasy tool info including name, description, and parameter schema. +func (t *mcpFantasyTool) Info() fantasy.ToolInfo { + return t.toolInfo +} + +// Run executes the MCP tool by routing through the connection pool. +// It maps the prefixed tool name back to the original name, retrieves a healthy +// connection, invokes the tool, and converts the MCP result to a fantasy ToolResponse. +func (t *mcpFantasyTool) Run(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) { + // Parse and validate JSON arguments + var arguments any + input := call.Input + if input == "" || input == "{}" { + arguments = nil + } else { + var temp any + if err := json.Unmarshal([]byte(input), &temp); err != nil { + return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid JSON arguments: %v", err)), nil + } + arguments = json.RawMessage(input) + } + + // Get connection from pool with health check + conn, err := t.mapping.manager.connectionPool.GetConnectionWithHealthCheck( + ctx, t.mapping.serverName, t.mapping.serverConfig, + ) + if err != nil { + return fantasy.ToolResponse{}, fmt.Errorf("failed to get healthy connection from pool: %w", err) + } + + // Call the MCP tool using the original (unprefixed) name + result, err := conn.client.CallTool(ctx, mcp.CallToolRequest{ + Request: mcp.Request{ + Method: "tools/call", + }, + Params: struct { + Name string `json:"name"` + Arguments any `json:"arguments,omitempty"` + Meta *mcp.Meta `json:"_meta,omitempty"` + }{ + Name: t.mapping.originalName, + Arguments: arguments, + }, + }) + if err != nil { + // Mark connection as unhealthy for automatic recovery + t.mapping.manager.connectionPool.HandleConnectionError(t.mapping.serverName, err) + return fantasy.ToolResponse{}, fmt.Errorf("failed to call mcp tool: %w", err) + } + + // Marshal the MCP result to JSON string + marshaledResult, err := json.Marshal(result) + if err != nil { + return fantasy.ToolResponse{}, fmt.Errorf("failed to marshal mcp tool result: %w", err) + } + + // Return as text response, preserving error status from MCP + if result.IsError { + return fantasy.NewTextErrorResponse(string(marshaledResult)), nil + } + return fantasy.NewTextResponse(string(marshaledResult)), nil +} + +// ProviderOptions returns provider-specific options for this tool. +func (t *mcpFantasyTool) ProviderOptions() fantasy.ProviderOptions { + return t.providerOptions +} + +// SetProviderOptions sets provider-specific options for this tool. +func (t *mcpFantasyTool) SetProviderOptions(opts fantasy.ProviderOptions) { + t.providerOptions = opts +} diff --git a/internal/tools/mcp.go b/internal/tools/mcp.go index 9a0e2c73..c244b1e2 100644 --- a/internal/tools/mcp.go +++ b/internal/tools/mcp.go @@ -4,14 +4,11 @@ import ( "context" "encoding/json" "fmt" + "slices" "strings" "time" - "github.com/bytedance/sonic" - "github.com/cloudwego/eino/components/model" - "github.com/cloudwego/eino/components/tool" - "github.com/cloudwego/eino/schema" - "github.com/eino-contrib/jsonschema" + "charm.land/fantasy" "github.com/mark3labs/mcp-go/client" "github.com/mark3labs/mcp-go/client/transport" "github.com/mark3labs/mcp-go/mcp" @@ -26,9 +23,9 @@ import ( // Thread-safe for concurrent tool invocations. type MCPToolManager struct { connectionPool *MCPConnectionPool - tools []tool.BaseTool - toolMap map[string]*toolMapping // maps prefixed tool names to their server and original name - model model.ToolCallingChatModel // LLM model for sampling + tools []fantasy.AgentTool + toolMap map[string]*toolMapping // maps prefixed tool names to their server and original name + model fantasy.LanguageModel // LLM model for sampling config *config.Config debug bool debugLogger DebugLogger @@ -42,18 +39,12 @@ type toolMapping struct { manager *MCPToolManager } -// mcpToolImpl implements the eino tool interface with server prefixing -type mcpToolImpl struct { - info *schema.ToolInfo - mapping *toolMapping -} - // NewMCPToolManager creates a new MCP tool manager instance. // Returns an initialized manager with empty tool collections ready to load tools from MCP servers. // The manager must be configured with SetModel and LoadTools before use. func NewMCPToolManager() *MCPToolManager { return &MCPToolManager{ - tools: make([]tool.BaseTool, 0), + tools: make([]fantasy.AgentTool, 0), toolMap: make(map[string]*toolMapping), } } @@ -62,7 +53,7 @@ func NewMCPToolManager() *MCPToolManager { // The model is used when MCP servers request sampling operations, allowing them to // leverage the host's LLM capabilities for text generation tasks. // This method should be called before LoadTools if any MCP servers require sampling support. -func (m *MCPToolManager) SetModel(model model.ToolCallingChatModel) { +func (m *MCPToolManager) SetModel(model fantasy.LanguageModel) { m.model = model } @@ -77,13 +68,13 @@ func (m *MCPToolManager) SetDebugLogger(logger DebugLogger) { } } -// samplingHandler implements the MCP sampling handler interface +// samplingHandler implements the MCP sampling handler interface using a fantasy LanguageModel type samplingHandler struct { - model model.ToolCallingChatModel + model fantasy.LanguageModel } // CreateMessage handles sampling requests from MCP servers by forwarding them to the configured LLM model. -// It converts MCP message formats to eino message formats, invokes the model for generation, +// It converts MCP message formats to fantasy message formats, invokes the model for generation, // and converts the response back to MCP format. Returns an error if no model is available // or if generation fails. func (h *samplingHandler) CreateMessage(ctx context.Context, request mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error) { @@ -91,17 +82,16 @@ func (h *samplingHandler) CreateMessage(ctx context.Context, request mcp.CreateM return nil, fmt.Errorf("no model available for sampling") } - // Convert MCP messages to eino messages - var messages []*schema.Message + // Build fantasy messages from MCP sampling request + var messages []fantasy.Message // Add system message if provided if request.SystemPrompt != "" { - messages = append(messages, schema.SystemMessage(request.SystemPrompt)) + messages = append(messages, fantasy.NewSystemMessage(request.SystemPrompt)) } // Convert sampling messages for _, msg := range request.Messages { - // Extract text content var content string if textContent, ok := msg.Content.(mcp.TextContent); ok { content = textContent.Text @@ -111,30 +101,36 @@ func (h *samplingHandler) CreateMessage(ctx context.Context, request mcp.CreateM switch msg.Role { case mcp.RoleUser: - messages = append(messages, schema.UserMessage(content)) + messages = append(messages, fantasy.NewUserMessage(content)) case mcp.RoleAssistant: - messages = append(messages, schema.AssistantMessage(content, nil)) + messages = append(messages, fantasy.Message{ + Role: fantasy.MessageRoleAssistant, + Content: []fantasy.MessagePart{fantasy.TextPart{Text: content}}, + }) default: - messages = append(messages, schema.UserMessage(content)) // Default to user + messages = append(messages, fantasy.NewUserMessage(content)) } } - // Generate response using the model (no config options for now) - response, err := h.model.Generate(ctx, messages) + // Generate response using the fantasy model + call := fantasy.Call{ + Prompt: fantasy.Prompt(messages), + } + response, err := h.model.Generate(ctx, call) if err != nil { return nil, fmt.Errorf("model generation failed: %w", err) } // Convert response back to MCP format result := &mcp.CreateMessageResult{ - Model: "mcphost-model", // Generic model name + Model: h.model.Model(), StopReason: "endTurn", } result.SamplingMessage = mcp.SamplingMessage{ Role: mcp.RoleAssistant, Content: mcp.TextContent{ Type: "text", - Text: response.Content, + Text: response.Content.Text(), }, } @@ -202,7 +198,7 @@ func (m *MCPToolManager) loadServerTools(ctx context.Context, serverName string, } } - // Convert MCP tools to eino tools with prefixed names + // Convert MCP tools to fantasy AgentTools with prefixed names for _, mcpTool := range listResults.Tools { // Filter tools based on allowedTools/excludedTools if len(serverConfig.AllowedTools) > 0 { @@ -216,29 +212,40 @@ func (m *MCPToolManager) loadServerTools(ctx context.Context, serverName string, continue } - // Convert schema - marshaledInputSchema, err := sonic.Marshal(mcpTool.InputSchema) + // Convert MCP InputSchema to map[string]any for fantasy ToolInfo + marshaledSchema, err := json.Marshal(mcpTool.InputSchema) if err != nil { return fmt.Errorf("conv mcp tool input schema fail(marshal): %w, tool name: %s", err, mcpTool.Name) } - // Fix for JSON Schema draft-07 vs draft-04 compatibility: - // Chrome DevTools MCP uses draft-07 where exclusiveMinimum/exclusiveMaximum are numbers, - // but kin-openapi (OpenAPI 3.0) expects them as booleans (draft-04 format). - // Pre-process the schema to convert numeric exclusive bounds to boolean format. - marshaledInputSchema = convertExclusiveBoundsToBoolean(marshaledInputSchema) + // Fix for JSON Schema draft-07 vs draft-04 compatibility + marshaledSchema = convertExclusiveBoundsToBoolean(marshaledSchema) - inputSchema := &jsonschema.Schema{} - err = sonic.Unmarshal(marshaledInputSchema, inputSchema) - if err != nil { + // Parse into map[string]any for fantasy's parameters format + var schemaMap map[string]any + if err := json.Unmarshal(marshaledSchema, &schemaMap); err != nil { return fmt.Errorf("conv mcp tool input schema fail(unmarshal): %w, tool name: %s", err, mcpTool.Name) } + // Extract properties and required from the schema + parameters := make(map[string]any) + var required []string + + if props, ok := schemaMap["properties"].(map[string]any); ok { + parameters = props + } + // Fix for issue #89: Ensure object schemas have a properties field - // OpenAI function calling requires object schemas to have a "properties" field - // even if it's empty, otherwise it throws "object schema missing properties" error - if inputSchema.Type == "object" && inputSchema.Properties == nil { - inputSchema.Properties = jsonschema.NewProperties() + if schemaType, ok := schemaMap["type"].(string); ok && schemaType == "object" && len(parameters) == 0 { + // Keep empty parameters map - fantasy handles this fine + } + + if req, ok := schemaMap["required"].([]any); ok { + for _, r := range req { + if s, ok := r.(string); ok { + required = append(required, s) + } + } } // Create prefixed tool name @@ -253,89 +260,26 @@ func (m *MCPToolManager) loadServerTools(ctx context.Context, serverName string, } m.toolMap[prefixedName] = mapping - // Create eino tool - einoTool := &mcpToolImpl{ - info: &schema.ToolInfo{ + // Create fantasy AgentTool + fantasyTool := &mcpFantasyTool{ + toolInfo: fantasy.ToolInfo{ Name: prefixedName, - Desc: mcpTool.Description, - ParamsOneOf: schema.NewParamsOneOfByJSONSchema(inputSchema), + Description: mcpTool.Description, + Parameters: parameters, + Required: required, }, mapping: mapping, } - m.tools = append(m.tools, einoTool) + m.tools = append(m.tools, fantasyTool) } return nil } -// Info returns the tool information including name, description, and parameter schema. -// This method implements the eino tool.BaseTool interface. -// The returned ToolInfo contains the prefixed tool name to ensure uniqueness across servers. -func (t *mcpToolImpl) Info(ctx context.Context) (*schema.ToolInfo, error) { - return t.info, nil -} - -// InvokableRun executes the tool by mapping the prefixed name back to the original tool name and server. -// It retrieves a healthy connection from the pool, invokes the tool on the appropriate MCP server, -// and returns the result as a JSON string. The method handles connection errors by marking -// connections as unhealthy in the pool for automatic recovery on subsequent requests. -// Thread-safe for concurrent invocations. -func (t *mcpToolImpl) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) { - // Handle empty or invalid JSON arguments - var arguments any - if argumentsInJSON == "" || argumentsInJSON == "{}" { - arguments = nil - } else { - // Validate that argumentsInJSON is valid JSON before using it - var temp any - if err := json.Unmarshal([]byte(argumentsInJSON), &temp); err != nil { - return "", fmt.Errorf("invalid JSON arguments: %w", err) - } - arguments = json.RawMessage(argumentsInJSON) - } - - // Get connection from pool for this server with health check - conn, err := t.mapping.manager.connectionPool.GetConnectionWithHealthCheck(ctx, t.mapping.serverName, t.mapping.serverConfig) - if err != nil { - return "", fmt.Errorf("failed to get healthy connection from pool: %w", err) - } - - result, err := conn.client.CallTool(ctx, mcp.CallToolRequest{ - Request: mcp.Request{ - Method: "tools/call", - }, - Params: struct { - Name string `json:"name"` - Arguments any `json:"arguments,omitempty"` - Meta *mcp.Meta `json:"_meta,omitempty"` - }{ - Name: t.mapping.originalName, // Use original name, not prefixed - Arguments: arguments, - }, - }) - if err != nil { - // Handle connection error in pool - t.mapping.manager.connectionPool.HandleConnectionError(t.mapping.serverName, err) - return "", fmt.Errorf("failed to call mcp tool: %w", err) - } - - marshaledResult, err := sonic.MarshalString(result) - if err != nil { - return "", fmt.Errorf("failed to marshal mcp tool result: %w", err) - } - - // If the MCP server returned an error, we still return the error content as the response - // to the LLM so it can see what went wrong. The error will be shown to the user via - // the UI callbacks, but the LLM needs to see the actual error details to continue - // the conversation appropriately. - return marshaledResult, nil -} - -// GetTools returns all loaded tools from all configured MCP servers. +// GetTools returns all loaded tools as fantasy AgentTools from all configured MCP servers. // Tools are returned with their prefixed names (serverName__toolName) to ensure uniqueness. -// The returned slice is a copy and can be safely modified by the caller. -func (m *MCPToolManager) GetTools() []tool.BaseTool { +func (m *MCPToolManager) GetTools() []fantasy.AgentTool { return m.tools } @@ -360,15 +304,11 @@ func (m *MCPToolManager) Close() error { // shouldExcludeTool determines if a tool should be excluded based on excludedTools func (m *MCPToolManager) shouldExcludeTool(toolName string, serverConfig config.MCPServerConfig) bool { - // If excludedTools is specified, exclude tools in the list if len(serverConfig.ExcludedTools) > 0 { - for _, excludedTool := range serverConfig.ExcludedTools { - if excludedTool == toolName { - return true - } + if slices.Contains(serverConfig.ExcludedTools, toolName) { + return true } } - return false } @@ -377,60 +317,44 @@ func (m *MCPToolManager) createMCPClient(ctx context.Context, serverName string, switch transportType { case "stdio": - // STDIO client var env []string var command string var args []string - // Handle command and environment if len(serverConfig.Command) > 0 { command = serverConfig.Command[0] if len(serverConfig.Command) > 1 { args = serverConfig.Command[1:] } else if len(serverConfig.Args) > 0 { - // Legacy fallback: Command only has the command, Args has the arguments - // This handles cases where legacy config conversion didn't work properly args = serverConfig.Args } } - // Convert environment variables if serverConfig.Environment != nil { for k, v := range serverConfig.Environment { env = append(env, fmt.Sprintf("%s=%s", k, v)) } } - // Legacy environment support if serverConfig.Env != nil { for k, v := range serverConfig.Env { env = append(env, fmt.Sprintf("%s=%v", k, v)) } } - // Create stdio transport stdioTransport := transport.NewStdio(command, env, args...) - stdioClient := client.NewClient(stdioTransport) - // Start the transport if err := stdioTransport.Start(ctx); err != nil { return nil, fmt.Errorf("failed to start stdio transport: %v", err) } - // Add a brief delay to allow the process to start and potentially fail time.Sleep(100 * time.Millisecond) - - // TODO: Add process health check here if the mcp-go library exposes process info - // For now, we rely on the timeout in initializeClient to catch dead processes - return stdioClient, nil case "sse": - // SSE client var options []transport.ClientOption - // Add headers if specified if len(serverConfig.Headers) > 0 { headers := make(map[string]string) for _, header := range serverConfig.Headers { @@ -451,7 +375,6 @@ func (m *MCPToolManager) createMCPClient(ctx context.Context, serverName string, return nil, err } - // Start the SSE client if err := sseClient.Start(ctx); err != nil { return nil, fmt.Errorf("failed to start SSE client: %v", err) } @@ -459,10 +382,8 @@ func (m *MCPToolManager) createMCPClient(ctx context.Context, serverName string, return sseClient, nil case "streamable": - // Streamable HTTP client var options []transport.StreamableHTTPCOption - // Add headers if specified if len(serverConfig.Headers) > 0 { headers := make(map[string]string) for _, header := range serverConfig.Headers { @@ -483,7 +404,6 @@ func (m *MCPToolManager) createMCPClient(ctx context.Context, serverName string, return nil, err } - // Start the streamable HTTP client if err := streamableClient.Start(ctx); err != nil { return nil, fmt.Errorf("failed to start streamable HTTP client: %v", err) } @@ -491,7 +411,6 @@ func (m *MCPToolManager) createMCPClient(ctx context.Context, serverName string, return streamableClient, nil case "inprocess": - // Builtin server return m.createBuiltinClient(ctx, serverName, serverConfig) default: @@ -500,7 +419,6 @@ func (m *MCPToolManager) createMCPClient(ctx context.Context, serverName string, } func (m *MCPToolManager) initializeClient(ctx context.Context, client client.MCPClient) error { - // Create a timeout context for initialization to prevent deadlocks initCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() @@ -523,13 +441,11 @@ func (m *MCPToolManager) initializeClient(ctx context.Context, client client.MCP func (m *MCPToolManager) createBuiltinClient(ctx context.Context, serverName string, serverConfig config.MCPServerConfig) (client.MCPClient, error) { registry := builtin.NewRegistry() - // Create the builtin server, passing the model for servers that need it builtinServer, err := registry.CreateServer(serverConfig.Name, serverConfig.Options, m.model) if err != nil { return nil, fmt.Errorf("failed to create builtin server: %v", err) } - // Create an in-process client that wraps the builtin server inProcessClient, err := client.NewInProcessClient(builtinServer.GetServer()) if err != nil { return nil, fmt.Errorf("failed to create in-process client: %v", err) @@ -566,77 +482,65 @@ func (m *MCPToolManager) debugLogConnectionInfo(serverName string, serverConfig // convertExclusiveBoundsToBoolean converts JSON Schema draft-07 style exclusive bounds // (where exclusiveMinimum/exclusiveMaximum are numbers) to draft-04 style // (where they are booleans that modify minimum/maximum). -// This enables compatibility with kin-openapi which uses OpenAPI 3.0 (draft-04 based) schemas. func convertExclusiveBoundsToBoolean(schemaJSON []byte) []byte { - var data map[string]interface{} + var data map[string]any if err := json.Unmarshal(schemaJSON, &data); err != nil { - return schemaJSON // Return unchanged on error + return schemaJSON } convertSchemaRecursive(data) result, err := json.Marshal(data) if err != nil { - return schemaJSON // Return unchanged on error + return schemaJSON } return result } // convertSchemaRecursive recursively processes a schema map and converts // numeric exclusiveMinimum/exclusiveMaximum to boolean format. -func convertSchemaRecursive(schema map[string]interface{}) { - // Convert exclusiveMinimum if it's a number +func convertSchemaRecursive(schema map[string]any) { if exMin, ok := schema["exclusiveMinimum"]; ok { if num, isNum := exMin.(float64); isNum { - // JSON Schema draft-07: exclusiveMinimum is the limit value - // Convert to draft-04: set minimum = value, exclusiveMinimum = true schema["minimum"] = num schema["exclusiveMinimum"] = true } } - // Convert exclusiveMaximum if it's a number if exMax, ok := schema["exclusiveMaximum"]; ok { if num, isNum := exMax.(float64); isNum { - // JSON Schema draft-07: exclusiveMaximum is the limit value - // Convert to draft-04: set maximum = value, exclusiveMaximum = true schema["maximum"] = num schema["exclusiveMaximum"] = true } } - // Recursively process properties - if props, ok := schema["properties"].(map[string]interface{}); ok { + if props, ok := schema["properties"].(map[string]any); ok { for _, prop := range props { - if propSchema, ok := prop.(map[string]interface{}); ok { + if propSchema, ok := prop.(map[string]any); ok { convertSchemaRecursive(propSchema) } } } - // Recursively process items (for arrays) - if items, ok := schema["items"].(map[string]interface{}); ok { + if items, ok := schema["items"].(map[string]any); ok { convertSchemaRecursive(items) } - // Recursively process additionalProperties - if addProps, ok := schema["additionalProperties"].(map[string]interface{}); ok { + if addProps, ok := schema["additionalProperties"].(map[string]any); ok { convertSchemaRecursive(addProps) } - // Recursively process allOf, anyOf, oneOf for _, key := range []string{"allOf", "anyOf", "oneOf"} { - if arr, ok := schema[key].([]interface{}); ok { + if arr, ok := schema[key].([]any); ok { for _, item := range arr { - if itemSchema, ok := item.(map[string]interface{}); ok { + if itemSchema, ok := item.(map[string]any); ok { convertSchemaRecursive(itemSchema) } } } } - // Recursively process not - if not, ok := schema["not"].(map[string]interface{}); ok { + if not, ok := schema["not"].(map[string]any); ok { convertSchemaRecursive(not) } } diff --git a/internal/tools/mcp_test.go b/internal/tools/mcp_test.go index 0c0168c9..4bec1b3b 100644 --- a/internal/tools/mcp_test.go +++ b/internal/tools/mcp_test.go @@ -6,8 +6,6 @@ import ( "testing" "time" - "github.com/cloudwego/eino/schema" - "github.com/eino-contrib/jsonschema" "github.com/mark3labs/mcphost/internal/config" ) @@ -84,7 +82,6 @@ func TestMCPToolManager_ToolWithoutProperties(t *testing.T) { manager := NewMCPToolManager() // Create a config with a builtin todo server (which has tools with properties) - // and test the schema conversion logic cfg := &config.Config{ MCPServers: map[string]config.MCPServerConfig{ "todo-server": { @@ -111,69 +108,68 @@ func TestMCPToolManager_ToolWithoutProperties(t *testing.T) { // Test that we can get tool info for each tool for _, tool := range tools { - info, err := tool.Info(ctx) - if err != nil { - t.Errorf("Failed to get tool info: %v", err) - continue + info := tool.Info() + + // Check that the tool has a valid name + if info.Name == "" { + t.Error("Tool has empty name") } - // Check that the tool has a valid schema - if info.ParamsOneOf == nil { - t.Errorf("Tool %s has nil ParamsOneOf", info.Name) - } - - t.Logf("Tool: %s, Description: %s", info.Name, info.Desc) + t.Logf("Tool: %s, Description: %s", info.Name, info.Description) } } // TestIssue89_ObjectSchemaMissingProperties tests the fix for issue #89 -// This is a regression test for the "object schema missing properties" error -// that occurs when tools have no input parameters and use OpenAI function calling +// This verifies that object schemas with nil properties get an empty properties map func TestIssue89_ObjectSchemaMissingProperties(t *testing.T) { - // Create a schema that would cause the OpenAI validation error - // This simulates what might happen with tools that have no input properties - brokenSchema := &jsonschema.Schema{ - Type: "object", - // Properties is nil - this causes "object schema missing properties" error in OpenAI + // Create a schema that would cause issues with tools that have no input properties + brokenSchema := map[string]any{ + "type": "object", + // Properties is nil - this used to cause "object schema missing properties" error } // Verify the problematic state - if brokenSchema.Type == "object" && brokenSchema.Properties == nil { - t.Log("Found object schema with nil properties - this causes OpenAI validation error") + if brokenSchema["type"] == "object" && brokenSchema["properties"] == nil { + t.Log("Found object schema with nil properties - this previously caused validation errors") } - // Apply the fix from issue #89 - if brokenSchema.Type == "object" && brokenSchema.Properties == nil { - brokenSchema.Properties = jsonschema.NewProperties() + // Apply the fix - add empty properties + if brokenSchema["type"] == "object" && brokenSchema["properties"] == nil { + brokenSchema["properties"] = map[string]any{} } // Verify the fix worked - if brokenSchema.Type == "object" && brokenSchema.Properties == nil { + if brokenSchema["properties"] == nil { t.Error("Fix failed: object schema still has nil properties") } - // Test that we can create a ParamsOneOf from the fixed schema - // This is what would fail before the fix - paramsOneOf := schema.NewParamsOneOfByJSONSchema(brokenSchema) - if paramsOneOf == nil { - t.Error("Failed to create ParamsOneOf from fixed schema - OpenAI function calling would fail") + // Verify it marshals cleanly + data, err := json.Marshal(brokenSchema) + if err != nil { + t.Errorf("Failed to marshal fixed schema: %v", err) + } + + var result map[string]any + if err := json.Unmarshal(data, &result); err != nil { + t.Errorf("Failed to unmarshal fixed schema: %v", err) + } + + if result["type"] != "object" { + t.Error("Schema type should be 'object'") } } // TestConvertExclusiveBoundsToBoolean tests the JSON Schema draft-07 to draft-04 conversion -// for exclusiveMinimum and exclusiveMaximum fields. -// Draft-07: exclusiveMinimum/exclusiveMaximum are numeric values (the actual bounds) -// Draft-04: exclusiveMinimum/exclusiveMaximum are booleans that modify minimum/maximum func TestConvertExclusiveBoundsToBoolean(t *testing.T) { tests := []struct { name string input string - expected map[string]interface{} + expected map[string]any }{ { name: "exclusiveMinimum as number", input: `{"type": "number", "exclusiveMinimum": 0}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "number", "minimum": float64(0), "exclusiveMinimum": true, @@ -182,7 +178,7 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "exclusiveMaximum as number", input: `{"type": "number", "exclusiveMaximum": 100}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "number", "maximum": float64(100), "exclusiveMaximum": true, @@ -191,7 +187,7 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "both exclusive bounds as numbers", input: `{"type": "integer", "exclusiveMinimum": 1, "exclusiveMaximum": 10}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "integer", "minimum": float64(1), "exclusiveMinimum": true, @@ -202,7 +198,7 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "already boolean exclusiveMinimum (draft-04 style)", input: `{"type": "number", "minimum": 0, "exclusiveMinimum": true}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "number", "minimum": float64(0), "exclusiveMinimum": true, @@ -211,7 +207,7 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "no exclusive bounds", input: `{"type": "string", "minLength": 1}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "string", "minLength": float64(1), }, @@ -219,10 +215,10 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "nested properties with exclusive bounds", input: `{"type": "object", "properties": {"age": {"type": "integer", "exclusiveMinimum": 0}}}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "object", - "properties": map[string]interface{}{ - "age": map[string]interface{}{ + "properties": map[string]any{ + "age": map[string]any{ "type": "integer", "minimum": float64(0), "exclusiveMinimum": true, @@ -233,9 +229,9 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "array items with exclusive bounds", input: `{"type": "array", "items": {"type": "number", "exclusiveMaximum": 100}}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "array", - "items": map[string]interface{}{ + "items": map[string]any{ "type": "number", "maximum": float64(100), "exclusiveMaximum": true, @@ -245,9 +241,9 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "allOf with exclusive bounds", input: `{"allOf": [{"type": "number", "exclusiveMinimum": 0}]}`, - expected: map[string]interface{}{ - "allOf": []interface{}{ - map[string]interface{}{ + expected: map[string]any{ + "allOf": []any{ + map[string]any{ "type": "number", "minimum": float64(0), "exclusiveMinimum": true, @@ -258,9 +254,9 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "additionalProperties with exclusive bounds", input: `{"type": "object", "additionalProperties": {"type": "integer", "exclusiveMinimum": 0, "exclusiveMaximum": 255}}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "object", - "additionalProperties": map[string]interface{}{ + "additionalProperties": map[string]any{ "type": "integer", "minimum": float64(0), "exclusiveMinimum": true, @@ -272,15 +268,15 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { { name: "Chrome DevTools MCP style schema (real-world example)", input: `{"type": "object", "properties": {"timeout": {"type": "integer", "exclusiveMinimum": 0}, "quality": {"type": "number", "minimum": 0, "maximum": 100}}}`, - expected: map[string]interface{}{ + expected: map[string]any{ "type": "object", - "properties": map[string]interface{}{ - "timeout": map[string]interface{}{ + "properties": map[string]any{ + "timeout": map[string]any{ "type": "integer", "minimum": float64(0), "exclusiveMinimum": true, }, - "quality": map[string]interface{}{ + "quality": map[string]any{ "type": "number", "minimum": float64(0), "maximum": float64(100), @@ -294,7 +290,7 @@ func TestConvertExclusiveBoundsToBoolean(t *testing.T) { t.Run(tt.name, func(t *testing.T) { result := convertExclusiveBoundsToBoolean([]byte(tt.input)) - var got map[string]interface{} + var got map[string]any if err := json.Unmarshal(result, &got); err != nil { t.Fatalf("Failed to unmarshal result: %v", err) } @@ -317,7 +313,7 @@ func TestConvertExclusiveBoundsToBoolean_InvalidJSON(t *testing.T) { } // deepEqual compares two maps recursively -func deepEqual(a, b map[string]interface{}) bool { +func deepEqual(a, b map[string]any) bool { if len(a) != len(b) { return false } @@ -327,13 +323,13 @@ func deepEqual(a, b map[string]interface{}) bool { return false } switch av := v.(type) { - case map[string]interface{}: - bvm, ok := bv.(map[string]interface{}) + case map[string]any: + bvm, ok := bv.(map[string]any) if !ok || !deepEqual(av, bvm) { return false } - case []interface{}: - bva, ok := bv.([]interface{}) + case []any: + bva, ok := bv.([]any) if !ok || !sliceEqual(av, bva) { return false } @@ -347,19 +343,19 @@ func deepEqual(a, b map[string]interface{}) bool { } // sliceEqual compares two slices recursively -func sliceEqual(a, b []interface{}) bool { +func sliceEqual(a, b []any) bool { if len(a) != len(b) { return false } for i := range a { switch av := a[i].(type) { - case map[string]interface{}: - bvm, ok := b[i].(map[string]interface{}) + case map[string]any: + bvm, ok := b[i].(map[string]any) if !ok || !deepEqual(av, bvm) { return false } - case []interface{}: - bva, ok := b[i].([]interface{}) + case []any: + bva, ok := b[i].([]any) if !ok || !sliceEqual(av, bva) { return false } diff --git a/internal/ui/callbacks.go b/internal/ui/callbacks.go deleted file mode 100644 index a9af937a..00000000 --- a/internal/ui/callbacks.go +++ /dev/null @@ -1,41 +0,0 @@ -package ui - -import ( - "context" - - "github.com/cloudwego/eino/callbacks" - "github.com/cloudwego/eino/components/tool" - "github.com/cloudwego/eino/schema" - utilCallbacks "github.com/cloudwego/eino/utils/callbacks" -) - -// CreateCallbackHandler creates and returns a callbacks.Handler that manages -// tool execution callbacks for the CLI. The handler displays tool calls, -// handles errors, and manages streaming output for interactive tool operations. -// It integrates with the eino callback system to provide real-time UI feedback -// during tool execution. -func (c *CLI) CreateCallbackHandler() callbacks.Handler { - toolHandler := &utilCallbacks.ToolCallbackHandler{ - OnStart: func(ctx context.Context, runInfo *callbacks.RunInfo, input *tool.CallbackInput) context.Context { - // Display the tool call message with the tool name and arguments - c.DisplayToolCallMessage(runInfo.Name, input.ArgumentsInJSON) - return ctx - }, - OnEnd: func(ctx context.Context, runInfo *callbacks.RunInfo, output *tool.CallbackOutput) context.Context { - // Tool execution completed - we could show results here if needed - return ctx - }, - OnEndWithStreamOutput: func(ctx context.Context, runInfo *callbacks.RunInfo, output *schema.StreamReader[*tool.CallbackOutput]) context.Context { - return ctx - }, - OnError: func(ctx context.Context, runInfo *callbacks.RunInfo, err error) context.Context { - // Display error message - c.DisplayError(err) - return ctx - }, - } - - return utilCallbacks.NewHandlerHelper(). - Tool(toolHandler). - Handler() -} diff --git a/internal/ui/cli.go b/internal/ui/cli.go index 99b29090..c78045f3 100644 --- a/internal/ui/cli.go +++ b/internal/ui/cli.go @@ -8,8 +8,8 @@ import ( "time" tea "charm.land/bubbletea/v2" + "charm.land/fantasy" "charm.land/lipgloss/v2" - "github.com/cloudwego/eino/schema" "golang.org/x/term" ) @@ -498,38 +498,27 @@ func (c *CLI) UpdateUsage(inputText, outputText string) { } } -// UpdateUsageFromResponse records token usage using metadata from the AI provider's +// UpdateUsageFromResponse records token usage using metadata from the fantasy // response when available. Falls back to text-based estimation if the metadata is // missing or appears unreliable. This provides more accurate usage tracking when // providers supply token count information. -func (c *CLI) UpdateUsageFromResponse(response *schema.Message, inputText string) { +func (c *CLI) UpdateUsageFromResponse(response *fantasy.Response, inputText string) { if c.usageTracker == nil { return } - // Try to extract token usage from response metadata - if response.ResponseMeta != nil && response.ResponseMeta.Usage != nil { - usage := response.ResponseMeta.Usage + usage := response.Usage + inputTokens := int(usage.InputTokens) + outputTokens := int(usage.OutputTokens) - // Use actual token counts from the response - inputTokens := int(usage.PromptTokens) - outputTokens := int(usage.CompletionTokens) - - // Validate that the metadata seems reasonable - // If token counts are 0 or seem unrealistic, fall back to estimation - if inputTokens > 0 && outputTokens > 0 { - // Handle cache tokens if available (some providers support this) - cacheReadTokens := 0 - cacheWriteTokens := 0 - - c.usageTracker.UpdateUsage(inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens) - } else { - // Metadata exists but seems incomplete/unreliable, use estimation - c.usageTracker.EstimateAndUpdateUsage(inputText, response.Content) - } + // Validate that the metadata seems reasonable + if inputTokens > 0 && outputTokens > 0 { + cacheReadTokens := int(usage.CacheReadTokens) + cacheWriteTokens := int(usage.CacheCreationTokens) + c.usageTracker.UpdateUsage(inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens) } else { // Fallback to estimation if no metadata is available - c.usageTracker.EstimateAndUpdateUsage(inputText, response.Content) + c.usageTracker.EstimateAndUpdateUsage(inputText, response.Content.Text()) } } diff --git a/internal/ui/commands.go b/internal/ui/commands.go index fbd52ac5..da0c7384 100644 --- a/internal/ui/commands.go +++ b/internal/ui/commands.go @@ -1,5 +1,7 @@ package ui +import "slices" + // SlashCommand represents a user-invokable slash command with its metadata. // Commands can have multiple aliases and are organized by category for better // discoverability and help display. @@ -68,10 +70,8 @@ func GetCommandByName(name string) *SlashCommand { if cmd.Name == name { return cmd } - for _, alias := range cmd.Aliases { - if alias == name { - return cmd - } + if slices.Contains(cmd.Aliases, name) { + return cmd } } return nil diff --git a/internal/ui/compact_renderer.go b/internal/ui/compact_renderer.go index 60fc26ec..002cb538 100644 --- a/internal/ui/compact_renderer.go +++ b/internal/ui/compact_renderer.go @@ -296,10 +296,11 @@ func (r *CompactRenderer) formatCompactContent(content string) string { content = strings.TrimSpace(content) // Truncate if too long (unless in debug mode) - maxLen := r.width - 28 // Reserve space for symbol and label more conservatively - if maxLen < 40 { - maxLen = 40 // Minimum width for readability - } + maxLen := max( + // Reserve space for symbol and label more conservatively + r.width-28, + // Minimum width for readability + 40) if !r.debug && len(content) > maxLen { content = content[:maxLen-3] + "..." } @@ -315,10 +316,9 @@ func (r *CompactRenderer) formatUserAssistantContent(content string) string { // Calculate available width more conservatively // Account for: symbol (1) + spaces (2) + label (up to 20 chars) + space (1) + margin (4) - availableWidth := r.width - 28 - if availableWidth < 40 { - availableWidth = 40 // Minimum width for readability - } + availableWidth := max(r.width-28, + // Minimum width for readability + 40) // Use glamour to render markdown content with proper width rendered := toMarkdown(content, availableWidth) @@ -407,10 +407,9 @@ func (r *CompactRenderer) formatToolResult(result string) string { } // Calculate available width more conservatively - availableWidth := r.width - 28 - if availableWidth < 40 { - availableWidth = 40 // Minimum width for readability - } + availableWidth := max(r.width-28, + // Minimum width for readability + 40) // First wrap the text to prevent long lines (tool results are usually plain text, not markdown) wrappedResult := r.wrapText(result, availableWidth) diff --git a/internal/ui/debug_logger.go b/internal/ui/debug_logger.go index 30fc7a5e..b0a04e78 100644 --- a/internal/ui/debug_logger.go +++ b/internal/ui/debug_logger.go @@ -36,12 +36,12 @@ func (l *CLIDebugLogger) LogDebug(message string) { // Check if this is a multi-line debug output (like connection info) if strings.Contains(message, "[DEBUG]") || strings.Contains(message, "[POOL]") { // Extract the tag and content - if strings.HasPrefix(message, "[DEBUG]") { - content := strings.TrimPrefix(message, "[DEBUG]") + if after, ok := strings.CutPrefix(message, "[DEBUG]"); ok { + content := after content = strings.TrimSpace(content) formattedMessage = fmt.Sprintf("šŸ” DEBUG: %s", content) - } else if strings.HasPrefix(message, "[POOL]") { - content := strings.TrimPrefix(message, "[POOL]") + } else if after, ok := strings.CutPrefix(message, "[POOL]"); ok { + content := after content = strings.TrimSpace(content) // Add appropriate emoji based on the message content diff --git a/internal/ui/progress/ollama.go b/internal/ui/progress/ollama.go index 0bc8a88a..27751a28 100644 --- a/internal/ui/progress/ollama.go +++ b/internal/ui/progress/ollama.go @@ -80,10 +80,7 @@ func (m ProgressModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil case tea.WindowSizeMsg: - newWidth := msg.Width - padding*2 - 4 - if newWidth > maxWidth { - newWidth = maxWidth - } + newWidth := min(msg.Width-padding*2-4, maxWidth) m.progress.SetWidth(newWidth) return m, nil @@ -167,14 +164,12 @@ func NewProgressReader(reader io.Reader) *ProgressReader { } // Start the TUI in a goroutine - pr.wg.Add(1) - go func() { - defer pr.wg.Done() + pr.wg.Go(func() { if _, err := program.Run(); err != nil { // Handle error silently for now } close(pr.done) - }() + }) return pr } diff --git a/internal/ui/spinner.go b/internal/ui/spinner.go index f8ec62c4..5a809d1b 100644 --- a/internal/ui/spinner.go +++ b/internal/ui/spinner.go @@ -1,153 +1,101 @@ package ui import ( - "context" "fmt" "image/color" "os" + "sync" + "time" - "charm.land/bubbles/v2/spinner" - tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" ) -// Spinner provides an animated loading indicator that displays while long-running -// operations are in progress. It wraps the bubbles spinner component and manages -// its lifecycle through a tea.Program for proper terminal handling. +// spinnerFrames defines available spinner animation styles. +var ( + pointsFrames = []string{"āˆ™āˆ™āˆ™", "ā—āˆ™āˆ™", "āˆ™ā—āˆ™", "āˆ™āˆ™ā—"} + pointsFPS = time.Second / 7 + + dotFrames = []string{"⣾ ", "⣽ ", "⣻ ", "⢿ ", "┿ ", "⣟ ", "⣯ ", "⣷ "} + dotFPS = time.Second / 10 +) + +// Spinner provides an animated loading indicator that displays while +// long-running operations are in progress. It writes directly to stderr +// using a goroutine-based animation loop, avoiding Bubble Tea's terminal +// capability queries that can leak escape sequences (mode 2026 DECRPM). type Spinner struct { - model spinner.Model - done chan struct{} - prog *tea.Program - ctx context.Context - cancel context.CancelFunc + message string + frames []string + fps time.Duration + color color.Color + done chan struct{} + once sync.Once } -// spinnerModel is the tea.Model for the spinner -type spinnerModel struct { - spinner spinner.Model - message string - quitting bool -} - -func (m spinnerModel) Init() tea.Cmd { - return m.spinner.Tick -} - -func (m spinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyPressMsg: - m.quitting = true - return m, tea.Quit - case spinner.TickMsg: - var cmd tea.Cmd - m.spinner, cmd = m.spinner.Update(msg) - return m, cmd - case quitMsg: - m.quitting = true - return m, tea.Quit - default: - return m, nil - } -} - -func (m spinnerModel) View() tea.View { - if m.quitting { - return tea.NewView("") - } - - // Enhanced spinner display with better styling - baseStyle := lipgloss.NewStyle() - theme := GetTheme() - - spinnerStyle := baseStyle. - Foreground(theme.Primary). - Bold(true) - - messageStyle := baseStyle. - Foreground(theme.Text). - Italic(true) - - return tea.NewView(fmt.Sprintf(" %s %s", - spinnerStyle.Render(m.spinner.View()), - messageStyle.Render(m.message))) -} - -// quitMsg is sent when we want to quit the spinner -type quitMsg struct{} - -// NewSpinner creates a new animated spinner with the specified message. The spinner -// uses the theme's primary color and a modern animation style. It runs in a separate -// tea.Program to avoid interfering with other terminal operations. +// NewSpinner creates a new animated spinner with the specified message. +// The spinner uses the theme's primary color and a points animation style. func NewSpinner(message string) *Spinner { - s := spinner.New() - s.Spinner = spinner.Points // More modern spinner style - theme := GetTheme() - s.Style = s.Style.Foreground(theme.Primary) - - ctx, cancel := context.WithCancel(context.Background()) - - model := spinnerModel{ - spinner: s, - message: message, - } - - prog := tea.NewProgram(model, tea.WithOutput(os.Stderr), tea.WithoutCatchPanics()) - return &Spinner{ - model: s, - done: make(chan struct{}), - prog: prog, - ctx: ctx, - cancel: cancel, + message: message, + frames: pointsFrames, + fps: pointsFPS, + color: GetTheme().Primary, + done: make(chan struct{}), } } // NewThemedSpinner creates a new animated spinner with custom color styling. // This allows for different spinner colors based on the operation type or status. -// The spinner runs independently in its own tea.Program. -func NewThemedSpinner(message string, color color.Color) *Spinner { - s := spinner.New() - s.Spinner = spinner.Dot - s.Style = s.Style.Foreground(color) - - ctx, cancel := context.WithCancel(context.Background()) - - model := spinnerModel{ - spinner: s, - message: message, - } - - prog := tea.NewProgram(model, tea.WithOutput(os.Stderr), tea.WithoutCatchPanics()) - +func NewThemedSpinner(message string, c color.Color) *Spinner { return &Spinner{ - model: s, - done: make(chan struct{}), - prog: prog, - ctx: ctx, - cancel: cancel, + message: message, + frames: dotFrames, + fps: dotFPS, + color: c, + done: make(chan struct{}), } } -// Start begins the spinner animation in a separate goroutine. The spinner will -// continue animating until Stop is called. The animation runs in a separate -// tea.Program to maintain smooth animation independent of other operations. +// Start begins the spinner animation in a separate goroutine. The spinner +// will continue animating until Stop is called. func (s *Spinner) Start() { - go func() { - defer close(s.done) - go func() { - <-s.ctx.Done() - s.prog.Send(quitMsg{}) - }() - _, err := s.prog.Run() - if err != nil { - fmt.Fprintf(os.Stderr, "Error running spinner: %v\n", err) - } - }() + go s.run() } -// Stop halts the spinner animation and cleans up resources. This method blocks -// until the spinner has fully stopped and the terminal state is restored. +// Stop halts the spinner animation and cleans up. This method blocks until +// the animation goroutine has exited and the line is cleared. func (s *Spinner) Stop() { - s.cancel() - <-s.done + s.once.Do(func() { close(s.done) }) +} + +// run is the animation loop that renders spinner frames to stderr. +func (s *Spinner) run() { + theme := GetTheme() + + spinnerStyle := lipgloss.NewStyle(). + Foreground(s.color). + Bold(true) + + messageStyle := lipgloss.NewStyle(). + Foreground(theme.Text). + Italic(true) + + ticker := time.NewTicker(s.fps) + defer ticker.Stop() + + var frame int + for { + select { + case <-s.done: + // Clear the spinner line and return. + fmt.Fprint(os.Stderr, "\r\033[K") + return + case <-ticker.C: + f := s.frames[frame%len(s.frames)] + fmt.Fprintf(os.Stderr, "\r %s %s", + spinnerStyle.Render(f), + messageStyle.Render(s.message)) + frame++ + } + } } diff --git a/internal/ui/styles.go b/internal/ui/styles.go index f5f4220e..d792614b 100644 --- a/internal/ui/styles.go +++ b/internal/ui/styles.go @@ -11,9 +11,15 @@ import ( const defaultMargin = 1 // Helper functions for style pointers -func boolPtr(b bool) *bool { return &b } -func stringPtr(s string) *string { return &s } -func uintPtr(u uint) *uint { return &u } +// +//go:fix inline +func boolPtr(b bool) *bool { return new(b) } + +//go:fix inline +func stringPtr(s string) *string { return new(s) } + +//go:fix inline +func uintPtr(u uint) *uint { return new(u) } // BaseStyle returns a new, empty lipgloss style that can be customized with // additional styling methods. This serves as the foundation for building more @@ -106,101 +112,101 @@ func generateMarkdownStyleConfig() ansi.StyleConfig { StylePrimitive: ansi.StylePrimitive{ BlockPrefix: "", BlockSuffix: "", - Color: stringPtr(textColor), + Color: new(textColor), }, Margin: uintPtr(0), // Remove margin to prevent spacing }, BlockQuote: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ - Color: stringPtr(mutedColor), - Italic: boolPtr(true), + Color: new(mutedColor), + Italic: new(true), Prefix: "ā”ƒ ", }, Indent: uintPtr(1), - IndentToken: stringPtr(lipgloss.NewStyle().Background(lipgloss.Color(bgColor)).Render(" ")), + IndentToken: new(lipgloss.NewStyle().Background(lipgloss.Color(bgColor)).Render(" ")), }, List: ansi.StyleList{ LevelIndent: 0, // Remove list indentation StyleBlock: ansi.StyleBlock{ - IndentToken: stringPtr(lipgloss.NewStyle().Background(lipgloss.Color(bgColor)).Render(" ")), + IndentToken: new(lipgloss.NewStyle().Background(lipgloss.Color(bgColor)).Render(" ")), StylePrimitive: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, }, }, Heading: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ BlockSuffix: "\n", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, H1: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "# ", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, H2: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "## ", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, H3: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "### ", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, H4: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "#### ", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, H5: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "##### ", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, H6: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "###### ", - Color: stringPtr(headingColor), - Bold: boolPtr(true), + Color: new(headingColor), + Bold: new(true), }, }, Strikethrough: ansi.StylePrimitive{ - CrossedOut: boolPtr(true), - Color: stringPtr(mutedColor), + CrossedOut: new(true), + Color: new(mutedColor), }, Emph: ansi.StylePrimitive{ - Color: stringPtr(emphColor), + Color: new(emphColor), - Italic: boolPtr(true), + Italic: new(true), }, Strong: ansi.StylePrimitive{ - Bold: boolPtr(true), - Color: stringPtr(strongColor), + Bold: new(true), + Color: new(strongColor), }, HorizontalRule: ansi.StylePrimitive{ - Color: stringPtr(mutedColor), + Color: new(mutedColor), Format: "\n─────────────────────────────────────────\n", }, Item: ansi.StylePrimitive{ BlockPrefix: "• ", - Color: stringPtr(textColor), + Color: new(textColor), }, Enumeration: ansi.StylePrimitive{ BlockPrefix: ". ", - Color: stringPtr(textColor), + Color: new(textColor), }, Task: ansi.StyleTask{ StylePrimitive: ansi.StylePrimitive{}, @@ -208,29 +214,29 @@ func generateMarkdownStyleConfig() ansi.StyleConfig { Unticked: "[ ] ", }, Link: ansi.StylePrimitive{ - Color: stringPtr(linkColor), + Color: new(linkColor), - Underline: boolPtr(true), + Underline: new(true), }, LinkText: ansi.StylePrimitive{ - Color: stringPtr(linkColor), + Color: new(linkColor), - Bold: boolPtr(true), + Bold: new(true), }, Image: ansi.StylePrimitive{ - Color: stringPtr(linkColor), + Color: new(linkColor), - Underline: boolPtr(true), + Underline: new(true), Format: "šŸ–¼ {{.text}}", }, ImageText: ansi.StylePrimitive{ - Color: stringPtr(linkColor), + Color: new(linkColor), Format: "{{.text}}", }, Code: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ - Color: stringPtr(codeColor), + Color: new(codeColor), Prefix: "", Suffix: "", @@ -240,92 +246,92 @@ func generateMarkdownStyleConfig() ansi.StyleConfig { StyleBlock: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ Prefix: "", - Color: stringPtr(codeColor), + Color: new(codeColor), }, Margin: uintPtr(0), // Remove margin }, Chroma: &ansi.Chroma{ Text: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, Error: ansi.StylePrimitive{ - Color: stringPtr(errorColor), + Color: new(errorColor), }, Comment: ansi.StylePrimitive{ - Color: stringPtr(commentColor), + Color: new(commentColor), }, CommentPreproc: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, Keyword: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, KeywordReserved: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, KeywordNamespace: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, KeywordType: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, Operator: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, Punctuation: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, Name: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, NameBuiltin: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, NameTag: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, NameAttribute: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, NameClass: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, NameConstant: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, NameDecorator: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, NameFunction: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, LiteralNumber: ansi.StylePrimitive{ - Color: stringPtr(numberColor), + Color: new(numberColor), }, LiteralString: ansi.StylePrimitive{ - Color: stringPtr(stringColor), + Color: new(stringColor), }, LiteralStringEscape: ansi.StylePrimitive{ - Color: stringPtr(keywordColor), + Color: new(keywordColor), }, GenericDeleted: ansi.StylePrimitive{ - Color: stringPtr(errorColor), + Color: new(errorColor), }, GenericEmph: ansi.StylePrimitive{ - Color: stringPtr(emphColor), + Color: new(emphColor), - Italic: boolPtr(true), + Italic: new(true), }, GenericInserted: ansi.StylePrimitive{ - Color: stringPtr(stringColor), + Color: new(stringColor), }, GenericStrong: ansi.StylePrimitive{ - Color: stringPtr(strongColor), + Color: new(strongColor), - Bold: boolPtr(true), + Bold: new(true), }, GenericSubheading: ansi.StylePrimitive{ - Color: stringPtr(headingColor), + Color: new(headingColor), }, }, }, @@ -336,20 +342,20 @@ func generateMarkdownStyleConfig() ansi.StyleConfig { BlockSuffix: "\n", }, }, - CenterSeparator: stringPtr("┼"), - ColumnSeparator: stringPtr("│"), - RowSeparator: stringPtr("─"), + CenterSeparator: new("┼"), + ColumnSeparator: new("│"), + RowSeparator: new("─"), }, DefinitionDescription: ansi.StylePrimitive{ BlockPrefix: "\n āÆ ", - Color: stringPtr(linkColor), + Color: new(linkColor), }, Text: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, Paragraph: ansi.StyleBlock{ StylePrimitive: ansi.StylePrimitive{ - Color: stringPtr(textColor), + Color: new(textColor), }, }, } diff --git a/sdk/mcphost.go b/sdk/mcphost.go index b598e5ca..d8167cdf 100644 --- a/sdk/mcphost.go +++ b/sdk/mcphost.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/cloudwego/eino/schema" + "charm.land/fantasy" "github.com/mark3labs/mcphost/cmd" "github.com/mark3labs/mcphost/internal/agent" "github.com/mark3labs/mcphost/internal/config" @@ -78,7 +78,7 @@ func New(ctx context.Context, opts *Options) (*MCPHost, error) { return nil, fmt.Errorf("failed to load system prompt: %v", err) } - // Create model configuration (same as CLI in root.go:387-406) + // Create model configuration (same as CLI in root.go) temperature := float32(viper.GetFloat64("temperature")) topP := float32(viper.GetFloat64("top-p")) topK := int32(viper.GetInt("top-k")) @@ -100,7 +100,7 @@ func New(ctx context.Context, opts *Options) (*MCPHost, error) { TLSSkipVerify: viper.GetBool("tls-skip-verify"), } - // Create agent using existing factory (same as CLI in root.go:431-440) + // Create agent using existing factory a, err := agent.CreateAgent(ctx, &agent.AgentCreationOptions{ ModelConfig: modelConfig, MCPConfig: mcpConfig, @@ -132,10 +132,10 @@ func (m *MCPHost) Prompt(ctx context.Context, message string) (string, error) { messages := m.sessionMgr.GetMessages() // Add new user message - userMsg := schema.UserMessage(message) + userMsg := fantasy.NewUserMessage(message) messages = append(messages, userMsg) - // Call agent (same as CLI does in root.go:902) + // Call agent result, err := m.agent.GenerateWithLoop(ctx, messages, nil, // onToolCall nil, // onToolExecution @@ -149,12 +149,11 @@ func (m *MCPHost) Prompt(ctx context.Context, message string) (string, error) { } // Update session with all messages from the conversation - // This preserves the complete history including tool calls if err := m.sessionMgr.ReplaceAllMessages(result.ConversationMessages); err != nil { return "", fmt.Errorf("failed to update session: %v", err) } - return result.FinalResponse.Content, nil + return result.FinalResponse.Content.Text(), nil } // PromptWithCallbacks sends a message with callbacks for monitoring tool execution @@ -171,7 +170,7 @@ func (m *MCPHost) PromptWithCallbacks( messages := m.sessionMgr.GetMessages() // Add new user message - userMsg := schema.UserMessage(message) + userMsg := fantasy.NewUserMessage(message) messages = append(messages, userMsg) // Call agent with callbacks @@ -193,7 +192,7 @@ func (m *MCPHost) PromptWithCallbacks( return "", fmt.Errorf("failed to update session: %v", err) } - return result.FinalResponse.Content, nil + return result.FinalResponse.Content.Text(), nil } // GetSessionManager returns the current session manager for direct access diff --git a/sdk/mcphost_test.go b/sdk/mcphost_test.go index b36f90b0..2189cf17 100644 --- a/sdk/mcphost_test.go +++ b/sdk/mcphost_test.go @@ -35,7 +35,7 @@ func TestNewWithOptions(t *testing.T) { ctx := context.Background() opts := &sdk.Options{ - Model: "anthropic:claude-3-haiku-20240307", + Model: "anthropic:claude-sonnet-4-20250514", MaxSteps: 5, Quiet: true, } diff --git a/sdk/types.go b/sdk/types.go index f77313c8..9bd356a5 100644 --- a/sdk/types.go +++ b/sdk/types.go @@ -1,7 +1,7 @@ package sdk import ( - "github.com/cloudwego/eino/schema" + "charm.land/fantasy" "github.com/mark3labs/mcphost/internal/session" ) @@ -13,14 +13,14 @@ type Message = session.Message // with its name, arguments, and result within a conversation. type ToolCall = session.ToolCall -// ConvertToSchemaMessage converts an SDK message to the underlying schema message +// ConvertToFantasyMessage converts an SDK message to the underlying fantasy message // format used by the agent for LLM interactions. -func ConvertToSchemaMessage(msg *Message) *schema.Message { - return msg.ConvertToSchemaMessage() +func ConvertToFantasyMessage(msg *Message) fantasy.Message { + return msg.ConvertToFantasyMessage() } -// ConvertFromSchemaMessage converts a schema message from the agent to an SDK +// ConvertFromFantasyMessage converts a fantasy message from the agent to an SDK // message format for use in the SDK API. -func ConvertFromSchemaMessage(msg *schema.Message) Message { - return session.ConvertFromSchemaMessage(msg) +func ConvertFromFantasyMessage(msg fantasy.Message) Message { + return session.ConvertFromFantasyMessage(msg) }