AI Toolkit
Ask AI, AI Chat, pré-visualização inline e uma gaveta AI Review — tudo construído sobre um único hook aiToolkitResolver, para que você possa usar hoje o resolver de demonstração incluído e trocá-lo amanhã pelo seu próprio backend sem mudar a interface.
Visão geral
O AI Toolkit adiciona três interfaces relacionadas ao editor:
- Ask AI — uma caixa de diálogo aberta pela barra de ferramentas, com sete modos de um clique (revisar, reescrever, encurtar, expandir, resumir, traduzir, justificar), um seletor de escopo seleção/documento e uma pré-visualização inline antes de aplicar.
- AI Chat — um painel lateral fixo para solicitações em várias rodadas. Leva o escopo em conta e oferece prompts rápidos e as ações copiar/aplicar/inserir/substituir em cada resposta da IA.
- AI Review — uma fila persistente de sugestões pendentes, aceitas e rejeitadas. Sincronização opcional com um registro no servidor para revisão entre sessões.
As três compartilham o mesmo hook aiToolkitResolver e o mesmo contrato de operações, então uma sugestão pré-visualizada em uma interface pode ser aceita, rejeitada ou encaminhada em outra.
Modo de demonstração. Sem nenhum resolver configurado, o plugin traz um defaultResolveAction determinístico, para que você possa executar Ask AI, Chat e Review localmente sem chave de API, sem chamadas de rede e com resultados previsíveis.
Instalação
Carregue a folha de estilos e o script do AI Toolkit depois do bundle principal do editor. Por padrão, ao ser carregado, o plugin insere automaticamente um botão Ask AI nas predefinições de barra de ferramentas padrão default, basic, full e 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>Configuração. O rte.js que você baixou tem, no início, um bloco RTE_DefaultConfig editável em texto simples — abra-o e altere os padrões de IA (chave de persistência, rótulo, endpoint do resolver etc.) junto com todas as outras configurações do editor. Não é preciso carregar nenhum arquivo de configuração separado. O aitoolkit.css precisa estar presente sempre que o botão de IA puder ser renderizado (mesmo com a barra de ferramentas padrão); caso contrário, o menu suspenso de IA terá o tamanho errado. Para manter a IA ativada, mas impedir a inserção automática do botão, defina aiToolkitAutoToolbarButtons: false e adicione aiassist apenas às barras de ferramentas em que você quiser o botão.
var editor = new RichTextEditor("#editor", {
toolbar: "default",
aiToolkitAutoToolbarButtons: false
});Três interfaces
Caixa de diálogo aberta pela barra de ferramentas. Painéis de origem e de resultado, seletor de modo, alternância de escopo, pré-visualização de antes/depois, plano de operações e botões aplicar / substituir / inserir / rejeitar.
Painel fixo. Mensagens que levam o escopo em conta, prompts rápidos, histórico de mensagens e ações aplicar / inserir / substituir em cada resposta.
Gaveta persistente. Fila de pendentes / aceitas / rejeitadas, controles em lote e sincronização opcional com um registro remoto.
Modos incluídos
Cada modo é uma entrada { id, title, description } em config.aiToolkitDialogModes. Eles aparecem no menu suspenso Action da caixa de diálogo Ask AI e podem ser chamados por runQuickAction(id).
| id | Título | Comportamento padrão |
|---|---|---|
proofread | Proofread | Normaliza espaçamento, pontuação e uso de maiúsculas, preservando o sentido. |
rewrite | Rewrite | Remove expressões de enchimento (very, really, in order to, due to the fact that) e deixa o texto mais enxuto. |
shorten | Shorten | Mantém os primeiros ~60% das palavras, com no mínimo 8. |
expand | Expand | Acrescenta uma frase de apoio abaixo do texto de origem. |
summarize | Summarize | Monta um resumo em tópicos a partir dos primeiros ~45% das palavras. |
translate | Translate | Produz um rascunho identificado com o idioma; o idioma de destino é passado em request.language. |
justify | Justify edit | O mesmo que rewrite, mais um campo reason que explica a alteração. |
São stubs determinísticos do resolver de demonstração. Depois que você conectar o aiToolkitResolver, a sua função decide como cada modo é tratado. Você também pode registrar novos modos — veja Ações personalizadas.
O hook aiToolkitResolver
Este é o ponto de extensão. O resolver recebe uma requisição estruturada e retorna um resultado (ou uma Promise que resolve para um resultado). O editor cuida da renderização, da pré-visualização, da revisão e da aplicação.
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
}]
};
}
});Formato da requisição
| Campo | Tipo | Significado |
|---|---|---|
actionId | string | Ação que o usuário acionou (corresponde ao id de uma ação ou de um modo registrado). |
mode | string | Modo da caixa de diálogo — proofread, rewrite, translate etc. |
source | string | Texto a ser processado. O texto da seleção, se houver; caso contrário, o texto do documento inteiro. |
prompt | string | Texto do prompt do usuário (no modo de chat). |
language | string | Idioma de destino no modo de tradução. Vazio nos demais. |
scope | string | "selection" ou "document". |
selectionText | string | Texto da seleção (pode estar vazio). |
documentText | string | Texto do documento inteiro. |
snapshot | object | Snapshot da seleção (hasSelection, rangeHTML, text, wholeText, ...). |
editor | RichTextEditor | A instância do editor. |
contract | object | Lista completa dos tipos de operação suportados (para validação). |
Formato da resposta
Retorne um objeto simples com qualquer um dos campos abaixo. Todos são opcionais; omita o que não precisar.
| Campo | Tipo | Significado |
|---|---|---|
result | string | Saída bruta da IA. Aparece no painel de resultado e é usada como corpo padrão da sugestão. |
reason | string | Por que a IA recomenda essa alteração. Aparece no painel “Why this suggestion”. |
message | string | Resposta no estilo de chat (somente na interface AI Chat). |
operations | Operation[] | Plano estruturado — veja Tipos de operação. |
target | string | Onde aplicar — "selection-preview", "document", "insert" etc. |
autoRun | boolean | Aplica automaticamente, sem confirmação do usuário (use com moderação). |
Você também pode retornar uma string ou uma Promise. Uma string vira { result: <that string> }; uma Promise é aguardada.
Tipos de operação
Operações são o plano estruturado que o seu resolver pode retornar. O editor as executa em ordem (ou uma de cada vez, conduzidas pelo usuário, a partir do painel do plano).
| type | Campos | O que faz |
|---|---|---|
preview-suggestion | text, reason? | Mostra uma pré-visualização inline de antes/depois. O usuário aceita ou rejeita. |
replace-selection | text | Substitui a seleção atual pelo texto informado. |
replace-document | text | Substitui todo o corpo do documento. |
insert-below | text | Insere um novo bloco depois do cursor ou da seleção. |
add-comment | text, reason? | Coloca um marcador de comentário de IA não destrutivo na seleção atual. |
open-chat-panel | message? | Abre o painel AI Chat; opcionalmente, já com uma mensagem. |
open-review-panel | - | Abre a gaveta AI Review. |
Tipos de operação personalizados podem ser registrados com 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 programática
Todas as interfaces podem ser abertas e controladas por código através de 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();Ações e modos personalizados
Registre ações específicas do seu domínio (por exemplo, reescrita para SEO, verificação de cláusulas jurídicas, ajuste de tom). Elas se integram à mesma interface de caixa de diálogo, chat e revisão.
// 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 */ }
/* ... */
};Persistência e registro remoto
As sugestões da gaveta AI Review são salvas no localStorage sob uma chave que você controla. Defina aiToolkitPersistenceKey para separar o escopo por instância do editor (por exemplo, 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)
});Quando a URL do registro está definida, o plugin faz um GET ao abrir e um POST ao aceitar/rejeitar, o que permite que a fila de revisão sobreviva entre sessões e seja compartilhada entre revisores.
BYOK (bring your own key — use a sua própria chave)
Importante: o editor não aceita nem armazena chaves de API. As chaves ficam no gerenciador de segredos do seu servidor.
O padrão de BYOK recomendado:
- A sua interface de administração permite que um tenant escolha um provedor e cole uma chave. O formulário faz um POST para o seu backend.
- O seu backend grava a chave no seu gerenciador de segredos, com escopo para o tenant.
- O
aiToolkitResolverdo editor faz um POST para/api/aicom o cookie de sessão. Nenhuma chave no navegador. - O seu backend busca a chave do tenant, chama o provedor e retorna uma resposta enxuta.
Veja a demonstração de BYOK para um formulário de administração funcional, um resolver roteado e um esboço de servidor no estilo Express.
Referência de configuração
| Opção | Tipo | Padrão | Finalidade |
|---|---|---|---|
aiToolkitEnabled | boolean | true | Defina como false para desativar o plugin por completo (sem inserção de botão, sem API). |
aiToolkitAutoToolbarButtons | boolean | true | Controla a inserção automática do botão de IA nas barras de ferramentas padrão e na barra de ferramentas flutuante da seleção de texto. Defina como false para manter a IA disponível por código enquanto você mesmo gerencia o posicionamento de aiassist. |
aiToolkitResolver | function | null | O seu hook — veja Resolver. Se não for definido, usa o resolver de demonstração incluído. |
aiToolkitActions | Action[] | incluídas | Lista completa das ações registradas. Use registerAction para ampliá-la. |
aiToolkitDialogModes | Mode[] | 7 incluídos | Modos mostrados no menu suspenso do Ask AI. |
aiToolkitOperationHandlers | object | {} | Handlers de tipos de operação personalizados, indexados por type. |
aiToolkitPersistenceKey | string | "" | Escopo no localStorage para a fila de revisão. Vazio = sem persistência. |
aiToolkitSuggestionLedgerUrl | string | "" | Endpoint do servidor para sincronizar o registro compartilhado. |
aiToolkitReviewLogUrl | string | "" | Endpoint do servidor para o feed de atividade de revisão. |
aiToolkitReviewSyncInterval | number | 15000 | Milissegundos entre as consultas ao registro. |
aiToolkitLabel | string | "Current editor" | Rótulo mostrado nas pílulas de metadados dentro da caixa de diálogo Ask AI. |
text_aiassist | string | "Ask AI" | Dica de ferramenta e título da caixa de diálogo (localize para cada idioma da interface). |
Experimente
Todas as interfaces acima funcionam sem chave de API nas demonstrações públicas:
- Demonstração do AI Toolkit — Ask AI, ações rápidas, Chat, gaveta Review
- Demonstração de BYOK — formulário de configurações de administração + resolver roteado + esboço do lado do servidor
- Visão geral do AI Toolkit — página de apresentação com uma simulação do editor ao vivo