Files
microdao-daarion/services/router/handoff.py
Apple ef3473db21 snapshot: NODE1 production state 2026-02-09
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>
2026-02-09 08:46:46 -08:00

92 lines
3.0 KiB
Python

"""
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}."