JerameeUC commited on
Commit
647032a
·
1 Parent(s): eedb2c4

Fixed what I broke

Browse files
Files changed (1) hide show
  1. app_storefront.py +71 -24
app_storefront.py CHANGED
@@ -1,20 +1,52 @@
1
  # app_storefront.py
2
  import os
 
3
  import gradio as gr
4
 
5
- from model_core import model_generate, MODEL_NAME
6
- from data_storefront import (
7
- DEFAULT_PRODUCTS, DEFAULT_PARKING, DEFAULT_VENUE,
8
- STORE_DATA, USE_HELPERS
 
 
 
 
 
 
 
 
 
 
 
 
9
  )
10
- from qna_router import storefront_qna
11
- from memory_core import build_prompt_from_history, clean_generation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  # ---------------- Chat logic ----------------
14
  def chat_pipeline(history, message, max_new_tokens=128, temperature=0.8, top_p=0.95):
 
15
  sf = storefront_qna(message)
16
  if sf:
17
  return sf
 
18
  prompt = build_prompt_from_history(history, message, k=4)
19
  gen = model_generate(prompt, max_new_tokens, temperature, top_p)
20
  return clean_generation(gen)
@@ -30,26 +62,34 @@ CSS = """
30
  with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
31
  gr.Markdown("## Storefront Chat")
32
 
33
- # One state object that mirrors the Chatbot value
34
  history_state = gr.State([])
35
 
36
  with gr.Tabs():
37
- # --- Chat tab ---
38
  with gr.TabItem("Chat"):
39
  with gr.Group(elem_classes=["panel"]):
40
- chat = gr.Chatbot(height=360, bubble_full_width=False, label="Chat")
 
 
 
 
41
 
42
  with gr.Row():
43
- msg = gr.Textbox(placeholder="Ask about parking rules, attire, cap & gown, pickup times…", scale=5)
 
 
 
44
  send = gr.Button("Send", scale=1)
45
 
 
46
  with gr.Row():
47
  chip1 = gr.Button("Parking rules", variant="secondary")
48
  chip2 = gr.Button("Multiple passes", variant="secondary")
49
  chip3 = gr.Button("Attire", variant="secondary")
50
  chip4 = gr.Button("When do lots open?", variant="secondary")
51
 
52
- # Advanced area (sliders + health/capabilities) — off the main screen
53
  with gr.Accordion("Advanced chat options", open=False):
54
  max_new = gr.Slider(32, 512, 128, 1, label="Max new tokens")
55
  temp = gr.Slider(0.1, 1.5, 0.8, 0.05, label="Temperature")
@@ -60,21 +100,21 @@ with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
60
  caps_btn = gr.Button("Capabilities", variant="secondary")
61
  status_md = gr.Markdown("Status: not checked", elem_classes=["small"])
62
 
63
- # --- Products tab ---
64
  with gr.TabItem("Products"):
65
  gr.Markdown("### Available Items")
66
  cols = list(DEFAULT_PRODUCTS[0].keys()) if DEFAULT_PRODUCTS else ["SKU","Name","Price","Notes"]
67
- data = [[p.get(c,"") for c in cols] for p in DEFAULT_PRODUCTS]
68
  gr.Dataframe(headers=cols, value=data, interactive=False, wrap=True, label="Products")
69
 
70
- # --- Rules tab ---
71
  with gr.TabItem("Rules"):
72
  gr.Markdown("### Venue rules")
73
  gr.Markdown("- " + "\n- ".join(DEFAULT_VENUE))
74
  gr.Markdown("### Parking rules")
75
  gr.Markdown("- " + "\n- ".join(DEFAULT_PARKING))
76
 
77
- # --- Logistics tab ---
78
  with gr.TabItem("Logistics"):
79
  gr.Markdown(
80
  "### Event Logistics\n"
@@ -85,8 +125,9 @@ with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
85
  "\n*Try asking the bot:* “What time should I arrive?” • “Where do I pick up the gown?”"
86
  )
87
 
88
- # ---------- Helpers that keep Chatbot history valid ----------
89
  def _append_bot_md(history, md_text):
 
90
  history = history or []
91
  return history + [[None, md_text]]
92
 
@@ -94,18 +135,24 @@ with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
94
  def on_send(history, message, max_new_tokens, temperature, top_p):
95
  t = (message or "").strip()
96
  if not t:
97
- return history, history, "" # no-op
 
98
  history = (history or []) + [[t, None]]
 
99
  reply = chat_pipeline(history[:-1], t, max_new_tokens, temperature, top_p)
100
  history[-1][1] = reply
 
101
  return history, history, ""
102
 
103
  def _health_cb(history):
104
- md = (f"### Status: ✅ Healthy\n"
105
- f"- Model: `{MODEL_NAME}`\n"
106
- f"- Storefront module: {'yes' if USE_HELPERS else 'no'}\n"
107
- f"- Storefront JSON: {'loaded' if bool(STORE_DATA) else 'not found'}")
 
 
108
  new_hist = _append_bot_md(history, md)
 
109
  return new_hist, new_hist, "Status: ✅ Healthy"
110
 
111
  def _caps_cb(history):
@@ -118,17 +165,17 @@ with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
118
  new_hist = _append_bot_md(history, md)
119
  return new_hist, new_hist
120
 
121
- # Wire up (update both state and Chatbot)
122
  send.click(on_send, [history_state, msg, max_new, temp, topp], [history_state, chat, msg])
123
  msg.submit(on_send, [history_state, msg, max_new, temp, topp], [history_state, chat, msg])
124
 
125
- # Chips
126
  chip1.click(lambda: "What are the parking rules?", outputs=msg)
127
  chip2.click(lambda: "Can I buy multiple parking passes?", outputs=msg)
128
  chip3.click(lambda: "Is formal attire required?", outputs=msg)
129
  chip4.click(lambda: "What time do the parking lots open?", outputs=msg)
130
 
131
- # Health / Capabilities (now inside the Advanced accordion)
132
  health_btn.click(_health_cb, inputs=[history_state], outputs=[history_state, chat, status_md])
133
  caps_btn.click(_caps_cb, inputs=[history_state], outputs=[history_state, chat])
134
 
 
1
  # app_storefront.py
2
  import os
3
+ import sys
4
  import gradio as gr
5
 
6
+ # Make "core/" importable even on Spaces
7
+ sys.path.append(os.path.join(os.path.dirname(__file__), "core"))
8
+
9
+ # --- New modules ---
10
+ from core.model import model_generate, MODEL_NAME
11
+ from core.memory import build_prompt_from_history
12
+ from core.storefront import (
13
+ load_storefront,
14
+ storefront_qna,
15
+ extract_products,
16
+ get_rules,
17
+ DEFAULT_PRODUCTS as CORE_DEFAULT_PRODUCTS,
18
+ DEFAULT_PARKING as CORE_DEFAULT_PARKING,
19
+ DEFAULT_VENUE as CORE_DEFAULT_VENUE,
20
+ USE_HELPERS,
21
+ STORE_DATA,
22
  )
23
+
24
+ # ---------------- Data for tabs (safe fallbacks) ----------------
25
+ # Try to load JSON data; if not available, use module defaults.
26
+ _loaded = load_storefront() # may be None if JSON absent/empty
27
+ if _loaded:
28
+ PRODUCTS = extract_products(_loaded) or CORE_DEFAULT_PRODUCTS
29
+ RULES = get_rules(_loaded) or {"venue": CORE_DEFAULT_VENUE, "parking": CORE_DEFAULT_PARKING}
30
+ else:
31
+ PRODUCTS = CORE_DEFAULT_PRODUCTS
32
+ RULES = {"venue": CORE_DEFAULT_VENUE, "parking": CORE_DEFAULT_PARKING}
33
+
34
+ DEFAULT_PRODUCTS = PRODUCTS
35
+ DEFAULT_VENUE = RULES.get("venue", CORE_DEFAULT_VENUE)
36
+ DEFAULT_PARKING = RULES.get("parking", CORE_DEFAULT_PARKING)
37
+
38
+ # ---------------- Utilities ----------------
39
+ def clean_generation(text: str) -> str:
40
+ """Tiny post-process to strip runaway prefixes or trailing artifacts."""
41
+ return (text or "").strip()
42
 
43
  # ---------------- Chat logic ----------------
44
  def chat_pipeline(history, message, max_new_tokens=128, temperature=0.8, top_p=0.95):
45
+ # 1) Intercept storefront facts first (reduces hallucinations)
46
  sf = storefront_qna(message)
47
  if sf:
48
  return sf
49
+ # 2) Memory-aware prompt for the model
50
  prompt = build_prompt_from_history(history, message, k=4)
51
  gen = model_generate(prompt, max_new_tokens, temperature, top_p)
52
  return clean_generation(gen)
 
62
  with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
63
  gr.Markdown("## Storefront Chat")
64
 
65
+ # Single source of truth for conversation history
66
  history_state = gr.State([])
67
 
68
  with gr.Tabs():
69
+ # --- TAB: Chat ---
70
  with gr.TabItem("Chat"):
71
  with gr.Group(elem_classes=["panel"]):
72
+ chat = gr.Chatbot(
73
+ height=360,
74
+ bubble_full_width=False,
75
+ label="Chat"
76
+ )
77
 
78
  with gr.Row():
79
+ msg = gr.Textbox(
80
+ placeholder="Ask about parking rules, attire, cap & gown, pickup times…",
81
+ scale=5
82
+ )
83
  send = gr.Button("Send", scale=1)
84
 
85
+ # Quick chips
86
  with gr.Row():
87
  chip1 = gr.Button("Parking rules", variant="secondary")
88
  chip2 = gr.Button("Multiple passes", variant="secondary")
89
  chip3 = gr.Button("Attire", variant="secondary")
90
  chip4 = gr.Button("When do lots open?", variant="secondary")
91
 
92
+ # Advanced (sliders + health/capabilities) — kept off the main screen
93
  with gr.Accordion("Advanced chat options", open=False):
94
  max_new = gr.Slider(32, 512, 128, 1, label="Max new tokens")
95
  temp = gr.Slider(0.1, 1.5, 0.8, 0.05, label="Temperature")
 
100
  caps_btn = gr.Button("Capabilities", variant="secondary")
101
  status_md = gr.Markdown("Status: not checked", elem_classes=["small"])
102
 
103
+ # --- TAB: Products ---
104
  with gr.TabItem("Products"):
105
  gr.Markdown("### Available Items")
106
  cols = list(DEFAULT_PRODUCTS[0].keys()) if DEFAULT_PRODUCTS else ["SKU","Name","Price","Notes"]
107
+ data = [[p.get(c, "") for c in cols] for p in DEFAULT_PRODUCTS]
108
  gr.Dataframe(headers=cols, value=data, interactive=False, wrap=True, label="Products")
109
 
110
+ # --- TAB: Rules ---
111
  with gr.TabItem("Rules"):
112
  gr.Markdown("### Venue rules")
113
  gr.Markdown("- " + "\n- ".join(DEFAULT_VENUE))
114
  gr.Markdown("### Parking rules")
115
  gr.Markdown("- " + "\n- ".join(DEFAULT_PARKING))
116
 
117
+ # --- TAB: Logistics ---
118
  with gr.TabItem("Logistics"):
119
  gr.Markdown(
120
  "### Event Logistics\n"
 
125
  "\n*Try asking the bot:* “What time should I arrive?” • “Where do I pick up the gown?”"
126
  )
127
 
128
+ # ---------- Helpers ----------
129
  def _append_bot_md(history, md_text):
130
+ """Append a bot-side markdown message while preserving the [[u,b],…] format."""
131
  history = history or []
132
  return history + [[None, md_text]]
133
 
 
135
  def on_send(history, message, max_new_tokens, temperature, top_p):
136
  t = (message or "").strip()
137
  if not t:
138
+ return history, history, "" # no-op; keep shapes identical
139
+ # add user row
140
  history = (history or []) + [[t, None]]
141
+ # generate reply using history prior to this turn
142
  reply = chat_pipeline(history[:-1], t, max_new_tokens, temperature, top_p)
143
  history[-1][1] = reply
144
+ # update both state and Chatbot, clear textbox
145
  return history, history, ""
146
 
147
  def _health_cb(history):
148
+ md = (
149
+ f"### Status: ✅ Healthy\n"
150
+ f"- Model: `{MODEL_NAME}`\n"
151
+ f"- Storefront module: {'yes' if USE_HELPERS else 'no'}\n"
152
+ f"- Storefront JSON: {'loaded' if bool(STORE_DATA) else 'not found'}"
153
+ )
154
  new_hist = _append_bot_md(history, md)
155
+ # Update chat AND status label
156
  return new_hist, new_hist, "Status: ✅ Healthy"
157
 
158
  def _caps_cb(history):
 
165
  new_hist = _append_bot_md(history, md)
166
  return new_hist, new_hist
167
 
168
+ # Wire up (update both the state and Chatbot widget)
169
  send.click(on_send, [history_state, msg, max_new, temp, topp], [history_state, chat, msg])
170
  msg.submit(on_send, [history_state, msg, max_new, temp, topp], [history_state, chat, msg])
171
 
172
+ # Chips → prefill textbox (don’t mutate history)
173
  chip1.click(lambda: "What are the parking rules?", outputs=msg)
174
  chip2.click(lambda: "Can I buy multiple parking passes?", outputs=msg)
175
  chip3.click(lambda: "Is formal attire required?", outputs=msg)
176
  chip4.click(lambda: "What time do the parking lots open?", outputs=msg)
177
 
178
+ # Health / Capabilities: now inside the Advanced accordion
179
  health_btn.click(_health_cb, inputs=[history_state], outputs=[history_state, chat, status_md])
180
  caps_btn.click(_caps_cb, inputs=[history_state], outputs=[history_state, chat])
181