Skip to content

# TASK_PHASE_NODE2_FULL_DAGI_INTEGRATION_v1

Проєкт: DAARION.city
Нода: NODE2 (MacBook M4 Max)
Мета: зробити так, щоб DAARION MVP бачив реальний DAGI-стек NODE2:

- Swapper з локальними моделями (Ollama, HF);
- DAGI Router та Gateway;
- усі ~50 DAGI-агентів у районах міста;
- коректні метрики в Node Cabinet.

## 0. Джерела істини (OBLIGATORY READ)

Спочатку прочитати, не редагувати:

- `docs/users/nodes/NODE_STATE_node-2-macbook-m4max.md`
- `docs/users/nodes/NODE_STATE_node-1-hetzner-gex44.md` (для порівняння)
- `docs/users/nodes/walkthrough.md` (якщо існує)
- `docs/users/nodes/NODE_GUARDIAN_AND_STEWARD.md`
- `docs/tasks/TASK_PHASE_SWAPPER_NODE_METRICS_AND_UI_v1.md`
- `docs/tasks/TASK_PHASE_NODE2_ROUTER_SWAPPER_ISOLATION_AND_AGENT_DISCOVERY_v1.md`

Конфігурація DAGI на NODE2 (знайти й використати, не вигадувати заново):

- `swapper_config_node2.yaml`
- `router_config_node2.yaml` (або подібний)
- `agents_city_mapping.yaml` / `agents/`
- логи в `logs/node2_*`

Мета цього таска — під'єднати існуючий стек, а не створювати новий.

## 1. Поточний стан (узагальнення)

Зафіксувати в коментарях до MR (або в кінці файлу), але орієнтовно:

- NODE2:
- Swapper: працює на `http://localhost:8890`, статус healthy, 8 моделей;
- DAGI Router: працює на `http://localhost:9102`;
- LLM Proxy: `http://localhost:7007`;
- Gateway з 5 агентами (daarwizz, helion, greenfood, nutra, druid);
- ~50 DAGI-агентів, розкладених по районах (Leadership Hall, System Control, Engineering Lab, Marketing Hub, Finance Office, Web3 District, Security Bunker, Vision Studio, R&D Lab, Memory Vault);

- node-guardian вже шле heartbeat, але МВП не бачить агентів/моделей повністю.

- NODE1:

- Swapper + Router вже інтегровані в MVP й працюють як еталон.

## 2. Scope

### Включено

1. Swapper NODE2 → city-service

2. коректні метрики per-node (healthy, models_loaded/total, swapper_state).

3. DAGI Router NODE2 → city-service

4. статус роутера (up/down);

5. кількість агентів, список агентів з Router API.

6. Agent Registry NODE2

7. записати 50 DAGI-агентів у БД (таблиця `agents` / `node_agents` / аналогічна);

8. прив'язка до NODE2 та відповідних MicroDAO.

9. API для Node Cabinet

10. `/internal/node/{node_id}/models`
11. `/internal/node/{node_id}/router`

12. `/internal/node/{node_id}/agents` (або адаптація існуючих, якщо вони вже є).

13. UI Node Cabinet

14. NODE2 має показувати свої:
    - Swapper моделі;
    - Router статус;
    - список агентів (хоча б з іменем, типом і MicroDAO).

### Виключено

- CrewAI-кімнати, групові чати, кнопки створення кімнат — це окремий таск.
- Авто-самолікування роутера / свопера.
- Веб-інтерфейс кар'єру/налаштувань для кожного агента.

## 3. Swapper інтеграція NODE2

### 3.1. Перевірити конфіг

- підтвердити точний Swapper URL для NODE2:
- `http://localhost:8890/health`
- `http://localhost:8890/models` (або фактичний endpoint; див. `swapper_config_node2.yaml` та `logs/node2_swapper_models.json`).

### 3.2. Оновити node-guardian-loop (NODE2)

У `scripts/node-guardian-loop.py`:

- переконатися, що при запуску з NODE2:
- використовується локальний Swapper URL (`localhost`, а не `swapper-service`);

- логуються `node_id` і `swapper_url` (для дебагу в майбутньому).

- функція збору Swapper-метрик повинна:

- витягнути реальний список моделей;
- порахувати `models_total`, `models_loaded`;
- скласти `swapper_state` (JSON) з полями:
  - `name`
  - `backend` (ollama / hf / інше)
  - `type` (llm / code / vision / reasoning)
  - `loaded`
  - `vram_gb` (якщо відомо).

Передавати ці значення в `POST /internal/node/{node_id}/metrics/update`.

### 3.3. Перевірити fn_node_heartbeat та `node_cache`

- переконатися, що `fn_node_heartbeat` оновлює тільки один запис по `node_id` і не перетирає дані іншої ноди;

- стовпці:

- `swapper_healthy`
- `swapper_models_loaded`
- `swapper_models_total`
- `swapper_state`

Перевірити руками:

    select node_id, swapper_healthy, swapper_models_loaded, swapper_models_total
    from node_cache
    order by node_id;

## 4. DAGI Router інтеграція NODE2

### 4.1. Виявити Router API

З логів і конфігів (NODE2):

- підтвердити базовий URL:
- `http://localhost:9102` (наприклад, `/health`, `/status`, `/agents`).

Зробити невеликий helper (окрема функція) у `node-guardian-loop.py`:

    def collect_router_metrics(router_base_url: str) -> dict:
        # router_healthy (bool)
        # router_agents_total (int)
        # router_agents_active (int / optional)
        # router_state (json: список агентів з базовою інформацією)

Передавати ці дані в `metrics/update`.

### 4.2. Розширити схему БД (якщо потрібно)

Міграція, наприклад `migrations/041_node_cache_router_metrics.sql`:

- `router_healthy boolean`
- `router_agents_total integer`
- `router_state jsonb`

Оновити `repo_city.py` / `models_city.py` / `routes_city.py`, щоб ці поля поверталися для:

- `GET /internal/node/{node_id}/metrics/current`
- `GET /internal/node/{node_id}` (якщо є short summary).

## 5. Node2 Agent Registry (50 DAGI-агентів)

### 5.1. Зчитати конфіги

Знайти та використати (тільки читання):

- `agents_city_mapping.yaml`
- директорію `agents/` (конфіги окремих агентів)
- звіт discovery (walkthrough / NODE_STATE)

Не створювати агентів "із голови": брати тільки те, що описано в цих файлах.

### 5.2. Оновити таблиці БД

Залежно від існуючої схеми, але логіка така:

- таблиця `agents` / `node_agents` повинна мати:
- `id` / `slug`
- `node_id` (node-1 / node-2)
- `name`
- `role` / `district` / `team`
- `microdao_slug` (якщо прив'язано)
- `is_core` / `is_system` / `is_microdao` (флаги)
- `model_name` / `model_backend` (ollama / hf / інше)

Потрібно:

1. Створити окремий sync-скрипт для NODE2, напр.: `scripts/sync-node2-dagi-agents.py`

Він повинен: * прочитати `agents_city_mapping.yaml` та `agents/`; * для кожного агента: * вставити/оновити запис у БД з `node_id = 'node-2-macbook-m4max'`; * не чіпати агентів NODE1.

1. Перед запуском — зробити dry-run (print summary), потім запустити реально.

## 6. API для Node Cabinet (тільки те, що потрібно зараз)

### 6.1. Agents

Endpoint:

- `GET /internal/node/{node_id}/agents`

Повертає:

    {
      "node_id": "node-2-macbook-m4max",
      "total": 50,
      "agents": [
        {
          "id": "helix",
          "name": "Helix",
          "role": "CTO",
          "district": "System Control",
          "microdao": "daarion-dao",
          "model_name": "qwen2.5-coder:32b",
          "kind": "core"
        },
        ...
      ]
    }

Node Cabinet на фронтенді вже має секцію "Агенти цієї ноди" — під'єднати її до цього endpoint (без змін дизайну).

### 6.2. Models (опційно, але бажано)

`GET /internal/node/{node_id}/models`

Повертає агреговані дані з `swapper_state`:

- скільки моделей,
- які backend'и,
- який тип.

Це потрібно, щоб у Node Cabinet список моделей точно відповідав тому, що Swapper бачить на NODE2.

## 7. UI Node Cabinet — очікуваний результат для NODE2

Після завершення таска:

1. Swapper Service (NODE2):
2. статус: `Healthy`;
3. `Models Loaded: X / 8` (від Swapper, а не від NODE1);

4. у списку моделей показуються саме локальні:

   - `deepseek-r1:70b`, `qwen2.5-coder:32b`, `gemma2:27b`, `mistral-nemo`, `phi3`, `starcoder2`, `gpt-oss`, `deepseek-coder:33b`.

5. DAGI Router (NODE2):

6. статус: `Up` (якщо сервіс запущений);
7. `Agents: 50` (або актуальна кількість);

8. кнопка "Агенти цієї ноди" відкриває список з усіма 50 агентами.

9. Ізоляція по node_id:

10. NODE1 показує свої 9 агентів і 7 моделей;
11. NODE2 показує свої 50 агентів і 8 моделей, але через свій Swapper/Router;
12. дані не змішуються.

## 8. Acceptance Criteria

1. `scripts/discover_node_state.py` (якщо є) показує різні Router/Swapper-дані для NODE1 та NODE2 (і вони збігаються з Node Cabinet).

2. `GET /internal/node/node-2-macbook-m4max/metrics/current` показує:

3. `swapper_healthy = true`,
4. `swapper_models_total = 8`,
5. `router_healthy = true`,

6. `router_agents_total >= 40`.

7. `GET /internal/node/node-2-macbook-m4max/agents` повертає список із ~50 агентів.

8. На UI:

9. Node Cabinet для NODE2 показує коректні Swapper-метрики й Router-агентів;

10. при перезапуску node-guardian дані оновлюються без ручних SQL.

11. Жоден endpoint / UI-блок для NODE1 не зламаний.

## 9. Район-агент маппінг (50 агентів NODE2)

### Leadership Hall (4)

- Solarius (CEO)
- Sofia
- PrimeSynth
- Nexor

### System Control (6)

- monitor-node2
- vindex
- helix
- aurora
- та інші...

### Engineering Lab (5)

- byteforge
- vector
- chainweaver
- cypher
- canvas

### Marketing Hub (6)

- roxy
- mira
- tempo
- harmony
- faye
- та інші...

### Finance Office (4)

- financial-analyst
- accountant
- budget-planner
- та інші...

### Web3 District (5)

- smart-contract-dev
- defi-analyst
- tokenomics-expert
- та інші...

### Security Bunker (7)

- shadelock
- exor
- penetration-tester
- та інші...

### Vision Studio (4)

- iris
- lumen
- spectra
- video-analyzer

### R&D Lab (6)

- protomind
- labforge
- testpilot
- modelscout
- та інші...

### Memory Vault (3)

- somnia
- memory-manager
- knowledge-indexer

Як тільки цей крок буде виконаний і задеплоєний, далі можемо рухатись: - крок 2: кімнати/чати MicroDAO + публічний головний чат; - крок 3: кнопки створення/видалення агента й групи (CrewAI-команди).