| |
1 | +// |
| |
2 | +// ModelCatalogData.swift |
| |
3 | +// Zyquo Atlas |
| |
4 | +// |
| |
5 | +// Author: Simon-Pierre Boucher |
| |
6 | +// Mail: contact@spboucher.ai |
| |
7 | +// |
| |
8 | +// Built-in model catalog, generated from docs/PROVIDERS.md and the per-provider |
| |
9 | +// research files in docs/research/ on 2026-07-30. This file and docs/PROVIDERS.md |
| |
10 | +// are a single source of truth and MUST stay in sync: when Phase 7 verification |
| |
11 | +// (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-research |
| |
15 | +// agents, and Responses-API-only models are excluded by design. |
| |
16 | +// |
| |
17 | + |
| |
18 | +import Foundation |
| |
19 | + |
| |
20 | +enum ModelCatalogData { |
| |
21 | + |
| |
22 | + // MARK: - Shared parameter-support presets |
| |
23 | + |
| |
24 | + /// OpenAI reasoning models (o-series, gpt-5.x reasoning variants): reject |
| |
25 | + /// 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: true |
| |
29 | + ) |
| |
30 | + |
| |
31 | + // MARK: - OpenAI |
| |
32 | + |
| |
33 | + static let openai: [AIModel] = [ |
| |
34 | + // Flagship GPT-5.6 trio |
| |
35 | + 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: true |
| |
42 | + ), |
| |
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: true |
| |
50 | + ), |
| |
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: openAIReasoning |
| |
57 | + ), |
| |
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.x |
| |
66 | + 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: openAIReasoning |
| |
72 | + ), |
| |
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: openAIReasoning |
| |
79 | + ), |
| |
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: openAIReasoning |
| |
86 | + ), |
| |
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: openAIReasoning |
| |
93 | + ), |
| |
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: openAIReasoning |
| |
107 | + ), |
| |
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: openAIReasoning |
| |
121 | + ), |
| |
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: openAIReasoning |
| |
128 | + ), |
| |
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: openAIReasoning |
| |
135 | + ), |
| |
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: openAIReasoning |
| |
142 | + ), |
| |
143 | + // o-series reasoning |
| |
144 | + 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: openAIReasoning |
| |
150 | + ), |
| |
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: openAIReasoning |
| |
157 | + ), |
| |
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: true |
| |
165 | + ), |
| |
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: true |
| |
173 | + ), |
| |
174 | + // Legacy GPT-4.x / 3.5 |
| |
175 | + 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: true |
| |
182 | + ), |
| |
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: true |
| |
190 | + ), |
| |
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: true |
| |
198 | + ), |
| |
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: true |
| |
206 | + ), |
| |
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: true |
| |
214 | + ), |
| |
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: true |
| |
222 | + ), |
| |
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: true |
| |
230 | + ), |
| |
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: true |
| |
238 | + ), |
| |
239 | + ] |
| |
240 | + |
| |
241 | + // MARK: - Anthropic |
| |
242 | + |
| |
243 | + 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: true |
| |
251 | + ), |
| |
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: true |
| |
259 | + ), |
| |
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: true |
| |
310 | + ), |
| |
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: true |
| |
318 | + ), |
| |
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: true |
| |
326 | + ), |
| |
327 | + ] |
| |
328 | + |
| |
329 | + // MARK: - xAI (Grok) |
| |
330 | + |
| |
331 | + 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: true |
| |
339 | + ), |
| |
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: true |
| |
368 | + ), |
| |
369 | + ] |
| |
370 | + |
| |
371 | + // MARK: - Mistral |
| |
372 | + |
| |
373 | + 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: true |
| |
381 | + ), |
| |
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: true |
| |
389 | + ), |
| |
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: true |
| |
397 | + ), |
| |
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: .openAIDefault |
| |
404 | + ), |
| |
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: .openAIDefault |
| |
411 | + ), |
| |
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: .openAIDefault |
| |
418 | + ), |
| |
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: .openAIDefault |
| |
425 | + ), |
| |
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: true |
| |
434 | + ), |
| |
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: true |
| |
442 | + ), |
| |
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: true |
| |
450 | + ), |
| |
451 | + ] |
| |
452 | + |
| |
453 | + // MARK: - Google Gemini |
| |
454 | + |
| |
455 | + 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: true |
| |
463 | + ), |
| |
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: true |
| |
478 | + ), |
| |
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: true |
| |
486 | + ), |
| |
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 / secondary |
| |
538 | + 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 | + ] |
| |
560 | + |
| |
561 | + // MARK: - Alibaba Qwen (DashScope) |
| |
562 | + |
| |
563 | + static let qwen: [AIModel] = [ |
| |
564 | + // Flagship commercial |
| |
565 | + 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: true |
| |
572 | + ), |
| |
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: true |
| |
580 | + ), |
| |
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: true |
| |
588 | + ), |
| |
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: true |
| |
639 | + ), |
| |
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 family |
| |
648 | + 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-language |
| |
677 | + 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-only |
| |
713 | + 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 DashScope |
| |
721 | + 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 DashScope |
| |
771 | + 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 | + ] |
| |
800 | + |
| |
801 | + // MARK: - DeepSeek |
| |
802 | + |
| |
803 | + 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: true |
| |
811 | + ), |
| |
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: true |
| |
819 | + ), |
| |
820 | + ] |
| |
821 | + |
| |
822 | + // MARK: - Kimi (Moonshot AI) |
| |
823 | + |
| |
824 | + 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: true |
| |
833 | + ), |
| |
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: true |
| |
841 | + ), |
| |
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: true |
| |
871 | + ), |
| |
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: true |
| |
879 | + ), |
| |
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: true |
| |
887 | + ), |
| |
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: true |
| |
895 | + ), |
| |
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: true |
| |
903 | + ), |
| |
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: true |
| |
911 | + ), |
| |
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: true |
| |
919 | + ), |
| |
920 | + ] |
| |
921 | + |
| |
922 | + // MARK: - Perplexity |
| |
923 | + |
| |
924 | + 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: true |
| |
932 | + ), |
| |
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: true |
| |
940 | + ), |
| |
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 | + ] |
| |
956 | + |
| |
957 | + // MARK: - Together AI |
| |
958 | + |
| |
959 | + 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: true |
| |
967 | + ), |
| |
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: .openAIDefault |
| |
974 | + ), |
| |
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: .openAIDefault |
| |
981 | + ), |
| |
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: true |
| |
989 | + ), |
| |
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: .openAIDefault |
| |
996 | + ), |
| |
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 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1022 | + pricing: ModelPricing(inputPerMTok: 0.17, outputPerMTok: 0.25), |
| |
1023 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) |
| |
1024 | + ), |
| |
1025 | + AIModel( |
| |
1026 | + id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", provider: .together, displayName: "Llama 3.3 70B Turbo", |
| |
1027 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1028 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1029 | + pricing: ModelPricing(inputPerMTok: 1.04, outputPerMTok: 1.04), |
| |
1030 | + parameterSupport: .openAIDefault |
| |
1031 | + ), |
| |
1032 | + AIModel( |
| |
1033 | + id: "openai/gpt-oss-120b", provider: .together, displayName: "GPT-OSS 120B", |
| |
1034 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1035 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1036 | + pricing: ModelPricing(inputPerMTok: 0.15, outputPerMTok: 0.60), |
| |
1037 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true), |
| |
1038 | + isRecommended: true |
| |
1039 | + ), |
| |
1040 | + AIModel( |
| |
1041 | + id: "openai/gpt-oss-20b", provider: .together, displayName: "GPT-OSS 20B", |
| |
1042 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1043 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1044 | + pricing: ModelPricing(inputPerMTok: 0.05, outputPerMTok: 0.20), |
| |
1045 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true) |
| |
1046 | + ), |
| |
1047 | + AIModel( |
| |
1048 | + id: "nvidia/nemotron-3-ultra-550b-a55b", provider: .together, displayName: "Nemotron 3 Ultra 550B", |
| |
1049 | + contextWindow: 512_288, maxOutputTokens: nil, |
| |
1050 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1051 | + pricing: ModelPricing(inputPerMTok: 0.60, outputPerMTok: 3.60), |
| |
1052 | + parameterSupport: .openAIDefault |
| |
1053 | + ), |
| |
1054 | + AIModel( |
| |
1055 | + id: "MiniMaxAI/MiniMax-M3", provider: .together, displayName: "MiniMax M3", |
| |
1056 | + contextWindow: 524_288, maxOutputTokens: nil, |
| |
1057 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1058 | + pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.20), |
| |
1059 | + parameterSupport: .openAIDefault |
| |
1060 | + ), |
| |
1061 | + AIModel( |
| |
1062 | + // vision disabled 2026-07-30: Together's endpoint accepts image |
| |
1063 | + // input but streams an empty answer (verified live) — text only. |
| |
1064 | + id: "google/gemma-4-31B-it", provider: .together, displayName: "Gemma 4 31B", |
| |
1065 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1066 | + capabilities: ModelCapabilities(vision: false, tools: true, jsonMode: true), |
| |
1067 | + pricing: ModelPricing(inputPerMTok: 0.39, outputPerMTok: 0.97), |
| |
1068 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) |
| |
1069 | + ), |
| |
1070 | + AIModel( |
| |
1071 | + id: "thinkingmachines/Inkling", provider: .together, displayName: "Inkling", |
| |
1072 | + contextWindow: 524_288, maxOutputTokens: nil, |
| |
1073 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1074 | + pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 4.05), |
| |
1075 | + parameterSupport: .openAIDefault |
| |
1076 | + ), |
| |
1077 | + ] |
| |
1078 | + |
| |
1079 | + // MARK: - DeepInfra |
| |
1080 | + |
| |
1081 | + static let deepinfra: [AIModel] = [ |
| |
1082 | + // Proxied frontier models (Claude / Gemini under DeepInfra billing) |
| |
1083 | + AIModel( |
| |
1084 | + id: "anthropic/claude-fable-5", provider: .deepinfra, displayName: "Claude Fable 5", |
| |
1085 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1086 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1087 | + pricing: ModelPricing(inputPerMTok: 10.00, outputPerMTok: 50.00), |
| |
1088 | + parameterSupport: ParameterSupport() |
| |
1089 | + ), |
| |
1090 | + AIModel( |
| |
1091 | + id: "anthropic/claude-opus-5", provider: .deepinfra, displayName: "Claude Opus 5", |
| |
1092 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1093 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1094 | + pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), |
| |
1095 | + parameterSupport: ParameterSupport() |
| |
1096 | + ), |
| |
1097 | + AIModel( |
| |
1098 | + id: "anthropic/claude-sonnet-5", provider: .deepinfra, displayName: "Claude Sonnet 5", |
| |
1099 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1100 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1101 | + pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 10.00), |
| |
1102 | + parameterSupport: ParameterSupport() |
| |
1103 | + ), |
| |
1104 | + AIModel( |
| |
1105 | + id: "anthropic/claude-opus-4-8", provider: .deepinfra, displayName: "Claude Opus 4.8", |
| |
1106 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1107 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1108 | + pricing: ModelPricing(inputPerMTok: 5.00, outputPerMTok: 25.00), |
| |
1109 | + parameterSupport: ParameterSupport() |
| |
1110 | + ), |
| |
1111 | + AIModel( |
| |
1112 | + id: "anthropic/claude-haiku-4-5", provider: .deepinfra, displayName: "Claude Haiku 4.5", |
| |
1113 | + contextWindow: 200_000, maxOutputTokens: nil, |
| |
1114 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1115 | + pricing: ModelPricing(inputPerMTok: 1.00, outputPerMTok: 5.00), |
| |
1116 | + parameterSupport: ParameterSupport() |
| |
1117 | + ), |
| |
1118 | + AIModel( |
| |
1119 | + id: "google/gemini-3.1-pro", provider: .deepinfra, displayName: "Gemini 3.1 Pro", |
| |
1120 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1121 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1122 | + pricing: ModelPricing(inputPerMTok: 2.00, outputPerMTok: 12.00), |
| |
1123 | + parameterSupport: ParameterSupport() |
| |
1124 | + ), |
| |
1125 | + AIModel( |
| |
1126 | + id: "google/gemini-3.5-flash", provider: .deepinfra, displayName: "Gemini 3.5 Flash", |
| |
1127 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1128 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1129 | + pricing: ModelPricing(inputPerMTok: 1.50, outputPerMTok: 9.00), |
| |
1130 | + parameterSupport: ParameterSupport() |
| |
1131 | + ), |
| |
1132 | + AIModel( |
| |
1133 | + id: "google/gemini-3.1-flash-lite", provider: .deepinfra, displayName: "Gemini 3.1 Flash-Lite", |
| |
1134 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1135 | + capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), |
| |
1136 | + pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 1.50), |
| |
1137 | + parameterSupport: ParameterSupport() |
| |
1138 | + ), |
| |
1139 | + AIModel( |
| |
1140 | + id: "google/gemini-2.5-pro", provider: .deepinfra, displayName: "Gemini 2.5 Pro", |
| |
1141 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1142 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1143 | + pricing: ModelPricing(inputPerMTok: 1.25, outputPerMTok: 10.00), |
| |
1144 | + parameterSupport: ParameterSupport() |
| |
1145 | + ), |
| |
1146 | + AIModel( |
| |
1147 | + id: "google/gemini-2.5-flash", provider: .deepinfra, displayName: "Gemini 2.5 Flash", |
| |
1148 | + contextWindow: 1_000_000, maxOutputTokens: nil, |
| |
1149 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1150 | + pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 2.50), |
| |
1151 | + parameterSupport: ParameterSupport() |
| |
1152 | + ), |
| |
1153 | + // Open-weight chat models |
| |
1154 | + AIModel( |
| |
1155 | + id: "deepseek-ai/DeepSeek-V4-Pro", provider: .deepinfra, displayName: "DeepSeek V4 Pro", |
| |
1156 | + contextWindow: 1_048_576, maxOutputTokens: nil, |
| |
1157 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1158 | + pricing: ModelPricing(inputPerMTok: 1.30, outputPerMTok: 2.60), |
| |
1159 | + parameterSupport: .openAIDefault, |
| |
1160 | + isRecommended: true |
| |
1161 | + ), |
| |
1162 | + AIModel( |
| |
1163 | + id: "deepseek-ai/DeepSeek-V4-Flash", provider: .deepinfra, displayName: "DeepSeek V4 Flash", |
| |
1164 | + contextWindow: 1_048_576, maxOutputTokens: nil, |
| |
1165 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1166 | + pricing: ModelPricing(inputPerMTok: 0.09, outputPerMTok: 0.18), |
| |
1167 | + parameterSupport: .openAIDefault, |
| |
1168 | + isRecommended: true |
| |
1169 | + ), |
| |
1170 | + AIModel( |
| |
1171 | + id: "deepseek-ai/DeepSeek-V3.1", provider: .deepinfra, displayName: "DeepSeek V3.1", |
| |
1172 | + contextWindow: 163_840, maxOutputTokens: nil, |
| |
1173 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1174 | + pricing: ModelPricing(inputPerMTok: 0.25, outputPerMTok: 0.95), |
| |
1175 | + parameterSupport: .openAIDefault |
| |
1176 | + ), |
| |
1177 | + AIModel( |
| |
1178 | + id: "deepseek-ai/DeepSeek-R1-0528", provider: .deepinfra, displayName: "DeepSeek R1 0528", |
| |
1179 | + contextWindow: 163_840, maxOutputTokens: nil, |
| |
1180 | + capabilities: ModelCapabilities(reasoning: true), |
| |
1181 | + pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 2.15), |
| |
1182 | + parameterSupport: .openAIDefault |
| |
1183 | + ), |
| |
1184 | + AIModel( |
| |
1185 | + id: "moonshotai/Kimi-K2.7-Code", provider: .deepinfra, displayName: "Kimi K2.7 Code", |
| |
1186 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1187 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1188 | + pricing: ModelPricing(inputPerMTok: 0.74, outputPerMTok: 3.50), |
| |
1189 | + parameterSupport: .openAIDefault |
| |
1190 | + ), |
| |
1191 | + AIModel( |
| |
1192 | + id: "moonshotai/Kimi-K2.6", provider: .deepinfra, displayName: "Kimi K2.6", |
| |
1193 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1194 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1195 | + pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 3.50), |
| |
1196 | + parameterSupport: .openAIDefault |
| |
1197 | + ), |
| |
1198 | + AIModel( |
| |
1199 | + id: "moonshotai/Kimi-K2.5", provider: .deepinfra, displayName: "Kimi K2.5", |
| |
1200 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1201 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1202 | + pricing: ModelPricing(inputPerMTok: 0.45, outputPerMTok: 2.25), |
| |
1203 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, requiresStreaming: true) |
| |
1204 | + ), |
| |
1205 | + AIModel( |
| |
1206 | + id: "zai-org/GLM-5.2", provider: .deepinfra, displayName: "GLM 5.2", |
| |
1207 | + contextWindow: 1_048_576, maxOutputTokens: nil, |
| |
1208 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1209 | + pricing: ModelPricing(inputPerMTok: 0.75, outputPerMTok: 2.40), |
| |
1210 | + parameterSupport: .openAIDefault, |
| |
1211 | + isRecommended: true |
| |
1212 | + ), |
| |
1213 | + AIModel( |
| |
1214 | + id: "zai-org/GLM-4.7", provider: .deepinfra, displayName: "GLM 4.7", |
| |
1215 | + contextWindow: 202_752, maxOutputTokens: nil, |
| |
1216 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1217 | + pricing: ModelPricing(inputPerMTok: 0.40, outputPerMTok: 1.75), |
| |
1218 | + parameterSupport: .openAIDefault |
| |
1219 | + ), |
| |
1220 | + AIModel( |
| |
1221 | + id: "Qwen/Qwen3.7-Max", provider: .deepinfra, displayName: "Qwen3.7 Max", |
| |
1222 | + contextWindow: 256_000, maxOutputTokens: nil, |
| |
1223 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1224 | + pricing: ModelPricing(inputPerMTok: 2.50, outputPerMTok: 7.50), |
| |
1225 | + parameterSupport: .openAIDefault |
| |
1226 | + ), |
| |
1227 | + AIModel( |
| |
1228 | + id: "Qwen/Qwen3.5-397B-A17B", provider: .deepinfra, displayName: "Qwen3.5 397B A17B", |
| |
1229 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1230 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1231 | + pricing: ModelPricing(inputPerMTok: 0.45, outputPerMTok: 3.00), |
| |
1232 | + parameterSupport: .openAIDefault |
| |
1233 | + ), |
| |
1234 | + AIModel( |
| |
1235 | + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", provider: .deepinfra, displayName: "Qwen3 235B Instruct 2507", |
| |
1236 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1237 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1238 | + pricing: ModelPricing(inputPerMTok: 0.09, outputPerMTok: 0.55), |
| |
1239 | + parameterSupport: .openAIDefault |
| |
1240 | + ), |
| |
1241 | + AIModel( |
| |
1242 | + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", provider: .deepinfra, displayName: "Qwen3 235B Thinking 2507", |
| |
1243 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1244 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1245 | + pricing: ModelPricing(inputPerMTok: 0.23, outputPerMTok: 2.30), |
| |
1246 | + parameterSupport: .openAIDefault |
| |
1247 | + ), |
| |
1248 | + AIModel( |
| |
1249 | + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo", provider: .deepinfra, displayName: "Qwen3 Coder 480B Turbo", |
| |
1250 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1251 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1252 | + pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.00), |
| |
1253 | + parameterSupport: .openAIDefault |
| |
1254 | + ), |
| |
1255 | + AIModel( |
| |
1256 | + id: "Qwen/Qwen3-VL-235B-A22B-Instruct", provider: .deepinfra, displayName: "Qwen3 VL 235B", |
| |
1257 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1258 | + capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), |
| |
1259 | + pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.88), |
| |
1260 | + parameterSupport: .openAIDefault |
| |
1261 | + ), |
| |
1262 | + AIModel( |
| |
1263 | + id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", provider: .deepinfra, displayName: "Llama 4 Maverick", |
| |
1264 | + contextWindow: 1_048_576, maxOutputTokens: nil, |
| |
1265 | + capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), |
| |
1266 | + pricing: ModelPricing(inputPerMTok: 0.20, outputPerMTok: 0.80), |
| |
1267 | + parameterSupport: .openAIDefault |
| |
1268 | + ), |
| |
1269 | + AIModel( |
| |
1270 | + id: "meta-llama/Llama-4-Scout-17B-16E-Instruct", provider: .deepinfra, displayName: "Llama 4 Scout", |
| |
1271 | + contextWindow: 327_680, maxOutputTokens: nil, |
| |
1272 | + capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), |
| |
1273 | + pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.30), |
| |
1274 | + parameterSupport: .openAIDefault |
| |
1275 | + ), |
| |
1276 | + AIModel( |
| |
1277 | + id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", provider: .deepinfra, displayName: "Llama 3.3 70B Turbo", |
| |
1278 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1279 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1280 | + pricing: ModelPricing(inputPerMTok: 0.10, outputPerMTok: 0.32), |
| |
1281 | + parameterSupport: .openAIDefault |
| |
1282 | + ), |
| |
1283 | + AIModel( |
| |
1284 | + id: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", provider: .deepinfra, displayName: "Llama 3.1 8B Turbo", |
| |
1285 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1286 | + capabilities: ModelCapabilities(tools: true, jsonMode: true), |
| |
1287 | + pricing: ModelPricing(inputPerMTok: 0.02, outputPerMTok: 0.04), |
| |
1288 | + parameterSupport: .openAIDefault |
| |
1289 | + ), |
| |
1290 | + AIModel( |
| |
1291 | + id: "openai/gpt-oss-120b", provider: .deepinfra, displayName: "GPT-OSS 120B", |
| |
1292 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1293 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1294 | + pricing: ModelPricing(inputPerMTok: 0.037, outputPerMTok: 0.17), |
| |
1295 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true), |
| |
1296 | + isRecommended: true |
| |
1297 | + ), |
| |
1298 | + AIModel( |
| |
1299 | + id: "openai/gpt-oss-20b", provider: .deepinfra, displayName: "GPT-OSS 20B", |
| |
1300 | + contextWindow: 131_072, maxOutputTokens: nil, |
| |
1301 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1302 | + pricing: ModelPricing(inputPerMTok: 0.03, outputPerMTok: 0.14), |
| |
1303 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, reasoningEffort: true) |
| |
1304 | + ), |
| |
1305 | + AIModel( |
| |
1306 | + id: "MiniMaxAI/MiniMax-M3", provider: .deepinfra, displayName: "MiniMax M3", |
| |
1307 | + contextWindow: 524_288, maxOutputTokens: nil, |
| |
1308 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1309 | + pricing: ModelPricing(inputPerMTok: 0.30, outputPerMTok: 1.20), |
| |
1310 | + parameterSupport: .openAIDefault |
| |
1311 | + ), |
| |
1312 | + AIModel( |
| |
1313 | + id: "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B", provider: .deepinfra, displayName: "Nemotron 3 Ultra 550B", |
| |
1314 | + contextWindow: 262_144, maxOutputTokens: nil, |
| |
1315 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1316 | + pricing: ModelPricing(inputPerMTok: 0.50, outputPerMTok: 2.20), |
| |
1317 | + parameterSupport: .openAIDefault |
| |
1318 | + ), |
| |
1319 | + AIModel( |
| |
1320 | + id: "mistralai/Mistral-Small-3.2-24B-Instruct-2506", provider: .deepinfra, displayName: "Mistral Small 3.2 24B", |
| |
1321 | + contextWindow: 128_000, maxOutputTokens: nil, |
| |
1322 | + capabilities: ModelCapabilities(vision: true, tools: true, jsonMode: true), |
| |
1323 | + pricing: ModelPricing(inputPerMTok: 0.075, outputPerMTok: 0.20), |
| |
1324 | + parameterSupport: .openAIDefault |
| |
1325 | + ), |
| |
1326 | + // google/gemma-4-31B-it removed 2026-07-30: endpoint hangs (60s+, zero |
| |
1327 | + // bytes) on chat completions — see docs/PROVIDERS.md Phase 7 amendments. |
| |
1328 | + ] |
| |
1329 | + |
| |
1330 | + // MARK: - Cerebras |
| |
1331 | + |
| |
1332 | + static let cerebras: [AIModel] = [ |
| |
1333 | + AIModel( |
| |
1334 | + id: "gpt-oss-120b", provider: .cerebras, displayName: "GPT-OSS 120B", |
| |
1335 | + contextWindow: 131_072, maxOutputTokens: 40_000, |
| |
1336 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1337 | + pricing: ModelPricing(inputPerMTok: 0.35, outputPerMTok: 0.75), |
| |
1338 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true), |
| |
1339 | + isRecommended: true |
| |
1340 | + ), |
| |
1341 | + AIModel( |
| |
1342 | + id: "gemma-4-31b", provider: .cerebras, displayName: "Gemma 4 31B", |
| |
1343 | + contextWindow: 131_072, maxOutputTokens: 40_000, |
| |
1344 | + capabilities: ModelCapabilities(vision: true, tools: true, reasoning: true, jsonMode: true), |
| |
1345 | + pricing: ModelPricing(inputPerMTok: 0.99, outputPerMTok: 1.49), |
| |
1346 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true) |
| |
1347 | + ), |
| |
1348 | + AIModel( |
| |
1349 | + id: "zai-glm-4.7", provider: .cerebras, displayName: "GLM 4.7", |
| |
1350 | + contextWindow: 131_072, maxOutputTokens: 40_000, |
| |
1351 | + capabilities: ModelCapabilities(tools: true, reasoning: true, jsonMode: true), |
| |
1352 | + pricing: ModelPricing(inputPerMTok: 2.25, outputPerMTok: 2.75), |
| |
1353 | + parameterSupport: ParameterSupport(frequencyPenalty: true, presencePenalty: true, usesMaxCompletionTokens: true, reasoningEffort: true), |
| |
1354 | + // Scheduled for discontinuation on 2026-08-17. |
| |
1355 | + isLegacy: true |
| |
1356 | + ), |
| |
1357 | + ] |
| |
1358 | + |
| |
1359 | + // MARK: - All providers |
| |
1360 | + |
| |
1361 | + static let all: [AIModel] = |
| |
1362 | + openai + anthropic + xai + mistral + gemini + qwen + |
| |
1363 | + deepseek + kimi + perplexity + together + deepinfra + cerebras |
| |
1364 | +} |