# app.py (Neutral Version: No Theme to prevent version conflicts) import gradio as gr import httpx import os import json import subprocess from visuals import create_progress_chart, create_calibration_table, create_cost_summary import config # --- Config --- BLAXEL_BASE_URL = os.getenv("BLAXEL_BACKEND_URL") BLAXEL_API_KEY = os.getenv("BLAXEL_API_KEY") # --- Backend Client --- def call_blaxel_backend(user_problem, google_key, anthropic_key, sambanova_key, openai_key, nebius_key): # 1. DEBUG: Check Server Config if not BLAXEL_BASE_URL: yield {status_output: "❌ ERROR: 'BLAXEL_BACKEND_URL' is missing from Secrets."} return if not BLAXEL_API_KEY: yield {status_output: "❌ ERROR: 'BLAXEL_API_KEY' is missing from Secrets."} return # 2. DEBUG: Check User Input if not google_key: yield {status_output: "❌ ERROR: You must enter a Google API Key in the text box."} return full_endpoint_url = f"{BLAXEL_BASE_URL.rstrip('/')}/solve_problem" headers = { "Authorization": f"Bearer {BLAXEL_API_KEY}", "Content-Type": "application/json" } # 3. Construct Payload payload = { "problem": user_problem, "keys": { "google": google_key, "anthropic": anthropic_key or None, "sambanova": sambanova_key or None, "openai": openai_key or None, "nebius": nebius_key or None, } } yield {status_output: f"Connecting to Agent at: {full_endpoint_url}..."} try: with httpx.stream("POST", full_endpoint_url, json=payload, headers=headers, timeout=120.0) as response: if response.status_code != 200: yield {status_output: f"❌ HTTP Error {response.status_code}: {response.text}"} return final_json = None full_log = "" for line in response.iter_lines(): if not line: continue if hasattr(line, "decode"): line = line.decode("utf-8") if line.startswith(":"): continue if line.startswith("data: "): content = line.replace("data: ", "", 1).strip() if content.startswith("FINAL:"): try: json_str = content.replace("FINAL:", "", 1) final_json = json.loads(json_str) except json.JSONDecodeError as e: full_log += f"\n[JSON Error]: {e}" else: full_log += content + "\n" yield {status_output: full_log} if final_json: log_data = final_json.get("log") yield { status_output: full_log + "\n✅ Done!", final_text_output: final_json.get("text"), final_json_log: log_data, progress_plot: create_progress_chart(log_data), calibration_data: create_calibration_table(log_data), cost_display: create_cost_summary(log_data) } except Exception as e: yield {status_output: f"❌ Connection Failed: {str(e)}"} # --- UI Layout --- def get_model_info(): # Use safe access to config in case keys are missing judge = config.MODELS.get('Gemini', {}).get('judge', 'Gemini 2.0 Flash') return f"### 🤖 System Config\nJudge: {judge}" # REMOVED THEME ARGUMENT BELOW TO FIX CRASH with gr.Blocks() as demo: gr.Markdown("# 🧠 MudabbirAI") with gr.Row(): with gr.Column(scale=2): problem_input = gr.Textbox(label="Business Problem", lines=4) with gr.Accordion("API Keys", open=True): google_key_input = gr.Textbox(label="Google API Key (Gemini 2.0 Flash) Required", type="password") # New providers with gr.Row(): anthropic_key_input = gr.Textbox(label="Anthropic Key (Claude 3.5 Haiku 202421022)", type="password") sambanova_key_input = gr.Textbox(label="SambaNova Key (Llama 4 Maverick 17B 128E Instruct)", type="password") with gr.Row(): openai_key_input = gr.Textbox(label="OpenAI Key (GPT-4o-mini)", type="password") nebius_key_input = gr.Textbox(label="Nebius Key (Qwen 3 235B A22B Thinking 2507)", type="password") with gr.Column(scale=1): gr.Markdown(get_model_info()) submit_button = gr.Button("🧠 Launch System", variant="primary") # Outputs with gr.Tabs(): with gr.TabItem("Dashboard"): progress_plot = gr.Plot() calibration_data = gr.Dataframe() cost_display = gr.Markdown() with gr.TabItem("Result"): final_text_output = gr.Markdown() with gr.TabItem("Logs"): status_output = gr.Textbox(lines=10, autoscroll=True) final_json_log = gr.JSON() submit_button.click( fn=call_blaxel_backend, inputs=[problem_input, google_key_input, anthropic_key_input, sambanova_key_input, openai_key_input, nebius_key_input], outputs=[status_output, final_text_output, final_json_log, progress_plot, calibration_data, cost_display] ) demo.launch()