import type { ExtensionAPI, ProviderModelConfig } from "@earendil-works/pi-coding-agent"; import { buildModelCatalog, parseModelListResponse, resolveBaseUrl, STATIC_FALLBACK_CATALOG, } from "./helpers.ts"; const PROVIDER_ID = "bailian"; function sanitizeRemoteMessage(value: unknown, apiKey: string): string | undefined { if (typeof value !== "string") return undefined; let text = value.replaceAll(apiKey, "[redacted]").replace(/sk-[A-Za-z0-9_-]{8,}/g, "[redacted]"); text = text.replace(/[\r\n\t]+/g, " ").trim(); return text ? text.slice(0, 300) : undefined; } async function readErrorMessage(response: Response, apiKey: string): Promise { try { const payload = (await response.json()) as { message?: unknown; error?: { message?: unknown } | string }; const message = payload?.message ?? (typeof payload?.error === "string" ? payload.error : payload?.error?.message); return sanitizeRemoteMessage(message, apiKey); } catch { return undefined; } } async function discoverModels(baseUrl: string, apiKey: string, signal: AbortSignal): Promise { if (!apiKey) throw new Error("DASHSCOPE_API_KEY is not set; Bailian model discovery cannot authenticate"); let response: Response; try { response = await fetch(`${baseUrl}/models`, { headers: { Accept: "application/json", Authorization: `Bearer ${apiKey}`, }, signal, }); } catch (error) { if (signal.aborted) throw error; throw new Error(`Bailian model discovery request failed: ${error instanceof Error ? error.message : "network error"}`); } if (!response.ok) { const remoteMessage = await readErrorMessage(response, apiKey); const hint = response.status === 401 || response.status === 403 ? " Check that the API key matches the configured region." : ""; throw new Error( `Bailian model discovery failed with HTTP ${response.status}${remoteMessage ? `: ${remoteMessage}` : ""}.${hint}`, ); } let payload: unknown; try { payload = await response.json(); } catch { throw new Error("Bailian model discovery returned invalid JSON"); } return buildModelCatalog(parseModelListResponse(payload)) as ProviderModelConfig[]; } export default function bailianExtension(pi: ExtensionAPI): void { const baseUrl = resolveBaseUrl(process.env); pi.registerProvider(PROVIDER_ID, { name: "Alibaba Cloud Bailian (API Key)", baseUrl, apiKey: "$DASHSCOPE_API_KEY", authHeader: true, api: "openai-completions", models: [...STATIC_FALLBACK_CATALOG] as ProviderModelConfig[], async refreshModels(context) { return discoverModels(baseUrl, process.env.DASHSCOPE_API_KEY?.trim() ?? "", context.signal); }, }); }