"""Pydantic v2 schemas for the Automation & Agents plugin API.""" from __future__ import annotations from datetime import datetime from typing import Any from pydantic import BaseModel, Field # ─── Agent Definition Schemas ─── class AgentDefinitionCreate(BaseModel): """Create a new agent definition.""" name: str = Field(..., min_length=1, max_length=120) description: str = Field(default="", max_length=500) llm_model: str = Field(default="ollama/deepseek-v4-flash", max_length=100) system_prompt: str = Field(default="") tool_ids: list[str] = Field(default_factory=list) heartbeat_interval_seconds: int = Field(default=0, ge=0) mode: str = Field(default="reactive", pattern="^(proactive|reactive)$") is_active: bool = Field(default=True) max_executions_per_hour: int = Field(default=10, ge=1, le=1000) max_duration_seconds: int = Field(default=300, ge=1, le=86400) budget_limit_usd: float = Field(default=1.0, ge=0.0, le=10000.0) class AgentDefinitionUpdate(BaseModel): """Update an existing agent definition (partial).""" name: str | None = Field(None, max_length=120) description: str | None = Field(None, max_length=500) llm_model: str | None = Field(None, max_length=100) system_prompt: str | None = None tool_ids: list[str] | None = None heartbeat_interval_seconds: int | None = Field(None, ge=0) mode: str | None = Field(None, pattern="^(proactive|reactive)$") is_active: bool | None = None max_executions_per_hour: int | None = Field(None, ge=1, le=1000) max_duration_seconds: int | None = Field(None, ge=1, le=86400) budget_limit_usd: float | None = Field(None, ge=0.0, le=10000.0) class AgentDefinitionResponse(BaseModel): """Agent definition response.""" id: str name: str description: str = "" llm_model: str system_prompt: str = "" tool_ids: list[str] = [] heartbeat_interval_seconds: int = 0 mode: str is_active: bool = True max_executions_per_hour: int = 10 max_duration_seconds: int = 300 budget_limit_usd: float = 1.0 created_by: str | None = None created_at: str | None = None updated_at: str | None = None # ─── Automation Definition Schemas ─── class AutomationDefinitionCreate(BaseModel): """Create a new automation definition.""" name: str = Field(..., min_length=1, max_length=120) description: str = Field(default="", max_length=500) trigger_type: str = Field(default="manual", pattern="^(event|schedule|manual)$") trigger_config: dict[str, Any] = Field(default_factory=dict) conditions: list[dict[str, Any]] = Field(default_factory=list) actions: list[dict[str, Any]] = Field(default_factory=list) is_active: bool = Field(default=True) dry_run: bool = Field(default=False) class AutomationDefinitionUpdate(BaseModel): """Update an existing automation definition (partial).""" name: str | None = Field(None, max_length=120) description: str | None = Field(None, max_length=500) trigger_type: str | None = Field(None, pattern="^(event|schedule|manual)$") trigger_config: dict[str, Any] | None = None conditions: list[dict[str, Any]] | None = None actions: list[dict[str, Any]] | None = None is_active: bool | None = None dry_run: bool | None = None class AutomationDefinitionResponse(BaseModel): """Automation definition response.""" id: str name: str description: str = "" trigger_type: str trigger_config: dict[str, Any] = {} conditions: list[dict[str, Any]] = [] actions: list[dict[str, Any]] = [] is_active: bool = True dry_run: bool = False created_by: str | None = None created_at: str | None = None updated_at: str | None = None # ─── Cron Job Schemas ─── class CronJobResponse(BaseModel): """Cron job response.""" id: str name: str cron_expression: str job_type: str target_id: str | None = None plugin_name: str = "" is_active: bool = True last_run_at: str | None = None next_run_at: str | None = None created_at: str | None = None updated_at: str | None = None # ─── Run Log Schemas ─── class AgentRunResponse(BaseModel): """Agent run log response.""" id: str agent_id: str status: str started_at: str completed_at: str | None = None duration_seconds: float | None = None result: str | None = None error: str | None = None cost_usd: float | None = None trigger_type: str = "manual" trigger_data: dict[str, Any] = {} created_at: str | None = None class AutomationRunResponse(BaseModel): """Automation run log response.""" id: str automation_id: str status: str started_at: str completed_at: str | None = None duration_seconds: float | None = None result: str | None = None error: str | None = None trigger_type: str = "manual" trigger_data: dict[str, Any] = {} dry_run: bool = False created_at: str | None = None # ─── Version Schemas ─── class AgentVersionResponse(BaseModel): """Agent version response.""" id: str agent_id: str version_number: int snapshot: dict[str, Any] changed_by: str | None = None created_at: str | None = None class AutomationVersionResponse(BaseModel): """Automation version response.""" id: str automation_id: str version_number: int snapshot: dict[str, Any] changed_by: str | None = None created_at: str | None = None # ─── Settings Schemas ─── class AgentMessageRequest(BaseModel): """Request to send a message from one agent to another.""" to_agent_name: str = Field(..., min_length=1, max_length=120) message: str = Field(..., min_length=1) class MiniAppCreate(BaseModel): """Create a custom MiniApp definition.""" app_id: str = Field(..., min_length=1, max_length=80) name: str = Field(..., min_length=1, max_length=120) icon: str = Field(default="AppWindow") description: str = Field(default="") render_schema: dict[str, Any] = Field(default_factory=dict) class MiniAppResponse(BaseModel): """MiniApp definition response.""" app_id: str name: str icon: str = "AppWindow" description: str = "" plugin_name: str = "" render_schema: dict[str, Any] = {} class AutomationSettingsResponse(BaseModel): """Automation settings response.""" default_llm_model: str = "ollama/deepseek-v4-flash" heartbeat_default_interval: int = 300 max_concurrent_agents: int = 5 log_level: str = "INFO" class AutomationSettingsUpdate(BaseModel): """Automation settings update (partial).""" default_llm_model: str | None = None heartbeat_default_interval: int | None = None max_concurrent_agents: int | None = None log_level: str | None = None # ─── List Response Schemas ─── class AgentDefinitionListResponse(BaseModel): """Paginated agent definition list.""" items: list[AgentDefinitionResponse] total: int class AutomationDefinitionListResponse(BaseModel): """Paginated automation definition list.""" items: list[AutomationDefinitionResponse] total: int class AgentRunListResponse(BaseModel): """Paginated agent run list.""" items: list[AgentRunResponse] total: int class AutomationRunListResponse(BaseModel): """Paginated automation run list.""" items: list[AutomationRunResponse] total: int class CronJobListResponse(BaseModel): """Paginated cron job list.""" items: list[CronJobResponse] total: int class AgentVersionListResponse(BaseModel): """Paginated agent version list.""" items: list[AgentVersionResponse] total: int class AutomationVersionListResponse(BaseModel): """Paginated automation version list.""" items: list[AutomationVersionResponse] total: int