Разбор по коду · 08.10.2026 · Repowise 0.55.0

chat-agent: понять связи и убрать лишнее

Кто с кем работаетПять основных ролейГде легко сломатьЗапуск модели и состояниеКак рисовать схемыRepowise → модель → видыИндекс: 363 файла · первоначально 2 827 символов · обновлён до c0738a6Стрелки — направление обмена. Две стрелки — запрос и ответ. Блоки можно нажимать.

Сервис уже разделён на несколько частей. Риск появляется там, где один обработчик управляет слишком многими состояниями. Ниже — короткий разбор и проверка, какие схемы Repowise умеет строить сам.

Состав стэка · Repowise CLI · Только исходники; production здесь не проверяли

Основной путь · подтверждён исходниками

Пять ролей вместо большой схемы

БраузерТекст и результатCoreПринять запросAgentРешить, что делатьLLM gatewayВызвать модельvLLM / H100Удалённая модельHTTPNATS RPCNATS RPCHTTPSЧасти ответа и статусы → chat_nats → /chat-wsНовая модель: Qwen3.8-27B-FP8. API: nats-proxy-vllm.gis-master.ru/v1/chat/completions

Core принимает запрос. Agent управляет его выполнением и выбирает инструменты; LLM gateway вызывает удалённую модель. RPC идёт через chat_nats, а части ответа приходят в браузер отдельными событиями — HTTP не держится открытым до конца ответа.

Приём запроса · Agent → LLM · LLM → vLLM

Голос · два владельца и два брокера

Аудио идёт по отдельной шине

БраузерWebRTC / WSSМедиа ingressПривести аудио к PCMaudio_natsОбщая шина ASRWhisperСоседний стэк voiceАудиопотокPCM16 · 16 kHzPCMASR JSONCoreПринять finalAgentОтветить этой сессииpartial / finalchat_natsМедиа ingress — только аудио.Core — один слушатель ASR.Whisper в этой задаче не меняем.

Медиасервис передаёт PCM в старый audio_nats. Whisper возвращает распознанный текст через ту же шину; Core запускает Agent по финальной фразе. В сообщениях сохраняются session_id и stream_id. Интерфейс получает одну финальную транскрипцию, а ответ ассистента — по частям.

PCM · ASR final · Обе шины и удалённый ASR

Отдельный HTTP-путь · данные для пользователя и агента

Карта и погода идут напрямую

Карта в браузереКаталог и положениеAPI gateway/api/domain · /api/weatherPostgreSQLСостояния и снимкиOpenWeatherТайлы и численная погодаHTTPSQLHTTPSGET view · PUT position · POST airport · GET weather tiles

Браузер читает каталог и сохраняет положение или состояния через API gateway. Он получает OpenWeather, хранит кеш погоды и состояния в PostgreSQL. Перед запуском Agent эти данные попадают в снимок запроса. Поэтому инструменты видят согласованный набор, даже если карту изменили во время ответа.

HTTP карты · OpenWeather и кеш · Снимок данных

Agent · данные · подтверждение

Инструменты читают снимок запроса

AgentВладелец запросаMonty / run_codeВычисления в sandbox8 чтенийSnapshotTools / artifactsВызов и результатЧтение и результат3 native toolsКарта и предложение планаPostgreSQLИстория, снимки, планыВызов и результатПлан после согласияСнимок фиксируется до очереди.Модель не выбирает другую сессию.

Положение самолёта, аэропорты и погода фиксируются перед постановкой в очередь. Восемь инструментов чтения доступны через Monty; три отдельные команды показывают карту и предлагают план. Запись плана требует решения человека. Старые pending-сценарии пока продолжает Ruby — это совместимость, а не скрытый fallback.

Инструменты · Snapshot и approval · Выбор нового / legacy пути

Подтверждено кодом · последствие следует из порядка запуска

Первое исправление: отвязать vLLM от Ollama

Запуск LLMСоздать vLLM clientПроверка OllamaМодель и старый tokenizerПодписка на NATSТеперь принимать запросыЗатемТолько при успехеОшибка Ollama → подписка не создаётся → agent_step тоже недоступен

Новый агент использует vLLM. Но при старте gateway всё равно проверяет старый Ollama и tokenizer до подписки на запросы. Поэтому отказ старого провайдера способен остановить новый путь. Предлагаю инициализировать legacy-режим отдельно или только при его первом вызове.

Порядок запуска · Подписка после on_run · Проверка Ollama

Agent и интерфейс · риск сопровождения

Второе исправление: разделить управление состоянием

Приём запросаAgentServer._admitСостояние в БДДедупликация и admissionWorkerЗапуск после принятияРезерв и записьАктивацияОтменаSettlement и terminalРедактированиеУдалить хвост историиВосстановлениеReload и поздние событияМеняет состояниеМеняет состояниеЧитает состояние

Приём, отмена, edit и восстановление работают с одним жизненным циклом. Сейчас AgentServer и AssistantApp держат много этой логики в больших обработчиках. Предлагаю выделить admission, переходы состояния и обработчики UI-событий, сохранив транзакции и fencing. Прямые тесты контроллера должны ловить поздние события и гонки.

Admission · UI-события · Что запускается в checks

Причина → последствие → ограниченная правка

Ещё четыре небольших, но полезных изменения

Что видимПочему это важноЧто предлагаем
Сборка может измениться самаЧасть Python-пакетов без точной версии; otel из Git без SHA.Закрепить зависимости и commit helper.
Удалённому LLM достаётся локальный движокВ образ устанавливаются llama-cpp, CMake и компилятор.Отдельная опция сборки local. Размер измерить после.
ICE зависит от внутренностей библиотекTrickle использует private API aiortc / aioice.Сохранить точные версии и media-тесты перед обновлением.
Legacy неверно объясняет погодуPrompt называет её демоданными, get_weather читает OpenWeather.Исправить описание источника в старом режиме.

Здесь не требуется переписывать чат целиком. Каждая правка уменьшает конкретную зависимость или убирает расхождение между инструкцией и кодом. Ускорение и уменьшение образа пока не измерены; обещать проценты по статическому анализу нельзя.

Python / otel · Состав образа · Private ICE · Реальная погода

Статический сигнал ≠ разрешение удалить

Неиспользуемый код: три кандидата, без массовой чистки

КодЧто провереноРешение
NatsPublisher в LLMВ проверенных исходниках не найдено использования.Кандидат на маленькую очистку.
get_params в ICEOffer разбирается в main.py; старый helper не вызывается.Кандидат на маленькую очистку.
setMicEnabledОбщий экспорт вызывает две функции, но сам не вызывается.Кандидат на удаление всей старой цепочки.
Frontend, worklet, gateway, RubyRepowise ошибочно пометил их как неиспользуемые.Использование подтверждено; оставить.

Repowise не выдал ни одного безопасного автоматического удаления. Поиск вызовов подтвердил три небольших кандидата. Альтернативные runtimes занимают около 5 600 непустых строк, но нужны локальным профилям. Предупреждение о пароле в release-script тоже оказалось ложным: код читает environment.

Publisher · get_params · Старая mic-цепочка · Локальные profiles

Штатная функция · реально выполнено на нашем проекте

Repowise уже умеет строить C4

8блоков исходников
29компонентов
99связей в экспорте
repowise export --format structurizr --standalone \
  --components --no-externals -o architecture.dsl

Mermaid: содержимое .mmd вставить в Code. В Config оставить {} или вставить скачанный JSON. Structurizr: файл .dsl открыть в Structurizr; Mermaid и LikeC4 его не читают. Эти схемы показывают связи исходников, а не весь работающий стэк.

Официальный Structurizr export · C4 / Mermaid API · Результат export на c0738a6

Ограничения проверены на экспорте нашего проекта

Автоматический граф требует смысловой проверки

Автоматическое правилоЧто получили здесьКак довести до правды
Каталог → блокНативный экспорт включает неактивный src_langgraph.По DRS различать production, local и legacy.
Import → стрелкаВнутренние вызовы видны лучше, чем NATS request/reply.Добавлять subjects, producers и consumers по коду.
Библиотека → внешняя системаMermaid показывает Asyncpg, а не нашу topology PostgreSQL.Разделять пакет, процесс, БД и удалённый API.
Набор файлов → архитектураЭкспорт без externals не содержит audio_nats, chat_nats и Whisper.Подключать проверенные ingress / DRS / ownership-связи.

Сам Repowise не восстановил полную рабочую топологию. Если сразу красиво оформить его граф, часть важных связей пропадёт, а лишние блоки останутся. Поэтому сначала сверяем роли и протоколы с кодом, затем строим отдельные виды для текста, аудио и инструментов.

Как каталоги превращаются в C4 · Наши реальные роли и маршруты · Фактические DSL / Mermaid доступны на предыдущей странице

Возможность и предложение · интеграция пока не реализована

Для наших схем подходит Repowise + LikeC4

RepowiseНайти файлы и связиПроверка моделиКод + DRS + subjectsLikeC4Уровни, виды, процессыНаш HTMLВыбранные SVG и рассказСырые фактыПеревод в .c4Выбранные видыГотовый путь: Repowise → Structurizr.Предлагаемый путь: проверенная модель → LikeC4; прямого экспорта .c4 в CLI 0.55.0 нет.

Быстрее всего начать со штатных C4 и Structurizr. Для схем в нашем стиле лучше отделить данные от оформления: один согласованный набор элементов и связей, несколько видов. LikeC4 умеет такую модель и динамические процессы; нужен перевод в его DSL. Наш автономный HTML остаётся отдельной подборкой понятных SVG.

LikeC4: model / views · Динамические виды · CLI и форматы экспорта

Предлагаемый порядок · приложение не меняли

Начать с малого, без полного переписывания

1. Отвязать запускvLLM не ждёт Ollama2. Убрать три остаткаУзкая очистка + smoke3. Разделить состояниеAdmission, события и тестыЗатемЗатемДля схем: начать с текста, аудио и подтверждения плана. Не показывать весь граф сразу.

Сначала убрать лишнюю зависимость запуска, затем проверить и удалить три небольших остатка. После этого разделять управление запросами и UI-событиями, сохраняя контракт и поведение. Для схем используем три понятных процесса; полный граф остаётся средством поиска кода, а не первой страницей объяснения.

Первое исправление · Состояние запроса · События UI · Предложения, не выполненные изменения

1 / 13

Служебные вложения доступны в исходном архиве.