---
title: "Default Agents"
framework: react
version: "2.1.2"
---

# Default Agents

Out of the box, the built-in runtime drives a team of specialised **agents** rather than one model doing everything. Each agent has its own instructions, its own set of tools, and permission to delegate to others. This page is the reference for the agents you get and what each can do.

## See It in Action

The example below has three pre-loaded conversation threads. Open the AI panel to follow how the Lead delegates to the Data, Page, and Widget agents.

#### Default Agents

```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, mainDemoCalendar } from "./data.tsx";
import { exampleAiState } from "./exampleAiState.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"),
    calendars: [mainDemoCalendar],
  });
  const initialState = useMemo<AgReportState>(() => {
    return {
      pages: [
        {
          id: "main",
          widgets: {
            "page-title-executive": {
              type: "text",
              format: {
                style: {
                  text: "Executive Overview",
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            // KPI tiles - row 1
            "kpi-net-sales": {
              type: "value",
              dataMapping: { value: [{ id: "net_sales" }] },
              format: {
                caption: {
                  enabled: true,
                  text: "Net Sales",
                  typography: {
                    fontFamily: '"Source Sans 3", sans-serif',
                    fontSize: 20,
                    fontWeight: "normal",
                    fontStyle: "normal",
                  },
                },
                value: {
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            "kpi-order-count": {
              type: "value",
              dataMapping: { value: [{ id: "order_count" }] },
              format: {
                caption: {
                  enabled: true,
                  text: "Order Count",
                  typography: {
                    fontFamily: '"Source Sans 3", sans-serif',
                    fontSize: 20,
                    fontWeight: "normal",
                    fontStyle: "normal",
                  },
                },
                value: {
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            "kpi-aov": {
              type: "value",
              dataMapping: { value: [{ id: "average_order_value" }] },
              format: {
                caption: {
                  enabled: true,
                  text: "AOV",
                  typography: {
                    fontFamily: '"Source Sans 3", sans-serif',
                    fontSize: 20,
                    fontWeight: "normal",
                    fontStyle: "normal",
                  },
                },
                value: {
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            // KPI tiles - row 2
            "kpi-gm-percent": {
              type: "value",
              dataMapping: { value: [{ id: "gross_margin_percentage" }] },
              format: {
                caption: {
                  enabled: true,
                  text: "Gross Margin %",
                  typography: {
                    fontFamily: '"Source Sans 3", sans-serif',
                    fontSize: 20,
                    fontWeight: "normal",
                    fontStyle: "normal",
                  },
                },
                value: {
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            "kpi-on-time-rate": {
              type: "value",
              dataMapping: { value: [{ id: "on_time_rate" }] },
              format: {
                caption: {
                  enabled: true,
                  text: "On-time Rate",
                  typography: {
                    fontFamily: '"Source Sans 3", sans-serif',
                    fontSize: 20,
                    fontWeight: "normal",
                    fontStyle: "normal",
                  },
                },
                value: {
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            "kpi-return-rate": {
              type: "value",
              dataMapping: { value: [{ id: "return_rate" }] },
              format: {
                caption: {
                  enabled: true,
                  text: "Return Rate",
                  typography: {
                    fontFamily: '"Source Sans 3", sans-serif',
                    fontSize: 20,
                    fontWeight: "normal",
                    fontStyle: "normal",
                  },
                },
                value: {
                  typography: {
                    fontWeight: "normal",
                  },
                },
              },
            },
            // Line chart: Net Sales by Month
            "net-sales-by-month": {
              type: "line-chart",
              dataMapping: {
                categoryKey: [{ id: "calendar::month" }],
                valueKey: [{ id: "line_net", aggregation: "sum" }],
              },
              format: { title: { enabled: true, text: "Net Sales by Month" } },
            },
            // Stacked bar charts
            "net-sales-by-region": {
              type: "bar-chart-stacked",
              dataMapping: {
                categoryKey: [{ id: "customers.region" }],
                valueKey: [
                  { id: "line_cogs", aggregation: "sum" },
                  { id: "line_margin", aggregation: "sum" },
                ],
                tooltipKey: [{ id: "line_net", aggregation: "sum" }],
              },
              sort: [
                {
                  field: { id: "line_cogs", aggregation: "sum" },
                  direction: "desc",
                },
              ],
              format: {
                title: { enabled: true, text: "Net Sales by Region" },
                style: {
                  theme: {
                    common: { legend: { enabled: true, position: "right" } },
                  },
                },
              },
            },
            "net-sales-by-subcategory": {
              type: "bar-chart-stacked",
              dataMapping: {
                categoryKey: [{ id: "products.subcategory" }],
                valueKey: [
                  { id: "line_cogs", aggregation: "sum" },
                  { id: "line_margin", aggregation: "sum" },
                ],
                tooltipKey: [{ id: "line_net", aggregation: "sum" }],
              },
              sort: [
                {
                  field: { id: "line_cogs", aggregation: "sum" },
                  direction: "desc",
                },
              ],
              format: {
                title: { enabled: true, text: "Net Sales by Subcategory" },
                style: {
                  theme: {
                    common: { legend: { enabled: true, position: "right" } },
                  },
                },
              },
            },
            // Table: Top Customers
            "top-customers": {
              type: "grid",
              dataMapping: {
                cols: [
                  { id: "customers.customer_name" },
                  { id: "orders.order_id" },
                  { id: "line_net", aggregation: "sum" },
                  { id: "average_order_value" },
                  { id: "gross_margin_percentage" },
                ],
              },
              sort: [
                {
                  field: { id: "line_net", aggregation: "sum" },
                  direction: "desc",
                },
              ],
              format: { title: { enabled: true, text: "Top Customers" } },
            },
          },
          widgetLayout: {
            "page-title-executive": {
              xTrack: 0,
              yTrack: 0,
              xSpan: 24,
              ySpan: 4,
            },
            "kpi-net-sales": { xTrack: 0, yTrack: 4, xSpan: 8, ySpan: 6 },
            "kpi-order-count": { xTrack: 8, yTrack: 4, xSpan: 8, ySpan: 6 },
            "kpi-aov": { xTrack: 16, yTrack: 4, xSpan: 8, ySpan: 6 },
            "kpi-gm-percent": { xTrack: 0, yTrack: 10, xSpan: 8, ySpan: 6 },
            "kpi-on-time-rate": { xTrack: 8, yTrack: 10, xSpan: 8, ySpan: 6 },
            "kpi-return-rate": { xTrack: 16, yTrack: 10, xSpan: 8, ySpan: 6 },
            "net-sales-by-month": {
              xTrack: 0,
              yTrack: 16,
              xSpan: 24,
              ySpan: 16,
            },
            "net-sales-by-region": {
              xTrack: 0,
              yTrack: 32,
              xSpan: 12,
              ySpan: 16,
            },
            "net-sales-by-subcategory": {
              xTrack: 12,
              yTrack: 32,
              xSpan: 12,
              ySpan: 16,
            },
            "top-customers": { xTrack: 0, yTrack: 48, xSpan: 24, ySpan: 20 },
          },
          filter: {
            page: [
              {
                field: {
                  id: "orders.order_datetime",
                },
                view: {
                  expanded: false,
                },
                model: {
                  operator: "greaterThan",
                  value: "2024-12-01",
                },
              },
            ],
          },
        },
      ],
      panels: {
        filters: { collapsed: true },
        edit: { collapsed: true },
        data: { collapsed: true },
      },
      selectedPageId: "main",
      ai: exampleAiState,
    };
  }, []);
  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}
          initialState={initialState}
          mode={"edit"}
          ai={ai}
        />
      </div>
    </div>
  );
};

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

[Live example: Default Agents](https://www.ag-grid.com/studio/examples/ai-ax/ai-ax-example/reactFunctionalTs/)

## Why a Team

A single prompt cannot reliably build a whole dashboard - the work needs inspecting the data, planning a layout, placing widgets, and configuring each one. The runtime splits this across focused agents. The **Lead** coordinates: it reads the request, decides the approach, and delegates to specialists that do the actual work.

## The Agents

AG Studio ships five built-in agents. Each has a role, a tool set, and a set of agents it may delegate to.

| Agent | Role | Tools | Delegates To |
| --- | --- | --- | --- |
| **Lead** | Coordinator. Receives user messages, inspects context, delegates to specialists. | `view_schema`, `view_page`, `view_plan`, `update_plan`, `clear_plan`, `rename_thread` | `planning`, `data`, `page`, `widget` |
| **Planning** | Creates structured plans for dashboard construction. | `view_schema`, `view_page`, `view_plan`, `create_plan` | - |
| **Data** | Explores and queries data sources. Answers data questions. | `execute_query`, `view_schema` | - |
| **Page** | Places widgets on the grid, manages positions, and handles page-level filters. | `view_schema`, `view_page`, `view_plan`, `add_page_filter`, `remove_page_filter`, `add_widget`, `position_widget`, `remove_widget` | - |
| **Widget** | Configures individual widgets - chart type, data mappings, titles, formatting. | `view_schema`, `view_plan`, `view_widget`, `configure_widget`, `add_widget_filter`, `remove_widget_filter` | - |

The **Widget** agent is parameterised - the Lead specifies the widget type when delegating (e.g. `{ type: 'bar-chart-grouped' }`), which tailors the configuration schema.

To change any of this - an agent's instructions, tools, or the team itself - see [Custom Agents](https://www.ag-grid.com/studio/react/ai-custom-agents/).

### Tool Reference

| Tool | Description |
| --- | --- |
| `view_schema` | Retrieves the current data schema - all data sources, fields, types, and relationships. |
| `execute_query` | Runs a query against the loaded data sources. Supports aggregation-based and SQL-like query modes. |
| `view_page` | Retrieves the current page state including widgets, positions, filters, grid dimensions, and layout issues. |
| `view_plan` | Retrieves the current plan, if one exists. |
| `view_widget` | Retrieves a widget's current config, size, filters, and health check issues. |
| `add_widget` | Adds an empty widget shell to the page with a type and position. |
| `position_widget` | Moves and/or resizes a widget on the grid. |
| `remove_widget` | Removes a widget from the page. |
| `configure_widget` | Configures a widget's data mappings, title, subtitle, formatting, and type-specific options. |
| `add_widget_filter` | Adds a filter to a specific widget. |
| `remove_widget_filter` | Removes a filter from a specific widget. |
| `add_page_filter` | Adds a page-level filter that applies to all widgets on the page. |
| `remove_page_filter` | Removes a page-level filter. |
| `create_plan` | Creates a structured plan for a complex task with layout tree, widget entries, and page filters. |
| `update_plan` | Updates plan status - tracks widget placement/configuration and filter application across execution phases. |
| `clear_plan` | Clears the active plan. |
| `rename_thread` | Sets a short thread name for the conversation. |
| `delegate_to` | Delegates a task to a specialist agent, creating a child conversation. |
| `complete_task` | Signals that the current delegated task is complete and returns control to the delegating agent. |

## Walkthrough: "Build Me a Dashboard"

The full delegation sequence when a user asks for a dashboard:

### 1. Lead Receives the Message

The Lead gets the user's message plus the current schema and layout context. It calls `view_schema` to understand the data, then decides the task needs a plan.

### 2. Lead Delegates to Planning

The Lead uses `delegate_to` to hand off to the Planning agent, passing a description of what the user wants and the schema context.

### 3. Planning Creates a Plan

The Planning agent calls `create_plan` to produce a structured plan - items like "Add KPI card for total revenue" or "Add bar chart for sales by category" - then calls `complete_task` to return control to the Lead.

### 4. Lead Delegates to Page

With the plan in hand, the Lead delegates to the Page agent. It calls `add_widget` to create widget shells and `position_widget` to arrange them, and handles page-level filters via `add_page_filter`. It returns the widget IDs.

### 5. Lead Delegates to Widget Agents

The Lead delegates to Widget agents, potentially in parallel. Each receives one widget ID and its plan item, then calls `configure_widget` to set the chart type, data mappings, titles, and formatting - and `add_widget_filter` for any widget-level filters.

### 6. Lead Confirms Completion

Once all delegated tasks return, the Lead marks the plan items complete and sends a summary back to the user.

## Session Model

Conversations are organised into a hierarchy.

- **Thread** - a persistent conversation container. A session can hold several threads, each with its own history.
- **Conversation** - within a thread, each agent gets its own conversation. The main one belongs to the Lead; delegating creates a child conversation for the specialist.
- **Exchange** - one user request through to full completion. It begins with a user message (or a delegation) and ends when the AI finishes. An exchange may span several turns.
- **Turn** - a single iteration of the loop. Turn 1 holds the user input and the AI's first response. If the AI calls tools, their results form the input for Turn 2, and so on until a final text response or `complete_task`.
- **Delegation** - one agent handing a task to another. The Lead delegates to specialists via `delegate_to`; the specialist works independently and returns via `complete_task`.

## Next Steps

- [Custom Agents](https://www.ag-grid.com/studio/react/ai-custom-agents/) - Change an agent's instructions or tools, or add your own.
- [Context](https://www.ag-grid.com/studio/react/ai-context/) - The data and dashboard state agents read when they run.
