Spaces:
Sleeping
Sleeping
Commit
·
2b2818d
1
Parent(s):
d317d45
chatbot with tool - completed
Browse files- README.md +4 -2
- screenshots/graph_chatbot_with_tool.png +0 -0
- src/langgraphagenticai/graph/graph_builder.py +52 -4
- src/langgraphagenticai/main.py +27 -9
- src/langgraphagenticai/node/chatbot_with_tool_node.py +37 -0
- src/langgraphagenticai/tools/search_tool.py +15 -0
- src/langgraphagenticai/ui/configfile.ini +1 -1
- src/langgraphagenticai/ui/streamlitui/loadui.py +10 -10
README.md
CHANGED
|
@@ -148,10 +148,12 @@ To stop the Streamlit app, press `Ctrl+C` in the terminal where the app is runni
|
|
| 148 |

|
| 149 |
|
| 150 |
|
| 151 |
-
### 2. Chatbot with Tool
|
| 152 |
**Prompt**: Latest news from the India vs Australia match?
|
|
|
|
| 153 |
**Reference**:
|
| 154 |
-

|
|
|
|
| 155 |
|
| 156 |
### 3. Appointment Receptionist
|
| 157 |
**Prompt 1**: Book an appointment for priti.
|
|
|
|
| 148 |

|
| 149 |
|
| 150 |
|
| 151 |
+
### 2. Chatbot with Tool
|
| 152 |
**Prompt**: Latest news from the India vs Australia match?
|
| 153 |
+
**Prompt2**: search latest news from india
|
| 154 |
**Reference**:
|
| 155 |
+

|
| 156 |
+

|
| 157 |
|
| 158 |
### 3. Appointment Receptionist
|
| 159 |
**Prompt 1**: Book an appointment for priti.
|
screenshots/graph_chatbot_with_tool.png
ADDED
|
src/langgraphagenticai/graph/graph_builder.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
| 1 |
from langgraph.graph import StateGraph
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from src.langgraphagenticai.node.basic_chatbot_node import BasicChatbotNode
|
| 3 |
from src.langgraphagenticai.state.state import State
|
| 4 |
|
|
@@ -9,16 +13,60 @@ class GraphBuilder:
|
|
| 9 |
def __init__(self,model):
|
| 10 |
self.llm = model
|
| 11 |
self.graph_builder = StateGraph(State)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
def setup_graph(self, usecase: str):
|
| 14 |
"""
|
| 15 |
Sets up the graph for the selected use case.
|
| 16 |
"""
|
| 17 |
if usecase == "Basic Chatbot":
|
| 18 |
-
self.
|
| 19 |
-
|
| 20 |
-
self.
|
| 21 |
-
self.graph_builder.set_finish_point("chatbot")
|
| 22 |
else:
|
| 23 |
raise ValueError("Invalid use case selected.")
|
| 24 |
return self.graph_builder.compile()
|
|
|
|
| 1 |
from langgraph.graph import StateGraph
|
| 2 |
+
from langgraph.prebuilt import tools_condition
|
| 3 |
+
|
| 4 |
+
from src.langgraphagenticai.tools.search_tool import create_tool_node, get_tools
|
| 5 |
+
from src.langgraphagenticai.node.chatbot_with_tool_node import ChatbotWithToolNode
|
| 6 |
from src.langgraphagenticai.node.basic_chatbot_node import BasicChatbotNode
|
| 7 |
from src.langgraphagenticai.state.state import State
|
| 8 |
|
|
|
|
| 13 |
def __init__(self,model):
|
| 14 |
self.llm = model
|
| 15 |
self.graph_builder = StateGraph(State)
|
| 16 |
+
|
| 17 |
+
def basic_chatbot_build_graph(self):
|
| 18 |
+
"""
|
| 19 |
+
Builds a basic chatbot graph using LangGraph.
|
| 20 |
+
|
| 21 |
+
This method initializes a chatbot node using the `BasicChatbotNode` class
|
| 22 |
+
and integrates it into the graph. The chatbot node is set as both the
|
| 23 |
+
entry and exit point of the graph.
|
| 24 |
+
"""
|
| 25 |
+
self.basic_chatbot_node = BasicChatbotNode(self.llm)
|
| 26 |
+
self.graph_builder.add_node("chatbot", self.basic_chatbot_node.process)
|
| 27 |
+
self.graph_builder.set_entry_point("chatbot")
|
| 28 |
+
self.graph_builder.set_finish_point("chatbot")
|
| 29 |
+
|
| 30 |
+
def chatbot_with_tool_build_graph(self):
|
| 31 |
+
"""
|
| 32 |
+
Builds an advanced chatbot graph with tool integration.
|
| 33 |
+
|
| 34 |
+
This method creates a chatbot graph that includes both a chatbot node
|
| 35 |
+
and a tool node. It defines tools, initializes the chatbot with tool
|
| 36 |
+
capabilities, and sets up conditional and direct edges between nodes.
|
| 37 |
+
The chatbot node is set as the entry point.
|
| 38 |
+
"""
|
| 39 |
+
# Define tools and tool node
|
| 40 |
+
tools = get_tools()
|
| 41 |
+
tool_node = create_tool_node(tools)
|
| 42 |
+
|
| 43 |
+
# Define LLM
|
| 44 |
+
llm = self.llm
|
| 45 |
+
|
| 46 |
+
# Define chatbot node
|
| 47 |
+
obj_chatbot_with_node = ChatbotWithToolNode(llm)
|
| 48 |
+
chatbot_node = obj_chatbot_with_node.create_chatbot(tools)
|
| 49 |
+
|
| 50 |
+
# Add nodes
|
| 51 |
+
self.graph_builder.add_node("chatbot", chatbot_node)
|
| 52 |
+
self.graph_builder.add_node("tools", tool_node)
|
| 53 |
+
|
| 54 |
+
# Define conditional and direct edges
|
| 55 |
+
self.graph_builder.add_conditional_edges("chatbot", tools_condition)
|
| 56 |
+
self.graph_builder.add_edge("tools", "chatbot")
|
| 57 |
+
|
| 58 |
+
# Set entry point and compile graph
|
| 59 |
+
self.graph_builder.set_entry_point("chatbot")
|
| 60 |
+
|
| 61 |
|
| 62 |
def setup_graph(self, usecase: str):
|
| 63 |
"""
|
| 64 |
Sets up the graph for the selected use case.
|
| 65 |
"""
|
| 66 |
if usecase == "Basic Chatbot":
|
| 67 |
+
self.basic_chatbot_build_graph()
|
| 68 |
+
elif usecase == "Chatbot with Tool":
|
| 69 |
+
self.chatbot_with_tool_build_graph()
|
|
|
|
| 70 |
else:
|
| 71 |
raise ValueError("Invalid use case selected.")
|
| 72 |
return self.graph_builder.compile()
|
src/langgraphagenticai/main.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
| 1 |
-
from src.langgraphagenticai.ui.configfile import Config
|
| 2 |
from src.langgraphagenticai.LLMS.groqllm import GroqLLM
|
| 3 |
from src.langgraphagenticai.graph.graph_builder import GraphBuilder
|
| 4 |
from src.langgraphagenticai.ui.streamlitui.loadui import LoadStreamlitUI
|
|
|
|
| 5 |
import streamlit as st
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
# MAIN Function START
|
|
@@ -25,14 +26,31 @@ def load_langgraph_agenticai_app():
|
|
| 25 |
graph = graph_builder.setup_graph(usecase)
|
| 26 |
|
| 27 |
# Display output in UI
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
st.
|
| 34 |
-
|
| 35 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
# display graph
|
| 38 |
if graph:
|
|
|
|
|
|
|
| 1 |
from src.langgraphagenticai.LLMS.groqllm import GroqLLM
|
| 2 |
from src.langgraphagenticai.graph.graph_builder import GraphBuilder
|
| 3 |
from src.langgraphagenticai.ui.streamlitui.loadui import LoadStreamlitUI
|
| 4 |
+
|
| 5 |
import streamlit as st
|
| 6 |
+
from langchain_core.messages import HumanMessage,AIMessage,ToolMessage
|
| 7 |
|
| 8 |
|
| 9 |
# MAIN Function START
|
|
|
|
| 26 |
graph = graph_builder.setup_graph(usecase)
|
| 27 |
|
| 28 |
# Display output in UI
|
| 29 |
+
if usecase =="Basic Chatbot":
|
| 30 |
+
for event in graph.stream({'messages':("user",user_message)}):
|
| 31 |
+
print(event.values())
|
| 32 |
+
for value in event.values():
|
| 33 |
+
print(value['messages'])
|
| 34 |
+
with st.chat_message("user"):
|
| 35 |
+
st.write(user_message)
|
| 36 |
+
with st.chat_message("assistant"):
|
| 37 |
+
st.write(value["messages"].content)
|
| 38 |
+
elif usecase =="Chatbot with Tool":
|
| 39 |
+
# Prepare state and invoke the graph
|
| 40 |
+
initial_state = {"messages": [user_message]}
|
| 41 |
+
res = graph.invoke(initial_state)
|
| 42 |
+
for message in res['messages']:
|
| 43 |
+
if type(message) == HumanMessage:
|
| 44 |
+
with st.chat_message("user"):
|
| 45 |
+
st.write(message.content)
|
| 46 |
+
elif type(message)==ToolMessage:
|
| 47 |
+
with st.chat_message("ai"):
|
| 48 |
+
st.write("Tool Call Start")
|
| 49 |
+
st.write(message.content)
|
| 50 |
+
st.write("Tool Call End")
|
| 51 |
+
elif type(message)==AIMessage and message.content:
|
| 52 |
+
with st.chat_message("assistant"):
|
| 53 |
+
st.write(message.content)
|
| 54 |
|
| 55 |
# display graph
|
| 56 |
if graph:
|
src/langgraphagenticai/node/chatbot_with_tool_node.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from src.langgraphagenticai.state.state import State
|
| 2 |
+
|
| 3 |
+
class ChatbotWithToolNode:
|
| 4 |
+
"""
|
| 5 |
+
Chatbot logic enhanced with tool integration.
|
| 6 |
+
"""
|
| 7 |
+
def __init__(self,model):
|
| 8 |
+
self.llm = model
|
| 9 |
+
|
| 10 |
+
def process(self, state: State) -> dict:
|
| 11 |
+
"""
|
| 12 |
+
Processes the input state and generates a response with tool integration.
|
| 13 |
+
"""
|
| 14 |
+
user_input = state["messages"][-1] if state["messages"] else ""
|
| 15 |
+
llm_response = self.llm.invoke([{"role": "user", "content": user_input}])
|
| 16 |
+
|
| 17 |
+
# Simulate tool-specific logic
|
| 18 |
+
tools_response = f"Tool integration for: '{user_input}'"
|
| 19 |
+
|
| 20 |
+
return {"messages": [llm_response, tools_response]}
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def create_chatbot(self, tools):
|
| 25 |
+
"""
|
| 26 |
+
Returns a chatbot node function.
|
| 27 |
+
"""
|
| 28 |
+
llm_with_tools = self.llm.bind_tools(tools)
|
| 29 |
+
|
| 30 |
+
def chatbot_node(state: State):
|
| 31 |
+
"""
|
| 32 |
+
Chatbot logic for processing the input state and returning a response.
|
| 33 |
+
"""
|
| 34 |
+
return {"messages": [llm_with_tools.invoke(state["messages"])]}
|
| 35 |
+
|
| 36 |
+
return chatbot_node
|
| 37 |
+
|
src/langgraphagenticai/tools/search_tool.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain_community.tools.tavily_search import TavilySearchResults
|
| 2 |
+
from langgraph.prebuilt import ToolNode
|
| 3 |
+
|
| 4 |
+
def get_tools():
|
| 5 |
+
"""
|
| 6 |
+
Returns a list of tools to be used in the chatbot.
|
| 7 |
+
"""
|
| 8 |
+
tool = TavilySearchResults( max_results=2)
|
| 9 |
+
return [tool]
|
| 10 |
+
|
| 11 |
+
def create_tool_node(tools):
|
| 12 |
+
"""
|
| 13 |
+
Creates and returns a tool node for the graph.
|
| 14 |
+
"""
|
| 15 |
+
return ToolNode(tools=tools)
|
src/langgraphagenticai/ui/configfile.ini
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
[DEFAULT]
|
| 2 |
-
PAGE_TITLE =
|
| 3 |
LLM_OPTIONS = Groq
|
| 4 |
USECASE_OPTIONS = Basic Chatbot, Chatbot with Tool, Appointment Receptionist, Customer Support
|
| 5 |
GROQ_MODEL_OPTIONS = mixtral-8x7b-32768, llama3-8b-8192, llama3-70b-8192, gemma-7b-i
|
|
|
|
| 1 |
[DEFAULT]
|
| 2 |
+
PAGE_TITLE = LangGraph: Build Stateful Agentic AI graph
|
| 3 |
LLM_OPTIONS = Groq
|
| 4 |
USECASE_OPTIONS = Basic Chatbot, Chatbot with Tool, Appointment Receptionist, Customer Support
|
| 5 |
GROQ_MODEL_OPTIONS = mixtral-8x7b-32768, llama3-8b-8192, llama3-70b-8192, gemma-7b-i
|
src/langgraphagenticai/ui/streamlitui/loadui.py
CHANGED
|
@@ -39,19 +39,19 @@ class LoadStreamlitUI:
|
|
| 39 |
type="password")
|
| 40 |
|
| 41 |
if self.user_controls['selected_usecase'] == "Appointment Receptionist":
|
| 42 |
-
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
|
| 47 |
-
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
-
elif self.user_controls['selected_usecase']=="
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
# TODO :: to be removed
|
| 54 |
-
if self.user_controls['selected_usecase'] != "Basic Chatbot":
|
| 55 |
st.warning("⌛Revamp is in progress...")
|
| 56 |
|
| 57 |
return self.user_controls
|
|
|
|
| 39 |
type="password")
|
| 40 |
|
| 41 |
if self.user_controls['selected_usecase'] == "Appointment Receptionist":
|
| 42 |
+
col1, col2 = st.columns(2)
|
| 43 |
|
| 44 |
+
with col1:
|
| 45 |
+
st.subheader("Appointment Manager")
|
| 46 |
|
| 47 |
+
with col2:
|
| 48 |
+
st.subheader("Appointments")
|
| 49 |
+
|
| 50 |
+
# TODO :: to be removed
|
| 51 |
+
st.warning("⌛Revamp is in progress...")
|
| 52 |
|
| 53 |
+
elif self.user_controls['selected_usecase']=="Customer Support":
|
| 54 |
+
# TODO :: to be removed
|
|
|
|
|
|
|
|
|
|
| 55 |
st.warning("⌛Revamp is in progress...")
|
| 56 |
|
| 57 |
return self.user_controls
|