-
Notifications
You must be signed in to change notification settings - Fork 72
feat: add thinking_node to rephrase user queries before routing #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add thinking_node to rephrase user queries before routing #111
Conversation
WalkthroughThe changes replace the deprecated FAQTool with a new FAQ handler that uses an LLM and web search to answer organizational queries. A "thinking_node" is added to the DevRelAgent's workflow, and related handler, tool wrapper, and search tool implementations are updated. Discord bot and cog logic are also refined. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DevRelAgent
participant LLM
participant WebSearchTool
User->>DevRelAgent: Ask organizational FAQ
DevRelAgent->>LLM: Generate refined search queries
LLM-->>DevRelAgent: List of queries
loop For each query
DevRelAgent->>WebSearchTool: Search(query)
WebSearchTool-->>DevRelAgent: Search results
end
DevRelAgent->>LLM: Synthesize answer from results
LLM-->>DevRelAgent: Synthesized answer + sources
DevRelAgent->>User: Return answer + source links
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
🧰 Additional context used🧠 Learnings (2)📓 Common learningsbackend/app/agents/devrel/nodes/handlers/faq.py (4)Learnt from: smokeyScraper Learnt from: smokeyScraper Learnt from: smokeyScraper Learnt from: smokeyScraper 🔇 Additional comments (2)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
backend/app/agents/devrel/agent.py (1)
65-65: Remove conflicting workflow edge.Line 65 adds a direct edge from "gather_context" to "react_supervisor", which conflicts with the new routing through "thinking_node" defined in lines 46-47. This creates an ambiguous workflow path.
# Entry point workflow.set_entry_point("gather_context") -workflow.add_edge("gather_context", "react_supervisor")The routing should flow: gather_context → thinking_node → react_supervisor, as defined in lines 46-47.
🧹 Nitpick comments (2)
backend/app/agents/devrel/tool_wrappers.py (2)
64-68: Consider extracting message retrieval logic into a helper function.The message extraction logic is duplicated between
thinking_node_tool_nodeandgithub_toolkit_tool_node. This violates DRY principles and makes maintenance harder.Consider creating a helper function:
+def _get_latest_message(state: AgentState) -> str: + """Extract the latest message from state""" + if state.messages: + return state.messages[-1].get("content", "") + elif state.context.get("original_message"): + return state.context["original_message"] + return "" + async def thinking_node_tool_node(state: AgentState, llm) -> Dict[str, Any]: """Rephrase user query into a clean and clear question""" logger.info(f"Executing Thinking Node for session {state.session_id}") - latest_message = "" - if state.messages: - latest_message = state.messages[-1].get("content", "") - elif state.context.get("original_message"): - latest_message = state.context["original_message"] + latest_message = _get_latest_message(state)
71-75: Consider enhancing the prompt for more consistent output.The current prompt is quite general and might produce inconsistent results. Consider making it more specific about the expected output format.
- prompt = ( - "Rephrase this user query into a clear and formal question " - "suitable for an FAQ or web search:\n\n" - f"'{latest_message}'" - ) + prompt = ( + "Rephrase the following user query into a clear, concise, and formal question " + "that would be suitable for FAQ lookup or web search. " + "Focus on the core intent and remove any casual language or filler words. " + "Return only the rephrased question without quotes or additional text:\n\n" + f"User query: {latest_message}" + )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
backend/app/agents/devrel/agent.py(2 hunks)backend/app/agents/devrel/tool_wrappers.py(1 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/tool_wrappers.py (1)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/agent.py (2)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
Learnt from: smokeyScraper
PR: #75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/tool_wrappers.py (1)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/agent.py (2)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
Learnt from: smokeyScraper
PR: #75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
🔇 Additional comments (5)
backend/app/agents/devrel/tool_wrappers.py (2)
78-84: Excellent error handling with fallback mechanism.The try-catch block with fallback to the original message ensures the system remains robust even when the LLM fails. The logging is also appropriate for debugging.
86-91: No conflicting usage ofrephrased_queryinstate.contextdetected.A search across the codebase shows that:
state.context["rephrased_query"]is only set inbackend/app/agents/devrel/tool_wrappers.py- There are no other reads or writes of this key elsewhere
Storing the rephrased query will not interfere with other components.
backend/app/agents/devrel/agent.py (3)
17-17: Import addition looks good.The import follows the existing pattern and is placed appropriately with other tool wrapper imports.
45-47: Workflow integration is well-implemented.The thinking_node is properly integrated using partial application and positioned correctly between gather_context and react_supervisor. This maintains the logical flow of the agent.
45-47: Workflow routing confirmedThe node connections in backend/app/agents/devrel/agent.py are intentional and conflict-free:
- gather_context → thinking_node
- thinking_node → react_supervisor
- gather_context → react_supervisor (to supply initial context alongside reasoning)
React Supervisor then uses
add_conditional_edgesfor tool dispatch. No overlapping or unintended paths were found—no changes needed here.
|
Hey @smokeyScraper 👋 I've completed the implementation for the The node now rephrases informal user queries using Gemini (LLM) and routes them more cleanly to the appropriate tool (FAQ or Web Search). Let me know if you'd like me to make any changes — happy to improve it further! 🚀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
frontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (5)
backend/app/agents/devrel/agent.py(2 hunks)backend/app/agents/devrel/tool_wrappers.py(1 hunks)backend/integrations/discord/bot.py(1 hunks)backend/main.py(1 hunks)frontend/package.json(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- backend/main.py
- frontend/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
- backend/app/agents/devrel/agent.py
- backend/app/agents/devrel/tool_wrappers.py
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#85
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T14:45:55.244Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer comprehensive test refactoring to separate PRs/efforts when doing major backend restructuring, rather than expanding the scope of the current refactoring PR to include test updates.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
|
The attached interactions aren't complete. Could you please attach a few complete responses from the agent? |
smokeyScraper
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not very much sure if this specific handler needs to be implemented in this way. Currently, I'm focusing on a simple routing technique to the required handlers and having all the operations internally over their workflow itself.
Can't deny the fact that queries can be aligned earlier but I'm preferring them to be specifically handled if required inside the handler itself and will think on unifying them as done in general cases of "Generalizing a DB"
Better to discuss a bit with @Rudra775 too as he too will be involved in this issue. You guys can raise a pair PR. I have started work on documenting and will share it soon.
| prompt = ( | ||
| "Rephrase this user query into a clear and formal question " | ||
| "suitable for an FAQ or web search:\n\n" | ||
| f"'{latest_message}'" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the ReAct supervisor node is the router right? won't aligning the query this way make it more aligned for FAQ or web search? as this thinking node is present prior to the router
have you tried any interactions, if yes please do share.
|
Hey @smokeyScraper 👋 Thanks a lot for the detailed feedback — really appreciate the insights! Based on your feedback, here’s what I’m going to do:
Small Request: Would Love to Take This On I’m genuinely enjoying breaking things and gluing them back better 😄 — so if you're cool with it, I’d love it if you could assign me to this issue officially. I’m all in on shaping this piece the right way. Let me know |
…updated frontend dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
backend/integrations/discord/bot.py (1)
29-210: Resolve merge conflicts before proceeding with review.This file contains unresolved merge conflicts between the
feat/thinking-nodeandmainbranches throughout the codebase. The conflicts affect critical functionality including message handling, thread management, and agent response processing.Please resolve all merge conflicts and push the resolved version before the code can be properly reviewed.
🧹 Nitpick comments (1)
backend/integrations/discord/cogs.py (1)
30-33: Implement token cleanup logic in the new task method.The
cleanup_expired_tokens_taskmethod is currently a placeholder. Since there's already acleanup_expired_tokensmethod (lines 42-50) that callsawait cleanup_expired_tokens()from the auth module, consider whether you need both methods or if this is intended to replace the existing one.Would you like me to help implement the token cleanup logic or open an issue to track this TODO?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
backend/integrations/discord/bot.py(7 hunks)backend/integrations/discord/cogs.py(1 hunks)backend/main.py(2 hunks)pyproject.toml(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- backend/main.py
🚧 Files skipped from review as they are similar to previous changes (1)
- pyproject.toml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#85
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T14:45:55.244Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer comprehensive test refactoring to separate PRs/efforts when doing major backend restructuring, rather than expanding the scope of the current refactoring PR to include test updates.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#87
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T23:15:13.374Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer test updates and fixes (like missing imports after module reorganization) to separate PRs rather than expanding the scope of module update/chore PRs to include comprehensive test refactoring.
backend/integrations/discord/bot.py (1)
Learnt from: smokeyScraper
PR: #76
File: backend/app/agents/shared/base_agent.py:22-44
Timestamp: 2025-06-14T05:57:43.872Z
Learning: In the Devr.AI codebase, user_id directly maps as thread_id for memory persistence in the agent system, ensuring thread_id is always non-empty and unique per user.
🧬 Code Graph Analysis (1)
backend/integrations/discord/bot.py (1)
backend/app/core/orchestration/queue_manager.py (2)
QueuePriority(12-15)enqueue(73-92)
🪛 Ruff (0.12.2)
backend/integrations/discord/bot.py
31-31: SyntaxError: Unexpected indentation
48-48: SyntaxError: Unexpected indentation
60-60: SyntaxError: unindent does not match any outer indentation level
80-80: SyntaxError: Expected an indented block after function definition
81-81: SyntaxError: Unexpected indentation
86-86: SyntaxError: Expected except or finally after try block
91-91: SyntaxError: unindent does not match any outer indentation level
108-108: SyntaxError: Expected except or finally after try block
110-110: SyntaxError: Unexpected indentation
134-134: SyntaxError: unindent does not match any outer indentation level
143-143: SyntaxError: unindent does not match any outer indentation level
146-146: SyntaxError: Unexpected indentation
147-147: SyntaxError: Unexpected indentation
152-152: SyntaxError: Unexpected indentation
154-154: SyntaxError: unindent does not match any outer indentation level
156-156: SyntaxError: Unexpected indentation
181-181: SyntaxError: Expected a statement
182-182: SyntaxError: Unexpected indentation
183-183: SyntaxError: unindent does not match any outer indentation level
183-183: SyntaxError: Expected a statement
183-183: SyntaxError: Expected a statement
183-184: SyntaxError: Expected an expression
185-185: SyntaxError: Unexpected indentation
189-189: SyntaxError: Expected a statement
200-200: SyntaxError: Expected except or finally after try block
201-201: SyntaxError: Unexpected indentation
210-210: SyntaxError: unindent does not match any outer indentation level
backend/integrations/discord/cogs.py
19-19: SyntaxError: unindent does not match any outer indentation level
20-20: SyntaxError: Unexpected indentation
22-22: SyntaxError: unindent does not match any outer indentation level
24-24: SyntaxError: Unexpected indentation
26-27: SyntaxError: Expected an indented block after if statement
28-28: SyntaxError: Unexpected indentation
30-30: SyntaxError: unindent does not match any outer indentation level
31-31: SyntaxError: Expected class, function definition or async function definition after decorator
35-35: SyntaxError: Unexpected indentation
37-37: SyntaxError: unindent does not match any outer indentation level
…updated frontend dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
backend/integrations/discord/bot.py (1)
29-67: Critical: Resolve merge conflicts preventing compilation.The file contains extensive unresolved Git merge conflicts with conflict markers (
<<<<<<<,=======,>>>>>>>), duplicate code sections, and broken indentation that make the code uncompilable.Please resolve the merge conflicts by:
- Choosing the appropriate code sections from each branch
- Removing all Git conflict markers
- Fixing indentation and syntax issues
- Testing that the merged code compiles and runs correctly
The static analysis shows 30+ syntax errors all stemming from these merge conflicts.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
backend/app/agents/devrel/agent.py(2 hunks)backend/app/agents/devrel/tool_wrappers.py(3 hunks)backend/integrations/discord/bot.py(7 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#85
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T14:45:55.244Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer comprehensive test refactoring to separate PRs/efforts when doing major backend restructuring, rather than expanding the scope of the current refactoring PR to include test updates.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#87
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T23:15:13.374Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer test updates and fixes (like missing imports after module reorganization) to separate PRs rather than expanding the scope of module update/chore PRs to include comprehensive test refactoring.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/agent.py (5)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
Learnt from: smokeyScraper
PR: #75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/init.py:2-2
Timestamp: 2025-06-08T13:15:11.074Z
Learning: In backend/app/agents/shared/base_agent.py, the BaseAgent class internally imports and re-exports AgentState, making it valid to import AgentState from shared.base_agent in addition to shared.state.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_web_search_node.py:31-42
Timestamp: 2025-06-08T13:31:11.572Z
Learning: In backend/app/agents/devrel/tools/search_tool.py, the TavilySearchTool.search() method has partial error handling for missing API key, AttributeError, ConnectionError, and TimeoutError, but lacks a comprehensive Exception catch-all block, so calling functions may still need additional error handling for other potential exceptions.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_web_search_node.py:31-42
Timestamp: 2025-06-08T13:31:11.572Z
Learning: In backend/app/agents/devrel/tools/search_tool.py, the TavilySearchTool.search() method already includes comprehensive error handling that catches all exceptions and returns an empty list instead of raising them, so calling functions don't need additional try-catch blocks.
backend/app/agents/devrel/tool_wrappers.py (2)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/init.py:2-2
Timestamp: 2025-06-08T13:15:11.074Z
Learning: In backend/app/agents/shared/base_agent.py, the BaseAgent class internally imports and re-exports AgentState, making it valid to import AgentState from shared.base_agent in addition to shared.state.
backend/integrations/discord/bot.py (1)
Learnt from: smokeyScraper
PR: #76
File: backend/app/agents/shared/base_agent.py:22-44
Timestamp: 2025-06-14T05:57:43.872Z
Learning: In the Devr.AI codebase, user_id directly maps as thread_id for memory persistence in the agent system, ensuring thread_id is always non-empty and unique per user.
🧬 Code Graph Analysis (1)
backend/integrations/discord/bot.py (1)
backend/app/core/orchestration/queue_manager.py (2)
QueuePriority(12-15)enqueue(73-92)
🪛 Ruff (0.12.2)
backend/app/agents/devrel/agent.py
18-18: Redefinition of unused thinking_node_tool_node from line 16
Remove definition: thinking_node_tool_node
(F811)
backend/app/agents/devrel/tool_wrappers.py
78-78: SyntaxError: Expected a statement
78-78: SyntaxError: Expected a statement
78-78: SyntaxError: Expected a statement
78-78: SyntaxError: Expected a statement
79-79: SyntaxError: Expected a statement
79-79: SyntaxError: Expected a statement
79-79: SyntaxError: Expected a statement
79-79: SyntaxError: Expected a statement
79-80: SyntaxError: Expected a statement
80-80: SyntaxError: Unexpected indentation
81-81: SyntaxError: Expected a statement
81-81: SyntaxError: Expected a statement
81-81: SyntaxError: Expected a statement
81-81: SyntaxError: Expected a statement
81-81: SyntaxError: Expected ',', found name
81-81: SyntaxError: Expected ',', found name
81-81: SyntaxError: Expected ',', found name
81-81: SyntaxError: Unparenthesized generator expression cannot be used here
81-81: SyntaxError: Expected 'in', found name
81-81: SyntaxError: Expected ',', found name
81-81: SyntaxError: Expected ',', found ';'
81-81: SyntaxError: Expected ',', found name
81-81: SyntaxError: Expected ',', found name
82-82: SyntaxError: Unexpected indentation
backend/integrations/discord/bot.py
31-31: SyntaxError: Unexpected indentation
48-48: SyntaxError: Unexpected indentation
51-51: SyntaxError: Expected a statement
51-51: SyntaxError: Expected a statement
51-51: SyntaxError: Expected a statement
51-51: SyntaxError: Expected a statement
52-52: SyntaxError: Expected a statement
52-52: SyntaxError: Expected a statement
52-52: SyntaxError: Expected a statement
52-52: SyntaxError: Expected a statement
52-53: SyntaxError: Expected a statement
53-53: SyntaxError: Unexpected indentation
56-56: SyntaxError: Expected a statement
56-56: SyntaxError: Expected a statement
56-56: SyntaxError: Expected a statement
56-56: SyntaxError: Expected a statement
56-56: SyntaxError: Expected ',', found name
56-56: SyntaxError: Expected ',', found name
56-56: SyntaxError: Expected ',', found name
56-56: SyntaxError: Unparenthesized generator expression cannot be used here
56-56: SyntaxError: Expected 'in', found name
56-56: SyntaxError: Expected ',', found name
56-56: SyntaxError: Expected ',', found ';'
56-56: SyntaxError: Expected ',', found name
56-56: SyntaxError: Expected ',', found name
57-57: SyntaxError: Unexpected indentation
66-66: SyntaxError: unindent does not match any outer indentation level
86-86: SyntaxError: Expected an indented block after function definition
87-87: SyntaxError: Unexpected indentation
92-92: SyntaxError: Expected except or finally after try block
97-97: SyntaxError: unindent does not match any outer indentation level
114-114: SyntaxError: Expected except or finally after try block
116-116: SyntaxError: Unexpected indentation
140-140: SyntaxError: unindent does not match any outer indentation level
149-149: SyntaxError: unindent does not match any outer indentation level
152-152: SyntaxError: Unexpected indentation
153-153: SyntaxError: Unexpected indentation
158-158: SyntaxError: Unexpected indentation
160-160: SyntaxError: unindent does not match any outer indentation level
162-162: SyntaxError: Unexpected indentation
187-187: SyntaxError: Expected a statement
188-188: SyntaxError: Unexpected indentation
189-189: SyntaxError: unindent does not match any outer indentation level
189-189: SyntaxError: Expected a statement
189-189: SyntaxError: Expected a statement
189-190: SyntaxError: Expected an expression
191-191: SyntaxError: Unexpected indentation
195-195: SyntaxError: Expected a statement
206-206: SyntaxError: Expected except or finally after try block
207-207: SyntaxError: Unexpected indentation
216-216: SyntaxError: unindent does not match any outer indentation level
🔇 Additional comments (5)
backend/app/agents/devrel/agent.py (2)
48-50: LGTM! Proper integration of thinking_node into workflow.The thinking_node is correctly positioned between gather_context and react_supervisor, allowing for query preprocessing before routing decisions. The partial application with the LLM parameter is appropriate.
55-55: LGTM! Updated FAQ handler aligns with deprecation of FAQTool.The migration from the deprecated FAQTool to the new LLM-driven FAQ handler is correctly implemented.
backend/integrations/discord/bot.py (1)
207-212: LGTM! Proper message chunking for Discord limits.Once merge conflicts are resolved, the message chunking implementation correctly handles Discord's 2000-character limit by splitting long responses into chunks.
backend/app/agents/devrel/tool_wrappers.py (2)
61-95: LGTM! Well-designed thinking_node implementation.Once merge conflicts are resolved, the
thinking_node_tool_nodefunction demonstrates solid design:
- Proper extraction of the latest user message from multiple possible sources
- Clear prompt for query rephrasing suitable for FAQ/web search
- Robust error handling with fallback to original message
- Appropriate storage of rephrased query in state context
- Structured return value following the tool pattern
The approach of preprocessing queries before routing should improve downstream tool accuracy.
5-8: LGTM! Import updates align with FAQ handler migration.The import changes correctly reflect the transition from deprecated FAQTool to the new LLM-driven FAQ handler, and the HumanMessage import supports the thinking_node functionality.
Migrates Discord bot commands from legacy prefix-based to modern slash commands using discord.py app_commands. Refactors DevRelCommands cog to use slash commands, improves token cleanup task management, and updates verification flows for ephemeral responses. Discord bot now loads cogs dynamically during async startup, and the Discord dependency is added to pyproject.toml.
…updated frontend dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (1)
backend/integrations/discord/bot.py (1)
106-110: Remove hard-coded acknowledgment message.Based on previous review feedback, the hard-coded acknowledgment messages should be removed to avoid redundancy and improve UX.
- # Send acknowledgment in thread - if thread_id: - thread = self.get_channel(int(thread_id)) - if thread: - await thread.send("I'm processing your request, please hold on...")
🧹 Nitpick comments (2)
backend/app/agents/devrel/nodes/handlers/faq.py (1)
15-20: Enhance LLM prompt for better query generation.The current prompt could be more specific to generate better search queries for organizational FAQ content.
prompt = ( - "You are an AI assistant. Given the following user question, " - "generate 2–3 specific search queries that can help answer it accurately from the web. " - "Only return the queries, one per line, no bullet points.\n\n" + "You are an AI assistant helping with organizational FAQ queries. " + "Given the following user question, generate 2–3 specific search queries " + "that would find information about the organization, its projects, mission, " + "or operations from official sources. Focus on factual, current information. " + "Return only the queries, one per line, no bullet points or numbering.\n\n" f"User question: {question}" )backend/integrations/discord/bot.py (1)
141-149: Consider making welcome message configurable.The detailed welcome message is helpful but could be made configurable for different deployment contexts.
Consider extracting the welcome message to a configuration constant:
+WELCOME_MESSAGE_TEMPLATE = ( + "Hello {mention}! 👋\n" + "I'm your DevRel assistant. I can help you with:\n" + "• Technical questions about Devr.AI\n" + "• Getting started and onboarding\n" + "• Searching for information on the web\n" + "• General developer support\n\n" + "This thread keeps our conversation organized!" +) + # In the method: - await thread.send( - f"Hello {message.author.mention}! 👋\n" - f"I'm your DevRel assistant. I can help you with:\n" - f"• Technical questions about Devr.AI\n" - f"• Getting started and onboarding\n" - f"• Searching for information on the web\n" - f"• General developer support\n\n" - f"This thread keeps our conversation organized!" - ) + await thread.send(WELCOME_MESSAGE_TEMPLATE.format(mention=message.author.mention))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
backend/app/agents/devrel/nodes/handlers/faq.py(1 hunks)backend/app/agents/devrel/nodes/handlers/web_search.py(3 hunks)backend/app/agents/devrel/tool_wrappers.py(3 hunks)backend/app/agents/devrel/tools/search_tool/ddg.py(1 hunks)backend/app/agents/devrel/tools/search_tool/duckduckgo_tool.py(1 hunks)backend/app/core/orchestration/queue_manager.py(0 hunks)backend/integrations/discord/bot.py(6 hunks)backend/integrations/discord/cogs.py(5 hunks)pyproject.toml(1 hunks)
💤 Files with no reviewable changes (1)
- backend/app/core/orchestration/queue_manager.py
🚧 Files skipped from review as they are similar to previous changes (3)
- backend/app/agents/devrel/tools/search_tool/ddg.py
- backend/app/agents/devrel/tool_wrappers.py
- backend/integrations/discord/cogs.py
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#85
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T14:45:55.244Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer comprehensive test refactoring to separate PRs/efforts when doing major backend restructuring, rather than expanding the scope of the current refactoring PR to include test updates.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#87
File: tests/test_supabase.py:1-3
Timestamp: 2025-06-28T23:15:13.374Z
Learning: In the Devr.AI project, smokeyScraper prefers to defer test updates and fixes (like missing imports after module reorganization) to separate PRs rather than expanding the scope of module update/chore PRs to include comprehensive test refactoring.
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/nodes/handlers/web_search.py (3)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_web_search_node.py:31-42
Timestamp: 2025-06-08T13:31:11.572Z
Learning: In backend/app/agents/devrel/tools/search_tool.py, the TavilySearchTool.search() method has partial error handling for missing API key, AttributeError, ConnectionError, and TimeoutError, but lacks a comprehensive Exception catch-all block, so calling functions may still need additional error handling for other potential exceptions.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_web_search_node.py:31-42
Timestamp: 2025-06-08T13:31:11.572Z
Learning: In backend/app/agents/devrel/tools/search_tool.py, the TavilySearchTool.search() method already includes comprehensive error handling that catches all exceptions and returns an empty list instead of raising them, so calling functions don't need additional try-catch blocks.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
backend/app/agents/devrel/tools/search_tool/duckduckgo_tool.py (2)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_web_search_node.py:31-42
Timestamp: 2025-06-08T13:31:11.572Z
Learning: In backend/app/agents/devrel/tools/search_tool.py, the TavilySearchTool.search() method has partial error handling for missing API key, AttributeError, ConnectionError, and TimeoutError, but lacks a comprehensive Exception catch-all block, so calling functions may still need additional error handling for other potential exceptions.
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_web_search_node.py:31-42
Timestamp: 2025-06-08T13:31:11.572Z
Learning: In backend/app/agents/devrel/tools/search_tool.py, the TavilySearchTool.search() method already includes comprehensive error handling that catches all exceptions and returns an empty list instead of raising them, so calling functions don't need additional try-catch blocks.
backend/integrations/discord/bot.py (2)
Learnt from: smokeyScraper
PR: #75
File: backend/app/agents/devrel/agent.py:34-35
Timestamp: 2025-06-13T21:56:19.183Z
Learning: In the Devr.AI backend, the DevRelAgent follows a singleton pattern where only one instance exists for the entire application lifetime, using InMemorySaver with thread-based conversation management to persist user conversations across sessions.
Learnt from: smokeyScraper
PR: #76
File: backend/app/agents/shared/base_agent.py:22-44
Timestamp: 2025-06-14T05:57:43.872Z
Learning: In the Devr.AI codebase, user_id directly maps as thread_id for memory persistence in the agent system, ensuring thread_id is always non-empty and unique per user.
backend/app/agents/devrel/nodes/handlers/faq.py (1)
Learnt from: smokeyScraper
PR: #72
File: backend/app/agents/devrel/nodes/handle_technical_support_node.py:6-17
Timestamp: 2025-06-08T13:15:40.536Z
Learning: The handle_technical_support_node function in backend/app/agents/devrel/nodes/handle_technical_support_node.py is intentionally minimal and will be extended after database configuration is completed.
🔇 Additional comments (5)
pyproject.toml (1)
27-29: All new dependencies are up to date and secure
- discord-py (>=2.5.2,<3.0.0): latest on PyPI is 2.5.2
- duckduckgo-search (>=8.1.1,<9.0.0): latest on PyPI is 8.1.1
- ddgs (>=9.0.2,<10.0.0): latest on PyPI is 9.4.3
- No security advisories found for discord-py; no known vulnerabilities reported for the other packages
No further changes required.
backend/app/agents/devrel/nodes/handlers/web_search.py (2)
38-39: LGTM! Method call updated to use async interface.The change from
search()toarun()correctly aligns with the updated asynchronous DuckDuckGo search tool interface that uses LangChain compatibility.
66-66: Confirm snippet field key in search resultsThe
create_search_responsefunction inbackend/app/agents/devrel/nodes/handlers/web_search.pycurrently does:snippet = result.get('content', 'N/A')By default, DuckDuckGoSearchTool returns the snippet under the
bodykey, notcontent. Please verify whether yoursearch_tool.arun()call remapsbody→content, or update the code to use:snippet = result.get('body', 'N/A')Locations to check:
- File: backend/app/agents/devrel/nodes/handlers/web_search.py
- Function: create_search_response (around line 66)
backend/integrations/discord/bot.py (2)
121-127: LGTM! Excellent thread lifecycle management.The verification of thread existence and cleanup of archived threads is a solid improvement that prevents resource leaks and stale references.
166-171: LGTM! Good message chunking implementation.The message chunking logic properly handles Discord's 2000 character limit with a clean conditional approach.
Closes #97
## 📝 Description
This PR introduces a new node called
thinking_nodeto the LangGraph workflow.Its purpose is to rephrase informal or unclear user queries using Gemini (LLM), making them more structured and suitable for routing to tools like FAQ or Web Search.
This improves overall accuracy and robustness when handling vague, casual, or incomplete questions from users.
🔧 Changes Made
thinking_node_tool_nodetotool_wrappers.pystate.context["rephrased_query"]gather_context➝thinking_node➝react_supervisorinagent.py@smokeyScraper
Summary by CodeRabbit
New Features
Bug Fixes
Chores
✅ Update: Final changes pushed after resolving merge conflicts and verifying bot integration with the backend.
thinking_nodeworks with real-time Discord messagesThese screenshots demonstrate the real-time interaction between the Discord Bot and user messages.
✅ Intelligent Message Handling
When I typed:
"I'm getting a 500 error when calling the API endpoint /predict",
the bot correctly triaged it as high-priority and responded:
"I'm processing your request, please hold on..."
It also automatically created a thread titled:
🧵 DevRel Chat - Prithvijit Bose,
where the conversation continued.
✅ This shows that the bot understands and escalates relevant technical issues for DevRel support.
🚫 Generic Input Ignored
However, when sending vague or informal messages like:
"Hello bot" or "hello",
the bot did not take further action.
It responded with a basic acknowledgment (or nothing), indicating that it didn’t identify any actionable DevRel context.