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()