Spaces:
Build error
Build error
kamaleswar Mohanta commited on
Commit ·
60f7bfc
1
Parent(s): c9f4fb2
sync
Browse files- src/langgraphagenticai/graph/__pycache__/graph_builder_blog.cpython-312.pyc +0 -0
- src/langgraphagenticai/nodes/__pycache__/blog_generation_node.cpython-312.pyc +0 -0
- src/langgraphagenticai/nodes/blog_generation_node.py +12 -9
- src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-312.pyc +0 -0
- src/langgraphagenticai/ui/streamlitui/__pycache__/display_result_blog.cpython-312.pyc +0 -0
- src/langgraphagenticai/ui/streamlitui/display_result.py +25 -3
- src/langgraphagenticai/ui/streamlitui/display_result_blog.py +74 -53
src/langgraphagenticai/graph/__pycache__/graph_builder_blog.cpython-312.pyc
CHANGED
|
Binary files a/src/langgraphagenticai/graph/__pycache__/graph_builder_blog.cpython-312.pyc and b/src/langgraphagenticai/graph/__pycache__/graph_builder_blog.cpython-312.pyc differ
|
|
|
src/langgraphagenticai/nodes/__pycache__/blog_generation_node.cpython-312.pyc
CHANGED
|
Binary files a/src/langgraphagenticai/nodes/__pycache__/blog_generation_node.cpython-312.pyc and b/src/langgraphagenticai/nodes/__pycache__/blog_generation_node.cpython-312.pyc differ
|
|
|
src/langgraphagenticai/nodes/blog_generation_node.py
CHANGED
|
@@ -172,8 +172,10 @@ class BlogGenerationNode:
|
|
| 172 |
return {"initial_draft": initial_draft}
|
| 173 |
|
| 174 |
def feedback_collector(self, state: State) -> dict:
|
| 175 |
-
logger.info(f"\n\n----------------:Entered
|
| 176 |
-
|
|
|
|
|
|
|
| 177 |
if state.get("messages") and len(state["messages"]) > 0 and isinstance(state["messages"][-1], HumanMessage):
|
| 178 |
try:
|
| 179 |
feedback_data = json.loads(state["messages"][-1].content)
|
|
@@ -220,11 +222,12 @@ class BlogGenerationNode:
|
|
| 220 |
# Conditional edge for feedback loop
|
| 221 |
def route_feedback(self, state: State):
|
| 222 |
"""Route based on whether draft is approved."""
|
| 223 |
-
|
| 224 |
-
logger.info(f"route_feedback:
|
| 225 |
-
|
|
|
|
| 226 |
logger.info("Draft approved; routing to file_generator")
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
|
|
|
| 172 |
return {"initial_draft": initial_draft}
|
| 173 |
|
| 174 |
def feedback_collector(self, state: State) -> dict:
|
| 175 |
+
logger.info(f"\n\n----------------:Entered feedback_collector with state:----------------------\n\n{state}")
|
| 176 |
+
logger.info(f"Message count: {len(state.get('messages', []))}")
|
| 177 |
+
logger.info(f"Last message type: {type(state['messages'][-1]) if state.get('messages') else 'None'}")
|
| 178 |
+
|
| 179 |
if state.get("messages") and len(state["messages"]) > 0 and isinstance(state["messages"][-1], HumanMessage):
|
| 180 |
try:
|
| 181 |
feedback_data = json.loads(state["messages"][-1].content)
|
|
|
|
| 222 |
# Conditional edge for feedback loop
|
| 223 |
def route_feedback(self, state: State):
|
| 224 |
"""Route based on whether draft is approved."""
|
| 225 |
+
draft_approved = state.get('draft_approved', False)
|
| 226 |
+
logger.info(f"route_feedback: draft_approved = {draft_approved}")
|
| 227 |
+
|
| 228 |
+
if draft_approved is True: # Strict comparison
|
| 229 |
logger.info("Draft approved; routing to file_generator")
|
| 230 |
+
return "file_generator"
|
| 231 |
+
else:
|
| 232 |
+
logger.info("Draft not approved; routing back to orchestrator for revision")
|
| 233 |
+
return "orchestrator"
|
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/__pycache__/display_result_blog.cpython-312.pyc
CHANGED
|
Binary files a/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result_blog.cpython-312.pyc and b/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result_blog.cpython-312.pyc differ
|
|
|
src/langgraphagenticai/ui/streamlitui/display_result.py
CHANGED
|
@@ -130,13 +130,35 @@ class DisplayResultStreamlit:
|
|
| 130 |
logger.info(f"\n{'*'*20}st.session_state[feedback] is {st.session_state["feedback"]}{'*'*20}\n")
|
| 131 |
st.rerun() # Trigger rerun to enter the processing_feedback stage
|
| 132 |
|
|
|
|
| 133 |
elif st.session_state.current_stage == "processing_feedback":
|
| 134 |
logger.info(f"\n\n{"="*20}: Entered main Display processing_feedback stage:{"="*20}\n\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
st.session_state.current_stage = "processing"
|
| 136 |
-
|
| 137 |
-
blog_display.process_graph_events(HumanMessage(content=json.dumps({"approved": False, "comments": st.session_state['feedback']})))
|
| 138 |
-
st.session_state['feedback_result'] = None # Clear the feedback result
|
| 139 |
st.rerun()
|
|
|
|
| 140 |
elif st.session_state.current_stage == "complete":
|
| 141 |
st.success("✅ Blog generation complete!")
|
| 142 |
if st.session_state.get("blog_content"):
|
|
|
|
| 130 |
logger.info(f"\n{'*'*20}st.session_state[feedback] is {st.session_state["feedback"]}{'*'*20}\n")
|
| 131 |
st.rerun() # Trigger rerun to enter the processing_feedback stage
|
| 132 |
|
| 133 |
+
# In DisplayResultStreamlit.process_user_input() for the "processing_feedback" stage
|
| 134 |
elif st.session_state.current_stage == "processing_feedback":
|
| 135 |
logger.info(f"\n\n{"="*20}: Entered main Display processing_feedback stage:{"="*20}\n\n")
|
| 136 |
+
|
| 137 |
+
# Create a proper feedback message
|
| 138 |
+
feedback_message = HumanMessage(content=json.dumps({
|
| 139 |
+
"approved": False,
|
| 140 |
+
"comments": st.session_state['feedback']
|
| 141 |
+
}))
|
| 142 |
+
|
| 143 |
+
# Resume the graph with the stored state and new feedback
|
| 144 |
+
logger.info(f"Resuming graph with feedback: {feedback_message.content}")
|
| 145 |
+
|
| 146 |
+
# Use the stored checkpoint state to resume the graph
|
| 147 |
+
checkpoint_state = st.session_state.get("graph_state")
|
| 148 |
+
if checkpoint_state:
|
| 149 |
+
input_data = {
|
| 150 |
+
"messages": [feedback_message],
|
| 151 |
+
"__checkpoint__": checkpoint_state # Pass the stored checkpoint
|
| 152 |
+
}
|
| 153 |
+
blog_display.process_graph_events_with_checkpoint(input_data)
|
| 154 |
+
else:
|
| 155 |
+
# Fall back to regular processing if no checkpoint available
|
| 156 |
+
blog_display.process_graph_events(feedback_message)
|
| 157 |
+
|
| 158 |
st.session_state.current_stage = "processing"
|
| 159 |
+
st.session_state['feedback_result'] = None # Clear the feedback result
|
|
|
|
|
|
|
| 160 |
st.rerun()
|
| 161 |
+
|
| 162 |
elif st.session_state.current_stage == "complete":
|
| 163 |
st.success("✅ Blog generation complete!")
|
| 164 |
if st.session_state.get("blog_content"):
|
src/langgraphagenticai/ui/streamlitui/display_result_blog.py
CHANGED
|
@@ -138,85 +138,106 @@ class DisplayBlogResult:
|
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
-
def process_feedback(self):
|
| 142 |
-
print("\n\n----blog_display process_feedback function entered----\n\n")
|
| 143 |
-
logger.info("---blog_display process_feedback function entered ----\n\n")
|
| 144 |
-
st.write("Session State in process_feedback:", st.session_state)
|
| 145 |
-
st.markdown("## Stage 3: Feedback")
|
| 146 |
-
if st.session_state.get("generated_draft"):
|
| 147 |
-
st.markdown("### Drafted Blog Content:")
|
| 148 |
-
st.markdown(st.session_state["generated_draft"])
|
| 149 |
-
with st.expander("Stage 3: Feedback", expanded=True):
|
| 150 |
-
feedback_text = st.text_input(
|
| 151 |
-
"Revision comments:",
|
| 152 |
-
placeholder="Please explain what changes you would like to see.",
|
| 153 |
-
key="revision_comments_area",
|
| 154 |
-
value=st.session_state.get("revision_comments_area", "Add some reference to it ")
|
| 155 |
-
)
|
| 156 |
-
st.session_state["feedback"] = feedback_text # Update session state for graph processing
|
| 157 |
-
|
| 158 |
-
col1, col2 = st.columns(2)
|
| 159 |
-
with col1:
|
| 160 |
-
st.button("✅ Approve Content", on_click=self._handle_approved_click, key="blog_feedback_approve_button")
|
| 161 |
-
with col2:
|
| 162 |
-
st.button("Submit Revision Request", on_click=self._handle_revised_click, key="blog_feedback_revise_button")
|
| 163 |
-
return st.session_state.get('feedback_result')
|
| 164 |
-
|
| 165 |
-
|
| 166 |
def process_graph_events(self, input_message=None):
|
| 167 |
try:
|
| 168 |
-
|
| 169 |
input_data = {"messages": [input_message]} if input_message else None
|
| 170 |
progress_bar = st.progress(0)
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
for i, event in enumerate(self.graph.stream(input_data, self.config)):
|
| 173 |
logger.info(f"Graph event received: #{i+1}")
|
| 174 |
-
|
| 175 |
# Update progress indicator
|
| 176 |
-
progress_value = min(i * 0.1, 0.9)
|
| 177 |
progress_bar.progress(progress_value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
|
| 179 |
# Process event data
|
| 180 |
for node, state in event.items():
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
# Specifically handle interrupt events
|
| 184 |
if node == "__interrupt__":
|
| 185 |
logger.info("Interrupt event received - transitioning to feedback stage")
|
| 186 |
st.session_state.waiting_for_feedback = True
|
| 187 |
-
logger.info("Waiting for feedback from user.")
|
| 188 |
st.session_state.current_stage = "feedback"
|
| 189 |
-
logger.info("Feedback stage initiated.")
|
| 190 |
st.rerun()
|
| 191 |
-
progress_bar.progress(1.0)
|
| 192 |
return
|
| 193 |
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
|
|
|
|
|
|
| 203 |
|
| 204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
if node == "file_generator":
|
| 206 |
logger.info("File generator node finished, setting stage to complete.")
|
| 207 |
st.session_state.blog_generation_complete = True
|
| 208 |
st.session_state.current_stage = "complete"
|
| 209 |
st.session_state.processing_complete = True
|
| 210 |
-
break
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
# Ensure progress completes
|
| 215 |
progress_bar.progress(1.0)
|
| 216 |
-
|
| 217 |
except Exception as e:
|
| 218 |
st.error(f"⚠️ Error processing workflow: {e}")
|
| 219 |
logger.exception(f"Error in graph streaming: {e}")
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
|
| 139 |
|
| 140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
def process_graph_events(self, input_message=None):
|
| 142 |
try:
|
|
|
|
| 143 |
input_data = {"messages": [input_message]} if input_message else None
|
| 144 |
progress_bar = st.progress(0)
|
| 145 |
+
|
| 146 |
+
# Store the graph state for resuming later
|
| 147 |
+
checkpoint_state = None
|
| 148 |
|
| 149 |
for i, event in enumerate(self.graph.stream(input_data, self.config)):
|
| 150 |
logger.info(f"Graph event received: #{i+1}")
|
| 151 |
+
|
| 152 |
# Update progress indicator
|
| 153 |
+
progress_value = min(i * 0.1, 0.9)
|
| 154 |
progress_bar.progress(progress_value)
|
| 155 |
+
|
| 156 |
+
# Store the latest checkpoint state for resuming after interrupt
|
| 157 |
+
if "__checkpoint__" in event:
|
| 158 |
+
checkpoint_state = event["__checkpoint__"]
|
| 159 |
+
st.session_state.graph_state = checkpoint_state
|
| 160 |
+
logger.info(f"Checkpoint state stored: {checkpoint_state}")
|
| 161 |
|
| 162 |
# Process event data
|
| 163 |
for node, state in event.items():
|
| 164 |
+
# Handle interrupt after synthesizer
|
|
|
|
|
|
|
| 165 |
if node == "__interrupt__":
|
| 166 |
logger.info("Interrupt event received - transitioning to feedback stage")
|
| 167 |
st.session_state.waiting_for_feedback = True
|
|
|
|
| 168 |
st.session_state.current_stage = "feedback"
|
|
|
|
| 169 |
st.rerun()
|
|
|
|
| 170 |
return
|
| 171 |
|
| 172 |
+
# Process synthesizer output
|
| 173 |
+
if node == "synthesizer" and "initial_draft" in state:
|
| 174 |
+
logger.info("Draft generated by synthesizer, displaying content")
|
| 175 |
+
st.session_state.generated_draft = state["initial_draft"]
|
| 176 |
+
st.session_state.content_displayed = True
|
| 177 |
+
st.session_state.synthesizer_output_processed = True
|
| 178 |
+
|
| 179 |
+
progress_bar.progress(1.0)
|
| 180 |
+
except Exception as e:
|
| 181 |
+
st.error(f"⚠️ Error processing workflow: {e}")
|
| 182 |
+
logger.exception(f"Error in graph streaming: {e}")
|
| 183 |
|
| 184 |
+
def process_graph_events_with_checkpoint(self, input_data):
|
| 185 |
+
"""Process graph events with a checkpoint to resume from interrupt"""
|
| 186 |
+
try:
|
| 187 |
+
progress_bar = st.progress(0)
|
| 188 |
+
|
| 189 |
+
# We're resuming from a stored checkpoint
|
| 190 |
+
for i, event in enumerate(self.graph.stream(input_data, self.config)):
|
| 191 |
+
logger.info(f"Graph event received (resuming): #{i+1}")
|
| 192 |
+
|
| 193 |
+
# Update progress indicator
|
| 194 |
+
progress_value = min(i * 0.1, 0.9)
|
| 195 |
+
progress_bar.progress(progress_value)
|
| 196 |
+
|
| 197 |
+
# Store the latest checkpoint state for resuming after interrupt
|
| 198 |
+
if "__checkpoint__" in event:
|
| 199 |
+
st.session_state.graph_state = event["__checkpoint__"]
|
| 200 |
+
|
| 201 |
+
# Process event data (similar to process_graph_events)
|
| 202 |
+
for node, state in event.items():
|
| 203 |
+
if node == "feedback_collector":
|
| 204 |
+
logger.info(f"Feedback collector processing: {state}")
|
| 205 |
+
|
| 206 |
if node == "file_generator":
|
| 207 |
logger.info("File generator node finished, setting stage to complete.")
|
| 208 |
st.session_state.blog_generation_complete = True
|
| 209 |
st.session_state.current_stage = "complete"
|
| 210 |
st.session_state.processing_complete = True
|
| 211 |
+
break
|
| 212 |
+
|
|
|
|
|
|
|
|
|
|
| 213 |
progress_bar.progress(1.0)
|
|
|
|
| 214 |
except Exception as e:
|
| 215 |
st.error(f"⚠️ Error processing workflow: {e}")
|
| 216 |
logger.exception(f"Error in graph streaming: {e}")
|
| 217 |
+
|
| 218 |
+
def process_feedback(self):
|
| 219 |
+
"""Process user feedback on the generated blog draft."""
|
| 220 |
+
print("\n\n----blog_display process_feedback function entered----\n\n")
|
| 221 |
+
logger.info("---blog_display process_feedback function entered ----\n\n")
|
| 222 |
+
|
| 223 |
+
st.markdown("## Stage 3: Feedback")
|
| 224 |
+
if st.session_state.get("generated_draft"):
|
| 225 |
+
st.markdown("### Drafted Blog Content:")
|
| 226 |
+
st.markdown(st.session_state["generated_draft"])
|
| 227 |
+
|
| 228 |
+
with st.expander("Stage 3: Feedback", expanded=True):
|
| 229 |
+
feedback_text = st.text_input(
|
| 230 |
+
"Revision comments:",
|
| 231 |
+
placeholder="Please explain what changes you would like to see.",
|
| 232 |
+
key="revision_comments_area",
|
| 233 |
+
value=st.session_state.get("revision_comments_area", "Add some reference to it ")
|
| 234 |
+
)
|
| 235 |
+
st.session_state["feedback"] = feedback_text # Update session state for graph processing
|
| 236 |
+
|
| 237 |
+
col1, col2 = st.columns(2)
|
| 238 |
+
with col1:
|
| 239 |
+
st.button("✅ Approve Content", on_click=self._handle_approved_click, key="blog_feedback_approve_button")
|
| 240 |
+
with col2:
|
| 241 |
+
st.button("Submit Revision Request", on_click=self._handle_revised_click, key="blog_feedback_revise_button")
|
| 242 |
+
|
| 243 |
+
return st.session_state.get('feedback_result')
|