From 972884098acb619b71a914561e410abe2e40dd98 Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Sun, 12 Oct 2025 00:51:53 +0200 Subject: [PATCH] all renderers using json --- .../renderers/rendererHtml.py | 84 ++++--------------- 1 file changed, 18 insertions(+), 66 deletions(-) diff --git a/modules/services/serviceGeneration/renderers/rendererHtml.py b/modules/services/serviceGeneration/renderers/rendererHtml.py index 03d3c9fd..79d9df1e 100644 --- a/modules/services/serviceGeneration/renderers/rendererHtml.py +++ b/modules/services/serviceGeneration/renderers/rendererHtml.py @@ -99,73 +99,25 @@ class RendererHtml(BaseRenderer): async def _get_html_styles(self, user_prompt: str, ai_service=None) -> Dict[str, Any]: """Get HTML styling definitions using base template AI styling.""" - if not ai_service: - return self._get_default_html_styles() + style_schema = { + "title": {"font_size": "2.5em", "color": "#1F4E79", "font_weight": "bold", "text_align": "center", "margin": "0 0 1em 0"}, + "heading1": {"font_size": "2em", "color": "#2F2F2F", "font_weight": "bold", "text_align": "left", "margin": "1.5em 0 0.5em 0"}, + "heading2": {"font_size": "1.5em", "color": "#4F4F4F", "font_weight": "bold", "text_align": "left", "margin": "1em 0 0.5em 0"}, + "paragraph": {"font_size": "1em", "color": "#2F2F2F", "font_weight": "normal", "text_align": "left", "margin": "0 0 1em 0", "line_height": "1.6"}, + "table": {"border": "1px solid #ddd", "border_collapse": "collapse", "width": "100%", "margin": "1em 0"}, + "table_header": {"background": "#4F4F4F", "color": "#FFFFFF", "font_weight": "bold", "text_align": "center", "padding": "12px"}, + "table_cell": {"background": "#FFFFFF", "color": "#2F2F2F", "font_weight": "normal", "text_align": "left", "padding": "8px", "border": "1px solid #ddd"}, + "bullet_list": {"font_size": "1em", "color": "#2F2F2F", "margin": "0 0 1em 0", "padding_left": "20px"}, + "code_block": {"font_family": "Courier New, monospace", "font_size": "0.9em", "color": "#2F2F2F", "background": "#F5F5F5", "padding": "1em", "border": "1px solid #ddd", "border_radius": "4px", "margin": "1em 0"}, + "image": {"max_width": "100%", "height": "auto", "margin": "1em 0", "border_radius": "4px"}, + "body": {"font_family": "Arial, sans-serif", "background": "#FFFFFF", "color": "#2F2F2F", "margin": "0", "padding": "20px"} + } - try: - prompt = f"""Return this exact JSON structure with your styling customizations: - -{{ - "title": {{"font_size": "2.5em", "color": "#1F4E79", "font_weight": "bold", "text_align": "center", "margin": "0 0 1em 0"}}, - "heading1": {{"font_size": "2em", "color": "#2F2F2F", "font_weight": "bold", "text_align": "left", "margin": "1.5em 0 0.5em 0"}}, - "heading2": {{"font_size": "1.5em", "color": "#4F4F4F", "font_weight": "bold", "text_align": "left", "margin": "1em 0 0.5em 0"}}, - "paragraph": {{"font_size": "1em", "color": "#2F2F2F", "font_weight": "normal", "text_align": "left", "margin": "0 0 1em 0", "line_height": "1.6"}}, - "table": {{"border": "1px solid #ddd", "border_collapse": "collapse", "width": "100%", "margin": "1em 0"}}, - "table_header": {{"background": "#4F4F4F", "color": "#FFFFFF", "font_weight": "bold", "text_align": "center", "padding": "12px"}}, - "table_cell": {{"background": "#FFFFFF", "color": "#2F2F2F", "font_weight": "normal", "text_align": "left", "padding": "8px", "border": "1px solid #ddd"}}, - "bullet_list": {{"font_size": "1em", "color": "#2F2F2F", "margin": "0 0 1em 0", "padding_left": "20px"}}, - "code_block": {{"font_family": "Courier New, monospace", "font_size": "0.9em", "color": "#2F2F2F", "background": "#F5F5F5", "padding": "1em", "border": "1px solid #ddd", "border_radius": "4px", "margin": "1em 0"}}, - "image": {{"max_width": "100%", "height": "auto", "margin": "1em 0", "border_radius": "4px"}}, - "body": {{"font_family": "Arial, sans-serif", "background": "#FFFFFF", "color": "#2F2F2F", "margin": "0", "padding": "20px"}} -}} - -NO TEXT. NO EXPLANATIONS. NO MARKDOWN. NO WRAPPER OBJECTS. ONLY THE JSON ABOVE.""" - - from modules.datamodels.datamodelAi import AiCallRequest, AiCallOptions, OperationType - - request_options = AiCallOptions() - request_options.operationType = OperationType.GENERAL - - request = AiCallRequest(prompt=prompt, context="", options=request_options) - response = await ai_service.aiObjects.call(request) - - import json - import re - - # Clean and parse JSON - result = response.content.strip() if response and response.content else "" - - # Check if result is empty - if not result: - self.logger.warning("AI styling returned empty response, using defaults") - return self._get_default_html_styles() - - # Extract JSON from markdown code blocks - json_match = re.search(r'```json\s*\n(.*?)\n```', result, re.DOTALL) - if json_match: - result = json_match.group(1).strip() - elif result.startswith('```json'): - result = re.sub(r'^```json\s*', '', result) - result = re.sub(r'\s*```$', '', result) - elif result.startswith('```'): - result = re.sub(r'^```\s*', '', result) - result = re.sub(r'\s*```$', '', result) - - # Try to parse JSON - try: - styles = json.loads(result) - except json.JSONDecodeError as json_error: - self.logger.warning(f"AI styling returned invalid JSON: {json_error}, using defaults") - return self._get_default_html_styles() - - # Validate and fix contrast issues - styles = self._validate_html_styles_contrast(styles) - - return styles - - except Exception as e: - self.logger.warning(f"AI styling failed: {str(e)}, using defaults") - return self._get_default_html_styles() + style_template = self._create_ai_style_template("html", user_prompt, style_schema) + styles = await self._get_ai_styles(ai_service, style_template, self._get_default_html_styles()) + + # Validate and fix contrast issues + return self._validate_html_styles_contrast(styles) def _validate_html_styles_contrast(self, styles: Dict[str, Any]) -> Dict[str, Any]: """Validate and fix contrast issues in AI-generated styles."""