How Craft Agents OSS Implements Multi-Provider LLM Support for Anthropic, Google, OpenAI, and Ollama
Craft Agents OSS abstracts every LLM behind a connection object that uses providerType, piAuthProvider, and customEndpoint fields to route requests to Anthropic, Google, OpenAI, or local Ollama instances through a unified network interceptor.
Craft Agents OSS provides a flexible multi-provider LLM support system that standardizes interactions across disparate AI services. The architecture centers on a connection-based abstraction layer defined in the shared configuration package, enabling seamless switching between cloud providers and local inference servers without changing application logic.
Understanding the LLM Connection Architecture
The system defines every LLM integration through the LlmConnection interface in packages/shared/src/config/llm-connections.ts. Each connection stores three critical routing fields:
providerType: Determines the backend handler (anthropic,pi, orpi_compat)piAuthProvider: When using the Pi SDK, specifies the upstream service (anthropic,openai,google-vertex, etc.)customEndpoint: For local or custom servers, defines the API protocol (openai-completionsoranthropic-messages)
This schema enables the system to treat diverse providers identically at the application layer while preserving provider-specific optimizations at the transport layer.
Provider-Specific Implementation Patterns
Anthropic – Direct SDK Integration
For first-party Anthropic access, set providerType: 'anthropic'. This bypasses the Pi SDK entirely and invokes the official Claude SDK (@anthropic-ai/claude-agent-sdk). The anthropicAdapter in packages/shared/src/unified-network-interceptor.ts handles HTTP interception, request normalization, and beta feature headers.
Google Vertex AI – Pi SDK Routing
Google integration uses the unified Pi SDK layer. Configure providerType: 'pi' with piAuthProvider: 'google-vertex' (or 'google' for other Google APIs). The Pi SDK bundles Google's Vertex AI model list and IAM credential authentication. The piAdapter forwards requests to Google's endpoints while handling the proprietary authentication flow.
OpenAI – Unified SDK Interface
OpenAI connections leverage providerType: 'pi' and piAuthProvider: 'openai' (or 'openai-codex' for ChatGPT-plus OAuth). The Pi SDK unifies Chat Completion and Completion APIs under a single interface. The openAiAdapter in the interceptor manages endpoint translation and model ID normalization.
Ollama – Custom Local Endpoints
Local Ollama servers require providerType: 'pi_compat' to bypass the Pi SDK's built-in provider registry. Set authType: 'none' and provide a customEndpoint: { api: 'openai-completions' } (or anthropic-messages depending on the model format). The user-supplied baseUrl (e.g., http://localhost:11434) streams requests directly to the local instance without cloud authentication.
Runtime Request Routing
The Unified Network Interceptor (packages/shared/src/unified-network-interceptor.ts) selects adapters at runtime based on the connection configuration:
if (connection.providerType === 'anthropic') {
use(anthropicAdapter);
} else if (connection.providerType === 'pi') {
use(piAdapter);
} else {
use(piCompatAdapter);
}
This interceptor injects tool metadata, strips unnecessary headers, and normalizes model IDs across providers. The requestViaAdapter function prepares the final HTTP request body and headers specific to each provider's requirements.
Migration and Legacy Compatibility
Legacy provider IDs such as anthropic_compat, openai_compat, bedrock, and vertex automatically migrate to the canonical pi/pi_compat layout via the migration logic in packages/shared/src/config/storage.ts. This ensures backward compatibility while maintaining a consistent internal API.
Configuration Code Examples
Anthropic Connection
import { LlmConnection } from '@/packages/shared/src/config/llm-connections';
const anthropicConn: LlmConnection = {
slug: 'anthropic-api',
name: 'Anthropic (API Key)',
providerType: 'anthropic',
authType: 'api_key',
baseUrl: 'https://api.anthropic.com',
defaultModel: 'claude-3-5-sonnet-20241022',
};
Google Vertex AI Connection
const googleConn: LlmConnection = {
slug: 'google-vertex',
name: 'Google Vertex AI',
providerType: 'pi',
piAuthProvider: 'google-vertex',
authType: 'service_account_file',
defaultModel: 'google/gemini-1.5-pro',
};
Ollama Local Connection
const ollamaConn: LlmConnection = {
slug: 'ollama-local',
name: 'Ollama',
providerType: 'pi_compat',
authType: 'none',
baseUrl: 'http://127.0.0.1:11434',
customEndpoint: { api: 'openai-completions' },
defaultModel: 'ollama/phi-3-mini',
};
Executing Requests
import { requestViaAdapter } from '@/packages/shared/src/unified-network-interceptor';
async function queryModel(conn: LlmConnection, prompt: string) {
const body = {
model: conn.defaultModel,
messages: [{ role: 'user', content: prompt }]
};
const { init, body: finalBody } = requestViaAdapter(conn, body);
const response = await fetch(conn.baseUrl, {
...init,
body: JSON.stringify(finalBody)
});
return response.json();
}
Summary
- Craft Agents OSS uses a connection-based abstraction with three routing fields (
providerType,piAuthProvider,customEndpoint) to standardize LLM access across providers. - Direct SDK integration handles Anthropic requests, while the Pi SDK unifies Google and OpenAI under a single interface.
- Ollama and custom endpoints use
pi_compatmode with explicitcustomEndpointdefinitions to support local inference. - The Unified Network Interceptor in
packages/shared/src/unified-network-interceptor.tsroutes requests to the appropriate adapter at runtime based on connection metadata. - Automatic migration in
packages/shared/src/config/storage.tsconverts legacy provider IDs to the current schema, ensuring backward compatibility.
Frequently Asked Questions
What is the difference between pi and pi_compat provider types?
The pi provider type uses the Pi SDK's built-in provider registry and authentication handlers for cloud services like OpenAI and Google Vertex AI. The pi_compat type bypasses the built-in registry to support custom endpoints such as local Ollama servers or proprietary APIs, requiring explicit customEndpoint configuration to specify the protocol format.
How does Craft Agents OSS handle authentication for different providers?
Authentication is determined by the authType field in the connection object. Anthropic connections use api_key, Google Vertex AI uses service_account_file or iam_credentials, OpenAI uses standard API keys or OAuth tokens, and local Ollama instances use authType: 'none'. The credentials manager in packages/shared/src/credentials/manager.ts securely stores and retrieves these secrets by provider slug.
Can I use models not in the default model list?
Yes. When using pi_compat mode, you can specify any model identifier in the defaultModel field, provided your custom endpoint supports it. The system validates model IDs against the central registry in packages/shared/src/models.ts for built-in providers, but passes custom strings directly to pi_compat endpoints without validation.
Where is the request routing logic implemented?
The runtime adapter selection occurs in packages/shared/src/unified-network-interceptor.ts. This file exports the requestViaAdapter function that inspects connection.providerType and invokes the appropriate anthropicAdapter, piAdapter, or piCompatAdapter to prepare provider-specific HTTP headers, body formatting, and authentication injection.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →