AI Toolkit
Ask AI, AI Chat, vista previa en línea y un panel AI Review, todo construido sobre un único hook aiToolkitResolver, para que puedas usar hoy el resolver de demostración integrado y mañana cambiarlo por tu propio backend sin tocar la interfaz.
Resumen
El AI Toolkit añade al editor tres interfaces relacionadas:
- Ask AI: un cuadro de diálogo que se abre desde la barra de herramientas, con siete modos de un clic (revisar, reescribir, acortar, ampliar, resumir, traducir, justificar), un selector de alcance entre selección y documento, y una vista previa en línea antes de aplicar.
- AI Chat: un panel lateral acoplado para solicitudes de varios turnos. Tiene en cuenta el alcance, con prompts rápidos y acciones de copiar, aplicar, insertar y reemplazar en cada respuesta de la IA.
- AI Review: una cola persistente de sugerencias pendientes, aceptadas y rechazadas. Sincronización opcional con un registro en el servidor para revisar entre sesiones.
Las tres comparten el mismo hook aiToolkitResolver y el mismo contrato de operaciones, así que una sugerencia que se previsualiza en una interfaz se puede aceptar, rechazar o escalar en otra.
Modo de demostración. Sin ningún resolver configurado, el plugin incluye un defaultResolveAction determinista para que puedas ejecutar Ask AI, Chat y Review en local sin clave de API, sin llamadas de red y con una salida predecible.
Instalación
Carga la hoja de estilos y el script del AI Toolkit después del bundle principal del editor. De forma predeterminada, el plugin inyecta automáticamente al cargarse un botón Ask AI en los presets de barra de herramientas estándar default, basic, full y mobile.
<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
<link rel="stylesheet" href="/richtexteditor/plugins/aitoolkit.css" />
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/all_plugins.js"></script>
<!-- aitoolkit.js is bundled inside all_plugins.js.
Include it separately only if you are loading plugins piecemeal. -->
<div id="editor"></div>
<script>
var editor = new RichTextEditor("#editor", {
toolbar: "full",
aiToolkitPersistenceKey: "my-editor-ai"
});
</script>Configuración. El rte.js que descargaste tiene al principio un bloque RTE_DefaultConfig editable en texto plano: ábrelo y cambia los valores predeterminados de la IA (clave de persistencia, etiqueta, endpoint del resolver, etc.) junto con el resto de los ajustes del editor. No hace falta cargar ningún archivo de configuración aparte. aitoolkit.css debe estar presente siempre que se pueda mostrar el botón de IA (incluso con la barra de herramientas predeterminada), o el menú desplegable de IA tendrá un tamaño incorrecto. Para mantener la IA activada pero detener la inyección automática del botón, establece aiToolkitAutoToolbarButtons: false y luego añade aiassist solo a las barras de herramientas donde lo quieras.
var editor = new RichTextEditor("#editor", {
toolbar: "default",
aiToolkitAutoToolbarButtons: false
});Tres interfaces
Cuadro de diálogo que se abre desde la barra de herramientas. Paneles de origen y resultado, selector de modo, selector de alcance, vista previa de antes y después, plan de operaciones y botones de aplicar, reemplazar, insertar y rechazar.
Panel acoplado. Mensajes que tienen en cuenta el alcance, prompts rápidos, historial de mensajes y acciones de aplicar, insertar y reemplazar en cada respuesta.
Panel persistente. Cola de pendientes, aceptadas y rechazadas, controles por lotes y sincronización opcional con un registro remoto.
Modos integrados
Cada modo es una entrada { id, title, description } de config.aiToolkitDialogModes. Aparecen en la lista desplegable Action del cuadro de diálogo Ask AI y se pueden llamar con runQuickAction(id).
| id | Título | Comportamiento predeterminado |
|---|---|---|
proofread | Proofread | Normaliza los espacios, la puntuación y las mayúsculas conservando el significado. |
rewrite | Rewrite | Elimina las expresiones de relleno (very, really, in order to, due to the fact that) y ajusta la redacción. |
shorten | Shorten | Conserva el primer ~60% de las palabras, con un mínimo de 8. |
expand | Expand | Añade una frase de apoyo debajo del texto de origen. |
summarize | Summarize | Crea un resumen con viñetas a partir del primer ~45% de las palabras. |
translate | Translate | Genera un borrador etiquetado con el idioma; el idioma de destino se pasa como request.language. |
justify | Justify edit | Igual que rewrite, más un campo reason que explica el cambio. |
Son implementaciones simuladas y deterministas del resolver de demostración. En cuanto conectes aiToolkitResolver, tu función decide cómo se gestiona cada modo. También puedes registrar modos nuevos; consulta Acciones personalizadas.
El hook aiToolkitResolver
Este es el punto de extensión. El resolver recibe una solicitud estructurada y devuelve un resultado (o una Promise que se resuelve en uno). El editor se encarga de mostrarlo, previsualizarlo, revisarlo y aplicarlo.
var editor = new RichTextEditor("#editor", {
toolbar: "full",
aiToolkitResolver: async function (request) {
var reply = await fetch("/api/ai", {
method: "POST",
body: JSON.stringify({
mode: request.mode,
text: request.source,
language: request.language
})
}).then(function (r) { return r.json(); });
return {
result: reply.text, // string: the AI output
reason: reply.explanation, // string: why this change
operations: [{ // structured plan (optional)
type: "preview-suggestion",
text: reply.text,
reason: reply.explanation
}]
};
}
});Forma de la solicitud
| Campo | Tipo | Significado |
|---|---|---|
actionId | string | La acción que invocó el usuario (coincide con el id de una acción o un modo registrados). |
mode | string | Modo del cuadro de diálogo: proofread, rewrite, translate, etc. |
source | string | Texto sobre el que operar. El texto de la selección si existe; si no, el texto de todo el documento. |
prompt | string | Texto del prompt del usuario (para el modo de chat). |
language | string | Idioma de destino para el modo translate. Vacío en los demás. |
scope | string | "selection" o "document". |
selectionText | string | Texto de la selección (puede estar vacío). |
documentText | string | Texto de todo el documento. |
snapshot | object | Instantánea de la selección (hasSelection, rangeHTML, text, wholeText, ...). |
editor | RichTextEditor | La instancia del editor. |
contract | object | Lista completa de los tipos de operación admitidos (para validar). |
Forma de la respuesta
Devuelve un objeto simple con cualquiera de los siguientes campos. Todos son opcionales; omite los que no necesites.
| Campo | Tipo | Significado |
|---|---|---|
result | string | Salida en bruto de la IA. Se muestra en el panel de resultado y se usa como cuerpo predeterminado de la sugerencia. |
reason | string | Por qué la IA recomienda este cambio. Aparece en el panel “Why this suggestion”. |
message | string | Respuesta de estilo chat (solo en la interfaz AI Chat). |
operations | Operation[] | Plan estructurado; consulta Tipos de operación. |
target | string | Dónde aplicarlo: "selection-preview", "document", "insert", etc. |
autoRun | boolean | Aplica automáticamente sin confirmación del usuario (úsalo con moderación). |
También puedes devolver una cadena o una Promise. Una cadena se convierte en { result: <that string> }; una Promise se espera.
Tipos de operación
Las operaciones son el plan estructurado que puede devolver tu resolver. El editor las ejecuta en orden (o una a una, según decida el usuario, desde el panel del plan).
| type | Campos | Qué hace |
|---|---|---|
preview-suggestion | text, reason? | Muestra una vista previa en línea de antes y después. El usuario acepta o rechaza. |
replace-selection | text | Sustituye la selección actual por el texto indicado. |
replace-document | text | Sustituye todo el cuerpo del documento. |
insert-below | text | Inserta un bloque nuevo después del cursor o de la selección. |
add-comment | text, reason? | Coloca sobre la selección actual un marcador de comentario de IA que no modifica el contenido. |
open-chat-panel | message? | Abre el panel AI Chat; opcionalmente, con un mensaje inicial. |
open-review-panel | - | Abre el panel AI Review. |
Se pueden registrar tipos de operación personalizados con editor.aiToolkit.registerOperationHandler(type, handler).
editor.aiToolkit.registerOperationHandler("insert-callout", function (op, ctx) {
// ctx = { snapshot, resolved, request, action, editor }
ctx.editor.insertHTML(
'<aside class="callout">' + ctx.editor.htmlEncode(op.text) + '</aside>'
);
return true; // mark the operation as handled
});API para usar desde código
Todas las interfaces se pueden abrir y controlar desde código mediante editor.aiToolkit.
// Open the Ask AI dialog
editor.aiToolkit.openDialog({ presetMode: "rewrite", autoRun: false });
// Quick actions (no dialog) - target: selection if present, else whole document
editor.aiToolkit.runQuickAction("proofread");
editor.aiToolkit.runQuickAction("translate", { language: "spanish" });
// Panels
editor.aiToolkit.openChatPanel({ focusComposer: true });
editor.aiToolkit.openReviewPanel({ focusPanel: true });
editor.aiToolkit.closeChatPanel();
editor.aiToolkit.closeReviewPanel();
editor.aiToolkit.toggleChatPanel();
editor.aiToolkit.toggleReviewPanel();
// Resolve without rendering - useful for tests + headless flows
editor.aiToolkit.resolveAction("rewrite", { source: "hello world" })
.then(function (resolved) { console.log(resolved.result); });
// Swap the resolver at runtime
editor.aiToolkit.setResolver(myResolver);
// Review queue
var pending = editor.aiToolkit.getSuggestions();
editor.aiToolkit.clearSuggestions();
editor.aiToolkit.saveSuggestionLedger();
editor.aiToolkit.loadSuggestionLedger();Acciones y modos personalizados
Registra acciones específicas de tu dominio (p. ej., reescritura SEO, revisión de cláusulas legales, ajuste del tono). Se integran en la misma interfaz de diálogo, chat y revisión.
// Add a new dialog mode (appears in the Action dropdown)
editor.aiToolkit.registerDialogMode({
id: "seo",
title: "SEO rewrite",
description: "Rewrite for stronger keyword coverage while preserving meaning."
});
// Register the action with a target (where output goes by default)
editor.aiToolkit.registerAction({
id: "seo",
title: "SEO rewrite",
target: "selection-preview",
resolverMode: "seo" // passed as request.mode to your resolver
});
// Your resolver handles it just like built-in modes
config.aiToolkitResolver = function (request) {
if (request.mode === "seo") { /* call your SEO service */ }
/* ... */
};Persistencia y registro remoto
Las sugerencias del panel AI Review se guardan en localStorage bajo una clave que tú controlas. Establece aiToolkitPersistenceKey para limitarlas a cada instancia del editor (p. ej., por documento).
new RichTextEditor("#editor", {
aiToolkitPersistenceKey: "doc-42-review", // localStorage scope
aiToolkitSuggestionLedgerUrl: "/api/ai/ledger", // optional GET/POST for cross-session sync
aiToolkitReviewLogUrl: "/api/ai/review-log", // optional activity feed endpoint
aiToolkitReviewSyncInterval: 15000 // ms between sync polls (default 15s)
});Cuando está definida la URL del registro, el plugin hace un GET al abrir y un POST al aceptar o rechazar, para que la cola de revisión sobreviva entre sesiones y se pueda compartir entre revisores.
BYOK (trae tu propia clave)
Importante: el editor no acepta ni guarda claves de API. Las claves van en el gestor de secretos de tu servidor.
El patrón BYOK recomendado:
- Tu interfaz de administración permite a un inquilino elegir un proveedor y pegar una clave. El formulario hace un POST a tu backend.
- Tu backend escribe la clave en tu gestor de secretos, limitada a ese inquilino.
- El
aiToolkitResolverdel editor hace un POST a/api/aicon la cookie de sesión. Ninguna clave en el navegador. - Tu backend busca la clave del inquilino, llama al proveedor y devuelve una respuesta recortada.
Consulta la demo de BYOK para ver un formulario de administración que funciona, un resolver con enrutamiento y un esbozo de servidor al estilo de Express.
Referencia de configuración
| Opción | Tipo | Predeterminado | Función |
|---|---|---|---|
aiToolkitEnabled | boolean | true | Establécelo en false para desactivar el plugin por completo (sin inyección de botones ni API). |
aiToolkitAutoToolbarButtons | boolean | true | Controla la inyección automática del botón de IA en las barras de herramientas estándar y en la barra flotante de selección de texto. Establécelo en false para mantener la IA disponible desde código mientras gestionas tú mismo dónde va aiassist. |
aiToolkitResolver | function | null | Tu hook; consulta Resolver. Si no se define, se usa el resolver de demostración integrado. |
aiToolkitActions | Action[] | integradas | Lista completa de las acciones registradas. Usa registerAction para ampliarla. |
aiToolkitDialogModes | Mode[] | 7 integrados | Modos que se muestran en la lista desplegable de Ask AI. |
aiToolkitOperationHandlers | object | {} | Controladores de tipos de operación personalizados, indexados por type. |
aiToolkitPersistenceKey | string | "" | Ámbito de localStorage para la cola de revisión. Vacío = sin persistencia. |
aiToolkitSuggestionLedgerUrl | string | "" | Endpoint del servidor para la sincronización del registro compartido. |
aiToolkitReviewLogUrl | string | "" | Endpoint del servidor para el feed de actividad de revisión. |
aiToolkitReviewSyncInterval | number | 15000 | Milisegundos entre consultas al registro. |
aiToolkitLabel | string | "Current editor" | Etiqueta que se muestra en las píldoras de metadatos dentro del cuadro de diálogo Ask AI. |
text_aiassist | string | "Ask AI" | Información sobre herramientas y título del cuadro de diálogo (localízalo para cada idioma de la interfaz). |
Pruébalo
Todas las interfaces de arriba funcionan sin clave de API en las demos públicas:
- Demo del AI Toolkit: Ask AI, acciones rápidas, Chat y panel Review
- Demo de BYOK: formulario de ajustes de administración + resolver con enrutamiento + esbozo del lado del servidor
- Presentación del AI Toolkit: página de presentación con una maqueta del editor en vivo