kamorou commited on
Commit
0fa0473
·
verified ·
1 Parent(s): 50ef2e7

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +157 -22
agent.py CHANGED
@@ -1,14 +1,26 @@
1
  import os
 
2
  import gradio as gr
 
 
 
 
 
 
 
 
 
3
  from langchain_huggingface import HuggingFaceEndpoint
 
4
  from langchain_community.tools.tavily_search import TavilySearchResults
5
- # NEW IMPORT
6
- from langchain_experimental.tools import PythonREPLTool
7
- from langchain_core.messages import BaseMessage, HumanMessage
8
- from langgraph.graph import StateGraph, END
9
- from langgraph.prebuilt import ToolNode
10
- from typing import TypedDict, Annotated, List
11
- from dotenv import load_dotenv
 
12
 
13
  # --- 1. LOAD API KEYS ---
14
  load_dotenv()
@@ -22,31 +34,153 @@ os.environ["TAVILY_API_KEY"] = tavily_api_key
22
 
23
  # --- 2. DEFINE TOOLS and INITIALIZE LLM ---
24
  # UPDATED TOOLS LIST
25
- tools = [TavilySearchResults(max_results=3), PythonREPLTool()]
26
- tool_node = ToolNode(tools)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
29
- llm = HuggingFaceEndpoint(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  repo_id=repo_id,
31
  huggingfacehub_api_token=hf_token,
32
- temperature=0.1,
33
  max_new_tokens=1024,
34
  )
35
- llm_with_tools = llm.bind_tools(tools)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
 
38
  # --- 3. DEFINE THE AGENT'S STATE ---
 
39
  class AgentState(TypedDict):
40
  messages: Annotated[List[BaseMessage], lambda x, y: x + y]
41
 
42
- # SYSTEM PROMPT
43
- system_prompt = """
44
- You are a helpful assistant tasked with answering questions using a set of tools.
45
- Now, I will ask you a question. Report your thoughts, and finish your answer with the following template:
46
- FINAL ANSWER: [YOUR FINAL ANSWER].
47
- 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.
48
- Your answer should only start with "FINAL ANSWER: ", then follows with the answer.
49
- """
50
 
51
 
52
 
@@ -115,4 +249,5 @@ iface = gr.Interface(
115
 
116
  # --- 8. LAUNCH THE APP ---
117
  iface.launch()
118
- # gr.launch()
 
 
1
  import os
2
+ from dotenv import load_dotenv
3
  import gradio as gr
4
+
5
+
6
+ # LangGraph & LangChain
7
+ from langgraph.graph import START, StateGraph, MessagesState
8
+ from langgraph.prebuilt import ToolNode, tools_condition
9
+ from langchain_core.messages import SystemMessage, HumanMessage
10
+ from langchain_core.tools import tool
11
+
12
+ #infrence provider
13
  from langchain_huggingface import HuggingFaceEndpoint
14
+ # Web search tool
15
  from langchain_community.tools.tavily_search import TavilySearchResults
16
+
17
+ # # NEW IMPORT
18
+ # from langchain_experimental.tools import PythonREPLTool
19
+ # from langchain_core.messages import BaseMessage, HumanMessage
20
+ # from langgraph.graph import StateGraph, END
21
+ # from langgraph.prebuilt import ToolNode
22
+ # from typing import TypedDict, Annotated, List
23
+
24
 
25
  # --- 1. LOAD API KEYS ---
26
  load_dotenv()
 
34
 
35
  # --- 2. DEFINE TOOLS and INITIALIZE LLM ---
36
  # UPDATED TOOLS LIST
37
+ # tools = [TavilySearchResults(max_results=3), PythonREPLTool()]
38
+ # tool_node = ToolNode(tools)
39
+
40
+
41
+ ### TOOLS
42
+
43
+ @tool
44
+ def multiply(a: int, b: int) -> int:
45
+ """Multiply two numbers.
46
+ Args:
47
+ a: first int
48
+ b: second int
49
+ """
50
+ return a * b
51
+
52
+ @tool
53
+ def add(a: int, b: int) -> int:
54
+ """Add two numbers.
55
+
56
+ Args:
57
+ a: first int
58
+ b: second int
59
+ """
60
+ return a + b
61
+
62
+ @tool
63
+ def subtract(a: int, b: int) -> int:
64
+ """Subtract two numbers.
65
+
66
+ Args:
67
+ a: first int
68
+ b: second int
69
+ """
70
+ return a - b
71
+
72
+ @tool
73
+ def divide(a: int, b: int) -> int:
74
+ """Divide two numbers.
75
+
76
+ Args:
77
+ a: first int
78
+ b: second int
79
+ """
80
+ if b == 0:
81
+ raise ValueError("Cannot divide by zero.")
82
+ return a / b
83
+
84
+ @tool
85
+ def modulus(a: int, b: int) -> int:
86
+ """Get the modulus of two numbers.
87
+
88
+ Args:
89
+ a: first int
90
+ b: second int
91
+ """
92
+ return a % b
93
+
94
+
95
+
96
+ @tool
97
+ def web_search(query: str) -> str:
98
+ """Search Tavily for a query and return maximum 3 results.
99
+
100
+ Args:
101
+ query: The search query."""
102
+ search_docs = TavilySearchResults(max_results=3).invoke(query=query)
103
+ formatted_search_docs = "\n\n---\n\n".join(
104
+ [
105
+ f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
106
+ for doc in search_docs
107
+ ])
108
+ return {"web_results": formatted_search_docs}
109
 
110
+ # SYSTEM PROMPT
111
+ system_prompt = """
112
+ You are a helpful assistant tasked with answering questions using a set of tools.
113
+ Now, I will ask you a question. Report your thoughts, and finish your answer with the following template:
114
+ FINAL ANSWER: [YOUR FINAL ANSWER].
115
+ 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.
116
+ Your answer should only start with "FINAL ANSWER: ", then follows with the answer.
117
+ """
118
+ tools = [divide, add, multiply,subtract, web_search,modulus ]
119
+
120
+ ### LLM
121
+ # repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
122
+ # llm = HuggingFaceEndpoint(
123
+ # repo_id=repo_id,
124
+ # huggingfacehub_api_token=hf_token,
125
+ # temperature=0.1,
126
+ # max_new_tokens=1024,
127
+ # )
128
+ # llm_with_tools = llm.bind_tools(tools)
129
+
130
+
131
+ def build_graph():
132
+ """Builds and returns the LangGraph graph."""
133
+ #llm = ChatGroq(model="qwen-qwq-32b", temperature=0,api_key=groq_api_key)
134
+ repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
135
+ llm = HuggingFaceEndpoint(
136
  repo_id=repo_id,
137
  huggingfacehub_api_token=hf_token,
138
+ temperature=0,
139
  max_new_tokens=1024,
140
  )
141
+ llm_with_tools = llm.bind_tools(tools)
142
+
143
+ # Node
144
+ def assistant(state: MessagesState):
145
+ """Assistant node"""
146
+ return {"messages": [llm_with_tools.invoke([system_prompt] + state["messages"])]}
147
+
148
+
149
+ builder = StateGraph(MessagesState)
150
+ # Nodes
151
+ builder.add_node("assistant", assistant)
152
+ builder.add_node("tools", ToolNode(tools))
153
+
154
+ # Edges
155
+ builder.add_edge(START, "assistant")
156
+ builder.add_conditional_edges("assistant", tools_condition)
157
+ builder.add_edge("tools", "assistant")
158
+
159
+ #Compile graph
160
+ return builder.compile()
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
 
177
 
178
  # --- 3. DEFINE THE AGENT'S STATE ---
179
+ """
180
  class AgentState(TypedDict):
181
  messages: Annotated[List[BaseMessage], lambda x, y: x + y]
182
 
183
+
 
 
 
 
 
 
 
184
 
185
 
186
 
 
249
 
250
  # --- 8. LAUNCH THE APP ---
251
  iface.launch()
252
+ # gr.launch()
253
+ """