Display suggestions

Suggestions are used to display the changes that the AI agent has made to the document.

If you're new to suggestions, we recommend you start with the following guides:

This page contains the API reference of all AI Toolkit methods related to suggestions.

The Suggestion object

A Suggestion represents a proposed change to a range of content in the editor, typically generated by an AI agent. It allows previewing, reviewing, and applying changes, and can include multiple replacement options.

Properties

  • id (string): A unique identifier for the suggestion.
  • range (Range): The range of content in the editor that the suggestion applies to.
  • rangeInOtherDoc? (Range): If this Suggestion was created by comparing this document with another, this property contains the range of the Change in the other document.
  • replacementOptions (ReplacementOption[]): One or more possible replacements for the selected range. The user can choose which option to apply. Each ReplacementOption has the following properties:
    • id (string): Unique identifier for this replacement option.
    • content (string | Slice): The replacement content. Can be a ProseMirror Slice for structured content with formatting, or a plain string for text-only replacements.
    • metadata? (Record<string, any>): Optional extra metadata for this replacement option (e.g., source, category).
  • displayOptions? (DisplayOptions): Optional display options to control how the suggestion is rendered in the editor UI.
    • showReplacement? (boolean): Whether to show replacement content as a diff. Default: true
    • hideCurrentContent? (boolean): Hide the current content in the diff widget. Default: false
    • showSubChanges? (boolean): Show sub-changes when an inline group is displayed. Default: true
    • attributes? (Record<string, any>): Extra HTML attributes to be added to the suggestion
    • replacementAttributes? (Record<string, any>): Extra HTML attributes for the replacement decoration
    • subChangeAttributes? (Record<string, any>): Extra HTML attributes for inline sub-change highlights
    • replacementSubChangeAttributes? (Record<string, any>): Extra HTML attributes for sub-change highlights inside replacement content
    • renderDecorations? (RenderDecorations): A function to render the suggestion as ProseMirror decorations
  • reviewMode? ('preview' | 'review'): The review mode of the suggestion. 'preview' indicates the suggestion is a preview of a change before applying (default). 'review' indicates the suggestion reviews a change that has already been made, allowing the user to undo it by applying the suggestion. This field is automatically set based on reviewOptions.mode when suggestions are created.
  • isInlineGroup? (boolean): Whether this suggestion represents grouped inline changes.
  • metadata? (Record<string, any>): Optional extra metadata for the suggestion. This can be used to store additional information such as the source, category, or any custom data. It is not used internally by the extension but can help customize UI rendering.

Style suggestions

Learn more about how to customize the appearance of suggestions with the Style suggestions guide.

getSuggestions

Returns all current suggestions.

Returns (Suggestion[])

  • Suggestion[]: The list of active suggestions.

Example

// Get all active suggestions
const suggestions = toolkit.getSuggestions()

getSelectedSuggestion

Returns the currently selected suggestion.

A suggestion is considered "selected" when the cursor (editor.state.selection.head) is over it.

Returns (Suggestion | null)

  • Suggestion | null: The currently selected suggestion, or null if no suggestion is selected.

Example

// Get the currently selected suggestion
const selectedSuggestion = toolkit.getSelectedSuggestion()

setSuggestions / addSuggestions

Replace or append suggestions.

setSuggestions replaces all current suggestions. addSuggestions appends new suggestions to the existing list.

Parameters

  • suggestions (Suggestion[]): A list of suggestions to display.

If two suggestions have overlapping ranges, only the first suggestion in the list will be displayed. The second suggestion will be ignored. Suggestions cannot have overlapping ranges because of a limitation in ProseMirror's decoration rendering engine.

Returns

void

Example

// Set suggestions
toolkit.setSuggestions([
  {
    id: 'suggestion-1',
    range: { from: 0, to: 5 },
    replacementOptions: [{ id: '1', content: 'Improved text' }],
  },
])

// Clear all suggestions
toolkit.setSuggestions([])

setSuggestionsFromDiff

Sets suggestions by comparing the current editor document with another document. Differences between the two documents are automatically converted into suggestions.

Parameters

  • options (SetSuggestionsFromDiffOptions): Configuration for the document comparison
    • doc (Node): The document to compare against the current editor document
    • reviewOptions? (ReviewOptions): Options that control how the suggestions are reviewed and displayed. See available options.

Schema issue

The doc parameter must have the same schema as the current document. If doc comes from a different editor, convert it to the target editor schema: doc: Node.fromJSON(editor.state.schema, otherEditor.getJSON())

Returns

void

Example

// Compare documents and show differences as suggestions
toolkit.setSuggestionsFromDiff({
  doc: otherDocument,
  reviewOptions: { mode: 'review' },
})

acceptSuggestion

Accepts a specific suggestion.

Parameters

  • suggestionId (string): The suggestion to accept
  • options? (AcceptSuggestionOptions): Options for the acceptSuggestion method
    • replacementOptionId? (string): The ID of the replacement option to apply. If not provided, the first replacement option will be applied

Returns

AcceptSuggestionResult

Returns an object containing:

  • aiFeedback ({ events: SuggestionFeedbackEvent[] }): AI feedback containing events for the accepted suggestion. Each event contains:
    • delete (string): HTML content that was deleted (or would be deleted)
    • insert (string): HTML content or text that was inserted (or would be inserted)
    • accepted (boolean): Whether the suggestion was accepted by the user (true) or rejected (false)

This feedback can be used to inform the AI about what changes were accepted or rejected by the user.

Example

// Accept a suggestion by id and get feedback
const result = toolkit.acceptSuggestion('suggestion-1')
result.aiFeedback.events

acceptAllSuggestions

Accepts all active suggestions at once.

This method accepts all suggestions by replacing the content at each suggestion's range with the first replacement option. After accepting all suggestions, the list of active suggestions is cleared.

Parameters

None

Returns

AcceptAllSuggestionsResult

Returns an object containing:

  • aiFeedback ({ events: SuggestionFeedbackEvent[] }): AI feedback containing events for all accepted suggestions. Each event contains:
    • delete (string): HTML content that was deleted (or would be deleted)
    • insert (string): HTML content or text that was inserted (or would be inserted)
    • accepted (boolean): Whether the suggestion was accepted by the user (true) or rejected (false)

This feedback can be used to inform the AI about what changes were accepted by the user.

Example

// Accept all suggestions at once and get feedback
const result = toolkit.acceptAllSuggestions()
result.aiFeedback.events

rejectSuggestion

Rejects a specific suggestion without applying it.

This method removes a suggestion from the active suggestions list without applying it to the document. It returns feedback about what was rejected.

Parameters

  • suggestionId (string): The suggestion to reject

Returns

RejectSuggestionResult

Returns an object containing:

  • aiFeedback ({ events: SuggestionFeedbackEvent[] }): AI feedback containing events for the rejected suggestion. Each event contains:
    • delete (string): HTML content that was deleted (or would be deleted)
    • insert (string): HTML content or text that was inserted (or would be inserted)
    • accepted (boolean): Whether the suggestion was accepted by the user (true) or rejected (false)

This feedback can be used to inform the AI about what changes were rejected by the user.

Example

// Reject a suggestion by id and get feedback
const result = toolkit.rejectSuggestion('suggestion-1')
result.aiFeedback.events

rejectAllSuggestions

Rejects all active suggestions without applying them.

This method removes all suggestions from the active suggestions list without applying them to the document. It returns feedback about what was rejected.

Parameters

None

Returns

RejectAllSuggestionsResult

Returns an object containing:

  • aiFeedback ({ events: SuggestionFeedbackEvent[] }): AI feedback containing events for all rejected suggestions. Each event contains:
    • delete (string): HTML content that was deleted (or would be deleted)
    • insert (string): HTML content or text that was inserted (or would be inserted)
    • accepted (boolean): Whether the suggestion was accepted by the user (true) or rejected (false)

This feedback can be used to inform the AI about what changes were rejected by the user.

Example

// Reject all suggestions and get feedback
const result = toolkit.rejectAllSuggestions()
result.aiFeedback.events

removeSuggestion

Removes a specific suggestion.

Parameters

  • suggestionId (string)

Returns

void

Example

// Remove a suggestion by id
toolkit.removeSuggestion('suggestion-1')

setMarkdownSuggestions

Loads AI-powered suggestions by comparing corrected Markdown with the current document content.

Markdown extension required

This method requires the Tiptap Markdown extension to be installed and configured.

This method supports two input formats:

  1. Full document format: Provide the corrected Markdown and let the toolkit compute the differences automatically
  2. Changes format: Provide an array of specific text replacements (delete/insert pairs)

The method uses a diff-based approach to identify changes and creates suggestions at the appropriate document positions.

Parameters

  • options (SetMarkdownSuggestionsOptions): Configuration options
    • content? (string): The corrected Markdown content from your AI provider. Use this for the full document format. Cannot be used together with changes.
    • changes? (TextChange[]): Array of text changes in the format { delete: string, insert: string }. Each change specifies text to delete and its replacement. Cannot be used together with content.
    • range? (Range): Optional range to limit suggestions to a specific portion of the document. The from value is inclusive and to is exclusive ([from, to)). Values represent absolute document positions (starting from 0 at the beginning of the document), using character offsets (not node positions). If not provided, the entire document will be processed.
    • reviewOptions? (ReviewOptions): Control preview/review behavior. See available options.

Changes format behavior

When using the changes format, ALL occurrences of each delete text will be replaced with the corresponding insert text throughout the specified range. If you need position-specific replacements, use the full document format instead.

Returns

SetMarkdownSuggestionsResult

Returns an object containing:

  • suggestions (Suggestion[]): The array of generated suggestions

Examples

Full document format with API integration

const toolkit = getAiToolkit(editor)

// Get corrected Markdown from your AI API
const response = await fetch('/api/grammar-check', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ markdown: editor.getMarkdown() }),
})
const { correctedMarkdown } = await response.json()

// Set suggestions using the corrected Markdown
const result = toolkit.setMarkdownSuggestions({
  content: correctedMarkdown,
})

console.log(`Generated ${result.suggestions.length} suggestions`)

Full document format with range parameter

const toolkit = getAiToolkit(editor)

// Only process a specific range of the document
toolkit.setMarkdownSuggestions({
  content: '# Corrected heading\n\nCorrected paragraph content',
  range: { from: 0, to: 100 },
})

Changes format with single change

const toolkit = getAiToolkit(editor)

// Capitalize all occurrences of 'api' to 'API'
toolkit.setMarkdownSuggestions({
  changes: [{ delete: 'api', insert: 'API' }],
})

Changes format with multiple changes

const toolkit = getAiToolkit(editor)

// Apply multiple text corrections at once
toolkit.setMarkdownSuggestions({
  changes: [
    { delete: 'javascript', insert: 'JavaScript' },
    { delete: 'typescript', insert: 'TypeScript' },
    { delete: 'api', insert: 'API' },
  ],
  range: { from: 0, to: 500 },
})

invertSuggestions

Applies all current suggestions to a copy of the document and returns the resulting document along with inverted suggestions that would undo those changes. This is a dry-run operation — the editor document is not modified.

For each original suggestion, the replacement is applied to produce the new document and an inverted suggestion is created. Accepting the inverted suggestion on the new document would revert the change. Preview mode suggestions become review mode in the inverted result, and vice versa. Each inverted suggestion preserves the id, metadata, and display options of the original.

Parameters

  • options? (InvertSuggestionsOptions): Optional configuration
    • schema? (Schema): A target ProseMirror schema. When provided, the returned document and all suggestion replacement slices are translated to this schema. This is useful when the inverted result will be used in an editor whose schema differs from the current one.

Returns

InvertSuggestionsResult

Returns an object containing:

  • doc (Node): The document after applying all suggestions. This document is not applied to the editor.
  • suggestions (Suggestion[]): Inverted suggestions that would undo the applied changes when set on the returned document.

Example

const toolkit = getAiToolkit(editor)

// Get the inverted result without modifying the editor
const { doc, suggestions } = toolkit.invertSuggestions()

// Translate the result to a different editor's schema
const { doc, suggestions } = toolkit.invertSuggestions({ schema: otherEditor.schema })