Complete snapshot of /opt/microdao-daarion/ from NODE1 (144.76.224.179).
This represents the actual running production code that has diverged
significantly from the previous main branch.
Key changes from old main:
- Gateway (http_api.py): expanded from ~40KB to 164KB with full agent support
- Router: new /v1/agents/{id}/infer endpoint with vision + DeepSeek routing
- Behavior Policy: SOWA v2.2 (3-level: FULL/ACK/SILENT)
- Agent Registry: config/agent_registry.yml as single source of truth
- 13 agents configured (was 3)
- Memory service integration
- CrewAI teams and roles
Excluded from snapshot: venv/, .env, data/, backups, .tgz archives
Co-authored-by: Cursor <cursoragent@cursor.com>
7.7 KiB
7.7 KiB
ADR: DAARWIZZ Orchestration Mode (Гібридна архітектура)
Дата: 2026-01-19
Статус: Прийнято
Версія: 1.0
Контекст
DAARION.city має 5 спеціалізованих агентів:
- Helion — енергетика, DePIN
- Nutra — харчування, дієти
- Druid — біомедичні добавки, лабораторії
- GreenFood — крафтові виробники, кооперативи
- DAARWIZZ — системний координатор
Проблема: Користувачі не знають, до якого агента звернутися. Потрібна єдина точка входу з автоматичною маршрутизацією.
Рішення: Гібридна архітектура (3 етапи)
Етап A (зараз): Ізольовані боти + "м'який" DAARWIZZ
Поведінка:
- Прямі боти (@energyunionBot, @NutraChat_bot, @DRUID73bot) працюють ізольовано
- @DAARWIZZBot працює як довідник + маршрутизатор:
- Класифікує intent користувача
- Рекомендує правильного агента
- Може зробити "soft handoff" (передати запит, але відповідь йде через DAARWIZZ)
- НЕ робить автоматичний handoff без згоди користувача
Приклад:
Користувач: "що їсти на сніданок?"
DAARWIZZ: "Це питання харчування. Рекомендую @NutraChat_bot.
Можу передати запит туди зараз — дозволиш?"
Етап B (пізніше): DAARWIZZ-first для 30-50% трафіку
Поведінка:
- @DAARWIZZBot стає рекомендованим entry point для нових користувачів
- Автоматичний handoff для "safe" класів запитів (single-domain)
- Прямі боти залишаються як "pro mode" для профі-користувачів
Етап C (майбутнє): Повна оркестрація multi-agent сценаріїв
Поведінка:
- DAARWIZZ планує multi-step сценарії (handoff між доменами)
- Збір фактів від кількох агентів
- Контекстні контракти: що можна передавати між агентами
Handoff Contract (стандартизований пакет)
Структура:
{
"intent": "nutrition_advice", # Що хоче користувач
"domain": "nutrition", # Домен (energy/food/supplements)
"user_goal": "що їсти на сніданок", # Оригінальне питання
"target_agent": "nutra", # Куди делегувати
"constraints": {
"max_response_time": 30, # Секунд
"format": "short", # short/medium/detailed
"language": "uk"
},
"context_summary": "Користувач питає про сніданок", # БЕЗ секретів
"sources": [], # IDs повідомлень/Co-Memory, не plaintext
"privacy_level": "public", # public/team/confidential
"requires_consent": true # Чи потрібна згода користувача
}
Правила передачі:
- Single-domain запити → автоматичний handoff (після Етапу A)
- Multi-domain запити → DAARWIZZ робить plan + збирає відповіді
- Confidential/E2EE → тільки sanitized summary або явна згода
Розділення пам'яті
Персональна пам'ять агентів (Nutra/Helion/Druid):
- Qdrant:
{agent_id}_messages,{agent_id}_docs - Neo4j:
:{AgentId}_*labels - НЕ передається автоматично в DAARWIZZ
Orchestration пам'ять DAARWIZZ:
- Qdrant:
daarwizz_orchestration(логи планів, стани задач) - Neo4j:
:Orchestrationnodes (handoff історія) - НЕ містить приватний контент користувачів
Політика приватності
За замовчуванням:
- Public запити → можна делегувати з context_summary
- Team запити → тільки в межах команди
- Confidential запити → тільки sanitized summary або явна згода
Ескалація:
- Якщо запит потребує handoff, але privacy_level = confidential:
- DAARWIZZ питає: "Дозволиш передати це питання в Nutra? (буде передано тільки узагальнений контекст)"
- Користувач підтверджує → handoff
- Користувач відхиляє → DAARWIZZ відповідає сам (якщо може)
Технічна реалізація
1. Intent Router в DAARWIZZ
def route_intent(message: str) -> Dict:
"""
Визначає intent та рекомендованого агента.
Повертає handoff contract (якщо потрібно).
"""
# Класифікація через LLM або keyword matching
# Повертає: intent, domain, target_agent, confidence
2. Handoff Handler
async def handle_handoff(contract: HandoffContract) -> Dict:
"""
Виконує handoff до target_agent.
Повертає відповідь для користувача.
"""
# Викликає Router з target_agent
# Повертає результат через DAARWIZZ
3. NATS Subjects для handoff
agent.daarwizz.handoff.request # Запит на handoff
agent.daarwizz.handoff.response # Відповідь від агента
agent.{agent_id}.invoke # Прямий виклик агента
Покрокове впровадження
✅ Етап A (зараз): "М'який" DAARWIZZ
- DAARWIZZ класифікує intent
- DAARWIZZ рекомендує агента
- DAARWIZZ пропонує "soft handoff" (з згодою)
- Логування handoff рішень
⏳ Етап B (пізніше): DAARWIZZ-first
- Автоматичний handoff для single-domain
- Метрики: % трафіку через DAARWIZZ
- A/B тестування: DAARWIZZ vs прямі боти
📋 Етап C (майбутнє): Multi-agent оркестрація
- Планування multi-step сценаріїв
- Збір фактів від кількох агентів
- Контекстні контракти
Критерії успіху
- Користувачі знають, куди звернутися (через DAARWIZZ)
- Прямі боти залишаються швидкими для профі-користувачів
- Приватність збережена (confidential не передається без згоди)
- Масштабування без міграції UX (можна додавати нових агентів)
Альтернативи (відхилені)
- Тільки прямі боти — користувачі не знають, куди звернутися
- Тільки DAARWIZZ — втрата швидкості для профі-користувачів
- Повна оркестрація одразу — занадто складно для MVP
Версія: 1.0
Останнє оновлення: 2026-01-19