Spaces:
Sleeping
Sleeping
| """ | |
| HTMLバリアント生成API | |
| 允E�EHTMLと変更点を受け取り、Eつの新しいHTMLを提案すめE | |
| """ | |
| import os | |
| from src.clients.llm_client import LLMClient | |
| import json | |
| import re | |
| from typing import List | |
| from pydantic import BaseModel, Field | |
| from datetime import datetime | |
| import pytz | |
| from src.utils.tracer import customtracer | |
| def _ask_raw_hf(messages, model, response_format=None): | |
| """Compatibility wrapper: routes OpenAI-style messages through HF LLMClient.""" | |
| from src.clients.llm_client import LLMClient | |
| import json as _json | |
| client = LLMClient() | |
| system_prompt = None | |
| user_text = "" | |
| images = [] | |
| for msg in messages: | |
| role = msg.get("role", "") | |
| c = msg.get("content", "") | |
| if role == "system": | |
| if isinstance(c, str): | |
| system_prompt = c | |
| elif role == "user": | |
| if isinstance(c, str): | |
| user_text = c | |
| elif isinstance(c, list): | |
| for part in c: | |
| if isinstance(part, dict): | |
| if part.get("type") == "text": | |
| user_text += part.get("text", "") | |
| elif part.get("type") == "image_url": | |
| url = part.get("image_url", {}).get("url", "") | |
| if url.startswith("data:"): | |
| images.append(url.split(",", 1)[1] if "," in url else url) | |
| else: | |
| images.append(url) | |
| if response_format is not None and hasattr(response_format, "model_json_schema"): | |
| result = client.call( | |
| prompt=user_text, | |
| schema=response_format, | |
| model=model, | |
| system_prompt=system_prompt, | |
| images=images if images else None, | |
| temperature=0, | |
| ) | |
| return _json.dumps(result.model_dump(), ensure_ascii=False) | |
| else: | |
| return client.call_raw( | |
| prompt=user_text, | |
| model=model, | |
| system_prompt=system_prompt, | |
| images=images if images else None, | |
| ) | |
| class HtmlVariant(BaseModel): | |
| html : str | |
| description: str | |
| changes: list[str] | |
| class HtmlVariantsResponse(BaseModel): | |
| variants : list[HtmlVariant] | |
| def get_openai_request(messages, format, openai_key): | |
| """OpenAI APIを呼び出ぁE"" | |
| client = LLMClient() | |
| response = _ask_raw_hf([{"role":"user","content":p}], model, | |
| model="meta-llama/Llama-3.3-70B-Instruct", | |
| messages=messages, | |
| top_p=1, | |
| frequency_penalty=0, | |
| presence_penalty=0, | |
| response_format=format, | |
| temperature=0.7 # バリエーションを�Eすため少し高めに設宁E | |
| ) | |
| return response | |
| @customtracer | |
| def html2variants(original_html: str, change_points: str, openai_key=os.environ.get('OPENAI_KEY')): | |
| """ | |
| input1 (text): <h1>title</h1> | |
| input2 (text): タイトルに下線を表示 | |
| input3 (text): default | |
| output1 (json): html | |
| """ | |
| print(datetime.now(pytz.timezone('Asia/Tokyo')).strftime("%Y-%m-%d %H:%M:%S"), __name__) | |
| if openai_key == "default" or not openai_key: | |
| openai_key = os.environ.get('OPENAI_KEY', '') | |
| if openai_key: | |
| os.environ['OPENAI_API_KEY'] = openai_key | |
| # HTMLの構造を簡潔に要紁E��長すぎる場合�E要紁E��E | |
| html_summary = original_html[:5000] # 最初�E5000斁E��を使用 | |
| if len(original_html) > 5000: | |
| html_summary += "\n\n[以下省略...]" | |
| # プロンプトを構篁E | |
| prompt = f"""以下�E允E�EHTMLと変更点の説明を基に、指定数のHTMLバリアントを生�Eしてください、E | |
| 【�EのHTML、E | |
| {html_summary} | |
| 【変更点の説明、E | |
| {change_points} | |
| 【要件、E | |
| 1. 允E�EHTMLの構造とスタイルを可能な限り維持すめE | |
| 2. 変更点の説明に基づぁE��、指定数のHTMLバリアントを生�Eする | |
| 3. バリアント�E完�EなHTMLドキュメントとして返す�E�E!DOCTYPE html>から</html>まで�E�E | |
| 4. 画像パス、CSSパス、JavaScriptパスなどは允E�EHTMLからそ�Eまま維持すめE | |
| 5. 変更するのは主にチE��ストコンチE��チE��、その周辺のチE��イン�E�フォントサイズ、色、レイアウト、余白、スタイルなど�E�でぁE | |
| 6. 変更点周辺のチE��インを変更することで、より効果的な表現を実現してください | |
| 7. ただし、変更点以外�E部刁E��ロゴ、ナビゲーション、フチE��ー、その他�Eセクション�E��EチE��インは維持してください | |
| 8. 允E�EHTMLのすべての要素�E�ESS、画像、JavaScript、メタタグなど�E�を完�Eに保持する | |
| 【�E力形式、E | |
| - variants: 持E��数のHtmlVariantオブジェクト�EリスチE | |
| - HtmlVariantには以下を含める: | |
| - html: 完�EなHTMLドキュメンチE | |
| - description: こ�Eバリアント�E説明(変更点の要紁E��E0斁E��程度�E�E | |
| - changes: 具体的な変更点のリスト(各頁E��は30斁E��程度�E�E | |
| """ | |
| messages = [ | |
| { | |
| "role": "system", | |
| "content": """あなた�EHTMLの専門家です。�EのHTMLと変更点の説明を基に、指定数のHTMLバリアントを生�Eしてください、E | |
| バリアント�E完�EなHTMLドキュメントとして返し、�EのHTMLの構造とスタイルを可能な限り維持しながら、変更点を反映してください、E | |
| 変更点周辺のチE��イン�E�フォントサイズ、色、レイアウト、余白、スタイルなど�E�も変更可能です、E"", | |
| }, | |
| { | |
| "role": "user", | |
| "content": prompt | |
| }, | |
| ] | |
| try: | |
| result = get_openai_request(messages, HtmlVariantsResponse, openai_key) | |
| return result | |
| except Exception as e: | |
| print(f"[html2variants] エラー: {e}") | |
| import traceback | |
| print(traceback.format_exc()) | |
| # エラー時�E空のレスポンスを返す | |
| return HtmlVariantsResponse(variants=[]) | |