Spaces:
Sleeping
Sleeping
| import os | |
| from src.clients.llm_client import LLMClient | |
| import json | |
| import pandas as pd | |
| from pydantic import BaseModel, Field | |
| from enum import Enum | |
| import base64 | |
| from io import BytesIO | |
| from PIL import Image | |
| from typing import List, Optional | |
| from functools import cache | |
| from datetime import datetime | |
| import pytz | |
| from src.utils.tracer import customtracer | |
| from src.models.common import model | |
| 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, | |
| ) | |
| # スキーマ定義�E�Eormat2fvinfo.pyから独立!E | |
| class Meta(BaseModel): | |
| 会社吁E str | |
| 業畁E str | |
| ブランチE str | |
| サービス: str | |
| 啁E��: str | |
| タイトル: str | |
| 構�Eの意図: str | |
| 訴求テーチE list[str] | |
| class Font(str, Enum): | |
| font1 = "ゴシチE��" | |
| font2 = "明朝" | |
| font3 = "手書ぁE | |
| class EvsF(str, Enum): | |
| EMOTIONAL = "惁E��E | |
| FUNCTIONAL = "機�E" | |
| class PvsS(str, Enum): | |
| PROBLEM = "問題提起" | |
| SOLUTION = "課題解決" | |
| class Copy(BaseModel): | |
| text: str | |
| font: Font | |
| color: str | |
| visual: str | |
| appeal_mode : EvsF | |
| forcus_stage : PvsS | |
| class CatchCopy(BaseModel): | |
| main_copy: list[Copy] | |
| sub_copy: list[Copy] | |
| class FVinfo(BaseModel): | |
| 非LP: bool | |
| メタ: Meta | |
| キャチE��コピ�E: CatchCopy | |
| 権威付け: list[str] | |
| ビジュアル: list[str] | |
| CTAボタン: list[str] | |
| def get_openai_request(messages, format, n=1): | |
| """ | |
| OpenAI API呼び出し!Eパラメータ対応!E | |
| Args: | |
| messages: メチE��ージリスチE | |
| format: レスポンスフォーマッチE | |
| n: 生�Eする候補数�E�デフォルチE 1�E�E | |
| Returns: | |
| list[str]: 常にリストで返却�E�E=1でも長ぁEのリスト!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=1.2, | |
| n=n | |
| ) | |
| # 常にリストで返す�E�E=1でも統一�E�E | |
| return [choice.message.content for choice in response.choices] | |
| def format2fvinfos(p, openai_key=os.environ.get('OPENAI_KEY'), n=1): | |
| """ | |
| 褁E��バリアントを返すformat2fvinfo�E��E列版�E�E | |
| input1 (text): prompt text | |
| input2 (text): default | |
| input3 (number): 1 | |
| output1 (json): variants list | |
| """ | |
| print(datetime.now(pytz.timezone('Asia/Tokyo')).strftime("%Y-%m-%d %H:%M:%S"), __name__, f"n={n}") | |
| if openai_key == "default": | |
| os.environ['OPENAI_API_KEY'] = os.environ.get('OPENAI_KEY') | |
| else: | |
| os.environ['OPENAI_API_KEY'] = openai_key | |
| # n を整数に変換し、篁E��チェチE�� | |
| try: | |
| n = int(n) | |
| if n < 1: | |
| print(f"Warning: n={n} is invalid, using n=1") | |
| n = 1 | |
| elif n > 10: | |
| print(f"Warning: n={n} is too large, capping at 10") | |
| n = 10 | |
| except (TypeError, ValueError): | |
| print(f"Warning: n={n} is invalid, using n=1") | |
| n = 1 | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": """提供したフォーマットデータから、忁E��なファーストビューの要素を生成してください、E"", | |
| }, | |
| { | |
| "role": "user", | |
| "content": [{"type": "text", "text":p}] | |
| }, | |
| ] | |
| # get_openai_requestは常にリストを返すので、そのまま使用 | |
| result = get_openai_request(messages, FVinfo, n=n) | |
| print(f"Generated {len(result)} variants") | |
| # リストをJSON斁E���Eとして返す | |
| return json.dumps(result, ensure_ascii=False) | |