Customize chat, history and language
The default assistant is a compact prompt in the grid header. Choose chat when users benefit from seeing earlier requests and responses. Both presentations use the same configured interpreter, permissions and approval flow.
The snippets extend the quick start; interpret, saved prompts and persistence callbacks are supplied by your application. For an explanation of the user controls, see Use the assistant.
Shared UI, history and translations
Section titled “Shared UI, history and translations”All assistant controls belong to @revolist/ui/ai. The compact prompt grows for multiline text; Enter submits and Shift+Enter inserts a line break. IME composition is respected, and typing in the prompt does not trigger grid editing. Suggestions sit inside the composer, below the message input, with two buttons by default (ui.maxVisibleSuggestions) and a More (…) dropdown for additional requests. Clarification choices reuse those controls. Request history is hidden by default in chat. Toolbar mode can show AiRequestTrail through a history icon without a step count; ui.showRequestHistory overrides that default. It lists successful requests in order and allows undoing only the newest reversible filter/sort request. New conversation is a separate icon in both modes. Mounted assistant UI does not provide a workspace reset button.
Optional chat presentation
Section titled “Optional chat presentation”grid.aiAssistant = { interpret, ui: { mode: 'chat' },};Chat mode reuses the shared AiChat/AiMessage components to display submitted requests and actual assistant/status responses. The default remains the compact toolbar. The demo enables chat through one shared configuration in all four frameworks. Previews and Apply/Cancel stay in the current assistant response; existing Undo/Redo, Restore and Reset controls remain separate grid operations.
The local transcript retains at most 50 messages and 64 KiB. It displays visible feedback, without exposing hidden model prompts or reasoning. Displaying messages does not send the transcript or action data to a model: conversation, samples and answerFromAction retain their independent disclosure policies. Scripted mode remains scripted.
Use the installed plugin’s clearChat() (the New conversation icon) to clear the transcript, draft, request bookkeeping and opt-in model context. It never applies or undoes grid changes. The next request uses the current filters, sorting and active workspace as its baseline. The icon appears only when there are messages, a draft or AI request context to clear, and is disabled while busy or awaiting approval. Use ui.showNewConversation: false to hide it. Host-persisted prompt recall is controlled separately by the application.
Prompt recall is separate from model conversation. Enable it only when wanted:
grid.aiAssistant = { interpret, conversation: { maxMessages: 8, maxBytes: 8192 }, // Sent to interpreter. ui: { promptHistory: { items: savedPrompts, // Oldest first; loaded by your application. onChange: (items) => savePromptsForCurrentUser(items), }, activityDurationMs: 8000, },};Recall keeps at most 20 prompts and 8 KiB. ArrowUp/Down recalls them only at the first/last line boundary and restores an unsent draft. There is no automatic localStorage persistence or model disclosure. Your persistence callback owns user isolation, retention and deletion. Activity auto-dismiss is optional; completed neutral/success items fade out, while busy/warning/error items remain. The demo places Activity in its bottom-right corner.
Use setSuggestions(items) on the installed AiAssistantPlugin to change suggested requests. Other public methods include submit, stop, restore, reset, removeStep, applyAction, cancelAction, undoData, redoData and getSnapshot and clearChat. Retrieve the instance with await grid.getPlugins(). A standalone AiViewController also supports subscribe, refresh and destroy; call refresh after host-owned view changes. Stale model results and stale prepared actions are rejected rather than applied to changed state.
Supply translations on aiAssistant to localize the controller and mounted UI. AI_UI_MESSAGES from @revolist/ui/ai and AI_VIEW_MESSAGES from Pro enumerate built-in keys, with English fallback. Preserve interpolation placeholders such as {count} and {field}. Field labels, suggestions, model messages and custom-action text remain application-owned. Standalone UI components accept their own translations prop. View navigation accepts viewSwitcher.translations (including product adapter keys); VIEW_SWITCHER_MESSAGES from Pro and PIVOT_VIEW_MESSAGES from Pivot enumerate those defaults. Reuse the same dictionary on aiAssistant.translations to translate view action results such as Showing {view}.. Translations are forwarded to native Pivot/chart AI tools. Custom view labels remain host-owned.
Next: Set up the AI backend.
Mount in a configurator
Section titled “Mount in a configurator”Set aiAssistant.mountTo: false to initialize the controller without adding a header toolbar. Retrieve the initialized AiAssistantPlugin through await grid.getPlugins() and call createAiConfiguratorSection(assistant) from @revolist/revogrid-pro. Add the returned section to the Grid, Pivot or Pivot Charts configurator’s sections configuration.
The helper uses the existing controller and shared chat UI. It defaults to a full-height chat, with the transcript scrolling above the bottom composer, and hides native data history controls. New conversation remains a separate icon; use ui.showNewConversation: false to hide it. Request history stays hidden by default in chat. Customize the tab label/visibility with the section options, and opt into those controls through ui.showHistoryControls: true. Other assistant mounts keep their default presentation.
For another application-owned surface, assistant.mount(host, uiOptions) returns { destroy() }. Destroy that handle when its view unmounts; the controller stays available to other surfaces. Destroying the plugin releases every mounted surface. See custom section lifecycle and examples.
One grid with Pivot and a chart dashboard
Section titled “One grid with Pivot and a chart dashboard”ViewSwitcherPlugin coordinates installed view owners. It does not import Pivot or Charts into Pro. Add createPivotViews from @revolist/pivot to register their native views, and opt into adapter: createViewSwitcherAiAdapter() to advertise view.switch, view.back and view.inspect. The active view also exposes its existing native Pivot or chart AI tools. Chart-type changes use view.switch so Back can restore the previous chart type; presentation edits use the native chart tool. Grouping stays in the ordinary grid configuration. The existing grouping.set action restores source data first when needed, then delegates to native grid grouping; it does not create another view. The application’s grid toolbar uses Data Grid | active control. The control name comes from its registered view, such as Pivot, Pivot Chart, Schedule or Gantt. Selecting Data Grid retains the latest control and its configuration so it can be selected again. Chat shows only the separate New conversation icon. New conversation clears only AI state and preserves the workspace. The assistant does not reset workspace configuration; reload the demo page to restore its initial state.
The assistant itself has no report IDs, chart layout, grouping routing or view-specific tool allowlist. The optional adapter composes those decisions through the installed plugin APIs. Omit adapter for ordinary grid behavior; existing actions, actionsForRequest, executor, gridState and UI options remain sufficient for most custom integrations. Supply a custom adapter when several plugins need a shared lifecycle:
grid.aiAssistant = { interpret, executor: applicationExecutor, actions: applicationTools, adapter: ({ executor, actions }) => ({ executor, // Keep or wrap the configured executor. actions: () => actions().filter((tool) => applicationAllows(tool.name)), // Optional: canReadColumns, subscribe (returns cleanup), ui and destroy. }),};Adapters replace the selected execution/tool policy; the built-in ViewSwitcher preset is not automatically added. Adapter factories are trusted host code and receive only the existing grid/providers and configured capabilities. Plugin subscriptions and adapter cleanup are released on reconfiguration or destruction. createViewSwitcherAiActions, createViewSwitcherAiExecutor and protectRecordActions are exported separately for applications that want only part of the preset. Hosts still own permissions and disclosure; controller validation and mutation previews remain enforced.
For a progression from one custom action to your own adapter, see Build your own assistant behavior.
The application owns the grid and dashboard surfaces. Keep the same grid visible beside the dashboard; Pivot supplies both its report rows and the charts. Keep the assistant outside these surfaces so it remains usable throughout:
import { AdvanceFilterPlugin, AiAssistantPlugin, ViewSwitcherPlugin, createViewSwitcherAiAdapter,} from '@revolist/revogrid-pro';import { PivotPlugin, PivotChartsPlugin, PivotChartsUiPlugin, createPivotViews,} from '@revolist/pivot';import { createChartsRenderer } from '@revolist/charts';
grid.plugins = [ AdvanceFilterPlugin, PivotPlugin, PivotChartsPlugin, PivotChartsUiPlugin, ViewSwitcherPlugin, AiAssistantPlugin,];grid.pivotCharts = { renderer: createChartsRenderer() };grid.viewSwitcher = { views: [ createPivotViews({ pivot: { dimensions: [ { prop: 'status', allowedRoles: ['rows', 'columns'] }, { prop: 'amount', allowedRoles: ['values'] }, ], rows: ['status'], columns: [], values: [{ prop: 'amount', aggregator: 'sum' }], }, chart: { container: chartSurface, controls: 'standard' }, }), ], onChange(state) { const view = state.pendingView ?? state.view; gridSurface.hidden = false; chartSurface.hidden = view !== 'chart'; },};grid.aiAssistant = { interpret, mountTo: assistantHost, adapter: createViewSwitcherAiAdapter(), gridActions: {}, // Reuse native grouping and grid configuration tools. conversation: {}, ui: { mode: 'chat' },};Set these properties before the grid initializes, with grid inside gridSurface and the chart/assistant hosts outside it. Use a wrapper for the grid surface: Core owns the grid element’s rendering styles. Omit chart to register only the Pivot adapter; omit controls: 'standard' to render the chart without its configuration UI. Chart types and bindings use the native Charts catalog and compatibility validation, including specialized charts that require additional channels. createPivotViews hides configurators by default. Explicit options: { configure: true } opens the existing native configurator; configure: false hides it again. Dashboard charts always omit their Data/Chart switch because the report grid is already visible. Configurator visibility is retained with saved view configuration, and host control restrictions remain enforced.
For example, an interpreter can return:
return { kind: 'action', name: 'view.switch', input: { view: 'chart', options: { chartType: 'donut', report: { rows: ['status'], columns: [], values: [{ field: 'amount', aggregator: 'sum' }], }, }, },};// Other targets: { view: 'pivot' }, { view: 'grid' }.// Grouping uses { kind: 'action', name: 'grouping.set', input: { fields: ['status'] } }.// Charts can use different dimensions while keeping the same source filters:// options: { charts: [// { chartType: 'donut' },// { chartType: 'area', query: { slice: { rows: ['country'], columns: [] } } },// ] }.// Return { kind: 'action', name: 'view.back', input: {} } to go back.A dashboard contains up to six native charts sharing one Pivot report. Each chart keeps its own appearance settings and can use a native query.slice with different row or column dimensions. These queries retain the report’s source filters. Omitting options restores that presentation’s last configuration. The switcher captures live settings before leaving, including manual chart edits, and retains up to 20 previous configurations. It restores configuration against the current data, rather than undoing source edits. Failed or cancelled switches restore the previous owner and leave Back history unchanged; restoration failures are surfaced as errors. Temporary contributed Pivot member filters must be persisted or cleared before switching; the owner refuses to discard them silently.
The demo uses a compact Data Grid / active control switch that preserves each configuration. Optional manual controls use the same API:
const views = (await grid.getPlugins()).find( (plugin) => plugin instanceof ViewSwitcherPlugin,)!;const controls = views.mount(viewControlsHost, { showViews: false });await views.switchView('chart', { chartType: 'area' });await views.back();// When your application unmounts the control host:controls.destroy();Other plugins can call registerView(adapter) or registerViews(factory) before enabling the assistant. Each adapter supplies capture, activate and optional deactivate/destroy, and retains ownership of its detached configuration and native APIs. Only adapter identities, typed input schemas and explicit tool results go to the model. getSnapshot() and subscribe() expose view availability, transition status and Back availability without exposing saved configuration or source records.
For compact embedded chart cards, set grid.pivotChartsUi to { settingsMode: 'replace', toolbarMode: 'overlay' }. Settings then fill the card and close through × or Escape; the native action toolbar appears on hover, keyboard focus, or touch devices in its own reserved row, without covering the plot. Dashboard adapters opt into the native embedded close action (closable: true), retaining only remaining widget models in view history. Pivot result cells are read-only; returning to Data restores its original editing policy. Ordinary AI filter/sort requests update the source query without leaving the report or dashboard. Report adapters apply source filters through native Pivot filtering without swapping to Data. Projection owners expose original field metadata through DATA_GRID_SOURCE_COLUMNS so the shared filter compiler evaluates source fields correctly. The generic switcher temporarily delegates other source operations to their Data executor while retaining mounted charts.
Custom view adapters may receive temporary: true during views.runInView(id, operation, signal). Retain presentation resources on temporary deactivation and refresh them when activation resumes. Ordinary navigation still releases them. The switcher serializes these operations and restores the selected owner if execution fails.