arubaDev commited on
Commit
b2bf24a
·
verified ·
1 Parent(s): 7b03579

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -108
app.py CHANGED
@@ -13,19 +13,21 @@ MODELS = {
13
  "Mistral 7B Instruct": "mistralai/Mistral-7B-Instruct-v0.3",
14
  }
15
 
16
- DATASETS = ["The Stack", "CodeXGLUE"]
17
- HF_TOKEN = os.getenv("HF_TOKEN")
18
  DB_PATH = "history.db"
19
 
20
  SYSTEM_DEFAULT = (
21
  "You are a backend-focused coding assistant. "
22
  "Always prioritize database, API, authentication, routing, migrations, and CRUD logic. "
23
  "Provide full backend code scaffolds with files, paths, and commands. "
24
- "Only include frontend if required for framework integration."
 
 
25
  )
26
 
27
  # ---------------------------
28
- # DB Setup (unchanged)
29
  # ---------------------------
30
  def db():
31
  conn = sqlite3.connect(DB_PATH)
@@ -121,7 +123,7 @@ def update_session_title_if_needed(session_id: int, first_user_text: str):
121
  conn.close()
122
 
123
  # ---------------------------
124
- # Helpers (unchanged)
125
  # ---------------------------
126
  def label_to_id(label: str | None) -> int | None:
127
  if not label:
@@ -148,7 +150,7 @@ def load_dataset_by_name(name: str):
148
  return None
149
 
150
  # ---------------------------
151
- # Gradio Callbacks (unchanged)
152
  # ---------------------------
153
  def refresh_sessions_cb():
154
  labels, _ = list_sessions()
@@ -183,6 +185,7 @@ def is_frontend_request(user_text: str) -> bool:
183
  text_lower = user_text.lower()
184
  return any(kw in text_lower for kw in FRONTEND_KEYWORDS)
185
 
 
186
  def send_cb(user_text, selected_label, chatbot_msgs, system_message, max_tokens, temperature, top_p, model_choice, dataset_choice, *args):
187
  sid = label_to_id(selected_label)
188
  if sid is None:
@@ -190,12 +193,14 @@ def send_cb(user_text, selected_label, chatbot_msgs, system_message, max_tokens,
190
  labels, _ = list_sessions()
191
  selected_label = next((lbl for lbl in labels if lbl.startswith(f"{sid} ")), None)
192
 
 
193
  add_message(sid, "user", user_text)
194
  update_session_title_if_needed(sid, user_text)
195
 
196
  display_msgs = chatbot_msgs[:]
197
  display_msgs.append({"role": "user", "content": user_text})
198
 
 
199
  if is_frontend_request(user_text):
200
  apology = "⚠️ I'm a backend-focused assistant and cannot provide frontend code."
201
  display_msgs.append({"role": "assistant", "content": apology})
@@ -203,6 +208,7 @@ def send_cb(user_text, selected_label, chatbot_msgs, system_message, max_tokens,
203
  yield (display_msgs, "", selected_label)
204
  return
205
 
 
206
  display_msgs.append({"role": "assistant", "content": "…"})
207
  yield (display_msgs, "", selected_label)
208
 
@@ -218,6 +224,7 @@ def send_cb(user_text, selected_label, chatbot_msgs, system_message, max_tokens,
218
  top_p=float(top_p),
219
  stream=True,
220
  ):
 
221
  if not hasattr(chunk, "choices") or not chunk.choices:
222
  continue
223
  choice = chunk.choices[0]
@@ -247,6 +254,7 @@ def regenerate_cb(selected_label, system_message, max_tokens, temperature, top_p
247
  if not msgs:
248
  return [], ""
249
 
 
250
  if msgs and msgs[-1]["role"] == "assistant":
251
  conn = db()
252
  cur = conn.cursor()
@@ -277,6 +285,7 @@ def regenerate_cb(selected_label, system_message, max_tokens, temperature, top_p
277
  top_p=float(top_p),
278
  stream=True,
279
  ):
 
280
  if not hasattr(chunk, "choices") or not chunk.choices:
281
  continue
282
  choice = chunk.choices[0]
@@ -298,7 +307,7 @@ def regenerate_cb(selected_label, system_message, max_tokens, temperature, top_p
298
  yield display_msgs
299
 
300
  # ---------------------------
301
- # App UI - OPTIMIZED LAYOUT
302
  # ---------------------------
303
  init_db()
304
  labels, _ = list_sessions()
@@ -311,19 +320,6 @@ default_selected = labels[0] if labels else None
311
  with gr.Blocks(title="Backend-Focused LLaMA/Mistral CRUD Assistant", theme=gr.themes.Soft()) as demo:
312
  gr.HTML("""
313
  <style>
314
- .compact-row {
315
- margin-bottom: 0.5rem !important;
316
- }
317
- .compact-slider {
318
- margin-bottom: 0.3rem !important;
319
- }
320
- .small-textbox {
321
- margin-bottom: 0.5rem !important;
322
- }
323
- .section-header {
324
- margin-bottom: 0.5rem !important;
325
- font-weight: 600;
326
- }
327
  button {
328
  background-color: #22c55e !important;
329
  color: #ffffff !important;
@@ -336,39 +332,41 @@ with gr.Blocks(title="Backend-Focused LLaMA/Mistral CRUD Assistant", theme=gr.th
336
  outline: 2px solid #166534 !important;
337
  outline-offset: 2px;
338
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  </style>
340
  """)
341
 
342
- gr.Markdown("## 🗄️ Backend CRUD Assistant")
343
 
344
- with gr.Row():
345
- # Left sidebar - compact layout
346
- with gr.Column(scale=1, min_width=280):
347
- # Sessions section
348
- gr.Markdown("### 📁 Sessions", elem_classes=["section-header"])
349
  session_list = gr.Radio(
350
  choices=labels,
351
  value=default_selected,
352
  label="Your chats",
353
- interactive=True,
354
- elem_classes=["compact-row"]
355
  )
356
-
357
- # Session management buttons in a tight grid
358
- with gr.Row(elem_classes=["compact-row"]):
359
- new_btn = gr.Button(" New", size="sm", variant="primary")
360
- del_btn = gr.Button("🗑️ Delete", size="sm", variant="stop")
361
- refresh_btn = gr.Button("🔄", size="sm", variant="secondary")
362
-
363
- # Rename section - more compact
364
- with gr.Row(elem_classes=["compact-row"]):
365
- edit_title_box = gr.Textbox(
366
- label="✏️ Rename",
367
- placeholder="New title...",
368
- scale=3,
369
- elem_classes=["small-textbox"]
370
- )
371
- rename_btn = gr.Button("💾", size="sm", scale=1)
372
 
373
  def rename_session_cb(new_title, selected_label):
374
  sid = label_to_id(selected_label)
@@ -378,83 +376,57 @@ with gr.Blocks(title="Backend-Focused LLaMA/Mistral CRUD Assistant", theme=gr.th
378
  cur.execute("UPDATE sessions SET title=? WHERE id=?", (new_title.strip(), sid))
379
  conn.commit()
380
  conn.close()
 
 
381
  labels, _ = list_sessions()
382
  new_selected = next((lbl for lbl in labels if lbl.startswith(f"{sid} ")), None)
383
  return gr.update(choices=labels, value=new_selected)
384
 
 
385
  rename_btn.click(rename_session_cb, inputs=[edit_title_box, session_list], outputs=session_list)
386
 
387
- # Model and Dataset in a compact row
388
- with gr.Row(elem_classes=["compact-row"]):
389
- with gr.Column(scale=1):
390
- gr.Markdown("**🤖 Model**")
391
- model_choice = gr.Dropdown(
392
- choices=list(MODELS.keys()),
393
- value=list(MODELS.keys())[0],
394
- label="",
395
- interactive=True,
396
- container=False
397
- )
398
- with gr.Column(scale=1):
399
- gr.Markdown("**📚 Dataset**")
400
- dataset_choice = gr.Dropdown(
401
- choices=DATASETS,
402
- value=DATASETS[0],
403
- label="",
404
- interactive=True,
405
- container=False
406
- )
407
-
408
- # Generation Settings - more compact
409
- gr.Markdown("### ⚙️ Settings", elem_classes=["section-header"])
410
-
411
- # Compact system message
412
- system_box = gr.Textbox(
413
- value=SYSTEM_DEFAULT,
414
- label="System prompt",
415
- lines=2,
416
- max_lines=2,
417
- elem_classes=["small-textbox"]
418
- )
419
-
420
- # Sliders in compact layout
421
- max_tokens = gr.Slider(
422
- 256, 2048, value=1200, step=16,
423
- label="Max tokens",
424
- elem_classes=["compact-slider"]
425
- )
426
- temperature = gr.Slider(
427
- 0.0, 2.0, value=0.25, step=0.05,
428
- label="Temperature",
429
- elem_classes=["compact-slider"]
430
  )
431
- top_p = gr.Slider(
432
- 0.1, 1.0, value=0.9, step=0.05,
433
- label="Top-p",
434
- elem_classes=["compact-slider"]
 
 
 
435
  )
436
 
437
- # Main chat area
 
 
 
 
 
 
 
 
 
 
 
 
438
  with gr.Column(scale=3):
439
- chatbot = gr.Chatbot(
440
- label="Assistant",
441
- height=520,
442
- type="messages",
443
- show_copy_button=True
444
- )
445
  with gr.Row():
446
- user_box = gr.Textbox(
447
- placeholder="Describe your CRUD/backend task…",
448
- lines=2,
449
- max_lines=3,
450
- scale=5,
451
- container=False
452
- )
453
  with gr.Row():
454
- send_btn = gr.Button("Send ▶️", variant="primary", size="sm")
455
- regen_btn = gr.Button("Regenerate 🔁", variant="secondary", size="sm")
456
 
457
- # Event handlers (unchanged)
458
  refresh_btn.click(refresh_sessions_cb, outputs=session_list)
459
  new_btn.click(new_chat_cb, outputs=[session_list, chatbot, user_box])
460
  del_btn.click(delete_chat_cb, inputs=session_list, outputs=[session_list, chatbot])
 
13
  "Mistral 7B Instruct": "mistralai/Mistral-7B-Instruct-v0.3",
14
  }
15
 
16
+ DATASETS = ["The Stack", "CodeXGLUE"] # Dropdown for dataset selection
17
+ HF_TOKEN = os.getenv("HF_TOKEN") # Set in your Space's Secrets
18
  DB_PATH = "history.db"
19
 
20
  SYSTEM_DEFAULT = (
21
  "You are a backend-focused coding assistant. "
22
  "Always prioritize database, API, authentication, routing, migrations, and CRUD logic. "
23
  "Provide full backend code scaffolds with files, paths, and commands. "
24
+ "Only include frontend if required for framework integration "
25
+ "(e.g., Laravel Blade, Django templates). "
26
+ "If user asks for too much frontend, politely say: 'I'm a backend-focused assistant and cannot provide excessive frontend code.'"
27
  )
28
 
29
  # ---------------------------
30
+ # DB Setup
31
  # ---------------------------
32
  def db():
33
  conn = sqlite3.connect(DB_PATH)
 
123
  conn.close()
124
 
125
  # ---------------------------
126
+ # Helpers
127
  # ---------------------------
128
  def label_to_id(label: str | None) -> int | None:
129
  if not label:
 
150
  return None
151
 
152
  # ---------------------------
153
+ # Gradio Callbacks
154
  # ---------------------------
155
  def refresh_sessions_cb():
156
  labels, _ = list_sessions()
 
185
  text_lower = user_text.lower()
186
  return any(kw in text_lower for kw in FRONTEND_KEYWORDS)
187
 
188
+ # --- Fixed send_cb to show user message ---
189
  def send_cb(user_text, selected_label, chatbot_msgs, system_message, max_tokens, temperature, top_p, model_choice, dataset_choice, *args):
190
  sid = label_to_id(selected_label)
191
  if sid is None:
 
193
  labels, _ = list_sessions()
194
  selected_label = next((lbl for lbl in labels if lbl.startswith(f"{sid} ")), None)
195
 
196
+ # Save user message
197
  add_message(sid, "user", user_text)
198
  update_session_title_if_needed(sid, user_text)
199
 
200
  display_msgs = chatbot_msgs[:]
201
  display_msgs.append({"role": "user", "content": user_text})
202
 
203
+ # Check for frontend-heavy request
204
  if is_frontend_request(user_text):
205
  apology = "⚠️ I'm a backend-focused assistant and cannot provide frontend code."
206
  display_msgs.append({"role": "assistant", "content": apology})
 
208
  yield (display_msgs, "", selected_label)
209
  return
210
 
211
+ # Normal backend response
212
  display_msgs.append({"role": "assistant", "content": "…"})
213
  yield (display_msgs, "", selected_label)
214
 
 
224
  top_p=float(top_p),
225
  stream=True,
226
  ):
227
+ # --- FIX: handle models that send empty chunks or use message instead of delta ---
228
  if not hasattr(chunk, "choices") or not chunk.choices:
229
  continue
230
  choice = chunk.choices[0]
 
254
  if not msgs:
255
  return [], ""
256
 
257
+ # Remove the last assistant message if it exists (to regenerate it)
258
  if msgs and msgs[-1]["role"] == "assistant":
259
  conn = db()
260
  cur = conn.cursor()
 
285
  top_p=float(top_p),
286
  stream=True,
287
  ):
288
+ # --- FIX: handle models that send empty chunks or use message instead of delta ---
289
  if not hasattr(chunk, "choices") or not chunk.choices:
290
  continue
291
  choice = chunk.choices[0]
 
307
  yield display_msgs
308
 
309
  # ---------------------------
310
+ # App UI
311
  # ---------------------------
312
  init_db()
313
  labels, _ = list_sessions()
 
320
  with gr.Blocks(title="Backend-Focused LLaMA/Mistral CRUD Assistant", theme=gr.themes.Soft()) as demo:
321
  gr.HTML("""
322
  <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  button {
324
  background-color: #22c55e !important;
325
  color: #ffffff !important;
 
332
  outline: 2px solid #166534 !important;
333
  outline-offset: 2px;
334
  }
335
+ .compact-sliders .gr-form {
336
+ margin-bottom: 0.5rem !important;
337
+ }
338
+ .compact-sliders .gr-slider {
339
+ margin-bottom: 0.5rem !important;
340
+ }
341
+ .compact-sliders .gr-number {
342
+ margin-bottom: 0.5rem !important;
343
+ }
344
+ .system-message-compact .gr-form {
345
+ margin-bottom: 0.5rem !important;
346
+ }
347
+ .system-message-compact .gr-textarea {
348
+ min-height: 80px !important;
349
+ max-height: 120px !important;
350
+ }
351
  </style>
352
  """)
353
 
354
+ gr.Markdown("## 🗄️ LLaMA & Mistral Backend-Focused CRUD Automation — with Persistent History")
355
 
356
+ with gr.Row(equal_height=True):
357
+ with gr.Column(scale=1, min_width=260):
358
+ gr.Markdown("### 📁 Sessions")
 
 
359
  session_list = gr.Radio(
360
  choices=labels,
361
  value=default_selected,
362
  label="Your chats",
363
+ interactive=True
 
364
  )
365
+ # -----------------------
366
+ # Editable title input
367
+ # -----------------------
368
+ edit_title_box = gr.Textbox(label="✏️ Rename Chat", placeholder="Edit selected chat title...")
369
+ rename_btn = gr.Button("💾 Save Title")
 
 
 
 
 
 
 
 
 
 
 
370
 
371
  def rename_session_cb(new_title, selected_label):
372
  sid = label_to_id(selected_label)
 
376
  cur.execute("UPDATE sessions SET title=? WHERE id=?", (new_title.strip(), sid))
377
  conn.commit()
378
  conn.close()
379
+
380
+ # Refresh the session list and keep the same one selected
381
  labels, _ = list_sessions()
382
  new_selected = next((lbl for lbl in labels if lbl.startswith(f"{sid} ")), None)
383
  return gr.update(choices=labels, value=new_selected)
384
 
385
+ # Connect button to callback
386
  rename_btn.click(rename_session_cb, inputs=[edit_title_box, session_list], outputs=session_list)
387
 
388
+ with gr.Row():
389
+ new_btn = gr.Button("➕ New Chat", variant="primary")
390
+ del_btn = gr.Button("🗑️ Delete", variant="stop")
391
+ refresh_btn = gr.Button("🔄 Refresh", variant="secondary")
392
+
393
+ gr.Markdown("### 🤖 Model Selection")
394
+ model_choice = gr.Dropdown(
395
+ choices=list(MODELS.keys()),
396
+ value=list(MODELS.keys())[0],
397
+ label="Choose a model",
398
+ interactive=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  )
400
+
401
+ gr.Markdown("### 📚 Dataset Selection")
402
+ dataset_choice = gr.Dropdown(
403
+ choices=DATASETS,
404
+ value=DATASETS[0],
405
+ label="Select a dataset",
406
+ interactive=True
407
  )
408
 
409
+ gr.Markdown("### ⚙️ Generation Settings")
410
+ with gr.Group(elem_classes="system-message-compact"):
411
+ system_box = gr.Textbox(
412
+ value=SYSTEM_DEFAULT,
413
+ label="System message",
414
+ lines=3
415
+ )
416
+
417
+ with gr.Group(elem_classes="compact-sliders"):
418
+ max_tokens = gr.Slider(256, 4096, value=1200, step=16, label="Max tokens")
419
+ temperature = gr.Slider(0.0, 2.0, value=0.25, step=0.05, label="Temperature")
420
+ top_p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-p")
421
+
422
  with gr.Column(scale=3):
423
+ chatbot = gr.Chatbot(label="Assistant", height=600, type="messages")
 
 
 
 
 
424
  with gr.Row():
425
+ user_box = gr.Textbox(placeholder="Describe your CRUD/backend task…", lines=3, scale=5)
 
 
 
 
 
 
426
  with gr.Row():
427
+ send_btn = gr.Button("Send ▶️", variant="primary")
428
+ regen_btn = gr.Button("Regenerate 🔁", variant="secondary")
429
 
 
430
  refresh_btn.click(refresh_sessions_cb, outputs=session_list)
431
  new_btn.click(new_chat_cb, outputs=[session_list, chatbot, user_box])
432
  del_btn.click(delete_chat_cb, inputs=session_list, outputs=[session_list, chatbot])