How to Integrate Custom LLM Providers with OpenMAIC: A Complete Guide

OpenMAIC integrates custom LLM providers through a centralized registry in lib/ai/providers.ts, supporting both static code definitions and dynamic UI-based configuration for any OpenAI-compatible API.

OpenMAIC is built on top of the Vercel AI SDK (generateText and streamText) and provides a flexible abstraction layer for LLM integrations. By leveraging the provider registry architecture, you can seamlessly integrate custom LLM providers with OpenMAIC without modifying core application logic, whether you prefer code-controlled deployments or runtime UI configuration.

Understanding the Provider Architecture

The LLM layer centers on two critical files in the lib/ai/ directory. The lib/ai/providers.ts file defines the provider registry (PROVIDERS object starting at line 75), which stores metadata about each service, including base URLs, authentication requirements, and model capabilities. When the application needs to call an LLM, it routes through lib/ai/llm.ts, where the callLLM and streamLLM functions (lines 25-33) handle provider resolution and request dispatch.

Every provider entry in the registry must define:

  • ID and name – Internal identifiers and UI labels
  • Base URL – Default endpoint or custom URL from environment variables
  • Authentication flag – Whether an API key is required
  • Model list – Supported models with capabilities (streaming, tools, vision, thinking)

The system extracts the model ID and provider ID from the params.model object, builds provider-specific payloads via injectProviderOptions (lines 47-57), and executes the request through a unified fetch wrapper.

Method 1: Adding a Static Provider Definition

For code-controlled deployments, hard-code your provider directly into the PROVIDERS object. This method provides version control and ensures consistent configuration across deployments.

Step 1: Define the Provider Entry

Open lib/ai/providers.ts and add a new key to the PROVIDERS map following the existing pattern (reference the openrouter entry for structure):

// lib/ai/providers.ts
export const PROVIDERS = {
  // ... existing providers
  myai: {
    id: 'myai',
    name: 'My-AI',
    type: 'openai',                     // Uses OpenAI-compatible path
    defaultBaseUrl: 'https://api.my-ai.com/v1',
    requiresApiKey: true,
    icon: '/logos/myai.svg',
    models: [
      {
        id: 'mygpt-4',
        name: 'MyGPT-4',
        contextWindow: 1048576,
        outputWindow: 65536,
        capabilities: {
          streaming: true,
          tools: true,
          vision: true,
          thinking: {
            toggleable: true,
            budgetAdjustable: true,
            defaultEnabled: true,
          },
        },
      },
    ],
  },
};

Step 2: Add the Provider Icon

Place the provider's logo in the public/logos/ directory and reference it in the icon field using a root-relative path.

Step 3: Handle Custom Thinking Parameters (Optional)

If your service uses non-standard reasoning flags, extend getCompatThinkingBodyParams around line 990 to translate OpenMAIC's thinking configuration into vendor-specific payload fields:

// lib/ai/providers.ts
function getCompatThinkingBodyParams(
  providerId: ProviderId,
  modelId: string,
  config: ThinkingConfig,
) {
  // ... existing cases ...
  case 'myai': {
    const mode = getThinkingMode(config);
    return mode === 'disabled' 
      ? { enable_thinking: false } 
      : { enable_thinking: true };
  }
}

Method 2: Dynamic Provider Configuration via UI

For environments requiring runtime flexibility without code changes, OpenMAIC supports dynamic provider definitions stored in browser localStorage.

  1. Navigate to Settings → LLM Providers in the UI
  2. Click Add Provider and submit a JSON object matching the ProviderConfig interface (see the runtime loader in providers.ts lines 85-92)
  3. The UI persists the configuration under the providersConfig localStorage key
  4. On page load, getProviderConfig (lines 85-92) merges this stored configuration with the built-in PROVIDERS list

This approach allows non-technical users to integrate custom endpoints without deploying new code, though it requires the custom service to follow the OpenAI API specification.

Implementing Provider-Specific Features

When integrating providers that support thinking or reasoning modes (such as budget-controlled inference or effort levels), you must map OpenMAIC's abstract thinking configuration to the provider's specific API parameters.

The thinkingContext.run wrapper in lib/ai/llm.ts injects vendor-specific body fields through the injectProviderOptions function. For providers requiring custom translation logic, add a case to getCompatThinkingBodyParams that converts the ThinkingConfig object into the expected payload structure. This ensures that toggles in the OpenMAIC UI correctly control reasoning behavior on the backend.

Calling Your Custom Provider

Once registered (either statically or dynamically), invoke your provider through the unified callLLM interface by specifying the provider ID and model ID:

import { callLLM } from '@/lib/ai/llm';

const response = await callLLM(
  {
    model: { 
      provider: 'myai', 
      modelId: 'mygpt-4' 
    },
    prompt: 'Explain quantum entanglement in simple terms.',
    maxOutputTokens: 1024,
    // Additional AI SDK parameters (tools, temperature, etc.)
  },
  'my-feature',  // Feature identifier for logging/tracking
);

The callLLM implementation automatically resolves the provider configuration, injects any thinking options via buildThinkingProviderOptions, and routes the request through the appropriate fetch wrapper in providers.ts.

Summary

  • All LLM calls funnel through callLLM and streamLLM in lib/ai/llm.ts, providing a single integration point for the entire platform
  • Static provider definitions in lib/ai/providers.ts (line 75) offer version-controlled, code-based configuration ideal for production deployments
  • Dynamic configuration via localStorage (lines 85-92) enables UI-driven provider addition without code changes
  • Thinking/reasoning support requires extending getCompatThinkingBodyParams (around line 990) to map abstract configs to vendor-specific API fields
  • OpenAI-compatible APIs integrate seamlessly using the type: 'openai' designation, requiring only base URL and model metadata configuration

Frequently Asked Questions

What file do I modify to add a custom LLM provider permanently?

Add your provider definition to the PROVIDERS object in lib/ai/providers.ts starting around line 75. This static registry ensures your configuration persists across deployments and version control tracks changes to your provider integration.

Can users add LLM providers without editing code?

Yes. OpenMAIC supports dynamic provider configuration through the Settings UI, which stores provider JSON in localStorage under the key providersConfig. The getProviderConfig function (lines 85-92) automatically merges these runtime definitions with the built-in registry on page load, enabling non-technical users to configure endpoints.

How do I handle custom reasoning or thinking parameters for my provider?

Extend the getCompatThinkingBodyParams function in lib/ai/providers.ts (around line 990) to translate OpenMAIC's ThinkingConfig into your provider's specific API fields. Add a case for your provider ID that returns the appropriate payload structure based on the thinking mode (enabled/disabled) and budget configuration.

Does OpenMAIC support non-OpenAI API formats?

While OpenMAIC is optimized for OpenAI-compatible APIs (using type: 'openai'), you can technically support other formats by modifying the fetch wrapper logic in lib/ai/providers.ts. However, this requires deeper customization of the request building logic beyond the standard provider registry configuration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →