Spaces:
Running
Running
File size: 6,230 Bytes
cf7f643 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | """
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=[])
|