feat(ai): 图像主力从 tokenssr 切到 yunqi(支持 images/edits 图生图)
TOKENSSR 余额将尽,切换图像默认 provider 到 yunqi。yunqi 的图生图 端点需 Azure 风格 ?api-version=2025-04-01-preview,不带会 404。 - provider 加 api_version 字段,OpenAICompatible 生图/改图端点自动附加 ?api-version=(配了才加,tokenssr 等零影响) - build_provider 解析 api_version:DB(ModelProvider.metadata)优先 → .env 回退 - 迁移 0007:启用 yunqi:gpt-image-2 为唯一 active 图像模型,禁用其余 - 摘除死代码 YunqiProvider 导出(旧类写死"不支持图生图"会误导) 端到端验证:图生图(三视图,36s)+文生图(14s)均正常出图。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
from .base import AIProvider, AIProviderResult
|
||||
from .openai_compatible import OpenAICompatibleProvider
|
||||
from .volcano import TtsNotConfigured, VolcanoArkProvider, VolcanoTtsProvider
|
||||
from .yunqi import YunqiProvider
|
||||
|
||||
|
||||
__all__ = [
|
||||
@@ -11,5 +10,4 @@ __all__ = [
|
||||
"TtsNotConfigured",
|
||||
"VolcanoArkProvider",
|
||||
"VolcanoTtsProvider",
|
||||
"YunqiProvider",
|
||||
]
|
||||
|
||||
@@ -24,6 +24,15 @@ class OpenAICompatibleProvider(VolcanoArkProvider):
|
||||
if not self.base_url:
|
||||
raise ValueError("OpenAICompatibleProvider requires base_url (中转站地址)")
|
||||
|
||||
def _endpoint_url(self, endpoint: str) -> str:
|
||||
"""拼端点 URL。若 provider 配了 api_version(如 yunqi),附加 Azure 风格 ?api-version=...
|
||||
—— yunqi 的 images/edits 不带此参数会 404。tokenssr 等不配则零影响。"""
|
||||
url = f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
if self.api_version:
|
||||
sep = "&" if "?" in url else "?"
|
||||
url = f"{url}{sep}api-version={self.api_version}"
|
||||
return url
|
||||
|
||||
def image_generation(
|
||||
self,
|
||||
*,
|
||||
@@ -41,7 +50,7 @@ class OpenAICompatibleProvider(VolcanoArkProvider):
|
||||
body["image"] = image
|
||||
# 实测中转站生图延迟可达 75s+,超时给到 300s
|
||||
response = requests.post(
|
||||
f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}",
|
||||
self._endpoint_url(endpoint),
|
||||
headers={"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"},
|
||||
json=body,
|
||||
timeout=300,
|
||||
@@ -79,7 +88,7 @@ class OpenAICompatibleProvider(VolcanoArkProvider):
|
||||
raise ValueError("image_edit 至少需要一张参考图")
|
||||
data = {"model": model, "prompt": prompt, "size": size, "n": "1"}
|
||||
response = requests.post(
|
||||
f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}",
|
||||
self._endpoint_url(endpoint),
|
||||
headers={"Authorization": f"Bearer {self.api_key}"}, # multipart 不要手设 Content-Type
|
||||
files=files,
|
||||
data=data,
|
||||
|
||||
@@ -15,6 +15,9 @@ from .base import AIProviderResult
|
||||
class VolcanoArkProvider:
|
||||
api_key: str | None = None
|
||||
base_url: str | None = None
|
||||
# 部分 OpenAI 兼容中转站(如 yunqi)的生图/改图端点要求 Azure 风格的 ?api-version=... 查询参数,
|
||||
# 不带会 404。火山官方直连用不到,默认 None。仅 OpenAICompatibleProvider 在拼 URL 时附加。
|
||||
api_version: str | None = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.api_key = self.api_key or settings.VOLCANO.get("ark_api_key")
|
||||
|
||||
Reference in New Issue
Block a user