auto-save 2026-05-26 09:38 (~2)
This commit is contained in:
@@ -1,30 +1,5 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Claude 会话结束 · 持续 0 秒 · 最近命令:claude · 分支 main · 1 项未提交变更 · 最近提交:auto-save 2026-05-20 14:23 (+1, ~1)",
|
|
||||||
"ts": "2026-05-20T06:37:09Z",
|
|
||||||
"type": "session-end"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Claude 会话结束 · 持续 0 秒 · 最近命令:claude · 分支 main · 1 项未提交变更 · 最近提交:auto-save 2026-05-20 14:23 (+1, ~1)",
|
|
||||||
"ts": "2026-05-20T06:37:09Z",
|
|
||||||
"type": "session-end"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"hash": "16f78ba",
|
|
||||||
"message": "auto-save 2026-05-20 14:39 (+1, ~1)",
|
|
||||||
"ts": "2026-05-20T14:39:42+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 2 项未提交变更 · 最近提交:auto-save 2026-05-20 14:39 (+1, ~1)",
|
|
||||||
"ts": "2026-05-20T06:43:58Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files_changed": 3,
|
"files_changed": 3,
|
||||||
"hash": "d6bba9d",
|
"hash": "d6bba9d",
|
||||||
@@ -3206,6 +3181,31 @@
|
|||||||
"type": "session-heartbeat",
|
"type": "session-heartbeat",
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: disable password login in production",
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: disable password login in production",
|
||||||
"files_changed": 1
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T09:08:30+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "chore: migrate legacy password data to Feishu owner",
|
||||||
|
"hash": "e0330bf",
|
||||||
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T01:09:34Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: migrate legacy password data to Feishu owner",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T01:19:34Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: migrate legacy password data to Feishu owner",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-26T01:29:34Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:chore: migrate legacy password data to Feishu owner",
|
||||||
|
"files_changed": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
86
api/main.py
86
api/main.py
@@ -8035,6 +8035,92 @@ def video_url_from_response(data: dict) -> str:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _video_public_error(raw: object) -> str:
|
||||||
|
text = str(raw or "").strip()
|
||||||
|
lower = text.lower()
|
||||||
|
|
||||||
|
if any(token.lower() in lower for token in (
|
||||||
|
"InputImageSensitiveContentDetected.PrivacyInformation".lower(),
|
||||||
|
"privacyinformation",
|
||||||
|
"privacy information",
|
||||||
|
"real person",
|
||||||
|
"input image may contain real person",
|
||||||
|
"human face",
|
||||||
|
"face detected",
|
||||||
|
"肖像",
|
||||||
|
"隐私",
|
||||||
|
"真人",
|
||||||
|
"人脸",
|
||||||
|
)):
|
||||||
|
return (
|
||||||
|
"视频生成失败:参考图里有清晰人物或疑似真实人脸,视频模型出于肖像/隐私风控拒绝生成。"
|
||||||
|
"请换成无可识别人脸的首帧,或先裁掉/模糊人物脸,再重新生成视频。"
|
||||||
|
)
|
||||||
|
|
||||||
|
if any(token in lower for token in (
|
||||||
|
"sensitivecontent",
|
||||||
|
"sensitive content",
|
||||||
|
"content policy",
|
||||||
|
"violate",
|
||||||
|
"violation",
|
||||||
|
"not allowed",
|
||||||
|
"risk control",
|
||||||
|
"moderation",
|
||||||
|
"敏感",
|
||||||
|
"安全审核",
|
||||||
|
"风控",
|
||||||
|
"违规",
|
||||||
|
)):
|
||||||
|
return (
|
||||||
|
"视频生成失败:参考图或提示词触发了视频模型的内容安全审核。"
|
||||||
|
"请换一张更中性的参考图,避免真实人物、暴露、医疗夸大、危险动作或敏感文字后重试。"
|
||||||
|
)
|
||||||
|
|
||||||
|
if any(token in lower for token in ("unauthorized", "invalid api key", "permission denied", "forbidden", "http 401", "http 403")):
|
||||||
|
return "视频生成失败:视频通道认证或权限异常,请联系管理员检查服务器上的视频 API Key 和模型权限。"
|
||||||
|
|
||||||
|
if any(token in lower for token in ("http 429", "rate limit", "too many requests", "quota", "insufficient", "balance", "限流", "额度", "余额")):
|
||||||
|
return "视频生成失败:视频模型当前限流或额度不足,请稍后重试;如果持续出现,请联系管理员检查视频通道额度。"
|
||||||
|
|
||||||
|
if any(token in lower for token in ("timeout", "timed out", "readtimeout", "connecttimeout", "超时")):
|
||||||
|
return "视频生成失败:视频模型响应超时,可能是上游繁忙或网络不稳定。请稍后重试,或缩短时长后再生成。"
|
||||||
|
|
||||||
|
if any(token in lower for token in (
|
||||||
|
"name or service not known",
|
||||||
|
"temporary failure in name resolution",
|
||||||
|
"nodename nor servname",
|
||||||
|
"connection refused",
|
||||||
|
"network is unreachable",
|
||||||
|
"connecterror",
|
||||||
|
"ssl:",
|
||||||
|
"网络",
|
||||||
|
"dns",
|
||||||
|
)):
|
||||||
|
return "视频生成失败:服务器连接视频模型网关异常,请稍后重试;如果连续失败,请联系管理员检查视频网关网络。"
|
||||||
|
|
||||||
|
if any(token in lower for token in ("http 404", "http 405", "unsupported", "not found", "method not allowed")):
|
||||||
|
return "视频生成失败:当前视频模型接口路径不可用,请联系管理员检查视频网关配置。"
|
||||||
|
|
||||||
|
if lower.startswith("video status: failed") or "video status: failed" in lower:
|
||||||
|
return "视频生成失败:视频模型返回生成失败。请换一张更清晰、主体更稳定的参考图,或简化提示词后重试。"
|
||||||
|
|
||||||
|
if text.startswith("视频生成失败:"):
|
||||||
|
return text[:500]
|
||||||
|
if text:
|
||||||
|
return f"视频生成失败:{text[:460]}"
|
||||||
|
return "视频生成失败:未知错误,请换一张参考图或稍后重试。"
|
||||||
|
|
||||||
|
|
||||||
|
def _video_create_failure_message(create_errors: list[str]) -> str:
|
||||||
|
raw = " | ".join(create_errors)
|
||||||
|
public = _video_public_error(raw)
|
||||||
|
if public.startswith("视频生成失败:当前视频模型接口路径不可用"):
|
||||||
|
return public
|
||||||
|
if public.startswith("视频生成失败:") and public != f"视频生成失败:{raw[:460]}":
|
||||||
|
return public
|
||||||
|
return "视频生成失败:视频模型没有接受本次请求。请换一张参考图或简化提示词后重试;如果持续失败,请联系管理员。"
|
||||||
|
|
||||||
|
|
||||||
def download_generated_video(client, base: str, headers: dict, provider_id: str, direct_url: str, out_mp4: Path) -> None:
|
def download_generated_video(client, base: str, headers: dict, provider_id: str, direct_url: str, out_mp4: Path) -> None:
|
||||||
if direct_url:
|
if direct_url:
|
||||||
url = direct_url if direct_url.startswith("http") else f"{base}{direct_url if direct_url.startswith('/') else '/' + direct_url}"
|
url = direct_url if direct_url.startswith("http") else f"{base}{direct_url if direct_url.startswith('/') else '/' + direct_url}"
|
||||||
|
|||||||
Reference in New Issue
Block a user