Skip to content

DataGrid - AI Assistant: Implement messageTemplate#33265

Open
Alyar666 wants to merge 11 commits intoDevExpress:26_1from
Alyar666:datagrid_ai_assistant_message_template_26_1
Open

DataGrid - AI Assistant: Implement messageTemplate#33265
Alyar666 wants to merge 11 commits intoDevExpress:26_1from
Alyar666:datagrid_ai_assistant_message_template_26_1

Conversation

@Alyar666
Copy link
Copy Markdown
Contributor

No description provided.

@Alyar666 Alyar666 self-assigned this Apr 14, 2026
@Alyar666 Alyar666 marked this pull request as ready for review April 20, 2026 10:17
Copilot AI review requested due to automatic review settings April 20, 2026 10:17
@Alyar666 Alyar666 requested review from a team as code owners April 20, 2026 10:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements richer AI Assistant chat message rendering in the DataGrid/TreeList AI Assistant UI, introducing status-aware message templates (pending/success/error) and moving message state management into a dedicated controller.

Changes:

  • Add messageTemplate rendering for AI Assistant messages (status icon/header/body, command result list, pending progress bar, regenerate action).
  • Introduce AIAssistantController to manage message store/data source and AI request lifecycle.
  • Refactor/extend AI chat styles (new aiChat layout, theme-specific includes) and add new localization keys for message headers.

Reviewed changes

Copilot reviewed 57 out of 57 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/devextreme/js/localization/messages/ar.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/bg.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ca.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/cs.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/da.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/de.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/el.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/en.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/es.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/fa.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/fi.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/fr.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/hu.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/it.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ja.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ko.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/lt.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/lv.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/nb.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/nl.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/pl.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/pt.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ro.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ru.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/sl.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/sv.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/tr.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/uk.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/vi.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/zh.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/zh-tw.json Add AI chat pending/error header message keys
packages/devextreme/js/__internal/grids/tree_list/module_not_extended/ai_assistant.ts Register new AI assistant controller and keep view controller under a new key
packages/devextreme/js/__internal/grids/data_grid/module_not_extended/ai_assistant.ts Register new AI assistant controller and keep view controller under a new key
packages/devextreme/js/__internal/grids/grid_core/m_types.ts Update controller type map for new AI assistant controller naming
packages/devextreme/js/__internal/grids/grid_core/ai_chat/types.ts Re-export command result types and add message status union type
packages/devextreme/js/__internal/grids/grid_core/ai_chat/const.ts Expand AI chat CSS class constants and add regenerate/icon constants
packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Implement custom messageTemplate rendering and status-specific UI
packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.test.ts Add Jest coverage for new message template behaviors
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts Introduce AI command/response/result types and callbacks contract
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/grid_commands.ts Add placeholder grid command validation/execution layer
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/const.ts Add AI assistant author constants and shared message status enum
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_view.ts Move message data source + request sending into controller
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_controller.ts New controller: message store lifecycle, AI integration callbacks, status transitions
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/tests/ai_assistant_view.test.ts Update tests to mock controller-driven data source and message sending
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/tests/ai_assistant_controller.test.ts Add unit tests for controller request lifecycle and message updates
packages/devextreme-scss/scss/widgets/material/gridBase/layout/aiChat/_index.scss Theme include for new aiChat mixins
packages/devextreme-scss/scss/widgets/material/gridBase/_index.scss Wire aiChat layout module and remove inline empty-view include
packages/devextreme-scss/scss/widgets/generic/gridBase/layout/aiChat/_index.scss Theme include for new aiChat mixins
packages/devextreme-scss/scss/widgets/generic/gridBase/_index.scss Wire aiChat layout module and remove inline empty-view include
packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/aiChat/_index.scss Theme include for new aiChat mixins
packages/devextreme-scss/scss/widgets/fluent/gridBase/_index.scss Wire aiChat layout module and remove inline empty-view include
packages/devextreme-scss/scss/widgets/base/gridBase/layout/aiChat/_mixins.scss New mixins for empty view and pending message styling
packages/devextreme-scss/scss/widgets/base/gridBase/layout/aiChat/_index.scss New base aiChat layout styles (message template layout + progress bar positioning)
packages/devextreme-scss/scss/widgets/base/gridBase/layout/ai-chat/_mixins.scss Remove legacy ai-chat mixins (superseded by aiChat)
packages/devextreme-scss/scss/widgets/base/gridBase/layout/ai-chat/_index.scss Remove legacy ai-chat base styles (superseded by aiChat)
packages/devextreme-scss/scss/widgets/base/gridBase/_mixins.scss Remove legacy forward for ai-chat mixins (path removed)
packages/devextreme-scss/scss/widgets/base/gridBase/_index.scss Switch base gridBase to use new layout/aiChat module

data: {
id: aiMessageId,
timestamp: parsedTimestamp,
// TODO: need to localize author name and move it to constants or options
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This TODO is partially outdated: the author is already centralized in AI_ASSISTANT_AUTHOR constants. Consider updating the comment to focus on the remaining work (e.g., localization/configurability), so it doesn’t imply the constant extraction is still pending.

Suggested change
// TODO: need to localize author name and move it to constants or options
// TODO: need to make author name configurable/localizable

Copilot uses AI. Check for mistakes.
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_assistant/grid_commands.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme-scss/scss/widgets/base/gridBase/layout/aiChat/_index.scss Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts Outdated
@@ -0,0 +1,85 @@
@use "../../../icon_fonts" as *;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to have screen shot etalons in different themes, so the designer could review them.
And the story book.

Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/types.ts
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Outdated
.addClass(`dx-icon dx-icon-${REGENERATE_ICON} ${CLASSES.messageRegenerateButton}`)
.appendTo($row);

eventsEngine.on($button, 'click', () => this.options.onRegenerate?.());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would event be automatically unsubscribed when button is removed from DOM after succesful regeneration or when the result can no longer be regenerated? Purhaps. we should use eventsEngine.one instead - as long as we re-render messageBubble after each change

Copy link
Copy Markdown
Contributor Author

@Alyar666 Alyar666 Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an element is removed from the DOM, all associated subscriptions are also cleaned up (assuming there are no remaining references to that element).

Using eventsEngine.one is unlikely to fully resolve the issue you described.

Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/const.ts Outdated
Copilot AI review requested due to automatic review settings April 22, 2026 11:04
@Alyar666 Alyar666 force-pushed the datagrid_ai_assistant_message_template_26_1 branch from 8c67a26 to 0ffb5d5 Compare April 22, 2026 11:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 59 out of 59 changed files in this pull request and generated 7 comments.

Comments suppressed due to low confidence (1)

packages/devextreme/js/__internal/grids/grid_core/ai_chat/types.ts:21

  • MessageStatus is declared here as a string union but isn’t used (the implementation uses MessageStatus from ai_assistant/const). This extra exported type is redundant and may cause confusion about which status type to use; consider removing it or aligning the code to use a single source of truth.

export type MessageStatus = 'pending' | 'success' | 'error';

Comment on lines +100 to +121
public sendRequestToAI(message: Message): void {
const aiMessageId = this.createPendingAIMessage(message);

this.aiAssistantIntegrationController?.sendRequest(message.text, {
onComplete: (response: ExecuteGridAssistantCommandResult): void => {
fromPromise(this.processResponse(response))
.done((commands: CommandResults) => {
this.completeAIMessage(aiMessageId, commands);
})
.fail((errorMessage) => {
const error = errorMessage instanceof Error
? errorMessage
: new Error(String(errorMessage));

this.failAIMessage(aiMessageId, error);
});
},
onError: (error: Error): void => {
this.failAIMessage(aiMessageId, error);
},
});
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sendRequestToAI always inserts a pending assistant message before calling sendRequest. If AI integration is not configured, AIAssistantIntegrationController.sendRequest returns early (and abort prevents callbacks), so the message will remain in the pending state indefinitely. Consider detecting this case (e.g., make sendRequest return a boolean / throw when no integration) and immediately mark the message as Error (or avoid inserting it) with a user-friendly error.

Copilot uses AI. Check for mistakes.
Comment thread packages/devextreme/js/__internal/grids/grid_core/ai_chat/const.ts
Comment on lines +100 to +121
public sendRequestToAI(message: Message): void {
const aiMessageId = this.createPendingAIMessage(message);

this.aiAssistantIntegrationController?.sendRequest(message.text, {
onComplete: (response: ExecuteGridAssistantCommandResult): void => {
fromPromise(this.processResponse(response))
.done((commands: CommandResults) => {
this.completeAIMessage(aiMessageId, commands);
})
.fail((errorMessage) => {
const error = errorMessage instanceof Error
? errorMessage
: new Error(String(errorMessage));

this.failAIMessage(aiMessageId, error);
});
},
onError: (error: Error): void => {
this.failAIMessage(aiMessageId, error);
},
});
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new request aborts the previous one in AIAssistantIntegrationController.sendRequest(), and RequestManager suppresses callbacks after abort. Since the controller doesn’t track/resolve the previously inserted pending message, sending multiple prompts can leave older assistant messages stuck in Pending forever. Consider keeping the previous pending message id and marking it as canceled/failed (or removing it) when a request is aborted/replaced.

Copilot uses AI. Check for mistakes.

"dxDataGrid-aiAssistantTitle": "AI Assistant",
"dxDataGrid-aiAssistantPendingMessageHeader": "Request in progress",
"dxDataGrid-aiAssistantProcessingMessage": "Processing...",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message list differ for other languages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants