Publish current ComfyUI O1Key code baseline

Replace the prior release tree with the current plugin, frontend, tests, and documentation. Document retired node IDs and the public Gitea update source.
This commit is contained in:
Jony
2026-09-24 19:56:48 +08:00
parent 3e337722ab
commit ba920f2b66
183 changed files with 49496 additions and 9934 deletions
+19 -44
View File
@@ -16,6 +16,10 @@ import aiohttp
from .base_client import BaseAPIClient
from ..utils.config import get_api_base_url, get_api_key_or_raise
from ..utils.video_task import (
POLL_DEADLINE_SECONDS as VIDEO_POLL_DEADLINE_SECONDS,
download_video_to_file,
)
class NewAPIVeoClient(BaseAPIClient):
@@ -26,6 +30,7 @@ class NewAPIVeoClient(BaseAPIClient):
RETRYABLE_STATUS_CODES = {408, 409, 425, 429, 500, 502, 503, 504}
COMPLETED_STATUSES = {"completed", "succeeded", "success", "done"}
FAILED_STATUSES = {"failed", "error", "cancelled", "canceled"}
POLL_DEADLINE_SECONDS = VIDEO_POLL_DEADLINE_SECONDS
def __init__(
self,
@@ -318,7 +323,7 @@ class NewAPIVeoClient(BaseAPIClient):
self,
task_id: str,
poll_interval: int = 5,
timeout: int = 900,
timeout: int = VIDEO_POLL_DEADLINE_SECONDS,
progress_callback: Optional[Callable[[int, str, float], None]] = None,
session: Optional[aiohttp.ClientSession] = None,
) -> Dict[str, Any]:
@@ -376,30 +381,8 @@ class NewAPIVeoClient(BaseAPIClient):
session: aiohttp.ClientSession,
max_retries: int = 3,
) -> None:
timeout = aiohttp.ClientTimeout(total=900, connect=30, sock_read=900)
last_status = 0
last_error = ""
for attempt in range(max_retries + 1):
async with session.get(url, timeout=timeout, allow_redirects=True) as response:
if response.status < 300:
os.makedirs(os.path.dirname(save_path), exist_ok=True)
with open(save_path, "wb") as f:
async for chunk in response.content.iter_chunked(1024 * 1024):
if chunk:
f.write(chunk)
return
last_status = response.status
last_error = await response.text()
if response.status not in self.RETRYABLE_STATUS_CODES or attempt >= max_retries:
break
await asyncio.sleep(min(2 ** attempt, 8))
raise RuntimeError(
self._format_http_error("download_url", last_status, last_error)
)
# 抗超时 / 断点续传 / 无限重试 / 可取消
await download_video_to_file(session, url, save_path, label="VEO 视频")
async def download_video_async(
self,
@@ -410,7 +393,7 @@ class NewAPIVeoClient(BaseAPIClient):
endpoint = self.CONTENT_ENDPOINT.format(task_id=task_id)
url = f"{self.base_url}{endpoint}"
headers = self.get_headers(use_bearer_token=True)
timeout = aiohttp.ClientTimeout(total=900, connect=30, sock_read=900)
timeout = aiohttp.ClientTimeout(total=120, connect=30, sock_read=120)
close_session = False
if session is None:
@@ -420,6 +403,7 @@ class NewAPIVeoClient(BaseAPIClient):
try:
last_status = 0
last_error = ""
# 先探测 content 端点:JSON 则取真实下载链接,否则视为视频流交给健壮下载器。
for attempt in range(4):
async with session.get(url, headers=headers, timeout=timeout, allow_redirects=True) as response:
if response.status < 300:
@@ -440,30 +424,21 @@ class NewAPIVeoClient(BaseAPIClient):
f"task_id: {task_id}"
)
await self._download_url_to_file(download_url, save_path, session)
else:
os.makedirs(os.path.dirname(save_path), exist_ok=True)
with open(save_path, "wb") as f:
async for chunk in response.content.iter_chunked(1024 * 1024):
if chunk:
f.write(chunk)
if not os.path.isfile(save_path) or os.path.getsize(save_path) <= 0:
raise RuntimeError(
"视频下载失败: 保存后的文件为空。\n"
f"endpoint: {endpoint}\n"
f"task_id: {task_id}"
)
return save_path
return save_path
break # 非 JSONcontent 端点即视频流(幂等 GET,可续传)
last_status = response.status
last_error = await response.text()
if response.status not in self.RETRYABLE_STATUS_CODES or attempt >= 3:
break
raise RuntimeError(
self._format_http_error(endpoint, last_status, last_error, task_id=task_id)
)
await asyncio.sleep(min(2 ** attempt, 8))
raise RuntimeError(
self._format_http_error(endpoint, last_status, last_error, task_id=task_id)
# 抗超时 / 断点续传 / 无限重试 / 可取消
return await download_video_to_file(
session, url, save_path, headers=headers, label="VEO 视频",
)
finally:
if close_session:
@@ -481,7 +456,7 @@ class NewAPIVeoClient(BaseAPIClient):
generate_audio: bool = True,
image_bytes: Optional[bytes] = None,
poll_interval: int = 5,
timeout: int = 900,
timeout: int = VIDEO_POLL_DEADLINE_SECONDS,
reuse_task_id: str = "",
progress_callback: Optional[Callable[[int, str, float], None]] = None,
) -> Dict[str, Any]: