148 lines
3.6 KiB
Python
148 lines
3.6 KiB
Python
"""
|
|
app/models.py
|
|
Pydantic request/response models used by the HTTP API.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, field_validator
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Enumerations
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class InstructionStatus(str, Enum):
|
|
pending = "pending"
|
|
consumed = "consumed"
|
|
|
|
|
|
class ResultType(str, Enum):
|
|
instruction = "instruction"
|
|
empty = "empty"
|
|
default_response = "default_response"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Instruction models
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class InstructionItem(BaseModel):
|
|
id: str
|
|
content: str
|
|
status: InstructionStatus
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
consumed_at: Optional[datetime] = None
|
|
consumed_by_agent_id: Optional[str] = None
|
|
position: int
|
|
|
|
|
|
class InstructionListResponse(BaseModel):
|
|
items: list[InstructionItem]
|
|
|
|
|
|
class InstructionCreateResponse(BaseModel):
|
|
item: InstructionItem
|
|
|
|
|
|
class CreateInstructionRequest(BaseModel):
|
|
content: str
|
|
|
|
@field_validator("content")
|
|
@classmethod
|
|
def content_not_empty(cls, v: str) -> str:
|
|
if not v.strip():
|
|
raise ValueError("content must not be blank")
|
|
return v.strip()
|
|
|
|
|
|
class UpdateInstructionRequest(BaseModel):
|
|
content: str
|
|
|
|
@field_validator("content")
|
|
@classmethod
|
|
def content_not_empty(cls, v: str) -> str:
|
|
if not v.strip():
|
|
raise ValueError("content must not be blank")
|
|
return v.strip()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Status models
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class ServerInfo(BaseModel):
|
|
status: str
|
|
started_at: datetime
|
|
version: str
|
|
|
|
|
|
class AgentInfo(BaseModel):
|
|
connected: bool
|
|
last_seen_at: Optional[datetime] = None
|
|
last_fetch_at: Optional[datetime] = None
|
|
agent_id: Optional[str] = None
|
|
|
|
|
|
class QueueCounts(BaseModel):
|
|
pending_count: int
|
|
consumed_count: int
|
|
|
|
|
|
class StatusResponse(BaseModel):
|
|
server: ServerInfo
|
|
agent: AgentInfo
|
|
queue: QueueCounts
|
|
settings: "ConfigResponse"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Config models
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class ConfigResponse(BaseModel):
|
|
default_wait_seconds: int
|
|
default_empty_response: str
|
|
agent_stale_after_seconds: int
|
|
|
|
|
|
class UpdateConfigRequest(BaseModel):
|
|
default_wait_seconds: Optional[int] = None
|
|
default_empty_response: Optional[str] = None
|
|
agent_stale_after_seconds: Optional[int] = None
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Health model
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class HealthResponse(BaseModel):
|
|
status: str
|
|
server_time: datetime
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# MCP tool response models
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class InstructionPayload(BaseModel):
|
|
id: str
|
|
content: str
|
|
consumed_at: datetime
|
|
|
|
|
|
class GetUserRequestResponse(BaseModel):
|
|
status: str
|
|
result_type: ResultType
|
|
instruction: Optional[InstructionPayload] = None
|
|
response: Optional[str] = None
|
|
remaining_pending: int
|
|
waited_seconds: int
|
|
|
|
|