spb/zyquo-atlas Public License
The AI-native macOS web browser — every surface, intelligent.
Swift 75.2%
JavaScript 22%
Shell 2%
Makefile 0.9%
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