8275a04903
CI / ai-gates (push) Successful in 38s
新增 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 目录。
55 lines
3.1 KiB
Bash
55 lines
3.1 KiB
Bash
# patbond-ai 配置样例。复制为 .env 后填入实际值——.env 已被 gitignore。
|
||
#
|
||
# 凭证纪律(ADR-021):真实密钥只允许存在于被忽略的文件中,本样例只放占位值。
|
||
# 被拦下时的第一动作是去服务商控制台轮换/禁用该密钥,然后才是清理提交。
|
||
|
||
# ---- 火山方舟(Ark)----
|
||
# 密钥无默认值。缺失时该适配器不装配,服务仍可启动并提供健康检查。
|
||
ARK_API_KEY=your-ark-api-key
|
||
# 北京区官方地址,一般无需改。
|
||
# ARK_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
|
||
# 单次 HTTP 往返超时(秒)。**不是生成耗时**——提交接口是异步的(只入队即返回),
|
||
# 调大成「等出图」会重新引入长连接占用与计费歧义。
|
||
# ARK_TIMEOUT_SEC=10
|
||
# 视频模型 ID,仅作兜底。正常路径由 Java 侧传入任务行冻结的模型快照——
|
||
# 适配层不自行选模型,否则任务记录与实际调用会不一致、事后无法对账。
|
||
ARK_VIDEO_MODEL=
|
||
# 厂商 execution_expires_after(秒),区间 [3600, 259200]。
|
||
# 默认取下限 1 小时:厂商默认 48 小时对交互式应用过长,被放弃的任务会挂两天。
|
||
# ARK_TASK_EXPIRY_SEC=3600
|
||
|
||
# ---- OpenAI 图片(gpt-image-2)----
|
||
# 密钥无默认值。缺失时该适配器不装配,服务仍可启动并提供健康检查。
|
||
OPENAI_API_KEY=your-openai-api-key
|
||
# OPENAI_BASE_URL=https://api.openai.com/v1
|
||
# 属于多个组织时才需要指定。
|
||
# OPENAI_ORGANIZATION=
|
||
# ⚠️ 与 ARK_TIMEOUT_SEC 语义不同:OpenAI 图片接口是**同步**的,一次请求里等到
|
||
# 图片生成完才返回,故这个值**确实是生成耗时的上限**,不是短往返的上限。
|
||
# OPENAI_TIMEOUT_SEC=180
|
||
# 图片模型 ID,仅作兜底。同 ARK_VIDEO_MODEL:正常由 Java 侧传入任务行的快照。
|
||
OPENAI_IMAGE_MODEL=
|
||
# 同时执行的同步调用数上限。这同时也是「同时有多少钱在花」的上界——超出的提交
|
||
# 排队,而不是一起打到服务商那里。
|
||
# OPENAI_MAX_CONCURRENT=4
|
||
# 已完成任务在内存注册表里的保留时长(秒)。**必须大于 Java 侧最长的轮询间隔**
|
||
# (当前阶梯最长 30 秒),否则结果会在被取走前被清掉——症状是「任务成功了但查
|
||
# 不到」,极难查。
|
||
# OPENAI_COMPLETED_TTL_SEC=900
|
||
# 注册表条目上限。满了以后新提交被拒(503),**不挤掉在途任务**——挤掉一个在途
|
||
# 任务会让一次可能正在计费的调用变成无人认领的开销。
|
||
# OPENAI_MAX_INFLIGHT=256
|
||
|
||
# ---- 服务身份 JWT(ADR-023 §5)----
|
||
# 与 patbond-creation 持有的私钥配对的 RS256 公钥。注意这是一对**独立于用户
|
||
# token 的**密钥:现有 JwtVerifier 只验签名、不校验 aud/iss,复用同一密钥对会
|
||
# 让服务票被四个 Java 模块当成合法用户 token 接受。
|
||
PATBOND_SERVICE_JWT_PUBLIC_KEY=
|
||
# PATBOND_SERVICE_JWT_ISSUER=patbond-api
|
||
# audience 必须强制校验,否则独立密钥对失去意义。
|
||
# PATBOND_SERVICE_JWT_AUDIENCE=patbond-ai
|
||
# PATBOND_SERVICE_JWT_TYPE=service
|
||
|
||
# ---- 其他 ----
|
||
# PATBOND_AI_LOG_LEVEL=INFO
|