api.getAiContext() returns a read-only view of the dashboard for an agent to work from: what data is there, what can be built with it, what words are valid, and what is currently wrong.
It pairs with tools. Context is what you read to write instructions and validate intent; tools are what you call to act. Neither needs a chat panel.
const context = api.getAiContext();
const { tables, relationships } = context.schema();
const widgets = context.catalogue();
const { aggregations, filterOperators } = context.vocabulary;
const pageHealth = await context.health.page(); What It Exposes Copy Link
schema() - the data model: tables, their fields with types and roles, which aggregations each field allows, and the relationships between tables. A field also carries its reference token (@field[id]), its format, and the date buckets it can be grouped by.
catalogue() - the widget types available, each with a description, usage guidance, a summary of its configuration options, and recommended sizing.
vocabulary - the static enumerations Studio understands: aggregation functions, filter operators, data types, field roles. Use these to tell a model what words are legal.
fragments - resolved prose, such as an explanation of the @table[id] / @field[id] reference syntax to paste into a prompt.
health - health.page() and health.widget(id) report what is currently misconfigured: a chart with no measure, a filter on a field that no longer exists, widgets overlapping.
schema() and catalogue() are functions, not values, and they re-evaluate on every call. The dashboard changes while a user works, so a snapshot taken at construction would be stale by the second turn.
Grounding Instructions Copy Link
The most common use is describing the data in an agent's instructions, so the model does not have to spend a turn discovering it:
directLlmRunner({
id: 'analyst',
adapter,
instructions: () => {
const { tables } = api.getAiContext().schema();
const summary = tables
.map((table) => `${table.name}: ${table.fields.map((field) => field.name).join(', ')}`)
.join('\n');
return `You answer questions about this data.\n${summary}\n\nCall view_schema for exact field ids before writing a query.`;
},
tools: () => [studio.viewSchema(), studio.executeQuery()],
});Note the last line. A summary in the instructions orients the model, and the view_schema tool gives it exact ids and types when it needs them. Putting the whole schema in the prompt costs tokens on every turn and goes stale mid-conversation.
Health as Feedback Copy Link
Health is how an agent checks its own work. Studio's view_page and view_widget tools include it in what they return, which is how the built-in agents notice they have configured a chart badly and fix it without the user saying anything.
You can do the same from a tool of your own:
result: async (value, args) => ({
response: `Configured ${args.widgetId}.`,
data: { issues: (await api.getAiContext().health.widget(args.widgetId)).issues },
}),Returning issues from a mutating tool turns a silent misconfiguration into something the model can act on in the next turn.
Without an Agent Copy Link
Context is a plain read of Studio's state, so it is equally useful outside a conversation - describing a dashboard to your own model, validating a request before running it, or reporting on what a user has built:
const { tables } = api.getAiContext().schema();
const dateFields = tables.flatMap((table) => table.fields.filter((field) => field.dataType === 'date'));getAiContext() needs the AI module registered. Without it you get an inert context whose schema() and catalogue() return nothing.
Reference Copy Link
The context itself:
Reflects current DataModel state. Re-evaluated on every access.
|
Widget catalogue. Re-evaluated on every access.
|
Static type enumerations available in Studio.
|
Resolved static prose fragments from AgAiStrings.
|
Health reports for what is on the page, each resolved when it is asked for.
|
What schema() returns, and the tables within it:
Optional description of the overall data model.
|
Tables available in the data model.
|
Relationships between tables in the data model.
|
Unique identifier for the table.
|
Human-readable display name.
|
Optional description of what the table represents.
|
Reference token for use in prompts, following the @table[id] syntax.
|
Columns, measures, and calculated fields defined on the table.
|
What catalogue() returns:
Widget type identifier.
|
Human-readable display name.
|
What the widget does and when to use it.
|
Optional guidance on how to configure the widget.
|
Optional summary of the widget's configuration options.
|
Recommended minimum and default sizing.
|
The static enumerations, and the prose fragments:
Aggregation functions available across the data model.
|
Filter operators available across the data model.
|
Data types recognised by Studio.
|
Roles a field can take in a widget.
|
Explanation of the @table[id] / @field[id] reference syntax for use in prompts.
|
Next Copy Link
- Custom Tools - using context inside a tool
- Agent Configuration - building instructions from context