Anshini commited on
Commit
14d1c17
·
verified ·
1 Parent(s): 48a48bb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -0
app.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ import os
4
+ import streamlit as st
5
+ from dotenv import load_dotenv
6
+
7
+ from langchain_community.tools import ArxivQueryRun, WikipediaQueryRun
8
+ from langchain_community.utilities import WikipediaAPIWrapper, ArxivAPIWrapper
9
+ from langchain_community.tools.tavily_search import TavilySearchResults
10
+ from langchain_groq import ChatGroq
11
+
12
+ from langgraph.graph import StateGraph, START, END
13
+ from langgraph.prebuilt import ToolNode, tools_condition
14
+ from langgraph.checkpoint.memory import MemorySaver
15
+ from langchain_core.messages import AIMessage, HumanMessage
16
+ from langgraph.graph.message import add_messages
17
+ from typing import Annotated
18
+ from typing_extensions import TypedDict
19
+
20
+ # Load environment
21
+ load_dotenv()
22
+ os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")
23
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY")
24
+
25
+ # Define tools
26
+ arxiv = ArxivQueryRun(api_wrapper=ArxivAPIWrapper(top_k_results=2, doc_content_chars_max=1000))
27
+ wiki = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=1000))
28
+ tavily = TavilySearchResults()
29
+ tools = [arxiv, wiki, tavily]
30
+
31
+ # LangGraph State
32
+ class State(TypedDict):
33
+ messages: Annotated[list, add_messages]
34
+ name: str
35
+ birthday: str
36
+
37
+ # LLM
38
+ llm = ChatGroq(model="deepseek-r1-distill-llama-70b")
39
+ llm_with_tools = llm.bind_tools(tools=tools)
40
+
41
+ # Memory
42
+ memory = MemorySaver()
43
+
44
+ # Define node
45
+ def ai_assistance(state: State):
46
+ result = llm_with_tools.invoke(state["messages"])
47
+ return {"messages": [result]}
48
+
49
+ # Build LangGraph
50
+ builder = StateGraph(State)
51
+ builder.add_node("AI_Assistance", ai_assistance)
52
+ builder.add_node("tools", ToolNode(tools))
53
+
54
+ builder.add_edge(START, "AI_Assistance")
55
+ builder.add_conditional_edges("AI_Assistance", tools_condition)
56
+ builder.add_edge("tools", "AI_Assistance")
57
+ graph = builder.compile(checkpointer=memory)
58
+
59
+ # Streamlit UI setup
60
+ st.set_page_config(page_title="LangGraph Chatbot", layout="wide")
61
+
62
+ st.markdown("""
63
+ <style>
64
+ .stChatMessage {
65
+ padding: 12px;
66
+ margin-bottom: 12px;
67
+ border-radius: 12px;
68
+ max-width: 90%;
69
+ }
70
+ .user {
71
+ background-color: #dcf8c6;
72
+ align-self: flex-end;
73
+ }
74
+ .bot {
75
+ background-color: #f1f0f0;
76
+ align-self: flex-start;
77
+ }
78
+ .input-box {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 0.5rem;
82
+ }
83
+ #floating-container {
84
+ display: flex;
85
+ align-items: center;
86
+ justify-content: space-between;
87
+ padding: 0.25rem 0.75rem;
88
+ background-color: #f9f9f9;
89
+ border-radius: 0.75rem;
90
+ margin-top: 1rem;
91
+ border: 1px solid #ccc;
92
+ }
93
+ .floating-popup {
94
+ margin-top: 0.5rem;
95
+ padding: 0.5rem;
96
+ border-radius: 0.5rem;
97
+ border: 1px solid #ccc;
98
+ background-color: white;
99
+ }
100
+ </style>
101
+ """, unsafe_allow_html=True)
102
+
103
+ st.title("🧠 LangGraph Chatbot (Groq + Tools)")
104
+
105
+ # Initialize session
106
+ if "thread_id" not in st.session_state:
107
+ st.session_state.thread_id = "1"
108
+ if "chat_history" not in st.session_state:
109
+ st.session_state.chat_history = []
110
+ if "show_upload" not in st.session_state:
111
+ st.session_state.show_upload = False
112
+ if "selected_tools" not in st.session_state:
113
+ st.session_state.selected_tools = ["Arxiv", "Wikipedia", "Tavily"]
114
+
115
+ # Show chat
116
+ for msg in st.session_state.chat_history:
117
+ role = "user" if isinstance(msg, HumanMessage) else "bot"
118
+ st.markdown(f"<div class='stChatMessage {role}'>{msg.content}</div>", unsafe_allow_html=True)
119
+
120
+ # Custom Chat Input Box UI
121
+ with st.container():
122
+ with st.form("chat_form", clear_on_submit=True):
123
+ st.markdown('<div id="floating-container">', unsafe_allow_html=True)
124
+
125
+ col1, col2 = st.columns([1, 17])
126
+ with col1:
127
+ toggle = st.form_submit_button("➕", use_container_width=True)
128
+ with col2:
129
+ user_input = st.text_input("Ask me", label_visibility="collapsed",placeholder="Ask me Anything")
130
+
131
+ st.markdown('</div>', unsafe_allow_html=True)
132
+
133
+ # Floating Popup for Uploads and Tools
134
+ if toggle:
135
+ st.session_state.show_upload = not st.session_state.show_upload
136
+
137
+ if st.session_state.show_upload:
138
+ with st.expander("📎 Upload Files or Images", expanded=False,width=300):
139
+ st.file_uploader("Upload:", type=["txt", "pdf", "docx"], key="text_file")
140
+ st.file_uploader("Upload image:", type=["jpg", "jpeg", "png"], key="img_file")
141
+
142
+ st.session_state.selected_tools = st.multiselect(
143
+ "🛠 Select Tools:",
144
+ ["Arxiv", "Wikipedia", "Tavily"],
145
+ default=st.session_state.selected_tools,
146
+ width= 300
147
+ )
148
+
149
+ submitted = st.form_submit_button(label = "Send")
150
+ if submitted and user_input:
151
+ st.session_state.chat_history.append(HumanMessage(content=user_input))
152
+ config = {"configurable": {"thread_id": st.session_state.thread_id}}
153
+ result = graph.invoke({"messages": st.session_state.chat_history}, config=config)
154
+ st.session_state.chat_history.append(result["messages"][-1])
155
+ st.rerun()
156
+
157
+