Humanlearning commited on
Commit
b1cd264
·
1 Parent(s): c91fcfb

added logs for debugging

Browse files
.gitignore CHANGED
@@ -1 +1,2 @@
1
- env*
 
 
1
+ env*
2
+ .env*
__pycache__/langraph_agent.cpython-313.pyc ADDED
Binary file (12.7 kB). View file
 
app.py CHANGED
@@ -55,7 +55,7 @@ async def generate_answers(profile: gr.OAuthProfile | None, progress=gr.Progress
55
  print(f"User logged in: {username}")
56
  else:
57
  print("User not logged in.")
58
- return "Please Login to Hugging Face with the button.", None, gr.update(interactive=False)
59
  api_url = DEFAULT_API_URL
60
  questions_url = f"{api_url}/questions"
61
  try:
@@ -64,11 +64,11 @@ async def generate_answers(profile: gr.OAuthProfile | None, progress=gr.Progress
64
  questions_data = response.json()
65
  if not questions_data:
66
  print("Fetched questions list is empty.")
67
- return "Fetched questions list is empty or invalid format.", None, gr.update(interactive=False)
68
  print(f"Fetched {len(questions_data)} questions.")
69
  except Exception as e:
70
  print(f"Error fetching questions: {e}")
71
- return f"Error fetching questions: {e}", None, gr.update(interactive=False)
72
  agent = BasicAgent()
73
  results_log = []
74
  answers_payload = []
@@ -102,7 +102,7 @@ async def generate_answers(profile: gr.OAuthProfile | None, progress=gr.Progress
102
  cached_results_log = results_log
103
  progress(100, desc="Done.")
104
  results_df = pd.DataFrame(results_log)
105
- return "Answer generation complete. Review and submit.", results_df, gr.update(interactive=True)
106
 
107
  def submit_answers(profile: gr.OAuthProfile | None):
108
  """
 
55
  print(f"User logged in: {username}")
56
  else:
57
  print("User not logged in.")
58
+ return "Please Login to Hugging Face with the button.", None, gr.update(interactive=False), gr.update(value=0, visible=False)
59
  api_url = DEFAULT_API_URL
60
  questions_url = f"{api_url}/questions"
61
  try:
 
64
  questions_data = response.json()
65
  if not questions_data:
66
  print("Fetched questions list is empty.")
67
+ return "Fetched questions list is empty or invalid format.", None, gr.update(interactive=False), gr.update(value=0, visible=False)
68
  print(f"Fetched {len(questions_data)} questions.")
69
  except Exception as e:
70
  print(f"Error fetching questions: {e}")
71
+ return f"Error fetching questions: {e}", None, gr.update(interactive=False), gr.update(value=0, visible=False)
72
  agent = BasicAgent()
73
  results_log = []
74
  answers_payload = []
 
102
  cached_results_log = results_log
103
  progress(100, desc="Done.")
104
  results_df = pd.DataFrame(results_log)
105
+ return "Answer generation complete. Review and submit.", results_df, gr.update(interactive=True), gr.update(value=100, visible=True)
106
 
107
  def submit_answers(profile: gr.OAuthProfile | None):
108
  """
debug_test.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ from langraph_agent import build_graph
3
+ from langchain_core.messages import HumanMessage
4
+
5
+ async def test_agent():
6
+ """Test the agent with a simple question"""
7
+ try:
8
+ print("Building graph...")
9
+ graph = build_graph(provider="groq")
10
+
11
+ print("Testing with a simple question...")
12
+ question = "What is 2 + 3?"
13
+ messages = [HumanMessage(content=question)]
14
+
15
+ print("Invoking agent...")
16
+ response = await graph.ainvoke({"messages": messages})
17
+
18
+ print(f"Response type: {type(response)}")
19
+ print(f"Response keys: {response.keys() if isinstance(response, dict) else 'Not a dict'}")
20
+
21
+ if 'messages' in response and response['messages']:
22
+ print(f"Number of messages: {len(response['messages'])}")
23
+ print(f"Last message content: {response['messages'][-1].content}")
24
+ return "SUCCESS"
25
+ else:
26
+ print("No messages in response or empty messages")
27
+ return "FAILED - No messages"
28
+ except Exception as e:
29
+ print(f"Error in test: {e}")
30
+ import traceback
31
+ traceback.print_exc()
32
+ return f"FAILED - {e}"
33
+
34
+ if __name__ == "__main__":
35
+ result = asyncio.run(test_agent())
36
+ print(f"Test result: {result}")
langraph_agent.py CHANGED
@@ -19,9 +19,18 @@ from supabase.client import Client, create_client
19
  from langfuse.langchain import CallbackHandler
20
 
21
  # Initialize Langfuse CallbackHandler for LangGraph/Langchain (tracing)
22
- langfuse_handler = CallbackHandler()
 
 
 
 
23
 
24
- load_dotenv()
 
 
 
 
 
25
 
26
  @tool
27
  def multiply(a: int, b: int) -> int:
@@ -81,13 +90,19 @@ def wiki_search(query: str) -> str:
81
 
82
  Args:
83
  query: The search query."""
84
- search_docs = WikipediaLoader(query=query, load_max_docs=2).load()
85
- formatted_search_docs = "\n\n---\n\n".join(
86
- [
87
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
88
- for doc in search_docs
89
- ])
90
- return {"wiki_results": formatted_search_docs}
 
 
 
 
 
 
91
 
92
  @tool
93
  def web_search(query: str) -> str:
@@ -95,13 +110,19 @@ def web_search(query: str) -> str:
95
 
96
  Args:
97
  query: The search query."""
98
- search_docs = TavilySearchResults(max_results=3).invoke(query=query)
99
- formatted_search_docs = "\n\n---\n\n".join(
100
- [
101
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
102
- for doc in search_docs
103
- ])
104
- return {"web_results": formatted_search_docs}
 
 
 
 
 
 
105
 
106
  @tool
107
  def arvix_search(query: str) -> str:
@@ -109,15 +130,19 @@ def arvix_search(query: str) -> str:
109
 
110
  Args:
111
  query: The search query."""
112
- search_docs = ArxivLoader(query=query, load_max_docs=3).load()
113
- formatted_search_docs = "\n\n---\n\n".join(
114
- [
115
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content[:1000]}\n</Document>'
116
- for doc in search_docs
117
- ])
118
- return {"arvix_results": formatted_search_docs}
119
-
120
-
 
 
 
 
121
 
122
  # load the system prompt from the file
123
  with open("system_prompt.txt", "r", encoding="utf-8") as f:
@@ -128,22 +153,33 @@ sys_msg = SystemMessage(content=system_prompt)
128
 
129
  # build a retriever
130
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") # dim=768
131
- supabase: Client = create_client(
132
- os.environ.get("SUPABASE_URL"),
133
- os.environ.get("SUPABASE_SERVICE_KEY"))
134
- vector_store = SupabaseVectorStore(
135
- client=supabase,
136
- embedding= embeddings,
137
- table_name="documents",
138
- query_name="match_documents_langchain",
139
- )
140
- create_retriever_tool = create_retriever_tool(
141
- retriever=vector_store.as_retriever(),
142
- name="Question Search",
143
- description="A tool to retrieve similar questions from a vector store.",
144
- )
145
-
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  tools = [
149
  multiply,
@@ -155,6 +191,8 @@ tools = [
155
  web_search,
156
  arvix_search,
157
  ]
 
 
158
 
159
  # Build graph function
160
  def build_graph(provider: str = "groq"):
@@ -182,15 +220,42 @@ def build_graph(provider: str = "groq"):
182
  # Node
183
  def assistant(state: MessagesState):
184
  """Assistant node"""
185
- return {"messages": [llm_with_tools.invoke(state["messages"])]}
 
 
 
 
 
 
 
 
 
186
 
187
  def retriever(state: MessagesState):
188
  """Retriever node"""
189
- similar_question = vector_store.similarity_search(state["messages"][0].content)
190
- example_msg = HumanMessage(
191
- content=f"Here I provide a similar question and answer for reference: \n\n{similar_question[0].page_content}",
192
- )
193
- return {"messages": [sys_msg] + state["messages"] + [example_msg]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
  builder = StateGraph(MessagesState)
196
  builder.add_node("retriever", retriever)
 
19
  from langfuse.langchain import CallbackHandler
20
 
21
  # Initialize Langfuse CallbackHandler for LangGraph/Langchain (tracing)
22
+ try:
23
+ langfuse_handler = CallbackHandler()
24
+ except Exception as e:
25
+ print(f"Warning: Could not initialize Langfuse handler: {e}")
26
+ langfuse_handler = None
27
 
28
+ # Load environment variables - try multiple files
29
+ load_dotenv() # Try .env first
30
+ load_dotenv("env.local") # Try env.local as backup
31
+
32
+ print(f"SUPABASE_URL loaded: {bool(os.environ.get('SUPABASE_URL'))}")
33
+ print(f"GROQ_API_KEY loaded: {bool(os.environ.get('GROQ_API_KEY'))}")
34
 
35
  @tool
36
  def multiply(a: int, b: int) -> int:
 
90
 
91
  Args:
92
  query: The search query."""
93
+ try:
94
+ search_docs = WikipediaLoader(query=query, load_max_docs=2).load()
95
+ if not search_docs:
96
+ return {"wiki_results": "No Wikipedia results found for the query."}
97
+ formatted_search_docs = "\n\n---\n\n".join(
98
+ [
99
+ f'<Document source="{doc.metadata.get("source", "Unknown")}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
100
+ for doc in search_docs
101
+ ])
102
+ return {"wiki_results": formatted_search_docs}
103
+ except Exception as e:
104
+ print(f"Error in wiki_search: {e}")
105
+ return {"wiki_results": f"Error searching Wikipedia: {e}"}
106
 
107
  @tool
108
  def web_search(query: str) -> str:
 
110
 
111
  Args:
112
  query: The search query."""
113
+ try:
114
+ search_docs = TavilySearchResults(max_results=3).invoke(query=query)
115
+ if not search_docs:
116
+ return {"web_results": "No web search results found for the query."}
117
+ formatted_search_docs = "\n\n---\n\n".join(
118
+ [
119
+ f'<Document source="{doc.get("url", "Unknown")}" />\n{doc.get("content", "No content")}\n</Document>'
120
+ for doc in search_docs
121
+ ])
122
+ return {"web_results": formatted_search_docs}
123
+ except Exception as e:
124
+ print(f"Error in web_search: {e}")
125
+ return {"web_results": f"Error searching web: {e}"}
126
 
127
  @tool
128
  def arvix_search(query: str) -> str:
 
130
 
131
  Args:
132
  query: The search query."""
133
+ try:
134
+ search_docs = ArxivLoader(query=query, load_max_docs=3).load()
135
+ if not search_docs:
136
+ return {"arvix_results": "No Arxiv results found for the query."}
137
+ formatted_search_docs = "\n\n---\n\n".join(
138
+ [
139
+ f'<Document source="{doc.metadata.get("source", "Unknown")}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content[:1000]}\n</Document>'
140
+ for doc in search_docs
141
+ ])
142
+ return {"arvix_results": formatted_search_docs}
143
+ except Exception as e:
144
+ print(f"Error in arvix_search: {e}")
145
+ return {"arvix_results": f"Error searching Arxiv: {e}"}
146
 
147
  # load the system prompt from the file
148
  with open("system_prompt.txt", "r", encoding="utf-8") as f:
 
153
 
154
  # build a retriever
155
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") # dim=768
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
+ # Try to create Supabase client with error handling
158
+ try:
159
+ supabase_url = os.environ.get("SUPABASE_URL")
160
+ supabase_key = os.environ.get("SUPABASE_SERVICE_KEY")
161
+
162
+ if not supabase_url or not supabase_key:
163
+ print("Warning: Supabase credentials not found, vector store will be disabled")
164
+ vector_store = None
165
+ create_retriever_tool = None
166
+ else:
167
+ supabase: Client = create_client(supabase_url, supabase_key)
168
+ vector_store = SupabaseVectorStore(
169
+ client=supabase,
170
+ embedding= embeddings,
171
+ table_name="documents",
172
+ query_name="match_documents_langchain",
173
+ )
174
+ create_retriever_tool = create_retriever_tool(
175
+ retriever=vector_store.as_retriever(),
176
+ name="Question Search",
177
+ description="A tool to retrieve similar questions from a vector store.",
178
+ )
179
+ except Exception as e:
180
+ print(f"Warning: Could not initialize Supabase vector store: {e}")
181
+ vector_store = None
182
+ create_retriever_tool = None
183
 
184
  tools = [
185
  multiply,
 
191
  web_search,
192
  arvix_search,
193
  ]
194
+ if create_retriever_tool:
195
+ tools.append(create_retriever_tool)
196
 
197
  # Build graph function
198
  def build_graph(provider: str = "groq"):
 
220
  # Node
221
  def assistant(state: MessagesState):
222
  """Assistant node"""
223
+ try:
224
+ print(f"Assistant node: Processing {len(state['messages'])} messages")
225
+ result = llm_with_tools.invoke(state["messages"])
226
+ print(f"Assistant node: LLM returned result type: {type(result)}")
227
+ return {"messages": [result]}
228
+ except Exception as e:
229
+ print(f"Error in assistant node: {e}")
230
+ from langchain_core.messages import AIMessage
231
+ error_msg = AIMessage(content=f"I encountered an error: {e}")
232
+ return {"messages": [error_msg]}
233
 
234
  def retriever(state: MessagesState):
235
  """Retriever node"""
236
+ try:
237
+ print(f"Retriever node: Processing {len(state['messages'])} messages")
238
+ if not state["messages"]:
239
+ print("Retriever node: No messages in state")
240
+ return {"messages": [sys_msg]}
241
+ if not vector_store:
242
+ print("Retriever node: Vector store not available, skipping retrieval")
243
+ return {"messages": [sys_msg] + state["messages"]}
244
+ query_content = state["messages"][0].content
245
+ print(f"Retriever node: Searching for similar questions with query: {query_content[:100]}...")
246
+ similar_question = vector_store.similarity_search(query_content)
247
+ print(f"Retriever node: Found {len(similar_question)} similar questions")
248
+ if not similar_question:
249
+ print("Retriever node: No similar questions found, proceeding without example")
250
+ return {"messages": [sys_msg] + state["messages"]}
251
+ example_msg = HumanMessage(
252
+ content=f"Here I provide a similar question and answer for reference: \n\n{similar_question[0].page_content}",
253
+ )
254
+ print(f"Retriever node: Added example message from similar question")
255
+ return {"messages": [sys_msg] + state["messages"] + [example_msg]}
256
+ except Exception as e:
257
+ print(f"Error in retriever node: {e}")
258
+ return {"messages": [sys_msg] + state["messages"]}
259
 
260
  builder = StateGraph(MessagesState)
261
  builder.add_node("retriever", retriever)
pyproject.toml CHANGED
@@ -3,7 +3,7 @@ name = "final-assignment-template"
3
  version = "0.1.0"
4
  description = "Add your description here"
5
  readme = "README.md"
6
- requires-python = ">=3.10,<3.12"
7
  dependencies = [
8
  "dotenv>=0.9.9",
9
  "hf-xet>=1.1.3",
 
3
  version = "0.1.0"
4
  description = "Add your description here"
5
  readme = "README.md"
6
+ requires-python = ">=3.13"
7
  dependencies = [
8
  "dotenv>=0.9.9",
9
  "hf-xet>=1.1.3",
test.py CHANGED
@@ -6,6 +6,8 @@ import requests
6
  import pandas as pd
7
  from langchain_core.messages import HumanMessage
8
  from agent import build_graph
 
 
9
 
10
 
11
 
@@ -184,6 +186,35 @@ with gr.Blocks() as demo:
184
  outputs=[status_output, results_table]
185
  )
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  if __name__ == "__main__":
188
  print("\n" + "-"*30 + " App Starting " + "-"*30)
189
  # Check for SPACE_HOST and SPACE_ID at startup for information
@@ -206,4 +237,7 @@ if __name__ == "__main__":
206
  print("-"*(60 + len(" App Starting ")) + "\n")
207
 
208
  print("Launching Gradio Interface for Basic Agent Evaluation...")
209
- demo.launch(debug=True, share=False)
 
 
 
 
6
  import pandas as pd
7
  from langchain_core.messages import HumanMessage
8
  from agent import build_graph
9
+ import asyncio
10
+ from langraph_agent import build_graph
11
 
12
 
13
 
 
186
  outputs=[status_output, results_table]
187
  )
188
 
189
+ async def test_agent():
190
+ """Test the agent with a simple question"""
191
+ try:
192
+ print("Building graph...")
193
+ graph = build_graph(provider="groq")
194
+
195
+ print("Testing with a simple question...")
196
+ question = "What is 2 + 3?"
197
+ messages = [HumanMessage(content=question)]
198
+
199
+ print("Invoking agent...")
200
+ response = await graph.ainvoke({"messages": messages})
201
+
202
+ print(f"Response type: {type(response)}")
203
+ print(f"Response keys: {response.keys() if isinstance(response, dict) else 'Not a dict'}")
204
+
205
+ if 'messages' in response and response['messages']:
206
+ print(f"Number of messages: {len(response['messages'])}")
207
+ print(f"Last message content: {response['messages'][-1].content}")
208
+ return "SUCCESS"
209
+ else:
210
+ print("No messages in response or empty messages")
211
+ return "FAILED - No messages"
212
+ except Exception as e:
213
+ print(f"Error in test: {e}")
214
+ import traceback
215
+ traceback.print_exc()
216
+ return f"FAILED - {e}"
217
+
218
  if __name__ == "__main__":
219
  print("\n" + "-"*30 + " App Starting " + "-"*30)
220
  # Check for SPACE_HOST and SPACE_ID at startup for information
 
237
  print("-"*(60 + len(" App Starting ")) + "\n")
238
 
239
  print("Launching Gradio Interface for Basic Agent Evaluation...")
240
+ demo.launch(debug=True, share=False)
241
+
242
+ result = asyncio.run(test_agent())
243
+ print(f"Test result: {result}")