""" DAARION Platform - Agent Handoff Contract Manages secure context transfer between agents """ from dataclasses import dataclass, field, asdict from datetime import datetime from typing import Optional, List, Dict, Any from enum import Enum import uuid import structlog logger = structlog.get_logger() class HandoffReason(Enum): DOMAIN_MISMATCH = "domain_mismatch" USER_REQUEST = "user_request" CAPABILITY_REQUIRED = "capability_required" ESCALATION = "escalation" @dataclass class HandoffContract: """Secure contract for transferring context between agents.""" handoff_id: str = field(default_factory=lambda: str(uuid.uuid4())) source_agent: str = "" target_agent: str = "" user_intent: str = "" timestamp: str = field(default_factory=lambda: datetime.utcnow().isoformat()) context_summary: Optional[str] = None language: str = "uk" user_id: Optional[str] = None channel_id: Optional[str] = None constraints: Dict[str, Any] = field(default_factory=dict) references: List[str] = field(default_factory=list) reason: HandoffReason = HandoffReason.DOMAIN_MISMATCH def to_dict(self) -> Dict[str, Any]: d = asdict(self) d["reason"] = self.reason.value return d class HandoffManager: """Manages agent handoffs with policy enforcement""" def __init__(self, registry: Dict[str, Any]): self.registry = registry self._active_handoffs: Dict[str, HandoffContract] = {} def can_handoff(self, source_agent: str, target_agent: str) -> bool: source_config = self.registry.get("agents", {}).get(source_agent, {}) data_policy = source_config.get("data_policy", {}) allowed = data_policy.get("handoff_allow", []) return target_agent in allowed def create_handoff( self, source_agent: str, target_agent: str, user_intent: str, context_summary: Optional[str] = None, language: str = "uk", reason: HandoffReason = HandoffReason.DOMAIN_MISMATCH ) -> Optional[HandoffContract]: if not self.can_handoff(source_agent, target_agent): logger.warning("handoff_blocked", source=source_agent, target=target_agent) return None contract = HandoffContract( source_agent=source_agent, target_agent=target_agent, user_intent=user_intent[:500], context_summary=context_summary[:1000] if context_summary else None, language=language, reason=reason ) self._active_handoffs[contract.handoff_id] = contract logger.info("handoff_created", handoff_id=contract.handoff_id) return contract def get_user_message(self, target_agent: str) -> str: names = { "helion": "Helion", "nutra": "Nutra", "greenfood": "GreenFood", "druid": "Druid" } name = names.get(target_agent, target_agent) return f"Передаю ваше питання до {name}."