11import logging
2+ import os
3+ import json
4+ import re
25from typing import Dict , Any
36from langchain_google_genai import ChatGoogleGenerativeAI
47from langchain_core .messages import HumanMessage
58from app .core .config import settings
69from .prompts .intent_analysis import GITHUB_INTENT_ANALYSIS_PROMPT
710from .tools .search import handle_web_search
8- # TODO: Implement all tools
11+ from . tools . github_support import handle_github_supp
912from .tools .contributor_recommendation import handle_contributor_recommendation
10- # from .tools.repository_query import handle_repo_query
11- # from .tools.issue_creation import handle_issue_creation
12- # from .tools.documentation_generation import handle_documentation_generation
1313from .tools .general_github_help import handle_general_github_help
14+
1415logger = logging .getLogger (__name__ )
1516
17+ DEFAULT_ORG = os .getenv ("GITHUB_ORG" )
18+
19+
20+ def normalize_org (org_from_user : str = None ) -> str :
21+ """Fallback to env org if user does not specify one."""
22+ if org_from_user and org_from_user .strip ():
23+ return org_from_user .strip ()
24+ return DEFAULT_ORG
25+
1626
1727class GitHubToolkit :
1828 """
@@ -32,30 +42,37 @@ def __init__(self):
3242 "web_search" ,
3343 "contributor_recommendation" ,
3444 "repo_support" ,
45+ "github_support" ,
3546 "issue_creation" ,
3647 "documentation_generation" ,
3748 "find_good_first_issues" ,
3849 "general_github_help"
3950 ]
4051
4152 async def classify_intent (self , user_query : str ) -> Dict [str , Any ]:
42- """
43- Classify intent and return classification with reasoning.
44-
45- Args:
46- user_query: The user's request or question
47-
48- Returns:
49- Dictionary containing classification, reasoning, and confidence
50- """
53+ """Classify intent and return classification with reasoning."""
5154 logger .info (f"Classifying intent for query: { user_query [:100 ]} " )
5255
5356 try :
5457 prompt = GITHUB_INTENT_ANALYSIS_PROMPT .format (user_query = user_query )
5558 response = await self .llm .ainvoke ([HumanMessage (content = prompt )])
5659
57- import json
58- result = json .loads (response .content .strip ())
60+ content = response .content .strip ()
61+
62+ try :
63+ result = json .loads (content )
64+ except json .JSONDecodeError :
65+ match = re .search (r"\{.*\}" , content , re .DOTALL )
66+ if match :
67+ result = json .loads (match .group ())
68+ else :
69+ logger .error (f"Invalid JSON in LLM response: { content } " )
70+ return {
71+ "classification" : "general_github_help" ,
72+ "reasoning" : "Failed to parse LLM response as JSON" ,
73+ "confidence" : "low" ,
74+ "query" : user_query
75+ }
5976
6077 classification = result .get ("classification" )
6178 if classification not in self .tools :
@@ -65,21 +82,12 @@ async def classify_intent(self, user_query: str) -> Dict[str, Any]:
6582
6683 result ["query" ] = user_query
6784
68- logger .info (f"Classified intent as for query: { user_query } is: { classification } " )
85+ logger .info (f"Classified intent for query: { user_query } -> { classification } " )
6986 logger .info (f"Reasoning: { result .get ('reasoning' , 'No reasoning provided' )} " )
7087 logger .info (f"Confidence: { result .get ('confidence' , 'unknown' )} " )
7188
7289 return result
7390
74- except json .JSONDecodeError as e :
75- logger .error (f"Error parsing JSON response from LLM: { str (e )} " )
76- logger .error (f"Raw response: { response .content } " )
77- return {
78- "classification" : "general_github_help" ,
79- "reasoning" : f"Failed to parse LLM response: { str (e )} " ,
80- "confidence" : "low" ,
81- "query" : user_query
82- }
8391 except Exception as e :
8492 logger .error (f"Error in intent classification: { str (e )} " )
8593 return {
@@ -90,9 +98,7 @@ async def classify_intent(self, user_query: str) -> Dict[str, Any]:
9098 }
9199
92100 async def execute (self , query : str ) -> Dict [str , Any ]:
93- """
94- Main execution method - classifies intent and delegates to appropriate tools
95- """
101+ """Main execution method - classifies intent and delegates to appropriate tools"""
96102 logger .info (f"Executing GitHub toolkit for query: { query [:100 ]} " )
97103
98104 try :
@@ -103,15 +109,16 @@ async def execute(self, query: str) -> Dict[str, Any]:
103109
104110 if classification == "contributor_recommendation" :
105111 result = await handle_contributor_recommendation (query )
112+ elif classification == "github_support" :
113+ org = normalize_org ()
114+ result = await handle_github_supp (query , org = org )
115+ result ["org_used" ] = org
106116 elif classification == "repo_support" :
107117 result = "Not implemented"
108- # result = await handle_repo_query(query)
109118 elif classification == "issue_creation" :
110119 result = "Not implemented"
111- # result = await handle_issue_creation(query)
112120 elif classification == "documentation_generation" :
113121 result = "Not implemented"
114- # result = await handle_documentation_generation(query)
115122 elif classification == "web_search" :
116123 result = await handle_web_search (query )
117124 else :
0 commit comments