AI
Quick Ask
Turn on Quick Ask, the AI button in the VitNode rich text editor that shortens, corrects, simplifies, changes the tone of or continues the selected text, and learn how it limits context, cost and markup.
Quick Ask is the Quick Ask (AI) button in the toolbar of VitNode's rich text editor. It rewrites the selected text or writes more of it, streams the answer into a preview, and changes nothing until the editor applies it. It is built into Core and switched off for everyone except root roles until an admin allows it.
Before you begin
- A language model with the
textandstreamingcapabilities inai.models. Quick Ask always streams, so without astreamingmodel it fails withAI_MODEL_INCOMPATIBLE. See AI setup. - A model with
pricingif the roles you allow have a points allowance. See Model pricing. - An admin with
ai:can_manageto change a role's AI access.
Turn on Quick Ask for a role
Allow the editor.assist permission
Open Users ā Roles, edit the role and switch to the Artificial intelligence (AI) tab. Find the row with Rewrite selected text and Quick Ask and set it to Allow. Both actions share the permission @vitnode/core:editor.assist, which has defaultGranted: false.
Give the role AI points
On the same tab, give the role a monthly points allowance or Unlimited points. The default allowance is 0, so a member of an allowed role without points gets AI_USER_LIMIT_REACHED. Save the role.
Check the result
Sign in with a member of that role and open any form with a rich text field, such as an article in the AdminCP. The toolbar shows Quick Ask (AI). Select a sentence, open Quick Ask and choose Shorten. The shorter text streams into a preview with Replace selection and Insert below. The run appears in Debug Panel ā AI logs as @vitnode/core:editor.selection.rewrite.
What it can do
| Operation | Action key | Does |
|---|---|---|
| Shorten | @vitnode/core:editor.selection.rewrite | Tighter text, same meaning. |
| Correct writing | @vitnode/core:editor.selection.rewrite | Spelling, grammar and punctuation only. |
| Simplify | @vitnode/core:editor.selection.rewrite | Simpler words, shorter sentences. |
| Change the tone | @vitnode/core:editor.selection.rewrite | Friendly, formal, confident or neutral. |
| Continue writing | @vitnode/core:editor.quick-ask | One or two paragraphs from where the text ends. |
| Ask anything | @vitnode/core:editor.quick-ask | A custom request about the selection (max 500 characters). |
An admin can switch either action off, or give it its own model, on Artificial Intelligence (AI) ā Actions.
How it behaves
- Bounded context. It sends the selection (up to 8,000 characters) and up to 1,500 characters before and after it, never the whole document.
- Cost shown first. With a selection, the panel shows the reservation bound, not a price: "One request costs at most N AI points - usually much less."
- Stop is cheap. Stop cancels the stream. Stopping before any text arrives charges nothing; stopping after text has streamed in counts as a run.
- Plain text only. The answer becomes paragraphs and hard breaks. The editor never parses it as HTML, so it cannot inject markup, links or scripts.
- Stale selection. If the selected text changed while the answer was written, Replace selection is disabled and Insert below still works.
- One-step undo. Applying is one editor transaction. The toast's Undo or Ctrl+Z restores the text exactly.
- Nothing is saved until you save the form.
- Content language. It writes in the language of the field being edited (the multi-language tab), not the interface language.
Quick Ask calls Core's AdminCP stream routes on /admin pages and the member routes everywhere else. See Streaming.
Build your own editor tool
Your own Tiptap tools can reuse the same pieces:
streamAiAction()andestimateAiAction()from@vitnode/core/lib/ai/stream-clientrun and price a text action. See Streaming.- From
@vitnode/core/components/tiptap/quick-ask/quick-ask-editor:takeQuickAskSnapshot(editor)captures the selection with its context ({ before, selection, after, from, to }),isQuickAskStale(editor, snapshot)tells whether the selection changed since, andapplyQuickAskResult(editor, { from, to, mode, text })inserts the answer as one undoable transaction, withmode"replace"or"below".
import { streamAiAction } from '@vitnode/core/lib/ai/stream-client'
await streamAiAction({
action: '@vitnode/core:editor.selection.rewrite',
input: { after, before, locale, operation: 'shorten', selection },
onDelta: (delta) => setPreview((text) => text + delta),
scope: 'admin',
})before, selection and after come from takeQuickAskSnapshot(editor), locale is the content language being edited, and setPreview is your component's state setter.