修复项目生成AI提词优化忽视视频附件BUG
This commit is contained in:
@@ -230,32 +230,97 @@ async def _call_openai_compatible(
|
|||||||
|
|
||||||
# Build multimodal user message content when images are present
|
# Build multimodal user message content when images are present
|
||||||
image_urls = []
|
image_urls = []
|
||||||
|
video_urls = []
|
||||||
if references:
|
if references:
|
||||||
for ref in references:
|
for ref in references:
|
||||||
if ref.get("type") == "image" and ref.get("url"):
|
if not isinstance(ref, dict):
|
||||||
image_urls.append(ref["url"])
|
continue
|
||||||
|
|
||||||
if image_urls:
|
ref_type = ref.get("type")
|
||||||
|
ref_url = ref.get("url")
|
||||||
|
|
||||||
|
if not ref_url:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ref_type == "image":
|
||||||
|
image_urls.append(ref_url)
|
||||||
|
|
||||||
|
if ref_type == "video":
|
||||||
|
video_urls.append(ref_url)
|
||||||
|
|
||||||
|
def _build_file_url_or_data_uri(file_url: str, fallback_mime: str) -> str:
|
||||||
|
"""
|
||||||
|
Convert local upload path to base64 data URI.
|
||||||
|
Keep remote http/https/data URLs as-is.
|
||||||
|
"""
|
||||||
|
if file_url.startswith(("http://", "https://", "data:")):
|
||||||
|
return file_url
|
||||||
|
|
||||||
|
# Compatible with /uploads/xxx and plain relative paths
|
||||||
|
relative_path = file_url.replace("/uploads/", "", 1).lstrip("/")
|
||||||
|
file_path = os.path.join(settings.UPLOAD_LOCAL_PATH, relative_path)
|
||||||
|
|
||||||
|
mime = mimetypes.guess_type(file_path)[0] or fallback_mime
|
||||||
|
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
b64 = base64.b64encode(f.read()).decode()
|
||||||
|
|
||||||
|
return f"data:{mime};base64,{b64}"
|
||||||
|
|
||||||
|
if image_urls or video_urls:
|
||||||
content_parts = [{"type": "text", "text": user_content}]
|
content_parts = [{"type": "text", "text": user_content}]
|
||||||
|
|
||||||
for img in image_urls:
|
for img in image_urls:
|
||||||
if img.startswith("http"):
|
url = _build_file_url_or_data_uri(img, "image/png")
|
||||||
url = img
|
content_parts.append({
|
||||||
else:
|
"type": "image_url",
|
||||||
# Local file: read and encode as base64 data URI
|
"image_url": {
|
||||||
file_path = os.path.join(settings.UPLOAD_LOCAL_PATH, img.replace("/uploads/", ""))
|
"url": url,
|
||||||
mime = mimetypes.guess_type(file_path)[0] or "image/png"
|
},
|
||||||
with open(file_path, "rb") as f:
|
})
|
||||||
b64 = base64.b64encode(f.read()).decode()
|
|
||||||
url = f"data:{mime};base64,{b64}"
|
for video in video_urls:
|
||||||
content_parts.append({"type": "image_url", "image_url": {"url": url}})
|
url = _build_file_url_or_data_uri(video, "video/mp4")
|
||||||
user_message = {"role": "user", "content": content_parts}
|
content_parts.append({
|
||||||
|
"type": "video_url",
|
||||||
|
"video_url": {
|
||||||
|
"url": url,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
user_message = {
|
||||||
|
"role": "user",
|
||||||
|
"content": content_parts,
|
||||||
|
}
|
||||||
|
|
||||||
# Log-friendly version: keep original paths instead of base64
|
# Log-friendly version: keep original paths instead of base64
|
||||||
log_user_message = {"role": "user", "content": [
|
log_content_parts = [{"type": "text", "text": user_content}]
|
||||||
{"type": "text", "text": user_content},
|
|
||||||
*[{"type": "image_url", "image_url": {"url": img}} for img in image_urls],
|
for img in image_urls:
|
||||||
]}
|
log_content_parts.append({
|
||||||
|
"type": "image_url",
|
||||||
|
"image_url": {
|
||||||
|
"url": img,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
for video in video_urls:
|
||||||
|
log_content_parts.append({
|
||||||
|
"type": "video_url",
|
||||||
|
"video_url": {
|
||||||
|
"url": video,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
log_user_message = {
|
||||||
|
"role": "user",
|
||||||
|
"content": log_content_parts,
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
user_message = {"role": "user", "content": user_content}
|
user_message = {
|
||||||
|
"role": "user",
|
||||||
|
"content": user_content,
|
||||||
|
}
|
||||||
log_user_message = None
|
log_user_message = None
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=120) as client:
|
async with httpx.AsyncClient(timeout=120) as client:
|
||||||
|
|||||||
Reference in New Issue
Block a user