AI Caret

The AiCaret extension displays a cursor decoration at the position where the AI is currently inserting content. It provides real-time visual feedback during streaming operations, similar to the Collaboration Caret extension.

Usage

Import the AiCaret extension from @tiptap-pro/ai-toolkit and add it to your editor extensions.

import { AiCaret, AiToolkit } from '@tiptap-pro/ai-toolkit'

const editor = useEditor({
  extensions: [StarterKit, AiToolkit, AiCaret],
})

The caret appears automatically during streaming operations like streamHtml, streamTool, and tiptapEditWorkflow. It disappears after the streaming finishes.

Configuration

You can configure the caret's timeout, user label, and rendering.

AiCaret.configure({
  // How long the caret stays visible after the last update (ms)
  timeout: 2000,
  // User details for the caret label
  user: {
    name: 'AI',
    color: '#a5b4fc',
  },
})

Options

OptionTypeDefaultDescription
timeoutnumber2000How long the caret stays visible after the last update (ms).
user{ name: string, color: string }{ name: 'AI', color: '#a5b4fc' }The name and color displayed on the caret label.
render(user: AiCaretUser) => HTMLElementBuilt-in render functionCustom function to render the caret DOM element.

CSS styles

The default render function creates a DOM element with the class tiptap-ai-caret and a label with the class tiptap-ai-caret__label. Add the following CSS to style the caret:

.tiptap .tiptap-ai-caret {
  border-left: 1px solid #0d0d0d;
  border-right: 1px solid #0d0d0d;
  margin-left: -1px;
  margin-right: -1px;
  pointer-events: none;
  position: relative;
  word-break: normal;
}

.tiptap .tiptap-ai-caret__label {
  border-radius: 3px 3px 3px 0;
  color: #0d0d0d;
  font-size: 12px;
  font-style: normal;
  font-weight: 600;
  left: -1px;
  line-height: normal;
  padding: 0.1rem 0.3rem;
  position: absolute;
  top: -1.4em;
  user-select: none;
  white-space: nowrap;
}

The border-color and background-color of the caret and label are set inline based on the user.color option.

Custom rendering

You can provide a custom render function to fully control the caret DOM element.

AiCaret.configure({
  render: (user) => {
    const el = document.createElement('span')
    el.className = 'my-custom-ai-caret'
    el.style.borderColor = user.color
    el.textContent = user.name
    return el
  },
})