feat: structure main agent result cards
This commit is contained in:
@@ -2740,6 +2740,115 @@ def register_oneliner_routes(app: Any, legacy: Any) -> None:
|
||||
return intent_routes[intent_key]
|
||||
return route("goto-production", "production", "回到生产中心", "继续推进当前主 Agent 任务的执行结果。")
|
||||
|
||||
def _build_agent_run_result_sections(
|
||||
row: dict[str, Any],
|
||||
plan: dict[str, Any],
|
||||
recommended_action: dict[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
source_screen = str(plan.get("source_screen") or row.get("source_screen") or "").strip().lower()
|
||||
recommended_screen = str(recommended_action.get("screen") or "").strip().lower()
|
||||
screen_key = recommended_screen or source_screen
|
||||
intent_key = str(plan.get("intent_key") or row.get("intent_key") or "custom").strip().lower() or "custom"
|
||||
platform = str(plan.get("platform") or row.get("platform") or "").strip()
|
||||
platform_label = legacy.platform_label(platform) if platform else ""
|
||||
plan_summary = str(plan.get("summary") or row.get("summary") or "").strip() or "主 Agent 已按当前上下文完成首轮收口。"
|
||||
goal = str(plan.get("goal") or row.get("title") or "主 Agent 任务").strip() or "主 Agent 任务"
|
||||
override_notice = _parse_json(row.get("active_admin_override_notice_json"), {})
|
||||
|
||||
workstream_map = {
|
||||
"dashboard": ("dashboard", "首页动作"),
|
||||
"discovery": ("discovery", "对标推进"),
|
||||
"tracking": ("tracking", "跟踪推进"),
|
||||
"production": ("production", "生产推进"),
|
||||
"review": ("review", "复盘推进"),
|
||||
"strategy": ("strategy", "策略治理"),
|
||||
"playbook": ("playbook", "Agent 治理"),
|
||||
"agent": ("playbook", "Agent 治理"),
|
||||
"automation": ("automation", "自动流程"),
|
||||
"intake": ("intake", "项目推进"),
|
||||
"projects": ("intake", "项目推进"),
|
||||
}
|
||||
workstream_key, workstream_label = workstream_map.get(screen_key, ("production", "主 Agent 执行结果"))
|
||||
|
||||
if intent_key in {"analyze_account", "analyze_top_videos", "import_homepage"}:
|
||||
workstream_key, workstream_label = "discovery", "对标推进"
|
||||
elif intent_key == "track_account":
|
||||
workstream_key, workstream_label = "tracking", "跟踪推进"
|
||||
elif intent_key in {"ai_video", "real_cut", "live_recorder"}:
|
||||
workstream_key, workstream_label = "production", "生产推进"
|
||||
elif intent_key == "review":
|
||||
workstream_key, workstream_label = "review", "复盘推进"
|
||||
elif intent_key in {"create_assistant"}:
|
||||
workstream_key, workstream_label = "playbook", "Agent 治理"
|
||||
elif intent_key in {"create_project"}:
|
||||
workstream_key, workstream_label = "intake", "项目推进"
|
||||
elif intent_key in {"storage_status", "ops_admin"}:
|
||||
workstream_key, workstream_label = "automation", "自动流程"
|
||||
|
||||
def card(title: str, body: str, *, tone: str = "blue", tags: list[str] | None = None) -> dict[str, Any]:
|
||||
return {
|
||||
"title": title,
|
||||
"body": body,
|
||||
"tone": tone,
|
||||
"tags": [item for item in list(tags or []) if str(item).strip()],
|
||||
}
|
||||
|
||||
cards = [
|
||||
card(
|
||||
"当前焦点",
|
||||
f"围绕「{goal}」先完成一版可执行收口,避免你先在多个页面之间来回切换。",
|
||||
tone="blue",
|
||||
tags=[platform_label or "当前平台", workstream_label],
|
||||
)
|
||||
]
|
||||
|
||||
focus_body_map = {
|
||||
"discovery": "优先回到找对标,继续看账号、相似关系和高分样本,再决定是否导入或加入跟踪。",
|
||||
"tracking": "优先回到跟踪账号,看最近日报窗口和值得继续跟进的对象,再决定同步或加深跟踪。",
|
||||
"production": "优先回到生产中心,看队列、失败恢复和产物,再决定下一步是推进还是补救。",
|
||||
"review": "优先回到发布与复盘,把最近完成任务沉淀成结构化复盘,再决定是否继续发布。",
|
||||
"strategy": "优先回到我的策略,先看当前生效层和管理员覆盖,再决定是否继续调整用户策略。",
|
||||
"playbook": "优先回到 Agent 工作区,结合当前平台 Agent、模型和技能,继续完善执行能力。",
|
||||
"automation": "优先回到自动流程,先看依赖健康和动作防呆,再决定是否恢复或放行动作。",
|
||||
"intake": "优先回到我的项目,先补项目、账号和导入基础,再决定往哪个工作页继续推进。",
|
||||
"dashboard": "优先回到首页当前推荐动作,把这一轮的重点从概览转成真实执行。",
|
||||
}
|
||||
cards.append(
|
||||
card(
|
||||
workstream_label,
|
||||
focus_body_map.get(workstream_key, plan_summary),
|
||||
tone="green",
|
||||
tags=[recommended_action.get("label") or "回到业务页"],
|
||||
)
|
||||
)
|
||||
cards.append(
|
||||
card(
|
||||
"建议落点",
|
||||
str(recommended_action.get("summary") or plan_summary).strip() or "回到对应业务页面继续推进。",
|
||||
tone="orange" if override_notice.get("title") else "blue",
|
||||
tags=[
|
||||
recommended_action.get("screen") or "",
|
||||
"管理员覆盖生效中" if override_notice.get("title") else "",
|
||||
"全平台" if str(plan.get("platform_scope") or row.get("platform_scope") or "") == "all_platforms" else "单平台",
|
||||
],
|
||||
)
|
||||
)
|
||||
if override_notice.get("title"):
|
||||
cards.append(
|
||||
card(
|
||||
"管理员覆盖提醒",
|
||||
str(override_notice.get("summary") or "当前执行会优先遵循管理员覆盖层。").strip(),
|
||||
tone="orange",
|
||||
tags=[str(override_notice.get("title") or "管理员覆盖").strip()],
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
"workstream_key": workstream_key,
|
||||
"workstream_label": workstream_label,
|
||||
"cards": cards,
|
||||
}
|
||||
|
||||
def _complete_agent_run_for_read(row: dict[str, Any]) -> dict[str, Any]:
|
||||
current_status = str(row.get("run_status") or "")
|
||||
run_id = str(row.get("id") or "")
|
||||
@@ -2783,6 +2892,7 @@ def register_oneliner_routes(app: Any, legacy: Any) -> None:
|
||||
summary_text = str(plan.get("summary") or row.get("summary") or "").strip() or "主 Agent 已根据当前计划完成第一版执行收口。"
|
||||
execution_summary = f"已完成「{str(plan.get('goal') or row.get('title') or '主 Agent 任务').strip() or '主 Agent 任务'}」的首轮执行建议。"
|
||||
recommended_action = _build_agent_run_recommended_action(row, plan)
|
||||
result_sections = _build_agent_run_result_sections(row, plan, recommended_action)
|
||||
result_payload = {
|
||||
"result_kind": "main_agent_plan",
|
||||
"run_id": run_id,
|
||||
@@ -2794,6 +2904,7 @@ def register_oneliner_routes(app: Any, legacy: Any) -> None:
|
||||
"platform": str(plan.get("platform") or row.get("platform") or "").strip(),
|
||||
"platform_scope": str(plan.get("platform_scope") or row.get("platform_scope") or "single_platform").strip() or "single_platform",
|
||||
"recommended_action": recommended_action,
|
||||
"result_sections": result_sections,
|
||||
"active_admin_override_notice": _parse_json(row.get("active_admin_override_notice_json"), {}),
|
||||
}
|
||||
_log_agent_run_event(
|
||||
|
||||
@@ -292,6 +292,9 @@ class MainAgentGovernanceTests(unittest.TestCase):
|
||||
self.assertEqual(payload["result"]["result_kind"], "main_agent_plan")
|
||||
self.assertEqual(payload["result"]["recommended_action"]["action"], "goto-discovery")
|
||||
self.assertEqual(payload["result"]["recommended_action"]["screen"], "discovery")
|
||||
self.assertEqual(payload["result"]["result_sections"]["workstream_key"], "discovery")
|
||||
self.assertGreaterEqual(len(payload["result"]["result_sections"]["cards"]), 2)
|
||||
self.assertEqual(payload["result"]["result_sections"]["cards"][0]["title"], "当前焦点")
|
||||
event_types = [item["event_type"] for item in payload["events"]]
|
||||
self.assertIn("run.progress", event_types)
|
||||
self.assertIn("run.done", event_types)
|
||||
|
||||
@@ -1808,6 +1808,10 @@ function renderOneLinerExecutionPayloadHtml(payload) {
|
||||
const landingSummary = String(
|
||||
payload.recommended_action?.summary || payload.execution_summary || payload.summary_text || ""
|
||||
).trim();
|
||||
const resultSections = payload.result_sections && typeof payload.result_sections === "object"
|
||||
? payload.result_sections
|
||||
: {};
|
||||
const resultCards = safeArray(resultSections.cards).slice(0, 4);
|
||||
const landingAttrs = buildMainAgentLandingAttrs({
|
||||
runId: landingRunId,
|
||||
screen: landingScreen,
|
||||
@@ -1825,6 +1829,29 @@ function renderOneLinerExecutionPayloadHtml(payload) {
|
||||
${payload.recommended_action?.action ? `<span class="tag clickable-tag" data-action="${escapeHtml(payload.recommended_action.action)}" data-main-agent-run-id="${escapeHtml(landingRunId)}" data-main-agent-screen="${escapeHtml(landingScreen)}" data-main-agent-title="${escapeHtml(landingTitle)}" data-main-agent-summary="${escapeHtml(landingSummary)}" ${landingAttrs}>${escapeHtml(payload.recommended_action.label || "回到对应页面")}</span>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
${resultCards.length ? `
|
||||
<div class="task-item compact" style="margin-top:12px;">
|
||||
<h4>${escapeHtml(resultSections.workstream_label || "执行结果分组")}</h4>
|
||||
<p>${escapeHtml(payload.summary_text || "主 Agent 已将当前执行结果整理为可继续推进的结构化建议。")}</p>
|
||||
<div class="detail-grid" style="margin-top:12px;">
|
||||
${resultCards.map((card, index) => {
|
||||
const tags = safeArray(card?.tags).slice(0, 3);
|
||||
const tone = String(card?.tone || "").trim();
|
||||
const toneClass = tone === "orange" ? "orange" : tone === "green" ? "green" : "blue";
|
||||
return `
|
||||
<div class="task-item compact">
|
||||
<h4>${escapeHtml(card?.title || (index === 0 ? "当前焦点" : "执行结果"))}</h4>
|
||||
<p>${escapeHtml(card?.body || "主 Agent 已生成一条可继续执行的结果说明。")}</p>
|
||||
<div class="task-meta">
|
||||
<span class="tag ${toneClass}">${escapeHtml(card?.title || (index === 0 ? "当前焦点" : "结果卡片"))}</span>
|
||||
${tags.map((tag) => `<span class="tag">${escapeHtml(tag)}</span>`).join("")}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join("")}
|
||||
</div>
|
||||
</div>
|
||||
` : ""}
|
||||
${payload.recommended_action?.summary ? `
|
||||
<div class="task-item compact" style="margin-top:12px;">
|
||||
<h4>建议回跳</h4>
|
||||
|
||||
@@ -249,6 +249,9 @@ test("main agent result rendering offers a direct route back into the recommende
|
||||
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
|
||||
const lastAction = extractBetween(APP, "function renderLastActionCard()", "function getJobRecoveryCategory(job)");
|
||||
assert.match(execution, /recommended_action/);
|
||||
assert.match(execution, /result_sections/);
|
||||
assert.match(execution, /当前焦点/);
|
||||
assert.match(execution, /detail-grid/);
|
||||
assert.match(execution, /data-action="\$\{escapeHtml\(payload\.recommended_action\.action\)\}"/);
|
||||
assert.match(lastAction, /open-oneliner-run-result/);
|
||||
assert.match(lastAction, /recommended_action/);
|
||||
|
||||
Reference in New Issue
Block a user