( spec: ModelSpecifier, apiKey?: string, )
| 166 | * @returns LanguageModel instance |
| 167 | */ |
| 168 | export function resolveModel( |
| 169 | spec: ModelSpecifier, |
| 170 | apiKey?: string, |
| 171 | ): LanguageModel { |
| 172 | // If already a LanguageModel instance, pass through |
| 173 | if (typeof spec !== "string") { |
| 174 | return spec; |
| 175 | } |
| 176 | |
| 177 | // Normalize "provider/model" or "provider:model" format |
| 178 | const normalized = spec.replace("/", ":").trim(); |
| 179 | const parts = normalized.split(":"); |
| 180 | const rawProvider = parts[0]; |
| 181 | const rest = parts.slice(1); |
| 182 | |
| 183 | if (!rawProvider) { |
| 184 | throw new Error( |
| 185 | `Invalid model string "${spec}". Use "openai/gpt-5", "anthropic/claude-sonnet-4.5", or "google/gemini-2.5-pro".`, |
| 186 | ); |
| 187 | } |
| 188 | |
| 189 | const provider = rawProvider.toLowerCase(); |
| 190 | const model = rest.join(":").trim(); |
| 191 | |
| 192 | if (!model) { |
| 193 | throw new Error( |
| 194 | `Invalid model string "${spec}". Use "openai/gpt-5", "anthropic/claude-sonnet-4.5", or "google/gemini-2.5-pro".`, |
| 195 | ); |
| 196 | } |
| 197 | |
| 198 | switch (provider) { |
| 199 | case "openai": { |
| 200 | // Lazily create OpenAI provider |
| 201 | // Use provided apiKey, or fall back to environment variable |
| 202 | const openai = createOpenAI({ |
| 203 | apiKey: apiKey || process.env.OPENAI_API_KEY!, |
| 204 | }); |
| 205 | // Accepts any OpenAI model id, e.g. "gpt-4o", "gpt-4.1-mini", "o3-mini" |
| 206 | return openai(model); |
| 207 | } |
| 208 | |
| 209 | case "anthropic": { |
| 210 | // Lazily create Anthropic provider |
| 211 | // Use provided apiKey, or fall back to environment variable |
| 212 | const anthropic = createAnthropic({ |
| 213 | apiKey: apiKey || process.env.ANTHROPIC_API_KEY!, |
| 214 | }); |
| 215 | // Accepts any Claude id, e.g. "claude-3.7-sonnet", "claude-3.5-haiku" |
| 216 | return anthropic(model); |
| 217 | } |
| 218 | |
| 219 | case "google": |
| 220 | case "gemini": |
| 221 | case "google-gemini": { |
| 222 | // Lazily create Google provider |
| 223 | // Use provided apiKey, or fall back to environment variable |
| 224 | const google = createGoogleGenerativeAI({ |
| 225 | apiKey: apiKey || process.env.GOOGLE_API_KEY!, |
no test coverage detected
searching dependent graphs…