Spaces:
Sleeping
Sleeping
File size: 5,849 Bytes
ca6c0e5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import { Link } from "react-router-dom";
import { Activity, Brain, GitBranch } from "lucide-react";
export default function StepList({ runId, steps = [], n_steps, activeStep, onSelect, status, progress }) {
const placeholder = Array.from({ length: n_steps || 3 });
const rows = steps.length
? steps
: placeholder.map((_, i) => ({ step_n: i + 1, _placeholder: true }));
return (
<div className="ns-card overflow-hidden" data-testid="step-list">
<header
className="flex items-center justify-between px-4 pt-3.5 pb-2"
style={{ borderBottom: "1px solid var(--ns-border-subtle)" }}
>
<span className="ns-section-title">trajectory</span>
<span className="font-mono text-[10px] text-[color:var(--ns-fg-muted)]">
{steps.length}/{n_steps} steps
</span>
</header>
<ul>
{rows.map((s) => {
const isActive = activeStep === s.step_n;
const done = !s._placeholder;
return (
<li
key={s.step_n}
className="cursor-pointer"
style={{
background: isActive
? "var(--ns-bg-surface-2)"
: "transparent",
borderLeft: isActive
? "2px solid var(--ns-accent)"
: "2px solid transparent",
}}
onClick={() => onSelect && onSelect(s.step_n)}
data-testid={`step-list-row-${s.step_n}`}
>
<div
className="flex items-start gap-3 px-4 py-2.5"
style={{ borderBottom: "1px solid var(--ns-border-subtle)" }}
>
<div className="flex flex-col items-center pt-0.5">
<span
className="font-mono text-[10px]"
style={{ color: done ? "var(--ns-accent)" : "var(--ns-fg-muted)" }}
>
s{s.step_n}
</span>
<span
className="mt-1 h-1.5 w-1.5 rounded-full"
style={{
background: done
? s.hallucination?.flag
? "var(--ns-warning)"
: "var(--ns-success)"
: status === "running" && progress?.completed_steps + 1 === s.step_n
? "var(--ns-accent)"
: "var(--ns-fg-faint)",
}}
/>
</div>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2 text-[11px]">
<Brain size={11} color="var(--ns-fg-muted)" />
<span className="truncate text-[color:var(--ns-fg-secondary)]">
{done ? s.output : "…"}
</span>
</div>
{done && (
<div className="mt-1 flex items-center gap-3 font-mono text-[10px] text-[color:var(--ns-fg-muted)]">
<span title="hallucination risk">
<Activity size={9} className="inline" /> risk{" "}
<span style={{ color: s.hallucination.flag ? "var(--ns-warning)" : "var(--ns-fg-secondary)" }}>
{s.hallucination.composite.toFixed(2)}
</span>
</span>
<span title="tool routed">
<GitBranch size={9} className="inline" />{" "}
{s.tool_called || "—"}
</span>
{runId && (
<Link
to={`/run/${runId}/step/${s.step_n}`}
className="ml-auto text-[color:var(--ns-accent)] hover:underline"
onClick={(e) => e.stopPropagation()}
data-testid={`step-list-detail-${s.step_n}`}
>
detail →
</Link>
)}
</div>
)}
</div>
</div>
</li>
);
})}
</ul>
</div>
);
}
|