-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
168 lines (148 loc) · 5.97 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# app.py
import streamlit as st
import os
from dotenv import load_dotenv
from typing import List
from pydantic import BaseModel, Field
from phi.agent import Agent
from phi.model.together import Together
from phi.tools.duckduckgo import DuckDuckGo
from phi.tools.newspaper4k import Newspaper4k
from phi.tools.yfinance import YFinanceTools
# Initialize session state
if 'chat_history' not in st.session_state:
st.session_state.chat_history = []
if 'current_agent' not in st.session_state:
st.session_state.current_agent = None
if 'config' not in st.session_state:
st.session_state.config = None
if 'factory' not in st.session_state:
st.session_state.factory = None
class Config:
"""Configuration class for AI agents"""
def __init__(self):
# Load environment variables
load_dotenv()
self.together_api_key = os.getenv('TOGETHER_API_KEY')
if not self.together_api_key:
raise ValueError("TOGETHER_API_KEY environment variable is not set")
class MovieScript(BaseModel):
"""Data model for movie script generation"""
setting: str = Field(..., description="Setting for a blockbuster movie")
ending: str = Field(..., description="Movie ending")
genre: str = Field(..., description="Movie genre")
name: str = Field(..., description="Movie name")
characters: List[str] = Field(..., description="Character names")
storyline: str = Field(..., description="3 sentence storyline")
class AIAgentFactory:
"""Factory class for creating different types of AI agents"""
def __init__(self, config: Config):
self.config = config
self.base_model = Together(
api_key=config.together_api_key,
id="meta-llama/Llama-3.3-70B-Instruct-Turbo"
)
def create_researcher_agent(self) -> Agent:
"""Creates a researcher agent for article writing"""
return Agent(
model=self.base_model,
tools=[DuckDuckGo(), Newspaper4k()],
description="You are a senior NYT researcher writing an article on a topic.",
instructions=[
"For a given topic, search for the top 5 links.",
"Then read each URL and extract the article text, if a URL isn't available, ignore it.",
"Analyse and prepare an NYT worthy article based on the information.",
],
markdown=True,
show_tool_calls=True,
add_datetime_to_instructions=True,
)
def create_finance_agent(self) -> Agent:
"""Creates a finance agent for market analysis"""
return Agent(
model=self.base_model,
tools=[YFinanceTools(
stock_price=True,
analyst_recommendations=True,
company_info=True,
company_news=True
)],
instructions=["Use tables to display data"],
show_tool_calls=True,
markdown=True,
)
def initialize_app():
"""Initialize the application configuration and factory"""
if st.session_state.config is None:
try:
st.session_state.config = Config()
st.session_state.factory = AIAgentFactory(st.session_state.config)
st.success("Application initialized successfully!")
except ValueError as e:
st.error(f"Initialization failed: {str(e)}")
st.stop()
def display_chat_history():
"""Display the chat history"""
for message in st.session_state.chat_history:
with st.chat_message(message["role"]):
st.markdown(message["content"])
def main():
st.set_page_config(
page_title="AI Research Assistant",
page_icon="🤖",
layout="wide"
)
# Sidebar
with st.sidebar:
st.title("🤖 AI Research Assistant")
st.markdown("---")
initialize_app()
# Agent selection with icons
agent_type = st.selectbox(
"Select Assistant Type",
["📰 Researcher", "📊 Finance"],
format_func=lambda x: x.split(" ")[1]
)
st.markdown("---")
# Help section in sidebar
with st.expander("ℹ️ How to use"):
st.markdown("""
1. Select your assistant type above
2. For Researcher: Enter any topic to get a researched article
3. For Finance: Enter a stock symbol to get financial analysis
4. Use the chat input below to interact
5. Clear chat history using the button below
""")
# Clear chat button
if st.button("🗑️ Clear Chat"):
st.session_state.chat_history = []
st.experimental_rerun()
# Main content area
st.title(f"{agent_type.split(' ')[1]} Assistant")
# Initialize or switch agent based on selection
selected_type = agent_type.split(" ")[1]
if selected_type != st.session_state.get('last_agent_type'):
if selected_type == "Researcher":
st.session_state.current_agent = st.session_state.factory.create_researcher_agent()
else: # Finance
st.session_state.current_agent = st.session_state.factory.create_finance_agent()
st.session_state.last_agent_type = selected_type
st.session_state.chat_history = []
# Display chat interface
display_chat_history()
# Chat input
if prompt := st.chat_input(
"Researcher: Enter a topic | Finance: Enter a stock symbol (e.g., AAPL)"
):
# Add user message to chat history
st.session_state.chat_history.append({"role": "user", "content": prompt})
# Get agent response
with st.chat_message("assistant"):
with st.spinner("Analyzing..."):
response = st.session_state.current_agent.run(prompt)
st.markdown(response.content)
st.session_state.chat_history.append(
{"role": "assistant", "content": response.content}
)
if __name__ == "__main__":
main()