KatGaw commited on
Commit
92b06f4
·
1 Parent(s): b45b554

adding newest pages

Browse files
Files changed (3) hide show
  1. .DS_Store +0 -0
  2. pages/chat.py +282 -0
  3. pages/tableau.py +18 -0
.DS_Store CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
 
pages/chat.py ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from openai import OpenAI
2
+ import streamlit as st
3
+ from langchain_openai import ChatOpenAI
4
+ from langchain_openai.embeddings import OpenAIEmbeddings
5
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
6
+ import markdown
7
+ from operator import itemgetter
8
+ from langchain.schema.runnable import RunnablePassthrough
9
+ from langchain_core.prompts import ChatPromptTemplate
10
+ from langchain.schema import Document
11
+ from dotenv import load_dotenv
12
+ from langchain_community.vectorstores import Qdrant
13
+ # from langchain_qdrant import Qdrant
14
+ import os
15
+ import pandas as pd
16
+ import numpy as np
17
+
18
+ st.set_page_config(
19
+ page_title="Narrativ 🧠",
20
+ layout="wide",
21
+ initial_sidebar_state="expanded",
22
+ page_icon="🧠",
23
+ )
24
+
25
+ # Custom CSS for enhanced styling
26
+ st.markdown("""
27
+ <style>
28
+ .circular-image {
29
+ width: 200px;
30
+ height: 200px;
31
+ border-radius: 50%;
32
+ object-fit: cover;
33
+ display: block;
34
+ margin: 20px auto;
35
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
36
+ }
37
+
38
+ /* Container for search section */
39
+ .search-container {
40
+ background: white;
41
+ padding: 20px;
42
+ border-radius: 10px;
43
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
44
+ margin: 20px 0;
45
+ }
46
+
47
+ /* Combined search input styling */
48
+ .combined-search {
49
+ display: flex;
50
+ gap: 10px;
51
+ align-items: center;
52
+ margin-bottom: 20px;
53
+ }
54
+ </style>
55
+ """, unsafe_allow_html=True)
56
+
57
+ load_dotenv()
58
+ OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
59
+ base_llm = ChatOpenAI(model="gpt-4o")
60
+ embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
61
+
62
+ #========== APP
63
+
64
+ from PIL import Image, ImageEnhance
65
+
66
+ image = Image.open('./data/Sentiment_index_traffic.png')
67
+ enhancer = ImageEnhance.Brightness(image)
68
+ darker_image = enhancer.enhance(0.5) # Adjust the brightness factor as needed
69
+ st.image(darker_image, use_container_width=True, output_format="PNG", clamp=True)
70
+
71
+ st.title("Narrativ 📰")
72
+
73
+ # Add a button to navigate to search page
74
+ if st.button("Go to Search 🔍", use_container_width=False):
75
+ st.switch_page("pages/search.py")
76
+
77
+ #check1 = st.button("Submit", key="submit_button")
78
+ prompt='I-495'
79
+
80
+ prompt=st.session_state.prompt
81
+ date=st.session_state.date
82
+ # Change the sidebar background with enhanced gradient and text styling
83
+ # sideb.markdown(
84
+
85
+ if 'messages' not in st.session_state:
86
+ st.session_state.messages = []
87
+
88
+ st.session_state.messages.append({"role": "assistant", "content": f'{date} {prompt}'})
89
+
90
+ if prompt:
91
+ if date:
92
+ try:
93
+ data=pd.read_csv('./data/sentiment_index_traffic_index_final1.csv',
94
+ index_col='index',
95
+ parse_dates=True,
96
+ infer_datetime_format=True
97
+ )
98
+
99
+ data = data.loc[data.index == date]
100
+ filtered_data = data[data.apply(lambda row: row.astype(str).str.contains(prompt, na=False).any(), axis=1)]
101
+ data_all = filtered_data.values.flatten()
102
+ docs = data_all
103
+ if len(docs)<1:
104
+ st.warning("No articles found that contain the prompt string.")
105
+
106
+ # Create markdown formatted text from the matching articles.
107
+ # docs_text = "\n".join([f"- {article}" for article in data_prompt if article])
108
+ # docs = [Document(page_content=docs_text)]
109
+ except Exception as e:
110
+ st.error(f"Error processing date: {e}")
111
+ else:
112
+ try:
113
+ data = pd.read_csv(
114
+ './data/sentiment_index_traffic_index_final1.csv',
115
+ index_col='index',
116
+ parse_dates=True,
117
+ infer_datetime_format=True
118
+ )
119
+
120
+ filtered_data = data[data.apply(lambda row: row.astype(str).str.contains(prompt, na=False).any(), axis=1)]
121
+ data_all = filtered_data.values.flatten()
122
+ docs = data_all
123
+ if len(docs)<1:
124
+ st.warning("No articles found that contain the prompt string.")
125
+
126
+ #data_all = data.values.flatten()
127
+ #docs = data_all
128
+ # with open(f'./data/sentiment_index_traffic_index_final1.md', "w", encoding="utf-8") as file:
129
+ # file.write(str(data_all))
130
+ # with open(f'./data/sentiment_index_traffic_index_final1.md', "r", encoding="utf-8") as file_content:
131
+ # docs = file_content.read()
132
+ except Exception as e:
133
+ st.error(f"Error loading data: {e}")
134
+
135
+ docs_text = "\n".join([f"- {value}" for value in data_all if not pd.isna(value)])
136
+ docs = [Document(page_content=docs_text)]
137
+ st.write(data)
138
+
139
+ # Remove the markdown.markdown() since we've already formatted the text
140
+ docs = [Document(page_content=docs_text)]
141
+ #docs = [Document(page_content=markdown.markdown(docs))]
142
+ print(docs)
143
+ split_documents = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
144
+ chunk_size=1000,
145
+ chunk_overlap=20
146
+ ).split_documents(docs)
147
+
148
+ vectorstore = Qdrant.from_documents(
149
+ split_documents,
150
+ embedding_model,
151
+ location=":memory:",
152
+ collection_name="langchainblogs"
153
+ )
154
+
155
+ retriever = vectorstore.as_retriever()
156
+
157
+ print("Loaded Vectorstore")
158
+
159
+ # Add user message to chat history
160
+ st.session_state.messages.append({"role": "user", "content": prompt})
161
+ # Display user message in chat message container
162
+ with st.chat_message("user"):
163
+ st.markdown(prompt)
164
+
165
+ # Generate summarized message rationalize dominant sentiment
166
+ RAG_PROMPT = """# Traffic Analyst - Transurban Prompt
167
+
168
+ You are a Transurban traffic consultant focusing on the I-495 and I-95 express lanes in the Greater Washington area (GWA). Your task is to analyze news articles provided by a client on a specific topic. You will receive the full text of the relevant articles for the assigned topic, along with key data points.
169
+ You analyze articles and explain phenomenon for the traffic on the date.
170
+ ## Your Tasks:
171
+
172
+ ### 1. Summarize Opinions:
173
+ - Extract the key opinions and perspectives from the provided news articles.
174
+ - The news articles will include: title, URL, date, text, article source, sentiment index created by Transurban, sentiment index using HF (Hugging Face) model, and confidence for the HF index.
175
+ - Highlight any significant patterns, agreements, or disagreements across the sources.
176
+
177
+ ### 2. Analyze Sentiment:
178
+ - Determine the overall sentiment (positive, negative, neutral) about the topic based on the extracted opinions.
179
+ - Provide a clear explanation of your sentiment conclusion, referencing specific points or trends from the articles.
180
+
181
+ ### 3. Provide Chain-of-Thought Reasoning:
182
+ - Detail your reasoning process step by step. Explain how you interpreted the articles, derived insights, and reached your sentiment conclusion.
183
+ - Ensure the reasoning is logical, transparent, and grounded in the content provided.
184
+
185
+ ### 4. Collect URL Sources:
186
+ - From the provided context, select 5 critical and recent URL sources related to the topic.
187
+
188
+ ## Output Format:
189
+
190
+ - **Summary of Opinions:** [Concise summary of key opinions]
191
+ - **Sentiment Analysis:**
192
+ - Sentiment: [Positive/Negative/Neutral]
193
+ - Reasoning: [Detailed explanation here]
194
+ - **Chain-of-Thought Reasoning:** [Step-by-step explanation]
195
+ - **Sources:** [URLs for 5 most critical and recent articles on this topic]
196
+
197
+ ## Guidelines:
198
+ - Maintain objectivity and precision in your analysis.
199
+ - Focus on the context specific to the Greater Washington Area.
200
+ - Use professional and analytical language suitable for client reports.
201
+ - Respond in the language of the article (mostly English).
202
+
203
+ CONTEXT:
204
+ {context}
205
+
206
+ QUERY:
207
+ {question}
208
+ Use the provided context to answer the provided user question. Only use the provided context to answer the question. If you do not know the answer, respond with "I don't know"
209
+ """
210
+ rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)
211
+ # RAG CHAIN
212
+ lcel_rag_chain = (
213
+ {"context": itemgetter("question") | retriever, "question": itemgetter("question")}
214
+ | RunnablePassthrough.assign(context=itemgetter("context"))
215
+ | {"response": rag_prompt | base_llm, "context": itemgetter("context")}
216
+ )
217
+
218
+ try:
219
+ summary = lcel_rag_chain.invoke({"question": prompt})
220
+ print(summary)
221
+ st.chat_message("assistant").write((summary['response'].content))
222
+ st.session_state.messages.append({"role": "assistant", "content": summary['response'].content})
223
+ except Exception as e:
224
+ st.error(f"Error generating summary: {e}")
225
+
226
+ if date:
227
+ with open('./data/sentiment_index_traffic_index_final_date.md', 'w') as file:
228
+ file.write(str(data_all))
229
+ else:
230
+ with open('./data/sentiment_index_traffic_index_final1.md', 'w') as file:
231
+ file.write(str(data_all))
232
+
233
+
234
+ client = OpenAI(api_key=OPENAI_API_KEY)
235
+
236
+ if "openai_model" not in st.session_state:
237
+ st.session_state["openai_model"] = "gpt-4o"
238
+
239
+ prompt1 = st.chat_input("Type your additional questions here...")
240
+
241
+ # Suggested keywords with enhanced styling
242
+ suggested_keywords = ["Summarize results", f"Explain the traffic drop", f"Explain the traffic growth"]
243
+ st.markdown("**Suggested Keywords:**")
244
+ cols = st.columns(len(suggested_keywords))
245
+ for idx, keyword in enumerate(suggested_keywords):
246
+ if cols[idx].button(keyword, key=keyword):
247
+ prompt1 = keyword
248
+
249
+ if prompt1:
250
+
251
+ if date:
252
+ file_path = f'./data/sentiment_index_traffic_index_final_date.md'
253
+ else:
254
+ file_path = f'./data/sentiment_index_traffic_index_final1.md'
255
+
256
+ try:
257
+ with open(file_path, "r", encoding="utf-8") as file_content:
258
+ docs = file_content.read()
259
+ except Exception as e:
260
+ st.error(f"Error loading context: {e}")
261
+ docs = ""
262
+
263
+ # Add user message to chat history
264
+ st.session_state.messages.append({"role": "user", "content": f'You are a data analyst, that answer questions: {prompt1} using context from {docs}'})
265
+ # Display user message in chat message container
266
+ with st.chat_message("user"):
267
+ st.markdown(prompt1)
268
+ # Display assistant response in chat message container
269
+ with st.chat_message("assistant"):
270
+ try:
271
+ stream = client.chat.completions.create(
272
+ model=st.session_state["openai_model"],
273
+ messages=[
274
+ {"role": m["role"], "content": m["content"]}
275
+ for m in st.session_state.messages
276
+ ],
277
+ stream=True,
278
+ )
279
+ response = st.write_stream(stream)
280
+ st.session_state.messages.append({"role": "assistant", "content": response})
281
+ except Exception as e:
282
+ st.error(f"Error generating response: {e}")
pages/tableau.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import streamlit as st
3
+
4
+ st.set_page_config(
5
+ page_title="Narrativ 🧠",
6
+ layout="wide",
7
+ initial_sidebar_state="expanded",
8
+ page_icon="🧠",
9
+ )
10
+
11
+ from PIL import Image, ImageEnhance
12
+
13
+ st.title("Narrativ 📰")
14
+ image = Image.open('./data/tableau.png')
15
+ enhancer = ImageEnhance.Brightness(image)
16
+ darker_image = enhancer.enhance(0.5) # Adjust the brightness factor as needed
17
+ st.image(darker_image, use_container_width=True, output_format="PNG", clamp=True)
18
+