feat(product-suite): add direct job state machine

This commit is contained in:
chengma
2026-07-20 18:12:44 +08:00
parent 2a2cbad7bd
commit aa000ff5e6
11 changed files with 820 additions and 101 deletions
+30 -1
View File
@@ -6,7 +6,7 @@ import os
import sys
from dataclasses import replace
from .. import appconfig, chrome, diagnostics, update_check, update_health
from .. import appconfig, chrome, db, diagnostics, image_studio_generation, update_check, update_health
from ..version import APP_NAME, APP_VERSION, display_name
from . import widgets as _widgets
from .widgets import *
@@ -155,10 +155,39 @@ def main() -> int:
update_health.write_health(health_context, "environment_blocked", str(exc))
QMessageBox.critical(None, "启动配置错误", str(exc))
return 1
runtime_lease = None
try:
database_path = appconfig.db_path(startup["config"])
db.init_db(database_path)
runtime_lease = image_studio_generation.acquire_startup_recovery_lease(
appconfig.data_dir(startup["config"])
)
recovery = image_studio_generation.recover_stale_direct_jobs_at_startup(
lease=runtime_lease,
path=database_path,
)
recovered_count = len(recovery.get("recovered") or [])
if recovered_count:
diagnostics.write_diagnostic_log(
"启动时标记未确认的自定义网关套图任务",
level="WARNING",
step="image_studio_direct_recovery",
payload={"recovered_count": recovered_count},
)
elif recovery.get("skipped"):
diagnostics.write_diagnostic_log(
"检测到另一个程序实例,跳过自定义网关套图任务恢复",
level="INFO",
step="image_studio_direct_recovery",
)
except Exception as exc:
_write_update_check_diagnostic("自定义网关套图任务恢复检查失败", exc=exc)
window = MainWindow(
config=startup["config"],
startup_status=startup["message"],
)
if runtime_lease is not None:
app.aboutToQuit.connect(runtime_lease.release)
window.show()
QTimer.singleShot(
0,
+11 -9
View File
@@ -262,7 +262,7 @@ class ImageStudioDownloadOriginalWorker(BaseWorker):
class ImageStudioGenerateJobsWorker(BaseWorker):
"""Run cmhub hosted image generation jobs for the AI studio."""
"""Run frozen-source image generation jobs for the AI studio."""
def __init__(
self,
@@ -285,12 +285,13 @@ class ImageStudioGenerateJobsWorker(BaseWorker):
self.job_type = str(job_type or "main")
self.aspect_ratio = str(aspect_ratio or "1:1")
self.db_path = db_path
backend = appconfig.ai_backend(config)
self.config = ai.freeze_runtime_config(
config,
cmhub_config_path=cmhub_config_path,
models_path=(config or {}).get("ai_models_path", appconfig.AI_MODELS_PATH),
include_cmhub=True,
include_direct_models=False,
include_cmhub=backend == "cmhub",
include_direct_models=backend == "direct",
)
self.cmhub_config_path = cmhub_config_path
self._done = 0
@@ -364,12 +365,13 @@ class ProductSuiteGenerateWorker(BaseWorker):
self.generation_round_key = str(generation_round_key or "").strip()
self.aspect_ratio = str(aspect_ratio or "1:1")
self.db_path = db_path
backend = appconfig.ai_backend(config)
self.config = ai.freeze_runtime_config(
config,
cmhub_config_path=cmhub_config_path,
models_path=(config or {}).get("ai_models_path", appconfig.AI_MODELS_PATH),
include_cmhub=True,
include_direct_models=False,
include_cmhub=backend == "cmhub",
include_direct_models=backend == "direct",
)
self.cmhub_config_path = cmhub_config_path
self.job_ids = []
@@ -378,12 +380,11 @@ class ProductSuiteGenerateWorker(BaseWorker):
self._lock = threading.Lock()
def execute(self):
if appconfig.ai_backend(self.config) != "cmhub":
raise ValueError("商品套图仅支持默认网关,请到⑤设置切换后再生成")
total = len(self.job_specs)
if total <= 0:
raise ValueError("商品套图生成任务不能为空")
jobs = []
source = image_studio_generation.generation_source_for_config(self.config)
for spec in self.job_specs:
jobs.append(
image_studio.create_job(
@@ -392,8 +393,8 @@ class ProductSuiteGenerateWorker(BaseWorker):
reference_asset_ids=spec.get("reference_asset_ids"),
job_type=spec.get("job_type") or "套图",
prompt=spec.get("prompt") or "",
generation_source="cmhub",
provider="cmhub",
generation_source=source["generation_source"],
provider=source["provider"],
generation_round_key=spec.get("generation_round_key") or self.generation_round_key or None,
generation_slot_index=spec.get("generation_slot_index"),
path=self.db_path,
@@ -435,6 +436,7 @@ class ProductSuiteGenerateWorker(BaseWorker):
path=self.db_path,
should_stop=self.should_cancel,
on_event=on_event,
run_session_id=self.run_token,
)
summary["project_id"] = self.project_id
summary["job_ids"] = list(self.job_ids)