Config policies (16 files): alert_routing, architecture_pressure, backlog, cost_weights, data_governance, incident_escalation, incident_intelligence, network_allowlist, nodes_registry, observability_sources, rbac_tools_matrix, release_gate, risk_attribution, risk_policy, slo_policy, tool_limits, tools_rollout Ops (22 files): Caddyfile, calendar compose, grafana voice dashboard, deployments/incidents logs, runbooks for alerts/audit/backlog/incidents/sofiia/voice, cron jobs, scripts (alert_triage, audit_cleanup, migrate_*, governance, schedule), task_registry, voice alerts/ha/latency/policy Docs (30+ files): HUMANIZED_STEPAN v2.7-v3 changelogs and runbooks, NODA1/NODA2 status and setup, audit index and traces, backlog, incident, supervisor, tools, voice, opencode, release, risk, aistalk, spacebot Made-with: Cursor
176 lines
6.7 KiB
Markdown
176 lines
6.7 KiB
Markdown
# Sofiia Console — Operations Runbook
|
||
|
||
## 1. Rebuild & Deploy (NODA2)
|
||
|
||
```bash
|
||
cd /opt/microdao-daarion # or ~/github-projects/microdao-daarion on dev
|
||
|
||
# Rebuild sofiia-console (UI + backend)
|
||
docker compose -f docker-compose.node2-sofiia.yml build sofiia-console --no-cache
|
||
docker compose -f docker-compose.node2-sofiia.yml up -d sofiia-console
|
||
|
||
# Rebuild gateway (for agent registry changes)
|
||
docker compose -f docker-compose.node2-sofiia.yml build gateway --no-cache
|
||
docker compose -f docker-compose.node2-sofiia.yml up -d gateway
|
||
```
|
||
|
||
## 2. Confirm Build Version
|
||
|
||
```bash
|
||
# Via API
|
||
APIKEY=$(grep SOFIIA_CONSOLE_API_KEY .env | cut -d= -f2)
|
||
curl -s http://localhost:8002/api/meta/version -H "X-API-Key: $APIKEY"
|
||
# Expected: {"version":"0.4.0","build_sha":"dev","build_time":"local",...}
|
||
|
||
# In UI: header shows "v0.4.0 dev" badge (top right)
|
||
```
|
||
|
||
## 3. Verify Agents List
|
||
|
||
```bash
|
||
APIKEY=$(grep SOFIIA_CONSOLE_API_KEY .env | cut -d= -f2)
|
||
|
||
# NODA2 agents
|
||
curl -s "http://localhost:8002/api/agents?nodes=NODA2" -H "X-API-Key: $APIKEY" | \
|
||
python3 -c "import sys,json; d=json.load(sys.stdin); print(f'items={len(d[\"items\"])} stats={d[\"stats\"]} errors={d[\"node_errors\"]}')"
|
||
|
||
# NODA1 agents
|
||
curl -s "http://localhost:8002/api/agents?nodes=NODA1" -H "X-API-Key: $APIKEY" | \
|
||
python3 -c "import sys,json; d=json.load(sys.stdin); print(f'items={len(d[\"items\"])} stats={d[\"stats\"]} errors={d[\"node_errors\"]}')"
|
||
|
||
# All nodes
|
||
curl -s "http://localhost:8002/api/agents?nodes=NODA1,NODA2" -H "X-API-Key: $APIKEY" | \
|
||
python3 -c "import sys,json; d=json.load(sys.stdin); print(f'items={len(d[\"items\"])} stats={d[\"stats\"]} errors={d[\"node_errors\"]}')"
|
||
|
||
# Direct gateway check (NODA2)
|
||
curl -s http://localhost:9300/health | python3 -c "
|
||
import sys,json; d=json.load(sys.stdin)
|
||
print(f'agents={d[\"agents_count\"]}')
|
||
for k,v in sorted(d[\"agents\"].items()): print(f' {k}: badges={v.get(\"badges\",[])}')
|
||
"
|
||
```
|
||
|
||
## 4. UI Debug Panel
|
||
|
||
У вкладці **📁 Проєкти → Agents**:
|
||
1. Натисніть кнопку **🔍 Debug** в панелі дій
|
||
2. Debug panel показує:
|
||
- `fetch`: час останнього запиту
|
||
- `nodes`: вибрані ноди
|
||
- `items`: кількість агентів
|
||
- `ok/total`: кількість успішних нод
|
||
- `errors`: помилки нод (якщо є)
|
||
|
||
## 5. Troubleshooting
|
||
|
||
### Агенти не відображаються в UI
|
||
|
||
1. Перевірте API ключ у налаштуваннях UI
|
||
2. Натисніть **↻ Sync**
|
||
3. Відкрийте **🔍 Debug** — перевірте `errors`
|
||
4. Перевірте gateway health: `curl http://localhost:9300/health`
|
||
|
||
### Gateway падає при старті
|
||
|
||
```bash
|
||
docker logs dagi-gateway-node2 --tail 50
|
||
```
|
||
|
||
Типова причина: ImportError у `http_api_doc.py` → `doc_service.py`
|
||
Рішення: перевірте що в `doc_service.py` є stub-функції (doc_service, update_document, list_document_versions, publish_document_artifact).
|
||
|
||
### SQLite "no such column: last_applied_hash"
|
||
|
||
БД у volume має стару схему. Вирішення — міграції виконуються автоматично при старті через `_MIGRATION_SQL_STMTS` у `db.py`. Restart контейнера вирішує:
|
||
```bash
|
||
docker restart sofiia-console
|
||
```
|
||
|
||
### NODA2 gateway_url недоступний з контейнера
|
||
|
||
У `config/nodes_registry.yml` NODA2 використовує `host.docker.internal:9300`.
|
||
Якщо UI запущений не в Docker — замініть на `localhost:9300`.
|
||
|
||
### Monitor / AISTALK не відображаються
|
||
|
||
Перевірте що в `gateway-bot/http_api.py`:
|
||
- `MONITOR_CONFIG` і `AISTALK_CONFIG` визначені через `load_agent_config`
|
||
- Вони додані в `AGENT_REGISTRY`
|
||
- Файл `gateway-bot/monitor_prompt.txt` існує
|
||
|
||
```bash
|
||
docker exec dagi-gateway-node2 python3 -c "
|
||
from http_api import AGENT_REGISTRY
|
||
print(list(AGENT_REGISTRY.keys()))
|
||
"
|
||
```
|
||
|
||
## 6. Monitor Policy
|
||
|
||
Monitor (`agent_id=monitor`) є **обов'язковим** агентом на кожній ноді.
|
||
|
||
### Перевірка
|
||
```bash
|
||
APIKEY=$(grep SOFIIA_CONSOLE_API_KEY .env | cut -d= -f2)
|
||
curl -s "http://localhost:8002/api/agents?nodes=NODA1,NODA2" -H "X-API-Key: $APIKEY" | \
|
||
python3 -c "import sys,json; d=json.load(sys.stdin); print('missing:', d.get('required_missing_nodes'))"
|
||
```
|
||
|
||
- `required_missing=[]` — все ОК
|
||
- `required_missing=[{"node_id":"NODA1","agent_id":"monitor"}]` — Monitor відсутній на NODA1 → перевірте gateway registry → rebuild gateway
|
||
|
||
### Governance event
|
||
Якщо Monitor відсутній на онлайн-ноді — автоматично записується `governance_event` типу `node_required_agent_missing` (severity=high).
|
||
|
||
## 7. Voice & Telegram Capabilities
|
||
|
||
У вкладці Agents:
|
||
- **🎙 Voice** badge — агент підтримує голос (AISTALK)
|
||
- **💬 Telegram** badge — агент активний у Telegram
|
||
- Фільтри **🎙 Voice** і **💬 Telegram** — client-side фільтрація
|
||
|
||
### API
|
||
```bash
|
||
curl -s "http://localhost:8002/api/agents?nodes=NODA1" -H "X-API-Key: $APIKEY" | \
|
||
python3 -c "import sys,json; d=json.load(sys.stdin);
|
||
voice=[a['agent_id'] for a in d['items'] if a.get('capabilities',{}).get('voice')]
|
||
print('voice:', voice)"
|
||
```
|
||
|
||
## 8. Document Versioning
|
||
|
||
API для версій документів (в межах Sofiia Console):
|
||
```bash
|
||
# Список версій
|
||
GET /api/projects/{project_id}/documents/{doc_id}/versions
|
||
|
||
# Оновити документ (зберігає нову версію)
|
||
POST /api/projects/{project_id}/documents/{doc_id}/update
|
||
{"content_md": "# Новий зміст", "author_id": "user", "reason": "оновлення", "dry_run": false}
|
||
|
||
# Відновити версію
|
||
POST /api/projects/{project_id}/documents/{doc_id}/restore
|
||
{"version_id": "...", "author_id": "user"}
|
||
```
|
||
|
||
## 9. Agent Registry SSoT
|
||
|
||
Canonical реєстр: `config/agent_registry.yml`
|
||
|
||
Gateway завантажує агентів з `gateway-bot/http_api.py::AGENT_REGISTRY` (Python dict).
|
||
Щоб додати нового агента:
|
||
1. Додайте запис в `config/agent_registry.yml`
|
||
2. Додайте `*_CONFIG = load_agent_config(...)` і запис в `AGENT_REGISTRY` у `gateway-bot/http_api.py`
|
||
3. Створіть `gateway-bot/<agent_id>_prompt.txt`
|
||
4. Rebuild gateway
|
||
|
||
## 10. Ports Reference
|
||
|
||
| Сервіс | Port | URL |
|
||
|---|---|---|
|
||
| Sofiia Console UI | 8002 | http://localhost:8002 |
|
||
| Gateway | 9300 | http://localhost:9300/health |
|
||
| Router | 9102 | http://localhost:9102/health |
|
||
| Memory | 8000 | http://localhost:8000/health |
|
||
| Qdrant | 6333 | http://localhost:6333/healthz |
|