Spaces:
Sleeping
Sleeping
File size: 7,113 Bytes
585cd37 a0b8672 585cd37 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | """OpenEnv type definitions for the Fish Farm environment.
FarmAction: What the agent can do each hour
FarmObservation: What the agent sees (partial observability — no ground truth disease state)
FarmState: Full internal state (for grading)
"""
from typing import Any, Dict, List
from openenv.core.env_server import Action, Observation, State
from pydantic import Field
class FarmAction(Action):
"""Agent's hourly farm management decision."""
feeding_rate: float = Field(
default=0.3, ge=0.0, le=1.0,
description="Feeding intensity (0=none, 0.3=conservative, 0.5=normal, 1.0=maximum ration). "
"Higher feeding grows fish faster but produces more ammonia and consumes more oxygen."
)
aeration_rate: float = Field(
default=0.5, ge=0.0, le=1.0,
description="Aerator power (0=off, 0.5=half, 1.0=full). "
"Increases dissolved oxygen but costs electricity."
)
heater_setting: float = Field(
default=0.0, ge=-1.0, le=1.0,
description="Temperature control (-1.0=max cooling, 0=off, 1.0=max heating). "
"Adjusts water temperature toward optimal growth range."
)
water_exchange_rate: float = Field(
default=0.02, ge=0.0, le=0.10,
description="Fresh water exchange (0=none, 0.05=5%/hour, 0.10=10%/hour max). "
"Dilutes ammonia and refreshes oxygen but costs water."
)
harvest_decision: bool = Field(
default=False,
description="Set True to harvest all fish and end the episode. "
"Revenue depends on total biomass and market price."
)
treatment: str = Field(
default="none",
description="Disease treatment: 'none', 'antibiotics' (speeds recovery, harms biofilter), "
"'salt' (reduces nitrite toxicity), 'probiotics' (boosts biofilter), "
"'vaccination' ($100, prevents 80% of future infections). "
"Treatments cost money."
)
class FarmObservation(Observation):
"""What the agent observes after each step.
Note: Disease infection count is NOT directly visible — the agent must
infer disease from behavioral indicators (feeding response, mortality spikes).
"""
# Fish status
avg_fish_weight: float = Field(default=5.0, description="Average individual fish weight (grams)")
population: int = Field(default=10000, description="Total fish count in tank")
mortality_today: int = Field(default=0, description="Fish deaths in the last 24 hours")
cumulative_mortality: int = Field(default=0, description="Total deaths since stocking")
survival_rate: float = Field(default=1.0, description="Fraction of original population still alive")
stress_level: float = Field(default=0.0, description="Fish stress index (0.0=calm, 1.0=critical)")
feeding_response: str = Field(default="normal", description="Fish appetite: eager/normal/sluggish/refusing")
biomass_kg: float = Field(default=50.0, description="Total fish biomass in kg")
growth_rate_g_day: float = Field(default=0.0, description="Current growth rate (g/day)")
fcr: float = Field(default=0.0, description="Feed conversion ratio (kg feed / kg gain). Target <2.0")
sgr: float = Field(default=0.0, description="Specific growth rate (%/day)")
stocking_density: float = Field(default=50.0, description="Fish per cubic meter")
# Water quality
temperature: float = Field(default=28.0, description="Water temperature (Celsius)")
dissolved_oxygen: float = Field(default=7.0, description="Dissolved oxygen (mg/L). Below 3=danger, below 1=lethal")
ph: float = Field(default=7.5, description="Water pH (6.5-8.5 optimal)")
ammonia: float = Field(default=0.1, description="Total ammonia nitrogen TAN (mg/L). Above 2=dangerous")
ammonia_toxic: float = Field(default=0.005, description="Unionized ammonia UIA (mg/L). Above 0.05=toxic")
nitrite: float = Field(default=0.05, description="Nitrite NO2 (mg/L). Above 0.5=stress")
nitrate: float = Field(default=0.0, description="Nitrate NO3 (mg/L). Product of nitrification")
water_quality_score: float = Field(default=1.0, description="Composite water quality (0-1)")
algae_bloom: bool = Field(default=False, description="Is algae bloom active (DO swings)")
nighttime_do_risk: float = Field(default=0.0, description="Nighttime DO crash risk (0=safe, 1=imminent). Increase aeration if high.")
# System status
aerator_working: bool = Field(default=True, description="Is the aerator functioning?")
biofilter_working: bool = Field(default=True, description="Is the biofilter functioning?")
heater_working: bool = Field(default=True, description="Is the heater functioning?")
feed_remaining_kg: float = Field(default=500.0, description="Feed inventory remaining (kg)")
# Economics
current_fish_value: float = Field(default=0.0, description="Current market value of all fish ($)")
total_cost_so_far: float = Field(default=0.0, description="Cumulative operating cost ($)")
current_profit: float = Field(default=0.0, description="Revenue - costs if harvested now ($)")
feed_price_per_kg: float = Field(default=0.50, description="Current feed price (stochastic, $/kg)")
market_price_multiplier: float = Field(default=1.0, description="Seasonal market price factor (1.0=normal)")
marginal_cost_per_hour: float = Field(default=0.0, description="Cost of last hour of operation ($)")
roi_pct: float = Field(default=0.0, description="Return on investment (%)")
# Weather
weather_forecast: str = Field(default="", description="Current weather conditions")
is_daytime: bool = Field(default=True, description="Is it daytime (affects photosynthesis/DO)")
storm_active: bool = Field(default=False, description="Is a storm currently active")
humidity: float = Field(default=75.0, description="Relative humidity (%)")
# Context
day_in_cycle: int = Field(default=0, description="Days since stocking")
time_of_day: int = Field(default=0, description="Hour (0-23)")
day_of_year: int = Field(default=1, description="Calendar day (1-365, for seasonal context)")
alerts: List[str] = Field(default_factory=list, description="Active alerts and warnings")
# Disease signals (partial observability — no infection count, but behavioral indicators)
disease_suspected: bool = Field(default=False, description="Behavioral signs suggest disease (mortality+appetite)")
# Env standard
feedback: str = Field(default="", description="Narrative feedback on the current situation")
class FarmState(State):
"""Full internal state — used by graders, NOT visible to agent.
Contains ground truth disease status, exact biochemistry, etc.
"""
task_id: str = Field(default="", description="Current task ID")
is_complete: bool = Field(default=False)
final_score: float = Field(default=0.0)
max_hours: int = Field(default=168)
# Full simulator snapshot
sim_state: Dict[str, Any] = Field(default_factory=dict)
|