import type { ModelCatalogEntry, ModelCredential } from "@rakazo/contracts"; export type ConnectedModelOption = { credentialId: string; provider: string; modelId: string; label: string; }; /** * Models the user's connections can run: every catalog model of a catalog provider, and the * saved id of a free-form connection plus any ids its server lists (keyed by credential id). */ export function connectedModelOptions( credentials: ModelCredential[], catalog: ModelCatalogEntry[], serverModels: Record = {}, ): ConnectedModelOption[] { const options: ConnectedModelOption[] = []; const seen = new Set(); for (const credential of credentials) { const providerModels = catalog.filter( (entry) => entry.provider === credential.provider && !entry.placeholder, ); const listed = serverModels[credential.id] ?? []; const freeForm = Boolean(credential.modelId) && !providerModels.some((entry) => entry.id === credential.modelId); const candidates = freeForm || listed.length ? [credential.modelId, ...listed] .filter((modelId): modelId is string => Boolean(modelId)) .map((modelId) => ({ modelId, label: `${credential.label} · ${modelId}` })) : providerModels.map((entry) => ({ modelId: entry.id, label: `${entry.providerName ?? entry.provider} · ${entry.label}`, })); for (const candidate of candidates) { const key = `${credential.provider}::${candidate.modelId}`; if (seen.has(key)) continue; seen.add(key); options.push({ credentialId: credential.id, provider: credential.provider, ...candidate }); } } return options; }