rushagentrush / backend /app /models.py
adityaverma977
Add fire status ETA event, probabilistic lethality by intensity, display ETA in UI
30e238f
Raw
History Blame Contribute Delete
3.99 kB
from typing import Any, Literal, Optional, Union
from pydantic import BaseModel
class AgentModel(BaseModel):
model_name: str # full id, e.g. "llama-3.1-8b-instant"
display_name: str # short label shown on map
x: int
y: int
alive: bool = True
allied_with: Optional[str] = None # model_name of ally (if stacked)
has_proposed_alliance: bool = False
last_message: Optional[str] = None
distance_to_fire: Optional[float] = None
# New fields for fire/coalition mechanics
water_collected: bool = False # carrying water
is_leader: bool = False # elected coalition leader
coalition_members: list[str] = [] # list of allied agent model_names
mode: Literal["solo", "coalition"] = "coalition" # agent's chosen path
status: Literal["searching", "collecting_water", "extinguishing_fire", "escaping", "idle"] = "idle"
vote_for: Optional[str] = None # who this agent voted for as leader
extinguish_score: float = 0.0 # total fire intensity reduced by this agent
class FireScenario(BaseModel):
x: int
y: int
radius: float = 50.0 # current fire radius
intensity: float = 100.0 # 0-100; when 0, fire is out
growth_rate: float = 3.0 # px per tick
class WaterSource(BaseModel):
id: str # unique id
x: int
y: int
water_amount: float = 50.0 # how much water available
class SimulationState(BaseModel):
simulation_id: str
scenario: str # "fire" (was "volcano")
map_width: int
map_height: int
agents: list[AgentModel]
fire: Optional[FireScenario] = None
water_sources: list[WaterSource] = []
round: int = 0
status: str = "waiting_for_scenario"
winner_model: Optional[str] = None
coalition_leader: Optional[str] = None # elected leader
coalition_members: list[str] = [] # all coalition members
# Event models
class DeathEvent(BaseModel):
type: Literal["death"] = "death"
model: str
class MessageEvent(BaseModel):
type: Literal["message"] = "message"
model: str
content: str
class AllianceProposalEvent(BaseModel):
type: Literal["alliance_proposal"] = "alliance_proposal"
from_model: str
to_model: str
class AllianceAcceptEvent(BaseModel):
type: Literal["alliance_accept"] = "alliance_accept"
model_a: str
model_b: str
stacked: bool = True
class AllianceRejectEvent(BaseModel):
type: Literal["alliance_reject"] = "alliance_reject"
from_model: str
to_model: str
class LeadershipVoteEvent(BaseModel):
type: Literal["leadership_vote"] = "leadership_vote"
voter: str
candidate: str
class LeaderElectedEvent(BaseModel):
type: Literal["leader_elected"] = "leader_elected"
leader: str
coalition_members: list[str]
class WaterCollectedEvent(BaseModel):
type: Literal["water_collected"] = "water_collected"
model: str
water_source_id: str
class FireExtinguishedEvent(BaseModel):
type: Literal["fire_extinguished"] = "fire_extinguished"
extinguished_by: list[str] # models that contributed
fire_intensity: float
class FireSpreadEvent(BaseModel):
type: Literal["fire_spread"] = "fire_spread"
new_radius: float
new_intensity: float
class FireStatusEvent(BaseModel):
type: Literal["fire_status"] = "fire_status"
radius: float
intensity: float
ticks_to_extinguish: Optional[int] = None
secs_to_extinguish: Optional[float] = None
class ChatEntry(BaseModel):
agent_id: str
message: str
tick: int
class TickResponse(BaseModel):
simulation_id: str
round: int
events: list[Union[DeathEvent, MessageEvent, AllianceProposalEvent, AllianceAcceptEvent,
AllianceRejectEvent, LeadershipVoteEvent, LeaderElectedEvent,
WaterCollectedEvent, FireExtinguishedEvent, FireSpreadEvent]]
chat: list[ChatEntry]
state: SimulationState