75 lines
5.1 KiB
Markdown
75 lines
5.1 KiB
Markdown
# Архитектура
|
|
|
|
## Место в системе
|
|
|
|
```
|
|
┌────────────────┐ MCP (stdio, JSON-RPC) ┌──────────────────┐
|
|
│ MCP-клиент │ ◄──────────────────────► │ omnichannel-mcp │
|
|
│ (AI-ассистент)│ │ (этот сервер) │
|
|
└────────────────┘ └────────┬─────────┘
|
|
│ HTTP (session)
|
|
▼
|
|
┌──────────────────┐
|
|
│ config_server │
|
|
│ (Flask API/UI) │
|
|
└────────┬─────────┘
|
|
│ задачи агентам
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ агенты на хостах │
|
|
│ docker-compose / swarm │
|
|
└───────────────────────────┘
|
|
```
|
|
|
|
`omnichannel-mcp` — тонкий клиент. Он не выполняет команды сам: создаёт задачи
|
|
через API `config_server`, а те забирают агенты нод. Сервер без состояния — при
|
|
перезапуске ничего не теряется.
|
|
|
|
## Модель задач
|
|
|
|
Действия жизненного цикла (`deploy`, `restart`, `down`, `migrate`,
|
|
`update_front`, релизные операции) асинхронны:
|
|
|
|
1. Инструмент вызывает API → создаётся задача → возвращается `task_id`.
|
|
2. Агент ноды забирает задачу, выполняет `docker-compose`, публикует результат.
|
|
3. Клиент опрашивает `get_task` до `completed`/`failed`.
|
|
|
|
Поэтому у инструментов есть параметр `wait`: по умолчанию он выключен (loop
|
|
ассистента последовательный — не стоит его блокировать), а при `wait=true`
|
|
ожидание ограничено `task_poll_max_sec` и не считается ошибкой, если время вышло:
|
|
вернётся текущее состояние задачи.
|
|
|
|
## Слои модуля
|
|
|
|
```
|
|
main.go каркас lifecycle: --health, -config, stdio
|
|
internal/configserver/ домен: без зависимостей от MCP
|
|
config.go разбор/валидация конфига, ${VAR}, merge local
|
|
session.go HTTP-клиент: cookie-сессия, релогin, ретраи GET
|
|
manager.go потокобезопасный диспетчер: конфиг, сессии, семафоры
|
|
api_*.go типизированные вызовы эндпоинтов config_server
|
|
internal/tools/ MCP-слой: разбор аргументов → вызов домена → текст
|
|
registry.go toolkit.go patterns.go util.go
|
|
observe.go configure.go operate.go release.go maintain.go overview.go
|
|
```
|
|
|
|
Правило разделения: домен тестируется без MCP; MCP-слой не содержит бизнес-логики.
|
|
|
|
## Надёжность
|
|
|
|
- **Сессия:** Flask-cookie хранится в cookie-jar; login ленивый, при `401`
|
|
выполняется один повторный вход и один повтор запроса.
|
|
- **Повторы:** только идемпотентные GET (сеть/5xx). Мутации не повторяются.
|
|
- **Ограничения:** context-deadline на каждый вызов, лимит на размер ответа,
|
|
обрезка вывода, семафор мутаций на сервер.
|
|
- **Ошибки:** доменные (4xx/5xx с текстом, ошибки валидации) возвращаются как
|
|
recoverable — ассистент видит причину и может исправить; инфраструктурные
|
|
(сеть) — как ошибка протокола.
|
|
- **Логи:** только в stderr (stdout занят JSON-RPC), с маскированием секретов.
|
|
|
|
## Логи и наблюдаемость
|
|
|
|
Логи модуля пишутся в stderr; уровень задаётся `--log-level` или `OMNI_LOG_LEVEL`
|
|
(`debug|info|warn|error`). HTTP-сервер `config_server` — источник данных о
|
|
задачах и статусах.
|