The Toolkit exposes Studio's built-in actions as standalone, framework-agnostic units, so you can drive the AI loop in your own runtime instead of the built-in one. A custom runtime needs no agents - you decide what the model can do by choosing which commands to expose as tools.
Commands and Tools Copy Link
The two are easy to conflate, so it is worth being precise:
- A command is the action itself. It validates its input, mutates state or runs a query, and returns a success or failure result. It has no name or description of its own.
- A tool is a command wrapped with a name, description, and status text - the form an LLM can discover and call.
Studio's Built-in Tools are commands wrapped this way for the built-in runtime. The Toolkit hands you the command; you supply the wrapper your runtime expects.
Retrieving a Command Copy Link
Pass an AgBuiltInAiCommandRef to api.defineAiCommand:
const command = api.defineAiCommand({ type: 'AgExecuteQueryCommand' });
const schema = command.toJSONSchema(); // hand to your runtime as a tool definition
const result = await command.apply(args); // { success: true, value } | { success: false, error }Commands that carry configuration take a params field. AgConfigureWidgetCommand narrows its schema by widget type:
const configureBar = api.defineAiCommand({
type: 'AgConfigureWidgetCommand',
params: { widgetType: 'bar-chart-grouped' },
}); Wrapping a Command as a Tool Copy Link
You own the name, description, and status text - and any extra work around execution, such as validating input or trimming the result before it returns to the model.
import { tool } from 'your-ai-runtime';
const executeQueryCommand = api.defineAiCommand({ type: 'AgExecuteQueryCommand' });
const executeQueryTool = tool({
name: 'execute_query',
description: 'Query the full dataset available',
schema: executeQueryCommand.toJSONSchema(),
execute: async (params) => {
const result = await executeQueryCommand.apply(params);
if (!result.success) {
return result;
}
// Trim to 50 rows to avoid overwhelming the context
return result.value.slice(0, 50);
},
});Commands never throw - apply() returns a discriminated result, so handle the failure branch rather than wrapping calls in try/catch. To describe the data to the model or validate arguments first, pull the current schema and vocabulary from Context.
Built-In Commands Copy Link
Ref type | What it does |
|---|---|
AgExecuteQueryCommand | Run a query against the data source. Supports aggregation (group-by with measures) and projection (raw row selection). |
AgAddPageFilterCommand | Append a filter to the page-level filter list. |
AgRemovePageFilterCommand | Remove a page-level filter, matching by its current state. |
AgAddWidgetFilterCommand | Add a filter scoped to a single widget. |
AgRemoveWidgetFilterCommand | Remove a widget-level filter, matching by its current state. |
AgAddWidgetCommand | Add a widget to the canvas. |
AgPositionWidgetCommand | Move or resize a widget. Omitted position fields preserve current values. |
AgRemoveWidgetCommand | Permanently remove a widget from the page. |
AgConfigureWidgetCommand | Configure a widget's data mapping, title, and formatting. Schema narrows by params.widgetType. |
Each button in the example sends a hardcoded prompt to OpenAI along with the matching command's JSON Schema as a single forced tool. The LLM returns tool arguments, which are handed straight to command.apply(). The console shows the message, schema, returned arguments, and command result for each.
JSON Schema Support Copy Link
AG Studio generates JSON Schema Draft 2020-12. Some LLM providers and runtimes do not support every feature of this version, so you may need to adapt the schema:
- Optional parameters - some LLMs require every parameter in the
requiredarray. Model an optional field as a union withnull(or a sentinel), then decode the result. - Nesting depth - some LLMs limit schema nesting depth. Studio uses
$defsand$refto keep schemas shallow, but you may still need to break a schema up further. - Root schema - some commands produce a union at the schema root, while some providers accept only an object there. Wrap the schema and unwrap the returned parameters before applying.
Next Steps Copy Link
- Context - Describe the data and dashboard to your model.
- LLM Adapter - The alternative: keep the built-in runtime and connect a provider.