Concept internals
Markdown-opmaak
OpenClaw formatteert uitgaande Markdown door deze om te zetten naar een gedeelde tussenrepresentatie (IR) voordat kanaalspecifieke uitvoer wordt gerenderd. De IR houdt de brontekst intact terwijl stijl-/linkspans worden meegenomen, zodat chunking en rendering consistent kunnen blijven tussen kanalen.
Doelen
- Consistentie: één parseerstap, meerdere renderers.
- Veilige chunking: splits tekst vóór rendering zodat inline-opmaak nooit over chunks heen breekt.
- Kanaalgeschiktheid: zet dezelfde IR om 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 geparseerd wanneer een kanaal zich aanmeldt voor tabelconversie.
- IR opdelen in chunks (format-first)
- Chunking gebeurt op de IR-tekst vóór rendering.
- Inline-opmaak wordt niet over chunks gesplitst; spans worden per chunk uitgesneden.
- Per kanaal renderen
- 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
- Slack-, Telegram- en Signal-adapters voor uitgaande berichten renderen vanuit de IR.
- Andere kanalen (WhatsApp, iMessage, Microsoft Teams, Discord) gebruiken nog steeds platte tekst of hun eigen opmaakregels, waarbij Markdown-tabelconversie vóór chunking wordt toegepast wanneer deze 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 Matrix, Signal en WhatsApp).off: schakel tabelparsing en -conversie uit; ruwe tabeltekst wordt doorgegeven.
Configuratiesleutels:
channels: discord: markdown: tables: code accounts: work: markdown: tables: offChunking-regels
- Chunklimieten komen uit kanaaladapters/configuratie en worden toegepast op de IR-tekst.
- Code fences blijven behouden als één blok met een afsluitende nieuwe regel, zodat kanalen ze correct renderen.
- Lijstprefixen en blockquote-prefixen maken deel uit van de IR-tekst, zodat chunking niet midden in een prefix 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 tussen kanalen, 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 geparseerd voor Signal, waar ze worden omgezet naar
SPOILER-stijlbereiken. Andere kanalen behandelen ze als platte tekst.
Een kanaalformatter toevoegen of bijwerken
- Eén keer parsen: gebruik de gedeelde helper
markdownToIR(...)met kanaalgeschikte opties (autolink, kopstijl, blockquote-prefix). - Renderen: implementeer een renderer met
renderMarkdownWithMarkers(...)en een stijlmarkeringsmap (of Signal-stijlbereiken). - Chunking: 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 formaattests toe of werk ze bij, en voeg een test voor uitgaande levering toe als het kanaal chunking gebruikt.
Veelvoorkomende valkuilen
- Slack-tokens met punthaken (
<@U123>,<#C123>,<https://...>) moeten worden behouden; escape ruwe HTML veilig. - Telegram HTML vereist escaping van tekst buiten tags om kapotte markup te voorkomen.
- Signal-stijlbereiken zijn afhankelijk van UTF-16-offsets; gebruik geen codepoint-offsets.
- Behoud afsluitende nieuwe regels voor fenced codeblokken, zodat sluitmarkeringen op hun eigen regel terechtkomen.