wishwakankanamg commited on
Commit
212150e
·
1 Parent(s): ef17b20
Files changed (3) hide show
  1. __pycache__/graph.cpython-310.pyc +0 -0
  2. app.log +12 -0
  3. graph.py +110 -90
__pycache__/graph.cpython-310.pyc CHANGED
Binary files a/__pycache__/graph.cpython-310.pyc and b/__pycache__/graph.cpython-310.pyc differ
 
app.log CHANGED
@@ -49982,3 +49982,15 @@ Traceback (most recent call last):
49982
  raise GraphRecursionError(msg)
49983
  langgraph.errors.GraphRecursionError: Recursion limit of 20 reached without hitting a stop condition. You can increase the limit by setting the `recursion_limit` config key.
49984
  For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/GRAPH_RECURSION_LIMIT
 
 
 
 
 
 
 
 
 
 
 
 
 
49982
  raise GraphRecursionError(msg)
49983
  langgraph.errors.GraphRecursionError: Recursion limit of 20 reached without hitting a stop condition. You can increase the limit by setting the `recursion_limit` config key.
49984
  For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/GRAPH_RECURSION_LIMIT
49985
+ 2025-06-06 16:42:56:__main__:INFO: Starting the interface
49986
+ 2025-06-06 16:44:31:__main__:INFO: Greeting added for new user via handle_initial_greeting_load.
49987
+ 2025-06-06 16:44:35:__main__:INFO: Greeting added for new user via handle_initial_greeting_load.
49988
+ 2025-06-06 16:44:43:__main__:INFO: Prompt: You are a helpful assistant.
49989
+ 2025-06-06 16:45:28:__main__:ERROR: Exception occurred
49990
+ Traceback (most recent call last):
49991
+ File "/home/user/app/app.py", line 85, in chat_fn
49992
+ async for stream_mode, chunk in graph.astream(
49993
+ File "/usr/local/lib/python3.10/site-packages/langgraph/pregel/__init__.py", line 2677, in astream
49994
+ raise GraphRecursionError(msg)
49995
+ langgraph.errors.GraphRecursionError: Recursion limit of 20 reached without hitting a stop condition. You can increase the limit by setting the `recursion_limit` config key.
49996
+ For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/GRAPH_RECURSION_LIMIT
graph.py CHANGED
@@ -24,6 +24,13 @@ from langgraph.types import Command, interrupt
24
  class State(TypedDict):
25
  messages: Annotated[list, add_messages]
26
 
 
 
 
 
 
 
 
27
 
28
  logger = logging.getLogger(__name__)
29
  ASSISTANT_SYSTEM_PROMPT_BASE = """"""
@@ -246,78 +253,116 @@ async def brainstorming_node(state: GraphProcessingState, config=None):
246
  print(f"Product Searching Complete: {state.product_searching_complete}")
247
  print(f"Purchasing Complete: {state.purchasing_complete}")
248
 
249
- if not model:
250
- return {"messages": [AIMessage(content="Model not available for brainstorming.")]}
251
-
252
- # Define the system prompt guiding the brainstorming assistant
253
- brainstorming_system_prompt = ChatPromptTemplate.from_messages(
254
- [
255
- ("system",
256
- "You are a brainstorming assistant for DIY projects. Your goal is to help the user finalize a single, specific DIY project idea. "
257
- "The project idea MUST satisfy these critical criteria:\n"
258
- "1. Buildable by an average person with basic DIY skills.\n"
259
- "2. Uses only materials and basic tools commonly available in general hardware stores, craft stores, or supermarkets worldwide. "
260
- "(e.g., wood, screws, glue, paint, fabric, cardboard, basic hand tools like screwdrivers, hammers, saws, drills. "
261
- "AVOID specialized electronic components, 3D printing, specific brand items not universally available, or complex machinery.)\n"
262
- "3. The final product should be a tangible item.\n\n"
263
- "Your interaction flow:\n"
264
- "- Engage with the user to understand their interests or initial thoughts.\n"
265
- "- Propose ideas or refine user's suggestions to meet the criteria.\n"
266
- "- If an idea proposed by you or the user clearly meets all criteria and you believe it's a good final choice, respond ONLY with the exact phrase: "
267
- "'IDEA FINALIZED: [Name of the Idea]'. Example: 'IDEA FINALIZED: Simple Wooden Spice Rack'. "
268
- "Do not add any other text before or after this phrase if you use it.\n"
269
- "- If you need more information from the user to refine an idea, or if their current suggestion doesn't meet the criteria, ask clarifying questions. "
270
- "Guide them towards simpler, more accessible options.\n"
271
- "- If you are stuck, the user's request is too vague for you to make progress towards a suitable idea, or they propose something clearly outside the "
272
- "'universally available materials' constraint, and you need their direct input to clarify fundamental aspects, you should use the 'human_assistance' tool. "
273
- "Frame your request for the human clearly. For example: 'To ensure the idea is simple enough, could you tell me what kind of tools you are comfortable using?' "
274
- "or 'The idea of a custom electronic gadget is interesting, but finding parts globally is hard. Could we think of a non-electronic version, or what's the core function "
275
- "you want from it that we could achieve with simpler materials?'"
276
- ),
277
- MessagesPlaceholder(variable_name="messages"),
278
- ]
279
- )
280
-
281
- # Tools allowed for brainstorming
282
- node_tools = [human_assistance]
283
- if state.search_enabled and tavily_search_tool: # only add search tool if enabled and initialized
284
- node_tools.append(tavily_search_tool)
285
-
286
- llm_with_tools = model.bind_tools(node_tools)
287
- chain = brainstorming_system_prompt | llm_with_tools
288
-
289
- # Pass current messages from the state to the chain
290
- response_message = await chain.ainvoke({"messages": state.messages}, config=config)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
- updates = {"messages": [response_message]}
 
 
 
 
293
 
294
- if isinstance(response_message, AIMessage) and response_message.content:
295
- content = response_message.content.strip()
296
 
297
- if content.startswith("IDEA FINALIZED:"):
298
- updates["brainstorming_complete"] = True
299
- updates["tool_call_required"] = False
300
- updates["loop_brainstorming"] = False
301
- print(f"✅ Brainstorming complete! Idea: {content}")
302
 
303
- elif getattr(response_message, "tool_calls", None):
304
- updates["tool_call_required"] = True
305
- updates["loop_brainstorming"] = False
306
- print(f"🛠️ Brainstorming node initiated tool call(s): {response_message.tool_calls}")
 
 
 
307
 
308
- else:
309
- updates["tool_call_required"] = False
310
- updates["loop_brainstorming"] = True
311
- print(f"💬 Brainstorming node continues discussion: {content}")
312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  else:
314
- # If no proper response, keep looping brainstorming
315
- updates["tool_call_required"] = False
316
- updates["loop_brainstorming"] = True
317
-
318
- print("\n--- End Brainstorming Node Debug ---")
319
 
320
- return updates
321
 
322
  async def planning_node(state: GraphProcessingState, config=None):
323
  # Define the system prompt for planning
@@ -353,33 +398,8 @@ async def planning_node(state: GraphProcessingState, config=None):
353
  "messages": response
354
  }
355
 
356
- def brainstorming_routing(state: GraphProcessingState) -> str:
357
- print("\n--- brainstorming_routing Edge (Debug via print) ---") # Added a newline for clarity
358
- print(f"Prompt: {state.prompt}")
359
- # print(f"Message: {state.messages}")
360
- print(f"Tools Enabled: {state.tools_enabled}")
361
- print(f"Search Enabled: {state.search_enabled}")
362
- print(f"Next Stage: {state.next_stage}")
363
 
364
 
365
- # Log boolean completion flags
366
- print(f"Idea Complete: {state.idea_complete}")
367
- print(f"Brainstorming Complete: {state.brainstorming_complete}")
368
- print(f"Planning Complete: {state.planning_complete}")
369
- print(f"Drawing Complete: {state.drawing_complete}")
370
- print(f"Product Searching Complete: {state.product_searching_complete}")
371
- print(f"Purchasing Complete: {state.purchasing_complete}")
372
- print("--- End Guidance Node Debug ---") # Added for clarity
373
- if state.tool_call_required:
374
- print('calling tools for brainstorming')
375
- return "tools"
376
- elif state.loop_brainstorming:
377
- print('returning back to brainstorming at the route')
378
- return "brainstorming_node"
379
- else:
380
- print('all good in brainstorming route going back to guidance')
381
- return "guidance_node"
382
-
383
  def guidance_routing(state: GraphProcessingState) -> str:
384
 
385
  print("\n--- Guidance Routing Edge (Debug via print) ---") # Added a newline for clarity
@@ -422,7 +442,7 @@ def define_workflow() -> CompiledStateGraph:
422
  workflow = StateGraph(GraphProcessingState)
423
 
424
  # Add nodes
425
- workflow.add_node("tools", ToolNode(tools))
426
  workflow.add_node("planning_node", planning_node)
427
  workflow.add_node("guidance_node", guidance_node)
428
  workflow.add_node("brainstorming_node", brainstorming_node)
 
24
  class State(TypedDict):
25
  messages: Annotated[list, add_messages]
26
 
27
+ class DebugToolNode(ToolNode):
28
+ async def invoke(self, state, config=None):
29
+ print("🛠️ ToolNode activated")
30
+ print(f"Available tools: {[tool.name for tool in self.tool_map.values()]}")
31
+ print(f"Tool calls in last message: {state.messages[-1].tool_calls}")
32
+ return await super().invoke(state, config)
33
+
34
 
35
  logger = logging.getLogger(__name__)
36
  ASSISTANT_SYSTEM_PROMPT_BASE = """"""
 
253
  print(f"Product Searching Complete: {state.product_searching_complete}")
254
  print(f"Purchasing Complete: {state.purchasing_complete}")
255
 
256
+ # if not model:
257
+ # return {"messages": [AIMessage(content="Model not available for brainstorming.")]}
258
+
259
+ # # Define the system prompt guiding the brainstorming assistant
260
+ # brainstorming_system_prompt = ChatPromptTemplate.from_messages(
261
+ # [
262
+ # ("system",
263
+ # "You are a brainstorming assistant for DIY projects. Your goal is to help the user finalize a single, specific DIY project idea. "
264
+ # "The project idea MUST satisfy these critical criteria:\n"
265
+ # "1. Buildable by an average person with basic DIY skills.\n"
266
+ # "2. Uses only materials and basic tools commonly available in general hardware stores, craft stores, or supermarkets worldwide. "
267
+ # "(e.g., wood, screws, glue, paint, fabric, cardboard, basic hand tools like screwdrivers, hammers, saws, drills. "
268
+ # "AVOID specialized electronic components, 3D printing, specific brand items not universally available, or complex machinery.)\n"
269
+ # "3. The final product should be a tangible item.\n\n"
270
+ # "Your interaction flow:\n"
271
+ # "- Engage with the user to understand their interests or initial thoughts.\n"
272
+ # "- Propose ideas or refine user's suggestions to meet the criteria.\n"
273
+ # "- If an idea proposed by you or the user clearly meets all criteria and you believe it's a good final choice, respond ONLY with the exact phrase: "
274
+ # "'IDEA FINALIZED: [Name of the Idea]'. Example: 'IDEA FINALIZED: Simple Wooden Spice Rack'. "
275
+ # "Do not add any other text before or after this phrase if you use it.\n"
276
+ # "- If you need more information from the user to refine an idea, or if their current suggestion doesn't meet the criteria, ask clarifying questions. "
277
+ # "Guide them towards simpler, more accessible options.\n"
278
+ # "- If you are stuck, the user's request is too vague for you to make progress towards a suitable idea, or they propose something clearly outside the "
279
+ # "'universally available materials' constraint, and you need their direct input to clarify fundamental aspects, you should use the 'human_assistance' tool. "
280
+ # "Frame your request for the human clearly. For example: 'To ensure the idea is simple enough, could you tell me what kind of tools you are comfortable using?' "
281
+ # "or 'The idea of a custom electronic gadget is interesting, but finding parts globally is hard. Could we think of a non-electronic version, or what's the core function "
282
+ # "you want from it that we could achieve with simpler materials?'"
283
+ # ),
284
+ # MessagesPlaceholder(variable_name="messages"),
285
+ # ]
286
+ # )
287
+
288
+ # # Tools allowed for brainstorming
289
+ # node_tools = [human_assistance]
290
+ # if state.search_enabled and tavily_search_tool: # only add search tool if enabled and initialized
291
+ # node_tools.append(tavily_search_tool)
292
+
293
+ # llm_with_tools = model.bind_tools(node_tools)
294
+ # chain = brainstorming_system_prompt | llm_with_tools
295
+
296
+ # # Pass current messages from the state to the chain
297
+ # response_message = await chain.ainvoke({"messages": state.messages}, config=config)
298
+
299
+ # updates = {"messages": [response_message]}
300
+
301
+ # if isinstance(response_message, AIMessage) and response_message.content:
302
+ # content = response_message.content.strip()
303
+
304
+ # if content.startswith("IDEA FINALIZED:"):
305
+ # updates["brainstorming_complete"] = True
306
+ # updates["tool_call_required"] = False
307
+ # updates["loop_brainstorming"] = False
308
+ # print(f"✅ Brainstorming complete! Idea: {content}")
309
+
310
+ # elif getattr(response_message, "tool_calls", None):
311
+ # updates["tool_call_required"] = True
312
+ # updates["loop_brainstorming"] = False
313
+ # print(f"🛠️ Brainstorming node initiated tool call(s): {response_message.tool_calls}")
314
+
315
+ # else:
316
+ # updates["tool_call_required"] = False
317
+ # updates["loop_brainstorming"] = True
318
+ # print(f"💬 Brainstorming node continues discussion: {content}")
319
+
320
+ # else:
321
+ # # If no proper response, keep looping brainstorming
322
+ # updates["tool_call_required"] = False
323
+ # updates["loop_brainstorming"] = True
324
+
325
+ # print("\n--- End Brainstorming Node Debug ---")
326
+
327
+ test_tool_call = ToolCall(name="human_assistance", args={"question": "What materials do you have?"})
328
+ test_message = AIMessage(content=None, tool_calls=[test_tool_call])
329
 
330
+ updates = {
331
+ "messages": [test_message],
332
+ "tool_call_required": True,
333
+ "loop_brainstorming": False,
334
+ }
335
 
336
+ return updates
 
337
 
 
 
 
 
 
338
 
339
+ def brainstorming_routing(state: GraphProcessingState) -> str:
340
+ print("\n--- brainstorming_routing Edge (Debug via print) ---") # Added a newline for clarity
341
+ print(f"Prompt: {state.prompt}")
342
+ # print(f"Message: {state.messages}")
343
+ print(f"Tools called: {state.tool_call_required}")
344
+ print(f"Search Enabled: {state.search_enabled}")
345
+ print(f"Next Stage: {state.next_stage}")
346
 
 
 
 
 
347
 
348
+ # Log boolean completion flags
349
+ print(f"Idea Complete: {state.idea_complete}")
350
+ print(f"Brainstorming Complete: {state.brainstorming_complete}")
351
+ print(f"Planning Complete: {state.planning_complete}")
352
+ print(f"Drawing Complete: {state.drawing_complete}")
353
+ print(f"Product Searching Complete: {state.product_searching_complete}")
354
+ print(f"Purchasing Complete: {state.purchasing_complete}")
355
+ print("--- End Guidance Node Debug ---") # Added for clarity
356
+ if state.tool_call_required:
357
+ print('calling tools for brainstorming')
358
+ return "tools"
359
+ elif state.loop_brainstorming:
360
+ print('returning back to brainstorming at the route')
361
+ return "brainstorming_node"
362
  else:
363
+ print('all good in brainstorming route going back to guidance')
364
+ return "guidance_node"
 
 
 
365
 
 
366
 
367
  async def planning_node(state: GraphProcessingState, config=None):
368
  # Define the system prompt for planning
 
398
  "messages": response
399
  }
400
 
 
 
 
 
 
 
 
401
 
402
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  def guidance_routing(state: GraphProcessingState) -> str:
404
 
405
  print("\n--- Guidance Routing Edge (Debug via print) ---") # Added a newline for clarity
 
442
  workflow = StateGraph(GraphProcessingState)
443
 
444
  # Add nodes
445
+ workflow.add_node("tools", DebugToolNode(tools))
446
  workflow.add_node("planning_node", planning_node)
447
  workflow.add_node("guidance_node", guidance_node)
448
  workflow.add_node("brainstorming_node", brainstorming_node)