---
product: "AG Studio"
title: "Built-in Tools"
description: "A reference for the tools AG Studio ships, what each one does, and how to list them on an agent."
framework: angular
version: "3.0.0"
related:
    - title: "Tools Overview"
      url: "https://www.ag-grid.com/studio/angular/ai-tools/"
    - title: "Custom Tools"
      url: "https://www.ag-grid.com/studio/angular/ai-custom-tools/"
    - title: "External Tools"
      url: "https://www.ag-grid.com/studio/angular/ai-tools-external/"
llms: "https://www.ag-grid.com/studio/llms.txt"
---

# Built-in Tools

`api.getAiTools()` returns Studio's tools, bound to the Studio instance and ready to run. They read live dashboard state when they execute.

Inside a `createAiHarness` config builder the same tools arrive on `tools.studio`, so you do not need to call `api.getAiTools()` yourself:

```ts
// Your AgLlmAdapter - see Direct LLM Runner.
const adapter = myOpenAiAdapter({ endpoint: '/api/llm' });

ai: ({ api }) =>
    createAiHarness(api, ({ tools: { studio } }) => ({
        agents: [
            directLlmRunner({
                id: 'analyst',
                adapter,
                tools: () => [studio.viewSchema(), studio.executeQuery(), studio.addWidget()],
            }),
        ],
        primary: 'analyst',
    })),
```

Every member is a function. Call it where you list it, optionally passing [overrides](https://www.ag-grid.com/studio/angular/ai-custom-agents/#change-the-tool-set).

## Reading

| Tool | Method | What it does |
| --- | --- | --- |
| `view_schema` | `viewSchema()` | The data model: tables, fields, types, aggregations, relationships. Agents are told to call this before writing a query. |
| `view_report` | `viewReport()` | Every page in the report, with its id, how much is on it, and which page is being viewed. The only tool that publishes page ids. |
| `view_page` | `viewPage()` | One page: widget positions, layout config, page filters, and any layout or filter problems. |
| `view_widget` | `viewWidget()` | One widget's config, size, filters and health issues. |
| `execute_query` | `executeQuery()` | Runs a query against the data. Returns rows as a table for the model, capped so a large result cannot swamp the context window. |

## Changing the Page

| Tool | Method | What it does |
| --- | --- | --- |
| `add_widget` | `addWidget()` | Adds a widget of a given type at a grid position. Seeds the type only; configuration follows separately. |
| `position_widget` | `positionWidget()` | Moves or resizes a widget. Omitted fields keep their current values. |
| `remove_widget` | `removeWidget()` | Removes a widget from the page. |
| `configure_widget` | `configureWidget({ widgetType, widgetId })` | Configures one widget: data mapping, titles, formatting, type-specific options. |

`configureWidget` is bound per listing to a specific widget, because its schema is narrowed to that widget type's options. See [Binding a Widget Tool](https://www.ag-grid.com/studio/angular/ai-custom-agents/#binding-a-widget-tool).

### Binding a Page

No tool takes a page as an argument. A tool that acts on a page is bound to one when it is listed:

```js
studio.addWidget({ pageId: 'sales' });
```

Leave `pageId` out and the tool acts on whichever page is being viewed when the call runs, which is what a single-page dashboard wants. Set it and every call from that listing reads and writes that page, whichever page the user is on.

Bind it when an agent is built for a particular page: the ids to choose from come from `view_report`, so an orchestrator reads the report and passes the page to each agent it starts. A model cannot pick a page itself, which is deliberate. Nothing tells it which page the work belongs to, so the choice would be a guess, and a guess that named a real page would be carried out in silence on the wrong page.

Work on a page other than the one being viewed is saved to that page and appears when the user moves to it.

## Calculated Fields

| Tool | Method | What it does |
| --- | --- | --- |
| `create_expression` | `createExpression()` | Adds a calculated column to the schema, computed per row from an expression over its fields. |
| `update_expression` | `updateExpression()` | Changes a calculated column's name, expression or format. Omitted parts are left as they are. |
| `delete_expression` | `deleteExpression()` | Removes a calculated column from the schema. |

Only calculated columns added to the schema can be changed or removed. Fields that came with the data cannot. See [Expressions](https://www.ag-grid.com/studio/angular/expressions/) for what an expression can contain.

## Filters

| Tool | Method | What it does |
| --- | --- | --- |
| `add_page_filter` | `addPageFilter()` | Appends a page-level filter, applying to every widget on the page. |
| `remove_page_filter` | `removePageFilter()` | Removes a page filter by its index in the page's filter list. |
| `add_widget_filter` | `addWidgetFilter()` | Adds a filter to one widget. |
| `remove_widget_filter` | `removeWidgetFilter()` | Removes a widget filter by index. |

The remove tools take an index, so an agent is expected to call `view_page` or `view_widget` first to see the current order.

## Harness Tools

Some tools are owned by the harness rather than the API, because they need per-conversation state. They arrive in the config builder alongside `studio`:

```ts
// Your AgLlmAdapter - see Direct LLM Runner.
const adapter = myOpenAiAdapter({ endpoint: '/api/llm' });

createAiHarness(api, ({ tools }) => ({
    agents: [
        directLlmRunner({
            id: 'lead',
            adapter,
            tools: () => [tools.plan.view(), tools.plan.update(), tools.delegateTo(['data', 'page'])],
        }),
    ],
    primary: 'lead',
}));
```

| Tool | Builder | What it does |
| --- | --- | --- |
| `view_plan` | `tools.plan.view()` | The current plan, with per-item status. |
| `create_plan` | `tools.plan.create()` | Creates a plan: a layout tree, widget entries, and optional page filters. Replaces any existing plan. |
| `update_plan` | `tools.plan.update()` | Marks plan items done or failed as work progresses. |
| `clear_plan` | `tools.plan.clear()` | Removes the active plan. Placed widgets remain. |
| `rename_thread` | `tools.renameThread()` | Names the conversation the call runs in, which starts out unnamed. List it on the agent that fronts the conversation. |
| `delegate_to` | `tools.delegateTo([ids])` | Delegates to another agent, creating a child run. Its schema enumerates the named targets and their parameters. |

A plan is a durable artefact on the thread, so it survives across messages and is rendered in the panel. `rename_thread` calls are hidden from the message list, because the renamed conversation is the visible outcome. `complete_task` is added automatically to a delegated run and does not need listing.

## Next

- [Custom Tools](https://www.ag-grid.com/studio/angular/ai-custom-tools/) - your own actions
- [Tools Overview](https://www.ag-grid.com/studio/angular/ai-tools/) - the model underneath, and running a tool without an agent
