diff --git a/MARKDOWN-SOURCE.md b/MARKDOWN-SOURCE.md new file mode 100644 index 0000000..28d5e63 --- /dev/null +++ b/MARKDOWN-SOURCE.md @@ -0,0 +1,146 @@ +# Откуда брать отрисовку Markdown + +Готовый рендер Markdown для Compose уже написан и лежит в репозитории **`ai/assistent`**. +Писать своё не надо — надо взять это. + +**Репозиторий:** https://git.binom.pw/ai/assistent (ветка `main`) +**Проверено на коммите:** `2c5b3f9` (файлы добавлены в `1acced4`, 2026-08-13) +**Важно:** репозиторий приватный. Браузерная ссылка откроется только у залогиненного; +для копирования файлов из скрипта — RAW-адреса с логином/паролем (ниже). + +--- + +## Что именно копировать: 4 файла + +Всё лежит в двух модулях. Модуль `client-shared` — общий, собирается под **JVM + Compose** +(то есть ровно наш случай, десктоп), не под Android. + +### 1. Модель данных — `MarkdownSegment.kt` (59 строк) + +``` +client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt +``` + +Что внутри: типы кусков разметки — текст, блок кода, таблица, картинка, разделитель. +Плюс описание стилевого участка: жирный, курсив, код, зачёркнутый, ссылка. +Зависимостей от Compose нет вообще — чистые данные. + +### 2. Парсер — `MarkdownParserImpl.kt` (353 строки) + +``` +client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt +``` + +Точка входа: `parseMarkdown(markdown: String): List`. +Единственная внешняя зависимость — библиотека парсера `ru.otpbank.ai:markdown` (см. ниже). +От Композа не зависит. + +### 3. Отрисовка — `MarkdownRendering.kt` (377 строк) + +``` +client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt +``` + +Точка входа: +`renderMarkdownSegments(content, textColor, fontSize, isBubbleScrolled, onUrlClick)`. +Внутри: текст с inline-стилями, кликабельные ссылки, блоки кода с копированием, +таблицы, картинки, разделители. Самый жирный файл и самая нужная часть. + +### 4. Десктопная обёртка — `MarkdownRenderer.kt` (25 строк) + +``` +client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt +``` + +Открытие ссылок в системном браузере (`Desktop.getDesktop().browse`) и +`parseMultiline`. Модуль `client` в assistent — это **десктопный** клиент на +Compose Desktop, так что пример использования ровно наш. + +--- + +## Что копировать НЕ надо + +- `client-shared/src/main/kotlin/pw/binom/client/shared/ui/MessageBubble.kt` (789 строк) — + пузырь сообщения целиком. Тянет за собой модуль `chat-common` (модели сообщений), + из плюшек — выделение текста и контекстное меню. Для отрисовки разметки не нужен, + но полезен, если понадобится пример. + +--- + +## Зависимости + +Одна, и она есть в нашем Nexus: + +```kotlin +implementation("ru.otpbank.ai:markdown:0.51.0") +``` + +Репозиторий в `build.gradle.kts` (без него не соберётся): + +```kotlin +maven { + url = uri("http://192.168.76.117/repository/developerspace-prod-mvn-hosted/") + isAllowInsecureProtocol = true +} +``` + +Проверено: в Nexus лежит, версии с `0.1.0` по `0.51.0`, файл `markdown-0.51.0.pom` +отдаёт `HTTP 200`. + +Из Compose нужны: `compose.material3`, `compose.foundation`, `compose.ui`, +`compose.materialIconsExtended` (иконка копирования в блоках кода). + +## Опубликован ли `client-shared` как библиотека + +**Нет.** Проверено поиском в Nexus (`pw/binom/client-shared`, `pw/binom/chat-common`) — +`HTTP 404`. Поэтому вариантов два: либо копируем исходники к себе (4 файла выше), +либо сперва публикуем модуль. Копирование проще. + +--- + +## Как копировать (RAW-адреса, работают с логином) + +Адрес вида `/raw/branch/main/<путь>` отдаёт файл. Проверено: `HTTP 200`, 1805 байт — +совпадает с локальным размером. + +```bash +BASE=https://git.binom.pw/ai/assistent/raw/branch/main +AUTH='subochev:ПАРОЛЬ' # подставить перед запуском + +for f in \ + client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt \ + client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt \ + client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt \ + client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt ; do + curl -sS -u "$AUTH" "$BASE/$f" -o "$(basename "$f")" +done +``` + +Браузерные ссылки для чтения глазами (нужен залогиненный git.binom.pw): + +``` +https://git.binom.pw/ai/assistent/src/branch/main/client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt +https://git.binom.pw/ai/assistent/src/branch/main/client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt +https://git.binom.pw/ai/assistent/src/branch/main/client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt +https://git.binom.pw/ai/assistent/src/branch/main/client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt +``` + +--- + +## Что придётся поправить после копирования + +1. **Пакеты.** Файлы лежат в `pw.binom.client.shared.*` — переименовать под наш проект + (или оставить как есть, если не смущает). +2. **`openUrl`.** В `MarkdownRenderer` открытие ссылок идёт через `java.awt.Desktop` — + на десктопе это работает, ничего менять не надо. +3. **Стиль.** Цвета текста и блоков кода в `MarkdownRendering` берутся из аргументов и + `MaterialTheme` — под нашу тёмную тему подставить свои значения. + +## Что этот рендер умеет (по коду) + +- **Текст** с участками: жирный, курсив, код, зачёркнутый, ссылки. +- **Блоки кода** — с названием языка и кнопкой копирования. +- **Таблицы** — заголовки и строки, с горизонтальной прокруткой. +- **Картинки** — `data:`-ссылки и обычные `http(s)`. Первые рисуются сразу из памяти. +- **Разделители** (`---`). +- **Кликабельные ссылки** — нажатие уходит в `onUrlClick`, оттуда открываем браузер. diff --git a/README.md b/README.md index 7457ea3..8059c81 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ sketches/003-three-pane-command/index.html # три панели + состо sketches/004-settings-agents/index.html # настройки агентов + проверка связи ``` +`MARKDOWN-SOURCE.md` — откуда брать готовую отрисовку Markdown (файлы и адреса). `REQUIREMENTS.md` — требования. Статус: накидываем, ни один пункт не обязателен к исполнению в том виде, как записан. @@ -34,8 +35,9 @@ sketches/004-settings-agents/index.html # настройки агентов Цвет помечает диалоги агента (полоска у строки, точка у группы); картинка показывается кружком вместо цвета. **Картинку клиент копирует себе**, а не берёт по исходному адресу — иначе значок пропадёт вместе с файлом. -- **Markdown** — показывать разметкой, а не сырыми символами. Готовая - библиотека уже используется в клиенте assistent, писать свою не надо. +- **Markdown** — показывать разметкой, а не сырыми символами. Готовый рендер + лежит в репозитории `ai/assistent` — писать свой не надо, брать оттуда. + Точные координаты файлов — в `MARKDOWN-SOURCE.md`. - **Папки над списком диалогов** («Все чаты», «Работа», «Дом») — часть выбранного варианта 1, не терять их при доработках. - **Проверка связи с агентом** — в отдельном окне поверх настроек: идёт → отвечает diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index c4ac12e..5ace134 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -45,8 +45,12 @@ за куском, а не появляется целиком в конце. Отображать именно так. - **R13.** **Разметка (markdown).** Если я или агент пишем текст, похожий на разметку, показывать его разметкой, а не сырыми символами: списки, выделение, - код, таблицы, ссылки. Код для этого писать не надо — готовая библиотека уже - используется в клиенте assistent. + код, таблицы, ссылки. Код для этого писать не надо — готовый рендер уже есть + в репозитории `ai/assistent`, брать оттуда. +- **R13.1.** **Откуда брать — точно.** См. `MARKDOWN-SOURCE.md`: репозиторий + `ai/assistent`, ветка `main`, коммит `2c5b3f9`. Копировать 4 файла: + модель разметки, парсер, отрисовку и десктопную обёртку открытия ссылок. + Одна внешняя зависимость — `ru.otpbank.ai:markdown:0.51.0` (есть в Nexus). ## 5. Панель ввода