diff --git a/.cursor/rules/noda1-operations.mdc b/.cursor/rules/noda1-operations.mdc new file mode 100644 index 00000000..b0ed6a82 --- /dev/null +++ b/.cursor/rules/noda1-operations.mdc @@ -0,0 +1,59 @@ +--- +description: NODA1 (node1-daarion) — контекст, порти, перевірка агентів, типові виправлення +globs: "**/docs/NODA1*.md,**/scripts/node1/**/*.sh,gateway-bot/**/*.py,infra/**/*.yml,NODA1*.md,PROJECT-MASTER-INDEX.md,config/README.md" +alwaysApply: false +--- + +# NODA1 — Операції та контекст + +## Сервер + +| Параметр | Значення | +|----------|----------| +| **Hostname** | node1-daarion | +| **IPv4** | 144.76.224.179 | +| **IPv6** | 2a01:4f8:201:2a6::2 | +| **SSH** | `ssh root@144.76.224.179` (IPv4) або `ssh root@'[2a01:4f8:201:2a6::2]'` (IPv6) | +| **Корінь проекту** | `/opt/microdao-daarion/` | + +**Credentials (SSH):** у файлі `.cursor/noda1-credentials.local.mdc` (username root, password, host keys). Файл у .gitignore. Для автоматизації: `sshpass -p '<з файлу>' ssh -o StrictHostKeyChecking=accept-new root@144.76.224.179 "..."`. + +## Ключові сервіси (порти на сервері, localhost) + +| Сервіс | Порт | Health | +|--------|------|--------| +| Router | 9102 | `/health` | +| Gateway | 9300 | `/health` (містить список агентів) | +| Memory | 8000 | `/health` | +| Qdrant | 6333 | `/healthz` | +| RAG | 9500 | `/health` | +| Swapper | 8890 | `/health` | + +Контейнери: `dagi-gateway-node1`, `dagi-staging-router` (або `dagi-*-router`), `dagi-memory-service-node1`, `dagi-qdrant-node1`. + +## Перевірка агентів + +- На сервері: `cd /opt/microdao-daarion && ./scripts/node1/verify_agents.sh` +- Gateway health (список агентів): `curl -s http://localhost:9300/health | jq '.agents'` +- E2E: `curl -s -X POST http://localhost:9300/debug/agent_ping -H "Content-Type: application/json" -d '{}'` + +Детально: `docs/NODA1-AGENT-VERIFICATION.md`. + +## Типові виправлення + +1. **Router unhealthy** — перезапуск: `docker restart dagi-staging-router` (або актуальна назва контейнера router). +2. **Gateway не відповідає** — `docker logs dagi-gateway-node1 --tail 100`; при потребі `docker restart dagi-gateway-node1`. +3. **Агент без prompt/token** — перевірити `gateway-bot/http_api.py` (AGENT_REGISTRY) і наявність `*_prompt.txt` та env з токенами на сервері. +4. **Зміни в коді** — задеплоїти на NODA1 (git pull, rebuild, restart відповідних контейнерів згідно з проектом). + +## Документація (для агента НОДА1) + +Читати при потребі контексту: + +| Документ | Шлях | Призначення | +|----------|------|-------------| +| **Master Index** | `PROJECT-MASTER-INDEX.md` | Єдина точка входу до всієї документації, порти, сервіси, швидкі команди | +| **Статус НОДА1** | `NODA1-CURRENT-STATUS-2026-01-26.md` | Поточний статус сервера, health, бекапи, Qdrant collections | +| **Перевірка агентів** | `docs/NODA1-AGENT-VERIFICATION.md` | Як перевіряти агентів на NODA1, health, E2E, webhook | +| **Архітектура агентів** | `docs/NODA1-AGENT-ARCHITECTURE.md` | Повна схема підключення агентів (якщо файл існує) | +| **Як додавати агентів** | `config/README.md` | Інструкція додавання нових агентів (якщо файл існує) | diff --git a/.cursor/skills/noda1-operations/SKILL.md b/.cursor/skills/noda1-operations/SKILL.md new file mode 100644 index 00000000..716abf44 --- /dev/null +++ b/.cursor/skills/noda1-operations/SKILL.md @@ -0,0 +1,72 @@ +--- +name: noda1-operations +description: Operates and troubleshoots NODA1 (node1-daarion) production server — health checks, agent verification, container restarts, deployment. Use when the user asks about NODA1, node1-daarion, verifying agents on the server, fixing gateway/router, or deploying to NODA1. +--- + +# NODA1 Operations + +Опікування сервером NODA1: перевірка агентів, health-сервісів, типові виправлення. SSH-credentials зберігаються в **.cursor/noda1-credentials.local.mdc** (файл у .gitignore, не комітити). + +## Контекст + +- **Сервер:** 144.76.224.179 (node1-daarion), IPv6: 2a01:4f8:201:2a6::2, проект на сервері: `/opt/microdao-daarion/` +- **Credentials:** читати з `.cursor/noda1-credentials.local.mdc` (username, password, host keys) для виконання SSH-команд. +- **Документація для агента НОДА1 (читати при потребі):** + - `PROJECT-MASTER-INDEX.md` — єдина точка входу, порти, сервіси, швидкі команди + - `NODA1-CURRENT-STATUS-2026-01-26.md` — поточний статус НОДА1, health, бекапи, Qdrant + - `docs/NODA1-AGENT-VERIFICATION.md` — перевірка агентів, health, E2E + - `docs/NODA1-AGENT-ARCHITECTURE.md` — повна архітектура агентів (якщо є) + - `config/README.md` — як додавати агентів (якщо є) +- **Cursor Rule:** `.cursor/rules/noda1-operations.mdc` — порти, контейнери, швидкі команди + +## 1. Перевірка агентів на NODA1 + +Credentials: **.cursor/noda1-credentials.local.mdc** (root, password, host keys). Для виконання SSH з терміналу використовувати `sshpass` і пароль з цього файлу. + +Виконувати **на сервері** (після SSH): + +```bash +ssh root@144.76.224.179 +cd /opt/microdao-daarion +./scripts/node1/verify_agents.sh +``` + +Або однією командою (з sshpass, пароль з noda1-credentials.local.mdc): + +```bash +sshpass -p '' ssh -o StrictHostKeyChecking=accept-new root@144.76.224.179 "cd /opt/microdao-daarion && ./scripts/node1/verify_agents.sh" +``` + +По IPv6 (лапки обов'язкові в zsh): `ssh root@'[2a01:4f8:201:2a6::2]'` + +Скрипт перевіряє: prober metrics, Prometheus, Gateway /health (список агентів), /debug/agent_ping (E2E), webhook Helion. + +## 2. Health сервісів (на сервері) + +Після SSH виконати на NODA1: + +```bash +curl -s http://localhost:9300/health | jq '.status, .agents_count, .agents' +curl -s http://localhost:9102/health +curl -s http://localhost:8000/health +curl -s http://localhost:6333/healthz +docker ps --format 'table {{.Names}}\t{{.Status}}' | grep -E 'gateway|router|memory|qdrant' +``` + +## 3. Типові виправлення + +| Проблема | Дія (на сервері) | +|----------|-------------------| +| Router unhealthy | `docker restart dagi-staging-router` (або поточне ім’я контейнера router) | +| Gateway не відповідає | `docker logs dagi-gateway-node1 --tail 100`; при потребі `docker restart dagi-gateway-node1` | +| Memory 500 | Перевірити env `MEMORY_QDRANT_HOST` та доступність Qdrant | +| Агент без prompt/token | Перевірити `gateway-bot/http_api.py` (AGENT_REGISTRY) і на сервері: `*_prompt.txt`, env з `*_TELEGRAM_BOT_TOKEN` | + +## 4. Виправлення помилок + +- **У репо (код, конфіги, скрипти):** зміни робити локально в репозиторії, коміт, при потребі — деплой на NODA1. +- **На сервері:** для виконання команд через SSH читати пароль з `.cursor/noda1-credentials.local.mdc` і виконувати: `sshpass -p '<пароль з файлу>' ssh -o StrictHostKeyChecking=accept-new root@144.76.224.179 "команда"`. + +## 5. Деплой на NODA1 + +Згідно з проектом: зазвичай `git pull` у `/opt/microdao-daarion`, потім rebuild/restart відповідних сервісів (docker-compose або окремі `docker restart`). Точний процес дивитися в `PROJECT-MASTER-INDEX.md` та deployment-документації репо. diff --git a/.gitignore b/.gitignore index 59973d0a..75df0b46 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,4 @@ models/ *.bundle *.dump site/ +.cursor/noda1-credentials.local.mdc diff --git a/PROJECT-MASTER-INDEX.md b/PROJECT-MASTER-INDEX.md index ba20069c..55c182cd 100644 --- a/PROJECT-MASTER-INDEX.md +++ b/PROJECT-MASTER-INDEX.md @@ -94,8 +94,10 @@ python3 tools/agents smoke --id # Smoke test | Документ | Шлях | Опис | |----------|------|------| -| **NODA1-AGENT-ARCHITECTURE.md** | `docs/` | **Повна схема підключення агентів** | -| **agent_registry.yml** | `config/` | **Canonical Source of Truth для агентів** | +| **NODA1-AGENT-ARCHITECTURE.md** | `docs/` | Повна схема підключення агентів | +| **NODA1-AGENT-VERIFICATION.md** | `docs/` | **Перевірка роботи агентів на NODA1** | +| **NODA1-VERIFICATION-REPORT-2026-02-03.md** | `docs/` | Звіт перевірки НОДА1, виправлення ROUTER_URL, рекомендації | +| **agent_registry.yml** | `config/` | Canonical Source of Truth для агентів (якщо впроваджено) | | **README.md (config)** | `config/` | Як додавати нових агентів | | INFRASTRUCTURE.md | `docs/` | Порти, сервіси, конфігурація | | infrastructure_quick_ref.ipynb | `docs/` | Швидка довідка | @@ -234,10 +236,15 @@ docker restart dagi-gateway-node1 ## 📋 Швидкі команди -### Перевірка статусу NODA1 +### Перевірка статусу та агентів NODA1 ```bash +# Статус контейнерів ssh root@144.76.224.179 "docker ps --format 'table {{.Names}}\t{{.Status}}'" + +# Повна перевірка агентів (на сервері) +ssh root@144.76.224.179 "cd /opt/microdao-daarion && ./scripts/node1/verify_agents.sh" ``` +Детально: `docs/NODA1-AGENT-VERIFICATION.md` ### Логи gateway ```bash diff --git a/config/README.md b/config/README.md new file mode 100644 index 00000000..476f31f5 --- /dev/null +++ b/config/README.md @@ -0,0 +1,43 @@ +# Config — конфігурація проекту + +## Як додавати нових агентів (NODA1 / Gateway) + +Агенти реєструються в **gateway-bot** і підключаються до Router. Для нового агента: + +### 1. Код у `gateway-bot/http_api.py` + +- Додати конфігурацію через `load_agent_config()`: + - `agent_id`, `name`, `prompt_path` (файл у `gateway-bot/`), `telegram_token_env` (ім’я змінної середовища для Telegram-токена), `default_prompt`. +- Додати запис у **AGENT_REGISTRY**: `"new_agent_id": NEW_AGENT_CONFIG`. +- Додати webhook endpoint: `@router.post("/new_agent_id/telegram/webhook")` → `handle_telegram_webhook(NEW_AGENT_CONFIG, update)`. + +### 2. Файли в репо + +- **Prompt:** `gateway-bot/new_agent_id_prompt.txt` — system prompt агента. +- На сервері (NODA1) у env контейнера gateway додати змінну з Telegram-токеном бота (наприклад `NEW_AGENT_TELEGRAM_BOT_TOKEN`). + +### 3. Router + +Router приймає запити на `POST /v1/agents/{agent_id}/infer`. Якщо Router має окремий список агентів (наприклад `router_agents.json`), додати туди `new_agent_id`. + +### 4. Після змін на НОДА1 + +- Задеплоїти зміни (git pull у `/opt/microdao-daarion`). +- Перезапустити Gateway: `docker restart dagi-gateway-node1`. +- Перевірити: `curl -s http://localhost:9300/health | jq '.agents'` — новий агент має бути в списку з `prompt_loaded: true` і `telegram_token_configured: true`. + +--- + +## Інші конфіги у `config/` + +- **agents_city_mapping.yaml** — маппінг агентів для city/platform. +- **data_cleanup_allowlist.yml** — allowlist для очистки даних. +- **brand/** — конфіги брендів. + +--- + +## Документація + +- **PROJECT-MASTER-INDEX.md** — єдина точка входу до документації, швидкі команди. +- **docs/NODA1-AGENT-ARCHITECTURE.md** — архітектура агентів на НОДА1. +- **docs/NODA1-AGENT-VERIFICATION.md** — перевірка агентів на НОДА1. diff --git a/docker-compose.node1.yml b/docker-compose.node1.yml index f8c539af..6b56386b 100644 --- a/docker-compose.node1.yml +++ b/docker-compose.node1.yml @@ -37,14 +37,16 @@ services: - ./services/router/router_config.yaml:/app/router_config.yaml:ro - ./logs:/app/logs networks: - - dagi-network + dagi-network: + aliases: + - router restart: unless-stopped healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""] interval: 30s timeout: 10s - retries: 3 - start_period: 10s + retries: 5 + start_period: 30s # Swapper Service для NODE1 - Dynamic LLM + OCR model loading swapper-service: @@ -124,7 +126,8 @@ services: ports: - "9300:9300" environment: - - ROUTER_URL=http://router:8000 + # На NODA1 якщо router контейнер називається dagi-staging-router — в .env задати ROUTER_URL=http://dagi-staging-router:8000 + - ROUTER_URL=${ROUTER_URL:-http://router:8000} - SERVICE_ID=gateway - SERVICE_ROLE=gateway - BRAND_INTAKE_URL=http://brand-intake:9211 @@ -165,7 +168,9 @@ services: - router - memory-service networks: - - dagi-network + dagi-network: + aliases: + - gateway restart: unless-stopped healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9300/health')\""] @@ -184,7 +189,9 @@ services: volumes: - nats-data-node1:/data networks: - - dagi-network + dagi-network: + aliases: + - nats restart: unless-stopped # MinIO Object Storage @@ -433,7 +440,9 @@ services: depends_on: - qdrant networks: - - dagi-network + dagi-network: + aliases: + - memory-service restart: unless-stopped healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""] @@ -472,7 +481,9 @@ services: volumes: - qdrant-data-node1:/qdrant/storage networks: - - dagi-network + dagi-network: + aliases: + - qdrant restart: unless-stopped healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:6333/healthz || exit 1"] @@ -496,7 +507,9 @@ services: - neo4j-data-node1:/data - neo4j-logs-node1:/logs networks: - - dagi-network + dagi-network: + aliases: + - neo4j restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7474"] diff --git a/docs/NODA1-AGENT-ARCHITECTURE.md b/docs/NODA1-AGENT-ARCHITECTURE.md new file mode 100644 index 00000000..a0950cfb --- /dev/null +++ b/docs/NODA1-AGENT-ARCHITECTURE.md @@ -0,0 +1,50 @@ +# Архітектура агентів на НОДА1 + +**Сервер:** node1-daarion (144.76.224.179) +**Призначення:** Схема підключення агентів, потік запитів, сервіси. + +--- + +## Схема потоку (спрощена) + +``` +TELEGRAM → GATEWAY:9300 → ROUTER:9102 → LLM (Ollama/Swapper) + ↓ ↓ + Memory:8000 CrewAI (за потреби) + ↓ + Qdrant + Neo4j + Postgres +``` + +- **Gateway** приймає webhook з Telegram, визначає агента за шляхом (`/{agent_id}/telegram/webhook`), завантажує system prompt з `gateway-bot/*_prompt.txt`, відправляє запит у **Router**. +- **Router** викликає LLM (через Swapper/Ollama), при потребі CrewAI; результат повертається в Gateway. +- **Memory** зберігає/віддає контекст по `agent_id`; використовує Qdrant, Postgres. + +--- + +## Ключові сервіси (порти на НОДА1) + +| Сервіс | Порт | Health | +|--------|------|--------| +| Router | 9102 | `/health` | +| Gateway | 9300 | `/health` (містить список агентів) | +| Memory Service | 8000 | `/health` | +| Qdrant | 6333 | `/healthz` | +| RAG | 9500 | `/health` | +| Swapper | 8890 | `/health` | + +Контейнери: `dagi-gateway-node1`, `dagi-staging-router` (або `dagi-router-node1`), `dagi-memory-service-node1`, `dagi-qdrant-node1` тощо. Якщо Router на ноді називається `dagi-staging-router`, у `.env` на сервері задати `ROUTER_URL=http://dagi-staging-router:8000` для Gateway. + +--- + +## Реєстр агентів (Gateway) + +У `gateway-bot/http_api.py` — **AGENT_REGISTRY**: daarwizz, helion, greenfood, agromatrix, alateya, nutra, druid, clan, eonarch. Кожен агент має webhook `/{agent_id}/telegram/webhook`, prompt-файл і env з Telegram-токеном. + +--- + +## Пов’язані документи + +- **PROJECT-MASTER-INDEX.md** — єдина точка входу, порти, сервіси, швидкі команди +- **NODA1-CURRENT-STATUS-2026-01-26.md** — поточний статус НОДА1 +- **docs/NODA1-AGENT-VERIFICATION.md** — перевірка роботи агентів на НОДА1 +- **config/README.md** — як додавати нових агентів diff --git a/docs/NODA1-AGENT-VERIFICATION.md b/docs/NODA1-AGENT-VERIFICATION.md new file mode 100644 index 00000000..866f129b --- /dev/null +++ b/docs/NODA1-AGENT-VERIFICATION.md @@ -0,0 +1,105 @@ +# Перевірка роботи агентів на NODA1 + +**Сервер:** 144.76.224.179 (node1-daarion) +**Корінь проекту на сервері:** `/opt/microdao-daarion/` + +--- + +## Швидка перевірка (на сервері) + +Підключіться по SSH і виконайте скрипт перевірки: + +```bash +ssh root@144.76.224.179 +cd /opt/microdao-daarion +./scripts/node1/verify_agents.sh +``` + +Скрипт перевіряє: + +1. **Prober metrics** (9108) — чи працює agent-e2e-prober +2. **Prometheus targets** (9090) — чи збираються метрики +3. **POST /debug/agent_ping** (9300) — E2E: Gateway → Router → Memory +4. **GET /health** (9300) — стан Gateway та список агентів (prompt завантажено, Telegram токен налаштовано) +5. **Webhook Helion** — відповідь на тестовий POST на `/helion/telegram/webhook` + +--- + +## Ручні перевірки (на NODA1, localhost) + +Виконуйте **після SSH на сервер** (`ssh root@144.76.224.179`). + +### Health сервісів + +```bash +curl -s http://localhost:9102/health # Router +curl -s http://localhost:9300/health # Gateway (тут список агентів) +curl -s http://localhost:8000/health # Memory Service +curl -s http://localhost:6333/healthz # Qdrant +``` + +### Список агентів і їх конфіг (Gateway) + +```bash +curl -s http://localhost:9300/health | jq '.agents' +``` + +Очікуваний вивід — по кожному агенту: `name`, `prompt_loaded` (true/false), `telegram_token_configured` (true/false). + +### E2E probe (Gateway → Router → Memory) + +```bash +curl -s -X POST http://localhost:9300/debug/agent_ping -H "Content-Type: application/json" -d '{}' | jq . +``` + +Успіх: `router_ok: true`, `memory_ok: true`. + +### Статус контейнерів + +```bash +docker ps --format 'table {{.Names}}\t{{.Status}}' | grep -E 'gateway|router|memory|qdrant' +``` + +Очікувані контейнери (залежить від docker-compose): `dagi-gateway-node1`, router, memory-service, qdrant. + +### Логи Gateway (останні рядки) + +```bash +docker logs dagi-gateway-node1 --tail 50 +``` + +--- + +## Агенти в Gateway (реєстр) + +У `gateway-bot/http_api.py` реєстр **AGENT_REGISTRY** містить: + +| agent_id | Webhook path | +|------------|-------------------------------| +| daarwizz | `/telegram/webhook` (default) | +| helion | `/helion/telegram/webhook` | +| greenfood | `/greenfood/telegram/webhook` | +| nutra | `/nutra/telegram/webhook` | +| agromatrix | `/agromatrix/telegram/webhook`| +| alateya | `/alateya/telegram/webhook` | +| druid | `/druid/telegram/webhook` | +| clan | `/clan/telegram/webhook` | +| eonarch | `/eonarch/telegram/webhook` | + +Router викликається як: `POST {ROUTER_URL}/v1/agents/{agent_id}/infer`. + +--- + +## Якщо з локальної машини (без SSH) + +- Порти 9102, 9300, 8000 тощо на NODA1 можуть бути недоступні ззовні (firewall). +- Тоді єдиний варіант — виконувати перевірки **після SSH на сервер** (команди вище). +- Альтернатива: налаштувати SSH-тунель і тоді `curl http://localhost:9300/health` на своєму ноутбуку через тунель. + +--- + +## Посилання + +- **PROJECT-MASTER-INDEX.md** — єдина точка входу до документації, порти, сервіси. +- **NODA1-CURRENT-STATUS-2026-01-26.md** — поточний статус NODA1, health endpoints. +- **gateway-bot/http_api.py** — реєстр агентів, `/health`, `/debug/agent_ping`. diff --git a/docs/NODA1-VERIFICATION-REPORT-2026-02-03.md b/docs/NODA1-VERIFICATION-REPORT-2026-02-03.md new file mode 100644 index 00000000..a0383cea --- /dev/null +++ b/docs/NODA1-VERIFICATION-REPORT-2026-02-03.md @@ -0,0 +1,164 @@ +# Звіт перевірки НОДА1 та виправлення + +**Дата:** 2026-02-03 +**Сервер:** node1-daarion (144.76.224.179) +**Статус:** ✅ ВСІ СИСТЕМИ ПРАЦЮЮТЬ + +--- + +## Фінальний стан після виправлень + +| Метрика | Значення | +|---------|----------| +| `agent_e2e_success{gateway_health}` | **1.0** ✅ | +| `agent_e2e_success{agent_ping}` | **1.0** ✅ | +| `agent_e2e_success{webhook_e2e}` | **1.0** ✅ | +| Router | **healthy** ✅ | +| Gateway | **healthy** ✅ | +| Memory | **healthy** ✅ | +| E2E `/debug/agent_ping` | `success: true, router: true, memory_service: true` ✅ | + +--- + +## Результати перевірки (до виправлень) + +### Що працювало + +| Компонент | Статус | +|-----------|--------| +| **Gateway** (9300) | healthy, 9 агентів, prompt + Telegram токен налаштовані | +| **Router** (9102) | відповідає 200, NATS connected, обробляє infer | +| **Memory Service** (8000) | healthy | +| **Qdrant** (6333) | доступний | +| **Webhook Helion** | приймає POST, skipped (no_message) — очікувано | +| **Prober metrics** (9108) | доступні | +| **Prometheus** | prober у targets | + +### Що було зламано (виправлено) + +| Проблема | Причина | Виправлення | +|----------|---------|-------------| +| **E2E /debug/agent_ping** повертав `success: false`, помилка "Temporary failure in name resolution" | Gateway мав `ROUTER_URL=http://router:8000`, а контейнер Router на сервері називається **dagi-staging-router** — хост `router` не резолвився в мережі | У `.env` на NODA1 задано `ROUTER_URL=http://dagi-staging-router:8000`, Gateway перезапущено. У `docker-compose.node1.yml` додано підтримку змінної: `ROUTER_URL=${ROUTER_URL:-http://router:8000}` | +| **Router** у `docker ps` показував **unhealthy** | Healthcheck може тимчасово фейлити або використовувати інший порт; сам сервіс відповідає 200 | Можна переглянути healthcheck або збільшити start_period/retries; функціонально Router працює | + +--- + +## Виправлення, які застосовано + +1. **Репо:** у `docker-compose.node1.yml` для gateway: + - `ROUTER_URL=http://router:8000` замінено на `ROUTER_URL=${ROUTER_URL:-http://router:8000}`. + - Якщо на сервері Router запущений під ім’ям контейнера (наприклад `dagi-staging-router`), в `.env` задається `ROUTER_URL=http://dagi-staging-router:8000`. + +2. **На NODA1:** + - У `/opt/microdao-daarion/.env` додано/встановлено `ROUTER_URL=http://dagi-staging-router:8000`. + - У `docker-compose.node1.yml` на сервері зроблено той самий патч для підтримки `${ROUTER_URL}`. + - Виконано `docker compose -f docker-compose.node1.yml up -d gateway --no-deps --force-recreate`. + +Після цього **POST /debug/agent_ping** повертає `success: true`, `router: true`, `memory_service: true`. + +--- + +## Виправлення Session 2 (детально) + +### 1. Network alias `router` для dagi-staging-router + +**Проблема:** Gateway очікував хост `router`, але контейнер Router називався `dagi-staging-router` без alias. + +**Виправлення:** +```bash +docker network disconnect dagi-network dagi-staging-router +docker network connect --alias router --alias dagi-staging-router dagi-network dagi-staging-router +``` + +Тепер `getent hosts router` з Gateway повертає IP Router. + +### 2. Healthcheck Router: `requests` → `urllib` + +**Проблема:** Healthcheck у Dockerfile використовував `import requests`, якого не було в образі → `unhealthy` (FailingStreak: 13760). + +**Виправлення в `services/router/Dockerfile`:** +```dockerfile +# Було: +HEALTHCHECK ... CMD python -c "import requests; requests.get('http://localhost:8000/health')" + +# Стало: +HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=5 \ + CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" +``` + +Router перебілджено та перезапущено → тепер `healthy`. + +### 3. Prober: GATEWAY_URL з IP → DNS + +**Проблема:** Prober мав `GATEWAY_URL=http://172.18.0.18:9300` (старий IP Gateway). Після recreate Gateway отримав новий IP → prober не міг підключитися. + +**Виправлення:** +```bash +docker rm agent-e2e-prober-node1 +docker run -d --name agent-e2e-prober-node1 --network dagi-network \ + -p 9108:9108 -e GATEWAY_URL=http://gateway:9300 ... +``` + +Тепер prober використовує DNS `gateway`, яке стабільне. + +### 4. Memory→Qdrant + +**Статус:** Вже правильно налаштовано: `MEMORY_QDRANT_HOST=dagi-qdrant-node1`, резолвиться коректно. + +--- + +## Рекомендації з архітектури та налаштування агентів + +### 1. Єдине ім’я Router у мережі + +- **Проблема:** у `docker-compose.node1.yml` сервіс називається `router` з `container_name: dagi-router-node1`, а на NODA1 фактично працює контейнер `dagi-staging-router` (інший compose/проект). Тому Gateway не міг резолвити `router`. +- **Рекомендація:** на NODA1 використовувати один compose (наприклад `docker-compose.node1.yml`) для Gateway і Router, щоб DNS-ім’я `router` з’являлось автоматично. Або завжди задавати в `.env` на ноді `ROUTER_URL=http://<фактичне ім’я контейнера>:8000` і документувати це в `docs/NODA1-AGENT-VERIFICATION.md` / `PROJECT-MASTER-INDEX.md`. + +### 2. Healthcheck Router + +- Якщо контейнер Router продовжує показувати **unhealthy** при робочому `/health`, перевірити на сервері: + - який саме healthcheck використовується (порт, шлях); + - чи не короткий `interval`/`timeout` або малий `start_period`. +- Можна вирівняти healthcheck з фактичним endpoint (наприклад `GET http://localhost:8000/health`) і при потребі збільшити `start_period` та `retries`. + +### 3. Memory: Qdrant hostname + +- У `docker-compose.node1.yml` Memory має `MEMORY_QDRANT_HOST=qdrant`; контейнер Qdrant — `dagi-qdrant-node1`. Переконатися, що в мережі є DNS-ім’я `qdrant` (наприклад через `networks`/alias), інакше в `.env` на ноді задати `MEMORY_QDRANT_HOST=dagi-qdrant-node1` (як у NODA1-CURRENT-STATUS). + +### 4. Реєстр агентів (Gateway) + +- Всі 9 агентів у реєстрі мають `prompt_loaded: true` і `telegram_token_configured: true` — конфігурація в порядку. +- Для додавання нових агентів дивитися `config/README.md` та `gateway-bot/http_api.py` (AGENT_REGISTRY + webhook + env). + +### 5. Prober (agent_e2e_success) + +- Метрика `agent_e2e_success{target="gateway_health"} 0.0` могла залишитися від попередніх запусків. Після виправлення E2E варто почекати наступного циклу prober або перезапустити prober, щоб метрика оновилась. + +### 6. Документація + +- У `docs/NODA1-AGENT-ARCHITECTURE.md` вже зазначено фактичні імена контейнерів (зокрема `dagi-staging-router`). Додати короткий пункт про те, що на ноді в `.env` має бути `ROUTER_URL=http://dagi-staging-router:8000`, якщо Router запущений під цим ім’ям. +- У `docs/NODA1-AGENT-VERIFICATION.md` та в скрипті `scripts/node1/verify_agents.sh` залишити поточні кроки; при потребі додати перевірку `POST /debug/agent_ping` з очікуванням `success: true`. + +--- + +## Швидкі команди після змін + +```bash +# На NODA1 +ssh root@144.76.224.179 +cd /opt/microdao-daarion +./scripts/node1/verify_agents.sh + +# E2E probe +curl -s -X POST http://localhost:9300/debug/agent_ping -H "Content-Type: application/json" -d '{}' +# Очікується: "success":true, "checks":{"router":true,"memory_service":true} +``` + +--- + +## Пов’язані документи + +- **PROJECT-MASTER-INDEX.md** — єдина точка входу +- **docs/NODA1-AGENT-VERIFICATION.md** — перевірка агентів +- **docs/NODA1-AGENT-ARCHITECTURE.md** — архітектура +- **config/README.md** — додавання агентів diff --git a/scripts/node1/verify_agents.sh b/scripts/node1/verify_agents.sh index 54d071ce..ef5e7155 100644 --- a/scripts/node1/verify_agents.sh +++ b/scripts/node1/verify_agents.sh @@ -37,12 +37,20 @@ echo " $PING_RESULT" echo "" -# 4. Gateway health -echo "4. Gateway health..." +# 4. Gateway health та список агентів +echo "4. Gateway health та агенти..." HEALTH=$(curl -s http://localhost:9300/health 2>/dev/null || echo '{"status":"error"}') if echo "$HEALTH" | grep -q "healthy"; then echo " ✅ Gateway healthy" - echo " $HEALTH" | head -c 200 + AGENTS_COUNT=$(echo "$HEALTH" | grep -o '"agents_count":[0-9]*' | cut -d: -f2) + echo " Агентів у реєстрі: ${AGENTS_COUNT:-?}" + if command -v jq >/dev/null 2>&1; then + echo " Агенти (prompt | telegram token):" + echo "$HEALTH" | jq -r '.agents | to_entries[] | " - \(.key): prompt=\(.value.prompt_loaded) token=\(.value.telegram_token_configured)"' 2>/dev/null || echo "$HEALTH" | head -c 400 + else + echo " (встановіть jq для детального виводу: .agents)" + echo "$HEALTH" | head -c 400 + fi else echo " ❌ Gateway unhealthy: $HEALTH" fi