/** * @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/aigateway * @publicApi */ import { ContextPlugin, type PluginDependenciesOf, type Editor } from "@ckeditor/ckeditor5-core"; import { DocumentChanges } from "../aisdk/documentchanges.js"; import { AICore } from "./aicore.js"; import { type AIModels } from "./model/aimodels.js"; import { AIResponseApplier } from "./pipeline/airesponseapplier.js"; import { type AIEditorRoot } from "./model/aieditorroot.js"; import { type AIOperationSource } from "./utils/markoperationsasai.js"; import type { AIRunResult } from "./model/airunresult.js"; import { type AIContextRef } from "./model/aicontextref.js"; /** * How AI run changes are applied to the editor when using {@link module:ai/aicore/aigateway~AIGateway#apply}. */ export type AIRunApplyMethod = "suggest" | "insert"; /** * A single AI suggestion. * * The suggestion refers to a single block element modified by AI. The `id` is a unique identifier of the modified element. It is the same * as `data-id` attribute for this element in the initial content. The `content` is the HTML content of the modified * block element with all AI changes applied. */ export type AIRunChangeData = { id: string; content: string; }; /** * Base options for running an AI operation via various available gateways. */ export type AIRunBaseOptions = { /** * An `AbortSignal` that cancels the run when aborted. Aborted runs resolve with `status: 'aborted'`. */ signal?: AbortSignal; /** * Context references attached to the request. * * @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. */ contexts?: Array; }; export type AIGatewayApplyOptions = { /** * How AI run changes are applied to the editor content. * * With `'insert'` the changes are written directly into the editor content. With `'suggest'` they are wrapped as * track-changes suggestions — this requires the `TrackChanges` plugin to be loaded on the editor. */ applyMethod: AIRunApplyMethod; /** * AI source identifier stamped on every operation produced for this run. * * Defaults to `'api'`. * * Note that when `applyMethod` is `'suggest'`, every created suggestion also receives the `@ai` * {@link module:track-changes/suggestion~Suggestion#attributes attribute} with the same identifier. The track changes * plugin uses this attribute to display the suggestion as AI-generated. */ aiSource?: AIOperationSource; /** * Restrict the apply to a subset of the result's per-root entries. Each entry's `channelId` and `rootName` must match * a per-root sub-result in the passed `AIRunResult`. When omitted, every entry in `result.results` is applied. */ roots?: Array; }; /** * Base plugin exposing common methods for end-to-end public AI API. */ export declare class AIGateway extends ContextPlugin { /** * @inheritDoc */ static get pluginName(): "AIGateway"; /** * @inheritDoc */ static get requires(): PluginDependenciesOf<[DocumentChanges, AICore]>; /** * The shared model registry. Exposed here so headless gateways are self-sufficient — integrators can * discover and resolve models (`getAvailableModels()`, `getModel()`, `resolveModel()`, …) without * reaching for the `AICore` plugin directly. * * @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. */ get models(): AIModels; /** * @inheritDoc */ static override get isOfficialPlugin(): true; /** * @inheritDoc */ static override get isPremiumPlugin(): true; /** * Applies an AI run result to editor content. Accepts the whole `AIRunResult` — per-root sub-results targeting * the same editor are batched into one `model.change()` block, so all of that editor's roots become a single * undoable step. An optional `options.roots` filter restricts the apply to a subset of the sub-results without the * caller having to unpack or repack the result. * * Refuses the call up front only on whole-run failures (`result.error` set or empty `result.results`). Per-root * failures on an otherwise successful run are validated after the filter, so the caller can filter around the * failed roots via `options.roots` and still apply the completed ones. If any *included* sub-result fails * validation the whole call throws before touching any editor, so partial applies can't leave content in a * mixed state. * * `options.roots` is validated at the call boundary — an explicitly empty array throws * `ai-gateway-apply-empty-roots`, and any entry that does not match a per-root sub-result in * `result.results` throws `ai-gateway-apply-root-not-found`. * * Also throws `ai-gateway-apply-invalid-status` when the whole run failed or when any included sub-result's * `status` is not `'completed'`, and `ai-no-track-changes` when `options.applyMethod` is `'suggest'` and any * targeted editor is missing the `TrackChanges` plugin. * * @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 result The result of a completed AI run. * @param options Additional options. */ apply(result: AIRunResult, options: AIGatewayApplyOptions): void; /** * Merges the AI changes with the original content, creating the final document content with all AI changes applied. * * @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. */ mergeChangesIntoContent(changes: ReadonlyArray, content: string, editor: Editor): ReturnType["parsedContent"]; }