JPM34 commited on
Commit
b7fa19f
·
1 Parent(s): 715a773

Added agent from mistral and llama

Browse files
Files changed (3) hide show
  1. agent_mistral.py +197 -0
  2. agent_openrouter_llama.py +197 -0
  3. app.py +3 -1
agent_mistral.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import os
3
+
4
+ import tempfile
5
+
6
+ from langchain.agents import AgentExecutor, create_tool_calling_agent
7
+ from langchain_core.prompts import ChatPromptTemplate
8
+ from langchain_core.tools import Tool
9
+ from langchain_mistralai import ChatMistralAI
10
+ from langchain_experimental.utilities import PythonREPL
11
+
12
+ from tools_audio import transcribe_audio
13
+
14
+ from tools_doc import (
15
+ analyze_csv_file,
16
+ analyze_excel_file,
17
+ download_file_from_url,
18
+ extract_text_from_image,
19
+ read_file,
20
+ )
21
+ from tools_video import (
22
+ review_youtube_video,
23
+ use_vision_model,
24
+ transcribe_youtube,
25
+ video_frames_to_images,
26
+ )
27
+
28
+ from tools_browser import website_scrape, web_search
29
+
30
+ from answers import create_final_answer_graph, validate_answer
31
+
32
+ logger = logging.getLogger(__name__)
33
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
34
+
35
+
36
+ class BasicAgent:
37
+ def __init__(self):
38
+ try:
39
+ logger.info("Initializing BasicAgent")
40
+
41
+ # Create the prompt template
42
+ prompt = ChatPromptTemplate.from_messages(
43
+ [
44
+ (
45
+ "system",
46
+ """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.
47
+ """,
48
+ ),
49
+ ("placeholder", "{chat_history}"),
50
+ ("human", "{input}"),
51
+ ("placeholder", "{agent_scratchpad}"),
52
+ ]
53
+ )
54
+ logger.info("Created prompt template")
55
+
56
+ # Initialize Gemini model
57
+ logger.info("Creating Gemini model...")
58
+ llm = ChatMistralAI(
59
+ # model="models/gemini-2.5-flash-preview-04-17",
60
+ model="mistral-small-latest",
61
+ google_api_key=os.getenv("GEMINI_KEY"),
62
+ temperature=0.2,
63
+ )
64
+ logger.info("Created Gemini model successfully")
65
+
66
+ # Define available tools
67
+ tools = [
68
+ # GoogleSearchResults(
69
+ # api_wrapper=GoogleSearchAPIWrapper(
70
+ # google_api_key=os.getenv("GOOGLE_SEARCH_API_KEY"),
71
+ # google_cse_id=os.getenv("GOOGLE_CSE_ID"),
72
+ # k=5, # Number of results to return
73
+ # )
74
+ # ),
75
+ web_search,
76
+ analyze_csv_file,
77
+ analyze_excel_file,
78
+ download_file_from_url,
79
+ extract_text_from_image,
80
+ read_file,
81
+ review_youtube_video,
82
+ transcribe_audio,
83
+ transcribe_youtube,
84
+ use_vision_model,
85
+ video_frames_to_images,
86
+ website_scrape,
87
+ Tool(
88
+ name="python_repl",
89
+ description="A Python shell. Use this to execute python commands. Input # should be a valid python command. If you want to see the output of a value, # you should print it out with `print(...)`.",
90
+ func=PythonREPL().run,
91
+ ),
92
+ ]
93
+ logger.info("Tools: %s", tools)
94
+
95
+ # Create the agent
96
+ agent = create_tool_calling_agent(llm, tools, prompt)
97
+ logger.info("Created tool calling agent")
98
+
99
+ # Create the agent executor
100
+ self.agent_executor = AgentExecutor(
101
+ agent=agent,
102
+ tools=tools,
103
+ return_intermediate_steps=True,
104
+ verbose=True,
105
+ )
106
+ logger.info("Created agent executor")
107
+
108
+ # Create the graph
109
+ self.validation_graph = create_final_answer_graph()
110
+
111
+ except Exception as e:
112
+ logger.error("Error initializing agent: %s", e, exc_info=True)
113
+ raise
114
+
115
+ def __call__(self, question: str, task_id: str) -> str:
116
+ """Execute the agent with the given question and optional file.
117
+ Args:
118
+ question (str): The question to answer
119
+ task_id (str): The task ID to fetch the file
120
+ """
121
+ max_retries = 3
122
+ attempt = 0
123
+
124
+ # Create a temporary directory that will be automatically cleaned up
125
+ print("HELLO")
126
+ with tempfile.TemporaryDirectory() as temp_dir:
127
+ while attempt < max_retries:
128
+ # default_api_url = os.getenv("DEFAULT_API_URL")
129
+ default_api_url = DEFAULT_API_URL
130
+ file_url = f"{default_api_url}/files/{task_id}"
131
+
132
+ try:
133
+ print("HELLO-A")
134
+ # Download file to temporary directory
135
+ file = download_file_from_url.invoke(
136
+ {
137
+ "url": file_url,
138
+ "directory": temp_dir,
139
+ }
140
+ )
141
+ except Exception as e:
142
+ logger.error(f"Error downloading file: {e}")
143
+ file = None
144
+
145
+ try:
146
+ print("HELLO-B")
147
+ attempt += 1
148
+ logger.info(f"Attempt {attempt} of {max_retries}")
149
+
150
+ # Prepare input with file information
151
+ if file and file.get("type") != "error":
152
+ input_data = {
153
+ "input": question
154
+ + f" [File: type={file.get('type', 'None')}, path={file.get('path', 'None')}]",
155
+ }
156
+ else:
157
+ input_data = {
158
+ "input": question,
159
+ }
160
+
161
+ # Run the agent to get the answer
162
+ result = self.agent_executor.invoke(input_data)
163
+ answer = result.get("output", "")
164
+
165
+ logger.info(f"Attempt {attempt} result: {result}")
166
+
167
+ # Run validation
168
+ validation_result = validate_answer(
169
+ self.validation_graph,
170
+ answer,
171
+ [result.get("intermediate_steps", [])],
172
+ )
173
+
174
+ valid_answer = validation_result.get("valid_answer", False)
175
+ final_answer = validation_result.get("final_answer", "")
176
+
177
+ if valid_answer:
178
+ logger.info(f"Valid answer found on attempt {attempt}")
179
+ return final_answer
180
+
181
+ logger.warning(
182
+ f"Validation failed on attempt {attempt}: {final_answer}"
183
+ )
184
+ if attempt >= max_retries:
185
+ raise Exception(
186
+ f"Failed to get valid answer after {max_retries} attempts. Last error: {final_answer}"
187
+ )
188
+
189
+ except Exception as e:
190
+ logger.error(
191
+ f"Error in attempt {attempt}: {e}", exc_info=True
192
+ )
193
+ if attempt >= max_retries:
194
+ raise Exception(
195
+ f"Failed after {max_retries} attempts. Last error: {str(e)}"
196
+ )
197
+ continue
agent_openrouter_llama.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import os
3
+
4
+ import tempfile
5
+
6
+ from langchain.agents import AgentExecutor, create_tool_calling_agent
7
+ from langchain_core.prompts import ChatPromptTemplate
8
+ from langchain_core.tools import Tool
9
+ from langchain_experimental.utilities import PythonREPL
10
+
11
+ from langchain_openai import ChatOpenAI
12
+
13
+
14
+ from tools_audio import transcribe_audio
15
+
16
+ from tools_doc import (
17
+ analyze_csv_file,
18
+ analyze_excel_file,
19
+ download_file_from_url,
20
+ extract_text_from_image,
21
+ read_file,
22
+ )
23
+ from tools_video import (
24
+ review_youtube_video,
25
+ use_vision_model,
26
+ transcribe_youtube,
27
+ video_frames_to_images,
28
+ )
29
+
30
+ from tools_browser import website_scrape, web_search
31
+
32
+ from answers import create_final_answer_graph, validate_answer
33
+
34
+ logger = logging.getLogger(__name__)
35
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
36
+
37
+
38
+ class BasicAgent:
39
+ def __init__(self):
40
+ try:
41
+ logger.info("Initializing BasicAgent")
42
+
43
+ # Create the prompt template
44
+ prompt = ChatPromptTemplate.from_messages(
45
+ [
46
+ (
47
+ "system",
48
+ """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.
49
+ """,
50
+ ),
51
+ ("placeholder", "{chat_history}"),
52
+ ("human", "{input}"),
53
+ ("placeholder", "{agent_scratchpad}"),
54
+ ]
55
+ )
56
+ logger.info("Created prompt template")
57
+
58
+ # Initialize Gemini model
59
+ llm = ChatOpenAI(
60
+ openai_api_key=os.getenv("OPENROUTER_API_KEY"),
61
+ openai_api_base="https://openrouter.ai/api/v1",
62
+ model_name="meta-llama/llama-4-scout:free",
63
+ )
64
+ logger.info("Created Gemini model successfully")
65
+
66
+ # Define available tools
67
+ tools = [
68
+ # GoogleSearchResults(
69
+ # api_wrapper=GoogleSearchAPIWrapper(
70
+ # google_api_key=os.getenv("GOOGLE_SEARCH_API_KEY"),
71
+ # google_cse_id=os.getenv("GOOGLE_CSE_ID"),
72
+ # k=5, # Number of results to return
73
+ # )
74
+ # ),
75
+ web_search,
76
+ analyze_csv_file,
77
+ analyze_excel_file,
78
+ download_file_from_url,
79
+ extract_text_from_image,
80
+ read_file,
81
+ review_youtube_video,
82
+ transcribe_audio,
83
+ transcribe_youtube,
84
+ use_vision_model,
85
+ video_frames_to_images,
86
+ website_scrape,
87
+ Tool(
88
+ name="python_repl",
89
+ description="A Python shell. Use this to execute python commands. Input # should be a valid python command. If you want to see the output of a value, # you should print it out with `print(...)`.",
90
+ func=PythonREPL().run,
91
+ ),
92
+ ]
93
+ logger.info("Tools: %s", tools)
94
+
95
+ # Create the agent
96
+ agent = create_tool_calling_agent(llm, tools, prompt)
97
+ logger.info("Created tool calling agent")
98
+
99
+ # Create the agent executor
100
+ self.agent_executor = AgentExecutor(
101
+ agent=agent,
102
+ tools=tools,
103
+ return_intermediate_steps=True,
104
+ verbose=True,
105
+ )
106
+ logger.info("Created agent executor")
107
+
108
+ # Create the graph
109
+ self.validation_graph = create_final_answer_graph()
110
+
111
+ except Exception as e:
112
+ logger.error("Error initializing agent: %s", e, exc_info=True)
113
+ raise
114
+
115
+ def __call__(self, question: str, task_id: str) -> str:
116
+ """Execute the agent with the given question and optional file.
117
+ Args:
118
+ question (str): The question to answer
119
+ task_id (str): The task ID to fetch the file
120
+ """
121
+ max_retries = 3
122
+ attempt = 0
123
+
124
+ # Create a temporary directory that will be automatically cleaned up
125
+ print("HELLO")
126
+ with tempfile.TemporaryDirectory() as temp_dir:
127
+ while attempt < max_retries:
128
+ # default_api_url = os.getenv("DEFAULT_API_URL")
129
+ default_api_url = DEFAULT_API_URL
130
+ file_url = f"{default_api_url}/files/{task_id}"
131
+
132
+ try:
133
+ print("HELLO-A")
134
+ # Download file to temporary directory
135
+ file = download_file_from_url.invoke(
136
+ {
137
+ "url": file_url,
138
+ "directory": temp_dir,
139
+ }
140
+ )
141
+ except Exception as e:
142
+ logger.error(f"Error downloading file: {e}")
143
+ file = None
144
+
145
+ try:
146
+ print("HELLO-B")
147
+ attempt += 1
148
+ logger.info(f"Attempt {attempt} of {max_retries}")
149
+
150
+ # Prepare input with file information
151
+ if file and file.get("type") != "error":
152
+ input_data = {
153
+ "input": question
154
+ + f" [File: type={file.get('type', 'None')}, path={file.get('path', 'None')}]",
155
+ }
156
+ else:
157
+ input_data = {
158
+ "input": question,
159
+ }
160
+
161
+ # Run the agent to get the answer
162
+ result = self.agent_executor.invoke(input_data)
163
+ answer = result.get("output", "")
164
+
165
+ logger.info(f"Attempt {attempt} result: {result}")
166
+
167
+ # Run validation
168
+ validation_result = validate_answer(
169
+ self.validation_graph,
170
+ answer,
171
+ [result.get("intermediate_steps", [])],
172
+ )
173
+
174
+ valid_answer = validation_result.get("valid_answer", False)
175
+ final_answer = validation_result.get("final_answer", "")
176
+
177
+ if valid_answer:
178
+ logger.info(f"Valid answer found on attempt {attempt}")
179
+ return final_answer
180
+
181
+ logger.warning(
182
+ f"Validation failed on attempt {attempt}: {final_answer}"
183
+ )
184
+ if attempt >= max_retries:
185
+ raise Exception(
186
+ f"Failed to get valid answer after {max_retries} attempts. Last error: {final_answer}"
187
+ )
188
+
189
+ except Exception as e:
190
+ logger.error(
191
+ f"Error in attempt {attempt}: {e}", exc_info=True
192
+ )
193
+ if attempt >= max_retries:
194
+ raise Exception(
195
+ f"Failed after {max_retries} attempts. Last error: {str(e)}"
196
+ )
197
+ continue
app.py CHANGED
@@ -9,7 +9,9 @@ import pandas as pd
9
  import requests
10
  from dotenv import load_dotenv
11
 
12
- from agent_gemini import BasicAgent
 
 
13
 
14
  # Load environment variables from .env file
15
  load_dotenv()
 
9
  import requests
10
  from dotenv import load_dotenv
11
 
12
+ # from agent_gemini import BasicAgent
13
+ # from agent_mistral import BasicAgent
14
+ from agent_openrouter_llama import BasicAgent
15
 
16
  # Load environment variables from .env file
17
  load_dotenv()