feat(mcp): drawio стадия 2 — правила генерации: guide, shape-каталог, elk-layout, quality-warnings #424

Open
opened 2026-07-09 23:34:21 +03:00 by agent_vscode · 0 comments
Collaborator

ТЗ: научить агента генерировать качественные диаграммы

Зависит от #423 (стадия 1: CRUD drawio_get/create/update).

Цель

После стадии 1 агент умеет создавать диаграммы, но качество — «сырое AI»: угаданные имена стенсилов рендерятся пустыми квадратами, ручные координаты дают налезания и edge сквозь фигуры, цветные заливки групп. Стадия 2 закрывает это правилами и справочными инструментами — без vision-цикла и без рендеринга (всё детерминированно, математикой по XML).

Состав

1. Хард-правила в description инструментов drawio_create/drawio_update

Сжатый блок правил прямо в описании (паттерн jgraph/drawio-mcp — правила инжектятся в tool description, модель видит их в момент вызова):

  • обязательные id=0/1; ячейка vertex xor edge; у edge — дочерний <mxGeometry>; без XML-комментариев; уникальные id;
  • html=1 в стилях + XML-экранирование в value; перенос строки — &#xa;, не \n;
  • контейнеры прозрачные: fillColor=none;container=1;dropTarget=1; — дети с parent=<groupId> и координатами относительно родителя; edge между контейнерами — parent="1";
  • adaptiveColors="auto" на mxGraphModel (тёмная тема Docmost бесплатно; цвета strokeColor/fillColor/fontColor="default" авто-адаптируются);
  • «не угадывай shape=mxgraph.* — сначала drawio_shapes».

2. drawio_guide(section?) — справочник по запросу

Progressive disclosure: полный authoring-справочник не раздувает контекст, читается по секциям: skeleton | layout | containers | icons-aws | icons-azure. Весь исходный материал секций — в Приложении ниже, писать guide прямо из этой ишью.

3. drawio_shapes(query, category?, limit?) — verified shape-каталог

  • Бандлим shape-index из jgraph/drawio-mcp (shape-search/search-index.json, ~4.7MB / ~10 400 шейпов, Apache-2.0; сжать в .json.gz). Формат записи: {style, w, h, title, tags, type}.
  • У jgraph есть shape-search/generate-index.js, перестраивающий индекс из app.min.js релиза draw.io — каталог не протухает; задокументировать процедуру обновления.
  • Поиск: подстрока + tags + fuzzy; возвращает точную style-строку + дефолтные w/h + категорию.
  • Blocklist заведомо битых стенсилов с заменами (см. Приложение) — прямо в данных.

Это фикс «пустых квадратов» №1.

4. layout: "elk" — параметр на drawio_create/drawio_update

  • Зависимость elkjs (EPL-2.0, чистый JS-порт Eclipse ELK, работает в Node без нативных зависимостей и без браузера): https://www.npmjs.com/package/elkjs
  • Модель даёт грубые координаты (или произвольные) → сервер прогоняет layered-layout с учётом вложенных контейнеров (compound-узлы) → перезаписывает mxGeometry.
  • Принцип: «модель объявляет логическую структуру, сервер считает пиксели».

5. Quality-warnings в линтере (замена vision-self-check, без рендера)

Вычислимо геометрией по XML:

  • пересечение bounding-box'ов фигур;
  • edge, проходящий сквозь bbox фигуры, не являющейся его source/target;
  • наложение edge на edge (совпадающие сегменты);
  • интервал между соседними фигурами < 150px (warning); подпись явно шире фигуры;
  • выход элементов за границы страницы / отрицательные координаты.

Warnings (не errors) возвращаются в результате create/update → модель чинит сама. В description — указание: «исправь warnings и повтори, максимум 2 итерации».


Приложение: исходный материал для guide-секций

layout — числовые эвристики (превращают «сделай красиво» в проверяемые правила)

  • Минимальный горизонтальный интервал между фигурами 200–220px, вертикальный между рядами/лейнами 250px; вспомогательные сервисы (мониторинг, DLQ) — ниже основного потока с зазором 280px+.
  • Координаты кратны 10 (сетка); базовые размеры: прямоугольник 140×60, ромб 140×80, круг 60×60; иконки облаков 78×78 основные / 65×65 вторичные, шрифт 12px.
  • Основной поток — слева направо, одна главная ось; ≤3–4 лейна/зоны; одна иконка на сервис.
  • ≤1 изгиб на edge (в идеале 0); edge не пересекает bbox чужой фигуры; два edge не лежат друг на друге.
  • Явные exitX/exitY/entryX/entryY для всех непрямых связей — иначе ортогональная авто-маршрутизация ведёт линии сквозь фигуры. Вертикальная связь: exitX=0.5;exitY=1entryX=0.5;entryY=0. Распределение точек при 2+ связях на узел: 0.25 / 0.5 / 0.75.
  • Базовая style-строка edge:
    edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;exitX=1;exitY=0.5;entryX=0;entryY=0.5;
    
  • Подписи edge: 1–2 слова максимум, labelBackgroundColor=#F5F5F5;fontSize=11;; не подписывать очевидный поток (Lambda→DynamoDB не нужен «Write»); лучше нумерация стадий (1,2,3), чем много подписей.
  • Внутри контейнера ≥30px отступ детей от рамки; стрелки — на задний слой (в XML раньше фигур); ≥20px зазор между стрелкой и подписью.
  • Семантика линий: сплошная = основной/sync поток; dashed=1 = async; красная штриховая strokeColor=#DD344C = error-path.
  • Выравнивание по центру родителя считать: child.x = parent.center_x - child.width/2, не на глаз.

containers — группы

  • Все группы: container=1;dropTarget=1;fillColor=none (цветная заливка группы — мгновенный признак «AI-generated»).
  • Дети: parent="<groupId>", координаты относительно родителя.
  • Edge между ячейками разных контейнеров: parent="1", иначе обрезается.
  • spacingLeft=40;spacingTop=-4; — чтобы заголовок группы не налезал на иконку группы.
  • Swimlane: swimlane;horizontal=0;startSize=110; — лейны с parent="1", дети внутри.

icons-aws — два взаимоисключающих паттерна (причина №1 битых иконок)

Паттерн Style strokeColor Для чего
Service-level shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.<name> #ffffff (обязательно) основные иконки сервисов (цветной квадрат + белый глиф)
Resource-level shape=mxgraph.aws4.<name> none (обязательно) суб-ресурсы (силуэты)

Полный шаблон service-level (для PNG-экспорта обязателен fillColor, иначе иконка невидима):

sketch=0;outlineConnect=0;fontColor=#232F3E;fillColor=<категорийный>;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.<NAME>

Категорийная палитра fillColor: Compute #ED7100, Networking #8C4FFF, Database #C925D1, Storage #3F8624, Security #DD344C, Integration #E7157B, AI/ML #01A88D.

Gotcha-ребрендинги (имена стенсилов отстают от AWS):

Сервис resIcon Почему
Amazon OpenSearch elasticsearch_service переименован в 2021
Amazon EventBridge eventbridge был CloudWatch Events
VPC Peering peering НЕ vpc_peering (пустой квадрат)
Amazon MSK managed_streaming_for_kafka НЕ msk
IAM Identity Center single_sign_on НЕ iam_identity_center

Blocklist битых → замены: dynamodb_tabledynamodb; general_saml_tokentraditional_server; kinesis_data_streams — ненадёжен. Неизвестный сервис → generic resIcon=mxgraph.aws4.general_AWScloud с подписью; безымянный цветной прямоугольник запрещён.

Групповые стенсилы: AWS Cloud group_aws_cloud_alt, VPC group_vpc2, Subnet group_security_group, Account group_account; сабнеты — shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_public_subnet;.

icons-azure — image-style вместо shape-style

shape=mxgraph.azure2.* рендерится не во всех хостах. Использовать image-style:

image;aspect=fixed;html=1;image=img/lib/azure2/<категория>/<Icon>.svg;

Известные рабочие пути: networking/Front_Doors.svg, app_services/API_Management_Services.svg, databases/Azure_Cosmos_DB.svg, identity/Managed_Identities.svg, management_governance/Monitor.svg, devops/Application_Insights.svg. Фолбэк для устойчивости — абсолютный URL: https://raw.githubusercontent.com/jgraph/drawio/dev/src/main/webapp/img/lib/azure2/<категория>/<Icon>.svg.

skeleton — каркас и формы XML

См. справку в #423 (канонический каркас, три формы входа, decode-chain). В guide продублировать кратко.


Где в коде

  • packages/mcp/src/tool-specs.ts — descriptions + новые инструменты drawio_guide, drawio_shapes;
  • packages/mcp/src/lib/drawio-xml.ts — quality-warnings (расширение линтера из #423);
  • packages/mcp/src/lib/drawio-layout.ts — обвязка elkjs (mxGraphModel → ELK-граф → обратно);
  • данные: packages/mcp/data/drawio-shape-index.json.gz + guide-контент (markdown-файлы или константы).

Критерии приёмки

  1. drawio_shapes("lambda") возвращает валидную style-строку mxgraph.aws4-иконки с корректным паттерном (service/resource) и размерами; запрос по стенсилу из blocklist возвращает замену.
  2. drawio_guide отдаёт каждую секцию; размер одной секции ≤ ~4KB (не раздувать контекст).
  3. drawio_create(layout:"elk") на графе из 10+ узлов с грубыми координатами выдаёт диаграмму без пересечений bbox и без warnings.
  4. Каждый quality-warning покрыт тестом (позитив/негатив), warnings не блокируют запись.
  5. elkjs — единственная новая рантайм-зависимость; браузер/нативные бинари не появились.

Внешние референсы

Вне скоупа

  • Семантический graph-JSON, ID-based правки, mermaid — стадия 3 (#425).
  • Vision/VLM-проверки — не делаем (нет рендера на беке).
# ТЗ: научить агента генерировать качественные диаграммы Зависит от #423 (стадия 1: CRUD `drawio_get/create/update`). ## Цель После стадии 1 агент умеет создавать диаграммы, но качество — «сырое AI»: угаданные имена стенсилов рендерятся пустыми квадратами, ручные координаты дают налезания и edge сквозь фигуры, цветные заливки групп. Стадия 2 закрывает это правилами и справочными инструментами — **без vision-цикла и без рендеринга** (всё детерминированно, математикой по XML). ## Состав ### 1. Хард-правила в description инструментов `drawio_create`/`drawio_update` Сжатый блок правил прямо в описании (паттерн jgraph/drawio-mcp — правила инжектятся в tool description, модель видит их в момент вызова): - обязательные `id=0/1`; ячейка `vertex` xor `edge`; у edge — дочерний `<mxGeometry>`; без XML-комментариев; уникальные id; - `html=1` в стилях + XML-экранирование в `value`; перенос строки — `&#xa;`, не `\n`; - контейнеры **прозрачные**: `fillColor=none;container=1;dropTarget=1;` — дети с `parent=<groupId>` и координатами относительно родителя; edge между контейнерами — `parent="1"`; - `adaptiveColors="auto"` на `mxGraphModel` (тёмная тема Docmost бесплатно; цвета `strokeColor/fillColor/fontColor="default"` авто-адаптируются); - «не угадывай `shape=mxgraph.*` — сначала `drawio_shapes`». ### 2. `drawio_guide(section?)` — справочник по запросу Progressive disclosure: полный authoring-справочник не раздувает контекст, читается по секциям: `skeleton` | `layout` | `containers` | `icons-aws` | `icons-azure`. **Весь исходный материал секций — в Приложении ниже**, писать guide прямо из этой ишью. ### 3. `drawio_shapes(query, category?, limit?)` — verified shape-каталог - Бандлим shape-index из `jgraph/drawio-mcp` (`shape-search/search-index.json`, ~4.7MB / ~10 400 шейпов, Apache-2.0; сжать в `.json.gz`). Формат записи: `{style, w, h, title, tags, type}`. - У jgraph есть `shape-search/generate-index.js`, перестраивающий индекс из `app.min.js` релиза draw.io — каталог не протухает; задокументировать процедуру обновления. - Поиск: подстрока + tags + fuzzy; возвращает точную style-строку + дефолтные `w/h` + категорию. - Blocklist заведомо битых стенсилов с заменами (см. Приложение) — прямо в данных. Это фикс «пустых квадратов» №1. ### 4. `layout: "elk"` — параметр на `drawio_create`/`drawio_update` - Зависимость **elkjs** (EPL-2.0, чистый JS-порт Eclipse ELK, работает в Node без нативных зависимостей и без браузера): https://www.npmjs.com/package/elkjs - Модель даёт грубые координаты (или произвольные) → сервер прогоняет layered-layout с учётом вложенных контейнеров (compound-узлы) → перезаписывает `mxGeometry`. - Принцип: «модель объявляет логическую структуру, сервер считает пиксели». ### 5. Quality-warnings в линтере (замена vision-self-check, без рендера) Вычислимо геометрией по XML: - пересечение bounding-box'ов фигур; - edge, проходящий сквозь bbox фигуры, не являющейся его source/target; - наложение edge на edge (совпадающие сегменты); - интервал между соседними фигурами < 150px (warning); подпись явно шире фигуры; - выход элементов за границы страницы / отрицательные координаты. Warnings (не errors) возвращаются в результате `create`/`update` → модель чинит сама. В description — указание: «исправь warnings и повтори, максимум 2 итерации». --- ## Приложение: исходный материал для guide-секций ### `layout` — числовые эвристики (превращают «сделай красиво» в проверяемые правила) - Минимальный горизонтальный интервал между фигурами **200–220px**, вертикальный между рядами/лейнами **250px**; вспомогательные сервисы (мониторинг, DLQ) — ниже основного потока с зазором 280px+. - Координаты кратны 10 (сетка); базовые размеры: прямоугольник 140×60, ромб 140×80, круг 60×60; иконки облаков 78×78 основные / 65×65 вторичные, шрифт 12px. - Основной поток — слева направо, одна главная ось; ≤3–4 лейна/зоны; одна иконка на сервис. - **≤1 изгиб на edge** (в идеале 0); edge не пересекает bbox чужой фигуры; два edge не лежат друг на друге. - Явные `exitX/exitY/entryX/entryY` для всех непрямых связей — иначе ортогональная авто-маршрутизация ведёт линии сквозь фигуры. Вертикальная связь: `exitX=0.5;exitY=1` → `entryX=0.5;entryY=0`. Распределение точек при 2+ связях на узел: 0.25 / 0.5 / 0.75. - Базовая style-строка edge: ``` edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;exitX=1;exitY=0.5;entryX=0;entryY=0.5; ``` - Подписи edge: 1–2 слова максимум, `labelBackgroundColor=#F5F5F5;fontSize=11;`; **не подписывать очевидный поток** (Lambda→DynamoDB не нужен «Write»); лучше нумерация стадий (1,2,3), чем много подписей. - Внутри контейнера ≥30px отступ детей от рамки; стрелки — на задний слой (в XML раньше фигур); ≥20px зазор между стрелкой и подписью. - Семантика линий: сплошная = основной/sync поток; `dashed=1` = async; красная штриховая `strokeColor=#DD344C` = error-path. - Выравнивание по центру родителя считать: `child.x = parent.center_x - child.width/2`, не на глаз. ### `containers` — группы - Все группы: `container=1;dropTarget=1;fillColor=none` (цветная заливка группы — мгновенный признак «AI-generated»). - Дети: `parent="<groupId>"`, координаты **относительно родителя**. - Edge между ячейками разных контейнеров: `parent="1"`, иначе обрезается. - `spacingLeft=40;spacingTop=-4;` — чтобы заголовок группы не налезал на иконку группы. - Swimlane: `swimlane;horizontal=0;startSize=110;` — лейны с `parent="1"`, дети внутри. ### `icons-aws` — два взаимоисключающих паттерна (причина №1 битых иконок) | Паттерн | Style | strokeColor | Для чего | |---|---|---|---| | Service-level | `shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.<name>` | `#ffffff` (обязательно) | основные иконки сервисов (цветной квадрат + белый глиф) | | Resource-level | `shape=mxgraph.aws4.<name>` | `none` (обязательно) | суб-ресурсы (силуэты) | Полный шаблон service-level (для PNG-экспорта обязателен `fillColor`, иначе иконка невидима): ``` sketch=0;outlineConnect=0;fontColor=#232F3E;fillColor=<категорийный>;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.<NAME> ``` Категорийная палитра fillColor: Compute `#ED7100`, Networking `#8C4FFF`, Database `#C925D1`, Storage `#3F8624`, Security `#DD344C`, Integration `#E7157B`, AI/ML `#01A88D`. Gotcha-ребрендинги (имена стенсилов отстают от AWS): | Сервис | resIcon | Почему | |---|---|---| | Amazon OpenSearch | `elasticsearch_service` | переименован в 2021 | | Amazon EventBridge | `eventbridge` | был CloudWatch Events | | VPC Peering | `peering` | НЕ `vpc_peering` (пустой квадрат) | | Amazon MSK | `managed_streaming_for_kafka` | НЕ `msk` | | IAM Identity Center | `single_sign_on` | НЕ `iam_identity_center` | Blocklist битых → замены: `dynamodb_table` → `dynamodb`; `general_saml_token` → `traditional_server`; `kinesis_data_streams` — ненадёжен. Неизвестный сервис → generic `resIcon=mxgraph.aws4.general_AWScloud` **с подписью**; безымянный цветной прямоугольник запрещён. Групповые стенсилы: AWS Cloud `group_aws_cloud_alt`, VPC `group_vpc2`, Subnet `group_security_group`, Account `group_account`; сабнеты — `shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_public_subnet;`. ### `icons-azure` — image-style вместо shape-style `shape=mxgraph.azure2.*` рендерится не во всех хостах. Использовать image-style: ``` image;aspect=fixed;html=1;image=img/lib/azure2/<категория>/<Icon>.svg; ``` Известные рабочие пути: `networking/Front_Doors.svg`, `app_services/API_Management_Services.svg`, `databases/Azure_Cosmos_DB.svg`, `identity/Managed_Identities.svg`, `management_governance/Monitor.svg`, `devops/Application_Insights.svg`. Фолбэк для устойчивости — абсолютный URL: `https://raw.githubusercontent.com/jgraph/drawio/dev/src/main/webapp/img/lib/azure2/<категория>/<Icon>.svg`. ### `skeleton` — каркас и формы XML См. справку в #423 (канонический каркас, три формы входа, decode-chain). В guide продублировать кратко. --- ## Где в коде - `packages/mcp/src/tool-specs.ts` — descriptions + новые инструменты `drawio_guide`, `drawio_shapes`; - `packages/mcp/src/lib/drawio-xml.ts` — quality-warnings (расширение линтера из #423); - `packages/mcp/src/lib/drawio-layout.ts` — обвязка elkjs (mxGraphModel → ELK-граф → обратно); - данные: `packages/mcp/data/drawio-shape-index.json.gz` + guide-контент (markdown-файлы или константы). ## Критерии приёмки 1. `drawio_shapes("lambda")` возвращает валидную style-строку `mxgraph.aws4`-иконки с корректным паттерном (service/resource) и размерами; запрос по стенсилу из blocklist возвращает замену. 2. `drawio_guide` отдаёт каждую секцию; размер одной секции ≤ ~4KB (не раздувать контекст). 3. `drawio_create(layout:"elk")` на графе из 10+ узлов с грубыми координатами выдаёт диаграмму без пересечений bbox и без warnings. 4. Каждый quality-warning покрыт тестом (позитив/негатив), warnings не блокируют запись. 5. elkjs — единственная новая рантайм-зависимость; браузер/нативные бинари не появились. ## Внешние референсы - Shape-index + генератор + xml/style-reference: https://github.com/jgraph/drawio-mcp (Apache-2.0) - elkjs: https://github.com/kieler/elkjs (EPL-2.0) - Источник AWS-паттернов/gotcha: https://github.com/vidanov/aws-architecture-diagram-skill + статья https://dev.to/aws-builders/i-built-a-skill-that-makes-ai-generated-aws-diagrams-actually-usable-43ep - Источник Azure image-style: https://github.com/thomast1906/github-copilot-agent-skills (`.github/skills/drawio-mcp-diagramming/`) - Официальные правила генерации: https://www.drawio.com/docs/reference/diagram-generation/ ## Вне скоупа - Семантический graph-JSON, ID-based правки, mermaid — стадия 3 (#425). - Vision/VLM-проверки — не делаем (нет рендера на беке).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#424