# Production: chat-agent и voice · 04.10.2026

> Текущая поставка от 06.10.2026: [chat-agent C3](</experiments/voice-ai/archive/w/DOCS/CHAT_AGENT_ACCEPTANCE_C3.md>).
> Ниже сохранён исторический состав 04.10; его адреса, registry owners и workflow routing не являются действующими инструкциями.

Это датированный снимок поставки и приёмки после разделения. Он описывает наблюдённые сценарии и границы проверки; состав и параметры следующей поставки нужно сверять с текущими DRS, CI и Insight.

## Поставка, на которой получен снимок

| Владелец | SHA конфигурации / приложения | CI и deploy |
| --- | --- | --- |
| Chat | `2728a0fb5f34039304b8f7821dddd9d3cafecd3d` | [4894](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/pipelines/4894>), selective build 9673 и deploy 9674: success |
| Voice | `5d1d9591d57f0b5535884425567c0440b62a91d1` | [4896](<https://git.giscloud.ru/voice-chat/py_faster_whisper/-/pipelines/4896>), selective build 9681 и deploy 9682: success; семь WebUI/lock images обновлены через Insight U |

Insight после этих deploy подтвердил Frontend revision `2728a0f`, version `1.0.673`, и все voice WebUI/lock revision `5d1d959`, version `1.0.219`. Остальные прикладные образы сохранены выборочной сборкой. Последующая публикация этого снимка и OpenWiki проверяется отдельно: docs-only voice build может сохранить image `5d1d959`, а публикация публичного каталога требует новой сборки Frontend.

## Адреса и владельцы

| Проект / стэк | Адрес | Владелец |
| --- | --- | --- |
| webrtc-komaroff / `web-rtc-komaroff` | https://chat-agent.gis-master.ru/ | Frontend, Core, Agent, LLM, workflows, Postgres, общий NATS и внутренние инструменты |
| py_faster_whisper / `py_faster_whisper` | https://voice.gis-master.ru/ | Единственный live ASR bridge, пять файловых UI, диагностика, lock, пять H100 requesters и три CPU-модели |
| Общий каталог | https://chat-agent.gis-master.ru/docs/ | Публикуется Frontend из webrtc-komaroff |
| Диагностика | https://voice.gis-master.ru/status/ | Voice; `/health/` — alias. Chat `/status` и `/health` перенаправляют сюда |

Все внешние UI/API/WS проходят штатный OAuth2-slim. Внутренние NATS UI, pgweb и PostgreSQL не имеют внешних application routes. Старые application/admin hosts удалены из ingress; wildcard DNS может продолжать разрешать их имена. Проверка старых Host headers поверх доверенного TLS нового host дала 404 для UI/API/WS.

Voice зависит от общего NATS и сети `web-rtc-komaroff_default`. H100 receivers/models, Ollama и TURN остаются у прежних владельцев. Порядок поставки, storage и rollback: [DEPLOYMENT](</experiments/voice-ai/archive/w/DOCS/DEPLOYMENT.md>).

## Фактический режим ASR и workflows

Production live ASR работает с `ASR_MODE=streaming`, полученным из protected `WEBRTC_ASR_MODE`. Только `py_faster_whisper_stt_whisper_to_nats` имеет `STREAM_BRIDGE_ENABLED=1`; остальные WebUI — `0`.

Core/bridge сохраняют `webrtc.komaroff.asr.stream.*` и `webrtc.komaroff.asr.text.*`. CPU VAD выделяет речь; H100 worker обрабатывает её через NATS и возвращает version 1 `partial/final/rejected/error`. Файловое ASR независимо использует LinTO HTTP через свой CONNECT requester; progress/results идут в browser по общему NATS `/ws`. Batch live-режим сохранён как отдельная поддерживаемая конфигурация.

Активен `WORKFLOW_RUNTIME=ruby_node`. Ruby Node и Ruby DSL содержат `where_my_flight@2.0.0`, `find_nearest_airport@2.0.0`, `free_speech@2.0.0`. `echo@2.0.0` есть в Python и в LLM allowlist, но отсутствует в Ruby catalogs. LLM выбирает сценарий и аргументы в пределах реализованных графов и tools; свободного создания новых графов во время запроса нет.

## Покрытие всех 29 сервисов

Имена в таблице приведены без префикса стэка. Для каждого сервиса проверены running task/container, отсутствие OOM и failed update; определённые healthchecks имеют healthy.

| Стэк | Сервис | Проверенный запрос / сценарий |
| --- | --- | --- |
| chat | `src_front` | Авторизованный UI, каталог, текстовый чат, голосовой ввод |
| chat | `src_core` | `/core`, WebRTC offer 200, ICE/DTLS connected, RTP через TURN relay |
| chat | `src_agent` | Новый запрос, ответ ассистента, история; прежние 22 сообщения совпали с baseline |
| chat | `src_llm` | Реальные Ruby Node/DSL free-speech запросы «2+2» завершились ответом «4» |
| chat | `src_langgraph` | Health и явный Python Echo request завершились |
| chat | `src_langgraph_rb` | Health, routing и free-speech через LLM завершились |
| chat | `src_langgraph_rb_node` | Health, production free-speech через LLM, текстовый и голосовой чат |
| chat | `src_api_gateway` | Discover и все пять tools: position, nearby airports, weather, flight status, route |
| chat | `src_postgres` | Чтение сохранённой истории и запись новых сообщений через Agent |
| chat | `audio_nats` | Core connection, JetStream inference API, request/reply, file progress/results и browser WS |
| chat | `nats_ui` | Внутренний HTTP UI; внешнего маршрута нет |
| chat | `pgweb_mcp` | Внутренний pgweb HTTP UI; image `sosedoff/pgweb:0.17.0`, внешнего маршрута нет |
| chat | `nats_box` | Внутренний toolbox с `sleep infinity`; отдельного audio/request API у него нет |
| voice | `stt_whisper_to_nats` | Единственный streaming bridge, WebRTC partial/final и основной file transcription UI |
| voice | `py_faster_whisper_diarize` | Upload → transcription → diarization → speaker transcript, два говорящих |
| voice | `py_faster_whisper_staged` | Отдельные Transcribe → Diarize → Combine по cached audio/artifacts |
| voice | `py_faster_whisper_bench` | Четыре H100-конфигурации и три явных CPU acceptance-конфигурации прошли весь pipeline |
| voice | `py_faster_whisper_summary` | Чтение тех же постоянных benchmark results, карточки и таблица сравнения |
| voice | `py_faster_whisper_status` | Health/smoke, NATS/browser checks, CPU и внутренние admin health targets |
| voice | `whisper_file_job_lock` | Между bench и ordinary/staged UI: concurrent upload 409; после освобождения retry 202 и DONE |
| voice | `nats_proxy_linto` | Реальный WAV multipart прошёл в LinTO и вернул текст |
| voice | `nats_proxy_pyannote_shared` | WAV transcription/diarization/Combine, два говорящих |
| voice | `nats_proxy_pyannote_isolated` | Полный benchmark pipeline на реальном WAV, два говорящих |
| voice | `nats_proxy_sherpa_onnx` | Полный benchmark pipeline на реальном WAV, два говорящих |
| voice | `nats_proxy_sortformer` | Полный benchmark pipeline на реальном WAV, два говорящих |
| voice | `pyannote_diarization` | Явный запрос к CPU standby с реальным WAV, два говорящих |
| voice | `sherpa_onnx_diarization` | Явный запрос к CPU standby с реальным WAV, два говорящих |
| voice | `sortformer_diarization` | Явный запрос к CPU standby с реальным WAV, два говорящих |
| voice | `gateway` | Root redirect, trusted HTTPS, NATS `/ws` и OAuth2 handshake |

## Входные данные и сохранность

Контрольный WAV: публичный синтетический двухголосый Silero Aidar/Xenia пример из материалов проекта, 9.32 с, mono PCM16 16 kHz. На нём проверены file UI, четыре H100 подхода, три CPU-модели и голосовой WebRTC путь. Физический микрофон, камеры и разрешения конкретного пользовательского устройства этим тестом не проверялись.

Combined diarization и все семь model-конфигураций дали два говорящих и три речевых turn. Transcription вернула содержательный текст примера; в одной фразе распознано «в сети» вместо «к сети». Это функциональная приёмка маршрутов и протоколов, не измерение WER/DER на корпусе.

История: 22 прежних сообщения прочитаны после переключения, canonical checksum совпала. Postgres остался на том же физическом volume. Все 34 прежние benchmark-записи сохранились без изменений; новые acceptance runs добавлены отдельно. Benchmark и summary читают физический `whisper_bench_jobs` на `gis-master.ru`. Обычные завершённые файловые задачи используют временные данные: их результат доступен в UI, но backend может удалить job cache после завершения; это не постоянное benchmark-хранилище.

После исправления загрузки и финальной публикации повторно выполнены ordinary transcription (135 символов), staged Transcribe → Diarize → Combine (два говорящих, три turn) и WebRTC → ASR → ответ ассистента. В WebRTC подтверждены connected ICE/DTLS, серверный TURN relay и отправленные RTP packets. Для WebRTC использована отдельная сессия: partial, final и SHOW_MESSAGE с ответом ассистента; сохранены совпадающие session/stream IDs. Синтетический источник продолжал передавать silent PCM после WAV. Источник, прекращающий пакеты без паузы, проверяет stream_disconnected, а не нормальный endpoint речи. Во время ответа новая речь получает agent_busy; это существующий режим voice blocking. Временный тестовый аудиоввод после проверки удалён. Progress/results staged и ordinary file jobs подтверждены полученными NATS frames через `/ws` и HTTP 202 для запуска этапов.

## Исправления, выявленные полной приёмкой

- Streaming ASR smoke теперь сначала открывает изолированную сессию корректным silent PCM frame, затем проверяет контролируемый `invalid_packet` с совпадающими session/stream ID. Legacy batch reply не считается streaming-успехом.
- Пустой `bench_config={}` обычной staged-задачи сохраняет deployment settings, включая speaker bounds и batch fields. Явно выбранный benchmark по-прежнему применяет собственные параметры, включая автоматическое число говорящих.
- Тестовый NATS сохраняет stderr и имеет ограниченное ожидание readiness. Audio/event account imports разведены, чтобы проверка циклов NATS не отвергала тестовый broker.
- При занятой файловой блокировке ordinary и staged upload теперь дочитывают multipart body перед HTTP 409. Ранее загрузка могла зависнуть на 100% при прохождении ingress. После исправления обе UI быстро показывают владельца lock; после освобождения новая загрузка получает 202 и завершается. Две HTTP-регрессии проверяют busy upload размером 500 KB, отсутствие модели/job artifacts и успешный retry.

- Стартовые сообщения live, ordinary-file и staged-file runners больше не выводят полный NATS URL: он может содержать credentials. Подключение и subjects сохранены.

Полный локальный набор voice: 169 tests, OK. CI проверяется для точного SHA. `build streaming asr` использует diff с `CI_COMMIT_BEFORE_SHA`: зелёный test-only job может не строить image. После failed source pipeline последующий test-only pipeline сам по себе не доставляет предыдущий source change. Для этой приёмки image revision и наличие новых checks проверены в runtime отдельно от deploy success. Dry-stack 0.1.53 применяет конфигурацию с --resolve-image=never; CI deploy сам по себе может оставить прежний latest image. В разрешённом rollout семь сервисов общего voice WebUI image обновлены отдельным штатным Insight U; models, requesters и CPU sidecars не перезапускались ради этого исправления.

## Практические ограничения

Прямой TCP/HTTP probe `192.168.28.134:80` из voice остаётся недоступен и виден в группе INFO. Функциональные H100 HTTP/model запросы проходят через NATS requesters; информационная прямая проба не используется как readiness этих моделей.

CPU standby функционален, но для 9.32-секундного примера наблюдалось около 89 с pyannote, 1.1 с sherpa-onnx и 41 с Sortformer backend processing. Это отдельные замеры данного запуска, не SLA. Обычные file UI сохраняют H100 transport; наличие CPU sidecars не означает автоматического fallback.

Авиационные tools сейчас возвращают данные текущей реализации/fixtures. Прохождение tools API не подтверждает подключение к внешнему поставщику актуальных рейсов или погоды. Diagnostics LLM smoke включается отдельно; в приёмке настоящий LLM проверялся запросами чата и Ruby runtimes.

Датированные исследования, старые PNG и evidence прежних запусков сохраняются как история. Текущие инструкции — README, DRS, deployment runbook, этот снимок и обновлённые project/agent overlays.

## Приёмка Trickle ICE · 05.10.2026

[Датированный отчёт](</experiments/voice-ai/archive/w/DOCS/WEBRTC_TRICKLE_ACCEPTANCE_2026-10-05.md>): пять подключений в той же Chrome-сессии, медиана local SDP → connected 1245 мс вместо 16108 мс. Проверены DTLS/RTP через TURN, partial/final/ответ, текст/история, legacy, OAuth negative и потеря ICE-канала после connected. STUN/TURN сохранены; это измерение подключения в текущей сети, без оценки физического микрофона/WER.
