Welly-code commited on
Commit
a54d1de
Β·
verified Β·
1 Parent(s): 44dd6cc

Dark theme with proper contrast: white text on black background

Browse files
Files changed (1) hide show
  1. app.py +176 -140
app.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Stack X Ultimate Inference β€” Hugging Face Space
3
  Agentic tool-calling model demo.
4
  """
5
 
@@ -8,7 +8,7 @@ import re
8
  import json
9
  from datetime import datetime
10
 
11
- # ─── Tool Definitions ────────────────────────────────────────────────────────
12
 
13
  TOOLS = [
14
  {
@@ -65,8 +65,6 @@ TOOLS = [
65
  },
66
  ]
67
 
68
- # ─── Tool Implementations ──────────────────────────────────────────────────
69
-
70
  def calculator(expression: str) -> str:
71
  try:
72
  cleaned = re.sub(r"[^0-9+\-*/.()% ]", "", expression)
@@ -101,183 +99,232 @@ def run_command(command: str, cwd: str = ".") -> str:
101
  return f"Error: {e}"
102
 
103
  def execute_tool(tool_name: str, tool_args: dict) -> str:
104
- fn_map = {
105
  "calculator": lambda: calculator(tool_args.get("expression", "")),
106
  "get_current_time": get_current_time,
107
  "search_files": lambda: search_files(tool_args.get("path", "."), tool_args.get("pattern", "*")),
108
  "run_command": lambda: run_command(tool_args.get("command", ""), tool_args.get("cwd", ".")),
109
  }
110
- fn = fn_map.get(tool_name, lambda: f"Unknown tool: {tool_name}")
111
- return fn()
112
 
113
- # ─── Response Generator ──────────────────────────────────────────────────────
114
 
115
  def generate_response(message: str) -> dict:
116
  msg_lower = message.lower()
117
 
118
- # Calculator
119
- calc_kw = ["calculate", "compute", "math", "roi", "compound", "interest", "%", "$"]
120
- if any(k in msg_lower for k in calc_kw):
121
  expr = re.search(r"[\d+\-*/.()% ]+", message)
122
- return {
123
- "tool_name": "calculator",
124
- "tool_args": {"expression": expr.group().strip() if expr else "0"},
125
- "display": f"Calculating: `{message}`"
126
- }
127
 
128
- # Time
129
- time_kw = ["time", "date", "now", "current"]
130
- if any(k in msg_lower for k in time_kw):
131
- return {
132
- "tool_name": "get_current_time",
133
- "tool_args": {},
134
- "display": "Fetching current time..."
135
- }
136
 
137
- # File search
138
- file_kw = ["find", "search", "file", "look for", "where is", "list"]
139
- if any(k in msg_lower for k in file_kw):
140
  pattern = re.search(r"\*\.[a-zA-Z]+", message)
141
- return {
142
- "tool_name": "search_files",
143
- "tool_args": {"path": ".", "pattern": pattern.group() if pattern else "*"},
144
- "display": f"Searching for files matching your query..."
145
- }
146
 
147
- # Command
148
- cmd_kw = ["run", "execute", "terminal", "bash", "git ", "ls", "ps ", "docker"]
149
- if any(k in msg_lower for k in cmd_kw):
150
  match = re.search(r"`([^`]+)`", message)
151
  cmd = match.group(1) if match else message.split()[-1]
152
- return {
153
- "tool_name": "run_command",
154
- "tool_args": {"command": cmd, "cwd": "."},
155
- "display": f"Running: `{cmd}`"
156
- }
157
 
158
- # No tool
159
- return {
160
- "tool_name": None,
161
- "tool_args": {},
162
- "display": None
163
- }
164
 
165
  # ─── Chat Function ───────────────────────────────────────────────────────────
166
 
167
  def chat_fn(message, history):
168
  resp = generate_response(message)
169
 
170
- if resp["tool_name"]:
171
- tool_result = execute_tool(resp["tool_name"], resp["tool_args"])
172
- call_display = f"πŸ”§ Calling `{resp['tool_name']}`...\n\n```\n{json.dumps(resp['tool_args'], indent=2)}\n```"
173
- result_display = f"βœ… **{resp['tool_name']}** result:\n\n```\n{tool_result}\n```"
174
- return [[resp["display"], call_display], [None, result_display]]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
- return [[message, "Stack X Ultimate is a fine-tuned agentic model that calls tools to answer your questions. Try one of the examples below to see it in action!"], None]
 
 
 
177
 
178
- # ─── Gradio Interface ────────────────────────────────────────────────────────
 
 
 
179
 
180
- css = """
181
- /* ─── Background & Base ──────────────────────────────────────────── */
182
- .gradio-container { background: #ffffff !important; }
183
- .main { background: #ffffff !important; }
184
 
185
- /* ─── Chat bubbles ────────────────────────────────────────────────── */
186
  .user-bubble {
187
- background: #f4f4f5 !important;
188
- border: 1px solid #d4d4d8 !important;
189
  border-radius: 12px 12px 4px 12px !important;
190
- color: #18181b !important;
191
  padding: 10px 14px !important;
 
192
  }
 
 
193
  .assistant-bubble {
194
- background: #fafafa !important;
195
- border: 1px solid #e4e4e7 !important;
196
  border-radius: 12px 12px 12px 4px !important;
197
- color: #27272a !important;
198
  padding: 10px 14px !important;
 
199
  }
200
 
201
- /* ─── Input styling ──────────────────────────────────────────────── */
202
  #main-input input {
203
- background: #ffffff !important;
204
- border: 2px solid #e4e4e7 !important;
205
- border-radius: 12px !important;
206
- color: #18181b !important;
207
  font-size: 1rem !important;
208
  padding: 12px 16px !important;
209
  }
210
  #main-input input:focus {
211
- border-color: #7c3aed !important;
212
  outline: none !important;
213
- box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.15) !important;
214
  }
215
 
216
- /* ─── Buttons ────────────────────────────────────────────────────── */
217
- .gradio-button.primary {
218
- background: #7c3aed !important;
219
  border: none !important;
220
  color: white !important;
221
  border-radius: 10px !important;
222
  font-weight: 600 !important;
 
223
  }
224
- .gradio-button.primary:hover {
225
- background: #6d28d9 !important;
226
  }
227
 
228
- /* ─── Examples ───────────────────────────────────────────────────── */
 
 
 
 
 
 
229
  .example-btn {
230
- background: #f4f4f5 !important;
231
- border: 1px solid #d4d4d8 !important;
232
  border-radius: 8px !important;
233
- color: #3f3f46 !important;
234
- font-size: 0.875rem !important;
235
  padding: 6px 12px !important;
236
  }
237
  .example-btn:hover {
238
- background: #e4e4e7 !important;
239
- color: #18181b !important;
 
240
  }
241
 
242
- /* ─── Stats bar ──────────────────────────────────────────────────── */
243
- .stats-bar {
244
- background: #fafafa !important;
245
- border: 1px solid #e4e4e7 !important;
246
  border-radius: 12px !important;
247
- padding: 16px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  display: flex !important;
249
  justify-content: center !important;
250
- gap: 40px !important;
 
251
  margin-bottom: 16px !important;
252
  }
253
- .stat-item { text-align: center; }
254
- .stat-value { font-size: 1.3rem; font-weight: 800; color: #7c3aed; }
255
- .stat-label { font-size: 0.7rem; color: #71717a; text-transform: uppercase; letter-spacing: 0.05em; }
256
-
257
- /* ─── Hero ───────────────────────────────────────────────────────── */
258
- .hero-text h1 {
259
- font-size: 1.8rem !important;
260
- font-weight: 900 !important;
261
- color: #18181b !important;
262
- margin-bottom: 6px !important;
 
263
  }
264
- .hero-text p { color: #52525b !important; font-size: 0.95rem !important; max-width: 500px; margin: 0 auto !important; }
265
 
266
- /* ─── Tool badges ────────────────────────────────────────────────── */
267
- .tool-badges { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
 
 
 
 
 
 
268
  .tool-badge {
269
- background: #f4f4f5 !important;
270
- border: 1px solid #d4d4d8 !important;
271
  border-radius: 999px !important;
272
  padding: 4px 12px !important;
273
  font-size: 0.75rem !important;
274
- color: #52525b !important;
275
  }
276
 
277
- /* ─── Footer ────────────────────────────────────────────────────── */
278
- .footer { text-align: center; color: #a1a1aa; font-size: 0.75rem; padding: 12px; border-top: 1px solid #e4e4e7; margin-top: 12px; }
 
 
 
 
 
 
 
 
 
279
  """
280
 
 
 
281
  EXAMPLES = [
282
  ["Calculate compound interest on $1500 at 7% over 30 years"],
283
  ["What time is it right now?"],
@@ -287,15 +334,13 @@ EXAMPLES = [
287
  ]
288
 
289
  def build():
290
- with gr.Blocks(css=css, title="Stack X Ultimate") as demo:
291
-
292
  # ── Hero ──────────────────────────────────────────────────────
293
  gr.HTML("""
294
- <div style="text-align:center; padding: 20px 16px 8px; border-bottom: 1px solid #e4e4e7; margin-bottom: 16px;">
295
- <div class="hero-text">
296
- <h1>πŸ€– Stack X Ultimate</h1>
297
- <p>Open-source agentic model with tool calling. Try it free β€” no API key needed.</p>
298
- </div>
299
  <div class="tool-badges">
300
  <span class="tool-badge">πŸ”’ calculator</span>
301
  <span class="tool-badge">πŸ• get_current_time</span>
@@ -304,13 +349,14 @@ def build():
304
  </div>
305
  </div>
306
  """)
307
-
308
  gr.HTML("""
309
  <div class="stats-bar">
310
- <div class="stat-item"><div class="stat-value">3B</div><div class="stat-label">Params</div></div>
311
- <div class="stat-item"><div class="stat-value">4-bit</div><div class="stat-label">QLoRA</div></div>
312
- <div class="stat-item"><div class="stat-value">V100</div><div class="stat-label">1 GPU</div></div>
313
- <div class="stat-item"><div class="stat-value">$0</div><div class="stat-label">API Cost</div></div>
 
314
  </div>
315
  """)
316
 
@@ -332,7 +378,12 @@ def build():
332
  show_label=False,
333
  elem_id="main-input",
334
  )
335
- send_btn = gr.Button("Send", scale=1, elem_classes="primary")
 
 
 
 
 
336
 
337
  # ── Examples ────────────────────────────────────────────────────
338
  gr.Examples(
@@ -342,31 +393,16 @@ def build():
342
  examples_per_page=5,
343
  )
344
 
345
- # ── Events ────────────────────────────────────────────────────
346
- def respond(message, history):
347
- result = chat_fn(message, history)
348
- return result
349
-
350
- msg.submit(respond, [msg, chat], [chat])
351
- send_btn.click(respond, [msg, chat], [chat])
352
- msg.submit(lambda: "", None, msg)
353
-
354
- # ── Footer ─────────────────────────────────────────────────────
355
  gr.HTML("""
356
  <div class="footer">
357
- πŸ”§ Demo shows tool-calling capability.
358
- <a href="https://huggingface.co/my-ai-stack/Stack-X-Ultimate" style="color:#7c3aed;">Deploy the model</a> Β·
359
- <a href="https://www.stack-ai.me/contact" style="color:#7c3aed;">Enterprise inquiry</a>
360
  </div>
361
  """)
362
 
363
  return demo
364
 
365
  if __name__ == "__main__":
366
- demo = build()
367
- demo.launch(
368
- server_name="0.0.0.0",
369
- server_port=7860,
370
- max_threads=4,
371
- show_api=False,
372
- )
 
1
  """
2
+ Stack X Ultimate β€” Hugging Face Space
3
  Agentic tool-calling model demo.
4
  """
5
 
 
8
  import json
9
  from datetime import datetime
10
 
11
+ # ─── Tools ─────────────────────────────────────────────────────────────────
12
 
13
  TOOLS = [
14
  {
 
65
  },
66
  ]
67
 
 
 
68
  def calculator(expression: str) -> str:
69
  try:
70
  cleaned = re.sub(r"[^0-9+\-*/.()% ]", "", expression)
 
99
  return f"Error: {e}"
100
 
101
  def execute_tool(tool_name: str, tool_args: dict) -> str:
102
+ fns = {
103
  "calculator": lambda: calculator(tool_args.get("expression", "")),
104
  "get_current_time": get_current_time,
105
  "search_files": lambda: search_files(tool_args.get("path", "."), tool_args.get("pattern", "*")),
106
  "run_command": lambda: run_command(tool_args.get("command", ""), tool_args.get("cwd", ".")),
107
  }
108
+ return fns.get(tool_name, lambda: f"Unknown: {tool_name}")()
 
109
 
110
+ # ─── Response Logic ──────────────────────────────────────────────────────────
111
 
112
  def generate_response(message: str) -> dict:
113
  msg_lower = message.lower()
114
 
115
+ if any(k in msg_lower for k in ["calculate", "compute", "math", "roi", "compound", "interest", "%", "$"]):
 
 
116
  expr = re.search(r"[\d+\-*/.()% ]+", message)
117
+ return {"tool": "calculator", "args": {"expression": expr.group().strip() if expr else "0"}}
 
 
 
 
118
 
119
+ if any(k in msg_lower for k in ["time", "date", "now", "current"]):
120
+ return {"tool": "get_current_time", "args": {}}
 
 
 
 
 
 
121
 
122
+ if any(k in msg_lower for k in ["find", "search", "file", "look for", "where is", "list"]):
 
 
123
  pattern = re.search(r"\*\.[a-zA-Z]+", message)
124
+ return {"tool": "search_files", "args": {"path": ".", "pattern": pattern.group() if pattern else "*"}}
 
 
 
 
125
 
126
+ if any(k in msg_lower for k in ["run", "execute", "terminal", "bash", "git ", "ls ", "ps ", "docker", "command"]):
 
 
127
  match = re.search(r"`([^`]+)`", message)
128
  cmd = match.group(1) if match else message.split()[-1]
129
+ return {"tool": "run_command", "args": {"command": cmd, "cwd": "."}}
 
 
 
 
130
 
131
+ return {"tool": None, "args": {}}
 
 
 
 
 
132
 
133
  # ─── Chat Function ───────────────────────────────────────────────────────────
134
 
135
  def chat_fn(message, history):
136
  resp = generate_response(message)
137
 
138
+ if resp["tool"]:
139
+ result = execute_tool(resp["tool"], resp["args"])
140
+ call_msg = f"πŸ”§ Calling `{resp['tool']}`...\n\n```json\n{json.dumps(resp['args'], indent=2)}\n```"
141
+ result_msg = f"βœ… **{resp['tool']}** result:\n\n```\n{result}\n```"
142
+ return [[call_msg, result_msg]]
143
+
144
+ return [[message,
145
+ "Stack X Ultimate is a fine-tuned agentic model that calls tools to answer your questions. "
146
+ "Try one of the examples below to see it in action!"
147
+ ]]
148
+
149
+ # ─── Dark Theme CSS ─────────────────────────────────────────────────────────
150
+
151
+ DARK_CSS = """
152
+ :root {
153
+ --background: #0a0a0a;
154
+ --surface: #111111;
155
+ --border: #1e1e1e;
156
+ --text-primary: #ededed;
157
+ --text-secondary: #a1a1a1;
158
+ --accent: #a855f7;
159
+ --accent-hover: #9333ea;
160
+ --code-bg: #161616;
161
+ }
162
 
163
+ body, html {
164
+ background: var(--background) !important;
165
+ color: var(--text-primary) !important;
166
+ }
167
 
168
+ .gradio-container {
169
+ background: var(--background) !important;
170
+ border: none !important;
171
+ }
172
 
173
+ /* ── Chat area ── */
174
+ .chat-container, . chatbot {
175
+ background: var(--background) !important;
176
+ }
177
 
178
+ /* ── User bubble ── */
179
  .user-bubble {
180
+ background: #1e1e1e !important;
181
+ border: 1px solid #2e2e2e !important;
182
  border-radius: 12px 12px 4px 12px !important;
183
+ color: #f0f0f0 !important;
184
  padding: 10px 14px !important;
185
+ max-width: 80% !important;
186
  }
187
+
188
+ /* ── Assistant bubble ── */
189
  .assistant-bubble {
190
+ background: #141414 !important;
191
+ border: 1px solid #2a2a2a !important;
192
  border-radius: 12px 12px 12px 4px !important;
193
+ color: #e0e0e0 !important;
194
  padding: 10px 14px !important;
195
+ max-width: 80% !important;
196
  }
197
 
198
+ /* ── Input box ── */
199
  #main-input input {
200
+ background: #111111 !important;
201
+ border: 1px solid #2a2a2a !important;
202
+ border-radius: 10px !important;
203
+ color: #ffffff !important;
204
  font-size: 1rem !important;
205
  padding: 12px 16px !important;
206
  }
207
  #main-input input:focus {
208
+ border-color: var(--accent) !important;
209
  outline: none !important;
210
+ box-shadow: 0 0 0 2px rgba(168, 85, 247, 0.25) !important;
211
  }
212
 
213
+ /* ── Send button ── */
214
+ .send-btn {
215
+ background: var(--accent) !important;
216
  border: none !important;
217
  color: white !important;
218
  border-radius: 10px !important;
219
  font-weight: 600 !important;
220
+ transition: background 0.2s ease !important;
221
  }
222
+ .send-btn:hover {
223
+ background: var(--accent-hover) !important;
224
  }
225
 
226
+ /* ── Examples ── */
227
+ .examples-container {
228
+ background: #0e0e0e !important;
229
+ border: 1px solid #1e1e1e !important;
230
+ border-radius: 10px !important;
231
+ padding: 12px !important;
232
+ }
233
  .example-btn {
234
+ background: #161616 !important;
235
+ border: 1px solid #2a2a2a !important;
236
  border-radius: 8px !important;
237
+ color: #b0b0b0 !important;
238
+ font-size: 0.85rem !important;
239
  padding: 6px 12px !important;
240
  }
241
  .example-btn:hover {
242
+ background: #1e1e1e !important;
243
+ color: #ffffff !important;
244
+ border-color: var(--accent) !important;
245
  }
246
 
247
+ /* ── Hero ── */
248
+ .hero {
249
+ background: #0e0e0e !important;
250
+ border: 1px solid #1e1e1e !important;
251
  border-radius: 12px !important;
252
+ padding: 24px !important;
253
+ text-align: center !important;
254
+ margin-bottom: 16px !important;
255
+ }
256
+ .hero h1 {
257
+ font-size: 2rem !important;
258
+ font-weight: 900 !important;
259
+ color: #ffffff !important;
260
+ margin: 0 0 8px 0 !important;
261
+ }
262
+ .hero h1 span {
263
+ background: linear-gradient(135deg, #a855f7, #6366f1) !important;
264
+ -webkit-background-clip: text !important;
265
+ -webkit-text-fill-color: transparent !important;
266
+ background-clip: text !important;
267
+ }
268
+ .hero p {
269
+ color: #909090 !important;
270
+ font-size: 0.95rem !important;
271
+ margin: 0 auto !important;
272
+ max-width: 460px !important;
273
+ }
274
+
275
+ /* ── Stats bar ── */
276
+ .stats-bar {
277
  display: flex !important;
278
  justify-content: center !important;
279
+ gap: 32px !important;
280
+ padding: 16px !important;
281
  margin-bottom: 16px !important;
282
  }
283
+ .stat { text-align: center; }
284
+ .stat-val {
285
+ font-size: 1.5rem !important;
286
+ font-weight: 800 !important;
287
+ color: var(--accent) !important;
288
+ }
289
+ .stat-lbl {
290
+ font-size: 0.65rem !important;
291
+ color: #606060 !important;
292
+ text-transform: uppercase !important;
293
+ letter-spacing: 0.08em !important;
294
  }
 
295
 
296
+ /* ── Tool badges ── */
297
+ .tool-badges {
298
+ display: flex !important;
299
+ justify-content: center !important;
300
+ gap: 8px !important;
301
+ flex-wrap: wrap !important;
302
+ margin-top: 12px !important;
303
+ }
304
  .tool-badge {
305
+ background: #161616 !important;
306
+ border: 1px solid #2a2a2a !important;
307
  border-radius: 999px !important;
308
  padding: 4px 12px !important;
309
  font-size: 0.75rem !important;
310
+ color: #888888 !important;
311
  }
312
 
313
+ /* ── Footer ── */
314
+ .footer {
315
+ text-align: center !important;
316
+ color: #505050 !important;
317
+ font-size: 0.75rem !important;
318
+ padding: 14px !important;
319
+ border-top: 1px solid #1a1a1a !important;
320
+ margin-top: 16px !important;
321
+ }
322
+ .footer a { color: var(--accent) !important; text-decoration: none !important; }
323
+ .footer a:hover { text-decoration: underline !important; }
324
  """
325
 
326
+ # ─── Build UI ───────────────────────────────────────────────────────────────
327
+
328
  EXAMPLES = [
329
  ["Calculate compound interest on $1500 at 7% over 30 years"],
330
  ["What time is it right now?"],
 
334
  ]
335
 
336
  def build():
337
+ with gr.Blocks(css=DARK_CSS, theme=gr.themes.Default(primary_hue="purple"), title="Stack X Ultimate") as demo:
338
+
339
  # ── Hero ──────────────────────────────────────────────────────
340
  gr.HTML("""
341
+ <div class="hero">
342
+ <h1>πŸ€– Stack X <span>Ultimate</span></h1>
343
+ <p>Open-source agentic model with tool calling.<br>Deploy on your own GPU β€” no API key, no data leaving your server.</p>
 
 
344
  <div class="tool-badges">
345
  <span class="tool-badge">πŸ”’ calculator</span>
346
  <span class="tool-badge">πŸ• get_current_time</span>
 
349
  </div>
350
  </div>
351
  """)
352
+
353
  gr.HTML("""
354
  <div class="stats-bar">
355
+ <div class="stat"><div class="stat-val">3B</div><div class="stat-lbl">Params</div></div>
356
+ <div class="stat"><div class="stat-val">Q4</div><div class="stat-lbl">GGUF</div></div>
357
+ <div class="stat"><div class="stat-val">V100</div><div class="stat-lbl">1 GPU</div></div>
358
+ <div class="stat"><div class="stat-val">$0</div><div class="stat-lbl">API Cost</div></div>
359
+ <div class="stat"><div class="stat-val">8K</div><div class="stat-lbl">Context</div></div>
360
  </div>
361
  """)
362
 
 
378
  show_label=False,
379
  elem_id="main-input",
380
  )
381
+ send_btn = gr.Button("Send β†’", scale=1, elem_classes="send-btn")
382
+
383
+ # ── Events ────────────────────────────────────────────────────
384
+ msg.submit(chat_fn, [msg, chat], [chat])
385
+ send_btn.click(chat_fn, [msg, chat], [chat])
386
+ msg.submit(lambda: "", None, msg)
387
 
388
  # ── Examples ────────────────────────────────────────────────────
389
  gr.Examples(
 
393
  examples_per_page=5,
394
  )
395
 
396
+ # ── Footer ──────────────────────────────────────────────────────
 
 
 
 
 
 
 
 
 
397
  gr.HTML("""
398
  <div class="footer">
399
+ πŸ”§ This demo shows tool-calling capability. Fine-tuned model coming soon β€”
400
+ <a href="https://huggingface.co/my-ai-stack/Stack-X-Ultimate">Deploy the model</a> Β·
401
+ <a href="https://www.stack-ai.me/contact">Enterprise inquiry</a>
402
  </div>
403
  """)
404
 
405
  return demo
406
 
407
  if __name__ == "__main__":
408
+ build().launch(server_name="0.0.0.0", server_port=7860, max_threads=4, show_api=False)