ManojParvatham commited on
Commit
c467f7e
·
verified ·
1 Parent(s): ab9ff53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -329
app.py CHANGED
@@ -1,376 +1,188 @@
1
  import os
 
2
  import gradio as gr
3
- import requests
4
  import pandas as pd
5
- import re
6
- import json
7
- import math
8
- from typing import Dict, List, Any, Optional
9
- from datetime import datetime
10
-
11
- # --- Advanced Tool-Based Agent ---
12
- class ToolBasedAgent:
13
- def __init__(self):
14
- print("ToolBasedAgent initialized with multiple tools")
15
- self.available_tools = {
16
- "web_search": self.web_search_tool,
17
- "calculator": self.calculator_tool,
18
- "data_analyzer": self.data_analyzer_tool,
19
- "text_processor": self.text_processor_tool,
20
- "reasoning_engine": self.reasoning_engine_tool
21
- }
22
-
23
- def web_search_tool(self, query: str) -> str:
24
- """Simulated web search tool - in production would integrate with real APIs"""
25
- # This would integrate with:
26
- # - SerpAPI, Google Search API
27
- # - Wikipedia API
28
- # - DuckDuckGo API
29
- return f"Based on search for '{query}', the information would be retrieved from reliable sources."
30
-
31
- def calculator_tool(self, expression: str, context: str = "") -> str:
32
- """Mathematical calculation tool"""
33
- try:
34
- # Safe evaluation of mathematical expressions
35
- if re.search(r'\d+', expression):
36
- # Simple arithmetic
37
- if '+' in expression:
38
- numbers = [int(x) for x in re.findall(r'\d+', expression)]
39
- return str(sum(numbers))
40
- elif 'sum' in expression.lower():
41
- numbers = [int(x) for x in re.findall(r'\d+', expression)]
42
- return str(sum(numbers))
43
- return "Calculation requires specific numbers and operations"
44
- except:
45
- return "Unable to perform calculation with given information"
46
-
47
- def data_analyzer_tool(self, data_description: str, question: str) -> str:
48
- """Data analysis tool for structured data questions"""
49
- if 'excel' in data_description.lower() or 'sales' in question.lower():
50
- return "Data analysis would process the Excel file to calculate total food sales excluding drinks, formatted as USD with two decimals"
51
- elif 'table' in data_description.lower() or 'data' in question.lower():
52
- return "Would analyze the provided dataset to extract relevant information and perform required calculations"
53
- return "Data analysis tool ready to process structured information"
54
 
55
- def text_processor_tool(self, text: str, operation: str) -> str:
56
- """Text processing and analysis tool"""
57
- if 'extract' in operation or 'find' in operation:
58
- # Extract key entities
59
- entities = re.findall(r'[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*', text)
60
- if entities:
61
- return f"Key entities found: {', '.join(set(entities))}"
62
- return "Text analysis completed"
63
 
64
- def reasoning_engine_tool(self, question: str, context: str = "") -> str:
65
- """Advanced reasoning for complex questions"""
66
- # Analyze question structure and type
67
- question_lower = question.lower()
68
-
69
- # Historical/Research questions
70
- if any(word in question_lower for word in ['olympics', 'athletes', 'ioc']):
71
- return "Research strategy: Query Olympic databases for 1928 Summer Games participation data, find country with minimum athletes, handle ties alphabetically, return IOC code"
72
-
73
- # Sports/Player data questions
74
- elif any(word in question_lower for word in ['pitchers', 'baseball', 'number before', 'number after']):
75
- return "Research strategy: Access baseball databases to find Taishō Tamai's player number, identify adjacent players, extract and format last names in Roman characters"
76
-
77
- # Competition/Historical research
78
- elif any(word in question_lower for word in ['malko competition', 'nationality', 'country no longer exists']):
79
- return "Research strategy: Analyze Malko Competition records post-1977, identify recipients from now-defunct countries, extract first names"
80
-
81
- # Data analysis questions
82
- elif any(word in question_lower for word in ['excel', 'sales', 'total', 'usd']):
83
- return "Analysis strategy: Process the attached Excel file, separate food and drink items, sum food sales, format result in USD with two decimal places"
84
-
85
- return "Complex reasoning required: Break down question into subproblems, research relevant information, synthesize answer"
86
 
87
- def analyze_question_structure(self, question: str) -> Dict[str, Any]:
88
- """Analyze question to determine required tools and approach"""
89
- analysis = {
90
- "type": "unknown",
91
- "required_tools": [],
92
- "complexity": "medium",
93
- "needs_research": False,
94
- "needs_calculation": False,
95
- "needs_data_analysis": False
96
- }
97
-
98
- question_lower = question.lower()
99
-
100
- # Determine question type
101
- if any(word in question_lower for word in ['calculate', 'sum', 'total', 'how many']):
102
- analysis["type"] = "calculation"
103
- analysis["required_tools"].append("calculator")
104
- analysis["needs_calculation"] = True
105
-
106
- if any(word in question_lower for word in ['excel', 'data', 'table', 'sales']):
107
- analysis["type"] = "data_analysis"
108
- analysis["required_tools"].append("data_analyzer")
109
- analysis["needs_data_analysis"] = True
110
-
111
- if any(word in question_lower for word in ['who', 'what country', 'which', 'name of']):
112
- analysis["type"] = "research"
113
- analysis["required_tools"].append("web_search")
114
- analysis["required_tools"].append("reasoning_engine")
115
- analysis["needs_research"] = True
116
-
117
- if any(word in question_lower for word in ['how', 'why', 'process', 'method']):
118
- analysis["type"] = "explanation"
119
- analysis["required_tools"].append("reasoning_engine")
120
- analysis["complexity"] = "high"
121
-
122
- # Adjust complexity based on question length and structure
123
- if len(question.split()) > 20:
124
- analysis["complexity"] = "high"
125
-
126
- return analysis
127
 
128
- def __call__(self, question: str) -> str:
129
- print(f"ToolBasedAgent processing: {question[:100]}...")
130
-
131
- # Analyze the question
132
- analysis = self.analyze_question_structure(question)
133
- print(f"Question analysis: {analysis}")
134
-
135
- # Use reasoning engine for complex questions
136
- if analysis["complexity"] == "high" or analysis["needs_research"]:
137
- reasoning_result = self.reasoning_engine_tool(question)
138
-
139
- # For very specific question patterns, provide targeted responses
140
- if "IOC country code" in question and "1928 Summer Olympics" in question:
141
- return "Research required: Access Olympic historical databases to find participating countries and athlete counts for 1928 Summer Olympics, identify country with fewest athletes, handle alphabetical tie-breaking, return 3-letter IOC code"
142
-
143
- elif "Taishō Tamai" in question and "pitchers" in question:
144
- return "Research required: Query baseball reference databases to find Taishō Tamai's uniform number, locate players with adjacent numbers, extract and format last names in Roman characters as 'Pitcher Before, Pitcher After'"
145
-
146
- elif "Malko Competition" in question and "country no longer exists" in question:
147
- return "Research required: Analyze Malko Competition archives for post-1977 recipients, identify those with nationalities from now-defunct countries (e.g., USSR, Yugoslavia, etc.), return first name of matching recipient"
148
-
149
- elif "Excel" in question and "sales" in question and "USD" in question:
150
- return "Analysis required: Process the attached Excel file data, separate food items from drinks, calculate sum of food sales only, format result as USD currency with two decimal places (e.g., 1234.56)"
151
-
152
- return reasoning_result
153
-
154
- # Use calculator for mathematical questions
155
- elif analysis["needs_calculation"]:
156
- return self.calculator_tool(question, "Mathematical calculation required")
157
-
158
- # Use data analyzer for data-related questions
159
- elif analysis["needs_data_analysis"]:
160
- return self.data_analyzer_tool(question, "Data analysis required")
161
-
162
- # Default to web search for general questions
163
- else:
164
- return self.web_search_tool(question)
165
 
166
- # --- Enhanced execution function ---
167
  def run_and_submit_all(profile: gr.OAuthProfile | None):
168
  """
169
- Enhanced execution with better progress tracking and error handling
 
170
  """
171
- space_id = os.getenv("SPACE_ID")
172
-
173
- if not profile:
174
- return "Please log in to Hugging Face to submit your answers.", None
 
 
 
 
 
175
 
176
- username = profile.username
177
- api_url = "https://agents-course-unit4-scoring.hf.space"
178
  questions_url = f"{api_url}/questions"
179
  submit_url = f"{api_url}/submit"
180
 
181
- # Initialize the tool-based agent
182
- try:
183
- agent = ToolBasedAgent()
184
- print("ToolBasedAgent initialized successfully")
185
- except Exception as e:
186
- error_msg = f"Error initializing ToolBasedAgent: {str(e)}"
187
- print(error_msg)
188
- return error_msg, None
189
-
190
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
 
191
 
192
- # Fetch questions with enhanced error handling
 
193
  try:
194
- print(f"Fetching questions from {questions_url}")
195
- response = requests.get(questions_url, timeout=45)
196
  response.raise_for_status()
197
  questions_data = response.json()
198
-
199
- if not isinstance(questions_data, list):
200
- return "Invalid response format: questions data is not a list", None
201
-
202
- print(f"Successfully fetched {len(questions_data)} questions")
203
-
204
- except requests.exceptions.Timeout:
205
- return "Timeout while fetching questions. Please try again.", None
206
  except requests.exceptions.RequestException as e:
207
- return f"Network error while fetching questions: {str(e)}", None
 
 
 
 
 
208
  except Exception as e:
209
- return f"Unexpected error fetching questions: {str(e)}", None
 
210
 
211
- # Process each question with the agent
 
212
  results_log = []
213
  answers_payload = []
214
-
215
- for index, item in enumerate(questions_data):
216
  task_id = item.get("task_id")
217
- question_text = item.get("question", "").strip()
218
-
219
- if not task_id or not question_text:
220
- print(f"Skipping invalid item at index {index}")
221
  continue
222
-
223
- print(f"Processing question {index + 1}/{len(questions_data)}")
224
- print(f"Question: {question_text[:100]}...")
225
-
226
  try:
227
- # Use the tool-based agent to generate answer
228
- submitted_answer = agent(question_text)
229
-
230
- # Ensure answer is reasonable length
231
- if len(submitted_answer) > 1000:
232
- submitted_answer = submitted_answer[:1000] + "... [truncated]"
233
-
234
- answers_payload.append({
235
- "task_id": task_id,
236
- "submitted_answer": submitted_answer
237
- })
238
-
239
- results_log.append({
240
- "Task ID": task_id,
241
- "Question": question_text,
242
- "Submitted Answer": submitted_answer
243
- })
244
-
245
- print(f"Generated answer: {submitted_answer[:100]}...")
246
-
247
  except Exception as e:
248
- error_msg = f"Agent processing error: {str(e)}"
249
- print(error_msg)
250
-
251
- answers_payload.append({
252
- "task_id": task_id,
253
- "submitted_answer": error_msg
254
- })
255
-
256
- results_log.append({
257
- "Task ID": task_id,
258
- "Question": question_text,
259
- "Submitted Answer": error_msg
260
- })
261
 
262
- # Submit answers if we have any
263
  if not answers_payload:
264
- return "No answers were generated. Please check the agent implementation.", pd.DataFrame(results_log)
 
 
 
 
 
 
265
 
266
- print(f"Submitting {len(answers_payload)} answers for user: {username}")
267
-
268
- submission_data = {
269
- "username": username.strip(),
270
- "agent_code": agent_code,
271
- "answers": answers_payload
272
- }
273
-
274
  try:
275
- response = requests.post(submit_url, json=submission_data, timeout=120)
276
  response.raise_for_status()
277
  result_data = response.json()
278
-
279
  final_status = (
280
- f"Submission Successful!\n"
281
- f"👤 User: {result_data.get('username', username)}\n"
282
- f"📊 Overall Score: {result_data.get('score', 'N/A')}% "
283
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
284
- f"💬 Message: {result_data.get('message', 'No additional message')}"
285
  )
286
-
287
- print("Submission completed successfully")
288
- return final_status, pd.DataFrame(results_log)
289
-
290
  except requests.exceptions.HTTPError as e:
291
- error_msg = f"HTTP Error {e.response.status_code}: {e.response.text[:200]}"
292
- print(f"Submission failed: {error_msg}")
293
- return f"Submission Failed: {error_msg}", pd.DataFrame(results_log)
294
-
 
 
 
 
 
 
295
  except requests.exceptions.Timeout:
296
- error_msg = "Submission timeout. The server took too long to respond."
297
- print(error_msg)
298
- return error_msg, pd.DataFrame(results_log)
299
-
 
 
 
 
 
300
  except Exception as e:
301
- error_msg = f"Unexpected error during submission: {str(e)}"
302
- print(error_msg)
303
- return error_msg, pd.DataFrame(results_log)
304
-
305
- # --- Improved Gradio Interface ---
306
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
307
- gr.Markdown("""
308
- # 🚀 Advanced Tool-Based Agent System
309
-
310
- **Next-generation agent capable of handling complex, diverse questions using specialized tools**
311
-
312
- ### 🔧 Available Tools:
313
- - **Web Search**: Research and information retrieval
314
- - **Calculator**: Mathematical computations
315
- - **Data Analyzer**: Excel and structured data processing
316
- - **Text Processor**: Text analysis and entity extraction
317
- - **Reasoning Engine**: Complex problem-solving strategies
318
-
319
- ### 📝 Instructions:
320
- 1. Log in with your Hugging Face account
321
- 2. Click "Run Evaluation & Submit Answers"
322
- 3. The agent will analyze each question and use appropriate tools
323
- 4. View results and score in the output sections
324
-
325
- *Note: Processing may take several minutes for complex questions*
326
- """)
327
-
328
- with gr.Row():
329
- with gr.Column(scale=1):
330
- gr.LoginButton()
331
- status_indicator = gr.HTML("<div style='padding: 10px; border-radius: 5px; background: #f0f0f0;'>Waiting for login...</div>")
332
-
333
- with gr.Column(scale=2):
334
- run_button = gr.Button(
335
- "🚀 Run Evaluation & Submit Answers",
336
- variant="primary",
337
- size="lg"
338
- )
339
 
340
- with gr.Row():
341
- status_output = gr.Textbox(
342
- label="📊 Submission Status",
343
- lines=4,
344
- interactive=False,
345
- show_copy_button=True
346
- )
347
-
348
- with gr.Row():
349
- results_table = gr.DataFrame(
350
- label="📋 Questions and Generated Answers",
351
- wrap=True,
352
- height=400
353
- )
354
 
355
- # Update login status
356
- def update_login_status(profile):
357
- if profile:
358
- return f"<div style='padding: 10px; border-radius: 5px; background: #d4edda; color: #155724;'>✅ Logged in as: {profile.name}</div>"
359
- else:
360
- return "<div style='padding: 10px; border-radius: 5px; background: #f8d7da; color: #721c24;'>❌ Please log in to continue</div>"
361
 
362
- demo.load(
363
- fn=update_login_status,
364
- inputs=gr.OAuthProfile(),
365
- outputs=status_indicator
366
- )
367
 
368
- run_button.click(
369
- fn=run_and_submit_all,
370
- inputs=gr.OAuthProfile(),
371
- outputs=[status_output, results_table]
372
- )
373
 
374
  if __name__ == "__main__":
375
- print("🚀 Starting Advanced Tool-Based Agent System...")
376
- demo.launch(debug=True, share=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+
3
  import gradio as gr
 
4
  import pandas as pd
5
+ import requests
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ import smolagents
8
+ from agent_for_unit4 import manager_agent, prepare_for_input
 
 
 
 
 
 
9
 
10
+ # (Keep Constants as is)
11
+ # --- Constants ---
12
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
13
+ FILE_BASE_URL = "https://agents-course-unit4-scoring.hf.space/files/"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ def fix_input_text(input_text: str) -> str:
16
+ if "You're helping your manager solve a wider task:" in input_text:
17
+ input_text = input_text.split("You're helping your manager solve a wider task:")[0]
18
+ return input_text.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
 
21
  def run_and_submit_all(profile: gr.OAuthProfile | None):
22
  """
23
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
24
+ and displays the results.
25
  """
26
+ # --- Determine HF Space Runtime URL and Repo URL ---
27
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
28
+
29
+ if profile:
30
+ username = f"{profile.username}"
31
+ print(f"User logged in: {username}")
32
+ else:
33
+ print("User not logged in.")
34
+ return "Please Login to Hugging Face with the button.", None
35
 
36
+ api_url = DEFAULT_API_URL
 
37
  questions_url = f"{api_url}/questions"
38
  submit_url = f"{api_url}/submit"
39
 
40
+ # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
 
 
 
 
 
 
 
 
41
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
42
+ print(agent_code)
43
 
44
+ # 2. Fetch Questions
45
+ print(f"Fetching questions from: {questions_url}")
46
  try:
47
+ response = requests.get(questions_url, timeout=15)
 
48
  response.raise_for_status()
49
  questions_data = response.json()
50
+ if not questions_data:
51
+ print("Fetched questions list is empty.")
52
+ return "Fetched questions list is empty or invalid format.", None
53
+ print(f"Fetched {len(questions_data)} questions.")
 
 
 
 
54
  except requests.exceptions.RequestException as e:
55
+ print(f"Error fetching questions: {e}")
56
+ return f"Error fetching questions: {e}", None
57
+ except requests.exceptions.JSONDecodeError as e:
58
+ print(f"Error decoding JSON response from questions endpoint: {e}")
59
+ print(f"Response text: {response.text[:500]}")
60
+ return f"Error decoding server response for questions: {e}", None
61
  except Exception as e:
62
+ print(f"An unexpected error occurred fetching questions: {e}")
63
+ return f"An unexpected error occurred fetching questions: {e}", None
64
 
65
+ # 3. Run your Agent
66
+ print(f"smolagents version: {smolagents.__version__}")
67
  results_log = []
68
  answers_payload = []
69
+ print(f"Running agent on {len(questions_data)} questions...")
70
+ for item in questions_data:
71
  task_id = item.get("task_id")
72
+ question_text = item.get("question")
73
+ if not task_id or question_text is None:
74
+ print(f"Skipping item with missing task_id or question: {item}")
 
75
  continue
 
 
 
 
76
  try:
77
+ # === RUN AGENT ===
78
+ input_text = prepare_for_input(item, FILE_BASE_URL)
79
+ print(f"input_text:\n{input_text}")
80
+ submitted_answer = manager_agent.run(input_text)
81
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
82
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  except Exception as e:
84
+ print(f"Error running agent on task {task_id}: {e}")
85
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
 
 
 
 
 
 
 
 
 
86
 
 
87
  if not answers_payload:
88
+ print("Agent did not produce any answers to submit.")
89
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
90
+
91
+ # 4. Prepare Submission
92
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
93
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
94
+ print(status_update)
95
 
96
+ # 5. Submit
97
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
 
 
 
 
 
 
98
  try:
99
+ response = requests.post(submit_url, json=submission_data, timeout=60)
100
  response.raise_for_status()
101
  result_data = response.json()
 
102
  final_status = (
103
+ f"Submission Successful!\n"
104
+ f"User: {result_data.get('username')}\n"
105
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
106
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
107
+ f"Message: {result_data.get('message', 'No message received.')}"
108
  )
109
+ print("Submission successful.")
110
+ results_df = pd.DataFrame(results_log)
111
+ return final_status, results_df
 
112
  except requests.exceptions.HTTPError as e:
113
+ error_detail = f"Server responded with status {e.response.status_code}."
114
+ try:
115
+ error_json = e.response.json()
116
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
117
+ except requests.exceptions.JSONDecodeError:
118
+ error_detail += f" Response: {e.response.text[:500]}"
119
+ status_message = f"Submission Failed: {error_detail}"
120
+ print(status_message)
121
+ results_df = pd.DataFrame(results_log)
122
+ return status_message, results_df
123
  except requests.exceptions.Timeout:
124
+ status_message = "Submission Failed: The request timed out."
125
+ print(status_message)
126
+ results_df = pd.DataFrame(results_log)
127
+ return status_message, results_df
128
+ except requests.exceptions.RequestException as e:
129
+ status_message = f"Submission Failed: Network error - {e}"
130
+ print(status_message)
131
+ results_df = pd.DataFrame(results_log)
132
+ return status_message, results_df
133
  except Exception as e:
134
+ status_message = f"An unexpected error occurred during submission: {e}"
135
+ print(status_message)
136
+ results_df = pd.DataFrame(results_log)
137
+ return status_message, results_df
138
+
139
+
140
+ # --- Build Gradio Interface using Blocks ---
141
+ with gr.Blocks() as demo:
142
+ gr.Markdown("# Basic Agent Evaluation Runner")
143
+ gr.Markdown(
144
+ """
145
+ **Instructions:**
146
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
147
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
148
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
149
+ ---
150
+ **Disclaimers:**
151
+ Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).
152
+ This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance for the delay process of the submit button, a solution could be to cache the answers and submit in a seperate action or even to answer the questions in async.
153
+ """
154
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ gr.LoginButton()
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
 
 
 
 
 
159
 
160
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
161
+ # Removed max_rows=10 from DataFrame constructor
162
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
 
163
 
164
+ run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
 
 
 
 
165
 
166
  if __name__ == "__main__":
167
+ print("\n" + "-" * 30 + " App Starting " + "-" * 30)
168
+ # Check for SPACE_HOST and SPACE_ID at startup for information
169
+ space_host_startup = os.getenv("SPACE_HOST")
170
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
171
+
172
+ if space_host_startup:
173
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
174
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
175
+ else:
176
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
177
+
178
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
179
+ print(f"✅ SPACE_ID found: {space_id_startup}")
180
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
181
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
182
+ else:
183
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
184
+
185
+ print("-" * (60 + len(" App Starting ")) + "\n")
186
+
187
+ print("Launching Gradio Interface for Basic Agent Evaluation...")
188
+ demo.launch(debug=True, share=False)