""" DAARWIZZ Handoff Contract ========================= Стандартизований пакет для делегування запитів між агентами. """ from dataclasses import dataclass from typing import Optional, Dict, Any, List from enum import Enum class PrivacyLevel(str, Enum): """Рівні приватності для handoff""" PUBLIC = "public" # Можна передавати з контекстом TEAM = "team" # Тільки в межах команди CONFIDENTIAL = "confidential" # Тільки sanitized summary або з згодою class HandoffType(str, Enum): """Типи handoff""" SINGLE_DOMAIN = "single_domain" # Один агент MULTI_DOMAIN = "multi_domain" # Кілька агентів ORCHESTRATION = "orchestration" # Складний multi-step сценарій @dataclass class HandoffContract: """ Контракт для делегування запиту між агентами. Використання: contract = HandoffContract( intent="nutrition_advice", domain="nutrition", user_goal="що їсти на сніданок", target_agent="nutra", requires_consent=True ) """ # Основна інформація intent: str # Що хоче користувач (nutrition_advice, energy_question, etc.) domain: str # Домен (nutrition, energy, supplements, etc.) user_goal: str # Оригінальне питання користувача target_agent: str # Куди делегувати (nutra, helion, druid, etc.) # Обмеження constraints: Optional[Dict[str, Any]] = None # max_response_time, format, language context_summary: Optional[str] = None # БЕЗ секретів, тільки узагальнений контекст sources: Optional[List[str]] = None # IDs повідомлень/Co-Memory, не plaintext # Приватність privacy_level: PrivacyLevel = PrivacyLevel.PUBLIC requires_consent: bool = False # Чи потрібна згода користувача # Метадані handoff_type: HandoffType = HandoffType.SINGLE_DOMAIN confidence: float = 0.0 # Впевненість в routing (0.0-1.0) reason: Optional[str] = None # Чому саме цей агент def to_dict(self) -> Dict[str, Any]: """Конвертує в dict для передачі через API/NATS""" return { "intent": self.intent, "domain": self.domain, "user_goal": self.user_goal, "target_agent": self.target_agent, "constraints": self.constraints or {}, "context_summary": self.context_summary, "sources": self.sources or [], "privacy_level": self.privacy_level.value, "requires_consent": self.requires_consent, "handoff_type": self.handoff_type.value, "confidence": self.confidence, "reason": self.reason } @classmethod def from_dict(cls, data: Dict[str, Any]) -> "HandoffContract": """Створює з dict""" return cls( intent=data["intent"], domain=data["domain"], user_goal=data["user_goal"], target_agent=data["target_agent"], constraints=data.get("constraints"), context_summary=data.get("context_summary"), sources=data.get("sources"), privacy_level=PrivacyLevel(data.get("privacy_level", "public")), requires_consent=data.get("requires_consent", False), handoff_type=HandoffType(data.get("handoff_type", "single_domain")), confidence=data.get("confidence", 0.0), reason=data.get("reason") ) def is_safe_for_auto_handoff(self) -> bool: """ Перевіряє, чи можна зробити автоматичний handoff без згоди. Правила: - privacy_level = PUBLIC - requires_consent = False - confidence > 0.7 - handoff_type = SINGLE_DOMAIN """ return ( self.privacy_level == PrivacyLevel.PUBLIC and not self.requires_consent and self.confidence > 0.7 and self.handoff_type == HandoffType.SINGLE_DOMAIN ) def sanitize_for_confidential(self) -> "HandoffContract": """ Створює sanitized версію для confidential запитів. Видаляє деталі, залишає тільки узагальнений контекст. """ return HandoffContract( intent=self.intent, domain=self.domain, user_goal="[Confidential query]", # Приховано target_agent=self.target_agent, constraints=self.constraints, context_summary="User query in confidential context", # Узагальнено sources=[], # Видалено privacy_level=PrivacyLevel.CONFIDENTIAL, requires_consent=True, # Завжди потрібна згода handoff_type=self.handoff_type, confidence=self.confidence, reason=self.reason ) # Приклад використання if __name__ == "__main__": # Створення контракту contract = HandoffContract( intent="nutrition_advice", domain="nutrition", user_goal="що їсти на сніданок", target_agent="nutra", constraints={"max_response_time": 30, "format": "short", "language": "uk"}, context_summary="Користувач питає про сніданок", privacy_level=PrivacyLevel.PUBLIC, requires_consent=False, confidence=0.9, reason="Query clearly about nutrition" ) print("Contract:", contract.to_dict()) print("Safe for auto-handoff:", contract.is_safe_for_auto_handoff()) # Confidential версія confidential = contract.sanitize_for_confidential() print("\nConfidential version:", confidential.to_dict())