# How Craft Agents OSS Implements Multi-Provider LLM Support for Anthropic, Google, OpenAI, and Ollama

> Discover how Craft Agents OSS integrates Anthropic, Google, OpenAI, and Ollama with multi-provider LLM support. Learn about its unified network interceptor for seamless LLM routing.

- Repository: [Craft Ai Agents/craft-agents-oss](https://github.com/craft-ai-agents/craft-agents-oss)
- Tags: deep-dive
- Published: 2026-07-03

---

**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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/config/llm-connections.ts). Each connection stores three critical routing fields:

- **`providerType`**: Determines the backend handler (`anthropic`, `pi`, or `pi_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-completions` or `anthropic-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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/unified-network-interceptor.ts)) selects adapters at runtime based on the connection configuration:

```typescript
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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/config/storage.ts). This ensures backward compatibility while maintaining a consistent internal API.

## Configuration Code Examples

### Anthropic Connection

```typescript
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

```typescript
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

```typescript
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

```typescript
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_compat` mode with explicit `customEndpoint` definitions to support local inference.
- The **Unified Network Interceptor** in [`packages/shared/src/unified-network-interceptor.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/unified-network-interceptor.ts) routes requests to the appropriate adapter at runtime based on connection metadata.
- **Automatic migration** in [`packages/shared/src/config/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/config/storage.ts) converts 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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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.