Update app.py
Browse files
app.py
CHANGED
@@ -106,69 +106,84 @@ app = st.session_state["app"]
|
|
106 |
|
107 |
# Function to invoke the agent and generate a response
|
108 |
def enforce_word_limit(text, limit):
|
109 |
-
"""
|
110 |
-
words =
|
111 |
-
return
|
112 |
|
113 |
def detect_unexpected_english(text, selected_language):
|
114 |
-
"""
|
115 |
if selected_language != "English":
|
116 |
-
|
117 |
-
|
118 |
-
english_count = sum(1 for word in words if word.lower() in common_english_words)
|
119 |
-
return english_count > 5 # Allow minor tolerance
|
120 |
|
121 |
def generate_response(topic, length, selected_language):
|
122 |
if not app or not hasattr(app, "graph"):
|
123 |
-
st.error("
|
124 |
return {"response": "Error: Agents not initialized."}
|
125 |
|
126 |
-
#
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
133 |
refined_prompt = f"""
|
134 |
-
Write a structured and
|
135 |
|
136 |
-
**Word Limit:** {length} words. **
|
137 |
-
**Language:**
|
138 |
|
139 |
**Essay Structure:**
|
140 |
-
- **Title
|
141 |
-
- **Introduction ({intro_limit} words max)**:
|
|
|
|
|
|
|
142 |
- **Main Body ({body_limit} words max, {num_sections} sections)**:
|
143 |
-
- Each section
|
144 |
-
|
145 |
-
|
|
|
|
|
146 |
- **Conclusion ({conclusion_limit} words max)**:
|
147 |
-
- Summarize key
|
148 |
-
-
|
|
|
149 |
|
150 |
-
**Rules:**
|
151 |
-
- **
|
152 |
-
- **Do not
|
|
|
|
|
|
|
153 |
"""
|
154 |
|
155 |
-
#
|
156 |
response = app.graph.invoke(input={
|
157 |
"topic": topic,
|
158 |
"length": length,
|
159 |
"prompt": refined_prompt,
|
160 |
"language": selected_language,
|
161 |
-
"max_tokens":
|
162 |
})
|
163 |
|
|
|
164 |
essay_text = enforce_word_limit(response.get("essay", ""), length)
|
165 |
|
|
|
166 |
if detect_unexpected_english(essay_text, selected_language):
|
167 |
-
return {"response": f"⚠️ Warning: English detected in {selected_language} essay. Try regenerating."}
|
168 |
|
169 |
return {"essay": essay_text}
|
170 |
|
171 |
|
|
|
172 |
# Define Tabs
|
173 |
tab1, tab2 = st.tabs(["📜 Essay Generation", "📊 Workflow Viz"])
|
174 |
|
@@ -198,7 +213,7 @@ with tab1:
|
|
198 |
with st.spinner("⏳ Generating your essay..."):
|
199 |
response = None
|
200 |
if app:
|
201 |
-
response =
|
202 |
else:
|
203 |
st.error("⚠️ Agents are not initialized. Please check the system or restart the app.")
|
204 |
|
@@ -216,22 +231,27 @@ with tab1:
|
|
216 |
|
217 |
with col1:
|
218 |
st.markdown(f"### 📝 Essay Preview ({essay_length} words)")
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
|
220 |
-
|
221 |
-
|
222 |
-
for part in essay_parts:
|
223 |
-
if part.startswith("## "): # Title
|
224 |
-
st.markdown(f"#### {part[3:]}")
|
225 |
-
elif part.startswith("### "): # Subheadings
|
226 |
-
st.markdown(f"**{part[4:]}**")
|
227 |
-
else:
|
228 |
-
st.markdown(part)
|
229 |
|
230 |
with col2:
|
231 |
st.markdown("### ✍️ Edit Your Essay:")
|
232 |
|
233 |
-
#
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
|
236 |
# Save and Download buttons
|
237 |
save_col1, save_col2 = st.columns(2)
|
@@ -279,6 +299,7 @@ with tab1:
|
|
279 |
st.error("⚠️ No response received. Please try again.")
|
280 |
|
281 |
|
|
|
282 |
# 📊 Tab 2: Workflow Visualization
|
283 |
with tab2:
|
284 |
#st.subheader("📊 Multi-Agent Essay Writer Workflow Viz")
|
|
|
106 |
|
107 |
# Function to invoke the agent and generate a response
|
108 |
def enforce_word_limit(text, limit):
|
109 |
+
"""Enforces strict word limit by truncating extra words."""
|
110 |
+
words = re.findall(r'\b\w+\b', text)
|
111 |
+
return ' '.join(words[:limit]) if len(words) > limit else text
|
112 |
|
113 |
def detect_unexpected_english(text, selected_language):
|
114 |
+
"""Detects unintended English words when another language is selected."""
|
115 |
if selected_language != "English":
|
116 |
+
english_words = re.findall(r'\b(?:is|the|and|or|in|on|at|to|with|for|of|by|it|that|this|was|he|she|they|we|you|I)\b', text)
|
117 |
+
return len(english_words) > 5 # Allow a small tolerance
|
|
|
|
|
118 |
|
119 |
def generate_response(topic, length, selected_language):
|
120 |
if not app or not hasattr(app, "graph"):
|
121 |
+
st.error("Agents are not initialized. Please check the system or restart the app.")
|
122 |
return {"response": "Error: Agents not initialized."}
|
123 |
|
124 |
+
# Dynamically adjust structure based on length
|
125 |
+
if length <= 250:
|
126 |
+
intro_limit, body_limit, conclusion_limit = length // 5, length // 2, length // 5
|
127 |
+
num_sections = 2 # Shorter essays should have fewer sections
|
128 |
+
elif length <= 350:
|
129 |
+
intro_limit, body_limit, conclusion_limit = length // 6, length // 1.8, length // 6
|
130 |
+
num_sections = 3
|
131 |
+
else:
|
132 |
+
intro_limit, body_limit, conclusion_limit = length // 7, length // 1.7, length // 7
|
133 |
+
num_sections = 4
|
134 |
+
|
135 |
+
# Optimized Structured Prompt
|
136 |
refined_prompt = f"""
|
137 |
+
Write a **well-structured, informative, and engaging** essay on "{topic}" **strictly in {selected_language}.**
|
138 |
|
139 |
+
**Word Limit:** Exactly {length} words. **Do not exceed or fall short of this limit.**
|
140 |
+
**Language Rules:** Use natural linguistic style from {selected_language}. **Do not use English** unless explicitly requested.
|
141 |
|
142 |
**Essay Structure:**
|
143 |
+
- **Title**: Max 10 words.
|
144 |
+
- **Introduction ({intro_limit} words max)**:
|
145 |
+
- Clearly define the topic and its significance.
|
146 |
+
- Provide a strong thesis statement.
|
147 |
+
- Preview the key points covered in the essay.
|
148 |
- **Main Body ({body_limit} words max, {num_sections} sections)**:
|
149 |
+
- Each section must have:
|
150 |
+
- A **clear subheading**.
|
151 |
+
- A concise topic sentence with supporting details.
|
152 |
+
- Relevant **examples, statistics, or historical references**.
|
153 |
+
- Maintain natural **flow** between sections.
|
154 |
- **Conclusion ({conclusion_limit} words max)**:
|
155 |
+
- Summarize key insights **without repetition**.
|
156 |
+
- Reinforce the thesis **based on discussion**.
|
157 |
+
- End with a strong **closing statement** (reflection or call to action).
|
158 |
|
159 |
+
**Hard Rules:**
|
160 |
+
- **Use only {selected_language}**. No English unless explicitly requested.
|
161 |
+
- **Do not exceed {length} words.** Absolute limit.
|
162 |
+
- **Write concisely and avoid fluff**. No redundancy.
|
163 |
+
- **Merge similar ideas** to maintain smooth readability.
|
164 |
+
- **Ensure strict adherence to section word limits**.
|
165 |
"""
|
166 |
|
167 |
+
# Invoke AI model with enforced word limit
|
168 |
response = app.graph.invoke(input={
|
169 |
"topic": topic,
|
170 |
"length": length,
|
171 |
"prompt": refined_prompt,
|
172 |
"language": selected_language,
|
173 |
+
"max_tokens": length + 10 # Small buffer for better trimming
|
174 |
})
|
175 |
|
176 |
+
# Strict word limit enforcement
|
177 |
essay_text = enforce_word_limit(response.get("essay", ""), length)
|
178 |
|
179 |
+
# Detect unintended English words in non-English essays
|
180 |
if detect_unexpected_english(essay_text, selected_language):
|
181 |
+
return {"response": f"⚠️ Warning: Some English words were detected in the {selected_language} essay. Try regenerating."}
|
182 |
|
183 |
return {"essay": essay_text}
|
184 |
|
185 |
|
186 |
+
|
187 |
# Define Tabs
|
188 |
tab1, tab2 = st.tabs(["📜 Essay Generation", "📊 Workflow Viz"])
|
189 |
|
|
|
213 |
with st.spinner("⏳ Generating your essay..."):
|
214 |
response = None
|
215 |
if app:
|
216 |
+
response = app.write_essay({"topic": topic})
|
217 |
else:
|
218 |
st.error("⚠️ Agents are not initialized. Please check the system or restart the app.")
|
219 |
|
|
|
231 |
|
232 |
with col1:
|
233 |
st.markdown(f"### 📝 Essay Preview ({essay_length} words)")
|
234 |
+
st.markdown(f"#### {essay['header']}")
|
235 |
+
st.markdown(essay["entry"])
|
236 |
+
|
237 |
+
for para in essay["paragraphs"]:
|
238 |
+
st.markdown(f"**{para['sub_header']}**")
|
239 |
+
st.markdown(para["paragraph"])
|
240 |
|
241 |
+
st.markdown("**🖊️ Conclusion:**")
|
242 |
+
st.markdown(essay["conclusion"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
|
244 |
with col2:
|
245 |
st.markdown("### ✍️ Edit Your Essay:")
|
246 |
|
247 |
+
# Combine all parts of the essay into one editable text field
|
248 |
+
full_essay_text = f"## {essay['header']}\n\n{essay['entry']}\n\n"
|
249 |
+
for para in essay["paragraphs"]:
|
250 |
+
full_essay_text += f"### {para['sub_header']}\n{para['paragraph']}\n\n"
|
251 |
+
full_essay_text += f"**Conclusion:**\n{essay['conclusion']}"
|
252 |
+
|
253 |
+
# Editable text area for the user
|
254 |
+
edited_essay = st.text_area("Edit Here:", value=full_essay_text, height=300)
|
255 |
|
256 |
# Save and Download buttons
|
257 |
save_col1, save_col2 = st.columns(2)
|
|
|
299 |
st.error("⚠️ No response received. Please try again.")
|
300 |
|
301 |
|
302 |
+
|
303 |
# 📊 Tab 2: Workflow Visualization
|
304 |
with tab2:
|
305 |
#st.subheader("📊 Multi-Agent Essay Writer Workflow Viz")
|