/** * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ /** * @module ai/aichat/aichatcontroller * @publicApi */ import { ContextPlugin } from '@ckeditor/ckeditor5-core'; import { AIConnector } from '../aicore/aiconnector.js'; import { AIChatConversation, type AIChatInteractionCreatedEvent } from './model/aichatconversation.js'; import { type AIInteractionReplyCreatedEvent, type AIToolData } from '../aicore/model/aiinteraction.js'; import { type AIChatInteraction } from './model/aichatinteraction.js'; import { DocumentCompare } from '@ckeditor/ckeditor5-collaboration-core'; import { type AIChatFeedCustomElementView } from './ui/feed/aichatfeedcustomelementview.js'; /** * Implements integration layer between AI Chat feature UI and logic. * * Provides an API to interact with AI Chat feature. * * @experimental **Experimental:** Some methods of this class are production-ready but experimental and may change * in minor releases without the standard deprecation policy. Check the changelog for migration guidance. */ export declare class AIChatController extends ContextPlugin { /** * Active conversation (currently open and visible in UI). */ activeConversation?: AIChatConversation; /** * @inheritDoc */ static get requires(): readonly [typeof AIConnector, typeof DocumentCompare]; /** * @inheritDoc */ static get pluginName(): "AIChatController"; /** * @inheritDoc */ static get isOfficialPlugin(): true; /** * @inheritDoc */ static get isPremiumPlugin(): true; /** * @inheritDoc */ init(): void; /** * @inheritDoc */ afterInit(): Promise; /** * @inheritDoc */ destroy(): Promise; /** * Loads a conversation by its ID and sets it as the active conversation. */ loadConversation(conversationId: string): Promise; /** * Registers a function that is called when data from a custom AI tool is received from the backend service. * * This data can only be received if you connect your own custom AI tool with the Cloud Services AI backend. By registering a callback * function, you can implement custom handling for this data, such as displaying custom elements inside the AI chat component, or * setting a custom loading message. * * When data is received, the callback is immediately called with two parameters: * * * `toolData` – data returned by the AI tool, * * `api` – {@link module:ai/aichat/aichatcontroller~AIChatFeedAPI set of tools} which you can use to reflect the received AI tool data * in the AI chat feed. * * The callback is called for data received from all tools that you have connected, and both for tool results and tool notifications. * Check `toolData.toolName` and `toolData.type` to handle various tools and actions. You can register multiple callbacks to better * organize your code. * * Please remember, that your tool is fully responsible for generating the contents of `toolData.data` and `toolData.attributes`. * * Example usage: * * 1. Register a callback that changes the loading message when tool "my-tool" returns a notification: * * ```ts * aiChat.registerToolDataCallback( ( toolData, api ) => { * if ( toolData.toolName === 'my-tool' && toolData.type === 'notification' ) { * api.setLoadingMessage( toolData.data.message ); * } * } ); * ``` * * 2. Register a callback to create a custom text chat reply based on custom tool data: * * ```ts * aiChat.registerToolDataCallback( ( toolData, api ) => { * if ( toolData.type == 'result' ) { * api.insertTextReply( toolData.toolName + ': ' + toolData.data.msg ); * } * } ); * ``` * * 3. Register a callback to insert a custom element into the chat feed based on custom tool data: * * ```ts * aiChat.registerToolDataCallback( async ( toolData, api ) => { * if ( toolData.type == 'result' && toolData.data.html ) { * api.insertCustomElement( toolData.data.html ) * .then( ( customElementView ) => { * // You can further manipulate the inserted custom element using `customElementView`. * // For example, you can fetch some data asynchronously and put it into the element. * // Use `customElementView.element` to reference the created DOM structure. * // The `customElementView.element` is a wrapper element of a custom UI HTML provided. * } ); * } * } ); * ``` * * @experimental **Experimental:** This is a production-ready API but may change in minor releases * without the standard deprecation policy. Check the changelog for migration guidance. * @param callback A callback function that is called when tool data is received. */ registerToolDataCallback(callback: AIToolEventCallback): void; /** * Adds the current document to the chat context. */ addCurrentDocumentToChatContext(): void; /** * Adds current document selection to the conversation context. If document is not added to the context, it is added as well. * * @experimental **Experimental:** This is a production-ready API but may change in minor releases * without the standard deprecation policy. Check the changelog for migration guidance. */ addSelectionToChatContext(): Promise; /** * Removes current document selection from the conversation context. * * @experimental **Experimental:** This is a production-ready API but may change in minor releases * without the standard deprecation policy. Check the changelog for migration guidance. */ removeSelectionFromChatContext(): void; /** * Moves focus to the AI Chat prompt input field. * * @experimental **Experimental:** This is a production-ready API but may change in minor releases * without the standard deprecation policy. Check the changelog for migration guidance. */ focusPromptInput(): void; /** * Creates a new, empty conversation. */ startConversation(): Promise; /** * Submits a user message to the currently active conversation. */ sendMessage(messageData: AIChatUserMessageData): Promise; /** * Returns the ID under which conversations are grouped. All created conversations will have this `groupId` set. Conversation history * will fetch conversations with such `groupId`. * * By default, this is equal to the document ID passed in editor configuration. */ getGroupId(): string; /** * Starts an AI chat conversation safely, catching and logging any errors. */ protected _startConversationSafely(id?: string): Promise; } /** * Data for the message send by the user in the AI chat. */ export type AIChatUserMessageData = { /** * The query that the user provided for the message. Displayed in the chat feed as the user's message. */ message: string; /** * Additional parameters for the message. This data is stored together with the message and can influence how the message is processed * or displayed. * * You can pass following properties to alter how the message behaves: * * * `displayedPrompt: string` - If set, will be displayed instead of the actual `message`. You can use it to display a shorter, * or a friendlier user message. This is also respected in the conversation history. Original `message` will still be used to query * the AI model. * * Besides supported properties, `attributes` can be used to save any additional metadata with the message, which can be used by your * integration in any way. Data passed in `attributes` will be saved in the conversation history. If your integration connects external * custom AI tools, `attributes` are passed to the tool calls and can be used by these tools. * * Additionally, other official features that interact with the AI chat feature may introduce their own attributes. */ attributes?: Record; }; /** * Set of helpers dedicated to be used inside {@link module:ai/aichat/aichatcontroller~AIToolEventCallback callbacks} registered * through {@link module:ai/aichat/aichatcontroller~AIChatController#registerToolDataCallback}. * * Using this tools you can manipulate AI chat feed (e.g. add custom replies) in response to the received custom AI tool data. * * @experimental **Experimental:** This is a production-ready API but may change in minor releases * without the standard deprecation policy. Check the changelog for migration guidance. */ export interface AIChatFeedAPI { /** * Creates a new reply in the current interaction. The created reply becomes the current reply of the interaction. * * Passing an `id` is optional. When passed, it is added to the wrapping HTML element as `data-cke-ai-id` attribute, * allowing to query it later with native DOM methods. * * This method allows adding custom text replies to the AI chat feed. You can pass plain text or Markdown-formatted text * as the `content` parameter. Markdown is automatically converted to proper HTML formatting when rendered in the chat feed. * * Note, that the text reply is **not** immediately inserted into the UI when this method is called. Insertions are queued * to ensure the reply is rendered after currently processed content. * * Note also, that the content of the reply is visually streamed in the chat feed (word by word), * so it will appear gradually. */ insertTextReply: (content: string, id?: string) => ReturnType; /** * Inserts a custom element into the AI chat feed. The element can be provided as a HTML string or as a `HTMLElement`. * * Passing an `id` is optional. When passed, it is added to the wrapping HTML element as `data-cke-ai-id` attribute, * allowing to query it later with native DOM methods. * * Note, that the element is **not** immediately inserted into the UI when this method is called. Insertions are queued * to ensure the element is rendered after currently processed content. * * Returns a promise which is resolved after the element is finally attached to the DOM. You can use this promise to further * manage the displayed content, for example, fetch asynchronous data and display it inside the inserted element. */ insertCustomElement: (element: string | HTMLElement, id?: string) => Promise; /** * Sets the currently displayed AI chat loading message. */ setLoadingMessage: (message: string) => void; /** * Clears the currently displayed AI chat loading message. No text will be shown. */ clearLoadingMessage: () => void; } /** * A callback type for handling custom AI tools data. * * This callback receives two parameters: * * * `toolData` - data returned by the AI tool. * * `api` - set of tools which you can use to reflect the received AI tool data in the AI chat feed. */ export type AIToolEventCallback = (toolData: AIToolData, api: AIChatFeedAPI) => void | Promise; /** * An event emitted by `AIChatController` when an AI reply is created. * * @eventName ~AIChatController#replyCreated */ export type AIChatControllerAIReplyCreatedEvent = AIInteractionReplyCreatedEvent; /** * An event emitted by `AIChatController` when an AI chat interaction is created. * * @eventName ~AIChatController#interactionCreated */ export type AIChatControllerAIInteractionCreatedEvent = AIChatInteractionCreatedEvent;