MADtoBAD commited on
Commit
3bcc4b6
·
verified ·
1 Parent(s): 9754221

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +298 -64
app.py CHANGED
@@ -1,70 +1,304 @@
 
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
-
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
 
16
  """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
-
19
- messages = [{"role": "system", "content": system_message}]
20
-
21
- messages.extend(history)
22
-
23
- messages.append({"role": "user", "content": message})
24
-
25
- response = ""
26
-
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
 
 
 
 
68
 
69
  if __name__ == "__main__":
70
- demo.launch()
 
 
1
+ import os
2
  import gradio as gr
3
+ import requests
4
+ import pandas as pd
5
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
6
+ import logging
7
+
8
+ # Настройка логирования
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # --- Константы ---
13
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
14
+
15
+ # --- Internet-Enabled Agent Definition ---
16
+ class InternetAgent:
17
+ def __init__(self):
18
+ print("🌐 InternetAgent initializing with web search capabilities...")
19
+
20
+ try:
21
+ # Используем модель от Hugging Face и инструмент поиска
22
+ self.model = HfApiModel("Qwen/Qwen2.5-Coder-32B-Instruct")
23
+ self.search_tool = DuckDuckGoSearchTool()
24
+
25
+ # Создаем агента с доступом к поиску
26
+ self.agent = CodeAgent(
27
+ tools=[self.search_tool],
28
+ model=self.model,
29
+ max_steps=6, # Ограничиваем шаги для скорости
30
+ add_base_tools=False # Используем только наши инструменты
31
+ )
32
+ print("✅ InternetAgent initialized successfully with web search")
33
+
34
+ except Exception as e:
35
+ print(f"❌ Error initializing InternetAgent: {e}")
36
+ self.agent = None
37
+ # Резервная база знаний на случай ошибки
38
+ self.fallback_knowledge = {
39
+ "capital of france": "Paris",
40
+ "capital of germany": "Berlin",
41
+ "capital of uk": "London",
42
+ "capital of usa": "Washington D.C.",
43
+ "2+2": "4",
44
+ "largest planet": "Jupiter",
45
+ }
46
+
47
+ def __call__(self, question: str) -> str:
48
+ print(f"🤖 Processing: {question}")
49
+
50
+ if not self.agent:
51
+ # Используем резервную базу знаний если агент не инициализирован
52
+ question_lower = question.lower()
53
+ for key, answer in self.fallback_knowledge.items():
54
+ if key in question_lower:
55
+ return answer
56
+ return "I need internet access to answer this question properly."
57
+
58
+ try:
59
+ # Создаем оптимизированный промпт для лучших результатов
60
+ optimized_prompt = f"""
61
+ Please provide a clear, concise, and accurate answer to the following question.
62
+ If you need to search for information, use the search tool.
63
+ Keep your answer brief and to the point.
64
+
65
+ Question: {question}
66
+
67
+ Answer:
68
+ """
69
+
70
+ # Запускаем агента
71
+ response = self.agent.run(optimized_prompt)
72
+
73
+ # Очищаем ответ
74
+ clean_response = self.clean_response(response)
75
+ print(f"✅ Answer: {clean_response[:100]}...")
76
+
77
+ return clean_response
78
+
79
+ except Exception as e:
80
+ print(f"❌ Error in agent execution: {e}")
81
+ return f"I encountered an error while searching for the answer: {str(e)}"
82
+
83
+ def clean_response(self, response: str) -> str:
84
+ """Очищает ответ от лишней информации"""
85
+ # Удаляем мета-комментарии агента
86
+ lines = response.split('\n')
87
+ clean_lines = []
88
+
89
+ for line in lines:
90
+ # Пропускаем строки с инструментами или процессами
91
+ if any(term in line.lower() for term in ['tool:', 'searching', 'step', 'using tool']):
92
+ continue
93
+ # Пропускаем пустые строки в начале
94
+ if not clean_lines and not line.strip():
95
+ continue
96
+ clean_lines.append(line)
97
+
98
+ clean_response = '\n'.join(clean_lines).strip()
99
+
100
+ # Если ответ слишком длинный, берем первую часть
101
+ if len(clean_response) > 500:
102
+ clean_response = clean_response[:497] + "..."
103
+
104
+ return clean_response if clean_response else "I couldn't find a clear answer to that question."
105
+
106
+ # --- Упрощенная версия для тестирования ---
107
+ class LiteInternetAgent:
108
+ def __init__(self):
109
+ print("🌐 LiteInternetAgent initializing...")
110
+ self.search_tool = DuckDuckGoSearchTool()
111
+
112
+ def __call__(self, question: str) -> str:
113
+ try:
114
+ # Прямой поиск через инструмент
115
+ result = self.search_tool(question)
116
+ return f"According to web search: {result[:300]}..." if len(result) > 300 else result
117
+ except Exception as e:
118
+ return f"Search failed: {str(e)}"
119
+
120
+ # --- Основная функция ---
121
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
122
  """
123
+ Fetches all questions, runs the InternetAgent on them, submits all answers,
124
+ and displays the results.
125
  """
126
+ space_id = os.getenv("SPACE_ID")
127
+
128
+ if profile:
129
+ username = f"{profile.username}"
130
+ print(f"User logged in: {username}")
131
+ else:
132
+ print("User not logged in.")
133
+ return "Please Login to Hugging Face with the button.", None
134
+
135
+ api_url = DEFAULT_API_URL
136
+ questions_url = f"{api_url}/questions"
137
+ submit_url = f"{api_url}/submit"
138
+
139
+ # 1. Instantiate our Internet Agent
140
+ try:
141
+ # Пробуем полную версию, если не работает - упрощенную
142
+ agent = InternetAgent()
143
+ if agent.agent is None:
144
+ agent = LiteInternetAgent()
145
+ print("✅ InternetAgent created successfully")
146
+ except Exception as e:
147
+ print(f"Error instantiating agent: {e}")
148
+ return f"Error initializing agent: {e}", None
149
+
150
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
151
+ print(f"Agent code URL: {agent_code}")
152
+
153
+ # 2. Fetch Questions
154
+ print(f"Fetching questions from: {questions_url}")
155
+ try:
156
+ response = requests.get(questions_url, timeout=30)
157
+ response.raise_for_status()
158
+ questions_data = response.json()
159
+ if not questions_data:
160
+ print("Fetched questions list is empty.")
161
+ return "Fetched questions list is empty or invalid format.", None
162
+ print(f"✅ Fetched {len(questions_data)} questions.")
163
+ except Exception as e:
164
+ error_msg = f"❌ Error fetching questions: {e}"
165
+ print(error_msg)
166
+
167
+ # Демо-режим с разными типами вопросов
168
+ demo_questions = [
169
+ {"task_id": "demo1", "question": "What is the capital of France?"},
170
+ {"task_id": "demo2", "question": "What is the current weather in Tokyo?"},
171
+ {"task_id": "demo3", "question": "Who won the Nobel Prize in Physics in 2023?"},
172
+ {"task_id": "demo4", "question": "What is the population of Brazil?"},
173
+ {"task_id": "demo5", "question": "Explain quantum computing in simple terms"},
174
+ ]
175
+ questions_data = demo_questions
176
+ print("🚨 Using demo questions since API is unavailable")
177
+
178
+ # 3. Run your Agent
179
+ results_log = []
180
+ answers_payload = []
181
+ print(f"Running agent on {len(questions_data)} questions...")
182
+
183
+ for i, item in enumerate(questions_data):
184
+ task_id = item.get("task_id")
185
+ question_text = item.get("question")
186
+
187
+ if not task_id or question_text is None:
188
+ print(f"Skipping item with missing task_id or question: {item}")
189
+ continue
190
+
191
+ print(f"🔍 Processing question {i+1}/{len(questions_data)}: {question_text[:50]}...")
192
+
193
+ try:
194
+ submitted_answer = agent(question_text)
195
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
196
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
197
+ except Exception as e:
198
+ print(f"❌ Error running agent on task {task_id}: {e}")
199
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
200
+
201
+ if not answers_payload:
202
+ print("Agent did not produce any answers to submit.")
203
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
204
+
205
+ # 4. Prepare Submission
206
+ submission_data = {
207
+ "username": username.strip(),
208
+ "agent_code": agent_code,
209
+ "answers": answers_payload
210
+ }
211
+
212
+ status_update = f"✅ Agent finished. Processed {len(answers_payload)} answers for user '{username}'"
213
+ print(status_update)
214
+
215
+ # 5. Submit answers (только если вопросы реальные, не демо)
216
+ if "demo" not in str(questions_data[0].get("task_id", "")):
217
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
218
+ try:
219
+ response = requests.post(submit_url, json=submission_data, timeout=120)
220
+ response.raise_for_status()
221
+ result_data = response.json()
222
+
223
+ final_status = (
224
+ f"🎉 Submission Successful!\n"
225
+ f"👤 User: {result_data.get('username')}\n"
226
+ f"📊 Overall Score: {result_data.get('score', 'N/A')}% "
227
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
228
+ f"💬 Message: {result_data.get('message', 'No message received.')}"
229
+ )
230
+ print("✅ Submission successful.")
231
+ results_df = pd.DataFrame(results_log)
232
+ return final_status, results_df
233
+
234
+ except Exception as e:
235
+ error_message = f"❌ Submission Failed: {str(e)}"
236
+ print(error_message)
237
+ results_df = pd.DataFrame(results_log)
238
+ return error_message, results_df
239
+ else:
240
+ # Демо-режим: показываем ответы но не отправляем
241
+ demo_status = (
242
+ f"🧪 DEMO MODE (API Unavailable)\n"
243
+ f"👤 User: {username}\n"
244
+ f"📊 Processed: {len(answers_payload)} demo questions\n"
245
+ f"🌐 Agent used web search for answers\n"
246
+ f"💬 Real submission disabled - API not accessible\n\n"
247
+ f"Check the web-powered answers below!"
248
+ )
249
+ print("✅ Demo completed - showing results without submission")
250
+ results_df = pd.DataFrame(results_log)
251
+ return demo_status, results_df
252
+
253
+ # --- Gradio Interface ---
254
+ with gr.Blocks(title="Internet-Enabled AI Agent") as demo:
255
+ gr.Markdown("""
256
+ # 🌐 Internet-Enabled AI Agent
257
+ **Powered by web search and large language models**
258
+
259
+ ### 🔧 Capabilities:
260
+ - **Web Search**: Real-time information from DuckDuckGo
261
+ - **LLM Power**: Qwen2.5-32B model for understanding
262
+ - **Multi-step Reasoning**: Complex question answering
263
+
264
+ ### 📚 Example questions:
265
+ - *"Current weather in any city"*
266
+ - *"Latest news headlines"*
267
+ - *"Historical facts and data"*
268
+ - *"Scientific explanations"*
269
+ - *"Complex calculations"*
270
+ """)
271
+
272
+ gr.Markdown("""
273
+ ### ⚠️ Important Notes:
274
+ - This agent requires internet access
275
+ - Responses may take longer due to web searches
276
+ - Some questions might not have clear online answers
277
+ """)
278
+
279
+ with gr.Row():
280
+ with gr.Column():
281
+ gr.LoginButton()
282
+ run_button = gr.Button("🚀 Run Evaluation", variant="primary")
283
+
284
+ with gr.Row():
285
+ with gr.Column():
286
+ status_output = gr.Textbox(
287
+ label="Status",
288
+ lines=4,
289
+ interactive=False
290
+ )
291
+ with gr.Column():
292
+ results_table = gr.DataFrame(
293
+ label="Questions & Answers",
294
+ wrap=True
295
+ )
296
 
297
+ run_button.click(
298
+ fn=run_and_submit_all,
299
+ outputs=[status_output, results_table]
300
+ )
301
 
302
  if __name__ == "__main__":
303
+ print("🚀 Starting Internet-Enabled AI Agent...")
304
+ demo.launch(debug=True, share=False)