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>
92 lines
3.0 KiB
Python
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}."
|