AI 参考
AIExtension
使用 AIExtension 创建一个新的 AI 扩展,可以在调用 useCreateBlockNote 时注册到编辑器。
// 用法示例:
useCreateBlockNote({
// 注册 AI 扩展
extensions: [AIExtension(options)],
// 其他编辑器配置
});
type AIExtensionOptions = AIRequestHelpers & {
/**
* AI 正在写作时代理光标的名称和颜色
* @default { name: "AI", color: "#8bc6ff" }
*/
agentCursor?: { name: string; color: string };
};
type AIRequestHelpers = {
/**
* AI SDK 用于向您的后端/LLM 发送请求的传输方式。
* 实现此项可定制后端 URL 或使用不同的传输方式(例如 websockets)。
*/
transport?: ChatTransport<UIMessage>;
/**
* 使用 ChatProvider 自定义 AI SDK Chat 实例的创建方式。
* 例如,当您想重用应用程序中其他部分使用的现有 Chat 实例时。
*
* @note 不能同时使用 `chatProvider` 和 `transport`。
*/
chatProvider?: () => Chat<UIMessage>;
/**
* 自定义 LLM 可用的流工具。
*/
streamToolsProvider?: StreamToolsProvider<any, any>;
// 可在 AIExtension(options) 中提供 `streamToolsProvider`,或通过 InvokeAIOptions 在调用时覆盖。
// 如果省略,默认使用 `aiDocumentFormats.html.getStreamToolsProvider()`。
/**
* 转发给 AI SDK 请求的额外选项(headers/body/metadata)。
*/
chatRequestOptions?: ChatRequestOptions;
/**
* 构建可序列化的文档状态,将转发给后端。
*
* @default aiDocumentFormats.html.defaultDocumentStateBuilder
*/
documentStateBuilder?: DocumentStateBuilder<any>;
};AIExtension 扩展实例
通过 editor.getExtension(AIExtension) 获得的 AIExtension 扩展实例,暴露状态和方法,用于与 BlockNote 的 AI 功能交互。
type AIExtensionInstance = {
/**
* 调用 LLM 并将结果应用到编辑器
*/
invokeAI(opts: InvokeAIOptions): Promise<void>;
/**
* 返回一个只读的 Tanstack Store,包含 AI 菜单的状态
*/
get store(): Store<{
aiMenuState:
| ({
/**
* AI 菜单打开时所在块的 ID。
* 在 AI 修改文档时会发生变化
*/
blockId: string;
} & (
| {
status: "error";
error: any;
}
| {
status:
| "user-input"
| "thinking"
| "ai-writing"
| "user-reviewing";
}
))
| "closed";
}>;
/**
* 返回包含 AI 扩展全局配置的 Tanstack Store。
* 调用 {@link invokeAI} 时,默认使用这些配置。
*/
readonly options: Store<AIRequestHelpers>;
/** 在特定块打开 AI 菜单 */
openAIMenuAtBlock(blockID: string): void;
/** 关闭 AI 菜单 */
closeAIMenu(): void;
/** 接受 LLM 所做的更改 */
acceptChanges(): void;
/** 拒绝 LLM 所做的更改 */
rejectChanges(): void;
/** 重试上一次 LLM 调用(仅当状态为 "error" 时有效) */
retry(): Promise<void>;
/** 中止当前的 LLM 请求 */
abort(reason?: any): Promise<void>;
/** 高级用法:手动更新 AI 菜单显示的状态 */
setAIResponseStatus(
status:
| "user-input"
| "thinking"
| "ai-writing"
| "user-reviewing"
| { status: "error"; error: any },
): void;
};InvokeAI
通过调用 AIExtension 实例的 invokeAI 发起对 LLM 的请求。该方法接受一个 InvokeAIOptions 对象作为参数。
type InvokeAIOptions = {
/** 用户提示 */
userPrompt: string;
/** 是否使用编辑器选区作为 LLM 调用内容(默认:true) */
useSelection?: boolean;
/**
* 如果用户光标处在一个空段落,当 AI 开始写作时自动删除该段落。
* 用于在空块中输入 `/ai` 时。(默认:true)
*/
deleteEmptyCursorBlock?: boolean;
} & AIRequestHelpers; // 可在每次调用时覆盖助手选项因为 InvokeAIOptions 继承自 AIRequestHelpers,您可以在每次调用时单独覆盖这些选项,而不改变全局的扩展配置。
getStreamToolsProvider
调用 LLM 时,需要解析文档并调用操作以修改文档。使用格式的 getStreamToolsProvider 获取 LLM 编辑时可能调用的工具。通常使用 aiDocumentFormats.html.getStreamToolsProvider(...)。
/** 返回供 LLM 使用的流工具提供者 */
type getStreamToolsProvider = (
// 是否在文档编辑间添加人工延迟
// 或者直接按 LLM 流式传入的数据立即应用,无延迟
// (默认:true)
withDelays: boolean,
// 使用的流工具,分别用于添加、更新和删除块
// (默认:{ add: true, update: true, delete: true })
defaultStreamTools?: {
add?: boolean;
update?: boolean;
delete?: boolean;
},
) => StreamToolsProvider;文档状态构建器(高级)
当 BlockNote AI 发送请求时,也会转发编辑器的序列化快照。LLM 使用该文档状态来理解文档、光标位置和选区。DocumentStateBuilder 类型定义了该快照的生成方式:
type DocumentStateBuilder<T> = (
aiRequest: Omit<AIRequest, "documentState">,
) => Promise<
| {
selection: false;
blocks: BlocksWithCursor<T>[];
isEmptyDocument: boolean;
}
| {
selection: true;
selectedBlocks: { id: string; block: T }[];
blocks: { block: T }[];
isEmptyDocument: boolean;
}
>;默认使用 aiDocumentFormats.html.defaultDocumentStateBuilder。
AIRequest(高级)
buildAIRequest 返回执行 AI 调用所需的所有内容:
type AIRequest = {
editor: BlockNoteEditor;
selectedBlocks?: Block[];
emptyCursorBlockToDelete?: string;
streamTools: StreamTool<any>[];
documentState: DocumentState<any>;
onStart: () => void;
};sendMessageWithAIRequest(高级)
需要手动调用 LLM 且不更新 BlockNote AI 菜单状态时,使用 sendMessageWithAIRequest。
例如,从不同上下文(如聊天窗口)提交 LLM 请求时。
sendMessageWithAIRequest 类似于 chat.sendMessages,但它会将 documentState 附加到发出的消息元数据中,配置工具流式传输,并将工具定义(JSON Schema)转发到后端。
async function sendMessageWithAIRequest(
chat: Chat<UIMessage>,
aiRequest: AIRequest,
message?: Parameters<Chat<UIMessage>["sendMessage"]>[0],
options?: Parameters<Chat<UIMessage>["sendMessage"]>[1],
): Promise<Result<void>>;buildAIRequest(高级)
如果绕过 invokeAI 直接调用 sendMessageWithAIRequest,使用 buildAIRequest 从编辑器状态组装 AIRequest。
async function buildAIRequest(opts: {
editor: BlockNoteEditor;
useSelection?: boolean;
deleteEmptyCursorBlock?: boolean;
streamToolsProvider?: StreamToolsProvider<any, any>;
documentStateBuilder?: DocumentStateBuilder<any>;
onBlockUpdated?: (blockId: string) => void;
onStart?: () => void;
}): Promise<AIRequest>;