ofermend commited on
Commit
ed18c6a
β€’
1 Parent(s): 5c70cac
Files changed (1) hide show
  1. app.py +35 -34
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. an integer between {min(years)} and {max(years)}.")
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 the a valid company ticker and year.
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.01,
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
- date = datetime.datetime.now().strftime("%Y-%m-%d")
118
- financial_bot_instructions = f"""
119
- - You are a helpful financial assistant, with expertise in finanal reporting, in conversation with a user.
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
- - Use tools when available instead of depending on your own knowledge.
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, bc2 = st.columns([1, 1])
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.messages[-1]["role"] != "assistant":
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
- cleaned = re.sub(r'\[\d+\]', '', res).replace('$', '\\$')
212
- message = {"role": "assistant", "content": cleaned, "avatar": 'πŸ€–'}
213
  st.session_state.messages.append(message)
214
- st.rerun()
 
215
 
216
- # Display log messages in an expander
217
- if st.session_state.show_logs:
218
- with st.expander("Agent Log Messages", expanded=True):
 
219
  for msg in st.session_state.log_messages:
220
  st.write(msg)
221
- if st.button('Close Logs'):
222
- st.session_state.show_logs = False
223
- st.rerun()
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