/** * Protocol-named AI model driver contracts. * * Driver ids: `mock` · `anthropic` · `openai-compatible` · `bedrock` · `vertex`. * Dev default is `mock`. There is **no** production default — prod must declare. */ import type { DriverExternal } from "./external.ts"; /** Protocol ids for AI model drivers. */ export type AiDriverId = "mock" | "anthropic" | "openai-compatible" | "bedrock" | "vertex"; /** Tool definition offered to a model (Flow-backed at the fx layer). */ export interface AiToolDef { readonly name: string; readonly description?: string; /** JSON-schema-like parameters object. */ readonly parameters?: unknown; } /** One model-initiated tool invocation. */ export interface AiToolCall { readonly id: string; readonly name: string; readonly arguments: unknown; } /** One chat / completion turn. */ export interface AiMessage { readonly role: "system" | "user" | "assistant" | "tool"; readonly content: string; readonly name?: string; /** When role is `tool`, the id of the tool call this message answers. */ readonly toolCallId?: string; /** When role is `assistant`, optional tool calls the model requested. */ readonly toolCalls?: readonly AiToolCall[]; } /** Options for a model completion (or stream start). */ export interface AiCompleteOptions { readonly messages: readonly AiMessage[]; readonly model?: string; readonly temperature?: number; readonly maxTokens?: number; /** Structured output hint (JSON schema or name). */ readonly responseFormat?: unknown; /** Tools the model may call (OpenAI-shaped; drivers map). */ readonly tools?: readonly AiToolDef[]; /** Ambient / local abort — cooperative cancellation for complete + stream. */ readonly signal?: AbortSignal; } /** Result of a model completion. */ export interface AiCompleteResult { readonly text: string; readonly raw?: unknown; readonly model: string; readonly driverId: AiDriverId; readonly toolCalls?: readonly AiToolCall[]; readonly usage?: { readonly inputTokens?: number; readonly outputTokens?: number; readonly cost?: number; }; /** Egress identity when the completion left the process. */ readonly external?: DriverExternal; } /** One tool-call fragment inside a model stream. */ export interface AiStreamToolCallDelta { /** Provider index for this call within the turn. */ readonly index: number; readonly id?: string; readonly name?: string; /** Partial JSON arguments. Empty when the call is only announced. */ readonly argumentsDelta?: string; } /** One streamed token / delta from a model. */ export interface AiStreamChunk { readonly text: string; readonly done?: boolean; readonly toolCall?: AiStreamToolCallDelta; readonly usage?: { readonly inputTokens?: number; readonly outputTokens?: number; readonly cost?: number; }; /** Provider payload. Present on the terminal chunk when the driver has one. */ readonly raw?: unknown; /** Egress identity, matching {@link AiCompleteResult.external}. */ readonly external?: DriverExternal; } /** Embedding request. */ export interface AiEmbedOptions { readonly input: string | readonly string[]; readonly model?: string; } /** Embedding result. */ export interface AiEmbedResult { readonly vectors: readonly (readonly number[])[]; readonly model: string; readonly driverId: AiDriverId; /** Egress identity when the embed left the process. */ readonly external?: DriverExternal; } /** Opened model client. */ export interface AiModelClient { readonly driverId: AiDriverId; readonly model: string; complete(options: AiCompleteOptions): Promise; /** * Stream tokens. Optional — callers fail loud when missing (no stub echo). * * @param options - Same as complete, plus optional signal */ stream?(options: AiCompleteOptions): AsyncIterable; embed?(options: AiEmbedOptions): Promise; close?(): Promise; } /** Options when opening a model driver. */ export interface AiOpenOptions { readonly model?: string; readonly apiKey?: string; readonly baseUrl?: string; /** * Extra HTTP headers (e.g. OpenRouter `HTTP-Referer` / `X-Title`). * Merged into chat and embed requests; does not invent a new driver. */ readonly headers?: Readonly>; /** Mock canned responses keyed by prompt name or substring. */ readonly mockResponses?: Readonly>; readonly fetch?: typeof globalThis.fetch; /** * Driver-reported egress classification for ledger entries. * Set by the AI element from declare-time provider identity — never guessed * by hostname regex inside the driver. */ readonly external?: { readonly kind: "third-party" | "infrastructure"; readonly provider?: string; }; } /** AI model driver factory. */ export interface AiDriver { readonly id: AiDriverId; open(options?: AiOpenOptions): Promise; }