- Intent classification with LLM structured output (single/multi/ambiguous) - Discount agent with apply_discount and generate_coupon tools - Interrupt manager with 30-min TTL auto-expiration and retry prompts - Webhook escalation module with exponential backoff retry (max 3) - Three vertical industry templates (e-commerce, SaaS, fintech) - Template loading in AgentRegistry - Enhanced supervisor prompt with dynamic agent descriptions - 153 tests passing, 90.18% coverage
80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
"""Discount agent tools -- apply discounts and generate coupons."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
|
|
from langchain_core.tools import tool
|
|
from langgraph.types import interrupt
|
|
|
|
|
|
@tool
|
|
def apply_discount(order_id: str, discount_percent: int) -> dict:
|
|
"""Apply a discount to an order. Requires human approval before execution."""
|
|
if discount_percent < 1 or discount_percent > 100:
|
|
return {
|
|
"status": "error",
|
|
"order_id": order_id,
|
|
"message": f"Invalid discount: {discount_percent}%. Must be between 1 and 100.",
|
|
}
|
|
|
|
response = interrupt(
|
|
{
|
|
"action": "apply_discount",
|
|
"order_id": order_id,
|
|
"discount_percent": discount_percent,
|
|
"message": (
|
|
f"Please confirm: apply {discount_percent}% discount to order {order_id}?"
|
|
),
|
|
}
|
|
)
|
|
|
|
if isinstance(response, bool):
|
|
approved = response
|
|
elif isinstance(response, dict):
|
|
approved = response.get("approved", False)
|
|
else:
|
|
approved = bool(response)
|
|
|
|
if approved:
|
|
return {
|
|
"status": "applied",
|
|
"order_id": order_id,
|
|
"discount_percent": discount_percent,
|
|
"message": (
|
|
f"{discount_percent}% discount applied to order {order_id}."
|
|
),
|
|
}
|
|
return {
|
|
"status": "declined",
|
|
"order_id": order_id,
|
|
"message": f"Discount for order {order_id} was declined.",
|
|
}
|
|
|
|
|
|
@tool
|
|
def generate_coupon(discount_percent: int, expiry_days: int = 30) -> dict:
|
|
"""Generate a coupon code with the specified discount percentage."""
|
|
if discount_percent < 1 or discount_percent > 100:
|
|
return {
|
|
"status": "error",
|
|
"message": f"Invalid discount: {discount_percent}%. Must be between 1 and 100.",
|
|
}
|
|
if expiry_days < 1:
|
|
return {
|
|
"status": "error",
|
|
"message": f"Invalid expiry: {expiry_days} days. Must be at least 1.",
|
|
}
|
|
|
|
coupon_code = f"SAVE{discount_percent}-{uuid.uuid4().hex[:8].upper()}"
|
|
return {
|
|
"status": "generated",
|
|
"coupon_code": coupon_code,
|
|
"discount_percent": discount_percent,
|
|
"expiry_days": expiry_days,
|
|
"message": (
|
|
f"Coupon {coupon_code} generated: {discount_percent}% off, "
|
|
f"valid for {expiry_days} days."
|
|
),
|
|
}
|