---
title: "LLM Adapter"
framework: react
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

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgStudio, AgStudioRef } from "ag-studio-react";
import { openaiAdapter } from "./shared/openaiAdapter.tsx";
import {
  AgAiAssistant,
  AgDataEngine,
  AgDataSourcesDefinition,
  AgReportState,
  AgStudioAiModule,
  AgStudioApi,
  AgStudioMode,
  AgStudioModuleRegistry,
  AgStudioProperties,
} from "ag-studio";
import { getMainDemoData } from "./data.tsx";

AgStudioModuleRegistry.registerModules([AgStudioAiModule]);

export const AI_API_URL = "https://ai-api.ag-grid.com/api/openai/v1";

export const AI_API_TOKEN = "";

const StudioExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const studioStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [data, setData] = useState<AgDataSource>(
    getMainDemoData("https://www.ag-grid.com/studio/example-assets"),
  );
  const initialState = useMemo<AgReportState>(() => {
    return {
      pages: [{ id: "main", widgets: {}, widgetLayout: {} }],
      selectedPageId: "main",
      panels: {
        filters: { collapsed: true },
        edit: { collapsed: true },
        data: { collapsed: true },
      },
    };
  }, []);
  const ai = useMemo<AgAiAssistant>(() => {
    return openaiAdapter({
      endpoint: AI_API_URL,
      key: AI_API_TOKEN,
    });
  }, []);

  return (
    <div style={containerStyle}>
      <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
        <AgStudio
          style={studioStyle}
          className="my-studio-container"
          data={data}
          mode={"edit"}
          initialState={initialState}
          ai={ai}
        />
      </div>
    </div>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <StudioExample />
  </StrictMode>,
);
```

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

## 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/react/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/react/custom-widgets#ai-integration) |  | JSON Schema describing the tool's parameters. |

## Next Steps

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