JorgeVanco commited on
Commit
ff0eb39
·
1 Parent(s): 1a5faa6
Files changed (5) hide show
  1. .gitignore +6 -1
  2. agent.py +161 -0
  3. app.py +29 -27
  4. requirements.txt +3 -1
  5. utils.py +10 -0
.gitignore CHANGED
@@ -1,2 +1,7 @@
1
  venv/
2
- .env
 
 
 
 
 
 
1
  venv/
2
+ .env
3
+ test.ipynb
4
+ __pycache__/
5
+ *.png
6
+ *.mp3
7
+ *.xlsx
agent.py ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import InferenceClient
2
+
3
+ # from langchain_together import Together
4
+ from smolagents import (
5
+ CodeAgent,
6
+ DuckDuckGoSearchTool,
7
+ WikipediaSearchTool,
8
+ VisitWebpageTool,
9
+ HfApiModel,
10
+ LiteLLMModel,
11
+ ApiModel,
12
+ PythonInterpreterTool,
13
+ )
14
+ from smolagents.tools import Tool
15
+ import yaml
16
+ import os
17
+ import requests
18
+ from urllib.parse import urlencode
19
+ from gradio_client import Client, handle_file
20
+
21
+
22
+ class ReadFileTool(Tool):
23
+ name = "read_file"
24
+ description = "Reads the content of a file."
25
+ inputs = {
26
+ "file_path": {"type": "string", "description": "The path to the file to read"}
27
+ }
28
+ output_type = "string"
29
+
30
+ def forward(self, file_path: str) -> str:
31
+ with open(file_path, "r", encoding="utf-8") as file:
32
+ return file.read()
33
+
34
+ def __init__(self, *args, **kwargs):
35
+ self.is_initialized = False
36
+
37
+
38
+ class TranscribeTool(Tool):
39
+ name = "transcribe"
40
+ description = "Transcribes audio files to text."
41
+ inputs = {
42
+ "audio_file_path": {
43
+ "type": "string",
44
+ "description": "The path to the audio file to transcribe",
45
+ }
46
+ }
47
+ output_type = "string"
48
+
49
+ def forward(self, audio_file_path: str) -> str:
50
+ # Placeholder for transcription logic
51
+ client = Client("viktor-hu/parakeet-asr-mcp-server")
52
+ result = client.predict(
53
+ audio_file=handle_file(audio_file_path), api_name="/transcribe_to_text"
54
+ )
55
+ return result
56
+
57
+
58
+ class GetChessBestMoveTool(Tool):
59
+ name = "get_chess_best_move"
60
+ description = "Gets the best move for a given chess position."
61
+ inputs = {
62
+ "fen_position": {
63
+ "type": "string",
64
+ "description": "The FEN string representing the chess position",
65
+ }
66
+ }
67
+ output_type = "string"
68
+
69
+ def forward(self, fen_position: str) -> str:
70
+ url = "https://stockfish.online/api/s/v2.php"
71
+ params = {"fen": fen_position, "depth": 5}
72
+ result = requests.get(url, params=urlencode(params), timeout=60)
73
+ return result.json()
74
+
75
+
76
+ class ImageAnalysisTool(Tool):
77
+ name = "image_analysis"
78
+ description = "Analyzes an image and answers questions about it."
79
+ inputs = {
80
+ "image_path": {
81
+ "type": "string",
82
+ "description": "The path to the image file to analyze",
83
+ },
84
+ "query": {
85
+ "type": "string",
86
+ "description": "The question to ask about the image. For example, 'Perform OCR on the text in the image.'",
87
+ },
88
+ }
89
+ output_type = "string"
90
+
91
+ def forward(self, image_path: str, query: str) -> str:
92
+ # Placeholder for image analysis logic
93
+ client = Client("prithivMLmods/DocScope-R1")
94
+ result = client.predict(
95
+ model_name="Cosmos-Reason1-7B",
96
+ text=query,
97
+ image=handle_file(image_path),
98
+ max_new_tokens=1024,
99
+ temperature=0.6,
100
+ top_p=0.9,
101
+ top_k=50,
102
+ repetition_penalty=1.2,
103
+ api_name="/generate_image",
104
+ )
105
+ return result
106
+
107
+ def __init__(self, *args, **kwargs):
108
+ self.is_initialized = False
109
+
110
+
111
+ class BasicAgent:
112
+ def __init__(
113
+ self, model_id: str = "meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
114
+ ) -> None:
115
+ with open("prompts.yaml", "r", encoding="utf-8") as stream:
116
+ prompt_templates = yaml.safe_load(stream)
117
+ self.agent = CodeAgent(
118
+ tools=[
119
+ DuckDuckGoSearchTool(max_results=2),
120
+ WikipediaSearchTool(),
121
+ VisitWebpageTool(),
122
+ PythonInterpreterTool(),
123
+ ReadFileTool(),
124
+ TranscribeTool(),
125
+ ImageAnalysisTool(),
126
+ GetChessBestMoveTool(),
127
+ ],
128
+ # model=HfApiModel(
129
+ # model_id=model_id,
130
+ # provider="together",
131
+ # token=os.getenv("TOGETHER_API_KEY"),
132
+ # ),
133
+ # model=ApiModel(
134
+ # model=model_id,
135
+ # # temperature=0.7,
136
+ # max_tokens=1500,
137
+ # api_key=os.getenv("TOGETHER_API_KEY")
138
+ # ),
139
+ # model=HfApiModel(),
140
+ model=LiteLLMModel(
141
+ # model_id="huggingface/together/Llama-3.3-70B-Instruct-Free",
142
+ model_id=f"together_ai/{model_id}",
143
+ # api_base="https://api.together.xyz/v1/chat/completions",
144
+ # custom_llm_provider="together",
145
+ api_key=os.getenv("TOGETHER_API_KEY"),
146
+ temperature=0.0,
147
+ ),
148
+ prompt_templates=prompt_templates,
149
+ additional_authorized_imports=["pandas", "numpy", "re", "requests", "bs4"],
150
+ )
151
+ self.prompt_templates = prompt_templates
152
+
153
+ def __call__(self, question: str) -> str:
154
+ return self.agent.run(
155
+ # self.prompt_templates["system_prompt"]+ "\n\n" +
156
+ "You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template: final_answer(YOUR FINAL ANSWER). YOUR FINAL ANSWER should be a number (python int of float, not numpy) OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities write Mount instead of Mt., Saint instead of St., etc), and write the digits in plain text unless specified otherwise, floats are shortened to one decimal if they are 0 so write the number as a string to avoid this (return '10.00' instead of 10.00). If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string. Put spaces between elements in the list such as 'a, b, c'. Divide the task in smaller tasks so thay you do every step correctly. Check if the answer you are going to submit follows all the rules before submitting it. If you are not sure about the answer, ask for more information or clarification. If you are asked to write a code, write the code in a single code block, and make sure that it is correct and that it follows exactly what has been asked. If you are asked to write a function, write the function in a single code block, and make sure that it is correct and that it follows exactly what has been asked."
157
+ # + "Before submitting your final answer, make sure to check that it is correct and that follows exactly what has been asked and it is represented in the asked format. it is very IMPORTANT that you give the answer exactly as asked by the user."
158
+ + "\n\n"
159
+ + question
160
+ # + "\n\n" + ,
161
+ )
app.py CHANGED
@@ -1,42 +1,32 @@
1
  import os
2
- import yaml
3
  import gradio as gr
4
  import requests
5
- import inspect
6
  import pandas as pd
7
- from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
8
- import asyncio
9
- from concurrent.futures import ThreadPoolExecutor
10
 
11
  # (Keep Constants as is)
12
  # --- Constants ---
13
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
14
 
 
15
 
16
- # --- Basic Agent Definition ---
17
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
18
 
 
 
 
 
 
19
 
20
- class BasicAgent:
21
- def __init__(self, model_id: str = "meta-llama/Llama-3.3-70B-Instruct") -> None:
22
- with open("prompts.yaml", "r") as stream:
23
- prompt_templates = yaml.safe_load(stream)
24
- self.agent = CodeAgent(
25
- tools=[DuckDuckGoSearchTool()],
26
- model=HfApiModel(
27
- model_id=model_id,
28
- provider="together",
29
- token=os.getenv("TOGETHER_API_KEY"),
30
- ),
31
- prompt_templates=prompt_templates,
32
- )
33
- self.executor = ThreadPoolExecutor()
34
 
35
- def __call__(self, question: str) -> str:
36
- return self.agent.run(
37
- "You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string."
38
- + question
39
- )
40
 
41
 
42
  def run_and_submit_all(profile: gr.OAuthProfile | None):
@@ -60,7 +50,9 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
60
 
61
  # 1. Instantiate Agent ( modify this part to create your agent)
62
  try:
63
- agent = BasicAgent()
 
 
64
  except Exception as e:
65
  print(f"Error instantiating agent: {e}")
66
  return f"Error initializing agent: {e}", None
@@ -100,6 +92,12 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
100
  print(f"Skipping item with missing task_id or question: {item}")
101
  continue
102
  try:
 
 
 
 
 
 
103
  submitted_answer = agent(question_text)
104
  answers_payload.append(
105
  {"task_id": task_id, "submitted_answer": submitted_answer}
@@ -136,6 +134,8 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
136
 
137
  # 5. Submit
138
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
 
 
139
  try:
140
  response = requests.post(submit_url, json=submission_data, timeout=60)
141
  response.raise_for_status()
@@ -176,6 +176,8 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
176
  print(status_message)
177
  results_df = pd.DataFrame(results_log)
178
  return status_message, results_df
 
 
179
 
180
 
181
  # --- Build Gradio Interface using Blocks ---
 
1
  import os
 
2
  import gradio as gr
3
  import requests
 
4
  import pandas as pd
5
+ import json
6
+ from agent import BasicAgent # Import your agent class from agent.py
7
+ from utils import download_file
8
 
9
  # (Keep Constants as is)
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
+ from dotenv import load_dotenv
14
 
15
+ load_dotenv()
16
+ # Initialize the InferenceClient with together as the provider
17
 
18
+ # client = InferenceClient(
19
+ # "meta-llama/Llama-3.3-70B-Instruct-Free",
20
+ # provider="together",
21
+ # api_key=os.getenv("TOGETHER_API_KEY") # Replace with your API key (HF or custom)
22
+ # )
23
 
24
+ # --- Basic Agent Definition ---
25
+ # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
26
+ # from huggingface_hub import login
27
+ # import os
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # login(token=os.getenv("HUGGINGFACE_TOKEN"))
 
 
 
 
30
 
31
 
32
  def run_and_submit_all(profile: gr.OAuthProfile | None):
 
50
 
51
  # 1. Instantiate Agent ( modify this part to create your agent)
52
  try:
53
+ agent = (
54
+ BasicAgent()
55
+ ) # (model_id="deepseek-ai/DeepSeek-R1-Distill-Llama-70B-free")
56
  except Exception as e:
57
  print(f"Error instantiating agent: {e}")
58
  return f"Error initializing agent: {e}", None
 
92
  print(f"Skipping item with missing task_id or question: {item}")
93
  continue
94
  try:
95
+ if item["file_name"]:
96
+ file_path = item["file_name"]
97
+ download_path = download_file(
98
+ f"{api_url}/files/{item['task_id']}", file_path
99
+ )
100
+ question_text += f"\n\nThe file is available locally at {download_path}. Please use it to answer the question."
101
  submitted_answer = agent(question_text)
102
  answers_payload.append(
103
  {"task_id": task_id, "submitted_answer": submitted_answer}
 
134
 
135
  # 5. Submit
136
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
137
+ json.dump(submission_data, open("submission_data.json", "w"), indent=2)
138
+ print("Submission data saved to submission_data.json for debugging.")
139
  try:
140
  response = requests.post(submit_url, json=submission_data, timeout=60)
141
  response.raise_for_status()
 
176
  print(status_message)
177
  results_df = pd.DataFrame(results_log)
178
  return status_message, results_df
179
+ finally:
180
+ print(submission_data) # Log the submission data for debugging
181
 
182
 
183
  # --- Build Gradio Interface using Blocks ---
requirements.txt CHANGED
@@ -1,3 +1,5 @@
1
  gradio
2
  requests
3
- smolagents
 
 
 
1
  gradio
2
  requests
3
+ smolagents==1.13.0
4
+ smolagents[litellm]
5
+ wikipedia-api
utils.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import shutil
2
+ import requests
3
+
4
+
5
+ def download_file(url, local_filename):
6
+ with requests.get(url, stream=True) as r:
7
+ with open(local_filename, "wb") as f:
8
+ shutil.copyfileobj(r.raw, f)
9
+
10
+ return local_filename