Providers Overview

phi-core supports multiple LLM providers through the StreamProvider trait and ApiProtocol dispatch. Callers never name a provider struct directly — ModelConfig is the single descriptor for every provider connection.

Supported Protocols

ApiProtocolWire FormatFactory Method
AnthropicMessagesAnthropic Messages APIModelConfig::anthropic(id, name, key)
OpenAiCompletionsOpenAI Chat Completions (15+ backends)ModelConfig::openai(id, name, key) / ModelConfig::local(url, id, key) / ModelConfig::openrouter(id, key)
OpenAiResponsesOpenAI Responses APIDirect struct construction
AzureOpenAiResponsesAzure OpenAI ResponsesDirect struct construction
GoogleGenerativeAiGoogle Gemini APIModelConfig::google(id, name, key)
GoogleVertexGoogle Vertex AIDirect struct construction
BedrockConverseStreamAWS Bedrock ConverseStreamDirect struct construction

ApiProtocol Enum

#![allow(unused)]
fn main() {
pub enum ApiProtocol {
    AnthropicMessages,
    OpenAiCompletions,
    OpenAiResponses,
    AzureOpenAiResponses,
    GoogleGenerativeAi,
    GoogleVertex,
    BedrockConverseStream,
}
}

ModelConfig

ModelConfig is the single, complete description of a provider connection. Pass it to BasicAgent::new(), SubAgentTool::new(), or AgentLoopConfig.model_config:

#![allow(unused)]
fn main() {
pub struct ModelConfig {
    pub id: String,              // e.g. "gpt-4o" — model name sent to the API
    pub name: String,            // e.g. "GPT-4o" — display label for logging/UI
    pub api: ApiProtocol,        // Which wire protocol to use (dispatch key)
    pub provider: String,        // e.g. "openai" — logging label
    pub base_url: String,        // API endpoint (no trailing slash)
    pub api_key: String,         // Auth credential (sk-..., or "access_key:secret" for Bedrock)
    pub reasoning: bool,         // Supports thinking/reasoning
    pub context_window: u32,     // Context size in tokens
    pub max_tokens: u32,         // Default max output
    pub cost: CostConfig,        // Pricing per million tokens (0.0 = no tracking)
    pub headers: HashMap<String, String>,  // Extra HTTP headers
    pub compat: Option<OpenAiCompat>,      // Quirk flags (OpenAiCompletions only)
}
}

Factory methods (all accept api_key as the auth parameter):

#![allow(unused)]
fn main() {
let api_key = std::env::var("ANTHROPIC_API_KEY").unwrap();
let anthropic = ModelConfig::anthropic("claude-sonnet-4-20250514", "Claude Sonnet 4", &api_key);

let openai_key = std::env::var("OPENAI_API_KEY").unwrap();
let openai = ModelConfig::openai("gpt-4o", "GPT-4o", &openai_key);

let gemini_key = std::env::var("GEMINI_API_KEY").unwrap();
let google = ModelConfig::google("gemini-2.0-flash", "Gemini 2.0 Flash", &gemini_key);

// Local server — pass empty string for api_key if unauthenticated
let local = ModelConfig::local("http://localhost:1234/v1", "my-model", "");

// OpenRouter — dedicated factory with correct compat flags
let or_key = std::env::var("OPENROUTER_API_KEY").unwrap();
let openrouter = ModelConfig::openrouter("anthropic/claude-sonnet-4", &or_key);
}

ProviderRegistry

Maps ApiProtocolStreamProvider. The default registry includes all built-in providers:

#![allow(unused)]
fn main() {
let registry = ProviderRegistry::default();

// Use it to stream with any model
let result = registry.stream(&model_config, stream_config, tx, cancel).await?;
}

Custom registries (advanced — for adding a fully custom StreamProvider implementation):

#![allow(unused)]
fn main() {
use phi_core::provider::{ProviderRegistry, ApiProtocol};

let mut registry = ProviderRegistry::new();
registry.register(ApiProtocol::AnthropicMessages, my_custom_provider);
// Then pass to AgentLoopConfig... (most users should use provider_override instead)
}

StreamProvider Trait

#![allow(unused)]
fn main() {
#[async_trait]
pub trait StreamProvider: Send + Sync {
    async fn stream(
        &self,
        config: StreamConfig,
        tx: mpsc::UnboundedSender<StreamEvent>,
        cancel: CancellationToken,
    ) -> Result<Message, ProviderError>;
}
}

All providers receive a StreamConfig, emit StreamEvents through the channel, and return the final Message.

OpenAPI Tool Adapter

In addition to LLM providers, phi-core can auto-generate tools from any OpenAPI 3.0 spec. This is a tool integration (not a provider), but it complements the provider system by letting agents call external APIs.

Enable with features = ["openapi"]. See the OpenAPI Tools guide for details.