---
title: "LLM Adapter"
framework: angular
version: "2.1.2"
---

# LLM Adapter

AG Studio is provider-agnostic - it does not bundle a connection to any LLM. The **adapter** is the seam between Studio and your provider. You implement the `AgAiAssistant` interface, which translates between Studio's request format and your chosen LLM.

The example below ships a complete OpenAI adapter. Copy it as a starting point and adapt it to your provider.

#### Adapter Example

```ts
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';

import { AppComponent } from './app.component.ts';

const app = bootstrapApplication(AppComponent, {
    providers: [provideHttpClient()],
});
```

[Live example: Adapter Example](https://www.ag-grid.com/studio/examples/ai-adapter/ai-adapter-example/angular/)

## The AgAiAssistant Interface

The adapter is a plain object. Its one required method is `executeTurn`.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `executeTurn` | `Function` |  | Execute a single turn of conversation with the AI. A turn consists of sending input and receiving a streamed response. |
| `agents` | `(AgAiAgent \| AgAiBuiltInAgent)[]` |  | The set of agents the active runtime runs — each agent is instructions + tools + a delegation graph. When omitted, the built-in runtime uses AG's default agents. Supply your own (compose with `agStudioDefaultAgents` to keep AG's) to fully control the set. This is orchestration policy interpreted by the active runtime: the built-in runtime runs these as its agents; a custom runtime may own its own agents and ignore this field. |
| `primaryAgent` | `string` |  | Type of the agent the conversation starts from. Defaults to `'lead'`. Interpreted by the active runtime alongside agents. |

> **Note**
>
> The `agents` and `primaryAgent` fields configure the agents the built-in runtime uses - see [Custom Agents](https://www.ag-grid.com/studio/angular/ai-custom-agents/).

### executeTurn

`executeTurn` is called each time Studio needs an AI response. It receives an `AgAiRequest` and must return an `AgAiResponseHandler` synchronously. The handler exposes a live stream and a completion promise.

## The Request

Each call to `executeTurn` receives everything the model needs for one turn.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `input` | `AgAiConversationItem[]` |  | Conversation history to send to the AI, providing context. |
| `instructions` | `string` |  | System instructions for this specific turn, overriding defaults. |
| `tools` | `AgToolSchema[]` |  | Tools available for the AI to use during this turn. |
| `toolChoice` | `"none" \| "required" \| "auto" \| AgAiToolChoice` |  | Strategy for how the AI should choose tools. 'auto': AI decides whether to use tools 'none': AI must not use tools 'required': AI must use at least one tool AgAiToolChoice: AI must use the specified tool |
| `responseFormat` | `AgAiJsonFormat \| AgAiTextFormat` |  | Output format configuration controlling response structure. |

## The Response

`executeTurn` returns an `AgAiResponseHandler` - a `stream` of incremental events and a `complete` promise that resolves with the final response.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `stream` | `{ [asyncIterator]: any }` |  | Async iterable of stream events for real-time updates. Events are yielded as they arrive from the AI provider. |
| `complete` | `Promise<AgAiResponse>` |  | Promise that resolves when the response is fully complete. Contains the final, consolidated response data. |

## Stream Events

The stream yields `AgAiStreamEvent` values. Each has a `type` and an `event` discriminator:

| Type | Event | Description |
| --- | --- | --- |
| `status` | `created` | The provider has created the response object. |
| `status` | `in_progress` | The model is actively generating. |
| `status` | `completed` | Generation finished. Includes the final `AgAiResponse`. |
| `status` | `failed` | Generation failed. |
| `error` | `api`, `network`, `timeout`, etc. | An error occurred. Includes `code` and `message`. |
| `item` | `added` | A new output item (message, tool call, reasoning) started. |
| `item` | `done` | An output item finished. |
| `part` | `added` | A content part within an item started. |
| `part` | `done` | A content part finished. |
| `delta` | `update` | Incremental content to append. |
| `delta` | `done` | Final content for a part. |

## Tool Calls

The adapter does **not** execute tools. It only:

1. Passes the `AgToolSchema[]` in `request.tools` to the LLM.
2. Relays the tool-call output items from the LLM back through the stream.

The runtime intercepts those tool calls, executes them, and feeds the results back as `function_call_output` items on the next turn. Your adapter never needs to know what `view_schema` or `configure_widget` do.

## Keeping Keys Off the Client

`executeTurn` runs in the browser, so calling a provider directly exposes your API key. For production, point `executeTurn` at your own backend endpoint instead: forward the `AgAiRequest`, call the provider server-side with your secret key, and stream the response back. The adapter contract is unchanged - only the URL it calls differs.

## Interface Reference

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  | Unique identifier for this response. |
| `createdAt` | `number` |  | Timestamp when the response was created (milliseconds since epoch). |
| `error` | `AgAiResponseError` |  | Error details if the response failed. |
| `incompleteDetails` | `AgAiResponseIncompleteDetails` |  | Details about why the response was incomplete. Present when the AI couldn't fully complete its response. |
| `output` | `AgAiOutputItem[]` |  | Output items produced by the AI (messages, tool calls, reasoning). |
| `status` | `"completed" \| "failed" \| "in_progress" \| "cancelled" \| "queued" \| "incomplete"` |  | Current status of the response. |

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` |  | Tool name. |
| `description` | `string` |  | Human-readable description for the LLM. |
| `parameters` | [`AgJSONSchema`](https://www.ag-grid.com/studio/angular/custom-widgets#ai-integration) |  | JSON Schema describing the tool's parameters. |

## Next Steps

- [Module Setup](https://www.ag-grid.com/studio/angular/ai-configuration/) - Register the module and show the panel.
- [Default Agents](https://www.ag-grid.com/studio/angular/ai-ax/) - The agents and tools the runtime drives.
