240 lines
5.7 KiB
Python
240 lines
5.7 KiB
Python
"""Pydantic schemas for API request/response models."""
|
|
|
|
from typing import Optional
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ============== Resource Schemas ==============
|
|
|
|
class ResourceSchema(BaseModel):
|
|
"""Schema for a resource item."""
|
|
type: str
|
|
quantity: int
|
|
created_turn: int
|
|
decay_rate: Optional[int] = None
|
|
|
|
|
|
# ============== Agent Schemas ==============
|
|
|
|
class PositionSchema(BaseModel):
|
|
"""Schema for agent position (float for smooth movement)."""
|
|
x: float
|
|
y: float
|
|
|
|
|
|
class StatsSchema(BaseModel):
|
|
"""Schema for agent vital stats."""
|
|
energy: int
|
|
hunger: int
|
|
thirst: int
|
|
heat: int
|
|
max_energy: int
|
|
max_hunger: int
|
|
max_thirst: int
|
|
max_heat: int
|
|
|
|
|
|
class AgentActionSchema(BaseModel):
|
|
"""Schema for current agent action."""
|
|
action_type: str
|
|
target_position: Optional[PositionSchema] = None
|
|
target_resource: Optional[str] = None
|
|
progress: float
|
|
is_moving: bool
|
|
message: str
|
|
|
|
|
|
class AgentResponse(BaseModel):
|
|
"""Schema for agent data."""
|
|
id: str
|
|
name: str
|
|
profession: str
|
|
position: PositionSchema
|
|
home_position: PositionSchema
|
|
stats: StatsSchema
|
|
inventory: list[ResourceSchema]
|
|
money: int
|
|
is_alive: bool
|
|
is_corpse: bool = False
|
|
can_act: bool
|
|
current_action: AgentActionSchema
|
|
last_action_result: str
|
|
death_turn: int = -1
|
|
death_reason: str = ""
|
|
# Age system
|
|
age: int = 25
|
|
max_age: int = 70
|
|
age_category: str = "prime"
|
|
birth_day: int = 0
|
|
generation: int = 0
|
|
parent_ids: list[str] = []
|
|
children_count: int = 0
|
|
# Age modifiers
|
|
skill_modifier: float = 1.0
|
|
energy_cost_modifier: float = 1.0
|
|
learning_modifier: float = 1.0
|
|
# Personality and skills
|
|
personality: dict = {}
|
|
skills: dict = {}
|
|
actions_performed: dict = {}
|
|
total_trades: int = 0
|
|
total_money_earned: int = 0
|
|
action_history: list = []
|
|
|
|
|
|
# ============== Market Schemas ==============
|
|
|
|
class OrderSchema(BaseModel):
|
|
"""Schema for a market order."""
|
|
id: str
|
|
seller_id: str
|
|
resource_type: str
|
|
quantity: int
|
|
price_per_unit: int
|
|
total_price: int
|
|
created_turn: int
|
|
status: str
|
|
turns_without_sale: int
|
|
|
|
|
|
class MarketPriceSchema(BaseModel):
|
|
"""Schema for market price summary."""
|
|
lowest_price: Optional[int]
|
|
highest_price: Optional[int]
|
|
total_available: int
|
|
num_orders: int
|
|
|
|
|
|
class TradeResultSchema(BaseModel):
|
|
"""Schema for a trade result."""
|
|
success: bool
|
|
order_id: str = ""
|
|
buyer_id: str = ""
|
|
seller_id: str = ""
|
|
resource_type: Optional[str] = None
|
|
quantity: int = 0
|
|
total_paid: int = 0
|
|
message: str = ""
|
|
|
|
|
|
class MarketStateResponse(BaseModel):
|
|
"""Schema for market state."""
|
|
orders: list[OrderSchema]
|
|
prices: dict[str, MarketPriceSchema]
|
|
recent_trades: list[TradeResultSchema]
|
|
|
|
|
|
# ============== World Schemas ==============
|
|
|
|
class WorldSizeSchema(BaseModel):
|
|
"""Schema for world dimensions."""
|
|
width: int
|
|
height: int
|
|
|
|
|
|
class StatisticsSchema(BaseModel):
|
|
"""Schema for world statistics."""
|
|
current_turn: int
|
|
current_day: int
|
|
step_in_day: int
|
|
time_of_day: str
|
|
living_agents: int
|
|
total_agents_spawned: int
|
|
total_agents_died: int
|
|
total_births: int = 0
|
|
total_money_in_circulation: int
|
|
professions: dict[str, int]
|
|
# Wealth inequality metrics
|
|
avg_money: float = 0.0
|
|
median_money: int = 0
|
|
richest_agent: int = 0
|
|
poorest_agent: int = 0
|
|
gini_coefficient: float = 0.0
|
|
# Age demographics
|
|
age_distribution: dict[str, int] = {}
|
|
avg_age: float = 0.0
|
|
oldest_agent: int = 0
|
|
youngest_agent: int = 0
|
|
generations: dict[int, int] = {}
|
|
# Death statistics
|
|
deaths_by_cause: dict[str, int] = {}
|
|
# Village storage
|
|
village_storage: dict[str, int] = {}
|
|
|
|
|
|
class ActionLogSchema(BaseModel):
|
|
"""Schema for an action in the turn log."""
|
|
agent_id: str
|
|
agent_name: str
|
|
decision: dict
|
|
result: Optional[dict] = None
|
|
|
|
|
|
class TurnLogSchema(BaseModel):
|
|
"""Schema for a turn log entry."""
|
|
turn: int
|
|
agent_actions: list[ActionLogSchema]
|
|
deaths: list[str]
|
|
births: list[str] = []
|
|
trades: list[dict]
|
|
resources_produced: dict[str, int] = {}
|
|
resources_consumed: dict[str, int] = {}
|
|
resources_spoiled: dict[str, int] = {}
|
|
day_events: dict = {}
|
|
|
|
|
|
class ResourceStatsSchema(BaseModel):
|
|
"""Schema for resource statistics."""
|
|
produced: dict[str, int] = {}
|
|
consumed: dict[str, int] = {}
|
|
spoiled: dict[str, int] = {}
|
|
in_inventory: dict[str, int] = {}
|
|
in_market: dict[str, int] = {}
|
|
|
|
|
|
class WorldStateResponse(BaseModel):
|
|
"""Full world state response."""
|
|
turn: int
|
|
day: int
|
|
step_in_day: int
|
|
time_of_day: str
|
|
world_size: WorldSizeSchema
|
|
agents: list[AgentResponse]
|
|
statistics: StatisticsSchema
|
|
market: MarketStateResponse
|
|
mode: str
|
|
is_running: bool
|
|
recent_logs: list[TurnLogSchema]
|
|
resource_stats: ResourceStatsSchema = ResourceStatsSchema()
|
|
|
|
|
|
# ============== Control Schemas ==============
|
|
|
|
class ControlResponse(BaseModel):
|
|
"""Response for control operations."""
|
|
success: bool
|
|
message: str
|
|
turn: Optional[int] = None
|
|
mode: Optional[str] = None
|
|
|
|
|
|
class SetModeRequest(BaseModel):
|
|
"""Request to set simulation mode."""
|
|
mode: str = Field(..., pattern="^(manual|auto)$")
|
|
|
|
|
|
class InitializeRequest(BaseModel):
|
|
"""Request to initialize simulation."""
|
|
num_agents: int = Field(default=8, ge=1, le=50)
|
|
world_width: int = Field(default=20, ge=5, le=100)
|
|
world_height: int = Field(default=20, ge=5, le=100)
|
|
|
|
|
|
# ============== Error Schemas ==============
|
|
|
|
class ErrorResponse(BaseModel):
|
|
"""Error response."""
|
|
error: str
|
|
detail: Optional[str] = None
|
|
|