# webrtc-komaroff

## От голоса к действию

Вы говорите: «Покажи ближайшие аэропорты». webrtc-komaroff должен распознать реплику, выбрать сценарий и показать результат на карте.

## Одна реплика — несколько границ

Этот путь проходит через несколько сервисов. Каждый отвечает за свою часть: соединение, распознавание, состояние разговора или выполнение инструментов.

## Core принимает живой звук

Браузер передаёт микрофон по WebRTC. Сервис Core завершает соединение и превращает звук в короткие пакеты для распознавания.

## 20 миллисекунд в одном кадре

В текущем формате кадр содержит двадцать миллисекунд звука. Пакеты идут через брокер сообщений NATS в соседний проект распознавания.

## Whisper bridge выделяет фразу

Там детектор речи отделяет голос от тишины. Когда фраза закончена, сервис отправляет её внешнему распознавателю LinTO и получает текст.

## Голос и текст сходятся

Теперь голосовой и текстовый запросы идут одним путём. Core передаёт Агенту текст и идентификаторы сессии и реплики.

## Agent хранит разговор

Агент загружает состояние диалога из базы PostgreSQL. Так следующий вопрос может продолжить предыдущий сценарий, а не начинать разговор заново.

## Workflow выбирает следующий шаг

Дальше работает сценарный движок. Он решает, какой инструмент нужен, какие данные уже есть и что ещё спросить у пользователя.

## Модель разбирает намерение

Для нового запроса об аэропортах текущий сценарий обращается к языковой модели дважды: сначала выбирает намерение, затем извлекает параметры поиска.

## Инструмент возвращает данные

Сам поиск выполняет инструмент по каталогу аэропортов. Модель не должна придумывать координаты. Маршрут строится только при явном запросе пользователя.

## Результат приходит событием

Агент сохраняет результат и публикует команды интерфейсу. Браузер получает событие и обновляет сообщение или карту. Ответ по HTTP — отдельная часть обмена.

## Стенд, а не источник авиационных данных

Здесь есть важная граница. Позиция, погода и рейсы в проверенном коде демонстрационные. Нарисованный маршрут не является дорожным маршрутом или инструкцией для полёта.

## Меньше ожидания перед стартом

Первое небольшое улучшение — начальная загрузка карты. Сейчас два запроса идут последовательно. Переиспользование соединения и параллельное выполнение уберут лишнее ожидание.

## Очередь должна иметь предел

Более серьёзная проблема — перегрузка. Семафор ограничивает активные вызовы, но ожидающие задачи уже созданы. Нужен предел очереди до приёма новой работы.

## Один turn — один сохранённый результат

Ещё важнее запись результата. Состояние и история сохраняются раздельно. При сбое повтор может снова вызвать сценарий. Нужны общая транзакция и защита от повторного исполнения.

## Три движка увеличивают цену изменений

В репозитории три реализации сценарного движка. Прежде чем удалять две, надо сравнить поведение и проверить их пользователей. Переименование каталогов эту работу не заменяет.

## Упростить границу диалога

Следующий вариант — объединить Агент и выбранный сценарный движок. Исчезнет один сетевой переход, но пользу нужно измерить. Медиасоединения и модели разумно оставить отдельно.

## Измерить, затем менять

Начинать стоит с очередей и корректности повторов. Затем считать вызовы модели, задержку ответа и ошибки. Полное переписывание без этих измерений пока не обосновано.

## От фразы до понятного результата

Так короткая просьба превращается в цепочку проверяемых действий. Этот разбор основан на снимке кода. Он объясняет устройство проекта, но не подтверждает состояние работающего кластера.
