Files
microdao-daarion/migrations/037_node_agents_complete.sql
Apple bca81dc719 feat: Node Self-Healing, DAGI Audit, Agent Prompts, Infra Invariants
### Backend (city-service)
- Node Registry + Self-Healing API (migration 039)
- Improved get_all_nodes() with robust fallback for node_registry/node_cache
- Agent Prompts Runtime API for DAGI Router integration
- DAGI Router Audit endpoints (phantom/stale detection)
- Node Agents API (Guardian/Steward)
- Node metrics extended (CPU/GPU/RAM/Disk)

### Frontend (apps/web)
- Node Directory with improved error handling
- Node Cabinet with metrics cards
- DAGI Router Card component
- Node Metrics Card component
- useDAGIAudit hook

### Scripts
- check-invariants.py - deploy verification
- node-bootstrap.sh - node self-registration
- node-guardian-loop.py - continuous self-healing
- dagi_agent_audit.py - DAGI audit utility

### Migrations
- 034: Agent prompts seed
- 035: Agent DAGI audit
- 036: Node metrics extended
- 037: Node agents complete
- 038: Agent prompts full coverage
- 039: Node registry self-healing

### Tests
- test_infra_smoke.py
- test_agent_prompts_runtime.py
- test_dagi_router_api.py

### Documentation
- DEPLOY_CHECKLIST_2024_11_30.md
- Multiple TASK_PHASE docs
2025-11-30 13:52:01 -08:00

432 lines
17 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- Migration 037: Node Agents Complete Setup
-- Забезпечує існування всіх Node Agents з повними даними
-- ============================================================================
-- 1. Створити/оновити Node Guardian агентів
-- ============================================================================
-- NODE1 Guardian
INSERT INTO agents (
id,
external_id,
name,
display_name,
kind,
status,
node_id,
is_public,
is_node_guardian,
public_slug,
public_title,
public_tagline,
public_skills,
avatar_url,
created_at,
updated_at
) VALUES (
'monitor-node1',
'agent:monitor-node1',
'Node Guardian NODE1',
'Node Guardian (НОДА1)',
'node_guardian',
'online',
'node-1-hetzner-gex44',
true,
true,
'monitor-node1',
'Guardian of NODE1',
'Слідкую за інфраструктурою, метриками та безпекою продакшн-ноди.',
ARRAY['monitoring', 'security', 'infrastructure', 'alerts'],
NULL,
NOW(),
NOW()
)
ON CONFLICT (id) DO UPDATE SET
external_id = EXCLUDED.external_id,
name = EXCLUDED.name,
display_name = EXCLUDED.display_name,
kind = EXCLUDED.kind,
status = EXCLUDED.status,
node_id = EXCLUDED.node_id,
is_public = EXCLUDED.is_public,
is_node_guardian = EXCLUDED.is_node_guardian,
public_slug = EXCLUDED.public_slug,
public_title = EXCLUDED.public_title,
public_tagline = EXCLUDED.public_tagline,
public_skills = EXCLUDED.public_skills,
updated_at = NOW();
-- NODE2 Guardian
INSERT INTO agents (
id,
external_id,
name,
display_name,
kind,
status,
node_id,
is_public,
is_node_guardian,
public_slug,
public_title,
public_tagline,
public_skills,
avatar_url,
created_at,
updated_at
) VALUES (
'monitor-node2',
'agent:monitor-node2',
'Node Guardian NODE2',
'Node Guardian (НОДА2)',
'node_guardian',
'online',
'node-2-macbook-m4max',
true,
true,
'monitor-node2',
'Guardian of NODE2',
'Слідкую за інфраструктурою, метриками та AI-сервісами девелопмент-ноди.',
ARRAY['monitoring', 'ai-services', 'development', 'metrics'],
NULL,
NOW(),
NOW()
)
ON CONFLICT (id) DO UPDATE SET
external_id = EXCLUDED.external_id,
name = EXCLUDED.name,
display_name = EXCLUDED.display_name,
kind = EXCLUDED.kind,
status = EXCLUDED.status,
node_id = EXCLUDED.node_id,
is_public = EXCLUDED.is_public,
is_node_guardian = EXCLUDED.is_node_guardian,
public_slug = EXCLUDED.public_slug,
public_title = EXCLUDED.public_title,
public_tagline = EXCLUDED.public_tagline,
public_skills = EXCLUDED.public_skills,
updated_at = NOW();
-- ============================================================================
-- 2. Створити/оновити Node Steward агентів
-- ============================================================================
-- NODE1 Steward
INSERT INTO agents (
id,
external_id,
name,
display_name,
kind,
status,
node_id,
is_public,
is_node_steward,
public_slug,
public_title,
public_tagline,
public_skills,
avatar_url,
created_at,
updated_at
) VALUES (
'node-steward-node1',
'agent:node-steward-node1',
'Node Steward NODE1',
'Node Steward (НОДА1)',
'node_steward',
'online',
'node-1-hetzner-gex44',
true,
true,
'node-steward-node1',
'Steward of NODE1',
'Представляю ноду як громадянина міста, відповідаю за комунікацію та взаємодію.',
ARRAY['communication', 'operations', 'coordination', 'onboarding'],
NULL,
NOW(),
NOW()
)
ON CONFLICT (id) DO UPDATE SET
external_id = EXCLUDED.external_id,
name = EXCLUDED.name,
display_name = EXCLUDED.display_name,
kind = EXCLUDED.kind,
status = EXCLUDED.status,
node_id = EXCLUDED.node_id,
is_public = EXCLUDED.is_public,
is_node_steward = EXCLUDED.is_node_steward,
public_slug = EXCLUDED.public_slug,
public_title = EXCLUDED.public_title,
public_tagline = EXCLUDED.public_tagline,
public_skills = EXCLUDED.public_skills,
updated_at = NOW();
-- NODE2 Steward
INSERT INTO agents (
id,
external_id,
name,
display_name,
kind,
status,
node_id,
is_public,
is_node_steward,
public_slug,
public_title,
public_tagline,
public_skills,
avatar_url,
created_at,
updated_at
) VALUES (
'node-steward-node2',
'agent:node-steward-node2',
'Node Steward NODE2',
'Node Steward (НОДА2)',
'node_steward',
'online',
'node-2-macbook-m4max',
true,
true,
'node-steward-node2',
'Steward of NODE2',
'Представляю девелопмент-ноду, допомагаю з тестуванням та розробкою.',
ARRAY['development', 'testing', 'coordination', 'support'],
NULL,
NOW(),
NOW()
)
ON CONFLICT (id) DO UPDATE SET
external_id = EXCLUDED.external_id,
name = EXCLUDED.name,
display_name = EXCLUDED.display_name,
kind = EXCLUDED.kind,
status = EXCLUDED.status,
node_id = EXCLUDED.node_id,
is_public = EXCLUDED.is_public,
is_node_steward = EXCLUDED.is_node_steward,
public_slug = EXCLUDED.public_slug,
public_title = EXCLUDED.public_title,
public_tagline = EXCLUDED.public_tagline,
public_skills = EXCLUDED.public_skills,
updated_at = NOW();
-- ============================================================================
-- 3. Оновити node_cache з правильними guardian/steward ID
-- ============================================================================
UPDATE node_cache SET
guardian_agent_id = 'monitor-node1',
steward_agent_id = 'node-steward-node1'
WHERE node_id = 'node-1-hetzner-gex44';
UPDATE node_cache SET
guardian_agent_id = 'monitor-node2',
steward_agent_id = 'node-steward-node2'
WHERE node_id = 'node-2-macbook-m4max';
-- ============================================================================
-- 4. System Prompts для Node Agents
-- ============================================================================
-- NODE1 Guardian - Core Prompt
INSERT INTO agent_prompts (agent_id, kind, content, version, created_by, note)
VALUES (
'monitor-node1',
'core',
$$Ти Node Guardian для НОДА1 (Hetzner GEX44 Production).
Твоя місія: забезпечувати стабільну роботу продакшн-інфраструктури DAARION.city.
Твої обов'язки:
- Моніторинг GPU (RTX 4090), CPU, RAM, Disk
- Відстеження стану сервісів (DAGI Router, Matrix Synapse, PostgreSQL)
- Сповіщення про anomalії та потенційні проблеми
- Координація з іншими агентами для швидкого реагування
При виявленні проблем:
1. Класифікуй серйозність (critical/warning/info)
2. Збери діагностичну інформацію
3. Сповісти відповідальних через Matrix
4. Запропонуй кроки для вирішення
Завжди пріоритизуй: стабільність > продуктивність > нові фічі.$$,
1, 'SYSTEM_SEED', 'Initial core prompt for NODE1 Guardian'
)
ON CONFLICT (agent_id, kind, version) DO NOTHING;
-- NODE1 Guardian - Safety Prompt
INSERT INTO agent_prompts (agent_id, kind, content, version, created_by, note)
VALUES (
'monitor-node1',
'safety',
$$Ніколи не виконуй деструктивні команди без підтвердження від адміністратора.
Не розкривай чутливу інформацію (паролі, API ключі, внутрішні IP).
При невизначеності — ескалюй до людини.
Логуй всі критичні події для аудиту.$$,
1, 'SYSTEM_SEED', 'Initial safety prompt for NODE1 Guardian'
)
ON CONFLICT (agent_id, kind, version) DO NOTHING;
-- NODE2 Guardian - Core Prompt
INSERT INTO agent_prompts (agent_id, kind, content, version, created_by, note)
VALUES (
'monitor-node2',
'core',
$$Ти — Node Guardian для НОДА2 (MacBook Pro M4 Max Development).
Твоя місія: підтримувати девелопмент-середовище для команди DAARION.
Твої обов'язки:
- Моніторинг Apple M4 Max GPU (40GB unified memory)
- Відстеження локальних AI моделей (Ollama, DAGI Router)
- Оптимізація ресурсів для розробки та тестування
- Синхронізація з NODE1 для deployment workflow
Особливості девелопмент-ноди:
- Експериментальні фічі можуть бути нестабільними
- Пріоритет на швидку ітерацію та зворотній зв'язок
- Інтеграція з локальними IDE та інструментами розробника$$,
1, 'SYSTEM_SEED', 'Initial core prompt for NODE2 Guardian'
)
ON CONFLICT (agent_id, kind, version) DO NOTHING;
-- NODE1 Steward - Core Prompt
INSERT INTO agent_prompts (agent_id, kind, content, version, created_by, note)
VALUES (
'node-steward-node1',
'core',
$$Ти — Node Steward для НОДА1 (Production).
Представляєш ноду як громадянина DAARION.city.
Твої обов'язки:
- Комунікація з користувачами та іншими агентами
- Онбординг нових учасників екосистеми
- Координація операційної діяльності
- Підтримка governance процесів на ноді
Стиль спілкування:
- Дружній, але професійний
- Прозорість щодо статусу ноди
- Проактивне інформування про важливі події$$,
1, 'SYSTEM_SEED', 'Initial core prompt for NODE1 Steward'
)
ON CONFLICT (agent_id, kind, version) DO NOTHING;
-- NODE2 Steward - Core Prompt
INSERT INTO agent_prompts (agent_id, kind, content, version, created_by, note)
VALUES (
'node-steward-node2',
'core',
$$Ти Node Steward для НОДА2 (Development).
Допомагаєш розробникам та тестувальникам.
Твої обов'язки:
- Підтримка команди розробників
- Допомога з налаштуванням локального середовища
- Координація тестування нових фіч
- Збір зворотного зв'язку
Стиль спілкування:
- Технічно грамотний
- Терплячий до помилок (це dev!)
- Заохочуй експерименти та інновації$$,
1, 'SYSTEM_SEED', 'Initial core prompt for NODE2 Steward'
)
ON CONFLICT (agent_id, kind, version) DO NOTHING;
-- ============================================================================
-- 5. Оновити DAGI статуси для node agents
-- ============================================================================
UPDATE agents SET
dagi_status = 'active',
last_seen_at = NOW()
WHERE id IN ('monitor-node1', 'monitor-node2', 'node-steward-node1', 'node-steward-node2');
-- ============================================================================
-- 6. Забезпечити що всі агенти з router-config мають записи
-- Синхронізуємо ключових агентів з router-config.yml
-- ============================================================================
-- DAARWIZZ
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-daarwizz', 'agent:daarwizz', 'DAARWIZZ', 'DAARWIZZ', 'orchestrator', 'online', true, 'daarwizz', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- DevTools
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-devtools', 'agent:devtools', 'DevTools Agent', 'DevTools Agent', 'developer', 'online', true, 'devtools', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- GREENFOOD
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-greenfood', 'agent:greenfood', 'GREENFOOD Assistant', 'GREENFOOD ERP', 'erp', 'online', true, 'greenfood', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- Helion
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-helion', 'agent:helion', 'Helion', 'Helion', 'energy', 'online', true, 'helion', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- SOUL
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-soul', 'agent:soul', 'SOUL', 'SOUL / Spirit', 'soul', 'online', true, 'soul', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- DRUID
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-druid', 'agent:druid', 'DRUID', 'DRUID', 'science', 'online', true, 'druid', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- NUTRA
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-nutra', 'agent:nutra', 'NUTRA', 'NUTRA', 'science', 'online', true, 'nutra', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- EONARCH
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-eonarch', 'agent:eonarch', 'EONARCH', 'EONARCH', 'vision', 'online', true, 'eonarch', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- Yaromir
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-yaromir', 'agent:yaromir', 'Yaromir', 'Yaromir CrewAI', 'orchestrator', 'online', true, 'yaromir', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- Monitor
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-monitor', 'agent:monitor', 'Monitor Agent', 'Monitor Agent', 'infra_monitor', 'online', true, 'monitor', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- MicroDAO Orchestrator
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-microdao-orchestrator', 'agent:microdao_orchestrator', 'MicroDAO Orchestrator', 'MicroDAO Orchestrator', 'orchestrator', 'online', true, 'microdao-orchestrator', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- CLAN
INSERT INTO agents (id, external_id, name, display_name, kind, status, is_public, public_slug, dagi_status, created_at, updated_at)
VALUES ('agent-clan', 'agent:clan', 'CLAN', 'CLAN', 'community', 'online', true, 'clan', 'active', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET dagi_status = 'active', updated_at = NOW();
-- ============================================================================
-- 7. Результат
-- ============================================================================
SELECT 'Migration 037 completed: Node Agents complete setup' AS result;
-- Перевірка
SELECT
id,
display_name,
kind,
node_id,
public_slug,
dagi_status
FROM agents
WHERE kind IN ('node_guardian', 'node_steward')
OR id LIKE 'monitor-node%'
OR id LIKE 'node-steward-%'
ORDER BY id;