Skip to content

# TASK_PHASE_DAGI_AGENT_AUTOSYNC_AND_METRICS_v1

## Проєкт

DAARION.city — Node Cabinet / DAGI Router

## Мета

Створити стабільний, ергономічний та самовідновлюваний кабінет Ноди, де: - DAGI-агенти кожної ноди відображаються в таблиці на вкладці "DAGI Router" - Статуси агентів (Active / Phantom / Stale / Error) автоматично синхронізуються - GPU/CPU/RAM/Disks та кількість агентів стабільно відображаються - Є набір API тестів для захисту від регресій

## Зроблено

### 1. Database Migration (036)

Файл: `migrations/036_node_metrics_extended.sql`

Розширено `node_cache` полями: - CPU: `cpu_model`, `cpu_cores`, `cpu_usage` - GPU: `gpu_model`, `gpu_vram_total`, `gpu_vram_used` - RAM: `ram_total`, `ram_used` - Disk: `disk_total`, `disk_used` - Agents: `agent_count_router`, `agent_count_system` - Heartbeat: `last_heartbeat`, `dagi_router_url`

Початкові дані для NODE1 (Hetzner) та NODE2 (MacBook M4 Max).

### 2. Backend API Endpoints

Файли: - `services/city-service/repo_city.py` — repo методи - `services/city-service/routes_city.py` — FastAPI endpoints

#### Нові endpoints:

Endpoint | Метод | Опис
--- | --- | ---
`/internal/node/{node_id}/dagi-router/agents` | GET | Таблиця агентів для Node Cabinet
`/internal/node/{node_id}/metrics/current` | GET | Метрики ноди (GPU/CPU/RAM/Disk)
`/internal/node/{node_id}/metrics/update` | POST | Оновлення метрик (heartbeat)
`/internal/node/{node_id}/dagi-router/phantom/sync` | POST | Синхронізація phantom агентів
`/internal/node/{node_id}/dagi-router/stale/mark` | POST | Позначення stale агентів

#### Response structures:

GET /dagi-router/agents:

    {
      "node_id": "node-2-macbook-m4max",
      "last_audit_at": "2025-11-30T14:35:00Z",
      "summary": {
        "active": 12,
        "phantom": 2,
        "stale": 5,
        "router_total": 14,
        "system_total": 17
      },
      "agents": [
        {
          "id": "daria",
          "name": "DARIA",
          "role": "city_guide",
          "status": "active",
          "node_id": "node-2-macbook-m4max",
          "models": [],
          "gpu": "Apple M4 Max GPU",
          "cpu": "16 cores",
          "last_seen_at": "2025-11-30T14:34:50Z",
          "has_cabinet": true,
          "cabinet_slug": "daria"
        }
      ]
    }

GET /metrics/current:

    {
      "node_id": "node-2-macbook-m4max",
      "node_name": "MacBook Pro M4 Max",
      "cpu_model": "Apple M4 Max",
      "cpu_cores": 16,
      "cpu_usage": 35.5,
      "gpu_model": "Apple M4 Max GPU",
      "gpu_memory_total": 40960,
      "gpu_memory_used": 28000,
      "ram_total": 65536,
      "ram_used": 40000,
      "disk_total": 1024000,
      "disk_used": 400000,
      "agent_count_router": 14,
      "agent_count_system": 17,
      "last_heartbeat": "2025-11-30T05:14:59Z"
    }

### 3. Frontend Components

Нові/оновлені файли: - `apps/web/src/hooks/useDAGIAudit.ts` — хуки для API - `apps/web/src/components/node-dashboard/DAGIRouterCard.tsx` — таблиця агентів - `apps/web/src/components/node-dashboard/NodeMetricsCard.tsx` — метрики ноди - `apps/web/src/app/nodes/[nodeId]/page.tsx` — інтеграція в Node Cabinet

#### DAGIRouterCard Features:

- Таблиця агентів з колонками: Agent, Status, Runtime, Last Seen, Cabinet
- Фільтр по статусу (All / Active / Phantom / Stale)
- Пошук по імені агента
- Кнопка "Запустити аудит"
- Кнопка "Sync" для phantom агентів
- Лічильники Active/Phantom/Stale

#### NodeMetricsCard Features:

- Progress bars для GPU/CPU/RAM/Disk
- Показує модель GPU/CPU
- Agent counts (Router / System)
- Last heartbeat timestamp

### 4. API Tests

Файл: `tests/test_dagi_router_api.py`

Тести для: - `TestDAGIRouterAgents` — GET agents endpoint - `TestNodeMetrics` — GET metrics endpoint - `TestDAGIAudit` — POST audit endpoint - `TestPhantomStaleSync` — sync endpoints - `TestIntegration` — повний цикл

## Застосування на сервері

    # 1. Застосувати міграцію
    docker exec -i dagi-postgres psql -U postgres -d daarion < migrations/036_node_metrics_extended.sql

    # 2. Перезапустити city-service
    docker-compose restart daarion-city-service

    # 3. Зібрати frontend
    cd apps/web && npm run build

    # 4. Запустити тести
    cd /opt/microdao-daarion
    pytest tests/test_dagi_router_api.py -v

## Acceptance Criteria

- [x] API `/dagi-router/agents` повертає уніфіковану таблицю агентів
- [x] API `/metrics/current` повертає метрики ноди
- [x] Node Cabinet показує NodeMetricsCard з GPU/CPU/RAM/Disk
- [x] Node Cabinet показує DAGIRouterCard з таблицею агентів
- [x] Phantom агенти можна синхронізувати через UI
- [x] Stale агенти відображаються окремо
- [x] API тести покривають основні сценарії
- [x] Обидві ноди (NODE1, NODE2) працюють однаково

## Залежності

- Migration 035 (`agent_prompts_seed.sql`)
- Migration 022 (`node_cache` table)
- Migration 030 (`guardian_agent_id`, `steward_agent_id`)

## Наступні кроки

1. Інтегрувати heartbeat agent на нодах для оновлення метрик
2. Додати Grafana dashboard для візуалізації метрик
3. Реалізувати автоматичний periodic audit (cron job)