feat: add main agent run filters
This commit is contained in:
@@ -53,6 +53,7 @@ const appState = {
|
|||||||
onelinerSessions: [],
|
onelinerSessions: [],
|
||||||
selectedOnelinerSessionId: "",
|
selectedOnelinerSessionId: "",
|
||||||
onelinerRuns: [],
|
onelinerRuns: [],
|
||||||
|
onelinerRunFilter: "focus",
|
||||||
selectedOnelinerRunId: "",
|
selectedOnelinerRunId: "",
|
||||||
lastCompletedOnelinerRunId: "",
|
lastCompletedOnelinerRunId: "",
|
||||||
onelinerMessages: [],
|
onelinerMessages: [],
|
||||||
@@ -984,6 +985,14 @@ function renderOneLinerRunsHtml() {
|
|||||||
const pendingRunCount = safeArray(runs).filter((item) => item.run_status === "needs_confirmation").length;
|
const pendingRunCount = safeArray(runs).filter((item) => item.run_status === "needs_confirmation").length;
|
||||||
const activeRunCount = safeArray(runs).filter((item) => ["queued", "running", "blocked"].includes(item.run_status)).length;
|
const activeRunCount = safeArray(runs).filter((item) => ["queued", "running", "blocked"].includes(item.run_status)).length;
|
||||||
const completedRunCount = safeArray(runs).filter((item) => item.run_status === "done").length;
|
const completedRunCount = safeArray(runs).filter((item) => item.run_status === "done").length;
|
||||||
|
const filterKey = String(appState.onelinerRunFilter || "").trim() || (activeRunCount || pendingRunCount ? "focus" : "done");
|
||||||
|
const runFilterPredicates = {
|
||||||
|
focus: (item) => ["needs_confirmation", "queued", "running", "blocked"].includes(item.run_status),
|
||||||
|
done: (item) => item.run_status === "done",
|
||||||
|
all: () => true
|
||||||
|
};
|
||||||
|
const filteredRuns = safeArray(runs).filter(runFilterPredicates[filterKey] || runFilterPredicates.focus);
|
||||||
|
const visibleRuns = (filteredRuns.length ? filteredRuns : runs).slice(0, 8);
|
||||||
const recentCompletedRuns = safeArray(runs)
|
const recentCompletedRuns = safeArray(runs)
|
||||||
.filter((item) => item.run_status === "done" && item.id !== currentRun.id)
|
.filter((item) => item.run_status === "done" && item.id !== currentRun.id)
|
||||||
.slice(0, 3);
|
.slice(0, 3);
|
||||||
@@ -1027,9 +1036,14 @@ function renderOneLinerRunsHtml() {
|
|||||||
<span class="tag green">执行中 ${escapeHtml(formatNumber(activeRunCount))}</span>
|
<span class="tag green">执行中 ${escapeHtml(formatNumber(activeRunCount))}</span>
|
||||||
<span class="tag">已完成 ${escapeHtml(formatNumber(completedRunCount))}</span>
|
<span class="tag">已完成 ${escapeHtml(formatNumber(completedRunCount))}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="task-meta" style="margin-top:10px;">
|
||||||
|
<span class="tag clickable-tag ${filterKey === "focus" ? "blue" : ""}" data-action="select-oneliner-run-filter" data-run-filter="focus">重点运行</span>
|
||||||
|
<span class="tag clickable-tag ${filterKey === "done" ? "green" : ""}" data-action="select-oneliner-run-filter" data-run-filter="done">已完成</span>
|
||||||
|
<span class="tag clickable-tag ${filterKey === "all" ? "orange" : ""}" data-action="select-oneliner-run-filter" data-run-filter="all">全部</span>
|
||||||
|
</div>
|
||||||
${runs.length > 1 ? `
|
${runs.length > 1 ? `
|
||||||
<div class="chip-row" style="margin-top:10px;">
|
<div class="chip-row" style="margin-top:10px;">
|
||||||
${runs.slice(0, 6).map((item) => `
|
${visibleRuns.map((item) => `
|
||||||
<span class="chip clickable-tag ${item.id === currentRun.id ? "active" : ""}" data-action="select-oneliner-run" data-run-id="${escapeHtml(item.id)}">
|
<span class="chip clickable-tag ${item.id === currentRun.id ? "active" : ""}" data-action="select-oneliner-run" data-run-id="${escapeHtml(item.id)}">
|
||||||
${escapeHtml(brief(item.title || item.plan?.goal || "主 Agent 任务", 14))} · ${escapeHtml({
|
${escapeHtml(brief(item.title || item.plan?.goal || "主 Agent 任务", 14))} · ${escapeHtml({
|
||||||
needs_confirmation: "待确认",
|
needs_confirmation: "待确认",
|
||||||
@@ -2118,6 +2132,8 @@ function openCurrentOneLinerRunResultAction(runId = "") {
|
|||||||
renderAll();
|
renderAll();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
appState.selectedOnelinerRunId = currentRun.id;
|
||||||
|
appState.onelinerRunFilter = currentRun.run_status === "done" ? "done" : appState.onelinerRunFilter;
|
||||||
openActionModal({
|
openActionModal({
|
||||||
title: currentRun.title || currentRun.plan?.goal || "主 Agent 执行结果",
|
title: currentRun.title || currentRun.plan?.goal || "主 Agent 执行结果",
|
||||||
description: currentRun.result?.execution_summary || currentRun.status_summary || "这是当前主 Agent 任务的执行结果。",
|
description: currentRun.result?.execution_summary || currentRun.status_summary || "这是当前主 Agent 任务的执行结果。",
|
||||||
@@ -10002,6 +10018,11 @@ document.addEventListener("click", async (event) => {
|
|||||||
renderAll();
|
renderAll();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (name === "select-oneliner-run-filter") {
|
||||||
|
appState.onelinerRunFilter = action.dataset.runFilter || "focus";
|
||||||
|
renderAll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (name === "select-oneliner-session") {
|
if (name === "select-oneliner-session") {
|
||||||
appState.selectedOnelinerSessionId = action.dataset.sessionId || "";
|
appState.selectedOnelinerSessionId = action.dataset.sessionId || "";
|
||||||
await loadOneLinerMessages(appState.selectedOnelinerSessionId);
|
await loadOneLinerMessages(appState.selectedOnelinerSessionId);
|
||||||
|
|||||||
@@ -313,9 +313,19 @@ test("oneliner runtime shows grouped run health summary above the current run ca
|
|||||||
assert.match(runtime, /已完成/);
|
assert.match(runtime, /已完成/);
|
||||||
assert.match(runtime, /最近完成/);
|
assert.match(runtime, /最近完成/);
|
||||||
assert.match(runtime, /recentCompletedRuns/);
|
assert.match(runtime, /recentCompletedRuns/);
|
||||||
|
assert.match(runtime, /select-oneliner-run-filter/);
|
||||||
|
assert.match(runtime, /重点运行/);
|
||||||
|
assert.match(runtime, /已完成/);
|
||||||
|
assert.match(runtime, /全部/);
|
||||||
assert.match(runtime, /safeArray\(runs\)\.filter\(\(item\) => item\.run_status === "needs_confirmation"\)\.length/);
|
assert.match(runtime, /safeArray\(runs\)\.filter\(\(item\) => item\.run_status === "needs_confirmation"\)\.length/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("opening a main agent run result keeps that run selected in the floating runtime", () => {
|
||||||
|
const resultAction = extractBetween(APP, "function openCurrentOneLinerRunResultAction(runId = \"\")", "function openConfirmOneLinerRunAction(runId = \"\")");
|
||||||
|
assert.match(resultAction, /appState\.selectedOnelinerRunId = currentRun\.id/);
|
||||||
|
assert.match(resultAction, /appState\.onelinerRunFilter = currentRun\.run_status === "done" \? "done" : appState\.onelinerRunFilter/);
|
||||||
|
});
|
||||||
|
|
||||||
test("oneliner panel auto-polls active runs while the floating panel stays open", () => {
|
test("oneliner panel auto-polls active runs while the floating panel stays open", () => {
|
||||||
const render = extractBetween(APP, "function renderOneLinerUi()", "function openOneLinerPanel()");
|
const render = extractBetween(APP, "function renderOneLinerUi()", "function openOneLinerPanel()");
|
||||||
const open = extractBetween(APP, "function openOneLinerPanel()", "function closeOneLinerPanel()");
|
const open = extractBetween(APP, "function openOneLinerPanel()", "function closeOneLinerPanel()");
|
||||||
|
|||||||
Reference in New Issue
Block a user