@imiobe/omnia-tinymce
v0.3.0
Published
TinyMCE plugin for iMio's Omnia AI API — content generation, improvement, correction, accessibility and translation
Readme
@ia/omnia-tinymce
TinyMCE plugin that integrates iMio's Omnia AI API for intelligent content manipulation: generation, expansion, improvement, reduction, correction, accessibility and translation.

Installation
The package is published on the GitLab Package Registry.
1. Configure npm to use the GitLab registry
Add to your project's .npmrc (replace <PROJECT_ID> with the numeric ID from the GitLab project page, and <TOKEN> with a deploy token or personal access token with read_api scope):
@ia:registry=https://gitlab.imio.be/api/v4/projects/<PROJECT_ID>/packages/npm/
//gitlab.imio.be/api/v4/projects/<PROJECT_ID>/packages/npm/:_authToken=<TOKEN>In GitLab CI, use the predefined CI_JOB_TOKEN instead of a personal token.
2. Install
npm install @ia/omnia-tinymce tinymceQuick start
import tinymce from 'tinymce';
import '@ia/omnia-tinymce';
tinymce.init({
selector: '#editor',
plugins: 'omnia',
toolbar: 'undo redo | omnia | bold italic',
contextmenu: 'omnia',
omnia_base_url: '/omnia-api',
});The plugin registers itself as omnia. Once loaded, it adds a toolbar menu button and (optionally) context menu items for all AI features.
Options
All options are prefixed with omnia_ and set in the TinyMCE init() config.
Alternative: window.omnia_tinymce_settings
When the host application cannot inject options directly into the tinymce.init() config (e.g. when TinyMCE is initialised inside a bundler-scoped module), you can set them via a global object instead:
<script>
window.omnia_tinymce_settings = {
omnia_base_url: '/omnia-api',
omnia_enabled_features: ['correct-text', 'translate-text'],
};
</script>The plugin reads from window.omnia_tinymce_settings at startup and applies any omnia_* key that was not already provided through the init config. Options passed directly to tinymce.init() always take precedence.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| omnia_base_url | string | '' | Required. Base URL of the Omnia-compatible API. |
| omnia_application | string | '' | Value sent as x-imio-application header. |
| omnia_municipality | string | '' | Value sent as x-imio-municipality header. |
| omnia_enabled_features | string[] | all except generate | Restrict to a subset of feature IDs (see below). |
| omnia_toolbar | boolean | true | Show the Omnia toolbar button. |
| omnia_context_menu | boolean | true | Show Omnia items in the context menu. |
| omnia_shortcuts | boolean \| object | true | Enable keyboard shortcuts. Pass an object for custom bindings. |
| omnia_translate_languages | string[] | ['fr','nl','de','en','es','it'] | Languages available for translation. |
| omnia_default_translate_language | string | 'fr' | Pre-selected translation target. |
| omnia_history_limit | number | 5 | Max items kept in the generation history. |
| omnia_floating_panel_mode | 'inline' \| 'blur' | 'inline' | Display mode: inline near selection or centred with blur overlay. |
| omnia_floating_panel_width | number \| 'full' | 500 | Floating panel width in pixels, or 'full' for viewport width. |
| omnia_endpoints | object | {} | Override individual endpoint paths (see API section). |
Features
| ID | Label | Shortcut | Requires selection |
|----|-------|----------|--------------------|
| generate | Generer du contenu | Alt+O, G | No |
| expand-text | Developper | Alt+O, D | Yes |
| improve-text | Ameliorer | Alt+O, A | Yes |
| reduce-text | Reduire | Alt+O, R | Yes |
| correct-text | Corriger | Alt+O, C | Yes |
| make-accessible | Rendre accessible | Alt+O, X | Yes |
| translate-text | Traduire | Alt+O, T | Yes |
Shortcuts use a chord system: press Alt+O (the prefix), release, then press the letter within 1.5 s. Both the prefix key and individual bindings can be customised:
omnia_shortcuts: {
prefix: 'o',
timeoutMs: 2000,
bindings: {
'generate': 'g',
'improve-text': 'i',
},
}Set omnia_shortcuts: false to disable shortcuts entirely.
Implementing an Omnia-compatible API proxy
The plugin expects a backend that exposes the endpoints listed below. All requests are POST with Content-Type: application/json. The base URL is set via omnia_base_url and every path is appended to it.
Headers
Every request includes these headers when configured:
| Header | Source |
|--------|--------|
| Content-Type | Always application/json |
| x-imio-application | omnia_application option |
| x-imio-municipality | omnia_municipality option |
Streaming requests additionally send Accept: text/event-stream.
Endpoints
POST /v1/agents/generate-content (streaming)
Generate content from a free-text prompt. Returns a Server-Sent Events stream.
Request:
{ "prompt": "Write an introduction about...", "tone": "formal" }The tone field is optional. Any extra options are forwarded as-is.
Response: SSE stream where each event contains a JSON chunk:
data: {"chunk":"Hello "}
data: {"chunk":"world."}
data: [DONE]The stream ends with a data: [DONE] sentinel.
POST /v1/agents/expand-text
Expand / enrich the input text.
// Request
{ "input": "<p>Short text.</p>", "expansion_target": 2 }
// Response
{ "result": "<p>Longer, more detailed text...</p>" }expansion_target is optional (multiplier, e.g. 2 = twice as long).
POST /v1/agents/improve-text
Improve the style and quality of the input text.
// Request
{ "input": "<p>Draft text.</p>" }
// Response
{ "result": "<p>Improved text.</p>" }POST /v1/agents/reduce-text
Shorten the input text.
// Request
{ "input": "<p>Verbose text...</p>", "reduction_target": 0.5 }
// Response
{ "result": "<p>Shorter text.</p>" }reduction_target is optional (ratio, e.g. 0.5 = half the length).
POST /v1/agents/correct-text
Fix spelling and grammar.
// Request
{ "input": "<p>Text with erors.</p>" }
// Response
{ "result": "<p>Text with errors.</p>" }POST /v1/agents/make-accessible
Rewrite for WCAG accessibility (plain language).
// Request
{ "input": "<p>Complex legal jargon...</p>" }
// Response
{ "result": "<p>Clear, accessible text...</p>" }POST /v1/agents/translate-text
Translate text to a target language.
// Request
{ "input": "<p>Bonjour le monde.</p>", "target_language": "nl" }
// Response
{ "result": "<p>Hallo wereld.</p>" }Supported language codes: fr, nl, de, en, es, it.
Overriding endpoints
Use omnia_endpoints to point individual features at different paths or full URLs:
omnia_endpoints: {
'generate': '/my/custom/generate',
'translate-text': 'https://other-api.example.com/translate',
}Minimal proxy example (FastAPI)
import httpx
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
app = FastAPI()
OMNIA_API = "https://omnia.example.be/api"
AGENTS = [
"expand-text", "improve-text", "reduce-text",
"correct-text", "make-accessible", "translate-text",
]
# --- Streaming proxy for generate-content (declare BEFORE agent_proxy) ---
class GenerateRequest(BaseModel):
prompt: str
tone: str | None = None
@app.post("/omnia/v1/agents/generate-content")
async def generate(body: GenerateRequest):
async def stream():
async with httpx.AsyncClient() as client:
async with client.stream(
"POST", f"{OMNIA_API}/v1/agents/generate-content",
json=body.model_dump(exclude_none=True),
headers={"Content-Type": "application/json"},
) as resp:
async for chunk in resp.aiter_bytes():
yield chunk
return StreamingResponse(stream(), media_type="text/event-stream")
# --- JSON proxy for agent endpoints ---
@app.post("/omnia/v1/agents/{agent}")
async def agent_proxy(agent: str, body: dict):
if agent not in AGENTS:
return {"error": "Unknown agent"}, 404
async with httpx.AsyncClient() as client:
resp = await client.post(
f"{OMNIA_API}/v1/agents/{agent}",
json=body,
headers={"Content-Type": "application/json"},
)
return resp.json()Then set omnia_base_url: '/omnia' in TinyMCE.
Development
make install # npm install
make dev # Storybook on port 6006
make build # Build to dist/Copy .env.example to .env for the Storybook "Live API" story:
VITE_OMNIA_BASE_URL=https://omnia.example.be/api
VITE_OMNIA_APPLICATION=my-app
VITE_OMNIA_MUNICIPALITY=my-communeWhen VITE_OMNIA_BASE_URL is a full URL, Storybook automatically proxies requests to avoid CORS.
Available commands
| Command | Description |
|---------|-------------|
| make install | Install dependencies |
| make dev | Start Storybook dev server (port 6006) |
| make dev-integration | Start integration test page (port 5173) |
| make build | Build library to dist/ (ES + UMD + CSS) |
| make build-storybook | Build static Storybook site |
| make clean | Remove dist/ and storybook-static/ |
| make publish | Build and publish to npm |
| make release VERSION=… | Bump version, update CHANGELOG, commit and tag |
Build output
The library builds to dist/ in two formats:
omnia-tinymce.js-- ES moduleomnia-tinymce.umd.cjs-- UMD (global:OmniaTinyMCE)omnia-tinymce.css-- Scoped styles (Tailwind withom:prefix)
TinyMCE is not bundled -- it must be provided by the host application.
License
Proprietary -- (c) iMio
