# What Is the ModelAdapter in Maka? Architecture and Responsibilities

> Discover the ModelAdapter in Maka. Learn how it bridges Maka's runtime with AI-SDK providers, normalizing interfaces, translating data, and managing configurations for efficient AI integration.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: architecture
- Published: 2026-09-05

---

**The ModelAdapter serves as the central bridge between Maka's runtime and underlying AI-SDK providers, normalizing streaming interfaces, translating raw provider chunks into Maka-native events, and managing provider-specific configurations including error classification, tool name remapping, and token budgets.**

The **ModelAdapter** is a foundational abstraction in the Apache Maka project that unifies interactions with large language model providers such as OpenAI and Anthropic. Located in [`packages/runtime/src/model-adapter.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-adapter.ts), this class encapsulates provider-specific complexity while exposing a consistent streaming interface for text generation. Understanding the ModelAdapter's architecture is essential for developers extending Maka's runtime capabilities or debugging provider integrations.

## Bridging Maka and AI-SDK Providers

### Resolving the Provider Runtime

The adapter creates a `ResolvedModelRuntime` based on the connection and model ID through the `resolveModel` method. It evaluates `runtimeEventReplaySupport` to determine if the current configuration supports event replay functionality. This resolution step ensures that Maka's backend receives a standardized runtime object regardless of whether the underlying provider is OpenAI, Anthropic, or another supported SDK.

### Building Provider-Specific Language Models

Using a `ModelFactory`, the adapter constructs provider-specific language models while injecting runtime-specific state. For example, when interfacing with OpenAI, it configures the chat reasoning transport or the OpenAI-Responses transport as needed. This factory pattern allows Maka to support provider-specific features—such as OpenAI's reasoning models—without leaking implementation details into the core runtime.

## Streaming Normalization and Event Translation

### Normalizing Stream Contracts

The `startStream` method wraps the provider's native `streamText` call, tracking stream activity through callbacks and enforcing a consistent streaming contract across all providers. This normalization ensures that consumer code receives uniform events whether streaming from GPT-4, Claude, or other models.

### Translating Raw Chunks to Maka Events

Raw AI-SDK chunks are converted into Maka-owned `ModelStreamEvent` types via the `translateChunk` method. This translation layer ensures that only Maka-native types are exposed to the backend, isolating the system from provider-specific payload structures. The protocol definitions for these events are maintained in [`packages/runtime/src/model-protocol.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-protocol.ts).

## Error Handling and Provider Normalization

### Error Classification and Failure Normalization

When providers return errors, the adapter invokes `normalizeProviderFailure` and `classifyError` to transform provider-specific exceptions into standardized `ModelFailure` objects. This classification system, implemented in [`packages/runtime/src/provider-error-classification.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/provider-error-classification.ts), enables consistent retry logic and error reporting across heterogeneous provider implementations.

### Mapping Finish Reasons and Tool Names

Provider-specific finish reasons are mapped to Maka's internal stop-reason enum through `mapFinishReason`. Additionally, when using the OpenAI-Responses adapter, the adapter handles tool name remapping via `remapModelMessageToolNames` and `remapProviderToolNamesInText` to ensure that Maka's persisted tool names remain consistent regardless of provider-side naming conventions.

## Token Management and Continuation Control

### Token Budget Calculation

The adapter computes the maximum output tokens allowed for a request through `selectedModelMaxOutputTokens`, enforcing budget constraints before dispatching requests to the provider. This prevents runtime failures due to context window exceeded errors.

### Continuation Lanes and Replay Support

For providers like OpenAI-Responses that support lane-based continuation, the adapter manages semantic request/response pairs and exposes replay-capability flags through `runtimeEventReplaySupport`. This functionality enables sophisticated conversation patterns where previous turns can be replayed or continued with modified parameters.

### Lifecycle Management

The adapter exposes explicit lifecycle methods to manage continuation state: `endContinuation`, `recordContinuationResponse`, `clearContinuation`, and `dispose`. These methods ensure proper cleanup of resources and state when streaming operations complete or when the adapter is destroyed.

## Implementation Reference

The ModelAdapter implementation spans several key files in the `apache/maka` repository:

- [`packages/runtime/src/model-adapter.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-adapter.ts) – Core class containing `startStream`, `translateChunk`, and lifecycle management.
- [`packages/runtime/src/model-protocol.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-protocol.ts) – TypeScript contracts defining `ModelStreamEvent`, `ModelFailure`, and finish reason enums.
- [`packages/runtime/src/model-runtime.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-runtime.ts) – Runtime resolution logic including `resolveModel` and `runtimeEventReplaySupport`.
- [`packages/runtime/src/provider-error-classification.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/provider-error-classification.ts) – Error normalization utilities used by the adapter's failure handling pipeline.

## Usage Examples

*Creating and using a Model Adapter*

```ts
import { ModelAdapter } from './model-adapter.js';
import { resolveModelRuntime } from './model-runtime.js';

// Input needed to construct the adapter
const adapterInput = {
  sessionId: 'sess-01',
  connection: myRuntimeConnection,
  apiKey: process.env.OPENAI_API_KEY,
  modelId: 'gpt-4o-mini',
  modelFactory: myModelFactory,
  newId: () => crypto.randomUUID(),
  now: () => Date.now(),
};

// Build the adapter
const adapter = new ModelAdapter(adapterInput);

// Prepare stream input
const streamInput = {
  model: await adapter.resolveModel(),
  messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
  tools: myToolSet,
  activeTools: [],
  onStreamActivity: () => console.log('stream activity'),
  abortSignal: new AbortController().signal,
  repairToolCall: async ({ toolCall, error }) => null,
};

// Start streaming
const result = await adapter.startStream(streamInput);

// Iterate over events
for await (const ev of result.events) {
  console.log('event:', ev);
}

// Get the final outcome
const outcome = await result.outcome;
console.log('outcome:', outcome);

```

*Handling a streamed error*

```ts
adapter.startStream(streamInput).then(({ events, outcome }) => {
  (async () => {
    for await (const ev of events) {
      if (ev.kind === 'error') {
        console.error('Stream error:', ev.failure);
      }
    }
    const final = await outcome;
    if (final.kind !== 'completed') {
      console.warn('Step failed:', final);
    }
  })();
});

```

## Summary

- The **ModelAdapter** acts as the primary abstraction layer between Maka's runtime and AI-SDK providers, handling OpenAI, Anthropic, and other implementations.
- It **normalizes streaming** through `startStream` and `translateChunk`, converting provider-specific outputs into standardized `ModelStreamEvent` types.
- **Error handling** is unified via `normalizeProviderFailure` and `classifyError`, producing consistent `ModelFailure` objects for all providers.
- The adapter manages **provider-specific metadata** including finish reason mapping, tool name remapping, and token budget calculations via `selectedModelMaxOutputTokens`.
- **Continuation and replay** capabilities are supported through lane-based state management and `runtimeEventReplaySupport` flags.
- All implementation resides in [`packages/runtime/src/model-adapter.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-adapter.ts) with supporting protocols in [`packages/runtime/src/model-protocol.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/model-protocol.ts).

## Frequently Asked Questions

### What is the primary role of the ModelAdapter in Maka?

The **ModelAdapter** serves as the central integration point that bridges Maka's runtime with underlying AI-SDK providers like OpenAI and Anthropic. It resolves provider runtimes, builds language models, normalizes streaming interfaces, and translates raw provider outputs into Maka-native events, ensuring a uniform interface regardless of the specific AI provider being used.

### How does ModelAdapter handle streaming errors?

The adapter catches errors from the provider's `streamText` implementation and processes them through `normalizeProviderFailure` and `classifyError` to create standardized `ModelFailure` objects. These failures are then emitted as `ModelStreamEvent` objects with kind `'error'`, allowing consumer code to handle retries or logging consistently across different providers.

### What is the difference between ModelAdapter and ModelFactory?

The **ModelFactory** creates provider-specific language model instances (such as OpenAI chat or reasoning transports), while the **ModelAdapter** orchestrates these instances, manages their lifecycle, and normalizes their outputs. The factory handles construction; the adapter handles integration, streaming, error translation, and state management.

### How does ModelAdapter support conversation replay functionality?

Through the `runtimeEventReplaySupport` flag and continuation lane methods (`endContinuation`, `recordContinuationResponse`, `clearContinuation`), the adapter records semantic request/response pairs for compatible providers like OpenAI-Responses. This enables the runtime to replay previous conversation turns or continue lanes with modified parameters while maintaining accurate state tracking.