175 lines
6.5 KiB
Python
175 lines
6.5 KiB
Python
"""Pydantic schemas for OpenClaw Gateway RPC response parsing.
|
|
|
|
These schemas map the raw JSON responses from gateway RPC methods to typed
|
|
Python objects. They are used by GatewayCollectorService to parse responses
|
|
before storing data in Mission Control's monitoring models.
|
|
|
|
Note: These are NOT DB models (those are in app/models/monitoring.py).
|
|
These are purely for RPC response parsing.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class CostPeriod(BaseModel):
|
|
"""Cost period breakdown."""
|
|
|
|
start: datetime
|
|
end: datetime
|
|
total: float = Field(default=0.0)
|
|
model_costs: dict[str, float] | None = Field(default=None, alias="models")
|
|
provider_costs: dict[str, float] | None = Field(default=None)
|
|
token_counts: dict[str, int] | None = Field(default=None)
|
|
|
|
|
|
class CostResponse(BaseModel):
|
|
"""Response from usage.cost RPC method."""
|
|
|
|
period_start: datetime = Field(alias="period_start")
|
|
period_end: datetime = Field(alias="period_end")
|
|
total_cost: float = Field(alias="total", default=0.0)
|
|
model_costs: dict[str, float] | None = Field(alias="models", default=None)
|
|
provider_costs: dict[str, float] | None = Field(default=None)
|
|
token_counts: dict[str, int] | None = Field(alias="tokens", default=None)
|
|
|
|
|
|
class UsageStatusResponse(BaseModel):
|
|
"""Response from usage.status RPC method."""
|
|
|
|
tokens_used: int = Field(default=0)
|
|
tokens_limit: int | None = Field(default=None)
|
|
cost_used: float = Field(default=0.0)
|
|
cost_limit: float | None = Field(default=None)
|
|
model_usage: dict[str, dict[str, Any]] | None = Field(default=None)
|
|
|
|
|
|
class CronJobStatus(BaseModel):
|
|
"""Individual cron job status."""
|
|
|
|
job_name: str = Field(alias="name")
|
|
schedule: str
|
|
enabled: bool = Field(default=True)
|
|
last_run_at: datetime | None = Field(default=None, alias="lastRun")
|
|
next_run_at: datetime | None = Field(default=None, alias="nextRun")
|
|
status: str = Field(default="idle")
|
|
failure_count: int = Field(default=0, alias="failureCount")
|
|
last_error: str | None = Field(default=None, alias="lastError")
|
|
metadata_: dict[str, Any] | None = Field(default=None, alias="metadata")
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class CronJobStatusResponse(BaseModel):
|
|
"""Response from cron.list RPC method."""
|
|
|
|
jobs: list[CronJobStatus] = Field(default_factory=list)
|
|
|
|
|
|
class SessionPreview(BaseModel):
|
|
"""Session preview data."""
|
|
|
|
session_key: str = Field(alias="key")
|
|
event_type: str = Field(default="unknown", alias="eventType")
|
|
model: str | None = Field(default=None)
|
|
agent_id: str | None = Field(default=None, alias="agentId")
|
|
channel: str | None = Field(default=None)
|
|
context_percent: float | None = Field(default=None, alias="contextPct")
|
|
token_counts: dict[str, int] | None = Field(default=None)
|
|
cost: float | None = Field(default=None)
|
|
metadata_: dict[str, Any] | None = Field(default=None, alias="metadata")
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class SessionsListResponse(BaseModel):
|
|
"""Response from sessions.list RPC method."""
|
|
|
|
sessions: list[SessionPreview] = Field(default_factory=list)
|
|
|
|
|
|
class SessionPreviewResponse(BaseModel):
|
|
"""Response from sessions.preview RPC method."""
|
|
|
|
session_key: str = Field(alias="key")
|
|
event_type: str = Field(default="preview", alias="eventType")
|
|
model: str | None = Field(default=None)
|
|
agent_id: str | None = Field(default=None, alias="agentId")
|
|
channel: str | None = Field(default=None)
|
|
context_percent: float | None = Field(default=None, alias="contextPct")
|
|
token_counts: dict[str, int] | None = Field(default=None)
|
|
cost: float | None = Field(default=None)
|
|
metadata_: dict[str, Any] | None = Field(default=None, alias="metadata")
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class GatewayHealthMetrics(BaseModel):
|
|
"""System health metrics from gateway health response."""
|
|
|
|
cpu_percent: float | None = Field(default=None, alias="cpu")
|
|
cpu_cores: int | None = Field(default=None, alias="cpuCores")
|
|
ram_used_bytes: int | None = Field(default=None, alias="ramUsed")
|
|
ram_total_bytes: int | None = Field(default=None, alias="ramTotal")
|
|
ram_percent: float | None = Field(default=None, alias="ramPercent")
|
|
swap_used_bytes: int | None = Field(default=None, alias="swapUsed")
|
|
swap_total_bytes: int | None = Field(default=None, alias="swapTotal")
|
|
swap_percent: float | None = Field(default=None, alias="swapPercent")
|
|
disk_path: str = Field(default="/", alias="diskPath")
|
|
disk_used_bytes: int | None = Field(default=None, alias="diskUsed")
|
|
disk_total_bytes: int | None = Field(default=None, alias="diskTotal")
|
|
disk_percent: float | None = Field(default=None, alias="diskPercent")
|
|
metadata_: dict[str, Any] | None = Field(default=None, alias="metadata")
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class GatewayHealthResponse(BaseModel):
|
|
"""Response from health RPC method."""
|
|
|
|
status: str = Field(default="unknown")
|
|
pid: int | None = Field(default=None)
|
|
uptime_ms: int | None = Field(default=None, alias="uptimeMs")
|
|
memory_bytes: int | None = Field(default=None, alias="memory")
|
|
rss_bytes: int | None = Field(default=None, alias="rss")
|
|
timestamp: datetime | None = Field(default=None)
|
|
metrics: GatewayHealthMetrics | None = Field(default=None)
|
|
|
|
|
|
class GatewayStatus(BaseModel):
|
|
"""Gateway runtime status."""
|
|
|
|
gateway_live: bool = Field(default=False, alias="live")
|
|
gateway_ready: bool = Field(default=False, alias="ready")
|
|
gateway_uptime_ms: int = Field(default=0, alias="uptimeMs")
|
|
gateway_pid: int = Field(default=0, alias="pid")
|
|
gateway_version: str = Field(default="unknown", alias="version")
|
|
agents_count: int = Field(default=0, alias="agents")
|
|
|
|
|
|
class GatewayStatusResponse(BaseModel):
|
|
"""Response from status RPC method."""
|
|
|
|
status: str = Field(default="unknown")
|
|
gateway: GatewayStatus
|
|
|
|
|
|
class SubAgentRun(BaseModel):
|
|
"""Sub-agent execution record."""
|
|
|
|
parent_session_key: str = Field(alias="parentSessionKey")
|
|
session_event_id: str | None = Field(default=None, alias="sessionId")
|
|
agent: str | None = Field(default=None)
|
|
model: str | None = Field(default=None)
|
|
status: str = Field(default="pending")
|
|
duration_ms: int | None = Field(default=None, alias="durationMs")
|
|
cost: float | None = Field(default=None)
|
|
token_counts: dict[str, int] | None = Field(default=None)
|
|
metadata_: dict[str, Any] | None = Field(default=None, alias="metadata")
|
|
|
|
model_config = {"populate_by_name": True}
|