kamaleswar Mohanta commited on
Commit
bdabf68
·
1 Parent(s): 59bb62c

cleaned main.py Remove obsolete langgraph API files and clean up related configurations

Browse files
.langgraph_api/.langgraph_checkpoint.1.pckl DELETED
Binary file (6 Bytes)
 
.langgraph_api/.langgraph_checkpoint.2.pckl DELETED
Binary file (6 Bytes)
 
.langgraph_api/.langgraph_ops.pckl DELETED
Binary file (525 Bytes)
 
.langgraph_api/.langgraph_retry_counter.pckl DELETED
Binary file (6 Bytes)
 
.langgraph_api/store.pckl DELETED
Binary file (6 Bytes)
 
.langgraph_api/store.vectors.pckl DELETED
Binary file (6 Bytes)
 
langgraph.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "dependencies": ["."],
3
- "graphs": {
4
- "main_graph": "C:\\Users\\kamal\\OneDrive\\Desktop\\Research\\krish\\Projects\\LangGraphProject\\src\\langgraphagenticai\\graph\\graph_builder.py:graph"
5
- },
6
- "env": "../.env"
7
- }
 
 
 
 
 
 
 
 
src/langgraphagenticai/__pycache__/main.cpython-312.pyc CHANGED
Binary files a/src/langgraphagenticai/__pycache__/main.cpython-312.pyc and b/src/langgraphagenticai/__pycache__/main.cpython-312.pyc differ
 
src/langgraphagenticai/main.py CHANGED
@@ -1,18 +1,17 @@
1
- # src/langgraphagenticai/main.py
2
  import streamlit as st
3
  import uuid
4
  import logging
5
  import os
6
- from langchain_core.messages import HumanMessage, AIMessage
7
  from langchain_community.chat_message_histories import ChatMessageHistory
8
  from langchain_core.chat_history import BaseChatMessageHistory
9
  from langchain_core.runnables.history import RunnableWithMessageHistory
10
  from src.langgraphagenticai.ui.streamlitui.loadui import LoadStreamlitUI
11
- from src.langgraphagenticai.ui.streamlitui.display_result import DisplayResultStreamlit
12
  from src.langgraphagenticai.LLMS.groqllm import GroqLLM
13
  from src.langgraphagenticai.LLMS.geminillm import GoogleLLM
14
  from src.langgraphagenticai.LLMS.chatgptllm import OpenaiLLM
15
  from src.langgraphagenticai.graph.graph_builder import GraphBuilder
 
16
 
17
  logging.basicConfig(level=logging.INFO)
18
  logger = logging.getLogger(__name__)
@@ -25,9 +24,12 @@ def get_session_history(session_id: str) -> BaseChatMessageHistory:
25
  return store[session_id]
26
 
27
  def load_langgraph_agenticai_app():
 
 
 
 
28
  ui = LoadStreamlitUI()
29
  user_controls = ui.load_streamlit_ui()
30
- display_result = DisplayResultStreamlit()
31
 
32
  if not user_controls:
33
  st.error("Error: Failed to load user controls from the UI.")
@@ -55,6 +57,7 @@ def load_langgraph_agenticai_app():
55
  st.warning("Please enter your OpenAI API key in the sidebar.")
56
  return
57
 
 
58
  if "session_id" not in st.session_state:
59
  st.session_state.session_id = str(uuid.uuid4())
60
  if "thread_id" not in st.session_state:
@@ -67,43 +70,11 @@ def load_langgraph_agenticai_app():
67
  st.session_state.blog_requirements_collected = False
68
  if "current_usecase" not in st.session_state:
69
  st.session_state.current_usecase = None
70
- if "outline_feedback" not in st.session_state:
71
- st.session_state.outline_feedback = None
72
- if "draft_feedback" not in st.session_state:
73
- st.session_state.draft_feedback = None
74
- if "draft_displayed" not in st.session_state:
75
- st.session_state.draft_displayed = False
76
- if "outline_displayed" not in st.session_state:
77
- st.session_state.outline_displayed = False
78
 
79
  config = {"configurable": {"session_id": st.session_state.session_id, "thread_id": st.session_state.thread_id, "recursion_limit": 50}}
80
  logger.info(f"Session ID: {st.session_state.session_id}, Thread ID: {st.session_state.thread_id}")
81
 
82
- st.markdown("### Chat")
83
- session_history = get_session_history(st.session_state.session_id)
84
- for message in session_history.messages:
85
- role = "user" if isinstance(message, HumanMessage) else "assistant"
86
- with st.chat_message(role):
87
- st.markdown(message.content, unsafe_allow_html=True)
88
-
89
- usecase = user_controls.get("selected_usecase")
90
- if not usecase:
91
- st.error("Error: No use case selected.")
92
- return
93
-
94
- if st.session_state.current_usecase != usecase:
95
- logger.info(f"Use case changed to: {usecase}. Resetting session state.")
96
- st.session_state.waiting_for_feedback = False
97
- st.session_state.blog_requirements_collected = False
98
- st.session_state.current_usecase = usecase
99
- st.session_state.draft_displayed = False
100
- st.session_state.outline_displayed = False
101
- session_history.clear()
102
- if "graph" in st.session_state:
103
- del st.session_state.graph
104
- if "with_message_history" in st.session_state:
105
- del st.session_state.with_message_history
106
-
107
  try:
108
  if selected_llm == "Groq":
109
  llm_config = GroqLLM(user_controls_input=user_controls)
@@ -120,6 +91,23 @@ def load_langgraph_agenticai_app():
120
  st.error("Error: LLM model could not be initialized.")
121
  return
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  if "graph" not in st.session_state:
124
  graph_builder = GraphBuilder(model)
125
  graph = graph_builder.setup_graph(usecase)
@@ -131,188 +119,15 @@ def load_langgraph_agenticai_app():
131
  )
132
  st.session_state.graph = graph
133
  st.session_state.with_message_history = with_message_history
134
- if not st.session_state.graph:
135
- raise ValueError("Graph initialization failed")
136
 
137
- except Exception as e:
138
- logger.error(f"Error initializing graph: {e}")
139
- st.error(f"Failed to initialize graph: {e}. Please check your configuration and try again.")
140
- return
141
-
142
- if usecase == "Blog Generation":
143
- if st.session_state.waiting_for_feedback:
144
- if st.session_state.graph_state:
145
- latest_state = st.session_state.graph_state.values
146
-
147
- # Display draft content only if not already displayed
148
- if "completed_sections" in latest_state and not st.session_state.get("draft_displayed"):
149
- with st.chat_message("assistant"):
150
- draft_content = "\n\n".join(latest_state["completed_sections"])
151
- st.markdown("### Generated Draft")
152
- st.markdown(draft_content)
153
- st.session_state.draft_displayed = True
154
- display_result.display_result(latest_state, usecase)
155
-
156
- # Determine which review stage we're in
157
- current_node = st.session_state.graph_state.next[0] if st.session_state.graph_state.next else None
158
- if current_node == "outline_review":
159
- st.write("Review the outline:")
160
- col1, col2 = st.columns(2)
161
- with col1:
162
- if st.button("Looks good", key="outline_approve"):
163
- st.session_state.outline_feedback = "approved"
164
- st.session_state.waiting_for_feedback = False
165
- st.session_state.outline_displayed = False # Reset for next stage
166
- logger.info("Outline approved via button")
167
- with col2:
168
- if st.button("Add more details", key="outline_reject"):
169
- st.session_state.outline_feedback = "add_more_details"
170
- st.session_state.waiting_for_feedback = False
171
- logger.info("Outline rejected via button, requesting more details")
172
- elif current_node == "draft_review":
173
- st.write("Review the draft:")
174
- col1, col2 = st.columns(2)
175
- with col1:
176
- if st.button("Looks good", key="draft_approve"):
177
- st.session_state.draft_feedback = "approved"
178
- st.session_state.waiting_for_feedback = False
179
- st.session_state.draft_displayed = False # Reset display flag
180
- logger.info("Draft approved via button")
181
- with col2:
182
- if st.button("Add more details", key="draft_reject"):
183
- st.session_state.draft_feedback = "add_more_details"
184
- st.session_state.waiting_for_feedback = False
185
- st.session_state.draft_displayed = False # Reset display flag
186
- logger.info("Draft rejected via button, requesting more details")
187
-
188
- # Process feedback if provided
189
- if not st.session_state.waiting_for_feedback:
190
- graph = st.session_state.get("graph")
191
- if not graph:
192
- logger.error("Graph not initialized in session state")
193
- st.error("Error: Workflow graph not initialized.")
194
- return
195
- with st.spinner("Processing feedback..."):
196
- for event in graph.stream(None, config=config):
197
- logger.info(f"Graph event: {event}")
198
- for node, state in event.items():
199
- # Update state handling for outline display
200
- if "messages" in state and state["messages"]:
201
- with st.chat_message("assistant"):
202
- if "sections" in state:
203
- # Force outline display when sections are available
204
- display_result.display_result({
205
- "sections": state["sections"],
206
- "messages": state["messages"]
207
- }, usecase)
208
- else:
209
- display_result.display_result(state, usecase)
210
- session_history.add_ai_message(state["messages"][-1].content)
211
- graph_state = graph.get_state(config)
212
- logger.info(f"Graph state after event: {graph_state}")
213
- if graph_state.next and graph_state.next[0] in ["outline_review", "draft_review"]:
214
- st.session_state.waiting_for_feedback = True
215
- st.session_state.graph_state = graph_state
216
- logger.info(f"Graph paused at: {graph_state.next}")
217
- break
218
- elif not graph_state.next:
219
- logger.info("Blog generation completed")
220
- st.session_state.blog_requirements_collected = False
221
- with st.chat_message("assistant"):
222
- st.markdown("✅ Blog generation completed!")
223
- if st.button("New Blog Generation", key="new_blog_button"):
224
- logger.info("Starting new blog generation")
225
- session_history.clear()
226
- st.session_state.graph_state = None
227
- st.session_state.waiting_for_feedback = False
228
- st.session_state.outline_feedback = None
229
- st.session_state.draft_feedback = None
230
- st.rerun()
231
- break
232
-
233
- elif not st.session_state.blog_requirements_collected:
234
- st.markdown("### Blog Requirements")
235
- with st.form("blog_requirements_form"):
236
- topic = st.text_input("Topic", placeholder="e.g., The Future of AI in Healthcare")
237
- objective = st.radio("Objective", ["Informative", "Persuasive", "Storytelling", "Other"])
238
- if objective == "Other":
239
- objective = st.text_input("Specify Objective", placeholder="Enter custom objective")
240
- target_audience = st.radio("Target Audience", ["Beginners", "Experts", "General Audience", "Other"])
241
- if target_audience == "Other":
242
- target_audience = st.text_input("Specify Target Audience", placeholder="Enter custom audience")
243
- tone_style = st.radio("Tone & Style", ["Formal", "Casual", "Technical", "Engaging", "Other"])
244
- if tone_style == "Other":
245
- tone_style = st.text_input("Specify Tone & Style", placeholder="Enter custom tone and style")
246
- word_count = st.number_input("Word Count", min_value=100, max_value=5000, value=1000, step=100)
247
- structure = st.text_area("Structure", placeholder="e.g., Introduction, Key Points, Conclusion")
248
- submit_button = st.form_submit_button("Submit Blog Requirements")
249
-
250
- if submit_button:
251
- if not topic or not objective or not target_audience or not tone_style or not structure:
252
- st.error("Please fill in all required fields.")
253
- return
254
-
255
- # Format user input as a single line
256
- user_message = f"Topic: {topic} Objective: {objective} Target Audience: {target_audience} Tone & Style: {tone_style} Word Count: {word_count} Structure: {structure}"
257
-
258
- logger.info(f"Blog requirements submitted: {user_message}")
259
- session_history.add_user_message(user_message)
260
- with st.chat_message("user"):
261
- st.markdown(user_message)
262
- st.session_state.blog_requirements_collected = True
263
 
264
- with st.spinner("Generating outline..."):
265
- input_data = {"messages": [HumanMessage(content=user_message)]}
266
- graph = st.session_state.graph
267
- if not graph:
268
- logger.error("Graph not initialized before streaming initial input")
269
- st.error("Error: Workflow graph not initialized.")
270
- return
271
- for event in graph.stream(input_data, config=config):
272
- logger.info(f"Graph event: {event}")
273
- for node, state in event.items():
274
- if "messages" in state and state["messages"]:
275
- with st.chat_message("assistant"):
276
- display_result.display_result(state, usecase)
277
- session_history.add_ai_message(state["messages"][-1].content)
278
- graph_state = graph.get_state(config)
279
- if graph_state.next and graph_state.next[0] in ["outline_review", "draft_review"]:
280
- st.session_state.waiting_for_feedback = True
281
- st.session_state.graph_state = graph_state
282
- break
283
- st.rerun()
284
-
285
- # Initialize session state for draft display tracking
286
- if "draft_displayed" not in st.session_state:
287
- st.session_state.draft_displayed = False
288
-
289
- else:
290
- user_message = st.chat_input("Enter your message:")
291
- if user_message:
292
- try:
293
- logger.info(f"User message: {user_message}")
294
- session_history.add_user_message(user_message)
295
- with st.chat_message("user"):
296
- st.markdown(user_message, unsafe_allow_html=True)
297
-
298
- with st.spinner("Processing..."):
299
- input_data = {"messages": [HumanMessage(content=user_message)]}
300
- logger.info(f"Streaming graph with input: {input_data}")
301
- for event in st.session_state.with_message_history.stream(input_data, config=config):
302
- logger.info(f"Graph event: {event}")
303
- for node, state in event.items():
304
- if "messages" in state and state["messages"]:
305
- with st.chat_message("assistant"):
306
- display_result.display_result(state, usecase)
307
- session_history.add_ai_message(state["messages"][-1].content)
308
- graph_state = st.session_state.graph.get_state(config)
309
- logger.info(f"Graph state after event: {graph_state}")
310
- if not graph_state.next:
311
- logger.info("Graph completed execution")
312
- break
313
- except Exception as e:
314
- logger.error(f"Error occurred: {e}")
315
- st.error(f"Error occurred: {e}")
316
 
317
  if __name__ == "__main__":
318
  load_langgraph_agenticai_app()
 
 
1
  import streamlit as st
2
  import uuid
3
  import logging
4
  import os
5
+ from langchain_core.messages import HumanMessage
6
  from langchain_community.chat_message_histories import ChatMessageHistory
7
  from langchain_core.chat_history import BaseChatMessageHistory
8
  from langchain_core.runnables.history import RunnableWithMessageHistory
9
  from src.langgraphagenticai.ui.streamlitui.loadui import LoadStreamlitUI
 
10
  from src.langgraphagenticai.LLMS.groqllm import GroqLLM
11
  from src.langgraphagenticai.LLMS.geminillm import GoogleLLM
12
  from src.langgraphagenticai.LLMS.chatgptllm import OpenaiLLM
13
  from src.langgraphagenticai.graph.graph_builder import GraphBuilder
14
+ from src.langgraphagenticai.ui.streamlitui.display_result import DisplayResultStreamlit
15
 
16
  logging.basicConfig(level=logging.INFO)
17
  logger = logging.getLogger(__name__)
 
24
  return store[session_id]
25
 
26
  def load_langgraph_agenticai_app():
27
+ """
28
+ Loads and runs the LangGraph AgenticAI application with Streamlit UI.
29
+ Initializes UI, configures LLM, sets up graph, and manages session state.
30
+ """
31
  ui = LoadStreamlitUI()
32
  user_controls = ui.load_streamlit_ui()
 
33
 
34
  if not user_controls:
35
  st.error("Error: Failed to load user controls from the UI.")
 
57
  st.warning("Please enter your OpenAI API key in the sidebar.")
58
  return
59
 
60
+ # Session state initialization
61
  if "session_id" not in st.session_state:
62
  st.session_state.session_id = str(uuid.uuid4())
63
  if "thread_id" not in st.session_state:
 
70
  st.session_state.blog_requirements_collected = False
71
  if "current_usecase" not in st.session_state:
72
  st.session_state.current_usecase = None
 
 
 
 
 
 
 
 
73
 
74
  config = {"configurable": {"session_id": st.session_state.session_id, "thread_id": st.session_state.thread_id, "recursion_limit": 50}}
75
  logger.info(f"Session ID: {st.session_state.session_id}, Thread ID: {st.session_state.thread_id}")
76
 
77
+ # Load LLM
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  try:
79
  if selected_llm == "Groq":
80
  llm_config = GroqLLM(user_controls_input=user_controls)
 
91
  st.error("Error: LLM model could not be initialized.")
92
  return
93
 
94
+ # Graph setup
95
+ usecase = user_controls.get("selected_usecase")
96
+ if not usecase:
97
+ st.error("Error: No use case selected.")
98
+ return
99
+
100
+ if st.session_state.current_usecase != usecase:
101
+ logger.info(f"Use case changed to: {usecase}. Resetting session state.")
102
+ st.session_state.waiting_for_feedback = False
103
+ st.session_state.blog_requirements_collected = False
104
+ st.session_state.current_usecase = usecase
105
+ get_session_history(st.session_state.session_id).clear()
106
+ if "graph" in st.session_state:
107
+ del st.session_state.graph
108
+ if "with_message_history" in st.session_state:
109
+ del st.session_state.with_message_history
110
+
111
  if "graph" not in st.session_state:
112
  graph_builder = GraphBuilder(model)
113
  graph = graph_builder.setup_graph(usecase)
 
119
  )
120
  st.session_state.graph = graph
121
  st.session_state.with_message_history = with_message_history
 
 
122
 
123
+ # Display chat history and process input
124
+ display = DisplayResultStreamlit(st.session_state.graph, st.session_state.with_message_history, config, usecase)
125
+ display.display_chat_history()
126
+ display.process_user_input()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ except Exception as e:
129
+ logger.error(f"Error initializing application: {e}")
130
+ st.error(f"Failed to initialize application: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  if __name__ == "__main__":
133
  load_langgraph_agenticai_app()
src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc CHANGED
Binary files a/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc and b/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc differ
 
src/langgraphagenticai/ui/streamlitui/display_result.py CHANGED
@@ -1,101 +1,183 @@
1
  import streamlit as st
 
2
 
3
  class DisplayResultStreamlit:
4
- def display_result(self, response: dict, usecase: str) -> str:
5
- if usecase == "Blog Generation":
6
- # Always prioritize direct sections display
7
- if "sections" in response:
8
- sections = response.get("sections", [])
9
- if sections and not st.session_state.get("outline_displayed", False):
10
- outline_text = "### Generated Outline\n\n"
11
- for section in sections:
12
- outline_text += f"**{section['name']}**: {section['description']}\n\n"
13
- st.markdown(outline_text)
14
- st.markdown("Please review the outline above.")
15
- st.session_state.outline_displayed = True
16
- return outline_text
17
-
18
- # Process message-based content
19
- messages = response.get("messages", [])
20
- if not messages:
21
- return "No response generated."
22
-
23
- assistant_response = messages[-1].content if messages else "No response generated."
24
-
25
- # Check for draft content with improved formatting
26
- if "# Generated Blog Draft" in assistant_response and not st.session_state.get("draft_displayed", False):
27
- formatted_content = self._format_blog_content(assistant_response)
28
- st.markdown(formatted_content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  st.session_state.draft_displayed = True
30
- # Check for final draft
31
- elif "Final approved draft:" in assistant_response:
32
- st.markdown("### Final Draft")
33
- final_content = assistant_response.split("Final approved draft:", 1)[1]
34
- formatted_final = self._format_blog_content(final_content)
35
- st.markdown(formatted_final)
36
- # Display other messages without repetition
37
- elif not any(x in assistant_response for x in ["Generated outline:", "# Generated Blog Draft", "Final approved draft:"]):
38
- st.markdown(assistant_response)
39
-
40
- return assistant_response
41
-
42
- elif usecase == "Basic Chatbot":
43
- assistant_response = response.get("messages", [{}])[-1].content if response.get("messages") else "No response generated."
44
- st.markdown(assistant_response)
45
- return assistant_response
46
-
47
- elif usecase == "Chatbot with Tool":
48
- if "messages" in response:
49
- assistant_response = response.get("messages", [{}])[-1].content
50
- tool_output = response.get("tool_output", "")
51
- if tool_output:
52
- st.markdown("**Tool Output:**")
53
- st.code(tool_output, language="text")
54
- st.markdown(assistant_response)
55
- return assistant_response
56
- return "No response generated."
57
-
58
- elif usecase == "Coding Peer Review":
59
- review_output = response.get("review_output", "No review generated.")
60
- corrected_code = response.get("corrected_code", "")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  st.markdown("### Code Review Feedback")
62
- st.markdown(review_output)
63
- if corrected_code:
64
  st.markdown("### Corrected Code")
65
  st.code(corrected_code, language="python")
66
- return review_output
67
 
68
- else:
69
- st.error(f"Unknown use case: {usecase}")
70
- return ""
71
-
72
- def _format_blog_content(self, content: str) -> str:
73
- """Format blog content with consistent styling and spacing."""
74
- # Split content into sections
75
- sections = content.split("\n\n")
76
- formatted_sections = []
77
-
78
- for section in sections:
79
- section = section.strip()
80
- if not section:
81
- continue
82
-
83
- # Format headings
84
- if section.startswith("#"):
85
- # Ensure proper heading format with spacing
86
- if not section.startswith("# ") and not section.startswith("## "):
87
- section = f"## {section.lstrip('#').strip()}"
88
- formatted_sections.append(f"\n{section}\n")
89
- else:
90
- # Regular paragraph
91
- formatted_sections.append(section)
92
-
93
- # Join sections with proper spacing
94
- formatted_content = "\n\n".join(formatted_sections)
95
-
96
- # Ensure proper spacing around headings
97
- formatted_content = formatted_content.replace("\n###", "\n\n###")
98
- formatted_content = formatted_content.replace("\n##", "\n\n##")
99
- formatted_content = formatted_content.replace("\n#", "\n\n#")
100
-
101
- return formatted_content
 
1
  import streamlit as st
2
+ from langchain_core.messages import HumanMessage, AIMessage
3
 
4
  class DisplayResultStreamlit:
5
+ def __init__(self, graph, with_message_history, config, usecase):
6
+ self.graph = graph
7
+ self.with_message_history = with_message_history
8
+ self.config = config
9
+ self.usecase = usecase
10
+ self.session_history = self._get_session_history()
11
+
12
+ def _get_session_history(self):
13
+ from langchain_community.chat_message_histories import ChatMessageHistory
14
+ store = {}
15
+ session_id = self.config["configurable"]["session_id"]
16
+ if session_id not in store:
17
+ store[session_id] = ChatMessageHistory()
18
+ return store[session_id]
19
+
20
+ def display_chat_history(self):
21
+ """Display the chat history from the session."""
22
+ for message in self.session_history.messages:
23
+ role = "user" if isinstance(message, HumanMessage) else "assistant"
24
+ with st.chat_message(role):
25
+ st.markdown(message.content, unsafe_allow_html=True)
26
+
27
+ def process_user_input(self):
28
+ """Process user input and display results based on the use case."""
29
+ if self.usecase == "Blog Generation":
30
+ self._handle_blog_generation()
31
+ else:
32
+ self._handle_chatbot_input()
33
+
34
+ def _handle_blog_generation(self):
35
+ if st.session_state.waiting_for_feedback:
36
+ self._process_feedback()
37
+ elif not st.session_state.blog_requirements_collected:
38
+ self._collect_blog_requirements()
39
+ else:
40
+ self._process_graph_stream()
41
+
42
+ def _collect_blog_requirements(self):
43
+ st.markdown("### Blog Requirements")
44
+ with st.form("blog_requirements_form"):
45
+ topic = st.text_input("Topic", placeholder="e.g., The Future of AI in Healthcare")
46
+ objective = st.radio("Objective", ["Informative", "Persuasive", "Storytelling", "Other"])
47
+ if objective == "Other":
48
+ objective = st.text_input("Specify Objective", placeholder="Enter custom objective")
49
+ target_audience = st.radio("Target Audience", ["Beginners", "Experts", "General Audience", "Other"])
50
+ if target_audience == "Other":
51
+ target_audience = st.text_input("Specify Target Audience", placeholder="Enter custom audience")
52
+ tone_style = st.radio("Tone & Style", ["Formal", "Casual", "Technical", "Engaging", "Other"])
53
+ if tone_style == "Other":
54
+ tone_style = st.text_input("Specify Tone & Style", placeholder="Enter custom tone and style")
55
+ word_count = st.number_input("Word Count", min_value=100, max_value=5000, value=1000, step=100)
56
+ structure = st.text_area("Structure", placeholder="e.g., Introduction, Key Points, Conclusion")
57
+ submit_button = st.form_submit_button("Submit Blog Requirements")
58
+
59
+ if submit_button:
60
+ if not all([topic, objective, target_audience, tone_style, structure]):
61
+ st.error("Please fill in all required fields.")
62
+ return
63
+ user_message = f"Topic: {topic} Objective: {objective} Target Audience: {target_audience} Tone & Style: {tone_style} Word Count: {word_count} Structure: {structure}"
64
+ self.session_history.add_user_message(user_message)
65
+ with st.chat_message("user"):
66
+ st.markdown(user_message)
67
+ st.session_state.blog_requirements_collected = True
68
+ self._process_graph_stream(HumanMessage(content=user_message))
69
+
70
+ def _process_feedback(self):
71
+ latest_state = st.session_state.graph_state.values if st.session_state.graph_state else {}
72
+ if "completed_sections" in latest_state and not st.session_state.get("draft_displayed", False):
73
+ with st.chat_message("assistant"):
74
+ draft_content = "\n\n".join(latest_state["completed_sections"])
75
+ st.markdown("### Generated Draft")
76
+ st.markdown(draft_content)
77
  st.session_state.draft_displayed = True
78
+
79
+ current_node = st.session_state.graph_state.next[0] if st.session_state.graph_state.next else None
80
+ if current_node == "outline_review":
81
+ st.write("Review the outline:")
82
+ col1, col2 = st.columns(2)
83
+ with col1:
84
+ if st.button("Looks good", key="outline_approve"):
85
+ st.session_state.outline_feedback = "approved"
86
+ st.session_state.waiting_for_feedback = False
87
+ with col2:
88
+ if st.button("Add more details", key="outline_reject"):
89
+ st.session_state.outline_feedback = "add_more_details"
90
+ st.session_state.waiting_for_feedback = False
91
+ elif current_node == "draft_review":
92
+ st.write("Review the draft:")
93
+ col1, col2 = st.columns(2)
94
+ with col1:
95
+ if st.button("Looks good", key="draft_approve"):
96
+ st.session_state.draft_feedback = "approved"
97
+ st.session_state.waiting_for_feedback = False
98
+ st.session_state.draft_displayed = False
99
+ with col2:
100
+ if st.button("Add more details", key="draft_reject"):
101
+ st.session_state.draft_feedback = "add_more_details"
102
+ st.session_state.waiting_for_feedback = False
103
+ st.session_state.draft_displayed = False
104
+
105
+ if not st.session_state.waiting_for_feedback:
106
+ self._process_graph_stream()
107
+
108
+ def _handle_chatbot_input(self):
109
+ user_message = st.chat_input("Enter your message:")
110
+ if user_message:
111
+ self.session_history.add_user_message(user_message)
112
+ with st.chat_message("user"):
113
+ st.markdown(user_message, unsafe_allow_html=True)
114
+ self._process_graph_stream(HumanMessage(content=user_message))
115
+
116
+ def _process_graph_stream(self, input_message=None):
117
+ with st.spinner("Processing..."):
118
+ input_data = {"messages": [input_message]} if input_message else None
119
+ for event in (self.graph.stream(input_data, self.config) if input_data else self.graph.stream(None, self.config)):
120
+ for node, state in event.items():
121
+ if "messages" in state and state["messages"]:
122
+ with st.chat_message("assistant"):
123
+ self._display_result(state)
124
+ self.session_history.add_ai_message(state["messages"][-1].content)
125
+ graph_state = self.graph.get_state(self.config)
126
+ if graph_state.next and graph_state.next[0] in ["outline_review", "draft_review"]:
127
+ st.session_state.waiting_for_feedback = True
128
+ st.session_state.graph_state = graph_state
129
+ break
130
+ elif not graph_state.next and self.usecase == "Blog Generation":
131
+ st.session_state.blog_requirements_collected = False
132
+ with st.chat_message("assistant"):
133
+ st.markdown("✅ Blog generation completed!")
134
+ if st.button("New Blog Generation"):
135
+ self.session_history.clear()
136
+ st.session_state.graph_state = None
137
+ st.session_state.waiting_for_feedback = False
138
+ st.rerun()
139
+
140
+ def _display_result(self, response):
141
+ if self.usecase == "Blog Generation":
142
+ if "sections" in response and not st.session_state.get("outline_displayed", False):
143
+ outline_text = "### Generated Outline\n\n" + "\n\n".join(f"**{s['name']}**: {s['description']}" for s in response["sections"])
144
+ st.markdown(outline_text)
145
+ st.markdown("Please review the outline above.")
146
+ st.session_state.outline_displayed = True
147
+ messages = response.get("messages", [])
148
+ if messages:
149
+ content = messages[-1].content
150
+ if "# Generated Blog Draft" in content and not st.session_state.get("draft_displayed", False):
151
+ st.markdown(self._format_blog_content(content))
152
+ st.session_state.draft_displayed = True
153
+ elif "Final approved draft:" in content:
154
+ st.markdown("### Final Draft")
155
+ st.markdown(self._format_blog_content(content.split("Final approved draft:", 1)[1]))
156
+ elif not any(x in content for x in ["Generated outline:", "# Generated Blog Draft", "Final approved draft:"]):
157
+ st.markdown(content)
158
+
159
+ elif self.usecase == "Basic Chatbot":
160
+ st.markdown(response.get("messages", [{}])[-1].content)
161
+
162
+ elif self.usecase == "Chatbot with Tool":
163
+ content = response.get("messages", [{}])[-1].content
164
+ tool_output = response.get("tool_output", "")
165
+ if tool_output:
166
+ st.markdown("**Tool Output:**")
167
+ st.code(tool_output, language="text")
168
+ st.markdown(content)
169
+
170
+ elif self.usecase == "Coding Peer Review":
171
  st.markdown("### Code Review Feedback")
172
+ st.markdown(response.get("review_output", "No review generated."))
173
+ if corrected_code := response.get("corrected_code", ""):
174
  st.markdown("### Corrected Code")
175
  st.code(corrected_code, language="python")
 
176
 
177
+ def _format_blog_content(self, content):
178
+ sections = content.strip().split("\n\n")
179
+ formatted = "\n\n".join(
180
+ f"\n\n{s.strip()}" if s.startswith("#") else s.strip()
181
+ for s in sections if s.strip()
182
+ )
183
+ return formatted.replace("\n###", "\n\n###").replace("\n##", "\n\n##").replace("\n#", "\n\n#")