/** * @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/aicore/model/aireply * @publicApi */ import { type Locale, type ObservableMixinConstructor } from "@ckeditor/ckeditor5-utils"; import { Element, type Document } from "../utils/htmlparser.js"; import { type Editor } from "@ckeditor/ckeditor5-core"; import { type AISuggestionContentPartDefinition } from "../utils/getsuggestionpartsfromreply.js"; import type { AISource } from "../aiconnector.js"; declare const _AIReplyBase: ObservableMixinConstructor; /** * The type of the reply. It can be one of the following: * * * `modification`: A content change suggestion made by the AI endpoint. * * `text`: A generic text response. */ export type AIReplyType = "modification" | "text"; /** * Represents a single reply from the AI endpoint. * * A reply's {@link #content} can be updated using the {@link #appendContent} method. */ export declare class AIReply extends _AIReplyBase { /** * The ID of the reply. */ readonly id: string; /** * The ID of the interaction that the reply belongs to. */ readonly interactionId: string; /** * The type of the reply. */ readonly type: AIReplyType; /** * The content of the reply as received from AI endpoint. It stores separate content for each document. */ content: Map; /** * The sources of the reply. Used for web search reply. */ sources: Array; /** * The parsed content of the reply. * * This property is automatically updated after reply {@link #content} changes. You can add a listener to `replyContentUpdated` event * in order to react to these changes. * * Note, that this property type is not DOM Document, but a simplified version provided by `domhandler` library. */ parsedContent: Map; /** * Whether the reply is done. The reply is done once the AI endpoint emitted the last chunk of the content * that matches the reply's type or the reply was interrupted (user stop, error, connection drop). * * See {@link #isComplete} for more information about the reply's completion state. * * @observable */ isDone: boolean; /** * Whether the reply finished organically, i.e. the stream ran out of chunks naturally. * * This is `false` while streaming, and also `false` if the reply was stopped or errored before the stream ended. * * See {@link #isDone} for more information. * * @observable */ isComplete: boolean; /** * @inheritDoc */ constructor({ type, isDone, isComplete, interactionId, areActionsDisabled, outdatedReasonByDocumentId, isFromHistory, documentContextContent, locale, id, channelsToEditors }: { type: AIReplyType; interactionId: string; channelsToEditors: Map; areActionsDisabled?: boolean; outdatedReasonByDocumentId?: ReadonlyMap; isFromHistory?: boolean; isDone?: boolean; isComplete?: boolean; documentContextContent?: Array<{ id?: string; content?: string; channelId: string; rootName?: string; }>; locale?: Locale; id?: string; }); /** * Appends new content to the reply. Text replies and any plain-text fragments default to the `'text'` bucket; * modification replies route by `documentId` to the per-document buckets in {@link #content}. */ appendContent(content: string, documentId?: string): void; /** * Destroys the reply. */ destroy(): void; } /** * An event emitted by an {@link module:ai/aicore/model/aireply~AIReply} when it's * {@link module:ai/aicore/model/aireply~AIReply#content} gets updated or the reply is marked as done. * * @eventName ~AIReply#replyContentUpdated */ export type AIReplyContentUpdatedEvent = { name: "replyContentUpdated"; args: [reply: AIReply, updatedChangeGroups?: Array]; }; export type AIReplyHotNode = { node: Element; id: string; type: AISuggestionContentPartDefinition["type"]; anchorId?: string | null; }; export type AIReplyChangeGroup = { readonly changes: Array; readonly documentId: string; readonly editor: Editor | undefined; readonly rootName: string; index: number; state: AIReplyChangeGroupState; outdatedReason?: AIReplyChangeGroupOutdatedReason; }; export type AIReplyChangeGroupState = "pending" | "accepted" | "rejected" | "outdated"; /** * The reason why a change group became {@link ~AIReplyChangeGroupState `'outdated'`}. It selects which * tooltip is shown on the "Outdated" pill. * * - `'content-removed'` - the targeted content was removed, or its root is no longer loaded. * - `'editor-removed'` - the target editor is gone or destroyed. * - `'session-changed'` - the suggestion was loaded from a previous session, so it can no longer be applied. */ export type AIReplyChangeGroupOutdatedReason = "content-removed" | "editor-removed" | "session-changed"; export {};