feat:统一格式,添加文本引用

This commit is contained in:
2025-12-11 18:44:12 +08:00
parent 09de5862dc
commit 6156064f56
4 changed files with 450 additions and 775 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
plugins/AIChat_Gemini.zip Normal file

Binary file not shown.

View File

@@ -95,6 +95,7 @@ class NanoImage(PluginBase):
if response.status_code == 200: if response.status_code == 200:
# 处理流式响应 # 处理流式响应
image_url = None image_url = None
image_base64 = None
full_content = "" full_content = ""
async for line in response.aiter_lines(): async for line in response.aiter_lines():
if line.startswith("data: "): if line.startswith("data: "):
@@ -106,33 +107,57 @@ class NanoImage(PluginBase):
data = json.loads(data_str) data = json.loads(data_str)
if "choices" in data and data["choices"]: if "choices" in data and data["choices"]:
delta = data["choices"][0].get("delta", {}) delta = data["choices"][0].get("delta", {})
# 方式1: 从 delta.images 中提取(新格式)
images = delta.get("images", [])
if images and len(images) > 0:
img_data = images[0].get("image_url", {}).get("url", "")
if img_data:
if img_data.startswith("data:image"):
# base64 格式
image_base64 = img_data
logger.info(f"从 delta.images 提取到 base64 图片")
elif img_data.startswith("http"):
image_url = img_data
logger.info(f"从 delta.images 提取到图片URL: {image_url}")
# 方式2: 从 content 中提取(旧格式)
content = delta.get("content", "") content = delta.get("content", "")
if content: if content:
full_content += content full_content += content
if "http" in content: if "http" in content:
# 提取图片URL
import re import re
urls = re.findall(r'https?://[^\s\)\]"\']+', content) urls = re.findall(r'https?://[^\s\)\]"\']+', content)
if urls: if urls:
image_url = urls[0].rstrip("'\"") image_url = urls[0].rstrip("'\"")
logger.info(f"提取到图片URL: {image_url}") logger.info(f"从 content 提取到图片URL: {image_url}")
except Exception as e: except Exception as e:
logger.warning(f"解析响应数据失败: {e}") logger.warning(f"解析响应数据失败: {e}")
continue continue
# 如果没有从流中提取到URL尝试从完整内容中提取 # 如果没有从流中提取到URL尝试从完整内容中提取
if not image_url and full_content: if not image_url and not image_base64 and full_content:
import re import re
urls = re.findall(r'https?://[^\s\)\]"\']+', full_content) urls = re.findall(r'https?://[^\s\)\]"\']+', full_content)
if urls: if urls:
image_url = urls[0].rstrip("'\"") image_url = urls[0].rstrip("'\"")
logger.info(f"从完整内容提取到图片URL: {image_url}") logger.info(f"从完整内容提取到图片URL: {image_url}")
if not image_url: if not image_url and not image_base64:
logger.error(f"未能提取到图片URL,完整响应: {full_content[:500]}") logger.error(f"未能提取到图片,完整响应: {full_content[:500]}")
# 处理 base64 图片
if image_base64:
image_path = await self._save_base64_image(image_base64)
if image_path:
logger.success("成功生成图像 (base64)")
return [image_path]
else:
logger.warning(f"base64图片保存失败将重试 ({attempt + 1}/{max_retry})")
continue
# 处理 URL 图片
if image_url: if image_url:
# 下载图片
image_path = await self._download_image(image_url) image_path = await self._download_image(image_url)
if image_path: if image_path:
logger.success("成功生成图像") logger.success("成功生成图像")
@@ -184,6 +209,48 @@ class NanoImage(PluginBase):
logger.warning(f"读取代理配置失败: {e}") logger.warning(f"读取代理配置失败: {e}")
return None return None
async def _save_base64_image(self, base64_data: str) -> Optional[str]:
"""保存 base64 图片到本地"""
try:
# 去除 data:image/xxx;base64, 前缀
if base64_data.startswith("data:image"):
# 提取格式和数据
header, data = base64_data.split(",", 1)
# 从 header 中提取格式,如 data:image/jpeg;base64
if "jpeg" in header or "jpg" in header:
ext = "jpg"
elif "png" in header:
ext = "png"
elif "gif" in header:
ext = "gif"
elif "webp" in header:
ext = "webp"
else:
ext = "jpg"
else:
data = base64_data
ext = "jpg"
# 解码 base64
image_bytes = base64.b64decode(data)
# 生成文件名
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
uid = uuid.uuid4().hex[:8]
file_path = self.images_dir / f"nano_{ts}_{uid}.{ext}"
# 保存文件
with open(file_path, "wb") as f:
f.write(image_bytes)
logger.info(f"base64图片保存成功: {file_path}")
return str(file_path)
except Exception as e:
logger.error(f"保存base64图片失败: {e}")
import traceback
logger.error(traceback.format_exc())
return None
async def _download_image(self, url: str) -> Optional[str]: async def _download_image(self, url: str) -> Optional[str]:
"""下载图片到本地""" """下载图片到本地"""
try: try: