新增 app/providers/openai/:client 传输(JSON + multipart)、errors 错误映射、 models 厂商 DTO、capabilities 尺寸算术约束、tasks 同步→异步桥、image 图片业务。 装配与配置同步接入,缺 OPENAI_API_KEY 时跳过装配、服务仍可启动。 与火山视频的三处根本差异及其处置: - 接口同步(无任务 ID、无查询端点)→ SyncTaskRegistry 在本服务内部吸收, 对外仍是 ADR-023 §4 的两段式提交/轮询。代价:本服务从此持有状态,进程重启 丢在途任务,且横向扩容前须先解决任务 ID 只在签发进程内有效的问题。 - 产物是 base64 字节而非 URL → 无过期问题,但字节只在内存里。asset_url 放 data URI 仅为满足领域不变式,绝不能原样写进 media.assets.external_url。 - 图生图走 multipart → 先下载参考图再上传;下载失败与超限按参数错误同步拒绝, 不变成注定失败的后台任务。 两处需要记住的判断: - 尺寸上限「3840x2160」文档未说清是逐边还是按像素。逐边理解会禁掉所有高于 2160 的竖图,而 1024x1536 是文档明示的标准竖图,故必然过严。采用最长边 ≤3840 且总像素 ≤3840×2160,已在 capabilities.py 与取证页标为推断。 - 两份文档都没有错误码表,故 errors.py 以 HTTP 状态码为主、type/code 为辅, 顶部标注「未经文档证实」。429 无线索时按限流而非配额耗尽(猜成配额会把可 重试的限流判死);400 无线索时归服务端错误而非内容被拒(错报会让用户去改 一个其实没问题的提示词)。 一处死锁已修并回归钉住:SyncTaskRegistry 原用 add_done_callback 记录完成时刻, 而快速完成的任务在注册时已 done,回调便同步地在持有非可重入锁的线程里执行。 改为首次被观察到时惰性记录。 测试 166 → 271(+105)。四道门禁逐条读退出码,全绿。 产物转存仍阻塞于存储决策(ADR-023 §7),图片模型因此未播种进 V7 目录。
This commit is contained in:
@@ -14,6 +14,9 @@ import logging
|
||||
|
||||
from app.config import Settings
|
||||
from app.providers.base import GenerationProvider
|
||||
from app.providers.openai.client import OpenAiClient
|
||||
from app.providers.openai.image import OpenAiImageProvider
|
||||
from app.providers.openai.tasks import SyncTaskRegistry
|
||||
from app.providers.registry import ProviderRegistry
|
||||
from app.providers.volcengine.client import ArkClient
|
||||
from app.providers.volcengine.video import SeedanceVideoProvider
|
||||
@@ -48,6 +51,29 @@ def build_registry(settings: Settings) -> ProviderRegistry:
|
||||
# 与它相隔很远。
|
||||
log.warning("ARK_API_KEY 未配置,火山方舟视频适配器未装配")
|
||||
|
||||
openai = settings.openai
|
||||
if openai.api_key:
|
||||
providers.append(
|
||||
OpenAiImageProvider(
|
||||
OpenAiClient(
|
||||
api_key=openai.api_key,
|
||||
base_url=openai.base_url,
|
||||
timeout_sec=openai.timeout_sec,
|
||||
organization=openai.organization or None,
|
||||
),
|
||||
# 同步→异步的任务注册表。每个适配器实例一份:它承载的是「本进程
|
||||
# 内哪些同步调用正在跑」,共享一份会让两个适配器互相挤占容量。
|
||||
SyncTaskRegistry(
|
||||
max_workers=openai.max_concurrent,
|
||||
completed_ttl_sec=openai.completed_ttl_sec,
|
||||
max_entries=openai.max_inflight,
|
||||
),
|
||||
default_model=openai.image_model,
|
||||
)
|
||||
)
|
||||
else:
|
||||
log.warning("OPENAI_API_KEY 未配置,图片生成适配器未装配")
|
||||
|
||||
registry = ProviderRegistry(providers)
|
||||
log.info("已装配 %d 个生成适配器:%s", len(registry), sorted(registry.codes))
|
||||
return registry
|
||||
|
||||
Reference in New Issue
Block a user