feat:统一格式,添加文本引用
This commit is contained in:
BIN
plugins/AIChat/data/persistent_memory.db
Normal file
BIN
plugins/AIChat/data/persistent_memory.db
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
plugins/AIChat_Gemini.zip
Normal file
BIN
plugins/AIChat_Gemini.zip
Normal file
Binary file not shown.
@@ -95,6 +95,7 @@ class NanoImage(PluginBase):
|
||||
if response.status_code == 200:
|
||||
# 处理流式响应
|
||||
image_url = None
|
||||
image_base64 = None
|
||||
full_content = ""
|
||||
async for line in response.aiter_lines():
|
||||
if line.startswith("data: "):
|
||||
@@ -106,33 +107,57 @@ class NanoImage(PluginBase):
|
||||
data = json.loads(data_str)
|
||||
if "choices" in data and data["choices"]:
|
||||
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", "")
|
||||
if content:
|
||||
full_content += content
|
||||
if "http" in content:
|
||||
# 提取图片URL
|
||||
import re
|
||||
urls = re.findall(r'https?://[^\s\)\]"\']+', content)
|
||||
if urls:
|
||||
image_url = urls[0].rstrip("'\"")
|
||||
logger.info(f"提取到图片URL: {image_url}")
|
||||
logger.info(f"从 content 提取到图片URL: {image_url}")
|
||||
except Exception as e:
|
||||
logger.warning(f"解析响应数据失败: {e}")
|
||||
continue
|
||||
|
||||
# 如果没有从流中提取到URL,尝试从完整内容中提取
|
||||
if not image_url and full_content:
|
||||
if not image_url and not image_base64 and full_content:
|
||||
import re
|
||||
urls = re.findall(r'https?://[^\s\)\]"\']+', full_content)
|
||||
if urls:
|
||||
image_url = urls[0].rstrip("'\"")
|
||||
logger.info(f"从完整内容提取到图片URL: {image_url}")
|
||||
|
||||
if not image_url:
|
||||
logger.error(f"未能提取到图片URL,完整响应: {full_content[:500]}")
|
||||
if not image_url and not image_base64:
|
||||
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:
|
||||
# 下载图片
|
||||
image_path = await self._download_image(image_url)
|
||||
if image_path:
|
||||
logger.success("成功生成图像")
|
||||
@@ -184,6 +209,48 @@ class NanoImage(PluginBase):
|
||||
logger.warning(f"读取代理配置失败: {e}")
|
||||
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]:
|
||||
"""下载图片到本地"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user