-
Notifications
You must be signed in to change notification settings - Fork 132
feat: Implement Enhanced FAQ Handler with Web Search for Organization… #100
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: Implement Enhanced FAQ Handler with Web Search for Organization… #100
Conversation
…al Queries (AOSSIE-Org#97) ✨ Features: - Enhanced FAQ Tool with intelligent organizational query detection - Dynamic web search for current organizational information - LLM-powered response synthesis from official sources - Source attribution with clear citations - Backward compatibility with existing FAQ responses 🔧 Architecture: - Created EnhancedFAQTool with pattern-based query classification - Added organizational FAQ handler with LLM synthesis - Enhanced ReAct supervisor for better query routing - Comprehensive prompts for query detection and synthesis 📝 Implementation: - Detects organizational queries using regex patterns and keywords - Generates targeted search queries for official sources - Uses Tavily Search API for web search capabilities - Synthesizes responses using Gemini LLM - Maintains fallback mechanisms for reliability 🎯 Addresses: - Dynamic organizational information retrieval - Reduces manual FAQ maintenance overhead - Provides up-to-date information from official sources - Maintains existing technical FAQ functionality Resolves AOSSIE-Org#97
|
""" WalkthroughThis update introduces an enhanced FAQ system for the DevRel agent, integrating a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DevRelAgent
participant FAQTool
participant EnhancedFAQTool
participant TavilySearchTool
participant LLM
User->>DevRelAgent: Ask FAQ (possibly organizational)
DevRelAgent->>FAQTool: get_enhanced_response(question)
FAQTool->>EnhancedFAQTool: get_response(question)
alt Organizational query
EnhancedFAQTool->>TavilySearchTool: web search (async)
TavilySearchTool-->>EnhancedFAQTool: search results
EnhancedFAQTool->>LLM: Synthesize answer (if handler invoked)
LLM-->>EnhancedFAQTool: synthesized response
EnhancedFAQTool-->>FAQTool: structured response (type, answer, sources)
else Static FAQ
EnhancedFAQTool-->>FAQTool: static answer
end
FAQTool-->>DevRelAgent: structured response or fallback
DevRelAgent-->>User: Present answer with metadata and sources
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
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 (
|
|
@smokeyScraper please have a look |
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: 6
🧹 Nitpick comments (5)
backend/app/agents/devrel/nodes/handlers/organizational_faq.py (1)
32-36: Simplify message extraction logic.The current logic for extracting the latest message has redundant conditions and could be more robust.
- 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 = ( + state.messages[-1].get("content", "") if state.messages + else state.context.get("original_message", "") + )backend/app/agents/devrel/prompts/organizational_faq_prompt.py (1)
50-51: Consider adding validation for JSON format.The search query generation prompt expects JSON format but doesn't include error handling instructions for malformed responses.
Format your response as a JSON list of strings: -["query1", "query2", "query3"] +["query1", "query2", "query3"] + +Important: Ensure the response is valid JSON. If uncertain, provide exactly 2-3 queries in the specified format.ENHANCED_FAQ_IMPLEMENTATION.md (3)
142-142: Fix compound adjective formatting.The term "open source" should be hyphenated when used as a compound adjective.
-2. Generates search queries: "Devr.AI open source projects", "Devr.AI GitHub repositories" +2. Generates search queries: "Devr.AI open-source projects", "Devr.AI GitHub repositories"
148-156: Add language specification to code blocks.The fenced code blocks should specify the language for proper syntax highlighting.
-**Output**: -``` +**Output**: +```markdown Devr.AI primarily focuses on creating tools for developer relations (DevRel), including AI-powered assistants for community engagement, issue triage, and onboarding. You can explore our main projects on our official website and GitHub page.
166-170: Add language specification to code blocks.This code block also needs language specification for proper syntax highlighting.
**Output**: -``` +```markdown You can contribute by visiting our GitHub repository, checking open issues, and submitting pull requests. We welcome all types of contributions including code, documentation, and bug reports.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
ENHANCED_FAQ_IMPLEMENTATION.md(1 hunks)backend/app/agents/devrel/agent.py(1 hunks)backend/app/agents/devrel/nodes/handlers/faq.py(2 hunks)backend/app/agents/devrel/nodes/handlers/organizational_faq.py(1 hunks)backend/app/agents/devrel/prompts/organizational_faq_prompt.py(1 hunks)backend/app/agents/devrel/prompts/react_prompt.py(1 hunks)backend/app/agents/devrel/tools/enhanced_faq_tool.py(1 hunks)backend/app/agents/devrel/tools/faq_tool.py(1 hunks)
🧰 Additional context used
🧠 Learnings (5)
backend/app/agents/devrel/tools/faq_tool.py (2)
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#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: AOSSIE-Org/Devr.AI#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/tools/enhanced_faq_tool.py (2)
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#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: AOSSIE-Org/Devr.AI#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/nodes/handlers/organizational_faq.py (1)
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/faq.py (1)
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 (3)
Learnt from: smokeyScraper
PR: AOSSIE-Org/Devr.AI#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: 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_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.
🧬 Code Graph Analysis (2)
backend/app/agents/devrel/tools/faq_tool.py (2)
backend/app/agents/devrel/tools/enhanced_faq_tool.py (3)
EnhancedFAQTool(8-231)get_response(177-223)_is_similar_question(225-231)backend/app/agents/devrel/tools/search_tool.py (1)
TavilySearchTool(10-52)
backend/app/agents/devrel/tools/enhanced_faq_tool.py (1)
backend/app/agents/devrel/tools/search_tool.py (1)
TavilySearchTool(10-52)
🪛 Ruff (0.11.9)
backend/app/agents/devrel/tools/faq_tool.py
43-43: SyntaxError: Expected except or finally after try block
46-46: SyntaxError: Unexpected indentation
50-50: SyntaxError: unindent does not match any outer indentation level
56-56: SyntaxError: Expected a statement
56-56: SyntaxError: Expected a statement
56-57: SyntaxError: Expected an expression
57-57: SyntaxError: Unexpected indentation
🪛 LanguageTool
ENHANCED_FAQ_IMPLEMENTATION.md
[uncategorized] ~142-~142: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...y 2. Generates search queries: "Devr.AI open source projects", "Devr.AI GitHub repositories...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
🪛 markdownlint-cli2 (0.17.2)
ENHANCED_FAQ_IMPLEMENTATION.md
148-148: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
166-166: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (5)
backend/app/agents/devrel/agent.py (1)
31-31: LGTM!The integration of search_tool into FAQTool enables the enhanced FAQ capabilities as intended.
backend/app/agents/devrel/prompts/react_prompt.py (1)
16-38: Well-structured prompt enhancements!The updated descriptions clearly differentiate between web search for external information and the enhanced FAQ handler for organizational/technical queries. The detailed capabilities section and action selection guidelines will help the ReAct supervisor make better routing decisions.
backend/app/agents/devrel/nodes/handlers/faq.py (1)
17-92: Excellent error handling and fallback implementation!The enhanced FAQ handler properly manages the transition from simple to enhanced responses with:
- Comprehensive error handling with nested try-except blocks
- Structured response format with rich metadata
- Graceful fallback to simple responses
- Detailed logging for monitoring
backend/app/agents/devrel/prompts/organizational_faq_prompt.py (1)
1-101: Excellent prompt design and structure.The prompt templates are well-crafted with clear instructions, good examples, and comprehensive coverage of different scenarios. The modular approach with separate prompts for detection, search query generation, synthesis, and fallback is excellent architecture.
ENHANCED_FAQ_IMPLEMENTATION.md (1)
1-223: Excellent comprehensive documentation.This documentation provides outstanding coverage of the enhanced FAQ implementation, including architecture, workflow, examples, and configuration details. The structure is clear and logical, making it easy for developers to understand and implement the system.
| def _synthesize_organizational_response(self, question: str, search_results: List[Dict[str, Any]]) -> str: | ||
| """Create a synthesized response from search results""" | ||
| if not search_results: | ||
| return self._get_fallback_response(question) | ||
|
|
||
| # Extract relevant information from search results | ||
| response_parts = [] | ||
| sources = [] | ||
|
|
||
| for result in search_results[:3]: # Use top 3 results | ||
| title = result.get('title', '') | ||
| content = result.get('content', '') | ||
| url = result.get('url', '') | ||
|
|
||
| if content and len(content) > 50: # Only use substantial content | ||
| # Take first 200 characters of content | ||
| snippet = content[:200] + "..." if len(content) > 200 else content | ||
| response_parts.append(snippet) | ||
| sources.append({"title": title, "url": url}) | ||
|
|
||
| if response_parts: | ||
| synthesized_answer = " ".join(response_parts) | ||
| return synthesized_answer | ||
| else: | ||
| return self._get_fallback_response(question) | ||
|
|
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.
🛠️ Refactor suggestion
Consider implementing LLM-based synthesis as mentioned in PR objectives.
The current implementation concatenates search result snippets, which may produce disjointed responses. According to the PR objectives, the system should use "LLM enhanced synthesis of search results into comprehensive answers."
The current simple concatenation approach might work for MVP, but for better coherence, consider:
- Passing search results to an LLM for synthesis
- Using a prompt template to guide the LLM in creating coherent responses
- Integrating with the organizational FAQ handler that may already have LLM synthesis
This would align with the architectural design mentioned in the PR summary.
🤖 Prompt for AI Agents
In backend/app/agents/devrel/tools/enhanced_faq_tool.py around lines 144 to 169,
the current method concatenates search result snippets directly, which can lead
to disjointed answers. To fix this, replace the concatenation logic by passing
the top search results to an LLM for synthesis using a prompt template that
guides the LLM to generate a coherent, comprehensive response. Integrate this
with the existing organizational FAQ handler's LLM synthesis functionality to
align with the PR objectives and architectural design.
| def _format_search_results_for_llm(search_results: List[Dict[str, Any]]) -> str: | ||
| """Format search results for LLM synthesis""" | ||
| if not search_results: | ||
| return "No search results available." | ||
|
|
||
| formatted_parts = [] | ||
| for i, result in enumerate(search_results, 1): | ||
| title = result.get('title', 'No title') | ||
| url = result.get('url', 'No URL') | ||
| content = result.get('content', 'No content available') | ||
|
|
||
| formatted_part = f""" | ||
| Result {i}: | ||
| Title: {title} | ||
| URL: {url} | ||
| Content: {content[:500]}{"..." if len(content) > 500 else ""} | ||
| """ | ||
| formatted_parts.append(formatted_part) | ||
|
|
||
| return "\n".join(formatted_parts) |
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.
🛠️ Refactor suggestion
Add input validation for search results.
The function should validate the structure of search results to prevent runtime errors.
def _format_search_results_for_llm(search_results: List[Dict[str, Any]]) -> str:
"""Format search results for LLM synthesis"""
if not search_results:
return "No search results available."
+
+ if not isinstance(search_results, list):
+ logger.warning("Search results is not a list, returning empty message")
+ return "No search results available."
formatted_parts = []
for i, result in enumerate(search_results, 1):
+ if not isinstance(result, dict):
+ logger.warning(f"Invalid search result format at index {i-1}")
+ continue
+
title = result.get('title', 'No title')
url = result.get('url', 'No URL')
content = result.get('content', 'No content available')📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _format_search_results_for_llm(search_results: List[Dict[str, Any]]) -> str: | |
| """Format search results for LLM synthesis""" | |
| if not search_results: | |
| return "No search results available." | |
| formatted_parts = [] | |
| for i, result in enumerate(search_results, 1): | |
| title = result.get('title', 'No title') | |
| url = result.get('url', 'No URL') | |
| content = result.get('content', 'No content available') | |
| formatted_part = f""" | |
| Result {i}: | |
| Title: {title} | |
| URL: {url} | |
| Content: {content[:500]}{"..." if len(content) > 500 else ""} | |
| """ | |
| formatted_parts.append(formatted_part) | |
| return "\n".join(formatted_parts) | |
| def _format_search_results_for_llm(search_results: List[Dict[str, Any]]) -> str: | |
| """Format search results for LLM synthesis""" | |
| if not search_results: | |
| return "No search results available." | |
| if not isinstance(search_results, list): | |
| logger.warning("Search results is not a list, returning empty message") | |
| return "No search results available." | |
| formatted_parts = [] | |
| for i, result in enumerate(search_results, 1): | |
| if not isinstance(result, dict): | |
| logger.warning(f"Invalid search result format at index {i-1}") | |
| continue | |
| title = result.get('title', 'No title') | |
| url = result.get('url', 'No URL') | |
| content = result.get('content', 'No content available') | |
| formatted_part = f""" | |
| Result {i}: | |
| Title: {title} | |
| URL: {url} | |
| Content: {content[:500]}{"..." if len(content) > 500 else ""} | |
| """ | |
| formatted_parts.append(formatted_part) | |
| return "\n".join(formatted_parts) |
🤖 Prompt for AI Agents
In backend/app/agents/devrel/nodes/handlers/organizational_faq.py around lines
85 to 104, the function _format_search_results_for_llm lacks input validation
for the search_results parameter. Add validation to ensure search_results is a
list of dictionaries and each dictionary contains the expected keys ('title',
'url', 'content') with appropriate types. If validation fails, handle it
gracefully by either returning a default message or raising a clear error to
prevent runtime exceptions.
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.
Please address all the changes as requested by coderabbit and would be great if you could please attach a few interactions with these all changes.
ENHANCED_FAQ_IMPLEMENTATION.md
Outdated
| @@ -0,0 +1,223 @@ | |||
| # Enhanced FAQ Handler with Web Search for Organizational Queries | |||
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.
this is not needed.
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 have successfully deleted this file
e9eae23 to
33e2924
Compare
|
Here is some interaction !! @smokeyScraper |
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.
Please align out in a bit of generalized way with minimal possible nodes and a thinking agent. Not just a flow that aligns thinking. I'll try documenting a bit on how this is needed. Will update in Notion itself. And please make sure to attach a mermaid diagram for the flow.
| faq_response = await enhanced_faq_tool.get_response(latest_message) | ||
|
|
||
| # If it's an organizational query, enhance with LLM synthesis | ||
| if faq_response.get("type") == "organizational_faq": |
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 don't think there is any need for segregation of FAQ types as long as they get answered, right? I mean the node itself should be able to determine out on it's own whether this search result is enough for answering on not?
|
|
||
| return "\n".join(formatted_parts) | ||
|
|
||
| def create_organizational_response(task_result: Dict[str, Any]) -> str: |
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.
not very much sure on this too. This seems very much like aligning a separate function for a separate response, but I think the LLM can directly align the response.
| - TECHNICAL: Questions about how to use the product, troubleshooting, implementation details, | ||
| contribution guidelines, specific feature requests | ||
|
|
||
| Examples of ORGANIZATIONAL questions: |
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.
These are very much aligned with DevR. We want a generalized handler as this product will be used by an organization that will have multiple repos and not just DevR.
| User Question: "{question}" | ||
|
|
||
| Guidelines for search queries: | ||
| 1. Include "Devr.AI" in each query |
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.
any clarifications on this? Why DevR need to be in each query?
| @@ -0,0 +1,101 @@ | |||
| # Prompts for organizational FAQ handling and synthesis | |||
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.
These much of prompts are very much overhead. As of now, one query takes at max 4-5 calls for the model (with proper thinking, tool usage, results alignment, and whole workflow), and including all these would be very heavy on the API usage part. The interaction can go back and forth between two nodes (cycle) and does not need to be aligned in a flow-based way.
| self.search_tool = search_tool or TavilySearchTool() | ||
|
|
||
| # Static FAQ responses for technical questions | ||
| self.technical_faq_responses = { |
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.
This is not needed. Let the model handle the whole of the response part. This hard coding won't work with a system in production.
| } | ||
|
|
||
| # Patterns that indicate organizational queries | ||
| self.organizational_patterns = [ |
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.
Same here.
|
|
||
| return has_org_keyword and has_question_keyword | ||
|
|
||
| def _generate_search_queries(self, question: str) -> List[str]: |
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.
No need to generate questions in this way. Just a thinking node to align the best out of the whole prompt is needed. Rest this thinking node will be forming a cycle with nodes handling the response/below ones, so it'll just align queries on its own.
| else: | ||
| return self._get_fallback_response(question) | ||
|
|
||
| def _get_fallback_response(self, question: str) -> str: |
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.
Seems very much hard-coded to DevR, this fallback isn't needed. Better to let the user know the service is down.
| self.enhanced_faq_tool = EnhancedFAQTool(search_tool) | ||
|
|
||
| # Legacy FAQ responses for backward compatibility | ||
| self.legacy_faq_responses = { |
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.
same here, hard-coded stuff.
|
Please follow this, |
|
closing this PR @Aditya30ag as commits are not well aligned with the requirements and this requires heavy changes. It would be better for you to start from scratch after a brief discussion with me and with contributors who prefer to work on the issue. |





Enhanced FAQ Handler with Web Search for Organizational Queries
#97
Overview
This implementation fulfills the feature request for an enhanced FAQ Handler that leverages web search to answer general, high-level questions about the Devr.AI organization. The system provides dynamic, up-to-date information by searching official sources and synthesizing comprehensive responses.
Features Implemented
🌟 Core Capabilities
🔍 Organizational Query Detection
The system recognizes queries such as:
🎯 Technical Query Support
Maintains support for existing technical FAQs:
Architecture
Components Created
Enhanced FAQ Tool (
enhanced_faq_tool.py)Organizational FAQ Handler (
organizational_faq.py)Enhanced Prompts (
organizational_faq_prompt.py)Updated Components
faq_tool.pyto use enhanced functionalityfaq.pyhandler with enhanced response handlingWorkflow
Step 1: Query Reception
User asks a question → FAQ Handler receives the query
Step 2: Query Classification
Step 3: Search Query Generation
Step 4: Web Search Execution
Step 5: Response Synthesis
Step 6: Response Delivery
{ "status": "success", "answer": "Devr.AI primarily focuses on creating tools for developer relations...", "sources": [ {"title": "Devr.AI - Official Website", "url": "https://devr.ai/projects"}, {"title": "Devr.AI on GitHub", "url": "https://github.com/AOSSIE-Org/Devr.AI"} ], "type": "organizational_faq" }Integration Points
ReAct Supervisor Integration
The ReAct supervisor now intelligently routes organizational queries to the FAQ handler:
Backward Compatibility
Key Files Modified/Created
New Files
backend/app/agents/devrel/tools/enhanced_faq_tool.pybackend/app/agents/devrel/nodes/handlers/organizational_faq.pybackend/app/agents/devrel/prompts/organizational_faq_prompt.pyModified Files
backend/app/agents/devrel/tools/faq_tool.pybackend/app/agents/devrel/nodes/handlers/faq.pybackend/app/agents/devrel/prompts/react_prompt.pybackend/app/agents/devrel/agent.pyUsage Examples
Organizational Query
Input: "What kind of projects does Devr.AI work on?"
Process:
Output:
Technical Query
Input: "How do I contribute to Devr.AI?"
Process:
Output:
Configuration
Environment Variables Required
TAVILY_API_KEY: For web search functionalityGEMINI_API_KEY: For LLM-powered synthesisDependencies
tavily-python: Web search API clientlangchain-google-genai: LLM integrationlanggraph: Agent workflow frameworkBenefits
🚀 Dynamic Information
🎯 Accuracy
📈 Scalability
🔧 Maintainability
Testing
The implementation includes:
Future Enhancements
Potential improvements could include:
This implementation successfully transforms the FAQ Handler from a static knowledge base into a dynamic, intelligent system that can provide current, accurate information about the Devr.AI organization while maintaining all existing functionality.
Summary by CodeRabbit
New Features
Improvements
Bug Fixes