/** * Custom API provider registry. * * Allows extensions to register streaming functions for custom API types * (e.g., "vertex-Anthropic model-api") that are not built into stream.ts. */ import type { Api, AssistantMessageEventStream, Context, KnownApi, Model, SimpleStreamOptions, StreamOptions, } from "./types"; const BUILTIN_APIS = new Set([ "openai-completions", "openai-responses", "openai-codex-responses", "azure-openai-responses", "anthropic-messages", "bedrock-converse-stream", "google-generative-ai", "google-gemini-cli", "google-vertex", "ollama-chat", "cursor-agent", ]); export type CustomStreamFn = ( model: Model, context: Context, options?: StreamOptions, ) => AssistantMessageEventStream; export type CustomStreamSimpleFn = ( model: Model, context: Context, options?: SimpleStreamOptions, ) => AssistantMessageEventStream; export interface RegisteredCustomApi { stream: CustomStreamFn; streamSimple: CustomStreamSimpleFn; sourceId?: string; } const customApiRegistry = new Map(); function assertCustomApiName(api: string): void { if (BUILTIN_APIS.has(api as KnownApi)) { throw new Error(`Cannot register custom API "${api}": built-in API names are reserved.`); } } /** * Register a custom API streaming function. */ export function registerCustomApi( api: string, streamSimple: CustomStreamSimpleFn, sourceId?: string, stream?: CustomStreamFn, ): void { assertCustomApiName(api); customApiRegistry.set(api, { stream: stream ?? ((model, context, options) => streamSimple(model, context, options as SimpleStreamOptions)), streamSimple, sourceId, }); } /** * Get a custom API provider by API identifier. */ export function getCustomApi(api: string): RegisteredCustomApi | undefined { return customApiRegistry.get(api); } /** * Remove all custom APIs registered by a specific source (e.g., extension path). */ export function unregisterCustomApis(sourceId: string): void { for (const [api, entry] of customApiRegistry.entries()) { if (entry.sourceId === sourceId) { customApiRegistry.delete(api); } } } /** * Clear all custom API registrations. */ export function clearCustomApis(): void { customApiRegistry.clear(); }