Files
socaichat/backend/app/tools/tickets.py
T
gongzhiyongandClaude Opus 4.6 efb3c53623 feat: add backend service and Azure deployment workflow
- Add complete Python backend (Litestar + LangGraph) with chat, conversations, tickets APIs
- Add GitHub Actions workflow for auto-deploying backend to Azure Web App (soc-backend)
- Add gunicorn to requirements.txt for production serving
- Update CLAUDE.md and EXTERNAL_SERVICES.md with latest config
- Remove obsolete claudehd.md (merged into gpthd.md)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 13:31:00 +08:00

118 lines
3.7 KiB
Python

"""Ticket system tools — proxy to Gongdan API (read-only)."""
from __future__ import annotations
import httpx
from langchain_core.tools import tool
from app.config import settings
def _gongdan_headers() -> dict[str, str]:
return {"X-Api-Key": settings.gongdan_api_key}
def _map_status(raw: str) -> str:
"""Map Gongdan status values to frontend-friendly values."""
mapping = {
"OPEN": "pending",
"ASSIGNED": "processing",
"IN_PROGRESS": "processing",
"PENDING_CUSTOMER": "processing",
"RESOLVED": "resolved",
"CLOSED": "resolved",
}
return mapping.get(raw, "pending")
def _map_priority(raw: str) -> str:
"""Map Gongdan priority to P0-P3."""
mapping = {
"URGENT": "P0",
"PRIORITY": "P1",
"NORMAL": "P2",
"LOW": "P3",
}
return mapping.get(raw, "P2")
@tool
async def ticket_list(page: int = 1, page_size: int = 20) -> str:
"""List tickets from the ticket system.
Use this tool when the user asks about tickets, work orders, issues,
or wants to see a summary of current support requests.
Args:
page: Page number (default 1).
page_size: Number of tickets per page (default 20).
"""
url = f"{settings.gongdan_api_base}/api/tickets"
params = {"page": page, "pageSize": page_size}
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url, params=params, headers=_gongdan_headers())
resp.raise_for_status()
data = resp.json()
tickets = data.get("tickets", [])
if not tickets:
return "No tickets found."
lines: list[str] = []
for t in tickets:
ticket_id = t.get("ticketNumber", t.get("id", "?"))
title = t.get("description", "")[:80]
status = _map_status(t.get("status", ""))
priority = _map_priority(t.get("priority", ""))
created = t.get("createdAt", "")[:10]
customer = t.get("customer", {}).get("name", "Unknown")
lines.append(
f"- [{ticket_id}] {title} | status={status} priority={priority} "
f"customer={customer} created={created}"
)
return f"Found {len(tickets)} tickets:\n" + "\n".join(lines)
@tool
async def ticket_detail(ticket_id: str) -> str:
"""Get detailed information about a specific ticket.
Use this tool when the user asks for details on a particular ticket
or work order, providing its ID.
Args:
ticket_id: The ticket UUID or ticket number.
"""
url = f"{settings.gongdan_api_base}/api/tickets/{ticket_id}"
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url, headers=_gongdan_headers())
resp.raise_for_status()
t = resp.json()
ticket_number = t.get("ticketNumber", t.get("id", "?"))
description = t.get("description", "N/A")
status = _map_status(t.get("status", ""))
priority = _map_priority(t.get("priority", ""))
platform = t.get("platform", "N/A")
model_used = t.get("modelUsed", "N/A")
account = t.get("accountInfo", "N/A")
request_example = t.get("requestExample", "")
customer_name = t.get("customer", {}).get("name", "Unknown")
engineer = t.get("assignedEngineer", {}).get("username", "Unassigned")
created = t.get("createdAt", "")
sla = t.get("slaDeadline", "")
return (
f"Ticket: {ticket_number}\n"
f"Status: {status} | Priority: {priority}\n"
f"Platform: {platform} | Model: {model_used}\n"
f"Customer: {customer_name} | Account: {account}\n"
f"Engineer: {engineer}\n"
f"Created: {created} | SLA: {sla}\n"
f"Description: {description}\n"
f"Request Example: {request_example}"
)