fix(web): 智能体汇报展示层兜底与进度口径(FIX-7)
- 汇报正文里的 UUID、能力 ID、原因码展示时换成名称和人话,原文收进「正文原文」,历史不改 - 步骤进度统一 stepProgress:分子只数完成,跳过单独计(「4/6 · 跳过 2」) - 进度行不再把失败的调用算进动作计数(3 次被拒的派发曾写成「派出了 5 个子会话」); 实际结果行按会话树显示派出的子会话数 - 会话标题里的 ISO 时间与 download_failed 等码转人话 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
1b22bb5131
commit
417af9f253
9 files changed
+393
-27
No files matched your search
@@ -39,7 +39,9 @@ import {
|
||||
runPlanIds,
|
||||
} from "./agent-conversation.tsx";
|
||||
import { RunPlan } from "./agent-interaction.tsx";
|
||||
import { shortGoalTitle } from "./agent-store.ts";
|
||||
import { SubagentTree } from "./agent-subagent-tree.tsx";
|
||||
import { stepProgress } from "./conversation-model.ts";
|
||||
import {
|
||||
NEW_RUN_COMMANDS,
|
||||
PROPOSE_FIRST,
|
||||
@@ -154,9 +156,8 @@ export function RunOverviewBar({
|
||||
const [open, setOpen] = useState(false);
|
||||
const r = snapshot.run;
|
||||
const steps = live.plan?.steps ?? [];
|
||||
const done = steps.filter((s) => s.status === "done" || s.status === "skipped").length;
|
||||
const current = steps.find((s) => s.status === "running") ?? steps.find((s) => s.status === "pending");
|
||||
const failed = steps.find((s) => s.status === "failed");
|
||||
const progress = stepProgress(steps);
|
||||
const failed = progress.failedStep;
|
||||
const family = (snapshot.children?.length ?? 0) > 0 || !!snapshot.parent;
|
||||
if (!steps.length && !family && !isRunActive(status)) return null;
|
||||
const u = { ...r.usage, ...(live.usage ?? {}) };
|
||||
@@ -177,11 +178,9 @@ export function RunOverviewBar({
|
||||
className={cn("size-3.5 shrink-0 text-muted-foreground", failed && "text-destructive")}
|
||||
/>
|
||||
<span className="shrink-0 text-foreground tabular-nums">
|
||||
步骤 {done}/{steps.length}
|
||||
</span>
|
||||
<span className="min-w-0 flex-1 truncate text-muted-foreground">
|
||||
{failed ? `失败:${failed.title}` : current ? `当前:${current.title}` : "全部完成"}
|
||||
步骤 {progress.done}/{progress.total}
|
||||
</span>
|
||||
<span className="min-w-0 flex-1 truncate text-muted-foreground">{progress.status}</span>
|
||||
</>
|
||||
) : (
|
||||
<span className="min-w-0 flex-1 truncate text-muted-foreground">
|
||||
@@ -197,7 +196,7 @@ export function RunOverviewBar({
|
||||
"h-full rounded-full transition-[width] duration-layout ease-standard motion-reduce:transition-none",
|
||||
failed ? "bg-destructive" : "bg-foreground/60",
|
||||
)}
|
||||
style={{ width: `${Math.round((done / steps.length) * 100)}%` }}
|
||||
style={{ width: `${progress.pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
@@ -384,6 +383,12 @@ export function AgentRunPanel({
|
||||
<AgentConversation
|
||||
run={r}
|
||||
live={live}
|
||||
knownNames={[
|
||||
...(run.data.children ?? []).map((c) => [c.id, shortGoalTitle(c.goal, 24)] as [string, string]),
|
||||
...(run.data.parent
|
||||
? [[run.data.parent.id, shortGoalTitle(run.data.parent.goal, 24)] as [string, string]]
|
||||
: []),
|
||||
]}
|
||||
audit={audit.data}
|
||||
userMessages={messages.map((m) => ({ at: m.createdAt, text: m.text, pending: m.status === "pending" }))}
|
||||
after={
|
||||
@@ -393,7 +398,14 @@ export function AgentRunPanel({
|
||||
.map((a) => (
|
||||
<ApprovalItem key={a.id} approval={a} />
|
||||
))}
|
||||
{finished ? <ResultLine run={r} report={report} live={live} /> : null}
|
||||
{finished ? (
|
||||
<ResultLine
|
||||
run={r}
|
||||
report={report}
|
||||
live={live}
|
||||
subagents={(run.data.children ?? []).filter((c) => c.parentRunId === r.id).length}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user