CoderHassan commited on
Commit
25c8c70
·
verified ·
1 Parent(s): 2942022

Upload intent.py

Browse files
Files changed (1) hide show
  1. agents/intent.py +123 -0
agents/intent.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Agent 1 — Intent Agent
2
+ Uses Gemini 1.5 Flash if GEMINI_API_KEY is valid.
3
+ Falls back to rule-based parser if key is missing/invalid (demo mode).
4
+ """
5
+ import os, json, re
6
+ import google.generativeai as genai
7
+
8
+ # ── Rule-based fallback (no API key needed) ──────────────────────
9
+ SERVICE_KEYWORDS = {
10
+ "AC Technician": ["ac", "air condition", "cooling", "hvac", "thanda"],
11
+ "Plumber": ["plumber", "plumbing", "pipe", "leakage", "tap", "nal"],
12
+ "Electrician": ["electric", "bijli", "wiring", "light", "switch", "fuse"],
13
+ "Tutor": ["tutor", "teacher", "teacher", "teacher", "padhai", "math", "science", "english"],
14
+ "Beautician": ["beauty", "parlour", "makeup", "salon", "facial", "wax"],
15
+ "Carpenter": ["carpenter", "wood", "furniture", "darwaza", "door", "shelf"],
16
+ "Painter": ["paint", "rang", "wall", "colour", "color"],
17
+ "Driver": ["driver", "car", "ride", "airport", "drop", "pick"],
18
+ "Maid": ["maid", "cleaning", "sweep", "jharo", "safai", "cook"],
19
+ "Delivery Worker": ["delivery", "parcel", "courier", "deliver", "send"],
20
+ }
21
+
22
+ AREA_KEYWORDS = [
23
+ "G-13","G-11","G-10","G-9","G-6","G-7","G-8",
24
+ "F-10","F-7","F-6","F-8","F-11",
25
+ "E-11","E-7","I-8","I-10","I-9",
26
+ ]
27
+
28
+ TIME_KEYWORDS = {
29
+ "morning": ["subah", "morning", "صبح", "savere"],
30
+ "afternoon": ["dopahar", "afternoon", "دوپہر"],
31
+ "evening": ["sham", "evening", "شام", "shaam"],
32
+ "asap": ["aaj", "today", "abhi", "now", "jaldi", "asap", "فوری"],
33
+ "tomorrow": ["kal", "tomorrow", "کل"],
34
+ }
35
+
36
+ def rule_based_parse(message: str) -> dict:
37
+ msg = message.lower()
38
+
39
+ service = None
40
+ for svc, keywords in SERVICE_KEYWORDS.items():
41
+ if any(k in msg for k in keywords):
42
+ service = svc
43
+ break
44
+
45
+ location = None
46
+ for area in AREA_KEYWORDS:
47
+ if area.lower() in msg:
48
+ location = area
49
+ break
50
+
51
+ time_str = "tomorrow morning"
52
+ for label, keywords in TIME_KEYWORDS.items():
53
+ if any(k in msg for k in keywords):
54
+ time_str = label
55
+ break
56
+
57
+ lang = "roman_urdu"
58
+ urdu_chars = set("ابتثجحخدذرزسشصضطظعغفقکگلمنوہیآ")
59
+ if any(c in urdu_chars for c in message):
60
+ lang = "urdu"
61
+ elif all(ord(c) < 128 for c in message):
62
+ lang = "english" if re.search(r'\b(i|need|want|please|the|a|an)\b', msg) else "roman_urdu"
63
+
64
+ return {
65
+ "service_type": service,
66
+ "location": location or "G-13",
67
+ "time": time_str,
68
+ "language": lang,
69
+ "confidence": 0.75,
70
+ "mode": "rule_based_fallback",
71
+ }
72
+
73
+
74
+ def run(message: str) -> dict:
75
+ api_key = os.environ.get("GEMINI_API_KEY", "").strip()
76
+
77
+ # ── Try Gemini first ─────────────────────────────────────────
78
+ if api_key and api_key != "your_gemini_api_key_here":
79
+ try:
80
+ genai.configure(api_key=api_key)
81
+ model = genai.GenerativeModel("gemini-1.5-flash")
82
+
83
+ prompt = f"""You are a service request parser for Pakistan's informal economy.
84
+ Extract structured info from the user message. Respond ONLY with valid JSON, no markdown, no explanation.
85
+
86
+ User message: "{message}"
87
+
88
+ Return exactly this JSON:
89
+ {{
90
+ "service_type": "<one of: AC Technician, Plumber, Electrician, Tutor, Beautician, Carpenter, Painter, Driver, Maid, Delivery Worker>",
91
+ "location": "<area name like G-13, F-10, etc. Extract from message>",
92
+ "time": "<e.g. tomorrow morning, today evening, asap>",
93
+ "language": "<urdu | roman_urdu | english | mixed>",
94
+ "confidence": <0.0 to 1.0>,
95
+ "mode": "gemini"
96
+ }}
97
+ If a field cannot be determined use null."""
98
+
99
+ response = model.generate_content(prompt)
100
+ raw = response.text.strip()
101
+ raw = re.sub(r"```json|```", "", raw).strip()
102
+ result = json.loads(raw)
103
+ result["mode"] = "gemini"
104
+ return result
105
+
106
+ except Exception as e:
107
+ err = str(e)
108
+ # Key invalid → fall through to rule-based, don't crash
109
+ if "API_KEY_INVALID" in err or "API key not valid" in err:
110
+ result = rule_based_parse(message)
111
+ result["_warning"] = "Gemini API key invalid — using rule-based parser. Check HF Secrets."
112
+ return result
113
+ # Quota exceeded → same fallback
114
+ if "quota" in err.lower() or "429" in err:
115
+ result = rule_based_parse(message)
116
+ result["_warning"] = "Gemini quota exceeded — using rule-based parser."
117
+ return result
118
+ raise # re-raise unexpected errors
119
+
120
+ # ── No key set → rule-based ───────────────────────────────────
121
+ result = rule_based_parse(message)
122
+ result["_warning"] = "GEMINI_API_KEY not set — using rule-based parser (demo mode)."
123
+ return result