mini-rl-openenv / server /tools.py
Darshan03's picture
docs: finalize production-grade documentation and technical comments across core files
0bbc2af
Raw History Blame Contribute Delete
6.46 kB
"""
Customer Support Toolset β€” OpenEnv CSA
=====================================
This file defines the 17 functional tools available to the Support Agent.
Each tool interacts directly with the mock databases in server/db.py.
Categories:
1. ORDER: lookup, status, cancellation
2. LOGISTICS: tracking, address updates, rescheduling
3. FINANCE: refunds, payment validation, returns
4. AUTH: password resets
5. SUPPORT: coupons, human escalation, final responses
"""
from server.db import USERS_DB, ORDERS_DB, PAYMENTS_DB, LOGISTICS_DB, COUPONS_DB, SLOTS_DB
# --- ORDER APIS ---
def get_order(order_id: str) -> dict:
"""Retrieves full order details (status, items, user) from the database."""
if order_id not in ORDERS_DB:
return {"error": f"Order {order_id} not found."}
return ORDERS_DB[order_id]
def get_order_status(order_id: str) -> str:
"""Returns a simple status string for a given order ID."""
order = get_order(order_id)
if "error" in order:
return order["error"]
return f"Status for {order_id}: {order['status']}."
def cancel_order(order_id: str) -> str:
"""Attempts to cancel an order. Only possible if the order hasn't shipped."""
order = get_order(order_id)
if "error" in order:
return order["error"]
if order["status"] in ["delivered", "shipped"]:
return f"Cannot cancel {order_id}. Current status: {order['status']}. Manual review or return needed."
ORDERS_DB[order_id]["status"] = "cancelled"
return f"Order {order_id} successfully cancelled."
# --- LOGISTICS APIS ---
def track_shipment(order_id: str) -> dict:
"""Fetches real-time tracking data (last location, courier) for an order."""
if order_id not in LOGISTICS_DB:
return {"error": f"No shipment found for {order_id}."}
return LOGISTICS_DB[order_id]
def update_address(order_id: str, new_address: str) -> str:
"""Updates the delivery address for an order not yet in the 'shipped' state."""
order = get_order(order_id)
if "error" in order: return order["error"]
if order["status"] in ["shipped", "delivered"]:
return f"Cannot update address for {order_id}. Item is already {order['status']}."
ORDERS_DB[order_id]["new_address"] = new_address
return f"Delivery address for {order_id} updated to: {new_address}"
def check_delivery_slot(order_id: str) -> list:
"""Returns a list of available rescheduling slots for an order."""
return SLOTS_DB.get(order_id, ["No slots available currently."])
def reschedule_delivery(order_id: str, slot: str) -> str:
"""Assigns a new delivery slot to an existing order."""
if order_id not in ORDERS_DB: return "Order not found."
ORDERS_DB[order_id]["rescheduled_to"] = slot
return f"Delivery for {order_id} rescheduled to: {slot}"
def investigate_missing(order_id: str) -> str:
"""Creates an internal ticket to investigate a missing but marked-as-delivered package."""
return f"Investigation ID-MISS-99 created for {order_id}. Logistics team will contact the courier."
# --- REFUND & RETURN APIS ---
def validate_return(order_id: str) -> dict:
"""Validates if an order is eligible for return (must be 'delivered')."""
order = get_order(order_id)
if "error" in order: return order
if order["status"] != "delivered":
return {"valid": False, "reason": "Not delivered yet."}
return {"valid": True, "reason": "Within return window."}
def ask_proof(order_id: str) -> str:
"""Requests and marks 'damage proof' as received for a specific order."""
if order_id in ORDERS_DB:
ORDERS_DB[order_id]["damage_proof_received"] = True
return f"Photo proof request sent for {order_id}. System marked 'Pending Review'."
return "Order not found."
def create_return_request(order_id: str) -> str:
"""Initializes a return process if the order is valid for return."""
val = validate_return(order_id)
if not val.get("valid"): return f"Return Failed: {val.get('reason')}"
return f"Return request created for {order_id}."
def initiate_refund(order_id: str) -> str:
"""Triggers a monetary refund against the transaction ID associated with an order."""
order = get_order(order_id)
if "error" in order: return order["error"]
txn_id = order.get("payment_id")
if txn_id and txn_id in PAYMENTS_DB:
PAYMENTS_DB[txn_id]["refunded"] = True
return f"Refund initiated against {txn_id}."
return f"Refund failed. No transaction record."
def get_payment_details(txn_id: str) -> dict:
"""Lookups transaction metadata (method, amount, refund status)."""
if txn_id not in PAYMENTS_DB:
return {"error": f"Transaction {txn_id} not found."}
return PAYMENTS_DB[txn_id]
# --- SUPPORT APIS ---
def validate_coupon(code: str) -> str:
coupon = COUPONS_DB.get(code)
if not coupon: return "Invalid coupon code."
if not coupon["valid"]: return "Coupon has expired."
return f"Coupon {code} applied! Discount: {coupon['discount_percent']}%"
def reset_password(email: str) -> str:
"""Sends a password reset link to the user's primary email."""
return f"Password reset link sent to {email}."
def escalate_to_human(issue: str) -> str:
"""Immediately transfers the interaction to a human supervisor for manual review."""
return f"Escalated: {issue}"
def respond(message: str) -> str:
"""Standard tool for the agent to provide a final response back to the customer."""
return message
# ── Action Registry ──────────────────────────────────────────────────────────
# Mapping tool names to their respective functions for the Environment's parser.
ACTION_REGISTRY = {
"get_order": get_order,
"get_order_status": get_order_status,
"cancel_order": cancel_order,
"track_shipment": track_shipment,
"get_payment_details": get_payment_details,
"update_address": update_address,
"check_delivery_slot": check_delivery_slot,
"reschedule_delivery": reschedule_delivery,
"investigate_missing": investigate_missing,
"validate_return": validate_return,
"ask_proof": ask_proof,
"create_return_request": create_return_request,
"initiate_refund": initiate_refund,
"validate_coupon": validate_coupon,
"reset_password": reset_password,
"escalate_to_human": escalate_to_human,
"respond": respond
}