Raje19112003/Invoice_Dispute_Resolution_Environment
0
1"""2Invoice Dispute Resolution Environment - Models3Defines Action, Observation, and State dataclasses used by both client and server.4"""5 6from pydantic import BaseModel, Field7from typing import Optional, Literal8 9 10# ──────────────────────────────────────────────11# ACTION (what the agent sends to the env)12# ──────────────────────────────────────────────13 14class DisputeAction(BaseModel):15 """16 The agent chooses a resolution decision and drafts a customer-facing response.17 18 decision:19 - "full_refund" : approve 100 % refund20 - "partial_refund" : approve a partial credit (specify amount)21 - "reject" : reject the dispute with justification22 - "escalate" : escalate to a human supervisor23 - "request_info" : ask the customer for more information24 25 response_text : the message that will be sent back to the customer26 refund_amount : only required when decision == "partial_refund"27 """28 decision: Literal[29 "full_refund",30 "partial_refund",31 "reject",32 "escalate",33 "request_info",34 ]35 response_text: str = Field(36 ...,37 description="Customer-facing message explaining the resolution decision",38 )39 refund_amount: Optional[float] = Field(40 default=None,41 description="Refund amount in USD; required for partial_refund decision",42 )43 44 45# ──────────────────────────────────────────────46# OBSERVATION (what the env returns to the agent)47# ──────────────────────────────────────────────48 49class DisputeObservation(BaseModel):50 """Feedback the environment sends back after each agent action."""51 52 step_result: str = Field(53 ...,54 description="Human-readable outcome of the agent's last action",55 )56 reward: float = Field(57 ...,58 description="Reward signal for this step (range -1.0 to +1.0)",59 )60 done: bool = Field(61 ...,62 description="True if the episode has ended",63 )64 feedback: str = Field(65 ...,66 description="Grader feedback explaining why the reward was given",67 )68 customer_reaction: Optional[str] = Field(69 default=None,70 description="Simulated customer reaction to the agent's response (if applicable)",71 )72 73 74# ──────────────────────────────────────────────75# STATE (full environment state, returned by state())76# ──────────────────────────────────────────────77 78class DisputeState(BaseModel):79 """Complete snapshot of the current episode."""80 81 # Invoice details82 invoice_id: str83 invoice_amount: float84 invoice_date: str85 line_items: list[dict] # e.g. [{"item": "Cloud Storage", "amount": 49.99}]86 87 # Dispute details88 dispute_type: Literal[89 "duplicate_charge",90 "wrong_amount",91 "service_not_received",92 "unauthorized_charge",93 "already_paid",94 ]95 customer_message: str # The complaint from the customer96 customer_tier: Literal["standard", "premium", "enterprise"]97 customer_history: dict # e.g. {"total_orders": 12, "disputes_filed": 1, "churn_risk": "low"}98 99 # Company policy (the rules the agent must follow)100 policy: dict # e.g. {"max_auto_refund": 200, "escalate_above": 500}101 102 # Episode progress103 step_count: int104 max_steps: int105 is_done: bool106 total_reward: float107 108 # Ground truth (used by grader, NOT shown to agent during episode)109 correct_decision: Optional[str] = Field(110 default=None,111 description="Ground-truth correct decision; revealed only after episode ends",112 )113 