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

> Learn how Maka integrates model adapters via AiSdkBackend. Discover the three-layer architecture orchestrating model creation, provider selection, and specification normalization for AI-SDK language models.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: deep-dive
- Published: 2026-08-31

---

**Maka integrates model adapters through a three-layer backend architecture: `AiSdkBackend` orchestrates model creation, delegates to a [`model-factory.ts`](https://github.com/apache/maka/blob/main/model-factory.ts) for provider selection, and uses [`model-adapter.ts`](https://github.com/apache/maka/blob/main/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`](https://github.com/apache/maka/blob/main/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.

```typescript
// 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`](https://github.com/apache/maka/blob/main/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.

```typescript
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`](https://github.com/apache/maka/blob/main/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`](https://github.com/apache/maka/blob/main/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

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

```

### Programmatic Backend Usage

```typescript
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`](https://github.com/apache/maka/blob/main/packages/runtime/src/ai-sdk-backend.ts) | `AiSdkBackend` class implementation; coordinates model creation, message conversion, usage tracking |
| [`packages/runtime/src/model-factory.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-factory.ts) | Creates language-model instances from `ModelSpec`; selects correct `@ai-sdk` provider |
| [`packages/runtime/src/model-adapter.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-adapter.ts) | `buildModelFromSpec` function; normalizes spec, builds SDK model, adds Maka capabilities |
| [`packages/runtime/src/model-protocol.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-protocol.ts) | TypeScript interfaces for `ModelSpec` and related types |
| [`packages/runtime/src/ai-sdk-compaction.ts`](https://github.com/apache/maka/blob/main/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`](https://github.com/apache/maka/blob/main/model-factory.ts) resolves provider names to concrete `@ai-sdk/*` creators
- **Adapter normalization** – [`model-adapter.ts`](https://github.com/apache/maka/blob/main/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`](https://github.com/apache/maka/blob/main/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`](https://github.com/apache/maka/blob/main/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.