ositamiles commited on
Commit
13655e7
·
verified ·
1 Parent(s): b11ade9

Add application file

Browse files
Files changed (1) hide show
  1. app.py +301 -0
app.py ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List
2
+
3
+ import nest_asyncio
4
+ import streamlit as st
5
+ from phi.assistant import Assistant
6
+ from phi.document import Document
7
+ from phi.document.reader.pdf import PDFReader
8
+ from phi.document.reader.website import WebsiteReader
9
+ from phi.utils.log import logger
10
+
11
+ from assistant import get_llm_os # type: ignore
12
+
13
+ nest_asyncio.apply()
14
+
15
+ st.set_page_config(
16
+ page_title="LLM OS",
17
+ page_icon=":orange_heart:",
18
+ )
19
+ st.title("LLM OS")
20
+ st.markdown("##### :orange_heart: built using [phidata](https://github.com/phidatahq/phidata)")
21
+
22
+
23
+ def main() -> None:
24
+ # Get LLM Model
25
+ llm_id = st.sidebar.selectbox("Select LLM", options=["gpt-4o", "gpt-4-turbo"]) or "gpt-4o"
26
+ # Set llm_id in session state
27
+ if "llm_id" not in st.session_state:
28
+ st.session_state["llm_id"] = llm_id
29
+ # Restart the assistant if llm_id changes
30
+ elif st.session_state["llm_id"] != llm_id:
31
+ st.session_state["llm_id"] = llm_id
32
+ restart_assistant()
33
+
34
+ # Sidebar checkboxes for selecting tools
35
+ st.sidebar.markdown("### Select Tools")
36
+
37
+ # Enable Calculator
38
+ if "calculator_enabled" not in st.session_state:
39
+ st.session_state["calculator_enabled"] = True
40
+ # Get calculator_enabled from session state if set
41
+ calculator_enabled = st.session_state["calculator_enabled"]
42
+ # Checkbox for enabling calculator
43
+ calculator = st.sidebar.checkbox("Calculator", value=calculator_enabled, help="Enable calculator.")
44
+ if calculator_enabled != calculator:
45
+ st.session_state["calculator_enabled"] = calculator
46
+ calculator_enabled = calculator
47
+ restart_assistant()
48
+
49
+ # Enable file tools
50
+ if "file_tools_enabled" not in st.session_state:
51
+ st.session_state["file_tools_enabled"] = True
52
+ # Get file_tools_enabled from session state if set
53
+ file_tools_enabled = st.session_state["file_tools_enabled"]
54
+ # Checkbox for enabling shell tools
55
+ file_tools = st.sidebar.checkbox("File Tools", value=file_tools_enabled, help="Enable file tools.")
56
+ if file_tools_enabled != file_tools:
57
+ st.session_state["file_tools_enabled"] = file_tools
58
+ file_tools_enabled = file_tools
59
+ restart_assistant()
60
+
61
+ # Enable Web Search via DuckDuckGo
62
+ if "ddg_search_enabled" not in st.session_state:
63
+ st.session_state["ddg_search_enabled"] = True
64
+ # Get ddg_search_enabled from session state if set
65
+ ddg_search_enabled = st.session_state["ddg_search_enabled"]
66
+ # Checkbox for enabling web search
67
+ ddg_search = st.sidebar.checkbox("Web Search", value=ddg_search_enabled, help="Enable web search using DuckDuckGo.")
68
+ if ddg_search_enabled != ddg_search:
69
+ st.session_state["ddg_search_enabled"] = ddg_search
70
+ ddg_search_enabled = ddg_search
71
+ restart_assistant()
72
+
73
+ # Enable shell tools
74
+ if "shell_tools_enabled" not in st.session_state:
75
+ st.session_state["shell_tools_enabled"] = False
76
+ # Get shell_tools_enabled from session state if set
77
+ shell_tools_enabled = st.session_state["shell_tools_enabled"]
78
+ # Checkbox for enabling shell tools
79
+ shell_tools = st.sidebar.checkbox("Shell Tools", value=shell_tools_enabled, help="Enable shell tools.")
80
+ if shell_tools_enabled != shell_tools:
81
+ st.session_state["shell_tools_enabled"] = shell_tools
82
+ shell_tools_enabled = shell_tools
83
+ restart_assistant()
84
+
85
+ # Sidebar checkboxes for selecting team members
86
+ st.sidebar.markdown("### Select Team Members")
87
+
88
+ # Enable Data Analyst
89
+ if "data_analyst_enabled" not in st.session_state:
90
+ st.session_state["data_analyst_enabled"] = False
91
+ # Get data_analyst_enabled from session state if set
92
+ data_analyst_enabled = st.session_state["data_analyst_enabled"]
93
+ # Checkbox for enabling web search
94
+ data_analyst = st.sidebar.checkbox(
95
+ "Data Analyst",
96
+ value=data_analyst_enabled,
97
+ help="Enable the Data Analyst assistant for data related queries.",
98
+ )
99
+ if data_analyst_enabled != data_analyst:
100
+ st.session_state["data_analyst_enabled"] = data_analyst
101
+ data_analyst_enabled = data_analyst
102
+ restart_assistant()
103
+
104
+ # Enable Python Assistant
105
+ if "python_assistant_enabled" not in st.session_state:
106
+ st.session_state["python_assistant_enabled"] = False
107
+ # Get python_assistant_enabled from session state if set
108
+ python_assistant_enabled = st.session_state["python_assistant_enabled"]
109
+ # Checkbox for enabling web search
110
+ python_assistant = st.sidebar.checkbox(
111
+ "Python Assistant",
112
+ value=python_assistant_enabled,
113
+ help="Enable the Python Assistant for writing and running python code.",
114
+ )
115
+ if python_assistant_enabled != python_assistant:
116
+ st.session_state["python_assistant_enabled"] = python_assistant
117
+ python_assistant_enabled = python_assistant
118
+ restart_assistant()
119
+
120
+ # Enable Research Assistant
121
+ if "research_assistant_enabled" not in st.session_state:
122
+ st.session_state["research_assistant_enabled"] = False
123
+ # Get research_assistant_enabled from session state if set
124
+ research_assistant_enabled = st.session_state["research_assistant_enabled"]
125
+ # Checkbox for enabling web search
126
+ research_assistant = st.sidebar.checkbox(
127
+ "Research Assistant",
128
+ value=research_assistant_enabled,
129
+ help="Enable the research assistant (uses Exa).",
130
+ )
131
+ if research_assistant_enabled != research_assistant:
132
+ st.session_state["research_assistant_enabled"] = research_assistant
133
+ research_assistant_enabled = research_assistant
134
+ restart_assistant()
135
+
136
+ # Enable Investment Assistant
137
+ if "investment_assistant_enabled" not in st.session_state:
138
+ st.session_state["investment_assistant_enabled"] = False
139
+ # Get investment_assistant_enabled from session state if set
140
+ investment_assistant_enabled = st.session_state["investment_assistant_enabled"]
141
+ # Checkbox for enabling web search
142
+ investment_assistant = st.sidebar.checkbox(
143
+ "Investment Assistant",
144
+ value=investment_assistant_enabled,
145
+ help="Enable the investment assistant. NOTE: This is not financial advice.",
146
+ )
147
+ if investment_assistant_enabled != investment_assistant:
148
+ st.session_state["investment_assistant_enabled"] = investment_assistant
149
+ investment_assistant_enabled = investment_assistant
150
+ restart_assistant()
151
+
152
+ # Get the assistant
153
+ llm_os: Assistant
154
+ if "llm_os" not in st.session_state or st.session_state["llm_os"] is None:
155
+ logger.info(f"---*--- Creating {llm_id} LLM OS ---*---")
156
+ llm_os = get_llm_os(
157
+ llm_id=llm_id,
158
+ calculator=calculator_enabled,
159
+ ddg_search=ddg_search_enabled,
160
+ file_tools=file_tools_enabled,
161
+ shell_tools=shell_tools_enabled,
162
+ data_analyst=data_analyst_enabled,
163
+ python_assistant=python_assistant_enabled,
164
+ research_assistant=research_assistant_enabled,
165
+ investment_assistant=investment_assistant_enabled,
166
+ )
167
+ st.session_state["llm_os"] = llm_os
168
+ else:
169
+ llm_os = st.session_state["llm_os"]
170
+
171
+ # Create assistant run (i.e. log to database) and save run_id in session state
172
+ try:
173
+ st.session_state["llm_os_run_id"] = llm_os.create_run()
174
+ except Exception:
175
+ st.warning("Could not create LLM OS run, is the database running?")
176
+ return
177
+
178
+ # Load existing messages
179
+ assistant_chat_history = llm_os.memory.get_chat_history()
180
+ if len(assistant_chat_history) > 0:
181
+ logger.debug("Loading chat history")
182
+ st.session_state["messages"] = assistant_chat_history
183
+ else:
184
+ logger.debug("No chat history found")
185
+ st.session_state["messages"] = [{"role": "assistant", "content": "Ask me questions..."}]
186
+
187
+ # Prompt for user input
188
+ if prompt := st.chat_input():
189
+ st.session_state["messages"].append({"role": "user", "content": prompt})
190
+
191
+ # Display existing chat messages
192
+ for message in st.session_state["messages"]:
193
+ if message["role"] == "system":
194
+ continue
195
+ with st.chat_message(message["role"]):
196
+ st.write(message["content"])
197
+
198
+ # If last message is from a user, generate a new response
199
+ last_message = st.session_state["messages"][-1]
200
+ if last_message.get("role") == "user":
201
+ question = last_message["content"]
202
+ with st.chat_message("assistant"):
203
+ response = ""
204
+ resp_container = st.empty()
205
+ for delta in llm_os.run(question):
206
+ response += delta # type: ignore
207
+ resp_container.markdown(response)
208
+ st.session_state["messages"].append({"role": "assistant", "content": response})
209
+
210
+ # Load LLM OS knowledge base
211
+ if llm_os.knowledge_base:
212
+ # -*- Add websites to knowledge base
213
+ if "url_scrape_key" not in st.session_state:
214
+ st.session_state["url_scrape_key"] = 0
215
+
216
+ input_url = st.sidebar.text_input(
217
+ "Add URL to Knowledge Base", type="default", key=st.session_state["url_scrape_key"]
218
+ )
219
+ add_url_button = st.sidebar.button("Add URL")
220
+ if add_url_button:
221
+ if input_url is not None:
222
+ alert = st.sidebar.info("Processing URLs...", icon="ℹ️")
223
+ if f"{input_url}_scraped" not in st.session_state:
224
+ scraper = WebsiteReader(max_links=2, max_depth=1)
225
+ web_documents: List[Document] = scraper.read(input_url)
226
+ if web_documents:
227
+ llm_os.knowledge_base.load_documents(web_documents, upsert=True)
228
+ else:
229
+ st.sidebar.error("Could not read website")
230
+ st.session_state[f"{input_url}_uploaded"] = True
231
+ alert.empty()
232
+
233
+ # Add PDFs to knowledge base
234
+ if "file_uploader_key" not in st.session_state:
235
+ st.session_state["file_uploader_key"] = 100
236
+
237
+ uploaded_file = st.sidebar.file_uploader(
238
+ "Add a PDF :page_facing_up:", type="pdf", key=st.session_state["file_uploader_key"]
239
+ )
240
+ if uploaded_file is not None:
241
+ alert = st.sidebar.info("Processing PDF...", icon="🧠")
242
+ auto_rag_name = uploaded_file.name.split(".")[0]
243
+ if f"{auto_rag_name}_uploaded" not in st.session_state:
244
+ reader = PDFReader()
245
+ auto_rag_documents: List[Document] = reader.read(uploaded_file)
246
+ if auto_rag_documents:
247
+ llm_os.knowledge_base.load_documents(auto_rag_documents, upsert=True)
248
+ else:
249
+ st.sidebar.error("Could not read PDF")
250
+ st.session_state[f"{auto_rag_name}_uploaded"] = True
251
+ alert.empty()
252
+
253
+ if llm_os.knowledge_base and llm_os.knowledge_base.vector_db:
254
+ if st.sidebar.button("Clear Knowledge Base"):
255
+ llm_os.knowledge_base.vector_db.clear()
256
+ st.sidebar.success("Knowledge base cleared")
257
+
258
+ # Show team member memory
259
+ if llm_os.team and len(llm_os.team) > 0:
260
+ for team_member in llm_os.team:
261
+ if len(team_member.memory.chat_history) > 0:
262
+ with st.status(f"{team_member.name} Memory", expanded=False, state="complete"):
263
+ with st.container():
264
+ _team_member_memory_container = st.empty()
265
+ _team_member_memory_container.json(team_member.memory.get_llm_messages())
266
+
267
+ if llm_os.storage:
268
+ llm_os_run_ids: List[str] = llm_os.storage.get_all_run_ids()
269
+ new_llm_os_run_id = st.sidebar.selectbox("Run ID", options=llm_os_run_ids)
270
+ if st.session_state["llm_os_run_id"] != new_llm_os_run_id:
271
+ logger.info(f"---*--- Loading {llm_id} run: {new_llm_os_run_id} ---*---")
272
+ st.session_state["llm_os"] = get_llm_os(
273
+ llm_id=llm_id,
274
+ calculator=calculator_enabled,
275
+ ddg_search=ddg_search_enabled,
276
+ file_tools=file_tools_enabled,
277
+ shell_tools=shell_tools_enabled,
278
+ data_analyst=data_analyst_enabled,
279
+ python_assistant=python_assistant_enabled,
280
+ research_assistant=research_assistant_enabled,
281
+ investment_assistant=investment_assistant_enabled,
282
+ run_id=new_llm_os_run_id,
283
+ )
284
+ st.rerun()
285
+
286
+ if st.sidebar.button("New Run"):
287
+ restart_assistant()
288
+
289
+
290
+ def restart_assistant():
291
+ logger.debug("---*--- Restarting Assistant ---*---")
292
+ st.session_state["llm_os"] = None
293
+ st.session_state["llm_os_run_id"] = None
294
+ if "url_scrape_key" in st.session_state:
295
+ st.session_state["url_scrape_key"] += 1
296
+ if "file_uploader_key" in st.session_state:
297
+ st.session_state["file_uploader_key"] += 1
298
+ st.rerun()
299
+
300
+
301
+ main()