push gitignore
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import os
|
||||
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
from pydantic import Field
|
||||
|
||||
|
||||
# ⚠️ 注意: 您需要安装 pydantic-settings: pip install pydantic-settings
|
||||
DEBUG = os.environ.get("DEBUG", True)
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""
|
||||
@@ -31,7 +34,10 @@ class Settings(BaseSettings):
|
||||
STYLIST_GUIDE_DIR: str = Field(default="/workspace/lc_stylist_agent/app/core/data/stylist_guide", description="风格指南文本目录")
|
||||
|
||||
# 向量数据库配置参数
|
||||
VECTOR_DB_DIR: str = Field(default="./app/db", description="向量数据库目录")
|
||||
if DEBUG:
|
||||
VECTOR_DB_DIR: str = Field(default="./db", description="向量数据库目录")
|
||||
else:
|
||||
VECTOR_DB_DIR: str = Field(default="./app/db", description="向量数据库目录")
|
||||
COLLECTION_NAME: str = Field(default="lc_clothing_embedding", description="向量数据库集合名称")
|
||||
EMBEDDING_MODEL_NAME: str = Field(default="openai/clip-vit-base-patch32", description="CLIP嵌入模型名称")
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ logger = logging.getLogger(__name__)
|
||||
class AsyncStylistAgent:
|
||||
CATEGORY_SET = {'Activewear', 'Watches', 'Shopping Totes', 'Underwear', 'Sunglasses', 'Dresses', 'Outerwear', 'Handbags', 'Backpacks', 'Belts', 'Hats', 'Skirts', 'Swimwear', 'Jewelry', 'Briefcases', 'Socks', 'Neckties', 'Pants', 'Suits', 'Shoes', 'Shirts & Tops', 'Scarves & Shawls'}
|
||||
|
||||
def __init__(self, local_db, max_len: int, gemini_model_name: str):
|
||||
def __init__(self, local_db, max_len: int, gemini_model_name: str, outfit_id=str):
|
||||
# self.outfit_items: List[Dict[str, str]] = []
|
||||
self.outfit_id = str(uuid.uuid4())
|
||||
self.outfit_id = outfit_id
|
||||
self.gemini_client = genai.Client(
|
||||
vertexai=True, project='aida-461108', location='us-central1'
|
||||
)
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
BASIC_PROMPT = """You are a professional, friendly, and insightful AI Styling Assistant.
|
||||
BASIC_PROMPT = """"""
|
||||
WOMEN_BASIC_PROMPT = """You are a professional, friendly, and insightful AI women's styling assistant.
|
||||
|
||||
Your primary mission is to engage in a multi-turn conversation with the user to fully understand their dressing intent. You must adopt a professional yet approachable tone.
|
||||
|
||||
CONVERSATION GOALS:
|
||||
1. **Occasion:** Determine the specific event (e.g., romantic dinner, summer wedding, business meeting).
|
||||
2. **Style:** Pinpoint the desired aesthetic (e.g., classic elegance, edgy, minimalist, bohemian).
|
||||
3. **Vibe/Details:** Gather any mood or specific constraints (e.g., needs to be comfortable, requires light colors, no bare shoulders).
|
||||
4. **Item Preference:** Ask the user if they have any specific preferences for an item type or silhouette (e.g., preference for a dress, skirt, tailored pants, or a particular neckline/length).
|
||||
|
||||
GUIDANCE FOR RESPONSE GENERATION:
|
||||
- After the user's initial request (e.g., "I want a chic outfit for dinner."), immediately reply with a friendly, targeted follow-up question to elicit the most crucial missing information (usually a combination of **Occasion** and **Style**).
|
||||
- Be concise. Ask only 1 to 2 essential questions per turn.
|
||||
- You must gather sufficient, clear intent before proceeding to actual clothing recommendations.
|
||||
|
||||
OUTPUT FORMAT INSTRUCTION:
|
||||
- **DO NOT** use any Markdown formatting whatsoever (e.g., do not use asterisks (*), bold text (**), lists, or code blocks).
|
||||
- **ONLY** output the plain text response spoken by the AI Assistant.
|
||||
|
||||
Example Follow-up (mimicking a conversational flow):
|
||||
User: I want a chic outfit for dinner.
|
||||
Your Response: Hey there! A chic dinner outfit, I love that! To give you the perfect recommendations, tell me: is this a romantic date, business dinner, or celebration with friends? And what's your go-to style vibe: classic elegance or something with more edge?"""
|
||||
MEN_BASIC_PROMPT = """You are a professional, friendly, and insightful AI men's styling assistant.
|
||||
|
||||
Your primary mission is to engage in a multi-turn conversation with the user to fully understand their dressing intent. You must adopt a professional yet approachable tone.
|
||||
|
||||
@@ -30,4 +53,4 @@ JSON FIELD REQUIREMENTS:
|
||||
- **style (string):** The overall aesthetic description (e.g., "Classic elegance", "Modern minimalist", "Bohemian vibe", "Edgy and contemporary").
|
||||
- **color_preference (string or list):** User's preferred or excluded colors/tones (e.g., "Light colors only", "Avoid deep shades", "['Cream', 'Pale Blue']", "No preference").
|
||||
- **clothing_type (string):** User's preference for specific garment types, material, or silhouette (e.g., "Lightweight maxi dress", "Skirt with silk blouse", "Tailored wide-leg pants", "Floral print").
|
||||
- **vibe_or_details (string):** Any other details, mood requirements, or specific constraints (e.g., "Needs to be comfortable and breathable", "Accent on accessories", "Must cover shoulders")."""
|
||||
- **vibe_or_details (string):** Any other details, mood requirements, or specific constraints (e.g., "Needs to be comfortable and breathable", "Accent on accessories", "Must cover shoulders")."""
|
||||
|
||||
1230
app/logs/debug.log
1230
app/logs/debug.log
File diff suppressed because it is too large
Load Diff
@@ -1,124 +0,0 @@
|
||||
2025-10-23 21:43:04,108 base_events.py [line:1758] ERROR Task exception was never retrieved
|
||||
future: <Task finished name='Task-3' coro=<LCAgent.background_run() done, defined at /workspace/lc_stylist_agent/app/server/ChatbotAgent/agent_server.py:57> exception=DefaultCredentialsError('Gemini API call failed: File /app/request.json was not found.')>
|
||||
Traceback (most recent call last):
|
||||
File "/workspace/lc_stylist_agent/app/core/llm_interface.py", line 45, in generate_response
|
||||
response = await self.gemini_client.aio.models.generate_content(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/models.py", line 6757, in generate_content
|
||||
response = await self._generate_content(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/models.py", line 5592, in _generate_content
|
||||
response = await self._api_client.async_request(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 1341, in async_request
|
||||
result = await self._async_request(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 1286, in _async_request
|
||||
return await self._async_retry( # type: ignore[no-any-return]
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 58, in __call__
|
||||
do = await self.iter(retry_state=retry_state)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 110, in iter
|
||||
result = await action(retry_state)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 78, in inner
|
||||
return fn(*args, **kwargs)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/__init__.py", line 410, in exc_check
|
||||
raise retry_exc.reraise()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/__init__.py", line 183, in reraise
|
||||
raise self.last_attempt.result()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/concurrent/futures/_base.py", line 451, in result
|
||||
return self.__get_result()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
|
||||
raise self._exception
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 61, in __call__
|
||||
result = await fn(*args, **kwargs)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 1153, in _async_request_once
|
||||
f'Bearer {await self._async_access_token()}'
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 970, in _async_access_token
|
||||
self._credentials, project = await asyncio.to_thread(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/asyncio/threads.py", line 25, in to_thread
|
||||
return await loop.run_in_executor(None, func_call)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/concurrent/futures/thread.py", line 58, in run
|
||||
result = self.fn(*self.args, **self.kwargs)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 184, in load_auth
|
||||
credentials, loaded_project_id = google.auth.default( # type: ignore[no-untyped-call]
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 705, in default
|
||||
credentials, project_id = checker()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 698, in <lambda>
|
||||
lambda: _get_explicit_environ_credentials(quota_project_id=quota_project_id),
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 346, in _get_explicit_environ_credentials
|
||||
credentials, project_id = load_credentials_from_file(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 173, in load_credentials_from_file
|
||||
raise exceptions.DefaultCredentialsError(
|
||||
google.auth.exceptions.DefaultCredentialsError: File /app/request.json was not found.
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/workspace/lc_stylist_agent/app/server/ChatbotAgent/agent_server.py", line 59, in background_run
|
||||
request_summary = await self.get_conversation_summary(request.user_id)
|
||||
File "/workspace/lc_stylist_agent/app/server/ChatbotAgent/agent_server.py", line 84, in get_conversation_summary
|
||||
summary = await self.llm.generate_response(history=[Message(role=Role.USER, content=input_message)], system_prompt=SUMMARY_PROMPT)
|
||||
File "/workspace/lc_stylist_agent/app/core/llm_interface.py", line 55, in generate_response
|
||||
raise type(e)(f"Gemini API call failed: {e}")
|
||||
google.auth.exceptions.DefaultCredentialsError: Gemini API call failed: File /app/request.json was not found.
|
||||
2025-10-23 21:43:39,697 base_events.py [line:1758] ERROR Task exception was never retrieved
|
||||
future: <Task finished name='Task-5' coro=<LCAgent.background_run() done, defined at /workspace/lc_stylist_agent/app/server/ChatbotAgent/agent_server.py:57> exception=DefaultCredentialsError('Gemini API call failed: File /app/request.json was not found.')>
|
||||
Traceback (most recent call last):
|
||||
File "/workspace/lc_stylist_agent/app/core/llm_interface.py", line 45, in generate_response
|
||||
response = await self.gemini_client.aio.models.generate_content(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/models.py", line 6757, in generate_content
|
||||
response = await self._generate_content(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/models.py", line 5592, in _generate_content
|
||||
response = await self._api_client.async_request(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 1341, in async_request
|
||||
result = await self._async_request(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 1286, in _async_request
|
||||
return await self._async_retry( # type: ignore[no-any-return]
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 58, in __call__
|
||||
do = await self.iter(retry_state=retry_state)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 110, in iter
|
||||
result = await action(retry_state)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 78, in inner
|
||||
return fn(*args, **kwargs)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/__init__.py", line 410, in exc_check
|
||||
raise retry_exc.reraise()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/__init__.py", line 183, in reraise
|
||||
raise self.last_attempt.result()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/concurrent/futures/_base.py", line 451, in result
|
||||
return self.__get_result()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
|
||||
raise self._exception
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/tenacity/_asyncio.py", line 61, in __call__
|
||||
result = await fn(*args, **kwargs)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 1153, in _async_request_once
|
||||
f'Bearer {await self._async_access_token()}'
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 970, in _async_access_token
|
||||
self._credentials, project = await asyncio.to_thread(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/asyncio/threads.py", line 25, in to_thread
|
||||
return await loop.run_in_executor(None, func_call)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/concurrent/futures/thread.py", line 58, in run
|
||||
result = self.fn(*self.args, **self.kwargs)
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/genai/_api_client.py", line 184, in load_auth
|
||||
credentials, loaded_project_id = google.auth.default( # type: ignore[no-untyped-call]
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 705, in default
|
||||
credentials, project_id = checker()
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 698, in <lambda>
|
||||
lambda: _get_explicit_environ_credentials(quota_project_id=quota_project_id),
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 346, in _get_explicit_environ_credentials
|
||||
credentials, project_id = load_credentials_from_file(
|
||||
File "/home/user/miniconda3/envs/test/lib/python3.10/site-packages/google/auth/_default.py", line 173, in load_credentials_from_file
|
||||
raise exceptions.DefaultCredentialsError(
|
||||
google.auth.exceptions.DefaultCredentialsError: File /app/request.json was not found.
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/workspace/lc_stylist_agent/app/server/ChatbotAgent/agent_server.py", line 59, in background_run
|
||||
request_summary = await self.get_conversation_summary(request.user_id)
|
||||
File "/workspace/lc_stylist_agent/app/server/ChatbotAgent/agent_server.py", line 84, in get_conversation_summary
|
||||
summary = await self.llm.generate_response(history=[Message(role=Role.USER, content=input_message)], system_prompt=SUMMARY_PROMPT)
|
||||
File "/workspace/lc_stylist_agent/app/core/llm_interface.py", line 55, in generate_response
|
||||
raise type(e)(f"Gemini API call failed: {e}")
|
||||
google.auth.exceptions.DefaultCredentialsError: Gemini API call failed: File /app/request.json was not found.
|
||||
2025-10-23 21:44:09,080 agent_server.py [line:73] ERROR ❌ Failed: 'NoneType' object has no attribute 'get'
|
||||
2025-10-24 09:59:19,870 agent_server.py [line:73] ERROR ❌ Failed: 'NoneType' object has no attribute 'get'
|
||||
2025-10-24 09:59:51,131 agent_server.py [line:73] ERROR ❌ Failed: 'NoneType' object has no attribute 'get'
|
||||
2025-10-24 10:15:04,724 agent_server.py [line:73] ERROR ❌ Failed: 'NoneType' object has no attribute 'get'
|
||||
2025-10-24 10:15:11,944 base_events.py [line:1758] ERROR Unclosed client session
|
||||
client_session: <aiohttp.client.ClientSession object at 0x7c7cc2989ff0>
|
||||
1230
app/logs/info.log
1230
app/logs/info.log
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@ class LCAgent(ls.LitAPI):
|
||||
key_prefix=settings.REDIS_HISTORY_KEY_PREFIX
|
||||
)
|
||||
self.vector_db = VectorDatabase(
|
||||
vector_db_dir=os.getenv('VECTOR_DB_DIR', '/app/app/db'),
|
||||
vector_db_dir=settings.VECTOR_DB_DIR,
|
||||
collection_name=settings.COLLECTION_NAME,
|
||||
embedding_model_name=settings.EMBEDDING_MODEL_NAME
|
||||
)
|
||||
@@ -43,6 +43,7 @@ class LCAgent(ls.LitAPI):
|
||||
'max_len': 5,
|
||||
'gemini_model_name': settings.LLM_MODEL_NAME
|
||||
}
|
||||
self.outfit_ids = []
|
||||
|
||||
async def decode_request(self, request: AgentRequestModel):
|
||||
"""
|
||||
@@ -59,8 +60,11 @@ class LCAgent(ls.LitAPI):
|
||||
return request
|
||||
|
||||
async def predict(self, request):
|
||||
|
||||
self.outfit_ids = [str(uuid.uuid4()) for _ in range(request.num_outfits)]
|
||||
|
||||
asyncio.create_task(self.background_run(request))
|
||||
return {"status": "Task initiated in background."}
|
||||
return {"status": "Task initiated in background.", "outfit_ids": self.outfit_ids}
|
||||
|
||||
async def encode_response(self, output):
|
||||
return output
|
||||
@@ -108,7 +112,8 @@ class LCAgent(ls.LitAPI):
|
||||
if start_outfit is None:
|
||||
start_outfit = []
|
||||
tasks = []
|
||||
for _ in range(num_outfits):
|
||||
for i in range(num_outfits):
|
||||
self.stylist_agent_kwages['outfit_id'] = self.outfit_ids[i]
|
||||
agent = AsyncStylistAgent(**self.stylist_agent_kwages)
|
||||
task = agent.run_styling_process(
|
||||
request_summary=request_summary,
|
||||
|
||||
@@ -12,7 +12,7 @@ from app.core.data_structure import Role, Message
|
||||
from app.core.llm_interface import AsyncGeminiLLM
|
||||
from app.core.redis_manager import RedisManager
|
||||
from app.core.stylist_agent import AsyncStylistAgent
|
||||
from app.core.system_prompt import BASIC_PROMPT, SUMMARY_PROMPT
|
||||
from app.core.system_prompt import BASIC_PROMPT, SUMMARY_PROMPT, MEN_BASIC_PROMPT, WOMEN_BASIC_PROMPT
|
||||
from app.core.vector_database import VectorDatabase
|
||||
from google.genai import types
|
||||
|
||||
@@ -22,6 +22,7 @@ logger = logging.getLogger(__name__)
|
||||
class PredictRequest(BaseModel):
|
||||
user_id: str # 用戶ID
|
||||
user_message: str # 用戶輸入
|
||||
gender: str # 服装类型
|
||||
|
||||
|
||||
class LCChatBot(ls.LitAPI):
|
||||
@@ -60,6 +61,10 @@ class LCChatBot(ls.LitAPI):
|
||||
user_msg = Message(role=Role.USER, content=user_message)
|
||||
chat_history = self.redis.get_history(user_id)
|
||||
chat_history.append(user_msg)
|
||||
if request.gender == 'male':
|
||||
BASIC_PROMPT = MEN_BASIC_PROMPT
|
||||
else:
|
||||
BASIC_PROMPT = WOMEN_BASIC_PROMPT
|
||||
|
||||
contents = []
|
||||
|
||||
@@ -103,86 +108,3 @@ class LCChatBot(ls.LitAPI):
|
||||
# The for-loop must have async keyword here since output is an AsyncGenerator
|
||||
async for out in output:
|
||||
yield {"output": out}
|
||||
|
||||
async def process_query(self, user_id: str, user_message: str) -> str:
|
||||
"""
|
||||
处理用户的最新输入,调用 LLM, 并更新历史记录。
|
||||
"""
|
||||
|
||||
# 添加用户消息到历史
|
||||
user_msg = Message(role=Role.USER, content=user_message)
|
||||
chat_history = self.redis.get_history(user_id)
|
||||
chat_history.append(user_msg)
|
||||
|
||||
# 生成 LLM 回复
|
||||
try:
|
||||
response_text = await self.llm.generate_response(chat_history, system_prompt=BASIC_PROMPT)
|
||||
except Exception as e:
|
||||
logger("\n--- Final Recommendation Results ---")
|
||||
|
||||
logger.error(f"LLM 调用失败: {e}")
|
||||
response_text = "抱歉,系统暂时无法响应,请稍后再试。"
|
||||
|
||||
# 添加助手消息到历史
|
||||
if response_text:
|
||||
assistant_msg = Message(role=Role.ASSISTANT, content=response_text)
|
||||
else:
|
||||
assistant_msg = Message(role=Role.ASSISTANT, content="No response generated. Try again later.")
|
||||
|
||||
self.redis.save_message(user_id, user_msg)
|
||||
self.redis.save_message(user_id, assistant_msg)
|
||||
|
||||
return response_text
|
||||
|
||||
async def get_conversation_summary(self, user_id: str) -> str:
|
||||
"""
|
||||
分析用户的完整会话历史,并打包成一个简洁的需求总结。
|
||||
|
||||
这个总结可以直接作为输入 Prompt 传递给 Stylist Agent。`
|
||||
"""
|
||||
history_messages = self.redis.get_history(user_id)
|
||||
input_message = "\n".join([f"{msg.role.value}: {msg.content}" for msg in history_messages])
|
||||
|
||||
# 临时调用 LLM 或使用本地逻辑生成总结
|
||||
summary = await self.llm.generate_response(history=[Message(role=Role.USER, content=input_message)], system_prompt=SUMMARY_PROMPT)
|
||||
|
||||
return summary
|
||||
|
||||
async def recommend_outfit(self, request_summary: str, stylist_name: str, start_outfit=None, num_outfits: int = 1):
|
||||
"""
|
||||
基于用户的对话历史和需求,推荐一套搭配。
|
||||
|
||||
Args:
|
||||
request_summary: 用户的request
|
||||
start_outfit: 可选的初始搭配列表,每个元素包含 'item_id' 和 'category'。
|
||||
"""
|
||||
if start_outfit is None:
|
||||
start_outfit = []
|
||||
tasks = []
|
||||
for _ in range(num_outfits):
|
||||
agent = AsyncStylistAgent(**self.stylist_agent_kwages)
|
||||
task = agent.run_styling_process(request_summary, stylist_name, start_outfit)
|
||||
tasks.append(task)
|
||||
logger.info(f"--- Starting {num_outfits} concurrent outfit generation tasks. ---")
|
||||
|
||||
try:
|
||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||
|
||||
successful_outfits = []
|
||||
failed_outfits = []
|
||||
for result in results:
|
||||
if isinstance(result, Exception):
|
||||
# 任务执行中发生异常
|
||||
failed_outfits.append(f"Failed: {result}")
|
||||
else:
|
||||
# 任务成功,result 是 run_styling_process 返回的图片路径
|
||||
successful_outfits.append(result)
|
||||
|
||||
return {
|
||||
"successful_outfits": successful_outfits,
|
||||
"failed_outfits": failed_outfits
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"An unexpected error occurred during concurrent recommendation: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
Reference in New Issue
Block a user