Raffaele Terribile commited on
Commit
a71669e
·
unverified ·
1 Parent(s): bb5402f

Aggiungi utilizzo di modello locale

Browse files
Files changed (2) hide show
  1. app.py +231 -208
  2. requirements.txt +11 -1
app.py CHANGED
@@ -4,7 +4,7 @@ import requests
4
  import inspect
5
  import pandas as pd
6
 
7
- from smolagents import CodeAgent, InferenceClientModel, VisitWebpageTool, PythonInterpreterTool, WebSearchTool, WikipediaSearchTool, FinalAnswerTool, Tool, tool # GoogleSearchTool (usa SERPAPI_API_KEY), DuckDuckGoSearchTool
8
 
9
  # (Keep Constants as is)
10
  # --- Constants ---
@@ -12,232 +12,255 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
  @tool
14
  def invert_sentence(sentence: str) -> str:
15
- """
16
- Inverts the order of all characters in a sentence.
17
- Args:
18
- sentence (str): The sentence to invert.
19
- Returns:
20
- str: The sentence with characters in reverse order.
21
- """
22
- return sentence[::-1]
23
 
24
  # --- First Agent Definition ---
25
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
26
  class FirstAgent:
27
- ### First Agent is the first attempt to develop an agent for the course. ###
28
- def __init__(self):
29
- # Usa un modello Hugging Face gratuito
30
- token = os.getenv(os.getenv("TOKEN_NAME"))
31
- os.environ["HF_TOKEN"] = token
32
- model = InferenceClientModel(
33
- token=token
34
- )
35
-
36
- self.agent = CodeAgent(
37
- model=model,
38
- tools=[
39
- # DuckDuckGoSearchTool(),
40
- # GoogleSearchTool(),
41
- WebSearchTool(),
42
- PythonInterpreterTool(),
43
- WikipediaSearchTool(),
44
- VisitWebpageTool() #,
45
- # FinalAnswerTool #,
46
- # Tool(name="invert_sentence", func=invert_sentence, description="Inverts the order of characters in a sentence.")
47
- ]
48
- )
49
- print("FirstAgent initialized.")
50
- def __call__(self, question: str) -> str:
51
- print(f"Agent received question (first 50 chars): {question[:50]}...")
52
- answer = self.agent.run(question)
53
- print(f"Agent returning fixed answer: {answer}")
54
- return answer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  # --- Basic Agent Definition ---
57
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
58
  class BasicAgent:
59
- ### Basic Agent is a placeholder for a simple agent that always returns a fixed answer. ###
60
- ### It is used to demonstrate the structure of an agent. ###
61
- def __init__(self):
62
- print("BasicAgent initialized.")
63
- def __call__(self, question: str) -> str:
64
- print(f"Agent received question (first 50 chars): {question[:50]}...")
65
- fixed_answer = "This is a default answer."
66
- print(f"Agent returning fixed answer: {fixed_answer}")
67
- return fixed_answer
68
 
69
  def run_and_submit_all( profile: gr.OAuthProfile | None):
70
- """
71
- Fetches all questions, runs the BasicAgent on them, submits all answers,
72
- and displays the results.
73
- """
74
- # --- Determine HF Space Runtime URL and Repo URL ---
75
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
76
-
77
- if profile:
78
- username= f"{profile.username}"
79
- print(f"User logged in: {username}")
80
- else:
81
- print("User not logged in.")
82
- return "Please Login to Hugging Face with the button.", None
83
-
84
- api_url = DEFAULT_API_URL
85
- questions_url = f"{api_url}/questions"
86
- submit_url = f"{api_url}/submit"
87
-
88
- # 1. Instantiate Agent ( modify this part to create your agent)
89
- try:
90
- agent = FirstAgent()
91
- except Exception as e:
92
- print(f"Error instantiating agent: {e}")
93
- return f"Error initializing agent: {e}", None
94
- # 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)
95
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
96
- print(agent_code)
97
-
98
- # 2. Fetch Questions
99
- print(f"Fetching questions from: {questions_url}")
100
- try:
101
- response = requests.get(questions_url, timeout=15)
102
- response.raise_for_status()
103
- questions_data = response.json()
104
- if not questions_data:
105
- print("Fetched questions list is empty.")
106
- return "Fetched questions list is empty or invalid format.", None
107
- print(f"Fetched {len(questions_data)} questions.")
108
- except requests.exceptions.RequestException as e:
109
- print(f"Error fetching questions: {e}")
110
- return f"Error fetching questions: {e}", None
111
- except requests.exceptions.JSONDecodeError as e:
112
- print(f"Error decoding JSON response from questions endpoint: {e}")
113
- print(f"Response text: {response.text[:500]}")
114
- return f"Error decoding server response for questions: {e}", None
115
- except Exception as e:
116
- print(f"An unexpected error occurred fetching questions: {e}")
117
- return f"An unexpected error occurred fetching questions: {e}", None
118
-
119
- # 3. Run your Agent
120
- results_log = []
121
- answers_payload = []
122
- print(f"Running agent on {len(questions_data)} questions...")
123
- for item in questions_data:
124
- task_id = item.get("task_id")
125
- question_text = item.get("question")
126
- if not task_id or question_text is None:
127
- print(f"Skipping item with missing task_id or question: {item}")
128
- continue
129
- try:
130
- submitted_answer = agent(question_text)
131
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
132
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
133
- except Exception as e:
134
- print(f"Error running agent on task {task_id}: {e}")
135
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
136
-
137
- if not answers_payload:
138
- print("Agent did not produce any answers to submit.")
139
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
140
-
141
- # 4. Prepare Submission
142
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
143
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
144
- print(status_update)
145
-
146
- # 5. Submit
147
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
148
- try:
149
- response = requests.post(submit_url, json=submission_data, timeout=60)
150
- response.raise_for_status()
151
- result_data = response.json()
152
- final_status = (
153
- f"Submission Successful!\n"
154
- f"User: {result_data.get('username')}\n"
155
- f"Overall Score: {result_data.get('score', 'N/A')}% "
156
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
157
- f"Message: {result_data.get('message', 'No message received.')}"
158
- )
159
- print("Submission successful.")
160
- results_df = pd.DataFrame(results_log)
161
- return final_status, results_df
162
- except requests.exceptions.HTTPError as e:
163
- error_detail = f"Server responded with status {e.response.status_code}."
164
- try:
165
- error_json = e.response.json()
166
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
167
- except requests.exceptions.JSONDecodeError:
168
- error_detail += f" Response: {e.response.text[:500]}"
169
- status_message = f"Submission Failed: {error_detail}"
170
- print(status_message)
171
- results_df = pd.DataFrame(results_log)
172
- return status_message, results_df
173
- except requests.exceptions.Timeout:
174
- status_message = "Submission Failed: The request timed out."
175
- print(status_message)
176
- results_df = pd.DataFrame(results_log)
177
- return status_message, results_df
178
- except requests.exceptions.RequestException as e:
179
- status_message = f"Submission Failed: Network error - {e}"
180
- print(status_message)
181
- results_df = pd.DataFrame(results_log)
182
- return status_message, results_df
183
- except Exception as e:
184
- status_message = f"An unexpected error occurred during submission: {e}"
185
- print(status_message)
186
- results_df = pd.DataFrame(results_log)
187
- return status_message, results_df
188
 
189
 
190
  # --- Build Gradio Interface using Blocks ---
191
  with gr.Blocks() as demo:
192
- gr.Markdown("# Basic Agent Evaluation Runner")
193
- gr.Markdown(
194
- """
195
- **Instructions:**
196
 
197
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
198
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
199
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
200
 
201
- ---
202
- **Disclaimers:**
203
- 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).
204
- 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.
205
- """
206
- )
207
 
208
- gr.LoginButton()
209
 
210
- run_button = gr.Button("Run Evaluation & Submit All Answers")
211
 
212
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
213
- # Removed max_rows=10 from DataFrame constructor
214
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
215
 
216
- run_button.click(
217
- fn=run_and_submit_all,
218
- outputs=[status_output, results_table]
219
- )
220
 
221
  if __name__ == "__main__":
222
- print("\n" + "-"*30 + " App Starting " + "-"*30)
223
- # Check for SPACE_HOST and SPACE_ID at startup for information
224
- space_host_startup = os.getenv("SPACE_HOST")
225
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
226
-
227
- if space_host_startup:
228
- print(f"✅ SPACE_HOST found: {space_host_startup}")
229
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
230
- else:
231
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
232
-
233
- if space_id_startup: # Print repo URLs if SPACE_ID is found
234
- print(f"✅ SPACE_ID found: {space_id_startup}")
235
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
236
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
237
- else:
238
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
239
-
240
- print("-"*(60 + len(" App Starting ")) + "\n")
241
-
242
- print("Launching Gradio Interface for Basic Agent Evaluation...")
243
- demo.launch(debug=True, share=False)
 
4
  import inspect
5
  import pandas as pd
6
 
7
+ from smolagents import CodeAgent, HfApiModel, VisitWebpageTool, PythonInterpreterTool, WebSearchTool, WikipediaSearchTool, FinalAnswerTool, Tool, tool # GoogleSearchTool (usa SERPAPI_API_KEY), DuckDuckGoSearchTool
8
 
9
  # (Keep Constants as is)
10
  # --- Constants ---
 
12
 
13
  @tool
14
  def invert_sentence(sentence: str) -> str:
15
+ """
16
+ Inverts the order of all characters in a sentence.
17
+ Args:
18
+ sentence (str): The sentence to invert.
19
+ Returns:
20
+ str: The sentence with characters in reverse order.
21
+ """
22
+ return sentence[::-1]
23
 
24
  # --- First Agent Definition ---
25
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
26
  class FirstAgent:
27
+ ### First Agent is the first attempt to develop an agent for the course. ###
28
+ def __init__(self):
29
+ # # Usa un modello Hugging Face gratuito
30
+ # token = os.getenv(os.getenv("TOKEN_NAME"))
31
+ # os.environ["HF_TOKEN"] = token
32
+ # model = InferenceClientModel(
33
+ # token=token
34
+ # )
35
+
36
+ # Configurazione con fallback multipli
37
+ model = None
38
+
39
+ # Try 1: Modello locale via Transformers
40
+ try:
41
+ from transformers import pipeline
42
+ model = HfApiModel(
43
+ model_id="microsoft/DialoGPT-small" # ~500MB, scaricato automaticamente
44
+ )
45
+ print("Using local DialoGPT model")
46
+ except Exception as e:
47
+ print(f"Local model failed: {e}")
48
+
49
+ # Try 2: Modello remoto gratuito
50
+ try:
51
+ model = LiteLLMModel(
52
+ model_id="groq/mixtral-8x7b-32768" # Gratuito con registrazione
53
+ )
54
+ print("Using Groq remote model")
55
+ except Exception as e:
56
+ print(f"Remote model failed: {e}")
57
+ raise Exception("No working model configuration found")
58
+
59
+ self.agent = CodeAgent(
60
+ model=model,
61
+ tools=[
62
+ # DuckDuckGoSearchTool(),
63
+ # GoogleSearchTool(),
64
+ WebSearchTool(),
65
+ PythonInterpreterTool(),
66
+ WikipediaSearchTool(),
67
+ VisitWebpageTool() #,
68
+ # FinalAnswerTool #,
69
+ # Tool(name="invert_sentence", func=invert_sentence, description="Inverts the order of characters in a sentence.")
70
+ ]
71
+ )
72
+ print("FirstAgent initialized.")
73
+ def __call__(self, question: str) -> str:
74
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
75
+ answer = self.agent.run(question)
76
+ print(f"Agent returning fixed answer: {answer}")
77
+ return answer
78
 
79
  # --- Basic Agent Definition ---
80
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
81
  class BasicAgent:
82
+ ### Basic Agent is a placeholder for a simple agent that always returns a fixed answer. ###
83
+ ### It is used to demonstrate the structure of an agent. ###
84
+ def __init__(self):
85
+ print("BasicAgent initialized.")
86
+ def __call__(self, question: str) -> str:
87
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
88
+ fixed_answer = "This is a default answer."
89
+ print(f"Agent returning fixed answer: {fixed_answer}")
90
+ return fixed_answer
91
 
92
  def run_and_submit_all( profile: gr.OAuthProfile | None):
93
+ """
94
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
95
+ and displays the results.
96
+ """
97
+ # --- Determine HF Space Runtime URL and Repo URL ---
98
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
99
+
100
+ if profile:
101
+ username= f"{profile.username}"
102
+ print(f"User logged in: {username}")
103
+ else:
104
+ print("User not logged in.")
105
+ return "Please Login to Hugging Face with the button.", None
106
+
107
+ api_url = DEFAULT_API_URL
108
+ questions_url = f"{api_url}/questions"
109
+ submit_url = f"{api_url}/submit"
110
+
111
+ # 1. Instantiate Agent ( modify this part to create your agent)
112
+ try:
113
+ agent = FirstAgent()
114
+ except Exception as e:
115
+ print(f"Error instantiating agent: {e}")
116
+ return f"Error initializing agent: {e}", None
117
+ # 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)
118
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
119
+ print(agent_code)
120
+
121
+ # 2. Fetch Questions
122
+ print(f"Fetching questions from: {questions_url}")
123
+ try:
124
+ response = requests.get(questions_url, timeout=15)
125
+ response.raise_for_status()
126
+ questions_data = response.json()
127
+ if not questions_data:
128
+ print("Fetched questions list is empty.")
129
+ return "Fetched questions list is empty or invalid format.", None
130
+ print(f"Fetched {len(questions_data)} questions.")
131
+ except requests.exceptions.RequestException as e:
132
+ print(f"Error fetching questions: {e}")
133
+ return f"Error fetching questions: {e}", None
134
+ except requests.exceptions.JSONDecodeError as e:
135
+ print(f"Error decoding JSON response from questions endpoint: {e}")
136
+ print(f"Response text: {response.text[:500]}")
137
+ return f"Error decoding server response for questions: {e}", None
138
+ except Exception as e:
139
+ print(f"An unexpected error occurred fetching questions: {e}")
140
+ return f"An unexpected error occurred fetching questions: {e}", None
141
+
142
+ # 3. Run your Agent
143
+ results_log = []
144
+ answers_payload = []
145
+ print(f"Running agent on {len(questions_data)} questions...")
146
+ for item in questions_data:
147
+ task_id = item.get("task_id")
148
+ question_text = item.get("question")
149
+ if not task_id or question_text is None:
150
+ print(f"Skipping item with missing task_id or question: {item}")
151
+ continue
152
+ try:
153
+ submitted_answer = agent(question_text)
154
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
155
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
156
+ except Exception as e:
157
+ print(f"Error running agent on task {task_id}: {e}")
158
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
159
+
160
+ if not answers_payload:
161
+ print("Agent did not produce any answers to submit.")
162
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
163
+
164
+ # 4. Prepare Submission
165
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
166
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
167
+ print(status_update)
168
+
169
+ # 5. Submit
170
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
171
+ try:
172
+ response = requests.post(submit_url, json=submission_data, timeout=60)
173
+ response.raise_for_status()
174
+ result_data = response.json()
175
+ final_status = (
176
+ f"Submission Successful!\n"
177
+ f"User: {result_data.get('username')}\n"
178
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
179
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
180
+ f"Message: {result_data.get('message', 'No message received.')}"
181
+ )
182
+ print("Submission successful.")
183
+ results_df = pd.DataFrame(results_log)
184
+ return final_status, results_df
185
+ except requests.exceptions.HTTPError as e:
186
+ error_detail = f"Server responded with status {e.response.status_code}."
187
+ try:
188
+ error_json = e.response.json()
189
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
190
+ except requests.exceptions.JSONDecodeError:
191
+ error_detail += f" Response: {e.response.text[:500]}"
192
+ status_message = f"Submission Failed: {error_detail}"
193
+ print(status_message)
194
+ results_df = pd.DataFrame(results_log)
195
+ return status_message, results_df
196
+ except requests.exceptions.Timeout:
197
+ status_message = "Submission Failed: The request timed out."
198
+ print(status_message)
199
+ results_df = pd.DataFrame(results_log)
200
+ return status_message, results_df
201
+ except requests.exceptions.RequestException as e:
202
+ status_message = f"Submission Failed: Network error - {e}"
203
+ print(status_message)
204
+ results_df = pd.DataFrame(results_log)
205
+ return status_message, results_df
206
+ except Exception as e:
207
+ status_message = f"An unexpected error occurred during submission: {e}"
208
+ print(status_message)
209
+ results_df = pd.DataFrame(results_log)
210
+ return status_message, results_df
211
 
212
 
213
  # --- Build Gradio Interface using Blocks ---
214
  with gr.Blocks() as demo:
215
+ gr.Markdown("# Basic Agent Evaluation Runner")
216
+ gr.Markdown(
217
+ """
218
+ **Instructions:**
219
 
220
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
221
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
222
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
223
 
224
+ ---
225
+ **Disclaimers:**
226
+ 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).
227
+ 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.
228
+ """
229
+ )
230
 
231
+ gr.LoginButton()
232
 
233
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
234
 
235
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
236
+ # Removed max_rows=10 from DataFrame constructor
237
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
238
 
239
+ run_button.click(
240
+ fn=run_and_submit_all,
241
+ outputs=[status_output, results_table]
242
+ )
243
 
244
  if __name__ == "__main__":
245
+ print("\n" + "-"*30 + " App Starting " + "-"*30)
246
+ # Check for SPACE_HOST and SPACE_ID at startup for information
247
+ space_host_startup = os.getenv("SPACE_HOST")
248
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
249
+
250
+ if space_host_startup:
251
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
252
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
253
+ else:
254
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
255
+
256
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
257
+ print(f"✅ SPACE_ID found: {space_id_startup}")
258
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
259
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
260
+ else:
261
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
262
+
263
+ print("-"*(60 + len(" App Starting ")) + "\n")
264
+
265
+ print("Launching Gradio Interface for Basic Agent Evaluation...")
266
+ demo.launch(debug=True, share=False)
requirements.txt CHANGED
@@ -3,5 +3,15 @@ requests
3
  pandas
4
  smolagents
5
  wikipedia-api
 
 
 
 
 
 
 
 
 
6
  # duckduckgo-search
7
- # huggingface_hub
 
 
3
  pandas
4
  smolagents
5
  wikipedia-api
6
+ # Dipendenze per modelli locali
7
+ transformers
8
+ torch
9
+ tokenizers
10
+ # Dipendenze per LiteLLM (modelli multipli)
11
+ litellm
12
+ # Hugging Face Hub per download modelli
13
+ huggingface_hub
14
+ # Opzionali ma utili
15
  # duckduckgo-search
16
+ # accelerate # Per modelli più grandi
17
+ # bitsandbytes # Per quantizzazione