Concept internals
Markdown-opmaak
OpenClaw formatteert uitgaande Markdown door deze om te zetten naar een gedeelde tussenliggende representatie (IR) voordat kanaalspecifieke uitvoer wordt gerenderd. De IR houdt de brontekst intact terwijl stijl-/linkspans worden meegedragen, zodat chunking en rendering consistent kunnen blijven over kanalen heen.
Doelen
- Consistentie: één parseerstap, meerdere renderers.
- Veilige chunking: splits tekst vóór rendering, zodat inline-opmaak nooit over chunks heen breekt.
- Kanaalpassing: map dezelfde IR naar Slack mrkdwn, Telegram HTML en Signal stijlbereiken zonder Markdown opnieuw te parsen.
Pipeline
- Markdown parsen -> IR
- IR is platte tekst plus stijlspans (vet/cursief/doorhalen/code/spoiler) en linkspans.
- Offsets zijn UTF-16-code-eenheden, zodat Signal-stijlbereiken overeenkomen met de API.
- Tabellen worden alleen geparsed wanneer een kanaal kiest voor tabelconversie.
- IR chunken (opmaak eerst)
- Chunking gebeurt op de IR-tekst vóór rendering.
- Inline-opmaak wordt niet over chunks gesplitst; spans worden per chunk uitgesneden.
- Renderen per kanaal
- Slack: mrkdwn-tokens (vet/cursief/doorhalen/code), links als
<url|label>. - Telegram: HTML-tags (
<b>,<i>,<s>,<code>,<pre><code>,<a href>). - Signal: platte tekst +
text-style-bereiken; links wordenlabel (url)wanneer het label verschilt.
- Slack: mrkdwn-tokens (vet/cursief/doorhalen/code), links als
IR-voorbeeld
Invoer-Markdown:
Hello **world** - see [docs](https://docs.openclaw.ai).
IR (schematisch):
{
"text": "Hello world - see docs.",
"styles": [{ "start": 6, "end": 11, "style": "bold" }],
"links": [{ "start": 19, "end": 23, "href": "https://docs.openclaw.ai" }]
}
Waar het wordt gebruikt
- Uitgaande adapters voor Slack, Telegram en Signal renderen vanuit de IR.
- Andere kanalen (WhatsApp, iMessage, Microsoft Teams, Discord) gebruiken nog platte tekst of hun eigen opmaakregels, waarbij Markdown-tabelconversie vóór chunking wordt toegepast wanneer die is ingeschakeld.
Tabelafhandeling
Markdown-tabellen worden niet consistent ondersteund door chatclients. Gebruik
markdown.tables om conversie per kanaal (en per account) te beheren.
code: render tabellen als codeblokken (standaard voor de meeste kanalen).bullets: converteer elke rij naar opsommingstekens (standaard voor Signal + WhatsApp).off: schakel tabelparsing en conversie uit; ruwe tabeltekst wordt doorgelaten.
Configuratiesleutels:
channels:
discord:
markdown:
tables: code
accounts:
work:
markdown:
tables: off
Chunking-regels
- Chunklimieten komen uit kanaaladapters/configuratie en worden toegepast op de IR-tekst.
- Code fences worden behouden als één blok met een afsluitende newline, zodat kanalen ze correct renderen.
- Lijstvoorvoegsels en blockquote-voorvoegsels maken deel uit van de IR-tekst, zodat chunking niet midden in een voorvoegsel splitst.
- Inline-stijlen (vet/cursief/doorhalen/inline-code/spoiler) worden nooit over chunks gesplitst; de renderer opent stijlen opnieuw binnen elke chunk.
Als je meer nodig hebt over chunking-gedrag over kanalen heen, zie Streaming + chunking.
Linkbeleid
- Slack:
[label](url)-><url|label>; kale URL's blijven kaal. Autolink is uitgeschakeld tijdens het parsen om dubbele links te voorkomen. - Telegram:
[label](url)-><a href="url">label</a>(HTML-parsemodus). - Signal:
[label](url)->label (url), tenzij het label overeenkomt met de URL.
Spoilers
Spoilermarkeringen (||spoiler||) worden alleen geparsed voor Signal, waar ze worden gemapt naar
SPOILER-stijlbereiken. Andere kanalen behandelen ze als platte tekst.
Een kanaalformatter toevoegen of bijwerken
- Eenmalig parsen: gebruik de gedeelde helper
markdownToIR(...)met kanaalgeschikte opties (autolink, kopstijl, blockquote-voorvoegsel). - Renderen: implementeer een renderer met
renderMarkdownWithMarkers(...)en een stijlmarkeringsmap (of Signal-stijlbereiken). - Chunken: roep
chunkMarkdownIR(...)aan vóór rendering; render elke chunk. - Adapter aansluiten: werk de uitgaande kanaaladapter bij om de nieuwe chunker en renderer te gebruiken.
- Testen: voeg opmaaktests toe of werk ze bij, plus een uitgaande bezorgtest als het kanaal chunking gebruikt.
Veelvoorkomende valkuilen
- Slack-tokens met punthaken (
<@U123>,<#C123>,<https://...>) moeten worden behouden; escape ruwe HTML veilig. - Telegram HTML vereist het escapen van tekst buiten tags om kapotte markup te vermijden.
- Signal-stijlbereiken hangen af van UTF-16-offsets; gebruik geen codepoint-offsets.
- Behoud afsluitende newlines voor fenced code blocks, zodat sluitmarkeringen op hun eigen regel terechtkomen.