/** * OpenAIProvider — wraps the `openai` SDK as an `LLMProvider`. * * Pattern: Adapter (GoF) + Ports-and-Adapters (Cockburn 2005). * Role: Outer ring — translates `LLMRequest`/`LLMResponse` to/from * OpenAI's Chat Completions API. Knows nothing about agents, * recorders, or compositions. * Emits: N/A. * * ─── Limitations ──────────────────────────────────────────────────── * * • Multi-modal NOT supported (`LLMMessage.content` is * `string`). May extend in a future release. * • `responseFormat` (JSON-mode) NOT exposed — pass schema * instructions via `systemPrompt` for now. * * The `baseURL` option enables OpenAI-compatible APIs (Ollama, Together, * Groq, vLLM, LM Studio) without a separate adapter — see the `ollama()` * convenience factory below. */ import type { LLMCallHooks, LLMChunk, LLMProvider, LLMRequest, LLMResponse } from '../types.js'; interface OpenAIClient { chat: { completions: { create(params: OpenAICreateParams): Promise | AsyncIterable; }; }; } interface OpenAICreateParams { model: string; messages: OpenAIMessage[]; tools?: OpenAITool[]; /** Legacy token cap — DEPRECATED by OpenAI and REJECTED by o-series reasoning * models. Kept only for custom OpenAI-compatible endpoints (Ollama/vLLM/…). */ max_tokens?: number; /** Current token cap — accepted by all OpenAI/Azure chat models incl. o-series. */ max_completion_tokens?: number; temperature?: number; stop?: string[]; stream?: boolean; /** Ask OpenAI/Azure to emit a final usage chunk while streaming. */ stream_options?: { include_usage: boolean; }; } interface OpenAIMessage { role: 'system' | 'developer' | 'user' | 'assistant' | 'tool'; content: string | null; tool_calls?: OpenAIToolCall[]; tool_call_id?: string; } interface OpenAIToolCall { id: string; type: 'function'; function: { name: string; arguments: string; }; } interface OpenAITool { type: 'function'; function: { name: string; description: string; parameters: Record; }; } interface OpenAIChatCompletion { id: string; model: string; choices: Array<{ index: number; message: { role: 'assistant'; content: string | null; tool_calls?: OpenAIToolCall[]; }; finish_reason: 'stop' | 'tool_calls' | 'length' | 'content_filter' | string; }>; usage?: { prompt_tokens: number; completion_tokens: number; }; } interface OpenAIStreamChunk { id: string; model: string; choices: Array<{ index: number; delta: { role?: string; content?: string | null; tool_calls?: Array<{ index: number; id?: string; type?: string; function?: { name?: string; arguments?: string; }; }>; }; finish_reason: string | null; }>; usage?: { prompt_tokens: number; completion_tokens: number; }; } export interface OpenAIProviderOptions { /** API key. Defaults to `OPENAI_API_KEY` env var. */ readonly apiKey?: string; /** Base URL — set for OpenAI-compatible APIs (Ollama, Together, vLLM). */ readonly baseURL?: string; /** * Default model used when `LLMRequest.model` is `'openai'` (the * shorthand). Full model ids pass through unchanged. */ readonly defaultModel?: string; /** Default max tokens when the request doesn't set it. Optional. */ readonly defaultMaxTokens?: number; /** * Treat the target as a **reasoning model** (o-series: o1 / o3 / o4-mini, or an * Azure reasoning deployment). Reasoning models reject `max_tokens` and an explicit * `temperature`, and use the `developer` role in place of `system`. Standard o-series * model ids are auto-detected; set this explicitly for Azure deployments whose name * does not reveal the underlying model. */ readonly reasoning?: boolean; /** @internal Pre-built client for testing. Skips SDK import. */ readonly _client?: OpenAIClient; } /** * Build an `LLMProvider` backed by OpenAI's Chat Completions API. * * @example * import { Agent } from 'agentfootprint'; * import { openai } from 'agentfootprint/llm-providers'; * * const agent = Agent.create({ * provider: openai({ defaultModel: 'gpt-4o' }), * model: 'openai', * }) * .tool(searchTool) * .build(); */ export declare function openai(options?: OpenAIProviderOptions): LLMProvider; /** * Class form for consumers who prefer `new OpenAIProvider(...)`. */ export declare class OpenAIProvider implements LLMProvider { readonly name = "openai"; private readonly inner; constructor(options?: OpenAIProviderOptions); complete(req: LLMRequest, hooks?: LLMCallHooks): Promise; stream(req: LLMRequest, hooks?: LLMCallHooks): AsyncIterable; } export interface AzureOpenAIProviderOptions { /** Resource endpoint, e.g. `https://my-co.openai.azure.com`. Env fallbacks: * `AZURE_OPENAI_ENDPOINT`, then `OPENAI_BASE_URL`. */ readonly endpoint?: string; /** API key. Env fallbacks: `AZURE_OPENAI_API_KEY`, then `OPENAI_API_KEY`. */ readonly apiKey?: string; /** Azure API version, e.g. `2024-12-01-preview`. Env fallback: * `AZURE_OPENAI_API_VERSION`. Required. */ readonly apiVersion?: string; /** The DEPLOYMENT name (Azure's "model"), e.g. `gpt-4o-128k`. Env fallbacks: * `AZURE_OPENAI_DEPLOYMENT`, then `MODEL_NAME`. Required. */ readonly deployment?: string; /** Default max tokens when the request doesn't set it. Optional. */ readonly defaultMaxTokens?: number; /** * Set when the Azure DEPLOYMENT is a **reasoning model** (o1/o3/o4-mini). Azure * deployment names are arbitrary, so this cannot be auto-detected — declare it to * omit `temperature` and send the `developer` role. (`max_completion_tokens` is used * for all Azure deployments regardless.) */ readonly reasoning?: boolean; /** @internal Pre-built client for testing. Skips SDK import. */ readonly _client?: OpenAIClient; } /** * Build an `LLMProvider` for **Azure OpenAI**. * * Azure is NOT a drop-in OpenAI-compatible URL — it uses a deployment-scoped * path, `api-key` header auth, and an `api-version` query param. This wraps the * `openai` SDK's `AzureOpenAI` client (which handles all that) and reuses the * exact same completion/streaming/tool-call logic as `openai()`. * * The request's `model` is the Azure **deployment** name. Pass a deployment id * to target it; the shorthands `'azure'` / `'azure-openai'` resolve to the * configured default `deployment`. * * @example * import { azureOpenai } from 'agentfootprint/llm-providers'; * * const agent = Agent.create({ * provider: azureOpenai({ * endpoint: process.env.OPENAI_BASE_URL, // *.openai.azure.com * apiKey: process.env.AZURE_OPENAI_API_KEY, * apiVersion: process.env.AZURE_OPENAI_API_VERSION, // 2024-12-01-preview * deployment: process.env.MODEL_NAME, // gpt-4o-128k * }), * model: 'azure', * }).build(); */ export declare function azureOpenai(options?: AzureOpenAIProviderOptions): LLMProvider; /** * Convenience factory for Ollama (OpenAI-compatible endpoint). * * @example * import { ollama } from 'agentfootprint/llm-providers'; * * const provider = ollama({ defaultModel: 'llama3.2' }); * // Talks to http://localhost:11434/v1 by default. */ export declare function ollama(options?: OpenAIProviderOptions & { readonly host?: string; }): LLMProvider; export {};