// // ModelCatalogData.swift // Zyquo Agent // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // // Built-in model catalog, generated from docs/PROVIDERS.md and the per-provider // research files in docs/research/ on 2026-07-30. This file and docs/PROVIDERS.md // are a single source of truth and MUST stay in sync: when Phase 7 verification // (or any later research pass) changes a model, update both together. // // Scope: chat-completions-capable chat models only. Embeddings, audio/TTS/ASR, // realtime, image/video generation, moderation, OCR, robotics, deep-research // agents, and Responses-API-only models are excluded by design. // import Foundation enum ModelCatalogData { // MARK: - Shared parameter-support presets /// OpenAI reasoning models (o-series, gpt-5.x reasoning variants): reject /// temperature/top_p/penalties, require max_completion_tokens, accept reasoning_effort. private static let openAIReasoning = ParameterSupport( temperature: false, topP: false, usesMaxCompletionTokens: true, reasoningEffort: true ) // MARK: - OpenAI static let openai: [AIModel] = [ // Flagship GPT-5.6 trio AIModel( id: "gpt-5.6-sol", provider: .openai, displayName: "GPT-5.6 Sol", contextWindow: 1_050_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 30.00), parameterSupport: openAIReasoning, isRecommended: true ), AIModel( id: "gpt-5.6-terra", provider: .openai, displayName: "GPT-5.6 Terra", contextWindow: 1_050_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 15.00), parameterSupport: openAIReasoning, isRecommended: true ), AIModel( id: "gpt-5.6-luna", provider: .openai, displayName: "GPT-5.6 Luna", contextWindow: 1_050_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 6.00), parameterSupport: openAIReasoning ), AIModel( id: "chat-latest", provider: .openai, displayName: "ChatGPT Latest", contextWindow: 128_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 30.00), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true) ), // Current / recent GPT-5.x AIModel( id: "gpt-5.5", provider: .openai, displayName: "GPT-5.5", contextWindow: 400_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 30.00), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5.4", provider: .openai, displayName: "GPT-5.4", contextWindow: 400_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 15.00), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5.4-mini", provider: .openai, displayName: "GPT-5.4 mini", contextWindow: 400_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 4.50), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5.4-nano", provider: .openai, displayName: "GPT-5.4 nano", contextWindow: 400_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 1.25), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5.3-chat-latest", provider: .openai, displayName: "GPT-5.3 Chat Latest", contextWindow: 128_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true) ), AIModel( id: "gpt-5.2", provider: .openai, displayName: "GPT-5.2", contextWindow: 400_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.75, outputPerMTok: 14.00), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5.2-chat-latest", provider: .openai, displayName: "GPT-5.2 Chat Latest", contextWindow: 128_000, maxOutputTokens: 16_000, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.75, outputPerMTok: 14.00), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true) ), AIModel( id: "gpt-5.1", provider: .openai, displayName: "GPT-5.1", contextWindow: 400_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5", provider: .openai, displayName: "GPT-5", contextWindow: 400_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5-mini", provider: .openai, displayName: "GPT-5 mini", contextWindow: 400_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 2.00), parameterSupport: openAIReasoning ), AIModel( id: "gpt-5-nano", provider: .openai, displayName: "GPT-5 nano", contextWindow: 400_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.05, outputPerMTok: 0.40), parameterSupport: openAIReasoning ), // o-series reasoning AIModel( id: "o3", provider: .openai, displayName: "OpenAI o3", contextWindow: 200_000, maxOutputTokens: 100_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00), parameterSupport: openAIReasoning ), AIModel( id: "o4-mini", provider: .openai, displayName: "OpenAI o4-mini", contextWindow: 200_000, maxOutputTokens: 100_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.10, outputPerMTok: 4.40), parameterSupport: openAIReasoning ), AIModel( id: "o3-mini", provider: .openai, displayName: "OpenAI o3-mini", contextWindow: 200_000, maxOutputTokens: 100_000, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.10, outputPerMTok: 4.40), parameterSupport: openAIReasoning, isLegacy: true ), AIModel( id: "o1", provider: .openai, displayName: "OpenAI o1", contextWindow: 200_000, maxOutputTokens: 100_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 15.00, outputPerMTok: 60.00), parameterSupport: openAIReasoning, isLegacy: true ), // Legacy GPT-4.x / 3.5 AIModel( id: "gpt-4.1", provider: .openai, displayName: "GPT-4.1", contextWindow: 1_047_576, maxOutputTokens: 32_768, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-4.1-mini", provider: .openai, displayName: "GPT-4.1 mini", contextWindow: 1_047_576, maxOutputTokens: 32_768, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 1.60), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-4.1-nano", provider: .openai, displayName: "GPT-4.1 nano", contextWindow: 1_047_576, maxOutputTokens: 32_768, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.40), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-4o", provider: .openai, displayName: "GPT-4o", contextWindow: 128_000, maxOutputTokens: 16_384, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 10.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-4o-mini", provider: .openai, displayName: "GPT-4o mini", contextWindow: 128_000, maxOutputTokens: 16_384, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-4-turbo", provider: .openai, displayName: "GPT-4 Turbo", contextWindow: 128_000, maxOutputTokens: 4_096, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 30.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-4", provider: .openai, displayName: "GPT-4", contextWindow: 8_192, maxOutputTokens: 8_192, capabilities: ModelCapabilities(tools: true), pricing: ModelPricing(inputPerMTok: 30.00, outputPerMTok: 60.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "gpt-3.5-turbo", provider: .openai, displayName: "GPT-3.5 Turbo", contextWindow: 16_385, maxOutputTokens: 4_096, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 1.50), parameterSupport: .openAIDefault, isLegacy: true ), ] // MARK: - Anthropic static let anthropic: [AIModel] = [ AIModel( id: "claude-opus-5", provider: .anthropic, displayName: "Claude Opus 5", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true), isRecommended: true ), AIModel( id: "claude-sonnet-5", provider: .anthropic, displayName: "Claude Sonnet 5", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00), parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true), isRecommended: true ), AIModel( id: "claude-fable-5", provider: .anthropic, displayName: "Claude Fable 5", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 50.00), // Thinking is always on and cannot be disabled — no toggle. parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: false) ), AIModel( id: "claude-opus-4-8", provider: .anthropic, displayName: "Claude Opus 4.8", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true) ), AIModel( id: "claude-opus-4-7", provider: .anthropic, displayName: "Claude Opus 4.7", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true) ), AIModel( id: "claude-opus-4-6", provider: .anthropic, displayName: "Claude Opus 4.6", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true) ), AIModel( id: "claude-sonnet-4-6", provider: .anthropic, displayName: "Claude Sonnet 4.6", contextWindow: 1_000_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00), parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true) ), AIModel( id: "claude-haiku-4-5-20251001", provider: .anthropic, displayName: "Claude Haiku 4.5", contextWindow: 200_000, maxOutputTokens: 64_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 5.00), parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true) ), AIModel( id: "claude-opus-4-5-20251101", provider: .anthropic, displayName: "Claude Opus 4.5", contextWindow: 200_000, maxOutputTokens: 64_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true), isLegacy: true ), AIModel( id: "claude-sonnet-4-5-20250929", provider: .anthropic, displayName: "Claude Sonnet 4.5", contextWindow: 1_000_000, maxOutputTokens: 64_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00), parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true), isLegacy: true ), AIModel( id: "claude-opus-4-1-20250805", provider: .anthropic, displayName: "Claude Opus 4.1", contextWindow: 200_000, maxOutputTokens: 32_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 15.00, outputPerMTok: 75.00), parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true), isLegacy: true ), ] // MARK: - xAI (Grok) static let xai: [AIModel] = [ AIModel( id: "grok-4.5", provider: .xai, displayName: "Grok 4.5", contextWindow: 500_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 6.00), parameterSupport: ParameterSupport(reasoningEffort: true), isRecommended: true ), AIModel( id: "grok-4.3", provider: .xai, displayName: "Grok 4.3", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 2.50), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "grok-4.20", provider: .xai, displayName: "Grok 4.20 Reasoning", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 2.50), parameterSupport: ParameterSupport() ), AIModel( id: "grok-4.20-non-reasoning", provider: .xai, displayName: "Grok 4.20 Non-Reasoning", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 2.50), parameterSupport: ParameterSupport() ), AIModel( id: "grok-code-fast-1", provider: .xai, displayName: "Grok Code Fast 1", contextWindow: 256_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 2.00), parameterSupport: ParameterSupport(), isRecommended: true ), ] // MARK: - Mistral static let mistral: [AIModel] = [ AIModel( id: "mistral-medium-latest", provider: .mistral, displayName: "Mistral Medium 3.5", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 7.50), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true), isRecommended: true ), AIModel( id: "mistral-large-latest", provider: .mistral, displayName: "Mistral Large 3", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 1.50), parameterSupport: .openAIDefault, isRecommended: true ), AIModel( id: "mistral-small-latest", provider: .mistral, displayName: "Mistral Small 4", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true), isRecommended: true ), AIModel( id: "codestral-latest", provider: .mistral, displayName: "Codestral", contextWindow: 256_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 0.90), parameterSupport: .openAIDefault ), AIModel( id: "ministral-14b-latest", provider: .mistral, displayName: "Ministral 3 14B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.20), parameterSupport: .openAIDefault ), AIModel( id: "ministral-8b-latest", provider: .mistral, displayName: "Ministral 3 8B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.15), parameterSupport: .openAIDefault ), AIModel( id: "ministral-3b-latest", provider: .mistral, displayName: "Ministral 3 3B", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.10), parameterSupport: .openAIDefault ), // Legacy / deprecated (still served; hidden by default) AIModel( id: "magistral-medium-latest", provider: .mistral, displayName: "Magistral Medium", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 5.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "devstral-latest", provider: .mistral, displayName: "Devstral 2", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 2.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "open-mistral-nemo", provider: .mistral, displayName: "Mistral Nemo", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.15), parameterSupport: .openAIDefault, isLegacy: true ), ] // MARK: - Google Gemini static let gemini: [AIModel] = [ AIModel( id: "gemini-3.6-flash", provider: .gemini, displayName: "Gemini 3.6 Flash", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 7.50), parameterSupport: ParameterSupport(reasoningEffort: true), isRecommended: true ), AIModel( id: "gemini-3.5-flash", provider: .gemini, displayName: "Gemini 3.5 Flash", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 9.00), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemini-3.5-flash-lite", provider: .gemini, displayName: "Gemini 3.5 Flash-Lite", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50), parameterSupport: ParameterSupport(reasoningEffort: true), isRecommended: true ), AIModel( id: "gemini-3.1-pro-preview", provider: .gemini, displayName: "Gemini 3.1 Pro (Preview)", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 12.00), parameterSupport: ParameterSupport(reasoningEffort: true), isRecommended: true ), AIModel( id: "gemini-3.1-flash-lite", provider: .gemini, displayName: "Gemini 3.1 Flash-Lite", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 1.50), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemini-2.5-pro", provider: .gemini, displayName: "Gemini 2.5 Pro", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemini-2.5-flash", provider: .gemini, displayName: "Gemini 2.5 Flash", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemini-2.5-flash-lite", provider: .gemini, displayName: "Gemini 2.5 Flash-Lite", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.40), parameterSupport: ParameterSupport(reasoningEffort: true) ), // Rolling aliases (auto-track the latest release; pricing varies with target) AIModel( id: "gemini-pro-latest", provider: .gemini, displayName: "Gemini Pro (Latest)", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemini-flash-latest", provider: .gemini, displayName: "Gemini Flash (Latest)", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemini-flash-lite-latest", provider: .gemini, displayName: "Gemini Flash-Lite (Latest)", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(reasoningEffort: true) ), // Preview / secondary AIModel( id: "gemini-3-flash-preview", provider: .gemini, displayName: "Gemini 3 Flash (Preview)", contextWindow: 1_048_576, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 3.00), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "gemma-4-26b-a4b-it", provider: .gemini, displayName: "Gemma 4 26B", contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: ModelCapabilities(jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "gemma-4-31b-it", provider: .gemini, displayName: "Gemma 4 31B", contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: ModelCapabilities(jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), ] // MARK: - Alibaba Qwen (DashScope) static let qwen: [AIModel] = [ // Flagship commercial AIModel( id: "qwen3.7-max", provider: .qwen, displayName: "Qwen3.7 Max", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 7.50), parameterSupport: ParameterSupport(thinkingToggle: true), isRecommended: true ), AIModel( id: "qwen3.7-plus", provider: .qwen, displayName: "Qwen3.7 Plus", contextWindow: 1_000_000, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.32, outputPerMTok: 1.28), parameterSupport: ParameterSupport(thinkingToggle: true), isRecommended: true ), AIModel( id: "qwen3.7-flash", provider: .qwen, displayName: "Qwen3.7 Flash", contextWindow: 1_000_000, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.03, outputPerMTok: 0.13), parameterSupport: ParameterSupport(thinkingToggle: true), isRecommended: true ), AIModel( id: "qwen3.6-plus", provider: .qwen, displayName: "Qwen3.6 Plus", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3.6-flash", provider: .qwen, displayName: "Qwen3.6 Flash", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3.5-plus", provider: .qwen, displayName: "Qwen3.5 Plus", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3.5-flash", provider: .qwen, displayName: "Qwen3.5 Flash", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), // Stable aliases (previous-gen commercial) AIModel( id: "qwen-max", provider: .qwen, displayName: "Qwen Max", contextWindow: 128_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen-plus", provider: .qwen, displayName: "Qwen Plus", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen-turbo", provider: .qwen, displayName: "Qwen Turbo", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true), isLegacy: true ), AIModel( id: "qwen-flash", provider: .qwen, displayName: "Qwen Flash", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), // Coder family AIModel( id: "qwen3-coder-plus", provider: .qwen, displayName: "Qwen3 Coder Plus", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-coder-flash", provider: .qwen, displayName: "Qwen3 Coder Flash", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-coder-next", provider: .qwen, displayName: "Qwen3 Coder Next", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-coder-480b-a35b-instruct", provider: .qwen, displayName: "Qwen3 Coder 480B A35B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), // Vision-language AIModel( id: "qwen3-vl-plus", provider: .qwen, displayName: "Qwen3 VL Plus", contextWindow: 1_000_000, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3-vl-flash", provider: .qwen, displayName: "Qwen3 VL Flash", contextWindow: 1_000_000, maxOutputTokens: 65_536, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3-vl-235b-a22b-instruct", provider: .qwen, displayName: "Qwen3 VL 235B Instruct", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-vl-235b-a22b-thinking", provider: .qwen, displayName: "Qwen3 VL 235B Thinking", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qvq-max", provider: .qwen, displayName: "QVQ Max", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(requiresStreaming: true) ), // Reasoning-only AIModel( id: "qwq-plus", provider: .qwen, displayName: "QwQ Plus", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(requiresStreaming: true) ), // Open-weights Qwen hosted on DashScope AIModel( id: "qwen3.5-397b-a17b", provider: .qwen, displayName: "Qwen3.5 397B A17B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3.5-122b-a10b", provider: .qwen, displayName: "Qwen3.5 122B A10B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3.5-35b-a3b", provider: .qwen, displayName: "Qwen3.5 35B A3B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "qwen3-235b-a22b-instruct-2507", provider: .qwen, displayName: "Qwen3 235B Instruct 2507", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-235b-a22b-thinking-2507", provider: .qwen, displayName: "Qwen3 235B Thinking 2507", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-next-80b-a3b-instruct", provider: .qwen, displayName: "Qwen3 Next 80B Instruct", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), AIModel( id: "qwen3-next-80b-a3b-thinking", provider: .qwen, displayName: "Qwen3 Next 80B Thinking", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport() ), // Third-party models hosted on DashScope AIModel( id: "deepseek-v4-pro", provider: .qwen, displayName: "DeepSeek V4 Pro (DashScope)", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "deepseek-v4-flash", provider: .qwen, displayName: "DeepSeek V4 Flash (DashScope)", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "glm-5.2", provider: .qwen, displayName: "GLM 5.2 (DashScope)", contextWindow: 198_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), AIModel( id: "kimi-k2.7-code", provider: .qwen, displayName: "Kimi K2.7 Code (DashScope)", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: nil, parameterSupport: ParameterSupport(thinkingToggle: true) ), ] // MARK: - DeepSeek static let deepseek: [AIModel] = [ AIModel( id: "deepseek-v4-flash", provider: .deepseek, displayName: "DeepSeek V4 Flash", contextWindow: 1_000_000, maxOutputTokens: 384_000, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.14, outputPerMTok: 0.28), parameterSupport: ParameterSupport(reasoningEffort: true, thinkingToggle: true), isRecommended: true ), AIModel( id: "deepseek-v4-pro", provider: .deepseek, displayName: "DeepSeek V4 Pro", contextWindow: 1_000_000, maxOutputTokens: 384_000, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.435, outputPerMTok: 0.87), parameterSupport: ParameterSupport(reasoningEffort: true, thinkingToggle: true), isRecommended: true ), ] // MARK: - Kimi (Moonshot AI) static let kimi: [AIModel] = [ AIModel( id: "kimi-k3", provider: .kimi, displayName: "Kimi K3", contextWindow: 1_048_576, maxOutputTokens: 131_072, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00), // Thinking always on with preserved thinking; depth via reasoning_effort. parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true, reasoningEffort: true), isRecommended: true ), AIModel( id: "kimi-k2.7-code", provider: .kimi, displayName: "Kimi K2.7 Code", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.95, outputPerMTok: 4.00), parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true), isRecommended: true ), AIModel( id: "kimi-k2.7-code-highspeed", provider: .kimi, displayName: "Kimi K2.7 Code Highspeed", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.90, outputPerMTok: 8.00), parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true) ), AIModel( id: "kimi-k2.6", provider: .kimi, displayName: "Kimi K2.6", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.95, outputPerMTok: 4.00), parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true, thinkingToggle: true) ), AIModel( id: "kimi-k2.5", provider: .kimi, displayName: "Kimi K2.5", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.60, outputPerMTok: 3.00), parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true, thinkingToggle: true) ), // Legacy moonshot-v1 "classic" series (temperature capped at 1.0) AIModel( id: "moonshot-v1-8k", provider: .kimi, displayName: "Moonshot v1 8K", contextWindow: 8_192, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 2.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "moonshot-v1-32k", provider: .kimi, displayName: "Moonshot v1 32K", contextWindow: 32_768, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 3.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "moonshot-v1-128k", provider: .kimi, displayName: "Moonshot v1 128K", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 5.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "moonshot-v1-auto", provider: .kimi, displayName: "Moonshot v1 Auto", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: nil, parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "moonshot-v1-8k-vision-preview", provider: .kimi, displayName: "Moonshot v1 8K Vision", contextWindow: 8_192, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 2.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "moonshot-v1-32k-vision-preview", provider: .kimi, displayName: "Moonshot v1 32K Vision", contextWindow: 32_768, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 3.00), parameterSupport: .openAIDefault, isLegacy: true ), AIModel( id: "moonshot-v1-128k-vision-preview", provider: .kimi, displayName: "Moonshot v1 128K Vision", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 5.00), parameterSupport: .openAIDefault, isLegacy: true ), ] // MARK: - Perplexity static let perplexity: [AIModel] = [ AIModel( id: "sonar", provider: .perplexity, displayName: "Sonar", contextWindow: 128_000, maxOutputTokens: 128_000, capabilities: ModelCapabilities(jsonMode: true, citations: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 1.00), parameterSupport: ParameterSupport(), isRecommended: true ), AIModel( id: "sonar-pro", provider: .perplexity, displayName: "Sonar Pro", contextWindow: 200_000, maxOutputTokens: 8_000, capabilities: ModelCapabilities(jsonMode: true, citations: true), pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00), parameterSupport: ParameterSupport(), isRecommended: true ), AIModel( id: "sonar-reasoning-pro", provider: .perplexity, displayName: "Sonar Reasoning Pro", contextWindow: 128_000, maxOutputTokens: nil, capabilities: ModelCapabilities(reasoning: true, jsonMode: true, citations: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00), parameterSupport: ParameterSupport(reasoningEffort: true) ), AIModel( id: "sonar-deep-research", provider: .perplexity, displayName: "Sonar Deep Research", contextWindow: 128_000, maxOutputTokens: nil, capabilities: ModelCapabilities(reasoning: true, jsonMode: true, citations: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00), parameterSupport: ParameterSupport(reasoningEffort: true) ), ] // MARK: - Together AI static let together: [AIModel] = [ AIModel( id: "moonshotai/Kimi-K3", provider: .together, displayName: "Kimi K3", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00), parameterSupport: .openAIDefault, isRecommended: true ), AIModel( id: "moonshotai/Kimi-K2.7-Code", provider: .together, displayName: "Kimi K2.7 Code", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.95, outputPerMTok: 4.00), parameterSupport: .openAIDefault ), AIModel( id: "moonshotai/Kimi-K2.6", provider: .together, displayName: "Kimi K2.6", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.20, outputPerMTok: 4.50), parameterSupport: .openAIDefault ), AIModel( id: "deepseek-ai/DeepSeek-V4-Pro", provider: .together, displayName: "DeepSeek V4 Pro", contextWindow: 512_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.74, outputPerMTok: 3.48), parameterSupport: .openAIDefault, isRecommended: true ), AIModel( id: "zai-org/GLM-5.2", provider: .together, displayName: "GLM 5.2", contextWindow: 512_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.40, outputPerMTok: 4.40), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3.7-Max", provider: .together, displayName: "Qwen3.7 Max", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 3.75), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) ), AIModel( id: "Qwen/Qwen3.7-Plus", provider: .together, displayName: "Qwen3.7 Plus", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.32, outputPerMTok: 1.28), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) ), AIModel( id: "Qwen/Qwen3.6-Plus", provider: .together, displayName: "Qwen3.6 Plus", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 3.00), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) ), AIModel( id: "Qwen/Qwen3.5-9B", provider: .together, displayName: "Qwen3.5 9B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.17, outputPerMTok: 0.25), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) ), AIModel( id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", provider: .together, displayName: "Llama 3.3 70B Turbo", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.04, outputPerMTok: 1.04), parameterSupport: .openAIDefault ), AIModel( id: "openai/gpt-oss-120b", provider: .together, displayName: "GPT-OSS 120B", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true), isRecommended: true ), AIModel( id: "openai/gpt-oss-20b", provider: .together, displayName: "GPT-OSS 20B", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.05, outputPerMTok: 0.20), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true) ), AIModel( id: "nvidia/nemotron-3-ultra-550b-a55b", provider: .together, displayName: "Nemotron 3 Ultra 550B", contextWindow: 512_288, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.60, outputPerMTok: 3.60), parameterSupport: .openAIDefault ), AIModel( id: "MiniMaxAI/MiniMax-M3", provider: .together, displayName: "MiniMax M3", contextWindow: 524_288, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.20), parameterSupport: .openAIDefault ), AIModel( // vision disabled 2026-07-30: Together's endpoint accepts image // input but streams an empty answer (verified live) — text only. id: "google/gemma-4-31B-it", provider: .together, displayName: "Gemma 4 31B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: false, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.39, outputPerMTok: 0.97), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) ), AIModel( id: "thinkingmachines/Inkling", provider: .together, displayName: "Inkling", contextWindow: 524_288, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 4.05), parameterSupport: .openAIDefault ), ] // MARK: - DeepInfra static let deepinfra: [AIModel] = [ // Proxied frontier models (Claude / Gemini under DeepInfra billing) AIModel( id: "anthropic/claude-fable-5", provider: .deepinfra, displayName: "Claude Fable 5", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 50.00), parameterSupport: ParameterSupport() ), AIModel( id: "anthropic/claude-opus-5", provider: .deepinfra, displayName: "Claude Opus 5", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport() ), AIModel( id: "anthropic/claude-sonnet-5", provider: .deepinfra, displayName: "Claude Sonnet 5", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 10.00), parameterSupport: ParameterSupport() ), AIModel( id: "anthropic/claude-opus-4-8", provider: .deepinfra, displayName: "Claude Opus 4.8", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), parameterSupport: ParameterSupport() ), AIModel( id: "anthropic/claude-haiku-4-5", provider: .deepinfra, displayName: "Claude Haiku 4.5", contextWindow: 200_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 5.00), parameterSupport: ParameterSupport() ), AIModel( id: "google/gemini-3.1-pro", provider: .deepinfra, displayName: "Gemini 3.1 Pro", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 12.00), parameterSupport: ParameterSupport() ), AIModel( id: "google/gemini-3.5-flash", provider: .deepinfra, displayName: "Gemini 3.5 Flash", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 9.00), parameterSupport: ParameterSupport() ), AIModel( id: "google/gemini-3.1-flash-lite", provider: .deepinfra, displayName: "Gemini 3.1 Flash-Lite", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 1.50), parameterSupport: ParameterSupport() ), AIModel( id: "google/gemini-2.5-pro", provider: .deepinfra, displayName: "Gemini 2.5 Pro", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00), parameterSupport: ParameterSupport() ), AIModel( id: "google/gemini-2.5-flash", provider: .deepinfra, displayName: "Gemini 2.5 Flash", contextWindow: 1_000_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50), parameterSupport: ParameterSupport() ), // Open-weight chat models AIModel( id: "deepseek-ai/DeepSeek-V4-Pro", provider: .deepinfra, displayName: "DeepSeek V4 Pro", contextWindow: 1_048_576, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 1.30, outputPerMTok: 2.60), parameterSupport: .openAIDefault, isRecommended: true ), AIModel( id: "deepseek-ai/DeepSeek-V4-Flash", provider: .deepinfra, displayName: "DeepSeek V4 Flash", contextWindow: 1_048_576, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.09, outputPerMTok: 0.18), parameterSupport: .openAIDefault, isRecommended: true ), AIModel( id: "deepseek-ai/DeepSeek-V3.1", provider: .deepinfra, displayName: "DeepSeek V3.1", contextWindow: 163_840, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 0.95), parameterSupport: .openAIDefault ), AIModel( id: "deepseek-ai/DeepSeek-R1-0528", provider: .deepinfra, displayName: "DeepSeek R1 0528", contextWindow: 163_840, maxOutputTokens: nil, capabilities: ModelCapabilities(reasoning: true), pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 2.15), parameterSupport: .openAIDefault ), AIModel( id: "moonshotai/Kimi-K2.7-Code", provider: .deepinfra, displayName: "Kimi K2.7 Code", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.74, outputPerMTok: 3.50), parameterSupport: .openAIDefault ), AIModel( id: "moonshotai/Kimi-K2.6", provider: .deepinfra, displayName: "Kimi K2.6", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 3.50), parameterSupport: .openAIDefault ), AIModel( id: "moonshotai/Kimi-K2.5", provider: .deepinfra, displayName: "Kimi K2.5", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.45, outputPerMTok: 2.25), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) ), AIModel( id: "zai-org/GLM-5.2", provider: .deepinfra, displayName: "GLM 5.2", contextWindow: 1_048_576, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 2.40), parameterSupport: .openAIDefault, isRecommended: true ), AIModel( id: "zai-org/GLM-4.7", provider: .deepinfra, displayName: "GLM 4.7", contextWindow: 202_752, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 1.75), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3.7-Max", provider: .deepinfra, displayName: "Qwen3.7 Max", contextWindow: 256_000, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 7.50), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3.5-397B-A17B", provider: .deepinfra, displayName: "Qwen3.5 397B A17B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.45, outputPerMTok: 3.00), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3-235B-A22B-Instruct-2507", provider: .deepinfra, displayName: "Qwen3 235B Instruct 2507", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.09, outputPerMTok: 0.55), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3-235B-A22B-Thinking-2507", provider: .deepinfra, displayName: "Qwen3 235B Thinking 2507", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.23, outputPerMTok: 2.30), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo", provider: .deepinfra, displayName: "Qwen3 Coder 480B Turbo", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.00), parameterSupport: .openAIDefault ), AIModel( id: "Qwen/Qwen3-VL-235B-A22B-Instruct", provider: .deepinfra, displayName: "Qwen3 VL 235B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.88), parameterSupport: .openAIDefault ), AIModel( id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", provider: .deepinfra, displayName: "Llama 4 Maverick", contextWindow: 1_048_576, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.80), parameterSupport: .openAIDefault ), AIModel( id: "meta-llama/Llama-4-Scout-17B-16E-Instruct", provider: .deepinfra, displayName: "Llama 4 Scout", contextWindow: 327_680, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.30), parameterSupport: .openAIDefault ), AIModel( id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", provider: .deepinfra, displayName: "Llama 3.3 70B Turbo", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.32), parameterSupport: .openAIDefault ), AIModel( id: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", provider: .deepinfra, displayName: "Llama 3.1 8B Turbo", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.02, outputPerMTok: 0.04), parameterSupport: .openAIDefault ), AIModel( id: "openai/gpt-oss-120b", provider: .deepinfra, displayName: "GPT-OSS 120B", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.037, outputPerMTok: 0.17), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true), isRecommended: true ), AIModel( id: "openai/gpt-oss-20b", provider: .deepinfra, displayName: "GPT-OSS 20B", contextWindow: 131_072, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.03, outputPerMTok: 0.14), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true) ), AIModel( id: "MiniMaxAI/MiniMax-M3", provider: .deepinfra, displayName: "MiniMax M3", contextWindow: 524_288, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.20), parameterSupport: .openAIDefault ), AIModel( id: "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B", provider: .deepinfra, displayName: "Nemotron 3 Ultra 550B", contextWindow: 262_144, maxOutputTokens: nil, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 2.20), parameterSupport: .openAIDefault ), AIModel( id: "mistralai/Mistral-Small-3.2-24B-Instruct-2506", provider: .deepinfra, displayName: "Mistral Small 3.2 24B", contextWindow: 128_000, maxOutputTokens: nil, capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.075, outputPerMTok: 0.20), parameterSupport: .openAIDefault ), // google/gemma-4-31B-it removed 2026-07-30: endpoint hangs (60s+, zero // bytes) on chat completions — see docs/PROVIDERS.md Phase 7 amendments. ] // MARK: - Cerebras static let cerebras: [AIModel] = [ AIModel( id: "gpt-oss-120b", provider: .cerebras, displayName: "GPT-OSS 120B", contextWindow: 131_072, maxOutputTokens: 40_000, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.35, outputPerMTok: 0.75), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true), isRecommended: true ), AIModel( id: "gemma-4-31b", provider: .cerebras, displayName: "Gemma 4 31B", contextWindow: 131_072, maxOutputTokens: 40_000, capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 0.99, outputPerMTok: 1.49), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true) ), AIModel( id: "zai-glm-4.7", provider: .cerebras, displayName: "GLM 4.7", contextWindow: 131_072, maxOutputTokens: 40_000, capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), pricing: ModelPricing(inputPerMTok: 2.25, outputPerMTok: 2.75), parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true), // Scheduled for discontinuation on 2026-08-17. isLegacy: true ), ] // MARK: - All providers static let all: [AIModel] = openai + anthropic + xai + mistral + gemini + qwen + deepseek + kimi + perplexity + together + deepinfra + cerebras }