Simplify search agent activity state

This commit is contained in:
wuyang
2026-07-08 14:11:13 +08:00
parent 894c914e26
commit 4892e7afad
3 changed files with 97 additions and 59 deletions
+21 -19
View File
@@ -521,22 +521,26 @@ function routeButtons(routes) {
`;
}
function searchSteps(steps = []) {
function searchActivity(steps = []) {
const current =
steps.find((step) => step.status === "running") ||
[...steps].reverse().find((step) => step.status === "done") ||
steps[0] ||
{};
const doneCount = steps.filter((step) => step.status === "done").length;
const currentIndex = Math.min(doneCount + (current.status === "running" ? 1 : 0), steps.length || 1);
const statusLabel = current.status === "running" ? "working" : current.status || "pending";
return `
<div class="agent-steps">
${steps
.map(
(step) => `
<div class="agent-step ${escapeHtml(step.status)}">
<span class="step-dot"></span>
<div>
<strong>${escapeHtml(step.label)}</strong>
<span>${escapeHtml(step.detail || step.status)}</span>
</div>
</div>
`,
)
.join("")}
<div class="agent-activity ${escapeHtml(current.status || "pending")}">
<span class="activity-dot"></span>
<div class="activity-copy">
<div class="activity-title">
<span>Search Agent</span>
<strong>${escapeHtml(current.label || "准备搜索")}</strong>
</div>
<div class="activity-detail">${escapeHtml(current.detail || "正在准备检索上下文")}</div>
</div>
<div class="activity-meta">${escapeHtml(statusLabel)} · ${currentIndex}/${steps.length || 1}</div>
</div>
`;
}
@@ -596,10 +600,7 @@ function renderSearchRunning(job) {
elements.lensTitle.textContent = job?.query || elements.searchInput.value.trim() || "搜索";
elements.lensBody.innerHTML = `
<section class="section">
<p class="statement">Search Agent 正在理解问题、扩展关键词并检索本地论文库。</p>
</section>
<section class="section">
${searchSteps(job?.steps || [])}
${searchActivity(job?.steps || [])}
</section>
`;
}
@@ -873,6 +874,7 @@ async function runSearch() {
],
};
renderSearchRunning(starter);
scrollLensIntoView();
try {
const payload = await api("/api/search/agent", {
method: "POST",
+2 -2
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Agent Knowledge Atlas</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%23cfe8e3'/%3E%3Ctext x='32' y='40' text-anchor='middle' font-size='24' font-family='Arial' font-weight='700' fill='%23064c47'%3EAK%3C/text%3E%3C/svg%3E" />
<link rel="stylesheet" href="/static/styles.css?v=atlas-20260708-10" />
<link rel="stylesheet" href="/static/styles.css?v=atlas-20260708-12" />
</head>
<body>
<main class="atlas-app">
@@ -79,6 +79,6 @@
</footer>
</main>
<script src="/static/app.js?v=atlas-20260708-10"></script>
<script src="/static/app.js?v=atlas-20260708-12"></script>
</body>
</html>
+74 -38
View File
@@ -521,55 +521,83 @@ button {
padding: 3px 6px;
}
.agent-steps {
.agent-activity {
display: grid;
gap: 10px;
grid-template-columns: auto minmax(0, 1fr) auto;
gap: 12px;
align-items: center;
border: 1px solid var(--line);
border-radius: 8px;
background: #fbfaf6;
padding: 12px;
}
.agent-step {
display: grid;
grid-template-columns: 13px 1fr;
gap: 10px;
align-items: start;
color: var(--muted);
}
.step-dot {
width: 9px;
height: 9px;
margin-top: 6px;
border: 1px solid #aab3ad;
.activity-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: #ffffff;
}
.agent-step strong {
display: block;
color: #17201d;
font-size: 13px;
}
.agent-step span:last-child {
display: block;
margin-top: 2px;
font-size: 12px;
line-height: 1.42;
}
.agent-step.running .step-dot {
border-color: var(--teal);
background: var(--teal);
box-shadow: 0 0 0 5px rgba(13, 118, 111, 0.12);
box-shadow: 0 0 0 7px rgba(13, 118, 111, 0.12);
}
.agent-step.done .step-dot {
border-color: var(--green);
.agent-activity.running .activity-dot {
animation: activityPulse 1.5s ease-in-out infinite;
}
.agent-activity.done .activity-dot {
background: var(--green);
box-shadow: 0 0 0 7px rgba(82, 127, 70, 0.12);
}
.agent-step.error .step-dot {
border-color: var(--coral);
.agent-activity.error .activity-dot {
background: var(--coral);
box-shadow: 0 0 0 7px rgba(186, 86, 68, 0.12);
}
.activity-copy {
min-width: 0;
}
.activity-title {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: baseline;
color: var(--muted);
font-size: 12px;
}
.activity-title strong {
color: #17201d;
font-size: 14px;
}
.activity-detail {
margin-top: 3px;
color: #4c5550;
font-size: 13px;
line-height: 1.38;
overflow-wrap: anywhere;
}
.activity-meta {
color: var(--muted);
font-size: 11px;
font-weight: 760;
white-space: nowrap;
}
@keyframes activityPulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 0 7px rgba(13, 118, 111, 0.1);
}
50% {
transform: scale(0.82);
box-shadow: 0 0 0 10px rgba(13, 118, 111, 0.18);
}
}
.search-brief h3 {
@@ -885,6 +913,14 @@ button {
max-width: 100%;
}
.agent-activity {
grid-template-columns: auto minmax(0, 1fr);
}
.activity-meta {
grid-column: 2;
}
.route-band,
.timeline-band {
margin-top: 12px;