Spaces:
Sleeping
Sleeping
cmgh
Browse files
app.py
CHANGED
|
@@ -21,10 +21,6 @@ def save_msg(user: str, text: str, role: str = "assistant") -> None:
|
|
| 21 |
REPLY: Dict[str, str] = {}
|
| 22 |
|
| 23 |
def add(k: str, v: str) -> None:
|
| 24 |
-
"""
|
| 25 |
-
Normalizes keys ONCE at insertion.
|
| 26 |
-
Makes lookups O(1) without re-normalizing every time.
|
| 27 |
-
"""
|
| 28 |
norm = normalize(k)
|
| 29 |
REPLY[norm] = v
|
| 30 |
|
|
@@ -35,56 +31,51 @@ def add(k: str, v: str) -> None:
|
|
| 35 |
_rx_clean = re.compile(r"[^a-z0-9+]+") # compiled once
|
| 36 |
|
| 37 |
def normalize(text: str) -> str:
|
| 38 |
-
"""
|
| 39 |
-
All keys and messages pass through the exact same normalizer.
|
| 40 |
-
Clean, strip, collapse spaces, lowercase.
|
| 41 |
-
"""
|
| 42 |
return _rx_clean.sub(" ", text.lower()).strip()
|
| 43 |
|
| 44 |
|
| 45 |
# ==========================================================
|
| 46 |
# DATA (unchanged)
|
| 47 |
# ==========================================================
|
| 48 |
-
# Your ADD entries EXACTLY preserved:
|
| 49 |
add("line array", "Line-array-top: KES 4 k / day per unit.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC.\nOr grab our 4-tops-2-subs combo: KES 22 k / day β save cash.")
|
| 50 |
-
add("moving head", "Moving-head-light: KES 3 k / day per unit..
|
| 51 |
-
add("parcan light", "Parcan-light: KES 1.5 k / day per unit..
|
| 52 |
-
add("led screen panel", "LED-screen-panel: KES 2.2 k / day per panel.
|
| 53 |
-
add("double 18 sub", "Double-18 sub: KES 4 k / day per sub...")
|
| 54 |
-
add("single 18 sub", "Single-18 sub: KES 3 k / day per sub..
|
| 55 |
-
add("monitor speaker", "Monitor-speaker: KES 2 k / day per monitor..
|
| 56 |
-
add("cordless mic", "Cordless-mic: KES 2 k / day per mic..
|
| 57 |
-
add("a frame tent", "A-frame-tent: KES 30 k / day (100 guests)..
|
| 58 |
-
add("dome tent", "Dome-tent: KES 45 k / day (200 guests)..
|
| 59 |
-
add("clear span tent", "Clear-span-tent: KES 80 k / day (500 guests)..
|
| 60 |
-
add("stage 8x4", "Stage 8Γ4: KES 15 k / day..
|
| 61 |
-
add("stage 12x6", "Stage 12Γ6: KES 25 k / day..
|
| 62 |
-
add("stage 16x8", "Stage 16Γ8: KES 40 k / day..
|
| 63 |
-
add("dj console", "DJ-console: KES 25 k / 6 hrs..
|
| 64 |
-
add("mc service", "MC-service: KES 15 k / event..
|
| 65 |
-
add("live band", "Live-band: KES 55 k / 2 sets..
|
| 66 |
-
add("photography 8h", "Photography-8h: KES 25 k..
|
| 67 |
-
add("videography 4k", "Videography-4K: KES 45 k..
|
| 68 |
-
add("drone 2h", "Drone-2h: KES 10 k..
|
| 69 |
-
|
| 70 |
-
#
|
| 71 |
-
add("bronze package", "LD Bronze Package: KES 150 kβ200 k..
|
| 72 |
-
add("silver package", "LD Silver Package: KES 350 kβ450 k..
|
| 73 |
-
add("gold package", "LD Gold Package: KES 650 kβ850 k..
|
| 74 |
-
add("platinum package", "LD Platinum Package: KES 1.2 Mβ1.8 M..
|
| 75 |
-
|
| 76 |
-
#
|
| 77 |
-
add("4 tops 2 subs combo", "4-tops-2-subs combo: KES 22 k / day..
|
| 78 |
-
add("6 tops 4 subs combo", "6-tops-4-subs combo: KES 36 k / day..
|
| 79 |
-
add("wedding combo", "Wedding-combo: KES 28 k / day..
|
| 80 |
-
add("corporate combo", "Corporate-combo: KES 18 k / day..
|
| 81 |
-
|
| 82 |
-
#
|
| 83 |
add("ld+weekend+urgency", "Only 2 silver packages left this weekend β lock it.")
|
| 84 |
add("ld+tomorrow+urgency", "Tomorrow still possible β reserve within 2 hrs.")
|
| 85 |
add("ld+location+checkout", "LD Events yard: Utawala, Githunguri β weekdays 9-5, free sound-check demo.")
|
| 86 |
|
| 87 |
-
#
|
| 88 |
add("ld+pay+today", "Pay via MPESA 0757-299-299 (name: LD Events). Send code to this chat for instant confirmation.")
|
| 89 |
add("ld+deposit", "50 % deposit to MPESA 0757-299-299 β balance on delivery. Forward the code to lock.")
|
| 90 |
add("ld+paid", "β
Deposit received β gear locked! Run-sheet coming shortly.")
|
|
@@ -97,45 +88,55 @@ add("ld+receipt", "Forward MPESA message β weβll confirm instantly.")
|
|
| 97 |
GEAR_WORDS = (
|
| 98 |
"ld", "event", "sound", "light", "tent", "stage", "speaker",
|
| 99 |
"mic", "wedding", "concert", "dj", "led", "screen", "decor",
|
| 100 |
-
"carpet", "line array", "array", "sub", "woofer", "mixer"
|
| 101 |
)
|
| 102 |
|
| 103 |
CONSTRUCTION_WORDS = (
|
| 104 |
"lamaki", "construction", "renovation", "build", "house",
|
| 105 |
"kitchen", "bathroom", "roofing", "interior", "cabinet",
|
| 106 |
-
"solar", "cctv", "smart", "gate", "plumbing", "tiling"
|
| 107 |
)
|
| 108 |
|
| 109 |
BILLING_WORDS = ("pay", "mpesa", "deposit", "book", "reserve", "send", "lock")
|
| 110 |
|
|
|
|
|
|
|
| 111 |
|
| 112 |
def secretary_reply(text: str) -> str:
|
| 113 |
t = normalize(text)
|
| 114 |
|
| 115 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
if t in REPLY:
|
| 117 |
return REPLY[t]
|
| 118 |
|
| 119 |
-
# 2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
if any(w in t for w in GEAR_WORDS):
|
| 121 |
-
# find closest relevant key
|
| 122 |
for k in REPLY:
|
| 123 |
if any(w in k for w in ("line array", "moving head", "led screen", "sub", "tent", "stage", "dj", "mic")):
|
| 124 |
return REPLY[k]
|
| 125 |
return "We have full event packages β tell me the item or package you need and Iβll quote instantly."
|
| 126 |
|
| 127 |
-
#
|
| 128 |
if any(w in t for w in CONSTRUCTION_WORDS):
|
| 129 |
return "We have full remodelling packages β tell me the service you need and Iβll quote instantly."
|
| 130 |
|
| 131 |
-
#
|
| 132 |
if any(w in t for w in BILLING_WORDS):
|
| 133 |
if "ld" in t:
|
| 134 |
return "Pay via MPESA 0757-299-299 (name: LD Events). Send code for instant confirmation."
|
| 135 |
if "lamaki" in t:
|
| 136 |
return "Pay via MPESA 0757-299-299 (name: Lamaki Designs). Send code for instant confirmation."
|
| 137 |
|
| 138 |
-
#
|
| 139 |
return "How may I help you today? (Type *LD* for events or *LAMAKI* for construction)"
|
| 140 |
|
| 141 |
|
|
@@ -169,3 +170,4 @@ def health():
|
|
| 169 |
|
| 170 |
if __name__ == "__main__":
|
| 171 |
app.run(host="0.0.0.0", port=7860, threaded=True)
|
|
|
|
|
|
| 21 |
REPLY: Dict[str, str] = {}
|
| 22 |
|
| 23 |
def add(k: str, v: str) -> None:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
norm = normalize(k)
|
| 25 |
REPLY[norm] = v
|
| 26 |
|
|
|
|
| 31 |
_rx_clean = re.compile(r"[^a-z0-9+]+") # compiled once
|
| 32 |
|
| 33 |
def normalize(text: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
return _rx_clean.sub(" ", text.lower()).strip()
|
| 35 |
|
| 36 |
|
| 37 |
# ==========================================================
|
| 38 |
# DATA (unchanged)
|
| 39 |
# ==========================================================
|
|
|
|
| 40 |
add("line array", "Line-array-top: KES 4 k / day per unit.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC.\nOr grab our 4-tops-2-subs combo: KES 22 k / day β save cash.")
|
| 41 |
+
add("moving head", "Moving-head-light: KES 3 k / day per unit.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes LED wash, 2 monitors, 2 pairs cordless mics, tent, stage, DJ, MC.\nOr grab our wedding combo: KES 28 k / day β save cash.")
|
| 42 |
+
add("parcan light", "Parcan-light: KES 1.5 k / day per unit.\nWe have the LD Bronze Package (KES 150 kβ200 k) that includes basic lights, 4 loud-speakers, mixer, 1 cordless mic, tent, stage.")
|
| 43 |
+
add("led screen panel", "LED-screen-panel: KES 2.2 k / day per panel.\nWe have the LD Gold Package (KES 650 kβ850 k) that includes 3Γ2 m LED wall, 4 line-array tops, 4 double-18 subs, amp rack, 4 monitors, 6 pairs cordless mics, snake, tent, stage, DJ, MC, photo, video.")
|
| 44 |
+
add("double 18 sub", "Double-18 sub: KES 4 k / day per sub.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes 2 single-18 subs, 3 line-array tops, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC.\nOr grab our 4-tops-2-subs combo: KES 22 k / day β save cash.")
|
| 45 |
+
add("single 18 sub", "Single-18 sub: KES 3 k / day per sub.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes 2 single-18 subs, 3 line-array tops, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC.")
|
| 46 |
+
add("monitor speaker", "Monitor-speaker: KES 2 k / day per monitor.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes 2 monitors, 3 line-array tops, 2 single-18 subs, digital mixer, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC.")
|
| 47 |
+
add("cordless mic", "Cordless-mic: KES 2 k / day per mic.\nWe have the LD Bronze Package (KES 150 kβ200 k) that includes 1 cordless mic, 4 loud-speakers, mixer, amplifier, basic lights, tent, stage.")
|
| 48 |
+
add("a frame tent", "A-frame-tent: KES 30 k / day (100 guests).\nWe have the LD Bronze Package (KES 150 kβ200 k) that includes A-frame tent, 4 loud-speakers, mixer, 1 cordless mic, basic lights, stage.")
|
| 49 |
+
add("dome tent", "Dome-tent: KES 45 k / day (200 guests).\nWe have the LD Silver Package (KES 350 kβ450 k) that includes dome tent, 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, stage, DJ, MC.")
|
| 50 |
+
add("clear span tent", "Clear-span-tent: KES 80 k / day (500 guests).\nWe have the LD Gold Package (KES 650 kβ850 k) that includes clear-span tent, 4 line-array tops, 4 double-18 subs, amp rack, 4 monitors, 6 pairs cordless mics, LED wall, snake, stage, DJ, MC, photo, video.")
|
| 51 |
+
add("stage 8x4", "Stage 8Γ4: KES 15 k / day.\nWe have the LD Bronze Package (KES 150 kβ200 k) that includes 8Γ4 stage, 4 loud-speakers, mixer, 1 cordless mic, basic lights, tent.")
|
| 52 |
+
add("stage 12x6", "Stage 12Γ6: KES 25 k / day.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes 12Γ6 stage, 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, DJ, MC.")
|
| 53 |
+
add("stage 16x8", "Stage 16Γ8: KES 40 k / day.\nWe have the LD Gold Package (KES 650 kβ850 k) that includes 16Γ8 stage, 4 line-array tops, 4 double-18 subs, amp rack, 4 monitors, 6 pairs cordless mics, LED wall, snake, tent, DJ, MC, photo, video.")
|
| 54 |
+
add("dj console", "DJ-console: KES 25 k / 6 hrs.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes DJ console, 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, MC.")
|
| 55 |
+
add("mc service", "MC-service: KES 15 k / event.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes MC service, 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ.")
|
| 56 |
+
add("live band", "Live-band: KES 55 k / 2 sets.\nWe have the LD Gold Package (KES 650 kβ850 k) that includes live band, 4 line-array tops, 4 double-18 subs, amp rack, 4 monitors, 6 pairs cordless mics, LED wall, snake, tent, stage, DJ, MC, photo, video.")
|
| 57 |
+
add("photography 8h", "Photography-8h: KES 25 k.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes photography, 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC.")
|
| 58 |
+
add("videography 4k", "Videography-4K: KES 45 k.\nWe have the LD Gold Package (KES 650 kβ850 k) that includes 4K video, 4 line-array tops, 4 double-18 subs, amp rack, 4 monitors, 6 pairs cordless mics, LED wall, snake, tent, stage, DJ, MC, photo.")
|
| 59 |
+
add("drone 2h", "Drone-2h: KES 10 k.\nWe have the LD Silver Package (KES 350 kβ450 k) that includes drone, 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, tent, stage, DJ, MC, photo.")
|
| 60 |
+
|
| 61 |
+
# Packages
|
| 62 |
+
add("bronze package", "LD Bronze Package: KES 150 kβ200 k for 50β150 guests.\nKit: 4 loud-speakers+stands, 1 mixer, 1 amplifier, 1 cordless mic, basic lights, A-frame tent, 8Γ4 stage.")
|
| 63 |
+
add("silver package", "LD Silver Package: KES 350 kβ450 k for 150β300 guests.\nKit: 3 line-array tops, 2 single-18 subs, digital mixer, 2 monitors, 2 pairs cordless mics, LED wash, dome tent, 12Γ6 stage, DJ, MC.")
|
| 64 |
+
add("gold package", "LD Gold Package: KES 650 kβ850 k for 300β800 guests.\nKit: 4 line-array tops, 4 double-18 subs, amp rack, 4 monitors, 6 pairs cordless mics, LED wall 3Γ2 m, snake, clear-span tent, 16Γ8 stage, DJ, MC, photo, video.")
|
| 65 |
+
add("platinum package", "LD Platinum Package: KES 1.2 Mβ1.8 M for 800β2000 guests.\nKit: 8 line-array tops, 6 double-18 subs, delay towers, 8 monitors, 8 pairs cordless mics, LED wall 6Γ3 m, full lighting, live-stream, clear-span tent, 16Γ8 stage, DJ, MC, photo, video, drone.")
|
| 66 |
+
|
| 67 |
+
# Combos
|
| 68 |
+
add("4 tops 2 subs combo", "4-tops-2-subs combo: KES 22 k / day.\nKit: 4Γ line-array tops + 2Γ double-18 subs + digital mixer + 2Γ monitors + 4Γ cordless mics.")
|
| 69 |
+
add("6 tops 4 subs combo", "6-tops-4-subs combo: KES 36 k / day.\nKit: 6Γ line-array tops + 4Γ double-18 subs + amp rack + 4Γ monitors + 6Γ cordless mics + snake.")
|
| 70 |
+
add("wedding combo", "Wedding-combo: KES 28 k / day.\nKit: 2Γ line-array tops + 1Γ double-18 sub + 2Γ monitors + 2Γ cordless mics + DJ console + fairy-light backdrop.")
|
| 71 |
+
add("corporate combo", "Corporate-combo: KES 18 k / day.\nKit: 2Γ line-array tops + 1Γ single-18 sub + 2Γ monitors + 2Γ cordless mics + projector + screen.")
|
| 72 |
+
|
| 73 |
+
# Special intents
|
| 74 |
add("ld+weekend+urgency", "Only 2 silver packages left this weekend β lock it.")
|
| 75 |
add("ld+tomorrow+urgency", "Tomorrow still possible β reserve within 2 hrs.")
|
| 76 |
add("ld+location+checkout", "LD Events yard: Utawala, Githunguri β weekdays 9-5, free sound-check demo.")
|
| 77 |
|
| 78 |
+
# Billing
|
| 79 |
add("ld+pay+today", "Pay via MPESA 0757-299-299 (name: LD Events). Send code to this chat for instant confirmation.")
|
| 80 |
add("ld+deposit", "50 % deposit to MPESA 0757-299-299 β balance on delivery. Forward the code to lock.")
|
| 81 |
add("ld+paid", "β
Deposit received β gear locked! Run-sheet coming shortly.")
|
|
|
|
| 88 |
GEAR_WORDS = (
|
| 89 |
"ld", "event", "sound", "light", "tent", "stage", "speaker",
|
| 90 |
"mic", "wedding", "concert", "dj", "led", "screen", "decor",
|
| 91 |
+
"carpet", "line array", "array", "sub", "woofer", "mixer"
|
| 92 |
)
|
| 93 |
|
| 94 |
CONSTRUCTION_WORDS = (
|
| 95 |
"lamaki", "construction", "renovation", "build", "house",
|
| 96 |
"kitchen", "bathroom", "roofing", "interior", "cabinet",
|
| 97 |
+
"solar", "cctv", "smart", "gate", "plumbing", "tiling"
|
| 98 |
)
|
| 99 |
|
| 100 |
BILLING_WORDS = ("pay", "mpesa", "deposit", "book", "reserve", "send", "lock")
|
| 101 |
|
| 102 |
+
GREETINGS = ("hello", "hi", "hey", "greetings", "morning", "evening")
|
| 103 |
+
|
| 104 |
|
| 105 |
def secretary_reply(text: str) -> str:
|
| 106 |
t = normalize(text)
|
| 107 |
|
| 108 |
+
# --- 0. GREETING HANDLER ---
|
| 109 |
+
if any(g in t for g in GREETINGS):
|
| 110 |
+
return "Hello! How may I assist you today? Tell me the item, service, or package you want."
|
| 111 |
+
|
| 112 |
+
# --- 1. EXACT LOOKUP ---
|
| 113 |
if t in REPLY:
|
| 114 |
return REPLY[t]
|
| 115 |
|
| 116 |
+
# --- 2. PARTIAL KEY MATCH ---
|
| 117 |
+
for k in REPLY:
|
| 118 |
+
if k in t:
|
| 119 |
+
return REPLY[k]
|
| 120 |
+
|
| 121 |
+
# --- 3. GEAR CONTEXT ---
|
| 122 |
if any(w in t for w in GEAR_WORDS):
|
|
|
|
| 123 |
for k in REPLY:
|
| 124 |
if any(w in k for w in ("line array", "moving head", "led screen", "sub", "tent", "stage", "dj", "mic")):
|
| 125 |
return REPLY[k]
|
| 126 |
return "We have full event packages β tell me the item or package you need and Iβll quote instantly."
|
| 127 |
|
| 128 |
+
# --- 4. CONSTRUCTION CONTEXT ---
|
| 129 |
if any(w in t for w in CONSTRUCTION_WORDS):
|
| 130 |
return "We have full remodelling packages β tell me the service you need and Iβll quote instantly."
|
| 131 |
|
| 132 |
+
# --- 5. BILLING ---
|
| 133 |
if any(w in t for w in BILLING_WORDS):
|
| 134 |
if "ld" in t:
|
| 135 |
return "Pay via MPESA 0757-299-299 (name: LD Events). Send code for instant confirmation."
|
| 136 |
if "lamaki" in t:
|
| 137 |
return "Pay via MPESA 0757-299-299 (name: Lamaki Designs). Send code for instant confirmation."
|
| 138 |
|
| 139 |
+
# --- 6. FALLBACK ---
|
| 140 |
return "How may I help you today? (Type *LD* for events or *LAMAKI* for construction)"
|
| 141 |
|
| 142 |
|
|
|
|
| 170 |
|
| 171 |
if __name__ == "__main__":
|
| 172 |
app.run(host="0.0.0.0", port=7860, threaded=True)
|
| 173 |
+
|