DrishtiSharma commited on
Commit
617cdaf
·
verified ·
1 Parent(s): 5ea8ff3

Create app5.py

Browse files
Files changed (1) hide show
  1. lab/app5.py +234 -0
lab/app5.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from graph import EssayWriter, RouteQuery, GraphState
3
+ from crew import *
4
+ import os
5
+ import traceback
6
+ import base64
7
+
8
+ # Install Graphviz if not found
9
+ if os.system("which dot") != 0:
10
+ os.system("apt-get update && apt-get install -y graphviz")
11
+
12
+ st.markdown(
13
+ """
14
+ <h1 style="text-align: center; white-space: nowrap; font-size: 2.5em;">
15
+ Multi-Agent Essay Writing Assistant
16
+ </h1>
17
+ """,
18
+ unsafe_allow_html=True
19
+ )
20
+
21
+ # Ensure session state variables are initialized properly
22
+ if "messages" not in st.session_state:
23
+ st.session_state["messages"] = [{"role": "assistant", "content": "Hello! How can I assist you today?"}]
24
+
25
+ if "app" not in st.session_state:
26
+ st.session_state["app"] = None
27
+
28
+ if "chat_active" not in st.session_state:
29
+ st.session_state["chat_active"] = True
30
+
31
+ # Sidebar with essay settings and user-defined length
32
+ with st.sidebar:
33
+ st.subheader("About:")
34
+ st.info(
35
+ "\n\n 1. This app uses the 'gpt-4o-mini-2024-07-18' model."
36
+ "\n\n 2. Writing essays may take some time, approximately 1-2 minutes."
37
+ )
38
+
39
+ # API Key Retrieval
40
+ openai_key = st.secrets.get("OPENAI_API_KEY", "")
41
+
42
+ st.divider()
43
+
44
+ # User-defined essay length selection
45
+ st.subheader("📝 Configure Essay Settings:")
46
+ essay_length = st.number_input(
47
+ "Select Essay Length (words):",
48
+ min_value=150,
49
+ max_value=500,
50
+ value=250,
51
+ step=50
52
+ )
53
+
54
+ st.divider()
55
+
56
+ # Reference section
57
+ st.subheader("📖 References:")
58
+ st.markdown(
59
+ "[1. Multi-Agent System with CrewAI and LangChain](https://discuss.streamlit.io/t/new-project-i-have-build-a-multi-agent-system-with-crewai-and-langchain/84002)",
60
+ unsafe_allow_html=True
61
+ )
62
+
63
+ # Initialize agents function
64
+ def initialize_agents():
65
+ if not openai_key:
66
+ st.error("⚠️ OpenAI API key is missing! Please provide a valid key through Hugging Face Secrets.")
67
+ st.session_state["chat_active"] = True
68
+ return None
69
+
70
+ os.environ["OPENAI_API_KEY"] = openai_key
71
+ try:
72
+ # Prevent re-initialization
73
+ if "app" in st.session_state and st.session_state["app"] is not None:
74
+ return st.session_state["app"]
75
+
76
+ # Initialize the full EssayWriter instance
77
+ essay_writer = EssayWriter() # Store the full instance
78
+ st.session_state["app"] = essay_writer # Now contains `graph`
79
+ st.session_state["chat_active"] = False # Enable chat after successful initialization
80
+
81
+ return essay_writer
82
+ except Exception as e:
83
+ st.error(f"❌ Error initializing agents: {e}")
84
+ st.session_state["chat_active"] = True
85
+ return None
86
+
87
+
88
+ # Automatically initialize agents on app load
89
+ if st.session_state["app"] is None:
90
+ st.session_state["app"] = initialize_agents()
91
+
92
+ if st.session_state["app"] is None:
93
+ st.error("⚠️ Failed to initialize agents. Please check your API key and restart the app.")
94
+
95
+ app = st.session_state["app"]
96
+
97
+ # Function to invoke the agent and generate a response
98
+ def generate_response(topic, length):
99
+ if not app or not hasattr(app, "graph"):
100
+ st.error("⚠️ Agents are not initialized. Please check the system or restart the app.")
101
+ return {"response": "Error: Agents not initialized."}
102
+
103
+ # Refined prompt for better essay generation
104
+ refined_prompt = f"""
105
+ Write a well-structured, engaging, and informative essay on "{topic}". The essay should be approximately {length} words and follow this structured format:
106
+ ## 1. Title
107
+ - Generate a compelling, creative, and relevant title that encapsulates the theme of the essay.
108
+ ## 2. Introduction (100-150 words)
109
+ - Clearly define the topic and its importance in the broader context.
110
+ - Provide a strong **thesis statement** that outlines the essay’s key argument.
111
+ - Briefly mention the **key themes** that will be explored in the body.
112
+ - Engage the reader with a thought-provoking fact, quote, or question.
113
+ ## 3. Main Body (Ensure clear organization and logical transitions)
114
+ Each section should:
115
+ - **Have a distinct, engaging subheading**.
116
+ - **Begin with a topic sentence** introducing the section’s main idea.
117
+ - **Include real-world examples, historical references, or statistical data**.
118
+ - **Maintain smooth transitions** between sections for cohesive reading.
119
+ ### Suggested Sections (Modify as Needed)
120
+ - **Historical Context**: Trace the origins and evolution of the topic over time.
121
+ - **Key Aspects**: Break down essential components (e.g., cultural, political, economic influences).
122
+ - **Modern Challenges & Debates**: Discuss **contemporary issues** and **conflicting viewpoints**.
123
+ - **Impact & Future Trends**: Examine how the topic influences the present and future.
124
+ ## 4. Conclusion (100-150 words)
125
+ - Concisely summarize key insights and arguments.
126
+ - Reinforce the essay’s thesis in light of the discussion.
127
+ - End with a **thought-provoking final statement**, such as:
128
+ - A **rhetorical question**.
129
+ - A **call to action**.
130
+ - A **broader reflection** on the topic’s long-term significance.
131
+ ## 5. Writing & Formatting Guidelines
132
+ - Maintain **formal, engaging, and precise** language.
133
+ - Ensure **clear paragraph structure and logical progression**.
134
+ - Avoid redundancy; keep insights sharp and impactful.
135
+ - Use **examples, expert opinions, or historical events** to strengthen arguments.
136
+ - Provide **citations or references** when possible.
137
+ """
138
+
139
+ response = app.graph.invoke(input={"topic": topic, "length": length, "prompt": refined_prompt})
140
+
141
+ return response
142
+
143
+
144
+
145
+ # Define Tabs
146
+ tab1, tab2 = st.tabs(["📜 Essay Generation", "📊 Workflow Viz"])
147
+
148
+ # 📜 Tab 1: Essay Generation
149
+ with tab1:
150
+ #st.subheader("📝 Generate an Essay")
151
+
152
+ # Display chat messages from the session
153
+ if "messages" not in st.session_state:
154
+ st.session_state["messages"] = [{"role": "assistant", "content": "Hello! How can I assist you today?"}]
155
+
156
+ for message in st.session_state["messages"]:
157
+ with st.chat_message(message["role"]):
158
+ st.markdown(message["content"], unsafe_allow_html=True)
159
+
160
+ # Handle user input
161
+ if topic := st.chat_input(placeholder="📝 Ask a question or provide an essay topic...", disabled=st.session_state["chat_active"]):
162
+ st.chat_message("user").markdown(topic)
163
+ st.session_state["messages"].append({"role": "user", "content": topic})
164
+
165
+ with st.spinner("⏳ Generating your essay..."):
166
+ response = None
167
+ if app:
168
+ response = app.write_essay({"topic": topic})
169
+ else:
170
+ st.error("⚠️ Agents are not initialized. Please check the system or restart the app.")
171
+
172
+ # Handle the assistant's response
173
+ with st.chat_message("assistant"):
174
+ if response and "essay" in response: # Display essay preview and download link
175
+ essay = response["essay"]
176
+ st.markdown(f"### 📝 Essay Preview ({essay_length} words)")
177
+ st.markdown(f"#### {essay['header']}")
178
+ st.markdown(essay["entry"])
179
+
180
+ for para in essay["paragraphs"]:
181
+ st.markdown(f"**{para['sub_header']}**")
182
+ st.markdown(para["paragraph"])
183
+
184
+ st.markdown("**🖊️ Conclusion:**")
185
+ st.markdown(essay["conclusion"])
186
+
187
+ # Provide download link for the PDF (only if available)
188
+ pdf_name = response.get("pdf_name")
189
+ if pdf_name and os.path.exists(pdf_name):
190
+ with open(pdf_name, "rb") as pdf_file:
191
+ b64 = base64.b64encode(pdf_file.read()).decode()
192
+ href = f"<a href='data:application/octet-stream;base64,{b64}' download='{pdf_name}'>📄 Click here to download the PDF</a>"
193
+ st.markdown(href, unsafe_allow_html=True)
194
+
195
+ # Save response in session state
196
+ st.session_state["messages"].append(
197
+ {"role": "assistant", "content": f"Here is your {essay_length}-word essay preview and the download link."}
198
+ )
199
+ elif response: # Other responses (fallback)
200
+ st.markdown(response["response"])
201
+ st.session_state["messages"].append({"role": "assistant", "content": response["response"]})
202
+ else:
203
+ st.error("⚠️ No response received. Please try again.")
204
+
205
+
206
+ # 📊 Tab 2: Workflow Visualization
207
+ with tab2:
208
+ #st.subheader("📊 Multi-Agent Essay Writer Workflow Viz")
209
+
210
+ try:
211
+ graph_path = "/tmp/graph.png"
212
+ if os.path.exists(graph_path):
213
+ st.image(graph_path, caption="Multi-Agent Essay Writer Workflow Visualization", use_container_width=True)
214
+ else:
215
+ st.warning("⚠️ Workflow graph not found. Please run `graph.py` to regenerate `graph.png`.")
216
+
217
+ except Exception as e:
218
+ st.error("❌ An error occurred while generating the workflow visualization.")
219
+ st.text_area("Error Details:", traceback.format_exc(), height=200)
220
+
221
+
222
+ # Acknowledgement Section
223
+ st.markdown(
224
+ """
225
+ <div style="text-align: center; font-size: 14px; color: #555; padding-top: 200px; margin-top: 200px;">
226
+ <strong>Acknowledgement:</strong> This app is based on Mesut Duman's work:
227
+ <a href="https://github.com/mesutdmn/Autonomous-Multi-Agent-Systems-with-CrewAI-Essay-Writer/tree/main"
228
+ target="_blank" style="color: #007BFF; text-decoration: none;">
229
+ CrewAI Essay Writer
230
+ </a>
231
+ </div>
232
+ """,
233
+ unsafe_allow_html=True,
234
+ )