feat: add live H1-H7 trace explorer
This commit is contained in:
@@ -1,31 +1,53 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { api } from '../lib/api';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { api, type HarnessRunRecord } from '../lib/api';
|
||||
import { Card, StatusBadge } from '../components/ui/Card';
|
||||
import { TraceExplorer } from '../components/trace/TraceExplorer';
|
||||
|
||||
export function Runs() {
|
||||
const { data, isLoading } = useQuery({ queryKey: ['runs'], queryFn: () => api.runs(100) });
|
||||
if (isLoading || !data) return <div className="text-gray-500">Loading…</div>;
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const selectedTrace = searchParams.get('trace') ?? '';
|
||||
|
||||
if (isLoading || !data) return <div className="text-slate-500">Loading…</div>;
|
||||
return (
|
||||
<Card title={`Recent runs (${data.count})`}>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead><tr className="text-left text-gray-500 border-b border-gray-200">
|
||||
<th className="py-2">time</th><th>step</th><th>status</th><th>latency</th><th>tokens</th><th>cost</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{data.runs.map((r: any, i: number) => (
|
||||
<tr key={i} className="border-b border-gray-100">
|
||||
<td className="py-2 text-gray-500">{r.timestamp?.replace('T', ' ').replace('Z', '')}</td>
|
||||
<td className="text-gray-700">{r.step ?? r.harness}</td>
|
||||
<td><StatusBadge value={r.status ?? '—'} /></td>
|
||||
<td>{r.latency_ms ?? '—'} ms</td>
|
||||
<td>{r.total_tokens ?? '—'}</td>
|
||||
<td>${Number(r.cost_estimate ?? 0).toFixed(5)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
<div className="space-y-5">
|
||||
{selectedTrace && <TraceExplorer traceId={selectedTrace} onClose={() => setSearchParams({})} />}
|
||||
<Card
|
||||
title={`Recent runs (${data.count})`}
|
||||
right={<span className="text-xs font-normal normal-case tracking-normal text-slate-400">Select a run to inspect H1–H7</span>}
|
||||
>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead><tr className="border-b border-slate-200 text-left text-slate-500">
|
||||
<th className="py-2">time</th><th>step</th><th>status</th><th>latency</th><th>tokens</th><th>cost</th><th className="text-right">trace</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{data.runs.map((run: HarnessRunRecord, index: number) => (
|
||||
<tr key={`${run.trace_id ?? 'run'}-${index}`} className="border-b border-slate-100 transition-colors hover:bg-slate-50/80">
|
||||
<td className="py-2 text-slate-500">{run.timestamp?.replace('T', ' ').replace('Z', '')}</td>
|
||||
<td className="text-slate-700">{run.step ?? run.harness}</td>
|
||||
<td><StatusBadge value={run.status ?? '—'} /></td>
|
||||
<td>{run.latency_ms ?? '—'} ms</td>
|
||||
<td>{run.total_tokens ?? '—'}</td>
|
||||
<td>${Number(run.cost_estimate ?? 0).toFixed(5)}</td>
|
||||
<td className="py-2 text-right">
|
||||
{run.trace_id ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSearchParams({ trace: run.trace_id ?? '' })}
|
||||
className="rounded-lg border border-blue-200 bg-blue-50 px-3 py-1.5 text-xs font-semibold text-blue-700 transition-colors hover:bg-blue-100"
|
||||
>
|
||||
Open H1–H7
|
||||
</button>
|
||||
) : <span className="text-slate-300">—</span>}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user