chat-agent · передача данных 01

От запроса до текста и карты

БраузерТекст, голос, картаCoreHTTP и ASR finalAgent + Pydantic AIИстория, инструменты, отменаLLM gatewayNATS → HTTP / SSEvLLM requesterПрокси → NATS → H100Qwen3.8-27B-FP8JSONNATSNATSHTTPSPostgreSQLИстория, снимки, предложения, планыОтвет в браузере/ws: фрагменты и команды · HTTP: итогЧтение / записьAgent публикует события; Core возвращает RPC/ws и /core/message

Пользователь работает на chat-agent.gis-master.ru. Core принимает текст или окончательную транскрипцию, а Agent ведёт запрос и запускает Pydantic AI внутри своего процесса. Модель работает удалённо на H100; результат возвращается в чат текстом и, при вызове инструмента, командой карте. Здесь восстановлены связи по коду и конфигурации на 07.10.2026 · 7747c4c; свежую проверку production эта схема не заменяет.

Код: Core → Agent · Agent + SDK · Адрес модели

chat-agent · передача данных 02

Core фиксирует данные до очереди

1. Браузер → Core

POST https://chat-agent.gis-master.ru/core/message

Content-Type: application/json

{
  "text": "Покажи маршрут до SVO для TEST123. Сколько времени остаётся, если до вылета 120 минут, дорога 70, запас 30?",
  "session_id": "11111111-1111-4111-8111-111111111111",
  "request_id": "22222222-2222-4222-8222-222222222222",
  "turn_id": "22222222-2222-4222-8222-222222222222"
}

2. Core → API gateway → PostgreSQL

POST http://chat-agent_src_api_gateway:8100/api/domain/{S}/snapshots/{R}

{
  "snapshot_id": "33333333-3333-4333-8333-333333333333"
}

Снимок включает position, data_revision, demo и plans. Agent получает его идентификатор, затем читает снимок из БД.

S - сессия, R - запрос. В примерах используются вымышленные UUID и исходные демоданные.

Перед отправкой текста браузер ждёт сохранения последнего перемещения самолёта. Core закрепляет положение этой сессии, общую версию демоданных и планы в одном снимке, поэтому изменение карты во время ожидания не подменяет вход запроса. Текст TEST123 здесь - конкретный пример контракта; числа 120, 70 и 30 присутствуют и в исходном демонаборе, но редактор может их изменить.

Код: HTTP и beforeSend · Снимок перед NATS · Состав снимка · Демо TEST123

chat-agent · передача данных 03

У одного запроса два канала ответа

БраузерCoreAPI / PostgreSQLAgent / SDKLLM gatewayvLLM requesterPOST /core/message · JSONСоздать immutable snapshotsnapshot_idnats.agent.user123 · request/replynats.llm.user123 · agent_step/tokenize, /v1/chat/completionsSSE: text delta / tool_callschat.agent.stream + LlmResponsenats.events.user123 через /wsAgentInboundResponseHTTP JSON: итог + client_events

HTTP-запрос остаётся открытым до итогового результата. Параллельно браузер уже может получать текст по NATS WebSocket, поэтому ожидание полного ответа не мешает видеть начало. После каждого tool call Agent возвращает результат инструмента модели и может повторить шаг генерации; обычная реплика без инструментов завершается одним шагом. Сплошная стрелка обозначает вызов, пунктир - возврат или событие.

Код: Agent RPC · Шаг модели · Фрагменты · Ответ и карта

chat-agent · передача данных 04

NATS передаёт JSON, а не “просто строку”

Core → Agent: nats.agent.user123

{
  "trace_id": "UUID трассы сообщения",
  "request_id": "22222222-2222-4222-8222-222222222222",
  "correlation_id": "UUID трассы сообщения",
  "session_id": "11111111-1111-4111-8111-111111111111",
  "ts_ms": 1791320000000,
  "text": "Покажи маршрут до SVO для TEST123…",
  "turn_id": "22222222-2222-4222-8222-222222222222",
  "user_id": "user123",
  "snapshot_id": "33333333-3333-4333-8333-333333333333"
}

Agent → LLM: nats.llm.user123

{
  "mode": "agent_step",
  "input": {
    "messages": [{"role": "user",
      "content": "Покажи маршрут до SVO…"}],
    "tools": [{"type": "function", "function": {
      "name": "run_code",
      "parameters": {"type": "object",
        "properties": {"code": {"type": "string"}},
        "required": ["code"]}
    }}]
  },
  "constraints": {}
}

Справа показана часть LlmRequest: он также содержит TraceEnvelope. Реально передаются system prompt, нужная история и все 4 объявленных инструмента с полными схемами.

Core отправляет UTF-8 JSON на nats.agent.user123; Agent вызывает модель на nats.llm.user123. Суффикс user123 общий, а принадлежность чату определяется session_id. Общий запрос и отдельный шаг модели имеют разные request_id: внешний ID, deadline, бюджет, attempt и generation передаются в NATS headers вместе с traceparent. Надписи вместо UUID и сокращённые payload здесь объясняют поля, а не служат готовым запросом.

Код: AgentInboundRequest · AgentStepInput · LlmRequest · NATS headers

chat-agent · передача данных 05

Модель возвращает текст либо tool calls

LLM gateway → существующий requester

POST https://nats-proxy-vllm.gis-master.ru/v1/chat/completions

{
  "model": "Qwen3.8-27B-FP8",
  "messages": [{"role": "user",
    "content": "Покажи маршрут до SVO…"}],
  "tools": [{"type": "function", "function": {
    "name": "run_code",
    "parameters": {"type": "object",
      "properties": {"code": {"type": "string"}},
      "required": ["code"]}
  }}],
  "stream": true, "temperature": 0,
  "max_tokens": 2048, "parallel_tool_calls": false,
  "stream_options": {"include_usage": true},
  "tool_choice": "auto",
  "chat_template_kwargs": {"enable_thinking": false}
}

Requester → gateway: SSE

Content-Type: text/event-stream

data: {"choices":[{"delta":{"content":"Для деморейса "},"finish_reason":null}]}

data: {"choices":[{"delta":{},"finish_reason":"stop"}]}

data: [DONE]

Tool call приходит как delta.tool_calls; аргументы могут идти частями. Gateway собирает вызов, проверяет имя и JSON Schema и только затем возвращает его Agent.

Показан один инструмент; реально передаются все 4 и полный контекст. Перед генерацией: POST /tokenize. Бюджет входа 6144 токена; ответ до 2048. Внутренний NATS subject requester → H100 в этой проверке не установлен.

Pydantic AI не подключается к H100 напрямую: наш адаптер обращается к LLM gateway по NATS, а gateway - к существующему vLLM requester по HTTPS. Он считает токены по действующей модели и сокращает только необязательную старую историю. SSE - поток HTTP-событий от requester; после разбора gateway публикует текстовые фрагменты в NATS. Внешний NATS-переход на H100 показан как граница соседнего сервиса, без придуманного имени subject.

Код: /tokenize · HTTP / SSE · messages / tool_call_id

chat-agent · передача данных 06

Расчёт и показ маршрута - разные действия

Шаг A: run_code → Monty

f = flight_get(flight_number="TEST123")
r = route_preview(code="SVO")
left = (f["departure_in_minutes"]
        - f["travel_minutes"]
        - f["buffer_minutes"])
{"minutes_left": left,
 "destination": f["to"],
 "distance_km": r["distance_km"]}

120 - 70 - 30 = 20 минут

Расстояние зависит от положения самолёта в снимке. Время дороги берётся из деморейса, а не выводится из расстояния.

Шаг B: отдельный map_show_route

{
  "id": "call_route_1",
  "name": "map_show_route",
  "arguments": {
    "code": "SVO"
  }
}

Инструмент вычисляет тот же маршрут и добавляет BUILD_ROUTE в client_events. route_preview возвращает данные и сам ничего не рисует.

Чтение работает по снимку внутри Agent. Monty не имеет сети, файлов, environment или credentials: 64 МиБ и 10 секунд вычислений.

Это допустимая последовательность для примера. Модель может выбрать другой порядок; фиксированный граф TEST123 отсутствует.

Для TEST123 модель может вызвать run_code и получить результат вычитания из настоящего исполнения Python в Monty. Вложенные функции читают серверный снимок; они не отправляют произвольные HTTP-запросы. Чтобы пользователь увидел маршрут, нужен отдельный native tool map_show_route, после которого Agent возвращает проверенные результаты в следующий шаг модели. Маршрут здесь - прямая линия для демо, не навигационный план полёта.

Код: flight_get / route_preview · map_show_route · CodeMode / Monty · Формат маршрута

chat-agent · передача данных 07

Фрагменты доходят до своего чата

LLM → Agent: chat.agent.stream

{
  "request_id": "22222222-2222-4222-8222-222222222222",
  "session_id": "11111111-1111-4111-8111-111111111111",
  "attempt_id": "22222222-2222-4222-8222-222222222222",
  "generation_id": "33333333-3333-4333-8333-333333333333",
  "generation_index": 3,
  "sequence": 1,
  "delta": "Для деморейса TEST123 осталось 20 минут. "
}

Публикуется только текст. Tool calls возвращаются в окончательном LlmResponse.data.tool_calls после проверки.

Agent → браузер: nats.events.user123

{
  "time": "2026-10-07T10:00:00.000+00:00",
  "service": "src_agent", "type": "command",
  "kind": "response_fragment",
  "data": {
    "request_id": "R", "session_id": "S",
    "attempt_id": "A", "generation_id": "G",
    "attempt_index": 0, "generation_index": 3,
    "sequence": 7, "state": "generating",
    "deadline_ms": 1791320120000,
    "delta": "Для TEST123 осталось 20 минут. "
  },
  "name": "", "uid": "UUID события"
}

S/R/A/G - сокращения UUID. UI sequence и sequence gateway различаются: Agent нумерует собственные события.

Agent принимает chat.agent.stream, проверяет владельца и порядок частей, затем оборачивает фрагмент в UI-событие. Браузер подписан на nats.events.user123 через wss://chat-agent.gis-master.ru/ws и проверяет session, request, attempt и generation. Пример generation_index=3 иллюстрирует третий шаг, а не обязательное число генераций. Старые части и чужие события не должны дополнять текущий ответ.

Код: Gateway fragment · Проверка фрагмента · UI sequence · Фильтр в браузере

chat-agent · передача данных 08

Карта меняется по команде, история - в БД

Команда карты через /ws

{
  "type": "command", "kind": "client",
  "data": {
    "command": "BUILD_ROUTE",
    "trace": {"session_id": "S", "request_id": "R",
      "attempt_id": "A", "generation_id": "G"},
    "artifacts": {"all": ["ui"], "last": "ui",
      "payload": {"ui": {"data": {"route": {
        "geometry": [[37.6, 55.7], [37.386677, 55.977486]],
        "distance_km": 33.607, "demo": true
      }}}}
    }
  }
}

Показана часть события и route. GeoJSON-совместимый порядок точек: [lon, lat]. Координаты в примере иллюстративные.

Итог на POST /core/message

{
  "ok": true, "status": "DONE",
  "session_id": "11111111-1111-4111-8111-111111111111",
  "request_id": "22222222-2222-4222-8222-222222222222",
  "result": "Для деморейса TEST123 остаётся 20 минут: 120 - 70 - 30. Маршрут до SVO показан на карте.",
  "errors": []
}

Сокращённый AgentInboundResponse: также есть trace_id, correlation_id, ts_ms, client_handler и client_events. Команда BUILD_ROUTE в client_events содержит тот же route.

Native tool добавляет команду в результат Agent; UiEventPublisher переводит её в формат artifacts.payload.ui для браузера. Самолёт при показе маршрута не перемещается. Agent сохраняет итог и историю в PostgreSQL, а Core возвращает тот же результат по HTTP, чтобы UI мог восстановиться при потере события. После reconnect используются snapshot активного запроса или история; полного replay в Core NATS нет.

Код: Формат команды · Запись результата · Итог HTTP · Применение карты

chat-agent · передача данных 09

Голос сначала становится текстом

МикрофонPCM в браузереwebrtc_ingressSDP + ICE: /core/*Media: DTLS/SRTP → PCMaudio_ws_ingress/audio/ws: binary PCM16LEJSON start / endОбщий AudioSessionResample 16 kHz, monoFIFO → пакеты 20 мсVoice streaming bridgewebrtc.komaroff.asr.stream.{S}VAD и поток на GPUWhisper worker на H100partial / final / rejected / errorCore → Agentfinal → запрос AgentWebRTCWSSDecoded audioPCM16LENATS PCMto.inference.webrtc.asr.audio.{T}from.inference.webrtc.asr.events.{T}ASR JSON

WebRTC и WSS - два входа в один аудиотракт. После нормализации ingress отправляет PCM в общий NATS; единственный live bridge в стэке voice выделяет речь и передаёт её удалённому Whisper worker. Core получает partial для интерфейса, а final превращает в тот же запрос Agent, что и текст. Здесь S - session_id, T - stream_id; ответ агента сейчас отображается текстом, синтез речи в этот путь не входит.

Код: WebRTC → PCM · WSS → PCM · NATS audio · Voice / GPU

chat-agent · передача данных 10

Аудио и текст имеют разные контракты

WSS: /audio/ws и пакет ingress

{"type": "start", "session_id": "S",
 "format": "pcm16le", "channels": 1,
 "sample_rate": 48000}

Затем binary frames ≤ 8192 байт. Частота - фактическая частота браузера; сервер пересчитывает в 16 kHz.

4 байта длины JSON, big-endian
+ UTF-8 JSON metadata
+ 640 байт PCM16LE на 20 мс
{"type": "frame", "seq": 1, "sample_rate": 16000,
 "channels": 1, "sample_width": 2,
 "session_id": "S", "stream_id": "T"}

ASR → Core: JSON

webrtc.komaroff.asr.text.{S}

{
  "version": 1, "result_type": "final",
  "session_id": "S", "stream_id": "T",
  "phrase_id": "P", "revision": 2,
  "text": "Покажи маршрут до SVO для TEST123."
}

partial обновляет транскрипцию, final запускает Agent. Проверяются stream, phrase и revision, чтобы старый или повторный final не запустил запрос ещё раз.

PCM не превращается в base64 и не передаётся модели LLM. end/abort имеют тот же бинарный конверт без PCM.

При WebRTC браузер сначала получает capabilities и отправляет SDP offer; ICE-кандидаты идут отдельно на /core/ice/{connection_id}. ICE-канал принимает первым сообщением {"type":"auth","token":"…"} и не переносит звук. Для WSS звук идёт непосредственно на /audio/ws. В обоих случаях NATS-пакет имеет заголовок длины, JSON и бинарный PCM; окончательная транскрипция возвращается уже JSON-сообщением. Эти три WebSocket-пути нельзя объединять в один блок.

Код: Start / binary · Бинарный конверт · ICE endpoint / auth · ASR protocol

chat-agent · передача данных 11

Сохранение ждёт отдельного подтверждения

plan_saveDeferred tool callПредложение в PGawaiting_confirmationКарточка в UISHOW_PROPOSALРешение пользователяPOST /core/requests/{R}/confirmЧерновик/wsapprove / rejectAgent + транзакция PGПроверить session, версии, аргументыСохранение / отказОдна запись либо без записиПредложение staleНовый снимок и карточкаchat.agent.requestsВерсии совпалиВерсии изменились
{"session_id":"S","proposal_id":"UUID","version":1,"decision":"approve"}Тело подтверждения; request_id находится в URL.

Просьба сохранить план создаёт предложение, а не запись плана. Agent сохраняет deferred call в PostgreSQL, завершает текущую работу и освобождает worker; ожидание человека не расходует 120 секунд активной работы. По confirm он проверяет версии положения, демоданных и плана в транзакции. Повторный клик не создаёт вторую запись; устаревшая карточка вызывает пересчёт и новое подтверждение. Обычное уточнение критериев при этом остаётся следующей репликой чата.

Код: DeferredToolRequests · Confirm HTTP / NATS · Проверка и запись · Новая карточка

chat-agent · передача данных 12

Что исправлено в вашей схеме

Исходная схема пользователя: Agent, Pydantic AI, Code Mode, инструменты и подтверждение
Исходная схема из вложения. Исправленная версия - следующая страница.
На исходной схемеКак реализовано
Пользователь сразу → AgentБраузер → OAuth ingress → Core; голос сначала проходит ASR.
“Pydantic AI + модель” в одном блокеSDK внутри Agent; модель отдельно на H100 через NATS и LLM gateway.
Все инструменты → NATS / API8 функций чтения доступны внутри Monty. Данные читаются из снимка в Agent; artifacts / планы - из PG.
“Уточнить / подтвердить / изменить” как один узелУточнение - реплика. Confirm принимает approve / reject; изменение - новый запрос и предложение.
Изменение карты вместе с “цель выполнена”Нужен вызов native map tool. Команда попадает в client_events, затем в /ws или HTTP result.
“Краткие данные + artifact_ref” всегдаМалый результат передаётся целиком; большой - artifact_id, count, preview и постраничное чтение.

Исходная схема правильно передаёт идею управляемого цикла и ожидания человека, но не разделяет процессы и форматы данных. Исправленная версия сохраняет эту идею и добавляет фактические границы: Core, SDK в Agent, удалённую модель, локальные инструменты снимка и отдельные команды UI. Универсальный каталог “прав” и готовый механизм компактной памяти целей не показаны как реализованные сервисы: в коде есть конкретные схемы, history, snapshot и проверки владения.

Код: Каталог инструментов · История и snapshot · Выход карты

Исправленная схема · 1 из 3 · каждая строка слева направо 13

Запрос и модель: читаем по строкам

1. Приём запроса: Core закрепляет снимок до очереди1БраузерPOST /core/messagetext · session_id · request_id2CoreСнимок → PostgreSQLJSON → nats.agent.user1233Agent + Pydantic AI6: история + снимок + схемыSDK управляет циклом toolsHTTPJSONNATSUTF-8 JSON2. Запрос модели: messages, схемы tools и параметры3Agent + Pydantic AINatsModel → agent_stepnats.llm.user1234LLM gateway/tokenize → лимит контекстаPOST /v1/chat/completions5Requester / H100Requester → NATS → vLLMМодель: Qwen3.8-27B-FP8NATSagent_stepHTTPSJSON3. Возврат модели: текст или проверенные tool calls5Requester / H100SSE: delta / tool_calls / usageГенерация на удалённом H1004LLM gatewayСборка и проверка tool callsJSON-итог + текстовые delta3Agent + Pydantic AIТекст → итог; tools → стр. 14–15Проверка действий до вызоваHTTPSSENATSdelta + итог

Строки идут сверху вниз; внутри каждой следуем стрелкам слева направо. Повтор блока показывает обратный путь данных без длинной петли. Текст приходит из браузера, а голосовой ASR final — в Core по NATS, как на страницах 9–10. Полный адрес модели: https://nats-proxy-vllm.gis-master.ru/v1/chat/completions. Цифры в кружках — номера блоков для разбора на страницах 16–17.

Код: Цикл модели · Инструменты · Предложения · Состояние и выход

Исправленная схема · 2 из 3 · выбирается нужная ветка 14

Инструменты и ответ: отдельные пути

1. Если нужны данные или расчёт: выполняется run_code3Agent + Pydantic AIПроверка имени и аргументовВызов run_code7Code Mode / Monty8 функций чтения snapshot64 МиБ · 10 с · без сети12Результат toolsJSON либо artifact handletool_call_id → обратно в SDKtool callcodereturnJSON2. Если нужно показать карту: выполняется native tool3Agent + Pydantic AIПроверка имени и аргументовmap_show_points / route8Инструменты картыЧитают тот же snapshotДобавляют client_events12Результат toolsДанные возвращаются в SDKSET_AIRPORTS / BUILD_ROUTEtool callJSONreturnJSON3. После завершения цикла: сохранить итог и показать его3Agent после циклаТекст + накопленные событияУспех или явная ошибка13История и ответСохранение через API / PGHTTP JSON + события NATS1БраузерТекст и команды картыПроверка session / generationcommitитогHTTP / /wsсвоя сессия

Первые две строки — возможные ветки, а не обязательные шаги каждого вопроса. Результат инструмента возвращается в SDK и, если работа продолжается, в следующий запрос модели. Monty читает снимок и считает; команды карты создаются отдельно и доставляются через /ws. Строка 3 показывает завершение: Agent сохраняет итог, а браузер применяет только события своей сессии и поколения.

Код: flight_get / route_preview · map_show_route · CodeMode / Monty · Формат маршрута

Исправленная схема · 3 из 3 · подтверждение отдельным запросом 15

Сохранение: сначала предложение, потом решение

1. Модель просит plan_save: появляется предложение3Agent + Pydantic AIplan_save → deferred tool callСохранённого плана ещё нет9Предложение в PGАргументы, версии, сообщенияОжидание; worker свободен10ПользовательSHOW_PROPOSAL → карточкаПроверяет предложенные поляdeferredсохранитьNATS / /wsкарточка2. Пользователь отвечает: Core передаёт решение Agent10Пользовательapprove либо rejectproposal_id · version · session2Core: confirmPOST /core/requests/{R}/confirmJSON → chat.agent.requests11Проверка + PGAgent: сессия и аргументыВерсии данных, позиции, планаHTTPJSONNATSрешение3. Проверка завершена: запись, отказ или новая карточка11Проверка + PGapprove → одна запись планаreject → план без изменений12Результат решенияapprove / reject → итогstale → пересчёт и карточка13История и ответЗафиксировать статус решенияПоказать его своей сессиитранзакциярезультатHTTP / /wsсвоя сессия

Ожидание решения хранится в PostgreSQL и не занимает worker. Подтверждение — новый HTTP-запрос с версией предложения, а не продолжение старого сокета. Agent проверяет актуальность данных перед записью: повторный клик не дублирует план, отказ не меняет его, а устаревшее предложение требует новой карточки и нового подтверждения. Успешное сохранение сообщается без дополнительной генерации модели.

Код: DeferredToolRequests · Confirm HTTP / NATS · Проверка и запись · Новая карточка

chat-agent · передача данных 16

Что делает каждый блок: вход и модель

Блок на схемеЧто принимает и за что отвечаетЧто передаёт дальше
1 · БраузерПринимает текст и показывает транскрипцию.POST /core/message; /ws для событий; карта применяет только события своего запроса.
2 · CoreПринимает HTTP или ASR final; закрепляет вход.Через API создаёт snapshot в PG; передаёт Agent JSON + execution headers по NATS.
3 · Agent + Pydantic AIAgent владеет очередью, историей, отменой. SDK ведёт цикл модели и tools.Использует фиксированный каталог и снимок. Проверяет ответ; завершает итогом, ошибкой или предложением.
4 · LLM gatewayПолучает LlmRequest(mode=agent_step).Проверяет input, считает токены, вызывает requester, собирает и валидирует tool calls; публикует delta.
5 · Requester / vLLMПолучает messages, tools и параметры через внешний requester.Генерирует текст / вызовы инструментов. Сам не пишет в нашу БД и не рисует карту.
6 · Контекст запросаИстория сессии + snapshot + схемы.PG фиксирует положение, общие демоданные и планы. Незавершённые proposals не входят в обычный контекст.

Первые шесть блоков готовят запрос и получают решение модели. Владельцем сессии остаётся приложение: модель не выбирает чужой snapshot и не назначает себе права. Схемы инструментов входят в модельный запрос, а фактические данные аэропортов попадают туда через результаты инструментов. При ошибке нового агента приложение возвращает ошибку; скрытого перехода на Ruby нет.

Код: Core · Контекст · Gateway · Pydantic / legacy

chat-agent · передача данных 17

Что делает каждый блок: действия и результат

Блок на схемеВход и работаРезультат и ограничение
7 · Code Mode / Montyrun_code выполняет Python с 8 разрешёнными функциями чтения.64 МиБ, 10 с, без сети / файлов. Результат - значения или artifact handle, не побочный эффект карты.
8 · Native map toolsmap_show_points(codes), map_show_route(code).По snapshot формируют SET_AIRPORTS / BUILD_ROUTE. Команды уходят своей сессии; положение самолёта не меняется.
9 · Предложение PGplan_save(name, airport_codes, notes, flight_number).Сохраняются действие, версии и сообщения deferred call. План ещё не записан; worker освобождён.
10 · ЧеловекВидит сохранённое предложение в карточке.Confirm передаёт session_id, proposal_id, version и approve / reject. Новое содержание задаётся новым запросом.
11 · Проверка + запись PGAgent сверяет предложение с решением и текущими версиями.В транзакции сохраняет одну версию плана или фиксирует отказ. Stale вызывает новую карточку, не запись.
12 · Результат инструментаПроверенное значение, tool_call_id и при необходимости artifact_id.SDK связывает tool result с вызовом модели. Для approve / reject факт записи выводится без новой генерации.
13 · История и ответИтог цикла, ошибки, client_events.Agent сохраняет результат. /ws доставляет события; Core возвращает HTTP JSON; GET history помогает после reload.

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

Код: Функции и native tools · Artifacts / proposals · Подтверждение без генерации

chat-agent · передача данных 18

Адреса, которые связывают весь путь

Путь на https://chat-agent.gis-master.ruНазначениеФормат / внутренний переход
POST /core/messageТекст → Core → nats.agent.user123JSON request → итог AgentInboundResponse
GET /core/history?session_id=SИстория после reloadJSON; Agent читает PG через nats.agent.history.user123
GET / DELETE /core/requests/R?session_id=SСостояние / отмена ответаchat.agent.requests; cancel дальше в chat.agent.cancel.*
POST /core/requests/R/confirmПодтверждение планаJSON; chat.agent.requests; версии проверяются сервером
GET /core/domain/view?session_id=S
PUT /core/domain/position?session_id=S
Карта и сохранение самолётаJSON; position: lat, lon, revision
GET /core/rtc-capabilities
POST /core/offer
WebRTC capability / SDPJSON: sdp, type, session_id, trickle
/core/ice/{connection_id}ICE WebSocket / DELETE stopJSON auth, ready, candidate, end, error
/audio/ws · /wsPCM WSS · NATS событияРазные сокеты: binary PCM и NATS protocol с JSON payload

Все перечисленные внешние HTTP/WS-маршруты проходят штатный OAuth ingress. Это граница входа; внутри приложение дополнительно сверяет принадлежность запроса сессии и версии предложения. В коде текстовый путь: message_handler → handle_transcription → AgentRunner.run → PydanticRunner.run → NatsModel.request. Модули следуют той же цепочке: src_front → src_core → src_agent → src_llm, контракты находятся в src_shared. Ruby сохраняется для прежних active/pending workflows, а новые запросы проходят Pydantic AI.

Код: HTTP routes · History · Control / cancel · Ingress и владельцы

1 / 18

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