Spaces:
Runtime error
Runtime error
Update main.py
Browse files
main.py
CHANGED
|
@@ -19,6 +19,7 @@ import io
|
|
| 19 |
import requests
|
| 20 |
import uvicorn
|
| 21 |
import logging
|
|
|
|
| 22 |
from langchain_core.prompts import ChatPromptTemplate
|
| 23 |
from langchain_core.tools import tool
|
| 24 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
|
@@ -31,15 +32,14 @@ from typing import List
|
|
| 31 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
| 32 |
|
| 33 |
# 檢查必要的環境變數是否都已設定
|
| 34 |
-
if not all(k in os.environ for k in ["CHANNEL_ACCESS_TOKEN", "CHANNEL_SECRET", "GOOGLE_API_KEY", "
|
| 35 |
-
logging.error("Missing environment variables. Please set CHANNEL_ACCESS_TOKEN, CHANNEL_SECRET, GOOGLE_API_KEY,
|
| 36 |
-
raise ValueError("Missing environment variables. Please set CHANNEL_ACCESS_TOKEN, CHANNEL_SECRET, GOOGLE_API_KEY,
|
| 37 |
|
| 38 |
# 獲取環境變數中的金鑰和 URL
|
| 39 |
google_api = os.environ["GOOGLE_API_KEY"]
|
| 40 |
line_channel_access_token = os.environ["CHANNEL_ACCESS_TOKEN"]
|
| 41 |
line_channel_secret = os.environ["CHANNEL_SECRET"]
|
| 42 |
-
IMGBB_API_KEY = os.environ["IMGBB_API_KEY"]
|
| 43 |
HF_SPACE_URL = os.environ["HF_SPACE"]
|
| 44 |
|
| 45 |
# Line Bot API 設定
|
|
@@ -54,15 +54,9 @@ user_states = defaultdict(lambda: {
|
|
| 54 |
"upper_body_images": [],
|
| 55 |
"lower_body_images": [],
|
| 56 |
"current_mode": None,
|
| 57 |
-
"is_ready_for_outfit": False,
|
| 58 |
-
"is_ready_for_photo": False,
|
| 59 |
-
"user_info": {},
|
| 60 |
-
"personal_photo": None,
|
| 61 |
-
"personal_photo_base64": None
|
| 62 |
})
|
| 63 |
|
| 64 |
MAX_IMAGES_PER_TYPE = 3
|
| 65 |
-
GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent"
|
| 66 |
IMAGIN_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent"
|
| 67 |
|
| 68 |
# 建立 FastAPI 應用程式
|
|
@@ -181,58 +175,25 @@ def generate_outfit_from_clothes(upper_body_urls: list, lower_body_urls: list) -
|
|
| 181 |
return generated_image_url
|
| 182 |
else:
|
| 183 |
logging.error("Failed to save generated outfit image locally.")
|
| 184 |
-
return
|
| 185 |
else:
|
| 186 |
logging.error("Gemini image response format is invalid for outfit generation.")
|
| 187 |
-
return
|
| 188 |
else:
|
| 189 |
logging.error(f"Gemini outfit generation response has no candidates: {response.text}")
|
| 190 |
-
return
|
| 191 |
except requests.exceptions.RequestException as e:
|
| 192 |
logging.error(f"Gemini outfit generation API request failed: {e}")
|
| 193 |
-
return
|
| 194 |
-
|
| 195 |
-
@tool
|
| 196 |
-
def analyze_image_with_text(image_url: str, user_text: str) -> str:
|
| 197 |
-
"""
|
| 198 |
-
這個工具可以根據圖片和文字提示來回答問題。
|
| 199 |
-
|
| 200 |
-
Args:
|
| 201 |
-
image_url: 圖片的 URL。
|
| 202 |
-
user_text: 針對圖片提出的文字問題。
|
| 203 |
-
|
| 204 |
-
Returns:
|
| 205 |
-
模型針對圖片和文字提示給出的回應。
|
| 206 |
-
"""
|
| 207 |
-
try:
|
| 208 |
-
if not image_url:
|
| 209 |
-
return "圖片路徑無效,無法進行分析。"
|
| 210 |
-
|
| 211 |
-
image_bytes = requests.get(image_url).content
|
| 212 |
-
img_user = Image.open(io.BytesIO(image_bytes))
|
| 213 |
-
|
| 214 |
-
response = genai_client.models.generate_content(
|
| 215 |
-
model="gemini-2.5-flash",
|
| 216 |
-
contents=[img_user, user_text]
|
| 217 |
-
)
|
| 218 |
-
if (response.text != None):
|
| 219 |
-
out = response.text
|
| 220 |
-
else:
|
| 221 |
-
out = "Gemini沒答案!請換個說法!"
|
| 222 |
-
except Exception as e:
|
| 223 |
-
# 處理錯誤
|
| 224 |
-
out = f"Gemini執行出錯: {e}"
|
| 225 |
-
|
| 226 |
-
return out
|
| 227 |
|
| 228 |
# ==========================# LangChain 代理人設定# ==========================#
|
| 229 |
# 結合所有工具
|
| 230 |
-
tools = [generate_outfit_from_clothes
|
| 231 |
# 建立 LLM 模型實例
|
| 232 |
llm = ChatGoogleGenerativeAI(google_api_key=google_api, model="gemini-2.5-flash", temperature=0.2)
|
| 233 |
# 建立提示模板
|
| 234 |
prompt_template = ChatPromptTemplate([
|
| 235 |
-
("system", "你是一個強大的圖像生成與問答助理,可以根據用戶的請求使用提供的工具。當你執行
|
| 236 |
("user", "{input}"),
|
| 237 |
("placeholder", "{agent_scratchpad}"),
|
| 238 |
])
|
|
@@ -309,9 +270,9 @@ def handle_message(event):
|
|
| 309 |
|
| 310 |
# 處理重置功能
|
| 311 |
if user_text in ["重置", "重來", "重新開始", "再一次"]:
|
| 312 |
-
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None
|
| 313 |
line_bot_api.reply_message(
|
| 314 |
-
reply_token, TextSendMessage(text="
|
| 315 |
)
|
| 316 |
return
|
| 317 |
|
|
@@ -359,7 +320,7 @@ def handle_message(event):
|
|
| 359 |
line_bot_api.push_message(user_id, TextSendMessage(text=f"圖片生成失敗,請稍後再試。錯誤:{e}"))
|
| 360 |
|
| 361 |
# 生成後重置狀態以便下一次使用
|
| 362 |
-
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None
|
| 363 |
return
|
| 364 |
else:
|
| 365 |
line_bot_api.reply_message(
|
|
|
|
| 19 |
import requests
|
| 20 |
import uvicorn
|
| 21 |
import logging
|
| 22 |
+
import base64
|
| 23 |
from langchain_core.prompts import ChatPromptTemplate
|
| 24 |
from langchain_core.tools import tool
|
| 25 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
|
|
|
| 32 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
| 33 |
|
| 34 |
# 檢查必要的環境變數是否都已設定
|
| 35 |
+
if not all(k in os.environ for k in ["CHANNEL_ACCESS_TOKEN", "CHANNEL_SECRET", "GOOGLE_API_KEY", "HF_SPACE"]):
|
| 36 |
+
logging.error("Missing environment variables. Please set CHANNEL_ACCESS_TOKEN, CHANNEL_SECRET, GOOGLE_API_KEY, and HF_SPACE.")
|
| 37 |
+
raise ValueError("Missing environment variables. Please set CHANNEL_ACCESS_TOKEN, CHANNEL_SECRET, GOOGLE_API_KEY, and HF_SPACE.")
|
| 38 |
|
| 39 |
# 獲取環境變數中的金鑰和 URL
|
| 40 |
google_api = os.environ["GOOGLE_API_KEY"]
|
| 41 |
line_channel_access_token = os.environ["CHANNEL_ACCESS_TOKEN"]
|
| 42 |
line_channel_secret = os.environ["CHANNEL_SECRET"]
|
|
|
|
| 43 |
HF_SPACE_URL = os.environ["HF_SPACE"]
|
| 44 |
|
| 45 |
# Line Bot API 設定
|
|
|
|
| 54 |
"upper_body_images": [],
|
| 55 |
"lower_body_images": [],
|
| 56 |
"current_mode": None,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
})
|
| 58 |
|
| 59 |
MAX_IMAGES_PER_TYPE = 3
|
|
|
|
| 60 |
IMAGIN_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent"
|
| 61 |
|
| 62 |
# 建立 FastAPI 應用程式
|
|
|
|
| 175 |
return generated_image_url
|
| 176 |
else:
|
| 177 |
logging.error("Failed to save generated outfit image locally.")
|
| 178 |
+
return None
|
| 179 |
else:
|
| 180 |
logging.error("Gemini image response format is invalid for outfit generation.")
|
| 181 |
+
return None
|
| 182 |
else:
|
| 183 |
logging.error(f"Gemini outfit generation response has no candidates: {response.text}")
|
| 184 |
+
return None
|
| 185 |
except requests.exceptions.RequestException as e:
|
| 186 |
logging.error(f"Gemini outfit generation API request failed: {e}")
|
| 187 |
+
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
|
| 189 |
# ==========================# LangChain 代理人設定# ==========================#
|
| 190 |
# 結合所有工具
|
| 191 |
+
tools = [generate_outfit_from_clothes]
|
| 192 |
# 建立 LLM 模型實例
|
| 193 |
llm = ChatGoogleGenerativeAI(google_api_key=google_api, model="gemini-2.5-flash", temperature=0.2)
|
| 194 |
# 建立提示模板
|
| 195 |
prompt_template = ChatPromptTemplate([
|
| 196 |
+
("system", "你是一個強大的圖像生成與問答助理,可以根據用戶的請求使用提供的工具。當你執行 generate_outfit_from_clothes 工具成功後會獲得一個 URL,然後你回答的 output 要包含有這個 URL 的完整資訊。如果工具有產生錯誤訊息請解讀並回應。"),
|
| 197 |
("user", "{input}"),
|
| 198 |
("placeholder", "{agent_scratchpad}"),
|
| 199 |
])
|
|
|
|
| 270 |
|
| 271 |
# 處理重置功能
|
| 272 |
if user_text in ["重置", "重來", "重新開始", "再一次"]:
|
| 273 |
+
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None})[user_id]
|
| 274 |
line_bot_api.reply_message(
|
| 275 |
+
reply_token, TextSendMessage(text="狀態已重置。請先輸入「上衣」或「褲子」來開始。")
|
| 276 |
)
|
| 277 |
return
|
| 278 |
|
|
|
|
| 320 |
line_bot_api.push_message(user_id, TextSendMessage(text=f"圖片生成失敗,請稍後再試。錯誤:{e}"))
|
| 321 |
|
| 322 |
# 生成後重置狀態以便下一次使用
|
| 323 |
+
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None})[user_id]
|
| 324 |
return
|
| 325 |
else:
|
| 326 |
line_bot_api.reply_message(
|