lam-ho commited on
Commit
ad535b7
·
verified ·
1 Parent(s): 391862b

Update agent.py

Browse files

Modified agent to use langgraph

Files changed (1) hide show
  1. agent.py +112 -235
agent.py CHANGED
@@ -1,253 +1,130 @@
1
- from smolagents import HfApiModel, CodeAgent, DuckDuckGoSearchTool, WikipediaSearchTool, Tool, LiteLLMModel
2
  from langchain_tavily import TavilySearch
3
- from langchain_community.document_loaders import WikipediaLoader, ArxivLoader
4
- import os, time, math, pandas, numpy, PIL
5
-
6
-
7
- class add(Tool):
8
- name = "add"
9
- description = """
10
- This tool adds two integers together and returns an integer.
11
-
12
- Args:
13
- a: first integer
14
- b: second integer
15
- """
16
- inputs = {
17
- "a":{
18
- "type":"integer",
19
- "description":"first integer"
20
- },
21
- "b":{
22
- "type":"integer",
23
- "description":"second integer"
24
- }
25
- }
26
- output_type = "integer"
27
-
28
- def forward(self, a: int, b: int):
29
- return a + b
30
-
31
-
32
- class subtract(Tool):
33
- name = "subtract"
34
- description = """
35
- This tool subtracts two integers and returns an integer.
36
 
37
- Args:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  a: first integer
39
  b: second integer
40
- """
41
- inputs = {
42
- "a":{
43
- "type":"integer",
44
- "description":"first integer"
45
- },
46
- "b":{
47
- "type":"integer",
48
- "description":"second integer"
49
- }
50
- }
51
- output_type = "integer"
52
-
53
- def forward(self, a: int, b: int):
54
- return a - b
55
-
56
- class multiply(Tool):
57
- name = "multiply"
58
- description = """
59
- This tool multiplies two integers and returns an integer.
60
 
61
- Args:
 
 
 
62
  a: first integer
63
  b: second integer
64
- """
65
- inputs = {
66
- "a":{
67
- "type":"integer",
68
- "description":"first integer"
69
- },
70
- "b":{
71
- "type":"integer",
72
- "description":"second integer"
73
- }
74
- }
75
- output_type = "integer"
76
-
77
- def forward(self, a: int, b: int):
78
- return a * b
79
-
80
- class divide(Tool):
81
- name = "divide"
82
- description = """
83
- This tool divides two integers and returns an integer.
84
 
85
- Args:
 
 
 
86
  a: first integer
87
  b: second integer
88
- """
89
- inputs = {
90
- "a":{
91
- "type":"integer",
92
- "description":"first integer"
93
- },
94
- "b":{
95
- "type":"integer",
96
- "description":"second integer"
97
- }
98
- }
99
- output_type = "integer"
100
-
101
- def forward(self, a: int, b: int):
102
- if b == 0:
103
- raise ValueError("Cannot divide by zero.")
104
- return a / b
105
-
106
- class modulo(Tool):
107
- name = "modulo"
108
- description = """
109
- This tool returns the modulus of two integers
110
 
111
- Args:
 
 
 
112
  a: first integer
113
  b: second integer
114
- """
115
- inputs = {
116
- "a":{
117
- "type":"integer",
118
- "description":"first integer"
119
- },
120
- "b":{
121
- "type":"integer",
122
- "description":"second integer"
123
- }
124
- }
125
- output_type = "integer"
126
-
127
- def forward(self, a: int, b: int):
128
- return a % b
129
-
130
- class WikipediaSearchTool(Tool):
131
- name = "wikipedia_search_tool"
132
-
133
- description = """
134
- Search Wikipedia for a query and return top 2 results.
135
-
136
- Args:
137
- query: the search query.
138
- """
139
-
140
- inputs = {
141
- "query":{
142
- "type":"string",
143
- "description":"the search query"
144
- }
145
- }
146
- output_type = "string"
147
-
148
- def forward(self, query: str) -> str:
149
- documents = WikipediaLoader(query=query, load_max_docs=2).load()
150
- condensed_docs = "\n\n---\n\n".join(
151
- [
152
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
153
- for doc in documents
154
- ])
155
- return {"wikipedia_results": condensed_docs}
156
-
157
- class TavilySearchTool(Tool):
158
- name = "tavily_search_tool"
159
-
160
- description = """
161
- Search the internet using the browser Tavily and return the top 3 results.
162
-
163
- Args:
164
- query: the search query.
165
  """
166
-
167
- inputs = {
168
- "query":{
169
- "type":"string",
170
- "description":"the search query"
171
- }
172
- }
173
- output_type = "string"
174
-
175
- def forward(self, query: str) -> str:
176
- documents = TavilySearch(max_results=3).invoke(query=query)
177
- condensed_docs = "\n\n---\n\n".join(
178
- [
179
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
180
- for doc in documents
181
- ])
182
- return {"web_search_results": condensed_docs}
183
-
184
-
185
- class ArvixSearchTool(Tool):
186
- name = "arvix_search_tool"
187
-
188
- description = """
189
- Search arxiv for a query and return maximum 3 result.
190
-
191
- Args:
192
- query: The search query.
193
- """
194
-
195
- inputs = {
196
- "query":{
197
- "type":"string",
198
- "description":"the search query"
199
- }
200
- }
201
- output_type = "string"
202
 
203
- def forward(self, query: str) -> str:
204
- documents = ArxivLoader(query=query, load_max_docs=3).load()
205
- condensed_docs = "\n\n---\n\n".join(
206
- [
207
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.content[:1000]}\n</Document>'
208
- for doc in documents
209
- ])
210
- return {"arvix_search_results": condensed_docs}
211
-
212
-
213
- tools=[
214
- add(),
215
- subtract(),
216
- multiply(),
217
- divide(),
218
- modulo(),
219
- WikipediaSearchTool(),
220
- ArvixSearchTool(),
221
- TavilySearchTool()
222
- ]
223
-
224
- # model = LiteLLMModel(model_id="gemini/gemini-2.0-flash-exp",
225
- # api_key=os.getenv("GEMINI_API_KEY"))
226
-
227
- model = LiteLLMModel(
228
- model_id="ollama/gemma3:27b", # Or try other Ollama-supported models
229
- api_base="http://localhost:11434", # Default Ollama local server
230
- num_ctx=8192,
231
- )
232
-
233
- def delay_execution_10(pagent, **kwargs) -> bool:
234
  """
235
- Delays the execution for 10 seconds.
 
 
 
 
236
  """
237
- time.sleep(10)
238
- return True
239
-
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  def create_agent():
241
- agent = CodeAgent(
242
- model = model,
243
- tools = tools,
244
- max_steps=10,
245
- verbosity_level=2,
246
- additional_authorized_imports=['*'],
247
- planning_interval=5,
248
- step_callbacks=[delay_execution_10]
249
- )
250
-
251
- return agent
252
-
253
-
 
 
 
 
 
 
 
 
 
 
1
  from langchain_tavily import TavilySearch
2
+ from langchain_community.document_loaders import WikipediaLoader
3
+ from langchain_ollama import ChatOllama
4
+ from langgraph.prebuilt import create_react_agent
5
+ from langgraph_supervisor import create_supervisor
6
+
7
+ llm_model=ChatOllama(model="qwen2:7b", temperature=0.0, max_tokens=1000, base_url="http://localhost:11434")
8
+
9
+ # Tool for searching wikipedia and returning the content
10
+ def search_wikipedia(query: str) -> str:
11
+ """Searches Wikipedia for the given query and returns the first result's content.
12
+ Args:
13
+ query (str): The search query to use for Wikipedia. Should be a simple keyword or phrase. Do not enter the URL or any other complex query.
14
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ loader = WikipediaLoader(query=query, load_max_docs=1)
17
+ docs = loader.load()
18
+ if docs:
19
+ return "From: " + docs[0].metadata['source'] + "\n\nContent: " + docs[0].page_content
20
+ return "No content found."
21
+
22
+ # Tool for searching the web using Tavily
23
+ def search_web(query: str) -> str:
24
+ """Searches the web for the given query and returns the first result's content.
25
+ Args:
26
+ query (str): The search query to use for web search. Should be a simple keyword or phrase. Do not enter the URL or any other complex query.
27
+ """
28
+ results = TavilySearch(max_results=1).invoke(input=query)
29
+ if results:
30
+ return "From: " + results['results'][0]['url'] + "\n\nContent: " + results['results'][0]['content']
31
+ return "No content found."
32
+
33
+ research_agent = create_react_agent(
34
+ model=llm_model,
35
+ tools=[search_wikipedia, search_web],
36
+ prompt=(
37
+ "You are a research agent.\n\n"
38
+ "INSTRUCTIONS:\n"
39
+ "- Assist ONLY with research-related tasks, DO NOT do any math\n"
40
+ "- After you're done with your tasks, respond to the supervisor directly\n"
41
+ "- Respond ONLY with the results of your work, do NOT include ANY other text."
42
+ ),
43
+ name="research_agent",
44
+ )
45
+
46
+ def add(a: int, b: int) -> int:
47
+ """
48
+ Add two integers and return the result.
49
+ Inputs:
50
  a: first integer
51
  b: second integer
52
+ """
53
+ return a + b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ def subtract(a: int, b: int) -> int:
56
+ """
57
+ Subtract two integers and return the result.
58
+ Inputs:
59
  a: first integer
60
  b: second integer
61
+ """
62
+ return a - b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
+ def multiply(a: int, b: int) -> int:
65
+ """
66
+ Multiply two integers and return the result.
67
+ Inputs:
68
  a: first integer
69
  b: second integer
70
+ """
71
+ return a * b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ def divide(a: int, b: int) -> float:
74
+ """
75
+ Divide two integers and return the result.
76
+ Inputs:
77
  a: first integer
78
  b: second integer
79
+ Note: If b is 0, return "Error: Division by zero is not allowed."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  """
81
+ if b == 0:
82
+ return "Error: Division by zero is not allowed."
83
+ return a / b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
+ def modulo(a: int, b: int) -> int:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  """
87
+ Calculate the modulo of two integers and return the result.
88
+ Inputs:
89
+ a: first integer
90
+ b: second integer
91
+ Note: If b is 0, return "Error: Division by zero is not allowed."
92
  """
93
+ if b == 0:
94
+ return "Error: Division by zero is not allowed."
95
+ return a % b
96
+
97
+ math_agent = create_react_agent(
98
+ model=llm_model,
99
+ tools=[add, subtract, multiply, divide, modulo],
100
+ prompt=(
101
+ "You are a math agent.\n\n"
102
+ "INSTRUCTIONS:\n"
103
+ "- Assist ONLY with math-related tasks\n"
104
+ "- After you're done with your tasks, respond to the supervisor directly\n"
105
+ "- Respond ONLY with the results of your work, do NOT include ANY other text."
106
+ ),
107
+ name="math_agent",
108
+ )
109
  def create_agent():
110
+ supervisor = create_supervisor(
111
+ model=llm_model,
112
+ agents=[research_agent, math_agent],
113
+ prompt=(
114
+ "You are a supervisor managing two agents:\n"
115
+ "- a research agent. Assign research-related tasks to this agent\n"
116
+ "- a math agent. Assign math-related tasks to this agent\n"
117
+ "Assign work to one agent at a time, do not call agents in parallel.\n"
118
+ "Do not do any work yourself. When you are ready to give the final answer, do so as simply as possible.If the answer is a number, write only the number do not use commas or any special characters or any other text. \n"
119
+ "If the answer is a string, write only the string without any additional text.\n"
120
+ "If the answer is a list, write the items in the list separated by commas while following the above rules for numbers and string where appropriate.\n"
121
+ "Preface your answer with FINAL ANSWER: {answer}\n"
122
+ "Example: How many planets are in the solar system?\n Answer: 8\n"
123
+ "Example: What is the capital of France?\n Answer: Paris\n"
124
+ "Example: What is 2 + 2?\n Answer: 4\n"
125
+ ),
126
+ add_handoff_back_messages=True,
127
+ output_mode="full_history",
128
+ ).compile()
129
+
130
+ return supervisor