Omlesna commited on
Commit
43761d3
·
1 Parent(s): 22db229

added local files, temporarely

Browse files
Files changed (3) hide show
  1. .gitignore +2 -1
  2. agents.py +36 -14
  3. app.py +172 -132
.gitignore CHANGED
@@ -1 +1,2 @@
1
- **/__pycache__/
 
 
1
+ **/__pycache__/
2
+ validation/
agents.py CHANGED
@@ -1,21 +1,43 @@
1
 
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  # --- Basic Agent Definition ---
4
- class BasicAgent:
5
  def __init__(self):
6
  print("BasicAgent initialized.")
7
- def __call__(self, question: str) -> str:
8
- print(f"Agent received question (first 50 chars): {question[:50]}...")
9
- fixed_answer = "This is a default answer."
10
- print(f"Agent returning fixed answer: {fixed_answer}")
11
- return fixed_answer
12
-
13
 
14
- class LangAgent:
 
 
 
 
 
15
  def __init__(self):
16
- print("BasicAgent initialized.")
17
- def __call__(self, question: str) -> str:
18
- print(f"Agent received question (first 50 chars): {question[:50]}...")
19
- fixed_answer = "This is a default answer."
20
- print(f"Agent returning fixed answer: {fixed_answer}")
21
- return fixed_answer
 
 
 
 
1
 
2
 
3
+ # --- Base Agent with file support ---
4
+ class FileAwareAgent:
5
+ """
6
+ Minimal base that accepts a question and an optional file_path.
7
+ Subclasses can override `answer` to implement custom logic.
8
+ """
9
+
10
+ def __call__(self, question: str, file_path: str | None = None) -> str:
11
+ preview = question[:50] if isinstance(question, str) else str(question)[:50]
12
+ print(f"Agent received question (first 50 chars): {preview}...")
13
+ if file_path:
14
+ print(f"Agent received file_path: {file_path}")
15
+ fixed_answer = self.answer(question, file_path)
16
+ print(f"Agent returning answer: {fixed_answer}")
17
+ return fixed_answer
18
+
19
+ def answer(self, question: str, file_path: str | None = None) -> str:
20
+ raise NotImplementedError
21
+
22
+
23
  # --- Basic Agent Definition ---
24
+ class BasicAgent(FileAwareAgent):
25
  def __init__(self):
26
  print("BasicAgent initialized.")
 
 
 
 
 
 
27
 
28
+ def answer(self, question: str, file_path: str | None = None) -> str:
29
+ # Placeholder logic; replace with real solution strategy.
30
+ return "This is a default answer."
31
+
32
+
33
+ class LangAgent(FileAwareAgent):
34
  def __init__(self):
35
+ print("LangAgent initialized.")
36
+
37
+ def answer(self, question: str, file_path: str | None = None) -> str:
38
+ # Placeholder logic; replace with language-model-based solution.
39
+ if file_path:
40
+ # Keep the intent (point to the file) but fix formatting.
41
+ return f"To answer this question I should read this file: {file_path}"
42
+ else:
43
+ return "This is a default answer."
app.py CHANGED
@@ -1,185 +1,189 @@
1
  import os
2
  import gradio as gr
3
  import requests
4
- import inspect
5
  import pandas as pd
6
- from agents import BasicAgent
7
 
8
  # (Keep Constants as is)
9
  # --- Constants ---
10
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
11
 
12
 
13
- def run_and_submit_all( profile: gr.OAuthProfile | None):
14
- """
15
- Fetches all questions, runs the BasicAgent on them, submits all answers,
16
- and displays the results.
17
- """
18
- # --- Determine HF Space Runtime URL and Repo URL ---
19
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
20
-
21
- if profile:
22
- username= f"{profile.username}"
23
- print(f"User logged in: {username}")
24
- else:
25
  print("User not logged in.")
26
- return "Please Login to Hugging Face with the button.", None
 
 
 
27
 
28
- api_url = DEFAULT_API_URL
29
- questions_url = f"{api_url}/questions"
30
- submit_url = f"{api_url}/submit"
31
 
32
- # 1. Instantiate Agent ( modify this part to create your agent)
33
  try:
34
- agent = BasicAgent()
35
  except Exception as e:
36
  print(f"Error instantiating agent: {e}")
37
- return f"Error initializing agent: {e}", None
38
- # 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)
39
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
40
- print(agent_code)
 
 
41
 
42
- # 2. Fetch Questions
43
  print(f"Fetching questions from: {questions_url}")
44
  try:
45
  response = requests.get(questions_url, timeout=15)
46
  response.raise_for_status()
47
  questions_data = response.json()
48
  if not questions_data:
49
- print("Fetched questions list is empty.")
50
- return "Fetched questions list is empty or invalid format.", None
51
  print(f"Fetched {len(questions_data)} questions.")
52
- # Log a quick overview so we can debug availability, especially file_name fields.
53
- with_file = [q for q in questions_data if q.get("file_name")]
54
- without_file = len(questions_data) - len(with_file)
55
- print(f"Questions with file_name set: {len(with_file)}; without: {without_file}")
56
- for q in with_file:
57
- print(f"Task {q.get('task_id')} expects file: {q.get('file_name')}")
58
- # Probe file availability so we can see what the backend returns.
59
- for q in with_file:
60
- task_id = q.get("task_id")
61
- file_url = f"{api_url}/files/{task_id}"
62
- try:
63
- probe = requests.get(file_url, timeout=15)
64
- print(
65
- f"Attempted access to resource at {file_url} -> "
66
- f"status {probe.status_code}, "
67
- f"content-type {probe.headers.get('content-type')}, "
68
- f"bytes {len(probe.content)}"
69
- )
70
- except Exception as e:
71
- print(f"Attempted access to resource at {file_url} -> error: {e}")
72
 
73
- # Try fetching the same files from the official GAIA dataset using the HF token.
74
- gaia_repo = "gaia-benchmark/GAIA"
75
- gaia_files_cache = None
 
 
 
 
 
 
76
  try:
77
- from huggingface_hub import list_repo_files, hf_hub_download
 
 
 
 
 
 
78
  except Exception as e:
79
- print(f"Skipping GAIA file fetch (huggingface_hub not available): {e}")
80
- gaia_repo = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- if gaia_repo:
83
- # Inspect profile to locate token; also allow env var fallbacks.
 
 
 
84
  try:
85
- print("Profile keys:", list(profile.__dict__.keys()))
 
 
 
86
  except Exception as e:
87
- print(f"Could not introspect profile: {e}")
88
-
89
- token = None
90
- for attr in ("access_token", "token"):
91
- token = getattr(profile, attr, None)
92
- if token:
93
- print(f"Using token from profile.{attr}")
94
- break
95
- if not token:
96
- # Some OAuth profiles keep tokens under .tokens or .auth
97
- for attr in ("tokens", "auth"):
98
- container = getattr(profile, attr, None)
99
- if isinstance(container, dict):
100
- token = container.get("access_token") or container.get("token")
101
- if token:
102
- print(f"Using token from profile.{attr}")
103
- break
104
- if not token:
105
- token = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACEHUB_API_TOKEN") or os.getenv("HUGGINGFACE_HUB_TOKEN")
106
- if token:
107
- print("Using token from environment.")
108
-
109
- if not token:
110
- print("Skipping GAIA file fetch (no HF token found in profile or env).")
111
- else:
112
- for q in with_file:
113
- fname = q.get("file_name")
114
- task_id = q.get("task_id")
115
- if gaia_files_cache is None:
116
- try:
117
- gaia_files_cache = list_repo_files(
118
- gaia_repo, repo_type="dataset", token=token
119
- )
120
- print(f"GAIA repo file count: {len(gaia_files_cache)}")
121
- except Exception as e:
122
- print(f"Failed to list GAIA repo files: {e}")
123
- gaia_files_cache = []
124
- matches = []
125
- if gaia_files_cache:
126
- # First try an exact filename match, then any path containing the task_id.
127
- matches = [p for p in gaia_files_cache if p.endswith(fname)]
128
- if not matches:
129
- matches = [p for p in gaia_files_cache if task_id in p]
130
- if not matches:
131
- print(f"GAIA file not found for task {task_id} (looking for {fname}).")
132
- continue
133
- match_path = matches[0]
134
- try:
135
- local_path = hf_hub_download(
136
- gaia_repo,
137
- match_path,
138
- repo_type="dataset",
139
- token=token,
140
- )
141
- print(f"Downloaded GAIA file for task {task_id} to {local_path}")
142
- except Exception as e:
143
- print(f"Failed to download GAIA file for task {task_id} ({match_path}): {e}")
144
- except requests.exceptions.RequestException as e:
145
- print(f"Error fetching questions: {e}")
146
- return f"Error fetching questions: {e}", None
147
- except requests.exceptions.JSONDecodeError as e:
148
- print(f"Error decoding JSON response from questions endpoint: {e}")
149
- print(f"Response text: {response.text[:500]}")
150
- return f"Error decoding server response for questions: {e}", None
151
- except Exception as e:
152
- print(f"An unexpected error occurred fetching questions: {e}")
153
- return f"An unexpected error occurred fetching questions: {e}", None
154
 
155
- # 3. Run your Agent
 
 
 
 
 
 
 
 
 
 
 
156
  results_log = []
157
  answers_payload = []
158
  print(f"Running agent on {len(questions_data)} questions...")
159
  for item in questions_data:
160
  task_id = item.get("task_id")
161
  question_text = item.get("question")
 
 
162
  if not task_id or question_text is None:
163
  print(f"Skipping item with missing task_id or question: {item}")
164
  continue
165
  try:
166
- submitted_answer = agent(question_text)
167
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
168
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
169
  except Exception as e:
170
- print(f"Error running agent on task {task_id}: {e}")
171
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
172
 
173
- if not answers_payload:
174
- print("Agent did not produce any answers to submit.")
175
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
176
 
177
- # 4. Prepare Submission
178
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
179
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
180
  print(status_update)
181
 
182
- # 5. Submit
183
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
184
  try:
185
  response = requests.post(submit_url, json=submission_data, timeout=60)
@@ -223,6 +227,42 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
223
  return status_message, results_df
224
 
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  # --- Build Gradio Interface using Blocks ---
227
  with gr.Blocks() as demo:
228
  gr.Markdown("# Basic Agent Evaluation Runner")
 
1
  import os
2
  import gradio as gr
3
  import requests
 
4
  import pandas as pd
5
+ from agents import LangAgent
6
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
 
12
+ def resolve_user(profile: gr.OAuthProfile | None):
13
+ if not profile:
 
 
 
 
 
 
 
 
 
 
14
  print("User not logged in.")
15
+ return None, "Please Login to Hugging Face with the button."
16
+ username = f"{profile.username}"
17
+ print(f"User logged in: {username}")
18
+ return username, None
19
 
 
 
 
20
 
21
+ def build_agent():
22
  try:
23
+ return LangAgent(), None
24
  except Exception as e:
25
  print(f"Error instantiating agent: {e}")
26
+ return None, f"Error initializing agent: {e}"
27
+
28
+
29
+ def build_agent_code(space_id: str | None):
30
+ return f"https://huggingface.co/spaces/{space_id}/tree/main"
31
+
32
 
33
+ def fetch_questions(questions_url: str):
34
  print(f"Fetching questions from: {questions_url}")
35
  try:
36
  response = requests.get(questions_url, timeout=15)
37
  response.raise_for_status()
38
  questions_data = response.json()
39
  if not questions_data:
40
+ print("Fetched questions list is empty.")
41
+ return None, "Fetched questions list is empty or invalid format."
42
  print(f"Fetched {len(questions_data)} questions.")
43
+ return questions_data, None
44
+ except requests.exceptions.RequestException as e:
45
+ print(f"Error fetching questions: {e}")
46
+ return None, f"Error fetching questions: {e}"
47
+ except requests.exceptions.JSONDecodeError as e:
48
+ print(f"Error decoding JSON response from questions endpoint: {e}")
49
+ return None, f"Error decoding server response for questions: {e}"
50
+ except Exception as e:
51
+ print(f"An unexpected error occurred fetching questions: {e}")
52
+ return None, f"An unexpected error occurred fetching questions: {e}"
 
 
 
 
 
 
 
 
 
 
53
 
54
+
55
+ def log_backend_file_status(with_file, total_count: int, api_url: str):
56
+ without_file = total_count - len(with_file)
57
+ print(f"Questions with file_name set: {len(with_file)}; without: {without_file}")
58
+ for q in with_file:
59
+ print(f"Task {q.get('task_id')} expects file: {q.get('file_name')}")
60
+ for q in with_file:
61
+ task_id = q.get("task_id")
62
+ file_url = f"{api_url}/files/{task_id}"
63
  try:
64
+ probe = requests.get(file_url, timeout=15)
65
+ print(
66
+ f"Attempted access to resource at {file_url} -> "
67
+ f"status {probe.status_code}, "
68
+ f"content-type {probe.headers.get('content-type')}, "
69
+ f"bytes {len(probe.content)}"
70
+ )
71
  except Exception as e:
72
+ print(f"Attempted access to resource at {file_url} -> error: {e}")
73
+
74
+
75
+ def get_hf_token(profile: gr.OAuthProfile | None):
76
+ token = None
77
+ if profile:
78
+ for attr in ("access_token", "token"):
79
+ token = getattr(profile, attr, None)
80
+ if token:
81
+ print(f"Using token from profile.{attr}")
82
+ break
83
+ if not token:
84
+ for attr in ("tokens", "auth"):
85
+ container = getattr(profile, attr, None)
86
+ if isinstance(container, dict):
87
+ token = container.get("access_token") or container.get("token")
88
+ if token:
89
+ print(f"Using token from profile.{attr}")
90
+ break
91
+ if not token:
92
+ token = (
93
+ os.getenv("HF_TOKEN")
94
+ or os.getenv("HUGGINGFACEHUB_API_TOKEN")
95
+ or os.getenv("HUGGINGFACE_HUB_TOKEN")
96
+ )
97
+ if token:
98
+ print("Using token from environment.")
99
+ return token
100
+
101
+
102
+ def try_fetch_from_gaia(with_file, profile: gr.OAuthProfile | None):
103
+ gaia_repo = "gaia-benchmark/GAIA"
104
+ try:
105
+ from huggingface_hub import list_repo_files, hf_hub_download
106
+ except Exception as e:
107
+ print(f"Skipping GAIA file fetch (huggingface_hub not available): {e}")
108
+ return
109
+
110
+ token = get_hf_token(profile)
111
+ if not token:
112
+ print("Skipping GAIA file fetch (no HF toLangAgentken found in profile or env).")
113
+ return
114
 
115
+ gaia_files_cache = None
116
+ for q in with_file:
117
+ fname = q.get("file_name")
118
+ task_id = q.get("task_id")
119
+ if gaia_files_cache is None:
120
  try:
121
+ gaia_files_cache = list_repo_files(
122
+ gaia_repo, repo_type="dataset", token=token
123
+ )
124
+ print(f"GAIA repo file count: {len(gaia_files_cache)}")
125
  except Exception as e:
126
+ print(f"Failed to list GAIA repo files: {e}")
127
+ gaia_files_cache = []
128
+ matches = []
129
+ if gaia_files_cache:
130
+ matches = [p for p in gaia_files_cache if p.endswith(fname)]
131
+ if not matches:
132
+ matches = [p for p in gaia_files_cache if task_id in p]
133
+ if not matches:
134
+ print(f"GAIA file not found for task {task_id} (looking for {fname}).")
135
+ continue
136
+ match_path = matches[0]
137
+ try:
138
+ local_path = hf_hub_download(
139
+ gaia_repo,
140
+ match_path,
141
+ repo_type="dataset",
142
+ token=token,
143
+ )
144
+ print(f"Downloaded GAIA file for task {task_id} to {local_path}")
145
+ except Exception as e:
146
+ print(f"Failed to download GAIA file for task {task_id} ({match_path}): {e}")
147
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
+ def resolve_local_file(file_name: str | None):
150
+ if not file_name:
151
+ return None
152
+ candidate = os.path.join("validation", file_name)
153
+ if os.path.exists(candidate):
154
+ print(f"Local file found: {candidate}")
155
+ return candidate
156
+ print(f"No local file found (expected {candidate})")
157
+ return None
158
+
159
+
160
+ def run_agent_on_questions(agent, questions_data):
161
  results_log = []
162
  answers_payload = []
163
  print(f"Running agent on {len(questions_data)} questions...")
164
  for item in questions_data:
165
  task_id = item.get("task_id")
166
  question_text = item.get("question")
167
+ file_name = item.get("file_name")
168
+ file_path = resolve_local_file(file_name)
169
  if not task_id or question_text is None:
170
  print(f"Skipping item with missing task_id or question: {item}")
171
  continue
172
  try:
173
+ submitted_answer = agent(question_text, file_path=file_path)
174
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
175
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
176
  except Exception as e:
177
+ print(f"Error running agent on task {task_id}: {e}")
178
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
179
+ return answers_payload, results_log
180
 
 
 
 
181
 
182
+ def submit_answers(submit_url: str, username: str, agent_code: str, answers_payload, results_log):
183
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
184
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
185
  print(status_update)
186
 
 
187
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
188
  try:
189
  response = requests.post(submit_url, json=submission_data, timeout=60)
 
227
  return status_message, results_df
228
 
229
 
230
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
231
+ """
232
+ Fetch questions, run the agent, and submit answers.
233
+ """
234
+ space_id = os.getenv("SPACE_ID")
235
+ api_url = DEFAULT_API_URL
236
+ questions_url = f"{api_url}/questions"
237
+ submit_url = f"{api_url}/submit"
238
+
239
+ username, user_error = resolve_user(profile)
240
+ if user_error:
241
+ return user_error, None
242
+
243
+ agent, agent_error = build_agent()
244
+ if agent_error:
245
+ return agent_error, None
246
+
247
+ agent_code = build_agent_code(space_id)
248
+ print(agent_code)
249
+
250
+ questions_data, fetch_error = fetch_questions(questions_url)
251
+ if fetch_error:
252
+ return fetch_error, None
253
+
254
+ with_file = [q for q in questions_data if q.get("file_name")]
255
+ log_backend_file_status(with_file, len(questions_data), api_url)
256
+ try_fetch_from_gaia(with_file, profile)
257
+
258
+ answers_payload, results_log = run_agent_on_questions(agent, questions_data)
259
+ if not answers_payload:
260
+ print("Agent did not produce any answers to submit.")
261
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
262
+
263
+ return submit_answers(submit_url, username, agent_code, answers_payload, results_log)
264
+
265
+
266
  # --- Build Gradio Interface using Blocks ---
267
  with gr.Blocks() as demo:
268
  gr.Markdown("# Basic Agent Evaluation Runner")