File size: 5,762 Bytes
6b6e83f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | #!/usr/bin/env python3
"""
cli.py β Complaint Auto-Routing System Β· Command Line Interface
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Usage examples:
# Submit a text complaint interactively
python app/cli.py
# Submit text directly
python app/cli.py --text "Pothole on MG Road near hospital. Very dangerous!"
# Submit an audio file
python app/cli.py --audio /path/to/complaint.mp3
# Submit a video file
python app/cli.py --video /path/to/complaint.mp4
# Control number of similar complaints shown
python app/cli.py --text "Power outage in Sector 14" --top-k 3
"""
import argparse
import json
import os
import sys
import textwrap
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from inference.engine import ComplaintRoutingEngine, SAVE_DIR
# βββ ANSI colours βββββββββββββββββββββββββββββββββββββββββββββ
class C:
RESET = "\033[0m"
BOLD = "\033[1m"
RED = "\033[91m"
YELLOW = "\033[93m"
GREEN = "\033[92m"
CYAN = "\033[96m"
BLUE = "\033[94m"
DIM = "\033[2m"
PRIORITY_COLOUR = {"High": C.RED, "Medium": C.YELLOW, "Low": C.GREEN}
def print_banner():
print(f"""
{C.BOLD}{C.CYAN}ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β COMPLAINT AUTO-ROUTING SYSTEM v1.0 β
β IVTEX Corporate Solutions Pvt. Ltd. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ{C.RESET}
""")
def format_result(result: dict) -> str:
lines = []
sep = "β" * 54
# ββ Officer
o = result["officer"]
lines.append(f"\n{C.BOLD}{'ASSIGNED OFFICER':β<54}{C.RESET}")
lines.append(f" {C.BOLD}Name :{C.RESET} {o['name']}")
lines.append(f" {C.BOLD}Department :{C.RESET} {o['department']}")
lines.append(f" {C.BOLD}Officer ID :{C.RESET} {o['id']}")
lines.append(f" {C.BOLD}Confidence :{C.RESET} {o['confidence']}%")
# ββ Priority
p = result["priority"]
pc = PRIORITY_COLOUR.get(p["level"], C.RESET)
lines.append(f"\n{C.BOLD}{'PRIORITY':β<54}{C.RESET}")
lines.append(f" {C.BOLD}Level :{C.RESET} {pc}{C.BOLD}{p['level']}{C.RESET}")
lines.append(f" {C.BOLD}Confidence :{C.RESET} {p['confidence']}%")
# ββ ETA
lines.append(f"\n{C.BOLD}{'ESTIMATED RESOLUTION TIME':β<54}{C.RESET}")
lines.append(f" {C.BOLD}ETA :{C.RESET} {C.CYAN}{result['eta_days']} day(s){C.RESET}")
# ββ Similar
sims = result.get("similar_complaints", [])
lines.append(f"\n{C.BOLD}{'SIMILAR PAST COMPLAINTS':β<54}{C.RESET}")
if not sims:
lines.append(" (none found)")
for i, s in enumerate(sims, 1):
snippet = textwrap.shorten(s["text_snippet"], width=65)
lines.append(
f" {i}. [{s['complaint_id']}] "
f"Score={s['similarity_score']:.3f} "
f"{PRIORITY_COLOUR.get(s['priority'], '')}[{s['priority']}]{C.RESET}\n"
f" {C.DIM}{snippet}{C.RESET}"
)
if result.get("modality") and result["modality"] != "text":
lines.append(f"\n{C.DIM} (Input modality: {result['modality']}){C.RESET}")
return "\n".join(lines)
def interactive_mode(engine: ComplaintRoutingEngine, top_k: int):
print(f"{C.DIM}Type your complaint and press Enter. "
f"Type 'quit' to exit.{C.RESET}\n")
while True:
try:
text = input(f"{C.BOLD}Enter complaint:{C.RESET} ").strip()
except (EOFError, KeyboardInterrupt):
print("\nGoodbye.")
break
if not text:
continue
if text.lower() in ("quit", "exit", "q"):
print("Goodbye.")
break
result = engine.predict(text, top_k_similar=top_k)
print(format_result(result))
print()
def main():
parser = argparse.ArgumentParser(
description="Complaint Auto-Routing System β CLI",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=__doc__,
)
parser.add_argument("--text", type=str, help="Complaint text (inline)")
parser.add_argument("--audio", type=str, help="Path to audio file (.wav/.mp3/β¦)")
parser.add_argument("--video", type=str, help="Path to video file (.mp4/.mkv/β¦)")
parser.add_argument("--top-k", type=int, default=5,
help="Number of similar complaints to retrieve (default: 5)")
parser.add_argument("--json", action="store_true",
help="Output raw JSON instead of formatted display")
args = parser.parse_args()
print_banner()
engine = ComplaintRoutingEngine().load(SAVE_DIR)
result = None
if args.text:
result = engine.process(text=args.text, top_k=args.top_k)
elif args.audio:
result = engine.process(audio_path=args.audio, top_k=args.top_k)
elif args.video:
result = engine.process(video_path=args.video, top_k=args.top_k)
else:
# Interactive mode
interactive_mode(engine, args.top_k)
return
if args.json:
print(json.dumps(result, indent=2, ensure_ascii=False))
else:
if result.get("modality") != "text":
print(f"{C.DIM}Transcription: {result.get('source_text', '')[:200]}β¦{C.RESET}\n")
print(format_result(result))
if __name__ == "__main__":
main()
|