fix(core): 资产详情大图随数据显示,缩略图已出大图不再卡转圈

- 三视图/立绘大图改为跟数据(url)走,出图完成即显示,不再被在途轮询的
  busy 标志挡住——根治「小缩略图已出、大图一直转圈」
- 一并带上工作区其余改动(script_agent / services / tests / ai-tools / actor-library / App)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-18 10:57:02 +08:00
co-authored by Claude Opus 4.8
parent fe38d3a512
commit 326c34ecd1
7 changed files with 200 additions and 47 deletions
+28
View File
@@ -819,6 +819,34 @@ def build_storyboard_frame_prompt_refs(project, version, segment, refs: list[dic
return "\n".join(line for line in lines if line)
def _is_transient_error(exc: Exception) -> bool:
"""网络抖动/超时类瞬时错误(可重试),区别于内容审核拦截、参数非法等确定性失败。
中转站(tokenssr 等)偶发 Read timeout / 连接重置会无谓掐掉单帧,这类才重试。"""
msg = str(exc).lower()
return any(
k in msg
for k in ("timed out", "timeout", "connection", "reset by peer", "temporarily",
"bad gateway", "502", "503", "504", "remotedisconnected", "max retries")
)
def _call_image_with_retry(fn, *, attempts: int = 3, base_delay: float = 2.0):
"""对一次出图网络调用做有界重试:仅瞬时错误重试(指数退避),确定性失败立即抛出。
出图无副作用(失败=没拿到图),重试安全;成功一次即返回。"""
import time
last: Exception | None = None
for i in range(attempts):
try:
return fn()
except Exception as exc: # noqa: BLE001
last = exc
if i == attempts - 1 or not _is_transient_error(exc):
raise
time.sleep(base_delay * (i + 1))
raise last # 理论不可达(循环内已 return/raise)
def _storyboard_frame_worker(task_id, version_id, segment_id, user_id) -> None:
"""后台线程:真正调 ARK 生成一帧故事板图并落库。每次 poll 不阻塞在此——HTTP 永远秒回。"""
import threading # noqa: F401 — 仅标注此函数运行在独立线程