broadfield-dev commited on
Commit
e8c849f
Β·
verified Β·
1 Parent(s): 5f09779

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -36
app.py CHANGED
@@ -390,23 +390,76 @@ def ui_upload_memories_action_fn(uploaded_file_obj, progress=gr.Progress()):
390
  msg = f"Memories Upload: Processed {total_to_process}. Added: {added_count}, Format Errors: {format_error_count}, Save Errors: {save_error_count}."
391
  logger.info(msg); return msg
392
 
393
- # --- UI Definition ---
394
- # Using the CSS inspired by the "AI Code & Space Generator" example
395
  custom_theme = gr.themes.Base(
396
  primary_hue="teal",
397
  secondary_hue="purple",
398
  neutral_hue="zinc",
399
- text_size="sm",
400
- spacing_size="md",
401
  radius_size="sm",
402
- font=["System UI", "sans-serif"]
403
  )
404
 
405
  custom_css = """
406
- body { background: linear-gradient(to bottom right, #2c3e50, #34495e); color: #ecf0f1; margin:0; padding:0; font-family: 'System UI', sans-serif; overflow-x: hidden;}
407
- .gradio-container { background: transparent !important; padding: 0 !important; /* Remove padding from the outermost container */ }
408
- .main-interface-wrapper { max-width: 100%; padding: 1rem; box-sizing: border-box; min-height: 100vh; display: flex; flex-direction: column;} /* New wrapper */
409
- .gr-block.gr-group, .gr-tabs, .gr-accordion { background-color: rgba(44, 62, 80, 0.8) !important; border: 1px solid rgba(189, 195, 199, 0.2) !important; border-radius: 8px !important; padding: 1em; margin-bottom: 1em;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  .gr-tabitem { background-color: rgba(52, 73, 94, 0.75) !important; border-radius: 6px !important; padding: 1em !important; border: 1px solid rgba(189, 195, 199, 0.1) !important;}
411
  .gr-textbox, .gr-dropdown, .gr-button, .gr-code, .gr-chat-message, .gr-json, .gr-file input[type="file"], .gr-file button { border-color: rgba(189, 195, 199, 0.3) !important; background-color: rgba(52, 73, 94, 0.9) !important; color: #ecf0f1 !important; border-radius: 6px !important;}
412
  .gr-textarea textarea, .gr-textbox input { color: #ecf0f1 !important; }
@@ -424,36 +477,38 @@ body { background: linear-gradient(to bottom right, #2c3e50, #34495e); color: #e
424
  .gr-chatbot .message.user { background-color: rgba(46, 204, 113, 0.9) !important; color: black !important; }
425
  .gr-input-label > .label-text, .gr-dropdown-label > .label-text { color: #bdc3c7 !important; }
426
  .status-bar { padding: 0.5rem 1rem; border-radius: 6px; margin-bottom: 1rem; background-color: rgba(44, 62, 80, 0.8) !important; }
427
- .tabnav button { background-color: rgba(52, 73, 94, 0.8) !important; color: #ecf0f1 !important; border-bottom: 2px solid transparent !important;}
428
  .tabnav button.selected { background-color: rgba(44, 62, 80, 0.95) !important; color: #1abc9c !important; border-bottom: 2px solid #1abc9c !important;}
429
- .app-title-area { padding: 0.5rem 0; text-align: center;} /* Area for title and subtitle */
 
 
 
 
430
  """
431
 
432
- with gr.Blocks(theme=custom_theme, css=custom_css, title="AI Research Agent v5.8") as demo:
433
- # Removed gr.HTML("<style>" + custom_css + "</style>") as css is passed to gr.Blocks
434
-
435
- with gr.Column(elem_classes="main-interface-wrapper"): # New overall wrapper for content
436
- with gr.Row(elem_classes="app-title-area"):
437
- gr.Markdown("# πŸ€– AI Research Agent")
438
- # Removed subtitle from here, can be added in description of Space if hosted on HF
439
 
440
  avail_provs = get_available_providers()
441
  def_prov = avail_provs[0] if avail_provs else None
442
  def_models = get_model_display_names_for_provider(def_prov) if def_prov else []
443
  def_model_disp = get_default_model_display_name_for_provider(def_prov) if def_prov else None
444
 
445
- with gr.Row(elem_classes="status-bar"):
446
  with gr.Column(scale=3): agent_stat_tb = gr.Textbox(label="Agent Status", interactive=False, lines=1, value="Initializing systems...")
447
  with gr.Column(scale=1): memory_backend_info_tb = gr.Textbox(label="Memory Backend", value=f"{MEMORY_STORAGE_BACKEND}", interactive=False)
448
- sqlite_path_display = gr.Textbox(label="SQLite Path", value=f"{MEMORY_SQLITE_PATH}", interactive=False, visible=(MEMORY_STORAGE_BACKEND == "SQLITE"), scale=2) # Use visible
449
- hf_repos_display = gr.Textbox(label="HF Repos", value=f"M: {MEMORY_HF_MEM_REPO}, R: {MEMORY_HF_RULES_REPO}", interactive=False, visible=(MEMORY_STORAGE_BACKEND == "HF_DATASET"), scale=2) # Use visible
450
 
451
- with gr.Row(equal_height=False):
452
- with gr.Sidebar(): # Using Gradio's explicit Sidebar component
453
  gr.Markdown("## βš™οΈ Configuration")
454
  with gr.Group():
455
  gr.Markdown("### AI Model Settings")
456
- api_key_tb = gr.Textbox(label="AI Provider API Key (Override)", type="password", placeholder="Uses .env if blank")
457
  prov_sel_dd = gr.Dropdown(label="AI Provider", choices=avail_provs, value=def_prov, interactive=True)
458
  model_sel_dd = gr.Dropdown(label="AI Model", choices=def_models, value=def_model_disp, interactive=True)
459
  with gr.Group():
@@ -462,39 +517,40 @@ with gr.Blocks(theme=custom_theme, css=custom_css, title="AI Research Agent v5.8
462
  if MEMORY_STORAGE_BACKEND == "RAM":
463
  save_faiss_sidebar_btn = gr.Button("Save FAISS Indices", variant="secondary")
464
 
465
- with gr.Column(scale=3): # Main content area to the right of sidebar
466
  with gr.Tabs():
467
  with gr.TabItem("πŸ’¬ AI Chat & Research Output"):
468
- gr.Markdown("### AI Chat Interface") # Using H3 for section titles within tabs
469
  main_chat_disp = gr.Chatbot(label="AI Research Chat", height=500, bubble_full_width=False, avatar_images=(None, "https://raw.githubusercontent.com/huggingface/brand-assets/main/hf-logo-with-title.png"), show_copy_button=True, render_markdown=True, sanitize_html=True)
470
  with gr.Row():
471
  user_msg_tb = gr.Textbox(show_label=False, placeholder="Ask your research question...", scale=7, lines=1, max_lines=5, autofocus=True)
472
  send_btn = gr.Button("Send", variant="primary", scale=1, min_width=100)
473
- with gr.Accordion("πŸ“ Full Response / Details", open=False):
474
  fmt_report_tb = gr.Textbox(label="Full AI Response", lines=10, interactive=True, show_copy_button=True)
475
  dl_report_btn = gr.DownloadButton("Download Report", interactive=False, visible=False)
476
  detect_out_md = gr.Markdown()
477
 
478
  with gr.TabItem("🧠 Knowledge Base Management"):
479
- gr.Markdown("### Manage Stored Knowledge")
480
  with gr.Row():
481
  with gr.Column():
482
  with gr.Group():
483
- gr.Markdown("#### πŸ“œ Rules (Insights)")
484
  rules_disp_ta = gr.TextArea(label="View/Edit Rules", lines=15, interactive=True, placeholder="Load rules or type new ones...")
485
  with gr.Row(): view_rules_btn = gr.Button("πŸ”„ Load"); save_edited_rules_btn = gr.Button("πŸ’Ύ Save Edits", variant="primary")
486
- upload_rules_fobj = gr.File(label="Upload Rules File", file_types=[".txt", ".jsonl"])
487
  rules_stat_tb = gr.Textbox(label="Rules Status", interactive=False, lines=2)
488
  clear_rules_btn = gr.Button("⚠️ Clear All Rules", variant="stop")
489
  with gr.Column():
490
  with gr.Group():
491
- gr.Markdown("#### πŸ“š Memories")
492
  mems_disp_json = gr.JSON(label="View Memories")
493
  view_mems_btn = gr.Button("πŸ”„ Load Memories")
494
- upload_mems_fobj = gr.File(label="Upload Memories File", file_types=[".jsonl"])
495
  mems_stat_tb = gr.Textbox(label="Memories Status", interactive=False, lines=2)
496
  clear_mems_btn = gr.Button("⚠️ Clear All Memories", variant="stop")
497
-
 
498
  def dyn_upd_model_dd(sel_prov_dyn:str): models_dyn, def_model_dyn = get_model_display_names_for_provider(sel_prov_dyn), get_default_model_display_name_for_provider(sel_prov_dyn); return gr.Dropdown(choices=models_dyn, value=def_model_dyn, interactive=True)
499
  prov_sel_dd.change(fn=dyn_upd_model_dd, inputs=prov_sel_dd, outputs=model_sel_dd)
500
  chat_ins = [user_msg_tb, main_chat_disp, prov_sel_dd, model_sel_dd, api_key_tb, sys_prompt_tb]
@@ -531,15 +587,13 @@ with gr.Blocks(theme=custom_theme, css=custom_css, title="AI Research Agent v5.8
531
  backend_status = f"AI Systems Initialized. Ready."
532
  rules_on_load = ui_view_rules_action_fn()
533
  mems_on_load = ui_view_memories_action_fn()
534
- # Initial visibility for conditional Textboxes based on backend
535
  vis_sqlite = MEMORY_STORAGE_BACKEND == "SQLITE"
536
  vis_hf = MEMORY_STORAGE_BACKEND == "HF_DATASET"
537
  return backend_status, rules_on_load, mems_on_load, gr.update(visible=vis_sqlite), gr.update(visible=vis_hf)
538
-
539
  demo.load(fn=app_load_fn, inputs=None, outputs=[agent_stat_tb, rules_disp_ta, mems_disp_json, sqlite_path_display, hf_repos_display])
540
 
541
  if __name__ == "__main__":
542
- logger.info(f"Starting Gradio AI Research Mega Agent (v5.8 - UI Style/Layout Update, Memory: {MEMORY_STORAGE_BACKEND})...")
543
  app_port, app_server = int(os.getenv("GRADIO_PORT", 7860)), os.getenv("GRADIO_SERVER_NAME", "127.0.0.1")
544
  app_debug, app_share = os.getenv("GRADIO_DEBUG", "False").lower()=="true", os.getenv("GRADIO_SHARE", "False").lower()=="true"
545
  logger.info(f"Launching Gradio server: http://{app_server}:{app_port}. Debug: {app_debug}, Share: {app_share}")
 
390
  msg = f"Memories Upload: Processed {total_to_process}. Added: {added_count}, Format Errors: {format_error_count}, Save Errors: {save_error_count}."
391
  logger.info(msg); return msg
392
 
393
+
 
394
  custom_theme = gr.themes.Base(
395
  primary_hue="teal",
396
  secondary_hue="purple",
397
  neutral_hue="zinc",
398
+ text_size="sm",
399
+ spacing_size="md",
400
  radius_size="sm",
401
+ font=[gr.themes.GoogleFont("Inter"), "System UI", "sans-serif"]
402
  )
403
 
404
  custom_css = """
405
+ body, html {
406
+ margin: 0 !important;
407
+ padding: 0 !important;
408
+ height: 100%;
409
+ overflow-x: hidden; /* Prevent horizontal scroll on body */
410
+ background: linear-gradient(to bottom right, #2c3e50, #34495e);
411
+ color: #ecf0f1;
412
+ font-family: 'Inter', 'System UI', sans-serif;
413
+ }
414
+
415
+ .gradio-container {
416
+ background: transparent !important;
417
+ max-width: 100% !important;
418
+ padding: 0 !important; /* Container itself has no padding */
419
+ box-sizing: border-box;
420
+ min-height: 100vh;
421
+ display: flex;
422
+ flex-direction: column;
423
+ overflow: hidden !important; /* Container does not scroll */
424
+ }
425
+
426
+ /* NEW: Attempt to override the problematic gap on main layout rows/columns */
427
+ .gradio-container > .main-interface-wrapper > .gr-row.svelte-vt1mxs, /* Target first main Row if it has the svelte class */
428
+ .gradio-container > .main-interface-wrapper > .gr-column.svelte-vt1mxs, /* Target first main Column if it has the svelte class */
429
+ .gradio-container > .main-interface-wrapper > div > .gr-row.svelte-vt1mxs, /* Deeper nesting if Gradio adds a div */
430
+ .gradio-container > .main-interface-wrapper > div > .gr-column.svelte-vt1mxs {
431
+ gap: 0 !important; /* Override the --layout-gap */
432
+ padding-top: 0 !important; /* Also ensure no top padding here */
433
+ margin-top: 0 !important; /* And no top margin */
434
+ }
435
+ /* More general override for any top-level block that might get this svelte class */
436
+ .gradio-container > .main-interface-wrapper > .gap.svelte-vt1mxs:first-child {
437
+ gap: 0 !important;
438
+ padding-top: 0 !important;
439
+ margin-top: 0 !important;
440
+ }
441
+
442
+
443
+ .main-interface-wrapper {
444
+ width: 100%; /* Ensure wrapper takes full width */
445
+ padding: 1rem; /* Overall padding for the content inside the wrapper */
446
+ box-sizing: border-box;
447
+ min-height: 100vh;
448
+ display: flex;
449
+ flex-direction: column;
450
+ overflow-y: auto; /* This is the main scrollable area */
451
+ flex-grow: 1;
452
+ }
453
+
454
+ .gr-block.gr-group, .gr-tabs, .gr-accordion {
455
+ background-color: rgba(44, 62, 80, 0.8) !important;
456
+ border: 1px solid rgba(189, 195, 199, 0.2) !important;
457
+ border-radius: 8px !important;
458
+ padding: 1em;
459
+ margin-bottom: 1em;
460
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
461
+ }
462
+ /* ... rest of your existing CSS from the last version ... */
463
  .gr-tabitem { background-color: rgba(52, 73, 94, 0.75) !important; border-radius: 6px !important; padding: 1em !important; border: 1px solid rgba(189, 195, 199, 0.1) !important;}
464
  .gr-textbox, .gr-dropdown, .gr-button, .gr-code, .gr-chat-message, .gr-json, .gr-file input[type="file"], .gr-file button { border-color: rgba(189, 195, 199, 0.3) !important; background-color: rgba(52, 73, 94, 0.9) !important; color: #ecf0f1 !important; border-radius: 6px !important;}
465
  .gr-textarea textarea, .gr-textbox input { color: #ecf0f1 !important; }
 
477
  .gr-chatbot .message.user { background-color: rgba(46, 204, 113, 0.9) !important; color: black !important; }
478
  .gr-input-label > .label-text, .gr-dropdown-label > .label-text { color: #bdc3c7 !important; }
479
  .status-bar { padding: 0.5rem 1rem; border-radius: 6px; margin-bottom: 1rem; background-color: rgba(44, 62, 80, 0.8) !important; }
480
+ .tabnav button { background-color: rgba(52, 73, 94, 0.8) !important; color: #ecf0f1 !important; border-bottom: 2px solid transparent !important; border-top-left-radius: 6px !important; border-top-right-radius: 6px !important;}
481
  .tabnav button.selected { background-color: rgba(44, 62, 80, 0.95) !important; color: #1abc9c !important; border-bottom: 2px solid #1abc9c !important;}
482
+ .app-title-area { padding: 0.5rem 0 0 0; text-align: center; margin-bottom: 0.5rem;}
483
+ #app-title { margin-bottom: 0.1rem !important; color: #ecf0f1 !important; font-size: 1.8rem !important;}
484
+ #app-subtitle { color: #bdc3c7; font-size: 0.9rem; margin-bottom: 1rem !important; }
485
+ .sidebar-column { /* No max-height, let it take natural height or be constrained by row */ overflow-y: visible; /* Let main wrapper scroll */ padding-right: 1em; }
486
+ .main-content-column { /* No max-height, let it take natural height or be constrained by row */ overflow-y: visible; }
487
  """
488
 
489
+ with gr.Blocks(theme=custom_theme, css=custom_css, title="AI Research Agent v5.9") as demo:
490
+ with gr.Column(elem_classes="main-interface-wrapper"): # This is the main scrollable wrapper
491
+ with gr.Column(elem_classes="app-title-area"): # Contains title and subtitle
492
+ gr.Markdown("# πŸ€– AI Research Agent", elem_id="app-title")
493
+ gr.Markdown("Configure AI, chat for research, and manage its knowledge base.", elem_id="app-subtitle")
 
 
494
 
495
  avail_provs = get_available_providers()
496
  def_prov = avail_provs[0] if avail_provs else None
497
  def_models = get_model_display_names_for_provider(def_prov) if def_prov else []
498
  def_model_disp = get_default_model_display_name_for_provider(def_prov) if def_prov else None
499
 
500
+ with gr.Row(elem_classes="status-bar"): # Status bar below titles
501
  with gr.Column(scale=3): agent_stat_tb = gr.Textbox(label="Agent Status", interactive=False, lines=1, value="Initializing systems...")
502
  with gr.Column(scale=1): memory_backend_info_tb = gr.Textbox(label="Memory Backend", value=f"{MEMORY_STORAGE_BACKEND}", interactive=False)
503
+ sqlite_path_display = gr.Textbox(label="SQLite Path", value=f"{MEMORY_SQLITE_PATH}", interactive=False, visible=(MEMORY_STORAGE_BACKEND == "SQLITE"), scale=2)
504
+ hf_repos_display = gr.Textbox(label="HF Repos", value=f"M: {MEMORY_HF_MEM_REPO}, R: {MEMORY_HF_RULES_REPO}", interactive=False, visible=(MEMORY_STORAGE_BACKEND == "HF_DATASET"), scale=2)
505
 
506
+ with gr.Row(equal_height=False): # Main layout: Sidebar + Content
507
+ with gr.Column(scale=1, min_width=360, elem_classes="sidebar-column"): # Explicit Sidebar Column
508
  gr.Markdown("## βš™οΈ Configuration")
509
  with gr.Group():
510
  gr.Markdown("### AI Model Settings")
511
+ api_key_tb = gr.Textbox(label="AI Provider API Key (Optional Override)", type="password", placeholder="Paste key or use .env")
512
  prov_sel_dd = gr.Dropdown(label="AI Provider", choices=avail_provs, value=def_prov, interactive=True)
513
  model_sel_dd = gr.Dropdown(label="AI Model", choices=def_models, value=def_model_disp, interactive=True)
514
  with gr.Group():
 
517
  if MEMORY_STORAGE_BACKEND == "RAM":
518
  save_faiss_sidebar_btn = gr.Button("Save FAISS Indices", variant="secondary")
519
 
520
+ with gr.Column(scale=2, elem_classes="main-content-column"): # Main Content Area
521
  with gr.Tabs():
522
  with gr.TabItem("πŸ’¬ AI Chat & Research Output"):
523
+ gr.Markdown("### AI Chat Interface")
524
  main_chat_disp = gr.Chatbot(label="AI Research Chat", height=500, bubble_full_width=False, avatar_images=(None, "https://raw.githubusercontent.com/huggingface/brand-assets/main/hf-logo-with-title.png"), show_copy_button=True, render_markdown=True, sanitize_html=True)
525
  with gr.Row():
526
  user_msg_tb = gr.Textbox(show_label=False, placeholder="Ask your research question...", scale=7, lines=1, max_lines=5, autofocus=True)
527
  send_btn = gr.Button("Send", variant="primary", scale=1, min_width=100)
528
+ with gr.Accordion("πŸ“ Full Response / Details", open=True):
529
  fmt_report_tb = gr.Textbox(label="Full AI Response", lines=10, interactive=True, show_copy_button=True)
530
  dl_report_btn = gr.DownloadButton("Download Report", interactive=False, visible=False)
531
  detect_out_md = gr.Markdown()
532
 
533
  with gr.TabItem("🧠 Knowledge Base Management"):
534
+ gr.Markdown("## Manage Stored Knowledge") # Use H2 for tab sections
535
  with gr.Row():
536
  with gr.Column():
537
  with gr.Group():
538
+ gr.Markdown("### πŸ“œ Rules (Insights)") # Use H3 for subsections
539
  rules_disp_ta = gr.TextArea(label="View/Edit Rules", lines=15, interactive=True, placeholder="Load rules or type new ones...")
540
  with gr.Row(): view_rules_btn = gr.Button("πŸ”„ Load"); save_edited_rules_btn = gr.Button("πŸ’Ύ Save Edits", variant="primary")
541
+ upload_rules_fobj = gr.File(label="Upload Rules File (.txt/.jsonl)", file_types=[".txt", ".jsonl"])
542
  rules_stat_tb = gr.Textbox(label="Rules Status", interactive=False, lines=2)
543
  clear_rules_btn = gr.Button("⚠️ Clear All Rules", variant="stop")
544
  with gr.Column():
545
  with gr.Group():
546
+ gr.Markdown("### πŸ“š Memories")
547
  mems_disp_json = gr.JSON(label="View Memories")
548
  view_mems_btn = gr.Button("πŸ”„ Load Memories")
549
+ upload_mems_fobj = gr.File(label="Upload Memories File (.jsonl)", file_types=[".jsonl"])
550
  mems_stat_tb = gr.Textbox(label="Memories Status", interactive=False, lines=2)
551
  clear_mems_btn = gr.Button("⚠️ Clear All Memories", variant="stop")
552
+
553
+ # --- Event Handlers (remain the same as your last correct version) ---
554
  def dyn_upd_model_dd(sel_prov_dyn:str): models_dyn, def_model_dyn = get_model_display_names_for_provider(sel_prov_dyn), get_default_model_display_name_for_provider(sel_prov_dyn); return gr.Dropdown(choices=models_dyn, value=def_model_dyn, interactive=True)
555
  prov_sel_dd.change(fn=dyn_upd_model_dd, inputs=prov_sel_dd, outputs=model_sel_dd)
556
  chat_ins = [user_msg_tb, main_chat_disp, prov_sel_dd, model_sel_dd, api_key_tb, sys_prompt_tb]
 
587
  backend_status = f"AI Systems Initialized. Ready."
588
  rules_on_load = ui_view_rules_action_fn()
589
  mems_on_load = ui_view_memories_action_fn()
 
590
  vis_sqlite = MEMORY_STORAGE_BACKEND == "SQLITE"
591
  vis_hf = MEMORY_STORAGE_BACKEND == "HF_DATASET"
592
  return backend_status, rules_on_load, mems_on_load, gr.update(visible=vis_sqlite), gr.update(visible=vis_hf)
 
593
  demo.load(fn=app_load_fn, inputs=None, outputs=[agent_stat_tb, rules_disp_ta, mems_disp_json, sqlite_path_display, hf_repos_display])
594
 
595
  if __name__ == "__main__":
596
+ logger.info(f"Starting Gradio AI Research Mega Agent (v5.9 - UI Layout/Scroll Fix, Memory: {MEMORY_STORAGE_BACKEND})...")
597
  app_port, app_server = int(os.getenv("GRADIO_PORT", 7860)), os.getenv("GRADIO_SERVER_NAME", "127.0.0.1")
598
  app_debug, app_share = os.getenv("GRADIO_DEBUG", "False").lower()=="true", os.getenv("GRADIO_SHARE", "False").lower()=="true"
599
  logger.info(f"Launching Gradio server: http://{app_server}:{app_port}. Debug: {app_debug}, Share: {app_share}")