Skip to content

Mermaid Live Editor

Showcase #1

Mermaid Live Editor is the official online diagram editor for Mermaid, supporting flowcharts, sequence diagrams, class diagrams, and more. We integrated rtc-agent with less than 30 lines of glue code, enabling the AI to:

  • 🗣️ Generate Mermaid code from natural language descriptions
  • ✍️ Automatically write to the editor and trigger live preview
  • ✅ Proactively invoke syntax validation and self-heal on errors
  • 🎨 Require zero manual code from the user throughout

The video above shows the full workflow: user describes what they want → AI writes code → validates → renders.

The entire integration only modifies 2 core files with zero changes to upstream source code:

FileChangeLines
src/routes/+layout.svelteLoad rtc-agent, mount component, configure agentConfig+98
src/lib/util/editorAPI.tsExpose window.editorAPI programmatic interface+105 (new)

rtc-agent’s core design principle is “the Agent never touches your source code — it only operates state through declarative APIs”. So the first step is exposing your app’s key state on window:

src/lib/util/editorAPI.ts
export interface EditorAPI {
getCode(): string; // Get current editor code
getDiagramType(): string; // Get diagram type (flowchart/sequence/...)
setCode(code: string): void; // Replace editor content and trigger validation
validate(): ValidateResult; // Return validation result (with error locations)
waitForReady(): Promise<void>; // Wait for async validation to complete
}
// Mount on window so rtc-agent tools can call them
window.editorAPI = { getCode, setCode, validate, getDiagramType, waitForReady };

Design principles behind this API:

  • Symmetric read/write: getCode pairs with setCode — the Agent can both read and write
  • Validation loop: After writing code, the Agent proactively calls validate() and self-heals on errors
  • Async-aware: waitForReady() lets the Agent know when validation completes, avoiding stale reads

Load rtc-agent in your layout and configure using the factory function:

src/routes/+layout.svelte
<script>
import { z, withMeta, createRtcAgent } from '@rtc-agent/component';
import { onMount, onDestroy } from 'svelte';
import { base } from '$app/paths';
let rtcAgent = null;
onMount(() => {
rtcAgent = createRtcAgent({
agentDescription: 'Mermaid Live Editor - AI assistant for creating diagrams',
agentName: 'MermaidEditor',
appLabel: 'Mermaid AI',
groups: [{
description: 'Editor operations for reading and writing Mermaid code',
name: 'editor',
functions: [
{
name: 'getCode',
description: 'Get the current Mermaid code from the editor',
handler: () => window.editorAPI.getCode(),
returns: { schema: { description: 'The current Mermaid code', type: 'string' } }
},
{
name: 'setCode',
description: 'Replace the entire editor content with new Mermaid code.',
handler: (params: { code: string }) => {
window.editorAPI.setCode(params.code);
return { success: true };
},
zodSchema: z.object({
code: withMeta(z.string(), { example: 'graph TD\n A-->B' })
.describe('The Mermaid code to write to the editor')
}),
returns: {
schema: { properties: { success: { type: 'boolean' } }, type: 'object' }
}
},
{
name: 'getDiagramType',
description: 'Get the detected diagram type',
handler: () => window.editorAPI.getDiagramType() ?? 'unknown',
returns: {
schema: { description: 'The diagram type or "unknown"', type: 'string' }
}
},
{
name: 'validate',
description: 'Validate the current Mermaid code and return any syntax errors.',
handler: () => window.editorAPI.validate(),
returns: { schema: { description: 'Validation result', type: 'object' } }
}
]
}],
persona: `You are a helpful Mermaid diagram assistant. You help users create and edit
Mermaid diagrams through natural language conversation. You can write Mermaid code,
check for syntax errors, and fix issues. Always validate your code after writing it
to ensure correctness. When creating diagrams, explain what you're drawing and use
clear, descriptive node names.`,
scenariosURL: `${base}/rtc-agent/scenarios/`,
server: {
url: 'https://rtc-agent.cherish.chat',
redirectUri: `${base}/auth/callback.html`
},
theme: mode.current ?? 'light',
window: {
bubblePosition: {
corner: 'bottom-left',
offset: { x: 20, y: 20 }
}
},
workerURL: `${base}/rtc-agent/shared-worker.js`,
on: {
ready: () => {
console.log('[Mermaid AI] RTC Agent ready');
}
}
});
document.body.appendChild(rtcAgent);
});
// Sync host theme changes to <rtc-agent>
$effect(() => {
if (rtcAgent) {
rtcAgent.theme = mode.current ?? 'light';
}
});
onDestroy(() => {
if (rtcAgent) {
rtcAgent.destroy();
rtcAgent = null;
}
});
</script>

rtc-agent supports light/dark themes. The theme is set during initialization via the theme property, and can be synced with the host app’s theme using Svelte’s $effect:

// Sync host theme changes to rtc-agent
$effect(() => {
if (rtcAgent) {
rtcAgent.theme = mode.current ?? 'light';
}
});

This is already included in the Step 2 code example above.

Beyond the two core files above, the following were also added:

FilePurpose
src/rtc-agent.d.tsrtc-agent TypeScript type declarations
static/auth/callback.htmlOAuth callback page
static/rtc-agent/scenarios/3 preset scenario templates + manifest

The integration modifies zero upstream source code, with a change rate of < 2%. rtc-agent is loaded from a local build artifact (switchable to CDN in production) — the 3MB bundle never enters the repository.

rtc-agent/mermaid-live-editor (forked from mermaid-js/mermaid-live-editor)