"""Shared data types for agent tool execution.""" from dataclasses import dataclass, field from typing import Any, Dict, List, Optional @dataclass(frozen=True) class ToolContext: """Normalized request context supplied by the notification/router layer. ``user_id`` is the unified identity used by legacy business handlers; ``target_id`` remains the actual private-chat or group delivery target. ``request_id`` and ``task_id`` are correlation values only and are never interpolated into legacy command strings. """ channel: Any msg_type: str user_id: int target_id: int is_admin: bool = False request_id: Optional[str] = None task_id: Optional[str] = None def __post_init__(self) -> None: if self.msg_type not in ("private", "group"): raise ValueError("msg_type must be 'private' or 'group'") @dataclass class ToolResult: """Safe, serializable result returned to the model orchestration layer. ``safe_message`` contains captured legacy text (or a generic error), never a traceback. ``artifacts`` contains public metadata only; local paths, base64 payloads and source URLs are kept inside ``ArtifactStore``. """ ok: bool code: str safe_message: str = "" data: Dict[str, Any] = field(default_factory=dict) artifacts: List[Dict[str, Any]] = field(default_factory=list) retryable: bool = False