Skip to content

Commit 3af5409

Browse files
committed
fix
1 parent 3ddd72e commit 3af5409

3 files changed

Lines changed: 59 additions & 4 deletions

File tree

apps/www/src/registry/default/components/editor/plugins/ai-plugins.tsx

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
import React from 'react';
44

5-
import { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';
5+
import type { AIChatPluginConfig } from '@udecode/plate-ai/react';
6+
7+
import { PathApi } from '@udecode/plate';
8+
import { streamInsertChunk, withAIBatch } from '@udecode/plate-ai';
9+
import { AIChatPlugin, AIPlugin, useChatChunk } from '@udecode/plate-ai/react';
10+
import { useEditorPlugin, usePluginOption } from '@udecode/plate/react';
611

712
import { markdownPlugin } from '@/registry/default/components/editor/plugins/markdown-plugin';
813
import { AILoadingBar } from '@/registry/default/plate-ui/ai-loading-bar';
914
import { AIMenu } from '@/registry/default/plate-ui/ai-menu';
1015

1116
import { cursorOverlayPlugin } from './cursor-overlay-plugin';
17+
1218
const systemCommon = `\
1319
You are an advanced AI-powered note-taking assistant, designed to enhance productivity and creativity in note management.
1420
Respond directly to user prompts with clear, concise, and relevant content. Maintain a neutral, helpful tone.
@@ -113,5 +119,55 @@ export const aiPlugins = [
113119
afterContainer: () => <AILoadingBar />,
114120
afterEditable: () => <AIMenu />,
115121
},
122+
}).extend({
123+
useHooks: () => {
124+
const { editor, getOption } = useEditorPlugin(AIChatPlugin);
125+
126+
const mode = usePluginOption(
127+
{ key: 'aiChat' } as AIChatPluginConfig,
128+
'mode'
129+
);
130+
131+
useChatChunk({
132+
onChunk: ({ chunk, isFirst, nodes, text }) => {
133+
if (isFirst && mode == 'insert') {
134+
editor.tf.withoutSaving(() => {
135+
editor.tf.insertNodes(
136+
{
137+
children: [{ text: '' }],
138+
type: AIChatPlugin.key,
139+
},
140+
{
141+
at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),
142+
}
143+
);
144+
});
145+
editor.setOption(AIChatPlugin, 'streaming', true);
146+
}
147+
148+
if (mode === 'insert' && nodes.length > 0) {
149+
withAIBatch(
150+
editor,
151+
() => {
152+
if (!getOption('streaming')) return;
153+
editor.tf.withScrolling(() => {
154+
streamInsertChunk(editor, chunk, {
155+
textProps: {
156+
ai: true,
157+
},
158+
});
159+
});
160+
},
161+
{ split: isFirst }
162+
);
163+
}
164+
},
165+
onFinish: ({ content }) => {
166+
editor.setOption(AIChatPlugin, 'streaming', false);
167+
editor.setOption(AIChatPlugin, '_blockChunks', '');
168+
editor.setOption(AIChatPlugin, '_blockPath', null);
169+
},
170+
});
171+
},
116172
}),
117173
] as const;

packages/ai/src/react/ai-chat/AIChatPlugin.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,9 @@ export const AIChatPlugin = createTPlatePlugin<AIChatPluginConfig>({
108108
promptTemplate: () => '{prompt}',
109109
systemTemplate: () => {},
110110
},
111+
useHooks: useAIChatHooks,
111112
})
112113
.overrideEditor(withAIChat)
113-
.extend(() => ({
114-
useHooks: useAIChatHooks,
115-
}))
116114
.extendApi<
117115
Pick<
118116
AIChatPluginConfig['api']['aiChat'],

packages/ai/src/react/ai-chat/useAIChatHook.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { streamInsertChunk, withAIBatch } from '../../lib';
55
import { type AIChatPluginConfig, AIChatPlugin } from './AIChatPlugin';
66
import { useChatChunk } from './hooks/useChatChunk';
77

8+
/** @deprecated Already moved to registry ai-plugins.tsx */
89
export const useAIChatHooks = () => {
910
const { editor, getOption } = useEditorPlugin(AIChatPlugin);
1011

0 commit comments

Comments
 (0)