修复项目生成AI提词优化忽视视频附件BUG

This commit is contained in:
2026-06-08 16:46:23 +08:00
parent d3a2df8cfd
commit 8c48ae0490
+84 -19
View File
@@ -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: