"""Pydantic models for all tool results. Every tool returns a subclass of BaseResult. - ok=true + warnings: 성공이지만 주의 필요 - ok=false + error_type + error: 실패 - raw: 디버깅 전용 보조 필드 (상위 레이어에서 기본 숨김) - checked_at: 모든 결과에 포함 (수집 시점 ISO timestamp) """ from __future__ import annotations from pydantic import BaseModel, Field class BaseResult(BaseModel): ok: bool checked_at: str warnings: list[str] = Field(default_factory=list) error_type: str | None = None # "timeout" | "auth" | "command_failed" | "parse_error" error: str | None = None # -- Docker ------------------------------------------------------------------ class ContainerInfo(BaseModel): name: str status: str # "running" | "exited" | "restarting" | ... uptime: str # "Up 3 days" etc. ports: str # published ports summary image: str class DockerStatusResult(BaseResult): host: str containers: list[ContainerInfo] = Field(default_factory=list) summary: str = "" # "5/5 running" | "4/5 running, 1 exited" raw: str = "" class DockerLogsResult(BaseResult): host: str container: str lines: int # requested line count truncated: bool = False content: str = "" # stdout stderr: str = "" # stderr (separate) raw: str = "" # -- Health ------------------------------------------------------------------- class HealthResult(BaseResult): service: str status: str = "unknown" # "healthy" | "degraded" | "down" details: dict = Field(default_factory=dict) raw: str | None = None # -- System ------------------------------------------------------------------- class FileSystemInfo(BaseModel): mount: str used_pct: int used: str avail: str total: str class DiskResult(BaseResult): host: str filesystems: list[FileSystemInfo] = Field(default_factory=list) raw: str = "" # -- Network ------------------------------------------------------------------ class TailscalePeer(BaseModel): hostname: str ip: str status: str # "active" | "idle" | "offline" os: str class TailscaleResult(BaseResult): peers: list[TailscalePeer] = Field(default_factory=list) raw: str = "" # -- Models ------------------------------------------------------------------- class ModelInfo(BaseModel): id: str size: str = "" modified: str = "" class ModelsResult(BaseResult): host: str source: str # "ollama" | "mlx" models: list[ModelInfo] = Field(default_factory=list) raw: str = ""