youssefleb commited on
Commit
ea5d6dc
·
verified ·
1 Parent(s): 3066f82

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -32
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py (New Secure & Robust Version - Gradio FIX)
2
  import gradio as gr
3
  import httpx
4
  import os
@@ -10,6 +10,8 @@ BLAXEL_BASE_URL = os.getenv("BLAXEL_BACKEND_URL")
10
  BLAXEL_API_KEY = os.getenv("BLAXEL_API_KEY")
11
 
12
  # --- Backend Client ---
 
 
13
  def call_blaxel_backend(
14
  user_problem: str,
15
  google_key: str,
@@ -17,7 +19,6 @@ def call_blaxel_backend(
17
  sambanova_key: str
18
  ):
19
 
20
- # --- 1. Validate Keys (FIX: All yields are now dictionaries) ---
21
  if not BLAXEL_BASE_URL or not BLAXEL_API_KEY:
22
  yield {status_output: "Configuration Error: The app's own BLAXEL secrets are not set in Hugging Face."}
23
  return
@@ -26,7 +27,6 @@ def call_blaxel_backend(
26
  yield {status_output: "Input Error: Please enter your Google API Key. It is required for the 'Judge' agent."}
27
  return
28
 
29
- # --- 2. Set up connection details ---
30
  full_endpoint_url = f"{BLAXEL_BASE_URL.rstrip('/')}/solve_problem"
31
 
32
  headers = {
@@ -34,7 +34,6 @@ def call_blaxel_backend(
34
  "Content-Type": "application/json"
35
  }
36
 
37
- # --- 3. Securely package the user's keys ---
38
  payload = {
39
  "problem": user_problem,
40
  "keys": {
@@ -44,16 +43,13 @@ def call_blaxel_backend(
44
  }
45
  }
46
 
47
- # FIX: Yield a dictionary
48
  yield {status_output: f"Connecting to MudabbirAI (at {full_endpoint_url})..."}
49
 
50
  try:
51
- # Set a long timeout for all the LLM calls
52
  with httpx.stream("POST", full_endpoint_url, json=payload, headers=headers, timeout=300.0) as response:
53
 
54
  if response.status_code != 200:
55
  error_details = response.read().decode()
56
- # FIX: Yield a dictionary
57
  yield {status_output: f"HTTP Error: Received status code {response.status_code} from Blaxel.\nDetails: {error_details}"}
58
  return
59
 
@@ -64,10 +60,8 @@ def call_blaxel_backend(
64
  final_json = json.loads(chunk.replace("FINAL:", ""))
65
  else:
66
  full_log += chunk + "\n"
67
- # FIX: Yield a dictionary to update just the log
68
  yield {status_output: full_log}
69
 
70
- # --- 4. Return final results to all UI components ---
71
  if final_json:
72
  yield {
73
  status_output: full_log + "\nDone!",
@@ -75,7 +69,6 @@ def call_blaxel_backend(
75
  final_audio_output: final_json.get("audio")
76
  }
77
 
78
- # FIX: All except blocks now yield dictionaries
79
  except httpx.ConnectError as e:
80
  yield {status_output: f"Connection Error: Could not connect to Blaxel.\nDetails: {str(e)}"}
81
  except httpx.ReadTimeout:
@@ -83,27 +76,26 @@ def call_blaxel_backend(
83
  except Exception as e:
84
  yield {status_output: f"An unknown error occurred: {str(e)}"}
85
 
86
- # --- Gradio UI (Now with Optional Keys) ---
87
- with gr.Blocks() as demo:
88
  gr.Markdown("# MudabbirAI: The Self-Calibrating Strategic Selector")
89
  gr.Markdown("Based on the research by Youssef Hariri (Papers 1 & 2)")
90
 
91
- with gr.Row():
92
- with gr.Column(scale=2):
93
- problem_input = gr.Textbox(
94
- label="Enter Your 'Wicked Problem'",
95
- placeholder="e.g., 'Develop a new market entry strategy for Southeast Asia...'",
96
- lines=5
97
- )
98
-
99
- gr.Markdown("### Sponsor API Keys")
 
100
  gr.Markdown("Your keys are sent securely, used only for this request, and never stored.")
101
-
102
  google_key_input = gr.Textbox(
103
  label="Google API Key (Required)", type="password",
104
  placeholder="Required for 'Judge' and 'default' agent"
105
  )
106
-
107
  with gr.Row():
108
  anthropic_key_input = gr.Textbox(
109
  label="Anthropic API Key (Optional)", type="password",
@@ -113,18 +105,23 @@ with gr.Blocks() as demo:
113
  label="SambaNova API Key (Optional)", type="password",
114
  placeholder="Enter to enable SambaNova models"
115
  )
116
-
117
- submit_button = gr.Button("Deploy Agent", variant="primary")
118
 
119
- with gr.Column(scale=1):
 
 
120
  status_output = gr.Textbox(
121
- label="Agent's Internal Monologue (Live Log)",
122
  lines=20,
123
- interactive=False
 
124
  )
125
- final_text_output = gr.Markdown(label="Final Briefing")
 
 
126
  final_audio_output = gr.Audio(label="Audio Presentation")
127
-
128
  all_inputs = [
129
  problem_input,
130
  google_key_input,
@@ -132,7 +129,6 @@ with gr.Blocks() as demo:
132
  sambanova_key_input
133
  ]
134
 
135
- # FIX: Define outputs as a stable LIST, not an unordered set
136
  all_outputs = [
137
  status_output,
138
  final_text_output,
@@ -142,7 +138,7 @@ with gr.Blocks() as demo:
142
  submit_button.click(
143
  fn=call_blaxel_backend,
144
  inputs=all_inputs,
145
- outputs=all_outputs # Pass the list
146
  )
147
 
148
  demo.launch()
 
1
+ # app.py (New Secure & Robust Version - with Tabs)
2
  import gradio as gr
3
  import httpx
4
  import os
 
10
  BLAXEL_API_KEY = os.getenv("BLAXEL_API_KEY")
11
 
12
  # --- Backend Client ---
13
+ # This function does not need to change.
14
+ # Its dictionary-based yields will work perfectly with the new tabs.
15
  def call_blaxel_backend(
16
  user_problem: str,
17
  google_key: str,
 
19
  sambanova_key: str
20
  ):
21
 
 
22
  if not BLAXEL_BASE_URL or not BLAXEL_API_KEY:
23
  yield {status_output: "Configuration Error: The app's own BLAXEL secrets are not set in Hugging Face."}
24
  return
 
27
  yield {status_output: "Input Error: Please enter your Google API Key. It is required for the 'Judge' agent."}
28
  return
29
 
 
30
  full_endpoint_url = f"{BLAXEL_BASE_URL.rstrip('/')}/solve_problem"
31
 
32
  headers = {
 
34
  "Content-Type": "application/json"
35
  }
36
 
 
37
  payload = {
38
  "problem": user_problem,
39
  "keys": {
 
43
  }
44
  }
45
 
 
46
  yield {status_output: f"Connecting to MudabbirAI (at {full_endpoint_url})..."}
47
 
48
  try:
 
49
  with httpx.stream("POST", full_endpoint_url, json=payload, headers=headers, timeout=300.0) as response:
50
 
51
  if response.status_code != 200:
52
  error_details = response.read().decode()
 
53
  yield {status_output: f"HTTP Error: Received status code {response.status_code} from Blaxel.\nDetails: {error_details}"}
54
  return
55
 
 
60
  final_json = json.loads(chunk.replace("FINAL:", ""))
61
  else:
62
  full_log += chunk + "\n"
 
63
  yield {status_output: full_log}
64
 
 
65
  if final_json:
66
  yield {
67
  status_output: full_log + "\nDone!",
 
69
  final_audio_output: final_json.get("audio")
70
  }
71
 
 
72
  except httpx.ConnectError as e:
73
  yield {status_output: f"Connection Error: Could not connect to Blaxel.\nDetails: {str(e)}"}
74
  except httpx.ReadTimeout:
 
76
  except Exception as e:
77
  yield {status_output: f"An unknown error occurred: {str(e)}"}
78
 
79
+ # --- Gradio UI (New Tabbed Layout) ---
80
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="neutral")) as demo:
81
  gr.Markdown("# MudabbirAI: The Self-Calibrating Strategic Selector")
82
  gr.Markdown("Based on the research by Youssef Hariri (Papers 1 & 2)")
83
 
84
+ # --- Section 1: Inputs ---
85
+ with gr.Group():
86
+ problem_input = gr.Textbox(
87
+ label="1. Enter Your 'Wicked Problem'",
88
+ placeholder="e.g., 'Develop a new market entry strategy for Southeast Asia...'",
89
+ lines=5
90
+ )
91
+
92
+ # Use an Accordion to hide the keys, matching the "simple on outside" philosophy
93
+ with gr.Accordion("2. Sponsor API Keys (Expand to Enter)", open=False):
94
  gr.Markdown("Your keys are sent securely, used only for this request, and never stored.")
 
95
  google_key_input = gr.Textbox(
96
  label="Google API Key (Required)", type="password",
97
  placeholder="Required for 'Judge' and 'default' agent"
98
  )
 
99
  with gr.Row():
100
  anthropic_key_input = gr.Textbox(
101
  label="Anthropic API Key (Optional)", type="password",
 
105
  label="SambaNova API Key (Optional)", type="password",
106
  placeholder="Enter to enable SambaNova models"
107
  )
108
+
109
+ submit_button = gr.Button("Deploy Agent", variant="primary")
110
 
111
+ # --- Section 2 & 3: Outputs (Separated by Tabs) ---
112
+ with gr.Tabs():
113
+ with gr.TabItem("Agent's Internal Monologue", id="log_tab"):
114
  status_output = gr.Textbox(
115
+ label="Live Log",
116
  lines=20,
117
+ interactive=False,
118
+ autoscroll=True
119
  )
120
+
121
+ with gr.TabItem("Final Briefing", id="result_tab"):
122
+ final_text_output = gr.Markdown(label="Final Polished Briefing")
123
  final_audio_output = gr.Audio(label="Audio Presentation")
124
+
125
  all_inputs = [
126
  problem_input,
127
  google_key_input,
 
129
  sambanova_key_input
130
  ]
131
 
 
132
  all_outputs = [
133
  status_output,
134
  final_text_output,
 
138
  submit_button.click(
139
  fn=call_blaxel_backend,
140
  inputs=all_inputs,
141
+ outputs=all_outputs
142
  )
143
 
144
  demo.launch()