---
product: "AG Studio"
title: "Agent Framework Overview"
description: "Let users explore data and build or modify dashboards in natural language by connecting AG Studio to your own LLM."
framework: react
version: "3.0.0"
related:
    - title: "Agent Quick Start"
      url: "https://www.ag-grid.com/studio/archive/3.0.0/react/ai-quickstart/"
    - title: "WebMCP"
      url: "https://www.ag-grid.com/studio/archive/3.0.0/react/ai-webmcp/"
llms: "https://www.ag-grid.com/studio/archive/3.0.0/llms.txt"
---

# Agent Framework Overview

The Studio Agent Framework lets users explore data and build or modify dashboards using natural language and an LLM supplied by your application.

AG Studio's Agent Framework is designed to integrate directly with your LLM - AG Studio does not provide any models, servers, or backends. This architecture means AG Studio is:

- **Agnostic:** You can integrate with any provider.
- **Private by design:** AG Studio sends no data to an AG Grid service. You choose the endpoint that receives it.
- **Economical:** There are no additional per-query costs, outside of what your provider charges.
- **Opt-in:** It's disabled by default until you explicitly opt-in via module registration.

[Video](https://www.ag-grid.com/studio/archive/3.0.0/_astro/studio-agent-framework.B-adaVu2.mp4)

## Example

The example below integrates OpenAI's Responses API into an instance of AG Studio that contains a weather report for 39 world cities, from [NOAA GHCN-Daily](https://www.ncei.noaa.gov/products/land-based-station/global-historical-climatology-network-daily). Open the chat panel and choose one of the [suggested prompts](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-chat-features/#suggesting-prompts), or type a request of your own. The picker beside the send button offers a [choice of model](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-chat-features/#offering-a-choice-of-model).

#### Agent Framework

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgStudio, AgStudioProvider, AgStudioRef } from "ag-studio-react";
import {
  AgAiHarnessSetup,
  AgAiModel,
  AgAiPromptStarter,
  AgDataEngine,
  AgDataSourcesDefinition,
  AgReportState,
  AgStudioAiModule,
  AgStudioMode,
  AgStudioProperties,
  createAiHarness,
  enableStudioDevValidations,
} from "ag-studio";
import { getGhcnCitiesData } from "./shared/ghcnCities/data.tsx";
import { ghcnCitiesReportState } from "./shared/ghcnCities/state.tsx";
import { openaiAdapter } from "./shared/openaiAdapter.tsx";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableStudioDevValidations();
}

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

export const AI_API_TOKEN = "";

const adapter = openaiAdapter({
  endpoint: AI_API_URL,
  key: AI_API_TOKEN,
});

/**
 * The suggestions offered before anyone has said anything, so a reader can put the assistant to
 * work without having to think of a request first. Each button is worded far shorter than the
 * message it sends.
 */
const PROMPT_STARTERS: AgAiPromptStarter[] = [
  {
    label: "Chart the extremes",
    prompt: "Add bar charts showing the hottest and the wettest cities.",
  },
  {
    label: "Table every city",
    prompt:
      "Add a table listing each city with its country, climate band, average high and average low.",
  },
  {
    label: "Explain the data",
    prompt:
      "What tables and fields does this dashboard have available, and what does each one measure?",
  },
];

/**
 * The models offered beside the send button. Each `id` reaches the adapter as declared here and is
 * passed straight on to the provider, so these are real model ids. The first is the one a new
 * conversation starts on.
 */
const MODELS: AgAiModel[] = [
  { id: "gpt-5.6-terra", label: "GPT-5.6 Terra" },
  { id: "gpt-5.6-sol", label: "GPT-5.6 Sol" },
  { id: "gpt-5.6-luna", label: "GPT-5.6 Luna" },
];

const StudioExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const studioStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [data, setData] = useState<AgDataSource>(
    getGhcnCitiesData("https://www.ag-grid.com/studio/archive/3.0.0/example-assets"),
  );
  const initialState = useMemo<AgReportState>(() => {
    return {
      ...ghcnCitiesReportState,
      // Collapse the filters panel and open on the blank page, so the assistant has work to do.
      panels: {
        ...ghcnCitiesReportState.panels,
        filters: {
          collapsed: true,
        },
      },
      selectedPageId: "blank",
    };
  }, []);
  const ai = useMemo<AgAiHarnessSetup>(() => {
    return ({ api }) =>
      createAiHarness(api, {
        adapter,
        promptStarters: PROMPT_STARTERS,
        models: MODELS,
      });
  }, []);

  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>
    <AgStudioProvider modules={[AgStudioAiModule]}>
      <StudioExample />
    </AgStudioProvider>
  </StrictMode>,
);
```

[Live example: Agent Framework](https://www.ag-grid.com/studio/archive/3.0.0/examples/ai/ai-overview-example/reactFunctionalTs/)

## Key Concepts

The Agent Framework provides the pieces your LLM needs to interact with AG Studio: a [Harness](https://www.ag-grid.com/studio/archive/3.0.0/react/ai/#harness) that holds the conversation, the [Agents](https://www.ag-grid.com/studio/archive/3.0.0/react/ai/#agents) that decide what to do, and the [Tools](https://www.ag-grid.com/studio/archive/3.0.0/react/ai/#tools) they act with.

Each of these can be used as-is, customised, or replaced entirely.

### Harness

The [Harness](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-harness/) manages the conversation with the user, orchestrates the agents within AG Studio, and exposes what your UI needs to render. Studio ships a harness, built with `createAiHarness`. You can also [write your own](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-custom-harness/).

Within Studio's harness, each agent is paired with a **runner**, which decides how much of each turn Studio runs for you:

- [Direct LLM Runner](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-direct-llm-runner/) - Studio runs the turn loop against a model you reach through an [adapter](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-direct-llm-runner/#the-adapter) you supply.
- [Client Tool Runner](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-client-tool-runner/) - you answer each turn, and Studio executes the tool calls you leave unresolved.
- [Custom Runner](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-custom-runner/) - your loop answers for itself, and Studio drives none of it.

AG Studio does not provide any adapters. Our examples contain an adapter for OpenAI's Responses API which can be repurposed for other providers.

### Agents

[Agents](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-agents/) decide what actions to take in response to a user's input. By default, AG Studio provides [five agents](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-builtin-agents/): Planning, Data, Page, Widget agents, and a Lead agent that co-ordinates them. Each agent carries a set of instructions specific to its task, which can be [customised](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-custom-agents/#change-instructions), or [replaced](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-custom-agents/#declare-your-own-team).

### Tools

[Tools](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-tools/) allow agents to interact with AG Studio. They expose a JSON schema to the LLM that advertises their capabilities, allowing the LLM to request actions on the dashboard. The tool call is then executed and its result returned to the model. AG Studio provides a number of [built-in tools](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-tools-builtin/) that allow agents to read and modify the page, apply filters, and manage agents. You can also define your own [custom tools](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-custom-tools/).

## What Leaves the Browser

Only what your adapter or your endpoint sends. AG Studio composes a request and hands it over; it makes no network calls of its own.

A request typically contains the conversation so far, the resolved instructions, and the tool schemas. A tool schema can include live values, such as an enum of field ids or of widget ids, so your data model's shape can appear in a prompt even when its rows do not. Row values reach the model only when a tool result carries them. `execute_query`, for example, returns rows as a table for the model to read.

> **Note**
>
> If a field or table name is itself sensitive, remember it may travel in a tool schema. Limit what the agent can see by listing fewer tools, or by writing a tool of your own over a narrower view of the data.

## Next Steps

**[Harness](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-harness/)**

Learn about the harness, and the runners it drives agents with.

**[Agents](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-agents/)**

Explore the built-in Agents, and how to customise or replace them.

**[Tools](https://www.ag-grid.com/studio/archive/3.0.0/react/ai-tools/)**

Understand how tools are created, defined, and customised.
