Spaces:
Running
Running
Commit ·
ac886d3
1
Parent(s): 4817f08
moved message parsing from app to StockAnalyst
Browse files- app.py +2 -22
- src/stock_analysis_agent.py +59 -8
app.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
import json
|
| 3 |
|
| 4 |
from src.stock_analysis_agent import StockAnalyst
|
| 5 |
|
|
@@ -18,27 +17,8 @@ def initialize_agent():
|
|
| 18 |
def interact_with_agent(agent_instance, ticker):
|
| 19 |
if agent_instance is None:
|
| 20 |
return 'Stock-Analysis Agent is not initialized. Please initialize first.'
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
summary_str = messages[-1].model_dump()['content']
|
| 24 |
-
response_pretty = ''
|
| 25 |
-
try:
|
| 26 |
-
FA_dict = json.loads(FA_str)
|
| 27 |
-
response_pretty += f"**Company Name:** {FA_dict['Company Name']} \n"
|
| 28 |
-
response_pretty += f"**Sector:** {FA_dict['Sector']}\n\n"
|
| 29 |
-
except Exception as e:
|
| 30 |
-
response_pretty += f"**ticker**: {ticker}\n\n"
|
| 31 |
-
print(f'Error parsing the Financial Analysis response:\n{e}')
|
| 32 |
-
try:
|
| 33 |
-
summary_dict = json.loads(summary_str)
|
| 34 |
-
for key, value in summary_dict.items():
|
| 35 |
-
if key != 'stock':
|
| 36 |
-
pretty_key = key.replace('_', ' ').title()
|
| 37 |
-
response_pretty += f"**{pretty_key}**: {value}\n\n"
|
| 38 |
-
except Exception as e:
|
| 39 |
-
response_pretty += f'*An error occured stylizing the response, printing the raw response*:\n{summary_str}'
|
| 40 |
-
print(f'Error parsing summary response:\n{e}\n')
|
| 41 |
-
return response_pretty
|
| 42 |
|
| 43 |
with gr.Blocks() as demo:
|
| 44 |
gr.Markdown("# Stock Analysis Agent")
|
|
|
|
| 1 |
import gradio as gr
|
|
|
|
| 2 |
|
| 3 |
from src.stock_analysis_agent import StockAnalyst
|
| 4 |
|
|
|
|
| 17 |
def interact_with_agent(agent_instance, ticker):
|
| 18 |
if agent_instance is None:
|
| 19 |
return 'Stock-Analysis Agent is not initialized. Please initialize first.'
|
| 20 |
+
response = agent_instance.get_formatted_stock_summary(ticker)
|
| 21 |
+
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
with gr.Blocks() as demo:
|
| 24 |
gr.Markdown("# Stock Analysis Agent")
|
src/stock_analysis_agent.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
| 1 |
-
from typing import Union, Dict, TypedDict, Annotated
|
| 2 |
|
| 3 |
import dotenv
|
| 4 |
from IPython.display import Image, display
|
|
|
|
| 5 |
from langgraph.graph import StateGraph, START # , END
|
| 6 |
from langchain_openai import ChatOpenAI
|
| 7 |
from langchain_core.messages import SystemMessage #, AIMessage, HumanMessage
|
|
@@ -195,14 +196,27 @@ class StockAnalyst():
|
|
| 195 |
# This requires some extra dependencies and is optional
|
| 196 |
pass
|
| 197 |
|
| 198 |
-
def
|
| 199 |
self,
|
| 200 |
-
|
| 201 |
-
) ->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
events = self.graph.stream(
|
| 203 |
{
|
| 204 |
'messages':[('user', 'Should I buy this stock?')],
|
| 205 |
-
'stock':
|
| 206 |
},
|
| 207 |
stream_mode='values'
|
| 208 |
)
|
|
@@ -211,10 +225,47 @@ class StockAnalyst():
|
|
| 211 |
if 'messages' in event:
|
| 212 |
messages.append(event['messages'][-1])
|
| 213 |
return messages
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
|
| 215 |
|
| 216 |
if __name__ == "__main__":
|
| 217 |
stock_analyst = StockAnalyst(debug=False)
|
| 218 |
-
messages = stock_analyst.get_stock_suggestion('GOOG')
|
| 219 |
-
for message in messages:
|
| 220 |
-
|
|
|
|
|
|
| 1 |
+
from typing import Union, Dict, TypedDict, Annotated, List
|
| 2 |
|
| 3 |
import dotenv
|
| 4 |
from IPython.display import Image, display
|
| 5 |
+
import json
|
| 6 |
from langgraph.graph import StateGraph, START # , END
|
| 7 |
from langchain_openai import ChatOpenAI
|
| 8 |
from langchain_core.messages import SystemMessage #, AIMessage, HumanMessage
|
|
|
|
| 196 |
# This requires some extra dependencies and is optional
|
| 197 |
pass
|
| 198 |
|
| 199 |
+
def get_stock_analyses(
|
| 200 |
self,
|
| 201 |
+
ticker
|
| 202 |
+
) -> List[str]:
|
| 203 |
+
"""
|
| 204 |
+
Retrieves a list of stock analyses based on a given ticker symbol.
|
| 205 |
+
This function interacts with the state graph to stream events related
|
| 206 |
+
to stock analysis for the specified ticker. It sends a message asking
|
| 207 |
+
"Should I buy this stock?" and collects the resulting messages generated
|
| 208 |
+
by the graph, which contain stock suggestions.
|
| 209 |
+
Args:
|
| 210 |
+
ticker : str
|
| 211 |
+
The stock symbol (ticker) of the company to get suggestions for.
|
| 212 |
+
Returns:
|
| 213 |
+
List[str]: A list of messages containing stock suggestions.
|
| 214 |
+
"""
|
| 215 |
+
|
| 216 |
events = self.graph.stream(
|
| 217 |
{
|
| 218 |
'messages':[('user', 'Should I buy this stock?')],
|
| 219 |
+
'stock': ticker
|
| 220 |
},
|
| 221 |
stream_mode='values'
|
| 222 |
)
|
|
|
|
| 225 |
if 'messages' in event:
|
| 226 |
messages.append(event['messages'][-1])
|
| 227 |
return messages
|
| 228 |
+
|
| 229 |
+
def get_formatted_stock_summary(
|
| 230 |
+
self,
|
| 231 |
+
ticker
|
| 232 |
+
) -> str:
|
| 233 |
+
"""
|
| 234 |
+
Retrieves analyses for a given stock ticker, syntheses information from messages, returns
|
| 235 |
+
a markdown formatted string containing a company's name, sector, and a summary of analyses.
|
| 236 |
+
|
| 237 |
+
Args:
|
| 238 |
+
ticker : str
|
| 239 |
+
The stock symbol (ticker) of the company to get the formatted summary for.
|
| 240 |
+
Returns:
|
| 241 |
+
str: A formatted string containing the company name, sector, and a summary of its stock analysis.
|
| 242 |
+
"""
|
| 243 |
+
messages = self.get_stock_analyses(ticker)
|
| 244 |
+
FA_str = messages[-2].model_dump()['content']
|
| 245 |
+
summary_str = messages[-1].model_dump()['content']
|
| 246 |
+
response_pretty = ''
|
| 247 |
+
try:
|
| 248 |
+
FA_dict = json.loads(FA_str)
|
| 249 |
+
response_pretty += f"**Company Name:** {FA_dict['Company Name']} \n"
|
| 250 |
+
response_pretty += f"**Sector:** {FA_dict['Sector']}\n\n"
|
| 251 |
+
except Exception as e:
|
| 252 |
+
response_pretty += f"**ticker**: {ticker}\n\n"
|
| 253 |
+
print(f'Error parsing the Financial Analysis response:\n{e}')
|
| 254 |
+
try:
|
| 255 |
+
summary_dict = json.loads(summary_str)
|
| 256 |
+
for key, value in summary_dict.items():
|
| 257 |
+
if key != 'stock':
|
| 258 |
+
pretty_key = key.replace('_', ' ').title()
|
| 259 |
+
response_pretty += f"**{pretty_key}**: {value}\n\n"
|
| 260 |
+
except Exception as e:
|
| 261 |
+
response_pretty += f'*An error occured stylizing the response, printing the raw response*:\n{summary_str}'
|
| 262 |
+
print(f'Error parsing summary response:\n{e}\n')
|
| 263 |
+
return response_pretty
|
| 264 |
|
| 265 |
|
| 266 |
if __name__ == "__main__":
|
| 267 |
stock_analyst = StockAnalyst(debug=False)
|
| 268 |
+
# messages = stock_analyst.get_stock_suggestion('GOOG')
|
| 269 |
+
# for message in messages:
|
| 270 |
+
# message.pretty_print()
|
| 271 |
+
print(stock_analyst.get_formatted_stock_summary('GOOG'))
|