Repository navigation
RU Architecture
Полный русский перевод архитектурного контракта. Для проверки актуальности поведения сверяйте разделы с исходной английской версией и текущей реализацией.
CADYX изначально спроектирован для работы ИИ-агентов: они используют версионированный API и общую Command System Core. Браузер — полноэкранный просмотрщик для чтения; агенты создают проекты и редактируют модели через Agent API, а клиенты-человеки могут использовать защищённые блокировкой маршруты Web API.
Дерево объектов находится во вкладке Geometry; просмотр файлов проекта доступен с учётом активности и блокировки агента. Браузер не обращается напрямую к геометрическому ядру и не владеет CAD-состоянием. Он показывает модель в реальном времени и одну строку с текущим действием/результатом, не выводя поток исходных команд или стенограмму.
Встроенная панель Revopoint отображает текущий кадр глубины либо сохранённый ASCII PLY только с точками из папки workspace. Сохранённые облака отрисовываются непосредственно точками через read-only-маршрут /api/v1/scanner/point-cloud; превью не преобразует их в треугольную сетку и не утверждает метрический масштаб.
Адаптер провайдера (будущий) -> Agent Runtime -> CADYX Core -> Command System -> Document
Внешний агент --------------------------> Agent API -> CADYX Core -> Project Workspace
Браузер --------------------------------> Web API -> CADYX Core -> Project Workspace
| Адаптер Geometry Kernel
+-> брокер событий -> SSE -> Браузер
Локальный прототип использует модули стандартной библиотеки Python для Core, Agent Runtime и HTTP-сервера, а интерфейс — обычные HTML/CSS/JavaScript. Текущая среда Windows x64 использует Python 3.15, нативный OCCT 8.0.1 и CPU-сборку Open3D 0.20.0 через собранные проектом мосты C ABI (native/, cadyx/native_kernel.py, cadyx/native_scan.py), независимые от ABI расширений Python.
Читатель STEP OCCT подключён через TKDESTEP; остальные runtime-DLL закреплены хешами в scripts/occt-runtime-lock.json и устанавливаются через scripts/setup-runtime.ps1. Open3D обрабатывает очистку облаков точек PLY, реконструкцию поверхностей screened Poisson и упрощение сеток. Обработчик ограничивает вычисления четырьмя потоками и 100000 точками. Для чтения PLY и предварительной обработки используются тензорные API; затем облако преобразуется в legacy API для screened Poisson, поскольку тензорного аналога нет. Очистка и упрощение треугольных сеток используют legacy API сеток Open3D.
Браузер получает от Core сетки тел и примитивы эскизов в именованных рабочих плоскостях XY/XZ/YZ и CUSTOM/FACE через тот же ортографический canvas с осью Z вверх, что и для PLY из папок. Чтобы сохранять отзывчивость браузера, большие PLY для отображения дискретизируются.
Снимки активности Core и события SSE сохраняют для клиентов Agent API реальные этапы команд, твердотельных операций, камеры и нативного сканирования. Интерфейс показывает одну карточку прогресса: текущий статус, прогресс/ETA, текущее или последнее реальное действие агента, текущую/последнюю завершённую задачу и историю завершённых/ошибочных действий — новые сначала, с локальным временем завершения. Планируемые этапы и будущая очередь доступны по Agent API, но браузер их скрывает. Активность хранится в памяти процесса; отчёты dashboard сохраняются строками по проектам в runtime SQLite-базе workspace. Отчёт и глобальная ревизия работы фиксируются одной транзакцией. При первом старте без базы старое состояние dashboard в JSON импортируется.
Внешние агенты публикуют состояние dashboard через Agent API. Данные телеметрии оборудования сейчас недоступны. См. Agent Runtime в оригинале, Viewport API, контракт импорта сканов, контракт импорта STEP и настройку среды.
Для текущих версий проекта и документа Workspace читает и проверяет разобранный снимок напрямую, без копии для миграции. Разделяемые записями тела, элементов и истории данные B-rep хранятся один раз в скрытых файлах проекта по content hash; перед валидацией и ответом API ссылки раскрываются. Подробнее — формат проекта.
Загрузка команд/preview использует число и байтовое смещение последней зафиксированной записи истории, не разбирая заново журнал. При сохранении добавляются только новые записи, а полная инспекция проекта проверяет зафиксированную часть журнала. Каждая команда выполняется на изолированном документе и добавляет в историю только свои записи. Уже проверенный документ повторно не валидируется на границе сохранения.
cadyx/core.py — граница приложения для обоих API. ProjectWorkspace хранит по одному версионированному project.json в каталоге проекта с понятным именем. Имя для новых проектов очищается для файловой системы; при совпадении добавляется числовой суффикс. Уже зарегистрированные каталоги сохраняют имена. Локальная метка .cadyx-project-id удерживает UUID доступным даже при повреждённом project.json. UUID остаётся идентификатором API и блокировки, старые каталоги, названные UUID, остаются читаемыми.
Файл проекта содержит метаданные, состояние документа, ревизию и историю команд. При загрузке явные последовательные миграции cadyx/migrations.py применяются к изолированной копии только если оболочка проекта или вложенный документ старше текущей версии. Актуальный снимок проверяется без миграционной копии; чтение не переписывает файлы. См. контракт миграции.
Каждая принятая команда меняет изолированный документ и атомарно заменяет project.json; ревизия документа и успешная запись истории фиксируются вместе. Read-only-списки, инспекция документа и рендер viewport используют последний атомарно сохранённый снимок, поэтому перезагруженная страница может восстановить модель, пока агент удерживает блокировку для следующей команды. Обе конечные точки списка проектов принимают на месте каждый непосредственный каталог без символьной ссылки и записи проекта, публикуя устойчивую UUID-метку и пустой project.json; существующие пользовательские файлы сохраняются.
Каталог projects/ содержит runtime-данные и игнорируется Git, кроме .gitkeep. Исходные сканы, сетки, CAD-файлы, изображения, измерения и референсы считаются пользовательскими данными: при обычной разработке их нельзя перезаписывать или удалять.
Agent API может загрузить STEP или PLY-файл маршрутом POST /api/v1/agent/projects/{id}/files/{name} (application/octet-stream, максимум 64 МиБ). Загрузка допускается в свободный проект, только с непосредственным именем .step, .stp или .ply, и не заменяет существующий файл.
import_project_scan обрабатывает помещённый в проект PLY в редактируемую треугольную сетку и сохраняет имя/хеш источника, чтобы последующие изменения параметров заново обрабатывали именно исходный файл. Локальный MCP-адаптер предоставляет загрузку STEP и PLY через cadyx_upload_project_step и cadyx_upload_project_scan: оба читают локальный обычный файл и передают его байты, а HTTP-хост не раскрывает произвольные пути клиента.
Для временных референсов реконструкции DELETE /api/v1/agent/projects/{id}/files/{name} удаляет только непосредственный STEP из свободного проекта и отказывается это делать, пока актуальный import_step продолжает использовать файл. MCP-команда cadyx_remove_staged_step удаляет референс лишь после удаления тела; исходный локальный файл не меняется.
POST /api/v1/agent/projects/{id}/copy-files рекурсивно копирует пользовательские файлы из другого свободного проекта, исключая метаданные и runtime-состояние .cadyx-*; сначала проверяются конфликты, перезапись запрещена. MCP-эквивалент — cadyx_copy_project_files. POST /api/v1/agent/projects/{id}/prune-files рекурсивно удаляет пользовательские файлы, сохраняя указанные прямые имена. Он требует свободный проект с пустым документом, сохраняет метаданные проекта и .cadyx-*, сообщает хеши оставшихся файлов. MCP-эквивалент — cadyx_prune_project_files. К файловым маршрутам применяется политика аутентификации хоста.
POST /api/v1/agent/projects принимает select: false, чтобы создать проект, не меняя выбор браузера, например, для загрузки файла, пока агент работает с другим проектом.
CadyxCore._project_availability объединяет снимок блокировки и состояние выполняющейся операции. Сохранённая активность dashboard остаётся отдельным сигналом для интерфейса/отчётов, но не участвует в допуске команды Core. Политика доступности — единая граница Core для чтения и записи проекта, управления файлами, выбора ресурсов и деструктивных операций. Отсутствующая, занятая или неизвестная блокировка не считается свободной.
Read-only-инспекция и списки используют неблокирующий снимок lease и возвращают последний атомарно сохранённый проект, даже пока работает писатель. Новую блокировку на изменение можно получить лишь для свободного проекта без требования восстановления и без выполняющейся операции; команда всё равно должна получить допустимую блокировку владельца и ревизию. Уже принятая к исполнению с корректной блокировкой команда остаётся атомарной, даже если блокировка истечёт во время работы.
Управление файлами и разрушительные действия требуют FREE, отсутствия восстановления блокировки и активной операции; в противном случае сохраняются существующие ошибки PROJECT_BUSY или PROJECT_LOCKED.
Выбор workspace — подсказка процессу браузера, а не способ определить владельца или направить команду. Core проверяет только целевой проект: он должен быть FREE, без требования восстановления и выполняющихся операций; можно выбрать проект с незавершённым workflow, если в данный момент между командами. Разрешено переключиться с занятого текущего проекта и выбрать проект, пока у других выполняются workflows. Создание проекта с выбором не ждёт workflows остальных проектов; select: false сохраняет текущий выбор. Разные чаты должны явно передавать project_id при операциях с проектом. Только отдельная блокировка проекта предотвращает одновременное редактирование двумя сессиями.
В боковой базе .cadyx-leases.sqlite3 у каждого проекта хранится одна долговечная блокировка, общая для локальных процессов хоста, использующих один workspace. Запись содержит project_id, owner_type, owner_id, время получения и heartbeat, непрозрачный lease_id и тайм-аут, выбранный при получении. Типы владельца: agent, human, system; состояния включают FREE, AI_LOCKED, HUMAN_LOCKED, SYSTEM_LOCKED. Heartbeat с хоста, настроенного на иной тайм-аут, не меняет исходный срок блокировки.
Все записи документа проходят через CadyxCore.execute_command и требуют текущий ID блокировки с подходящим для данного API владельцем-человеком или агентом. Транзакция SQLite BEGIN IMMEDIATE удерживает межпроцессную блокировку ОС проекта на время проверки lease, загрузки документа, выполнения команды, проверки и атомарной замены project.json. Получение, heartbeat, освобождение, инспекция и восстановление используют ту же блокировку. У разных проектов отдельные базы, они остаются независимыми.
Если занятый проект не освободился за пять секунд ожидания, операция возвращает PROJECT_BUSY (HTTP 409). Её можно повторить; текущую команду не прерывают.
Истечение heartbeat помечает блокировку устаревшей, но не освобождает проект автоматически. Для восстановления Core получает ту же блокировку, загружает последний атомарно сохранённый проект, проверяет документ и геометрию и лишь затем удаляет просроченную запись. Команда, начатая с корректной блокировкой, может завершиться после её истечения; восстановление не пересечётся с сохранением.
При аварийном завершении процесса блокировка SQLite снимается, но зафиксированный lease сохраняется, в том числе после перезапуска сервера. После истечения срока всё равно требуется процедура восстановления. Сбой до атомарной замены оставляет прежнюю ревизию; сбой после — полный новый документ и историю. Клиент мог не получить ответ, поэтому перед повторным запуском команды после потери связи проверьте сохранённую историю.
Механизм рассчитан на взаимодействующие актуальные хосты CADYX на одной локальной машине и локальной файловой системе. Перед обновлением остановите старые хосты: прежние версии не поддерживают текущий протокол остановки агента, а самые ранние не имеют общих межпроцессных блокировок. Не удаляйте и не заменяйте базы координации или журналы при работающих хостах. Резервное копирование/перенос выполняйте при остановленных хостах; боковые файлы координации — отдельные runtime-данные, не часть переносимого project.json. Прямая запись сторонними процессами и сетевые файловые системы вне контракта.
Доставка SSE ограничена процессом. Лёгкий периодический опрос обновлений браузером автоматически показывает подтверждённые изменения проекта и файлов workspace, внесённые другим взаимодействующим хостом.
Внешний агент вызывает POST /api/v1/agent/projects/{id}/stop, передавая lease_id. Сначала Core фиксирует ограждение для токена в .cadyx-agent.sqlite3 независимо от транзакции документа/блокировки. Команда проходит в исполнение, когда под защитой проекта проверяет это ограждение: команды, допущенные до его установки, могут завершиться; последующие команды с тем же токеном получают AGENT_STOPPING.
Затем stop получает ту же блокировку проекта, проверяет, что этот токен владеет текущей агентской блокировкой, заново загружает и проверяет сохранённый документ и геометрию и освобождает блокировку. Это позволяет безопасно остановить и просроченную блокировку агента. Запрос stop со старым токеном не может снять человеческую блокировку либо блокировку нового владельца. Команды принудительно не прерываются.
Успешный ответ содержит stopped: true, project, document, history и ставшую свободной блокировку lock; ревизия и история отражают последнюю целиком атомарно сохранённую версию. При ошибке проверки блокировка и долговечное ограждение сохраняются. Для занятого проекта через пять секунд может вернуться PROJECT_BUSY, при этом ограждение остаётся активным; повторите stop с тем же токеном. При сбое хоста ограждение сохраняется. Если ответ на stop потерян, проинспектируйте проект: свободная блокировка либо блокировка нового владельца означает, что прежний токен уже не владелец. Повтор stop не снимет блокировку нового владельца. Восстановление истёкшей блокировки остаётся доступным и также проверяет сохранённое состояние.
Чтобы продолжить работу (или начать её с защитой ревизии), проинспектируйте проект и вызовите POST /api/v1/agent/projects/{id}/resume, передав owner_id и целочисленную expected_revision. Внутри одной блокировки проекта Core проверяет сохранённое состояние, сверяет ревизию, получает новую агентскую блокировку и возвращает resumed: true, lease и полный снимок инспекции. Активную блокировку нельзя отобрать; сначала требуется остановить/восстановить истёкшую. Если человек отредактировал модель после инспекции, возвращается REVISION_CONFLICT: повторно инспектируйте проект и пересмотрите следующую команду. Resume не выполняет команды и не восстанавливает прежний снимок модели.
Каждая команда на возобновлённой блокировке требует expected_revision. При отсутствии/недопустимом значении возвращается VALIDATION_ERROR, при изменившейся ревизии — REVISION_CONFLICT до исполнения. После каждого успешного ответа обновляйте ожидаемую ревизию. Если ответ команды потерян, перед повтором проверьте ревизию и сохранённую историю, чтобы установить, зафиксировалась ли команда; автоматически повторять её нельзя. Повтор с той же ожидаемой ревизией не может создать второе успешное сохранение.
Существующие операции получения блокировки /leases и выполнения команд остаются совместимыми: для таких lease expected_revision необязательна и наличие поля не обязательно проверяется. Новым агентам для защищённой работы следует использовать /resume.
Служебная SQLite-база хранит только ограждения токенов и флаги защиты ревизий; новая возобновлённая блокировка очищает предыдущие токены. Переносимую схему проекта/документа это не меняет, миграция формата не нужна. Пока хосты работают, сохраняйте обе SQLite-базы координации. UI-кнопки остановки находятся вне этого этапа API.
cadyx.agent_runtime.AgentRuntime выполняет для одного существующего проекта цикл вызова провайдера и инструментов, независимый от поставщика модели. Адаптер реализует небольшой протокол AgentProvider.complete(messages, tools) и преобразует нативные форматы запроса/ответа в типы CADYX AgentMessage, AgentToolSpec, AgentResponse. В Core нет SDK провайдера и настроек под конкретного поставщика.
Среда предоставляет провайдеру три инструмента: инспекцию текущего проекта, чтение сцены viewport и исполнение одной команды Command System. Для каждой команды Runtime получает новую агентскую блокировку, проверяет последнюю осмотренную ревизию, поддерживает heartbeat только во время команды и в finally освобождает блокировку проверенной остановкой агента.
Во время ожидания провайдера и read-only-инструментов блокировка не удерживается; явная инспекция обновляет ожидаемую ревизию. Конкурирующий редактор или изменение ревизии возвращает структурированный конфликт и не освобождает чужую блокировку. Число раундов вызова инструментов и их суммарное количество ограничены.
Неожиданная ошибка команды/очистки сохраняет исходную ошибку и запускает попытку проверенно освободить блокировку. При ошибке только провайдера освобождать нечего.
Runtime — внутрипроцессный Python API cadyx.AgentRuntime, а не интеграция с конкретным провайдером, HTTP-маршрут или фоновая служба. До запуска Runtime проект создаётся существующим Core или Agent API. См. модуль Agent Runtime и целевые тесты.
Провайдеронезависимый Agent Runtime и локальная MCP-поверхность распознают неизвестную команду Command System и возвращают CAPABILITY_MISSING. Агент может проверить постоянный реестр возможностей workspace, предложить новую возможность, выполнить её в изолированном Document с активным геометрическим ядром, зарегистрировать успешный результат, запустить способность в целевой модели и при необходимости восстановить предыдущую контрольную точку реестра.
Операции доступны в Agent API по /api/v1/agent/projects/{id}/capabilities; контракты команд и зарегистрированные способности возвращаются через GET /api/v1/agent/capabilities.
Реестр находится в корне workspace: .cadyx-capabilities.sqlite3. Запись возможности включает постоянный ID, заголовок и описание, версию MAJOR.MINOR.PATCH, закрытые схемы входа/выхода, привязки полей к результатам команд, зависимости, декларативные шаги Command System, тестовые данные/доказательства, хеш актуального контракта команды и имя вызова MCP. Перед заменой способности снимаются контрольные точки SQLite; cadyx_rollback_capability возвращает предыдущую версию. Для повторного использования доступны только совместимые записи в состоянии ready.
Каждая живая команда внутри способности отдельно получает и освобождает блокировку агента с защитой ревизии. Поэтому завершённые шаги остаются сохранёнными и видимыми, если следующий шаг завершится ошибкой.
Инструкции модельного агента по умолчанию сначала предлагают испытанную композицию. Если алгоритму не хватает кода, вместо неё используется ограниченный путь разработки исходников. Агент может читать только разрешённые cadyx/*.py, tests/test_*.py и Markdown-файлы. Предложение привязано к ревизии через SHA-256 каждого файла; ограничения: не более 12 файлов, 256 КиБ на файл, 2 МиБ суммарно и восемь уже существующих модулей tests.test_*. Нельзя добавлять зависимости, менять runtime/нативные бинарные файлы, данные проектов или конфигурацию.
Кандидатные файлы и выбранные тесты копируются во временное дерево. В Windows изолированный интерпретатор Python запускается через CreateProcessW с PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES в одноразовом именованном AppContainer без сетевых возможностей. CADYX выдаёт SID пакета только чтение каталогов кандидата и среды, а единственной папкой для записи задаёт профильный Temp AppContainer. После завершения процесса временные разрешения ACL и профиль удаляются.
Через явный список дескрипторов процесс наследует только дескриптор файла диагностики с правом записи. Для него создаётся Job Object на один процесс; лимит времени — 180 секунд, памяти — 2 ГиБ. Окружение разрешает только стандартные переменные среды Windows. Временные папки Python наследуют ACL профиля AppContainer, поэтому вложенные тесты могут создавать scratch-файлы, не получая доступа к кандидатным исходникам.
Если создание AppContainer, настройка ACL, ограничения процесса или очистка не прошли, операция закрывается с ошибкой SOURCE_SANDBOX_UNAVAILABLE; кандидат никогда не запускается в обычном режиме. Регрессионная проверка безопасности Windows удостоверяет, что запись временных scratch-файлов работает, но sentinel хоста нельзя читать/менять и исходящие сетевые подключения не проходят.
Только после того, как как минимум один выбранный тест завершится успешно без ошибок и падений, CADYX сохраняет долговечную контрольную точку в .cadyx-source-extensions.sqlite3 и атомарно применяет патч, сверяя исходные хеши. Ошибка при частичном применении откатывает изменения. Откат восстанавливает файлы только если текущий хеш каждого совпадает с хешем применённой версии; изменения человека приводят к SOURCE_REVISION_CONFLICT.
Agent API предоставляет чтение, список, разработку и откат по /api/v1/agent/projects/{id}/source-extensions и /api/v1/agent/source-files/read; Agent Runtime и локальный MCP дают соответствующие инструменты. Успешная установка исходников через HTTP назначает управляемый перезапуск хоста после возврата результата. Модель проекта сохраняется и доступна для инспекции после перезапуска.
Это ограниченный путь обновления доверенных исходников, а не произвольный процесс или shell. Изменения, которым нужна новая внешняя зависимость или нативная библиотека, находятся вне его области.
Этапы жизненного цикла возможностей используют существующий поток SSE agent.activity. Браузер получает обновления разработки через тот же поток: название операции, результат тестов и итог интеграции. Текущие версии исходных расширений и статус их жизненного цикла сохраняются при перезапуске хоста.
Тесты: саморазвивающиеся возможности, жизненный цикл Agent Runtime, Agent API.
add_sketch_internal_involute_gear создаёт замкнутую границу внутреннего зубчатого венца как редактируемый замкнутый периодический сплайн эскиза XY через вычисленные точки. В gear_parameters возвращаются модуль, число зубьев, угол давления, центр, поворот и боковой зазор.
Для внешней и внутренней шестерни при выдавливании границы рёбер OCCT используют периодические B-spline, проходящие через те же точки. Эскиз хранит один замкнутый сплайн и исходные точки, не цепочку отрезков; изменение параметров заново генерирует сплайн, а старые эскизы из линий преобразуются при следующем параметрическом перестроении.
Команда требует существующую внешнюю окружность и отсутствие других профилей в эскизе, чтобы extrude_sketch мог сохранить кольцо как один внешний контур и один внутренний зубчатый. Используются стандартные радиусы внутренней шестерни без смещения исходного профиля: pitch = module * teeth / 2, tip = pitch - module, root = pitch + 1.25 * module. Контрольные точки строятся по математической эвольвенте боковой поверхности зуба и окружным сегментам вершин/оснований.
Ребро OCCT — периодический интерполяционный B-spline через эти точки, не точная аналитическая эвольвента и не аппроксимация с сертифицированной точностью. Применяется та же проверка минимального числа зубьев против подрезания, что и для внешнего генератора. Выдавливание создаёт проверенную редактируемую B-rep OCCT с полостью по периодическому B-spline.
Read-only-маршрут POST /api/v1/agent/projects/{id}/validations/planetary-kinematics читает метаданные построенных внешних/внутренних шестерён на точной сохранённой ревизии. Проверяются соответствие модуля и угла давления, равенство числа зубьев планет, делительные межосевые расстояния солнце–планета и венец–планета, индексация равномерно расставленных зубьев и сохранённые фазы обоих зацеплений.
Идеальный решатель скоростей жёстких тел использует условия индексации планет (Ns + Nr) * planet_spacing / 360 = integer и скорость водила wc = (Ns*ws + Nr*wr) / (Ns + Nr). Результат сообщает вращение планет, делительные межосевые расстояния, невязки фаз и равномерность расстановки планет. Это проверка идеальных кинематических связей; она не моделирует упругий контакт, нагруженный люфт, баланс сил или производственные допуски.
Необязательный animate_duration_ms отправляет событие viewport.body-motion выбранному браузерному viewer. На ограниченное время анимируются вращение/орбита существующих сохранённых B-rep тел по траекториям решателя; после завершения восстанавливаются сохранённые положения. Геометрия и ревизия документа не меняются, постоянная запись сопряжения сборки не создаётся. Для анимации сохранённого водила с рассчитанной скоростью задайте carrier_body_id. Контракт операции и локальная MCP-команда генерируются из cadyx/api_contracts.py.
Многоконтурное выдавливание линейных контуров добавляет каждый контур отверстия внутренним проволочным контуром той же грани OCCT перед одной операцией prism. Для криволинейных или аналитических сегментов остаётся существующий проверенный путь последовательных булевых операций. В обоих случаях исходные редактируемые контуры сохраняются и используются при перестроении.
Общая Command System поддерживает коробки и изменение параметров; импорт сканов PLY из workspace/проекта и изменение параметров; постоянный импорт загруженного PLY только с точками; импорт одного прямого STEP-тела; эскизы XY/XZ/YZ/CUSTOM/FACE с ограничениями; замену профиля/траектории; связанные элементы твёрдых тел.
Импорт только с точками сохраняется как постоянное облако без граней и не может использоваться как треугольная сетка для извлечения сечений скана. Выдавливание/вращение профиля, sweep круглого сечения, объединение связанных булевых тел и скругление рёбер по топологии создают редактируемые B-rep OCCT.
Импорт STEP сохраняет переданную B-rep OCCT с хешем источника и метриками геометрии; если OCCT не может исправить исходную форму в документированном допуске, она остаётся помеченной как некорректная. Дескрипторы элементов хранят исходные эскизы или тела и параметры; поддерживаемые изменения выше по цепочке перестраивают зависимые элементы по порядку документа в одной атомарной команде.
Булево объединение принимает пересекающиеся B-rep-тела, в том числе трубы sweep и результаты прежних fuse/fillet, и должно вернуть одно связное тело. Скругление выбирается по актуальным уникальным индексам рёбер B-rep из Agent topology API; индексы являются результатом текущего обхода топологии, а не постоянными именами.
Команды сканирования разрешают непосредственные PLY из workspace/проекта через ProjectWorkspace, выполняются с той же блокировкой Core и атомарным сохранением, никогда не меняя исходный файл. Каждая обработанная сетка публикуется рядом с источником как атомарный бинарный PLY с именем по содержимому; одинаковый файл переиспользуется, конфликтующие файлы не перезаписываются.
Элемент reconstruct_scan хранит путь и хеш источника, метаданные результирующего файла и параметры обработки. Геометрия тела cadyx-mesh-v1 хранит в project.json ограниченные по размеру сжатые вершины float32 и грани uint32. Core сохраняет последние 128 снимков активности проекта в памяти и отправляет изменения по SSE agent.activity. Снимки охватывают инспекции Agent Runtime/API, запросы рендеринга, команды, твёрдотельные операции, повороты камеры и нативные этапы сканирования. Браузер показывает текущее действие/задачу и историю завершённых/ошибочных действий с временными отметками, новые сначала, не раскрывая полный журнал.
Протокол GeometryKernel отделяет Core CADYX от конкретного ядра. OCCTKernelAdapter создаёт/проверяет коробки, выдавливания и вращения профилей, трубы sweep, объединённые и скруглённые тела, а также импортированные STEP-тела; он также проверяет старые дескрипторы primitive-v1. Адаптер проверяет и триангулирует переносимые сетки, не преобразуя их в B-rep. PrimitiveKernelAdapter остаётся для демонстраций и B-rep не создаёт. Точные команды и ограничения см. в контракте Document Model v7.
export_brep требует expected_revision, проверяет актуальную однотельную B-rep, экспортирует STEP и импортирует его повторно, чтобы до публикации сверить валидность, число тел, границы и объём. Необязательный бинарный STL проверяется на водонепроницаемость и ориентацию; ошибка объёма сетки и ограниченное выборочное отклонение поверхности сохраняются в манифесте с привязкой к ревизии. Файлы экспорта атомарно публикуются в каталоге проекта без замены прежних; манифест записывается последним. STEP остаётся авторитетным; выборки STL не доказывают полную эквивалентность поверхности. См. контракт проверяемой передачи.
cadyx/kernel.py остаётся публичной границей GeometryKernel и адаптера OCCT; OCPKernelAdapter и PrimitiveKernelAdapter сохраняются как совместимые с прежними импортами псевдонимы. Нормализация чисел/профилей и сопоставление сечений loft находятся в kernel_profiles.py, демонстрационный адаптер — в kernel_primitive.py.
kernel_descriptors.py отвечает за каноническую сериализацию JSON, ограниченный кеш валидации, существующие проверки дескрипторов по типу/native-volume и дискриминированные контракты TypedDict для коробок, профилей, loft, булевых операций, труб, резьб, импортированных B-rep, скруглений и треугольных сеток. Валидация/декодирование payload сетки остаётся в mesh_geometry.py.
Сохранённая геометрия поступает как рекурсивные значения JSON. normalize_geometry проверяет дескриптор тем же кешем, что validate, и возвращает независимый JSON-снимок типа CheckedGeometry; его изменение не может менять источник или портить записи кеша. Операции OCCT, ранее проверявшие исходные дескрипторы, теперь используют проверенный снимок. Конструкторы геометрии указывают тип результата конкретного вида. Авторитетными остаются проверки формы нативного ядра; аннотации типов не означают, что вся реализация адаптера покрывается инкрементальным проходом mypy. Сохраняемый JSON, старые дескрипторы primitive-v1/сплайнов, ошибки валидации и алгоритмы восстановления формы не меняются; миграция не требуется.
Триангуляция viewport использует общий ограниченный LRU-кеш процесса, ключ которого — SHA-256 канонического дескриптора геометрии и явный контракт occt-viewport-v1-linear-0.01-display-mesh-v1. Кеш содержит не более 128 сеток и 64 МиБ, возвращает независимые копии. Переносимые треугольные сетки в нём не хранятся: они декодируются и проверяются из собственных дескрипторов по содержимому. Второй LRU-кеш на 128 элементов/64 МиБ хранит преобразованные позиции вершин экземпляров сборки по хешу исходной геометрии и преобразованию размещения. Снимки сцены в браузерном протоколе по-прежнему привязаны к ревизии; сетки тел и экземпляров сборки с неизменившейся геометрией переживают пересборку сцены.
native/kernel_abi.hpp — каноническое объявление C ABI OCCT и перечень экспортируемых символов. Единственная точка экспорта — native/kernel.cpp; реализации находятся в общих модулях, примитивах/профилях, топологии, выдаче результатов, валидации, сложных элементах и функциях для агента. kernel_common.cpp отвечает за JSON-сериализацию формы, копирование буфера ошибок и все аллокаторы результата new[]. Каждый возвращённый буфер освобождается через cadyx_free; мост сканирования Open3D отделён.
Фасад через cadyx_kernel_abi_manifest сообщает версию ABI и объявленный список экспортов. Перед привязкой к любому другому символу cadyx/native_kernel.py проверяет версию ABI, обязательные экспорты и наличие каждого объявленного символа. Необязательная возможность связывается только если её перечисляет манифест. Мост без поддерживаемого манифеста останавливает запуск и сообщает, что его нужно пересобрать.
Сигнатуры Python централизованы в _NATIVE_FUNCTION_SIGNATURES. Модули моделирования используют типизированные методы NativeKernel, не обращаясь напрямую к DLL и не настраивая сигнатуры ctypes.
Document Model v8 добавила к v7 именованные числовые параметры и привязки выражений. Текущий Document v12 сохраняет примитивы точек/линий/окружностей/эллипсов/сплайнов, добавляет YZ/CUSTOM/FACE к XY/XZ, атомарные построители полилиний/многоугольников/прямоугольников/окружностей, проверяемые геометрические и размерные ограничения, связанные операции выдавливания/вращения/sweep/fuse/fillet OCCT и наружную метрическую резьбу.
Command System также строит выборочные контуры эвольвентного прямозубого колеса из его параметров как редактируемый замкнутый периодический сплайн эскиза XY. Оба процесса используют существующий Agent API и не добавляют браузерного управления моделированием. Диапазоны и приближения геометрии приведены в Document Model v7.
Ссылки между эскизными элементами — устойчивые типизированные UUID; они проверяются при загрузке и после каждой команды. Координаты можно изменять атомарно пакетом; удаление не может оставить висячие ссылки. Изменение ограничений запускает сохранённый решатель эскиза и атомарно применяет геометрию. Существующие маршруты команд работают с этими объектами через те же блокировки и путь атомарного сохранения. Документы v1–v11 мигрируют в памяти до v12; оболочка проекта остаётся v1. Базовый граф объектов описан в Document Model v7, именованные параметры и перестроение — в v8, текущие системы координат эскизов — в контракте рабочих плоскостей v12.
В общей сцене отображаются точки, линии, окружности, полные эллипсы, эллиптические дуги и интерполяционные сплайны эскизов. Агент создаёт проекты/модели через Agent API; клиенты-человеки могут записывать через Web API, браузер непосредственно проекты/документы не меняет. Агент получает точный PNG главного viewport браузера, если есть актуальный кадр; автономный API сохраняет серверный fallback. Браузерные кадры помечены ревизией и хранятся в памяти.
HTTP API обменивается JSON под /api/v1, Agent API размещён в /api/v1/agent и использует операции Core. Агентские команды требуют блокировку агента. Проекты создаются через /api/v1/agent/projects, поддерживаемые тела и эскизы редактируются через /api/v1/agent/projects/{id}/commands общей Command System. Клиент-человек может использовать маршрут команд Web API с человеческой блокировкой. Маршрут GET /api/v1/agent/projects/{id}/topology?body_id=... возвращает текущие рёбра B-rep для выбора в fillet.
POST /api/v1/agent/projects/{id}/viewport/camera отправляет выбранному браузерному viewport временный анимированный поворот; документ не меняется, lease не требуется. Браузер отправляет отрисованный главный viewport на POST /api/v1/agent/projects/{id}/viewport/snapshot с ревизией документа. Соответствующий GET .../viewport.png возвращает те же байты PNG с X-CADYX-Viewport-Source: browser. Если кадр отсутствует или принадлежит старой ревизии, API возвращает серверный fallback с меткой server-fallback. Публикация кадра read-only, без lease, изображение хранится только в памяти.
GET /api/v1/projects/{id}/dashboard и его вариант Agent API возвращают сохранённый отчёт workflow и очередь задач. POST /api/v1/agent/projects/{id}/dashboard заменяет отчёт, не получая блокировку документа. Отчёты передаются через SSE как agent.dashboard вместе с глобальным состоянием занятости. GET /api/v1/updates сообщает, остаются ли незавершённые workflow/этапы/задачи. Браузер отключает мутации только для проекта, занятость которого вызвана его собственной блокировкой, выполняемой операцией или незавершённым workflow. Остальные проекты доступны, отчёты сохраняются после рестарта хоста.
Единая карточка прогресса показывает текущее/последнее реальное действие, текущую/недавно завершённую задачу, а также историю завершённых/ошибочных действий (новые сначала, локальное время завершения). Будущие пункты плана скрыты. Оба API возвращают JSON-сцену через GET .../viewport; загрузка PNG read-only и lease не требует.
GET /api/v1/projects и GET /api/v1/agent/projects возвращают сохранённые проекты в projects, а непосредственные имена каталогов — в folders. GET /api/v1/workspace/folders/{folder}/files перечисляет прямые обычные файлы; соответствующий /files/{name} выдаёт файл. Вкладка Projects (07) выбирает CAD-проект через существующий маршрут выбора Agent API; выбор папки workspace остаётся обязанностью агента.
Событие workspace.selection.changed отражает выбор; интерфейс использует общую оболочку для проектов и папок. В левой навигации есть Overview, Geometry, Analysis, Manufacturing, Activity, Files (06) и Projects (07). Проект можно выбрать, только если текущий ресурс подтверждён свободным, а целевой имеет FREE и не выполняет операцию. В выбранном CAD-проекте браузер блокирует мутации, если его lease не FREE, выполняется операция, очередь/workflow не закончены или состояние доступности неизвестно/устарело. Активность других проектов его не блокирует. Карточка прогресса остаётся читаемой и показывает фактическую работу, не будущие пункты.
Браузер читает снимки проектов и сцены viewport, но не создаёт проекты и не записывает документы модели. Viewport проекта, дерево объектов, сравнение, пустой экран manufacturing data, ортографические виды и dashboard агента находятся в общей оболочке. Доки модели/свойств изначально свёрнуты.
Обновления проекта публикуются в рамках процесса через SSE по /api/v1/events. Значения SSE id — непрозрачные курсоры server-epoch:event-number. Last-Event-ID продолжает поток из неизменяемого кольца памяти: максимум 256 событий и 1 МиБ сериализованной нагрузки; в очереди каждого подписчика — до 128 событий. Повторная выдача истории и регистрация подписчика защищены общей блокировкой публикации брокера, поэтому сохраняется порядок при параллельных публикациях.
Фильтрованная по проекту подписка получает только события своего проекта, без событий других проектов и глобальных событий. Неверный/устаревший курсор, перезапуск сервера, событие, которое нельзя буферизовать, или повторы больше ёмкости очереди приводят к stream.gap с причиной и последним ID вместо молчаливой выдачи неполной истории. После gap клиент должен немедленно заново прочитать авторитетное сохранённое состояние проекта/блокировки/viewport; браузер также синхронизируется после переподключения. Пятсекундный опрос /updates продолжает выявлять межпроцессные изменения и переполнение живой очереди.
Replay не переживает рестарт и не заменяет авторитетный Project API. После фиксации команды document.changed объявляет новую ревизию, command.completed отправляет ограниченную квитанцию v2 (schema_version: 2, operation_id, revision, command, outcome: "completed", необязательный feature_id). Событие завершения не содержит входные параметры или потенциально крупный геометрический результат. command.started использует тот же operation_id для корреляции; полные неизменяемые результаты и история доступны в ответе команды и API чтения проекта. Агентам/просмотрщикам нельзя принимать квитанцию за полную запись истории.
GET /api/v1/agent/workspace/selection сообщает выбранный в данном процессе проект или папку workspace. Агент выбирает существующий проект CAD через POST /api/v1/agent/workspace/selection с {"type":"project","project_id":"..."}, а папку — с {"type":"folder","folder_name":"..."}.
Выбор глобален для процесса и служит только подсказкой браузеру; параллельные чаты могут его менять. Нельзя определять по нему целевой проект команды. Каждая операция с проектом использует явный project_id. Core проверяет только целевой проект и рассылает workspace.selection.changed по SSE. Цель должна быть свободна, восстановлена и без выполняющейся операции; между командами можно выбрать проект с незавершённым собственным workflow. Занятость текущего выбора или workflow других проектов не запрещают переключение. Можно также создать выбранный проект, пока у других проектов идут workflow; select: false создаёт проект без смены выбора. MCP поручает Core проверку цели через Agent API.
Вкладка Projects (07) перечисляет сохранённые проекты и открывает каждый отдельной вкладкой, не изменяя процессный выбор Agent API. Выбор папки workspace остаётся только через Agent API.
Браузер открывает модель по читаемому адресу /p/<project-slug>. Slug основан на отображаемом имени; при совпадении/коллизии добавляется суффикс ID. Старые ссылки ?project_id=<UUID> поддерживаются и после загрузки списка проектов канонизируются в читаемый путь. Переименование меняет канонический slug.
Адрес корня без параметров открывает Projects, не восстанавливая текущий выбор хоста; ?view=projects работает так же. Проект или папка показываются лишь когда адрес явно содержит slug проекта, project_id либо folder. Явные маршруты проекта/папки/view=projects сохраняются при событиях смены workspace selection; адрес меняют только явная навигация либо только что созданный проект.
Выбор проекта через Projects открывает /p/<project-slug> в отдельной вкладке; папка задаётся ?folder=<folder name>. Адрес ресурса закрепляет вкладку за конкретным проектом или папкой, поэтому разные вкладки могут показывать разные ресурсы. Карточка проекта открывает его URL в новой вкладке даже при блокировке: новая вкладка видит последнюю подтверждённую модель, но её мутации отключены до освобождения проекта.
Данные и блокировки разделяются по ID проекта; адрес разделяет только просмотр, не lease. Вкладка ?view=projects остаётся доступной для навигации во время активности агента. Вкладка, закреплённая за проектом, держит мутации отключёнными, пока lease или активность данного проекта не свободны.
Вкладка Projects поддерживает логические группы. Описания групп и назначения проектов сохраняются отдельно от документов/каталогов проектов в корневом .cadyx-project-groups.sqlite3. GET /api/v1/projects включает groups и group_id у записей. POST /api/v1/project-groups создаёт группу; POST /api/v1/projects/{id}/group назначает группу или принимает group_id: null, возвращая проект в список без группы.
Для назначения проекта он должен быть свободен и не выполнять операцию. Создание группы и назначение не перемещают каталог проекта и не переписывают его документ.
Проект можно удалить аутентифицированным запросом DELETE /api/v1/projects/{id}. Перед этим вкладка Projects спрашивает подтверждение, что модель, история и все файлы проекта будут удалены безвозвратно. Core отказывает, если проект заблокирован, требует восстановления lease или выполняет операцию.
Перед отключением каталога Core запрещает новые запросы блокировки, очищает назначение группы и активный выбор Core, затем отправляет project.deleted. Если открытый просмотрщик ещё держит файлы, каталог остаётся в скрытой корзине удаления, а список workspace повторяет очистку; в этом случае API сообщает cleanup_pending: true.
По умолчанию хост использует 127.0.0.1. Привязка к адресу вне loopback требует описанной выше аутентификации хоста; для конфиденциальности трафика встроенный сервер всё равно требует доверенную LAN или внешний TLS/VPN.
cadyx/extensions.py объявляет упорядоченный набор встроенных расширений: сложные элементы, агентское авторство, производственные операции, семантический выбор, уточнения контрактов выбора и реконструкцию сканов. capabilities.py создаёт единый COMMAND_REGISTRY из BASE_COMMAND_CAPABILITIES и этих определений, затем публикует итоговый снимок контракта.
При композиции метаданные входа копируются. Отклоняются повторные имена команд/расширений, отсутствующие обработчики и уточнения, переименовывающие зарегистрированные команды. Пересборка реестра детерминирована и не мутирует базовый реестр или предыдущий снимок.
Каждый CommandSystem при инициализации привязывает зарегистрированные обработчики и middleware к базовому исполнителю. Семантический выбор оборачивает диспетчеризацию; выравнивание скана оборачивает этот pipeline и повторно применяет сохранённое преобразование после set_scan_parameter. Последний зарегистрированный middleware является внешним. Прогресс и контекст проекта проходят тот же pipeline внутри существующей границы Core: lease, ревизия и атомарное сохранение.
Базовые обработчики передаёт base_command_handlers(); до подключения расширений их имена должны точно совпадать с именами базовых возможностей. В production для каждой команды discovery есть зарегистрированный обработчик.
Модули расширений определяют обычные функции и метаданные; они не используют install() и не подменяют методы или глобальные контракты. OCCTKernelAdapter.topology явно вызывает дополнение аналитических свойств топологии. Общий рендерер явно отфильтровывает потреблённые исходные тела, сохраняя метаданные документа. Селекторы граней разрешают грани и не захватывают ссылки на рёбра.
tests/test_extensions.py проверяет композицию, конфликты имён, порядок middleware, изолированные обработчики и порядок импортирования. Нативные тесты авторства и рендеринга покрывают интеграцию адаптера и сцены.
В commands.py остаются конструктор CommandSystem, общий контекст выполнения и публичная проверка запросов/типов. Реализация разнесена по специализированным модулям command_*: общие функции/редактирование эскиза, профильные эскизы, кривые эскизов, операции тел, история/удаление, параметры, перестроение зависимостей, обработка сканов, импорт STEP и проверяемая выдача.
Классы объединяются обычным наследованием, поэтому прежние вызовы общих helper-методов из расширений продолжают использовать то же ядро, резолверы, писатели артефактов и подготовленный документ. Между семействами уникальные имена helper-методов; после определения класса методы не присваиваются.
Каждое семейство объявляет свою таблицу COMMAND_HANDLERS; base_commands.py объединяет таблицы и проверяет повторы. capabilities.py связывает имена обработчиков с каноническими метаданными через тот же реестр, что используется для расширений. При создании реестра отсутствующая, лишняя или некликабельная базовая привязка вызывает ошибку. Alias-обработчики сохраняют исходное соответствие параметров, имена операций элементов и фазы прогресса. Поиск команды не зависит от упорядоченной цепочки if.
Обработчики не получают блокировку и не сохраняют проект. Core продолжает копировать и проверять документ, применять lease/ревизию/stop-ограждение, записывать историю и фиксировать результат один раз через существующий атомарный путь Workspace. Исключение после частичного изменения подготовленного документа не меняет сохранённый документ, ревизию и историю. tests/test_command_families.py без загрузки нативных библиотек проверяет работу изолированных семейств, соответствие реестра и инвариант отказа атомарной команды.
По умолчанию CLI-хост привязывается к 127.0.0.1. Режим loopback сохраняет обратную совместимость и может работать без HTTP-аутентификации. До создания сервера cadyx.auth.validate_bind_auth отклоняет адреса, которые нельзя явно доказать loopback, если не загружен действительный токен. Имена хостов с неопределённой loopback-принадлежностью считаются внешними и требуют аутентификации. Поэтому случайная привязка --host 0.0.0.0 или LAN-IP завершается отказом.
Токен передаётся ровно одним runtime-источником: переменной CADYX_AUTH_TOKEN либо UTF-8-файлом через --auth-token-file / CADYX_AUTH_TOKEN_FILE. Длина токена не меньше 32 символов, пробелы запрещены. Он не хранится в project.json, базах блокировок, истории команд или переносимой схеме, поэтому включение аутентификации не требует миграции формата проекта. CLI намеренно не принимает токен как аргумент, чтобы обычное чтение списка процессов не раскрывало секрет.
Если токен настроен, cadyx.web проверяет каждый прикладной запрос до обработки маршрута. Один и тот же барьер защищает интерфейс браузера и статические файлы, Web API, Agent API, предпросмотр/загрузку файлов workspace, JSON/PNG viewport, маршруты блокировок и команд, поток SSE. Только GET /api/v1/health открыт; он возвращает лишь состояние готовности и версию API. Отклонённый запрос получает HTTP 401, соединение закрывается до того, как непрочитанное тело POST может быть интерпретировано как следующий запрос HTTP/1.1.
Агенты и API-клиенты используют Authorization: Bearer <token>. Навигация браузера применяет стандартную HTTP Basic-аутентификацию: имя пользователя cadyx, пароль — тот же токен. Затем браузер использует те же same-origin учётные данные для fetch-запросов и потока событий. Сравнение токенов выполняется secrets.compare_digest. Токен нельзя передавать в URL или query-параметре.
Это граница аутентификации, не шифрование транспорта: встроенный сервер работает по обычному HTTP. Поэтому работа вне loopback ограничена доверенной частной LAN, если её трафик не защищён TLS reverse-proxy или доверенным VPN. Прямое выставление HTTP-listener в Интернет вне поддерживаемой границы безопасности. Постоянная задача Windows по умолчанию привязана только к loopback.
MCP-адаптер по умолчанию выполняет cadyx_execute_command одним запросом POST /api/v1/agent/projects/{id}/commands/execute. Core удерживает защиту проекта, пока получает lease агента, проверяет точную ревизию, исполняет одну команду, формирует ограниченную квитанцию и освобождает блокировку. Допускается передать возобновлённый lease; он проверяется на совпадение с владельцем MCP. Квитанция содержит ревизию, число объектов и компактный результат команды, но не сериализует сохранённые объекты или полную историю команд. Для других клиентов остаётся прежний маршрут /commands с явной блокировкой.
MCP-инструмент cadyx_inspect_project по умолчанию читает inspection?section=summary; для ограниченных подробностей вызывайте cadyx_inspect_compact, а cadyx_inspect_project_full — только если требуется вся геометрия или история. Встроенный AgentRuntime также начинает с компактной сводки; инструмент inspect_project выдаёт ограниченные страницы, а большой ответ требует явного full=true.
GET /api/v1/agent/capabilities — доступный только для чтения машиночитаемый список маршрутов Agent API, имён поддерживаемых команд Command System, обязательных/необязательных параметров, необязательных подсказок JSON Schema, кодов ошибок и документированных ограничений. Метаданные параметров служат справкой для оператора; авторитетными остаются валидаторы Core/команд и связанные контракты модели. CommandSystem.execute отклоняет тип команды, отсутствующий в реестре discovery: новая операция не становится доступна до регистрации её контракта.
Типизированные ошибки Agent API сохраняют верхнеуровневые error и message и добавляют diagnostics: тип ошибки, нарушенное предусловие, тип команды, сохранённая ревизия, ID элементов/тел/эскизов/сущностей, измеренные значения и, если доступно, подсказку correction_hint. Если операция не выполнила измерение, его значение null; CADYX не выдумывает измерения и не выбирает способ исправления. Ошибки ядра, выбора топологии, ограничений эскиза, сканирования, экспорта, лимитов ресурсов и неподдерживаемых операций имеют стабильные коды, которые перечисляются в discovery.
MCP-мост сообщает о сбое чтения транспорта кодом TRANSIENT_TRANSPORT, а о неоднозначном результате мутации — OPERATION_OUTCOME_UNCERTAIN. Перед решением о повторе проверьте ревизию/историю. Неожиданные ошибки HTTP/MCP возвращают общий INTERNAL_ERROR; публичные ошибки очищаются от Bearer-токенов и абсолютных путей хоста.
Подсказки о значениях параметров команд находятся в соответствующей записи COMMAND_CAPABILITIES. Ветки команд MCP получают поля и схемы из окончательного реестра, включая расширения; поля без подтверждённой схемы значения остаются разрешительными.
Общий реестр проверок из cadyx/api_contracts.py служит источником operations и описаний маршрутов для discovery, схем инструментов MCP и проекции/defaults запросов, а также HTTP-проверок обязательных/допустимых полей для размеров, зазора, сохранения и толщины. operations — расширяющие метаданные discovery, не второй API исполнения. Core по-прежнему проверяет значения, ревизии и геометрию; HTTP сохраняет существующие сообщения ошибок и обёртки прогресса. Тесты source-контрактов сверяют реестры, проекцию запросов, пути документации и актуальную версию документа; Web API-тесты проверяют граничные поля и делегирование Core.
Локальный stdio MCP-адаптер cadyx/mcp_server.py использует только стандартную библиотеку Python. Он вызывает защищённый HTTP Agent API CADYX и не импортирует Core или не читает файлы проекта напрямую. Инструменты охватывают выбор workspace, инспекцию проектов/файлов/моделей, возможности, актуальную топологию B-rep, сцену/PNG, камеру, dashboard, команды, безопасное копирование/удаление файлов проекта, остановку/продолжение работы и проверенное восстановление просроченного lease.
cadyx_get_project_thumbnail_batch возвращает в одном результате до восьми серверных PNG-миниатюр размером 480×270. К каждой картинке добавлены ID проекта, ревизия документа и источник кадра. Это позволяет вызывающему ИИ-агенту сопоставить референсное изображение, прочитанное существующими средствами работы с файлами проекта/workspace, с возможными CAD-проектами. Ранжирование и решение о построении модели остаются за агентом. MCP не предоставляет shell, произвольный HTTP или запись файлов модели.
Каждая команда модели требует ревизию, увиденную вызывающей стороной; маршрут однозапросного исполнения получает и освобождает lease внутри Core. Предварительная проверка блокировки/ревизии читает компактную сводку инспекции, не полные снимки геометрии/истории. Потерянный ответ команды автоматически не повторяется. Инструмент остановки при параллельном исполнении устанавливает долговечное ограждение Core, ждёт завершения уже допущенной команды и возвращает проверенное Core сохранённое состояние.
Выбор workspace через MCP — подсказка браузеру глобальная в рамках процесса, её может изменить другой чат. Core проверяет только выбранную цель; активные процессы в других проектах не препятствуют выбору. Инструменты операций проекта всегда требуют явный project_id; отдельный lease каждого проекта обеспечивает эксклюзивность в пределах этого проекта. /api/v1/updates перечисляет ID проектов с активными workflow для блокировки UI по проекту.
Ответ команды MCP намеренно не включает полный массив объектов сохранённого документа и крупную геометрию: он возвращает ревизию, количество объектов и компактный результат команды/истории. Встроенный AgentRuntime по умолчанию ведёт себя так же и отдельно предлагает полную инспекцию.
Локальный MCP-адаптер предоставляет cadyx_start_scan_360 и cadyx_get_scan_360_status через существующие маршруты Agent API. Захват запускает контроллер прямого UVC через Core; статус включает последний захваченный файл облака точек, а просмотрщик проекта опрашивает тот же маршрут для обновления живого слоя скана.
HTTP-мост MCP считывает ответ порциями не больше 64 КиБ и отклоняет превышающий лимит Content-Length ещё до чтения тела. Отсутствие/ошибка длины не обходит лимит потокового чтения. Бюджеты тела: 16 МиБ для обычного JSON, 64 МиБ для полной модели/сцены/топологии/команды, 8 МиБ для JSON постраничной компактной инспекции, 24 МиБ для PNG viewport, 8 МиБ на миниатюру, 64 МиБ для файлов проекта/workspace, 64 КиБ для тела HTTP-ошибки.
Лимиты применяются до декодирования/base64 и не гарантируют отсутствия дополнительных затрат памяти на последующий разбор JSON или сериализацию MCP. При превышении лимита чтения возвращается RESPONSE_TOO_LARGE с границей байтов и советом: запрашивать страницы cadyx_inspect_compact через section/limit/offset, вместо чрезмерного PNG брать миниатюру или использовать загрузку STEP/PLY в проект, а не передавать большой исходник текстом MCP.
Слишком большое HTTP-тело ошибки возвращает HTTP_ERROR_BODY_TOO_LARGE с исходным HTTP-статусом, включая различие определённого/неоднозначного результата мутации. При слишком большом ответе на успешную мутацию исход операции остаётся неопределённым: он ограничивается и инспектируется, автоматический повтор запрещён. Это защита памяти транспорта, не серверная пагинация и не доказательство неизменившейся геометрии.
Точка входа инструкций репозитория — AGENTS.md, она указывает на локальный skill .agents/skills/cadyx-operator/SKILL.md. .codex/config.toml регистрирует stdio-процесс на уровне проекта при открытии доверенного checkout в Codex. Клиент принимает токен из переменной процесса или CADYX_API_TOKEN_FILE; значение токена не передаётся аргументом процесса и не попадает в логи. Пакет MCP и SDK поставщика модели не требуются.
Последовательность разработки, включая аутентифицированный LAN-доступ и предпосылки scan-to-CAD, поддерживается в дорожной карте проекта CADYX. Прежде чем считать веху выполненной или незавершённой, сверяйте текущую реализацию.
Сжатие/декодирование упакованной геометрии скана используют представления буфера, избегая промежуточных копий полного набора байтов; декодированные массивы остаются независимо владеющими данными. При повторном использовании созданного PLY его существующий файл хешируется инкрементально, не загружаясь целиком в память.
Для браузерного PLY-превью считыватели координат определяются один раз. Невыбранные многоугольники и неиспользуемые списочные данные пропускаются по длине в байтах; дополнительно проверяется, что пропускаемый фрагмент помещается во входной файл. Данные вершин проверяются до выделения памяти массива превью. Выборка и триангуляция не меняются. Превью не является полной проверкой индексов граней, которые не попали в выборку. Регрессии: tests/test_ply_preview.cjs и переносимые тесты сканирования.
Внешний агент вызывает POST /api/v1/agent/projects/{id}/topology/query (MCP cadyx_query_topology), передавая body_id, точную expected_revision и типизированный query:
{"body_id":"body:...","expected_revision":4,"query":{
"entity":"face","surface":"cylinder",
"radius":{"value":2.5,"tolerance":0.01},
"axis":{"origin":[0,0,0],"direction":[0,0,1],"tolerance":0.01}
}}entity должен быть face или edge. Поддерживаемые фильтры: surface, curve, radius, diameter, area, length, orientation, normal, position, center_in_box, axis. Скаляры используют value и абсолютный tolerance в единицах модели (для площади — квадратных единицах).
Фильтры направления используют vector, необязательный mode (aligned, parallel, perpendicular) и angle_tolerance_degrees (по умолчанию 1°). position принимает point и допуск и сопоставляет их с центроидом элемента. center_in_box проверяет только центроид; он не подтверждает, что вся грань/ребро целиком заключены в коробке. axis сопоставляет положение и направление аналитической оси по origin, direction и допуску расстояния.
Элементы без аналитических дескрипторов не считаются совпадением. max_results ограничивает возвращаемый префикс (по умолчанию 100, максимум 500), не общее число найденных кандидатов.
Read-only-результат содержит сохранённую ревизию revision, отсортированный детерминированно по индексам список candidates, match_count, truncated и status (no_match, unique, ambiguous). Уверенность кандидата descriptor_within_tolerance — описательная метка, а не рассчитанная вероятность.
Агент должен явно выбрать индекс либо семантический ключ, который разрешается в единственный результат; отпечатки не являются постоянными ID топологии. В команду, изменяющую грань/ребро, передавайте topology_revision, равную осмотренной сохранённой ревизии, вместе с обычной expected_revision и свежей блокировкой на изменение. Устаревшая ревизия возвращает TOPOLOGY_CHANGED, повторяющийся семантический отпечаток — TOPOLOGY_AMBIGUOUS; команда не применяется.