Skip to content

AI Assistant

Use createGanttAiActions from @revolist/gantt to connect an initialized GanttPlugin to the shared AI assistant. The adapter uses native task reads and updates. Gantt still owns scheduling, dependency effects, validation, permissions and history; no second scheduling engine or task editor is introduced.

Try the Gantt 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 tasks, then choose “Set Design progress to 50 percent”. Cancel keeps progress at 0%; submit again and Apply to update the task and its bar.

The demo loads when visible.

Reset demo restores the original sample data and clears its conversation. To use your own prompts, follow the API-client setup guide.

Your existing Gantt project remains the data and behavior owner. The assistant plugin supplies the prompt/chat and approval UI. createGanttAiActions connects the assistant to your actual GanttPlugin instance. Your API client sends prompts and action descriptors to an authenticated application route, which returns a supported action.

If you do not have a working Gantt project yet, complete the first-app guide first. Use a complete local project for this walkthrough. A partial remote schedule needs application-owned service actions; loaded tasks must not be treated as the whole project. Replace the example task ID design with a real stable task ID.

Use compatible Pro and Gantt package versions that export AiAssistantPlugin and createGanttAiActions. If an import is missing, check the installed versions; in a source checkout, rebuild stale generated packages and restart your app.

1. Include the assistant during grid initialization

Section titled “1. Include the assistant during grid initialization”

Add AiAssistantPlugin alongside your existing Gantt and other plugins before mounting the grid. Keep your current configuration and source setup:

import { GanttPlugin } from '@revolist/gantt';
import { AiAssistantPlugin } from '@revolist/revogrid-pro';
import '@revolist/revogrid-pro/styles.css';
import '@revolist/gantt/styles.css';
grid.plugins = [GanttPlugin, AiAssistantPlugin]; // Keep your other plugins too.
// Continue your existing Gantt configuration, source and mount setup.

Add a container alongside your existing grid in the application template:

<div id="gantt-assistant"></div>

2. Connect the active Gantt instance and your API client

Section titled “2. Connect the active Gantt instance and your API client”

Call this after the grid has mounted and the initial Gantt project is loaded. A mounted component alone does not guarantee that application data has finished loading.

import { GanttPlugin, createGanttAiActions } from '@revolist/gantt';
import {
AiAssistantPlugin,
type AiViewInterpreter,
} from '@revolist/revogrid-pro';
import { apiClient } from './api-client'; // Your existing authenticated client.
// Axios-style example: .data is the parsed assistant result.
const interpret: AiViewInterpreter = async (request, { signal }) => {
const response = await apiClient.post('/api/ai/gantt', request, { signal });
return response.data;
};
export async function connectGanttAssistant(
grid: HTMLRevoGridElement,
host: HTMLElement,
interpret: AiViewInterpreter,
) {
const plugins = await grid.getPlugins();
const gantt = plugins.find(
(plugin): plugin is GanttPlugin => plugin instanceof GanttPlugin,
);
const assistant = plugins.find(
(plugin): plugin is AiAssistantPlugin => plugin instanceof AiAssistantPlugin,
);
if (!gantt || !assistant) {
throw new Error('Install GanttPlugin and AiAssistantPlugin on this grid.');
}
if (!gantt.getProjectSnapshot()) {
throw new Error('Load the Gantt project before connecting its assistant.');
}
grid.aiAssistant = {
interpret,
mountTo: host,
fields: [], // Keep ordinary flat-grid fields and commands disabled.
executor: {
read: () => ({ sort: [] }),
async apply() {
throw new Error('Use native Gantt actions for this view.');
},
},
actions: createGanttAiActions(gantt, {
read: {
fields: ['id', 'parentId', 'name', 'progressPercent', 'startDate', 'endDate'],
maxTasks: 20,
},
update: { fields: ['name', 'progressPercent', 'workflowStatus'] },
}),
ui: {
mode: 'chat',
suggestions: [
'Read up to three tasks',
'Set task design progress to 50 percent',
],
},
};
return () => { grid.aiAssistant = undefined; };
}
// Call from your app after the existing Gantt project is ready.
const host = document.getElementById('gantt-assistant');
if (!host) throw new Error('Missing Gantt assistant container.');
const disconnectAssistant = await connectGanttAssistant(grid, host, interpret);
// Call disconnectAssistant() when this application view unmounts.

grid is your existing grid element. apiClient and /api/ai/gantt are application-owned; replace the import path and route with your own. This example assumes an Axios-style client. If your client returns the parsed body directly, return that instead of response.data. Forward signal so Stop and disposal can cancel pending requests. Your client supplies its usual user session or bearer token and handles token refresh; provider keys stay on your backend.

interpret receives the prompt, permitted context and enabled action descriptors. It must resolve to one structured assistant result. See the request/response contract. createAiViewHttpInterpreter is an optional Fetch alternative.

The top-level fields: [] keeps this an action-only assistant. The adapter options separately allow native Gantt operations and disclose their schemas. Do not enable generic gridActions, dataActions or schemaActions against the product projection. Recreate the adapter when field/permission policies change. Cleanup disposes the assistant and cancels pending work without destroying your Gantt project.

3. Return native actions from your backend

Section titled “3. Return native actions from your backend”

Implement the example /api/ai/gantt route in your application. Installing the plugin does not create it. Authenticate the user, enforce your server-owned field/action policy and constrain your model to the approved action schemas from request.actions. The request’s top-level fields list is intentionally empty in this setup; native capabilities are described by their action descriptors. Browser descriptors do not grant server permissions.

For “Set task design progress to 50 percent”, return this JSON body:

{
"kind": "action",
"name": "gantt.updateTask",
"input": { "id": "design", "patch": { "progressPercent": 50 } }
}

The client returns that object to the assistant, which validates it and displays a preview. Apply calls the existing native Gantt API; Cancel changes nothing. Use actual task IDs from your app. A read request can return { "kind": "action", "name": "gantt.readTasks", "input": { "limit": 3 } } instead.

The backend guide explains the reference service and authentication. Replace its orders fixture metadata with your own approved project policy. Return the assistant result itself, rather than a provider response or HTTP-client wrapper. Read results appear locally in the assistant UI; sending them back to the model for a prose answer requires explicit evidence configuration.

Replace the final connection call above with this deterministic interpreter. Do not run both connection calls at once:

const readThree: AiViewInterpreter = async () => ({
kind: 'action',
name: 'gantt.readTasks',
input: { limit: 3 },
});
const disconnectAssistant = await connectGanttAssistant(grid, host, readThree);

Submit any prompt: the fixed interpreter always reads up to three permitted tasks. Check that the prompt appears and the returned fields match your disclosure policy. This verifies the UI and native adapter without an HTTP route or model key. It does not test natural-language understanding.

Reconnect with your API-client interpreter, then submit the update example using a real record ID. Check Cancel first, then Apply and the native task result. For HTTP failures, check your route and user authentication. If the prompt is missing, check the host and installed plugin. If the project is not ready, wait for successful application data loading. Do not use this local adapter to infer complete-project results from a partial remote schedule.

ActionBehaviorinput example
gantt.readTasksRead bounded effective scheduled tasks, optionally restricted by IDs.{ "ids": ["design"], "limit": 1 }
gantt.getChildrenRead immediate children of a task; parentId: null reads roots.{ "parentId": "release", "limit": 10 }
gantt.updateTaskPreview one allowed task patch, then Apply or Cancel.{ "id": "design", "patch": { "progressPercent": 50 } }

An interpreter returns a typed response such as { kind: 'action', name: 'gantt.updateTask', input: { id: 'design', patch: { progressPercent: 50 } } }. It may choose only registered capabilities; the adapter validates it again before execution.

Allowed read fields are id, parentId, name, startDate, endDate, duration, durationUnit, progressPercent, workflowStatus, isCritical and status. They describe the effective native schedule, not arbitrary raw task properties.

Reads default to 20 tasks, or your smaller configured maximum. The hard limit is 50 tasks and 16 KiB per result. Strings are bounded to 500 characters. Child reads are immediate children, not an automatic recursive traversal of the project.

Duration has two distinct representations:

  • Read: duration is the effective native duration in scheduling days, and durationUnit is always scheduling-day. This is separate from the task’s authored display unit. For example, four working hours on a seven-hour calendar are reported as 4 / 7 scheduling days. If you disclose duration, you must also disclose durationUnit.
  • Update: a duration patch is expressed in canonical hours, regardless of the displayed unit. For example, { "duration": 8 } requests eight canonical hours, not eight days. Enable duration in update.fields only if the assistant should change it.

The other editable fields are name, progressPercent (0–100) and workflowStatus (not-started, in-progress, done, blocked). Omitted task fields stay unchanged. Names must be nonempty and at most 500 characters; durations must be finite and between 0 and 1,000,000 canonical hours.

Optional read.canRead(task) and update.canUpdate(task, patch) callbacks narrow your application policy. When a read policy is configured, it also guards explicitly targeted updates. Locked tasks cannot be updated through this adapter. Native Gantt permissions and cancelable before-change events remain authoritative.

The existing shared assistant UI shows the requested patch before Apply. Preparation does not update the schedule. Apply rechecks the project revision, cancellation and task policy, then calls native updateTask. The preview shows the requested patch; dependent dates are recalculated by the native scheduler when the update is applied.

Include the existing HistoryPlugin to record supported native task changes. To expose Undo/Redo inside the assistant, connect AiAssistantConfig.actionHistory to that same installed History instance. View-request steps and task-data history are separate; restoring an assistant filter/sort step does not undo a task edit.

Only configured read fields are returned. Results initially stay in the shared assistant UI; they are not automatically sent back to the model. Optional answerFromAction requires an explicit result projector and a matching backend evidence allowlist. Pending previews and prepared-write results do not trigger that extra model call.

The adapter does not provide backend authentication, remote commit receipts, task paging or complete-server-project reads. Your service owns access control, mandatory predicates, project versions and persisted mutations. Do not attach flat-grid data actions to partially loaded Gantt rows as a substitute.

The initial adapter does not create/delete tasks, edit dependencies, calendars or assignments, directly set task start/end dates, or expose timeline presentation commands. Reading isCritical does not enable a critical-path display toggle.

Allow the adapter schemas in your interpreter. The reference backend recognizes the three Gantt action names but uses orders fixture metadata by default; replace that policy for your application. Provider credentials stay on your backend, and action-name recognition is not authorization.

Use deterministic responses to test reads, preview/cancel/apply, dependency rescheduling, native Undo, stale proposals and Stop without making model calls. See testing without a model and the Gantt data model.