SPB Git

spb/zyquo-atlas Public License

The AI-native macOS web browser — every surface, intelligent.

Swift 75.2% JavaScript 22% Shell 2% Makefile 0.9%
71.6 KB · 1,361 lines swift
Raw Blame History
1//2//  ModelCatalogData.swift3//  Zyquo Atlas4//5//  Author: Simon-Pierre Boucher6//  Mail: contact@spboucher.ai7//8//  Built-in model catalog, generated from docs/PROVIDERS.md and the per-provider9//  research files in docs/research/ on 2026-07-30. This file and docs/PROVIDERS.md10//  are a single source of truth and MUST stay in sync: when Phase 7 verification11//  (or any later research pass) changes a model, update both together.12//13//  Scope: chat-completions-capable chat models only. Embeddings, audio/TTS/ASR,14//  realtime, image/video generation, moderation, OCR, robotics, deep-research15//  agents, and Responses-API-only models are excluded by design.16//1718import Foundation1920enum ModelCatalogData {2122    // MARK: - Shared parameter-support presets2324    /// OpenAI reasoning models (o-series, gpt-5.x reasoning variants): reject25    /// temperature/top_p/penalties, require max_completion_tokens, accept reasoning_effort.26    private static let openAIReasoning = ParameterSupport(27        temperature: false, topP: false,28        usesMaxCompletionTokens: true, reasoningEffort: true29    )3031    // MARK: - OpenAI3233    static let openai: [AIModel] = [34        // Flagship GPT-5.6 trio35        AIModel(36            id: "gpt-5.6-sol", provider: .openai, displayName: "GPT-5.6 Sol",37            contextWindow: 1_050_000, maxOutputTokens: 128_000,38            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),39            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 30.00),40            parameterSupport: openAIReasoning,41            isRecommended: true42        ),43        AIModel(44            id: "gpt-5.6-terra", provider: .openai, displayName: "GPT-5.6 Terra",45            contextWindow: 1_050_000, maxOutputTokens: 128_000,46            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),47            pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 15.00),48            parameterSupport: openAIReasoning,49            isRecommended: true50        ),51        AIModel(52            id: "gpt-5.6-luna", provider: .openai, displayName: "GPT-5.6 Luna",53            contextWindow: 1_050_000, maxOutputTokens: 128_000,54            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),55            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 6.00),56            parameterSupport: openAIReasoning57        ),58        AIModel(59            id: "chat-latest", provider: .openai, displayName: "ChatGPT Latest",60            contextWindow: 128_000, maxOutputTokens: nil,61            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),62            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 30.00),63            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true)64        ),65        // Current / recent GPT-5.x66        AIModel(67            id: "gpt-5.5", provider: .openai, displayName: "GPT-5.5",68            contextWindow: 400_000, maxOutputTokens: nil,69            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),70            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 30.00),71            parameterSupport: openAIReasoning72        ),73        AIModel(74            id: "gpt-5.4", provider: .openai, displayName: "GPT-5.4",75            contextWindow: 400_000, maxOutputTokens: 128_000,76            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),77            pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 15.00),78            parameterSupport: openAIReasoning79        ),80        AIModel(81            id: "gpt-5.4-mini", provider: .openai, displayName: "GPT-5.4 mini",82            contextWindow: 400_000, maxOutputTokens: nil,83            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),84            pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 4.50),85            parameterSupport: openAIReasoning86        ),87        AIModel(88            id: "gpt-5.4-nano", provider: .openai, displayName: "GPT-5.4 nano",89            contextWindow: 400_000, maxOutputTokens: nil,90            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),91            pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 1.25),92            parameterSupport: openAIReasoning93        ),94        AIModel(95            id: "gpt-5.3-chat-latest", provider: .openai, displayName: "GPT-5.3 Chat Latest",96            contextWindow: 128_000, maxOutputTokens: nil,97            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),98            pricing: nil,99            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true)100        ),101        AIModel(102            id: "gpt-5.2", provider: .openai, displayName: "GPT-5.2",103            contextWindow: 400_000, maxOutputTokens: 128_000,104            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),105            pricing: ModelPricing(inputPerMTok: 1.75, outputPerMTok: 14.00),106            parameterSupport: openAIReasoning107        ),108        AIModel(109            id: "gpt-5.2-chat-latest", provider: .openai, displayName: "GPT-5.2 Chat Latest",110            contextWindow: 128_000, maxOutputTokens: 16_000,111            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),112            pricing: ModelPricing(inputPerMTok: 1.75, outputPerMTok: 14.00),113            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true)114        ),115        AIModel(116            id: "gpt-5.1", provider: .openai, displayName: "GPT-5.1",117            contextWindow: 400_000, maxOutputTokens: 128_000,118            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),119            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00),120            parameterSupport: openAIReasoning121        ),122        AIModel(123            id: "gpt-5", provider: .openai, displayName: "GPT-5",124            contextWindow: 400_000, maxOutputTokens: 128_000,125            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),126            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00),127            parameterSupport: openAIReasoning128        ),129        AIModel(130            id: "gpt-5-mini", provider: .openai, displayName: "GPT-5 mini",131            contextWindow: 400_000, maxOutputTokens: 128_000,132            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),133            pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 2.00),134            parameterSupport: openAIReasoning135        ),136        AIModel(137            id: "gpt-5-nano", provider: .openai, displayName: "GPT-5 nano",138            contextWindow: 400_000, maxOutputTokens: 128_000,139            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),140            pricing: ModelPricing(inputPerMTok: 0.05, outputPerMTok: 0.40),141            parameterSupport: openAIReasoning142        ),143        // o-series reasoning144        AIModel(145            id: "o3", provider: .openai, displayName: "OpenAI o3",146            contextWindow: 200_000, maxOutputTokens: 100_000,147            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),148            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00),149            parameterSupport: openAIReasoning150        ),151        AIModel(152            id: "o4-mini", provider: .openai, displayName: "OpenAI o4-mini",153            contextWindow: 200_000, maxOutputTokens: 100_000,154            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),155            pricing: ModelPricing(inputPerMTok: 1.10, outputPerMTok: 4.40),156            parameterSupport: openAIReasoning157        ),158        AIModel(159            id: "o3-mini", provider: .openai, displayName: "OpenAI o3-mini",160            contextWindow: 200_000, maxOutputTokens: 100_000,161            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),162            pricing: ModelPricing(inputPerMTok: 1.10, outputPerMTok: 4.40),163            parameterSupport: openAIReasoning,164            isLegacy: true165        ),166        AIModel(167            id: "o1", provider: .openai, displayName: "OpenAI o1",168            contextWindow: 200_000, maxOutputTokens: 100_000,169            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),170            pricing: ModelPricing(inputPerMTok: 15.00, outputPerMTok: 60.00),171            parameterSupport: openAIReasoning,172            isLegacy: true173        ),174        // Legacy GPT-4.x / 3.5175        AIModel(176            id: "gpt-4.1", provider: .openai, displayName: "GPT-4.1",177            contextWindow: 1_047_576, maxOutputTokens: 32_768,178            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),179            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00),180            parameterSupport: .openAIDefault,181            isLegacy: true182        ),183        AIModel(184            id: "gpt-4.1-mini", provider: .openai, displayName: "GPT-4.1 mini",185            contextWindow: 1_047_576, maxOutputTokens: 32_768,186            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),187            pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 1.60),188            parameterSupport: .openAIDefault,189            isLegacy: true190        ),191        AIModel(192            id: "gpt-4.1-nano", provider: .openai, displayName: "GPT-4.1 nano",193            contextWindow: 1_047_576, maxOutputTokens: 32_768,194            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),195            pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.40),196            parameterSupport: .openAIDefault,197            isLegacy: true198        ),199        AIModel(200            id: "gpt-4o", provider: .openai, displayName: "GPT-4o",201            contextWindow: 128_000, maxOutputTokens: 16_384,202            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),203            pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 10.00),204            parameterSupport: .openAIDefault,205            isLegacy: true206        ),207        AIModel(208            id: "gpt-4o-mini", provider: .openai, displayName: "GPT-4o mini",209            contextWindow: 128_000, maxOutputTokens: 16_384,210            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),211            pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60),212            parameterSupport: .openAIDefault,213            isLegacy: true214        ),215        AIModel(216            id: "gpt-4-turbo", provider: .openai, displayName: "GPT-4 Turbo",217            contextWindow: 128_000, maxOutputTokens: 4_096,218            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),219            pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 30.00),220            parameterSupport: .openAIDefault,221            isLegacy: true222        ),223        AIModel(224            id: "gpt-4", provider: .openai, displayName: "GPT-4",225            contextWindow: 8_192, maxOutputTokens: 8_192,226            capabilities: ModelCapabilities(tools: true),227            pricing: ModelPricing(inputPerMTok: 30.00, outputPerMTok: 60.00),228            parameterSupport: .openAIDefault,229            isLegacy: true230        ),231        AIModel(232            id: "gpt-3.5-turbo", provider: .openai, displayName: "GPT-3.5 Turbo",233            contextWindow: 16_385, maxOutputTokens: 4_096,234            capabilities: ModelCapabilities(tools: true, jsonMode: true),235            pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 1.50),236            parameterSupport: .openAIDefault,237            isLegacy: true238        ),239    ]240241    // MARK: - Anthropic242243    static let anthropic: [AIModel] = [244        AIModel(245            id: "claude-opus-5", provider: .anthropic, displayName: "Claude Opus 5",246            contextWindow: 1_000_000, maxOutputTokens: 128_000,247            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),248            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),249            parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true),250            isRecommended: true251        ),252        AIModel(253            id: "claude-sonnet-5", provider: .anthropic, displayName: "Claude Sonnet 5",254            contextWindow: 1_000_000, maxOutputTokens: 128_000,255            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),256            pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00),257            parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true),258            isRecommended: true259        ),260        AIModel(261            id: "claude-fable-5", provider: .anthropic, displayName: "Claude Fable 5",262            contextWindow: 1_000_000, maxOutputTokens: 128_000,263            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),264            pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 50.00),265            // Thinking is always on and cannot be disabled — no toggle.266            parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: false)267        ),268        AIModel(269            id: "claude-opus-4-8", provider: .anthropic, displayName: "Claude Opus 4.8",270            contextWindow: 1_000_000, maxOutputTokens: 128_000,271            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),272            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),273            parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true)274        ),275        AIModel(276            id: "claude-opus-4-7", provider: .anthropic, displayName: "Claude Opus 4.7",277            contextWindow: 1_000_000, maxOutputTokens: 128_000,278            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),279            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),280            parameterSupport: ParameterSupport(temperature: false, topP: false, thinkingToggle: true)281        ),282        AIModel(283            id: "claude-opus-4-6", provider: .anthropic, displayName: "Claude Opus 4.6",284            contextWindow: 1_000_000, maxOutputTokens: 128_000,285            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),286            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),287            parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true)288        ),289        AIModel(290            id: "claude-sonnet-4-6", provider: .anthropic, displayName: "Claude Sonnet 4.6",291            contextWindow: 1_000_000, maxOutputTokens: 128_000,292            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),293            pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00),294            parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true)295        ),296        AIModel(297            id: "claude-haiku-4-5-20251001", provider: .anthropic, displayName: "Claude Haiku 4.5",298            contextWindow: 200_000, maxOutputTokens: 64_000,299            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),300            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 5.00),301            parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true)302        ),303        AIModel(304            id: "claude-opus-4-5-20251101", provider: .anthropic, displayName: "Claude Opus 4.5",305            contextWindow: 200_000, maxOutputTokens: 64_000,306            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),307            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),308            parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true),309            isLegacy: true310        ),311        AIModel(312            id: "claude-sonnet-4-5-20250929", provider: .anthropic, displayName: "Claude Sonnet 4.5",313            contextWindow: 1_000_000, maxOutputTokens: 64_000,314            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),315            pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00),316            parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true),317            isLegacy: true318        ),319        AIModel(320            id: "claude-opus-4-1-20250805", provider: .anthropic, displayName: "Claude Opus 4.1",321            contextWindow: 200_000, maxOutputTokens: 32_000,322            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),323            pricing: ModelPricing(inputPerMTok: 15.00, outputPerMTok: 75.00),324            parameterSupport: ParameterSupport(temperature: true, topP: true, thinkingToggle: true),325            isLegacy: true326        ),327    ]328329    // MARK: - xAI (Grok)330331    static let xai: [AIModel] = [332        AIModel(333            id: "grok-4.5", provider: .xai, displayName: "Grok 4.5",334            contextWindow: 500_000, maxOutputTokens: nil,335            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),336            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 6.00),337            parameterSupport: ParameterSupport(reasoningEffort: true),338            isRecommended: true339        ),340        AIModel(341            id: "grok-4.3", provider: .xai, displayName: "Grok 4.3",342            contextWindow: 1_000_000, maxOutputTokens: nil,343            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),344            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 2.50),345            parameterSupport: ParameterSupport(reasoningEffort: true)346        ),347        AIModel(348            id: "grok-4.20", provider: .xai, displayName: "Grok 4.20 Reasoning",349            contextWindow: 1_000_000, maxOutputTokens: nil,350            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),351            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 2.50),352            parameterSupport: ParameterSupport()353        ),354        AIModel(355            id: "grok-4.20-non-reasoning", provider: .xai, displayName: "Grok 4.20 Non-Reasoning",356            contextWindow: 1_000_000, maxOutputTokens: nil,357            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),358            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 2.50),359            parameterSupport: ParameterSupport()360        ),361        AIModel(362            id: "grok-code-fast-1", provider: .xai, displayName: "Grok Code Fast 1",363            contextWindow: 256_000, maxOutputTokens: nil,364            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),365            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 2.00),366            parameterSupport: ParameterSupport(),367            isRecommended: true368        ),369    ]370371    // MARK: - Mistral372373    static let mistral: [AIModel] = [374        AIModel(375            id: "mistral-medium-latest", provider: .mistral, displayName: "Mistral Medium 3.5",376            contextWindow: 262_144, maxOutputTokens: nil,377            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),378            pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 7.50),379            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true),380            isRecommended: true381        ),382        AIModel(383            id: "mistral-large-latest", provider: .mistral, displayName: "Mistral Large 3",384            contextWindow: 262_144, maxOutputTokens: nil,385            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),386            pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 1.50),387            parameterSupport: .openAIDefault,388            isRecommended: true389        ),390        AIModel(391            id: "mistral-small-latest", provider: .mistral, displayName: "Mistral Small 4",392            contextWindow: 262_144, maxOutputTokens: nil,393            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),394            pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60),395            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true),396            isRecommended: true397        ),398        AIModel(399            id: "codestral-latest", provider: .mistral, displayName: "Codestral",400            contextWindow: 256_000, maxOutputTokens: nil,401            capabilities: ModelCapabilities(tools: true, jsonMode: true),402            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 0.90),403            parameterSupport: .openAIDefault404        ),405        AIModel(406            id: "ministral-14b-latest", provider: .mistral, displayName: "Ministral 3 14B",407            contextWindow: 262_144, maxOutputTokens: nil,408            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),409            pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.20),410            parameterSupport: .openAIDefault411        ),412        AIModel(413            id: "ministral-8b-latest", provider: .mistral, displayName: "Ministral 3 8B",414            contextWindow: 262_144, maxOutputTokens: nil,415            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),416            pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.15),417            parameterSupport: .openAIDefault418        ),419        AIModel(420            id: "ministral-3b-latest", provider: .mistral, displayName: "Ministral 3 3B",421            contextWindow: 131_072, maxOutputTokens: nil,422            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),423            pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.10),424            parameterSupport: .openAIDefault425        ),426        // Legacy / deprecated (still served; hidden by default)427        AIModel(428            id: "magistral-medium-latest", provider: .mistral, displayName: "Magistral Medium",429            contextWindow: 131_072, maxOutputTokens: nil,430            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),431            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 5.00),432            parameterSupport: .openAIDefault,433            isLegacy: true434        ),435        AIModel(436            id: "devstral-latest", provider: .mistral, displayName: "Devstral 2",437            contextWindow: 262_144, maxOutputTokens: nil,438            capabilities: ModelCapabilities(tools: true, jsonMode: true),439            pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 2.00),440            parameterSupport: .openAIDefault,441            isLegacy: true442        ),443        AIModel(444            id: "open-mistral-nemo", provider: .mistral, displayName: "Mistral Nemo",445            contextWindow: 131_072, maxOutputTokens: nil,446            capabilities: ModelCapabilities(tools: true, jsonMode: true),447            pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.15),448            parameterSupport: .openAIDefault,449            isLegacy: true450        ),451    ]452453    // MARK: - Google Gemini454455    static let gemini: [AIModel] = [456        AIModel(457            id: "gemini-3.6-flash", provider: .gemini, displayName: "Gemini 3.6 Flash",458            contextWindow: 1_048_576, maxOutputTokens: 65_536,459            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),460            pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 7.50),461            parameterSupport: ParameterSupport(reasoningEffort: true),462            isRecommended: true463        ),464        AIModel(465            id: "gemini-3.5-flash", provider: .gemini, displayName: "Gemini 3.5 Flash",466            contextWindow: 1_048_576, maxOutputTokens: 65_536,467            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),468            pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 9.00),469            parameterSupport: ParameterSupport(reasoningEffort: true)470        ),471        AIModel(472            id: "gemini-3.5-flash-lite", provider: .gemini, displayName: "Gemini 3.5 Flash-Lite",473            contextWindow: 1_048_576, maxOutputTokens: 65_536,474            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),475            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50),476            parameterSupport: ParameterSupport(reasoningEffort: true),477            isRecommended: true478        ),479        AIModel(480            id: "gemini-3.1-pro-preview", provider: .gemini, displayName: "Gemini 3.1 Pro (Preview)",481            contextWindow: 1_048_576, maxOutputTokens: 65_536,482            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),483            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 12.00),484            parameterSupport: ParameterSupport(reasoningEffort: true),485            isRecommended: true486        ),487        AIModel(488            id: "gemini-3.1-flash-lite", provider: .gemini, displayName: "Gemini 3.1 Flash-Lite",489            contextWindow: 1_048_576, maxOutputTokens: 65_536,490            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),491            pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 1.50),492            parameterSupport: ParameterSupport(reasoningEffort: true)493        ),494        AIModel(495            id: "gemini-2.5-pro", provider: .gemini, displayName: "Gemini 2.5 Pro",496            contextWindow: 1_048_576, maxOutputTokens: 65_536,497            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),498            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00),499            parameterSupport: ParameterSupport(reasoningEffort: true)500        ),501        AIModel(502            id: "gemini-2.5-flash", provider: .gemini, displayName: "Gemini 2.5 Flash",503            contextWindow: 1_048_576, maxOutputTokens: 65_536,504            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),505            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50),506            parameterSupport: ParameterSupport(reasoningEffort: true)507        ),508        AIModel(509            id: "gemini-2.5-flash-lite", provider: .gemini, displayName: "Gemini 2.5 Flash-Lite",510            contextWindow: 1_048_576, maxOutputTokens: 65_536,511            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),512            pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.40),513            parameterSupport: ParameterSupport(reasoningEffort: true)514        ),515        // Rolling aliases (auto-track the latest release; pricing varies with target)516        AIModel(517            id: "gemini-pro-latest", provider: .gemini, displayName: "Gemini Pro (Latest)",518            contextWindow: 1_048_576, maxOutputTokens: 65_536,519            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),520            pricing: nil,521            parameterSupport: ParameterSupport(reasoningEffort: true)522        ),523        AIModel(524            id: "gemini-flash-latest", provider: .gemini, displayName: "Gemini Flash (Latest)",525            contextWindow: 1_048_576, maxOutputTokens: 65_536,526            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),527            pricing: nil,528            parameterSupport: ParameterSupport(reasoningEffort: true)529        ),530        AIModel(531            id: "gemini-flash-lite-latest", provider: .gemini, displayName: "Gemini Flash-Lite (Latest)",532            contextWindow: 1_048_576, maxOutputTokens: 65_536,533            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),534            pricing: nil,535            parameterSupport: ParameterSupport(reasoningEffort: true)536        ),537        // Preview / secondary538        AIModel(539            id: "gemini-3-flash-preview", provider: .gemini, displayName: "Gemini 3 Flash (Preview)",540            contextWindow: 1_048_576, maxOutputTokens: 65_536,541            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),542            pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 3.00),543            parameterSupport: ParameterSupport(reasoningEffort: true)544        ),545        AIModel(546            id: "gemma-4-26b-a4b-it", provider: .gemini, displayName: "Gemma 4 26B",547            contextWindow: 262_144, maxOutputTokens: 32_768,548            capabilities: ModelCapabilities(jsonMode: true),549            pricing: nil,550            parameterSupport: ParameterSupport()551        ),552        AIModel(553            id: "gemma-4-31b-it", provider: .gemini, displayName: "Gemma 4 31B",554            contextWindow: 262_144, maxOutputTokens: 32_768,555            capabilities: ModelCapabilities(jsonMode: true),556            pricing: nil,557            parameterSupport: ParameterSupport()558        ),559    ]560561    // MARK: - Alibaba Qwen (DashScope)562563    static let qwen: [AIModel] = [564        // Flagship commercial565        AIModel(566            id: "qwen3.7-max", provider: .qwen, displayName: "Qwen3.7 Max",567            contextWindow: 1_000_000, maxOutputTokens: nil,568            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),569            pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 7.50),570            parameterSupport: ParameterSupport(thinkingToggle: true),571            isRecommended: true572        ),573        AIModel(574            id: "qwen3.7-plus", provider: .qwen, displayName: "Qwen3.7 Plus",575            contextWindow: 1_000_000, maxOutputTokens: 65_536,576            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),577            pricing: ModelPricing(inputPerMTok: 0.32, outputPerMTok: 1.28),578            parameterSupport: ParameterSupport(thinkingToggle: true),579            isRecommended: true580        ),581        AIModel(582            id: "qwen3.7-flash", provider: .qwen, displayName: "Qwen3.7 Flash",583            contextWindow: 1_000_000, maxOutputTokens: 65_536,584            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),585            pricing: ModelPricing(inputPerMTok: 0.03, outputPerMTok: 0.13),586            parameterSupport: ParameterSupport(thinkingToggle: true),587            isRecommended: true588        ),589        AIModel(590            id: "qwen3.6-plus", provider: .qwen, displayName: "Qwen3.6 Plus",591            contextWindow: 1_000_000, maxOutputTokens: nil,592            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),593            pricing: nil,594            parameterSupport: ParameterSupport(thinkingToggle: true)595        ),596        AIModel(597            id: "qwen3.6-flash", provider: .qwen, displayName: "Qwen3.6 Flash",598            contextWindow: 1_000_000, maxOutputTokens: nil,599            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),600            pricing: nil,601            parameterSupport: ParameterSupport(thinkingToggle: true)602        ),603        AIModel(604            id: "qwen3.5-plus", provider: .qwen, displayName: "Qwen3.5 Plus",605            contextWindow: 1_000_000, maxOutputTokens: nil,606            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),607            pricing: nil,608            parameterSupport: ParameterSupport(thinkingToggle: true)609        ),610        AIModel(611            id: "qwen3.5-flash", provider: .qwen, displayName: "Qwen3.5 Flash",612            contextWindow: 1_000_000, maxOutputTokens: nil,613            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),614            pricing: nil,615            parameterSupport: ParameterSupport(thinkingToggle: true)616        ),617        // Stable aliases (previous-gen commercial)618        AIModel(619            id: "qwen-max", provider: .qwen, displayName: "Qwen Max",620            contextWindow: 128_000, maxOutputTokens: nil,621            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),622            pricing: nil,623            parameterSupport: ParameterSupport(thinkingToggle: true)624        ),625        AIModel(626            id: "qwen-plus", provider: .qwen, displayName: "Qwen Plus",627            contextWindow: 1_000_000, maxOutputTokens: nil,628            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),629            pricing: nil,630            parameterSupport: ParameterSupport(thinkingToggle: true)631        ),632        AIModel(633            id: "qwen-turbo", provider: .qwen, displayName: "Qwen Turbo",634            contextWindow: 1_000_000, maxOutputTokens: nil,635            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),636            pricing: nil,637            parameterSupport: ParameterSupport(thinkingToggle: true),638            isLegacy: true639        ),640        AIModel(641            id: "qwen-flash", provider: .qwen, displayName: "Qwen Flash",642            contextWindow: 1_000_000, maxOutputTokens: nil,643            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),644            pricing: nil,645            parameterSupport: ParameterSupport(thinkingToggle: true)646        ),647        // Coder family648        AIModel(649            id: "qwen3-coder-plus", provider: .qwen, displayName: "Qwen3 Coder Plus",650            contextWindow: 1_000_000, maxOutputTokens: nil,651            capabilities: ModelCapabilities(tools: true, jsonMode: true),652            pricing: nil,653            parameterSupport: ParameterSupport()654        ),655        AIModel(656            id: "qwen3-coder-flash", provider: .qwen, displayName: "Qwen3 Coder Flash",657            contextWindow: 1_000_000, maxOutputTokens: nil,658            capabilities: ModelCapabilities(tools: true, jsonMode: true),659            pricing: nil,660            parameterSupport: ParameterSupport()661        ),662        AIModel(663            id: "qwen3-coder-next", provider: .qwen, displayName: "Qwen3 Coder Next",664            contextWindow: 262_144, maxOutputTokens: nil,665            capabilities: ModelCapabilities(tools: true, jsonMode: true),666            pricing: nil,667            parameterSupport: ParameterSupport()668        ),669        AIModel(670            id: "qwen3-coder-480b-a35b-instruct", provider: .qwen, displayName: "Qwen3 Coder 480B A35B",671            contextWindow: 262_144, maxOutputTokens: nil,672            capabilities: ModelCapabilities(tools: true, jsonMode: true),673            pricing: nil,674            parameterSupport: ParameterSupport()675        ),676        // Vision-language677        AIModel(678            id: "qwen3-vl-plus", provider: .qwen, displayName: "Qwen3 VL Plus",679            contextWindow: 1_000_000, maxOutputTokens: 65_536,680            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),681            pricing: nil,682            parameterSupport: ParameterSupport(thinkingToggle: true)683        ),684        AIModel(685            id: "qwen3-vl-flash", provider: .qwen, displayName: "Qwen3 VL Flash",686            contextWindow: 1_000_000, maxOutputTokens: 65_536,687            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),688            pricing: nil,689            parameterSupport: ParameterSupport(thinkingToggle: true)690        ),691        AIModel(692            id: "qwen3-vl-235b-a22b-instruct", provider: .qwen, displayName: "Qwen3 VL 235B Instruct",693            contextWindow: 131_072, maxOutputTokens: nil,694            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),695            pricing: nil,696            parameterSupport: ParameterSupport()697        ),698        AIModel(699            id: "qwen3-vl-235b-a22b-thinking", provider: .qwen, displayName: "Qwen3 VL 235B Thinking",700            contextWindow: 131_072, maxOutputTokens: nil,701            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),702            pricing: nil,703            parameterSupport: ParameterSupport()704        ),705        AIModel(706            id: "qvq-max", provider: .qwen, displayName: "QVQ Max",707            contextWindow: 131_072, maxOutputTokens: nil,708            capabilities: ModelCapabilities(vision: true, reasoning: true, jsonMode: true),709            pricing: nil,710            parameterSupport: ParameterSupport(requiresStreaming: true)711        ),712        // Reasoning-only713        AIModel(714            id: "qwq-plus", provider: .qwen, displayName: "QwQ Plus",715            contextWindow: 131_072, maxOutputTokens: nil,716            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),717            pricing: nil,718            parameterSupport: ParameterSupport(requiresStreaming: true)719        ),720        // Open-weights Qwen hosted on DashScope721        AIModel(722            id: "qwen3.5-397b-a17b", provider: .qwen, displayName: "Qwen3.5 397B A17B",723            contextWindow: 262_144, maxOutputTokens: nil,724            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),725            pricing: nil,726            parameterSupport: ParameterSupport(thinkingToggle: true)727        ),728        AIModel(729            id: "qwen3.5-122b-a10b", provider: .qwen, displayName: "Qwen3.5 122B A10B",730            contextWindow: 262_144, maxOutputTokens: nil,731            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),732            pricing: nil,733            parameterSupport: ParameterSupport(thinkingToggle: true)734        ),735        AIModel(736            id: "qwen3.5-35b-a3b", provider: .qwen, displayName: "Qwen3.5 35B A3B",737            contextWindow: 262_144, maxOutputTokens: nil,738            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),739            pricing: nil,740            parameterSupport: ParameterSupport(thinkingToggle: true)741        ),742        AIModel(743            id: "qwen3-235b-a22b-instruct-2507", provider: .qwen, displayName: "Qwen3 235B Instruct 2507",744            contextWindow: 262_144, maxOutputTokens: nil,745            capabilities: ModelCapabilities(tools: true, jsonMode: true),746            pricing: nil,747            parameterSupport: ParameterSupport()748        ),749        AIModel(750            id: "qwen3-235b-a22b-thinking-2507", provider: .qwen, displayName: "Qwen3 235B Thinking 2507",751            contextWindow: 262_144, maxOutputTokens: nil,752            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),753            pricing: nil,754            parameterSupport: ParameterSupport()755        ),756        AIModel(757            id: "qwen3-next-80b-a3b-instruct", provider: .qwen, displayName: "Qwen3 Next 80B Instruct",758            contextWindow: 262_144, maxOutputTokens: nil,759            capabilities: ModelCapabilities(tools: true, jsonMode: true),760            pricing: nil,761            parameterSupport: ParameterSupport()762        ),763        AIModel(764            id: "qwen3-next-80b-a3b-thinking", provider: .qwen, displayName: "Qwen3 Next 80B Thinking",765            contextWindow: 262_144, maxOutputTokens: nil,766            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),767            pricing: nil,768            parameterSupport: ParameterSupport()769        ),770        // Third-party models hosted on DashScope771        AIModel(772            id: "deepseek-v4-pro", provider: .qwen, displayName: "DeepSeek V4 Pro (DashScope)",773            contextWindow: 1_000_000, maxOutputTokens: nil,774            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),775            pricing: nil,776            parameterSupport: ParameterSupport(thinkingToggle: true)777        ),778        AIModel(779            id: "deepseek-v4-flash", provider: .qwen, displayName: "DeepSeek V4 Flash (DashScope)",780            contextWindow: 1_000_000, maxOutputTokens: nil,781            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),782            pricing: nil,783            parameterSupport: ParameterSupport(thinkingToggle: true)784        ),785        AIModel(786            id: "glm-5.2", provider: .qwen, displayName: "GLM 5.2 (DashScope)",787            contextWindow: 198_000, maxOutputTokens: nil,788            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),789            pricing: nil,790            parameterSupport: ParameterSupport(thinkingToggle: true)791        ),792        AIModel(793            id: "kimi-k2.7-code", provider: .qwen, displayName: "Kimi K2.7 Code (DashScope)",794            contextWindow: 262_144, maxOutputTokens: nil,795            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),796            pricing: nil,797            parameterSupport: ParameterSupport(thinkingToggle: true)798        ),799    ]800801    // MARK: - DeepSeek802803    static let deepseek: [AIModel] = [804        AIModel(805            id: "deepseek-v4-flash", provider: .deepseek, displayName: "DeepSeek V4 Flash",806            contextWindow: 1_000_000, maxOutputTokens: 384_000,807            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),808            pricing: ModelPricing(inputPerMTok: 0.14, outputPerMTok: 0.28),809            parameterSupport: ParameterSupport(reasoningEffort: true, thinkingToggle: true),810            isRecommended: true811        ),812        AIModel(813            id: "deepseek-v4-pro", provider: .deepseek, displayName: "DeepSeek V4 Pro",814            contextWindow: 1_000_000, maxOutputTokens: 384_000,815            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),816            pricing: ModelPricing(inputPerMTok: 0.435, outputPerMTok: 0.87),817            parameterSupport: ParameterSupport(reasoningEffort: true, thinkingToggle: true),818            isRecommended: true819        ),820    ]821822    // MARK: - Kimi (Moonshot AI)823824    static let kimi: [AIModel] = [825        AIModel(826            id: "kimi-k3", provider: .kimi, displayName: "Kimi K3",827            contextWindow: 1_048_576, maxOutputTokens: 131_072,828            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),829            pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00),830            // Thinking always on with preserved thinking; depth via reasoning_effort.831            parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true, reasoningEffort: true),832            isRecommended: true833        ),834        AIModel(835            id: "kimi-k2.7-code", provider: .kimi, displayName: "Kimi K2.7 Code",836            contextWindow: 262_144, maxOutputTokens: nil,837            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),838            pricing: ModelPricing(inputPerMTok: 0.95, outputPerMTok: 4.00),839            parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true),840            isRecommended: true841        ),842        AIModel(843            id: "kimi-k2.7-code-highspeed", provider: .kimi, displayName: "Kimi K2.7 Code Highspeed",844            contextWindow: 262_144, maxOutputTokens: nil,845            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),846            pricing: ModelPricing(inputPerMTok: 1.90, outputPerMTok: 8.00),847            parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true)848        ),849        AIModel(850            id: "kimi-k2.6", provider: .kimi, displayName: "Kimi K2.6",851            contextWindow: 262_144, maxOutputTokens: nil,852            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),853            pricing: ModelPricing(inputPerMTok: 0.95, outputPerMTok: 4.00),854            parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true, thinkingToggle: true)855        ),856        AIModel(857            id: "kimi-k2.5", provider: .kimi, displayName: "Kimi K2.5",858            contextWindow: 262_144, maxOutputTokens: nil,859            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),860            pricing: ModelPricing(inputPerMTok: 0.60, outputPerMTok: 3.00),861            parameterSupport: ParameterSupport(temperature: false, topP: false, usesMaxCompletionTokens: true, thinkingToggle: true)862        ),863        // Legacy moonshot-v1 "classic" series (temperature capped at 1.0)864        AIModel(865            id: "moonshot-v1-8k", provider: .kimi, displayName: "Moonshot v1 8K",866            contextWindow: 8_192, maxOutputTokens: nil,867            capabilities: ModelCapabilities(tools: true, jsonMode: true),868            pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 2.00),869            parameterSupport: .openAIDefault,870            isLegacy: true871        ),872        AIModel(873            id: "moonshot-v1-32k", provider: .kimi, displayName: "Moonshot v1 32K",874            contextWindow: 32_768, maxOutputTokens: nil,875            capabilities: ModelCapabilities(tools: true, jsonMode: true),876            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 3.00),877            parameterSupport: .openAIDefault,878            isLegacy: true879        ),880        AIModel(881            id: "moonshot-v1-128k", provider: .kimi, displayName: "Moonshot v1 128K",882            contextWindow: 131_072, maxOutputTokens: nil,883            capabilities: ModelCapabilities(tools: true, jsonMode: true),884            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 5.00),885            parameterSupport: .openAIDefault,886            isLegacy: true887        ),888        AIModel(889            id: "moonshot-v1-auto", provider: .kimi, displayName: "Moonshot v1 Auto",890            contextWindow: 131_072, maxOutputTokens: nil,891            capabilities: ModelCapabilities(tools: true, jsonMode: true),892            pricing: nil,893            parameterSupport: .openAIDefault,894            isLegacy: true895        ),896        AIModel(897            id: "moonshot-v1-8k-vision-preview", provider: .kimi, displayName: "Moonshot v1 8K Vision",898            contextWindow: 8_192, maxOutputTokens: nil,899            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),900            pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 2.00),901            parameterSupport: .openAIDefault,902            isLegacy: true903        ),904        AIModel(905            id: "moonshot-v1-32k-vision-preview", provider: .kimi, displayName: "Moonshot v1 32K Vision",906            contextWindow: 32_768, maxOutputTokens: nil,907            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),908            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 3.00),909            parameterSupport: .openAIDefault,910            isLegacy: true911        ),912        AIModel(913            id: "moonshot-v1-128k-vision-preview", provider: .kimi, displayName: "Moonshot v1 128K Vision",914            contextWindow: 131_072, maxOutputTokens: nil,915            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),916            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 5.00),917            parameterSupport: .openAIDefault,918            isLegacy: true919        ),920    ]921922    // MARK: - Perplexity923924    static let perplexity: [AIModel] = [925        AIModel(926            id: "sonar", provider: .perplexity, displayName: "Sonar",927            contextWindow: 128_000, maxOutputTokens: 128_000,928            capabilities: ModelCapabilities(jsonMode: true, citations: true),929            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 1.00),930            parameterSupport: ParameterSupport(),931            isRecommended: true932        ),933        AIModel(934            id: "sonar-pro", provider: .perplexity, displayName: "Sonar Pro",935            contextWindow: 200_000, maxOutputTokens: 8_000,936            capabilities: ModelCapabilities(jsonMode: true, citations: true),937            pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00),938            parameterSupport: ParameterSupport(),939            isRecommended: true940        ),941        AIModel(942            id: "sonar-reasoning-pro", provider: .perplexity, displayName: "Sonar Reasoning Pro",943            contextWindow: 128_000, maxOutputTokens: nil,944            capabilities: ModelCapabilities(reasoning: true, jsonMode: true, citations: true),945            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00),946            parameterSupport: ParameterSupport(reasoningEffort: true)947        ),948        AIModel(949            id: "sonar-deep-research", provider: .perplexity, displayName: "Sonar Deep Research",950            contextWindow: 128_000, maxOutputTokens: nil,951            capabilities: ModelCapabilities(reasoning: true, jsonMode: true, citations: true),952            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 8.00),953            parameterSupport: ParameterSupport(reasoningEffort: true)954        ),955    ]956957    // MARK: - Together AI958959    static let together: [AIModel] = [960        AIModel(961            id: "moonshotai/Kimi-K3", provider: .together, displayName: "Kimi K3",962            contextWindow: 1_000_000, maxOutputTokens: nil,963            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),964            pricing: ModelPricing(inputPerMTok: 3.00, outputPerMTok: 15.00),965            parameterSupport: .openAIDefault,966            isRecommended: true967        ),968        AIModel(969            id: "moonshotai/Kimi-K2.7-Code", provider: .together, displayName: "Kimi K2.7 Code",970            contextWindow: 262_144, maxOutputTokens: nil,971            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),972            pricing: ModelPricing(inputPerMTok: 0.95, outputPerMTok: 4.00),973            parameterSupport: .openAIDefault974        ),975        AIModel(976            id: "moonshotai/Kimi-K2.6", provider: .together, displayName: "Kimi K2.6",977            contextWindow: 262_144, maxOutputTokens: nil,978            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),979            pricing: ModelPricing(inputPerMTok: 1.20, outputPerMTok: 4.50),980            parameterSupport: .openAIDefault981        ),982        AIModel(983            id: "deepseek-ai/DeepSeek-V4-Pro", provider: .together, displayName: "DeepSeek V4 Pro",984            contextWindow: 512_000, maxOutputTokens: nil,985            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),986            pricing: ModelPricing(inputPerMTok: 1.74, outputPerMTok: 3.48),987            parameterSupport: .openAIDefault,988            isRecommended: true989        ),990        AIModel(991            id: "zai-org/GLM-5.2", provider: .together, displayName: "GLM 5.2",992            contextWindow: 512_000, maxOutputTokens: nil,993            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),994            pricing: ModelPricing(inputPerMTok: 1.40, outputPerMTok: 4.40),995            parameterSupport: .openAIDefault996        ),997        AIModel(998            id: "Qwen/Qwen3.7-Max", provider: .together, displayName: "Qwen3.7 Max",999            contextWindow: 1_000_000, maxOutputTokens: nil,1000            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1001            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 3.75),1002            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true)1003        ),1004        AIModel(1005            id: "Qwen/Qwen3.7-Plus", provider: .together, displayName: "Qwen3.7 Plus",1006            contextWindow: 1_000_000, maxOutputTokens: nil,1007            capabilities: ModelCapabilities(tools: true, jsonMode: true),1008            pricing: ModelPricing(inputPerMTok: 0.32, outputPerMTok: 1.28),1009            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true)1010        ),1011        AIModel(1012            id: "Qwen/Qwen3.6-Plus", provider: .together, displayName: "Qwen3.6 Plus",1013            contextWindow: 1_000_000, maxOutputTokens: nil,1014            capabilities: ModelCapabilities(tools: true, jsonMode: true),1015            pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 3.00),1016            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true)1017        ),1018        AIModel(1019            id: "Qwen/Qwen3.5-9B", provider: .together, displayName: "Qwen3.5 9B",1020            contextWindow: 262_144, maxOutputTokens: nil,1021            // Reasoning model (verified 2026-07-30: streams reasoning_content; needs a large budget to reach text).1022            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1023            pricing: ModelPricing(inputPerMTok: 0.17, outputPerMTok: 0.25),1024            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true)1025        ),1026        AIModel(1027            id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", provider: .together, displayName: "Llama 3.3 70B Turbo",1028            contextWindow: 131_072, maxOutputTokens: nil,1029            capabilities: ModelCapabilities(tools: true, jsonMode: true),1030            pricing: ModelPricing(inputPerMTok: 1.04, outputPerMTok: 1.04),1031            parameterSupport: .openAIDefault1032        ),1033        AIModel(1034            id: "openai/gpt-oss-120b", provider: .together, displayName: "GPT-OSS 120B",1035            contextWindow: 131_072, maxOutputTokens: nil,1036            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1037            pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60),1038            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true),1039            isRecommended: true1040        ),1041        AIModel(1042            id: "openai/gpt-oss-20b", provider: .together, displayName: "GPT-OSS 20B",1043            contextWindow: 131_072, maxOutputTokens: nil,1044            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1045            pricing: ModelPricing(inputPerMTok: 0.05, outputPerMTok: 0.20),1046            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true)1047        ),1048        AIModel(1049            id: "nvidia/nemotron-3-ultra-550b-a55b", provider: .together, displayName: "Nemotron 3 Ultra 550B",1050            contextWindow: 512_288, maxOutputTokens: nil,1051            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1052            pricing: ModelPricing(inputPerMTok: 0.60, outputPerMTok: 3.60),1053            parameterSupport: .openAIDefault1054        ),1055        AIModel(1056            id: "MiniMaxAI/MiniMax-M3", provider: .together, displayName: "MiniMax M3",1057            contextWindow: 524_288, maxOutputTokens: nil,1058            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1059            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.20),1060            parameterSupport: .openAIDefault1061        ),1062        // google/gemma-4-31B-it removed 2026-07-30 (Phase 7): Together's endpoint1063        // streams an empty answer (finish=length, zero content) on plain chat1064        // completions — not usable in the browser. See docs/VERIFICATION.md.1065        AIModel(1066            id: "thinkingmachines/Inkling", provider: .together, displayName: "Inkling",1067            contextWindow: 524_288, maxOutputTokens: nil,1068            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1069            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 4.05),1070            parameterSupport: .openAIDefault1071        ),1072    ]10731074    // MARK: - DeepInfra10751076    static let deepinfra: [AIModel] = [1077        // Proxied frontier models (Claude / Gemini under DeepInfra billing)1078        AIModel(1079            id: "anthropic/claude-fable-5", provider: .deepinfra, displayName: "Claude Fable 5",1080            contextWindow: 1_000_000, maxOutputTokens: nil,1081            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1082            pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 50.00),1083            parameterSupport: ParameterSupport()1084        ),1085        AIModel(1086            id: "anthropic/claude-opus-5", provider: .deepinfra, displayName: "Claude Opus 5",1087            contextWindow: 1_000_000, maxOutputTokens: nil,1088            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1089            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),1090            parameterSupport: ParameterSupport()1091        ),1092        AIModel(1093            id: "anthropic/claude-sonnet-5", provider: .deepinfra, displayName: "Claude Sonnet 5",1094            contextWindow: 1_000_000, maxOutputTokens: nil,1095            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1096            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 10.00),1097            parameterSupport: ParameterSupport()1098        ),1099        AIModel(1100            id: "anthropic/claude-opus-4-8", provider: .deepinfra, displayName: "Claude Opus 4.8",1101            contextWindow: 1_000_000, maxOutputTokens: nil,1102            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1103            pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00),1104            parameterSupport: ParameterSupport()1105        ),1106        AIModel(1107            id: "anthropic/claude-haiku-4-5", provider: .deepinfra, displayName: "Claude Haiku 4.5",1108            contextWindow: 200_000, maxOutputTokens: nil,1109            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1110            pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 5.00),1111            parameterSupport: ParameterSupport()1112        ),1113        AIModel(1114            id: "google/gemini-3.1-pro", provider: .deepinfra, displayName: "Gemini 3.1 Pro",1115            contextWindow: 1_000_000, maxOutputTokens: nil,1116            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1117            pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 12.00),1118            parameterSupport: ParameterSupport()1119        ),1120        AIModel(1121            id: "google/gemini-3.5-flash", provider: .deepinfra, displayName: "Gemini 3.5 Flash",1122            contextWindow: 1_000_000, maxOutputTokens: nil,1123            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1124            pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 9.00),1125            parameterSupport: ParameterSupport()1126        ),1127        AIModel(1128            id: "google/gemini-3.1-flash-lite", provider: .deepinfra, displayName: "Gemini 3.1 Flash-Lite",1129            contextWindow: 1_000_000, maxOutputTokens: nil,1130            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),1131            pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 1.50),1132            parameterSupport: ParameterSupport()1133        ),1134        AIModel(1135            id: "google/gemini-2.5-pro", provider: .deepinfra, displayName: "Gemini 2.5 Pro",1136            contextWindow: 1_000_000, maxOutputTokens: nil,1137            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1138            pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00),1139            parameterSupport: ParameterSupport()1140        ),1141        AIModel(1142            id: "google/gemini-2.5-flash", provider: .deepinfra, displayName: "Gemini 2.5 Flash",1143            contextWindow: 1_000_000, maxOutputTokens: nil,1144            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1145            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50),1146            parameterSupport: ParameterSupport()1147        ),1148        // Open-weight chat models1149        AIModel(1150            id: "deepseek-ai/DeepSeek-V4-Pro", provider: .deepinfra, displayName: "DeepSeek V4 Pro",1151            contextWindow: 1_048_576, maxOutputTokens: nil,1152            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1153            pricing: ModelPricing(inputPerMTok: 1.30, outputPerMTok: 2.60),1154            parameterSupport: .openAIDefault,1155            isRecommended: true1156        ),1157        AIModel(1158            id: "deepseek-ai/DeepSeek-V4-Flash", provider: .deepinfra, displayName: "DeepSeek V4 Flash",1159            contextWindow: 1_048_576, maxOutputTokens: nil,1160            capabilities: ModelCapabilities(tools: true, jsonMode: true),1161            pricing: ModelPricing(inputPerMTok: 0.09, outputPerMTok: 0.18),1162            parameterSupport: .openAIDefault,1163            isRecommended: true1164        ),1165        AIModel(1166            id: "deepseek-ai/DeepSeek-V3.1", provider: .deepinfra, displayName: "DeepSeek V3.1",1167            contextWindow: 163_840, maxOutputTokens: nil,1168            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1169            pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 0.95),1170            parameterSupport: .openAIDefault1171        ),1172        AIModel(1173            id: "deepseek-ai/DeepSeek-R1-0528", provider: .deepinfra, displayName: "DeepSeek R1 0528",1174            contextWindow: 163_840, maxOutputTokens: nil,1175            capabilities: ModelCapabilities(reasoning: true),1176            pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 2.15),1177            parameterSupport: .openAIDefault1178        ),1179        AIModel(1180            id: "moonshotai/Kimi-K2.7-Code", provider: .deepinfra, displayName: "Kimi K2.7 Code",1181            contextWindow: 262_144, maxOutputTokens: nil,1182            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1183            pricing: ModelPricing(inputPerMTok: 0.74, outputPerMTok: 3.50),1184            parameterSupport: .openAIDefault1185        ),1186        AIModel(1187            id: "moonshotai/Kimi-K2.6", provider: .deepinfra, displayName: "Kimi K2.6",1188            contextWindow: 262_144, maxOutputTokens: nil,1189            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1190            pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 3.50),1191            parameterSupport: .openAIDefault1192        ),1193        AIModel(1194            id: "moonshotai/Kimi-K2.5", provider: .deepinfra, displayName: "Kimi K2.5",1195            contextWindow: 262_144, maxOutputTokens: nil,1196            // Reasoning model (verified 2026-07-30: streams reasoning_content before the answer).1197            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1198            pricing: ModelPricing(inputPerMTok: 0.45, outputPerMTok: 2.25),1199            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true)1200        ),1201        AIModel(1202            id: "zai-org/GLM-5.2", provider: .deepinfra, displayName: "GLM 5.2",1203            contextWindow: 1_048_576, maxOutputTokens: nil,1204            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1205            pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 2.40),1206            parameterSupport: .openAIDefault,1207            isRecommended: true1208        ),1209        AIModel(1210            id: "zai-org/GLM-4.7", provider: .deepinfra, displayName: "GLM 4.7",1211            contextWindow: 202_752, maxOutputTokens: nil,1212            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1213            pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 1.75),1214            parameterSupport: .openAIDefault1215        ),1216        AIModel(1217            id: "Qwen/Qwen3.7-Max", provider: .deepinfra, displayName: "Qwen3.7 Max",1218            contextWindow: 256_000, maxOutputTokens: nil,1219            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1220            pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 7.50),1221            parameterSupport: .openAIDefault1222        ),1223        AIModel(1224            id: "Qwen/Qwen3.5-397B-A17B", provider: .deepinfra, displayName: "Qwen3.5 397B A17B",1225            contextWindow: 262_144, maxOutputTokens: nil,1226            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1227            pricing: ModelPricing(inputPerMTok: 0.45, outputPerMTok: 3.00),1228            parameterSupport: .openAIDefault1229        ),1230        AIModel(1231            id: "Qwen/Qwen3-235B-A22B-Instruct-2507", provider: .deepinfra, displayName: "Qwen3 235B Instruct 2507",1232            contextWindow: 262_144, maxOutputTokens: nil,1233            capabilities: ModelCapabilities(tools: true, jsonMode: true),1234            pricing: ModelPricing(inputPerMTok: 0.09, outputPerMTok: 0.55),1235            parameterSupport: .openAIDefault1236        ),1237        AIModel(1238            id: "Qwen/Qwen3-235B-A22B-Thinking-2507", provider: .deepinfra, displayName: "Qwen3 235B Thinking 2507",1239            contextWindow: 262_144, maxOutputTokens: nil,1240            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1241            pricing: ModelPricing(inputPerMTok: 0.23, outputPerMTok: 2.30),1242            parameterSupport: .openAIDefault1243        ),1244        AIModel(1245            id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo", provider: .deepinfra, displayName: "Qwen3 Coder 480B Turbo",1246            contextWindow: 262_144, maxOutputTokens: nil,1247            capabilities: ModelCapabilities(tools: true, jsonMode: true),1248            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.00),1249            parameterSupport: .openAIDefault1250        ),1251        AIModel(1252            id: "Qwen/Qwen3-VL-235B-A22B-Instruct", provider: .deepinfra, displayName: "Qwen3 VL 235B",1253            contextWindow: 262_144, maxOutputTokens: nil,1254            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),1255            pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.88),1256            parameterSupport: .openAIDefault1257        ),1258        AIModel(1259            id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", provider: .deepinfra, displayName: "Llama 4 Maverick",1260            contextWindow: 1_048_576, maxOutputTokens: nil,1261            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),1262            pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.80),1263            parameterSupport: .openAIDefault1264        ),1265        AIModel(1266            id: "meta-llama/Llama-4-Scout-17B-16E-Instruct", provider: .deepinfra, displayName: "Llama 4 Scout",1267            contextWindow: 327_680, maxOutputTokens: nil,1268            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),1269            pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.30),1270            parameterSupport: .openAIDefault1271        ),1272        AIModel(1273            id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", provider: .deepinfra, displayName: "Llama 3.3 70B Turbo",1274            contextWindow: 131_072, maxOutputTokens: nil,1275            capabilities: ModelCapabilities(tools: true, jsonMode: true),1276            pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.32),1277            parameterSupport: .openAIDefault1278        ),1279        AIModel(1280            id: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", provider: .deepinfra, displayName: "Llama 3.1 8B Turbo",1281            contextWindow: 131_072, maxOutputTokens: nil,1282            capabilities: ModelCapabilities(tools: true, jsonMode: true),1283            pricing: ModelPricing(inputPerMTok: 0.02, outputPerMTok: 0.04),1284            parameterSupport: .openAIDefault1285        ),1286        AIModel(1287            id: "openai/gpt-oss-120b", provider: .deepinfra, displayName: "GPT-OSS 120B",1288            contextWindow: 131_072, maxOutputTokens: nil,1289            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1290            pricing: ModelPricing(inputPerMTok: 0.037, outputPerMTok: 0.17),1291            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true),1292            isRecommended: true1293        ),1294        AIModel(1295            id: "openai/gpt-oss-20b", provider: .deepinfra, displayName: "GPT-OSS 20B",1296            contextWindow: 131_072, maxOutputTokens: nil,1297            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1298            pricing: ModelPricing(inputPerMTok: 0.03, outputPerMTok: 0.14),1299            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true)1300        ),1301        AIModel(1302            id: "MiniMaxAI/MiniMax-M3", provider: .deepinfra, displayName: "MiniMax M3",1303            contextWindow: 524_288, maxOutputTokens: nil,1304            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1305            pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.20),1306            parameterSupport: .openAIDefault1307        ),1308        AIModel(1309            id: "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B", provider: .deepinfra, displayName: "Nemotron 3 Ultra 550B",1310            contextWindow: 262_144, maxOutputTokens: nil,1311            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1312            pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 2.20),1313            parameterSupport: .openAIDefault1314        ),1315        AIModel(1316            id: "mistralai/Mistral-Small-3.2-24B-Instruct-2506", provider: .deepinfra, displayName: "Mistral Small 3.2 24B",1317            contextWindow: 128_000, maxOutputTokens: nil,1318            capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true),1319            pricing: ModelPricing(inputPerMTok: 0.075, outputPerMTok: 0.20),1320            parameterSupport: .openAIDefault1321        ),1322        // google/gemma-4-31B-it removed 2026-07-30: endpoint hangs (60s+, zero1323        // bytes) on chat completions — see docs/PROVIDERS.md Phase 7 amendments.1324    ]13251326    // MARK: - Cerebras13271328    static let cerebras: [AIModel] = [1329        AIModel(1330            id: "gpt-oss-120b", provider: .cerebras, displayName: "GPT-OSS 120B",1331            contextWindow: 131_072, maxOutputTokens: 40_000,1332            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1333            pricing: ModelPricing(inputPerMTok: 0.35, outputPerMTok: 0.75),1334            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true),1335            isRecommended: true1336        ),1337        AIModel(1338            id: "gemma-4-31b", provider: .cerebras, displayName: "Gemma 4 31B",1339            contextWindow: 131_072, maxOutputTokens: 40_000,1340            capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true),1341            pricing: ModelPricing(inputPerMTok: 0.99, outputPerMTok: 1.49),1342            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true)1343        ),1344        AIModel(1345            id: "zai-glm-4.7", provider: .cerebras, displayName: "GLM 4.7",1346            contextWindow: 131_072, maxOutputTokens: 40_000,1347            capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true),1348            pricing: ModelPricing(inputPerMTok: 2.25, outputPerMTok: 2.75),1349            parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true),1350            // Scheduled for discontinuation on 2026-08-17.1351            isLegacy: true1352        ),1353    ]13541355    // MARK: - All providers13561357    static let all: [AIModel] =1358        openai + anthropic + xai + mistral + gemini + qwen +1359        deepseek + kimi + perplexity + together + deepinfra + cerebras1360}1361