Concept internals
Форматування Markdown
OpenClaw перетворює вихідний Markdown на спільне проміжне представлення (IR), перш ніж формувати вивід для конкретного каналу. IR зберігає звичайний текст разом з діапазонами стилів і посилань, тому один етап синтаксичного аналізу обслуговує всі канали, а поділ на частини ніколи не розділяє форматування всередині діапазону.
Конвеєр
- Перетворення Markdown на IR (
markdownToIR) — звичайний текст разом із діапазонами стилів (жирний, курсив, закреслений, код, блок коду, спойлер, цитата, заголовки 1–6) і діапазонами посилань. Зміщення вимірюються кодовими одиницями UTF-16, тому діапазони стилів Signal безпосередньо узгоджуються з його API. Таблиці аналізуються лише тоді, коли канал використовує режим таблиць. - Поділ IR на частини (
chunkMarkdownIR/renderMarkdownIRChunksWithinLimit) — поділ виконується над текстом IR до формування виводу, тому вбудовані стилі та посилання розрізаються для кожної частини, а не розриваються на межі. - Формування виводу для кожного каналу (
renderMarkdownWithMarkers) — мапа маркерів стилів перетворює діапазони на нативну розмітку каналу.
| Канал | Засіб формування виводу | Примітки |
|---|---|---|
| Slack | токени mrkdwn (*жирний*, _курсив_, `код`, огорожі коду) |
Посилання перетворюються на <url|label>; автоматичні посилання вимкнено під час аналізу, щоб уникнути дублювання |
| Telegram | HTML-теги (<b>, <i>, <s>, <code>, <pre><code>, <a href>, <tg-spoiler>) |
Також підтримує таблиці та заголовки форматованих повідомлень (<h1>–<h6>), коли ввімкнено richMessages |
| Signal | звичайний текст + діапазони text-style |
Посилання відображаються як label (url), якщо підпис відрізняється від URL |
| Discord, WhatsApp, iMessage, Microsoft Teams та інші канали | звичайний текст | Стилізація на основі IR відсутня; перетворення таблиць Markdown усе одно виконується через convertMarkdownTables |
Приклад IR
Вхідний Markdown: OC_I18N_900000 IR (схематично): OC_I18N_900001
Обробка таблиць
markdown.tables визначає, як канал перетворює таблиці Markdown, окремо для
кожного каналу та, за потреби, для кожного облікового запису:
| Режим | Поведінка |
|---|---|
code |
Формувати вирівняну ASCII-таблицю всередині блока коду (типове резервне значення) |
bullets |
Перетворювати кожен рядок на марковані пункти label: value |
block |
Зберігати нативні таблиці там, де транспорт їх підтримує; інакше використовувати code |
off |
Вимкнути аналіз таблиць; необроблений текст таблиці передається без змін |
Типові значення Plugin для кожного каналу: Signal, WhatsApp і Matrix типово використовують
bullets; Mattermost типово використовує off; Telegram типово використовує block (який
перетворюється на code, якщо для облікового запису не ввімкнено richMessages). Будь-який
канал без явно заданого типового значення Plugin використовує code.
OC_I18N_900002
Правила поділу на частини
- Обмеження розміру частин надходять від адаптерів або конфігурації каналів і застосовуються до тексту IR, а не до сформованого виводу.
- Огороджені блоки коду зберігаються як один блок із завершальним символом нового рядка, щоб канали правильно відображали завершальну огорожу.
- Префікси списків і цитат є частиною тексту IR, тому поділ на частини ніколи не розриває префікс.
- Вбудовані стилі ніколи не розділяються між частинами; засіб формування виводу повторно відкриває активний стиль на початку наступної частини.
Докладніше про межі частин і поведінку доставлення в різних каналах див. у розділі Потокове передавання та поділ на частини.
Політика посилань
- Slack:
[label](url)-><url|label>; URL без підпису залишаються без змін. - Telegram:
[label](url)-><a href="url">label</a>(режим аналізу HTML). - Signal:
[label](url)->label (url), якщо підпис ще не збігається з URL.
Спойлери
Маркери спойлерів (||spoiler||) аналізуються для Signal (перетворюються на діапазони стилю SPOILER)
і Telegram (перетворюються на <tg-spoiler>). Інші канали сприймають
||...|| як звичайний текст.
Додавання або оновлення засобу форматування каналу
- Виконайте аналіз один раз за допомогою
markdownToIR(...), передавши доречні для каналу параметри (autolink,headingStyle,blockquotePrefix,tableMode). - Сформуйте вивід за допомогою
renderMarkdownWithMarkers(...)і мапи маркерів стилів (або спеціальної логіки діапазонів стилів для транспортів на кшталт Signal). - Поділіть на частини за допомогою
chunkMarkdownIR(...)абоrenderMarkdownIRChunksWithinLimit(...)перед формуванням виводу кожної частини. - Підключіть адаптер, щоб він викликав новий засіб поділу на частини та формування виводу зі шляху вихідного надсилання.
- Протестуйте за допомогою тестів форматування та тесту вихідного доставлення, якщо канал ділить повідомлення на частини.
Поширені проблеми
- Токени Slack у кутових дужках (
<@U123>,<#C123>,<https://...>) мають зберігатися під час екранування; необроблений HTML усе одно потрібно безпечно екранувати. - HTML у Telegram потребує екранування тексту поза тегами, щоб уникнути пошкодженої розмітки.
- Діапазони стилів Signal використовують зміщення UTF-16, а не зміщення кодових точок.
- Зберігайте завершальні символи нового рядка в огороджених блоках коду, щоб завершальний маркер опинявся в окремому рядку.