from typing import List, Tuple, Dict import re # History/message helpers History = List[Tuple[str, str]] Messages = List[Dict[str, str]] def history_to_messages(history: History, system: str) -> Messages: messages = [{'role': 'system', 'content': system}] for h in history: user_content = h[0] if isinstance(user_content, list): text_content = "" for item in user_content: if isinstance(item, dict) and item.get("type") == "text": text_content += item.get("text", "") user_content = text_content if text_content else str(user_content) messages.append({'role': 'user', 'content': user_content}) messages.append({'role': 'assistant', 'content': h[1]}) return messages def messages_to_history(messages: Messages) -> Tuple[str, History]: assert messages[0]['role'] == 'system' history = [] for q, r in zip(messages[1::2], messages[2::2]): user_content = q['content'] if isinstance(user_content, list): text_content = "" for item in user_content: if isinstance(item, dict) and item.get("type") == "text": text_content += item.get("text", "") user_content = text_content if text_content else str(user_content) history.append([user_content, r['content']]) return history def history_render(history: History): return gr.update(visible=True), history def clear_history(): return [], [], None, "" def update_image_input_visibility(model): is_ernie_vl = model.get("id") == "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT" is_glm_vl = model.get("id") == "THUDM/GLM-4.1V-9B-Thinking" return gr.update(visible=is_ernie_vl or is_glm_vl) def process_image_for_model(image): import io, base64 import numpy as np from PIL import Image if image is None: return None if isinstance(image, np.ndarray): image = Image.fromarray(image) buffer = io.BytesIO() image.save(buffer, format='PNG') img_str = base64.b64encode(buffer.getvalue()).decode() return f"data:image/png;base64,{img_str}" def create_multimodal_message(text, image=None): if image is None: return {"role": "user", "content": text} content = [ {"type": "text", "text": text}, {"type": "image_url", "image_url": {"url": process_image_for_model(image)}} ] return {"role": "user", "content": content} # Code–block parsing def remove_code_block(text): patterns = [ r'```(?:html|HTML)\n([\s\S]+?)\n```', r'```\n([\s\S]+?)\n```', r'```([\s\S]+?)```' ] for pattern in patterns: match = re.search(pattern, text, re.DOTALL) if match: extracted = match.group(1).strip() if extracted.split('\n', 1)[0].strip().lower() in ['python','html','css','javascript','json','c','cpp','markdown','latex','jinja2','typescript','yaml','dockerfile','shell','r','sql','sql-mssql','sql-mysql','sql-mariadb','sql-sqlite','sql-cassandra','sql-plsql','sql-hive','sql-pgsql','sql-gql','sql-gpsql','sql-sparksql','sql-esper']: return extracted.split('\n',1)[1] if '\n' in extracted else '' return extracted if text.strip().startswith('1 else '' return text.strip() def parse_transformers_js_output(text): files={'index.html':'','index.js':'','style.css':''} html_match=re.search(r'```html\s*\n([\s\S]+?)\n```',text,re.IGNORECASE) if html_match: files['index.html']=html_match.group(1).strip() js_match=re.search(r'```javascript\s*\n([\s\S]+?)\n```',text,re.IGNORECASE) if js_match: files['index.js']=js_match.group(1).strip() css_match=re.search(r'```css\s*\n([\s\S]+?)\n```',text,re.IGNORECASE) if css_match: files['style.css']=css_match.group(1).strip() if not(files['index.html'] and files['index.js'] and files['style.css']): html_fallback=re.search(r'===\s*index\.html\s*===\n([\s\S]+?)(?=\n===|$)',text,re.IGNORECASE) js_fallback=re.search(r'===\s*index\.js\s*===\n([\s\S]+?)(?=\n===|$)',text,re.IGNORECASE) css_fallback=re.search(r'===\s*style\.css\s*===\n([\s\S]+?)(?=\n===|$)',text,re.IGNORECASE) if html_fallback: files['index.html']=html_fallback.group(1).strip() if js_fallback: files['index.js']=js_fallback.group(1).strip() if css_fallback: files['style.css']=css_fallback.group(1).strip() return files def format_transformers_js_output(files): output=[] output.append("=== index.html ===") output.append(files['index.html']) output.append("\n=== index.js ===") output.append(files['index.js']) output.append("\n=== style.css ===") output.append(files['style.css']) return '\n'.join(output)