Spaces:
Running
Running
| # app.py (New Secure & Robust Version) | |
| import gradio as gr | |
| import httpx | |
| import os | |
| import json | |
| # --- Config --- | |
| # Secrets for our *own* backend | |
| BLAXEL_BASE_URL = os.getenv("BLAXEL_BACKEND_URL") | |
| BLAXEL_API_KEY = os.getenv("BLAXEL_API_KEY") | |
| # --- Backend Client --- | |
| def call_blaxel_backend( | |
| user_problem: str, | |
| google_key: str, | |
| anthropic_key: str, | |
| sambanova_key: str | |
| ): | |
| # --- 1. Validate Keys --- | |
| if not BLAXEL_BASE_URL or not BLAXEL_API_KEY: | |
| yield "Configuration Error: The app's own BLAXEL secrets are not set." | |
| return | |
| # We require at least the Google key | |
| if not google_key: | |
| yield {status_output: "Input Error: Please enter your Google API Key to continue. It is required for the 'Judge' agent."} | |
| return | |
| # --- 2. Set up connection details --- | |
| full_endpoint_url = f"{BLAXEL_BASE_URL.rstrip('/')}/solve_problem" | |
| headers = { | |
| "Authorization": f"Bearer {BLAXEL_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| # --- 3. Securely package the user's keys --- | |
| payload = { | |
| "problem": user_problem, | |
| "keys": { | |
| "google": google_key, | |
| "anthropic": anthropic_key or None, # Send None if empty | |
| "sambanova": sambanova_key or None, # Send None if empty | |
| } | |
| } | |
| yield f"Connecting to MudabbirAI (at {full_endpoint_url})..." | |
| try: | |
| # Set a long timeout for all the LLM calls | |
| with httpx.stream("POST", full_endpoint_url, json=payload, headers=headers, timeout=300.0) as response: | |
| if response.status_code != 200: | |
| error_details = response.read().decode() | |
| yield {status_output: f"HTTP Error: Received status code {response.status_code} from Blaxel.\nDetails: {error_details}"} | |
| return | |
| final_json = None | |
| full_log = "" | |
| for chunk in response.iter_text(): | |
| if chunk.startswith("FINAL:"): | |
| # This is our final package, don't yield it | |
| final_json = json.loads(chunk.replace("FINAL:", "")) | |
| else: | |
| # This is a live log update | |
| full_log += chunk + "\n" | |
| yield {status_output: full_log} # Update log | |
| # --- 4. Return final results to all UI components --- | |
| if final_json: | |
| yield { | |
| status_output: full_log + "\nDone!", | |
| final_text_output: final_json.get("text"), | |
| final_audio_output: final_json.get("audio") | |
| } | |
| except httpx.ConnectError as e: | |
| yield {status_output: f"Connection Error: Could not connect to Blaxel.\nDetails: {str(e)}"} | |
| except httpx.ReadTimeout: | |
| yield {status_output: "Error: The connection timed out. (This is a complex agent and may take several minutes.)"} | |
| except Exception as e: | |
| yield {status_output: f"An unknown error occurred: {str(e)}"} | |
| # --- Gradio UI (Now with Optional Keys) --- | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# MudabbirAI: The Self-Calibrating Strategic Selector") | |
| gr.Markdown("Based on the research by Youssef Hariri (Papers 1 & 2)") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| problem_input = gr.Textbox( | |
| label="Enter Your 'Wicked Problem'", | |
| placeholder="e.g., 'Develop a new market entry strategy for Southeast Asia...'", | |
| lines=5 | |
| ) | |
| gr.Markdown("### Sponsor API Keys") | |
| gr.Markdown("Your keys are sent securely, used only for this request, and never stored.") | |
| google_key_input = gr.Textbox( | |
| label="Google API Key (Required)", type="password", | |
| placeholder="Required for 'Judge' and 'default' agent" | |
| ) | |
| with gr.Row(): | |
| anthropic_key_input = gr.Textbox( | |
| label="Anthropic API Key (Optional)", type="password", | |
| placeholder="Enter to enable Anthropic models" | |
| ) | |
| sambanova_key_input = gr.Textbox( | |
| label="SambaNova API Key (Optional)", type="password", | |
| placeholder="Enter to enable SambaNova models" | |
| ) | |
| submit_button = gr.Button("Deploy Agent", variant="primary") | |
| with gr.Column(scale=1): | |
| status_output = gr.Textbox( | |
| label="Agent's Internal Monologue (Live Log)", | |
| lines=20, # Made log even taller | |
| interactive=False | |
| ) | |
| final_text_output = gr.Markdown(label="Final Briefing") | |
| final_audio_output = gr.Audio(label="Audio Presentation") | |
| all_inputs = [ | |
| problem_input, | |
| google_key_input, | |
| anthropic_key_input, | |
| sambanova_key_input | |
| ] | |
| all_outputs = { | |
| status_output, | |
| final_text_output, | |
| final_audio_output | |
| } | |
| submit_button.click( | |
| fn=call_blaxel_backend, | |
| inputs=all_inputs, | |
| outputs=list(all_outputs) # Convert set to list | |
| ) | |
| demo.launch() |