auto-save 2026-05-14 13:32 (~4)

This commit is contained in:
2026-05-14 13:32:50 +08:00
parent 00435b21ae
commit 31cb874028
4 changed files with 59 additions and 20 deletions

View File

@@ -1,19 +1,5 @@
{
"entries": [
{
"files_changed": 1,
"hash": "686baa1",
"message": "auto-save 2026-05-13 08:51 (~1)",
"ts": "2026-05-13T08:52:11+08:00",
"type": "commit"
},
{
"files_changed": 1,
"hash": "afab4bc",
"message": "auto-save 2026-05-13 08:57 (~1)",
"ts": "2026-05-13T08:57:46+08:00",
"type": "commit"
},
{
"files_changed": 1,
"hash": "d6a5223",
@@ -3278,6 +3264,19 @@
"type": "session-heartbeat",
"message": "Codex 会话活跃 · 最近命令codex · 1 项未提交变更 · 最近提交auto-save 2026-05-14 13:21 (~3)",
"files_changed": 1
},
{
"ts": "2026-05-14T13:27:18+08:00",
"type": "commit",
"message": "auto-save 2026-05-14 13:27 (~1)",
"hash": "00435b2",
"files_changed": 1
},
{
"ts": "2026-05-14T05:28:40Z",
"type": "session-heartbeat",
"message": "Codex 会话活跃 · 最近命令codex · 2 项未提交变更 · 最近提交auto-save 2026-05-14 13:27 (~1)",
"files_changed": 2
}
]
}

View File

@@ -36,6 +36,10 @@ POE_API_KEY=
# SKG 豆包/Seedance 视频网关也使用同一套 content JSON 提交格式:
# VIDEO_API_BASE_URL=https://ai.skg.com/doubao
# VIDEO_API_KEY=
# VIDEO_MODEL_SEEDANCE=doubao-seedance-2-0-fast-260128
# VIDEO_CREATE_PATHS=/api/v3/contents/generations/tasks
# VIDEO_STATUS_PATH=/api/v3/contents/generations/tasks/{id}
# VIDEO_CONTENT_PATH=/api/v3/contents/generations/tasks/{id}/content
#
# 自定义视频网关覆盖;留空时如配置 POE_API_KEY则走 Poe。
VIDEO_API_BASE_URL=

View File

@@ -91,14 +91,37 @@ VIDEO_MODEL_ALIASES = {
}
VIDEO_API_BASE_URL = os.getenv("VIDEO_API_BASE_URL", "").strip()
VIDEO_API_KEY = os.getenv("VIDEO_API_KEY", "").strip()
VIDEO_CREATE_PATH = os.getenv("VIDEO_CREATE_PATH", "/videos").strip() or "/videos"
def default_video_gateway_paths(base_url: str) -> tuple[str, str, str]:
base = base_url.strip().rstrip("/").lower()
if "ai.skg.com/doubao" in base:
return (
"/api/v3/contents/generations/tasks",
"/api/v3/contents/generations/tasks/{id}",
"/api/v3/contents/generations/tasks/{id}/content",
)
if "ark.cn-beijing.volces.com" in base:
return (
"/contents/generations/tasks",
"/contents/generations/tasks/{id}",
"/contents/generations/tasks/{id}/content",
)
return ("/videos", "/videos/{id}", "/videos/{id}/content")
DEFAULT_VIDEO_CREATE_PATH, DEFAULT_VIDEO_STATUS_PATH, DEFAULT_VIDEO_CONTENT_PATH = default_video_gateway_paths(VIDEO_API_BASE_URL)
VIDEO_CREATE_PATH = os.getenv("VIDEO_CREATE_PATH", DEFAULT_VIDEO_CREATE_PATH).strip() or DEFAULT_VIDEO_CREATE_PATH
VIDEO_CREATE_PATHS = [
p.strip()
for p in os.getenv("VIDEO_CREATE_PATHS", f"{VIDEO_CREATE_PATH},/videos/generations,/video/generations").split(",")
for p in os.getenv(
"VIDEO_CREATE_PATHS",
VIDEO_CREATE_PATH if VIDEO_CREATE_PATH != "/videos" else f"{VIDEO_CREATE_PATH},/videos/generations,/video/generations",
).split(",")
if p.strip()
]
VIDEO_STATUS_PATH = os.getenv("VIDEO_STATUS_PATH", "/videos/{id}").strip() or "/videos/{id}"
VIDEO_CONTENT_PATH = os.getenv("VIDEO_CONTENT_PATH", "/videos/{id}/content").strip() or "/videos/{id}/content"
VIDEO_STATUS_PATH = os.getenv("VIDEO_STATUS_PATH", DEFAULT_VIDEO_STATUS_PATH).strip() or DEFAULT_VIDEO_STATUS_PATH
VIDEO_CONTENT_PATH = os.getenv("VIDEO_CONTENT_PATH", DEFAULT_VIDEO_CONTENT_PATH).strip() or DEFAULT_VIDEO_CONTENT_PATH
VIDEO_DURATION_FIELD = os.getenv("VIDEO_DURATION_FIELD", "seconds").strip() or "seconds"
VIDEO_POLL_TIMEOUT_SECONDS = max(60, int(os.getenv("VIDEO_POLL_TIMEOUT_SECONDS", "900")))

View File

@@ -919,6 +919,19 @@ SubjectAsset {
<h2>变更记录</h2>
<p>这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。</p>
<div class="changelog">
<article class="change">
<header>
<h3>2026-05-14 · 修正 SKG 豆包视频网关路径</h3>
<span class="tag orange">Video Gen</span>
<span class="tag blue">Seedance</span>
</header>
<div class="body">
<p><strong>问题:</strong>产品融合视频能进入队列,但后台任务 5% 后失败,错误为 <code>/contents/generations/tasks</code> 返回 404。</p>
<p><strong>根因:</strong><code>https://ai.skg.com/doubao</code> 这个 SKG 豆包网关的真实视频入口是 <code>/api/v3/contents/generations/tasks</code>,不是火山方舟直连 base 下使用的 <code>/contents/generations/tasks</code></p>
<p><strong>改动:</strong>后端默认路径识别 <code>ai.skg.com/doubao</code> 并自动使用 <code>/api/v3/contents/generations/tasks</code><code>/api/v3/contents/generations/tasks/{id}</code><code>/api/v3/contents/generations/tasks/{id}/content</code>;本机 <code>api/.env</code><code>api/.env.example</code> 同步更新。</p>
<p><strong>影响:</strong><code>api/main.py</code><code>api/.env</code><code>api/.env.example</code><code>docs/source-analysis.html</code></p>
</div>
</article>
<article class="change">
<header>
<h3>2026-05-14 · 产品融合改为内置角色 + 产品 + 描述生成</h3>
@@ -1076,7 +1089,7 @@ SubjectAsset {
</header>
<div class="body">
<p><strong>问题:</strong>用户提供 <code>https://ai.skg.com/doubao</code> 作为视频模型网关;该网关应按 Seedance / 方舟内容生成任务格式提交,而不能误走普通 multipart 上传。</p>
<p><strong>改动:</strong><code>video_uses_ark()</code> 现在同时识别火山方舟域名和 <code>ai.skg.com/doubao</code>,统一使用 <code>content</code> JSON文本 prompt、首帧、尾帧和产品参考图作为不同 role 传入,再<code>/contents/generations/tasks/{id}</code> 轮询。<code>api/.env.example</code> 增加 SKG 豆包视频网关配置示例;生视频轮询上限改为 <code>VIDEO_POLL_TIMEOUT_SECONDS</code>,默认 900 秒,避免慢任务过早失败。</p>
<p><strong>改动:</strong><code>video_uses_ark()</code> 现在同时识别火山方舟域名和 <code>ai.skg.com/doubao</code>,统一使用 <code>content</code> JSON文本 prompt、首帧、尾帧和产品参考图作为不同 role 传入。火山方舟直连按 <code>/contents/generations/tasks/{id}</code> 轮询SKG 豆包网关<code>/api/v3/contents/generations/tasks/{id}</code> 轮询。<code>api/.env.example</code> 增加 SKG 豆包视频网关配置示例;生视频轮询上限改为 <code>VIDEO_POLL_TIMEOUT_SECONDS</code>,默认 900 秒,避免慢任务过早失败。</p>
<p><strong>影响:</strong><code>api/main.py</code><code>api/.env.example</code><code>docs/source-analysis.html</code>。本机 <code>api/.env</code> 已配置 <code>VIDEO_API_BASE_URL=https://ai.skg.com/doubao</code> 和视频专用 key。</p>
</div>
</article>
@@ -1696,7 +1709,7 @@ SubjectAsset {
</header>
<div class="body">
<p><strong>问题:</strong>用户提供火山方舟 <code>https://ark.cn-beijing.volces.com/api/v3</code> 作为生视频通道;这个通道不是 Poe 的 <code>/videos</code> 形态,而是内容生成异步任务。</p>
<p><strong>改动:</strong>后端识别 Ark base 后,提交改为 <code>POST /contents/generations/tasks</code>,请求体使用 <code>content</code> 数组:文本 prompt + 首帧 <code>image_url</code> data URL轮询改为 <code>GET /contents/generations/tasks/{id}</code>,成功后读取 <code>content.video_url</code> 下载 MP4。本机默认 Seedance 模型改为 Ark 可见的 <code>doubao-seedance-2-0-fast-260128</code></p>
<p><strong>改动:</strong>后端识别 Ark base 后,提交改为内容生成任务接口,火山方舟直连使用 <code>POST /contents/generations/tasks</code>SKG 豆包网关使用 <code>POST /api/v3/contents/generations/tasks</code>请求体使用 <code>content</code> 数组:文本 prompt + 首帧 <code>image_url</code> data URL轮询对应的 <code>{id}</code> 任务地址,成功后读取 <code>content.video_url</code> 下载 MP4。本机默认 Seedance 模型改为 Ark 可见的 <code>doubao-seedance-2-0-fast-260128</code></p>
<p><strong>影响:</strong><code>api/main.py</code><code>api/.env.example</code><code>docs/source-analysis.html</code>。本机 <code>api/.env</code> 需要把 <code>VIDEO_API_BASE_URL</code>/<code>VIDEO_API_KEY</code>/<code>VIDEO_CREATE_PATHS</code>/<code>VIDEO_STATUS_PATH</code> 指向 Ark。</p>
</div>
</article>