From 0b96562e863586818fe95820b2c5536d05dfa328 Mon Sep 17 00:00:00 2001 From: kris Date: Sun, 5 Apr 2026 08:14:33 +0800 Subject: [PATCH] feat: land direct copy results and expand live action smoke --- CHANGELOG.md | 1 + collector-service/app/oneliner_features.py | 6 +++--- scripts/smoke_fnos_storyforge_lan.sh | 1 + tests/test_main_agent_governance.py | 2 +- web/storyforge-web-v4/assets/app.js | 5 +++++ web/storyforge-web-v4/tests/workbench-pages.test.mjs | 1 + 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be56dea..526901a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -477,3 +477,4 @@ - 后端新增了 `import-video-link / import-text` 两条真实执行动作,并且 `generate-copy / import-homepage / track-account / create-ai-video` 现在都会优先尊重显式 `assistant_id`,避免切到执行器后丢失用户在表单里选定的 Agent。 - `runDirectWorkbenchAction / runDirectDiscoveryAction` 也已支持显式 `projectId / platform`,所以这批旧表单里的“归属项目 / 平台”选择不会在切换到执行器后失效。 - SQLite 连接现在保持 `WAL` 优先,但在临时盘或受限文件系统无法启用 `WAL` 时会自动回退到 `DELETE`,避免测试环境和受限部署因为 `disk I/O error` 直接起不来。 +- `generate-copy` 这条执行链现在会直接推荐回到“最近生成”结果区,而不是再打开旧文案表单;LAN smoke 也同步把 `track-account / import-video-link / import-text / generate-copy / create-assistant` 纳入 action-registry 护栏。 diff --git a/collector-service/app/oneliner_features.py b/collector-service/app/oneliner_features.py index 4b06ed0..bbe1adf 100644 --- a/collector-service/app/oneliner_features.py +++ b/collector-service/app/oneliner_features.py @@ -5756,9 +5756,9 @@ def register_oneliner_routes(app: Any, legacy: Any) -> None: "summary": f"已用 {assistant.get('name') or '默认 Agent'} 生成一版可发布文案。", "payload": payload, "recommended_action": _recommended_action( - "open-generate-copy", - label="继续调文案", - summary="继续修改提示、受众和补充要求,快速迭代这版文案。", + "open-generated-copy-results", + label="查看最近生成", + summary="直接回到最近生成结果区,继续查看、复制和迭代这版文案。", screen="playbook", platform=normalized_platform or "douyin", ), diff --git a/scripts/smoke_fnos_storyforge_lan.sh b/scripts/smoke_fnos_storyforge_lan.sh index 76675db..a5b6292 100755 --- a/scripts/smoke_fnos_storyforge_lan.sh +++ b/scripts/smoke_fnos_storyforge_lan.sh @@ -114,6 +114,7 @@ payload = json.loads(pathlib.Path(sys.argv[1]).read_text()) items = payload.get("items") or [] keys = {str(item.get("action_key") or "") for item in items} required = {"import-homepage", "search-similar-accounts", "save-benchmark-link", "refresh-tracking", "mark-tracking-read"} +required = required | {"track-account", "import-video-link", "import-text", "generate-copy", "create-assistant"} missing = sorted(required - keys) if missing: raise SystemExit(f"action registry missing: {missing}") diff --git a/tests/test_main_agent_governance.py b/tests/test_main_agent_governance.py index 2d7c639..bacec29 100644 --- a/tests/test_main_agent_governance.py +++ b/tests/test_main_agent_governance.py @@ -1016,7 +1016,7 @@ class MainAgentGovernanceTests(unittest.TestCase): ) self.assertEqual(copy_response.status_code, 200, copy_response.text) copy_payload = copy_response.json() - self.assertEqual(copy_payload["recommended_action"]["action"], "open-generate-copy") + self.assertEqual(copy_payload["recommended_action"]["action"], "open-generated-copy-results") self.assertEqual(copy_payload["recommended_action"]["screen"], "playbook") self.assertEqual(copy_payload["recommended_action"]["platform"], "douyin") diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index 090ca38..c282ece 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -12325,6 +12325,11 @@ document.addEventListener("click", async (event) => { openGenerateCopyAction(); return; } + if (name === "open-generated-copy-results") { + closeActionModal(); + focusRecentGeneratedCopy(); + return; + } if (name === "direct-generate-copy") { const jobId = action.dataset.jobId || ""; const detail = appState.lastJobDetail?.job?.id === jobId ? appState.lastJobDetail.job : null; diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index 7d27b38..a8b2a3e 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -387,6 +387,7 @@ test("job detail and follow-up flows use direct generate-copy execution and pers assert.match(APP, /function cacheGeneratedCopyResult\(payload, options = \{\}\)/); assert.match(jobDetail, /actionTag\("用摘要写文案", "direct-generate-copy"/); + assert.match(clickActions, /name === "open-generated-copy-results"[\s\S]*focusRecentGeneratedCopy\(\)/); assert.match(clickActions, /name === "direct-generate-copy"[\s\S]*runDirectWorkbenchAction\("generate-copy"/); assert.match(clickActions, /name === "direct-generate-copy"[\s\S]*followRecommendedAction:\s*false/); assert.match(clickActions, /name === "direct-generate-copy"[\s\S]*cacheGeneratedCopyResult\(result,\s*\{\s*brief\s*\}\)/);