Jerry
Upgrade: Premium Dashboard, Multi-Agent capacity logic, and GRPO training updates
c276e2c
Raw
History Blame Contribute Delete
5.69 kB
"""
LogisticsShipmentRL — Models
Pydantic schemas describing the Action, Observation, and State API contracts.
"""
from typing import Any, Dict, List, Literal, Optional
from pydantic import BaseModel, Field
# ---------------------------------------------------------------------------
# Core Entities (Sub-models)
# ---------------------------------------------------------------------------
class ShipmentStatus(BaseModel):
shipment_id: str
origin: str
destination: str
cargo_type: Literal["standard", "perishable", "hazmat", "high_value"]
cargo_description: str
current_location: str
current_status: Literal["in_transit", "delayed", "at_hub", "customs_hold", "delivered"]
assigned_carrier: str
assigned_route: str
estimated_arrival: str # e.g., "+6h", or ISO timestamp
sla_deadline: str
sla_buffer_hours: float # Negative value means SLA breached
current_delay_hours: float
value_usd: float
is_priority: bool
notes: str
class DisruptionEvent(BaseModel):
event_id: str
event_type: Literal["breakdown", "weather", "port_congestion", "customs_hold",
"strike", "accident", "road_closure", "capacity_shortage"]
location: str
affected_routes: List[str]
affected_shipments: List[str]
severity: Literal["low", "medium", "high", "critical"]
estimated_duration_hours: float
estimated_additional_delay_hours: float
description: str
can_be_bypassed: bool
class RouteOption(BaseModel):
route_id: str
route_name: str
origin: str
destination: str
distance_km: float
estimated_hours: float
cost_usd: float
carrier_options: List[str]
current_congestion: Literal["clear", "light", "moderate", "high"]
weather_risk: Literal["none", "low", "moderate", "high"]
is_available: bool
# ---------------------------------------------------------------------------
# API Contracts: Action
# ---------------------------------------------------------------------------
class ReroutingDecision(BaseModel):
new_route: str = Field(description="Route ID from available_routes (e.g., 'R2')")
new_carrier: Optional[str] = Field(default=None, description="Carrier name, or None to keep existing")
reason: str = Field(description="One-sentence justification for this re-routing")
class LogisticsAction(BaseModel):
"""
The full action submitted by the AI agent per step.
The agent receives a heavily delayed network and must repair it.
"""
reasoning: str = Field(
description="Chain-of-thought analysis explaining strategy and risk assessment."
)
rerouting_decisions: Dict[str, ReroutingDecision] = Field(
default_factory=dict,
description="Shipment ID -> Re-routing decision. Only include active changes.",
)
priority_shipments: List[str] = Field(
default_factory=list,
description="Identify up to 3 shipment IDs to expedite handling.",
)
customer_communications: Dict[str, str] = Field(
default_factory=dict,
description="ETA messages keyed by shipment ID, sent to customers.",
)
escalations: List[str] = Field(
default_factory=list,
description="Shipments passing human limit, requiring a real dispatcher.",
)
# ---------------------------------------------------------------------------
# API Contracts: Observation
# ---------------------------------------------------------------------------
class LogisticsObservation(BaseModel):
"""Full network snapshot returned by the Environment."""
scenario_id: str
scenario_title: str
network_snapshot: str # Natural language context summary
# State tracking
active_shipments: List[ShipmentStatus]
total_shipments: int
delayed_shipments: int
sla_at_risk_count: int # Shipments within 2 hrs of breaking SLA
# Dynamics
disruption_events: List[DisruptionEvent]
active_disruptions_count: int
available_routes: List[RouteOption]
weather_forecast: str
carrier_availability: Dict[str, int] # Name -> trucks available
field_updates: List[str] # Alerts from the field
# Global metrics
current_total_delay_hours: float
sla_violations: List[str]
on_time_shipments: int
# Turn metrics
step_number: int
max_steps: int
episode_done: bool
previous_action_feedback: str
previous_reward: float
previous_reward_breakdown: Dict[str, float]
# Cumulative stats
cumulative_reward: float
total_delay_saved_hours: float
total_rerouting_cost_usd: float
sla_compliance_rate: float
action_hint: str = (
"Re-route shipments impacted by disruptions to available routes to save delay time. "
"Prioritize rescuing negative sla_buffer_hours shipments and write clear customer_communications."
)
# ---------------------------------------------------------------------------
# End-of-Episode State
# ---------------------------------------------------------------------------
class LogisticsState(BaseModel):
"""End-of-episode comprehensive metadata."""
episode_id: str
step_count: int
max_steps: int
done: bool
scenario_id: str
total_shipments: int
total_delay_saved_hours: float
total_rerouting_cost_usd: float
sla_violations_count: int
sla_compliance_rate: float
cumulative_reward: float
reward_breakdown: Dict[str, float]
class LogisticsStepResult(BaseModel):
observation: LogisticsObservation
reward: float
done: bool
info: Dict[str, Any] = Field(default_factory=dict)