JulsdL commited on
Commit
7b47aa3
·
1 Parent(s): 9f2166e

Refactor chainlit_frontend.py to streamline message processing and integrate new agent states

Browse files

- Reduce recursion limit in tutor_chain.stream to improve performance
- Simplify message processing logic by removing conditional checks for end state and directly processing agent states
- Implement direct handling for QAAgent, QuizAgent, and FlashcardsAgent with specific actions for each agent type
- Update flashcards creation flow to use a dynamic path stored in agent state, enhancing flexibility
- Replace langchain.pydantic_v1 import with pydantic in tools.py for BaseModel and Field, aligning with updated dependencies
- Add explicit directory creation for flashcard files to ensure path validity
- Introduce debug prints across chainlit_frontend.py, tools.py, and graph.py for better traceability of the processing flow
- Adjust states.py to replace flashcard_filename with flashcard_path, reflecting the new method of handling flashcard file paths

notebook_tutor/chainlit_frontend.py CHANGED
@@ -78,52 +78,43 @@ async def main(message: cl.Message):
78
  print("\033[93m" + f"Initial state: {state}" + "\033[0m")
79
 
80
  # Process the message through the LangGraph chain
81
- for s in tutor_chain.stream(state, {"recursion_limit": 10}):
82
  print("\033[93m" + f"State after processing: {s}" + "\033[0m")
83
 
84
- # Extract messages from the state
85
- if "__end__" not in s:
86
- agent_state = next(iter(s.values()))
87
- if "messages" in agent_state:
88
- response = agent_state["messages"][-1].content
89
- print("\033[93m" + f"Response: {response}" + "\033[0m")
90
- await cl.Message(content=response).send()
91
- else:
92
- print("Error: No messages found in agent state.")
93
- else:
94
- # Extract the final state
95
- final_state = next(iter(s.values()))
96
- print("\033[93m" + f"Final state: {final_state}" + "\033[0m")
97
-
98
- # Check if the quiz was created and send it to the frontend
99
- if final_state.get("quiz_created"):
100
- quiz_message = final_state["messages"][-1].content
101
- await cl.Message(content=quiz_message).send()
102
 
103
- # Check if a question was answered and send the response to the frontend
104
- if final_state.get("question_answered"):
105
- qa_message = final_state["messages"][-1].content
 
106
  await cl.Message(content=qa_message).send()
107
 
108
- # Check if flashcards are ready and send the file to the frontend
109
- if final_state.get("flashcards_created"):
110
- flashcards_message = final_state["messages"][-1].content
 
 
 
 
 
 
 
111
  await cl.Message(content=flashcards_message).send()
112
 
113
- # Create a relative path to the file
114
- flashcard_filename = final_state["flashcard_filename"]
115
- print("\033[93m" + f"Flashcard filename: {flashcard_filename}" + "\033[0m")
116
- flashcard_path = os.path.join(".files", flashcard_filename)
117
  print("\033[93m" + f"Flashcard path: {flashcard_path}" + "\033[0m")
118
 
 
119
  # Use the File class to send the file
120
- file_element = cl.File(name=os.path.basename(flashcard_path), path=flashcard_path)
121
  print("\033[93m" + f"Sending flashcards file: {file_element}" + "\033[0m")
122
  await cl.Message(
123
  content="Here are your flashcards:",
124
  elements=[file_element]
125
  ).send()
126
 
127
- print("\033[93m" + "Reached END state." + "\033[0m")
 
128
 
129
- break
 
78
  print("\033[93m" + f"Initial state: {state}" + "\033[0m")
79
 
80
  # Process the message through the LangGraph chain
81
+ for s in tutor_chain.stream(state, {"recursion_limit": 3}):
82
  print("\033[93m" + f"State after processing: {s}" + "\033[0m")
83
 
84
+ agent_state = next(iter(s.values()))
85
+ print("\033[93m" + f"Agent state: {agent_state}" + "\033[0m")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ if "QAAgent" in s:
88
+ if s['QAAgent']['question_answered']:
89
+ print("\033[93m" + "************************Question answered**********************." + "\033[0m")
90
+ qa_message = agent_state["messages"][-1].content
91
  await cl.Message(content=qa_message).send()
92
 
93
+ if "QuizAgent" in s:
94
+ if s['QuizAgent']['quiz_created']:
95
+ print("\033[93m" + "************************Quiz created**********************." + "\033[0m")
96
+ quiz_message = agent_state["messages"][-1].content
97
+ await cl.Message(content=quiz_message).send()
98
+
99
+ if "FlashcardsAgent" in s:
100
+ if s['FlashcardsAgent']['flashcards_created']:
101
+ print("\033[93m" + "************************Flashcards created**********************." + "\033[0m")
102
+ flashcards_message = agent_state["messages"][-1].content
103
  await cl.Message(content=flashcards_message).send()
104
 
105
+ flashcard_path = agent_state["flashcard_path"]
 
 
 
106
  print("\033[93m" + f"Flashcard path: {flashcard_path}" + "\033[0m")
107
 
108
+
109
  # Use the File class to send the file
110
+ file_element = cl.File(name="Flashcards", path=flashcard_path)
111
  print("\033[93m" + f"Sending flashcards file: {file_element}" + "\033[0m")
112
  await cl.Message(
113
  content="Here are your flashcards:",
114
  elements=[file_element]
115
  ).send()
116
 
117
+ final_state = s # Save the final state after processing
118
+ print("\033[93m" + f"Final state: {final_state}" + "\033[0m")
119
 
120
+ print("\033[93m" + "Reached END state." + "\033[0m")
notebook_tutor/graph.py CHANGED
@@ -69,6 +69,8 @@ def agent_node(state, agent, name):
69
  raise ValueError(f"No messages found in agent state: {result}")
70
  new_state = {"messages": state["messages"] + [AIMessage(content=result["output"], name=name)]}
71
 
 
 
72
  # Set the appropriate flags and next state
73
  if name == "QuizAgent":
74
  new_state["quiz_created"] = True
@@ -76,7 +78,8 @@ def agent_node(state, agent, name):
76
  new_state["question_answered"] = True
77
  elif name == "FlashcardsAgent":
78
  new_state["flashcards_created"] = True
79
- new_state["flashcard_filename"] = result["output"].split('(')[-1].strip(')')
 
80
 
81
  new_state["next"] = "FINISH"
82
  return new_state
 
69
  raise ValueError(f"No messages found in agent state: {result}")
70
  new_state = {"messages": state["messages"] + [AIMessage(content=result["output"], name=name)]}
71
 
72
+ print("\033[93m" + f"agent_node function state {state}" + "\033[0m")
73
+
74
  # Set the appropriate flags and next state
75
  if name == "QuizAgent":
76
  new_state["quiz_created"] = True
 
78
  new_state["question_answered"] = True
79
  elif name == "FlashcardsAgent":
80
  new_state["flashcards_created"] = True
81
+ print("\033[93m" + f"agent_node function result_output {result}" + "\033[0m")
82
+ # new_state["flashcard_path"] = result["output"]
83
 
84
  new_state["next"] = "FINISH"
85
  return new_state
notebook_tutor/states.py CHANGED
@@ -9,4 +9,4 @@ class TutorState(TypedDict):
9
  quiz_created: bool
10
  question_answered: bool
11
  flashcards_created: bool
12
- flashcard_filename: str
 
9
  quiz_created: bool
10
  question_answered: bool
11
  flashcards_created: bool
12
+ flashcard_path: str
notebook_tutor/tools.py CHANGED
@@ -1,5 +1,5 @@
1
  from typing import Optional, Type
2
- from langchain.pydantic_v1 import BaseModel, Field
3
  from langchain.tools import BaseTool
4
  from langchain.callbacks.manager import (
5
  AsyncCallbackManagerForToolRun,
@@ -23,7 +23,9 @@ class FlashcardTool(BaseTool):
23
  """Use the tool to create flashcards."""
24
  filename = f"flashcards_{uuid.uuid4()}.csv"
25
  save_path = os.path.join('.files', filename)
26
- # os.makedirs(os.path.dirname(save_path), exist_ok=True) # Create directory if it doesn't exist
 
 
27
  with open(save_path, 'w', newline='') as csvfile:
28
  fieldnames = ['Front', 'Back']
29
  writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
 
1
  from typing import Optional, Type
2
+ from pydantic import BaseModel, Field
3
  from langchain.tools import BaseTool
4
  from langchain.callbacks.manager import (
5
  AsyncCallbackManagerForToolRun,
 
23
  """Use the tool to create flashcards."""
24
  filename = f"flashcards_{uuid.uuid4()}.csv"
25
  save_path = os.path.join('.files', filename)
26
+ print("\033[91m" + f"Saving flashcards to {save_path}" + "\033[0m")
27
+
28
+ os.makedirs(os.path.dirname(save_path), exist_ok=True) # Create directory if it doesn't exist
29
  with open(save_path, 'w', newline='') as csvfile:
30
  fieldnames = ['Front', 'Back']
31
  writer = csv.DictWriter(csvfile, fieldnames=fieldnames)