# How to Create a Custom Provider Integration for an Unsupported Model in Prime Agent

> Integrate unsupported models into Prime Agent by creating a custom provider. Learn to register your model, define specs, and implement streamSimple for seamless integration.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: how-to-guide
- Published: 2026-08-09

---

**To create a custom provider integration for an unsupported model in Prime Agent, implement a provider registration object with a unique API identifier, define your model specifications, and provide a `streamSimple` function that translates Prime Agent's unified `Context` into the provider's request format while emitting `AssistantMessageEvent` streams.**

Prime Agent supports a plug-in architecture that allows developers to extend its capabilities beyond built-in LLM providers. This guide walks through the exact steps to register a new provider for models not natively supported by the framework, referencing the core types and registration patterns found in the `PrimeIntellect-ai/prime-agent` repository.

## Understanding the Core Provider Types

Before implementing a custom provider, you must understand the type definitions that govern all provider integrations. The core interfaces live in [`packages/ai/src/types.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/types.ts), which defines the contracts for `Api`, `Provider`, `Model<TApi>`, and `SimpleStreamOptions`.

The `Model<TApi>` interface requires you to specify capabilities such as context window size, supported input modalities (text, image), reasoning capabilities, and pricing metrics. Each model must reference a unique API identifier that distinguishes it from built-in providers. The `SimpleStreamOptions` type defines the optional parameters passed to your streaming function, including API keys and abort signals.

Your custom provider must implement the `streamSimple` function signature: it receives a `Model` instance, a `Context` object containing the conversation history, and optional `SimpleStreamOptions`, then returns an `AssistantMessageEventStream` that follows Prime Agent's event protocol.

## Implementing the Streaming Function

The `streamSimple` function serves as the translation layer between Prime Agent's unified interface and the target provider's API. This function must return an `AssistantMessageEventStream` that emits specific event types defined in [`packages/ai/src/types.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/types.ts).

Your implementation should handle the following event types:

- **`start`** – Emitted immediately with a partial `AssistantMessage` object containing metadata
- **`text_delta`** – Contains incremental text content from the model
- **`toolcall_start`** and **`toolcall_delta`** – For function calling capabilities
- **`done`** – Signals successful completion with the final stop reason
- **`error`** – Indicates failure with error details

The function must convert Prime Agent's `Context` format into the provider-specific request payload. For example, you might map the context messages to OpenAI-style chat completion formats or Anthropic's message structures, depending on your target API.

## Registering Your Custom Provider

Registration occurs through the `ExtensionAPI.registerProvider` method exposed by the coding-agent package. Your extension entry point receives an `ExtensionAPI` instance and must call `registerProvider` with a configuration object containing:

- **`api`** – A unique string identifier (must not conflict with built-in `KnownApi` values)
- **`baseUrl`** – The root endpoint for the provider's HTTP API
- **`apiKey`** – The environment variable name holding the static API key (if applicable)
- **`models`** – An array of `Model` descriptors defining available models, their costs, and capabilities
- **`oauth`** – Optional OAuth configuration object with `login`, `refreshToken`, and `getApiKey` methods
- **`streamSimple`** – Your implemented streaming function

Once registered, Prime Agent automatically adds these models to the internal registry, making them selectable via the `/model` command without requiring core code modifications.

## Handling Authentication

Prime Agent delegates credential management to the `auth-storage` subsystem found in [`packages/coding-agent/src/core/auth-storage.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/auth-storage.ts). You have two authentication patterns available for custom providers.

**API Key Authentication** is the simplest approach. Specify the `apiKey` field in your registration object with the name of an environment variable (e.g., `"MY_CUSTOM_API_KEY"`). The auth-storage system automatically retrieves this value and passes it through `SimpleStreamOptions` when calling your `streamSimple` function.

**OAuth Authentication** requires implementing three methods in the `oauth` configuration object: `login` to initiate the authorization flow, `refreshToken` to handle token renewal, and `getApiKey` to extract the usable credential from stored OAuth data. Reference the example in [`packages/ai/src/utils/oauth/anthropic.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/utils/oauth/anthropic.ts) for a working implementation pattern that you can adapt to other OAuth-capable services.

## Complete Working Example

The following implementation demonstrates a custom provider for a hypothetical API service. This pattern mirrors the reference implementation found in [`packages/coding-agent/examples/extensions/custom-provider-anthropic/index.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/examples/extensions/custom-provider-anthropic/index.ts).

First, implement the streaming function that handles the HTTP translation:

```typescript
import { 
  Model, 
  Api, 
  Context, 
  SimpleStreamOptions,
  createAssistantMessageEventStream,
  AssistantMessageEventStream 
} from '@prime-intellect-ai/ai';

export function streamMyProvider(
  model: Model<Api>,
  context: Context,
  options?: SimpleStreamOptions,
): AssistantMessageEventStream {
  const stream = createAssistantMessageEventStream();
  
  (async () => {
    const output = {
      role: "assistant" as const,
      content: [],
      api: model.api,
      provider: model.provider,
      model: model.id,
      usage: { 
        input: 0, 
        output: 0, 
        cacheRead: 0, 
        cacheWrite: 0, 
        totalTokens: 0, 
        cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } 
      },
      stopReason: "stop" as const,
      timestamp: Date.now(),
    };
    
    stream.push({ type: "start", partial: output });

    const payload = {
      model: model.id,
      messages: context.messages,
      stream: true,
      max_tokens: model.maxTokens,
    };

    const response = await fetch(`${model.baseUrl}/v1/chat/completions`, {
      method: "POST",
      headers: { 
        "Content-Type": "application/json", 
        "Authorization": `Bearer ${options?.apiKey}` 
      },
      body: JSON.stringify(payload),
    });

    for await (const chunk of response.body as any) {
      const text = parseChunkToText(chunk);
      if (text) {
        stream.push({ type: "text_delta", text });
      }
    }

    stream.push({ type: "done", reason: "stop", message: output });
    stream.end();
  })().catch(err => {
    output.stopReason = "error";
    output.errorMessage = err.message;
    stream.push({ type: "error", reason: "error", error: output });
    stream.end();
  });
  
  return stream;
}

```

Then, register the provider through your extension's entry point:

```typescript
import { ExtensionAPI } from '@prime-intellect-ai/coding-agent';

export default function (pi: ExtensionAPI) {
  pi.registerProvider("my-custom", {
    baseUrl: "https://api.myprovider.com",
    apiKey: "MY_CUSTOM_API_KEY",
    api: "my-custom-api",
    models: [
      {
        id: "my-model-1",
        name: "My Model 1",
        reasoning: true,
        input: ["text", "image"],
        cost: { input: 0.5, output: 1.5, cacheRead: 0.1, cacheWrite: 0.2 },
        contextWindow: 100000,
        maxTokens: 32768,
      },
    ],
    streamSimple: streamMyProvider,
  });
}

```

## Summary

- **Core types** for custom providers are defined in [`packages/ai/src/types.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/types.ts), including `Model<TApi>`, `SimpleStreamOptions`, and `AssistantMessageEventStream`.

- **Implementation** requires creating a `streamSimple` function that converts Prime Agent's `Context` into provider-specific HTTP requests while emitting standardized events like `start`, `text_delta`, and `done`.

- **Registration** happens via `ExtensionAPI.registerProvider`, which accepts configuration for base URLs, model descriptors, authentication methods, and your streaming implementation.

- **Authentication** supports both static API keys (referenced by environment variable name) and dynamic OAuth flows managed by the `auth-storage` subsystem in [`packages/coding-agent/src/core/auth-storage.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/auth-storage.ts).

- **Reference implementation** is available in [`packages/coding-agent/examples/extensions/custom-provider-anthropic/index.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/examples/extensions/custom-provider-anthropic/index.ts), demonstrating OAuth integration and complete event streaming.

## Frequently Asked Questions

### What file contains the type definitions required for custom provider integration?

The type definitions live in [`packages/ai/src/types.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/types.ts). This file contains the `Api`, `Provider`, `Model<TApi>`, and `SimpleStreamOptions` interfaces that your custom implementation must conform to, along with the event types for the streaming protocol.

### How does Prime Agent handle API keys for custom providers?

Prime Agent uses the `auth-storage` subsystem located in [`packages/coding-agent/src/core/auth-storage.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/auth-storage.ts) to resolve credentials. When you specify an `apiKey` field in your provider registration, the system reads that environment variable and passes the value through `SimpleStreamOptions` to your `streamSimple` function.

### Can I use OAuth instead of static API keys for my custom provider?

Yes. The provider registration object accepts an optional `oauth` configuration object containing `login`, `refreshToken`, and `getApiKey` methods. You can reference the implementation pattern in [`packages/ai/src/utils/oauth/anthropic.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/utils/oauth/anthropic.ts) to implement OAuth flows for services that support them.

### What event types must my streamSimple function emit?

Your implementation must emit events according to the protocol defined in [`packages/ai/src/types.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/types.ts). Required events include `start` (with initial metadata), `text_delta` (for content chunks), `toolcall_start` and `toolcall_delta` (for function calls), and either `done` (successful completion) or `error` (failure states).