Providers and compatibility
All providers implement the same interface:
interface LLMProvider {
name: string
complete(params: CompletionParams): Promise<string>
stream?(params: CompletionParams): AsyncIterable<string>
}
The provider only returns raw text. Parsing, repair retries, and validation stay in the core engine.
OpenAI chat.completions
new OpenAIProvider({ apiKey, baseURL, organization, defaultModel })
json_schema:response_format: { type: 'json_schema', json_schema: { strict: true } }json_object/auto:response_format: { type: 'json_object' }tool_call:tools + tool_choice; returnstool_calls[0].function.arguments- OpenAI-compatible gateways use the same provider with
baseURL; if a gateway does not support native modes, usemode: 'json_object'ormode: 'prompt'.
OpenAI Responses API
new OpenAIResponsesProvider({ apiKey, baseURL, organization, defaultModel })
- System messages are mapped to
instructions; other messages become Responsesinput. json_schema/json_objectusetext.format.tool_callreadsoutput[*].function_call.arguments.- Streaming currently yields the final text once so
streamStructuredshares the same validation path; incremental Responses events are not normalized yet.
Anthropic
new AnthropicProvider({ apiKey, defaultModel })
- Non-tool modes move system messages into Anthropic
systemand append a raw-JSON instruction. tool_callusestools + tool_choiceand serializestool_use.inputback to JSON text for the shared validator.
Google Gemini
new GoogleProvider({ apiKey, defaultModel })
- Uses
responseMimeType: 'application/json'and, forjson_schema/auto,responseSchema. - Chat history is converted to Gemini
contentswithuser/modelroles.
Custom provider
Implement LLMProvider and return raw model text from complete. Add stream when the provider can emit text deltas. Keep provider-specific response parsing inside the provider so the core retry logic stays provider-agnostic.