sanjeed5 commited on
Commit
555dbe6
·
1 Parent(s): b94f3d0

Update dependencies in pyproject.toml and requirements.txt, and add test_single_q.py for running single and all question tests. Introduce tools.py for Perplexity API integration with enhanced error handling and logging.

Browse files
Files changed (4) hide show
  1. pyproject.toml +8 -0
  2. requirements.txt +4 -1
  3. test_single_q.py +149 -0
  4. tools.py +68 -0
pyproject.toml CHANGED
@@ -5,5 +5,13 @@ description = "Add your description here"
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
 
 
8
  "duckduckgo-search>=8.0.2",
 
 
 
 
 
 
9
  ]
 
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
8
+ "bs4>=0.0.2",
9
+ "dotenv>=0.9.9",
10
  "duckduckgo-search>=8.0.2",
11
+ "gradio>=5.29.1",
12
+ "markdownify>=1.1.0",
13
+ "openai>=1.75.0",
14
+ "openpyxl>=3.1.5",
15
+ "requests>=2.32.3",
16
+ "smolagents[litellm]>=1.16.1",
17
  ]
requirements.txt CHANGED
@@ -1,2 +1,5 @@
1
  gradio
2
- requests
 
 
 
 
1
  gradio
2
+ requests
3
+ openai
4
+ smolagents
5
+ openpyxl
test_single_q.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import requests
4
+ import sys # Added for command-line arguments
5
+ from agent import BasicAgent
6
+
7
+ # --- Constants ---
8
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
9
+ DOWNLOAD_DIR = "downloaded_task_files" # Directory to save downloaded files
10
+ QUESTIONS_FILE = "data/questions.json"
11
+ # QUESTION_INDEX = 3 # Removed global constant
12
+
13
+ def run_single_question_test(question_index: int): # Added question_index parameter
14
+ """
15
+ Fetches a single question by index, downloads its associated file (if any),
16
+ runs the BasicAgent on it, and prints the answer.
17
+ """
18
+ # Create download directory if it doesn't exist
19
+ try:
20
+ os.makedirs(DOWNLOAD_DIR, exist_ok=True)
21
+ print(f"Ensured download directory exists: {DOWNLOAD_DIR}")
22
+ except OSError as e:
23
+ print(f"Error creating download directory {DOWNLOAD_DIR}: {e}")
24
+ return
25
+
26
+ # 1. Load Questions
27
+ try:
28
+ with open(QUESTIONS_FILE, 'r') as f:
29
+ questions_data = json.load(f)
30
+ if not questions_data or not isinstance(questions_data, list) or len(questions_data) <= question_index:
31
+ print(f"Error: Could not load question at index {question_index} (0-indexed) from {QUESTIONS_FILE}. Total questions: {len(questions_data) if isinstance(questions_data, list) else 'N/A'}")
32
+ return
33
+ item = questions_data[question_index]
34
+ print(f"Loaded question {question_index + 1} (from 1-indexed input): {item.get('question')}")
35
+ except FileNotFoundError:
36
+ print(f"Error: Questions file not found at {QUESTIONS_FILE}")
37
+ return
38
+ except json.JSONDecodeError:
39
+ print(f"Error: Could not decode JSON from {QUESTIONS_FILE}")
40
+ return
41
+ except Exception as e:
42
+ print(f"Error loading or parsing {QUESTIONS_FILE}: {e}")
43
+ return
44
+
45
+ # 2. Instantiate Agent
46
+ try:
47
+ agent = BasicAgent()
48
+ print("Agent instantiated successfully.")
49
+ except Exception as e:
50
+ print(f"Error instantiating agent: {e}")
51
+ return
52
+
53
+ task_id = item.get("task_id")
54
+ question_text = item.get("question")
55
+ file_name = item.get("file_name")
56
+ local_file_path = None
57
+
58
+ if not task_id or question_text is None:
59
+ print(f"Skipping item with missing task_id or question: {item}")
60
+ return
61
+
62
+ if file_name:
63
+ download_url = f"{DEFAULT_API_URL}/files/{task_id}"
64
+ local_file_path = os.path.join(DOWNLOAD_DIR, file_name)
65
+ print(f"Attempting to download file for task {task_id} (using task_id in URL): {file_name} from {download_url}")
66
+ try:
67
+ file_response = requests.get(download_url, stream=True, timeout=30)
68
+ file_response.raise_for_status()
69
+ with open(local_file_path, 'wb') as f:
70
+ for chunk in file_response.iter_content(chunk_size=8192):
71
+ f.write(chunk)
72
+ print(f"Successfully downloaded to {local_file_path}")
73
+ except requests.exceptions.RequestException as e:
74
+ print(f"Failed to download {file_name}: {e}")
75
+ local_file_path = None # Ensure agent doesn't get a path to a non-existent/failed file
76
+ except Exception as e:
77
+ print(f"An unexpected error occurred downloading {file_name}: {e}")
78
+ local_file_path = None
79
+ else:
80
+ print("No file associated with this question.")
81
+
82
+ # 3. Run Agent on the single question
83
+ try:
84
+ print(f"Running agent on question: {question_text}")
85
+ if local_file_path:
86
+ print(f"Providing file: {local_file_path}")
87
+ submitted_answer = agent(question_text, file_path=local_file_path)
88
+ print(f"\n--- Agent's Answer for Task ID: {task_id} ---")
89
+ print(submitted_answer)
90
+ print("--- End of Answer ---")
91
+
92
+ except Exception as e:
93
+ print(f"Error running agent on task {task_id}: {e}")
94
+
95
+ def run_all_questions_test():
96
+ """
97
+ Runs the test for all questions in the QUESTIONS_FILE.
98
+ """
99
+ print("Attempting to run tests for all questions...")
100
+ try:
101
+ with open(QUESTIONS_FILE, 'r') as f:
102
+ questions_data = json.load(f)
103
+ if not questions_data or not isinstance(questions_data, list):
104
+ print(f"Error: Could not load questions from {QUESTIONS_FILE} or it's not a list.")
105
+ return
106
+
107
+ num_questions = len(questions_data)
108
+ if num_questions == 0:
109
+ print(f"No questions found in {QUESTIONS_FILE}.")
110
+ return
111
+
112
+ print(f"Found {num_questions} questions to test.")
113
+ for i in range(num_questions):
114
+ print(f"\n--- Running Test for Question {i+1}/{num_questions} ---")
115
+ run_single_question_test(i)
116
+ print(f"--- Finished Test for Question {i+1}/{num_questions} ---\n")
117
+ print("All question tests completed.")
118
+
119
+ except FileNotFoundError:
120
+ print(f"Error: Questions file not found at {QUESTIONS_FILE}")
121
+ except json.JSONDecodeError:
122
+ print(f"Error: Could not decode JSON from {QUESTIONS_FILE}")
123
+ except Exception as e:
124
+ print(f"An unexpected error occurred while running all questions: {e}")
125
+
126
+ if __name__ == "__main__":
127
+ if len(sys.argv) < 2:
128
+ print("Usage: python test_single_q.py <question_number | 'all'>")
129
+ print("Example (single question): python test_single_q.py 4")
130
+ print("Example (all questions): python test_single_q.py all")
131
+ run_all_questions_test() # Default to running all if no argument is provided
132
+ sys.exit(0)
133
+
134
+ argument = sys.argv[1]
135
+
136
+ if argument.lower() == "all":
137
+ run_all_questions_test()
138
+ else:
139
+ try:
140
+ question_number_arg = int(argument)
141
+ if question_number_arg <= 0:
142
+ print("Error: Question number must be a positive integer.")
143
+ sys.exit(1)
144
+ # Convert 1-indexed input to 0-indexed for list access
145
+ question_idx_0_based = question_number_arg - 1
146
+ run_single_question_test(question_idx_0_based)
147
+ except ValueError:
148
+ print("Error: Invalid argument. Please enter an integer for a specific question or 'all'.")
149
+ sys.exit(1)
tools.py CHANGED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from openai import OpenAI
2
+ from smolagents import tool
3
+ import os
4
+ from dotenv import load_dotenv
5
+
6
+ load_dotenv()
7
+
8
+ PERPLEXITY_API_KEY = os.getenv("PERPLEXITY_API_KEY")
9
+
10
+
11
+ @tool
12
+ def perplexity_search_tool(query: str) -> str:
13
+ """
14
+ Performs a web search using the Perplexity API and returns the result.
15
+
16
+ Args:
17
+ query: The search query.
18
+
19
+ Returns:
20
+ The search result from Perplexity API or an error message.
21
+ """
22
+ if not PERPLEXITY_API_KEY:
23
+ return "Error: Perplexity API key not set. Please set the PERPLEXITY_API_KEY environment variable."
24
+
25
+ messages = [
26
+ {
27
+ "role": "system",
28
+ "content": (
29
+ "You are a helpful assistant"
30
+ ),
31
+ },
32
+ {
33
+ "role": "user",
34
+ "content": query,
35
+ },
36
+ ]
37
+
38
+ try:
39
+ client = OpenAI(api_key=PERPLEXITY_API_KEY, base_url="https://api.perplexity.ai")
40
+
41
+ response = client.chat.completions.create(
42
+ model="sonar-pro", # Using sonar-pro as per documentation
43
+ messages=messages,
44
+ )
45
+ # Assuming the main content is in the first choice's message
46
+ if response.choices and len(response.choices) > 0:
47
+ return response.choices[0].message.content
48
+ else:
49
+ return "Error: No response choices received from Perplexity API."
50
+ except Exception as e:
51
+ return f"Error calling Perplexity API: {str(e)}"
52
+
53
+
54
+ if __name__ == "__main__":
55
+ # Example usage:
56
+ # Make sure to set the PERPLEXITY_API_KEY environment variable before running directly
57
+ if PERPLEXITY_API_KEY:
58
+ search_query = "What are the latest advancements in AI?"
59
+ result = perplexity_search_tool(search_query)
60
+ print(f"Search query: {search_query}")
61
+ print(f"Result:\\n{result}")
62
+
63
+ search_query_stars = "How many stars are there in our galaxy?"
64
+ result_stars = perplexity_search_tool(search_query_stars)
65
+ print(f"Search query: {search_query_stars}")
66
+ print(f"Result:\\n{result_stars}")
67
+ else:
68
+ print("Please set the PERPLEXITY_API_KEY environment variable to test the tool.")