diff --git a/backend/python/app/api/chat.py b/backend/python/app/api/chat.py index 98b78b5..1df62c3 100644 --- a/backend/python/app/api/chat.py +++ b/backend/python/app/api/chat.py @@ -239,6 +239,49 @@ async def _optimize_media_prompt(raw_prompt: str, media_type: str, db=None) -> s return stripped +def _friendly_media_err(kind: str, raw: str) -> str: + """把 AGNES 原始错误转译为对用户友好的中文。 + + AGNES 常见错误:429 限频(每分钟1次视频) / Server disconnected(连接重置) / + publish_video_queue_failed + context deadline exceeded(队列超时)。这些都不是 + 平台代码问题,统一给出可操作的提示,不把原始 HTTP/JSON 甩给用户。 + """ + r = (raw or "").lower() + if "429" in raw or "rate limit" in r: + return (f"⚠️ {kind}生成请求过于频繁(AGNES 限制每分钟 1 次)," + f"请稍等 1 分钟后再试。") + if "server disconnected" in r or "连接" in raw or "reset" in r: + return f"⚠️ {kind}生成服务暂时连接失败,请稍后重试。" + if "publish_video" in r or "queue" in r or "deadline" in r or "context" in r: + return f"⚠️ {kind}生成队列繁忙(AGNES 处理超时),请稍后重试。" + return f"⚠️ {kind}生成失败(请稍后重试):{(raw or '')[:120]}" + + +async def _agnes_post_json(api_url: str, headers: dict, payload: dict, timeout) -> tuple: + """直连 AGNES 发 POST,对 5xx / 连接中断做指数退避重试。 + + AGNES 视频/图像队列极不稳定:经常返回 500 publish_video_queue_failed / + context deadline exceeded,或连接被重置(Server disconnected)。这类错误是 AGNES + 侧瞬时抖动,重试通常立刻成功。4xx(参数错误)不重试,直接返回。 + 返回 (resp, err):成功(resp.status_code<500) 时 err=None;耗尽重试时 resp=None。 + """ + last_err = None + for attempt in range(3): + try: + async with httpx.AsyncClient( + timeout=timeout, proxy=_proxy_for_url(api_url), trust_env=False + ) as client: + resp = await client.post(api_url, headers=headers, json=payload) + if resp.status_code < 500: + return resp, None + last_err = f"HTTP {resp.status_code}: {resp.text[:200]}" + except Exception as e: + last_err = str(e)[:200] + if attempt < 2: + await asyncio.sleep(2 * (attempt + 1)) + return None, last_err + + async def _generate_media(db, ai_model, prompt: str, user_id: str = None) -> str: """图像/视频生成模型统一入口:按 capabilities 调用 AGNES 等媒体生成 API。 返回可直接在 AI 聊天中渲染的富文本(含 /