Text Editor - AI Improve Plugin
Improve selected text using Claude AI with real-time streaming.
#Usage
import { TextEditor } from '@primeui/vue-texteditor';
import { aiImprovePlugin } from './ai-improve-plugin';<TextEditor.Root v-model="value" :plugins="[aiImprovePlugin]">
<TextEditor.ContextToolbar>
<AIButton />
</TextEditor.ContextToolbar>
<TextEditor.Content />
</TextEditor.Root>The AI Improve plugin adds an improve command that rewrites the selected text for grammar, spelling, and clarity, streaming the result back into the selection. Pass aiImprovePlugin through the plugins prop, then call pluginCommands.aiImprove?.improve() from a toolbar widget. The plugin owns the model request and streaming; the editor owns the selection it replaces.
#Overview
The plugin rewrites the selected text through the Anthropic Claude API. The response streams token-by-token over Server-Sent Events, so the selection is replaced incrementally as the model generates output.
#Plugin Definition
import { defineTextEditorPlugin } from '@primeui/vue-texteditor';
export interface AIImproveOptions {
model?: string;
}
export const aiImprovePlugin = defineTextEditorPlugin<AIImproveOptions>('aiImprove', ({ getSelectedText, replaceSelection, options }) => {
const model = options?.model ?? 'claude-haiku-4-5-20251001';
return {
commands: {
improve: async () => {
const text = getSelectedText();
if (!text) return;
const response = await fetch('/api/ai-improve', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text, model })
});
if (!response.ok || !response.body) return;
// Clear the selection; the cursor is now at the insertion point
replaceSelection('');
// Parse SSE stream and insert chunks as they arrive
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() ?? '';
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const data = line.slice(6);
if (data === '[DONE]') break;
try {
const event = JSON.parse(data);
if (event.type === 'content_block_delta' && event.delta?.text) {
replaceSelection(event.delta.text);
}
} catch {
// skip non-JSON lines
}
}
}
}
}
};
});#Options
| Option | Type | Default | Description |
|---|---|---|---|
model | string | 'claude-haiku-4-5-20251001' | Claude model to use |
#Commands
| Command | Signature | Description |
|---|---|---|
improve | () => Promise<void> | Improves selected text using Claude AI with streaming |
#Example
Select text in the editor to open the ContextToolbar, then click the AI button.
Live demo, rate limited. The button may be inactive once the limit is hit.
Loading Demo...