/** * Provider mirror metadata and model-registry helpers. * * Both pi-credential-vault and pi-multicodex need to mirror existing * provider configurations before installing extension-owned behavior. * This module provides a single copy of that logic. */ import { getApiProvider, getModels, getProviders, type KnownProvider, } from "@mariozechner/pi-ai"; /** * Model definition shape shared by provider mirrors. * * Captures the subset of a pi-ai Model that extensions need when * re-registering a provider via pi.registerProvider(). */ export interface MirroredModelDef { readonly id: string; readonly name: string; readonly reasoning: boolean; readonly input: ReadonlyArray<"text" | "image">; readonly cost: { readonly input: number; readonly output: number; readonly cacheRead: number; readonly cacheWrite: number; }; readonly contextWindow: number; readonly maxTokens: number; } /** * A snapshot of an existing provider's configuration. * * Contains everything an extension needs to re-register the provider * with modified behavior while preserving the original models and base URL. */ export interface MirroredProvider { readonly providerId: string; readonly baseUrl: string; readonly api: string; readonly models: ReadonlyArray; readonly hasStreamSimple: boolean; } /** * Mirror an existing provider's configuration from pi-ai's registry. * * Returns undefined if the provider has no registered models. */ export function mirrorProvider( providerId: KnownProvider, ): MirroredProvider | undefined { const models = getModels(providerId); if (models.length === 0) { return undefined; } const first = models[0]; if (!first) { return undefined; } const baseProvider = getApiProvider(first.api); const baseUrl = first.baseUrl ?? ""; return { providerId, baseUrl, api: first.api, models: models.map((m) => ({ id: m.id, name: m.name, reasoning: m.reasoning, input: m.input, cost: m.cost, contextWindow: m.contextWindow, maxTokens: m.maxTokens, })), hasStreamSimple: Boolean(baseProvider), }; } /** * List all provider IDs that have at least one registered model. * * Uses pi-ai's getProviders() — no hardcoded list needed. */ export function listProviderIdsWithModels(): KnownProvider[] { return getProviders().filter((id) => getModels(id).length > 0); }