grid / smartgrid_mas /models.py
Not-OmKar's picture
Big update
427a79e
from typing import Dict, List, Literal, Optional
from pydantic import BaseModel, Field
AgentRole = Literal[
"renewable_prosumer",
"ev_aggregator",
"peaker_plant",
"industrial_load",
]
BidType = Literal["supply", "demand"]
class AgentBid(BaseModel):
agent_id: str = Field(..., description="Unique agent id")
role: AgentRole = Field(..., description="Agent role")
bid_type: BidType = Field(..., description="Supply or demand bid")
quantity_mwh: float = Field(..., ge=0.0, description="Bid quantity in MWh")
price_usd_per_mwh: float = Field(..., ge=0.0, description="Bid price")
class JointAction(BaseModel):
bids: List[AgentBid] = Field(default_factory=list, description="Bids from all agents")
ev_charge_mwh: float = Field(0.0, ge=0.0, description="EV fleet charge command")
ev_discharge_mwh: float = Field(0.0, ge=0.0, description="EV fleet discharge command")
class DispatchAction(BaseModel):
reserve_activation_mwh: float = Field(0.0, ge=0.0, description="Reserve activation target")
peaker_adjustment_mwh: float = Field(0.0, description="Peaker redispatch adjustment")
storage_dispatch_mwh: float = Field(0.0, description="Signed storage dispatch adjustment")
corrective_redispatch_mwh: float = Field(0.0, description="Signed corrective redispatch adjustment")
class MarketObservation(BaseModel):
step: int
steps_taken: int
max_steps: int
demand_mwh: float
renewable_availability_mwh: float
peaker_capacity_mwh: float
ev_storage_mwh: float
ev_storage_capacity_mwh: float
last_clearing_price: float
leader_price_signal: float
scarcity_index: float
shock_active: bool
forecast_demand_mwh: float = 0.0
forecast_renewable_mwh: float = 0.0
load_forecast_error_mwh: float = 0.0
renewable_forecast_error_mwh: float = 0.0
contingency_active: bool = False
contingency_type: str = "none"
operator_override_enabled: bool = False
public_signal: str
schema_info: str
hint: Optional[str] = None
error_message: Optional[str] = None
class MarketReward(BaseModel):
score: float = Field(..., ge=0.0, le=1.0)
reason: str
demand_satisfaction_score: float
cost_efficiency_score: float
renewable_utilization_score: float
stability_score: float
reserve_adequacy_score: float = 0.0
emissions_intensity_tco2_per_mwh: float = 0.0
infeasibility_penalty: float
blackout_penalty: float
class ResetRequest(BaseModel):
task_id: str = "default"
seed: Optional[int] = None
class ResetResponse(BaseModel):
session_id: str
task_id: str
task_description: str
schema_info: str
steps_taken: int
observation: MarketObservation
class StepRequest(BaseModel):
action: JointAction
dispatch_action: Optional[DispatchAction] = None
class StepResponse(BaseModel):
observation: MarketObservation
reward: MarketReward
done: bool
truncated: bool
info: Dict
class StateResponse(BaseModel):
current_task_id: str
steps_taken: int
episode_done: bool
observation: Optional[MarketObservation] = None
class EpisodeSummary(BaseModel):
average_reward: float
total_demand_met: float
total_cost: float
infeasible_actions: int
corrections: int
shock_response_score: float