import { ModelProvider, ProviderProbeResult } from "./types.js"; import { createId, nowIso } from "./ids.js"; export function createProvider( kind: ModelProvider["kind"], name: string, baseUrl: string ): ModelProvider { const createdAt = nowIso(); return { id: createId("provider"), name: name.trim(), kind, baseUrl: normalizeBaseUrl(baseUrl), enabled: true, supportsTools: kind !== "ollama", contextWindow: 8192, defaults: {}, createdAt, updatedAt: createdAt }; } export function normalizeBaseUrl(baseUrl: string): string { return baseUrl.trim().replace(/\/+$/, ""); } export async function probeOpenAiCompatibleProvider( provider: ModelProvider, fetchImpl: typeof fetch = fetch ): Promise { const url = `${normalizeBaseUrl(provider.baseUrl)}/models`; try { const response = await fetchImpl(url, { headers: provider.apiKey ? { Authorization: `Bearer ${provider.apiKey}` } : undefined }); if (!response.ok) { return { ok: false, providerId: provider.id, models: [], message: `Provider returned HTTP ${response.status}` }; } const body = await response.json() as { data?: Array<{ id?: string }>; models?: string[] }; const models = Array.isArray(body.data) ? body.data.map((model) => model.id).filter(Boolean) as string[] : Array.isArray(body.models) ? body.models : []; return { ok: models.length > 0, providerId: provider.id, models, message: models.length > 0 ? "Provider is reachable." : "Provider responded without model ids." }; } catch (error) { return { ok: false, providerId: provider.id, models: [], message: error instanceof Error ? error.message : "Provider probe failed." }; } }