( connection: ConnectionEffectConnection, apiKey: string, fetchFn: ConnectionEffectFetch | undefined, )
| 156 | } |
| 157 | |
| 158 | async function fetchProviderModelsStrict( |
| 159 | connection: ConnectionEffectConnection, |
| 160 | apiKey: string, |
| 161 | fetchFn: ConnectionEffectFetch | undefined, |
| 162 | ): Promise<ModelInfo[]> { |
| 163 | const baseUrl = effectiveBaseUrl(connection); |
| 164 | const definition = PROVIDER_DEFAULTS[connection.providerType]; |
| 165 | // Unknown providerType → no discovery path. Throw a clear error (caught and |
| 166 | // generalized by the caller) rather than crashing on `.modelDiscovery`. |
| 167 | // Mirrors `isFakeBackend` in @maka/core/connection-readiness.ts. |
| 168 | if (!definition) { |
| 169 | throw new Error(`Unknown provider type "${connection.providerType}"`); |
| 170 | } |
| 171 | const discovery = definition.modelDiscovery; |
| 172 | |
| 173 | if (discovery.kind === 'fallback') { |
| 174 | return definition.fallbackModels.map((id) => ({ id })); |
| 175 | } |
| 176 | if (discovery.kind === 'ollama') { |
| 177 | const r = await fetchForConnectionEffect(fetchFn, `${ollamaRoot(baseUrl)}/api/tags`, { |
| 178 | timeoutMs: MODEL_FETCH_TIMEOUT_MS, |
| 179 | }); |
| 180 | if (!r.ok) { |
| 181 | await r.cancel(); |
| 182 | throw new ConnectionEffectHttpError(r.status); |
| 183 | } |
| 184 | const data = await readProviderJson<{ models?: unknown }>(r); |
| 185 | return providerObjectArray<{ name?: string }>(data.models, 'Ollama models').flatMap((model) => |
| 186 | model.name ? [{ id: model.name }] : [], |
| 187 | ); |
| 188 | } |
| 189 | if (discovery.kind === 'fireworks') { |
| 190 | return fetchFireworksModels(baseUrl, apiKey, discovery, fetchFn); |
| 191 | } |
| 192 | if (discovery.kind === 'cohere') { |
| 193 | return fetchCohereModels(baseUrl, apiKey, fetchFn); |
| 194 | } |
| 195 | if (discovery.kind === 'cloudflare') { |
| 196 | return fetchCloudflareModels(baseUrl, apiKey, fetchFn); |
| 197 | } |
| 198 | if (discovery.auth === 'github-copilot') { |
| 199 | return fetchGitHubCopilotModels(baseUrl, apiKey, fetchFn); |
| 200 | } |
| 201 | if (discovery.auth === 'openai-codex') { |
| 202 | return fetchOpenAiCodexModels(baseUrl, apiKey, fetchFn); |
| 203 | } |
| 204 | |
| 205 | switch (definition.protocol) { |
| 206 | case 'anthropic': { |
| 207 | const r = await fetchForConnectionEffect(fetchFn, anthropicV1Url(baseUrl, '/models'), { |
| 208 | headers: anthropicModelHeaders( |
| 209 | discovery.auth === 'claude-subscription' ? discovery.auth : undefined, |
| 210 | apiKey, |
| 211 | ), |
| 212 | timeoutMs: MODEL_FETCH_TIMEOUT_MS, |
| 213 | }); |
| 214 | if (!r.ok) { |
| 215 | await r.cancel(); |
no test coverage detected