AI Assistant
Use createPivotAiActions from @revolist/pivot to connect an active PivotPlugin to the shared AI assistant. Pivot remains responsible for field roles, aggregations, report configuration and analytical queries. The model proposes typed actions; it does not edit raw records or replace the Pivot engine.
Try it without a backend
Section titled “Try it without a backend”Try the Pivot assistant
Choose a suggested request below. This scripted demo runs entirely in your browser, with no backend, model key or model calls. It recognizes only the suggested requests.
Try it: Read the report, then choose “Show total amount by region”. Cancel the preview first, then submit again and Apply. Europe totals 300 and Asia totals 700.
Reset demo restores the original sample data and clears its conversation. To use your own prompts, follow the API-client setup guide.
What you will connect
Section titled “What you will connect”There are three parts:
- Your existing Pivot report owns the source data, report configuration and aggregate calculations.
- The assistant plugin displays the prompt, messages and Apply/Cancel controls.
createPivotAiActionsconnects those controls to your actual Pivot instance. - Your application’s API route authenticates the user and translates their prompt into a supported Pivot action. Call it through your existing API client; provider credentials stay on your server.
The steps below add the assistant to a working app. If you do not have a Pivot report yet, complete Your First Pivot first. The example assumes your report defines region, year and numeric amount dimensions. Replace these IDs and the suggestions with your report’s own dimensions.
Use compatible Pro and Pivot package versions that export AiAssistantPlugin and createPivotAiActions. If these imports are missing, check the installed versions. In a source checkout, stale generated packages also need rebuilding; restart your app after rebuilding so it loads the updated exports.
1. Include the assistant during grid initialization
Section titled “1. Include the assistant during grid initialization”Keep your existing Pivot configuration, source and other plugins. Add AiAssistantPlugin to the plugin list when you initialize the grid, before mounting it:
import { PivotPlugin } from '@revolist/pivot';import { AiAssistantPlugin } from '@revolist/revogrid-pro';import '@revolist/revogrid-pro/styles.css';import '@revolist/pivot/styles.css';
grid.plugins = [PivotPlugin, AiAssistantPlugin]; // Include your other plugins here.// Continue your existing grid.pivot, grid.source and mount setup.Create a place for the assistant in your app’s template, alongside the grid:
<div id="pivot-assistant"></div><!-- Your existing Pivot grid stays in its current container. -->2. Connect your active Pivot instance and API client
Section titled “2. Connect your active Pivot instance and API client”Run this after your grid has mounted and its initial Pivot report has loaded successfully. For a remote report, wait for your application’s successful report-load state, not just the component mount.
The code below retrieves both installed plugins, registers native Pivot actions and mounts the assistant in the container you created. It does not create another Pivot report or copy your source rows.
import { PivotPlugin, createPivotAiActions } from '@revolist/pivot';import { AiAssistantPlugin, type AiViewInterpreter,} from '@revolist/revogrid-pro';import { apiClient } from './api-client'; // Your existing authenticated client.
// This example assumes an Axios-style response with the parsed body in .data.const interpret: AiViewInterpreter = async (request, { signal }) => { const response = await apiClient.post('/api/ai/pivot', request, { signal }); return response.data;};
export async function connectPivotAssistant( grid: HTMLRevoGridElement, host: HTMLElement, interpret: AiViewInterpreter,) { const plugins = await grid.getPlugins(); const pivot = plugins.find( (plugin): plugin is PivotPlugin => plugin instanceof PivotPlugin, ); const assistant = plugins.find( (plugin): plugin is AiAssistantPlugin => plugin instanceof AiAssistantPlugin, ); if (!pivot || !assistant) { throw new Error('Install PivotPlugin and AiAssistantPlugin on this grid.'); } if (!pivot.getRuntimeSnapshot()) { throw new Error('Load the Pivot report before connecting its assistant.'); }
grid.aiAssistant = { interpret, mountTo: host, fields: [], // Do not expose the aggregate grid as ordinary source columns. executor: { read: () => ({ sort: [] }), async apply() { throw new Error('Use native Pivot actions to change this report.'); }, }, actions: createPivotAiActions(pivot, { fields: ['region', 'year', 'amount'], // Your Pivot dimension IDs. readRows: true, maxRows: 20, }), ui: { mode: 'chat', suggestions: [ 'Show total amount by region and year', 'Read the current report results', ], }, };
return () => { grid.aiAssistant = undefined; };}
// Call from your app after the existing report is ready.const host = document.getElementById('pivot-assistant');if (!host) throw new Error('Missing Pivot assistant container.');const disconnectAssistant = await connectPivotAssistant(grid, host, interpret);// Call disconnectAssistant() when this app view unmounts.grid is your existing grid element. apiClient and /api/ai/pivot belong to your application: replace the import and route with your own. The client should use your normal user session or bearer token. If it already returns the parsed body, return that directly instead of response.data. See the shared interpret contract for all request fields, cancellation and response shapes. The Fetch helper is an optional alternative.
The two fields settings have different purposes. The assistant’s top-level fields: [] disables ordinary flat-grid field disclosure. The adapter’s fields list allows native Pivot dimensions. Available Pivot fields and aggregators are described in the registered action schemas. Keep generic gridActions, dataActions and schemaActions disabled so they cannot operate on aggregate rows.
Recreate the adapter configuration when your disclosure policy or native capabilities change. Setting grid.aiAssistant to undefined disposes the assistant UI and cancels pending work; it does not destroy the Pivot report.
3. Return Pivot actions from your backend
Section titled “3. Return Pivot actions from your backend”Implement the /api/ai/pivot route used above. Installing the plugin does not create it. Your route must:
- Authenticate the caller and enforce your report’s field and data permissions.
- Accept the assistant request, including its
promptandactionsdescriptors. The top-levelfieldslist is intentionally empty for this action-only integration. - Constrain your model to the server-approved Pivot action schemas.
createAiViewResponseSchemacan build the response schema using the descriptors your server has validated against its policy. - Return one assistant result as the JSON body, rather than a raw model response or an HTTP-client wrapper.
For “Show total amount by region and year”, return:
{ "kind": "action", "name": "pivot.configure", "input": { "rows": ["region"], "columns": ["year"], "values": [{ "field": "amount", "aggregator": "sum" }] }}The browser validates this result and opens a preview. Apply updates the existing Pivot report through its native API; Cancel leaves it unchanged. For a read, return { "kind": "action", "name": "pivot.read", "input": { "limit": 10 } }. Aggregate results appear in the assistant UI; generating a prose answer from them requires the explicit evidence opt-in described below.
The backend guide provides a reference service and explains authentication. Its fixture policy describes orders, so configure your own approved Pivot dimensions and action schemas before connecting a real report. Browser descriptors are capability descriptions, not server authorization.
4. Check the connection before enabling a model
Section titled “4. Check the connection before enabling a model”To verify the UI and Pivot wiring without a backend, replace the final connection call above with this fixed interpreter:
const previewRegionTotals: AiViewInterpreter = async () => ({ kind: 'action', name: 'pivot.configure', input: { rows: ['region'], columns: [], values: [{ field: 'amount', aggregator: 'sum' }], },});const disconnectAssistant = await connectPivotAssistant( grid, host, previewRegionTotals,);Submit any prompt: this test interpreter always proposes the same report. Check that a preview appears, Cancel keeps the existing report, and Apply groups Amount by Region. Then reconnect using your API-client interpreter and check a real prompt against your backend. The fixed interpreter verifies execution, not natural-language understanding.
If the prompt does not appear, check the host container and installed assistant plugin. If the report is not active, wait for initial Pivot loading. For HTTP errors, check the route and user authentication. If pivot.read is unavailable, check the native capability and remote limits below.
Supported actions
Section titled “Supported actions”| Action | Behavior | input example |
|---|---|---|
pivot.configure | Preview row dimensions, column dimensions and measures, then Apply or Cancel. | { "rows": ["region"], "columns": ["year"], "values": [{ "field": "amount", "aggregator": "sum" }] } |
pivot.read | Read bounded current aggregate results without changing the report. Requires readRows: true and native analytical-query support. | { "limit": 10 } |
An interpreter returns a typed response such as { kind: 'action', name: 'pivot.read', input: { limit: 10 } }. It must choose from the advertised schemas. Available aggregators and allowed field roles come from the configured Pivot dimensions rather than a separate AI calculation engine.
For pivot.configure, omitted axes and measures remain unchanged. Explicit replacements support at most 20 entries per axis/measure list. The adapter rejects a replacement that would remove currently active fields outside the disclosure policy. The preview contains only the requested changes, and Apply rejects a stale or cancelled proposal before calling the native configuration API.
Aggregate scope and privacy
Section titled “Aggregate scope and privacy”pivot.read returns aggregate paths and measure values, never raw source records. It respects the native analytical query’s current source/filter context and field policy. It rejects a read when an active row/column path contains undisclosed fields.
- Default read limit: 20 aggregate rows, or your smaller configured limit.
- Maximum: 50 rows, 20 analytical series, and 16 KiB returned JSON. Native analytical limits can reject an oversized query rather than silently claim complete totals.
- Returned text is bounded to 500 characters per value. A bounded row list is not a promise to return every report category.
- Results stay in the shared assistant UI by default. Sending selected evidence back to the model requires explicit
answerFromActionconfiguration and backend approval of the evidence action name.
Field disclosure is not tenant authorization. Your data source/backend still owns access restrictions and mandatory filters. Prompt text and disclosed member values may contain business data.
Native capability and remote limits
Section titled “Native capability and remote limits”The read action is advertised only when getAnalyticalQueryCapability().supported is true. Currently, isolated analytical reads require the client engine and an exactly preserved source-filter context. Server-engine reports, active top/bottom settings, result filters or opaque Core filters can make this capability unavailable.
Do not interpret an unavailable read action as permission to calculate a total from a loaded server page. For complete remote analysis, provide an application-owned action that queries your authorized analytical backend. See server-side Pivot.
pivot.configure changes report configuration, not raw data. The adapter does not add source-row CRUD, filter/sort commands, export or a universal undo action. Report history belongs to the native authoring owner; do not assume a direct configuration call records the same command history as that owner. See report Undo and Redo and connect assistant history only to the owner that actually records your changes.
Backend and testing
Section titled “Backend and testing”Allow the adapter’s action schemas in your server interpreter and enforce server-owned field/data policy. The reference backend recognizes pivot.configure and pivot.read, but its example metadata describes orders; replace it for your report. Recognizing an action name does not grant access to report data.
The adapter is provider-neutral. You can test deterministic action responses, preview/cancel/apply, revision rejection and bounded aggregate reads without a model key. See testing without a model.