builder / utils.py
mgbam's picture
Update utils.py
0ff9995 verified
raw
history blame
3.92 kB
### `utils.py`
from typing import List, Tuple, Dict
import re
import gradio as gr
import io, base64
import numpy as np
from PIL import Image
# 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):
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()
lines = extracted.split('\n', 1)
if lines[0].strip().lower() in ['python', 'html', 'css', 'javascript']:
return lines[1] if len(lines) > 1 else ''
return extracted
return text.strip()
def parse_transformers_js_output(text):
files = {'index.html': '', 'index.js': '', 'style.css': ''}
files['index.html'] = re.search(r'```html\s*\n([\s\S]+?)\n```', text, re.IGNORECASE).group(1).strip() if re.search(r'```html\s*\n([\s\S]+?)\n```', text, re.IGNORECASE) else ''
files['index.js'] = re.search(r'```javascript\s*\n([\s\S]+?)\n```', text, re.IGNORECASE).group(1).strip() if re.search(r'```javascript\s*\n([\s\S]+?)\n```', text, re.IGNORECASE) else ''
files['style.css'] = re.search(r'```css\s*\n([\s\S]+?)\n```', text, re.IGNORECASE).group(1).strip() if re.search(r'```css\s*\n([\s\S]+?)\n```', text, re.IGNORECASE) else ''
return files
def format_transformers_js_output(files):
return f"=== index.html ===\n{files['index.html']}\n=== index.js ===\n{files['index.js']}\n=== style.css ===\n{files['style.css']}"