tuan3335 commited on
Commit
a55ef75
·
1 Parent(s): 75849d9

final agent course submit

Browse files
Files changed (1) hide show
  1. app.py +103 -284
app.py CHANGED
@@ -8,308 +8,127 @@ Features:
8
  - Beautiful UI với LangGraph workflow visualization
9
  """
10
 
 
11
  import gradio as gr
12
  import requests
13
- import json
14
- from agent import process_question
15
 
16
- # =============================================================================
17
- # API FUNCTIONS
18
- # =============================================================================
 
 
 
 
 
 
 
 
 
 
19
 
20
- def get_questions():
21
- """Fetch questions from API"""
22
- try:
23
- response = requests.get("https://agents-course-unit4-scoring.hf.space/questions")
24
- if response.status_code == 200:
25
- return response.json()
26
- else:
27
- return {"error": f"API error: {response.status_code}"}
28
- except Exception as e:
29
- return {"error": f"Request failed: {str(e)}"}
30
 
31
- def submit_answers(username: str, agent_code: str, answers: dict):
32
- """Submit answers to API"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  try:
34
- payload = {
35
- "username": username,
36
- "agent_code": agent_code,
37
- "answers": answers
38
- }
39
-
40
- response = requests.post(
41
- "https://agents-course-unit4-scoring.hf.space/submit",
42
- json=payload,
43
- headers={"Content-Type": "application/json"}
44
- )
45
-
46
- if response.status_code == 200:
47
- return response.json()
48
- else:
49
- return {"error": f"Submit failed: {response.status_code}"}
50
  except Exception as e:
51
- return {"error": f"Submit error: {str(e)}"}
 
52
 
53
- # =============================================================================
54
- # GRADIO INTERFACE FUNCTIONS
55
- # =============================================================================
56
 
57
- def answer_question(question: str, task_id: str = "", file_name: str = ""):
58
- """Process single question through AI agent"""
59
- if not question.strip():
60
- return "Please enter a question"
61
-
62
  try:
63
- # Process through LangGraph AI agent
64
- answer = process_question(question, task_id, file_name)
65
- return answer
 
 
 
 
66
  except Exception as e:
67
- return f"Error: {str(e)}"
68
-
69
- def load_all_questions():
70
- """Load and display all questions from API"""
71
- questions_data = get_questions()
72
-
73
- if "error" in questions_data:
74
- return f"Error loading questions: {questions_data['error']}"
75
-
76
- # Format questions for display
77
- formatted = "📋 **ALL QUESTIONS FROM API:**\n\n"
78
-
79
- for i, q_data in enumerate(questions_data, 1):
80
- question = q_data.get('question', 'No question')
81
- task_id = q_data.get('task_id', '')
82
- file_name = q_data.get('file_name', '')
83
-
84
- formatted += f"**Question {i}:**\n"
85
- formatted += f"Q: {question}\n"
86
- if task_id:
87
- formatted += f"Task ID: `{task_id}`\n"
88
- if file_name:
89
- formatted += f"File: `{file_name}`\n"
90
- formatted += f"\n---\n\n"
91
-
92
- return formatted
93
 
94
- def process_all_questions(username: str):
95
- """Process all questions and prepare for submission"""
96
- if not username.strip():
97
- return "Please enter your username first"
98
-
99
- # Get questions
100
- questions_data = get_questions()
101
- if "error" in questions_data:
102
- return f"Error: {questions_data['error']}"
103
-
104
- # Process each question
105
- results = []
106
- answers = {}
107
-
108
- for i, q_data in enumerate(questions_data, 1):
109
- question = q_data.get('question', '')
110
- task_id = q_data.get('task_id', '')
111
- file_name = q_data.get('file_name', '')
112
-
113
- # Process through agent
114
  try:
115
- answer = process_question(question, task_id, file_name)
116
- answers[str(i)] = answer
117
-
118
- results.append(f"**Q{i}:** {question}")
119
- results.append(f"**A{i}:** {answer}")
120
- results.append("---")
121
-
122
  except Exception as e:
123
- error_msg = f"Error processing Q{i}: {str(e)}"
124
- answers[str(i)] = error_msg
125
- results.append(f"**Q{i}:** {question}")
126
- results.append(f"**A{i}:** {error_msg}")
127
- results.append("---")
128
-
129
- # Format results
130
- formatted_results = "\n".join(results)
131
-
132
- # Save answers for potential submission
133
- global cached_answers, cached_username
134
- cached_answers = answers
135
- cached_username = username
136
-
137
- return f"🤖 **PROCESSING COMPLETED FOR {username}**\n\n{formatted_results}\n\n✅ **Ready for submission!**"
138
 
139
- def submit_all_answers():
140
- """Submit all processed answers"""
141
- global cached_answers, cached_username
142
-
143
- if not cached_answers or not cached_username:
144
- return "No answers to submit. Please process questions first."
145
-
146
- # Submit to API
147
- result = submit_answers(
148
- username=cached_username,
149
- agent_code="LangGraphQwen3Agent",
150
- answers=cached_answers
151
- )
152
-
153
- if "error" in result:
154
- return f"❌ Submission failed: {result['error']}"
155
- else:
156
- score = result.get('score', 'Unknown')
157
- return f"🎉 **SUBMISSION SUCCESSFUL!**\n\nScore: {score}\nResult: {json.dumps(result, indent=2)}"
 
158
 
159
- # Global variables for caching
160
- cached_answers = {}
161
- cached_username = ""
 
 
 
162
 
163
- # =============================================================================
164
- # GRADIO APP
165
- # =============================================================================
 
166
 
167
- def create_app():
168
- """Create Gradio interface"""
169
-
170
- with gr.Blocks(title="🤖 LangGraph AI Agent", theme=gr.themes.Soft()) as app:
171
-
172
- gr.Markdown("""
173
- # 🤖 LangGraph AI Agent with Qwen3-8B
174
-
175
- **AI-Driven Tool Calling Agent for Hugging Face Agents Course**
176
-
177
- 🧠 **Brain:** Qwen3-8B via HuggingFace InferenceClient
178
- 🔧 **Tools:** Audio transcription, OCR, file reading, Wikipedia search, math calculation, YouTube extraction
179
- 🌐 **Architecture:** LangGraph workflow với dynamic AI routing
180
- ⚡ **Features:** Không hardcode - AI tự quyết định tool nào cần dùng!
181
- """)
182
-
183
- with gr.Tabs():
184
-
185
- # Tab 1: Single Question Testing
186
- with gr.Tab("🔍 Single Question Test"):
187
- gr.Markdown("### Test individual questions with the AI agent")
188
-
189
- with gr.Row():
190
- with gr.Column():
191
- question_input = gr.Textbox(
192
- label="Question",
193
- placeholder="Enter your question here...",
194
- lines=2
195
- )
196
- task_id_input = gr.Textbox(
197
- label="Task ID (optional)",
198
- placeholder="e.g., task_123"
199
- )
200
- file_name_input = gr.Textbox(
201
- label="File Name (optional)",
202
- placeholder="e.g., audio.mp3"
203
- )
204
-
205
- answer_btn = gr.Button("🤖 Get Answer", variant="primary")
206
-
207
- with gr.Column():
208
- answer_output = gr.Textbox(
209
- label="AI Agent Answer",
210
- lines=10,
211
- interactive=False
212
- )
213
-
214
- answer_btn.click(
215
- answer_question,
216
- inputs=[question_input, task_id_input, file_name_input],
217
- outputs=answer_output
218
- )
219
-
220
- # Tab 2: View All Questions
221
- with gr.Tab("📋 All Questions"):
222
- gr.Markdown("### View all questions from the API")
223
-
224
- load_questions_btn = gr.Button("📥 Load All Questions", variant="secondary")
225
- questions_display = gr.Markdown()
226
-
227
- load_questions_btn.click(
228
- load_all_questions,
229
- outputs=questions_display
230
- )
231
-
232
- # Tab 3: Full Processing & Submission
233
- with gr.Tab("🚀 Full Processing"):
234
- gr.Markdown("### Process all questions and submit for scoring")
235
-
236
- with gr.Row():
237
- username_input = gr.Textbox(
238
- label="Username",
239
- placeholder="Enter your username",
240
- value=""
241
- )
242
-
243
- with gr.Row():
244
- process_all_btn = gr.Button("🔄 Process All Questions", variant="primary")
245
- submit_btn = gr.Button("📤 Submit Answers", variant="secondary")
246
-
247
- results_output = gr.Markdown()
248
-
249
- process_all_btn.click(
250
- process_all_questions,
251
- inputs=username_input,
252
- outputs=results_output
253
- )
254
-
255
- submit_btn.click(
256
- submit_all_answers,
257
- outputs=results_output
258
- )
259
-
260
- # Tab 4: Agent Info
261
- with gr.Tab("ℹ️ Agent Info"):
262
- gr.Markdown("""
263
- ### 🤖 LangGraph AI Agent Architecture
264
-
265
- **Main Components:**
266
- - **🧠 Qwen3-8B Brain:** HuggingFace InferenceClient cho reasoning
267
- - **🔧 LangGraph Workflow:** Dynamic routing based on AI decisions
268
- - **📡 Tool Nodes:** Groq Whisper, EasyOCR, Wikipedia, Math, YouTube, File processing
269
-
270
- **Flow:**
271
- 1. **AI Decision Node:** Qwen3-8B phân tích câu hỏi và quyết định action
272
- 2. **Dynamic Routing:** LangGraph route đến tool node tương ứng
273
- 3. **Tool Execution:** Node thực hiện tool và trả về kết quả
274
- 4. **Final Answer:** AI tổng hợp kết quả và đưa ra câu trả lời cuối
275
-
276
- **Available Tools:**
277
- - `transcribe_audio` - Groq Whisper cho audio files
278
- - `ocr_image` - EasyOCR cho images với text
279
- - `read_file` - Python libraries cho Excel/Python/text files
280
- - `search_wikipedia` - Wikipedia API cho factual information
281
- - `calculate_math` - Safe eval cho math calculations
282
- - `get_youtube` - yt-dlp cho YouTube video info
283
- - `answer_directly` - Direct reasoning cho simple questions
284
-
285
- **Key Features:**
286
- ✅ **Pure AI-driven** - Không hardcode routing logic
287
- ✅ **Tool calling pattern** - AI quyết định tool nào cần dùng
288
- ✅ **LangGraph workflow** - Structured execution với state management
289
- ✅ **Error handling** - Robust fallbacks cho mọi tool
290
- ✅ **Dynamic parameters** - AI extract parameters cho tools
291
-
292
- **Environment:**
293
- - `HF_TOKEN` - HuggingFace API key cho Qwen3-8B
294
- - `GROQ_API_KEY` - Groq API key cho Whisper transcription
295
- """)
296
-
297
- # Footer
298
- gr.Markdown("""
299
- ---
300
- *Developed for Hugging Face Agents Course Unit 4 - AI-Driven Tool Calling Agent*
301
- """)
302
-
303
- return app
304
 
305
- # =============================================================================
306
- # MAIN
307
- # =============================================================================
 
 
308
 
309
  if __name__ == "__main__":
310
- app = create_app()
311
- app.launch(
312
- server_name="0.0.0.0",
313
- server_port=7860,
314
- share=True
315
- )
 
8
  - Beautiful UI với LangGraph workflow visualization
9
  """
10
 
11
+ import os
12
  import gradio as gr
13
  import requests
14
+ import pandas as pd
 
15
 
16
+ # --- Constants ---
17
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
18
+
19
+ # --- Basic Agent Definition ---
20
+ # ----- THIS IS WHERE YOU CAN BUILD WHAT YOU WANT ------
21
+ class BasicAgent:
22
+ def __init__(self):
23
+ print("BasicAgent initialized.")
24
+ def __call__(self, question: str) -> str:
25
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
26
+ fixed_answer = "This is a default answer."
27
+ print(f"Agent returning fixed answer: {fixed_answer}")
28
+ return fixed_answer
29
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
32
+ """
33
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
34
+ and displays the results.
35
+ """
36
+ # Determine HF Space Runtime URL and Repo URL
37
+ space_id = os.getenv("SPACE_ID")
38
+
39
+ if profile:
40
+ username = profile.username
41
+ print(f"User logged in: {username}")
42
+ else:
43
+ print("User not logged in.")
44
+ return "Please Login to Hugging Face with the button.", None
45
+
46
+ api_url = DEFAULT_API_URL
47
+ questions_url = f"{api_url}/questions"
48
+ submit_url = f"{api_url}/submit"
49
+
50
+ # Instantiate Agent
51
  try:
52
+ agent = BasicAgent()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  except Exception as e:
54
+ print(f"Error instantiating agent: {e}")
55
+ return f"Error initializing agent: {e}", None
56
 
57
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
58
+ print(agent_code)
 
59
 
60
+ # Fetch Questions
 
 
 
 
61
  try:
62
+ response = requests.get(questions_url, timeout=15)
63
+ response.raise_for_status()
64
+ questions_data = response.json()
65
+ if not questions_data:
66
+ print("Fetched questions list is empty.")
67
+ return "Fetched questions list is empty or invalid.", None
68
+ print(f"Fetched {len(questions_data)} questions.")
69
  except Exception as e:
70
+ print(f"Error fetching questions: {e}")
71
+ return f"Error fetching questions: {e}", None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ # Run Agent on each question
74
+ results_log = []
75
+ answers_payload = []
76
+ for item in questions_data:
77
+ task_id = item.get("task_id")
78
+ question_text = item.get("question")
79
+ if not task_id or question_text is None:
80
+ continue
 
 
 
 
 
 
 
 
 
 
 
 
81
  try:
82
+ submitted_answer = agent(question_text)
83
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
84
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
 
 
 
85
  except Exception as e:
86
+ print(f"Error on task {task_id}: {e}")
87
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"ERROR: {e}"})
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
+ if not answers_payload:
90
+ print("Agent did not produce any answers to submit.")
91
+ return "No answers to submit.", pd.DataFrame(results_log)
92
+
93
+ # Submit answers
94
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
95
+ try:
96
+ response = requests.post(submit_url, json=submission_data, timeout=60)
97
+ response.raise_for_status()
98
+ result_data = response.json()
99
+ final_status = (
100
+ f"Submission Successful!\n"
101
+ f"User: {result_data.get('username')}\n"
102
+ f"Score: {result_data.get('score', 'N/A')}%\n"
103
+ f"Message: {result_data.get('message', '')}"
104
+ )
105
+ return final_status, pd.DataFrame(results_log)
106
+ except Exception as e:
107
+ print(f"Submission failed: {e}")
108
+ return f"Submission failed: {e}", pd.DataFrame(results_log)
109
 
110
+ # --- Build Gradio Interface ---
111
+ with gr.Blocks() as demo:
112
+ gr.Markdown("# Basic Agent Evaluation Runner")
113
+ gr.Markdown(
114
+ """
115
+ **Instructions:**
116
 
117
+ 1. Log in with your Hugging Face account using the button below.
118
+ 2. Click 'Run Evaluation & Submit All Answers' to fetch, run, and submit.
119
+ """
120
+ )
121
 
122
+ login_btn = gr.LoginButton()
123
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
124
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
125
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ run_button.click(
128
+ fn=run_and_submit_all,
129
+ inputs=[login_btn],
130
+ outputs=[status_output, results_table]
131
+ )
132
 
133
  if __name__ == "__main__":
134
+ demo.launch(debug=True, share=False)