feat(product-suite): enable direct generation flow
This commit is contained in:
@@ -69,6 +69,7 @@ from ... import (
|
||||
cmhub_models,
|
||||
diagnostics,
|
||||
image_studio,
|
||||
image_studio_generation,
|
||||
image_studio_images,
|
||||
product_suite,
|
||||
prompts,
|
||||
@@ -1865,6 +1866,7 @@ class SuiteTaskState:
|
||||
generation_mode: str = "batch"
|
||||
generation_retry_job_id: int = None
|
||||
generation_round_key: str = ""
|
||||
generation_source: str = ""
|
||||
worker: object = None
|
||||
thread: object = None
|
||||
generation_run_token: str = ""
|
||||
@@ -3195,8 +3197,10 @@ class ProductSuiteTab(QWidget):
|
||||
def _update_context_actions(self, state):
|
||||
is_draft = self._is_draft_state(state)
|
||||
pull_running = bool(state and state.pull_running())
|
||||
generation_running = bool(state and state.generation_running())
|
||||
self.pull_button.setEnabled(
|
||||
state is not None
|
||||
and not generation_running
|
||||
and (
|
||||
pull_running
|
||||
or is_draft
|
||||
@@ -3204,7 +3208,9 @@ class ProductSuiteTab(QWidget):
|
||||
)
|
||||
)
|
||||
self.pull_button.setToolTip(
|
||||
"正在停止拉取"
|
||||
"生成中不能拉取蝦皮主图"
|
||||
if generation_running
|
||||
else "正在停止拉取"
|
||||
if pull_running and state.pull_stop_requested
|
||||
else "停止拉取蝦皮主图"
|
||||
if pull_running
|
||||
@@ -4181,6 +4187,45 @@ class ProductSuiteTab(QWidget):
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _is_direct_gateway(self):
|
||||
try:
|
||||
return appconfig.ai_backend(self.config) == "direct"
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _direct_generation_config_error(self):
|
||||
"""Return a user-safe direct image-model preflight error, if any."""
|
||||
|
||||
try:
|
||||
ai_config = appconfig.ai_config(self.config)
|
||||
model_name = str(ai_config.get("default_image_model") or "").strip()
|
||||
if not model_name:
|
||||
return "尚未选择图片模型"
|
||||
model = appconfig.get_model(
|
||||
model_name,
|
||||
path=appconfig.ai_models_config_path(self.config),
|
||||
)
|
||||
except Exception:
|
||||
return "当前图片模型不存在或无法读取"
|
||||
if not model.get("enabled", True):
|
||||
return "当前图片模型未启用"
|
||||
return appconfig.image_model_config_error(model)
|
||||
|
||||
def _ensure_generation_gateway(self):
|
||||
if self._is_default_gateway():
|
||||
return True
|
||||
if self._is_direct_gateway():
|
||||
error = self._direct_generation_config_error()
|
||||
if not error:
|
||||
return True
|
||||
self._message(
|
||||
"自定义网关配置不完整",
|
||||
"商品套图无法生成:%s。\n请到⑤设置补齐并保存图片模型配置。" % error,
|
||||
)
|
||||
return False
|
||||
self._message("生成网关不可用", "请到⑤设置选择默认网关或配置自定义网关。")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _is_default_gateway_job(job):
|
||||
return (
|
||||
@@ -4578,6 +4623,8 @@ class ProductSuiteTab(QWidget):
|
||||
(
|
||||
"确认停止当前图片重试吗?已提交任务会在安全边界停止。"
|
||||
if retrying
|
||||
else "确认停止当前任务吗?正在请求的自定义网关图片无法立即撤销;如果图片已返回,程序会先保存,再结束后续任务。"
|
||||
if state.generation_source == image_studio.GENERATION_SOURCE_DIRECT
|
||||
else "确认取消当前任务吗?已提交任务会在安全边界停止。"
|
||||
),
|
||||
destructive=True,
|
||||
@@ -4593,6 +4640,8 @@ class ProductSuiteTab(QWidget):
|
||||
self._status(
|
||||
"已请求停止当前图片重试"
|
||||
if retrying
|
||||
else "正在停止,等待当前图片返回后结束"
|
||||
if state.generation_source == image_studio.GENERATION_SOURCE_DIRECT
|
||||
else "已请求停止当前套图任务",
|
||||
"warning",
|
||||
)
|
||||
@@ -4600,7 +4649,7 @@ class ProductSuiteTab(QWidget):
|
||||
self.start_generation(state)
|
||||
|
||||
def start_generation(self, state, specs=None, *, retry_job_id=None):
|
||||
if not self._require_default_gateway("商品套图生成"):
|
||||
if not self._ensure_generation_gateway():
|
||||
return False
|
||||
if state.generation_running():
|
||||
self._status("当前套图任务仍在生成", "warning")
|
||||
@@ -4711,6 +4760,7 @@ class ProductSuiteTab(QWidget):
|
||||
retry_job_id,
|
||||
):
|
||||
self._persist_state(state)
|
||||
source = image_studio_generation.generation_source_for_config(self.config)
|
||||
run_token = uuid.uuid4().hex
|
||||
worker = ProductSuiteGenerateWorker(
|
||||
state.project_id,
|
||||
@@ -4728,6 +4778,7 @@ class ProductSuiteTab(QWidget):
|
||||
state.generation_terminal_streak = 0
|
||||
state.generation_job_ids = []
|
||||
state.generation_mode = "retry" if retrying else "batch"
|
||||
state.generation_source = source["generation_source"]
|
||||
state.generation_retry_job_id = retry_job_id
|
||||
state.generation_round_key = generation_round_key
|
||||
state.done = 0
|
||||
@@ -4775,6 +4826,15 @@ class ProductSuiteTab(QWidget):
|
||||
self._status("正在读取套图预计扣点", "info")
|
||||
return False
|
||||
snapshot = self._generation_plan_snapshot(state, local_assets, specs, template_text)
|
||||
if self._is_direct_gateway():
|
||||
return self._confirm_generation_price_request(
|
||||
state,
|
||||
local_assets,
|
||||
specs,
|
||||
generation_round_key,
|
||||
snapshot,
|
||||
None,
|
||||
)
|
||||
params = self._cmhub_catalog_params("image_alias")
|
||||
cached_models = (
|
||||
cmhub_models.cached_model_catalog(params["base_url"], params["alias"])
|
||||
@@ -4861,6 +4921,7 @@ class ProductSuiteTab(QWidget):
|
||||
"item_id": str(state.item_id or ""),
|
||||
"template_text": str(template_text or ""),
|
||||
"specs": self._generation_specs_signature(specs),
|
||||
"generation_backend": appconfig.ai_backend(self.config),
|
||||
}
|
||||
|
||||
def _generation_plan_is_current(self, state, snapshot):
|
||||
@@ -4996,6 +5057,10 @@ class ProductSuiteTab(QWidget):
|
||||
0,
|
||||
len(local_assets) - 1 - reference_count,
|
||||
)
|
||||
output_spec = image_studio_generation.requested_output_spec(
|
||||
state.settings.get("ratio") or "1:1"
|
||||
)
|
||||
direct_gateway = self._is_direct_gateway()
|
||||
lines = [
|
||||
"店铺:%s" % self._account_context_label(state),
|
||||
"商品ID:%s" % (state.item_id or "未绑定商品"),
|
||||
@@ -5030,7 +5095,25 @@ class ProductSuiteTab(QWidget):
|
||||
"",
|
||||
]
|
||||
)
|
||||
if estimate is None:
|
||||
lines.extend(
|
||||
[
|
||||
"输出尺寸:%s%s"
|
||||
% (
|
||||
output_spec["requested_output_size"],
|
||||
"(接近比例生成)" if output_spec["approximate_ratio"] else "",
|
||||
),
|
||||
"",
|
||||
]
|
||||
)
|
||||
if direct_gateway:
|
||||
lines.extend(
|
||||
[
|
||||
"生成来源:自定义网关",
|
||||
"自定义网关不计点数,实际费用以服务商为准。",
|
||||
"首图作为主要商品参考;参考图效果取决于模型,商品主体一致性可能弱于默认网关。",
|
||||
]
|
||||
)
|
||||
elif estimate is None:
|
||||
lines.append("本次会消耗 cmhub 点数,暂时无法取得预计扣点,实际以网关返回为准。")
|
||||
else:
|
||||
unit_cost, total_cost = estimate
|
||||
@@ -5395,6 +5478,7 @@ class ProductSuiteTab(QWidget):
|
||||
state.generation_job_ids = []
|
||||
state.generation_retry_job_id = None
|
||||
state.generation_round_key = ""
|
||||
state.generation_source = ""
|
||||
state.worker = None
|
||||
state.thread = None
|
||||
state.done = success + failed + cancelled
|
||||
@@ -5535,6 +5619,7 @@ class ProductSuiteTab(QWidget):
|
||||
generation_price_pending = state.generation_price_worker is not None
|
||||
pull_running = state.pull_running()
|
||||
default_gateway = self._is_default_gateway()
|
||||
supported_gateway = default_gateway or self._is_direct_gateway()
|
||||
self.pull_button.setText(
|
||||
"正在停止..."
|
||||
if pull_running and state.pull_stop_requested
|
||||
@@ -5554,6 +5639,7 @@ class ProductSuiteTab(QWidget):
|
||||
self.ratio_combo,
|
||||
self.per_image_checkbox,
|
||||
self.prompt_edit,
|
||||
self.prompt_settings_button,
|
||||
self.add_category_button,
|
||||
self.custom_category_edit,
|
||||
):
|
||||
@@ -5561,7 +5647,7 @@ class ProductSuiteTab(QWidget):
|
||||
for row in self.category_rows.values():
|
||||
row.set_controls_enabled(not generation_running)
|
||||
self.generate_button.setEnabled(
|
||||
generation_running or generation_price_pending or default_gateway
|
||||
generation_running or generation_price_pending or supported_gateway
|
||||
)
|
||||
if generation_running:
|
||||
self.generate_button.setText(
|
||||
@@ -5593,7 +5679,7 @@ class ProductSuiteTab(QWidget):
|
||||
)
|
||||
if not default_gateway and not ai_running:
|
||||
self.ai_write_button.setToolTip("商品套图AI帮写仅支持默认网关")
|
||||
self.generate_button.setToolTip("商品套图生成仅支持默认网关")
|
||||
self.generate_button.setToolTip("自定义网关生成不计点数,实际费用以服务商为准")
|
||||
else:
|
||||
self.ai_write_button.setToolTip("")
|
||||
self.generate_button.setToolTip("")
|
||||
|
||||
Reference in New Issue
Block a user