feat: version platform agent profiles through main agent runs
This commit is contained in:
@@ -2019,6 +2019,7 @@ function renderOneLinerExecutionPayloadHtml(payload) {
|
||||
<span class="tag blue">${escapeHtml(platformAgentProfile.platform_label || platformLabel(platformAgentProfile.platform))}</span>
|
||||
${platformAgentProfile.name ? `<span class="tag">${escapeHtml(platformAgentProfile.name)}</span>` : ""}
|
||||
${platformAgentProfile.assistant_name ? `<span class="tag green">${escapeHtml(platformAgentProfile.assistant_name)}</span>` : ""}
|
||||
${platformAgentProfile.version_no ? `<span class="tag">${escapeHtml(platformLabel(platformAgentProfile.platform || payload.platform || ""))} Agent v${escapeHtml(formatNumber(platformAgentProfile.version_no || 0))}</span>` : ""}
|
||||
${platformAgentProfile.readiness_label ? `<span class="tag ${platformAgentProfile.readiness_score >= 75 ? "green" : platformAgentProfile.readiness_score >= 50 ? "blue" : "orange"}">${escapeHtml(platformAgentProfile.readiness_label)} ${escapeHtml(formatNumber(platformAgentProfile.readiness_score || 0))}</span>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
@@ -4458,6 +4459,7 @@ function renderPlatformAgentPanel() {
|
||||
<span class="tag blue">${escapeHtml(item.recent_execution.intent_label || "主 Agent 任务")}</span>
|
||||
<span class="tag">${escapeHtml(item.recent_execution.run_status || "done")}</span>
|
||||
${item.recent_execution.oneliner_profile_version_no ? `<span class="tag">配置 v${escapeHtml(formatNumber(item.recent_execution.oneliner_profile_version_no))}</span>` : ""}
|
||||
${item.recent_execution.platform_agent_profile_version_no ? `<span class="tag">${escapeHtml(item.platform_label || platformLabel(item.platform))} Agent v${escapeHtml(formatNumber(item.recent_execution.platform_agent_profile_version_no))}</span>` : ""}
|
||||
${item.recent_execution.source_screen ? `<span class="tag">${escapeHtml(screenLabel(item.recent_execution.source_screen) || item.recent_execution.source_screen)}</span>` : ""}
|
||||
</div>
|
||||
<div class="task-meta" style="margin-top:8px;">
|
||||
@@ -4469,6 +4471,7 @@ function renderPlatformAgentPanel() {
|
||||
<div class="task-meta" style="margin-top:10px;">
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-detail" data-platform="${escapeHtml(item.platform)}">查看详情</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-profile" data-platform="${escapeHtml(item.platform)}">配置</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-profile-history" data-platform="${escapeHtml(item.platform)}">看配置历史</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-memory" data-platform="${escapeHtml(item.platform)}">补记忆</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-skill" data-platform="${escapeHtml(item.platform)}">补技能</span>
|
||||
</div>
|
||||
@@ -9239,11 +9242,13 @@ function openPlatformAgentProfileAction(platform) {
|
||||
description: "给这个平台绑定自己的执行 Agent,并补充任务目标和方法论定位。",
|
||||
submitLabel: "保存平台 Agent",
|
||||
fields: [
|
||||
{ type: "html", label: "当前版本", html: renderPolicyVersionSummary(current, `当前 ${platformLabel(platform)} Agent 还没有历史版本。`) },
|
||||
{ name: "assistantId", label: "绑定执行 Agent", type: "select", value: current.assistant_id || assistants[0]?.value || "", options: [{ value: "", label: "先不绑定" }, ...assistants] },
|
||||
{ name: "name", label: "名称", value: current.name || `${platformLabel(platform)} Agent`, placeholder: "例如:快手增长 Agent" },
|
||||
{ name: "mission", label: "任务目标", type: "textarea", rows: 4, value: current.mission || "", placeholder: "例如:沉淀快手平台的开场结构、停留逻辑和转化方法论" },
|
||||
{ name: "notes", label: "补充说明", type: "textarea", rows: 4, value: current.notes || "", placeholder: "例如:优先观察短句节奏、直播切片和成交句式" },
|
||||
{ name: "status", label: "状态", type: "select", value: current.status || "active", options: [{ value: "active", label: "启用" }, { value: "draft", label: "草稿" }, { value: "paused", label: "暂停" }] }
|
||||
{ name: "status", label: "状态", type: "select", value: current.status || "active", options: [{ value: "active", label: "启用" }, { value: "draft", label: "草稿" }, { value: "paused", label: "暂停" }] },
|
||||
{ name: "reason", label: "变更原因", type: "textarea", rows: 3, value: "", placeholder: "例如:调整当前平台 Agent 的拆解重点和执行方向" }
|
||||
],
|
||||
onSubmit: async (values) => {
|
||||
const saved = await storyforgeFetch(`/v2/platform-agents/${encodeURIComponent(platform)}/profile`, {
|
||||
@@ -9255,6 +9260,7 @@ function openPlatformAgentProfileAction(platform) {
|
||||
mission: values.mission || "",
|
||||
notes: values.notes || "",
|
||||
status: values.status || "active",
|
||||
reason: values.reason || "",
|
||||
config: {
|
||||
self_optimize: true,
|
||||
tenant_scoped_memory: true,
|
||||
@@ -9263,7 +9269,44 @@ 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。`, "green", saved);
|
||||
rememberAction("平台 Agent 已保存", `已更新 ${platformLabel(platform)} Agent,当前版本 ${saved.current_version?.version_no || 1}。`, "green", saved);
|
||||
renderAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function openPlatformAgentProfileHistoryAction(platform) {
|
||||
const project = requireSelectedProject();
|
||||
const normalizedPlatform = normalizePlatformValue(platform || getPreferredPlatform(), "douyin");
|
||||
const history = await loadPolicyVersions(`/v2/platform-agents/${encodeURIComponent(normalizedPlatform)}/profile/versions?project_id=${encodeURIComponent(project.id)}`);
|
||||
const audits = await storyforgeFetch(`/v2/platform-agents/${encodeURIComponent(normalizedPlatform)}/profile/audits?project_id=${encodeURIComponent(project.id)}`).catch(() => ({ items: [] }));
|
||||
const current = safeArray(appState.platformAgents).find((item) => item.platform === normalizedPlatform) || {};
|
||||
const selectedVersionId = history.items[0]?.id || "";
|
||||
openActionModal({
|
||||
title: `${platformLabel(normalizedPlatform)} Agent 配置历史`,
|
||||
description: "查看平台 Agent 配置版本,并从历史里选择一个版本回滚。",
|
||||
submitLabel: "回滚到所选版本",
|
||||
hideSubmit: !selectedVersionId,
|
||||
fields: [
|
||||
{ type: "html", label: "当前版本", html: renderPolicyVersionSummary(current, `当前 ${platformLabel(normalizedPlatform)} Agent 还没有历史版本。`) },
|
||||
{ type: "html", label: "历史版本", html: renderPolicyVersionsHtml(history.items, `当前 ${platformLabel(normalizedPlatform)} Agent 还没有历史版本。`) },
|
||||
{ type: "html", label: "审计记录", html: renderPolicyAuditsHtml(safeArray(audits.items || audits), "当前还没有审计记录。") },
|
||||
...(selectedVersionId ? [
|
||||
{ name: "versionId", label: "回滚版本", type: "select", value: selectedVersionId, options: safeArray(history.items).map((item) => ({ value: item.id, label: `v${formatNumber(item.version_no || 0)} · ${item.title || brief(item.summary || item.id, 24)}` })) },
|
||||
{ name: "reason", label: "回滚原因", type: "textarea", rows: 3, value: "", placeholder: "例如:恢复到上一版平台 Agent 方法论" }
|
||||
] : [])
|
||||
],
|
||||
onSubmit: async (values) => {
|
||||
const saved = await storyforgeFetch(`/v2/platform-agents/${encodeURIComponent(normalizedPlatform)}/profile/rollback`, {
|
||||
method: "POST",
|
||||
body: {
|
||||
project_id: project.id,
|
||||
version_id: values.versionId || selectedVersionId,
|
||||
reason: values.reason || ""
|
||||
}
|
||||
});
|
||||
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();
|
||||
}
|
||||
});
|
||||
@@ -9394,6 +9437,7 @@ async function openPlatformAgentDetailAction(platform) {
|
||||
<span class="tag blue">${escapeHtml(profile.recent_execution.intent_label || "主 Agent 任务")}</span>
|
||||
<span class="tag">${escapeHtml(profile.recent_execution.run_status || "done")}</span>
|
||||
${profile.recent_execution.oneliner_profile_version_no ? `<span class="tag">配置 v${escapeHtml(formatNumber(profile.recent_execution.oneliner_profile_version_no))}</span>` : ""}
|
||||
${profile.recent_execution.platform_agent_profile_version_no ? `<span class="tag">${escapeHtml(platformLabel(normalizedPlatform))} Agent v${escapeHtml(formatNumber(profile.recent_execution.platform_agent_profile_version_no))}</span>` : ""}
|
||||
${profile.recent_execution.source_screen ? `<span class="tag">${escapeHtml(screenLabel(profile.recent_execution.source_screen) || profile.recent_execution.source_screen)}</span>` : ""}
|
||||
</div>
|
||||
<div class="task-meta" style="margin-top:8px;">
|
||||
@@ -9446,6 +9490,7 @@ async function openPlatformAgentDetailAction(platform) {
|
||||
<div class="task-meta" style="margin-top:12px;">
|
||||
<span class="tag clickable-tag" data-action="run-oneliner-action" data-executor-key="platform-self-check" data-platform="${escapeHtml(normalizedPlatform)}">运行平台自检</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-profile" data-platform="${escapeHtml(normalizedPlatform)}">编辑配置</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-profile-history" data-platform="${escapeHtml(normalizedPlatform)}">看配置历史</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-memory" data-platform="${escapeHtml(normalizedPlatform)}">继续补记忆</span>
|
||||
<span class="tag clickable-tag" data-action="open-platform-agent-skill" data-platform="${escapeHtml(normalizedPlatform)}">继续补技能</span>
|
||||
<span class="tag clickable-tag" data-action="handoff-to-main-agent" data-platform="${escapeHtml(normalizedPlatform)}" data-source-screen="playbook" data-source-action-key="platform-agent-handoff" data-intent-key="custom" data-title="继续完善平台 Agent" data-goal="继续完善平台 Agent" data-summary="让主 Agent 结合当前平台记忆和技能,给出下一步执行计划。" data-plan-steps="${escapeHtml(JSON.stringify(["读取当前平台 Agent 配置", "检查记忆与技能缺口", "生成下一步执行计划"]))}">交给主 Agent 继续</span>
|
||||
@@ -11172,6 +11217,10 @@ document.addEventListener("click", async (event) => {
|
||||
openPlatformAgentProfileAction(action.dataset.platform || "");
|
||||
return;
|
||||
}
|
||||
if (name === "open-platform-agent-profile-history") {
|
||||
await openPlatformAgentProfileHistoryAction(action.dataset.platform || "");
|
||||
return;
|
||||
}
|
||||
if (name === "open-platform-agent-detail") {
|
||||
await openPlatformAgentDetailAction(action.dataset.platform || "");
|
||||
return;
|
||||
|
||||
@@ -749,6 +749,33 @@ test("main agent result rendering offers a direct route back into the recommende
|
||||
assert.match(lastAction, /recommended_action/);
|
||||
});
|
||||
|
||||
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 profileEditor = extractBetween(APP, "function openPlatformAgentProfileAction(platform)", "async function openPlatformAgentProfileHistoryAction(platform)");
|
||||
const profileHistory = extractBetween(APP, "async function openPlatformAgentProfileHistoryAction(platform)", "function openPlatformAgentMemoryAction(platform)");
|
||||
const panel = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()");
|
||||
const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)");
|
||||
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
|
||||
|
||||
assert.match(profileEditor, /renderPolicyVersionSummary\(current,/);
|
||||
assert.match(profileEditor, /name: "reason"/);
|
||||
assert.match(profileEditor, /saved\.current_version\?\.version_no/);
|
||||
|
||||
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(panel, /open-platform-agent-profile-history/);
|
||||
assert.match(detail, /open-platform-agent-profile-history/);
|
||||
assert.match(panel, /platform_agent_profile_version_no/);
|
||||
assert.match(detail, /platform_agent_profile_version_no/);
|
||||
assert.match(execution, /platformAgentProfile\.version_no/);
|
||||
assert.match(actions, /name === "open-platform-agent-profile-history"/);
|
||||
assert.match(actions, /openPlatformAgentProfileHistoryAction/);
|
||||
});
|
||||
|
||||
test("main agent route actions keep landing context and destination screens render a notice", () => {
|
||||
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
|
||||
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
|
||||
|
||||
Reference in New Issue
Block a user