CanerCoban commited on
Commit
af0c0fa
·
verified ·
1 Parent(s): 924d75b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -1
app.py CHANGED
@@ -26,6 +26,12 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
26
 
27
  # --- Basic Agent Definition ---
28
  # ---- THIS IS WHERE YOU CAN BUILD WHAT YOU WANT ----
 
 
 
 
 
 
29
  class BasicAgent:
30
  def __init__(self):
31
  # Pull a HF access token from the Space's secrets or your local shell. You can download private models, call paid-tier Inference endpoints, push artefacts
@@ -62,9 +68,12 @@ class BasicAgent:
62
  tools=[self.search_tool],
63
  # drops in a small standard library (Python REPL, JSON loader etc.) so you can solve many tasks without defining anything else.
64
  add_base_tools=True # - python_repl, browser, math etc.
 
 
65
  )
66
 
67
  # Send a single "bootstrap" run whose only job is lock in behaviour rules:
 
68
  self.response = self.agent.run(
69
  """
70
  You are a general AI assistant.
@@ -76,4 +85,111 @@ class BasicAgent:
76
  You have access to the following tools:
77
  Tool Name: search_tool, description: lets you search and browse the internet for accessing the most updated information out there.
78
  If you require more tools to get a correct answer, create your own tools to utilize.
79
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  # --- Basic Agent Definition ---
28
  # ---- THIS IS WHERE YOU CAN BUILD WHAT YOU WANT ----
29
+ # This class is a ready-to-run wrapper that:
30
+ # 1. Authenticates to the Hub
31
+ # 2. Spins up a server-side Qwen-32B LLM.
32
+ # 3. Gives it a DuckDuckGo search plug-in plus smolagents' standard library
33
+ # 4. Primes it with strict grading instructions.
34
+ # 5. Exposes a clean, callable interface for what ever frontend(Gradio, FastAPI, etc.) you bolt on.
35
  class BasicAgent:
36
  def __init__(self):
37
  # Pull a HF access token from the Space's secrets or your local shell. You can download private models, call paid-tier Inference endpoints, push artefacts
 
68
  tools=[self.search_tool],
69
  # drops in a small standard library (Python REPL, JSON loader etc.) so you can solve many tasks without defining anything else.
70
  add_base_tools=True # - python_repl, browser, math etc.
71
+ # CodeAgent's auto_document_tools convenience flag
72
+ auto_document_tools=True
73
  )
74
 
75
  # Send a single "bootstrap" run whose only job is lock in behaviour rules:
76
+ # The returned text is captured in self.responses.
77
  self.response = self.agent.run(
78
  """
79
  You are a general AI assistant.
 
85
  You have access to the following tools:
86
  Tool Name: search_tool, description: lets you search and browse the internet for accessing the most updated information out there.
87
  If you require more tools to get a correct answer, create your own tools to utilize.
88
+ """)
89
+ # Turning BasicAgent into a callable object
90
+ # It means you can drop it straight into Gradio (or any other framework) without wrapping it in a standalone function.
91
+ # Debug prints show the round-trip in the server logs.
92
+ def __call__(self, question: str) -> str:
93
+ print(f"Agent received question:")
94
+ response = self.agent.run(question)
95
+ # the reply is generated on-the-fly, not hard coded.
96
+ print(f"Agent returning answer: {response}")
97
+ return response
98
+
99
+ # 1. Check if the user is logged in
100
+ # 2. Download questions from a grading API.
101
+ # 3. Use the BasicAgent to generate answers
102
+ # 4. Submit those answers back to the API.
103
+ # 5. Return the grading results + a full log for UI display (e.g. Gradio Table)
104
+ # Includes detailed logging, robust error handling, and submission payload formatting
105
+ def run_and_submit_all( profile: gr.OAuthProfile | None):
106
+ """
107
+ Fetches all questions, runs the BasicAgent on them, submits all answers, and display the results.
108
+ """
109
+ # --- Determine HF Space Runtime URL and Repo URL ---
110
+ # Authenticate user and runtime info
111
+ # Grabbing space_id from the environment lets the app dynamically construct a URL to your codebase.
112
+ # This will be included in the submission for transparency (important in peer-review courses.)
113
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
114
+
115
+ # If the gradio OAuth profile object is present, extract the username.
116
+ if profile:
117
+ username = f"{profile.username}"
118
+ print(f"User logged in: {username}")
119
+ # Otherwise, early exit with a friendly error message
120
+ else:
121
+ print("User not logged in.")
122
+ return "Please login to Hugging Face with the button.",None
123
+
124
+ # --- PrePare API endpoints ---
125
+ # Uses the provided scoring end point (defaulting to the course's hosted backen)
126
+ # Constucts two URLs:
127
+ api_url = DEFAULT_API_URL
128
+ # URL to Fetch the question bank.
129
+ question_url = f"{api_url}/questions"
130
+ # URL to POST answers for grading
131
+ submit_url = f"{api_url}/submit"
132
+
133
+ # 1. Instantiate Agent ( modify this part to create your agent)
134
+ # Tries to spin up your BasicAgent class from earlier.
135
+ # Includes token validation, model loading, tool setup, and system prompt injection.
136
+ # If this fails, the app gracefully exits, returning a user-visible error.
137
+ try:
138
+ agent = BasicAgent()
139
+ except Exception as e:
140
+ print(f"Error instantiating agent: {e}")
141
+ return f"Error initialiazing agent: {e}", None
142
+
143
+ # In the case of an app running as a HF space, this link points toward your codebase
144
+ # (usefull for others so please keep it public)
145
+ # Builds a link to your code repor on HF Hub (public space)
146
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
147
+ # Gets submitted with the answers for transparacey
148
+ print(agent_code)
149
+
150
+ # 2. Fetch Questions
151
+ # --- FETCH QUESTIONS FROM THE BACKEND ---
152
+ print(f"Fetching questions from: {questions_url}")
153
+ # Tries to GET the questions from the course's scoring server
154
+ try:
155
+ # Timout and error handling ensure the app does not hang or crash.
156
+
157
+ response = requests.get(requests, timeout=15)
158
+ questions_data = response.json()
159
+ # handles edge cases like empty response, malformed JSON, network Errors
160
+ # Empty response handling
161
+ if not questions_data:
162
+ print("Fetched questions list is empty.")
163
+ return "Fetched questions list is empty or invalid format.", None
164
+ print(f"Fetched {len(question_data) questions.}")
165
+ except requests.exceptions,RequestException as e:
166
+ print(f"Error fetching questions: {e}")
167
+ return f"Error fetching questions: {e}", None
168
+ except reqests.exceptions.JSONDecodeError as e:
169
+ print(f"Error decoding JSON response from questions endpoint: {e}")
170
+ print(f"Response text: {response.text[:500]}")
171
+ return f"Error decoding server response for questions: {e}, None"
172
+ except Exception as e:
173
+ print(f"An unexpected error occured fetching questions: {e}")
174
+ return f"An unexpected error occurred fetching questions: {e}", None
175
+ # 3. Run your agent.
176
+ # Loop through questions and generate answers
177
+ results_log = [] # Used to make a DataFrame for UI display (question + answer)
178
+ answers_payload = [] # sent to grading API in the final submission
179
+
180
+ for item in questions_data:
181
+ task_id = item.get("task_id")
182
+ question_text = item.get("question")
183
+ if not task_id or question_text is None:
184
+ print(f"Skipping item with missing task_id or question: {item}")
185
+ continue
186
+ try:
187
+ submitted_answer = agent(question_text)
188
+ answers_payload.append({"task_id": task_id, "submmitted_answer": submitted_answer})
189
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
190
+ except Exception as e:
191
+ print(f"Erron running agent on task {task_id}: {e}")
192
+ results_log.append
193
+
194
+
195
+