Spaces:
Running
Running
updates
Browse files
app.py
CHANGED
@@ -3,9 +3,7 @@ from omegaconf import OmegaConf
|
|
3 |
import streamlit as st
|
4 |
import os
|
5 |
from PIL import Image
|
6 |
-
import re
|
7 |
import sys
|
8 |
-
import datetime
|
9 |
import pandas as pd
|
10 |
import requests
|
11 |
from dotenv import load_dotenv
|
@@ -78,7 +76,7 @@ def create_tools(cfg):
|
|
78 |
|
79 |
class QueryTranscriptsArgs(BaseModel):
|
80 |
query: str = Field(..., description="The user query.")
|
81 |
-
year: int = Field(..., description=f"The year.
|
82 |
ticker: str = Field(..., description=f"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.")
|
83 |
|
84 |
tools_factory = ToolsFactory(vectara_api_key=cfg.api_key,
|
@@ -90,14 +88,14 @@ def create_tools(cfg):
|
|
90 |
Given a company name and year,
|
91 |
returns a response (str) to a user question about a company, based on analyst call transcripts about the company's financial reports for that year.
|
92 |
You can ask this tool any question about the compaany including risks, opportunities, financial performance, competitors and more.
|
93 |
-
make sure to provide
|
94 |
""",
|
95 |
tool_args_schema = QueryTranscriptsArgs,
|
96 |
-
tool_filter_template = "doc.year = {year} and doc.ticker = '{ticker}'",
|
97 |
reranker = "multilingual_reranker_v1", rerank_k = 100,
|
98 |
-
n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.
|
99 |
summary_num_results = 10,
|
100 |
vectara_summarizer = 'vectara-summary-ext-24-05-med-omni',
|
|
|
101 |
)
|
102 |
|
103 |
return (tools_factory.get_tools(
|
@@ -114,18 +112,14 @@ def create_tools(cfg):
|
|
114 |
)
|
115 |
|
116 |
def initialize_agent(_cfg):
|
117 |
-
|
118 |
-
|
119 |
-
-
|
120 |
-
- Today's date is {date}.
|
121 |
-
- Guardrails: never discuss politics, and always respond politely.
|
122 |
- Respond in a compact format by using appropriate units of measure (e.g., K for thousands, M for millions, B for billions).
|
123 |
Do not report the same number twice (e.g. $100K and 100,000 USD).
|
124 |
-
-
|
125 |
-
- If a tool cannot respond properly, retry with a rephrased question or ask the user for more information.
|
126 |
- When querying a tool for a numeric value or KPI, use a concise and non-ambiguous description of what you are looking for.
|
127 |
- If you calculate a metric, make sure you have all the necessary information to complete the calculation. Don't guess.
|
128 |
-
- Be very careful not to report results you are not confident about.
|
129 |
"""
|
130 |
|
131 |
def update_func(status_type: AgentStatusType, msg: str):
|
@@ -140,13 +134,16 @@ def initialize_agent(_cfg):
|
|
140 |
)
|
141 |
return agent
|
142 |
|
|
|
|
|
|
|
|
|
143 |
def launch_bot():
|
144 |
def reset():
|
145 |
-
cfg = st.session_state.cfg
|
146 |
st.session_state.messages = [{"role": "assistant", "content": initial_prompt, "avatar": "π¦"}]
|
147 |
st.session_state.thinking_message = "Agent at work..."
|
148 |
-
st.session_state.agent = initialize_agent(cfg)
|
149 |
st.session_state.log_messages = []
|
|
|
150 |
st.session_state.show_logs = False
|
151 |
|
152 |
st.set_page_config(page_title="Financial Assistant", layout="wide")
|
@@ -158,7 +155,10 @@ def launch_bot():
|
|
158 |
})
|
159 |
st.session_state.cfg = cfg
|
160 |
reset()
|
|
|
161 |
cfg = st.session_state.cfg
|
|
|
|
|
162 |
|
163 |
# left side content
|
164 |
with st.sidebar:
|
@@ -171,13 +171,10 @@ def launch_bot():
|
|
171 |
)
|
172 |
|
173 |
st.markdown("\n\n")
|
174 |
-
bc1,
|
175 |
with bc1:
|
176 |
if st.button('Start Over'):
|
177 |
reset()
|
178 |
-
with bc2:
|
179 |
-
if st.button('Show Logs'):
|
180 |
-
st.session_state.show_logs = not st.session_state.show_logs
|
181 |
|
182 |
st.markdown("---")
|
183 |
st.markdown(
|
@@ -187,10 +184,9 @@ def launch_bot():
|
|
187 |
)
|
188 |
st.markdown("---")
|
189 |
|
190 |
-
|
191 |
if "messages" not in st.session_state.keys():
|
192 |
reset()
|
193 |
-
|
194 |
# Display chat messages
|
195 |
for message in st.session_state.messages:
|
196 |
with st.chat_message(message["role"], avatar=message["avatar"]):
|
@@ -199,28 +195,33 @@ def launch_bot():
|
|
199 |
# User-provided prompt
|
200 |
if prompt := st.chat_input():
|
201 |
st.session_state.messages.append({"role": "user", "content": prompt, "avatar": 'π§βπ»'})
|
|
|
|
|
|
|
202 |
with st.chat_message("user", avatar='π§βπ»'):
|
203 |
print(f"Starting new question: {prompt}\n")
|
204 |
st.write(prompt)
|
205 |
-
|
206 |
# Generate a new response if last message is not from assistant
|
207 |
-
if st.session_state.
|
208 |
with st.chat_message("assistant", avatar='π€'):
|
209 |
with st.spinner(st.session_state.thinking_message):
|
210 |
-
res = st.session_state.agent.chat(prompt)
|
211 |
-
|
212 |
-
message = {"role": "assistant", "content":
|
213 |
st.session_state.messages.append(message)
|
214 |
-
st.
|
|
|
215 |
|
216 |
-
|
217 |
-
|
218 |
-
|
|
|
219 |
for msg in st.session_state.log_messages:
|
220 |
st.write(msg)
|
221 |
-
|
222 |
-
|
223 |
-
st.
|
224 |
|
225 |
sys.stdout.flush()
|
226 |
|
|
|
3 |
import streamlit as st
|
4 |
import os
|
5 |
from PIL import Image
|
|
|
6 |
import sys
|
|
|
7 |
import pandas as pd
|
8 |
import requests
|
9 |
from dotenv import load_dotenv
|
|
|
76 |
|
77 |
class QueryTranscriptsArgs(BaseModel):
|
78 |
query: str = Field(..., description="The user query.")
|
79 |
+
year: int = Field(..., description=f"The year. An integer between {min(years)} and {max(years)}.")
|
80 |
ticker: str = Field(..., description=f"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.")
|
81 |
|
82 |
tools_factory = ToolsFactory(vectara_api_key=cfg.api_key,
|
|
|
88 |
Given a company name and year,
|
89 |
returns a response (str) to a user question about a company, based on analyst call transcripts about the company's financial reports for that year.
|
90 |
You can ask this tool any question about the compaany including risks, opportunities, financial performance, competitors and more.
|
91 |
+
make sure to provide a valid company ticker and year.
|
92 |
""",
|
93 |
tool_args_schema = QueryTranscriptsArgs,
|
|
|
94 |
reranker = "multilingual_reranker_v1", rerank_k = 100,
|
95 |
+
n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.005,
|
96 |
summary_num_results = 10,
|
97 |
vectara_summarizer = 'vectara-summary-ext-24-05-med-omni',
|
98 |
+
include_citations = False,
|
99 |
)
|
100 |
|
101 |
return (tools_factory.get_tools(
|
|
|
112 |
)
|
113 |
|
114 |
def initialize_agent(_cfg):
|
115 |
+
financial_bot_instructions = """
|
116 |
+
- You are a helpful financial assistant, with expertise in financial reporting, in conversation with a user.
|
117 |
+
- Never discuss politics, and always respond politely.
|
|
|
|
|
118 |
- Respond in a compact format by using appropriate units of measure (e.g., K for thousands, M for millions, B for billions).
|
119 |
Do not report the same number twice (e.g. $100K and 100,000 USD).
|
120 |
+
- Always check the get_company_info and get_valid_years tools to validate company and year are valid.
|
|
|
121 |
- When querying a tool for a numeric value or KPI, use a concise and non-ambiguous description of what you are looking for.
|
122 |
- If you calculate a metric, make sure you have all the necessary information to complete the calculation. Don't guess.
|
|
|
123 |
"""
|
124 |
|
125 |
def update_func(status_type: AgentStatusType, msg: str):
|
|
|
134 |
)
|
135 |
return agent
|
136 |
|
137 |
+
|
138 |
+
def toggle_logs():
|
139 |
+
st.session_state.show_logs = not st.session_state.show_logs
|
140 |
+
|
141 |
def launch_bot():
|
142 |
def reset():
|
|
|
143 |
st.session_state.messages = [{"role": "assistant", "content": initial_prompt, "avatar": "π¦"}]
|
144 |
st.session_state.thinking_message = "Agent at work..."
|
|
|
145 |
st.session_state.log_messages = []
|
146 |
+
st.session_state.prompt = None
|
147 |
st.session_state.show_logs = False
|
148 |
|
149 |
st.set_page_config(page_title="Financial Assistant", layout="wide")
|
|
|
155 |
})
|
156 |
st.session_state.cfg = cfg
|
157 |
reset()
|
158 |
+
|
159 |
cfg = st.session_state.cfg
|
160 |
+
if 'agent' not in st.session_state:
|
161 |
+
st.session_state.agent = initialize_agent(cfg)
|
162 |
|
163 |
# left side content
|
164 |
with st.sidebar:
|
|
|
171 |
)
|
172 |
|
173 |
st.markdown("\n\n")
|
174 |
+
bc1, _ = st.columns([1, 1])
|
175 |
with bc1:
|
176 |
if st.button('Start Over'):
|
177 |
reset()
|
|
|
|
|
|
|
178 |
|
179 |
st.markdown("---")
|
180 |
st.markdown(
|
|
|
184 |
)
|
185 |
st.markdown("---")
|
186 |
|
|
|
187 |
if "messages" not in st.session_state.keys():
|
188 |
reset()
|
189 |
+
|
190 |
# Display chat messages
|
191 |
for message in st.session_state.messages:
|
192 |
with st.chat_message(message["role"], avatar=message["avatar"]):
|
|
|
195 |
# User-provided prompt
|
196 |
if prompt := st.chat_input():
|
197 |
st.session_state.messages.append({"role": "user", "content": prompt, "avatar": 'π§βπ»'})
|
198 |
+
st.session_state.prompt = prompt # Save the prompt in session state
|
199 |
+
st.session_state.log_messages = []
|
200 |
+
st.session_state.show_logs = False
|
201 |
with st.chat_message("user", avatar='π§βπ»'):
|
202 |
print(f"Starting new question: {prompt}\n")
|
203 |
st.write(prompt)
|
204 |
+
|
205 |
# Generate a new response if last message is not from assistant
|
206 |
+
if st.session_state.prompt:
|
207 |
with st.chat_message("assistant", avatar='π€'):
|
208 |
with st.spinner(st.session_state.thinking_message):
|
209 |
+
res = st.session_state.agent.chat(st.session_state.prompt)
|
210 |
+
res = res.replace('$', '\\$') # escape dollar sign for markdown
|
211 |
+
message = {"role": "assistant", "content": res, "avatar": 'π€'}
|
212 |
st.session_state.messages.append(message)
|
213 |
+
st.markdown(res)
|
214 |
+
st.session_state.prompt = None
|
215 |
|
216 |
+
log_placeholder = st.empty()
|
217 |
+
with log_placeholder.container():
|
218 |
+
if st.session_state.show_logs:
|
219 |
+
st.button("Hide Logs", on_click=toggle_logs)
|
220 |
for msg in st.session_state.log_messages:
|
221 |
st.write(msg)
|
222 |
+
else:
|
223 |
+
if len(st.session_state.log_messages) > 0:
|
224 |
+
st.button("Show Logs", on_click=toggle_logs)
|
225 |
|
226 |
sys.stdout.flush()
|
227 |
|