Copilot

Render AI suggestions ghost text as you type.

Loading...
Files
components/copilot-demo.tsx
'use client';

import React from 'react';

import { Plate } from '@udecode/plate-common/react';

import { editorPlugins } from '@/components/editor/plugins/editor-plugins';
import { useCreateEditor } from '@/components/editor/use-create-editor';
import { copilotValue } from '@/components/values/copilot-value';
import { Editor, EditorContainer } from '@/components/plate-ui/editor';

import { copilotPlugins } from '../components/editor/plugins/copilot-plugins';

export default function CopilotDemo() {
  const editor = useCreateEditor({
    plugins: [...copilotPlugins, ...editorPlugins],
    value: copilotValue,
  });

  return (
    <Plate editor={editor}>
      <EditorContainer variant="demo">
        <Editor />
      </EditorContainer>
    </Plate>
  );
}

功能

  • 在输入时渲染 ghost text suggestions
  • 两种触发模式:
    • 快捷键 (Ctrl+Space). 再次按下以获取替代建议。
    • 防抖模式:在段落末尾自动触发
  • 使用 Tab 或逐词接受建议,使用 Cmd+→
  • 内置支持 Vercel AI SDK 完成 API

安装

npm install @udecode/plate-ai @udecode/plate-markdown

使用

import { CopilotPlugin } from '@udecode/plate-ai/react';
import {
  MarkdownPlugin,
  serializeMdNodes,
  stripMarkdown,
} from '@udecode/plate-markdown';
const plugins = [
  // ...otherPlugins,
  MarkdownPlugin.configure({ options: { indentList: true } }),
  CopilotPlugin.configure(({ api }) => ({
    options: {
    completeOptions: {
      api: '/api/your-api-endpoint',
      body: {
        system: `You are an advanced AI writing assistant, similar to VSCode Copilot but for general text. Your task is to predict and generate the next part of the text based on the given context.
 
Rules:
- Continue the text naturally up to the next punctuation mark (., ,, ;, :, ?, or !).
- Maintain style and tone. Don't repeat given text.
- For unclear context, provide the most likely continuation.
- Handle code snippets, lists, or structured text if needed.
- Don't include """ in your response.
- CRITICAL: Always end with a punctuation mark.
- CRITICAL: Avoid starting a new block. Do not use block formatting like >, #, 1., 2., -, etc. The suggestion should continue in the same block as the context.
- If no context is provided or you can't generate a continuation, return "0" without explanation.`,
      },
      onFinish: (_, completion) => {
        if (completion === '0') return;
 
        api.copilot.setBlockSuggestion({
          //stripMarkdownBlocks in plus GhostText
          text: stripMarkdown(completion),
        });
      },
    },
    debounceDelay: 500,
    getPrompt: ({ editor }) => {
      const contextEntry = getAncestorNode(editor);
 
      if (!contextEntry) return '';
 
      const prompt = serializeMdNodes([contextEntry[0] as TElement]);
 
      return `Continue the text up to the next punctuation mark:
"""
${prompt}
"""`;
    },
    renderGhostText: GhostText,
  },
}));

Tab 键处理

Copilot 插件使用 Tab 键接受建议。为了避免与其他使用 Tab 的插件(如 IndentPluginTabbablePlugin)发生冲突,确保 CopilotPlugin 在您的插件配置中位于它们之前。这使得 Copilot 在有建议时优先处理 Tab 键事件。

const plugins = [
  // ...otherPlugins,
  CopilotPlugin,
  // 将使用 Tab 的插件放在 Copilot 之后
  IndentPlugin,
  TabbablePlugin,
];

示例

Plate UI

请参阅上面的预览。

Plate Plus

键盘快捷键

KeyDescription
Ctrl + Space

触发建议。再次按下以获取替代建议。

Tab接受整个建议。
Cmd + →

接受建议的下一个单词。

Escape

取消当前建议。

Plugins

CopilotPlugin

Options

Collapse all

    自动触发 copilot 的条件。默认检查:

    • 上面的块不为空
    • 上面的块以空格结尾
    • 没有现有的建议

    AI 完成配置选项。请参阅 AI SDK useCompletion 参数

    防抖延迟。默认: 0

    从建议文本中提取下一个单词的函数。

    生成 AI 补全提示的函数。**默认:**使用祖先节点的 markdown 序列化

    渲染幽灵文本建议的组件。

    触发 copilot 的条件。默认检查:

    • 选择未展开
    • 选择在块末尾

API

editor.api.copilot.accept()

接受当前建议。

editor.api.copilot.acceptNextWord()

接受建议的下一个单词。

editor.api.copilot.reset()

重置插件状态:

  • 中止任何正在进行的 API 请求
  • 清除当前补全
  • 清除建议节点 ID 和文本

editor.api.copilot.setBlockSuggestion()

为块设置建议文本。

Parameters

Collapse all

editor.api.copilot.stop()

停止正在进行的建议请求:

  • 取消防抖触发调用
  • 中止当前 API 请求
  • 重置中止控制器

editor.api.copilot.triggerSuggestion()

触发新的建议请求。可以根据插件配置进行防抖。