How Model Adapters Are Integrated into Maka via AiSdkBackend: A Complete Technical Guide

Maka integrates model adapters through a three-layer backend architecture: AiSdkBackend orchestrates model creation, delegates to a model-factory.ts for provider selection, and uses model-adapter.ts to normalize specifications into concrete AI-SDK language models.

Maka's runtime abstracts every LLM interaction behind a unified Backend interface. When your workflow configuration sets the backend type to "ai-sdk", the system automatically wires requests through the AI‑SDK backend implemented in AiSdkBackend. This design enables seamless provider switching—OpenAI, Anthropic, Google, and others—without changing flow definitions.

Backend Registration and Entry Point

The AI‑SDK integration starts with backend registration. Maka registers the implementation under the key ai-sdk in src/ai-sdk-backend.ts.

When a flow step requires a language model, the runtime locates the registered backend and invokes its model creation method. This entry point shields the rest of the system from provider-specific details.

// Simplified conceptual flow
const backend = runtime.getBackend('ai-sdk'); // Resolves to AiSdkBackend instance
const model = backend.createModel(spec);        // Delegates to factory + adapter chain

The Model Factory: Provider Selection

The backend delegates actual model instantiation to the model factory (packages/runtime/src/model-factory.ts). This factory reads the ModelSpec configuration—provider name, model ID, temperature, max tokens—and selects the appropriate creator from the corresponding @ai-sdk/* package.

The factory maintains a registry mapping provider identifiers to SDK-specific creation functions. When you specify provider: '@ai-sdk/openai' or provider: '@ai-sdk/anthropic', the factory resolves this to the correct import and initialization logic.

import { createModelFactory } from '@maka/runtime/model-factory';
import type { ModelSpec } from '@maka/runtime/model-protocol';

const factory = createModelFactory();

const spec: ModelSpec = {
  backend: 'ai-sdk',
  provider: '@ai-sdk/anthropic',
  modelId: 'claude-3-5-sonnet-20240620',
  temperature: 0.7,
};

const model = factory.build(spec); // Returns LanguageModelV4 instance

The Adapter Layer: Normalization and Capability Injection

packages/runtime/src/model-adapter.ts contains buildModelFromSpec, the critical bridge between generic configuration and concrete SDK types. This adapter performs three essential functions:

  • Type erasure – Hides provider-specific SDK interfaces behind Maka's LanguageModel abstraction
  • Option normalization – Converts temperature, maxTokens, and other parameters to SDK-expected formats
  • Capability attachment – Adds Maka-specific features including telemetry hooks, usage tracking, and tool-call handling

The adapter ensures that regardless of which @ai-sdk provider you use, the resulting model behaves consistently within Maka's runtime.

Step Execution and Response Wrapping

When AiSdkBackend runs a workflow step, it:

  1. Invokes the adapter-produced model to generate responses
  2. Receives raw SDK output (text, tool calls, usage metadata)
  3. Wraps this output back into Maka's internal Message format for downstream processing

This bidirectional translation—spec to SDK model, SDK response to internal message—happens transparently at the backend boundary.

Compaction and Usage Tracking

The backend forwards usage data to AI‑SDK compaction utilities in packages/runtime/src/ai-sdk-compaction.ts. This enables:

  • Token-budget enforcement – Uniform budget tracking across all providers
  • Response caching – Provider-agnostic caching strategies
  • Cost attribution – Aggregated usage reporting for observability

Configuration Examples

JSON Workflow Configuration

{
  "model": {
    "backend": "ai-sdk",
    "provider": "openai",
    "modelId": "gpt-4o-mini",
    "temperature": 0.7,
    "maxTokens": 1024
  }
}

Programmatic Backend Usage

import { AiSdkBackend } from '@maka/runtime/ai-sdk-backend';
import type { ModelSpec } from '@maka/runtime/model-protocol';

// Runtime-provided context (logging, telemetry, etc.)
const backend = new AiSdkBackend(context);

const spec: ModelSpec = {
  backend: 'ai-sdk',
  provider: '@ai-sdk/openai',
  modelId: 'gpt-4o-mini',
  temperature: 0.7,
};

// Internal: createModel uses factory + adapter
const lm = backend.createModel(spec);

const result = await lm.complete('Explain how model adapters work.');
console.log(result.text);

Key Source Files

File Purpose
packages/runtime/src/ai-sdk-backend.ts AiSdkBackend class implementation; coordinates model creation, message conversion, usage tracking
packages/runtime/src/model-factory.ts Creates language-model instances from ModelSpec; selects correct @ai-sdk provider
packages/runtime/src/model-adapter.ts buildModelFromSpec function; normalizes spec, builds SDK model, adds Maka capabilities
packages/runtime/src/model-protocol.ts TypeScript interfaces for ModelSpec and related types
packages/runtime/src/ai-sdk-compaction.ts Token-budget compaction and usage reporting utilities

Summary

  • Backend abstraction – AiSdkBackend registered under key ai-sdk provides the entry point
  • Factory pattern – model-factory.ts resolves provider names to concrete @ai-sdk/* creators
  • Adapter normalization – model-adapter.ts type-erases SDK differences and injects Maka capabilities
  • Unified interface – All providers expose identical LanguageModel behavior to workflow steps
  • Cross-cutting concerns – Compaction and usage tracking work uniformly via ai-sdk-compaction.ts

Frequently Asked Questions

What is the relationship between AiSdkBackend and the model factory?

AiSdkBackend depends on the model factory as an internal implementation detail. When you call backend.createModel(spec), the backend delegates to createModelFactory().build(spec). This separation keeps the backend focused on orchestration while the factory handles provider-specific instantiation logic.

Can I use AiSdkBackend directly without the full Maka runtime?

Yes. Instantiate AiSdkBackend with a compatible context object containing logging and telemetry interfaces. However, most production use goes through the runtime's backend registry, which manages lifecycle and configuration loading automatically.

How does Maka handle provider-specific options like Anthropic's extended thinking?

The ModelSpec interface includes an extensible options field. The adapter in model-adapter.ts passes unrecognized options through to the underlying SDK after normalization. Provider-specific features work as long as the target @ai-sdk/* package supports them.

Why does model-adapter.ts type-erase the concrete SDK type?

Type erasure enables polymorphism. Workflow steps receive a LanguageModel interface without caring whether the underlying implementation is OpenAI, Anthropic, or another provider. This allows runtime provider switching and simplifies testing with mock implementations.

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 →