Spaces:
Running
Running
Update app/main.py
Browse files- app/main.py +5 -11
app/main.py
CHANGED
|
@@ -62,8 +62,13 @@ def sync_review_worker(file_list: List[FileRequest]):
|
|
| 62 |
def parse_tree_to_list(raw_tree: str):
|
| 63 |
nodes = []
|
| 64 |
for line in raw_tree.strip().split('\n'):
|
|
|
|
|
|
|
| 65 |
level = line.count('|') + (line.count(' ') // 2)
|
|
|
|
| 66 |
name = re.sub(r'[|└├─]', '', line).strip()
|
|
|
|
|
|
|
| 67 |
if name:
|
| 68 |
nodes.append({
|
| 69 |
"name": name,
|
|
@@ -121,28 +126,23 @@ async def get_dashboard_stats(request: BatchReviewRequest):
|
|
| 121 |
raw_reviews = await loop.run_in_executor(executor, sync_review_worker, request.files)
|
| 122 |
if not isinstance(raw_reviews, list):
|
| 123 |
raw_reviews = [raw_reviews]
|
| 124 |
-
|
| 125 |
total_vulns = 0
|
| 126 |
maint_scores = []
|
| 127 |
found_apis = set()
|
| 128 |
api_regex = re.compile(r'(?:get|post|put|delete|patch)\([\'"]\/(.*?)[\'"]', re.IGNORECASE)
|
| 129 |
-
|
| 130 |
for i, current_review in enumerate(raw_reviews):
|
| 131 |
vulns = current_review.get("vulnerabilities", [])
|
| 132 |
total_vulns += len(vulns)
|
| 133 |
m_score = current_review.get("metrics", {}).get("maintainability", 8.0)
|
| 134 |
maint_scores.append(m_score)
|
| 135 |
-
|
| 136 |
content = request.files[i].content if i < len(request.files) else None
|
| 137 |
if content:
|
| 138 |
matches = api_regex.findall(content)
|
| 139 |
for match in matches:
|
| 140 |
found_apis.add(f"/{match}")
|
| 141 |
-
|
| 142 |
num_files = len(maint_scores)
|
| 143 |
avg_maint = (sum(maint_scores) / num_files) if num_files > 0 else 0.0
|
| 144 |
health_score = calculate_repo_health(total_vulns, avg_maint)
|
| 145 |
-
|
| 146 |
return {
|
| 147 |
"repo_health": health_score,
|
| 148 |
"health_label": "Excellent" if health_score > 85 else "Good" if health_score > 60 else "Critical",
|
|
@@ -180,10 +180,8 @@ async def semantic_search(request: SearchRequest):
|
|
| 180 |
embeddings = request.embeddings
|
| 181 |
if not embeddings and request.repoName and request.repoName in REPO_CACHE:
|
| 182 |
embeddings = REPO_CACHE[request.repoName]
|
| 183 |
-
|
| 184 |
if not embeddings:
|
| 185 |
return {"results": []}
|
| 186 |
-
|
| 187 |
results = classifier.semantic_search(request.query, embeddings)
|
| 188 |
return {"results": results}
|
| 189 |
except Exception as e:
|
|
@@ -195,12 +193,10 @@ async def chat(request: ChatRequest):
|
|
| 195 |
context_str = ""
|
| 196 |
for item in request.context:
|
| 197 |
context_str += f"--- FILE: {item['fileName']} ---\n{item['content']}\n\n"
|
| 198 |
-
|
| 199 |
prompt = f"""You are "GitGud AI", an expert software architect.
|
| 200 |
Repository: "{request.repoName}"
|
| 201 |
CONTEXT: {context_str if request.context else "(NO CODE PROVIDED)"}
|
| 202 |
USER QUESTION: {request.query}"""
|
| 203 |
-
|
| 204 |
response = llm_engine.generate_text(prompt)
|
| 205 |
return {"response": response, "status": "success"}
|
| 206 |
except Exception as e:
|
|
@@ -213,11 +209,9 @@ async def generate_guide(request: GuideRequest):
|
|
| 213 |
try:
|
| 214 |
markdown = guide_generator.generate_markdown(request.repoName, request.filePaths)
|
| 215 |
tree_match = re.search(r"Project Structure\n\n(.*?)(?=\n\n|$)", markdown, re.S)
|
| 216 |
-
|
| 217 |
structured_tree = []
|
| 218 |
if tree_match:
|
| 219 |
structured_tree = parse_tree_to_list(tree_match.group(1))
|
| 220 |
-
|
| 221 |
return {
|
| 222 |
"markdown": markdown,
|
| 223 |
"structured_tree": structured_tree,
|
|
|
|
| 62 |
def parse_tree_to_list(raw_tree: str):
|
| 63 |
nodes = []
|
| 64 |
for line in raw_tree.strip().split('\n'):
|
| 65 |
+
if line.startswith("```") or not line.strip():
|
| 66 |
+
continue
|
| 67 |
level = line.count('|') + (line.count(' ') // 2)
|
| 68 |
+
# Strip tree connectors
|
| 69 |
name = re.sub(r'[|└├─]', '', line).strip()
|
| 70 |
+
# Strip AI layer annotations like [Backend] or [Frontend]
|
| 71 |
+
name = re.sub(r'\[.*?\]', '', name).strip()
|
| 72 |
if name:
|
| 73 |
nodes.append({
|
| 74 |
"name": name,
|
|
|
|
| 126 |
raw_reviews = await loop.run_in_executor(executor, sync_review_worker, request.files)
|
| 127 |
if not isinstance(raw_reviews, list):
|
| 128 |
raw_reviews = [raw_reviews]
|
|
|
|
| 129 |
total_vulns = 0
|
| 130 |
maint_scores = []
|
| 131 |
found_apis = set()
|
| 132 |
api_regex = re.compile(r'(?:get|post|put|delete|patch)\([\'"]\/(.*?)[\'"]', re.IGNORECASE)
|
|
|
|
| 133 |
for i, current_review in enumerate(raw_reviews):
|
| 134 |
vulns = current_review.get("vulnerabilities", [])
|
| 135 |
total_vulns += len(vulns)
|
| 136 |
m_score = current_review.get("metrics", {}).get("maintainability", 8.0)
|
| 137 |
maint_scores.append(m_score)
|
|
|
|
| 138 |
content = request.files[i].content if i < len(request.files) else None
|
| 139 |
if content:
|
| 140 |
matches = api_regex.findall(content)
|
| 141 |
for match in matches:
|
| 142 |
found_apis.add(f"/{match}")
|
|
|
|
| 143 |
num_files = len(maint_scores)
|
| 144 |
avg_maint = (sum(maint_scores) / num_files) if num_files > 0 else 0.0
|
| 145 |
health_score = calculate_repo_health(total_vulns, avg_maint)
|
|
|
|
| 146 |
return {
|
| 147 |
"repo_health": health_score,
|
| 148 |
"health_label": "Excellent" if health_score > 85 else "Good" if health_score > 60 else "Critical",
|
|
|
|
| 180 |
embeddings = request.embeddings
|
| 181 |
if not embeddings and request.repoName and request.repoName in REPO_CACHE:
|
| 182 |
embeddings = REPO_CACHE[request.repoName]
|
|
|
|
| 183 |
if not embeddings:
|
| 184 |
return {"results": []}
|
|
|
|
| 185 |
results = classifier.semantic_search(request.query, embeddings)
|
| 186 |
return {"results": results}
|
| 187 |
except Exception as e:
|
|
|
|
| 193 |
context_str = ""
|
| 194 |
for item in request.context:
|
| 195 |
context_str += f"--- FILE: {item['fileName']} ---\n{item['content']}\n\n"
|
|
|
|
| 196 |
prompt = f"""You are "GitGud AI", an expert software architect.
|
| 197 |
Repository: "{request.repoName}"
|
| 198 |
CONTEXT: {context_str if request.context else "(NO CODE PROVIDED)"}
|
| 199 |
USER QUESTION: {request.query}"""
|
|
|
|
| 200 |
response = llm_engine.generate_text(prompt)
|
| 201 |
return {"response": response, "status": "success"}
|
| 202 |
except Exception as e:
|
|
|
|
| 209 |
try:
|
| 210 |
markdown = guide_generator.generate_markdown(request.repoName, request.filePaths)
|
| 211 |
tree_match = re.search(r"Project Structure\n\n(.*?)(?=\n\n|$)", markdown, re.S)
|
|
|
|
| 212 |
structured_tree = []
|
| 213 |
if tree_match:
|
| 214 |
structured_tree = parse_tree_to_list(tree_match.group(1))
|
|
|
|
| 215 |
return {
|
| 216 |
"markdown": markdown,
|
| 217 |
"structured_tree": structured_tree,
|