From 4ef0b3e8051da7cc0b73ee50186bc3021b670696 Mon Sep 17 00:00:00 2001 From: kris Date: Sat, 4 Apr 2026 08:49:57 +0800 Subject: [PATCH] feat: reopen platform agent detail after mutations --- CHANGELOG.md | 6 ++++++ web/storyforge-web-v4/assets/app.js | 12 ++++++++++++ .../tests/workbench-pages.test.mjs | 13 +++++++++++++ 3 files changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aa0bca..911a73e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ ## 2026-04-04 +### 平台 Agent 变更后自动回到详情工作区 + +- `平台 Agent 配置保存 / 配置回滚 / 记忆保存 / 技能保存 / 技能验收 / 技能回滚` 这些动作成功后,不再只停在通用成功提示。 +- 前端现在会在动作完成后自动重开对应的平台 Agent 详情工作区,让用户立刻看到最新记忆、技能、最近执行和配置版本,不用自己再点回去确认结果。 +- 这条行为已经补进前端回归,锁住平台 Agent 相关变更必须能顺着同一个详情视图继续做下一步。 + ### 主 Agent 完成态保留精确对象上下文 - 主 Agent run 在创建时会把 `target_account_id / tracked_account_id / job_id / review_id / source_id / assistant_id` 这类对象上下文固化进执行计划,不再只记一个泛化的来源页面。 diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index ca8b0a2..7119e6a 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -9533,6 +9533,12 @@ async function openSystemPlatformPolicyHistoryAction(platform, preferredVersionI }); } +function reopenPlatformAgentDetailSoon(platform) { + setTimeout(() => { + void openPlatformAgentDetailAction(platform); + }, 0); +} + function openPlatformAgentProfileAction(platform) { const project = requireSelectedProject(); const agents = safeArray(appState.platformAgents); @@ -9572,6 +9578,7 @@ function openPlatformAgentProfileAction(platform) { appState.platformAgents = safeArray(appState.platformAgents).filter((item) => item.platform !== platform).concat(saved).sort((a, b) => String(a.platform).localeCompare(String(b.platform))); rememberAction("平台 Agent 已保存", `已更新 ${platformLabel(platform)} Agent,当前版本 ${saved.current_version?.version_no || 1}。`, "green", saved); renderAll(); + reopenPlatformAgentDetailSoon(platform); } }); } @@ -9609,6 +9616,7 @@ async function openPlatformAgentProfileHistoryAction(platform, preferredVersionI appState.platformAgents = safeArray(appState.platformAgents).filter((item) => item.platform !== normalizedPlatform).concat(saved).sort((a, b) => String(a.platform).localeCompare(String(b.platform))); rememberAction(`${platformLabel(normalizedPlatform)} Agent 已回滚`, `已回滚到版本 ${saved.current_version?.version_no || "所选版本"}。`, "green", saved); renderAll(); + reopenPlatformAgentDetailSoon(normalizedPlatform); } }); } @@ -9647,6 +9655,7 @@ function openPlatformAgentMemoryAction(platform) { rememberAction("平台记忆已保存", `已把这条方法沉淀到 ${platformLabel(platform)} Agent 记忆中。`, "green", saved); await loadAgentControlSurfaces(project.id); renderAll(); + reopenPlatformAgentDetailSoon(platform); } }); } @@ -9685,6 +9694,7 @@ function openPlatformAgentSkillAction(platform) { rememberAction("平台技能已保存", `已把方法固化到 ${platformLabel(platform)} Agent 技能中。`, "green", saved); await loadAgentControlSurfaces(project.id); renderAll(); + reopenPlatformAgentDetailSoon(platform); } }); } @@ -9860,6 +9870,7 @@ function openPlatformSkillReviewAction(platform, skillId, accepted) { ); await loadAgentControlSurfaces(project.id); renderAll(); + reopenPlatformAgentDetailSoon(normalizedPlatform); } }); } @@ -9897,6 +9908,7 @@ function openPlatformSkillRollbackAction(platform, skillId, versionId) { rememberAction("技能已回滚", `已回滚到版本 ${payload.rollback_from_version?.version_no || "指定版本"}。`, "green", payload); await loadAgentControlSurfaces(project.id); renderAll(); + reopenPlatformAgentDetailSoon(normalizedPlatform); } }); } diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index 7779eb5..8c93dc7 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -790,21 +790,34 @@ test("main agent runtime and platform recent execution preserve structured follo test("platform agent profiles expose history, rollback, and execution version context", () => { const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {"); + const reopenHelper = extractBetween(APP, "function reopenPlatformAgentDetailSoon(platform) {", "function openPlatformAgentProfileAction(platform) {"); const profileEditor = extractBetween(APP, "function openPlatformAgentProfileAction(platform)", "async function openPlatformAgentProfileHistoryAction(platform, preferredVersionId = \"\")"); const profileHistory = extractBetween(APP, "async function openPlatformAgentProfileHistoryAction(platform, preferredVersionId = \"\")", "function openPlatformAgentMemoryAction(platform)"); + const memoryEditor = extractBetween(APP, "function openPlatformAgentMemoryAction(platform)", "function openPlatformAgentSkillAction(platform)"); + const skillEditor = extractBetween(APP, "function openPlatformAgentSkillAction(platform)", "async function openPlatformAgentDetailAction(platform)"); const panel = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()"); const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)"); + const skillReview = extractBetween(APP, "function openPlatformSkillReviewAction(platform, skillId, accepted)", "function openPlatformSkillRollbackAction(platform, skillId, versionId)"); + const skillRollback = extractBetween(APP, "function openPlatformSkillRollbackAction(platform, skillId, versionId)", "function openActionRegistryEditAction(actionKey)"); const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)"); + assert.match(reopenHelper, /setTimeout/); + assert.match(reopenHelper, /openPlatformAgentDetailAction/); assert.match(profileEditor, /renderPolicyVersionSummary\(current,/); assert.match(profileEditor, /name: "reason"/); assert.match(profileEditor, /saved\.current_version\?\.version_no/); + assert.match(profileEditor, /reopenPlatformAgentDetailSoon\(platform\)/); assert.match(profileHistory, /\/v2\/platform-agents\/\$\{encodeURIComponent\(normalizedPlatform\)\}\/profile\/versions/); assert.match(profileHistory, /\/v2\/platform-agents\/\$\{encodeURIComponent\(normalizedPlatform\)\}\/profile\/audits/); assert.match(profileHistory, /\/v2\/platform-agents\/\$\{encodeURIComponent\(normalizedPlatform\)\}\/profile\/rollback/); assert.match(profileHistory, /renderPolicyVersionsHtml/); assert.match(profileHistory, /renderPolicyAuditsHtml/); + assert.match(profileHistory, /reopenPlatformAgentDetailSoon\(normalizedPlatform\)/); + assert.match(memoryEditor, /reopenPlatformAgentDetailSoon\(platform\)/); + assert.match(skillEditor, /reopenPlatformAgentDetailSoon\(platform\)/); + assert.match(skillReview, /reopenPlatformAgentDetailSoon\(normalizedPlatform\)/); + assert.match(skillRollback, /reopenPlatformAgentDetailSoon\(normalizedPlatform\)/); assert.match(panel, /open-platform-agent-profile-history/); assert.match(detail, /open-platform-agent-profile-history/);