107 lines
3.3 KiB
Python
107 lines
3.3 KiB
Python
"""
|
|
JSON renderer for report generation.
|
|
"""
|
|
|
|
from .base_renderer import BaseRenderer
|
|
from typing import Dict, Any, Tuple, List
|
|
import json
|
|
|
|
class JsonRenderer(BaseRenderer):
|
|
"""Renders content to JSON format with format-specific extraction."""
|
|
|
|
@classmethod
|
|
def get_supported_formats(cls) -> List[str]:
|
|
"""Return supported JSON formats."""
|
|
return ['json']
|
|
|
|
@classmethod
|
|
def get_format_aliases(cls) -> List[str]:
|
|
"""Return format aliases."""
|
|
return ['data']
|
|
|
|
@classmethod
|
|
def get_priority(cls) -> int:
|
|
"""Return priority for JSON renderer."""
|
|
return 80
|
|
|
|
def getExtractionPrompt(self, user_prompt: str, title: str) -> str:
|
|
"""Get JSON-specific extraction prompt."""
|
|
return f"""
|
|
{user_prompt}
|
|
|
|
Generate a comprehensive JSON report with the title: "{title}"
|
|
|
|
JSON STRUCTURE REQUIREMENTS:
|
|
- Create a well-structured JSON object
|
|
- Include title, sections, and metadata
|
|
- Use proper JSON syntax and formatting
|
|
- Include source document information
|
|
- Add generation timestamps
|
|
- Structure data logically
|
|
|
|
JSON SCHEMA:
|
|
{{
|
|
"title": "Report Title",
|
|
"sections": [
|
|
{{
|
|
"type": "text|table|list|summary",
|
|
"heading": "Section Heading",
|
|
"content": "Section content",
|
|
"metadata": {{"source": "document_name", "page": 1}}
|
|
}}
|
|
],
|
|
"metadata": {{
|
|
"totalDocuments": number,
|
|
"processedDocuments": number,
|
|
"generatedAt": "timestamp",
|
|
"summary": "Brief report summary"
|
|
}}
|
|
}}
|
|
|
|
OUTPUT POLICY:
|
|
- Return ONLY valid JSON
|
|
- No markdown, no code blocks, no additional text
|
|
- Properly formatted and indented
|
|
- Include all necessary information
|
|
- Valid JSON that can be parsed
|
|
|
|
Generate the complete JSON report:
|
|
"""
|
|
|
|
async def render(self, extracted_content: str, title: str) -> Tuple[str, str]:
|
|
"""Render extracted content to JSON format."""
|
|
try:
|
|
# The extracted content should already be JSON from the AI
|
|
# Just validate and format it
|
|
json_content = self._clean_json_content(extracted_content, title)
|
|
|
|
return json_content, "application/json"
|
|
|
|
except Exception as e:
|
|
self.logger.error(f"Error rendering JSON: {str(e)}")
|
|
# Return minimal JSON fallback
|
|
fallback_data = {
|
|
"title": title,
|
|
"sections": [{"type": "text", "content": f"Error rendering report: {str(e)}"}],
|
|
"metadata": {"error": str(e)}
|
|
}
|
|
return json.dumps(fallback_data, indent=2), "application/json"
|
|
|
|
def _clean_json_content(self, content: str, title: str) -> str:
|
|
"""Clean and validate JSON content from AI."""
|
|
content = content.strip()
|
|
|
|
# Remove markdown code blocks if present
|
|
if content.startswith("```") and content.endswith("```"):
|
|
lines = content.split('\n')
|
|
if len(lines) > 2:
|
|
content = '\n'.join(lines[1:-1]).strip()
|
|
|
|
# Validate JSON
|
|
try:
|
|
parsed = json.loads(content)
|
|
# Re-format with proper indentation
|
|
return json.dumps(parsed, indent=2, ensure_ascii=False)
|
|
except json.JSONDecodeError:
|
|
# If not valid JSON, return as-is
|
|
return content
|