feat(product-suite): add cmhub vision AI writing

This commit is contained in:
chengma
2026-07-17 09:09:09 +08:00
parent 56d6b59a00
commit 40a9f5fbf2
15 changed files with 575 additions and 40 deletions
+66
View File
@@ -929,6 +929,61 @@ class ProductSuiteGuiTests(TempDirMixin, unittest.TestCase):
self.assert_removed(temp_dir)
def test_ai_write_uses_first_eight_originals_in_source_order(self):
with self.make_temp_dir() as temp_dir:
config = self._config(temp_dir)
project, assets = self._create_project_with_assets(temp_dir, config, 9)
tab = ProductSuiteTab(config=config, db_path=config["db_path"])
self.addCleanup(tab.close)
state = tab._displayed_state
state.account_alias = "alias-a"
state.item_id = project.item_id
state.project_id = project.id
state.project_binding_state = project.binding_state
tab._load_state(state)
captured = {}
class _Signal:
def connect(self, callback):
self.callback = callback
class _AiWriteWorker:
def __init__(self, instruction, context, **kwargs):
captured["instruction"] = instruction
captured["context"] = context
captured["image_paths"] = list(kwargs.get("image_paths") or [])
self.finished = _Signal()
self.cancelled = _Signal()
self.failed = _Signal()
def cancel(self):
pass
with mock.patch(
"app.gui.tabs.product_suite.ProductSuiteAiWriteWorker",
_AiWriteWorker,
), mock.patch.object(tab, "_start_thread", return_value=object()), mock.patch.object(
tab, "_status"
) as status:
tab.start_ai_write()
self.assertEqual(
[asset.local_path for asset in assets[:8]],
captured["image_paths"],
)
self.assertTrue(
any(
"已使用前8张商品原图进行理解" in str(call.args[0])
for call in status.call_args_list
)
)
state.ai_worker = None
state.ai_thread = None
state.ai_started_at = None
tab._apply_running_state(state)
self.assert_removed(temp_dir)
def test_prompt_edit_expands_shrinks_and_reflows_without_internal_scrollbars(self):
edit = AutoHeightPlainTextEdit()
self.addCleanup(edit.close)
@@ -2219,6 +2274,7 @@ class ProductSuiteGuiTests(TempDirMixin, unittest.TestCase):
def __init__(self, instruction, context, **kwargs):
captured["instruction"] = instruction
captured["context"] = context
captured["image_paths"] = list(kwargs.get("image_paths") or [])
self.finished = _Signal()
self.cancelled = _Signal()
self.failed = _Signal()
@@ -2233,6 +2289,16 @@ class ProductSuiteGuiTests(TempDirMixin, unittest.TestCase):
tab.start_ai_write()
self.assertIn("未绑定商品", captured["context"])
self.assertNotIn("draft_", captured["context"])
self.assertEqual(
[
image_studio.list_assets(
draft.id,
kind=image_studio.ASSET_KIND_ORIGINAL,
path=config["db_path"],
)[0].local_path
],
captured["image_paths"],
)
state.ai_worker = None
state.ai_thread = None
state.ai_started_at = None