JerameeUC commited on
Commit
8be2c1b
·
1 Parent(s): 302faa6

Huge Commit of the code that was known working on the front-end.

Browse files
Files changed (8) hide show
  1. .gitignore +0 -0
  2. README.md +6 -2
  3. app_storefront.py +212 -0
  4. core/memory.py +34 -0
  5. core/model.py +45 -0
  6. core/storefront.py +175 -0
  7. space_app.py +0 -41
  8. storefront_data.json +84 -0
.gitignore CHANGED
Binary files a/.gitignore and b/.gitignore differ
 
README.md CHANGED
@@ -1,10 +1,14 @@
1
  ---
2
- title: Agentic-Chat-bot
3
  emoji: 💬
4
  colorFrom: indigo
5
  colorTo: blue
6
  sdk: gradio
7
  sdk_version: "4.38.0"
8
- app_file: space_app.py
9
  pinned: false
 
 
10
  ---
 
 
 
1
  ---
2
+ title: Store Front Agentic Chat Bot
3
  emoji: 💬
4
  colorFrom: indigo
5
  colorTo: blue
6
  sdk: gradio
7
  sdk_version: "4.38.0"
8
+ app_file: app_storefront.py
9
  pinned: false
10
+ license: mit
11
+ short_description: Test for the project front-end.
12
  ---
13
+
14
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app_storefront.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app_storefront.py
2
+ import os
3
+ import sys
4
+ import gradio as gr
5
+
6
+ # Ensure "core/" is importable
7
+ sys.path.append(os.path.join(os.path.dirname(__file__), "core"))
8
+
9
+ # Import only functions; core.storefront doesn't export constants
10
+ from core.model import model_generate, MODEL_NAME
11
+ from core.memory import build_prompt_from_history
12
+ from core.storefront import load_storefront, storefront_qna, extract_products, get_rules
13
+ from core.storefront import is_storefront_query
14
+
15
+ def chat_pipeline(history, message, max_new_tokens=96, temperature=0.7, top_p=0.9):
16
+ # 1) Try storefront facts first
17
+ sf = storefront_qna(DATA, message)
18
+ if sf:
19
+ return sf
20
+
21
+ # 2) If not a storefront query, offer guided help (no LLM)
22
+ if not is_storefront_query(message):
23
+ return (
24
+ "I can help with the graduation storefront. Examples:\n"
25
+ "- Parking rules, lots opening times\n"
26
+ "- Attire / dress code\n"
27
+ "- Cap & Gown details and pickup\n"
28
+ "- Parking passes (multiple allowed)\n"
29
+ "Ask one of those, and I’ll answer directly."
30
+ )
31
+
32
+ # 3) Otherwise, generate with memory and hard stops
33
+ prompt = build_prompt_from_history(history, message, k=4)
34
+ gen = model_generate(prompt, max_new_tokens, temperature, top_p)
35
+ return clean_generation(gen)
36
+
37
+ def clean_generation(text: str) -> str:
38
+ return (text or "").strip()
39
+
40
+ # ---------------- Load data + safe fallbacks ----------------
41
+ DATA = load_storefront() # may be None if storefront_data.json missing/empty
42
+
43
+ # Fallbacks used if JSON not present
44
+ FALLBACK_PRODUCTS = [
45
+ {"sku": "CG-SET", "name": "Cap & Gown Set", "price": 59.00,
46
+ "notes": "Tassel included; ships until 10 days before the event"},
47
+ {"sku": "PK-1", "name": "Parking Pass", "price": 10.00,
48
+ "notes": "Multiple passes are allowed per student"}
49
+ ]
50
+ FALLBACK_VENUE = [
51
+ "Formal attire recommended (not required).",
52
+ "No muscle shirts.",
53
+ "No sagging pants."
54
+ ]
55
+ FALLBACK_PARKING = [
56
+ "No double parking.",
57
+ "Vehicles parked in handicap spaces will be towed."
58
+ ]
59
+
60
+ # Normalize products/rules for the tabs
61
+ if DATA:
62
+ PRODUCTS = extract_products(DATA) or FALLBACK_PRODUCTS
63
+ venue_rules, parking_rules = get_rules(DATA)
64
+ VENUE_RULES = venue_rules or FALLBACK_VENUE
65
+ PARKING_RULES = parking_rules or FALLBACK_PARKING
66
+ else:
67
+ PRODUCTS = FALLBACK_PRODUCTS
68
+ VENUE_RULES = FALLBACK_VENUE
69
+ PARKING_RULES = FALLBACK_PARKING
70
+
71
+
72
+
73
+ # ---------------- UI ----------------
74
+ CSS = """
75
+ :root { --bg:#0b0d12; --panel:#0f172a; --border:#1f2940; --text:#e5e7eb; --muted:#9ca3af; }
76
+ .gradio-container { background: var(--bg) !important; color: var(--text) !important; }
77
+ .panel { border:1px solid var(--border); border-radius:16px; background:var(--panel); }
78
+ .small { font-size:12px; color: var(--muted); }
79
+ """
80
+
81
+ with gr.Blocks(title="Storefront Chat", css=CSS) as demo:
82
+ gr.Markdown("## Storefront Chat")
83
+
84
+ # Single history state (kept in sync with Chatbot)
85
+ history_state = gr.State([])
86
+
87
+ with gr.Tabs():
88
+ # --- TAB: Chat ---
89
+ with gr.TabItem("Chat"):
90
+ with gr.Group(elem_classes=["panel"]):
91
+ chat = gr.Chatbot(height=360, bubble_full_width=False, label="Chat")
92
+
93
+ with gr.Row():
94
+ msg = gr.Textbox(placeholder="Ask about parking rules, attire, cap & gown, pickup times…", scale=5)
95
+ send = gr.Button("Send", scale=1)
96
+
97
+ # Quick chips
98
+ with gr.Row():
99
+ chip1 = gr.Button("Parking rules", variant="secondary")
100
+ chip2 = gr.Button("Multiple passes", variant="secondary")
101
+ chip3 = gr.Button("Attire", variant="secondary")
102
+ chip4 = gr.Button("When do lots open?", variant="secondary")
103
+
104
+ # Advanced options (sliders + Health/Capabilities)
105
+ with gr.Accordion("Advanced chat options", open=False):
106
+ max_new = gr.Slider(32, 512, 128, 1, label="Max new tokens")
107
+ temp = gr.Slider(0.1, 1.5, 0.8, 0.05, label="Temperature")
108
+ topp = gr.Slider(0.1, 1.0, 0.95, 0.05, label="Top-p")
109
+
110
+ with gr.Row():
111
+ health_btn = gr.Button("Health", variant="secondary")
112
+ caps_btn = gr.Button("Capabilities", variant="secondary")
113
+ status_md = gr.Markdown("Status: not checked", elem_classes=["small"])
114
+
115
+ # --- TAB: Products ---
116
+ with gr.TabItem("Products"):
117
+ gr.Markdown("### Available Items")
118
+ cols = ["sku", "name", "price", "notes"]
119
+ data = [[p.get(c, "") for c in cols] for p in PRODUCTS]
120
+ gr.Dataframe(headers=[c.upper() for c in cols], value=data, interactive=False, wrap=True, label="Products")
121
+
122
+ # --- TAB: Rules ---
123
+ with gr.TabItem("Rules"):
124
+ gr.Markdown("### Venue rules")
125
+ gr.Markdown("- " + "\n- ".join(VENUE_RULES))
126
+ gr.Markdown("### Parking rules")
127
+ gr.Markdown("- " + "\n- ".join(PARKING_RULES))
128
+
129
+ # --- TAB: Logistics ---
130
+ with gr.TabItem("Logistics"):
131
+ gr.Markdown(
132
+ "### Event Logistics\n"
133
+ "- Shipping available until 10 days before event (typ. 3–5 business days)\n"
134
+ "- Pickup: Student Center Bookstore during the week prior to event\n"
135
+ "- Graduates arrive 90 minutes early; guests 60 minutes early\n"
136
+ "- Lots A & B open 2 hours before; overflow as needed\n"
137
+ "\n*Try asking the bot:* “What time should I arrive?” • “Where do I pick up the gown?”"
138
+ )
139
+
140
+ # ---------- Helpers ----------
141
+ def _append_bot_md(history, md_text):
142
+ history = history or []
143
+ return history + [[None, md_text]]
144
+
145
+ # ---------- Callbacks ----------
146
+ def on_send(history, message, max_new_tokens, temperature, top_p):
147
+ t = (message or "").strip()
148
+ if not t:
149
+ return history, history, "" # no-op; shapes must match
150
+ history = (history or []) + [[t, None]]
151
+ reply = chat_pipeline(history[:-1], t, max_new_tokens, temperature, top_p)
152
+ history[-1][1] = reply
153
+ return history, history, ""
154
+
155
+ def _health_cb(history):
156
+ md = (
157
+ f"### Status: ✅ Healthy\n"
158
+ f"- Model: `{MODEL_NAME}`\n"
159
+ f"- Storefront JSON: {'loaded' if bool(DATA) else 'not found'}"
160
+ )
161
+ new_hist = _append_bot_md(history, md)
162
+ return new_hist, new_hist, "Status: ✅ Healthy"
163
+
164
+ def _caps_cb(history):
165
+ md = (
166
+ "### Capabilities\n"
167
+ "- Chat (LLM text-generation, memory-aware prompt)\n"
168
+ "- Storefront Q&A (parking, attire, products, logistics)\n"
169
+ "- Adjustable: max_new_tokens, temperature, top-p"
170
+ )
171
+ new_hist = _append_bot_md(history, md)
172
+ return new_hist, new_hist
173
+
174
+ # Wire up (state + chatbot)
175
+ send.click(on_send, [history_state, msg, max_new, temp, topp], [history_state, chat, msg])
176
+ msg.submit(on_send, [history_state, msg, max_new, temp, topp], [history_state, chat, msg])
177
+
178
+ # Chips → prefill textbox
179
+ chip1.click(lambda: "What are the parking rules?", outputs=msg)
180
+ chip2.click(lambda: "Can I buy multiple parking passes?", outputs=msg)
181
+ chip3.click(lambda: "Is formal attire required?", outputs=msg)
182
+ chip4.click(lambda: "What time do the parking lots open?", outputs=msg)
183
+
184
+ # Health / Capabilities live inside Advanced
185
+ health_btn.click(_health_cb, inputs=[history_state], outputs=[history_state, chat, status_md])
186
+ caps_btn.click(_caps_cb, inputs=[history_state], outputs=[history_state, chat])
187
+
188
+ def clean_generation(text: str) -> str:
189
+ s = (text or "").strip()
190
+
191
+ # If the prompt contained "Assistant:", keep only what comes after the last one
192
+ last = s.rfind("Assistant:")
193
+ if last != -1:
194
+ s = s[last + len("Assistant:"):].strip()
195
+
196
+ # If it accidentally continued into a new "User:" or instructions, cut there
197
+ cut_marks = ["\nUser:", "\nYOU ARE ANSWERING", "\nProducts:", "\nVenue rules:", "\nParking rules:"]
198
+ cut_positions = [s.find(m) for m in cut_marks if s.find(m) != -1]
199
+ if cut_positions:
200
+ s = s[:min(cut_positions)].strip()
201
+
202
+ # Collapse repeated lines like "Yes, multiple parking passes..." spam
203
+ lines, out = s.splitlines(), []
204
+ seen = set()
205
+ for ln in lines:
206
+ # dedupe only exact consecutive repeats; keep normal conversation lines
207
+ if not out or ln != out[-1]:
208
+ out.append(ln)
209
+ return "\n".join(out).strip()
210
+
211
+ if __name__ == "__main__":
212
+ demo.launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860")))
core/memory.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # core/memory.py
2
+
3
+ META_MARKERS = ("### Status:", "### Capabilities", "Status:", "Capabilities", "Model:", "Storefront JSON:")
4
+
5
+ def _is_meta(s: str | None) -> bool:
6
+ if not s: return False
7
+ ss = s.strip()
8
+ return any(m in ss for m in META_MARKERS)
9
+
10
+ def build_prompt_from_history(history, user_text, k=4) -> str:
11
+ """
12
+ history: list[[user, bot], ...] from Gradio Chatbot.
13
+ Keep prompt compact; exclude meta/diagnostic messages.
14
+ """
15
+ lines = [
16
+ "System: Answer questions about the university graduation storefront.",
17
+ "System: Be concise. If unsure, state what is known."
18
+ ]
19
+
20
+ # Keep only the last k turns that aren't meta
21
+ kept = []
22
+ for u, b in (history or []):
23
+ if u and not _is_meta(u):
24
+ kept.append(("User", u))
25
+ if b and not _is_meta(b):
26
+ kept.append(("Assistant", b))
27
+ kept = kept[-(2*k):] # up to k exchanges
28
+
29
+ for role, text in kept:
30
+ lines.append(f"{role}: {text}")
31
+
32
+ lines.append(f"User: {user_text}")
33
+ lines.append("Assistant:")
34
+ return "\n".join(lines)
core/model.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # core/model.py
2
+ import re, os
3
+ from transformers import pipeline, StoppingCriteria, StoppingCriteriaList
4
+
5
+ MODEL_NAME = os.getenv("HF_MODEL_GENERATION", "distilgpt2")
6
+ _pipe = None
7
+
8
+ class StopOnMarkers(StoppingCriteria):
9
+ def __init__(self, tokenizer, stop_strs=("\nUser:", "\nSystem:", "\n###", "\nProducts:", "\nVenue rules:", "\nParking rules:")):
10
+ self.tokenizer = tokenizer
11
+ self.stop_ids = [tokenizer(s, add_special_tokens=False).input_ids for s in stop_strs]
12
+
13
+ def __call__(self, input_ids, scores, **kwargs):
14
+ # stop if any marker sequence just appeared at the end
15
+ for seq in self.stop_ids:
16
+ L = len(seq)
17
+ if L and len(input_ids[0]) >= L and input_ids[0][-L:].tolist() == seq:
18
+ return True
19
+ return False
20
+
21
+ def _get_pipe():
22
+ global _pipe
23
+ if _pipe is None:
24
+ _pipe = pipeline("text-generation", model=MODEL_NAME)
25
+ return _pipe
26
+
27
+ def model_generate(prompt, max_new_tokens=96, temperature=0.7, top_p=0.9):
28
+ pipe = _get_pipe()
29
+ tok = pipe.tokenizer
30
+
31
+ stop = StoppingCriteriaList([StopOnMarkers(tok)])
32
+
33
+ out = pipe(
34
+ prompt,
35
+ max_new_tokens=int(max_new_tokens),
36
+ do_sample=True,
37
+ temperature=float(temperature),
38
+ top_p=float(top_p),
39
+ repetition_penalty=1.15, # discourages exact loops
40
+ no_repeat_ngram_size=3, # blocks short repeats like "Account/Account"
41
+ pad_token_id=tok.eos_token_id or 50256,
42
+ eos_token_id=tok.eos_token_id, # stop at EOS if model supports
43
+ stopping_criteria=stop,
44
+ )
45
+ return out[0]["generated_text"]
core/storefront.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # core/storefront.py
2
+ import json, os
3
+
4
+ def clean_generation(text: str) -> str:
5
+ s = (text or "").strip()
6
+
7
+ # Keep only text after the last "Assistant:"
8
+ last = s.rfind("Assistant:")
9
+ if last != -1:
10
+ s = s[last + len("Assistant:"):].strip()
11
+
12
+ # Cut at the first sign of a new turn or meta
13
+ cut_marks = ["\nUser:", "\nSystem:", "\n###", "\nProducts:", "\nVenue rules:", "\nParking rules:"]
14
+ cuts = [s.find(m) for m in cut_marks if s.find(m) != -1]
15
+ if cuts:
16
+ s = s[:min(cuts)].strip()
17
+
18
+ # Remove egregious token loops like "Account/Account/..."
19
+ s = re.sub(r"(?:\b([A-Z][a-zA-Z0-9_/.-]{2,})\b(?:\s*/\s*\1\b)+)", r"\1", s)
20
+
21
+ # Collapse consecutive duplicate lines
22
+ dedup = []
23
+ for ln in s.splitlines():
24
+ if not dedup or ln.strip() != dedup[-1].strip():
25
+ dedup.append(ln)
26
+ return "\n".join(dedup).strip()
27
+
28
+ HELP_KEYWORDS = {
29
+ "help", "assist", "assistance", "tips", "how do i", "what can you do",
30
+ "graduation help", "help me with graduation", "can you help me with graduation"
31
+ }
32
+
33
+ STORE_KEYWORDS = {
34
+ "cap", "gown", "parking", "pass", "passes", "attire", "dress",
35
+ "venue", "logistics", "shipping", "pickup", "lot", "lots", "arrival", "size", "sizing"
36
+ }
37
+
38
+ def is_storefront_query(text: str) -> bool:
39
+ t = (text or "").lower()
40
+ return any(k in t for k in STORE_KEYWORDS) or any(k in t for k in HELP_KEYWORDS)
41
+
42
+ def _get_lots_open_hours(data) -> int:
43
+ try:
44
+ return int(((data or {}).get("logistics") or {}).get("lots_open_hours_before") or 2)
45
+ except Exception:
46
+ return 2
47
+
48
+ # Main router (drop-in)
49
+ def storefront_qna(data, user_text: str) -> str | None:
50
+ """
51
+ Deterministic storefront answers first:
52
+ - single-word intents (parking / wear / passes)
53
+ - help/capability prompt
54
+ - FAQ (if you have answer_faq)
55
+ - explicit rules queries
56
+ - 'lots open' timing
57
+ - compact products list
58
+ Returns None to allow LLM fallback in your chat pipeline.
59
+ """
60
+ if not user_text:
61
+ return None
62
+ t = user_text.strip().lower()
63
+
64
+ # 1) Single-word / exact intents to avoid LLM hallucinations
65
+ if t in {"parking"}:
66
+ _, pr = get_rules(data)
67
+ if pr:
68
+ return "Parking rules:\n- " + "\n- ".join(pr)
69
+
70
+ # Map 'wear/attire' variants directly to venue rules
71
+ if t in {"venue", "attire", "dress", "dress code", "wear"} or "what should i wear" in t:
72
+ vr, _ = get_rules(data)
73
+ if vr:
74
+ return "Venue rules:\n- " + "\n- ".join(vr)
75
+
76
+ # Parking passes (multiple allowed)
77
+ if t in {"passes", "parking pass", "parking passes"}:
78
+ return "Yes, multiple parking passes are allowed per student."
79
+
80
+ # 2) Help / capability intent → deterministic guidance
81
+ if any(k in t for k in HELP_KEYWORDS):
82
+ return (
83
+ "I can help with the graduation storefront. Try:\n"
84
+ "- “What are the parking rules?”\n"
85
+ "- “Can I buy multiple parking passes?”\n"
86
+ "- “Is formal attire required?”\n"
87
+ "- “Where do I pick up the gown?”\n"
88
+ "- “When do lots open?”"
89
+ )
90
+
91
+ # 3) JSON-driven FAQ (if available)
92
+ try:
93
+ a = answer_faq(data, t)
94
+ if a:
95
+ return a
96
+ except Exception:
97
+ pass # answer_faq may not exist or data may be None
98
+
99
+ # 4) Explicit rules phrasing (keeps answers tight and consistent)
100
+ if "parking" in t and "rule" in t:
101
+ _, pr = get_rules(data)
102
+ if pr:
103
+ return "Parking rules:\n- " + "\n- ".join(pr)
104
+
105
+ if ("venue" in t and "rule" in t) or "attire" in t or "dress code" in t:
106
+ vr, _ = get_rules(data)
107
+ if vr:
108
+ return "Venue rules:\n- " + "\n- ".join(vr)
109
+
110
+ # 5) “When do lots open?” / hours / time
111
+ if "parking" in t and ("hours" in t or "time" in t or "open" in t):
112
+ lots_open = _get_lots_open_hours(data)
113
+ return f"Parking lots open {lots_open} hours before the ceremony."
114
+
115
+ # 6) Product info (cap/gown/parking pass)
116
+ if any(k in t for k in ("cap", "gown", "parking pass", "product", "item", "price")):
117
+ prods = extract_products(data)
118
+ if prods:
119
+ lines = []
120
+ for p in prods:
121
+ name = p.get("name", "Item")
122
+ price = p.get("price", p.get("price_usd", ""))
123
+ notes = p.get("notes", p.get("description", ""))
124
+ price_str = f"${price:.2f}" if isinstance(price, (int, float)) else str(price)
125
+ lines.append(f"{name} — {price_str}: {notes}")
126
+ return "\n".join(lines)
127
+
128
+ # No deterministic match → let the caller fall back to the LLM
129
+ return None
130
+
131
+ def _find_json():
132
+ candidates = [
133
+ os.path.join(os.getcwd(), "storefront_data.json"),
134
+ os.path.join(os.getcwd(), "agenticcore", "storefront_data.json"),
135
+ ]
136
+ for p in candidates:
137
+ if os.path.exists(p):
138
+ return p
139
+ return None
140
+
141
+ def load_storefront():
142
+ p = _find_json()
143
+ if not p:
144
+ return None
145
+ with open(p, "r", encoding="utf-8") as f:
146
+ return json.load(f)
147
+
148
+ def _string_in_any(s, variants):
149
+ s = s.lower()
150
+ return any(v in s for v in variants)
151
+
152
+ def answer_faq(data, text: str):
153
+ """Very small FAQ matcher by substring; safe if faq[] missing."""
154
+ faq = (data or {}).get("faq") or []
155
+ t = text.lower()
156
+ for item in faq:
157
+ qs = item.get("q") or []
158
+ if any(q.lower() in t for q in qs):
159
+ return item.get("a")
160
+ return None
161
+
162
+ def extract_products(data):
163
+ prods = []
164
+ for p in (data or {}).get("products", []):
165
+ prods.append({
166
+ "sku": p.get("sku",""),
167
+ "name": p.get("name",""),
168
+ "price": p.get("price_usd",""),
169
+ "notes": (p.get("description") or "")[:140],
170
+ })
171
+ return prods
172
+
173
+ def get_rules(data):
174
+ pol = (data or {}).get("policies", {}) or {}
175
+ return pol.get("venue_rules", []), pol.get("parking_rules", [])
space_app.py DELETED
@@ -1,41 +0,0 @@
1
- import os
2
- import gradio as gr
3
- from transformers import pipeline
4
-
5
- MODEL_NAME = os.getenv("HF_MODEL_GENERATION", "distilgpt2")
6
-
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 chat_fn(message, max_new_tokens=128, temperature=0.8, top_p=0.95):
15
- message = (message or "").strip()
16
- if not message:
17
- return "Please type something!"
18
- pipe = _get_pipe()
19
- out = pipe(
20
- message,
21
- max_new_tokens=int(max_new_tokens),
22
- do_sample=True,
23
- temperature=float(temperature),
24
- top_p=float(top_p),
25
- pad_token_id=50256
26
- )
27
- return out[0]["generated_text"]
28
-
29
- with gr.Blocks(title="Agentic-Chat-bot") as demo:
30
- gr.Markdown("# 🤖 Agentic Chat Bot\nGradio + Transformers demo")
31
- prompt = gr.Textbox(label="Prompt", placeholder="Ask me anything…", lines=4)
32
- out = gr.Textbox(label="Response", lines=6)
33
- max_new = gr.Slider(32, 512, 128, 1, label="Max new tokens")
34
- temp = gr.Slider(0.1, 1.5, 0.8, 0.05, label="Temperature")
35
- topp = gr.Slider(0.1, 1.0, 0.95, 0.05, label="Top-p")
36
- btn = gr.Button("Send")
37
- btn.click(chat_fn, [prompt, max_new, temp, topp], out)
38
- prompt.submit(chat_fn, [prompt, max_new, temp, topp], out)
39
-
40
- if __name__ == "__main__":
41
- demo.launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860")))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
storefront_data.json ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "products": [
3
+ {
4
+ "sku": "CG-SET",
5
+ "name": "Cap & Gown Set",
6
+ "price_usd": 59.0,
7
+ "description": "Tassel included; ships until 10 days before the event. Sizes available at pickup; exchange allowed on-site if inventory permits."
8
+ },
9
+ {
10
+ "sku": "PK-1",
11
+ "name": "Parking Pass",
12
+ "price_usd": 10.0,
13
+ "description": "One vehicle per pass. Multiple passes are allowed per student for extended family or guests."
14
+ }
15
+ ],
16
+ "policies": {
17
+ "parking_rules": [
18
+ "No double parking.",
19
+ "Vehicles parked in handicap spaces will be towed."
20
+ ],
21
+ "venue_rules": [
22
+ "Formal attire is recommended (not required).",
23
+ "No muscle shirts.",
24
+ "No sagging pants."
25
+ ]
26
+ },
27
+ "logistics": {
28
+ "shipping_cutoff_days": 10,
29
+ "shipping_window_business_days": "3–5",
30
+ "pickup_location": "Student Center Bookstore",
31
+ "arrival_times": {
32
+ "graduates_minutes_early": 90,
33
+ "guests_minutes_early": 60
34
+ },
35
+ "lots_open_hours_before": 2,
36
+ "lots": ["A", "B"],
37
+ "overflow": "As needed"
38
+ },
39
+ "faq": [
40
+ {
41
+ "q": [
42
+ "Can I buy multiple parking passes?",
43
+ "multiple passes",
44
+ "more than one parking pass",
45
+ "extra parking pass"
46
+ ],
47
+ "a": "Yes, multiple parking passes are allowed per student."
48
+ },
49
+ {
50
+ "q": [
51
+ "What time do the parking lots open?",
52
+ "When do lots open",
53
+ "parking hours",
54
+ "what time parking"
55
+ ],
56
+ "a": "Parking lots open 2 hours before the ceremony."
57
+ },
58
+ {
59
+ "q": [
60
+ "Is formal attire required?",
61
+ "dress code",
62
+ "what should I wear",
63
+ "attire rules"
64
+ ],
65
+ "a": "Formal attire is recommended but not required. No muscle shirts or sagging pants."
66
+ },
67
+ {
68
+ "q": [
69
+ "Where do I pick up the gown?",
70
+ "gown pickup",
71
+ "pickup location"
72
+ ],
73
+ "a": "Pickup is at the Student Center Bookstore during the week prior to the event."
74
+ },
75
+ {
76
+ "q": [
77
+ "Shipping cutoff",
78
+ "last day to ship",
79
+ "when is shipping available until"
80
+ ],
81
+ "a": "Shipping is available until 10 days before the event. Typical shipping takes 3–5 business days."
82
+ }
83
+ ]
84
+ }