youssefleb commited on
Commit
b7595da
·
verified ·
1 Parent(s): b3bcf15

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -37
app.py CHANGED
@@ -1,76 +1,146 @@
1
- # app.py (Smoke Test - Now with Authentication)
2
  import gradio as gr
3
  import httpx
4
  import os
 
5
 
6
  # --- Config ---
7
- # Read the BASE URL from Hugging Face secrets
8
  BLAXEL_BASE_URL = os.getenv("BLAXEL_BACKEND_URL")
9
- # Read the API KEY from Hugging Face secrets
10
  BLAXEL_API_KEY = os.getenv("BLAXEL_API_KEY")
11
 
12
  # --- Backend Client ---
13
- def call_blaxel_backend(user_problem):
 
 
 
 
 
14
 
15
- # 1. Check if the URL secret was loaded
16
- if not BLAXEL_BASE_URL:
17
- yield "Configuration Error: BLAXEL_BACKEND_URL secret is not set in Hugging Face."
18
- return
19
-
20
- # 2. Check if the API KEY secret was loaded
21
- if not BLAXEL_API_KEY:
22
- yield "Configuration Error: BLAXEL_API_KEY secret is not set in Hugging Face."
23
- yield "Please add your Blaxel API Key to the 'Secrets' section."
24
  return
25
 
26
- # 3. Construct the correct, full URL
27
  full_endpoint_url = f"{BLAXEL_BASE_URL.rstrip('/')}/solve_problem"
28
 
29
- # 4. Create the authentication headers
30
  headers = {
31
  "Authorization": f"Bearer {BLAXEL_API_KEY}",
32
  "Content-Type": "application/json"
33
  }
 
 
 
 
 
 
 
 
 
 
34
 
35
- yield f"Attempting to connect to MudabbirAI (at {full_endpoint_url})..."
36
 
37
  try:
38
- # 5. Pass the headers to the request
39
- with httpx.stream("POST", full_endpoint_url, json={"problem": user_problem}, headers=headers, timeout=60) as response:
40
 
41
  if response.status_code != 200:
42
- # Manually read the error response text
43
  error_details = response.read().decode()
44
- if response.status_code == 401 or response.status_code == 403:
45
- yield f"Authentication Error (HTTP {response.status_code}): Incorrect or invalid BLAXEL_API_KEY secret."
46
- else:
47
- yield f"HTTP Error: Received status code {response.status_code} from Blaxel."
48
- yield f"Details: {error_details}"
49
  return
50
 
51
- # If we get here, the status is 200!
 
52
  for chunk in response.iter_text():
53
- # Each chunk is a status update
54
- yield chunk
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  except httpx.ConnectError as e:
57
- yield f"Connection Error: Could not connect to Blaxel. Is the URL correct and the backend running?\nDetails: {str(e)}"
58
  except httpx.ReadTimeout:
59
- yield "Error: The connection timed out."
60
  except Exception as e:
61
- yield f"An unknown error occurred: {str(e)}"
62
 
63
- # --- Gradio UI ---
64
  with gr.Blocks() as demo:
65
- gr.Markdown("# MudabbirAI - Connection Test")
66
- problem_input = gr.Textbox(label="Enter any text to test")
67
- submit_button = gr.Button("Test Connection")
68
- status_output = gr.Textbox(label="Live Log from Blaxel", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
 
 
 
 
 
 
70
  submit_button.click(
71
  fn=call_blaxel_backend,
72
- inputs=problem_input,
73
- outputs=status_output
74
  )
75
 
76
  demo.launch()
 
1
+ # app.py (New Secure & Robust Version)
2
  import gradio as gr
3
  import httpx
4
  import os
5
+ import json
6
 
7
  # --- Config ---
8
+ # Secrets for our *own* backend
9
  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,
16
+ anthropic_key: str,
17
+ sambanova_key: str
18
+ ):
19
 
20
+ # --- 1. Validate Keys ---
21
+ if not BLAXEL_BASE_URL or not BLAXEL_API_KEY:
22
+ yield "Configuration Error: The app's own BLAXEL secrets are not set."
23
+ return
24
+
25
+ # We require at least the Google key
26
+ if not google_key:
27
+ yield {status_output: "Input Error: Please enter your Google API Key to continue. It is required for the 'Judge' agent."}
 
28
  return
29
 
30
+ # --- 2. Set up connection details ---
31
  full_endpoint_url = f"{BLAXEL_BASE_URL.rstrip('/')}/solve_problem"
32
 
 
33
  headers = {
34
  "Authorization": f"Bearer {BLAXEL_API_KEY}",
35
  "Content-Type": "application/json"
36
  }
37
+
38
+ # --- 3. Securely package the user's keys ---
39
+ payload = {
40
+ "problem": user_problem,
41
+ "keys": {
42
+ "google": google_key,
43
+ "anthropic": anthropic_key or None, # Send None if empty
44
+ "sambanova": sambanova_key or None, # Send None if empty
45
+ }
46
+ }
47
 
48
+ yield 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
+ yield {status_output: f"HTTP Error: Received status code {response.status_code} from Blaxel.\nDetails: {error_details}"}
 
 
 
 
57
  return
58
 
59
+ final_json = None
60
+ full_log = ""
61
  for chunk in response.iter_text():
62
+ if chunk.startswith("FINAL:"):
63
+ # This is our final package, don't yield it
64
+ final_json = json.loads(chunk.replace("FINAL:", ""))
65
+ else:
66
+ # This is a live log update
67
+ full_log += chunk + "\n"
68
+ yield {status_output: full_log} # Update log
69
+
70
+ # --- 4. Return final results to all UI components ---
71
+ if final_json:
72
+ yield {
73
+ status_output: full_log + "\nDone!",
74
+ final_text_output: final_json.get("text"),
75
+ final_audio_output: final_json.get("audio")
76
+ }
77
 
78
  except httpx.ConnectError as e:
79
+ yield {status_output: f"Connection Error: Could not connect to Blaxel.\nDetails: {str(e)}"}
80
  except httpx.ReadTimeout:
81
+ yield {status_output: "Error: The connection timed out. (This is a complex agent and may take several minutes.)"}
82
  except Exception as e:
83
+ yield {status_output: f"An unknown error occurred: {str(e)}"}
84
 
85
+ # --- Gradio UI (Now with Optional Keys) ---
86
  with gr.Blocks() as demo:
87
+ gr.Markdown("# MudabbirAI: The Self-Calibrating Strategic Selector")
88
+ gr.Markdown("Based on the research by Youssef Hariri (Papers 1 & 2)")
89
+
90
+ with gr.Row():
91
+ with gr.Column(scale=2):
92
+ problem_input = gr.Textbox(
93
+ label="Enter Your 'Wicked Problem'",
94
+ placeholder="e.g., 'Develop a new market entry strategy for Southeast Asia...'",
95
+ lines=5
96
+ )
97
+
98
+ gr.Markdown("### Sponsor API Keys")
99
+ gr.Markdown("Your keys are sent securely, used only for this request, and never stored.")
100
+
101
+ google_key_input = gr.Textbox(
102
+ label="Google API Key (Required)", type="password",
103
+ placeholder="Required for 'Judge' and 'default' agent"
104
+ )
105
+
106
+ with gr.Row():
107
+ anthropic_key_input = gr.Textbox(
108
+ label="Anthropic API Key (Optional)", type="password",
109
+ placeholder="Enter to enable Anthropic models"
110
+ )
111
+ sambanova_key_input = gr.Textbox(
112
+ label="SambaNova API Key (Optional)", type="password",
113
+ placeholder="Enter to enable SambaNova models"
114
+ )
115
+
116
+ submit_button = gr.Button("Deploy Agent", variant="primary")
117
+
118
+ with gr.Column(scale=1):
119
+ status_output = gr.Textbox(
120
+ label="Agent's Internal Monologue (Live Log)",
121
+ lines=20, # Made log even taller
122
+ interactive=False
123
+ )
124
+ final_text_output = gr.Markdown(label="Final Briefing")
125
+ final_audio_output = gr.Audio(label="Audio Presentation")
126
+
127
+ all_inputs = [
128
+ problem_input,
129
+ google_key_input,
130
+ anthropic_key_input,
131
+ sambanova_key_input
132
+ ]
133
 
134
+ all_outputs = {
135
+ status_output,
136
+ final_text_output,
137
+ final_audio_output
138
+ }
139
+
140
  submit_button.click(
141
  fn=call_blaxel_backend,
142
+ inputs=all_inputs,
143
+ outputs=list(all_outputs) # Convert set to list
144
  )
145
 
146
  demo.launch()