Spaces:
Running
Running
Commit ·
58c90e6
1
Parent(s): 86ed234
Enhance coder interation and extraction with report route
Browse files- helpers/coder.py +61 -0
- routes/reports.py +8 -1
helpers/coder.py
CHANGED
|
@@ -67,3 +67,64 @@ async def generate_code_artifacts(
|
|
| 67 |
return code_md
|
| 68 |
|
| 69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
return code_md
|
| 68 |
|
| 69 |
|
| 70 |
+
def extract_structured_code(markdown: str):
|
| 71 |
+
"""Extract structured code blocks from the Gemini output.
|
| 72 |
+
|
| 73 |
+
Expects sections like:
|
| 74 |
+
'File: path/to/file.py' followed by a fenced code block and then an explanation paragraph.
|
| 75 |
+
|
| 76 |
+
Returns list of {path, language, code, explanation}.
|
| 77 |
+
"""
|
| 78 |
+
import re
|
| 79 |
+
blocks = []
|
| 80 |
+
if not markdown:
|
| 81 |
+
return blocks
|
| 82 |
+
|
| 83 |
+
# Split on 'File:' headings to locate file sections
|
| 84 |
+
parts = re.split(r"\n(?=File:\s*)", markdown)
|
| 85 |
+
for part in parts:
|
| 86 |
+
part = part.strip()
|
| 87 |
+
if not part.lower().startswith("file:"):
|
| 88 |
+
# The first chunk may be prelude; skip if no code block
|
| 89 |
+
continue
|
| 90 |
+
# Extract path
|
| 91 |
+
m_path = re.match(r"File:\s*(.+)", part)
|
| 92 |
+
file_path = m_path.group(1).strip() if m_path else "unknown"
|
| 93 |
+
|
| 94 |
+
# Extract fenced code block with optional language
|
| 95 |
+
m_code = re.search(r"```([a-zA-Z0-9_+-]*)\n([\s\S]*?)\n```", part)
|
| 96 |
+
language = (m_code.group(1) or '').strip() if m_code else ''
|
| 97 |
+
code = m_code.group(2) if m_code else ''
|
| 98 |
+
|
| 99 |
+
# Remove the matched code from part to find explanation remainder
|
| 100 |
+
explanation = ''
|
| 101 |
+
if m_code:
|
| 102 |
+
start, end = m_code.span()
|
| 103 |
+
# Text after code block is considered explanation
|
| 104 |
+
explanation = part[end:].strip()
|
| 105 |
+
|
| 106 |
+
blocks.append({
|
| 107 |
+
"path": file_path,
|
| 108 |
+
"language": language or detect_language_from_path(file_path),
|
| 109 |
+
"code": code.strip(),
|
| 110 |
+
"explanation": explanation
|
| 111 |
+
})
|
| 112 |
+
return blocks
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def detect_language_from_path(path: str) -> str:
|
| 116 |
+
ext = (path.split('.')[-1].lower() if '.' in path else '')
|
| 117 |
+
return {
|
| 118 |
+
'py': 'python',
|
| 119 |
+
'js': 'javascript',
|
| 120 |
+
'ts': 'typescript',
|
| 121 |
+
'json': 'json',
|
| 122 |
+
'md': 'markdown',
|
| 123 |
+
'html': 'html',
|
| 124 |
+
'css': 'css',
|
| 125 |
+
'sh': 'bash',
|
| 126 |
+
'yml': 'yaml',
|
| 127 |
+
'yaml': 'yaml'
|
| 128 |
+
}.get(ext, '')
|
| 129 |
+
|
| 130 |
+
|
routes/reports.py
CHANGED
|
@@ -10,7 +10,7 @@ from .search import build_web_context
|
|
| 10 |
from helpers.models import ReportResponse, StatusUpdateResponse
|
| 11 |
from utils.service.common import trim_text
|
| 12 |
from utils.api.router import select_model, generate_answer_with_model
|
| 13 |
-
from helpers.coder import generate_code_artifacts
|
| 14 |
from helpers.diagram import should_generate_mermaid, generate_mermaid_diagram
|
| 15 |
|
| 16 |
|
|
@@ -477,6 +477,12 @@ async def execute_detailed_subtasks(cot_plan: Dict[str, Any], context_text: str,
|
|
| 477 |
)
|
| 478 |
# Append code and explanation beneath the analysis
|
| 479 |
subtask_result = subtask_result + "\n\n" + code_markdown
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 480 |
except Exception as ce:
|
| 481 |
logger.warning(f"[REPORT] Code generation failed for {subsection_id}: {ce}")
|
| 482 |
|
|
@@ -498,6 +504,7 @@ async def execute_detailed_subtasks(cot_plan: Dict[str, Any], context_text: str,
|
|
| 498 |
"expected_output": expected_output,
|
| 499 |
"quality_checks": quality_checks,
|
| 500 |
"analysis": subtask_result,
|
|
|
|
| 501 |
"agent_context": agent_context.copy()
|
| 502 |
})
|
| 503 |
|
|
|
|
| 10 |
from helpers.models import ReportResponse, StatusUpdateResponse
|
| 11 |
from utils.service.common import trim_text
|
| 12 |
from utils.api.router import select_model, generate_answer_with_model
|
| 13 |
+
from helpers.coder import generate_code_artifacts, extract_structured_code
|
| 14 |
from helpers.diagram import should_generate_mermaid, generate_mermaid_diagram
|
| 15 |
|
| 16 |
|
|
|
|
| 477 |
)
|
| 478 |
# Append code and explanation beneath the analysis
|
| 479 |
subtask_result = subtask_result + "\n\n" + code_markdown
|
| 480 |
+
# Parse structured code for indexing and downstream usage
|
| 481 |
+
try:
|
| 482 |
+
code_blocks = extract_structured_code(code_markdown)
|
| 483 |
+
except Exception as pe:
|
| 484 |
+
logger.warning(f"[REPORT] Failed to parse structured code for {subsection_id}: {pe}")
|
| 485 |
+
code_blocks = []
|
| 486 |
except Exception as ce:
|
| 487 |
logger.warning(f"[REPORT] Code generation failed for {subsection_id}: {ce}")
|
| 488 |
|
|
|
|
| 504 |
"expected_output": expected_output,
|
| 505 |
"quality_checks": quality_checks,
|
| 506 |
"analysis": subtask_result,
|
| 507 |
+
**({"code_blocks": code_blocks} if 'code_blocks' in locals() else {}),
|
| 508 |
"agent_context": agent_context.copy()
|
| 509 |
})
|
| 510 |
|