JerameeUC commited on
Commit
3a3f10b
·
1 Parent(s): 05645c6

added tabs to frontend by changing file to storefront_tabs_app.py

Browse files
Files changed (2) hide show
  1. README.md +1 -1
  2. storefront_tabs_app.py +225 -0
README.md CHANGED
@@ -5,7 +5,7 @@ colorFrom: indigo
5
  colorTo: blue
6
  sdk: gradio
7
  sdk_version: "4.38.0"
8
- app_file: storefront_app.py
9
  pinned: false
10
  license: mit
11
  short_description: Test for the project front-end.
 
5
  colorTo: blue
6
  sdk: gradio
7
  sdk_version: "4.38.0"
8
+ app_file: storefront_tabs_app.py
9
  pinned: false
10
  license: mit
11
  short_description: Test for the project front-end.
storefront_tabs_app.py ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, json
2
+ import gradio as gr
3
+ from transformers import pipeline
4
+
5
+ # ---------------- Model (same pipeline you used) ----------------
6
+ MODEL_NAME = os.getenv("HF_MODEL_GENERATION", "distilgpt2")
7
+ _pipe = None
8
+ def _get_pipe():
9
+ global _pipe
10
+ if _pipe is None:
11
+ _pipe = pipeline("text-generation", model=MODEL_NAME)
12
+ return _pipe
13
+
14
+ def model_generate(message, max_new_tokens=128, temperature=0.8, top_p=0.95):
15
+ out = _get_pipe()(
16
+ message,
17
+ max_new_tokens=int(max_new_tokens),
18
+ do_sample=True,
19
+ temperature=float(temperature),
20
+ top_p=float(top_p),
21
+ pad_token_id=50256,
22
+ )
23
+ return out[0]["generated_text"]
24
+
25
+
26
+ # ---------------- Storefront knowledge (helper module preferred) ----------------
27
+ STORE_DATA, USE_HELPERS = None, False
28
+ try:
29
+ # If you keep these under agenticcore/
30
+ from agenticcore.storefront_rules import (
31
+ load_storefront, answer_faq, get_parking_rules, get_venue_rules, search_products
32
+ )
33
+ STORE_DATA = load_storefront()
34
+ USE_HELPERS = True
35
+ except Exception:
36
+ # Fallback: look for JSON near this file or under agenticcore/
37
+ for p in [
38
+ os.path.join(os.path.dirname(__file__), "storefront_data.json"),
39
+ os.path.join(os.path.dirname(__file__), "agenticcore", "storefront_data.json"),
40
+ ]:
41
+ if os.path.exists(p):
42
+ with open(p, "r", encoding="utf-8") as f:
43
+ STORE_DATA = json.load(f)
44
+ break
45
+
46
+ # Defaults if JSON is missing
47
+ DEFAULT_PRODUCTS = [
48
+ {"SKU": "CG-SET", "Name": "Cap & Gown Set", "Price": 59.00, "Notes": "Tassel included; ship until 10 days before event"},
49
+ {"SKU": "PK-1", "Name": "Parking Pass", "Price": 10.00, "Notes": "Multiple passes allowed per student"},
50
+ ]
51
+ DEFAULT_PARKING = ["No double parking.", "Vehicles parked in handicap will be towed."]
52
+ DEFAULT_VENUE = ["Formal attire recommended (not required).", "No muscle shirts.", "No sagging pants."]
53
+
54
+ if STORE_DATA:
55
+ try:
56
+ DEFAULT_PRODUCTS = [{
57
+ "SKU": p.get("sku",""),
58
+ "Name": p.get("name",""),
59
+ "Price": p.get("price_usd",""),
60
+ "Notes": (p.get("description") or "")[:120],
61
+ } for p in STORE_DATA.get("products", [])]
62
+ DEFAULT_PARKING = STORE_DATA.get("policies", {}).get("parking_rules", DEFAULT_PARKING)
63
+ DEFAULT_VENUE = STORE_DATA.get("policies", {}).get("venue_rules", DEFAULT_VENUE)
64
+ except Exception:
65
+ pass
66
+
67
+
68
+ # ---------------- Routing: storefront first, then LLM ----------------
69
+ def storefront_qna(text: str) -> str | None:
70
+ t = (text or "").lower().strip()
71
+ if not t:
72
+ return None
73
+
74
+ # Prefer your helper functions if available
75
+ if USE_HELPERS and STORE_DATA:
76
+ a = answer_faq(STORE_DATA, t)
77
+ if a:
78
+ return a
79
+ if "parking" in t and "rule" in t:
80
+ r = get_parking_rules(STORE_DATA)
81
+ if r:
82
+ return "Parking rules:\n- " + "\n- ".join(r)
83
+ if "venue" in t and "rule" in t or "attire" in t or "dress code" in t:
84
+ r = get_venue_rules(STORE_DATA)
85
+ if r:
86
+ return "Venue rules:\n- " + "\n- ".join(r)
87
+ # Extra: arrival timing for parking lots
88
+ if "parking" in t and ("hours" in t or "time" in t):
89
+ return "Parking lots open 2 hours before the ceremony."
90
+ hits = search_products(STORE_DATA, t)
91
+ if hits:
92
+ return "\n".join(
93
+ f"{p.get('name','Item')} — ${p.get('price_usd',0):.2f}: {p.get('description','')}"
94
+ for p in hits
95
+ )
96
+ return None
97
+
98
+ # Fallback rules (no helper module)
99
+ if "parking" in t and ("multiple" in t or "more than one" in t or "extra" in t):
100
+ return "Yes, multiple parking passes are allowed per student."
101
+ if "parking" in t and "rule" in t:
102
+ return "Parking rules:\n- " + "\n- ".join(DEFAULT_PARKING)
103
+ if "parking" in t and ("hours" in t or "time" in t):
104
+ return "Parking lots open 2 hours before the ceremony."
105
+ if "attire" in t or "dress code" in t or ("venue" in t and "rule" in t):
106
+ return "Venue rules:\n- " + "\n- ".join(DEFAULT_VENUE)
107
+ if "cap" in t or "gown" in t:
108
+ return "\n".join(f"{p['Name']} — ${p['Price']:.2f}: {p['Notes']}" for p in DEFAULT_PRODUCTS)
109
+ return None
110
+
111
+
112
+ def chat_pipeline(message, max_new_tokens=128, temperature=0.8, top_p=0.95):
113
+ """Intercept storefront topics first; else generate with the model."""
114
+ sf = storefront_qna(message)
115
+ if sf:
116
+ return sf
117
+ return model_generate(message, max_new_tokens, temperature, top_p)
118
+
119
+
120
+ # ---------------- Gradio UI (Tabs + Accordion) ----------------
121
+ CSS = """
122
+ :root { --bg:#0b0d12; --panel:#0f172a; --border:#1f2940; --text:#e5e7eb; --muted:#9ca3af; }
123
+ .gradio-container { background: var(--bg) !important; color: var(--text) !important; }
124
+ .panel { border:1px solid var(--border); border-radius:16px; background:var(--panel); }
125
+ .small { font-size:12px; color: var(--muted); }
126
+ """
127
+
128
+ with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
129
+ gr.Markdown("## Storefront Chat")
130
+
131
+ with gr.Tabs():
132
+ # --- TAB 1: Chat (sliders tucked away) ---
133
+ with gr.TabItem("Chat"):
134
+ with gr.Group(elem_classes=["panel"]):
135
+ chat = gr.Chatbot(height=360, bubble_full_width=False, label="Chat")
136
+ with gr.Row():
137
+ msg = gr.Textbox(placeholder="Ask about parking rules, attire, cap & gown, pickup times…", scale=5)
138
+ send = gr.Button("Send", scale=1)
139
+
140
+ # Quick chips
141
+ with gr.Row():
142
+ chip1 = gr.Button("Parking rules", variant="secondary")
143
+ chip2 = gr.Button("Multiple passes", variant="secondary")
144
+ chip3 = gr.Button("Attire", variant="secondary")
145
+ chip4 = gr.Button("When do lots open?", variant="secondary")
146
+
147
+ # Advanced chat options in an Accordion
148
+ with gr.Accordion("Advanced chat options", open=False):
149
+ max_new = gr.Slider(32, 512, 128, 1, label="Max new tokens")
150
+ temp = gr.Slider(0.1, 1.5, 0.8, 0.05, label="Temperature")
151
+ topp = gr.Slider(0.1, 1.0, 0.95, 0.05, label="Top-p")
152
+
153
+ # Simple health & capabilities as small buttons
154
+ with gr.Row():
155
+ health_btn = gr.Button("Health", variant="secondary")
156
+ caps_btn = gr.Button("Capabilities", variant="secondary")
157
+ status_md = gr.Markdown("Status: not checked", elem_classes=["small"])
158
+
159
+ # --- TAB 2: Products ---
160
+ with gr.TabItem("Products"):
161
+ gr.Markdown("### Available Items")
162
+ cols = list(DEFAULT_PRODUCTS[0].keys()) if DEFAULT_PRODUCTS else ["SKU","Name","Price","Notes"]
163
+ data = [[p.get(c,"") for c in cols] for p in DEFAULT_PRODUCTS]
164
+ products_tbl = gr.Dataframe(headers=cols, value=data, interactive=False, wrap=True, label="Products")
165
+
166
+ # --- TAB 3: Rules ---
167
+ with gr.TabItem("Rules"):
168
+ gr.Markdown("### Venue rules")
169
+ gr.Markdown("- " + "\n- ".join(DEFAULT_VENUE))
170
+ gr.Markdown("### Parking rules")
171
+ gr.Markdown("- " + "\n- ".join(DEFAULT_PARKING))
172
+
173
+ # --- TAB 4: Logistics ---
174
+ with gr.TabItem("Logistics"):
175
+ gr.Markdown(
176
+ "### Event Logistics\n"
177
+ "- Shipping available until 10 days before event (typ. 3–5 business days)\n"
178
+ "- Pickup: Student Center Bookstore during the week prior to event\n"
179
+ "- Graduates arrive 90 minutes early; guests 60 minutes early\n"
180
+ "- Lots A & B open 2 hours before; overflow as needed\n"
181
+ "\n*Try asking the bot:* “What time should I arrive?” • “Where do I pick up the gown?”"
182
+ )
183
+
184
+ # ---- Wiring ----
185
+ def on_send(history, message, max_new_tokens, temperature, top_p):
186
+ t = (message or "").strip()
187
+ if not t:
188
+ return history, ""
189
+ history = history + [[t, None]]
190
+ reply = chat_pipeline(t, max_new_tokens, temperature, top_p)
191
+ history[-1][1] = reply
192
+ return history, ""
193
+
194
+ send.click(on_send, [chat, msg, max_new, temp, topp], [chat, msg])
195
+ msg.submit(on_send, [chat, msg, max_new, temp, topp], [chat, msg])
196
+
197
+ # Quick chips → prefill textbox
198
+ chip1.click(lambda: "What are the parking rules?", outputs=msg)
199
+ chip2.click(lambda: "Can I buy multiple parking passes?", outputs=msg)
200
+ chip3.click(lambda: "Is formal attire required?", outputs=msg)
201
+ chip4.click(lambda: "What time do the parking lots open?", outputs=msg)
202
+
203
+ # Health / capabilities
204
+ def ui_health_check():
205
+ return (f"### Status: ✅ Healthy\n"
206
+ f"- Model: `{MODEL_NAME}`\n"
207
+ f"- Storefront module: {'yes' if USE_HELPERS else 'no'}\n"
208
+ f"- Storefront JSON: {'loaded' if bool(STORE_DATA) else 'not found'}")
209
+
210
+ def ui_capabilities():
211
+ caps = [
212
+ "Chat (LLM text-generation)",
213
+ "Storefront Q&A (parking, attire, products, logistics)",
214
+ "Adjustable: max_new_tokens, temperature, top-p",
215
+ ]
216
+ return "### Capabilities\n- " + "\n- ".join(caps)
217
+
218
+ def _health():
219
+ return ui_health_check(), "Status: ✅ Healthy"
220
+
221
+ health_btn.click(_health, outputs=[chat, status_md])
222
+ caps_btn.click(ui_capabilities, outputs=chat)
223
+
224
+ if __name__ == "__main__":
225
+ demo.launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860")))