feat: decision tree visualization with React Flow + Dagre auto-layout

This commit is contained in:
Vectry
2026-02-09 23:58:41 +00:00
parent 21b4f9f316
commit 867e1e9eb1
6 changed files with 1151 additions and 24 deletions

View File

@@ -1,18 +1,17 @@
import { notFound } from "next/navigation";
import { TraceDetail } from "@/components/trace-detail";
interface TraceResponse {
trace: {
id: string;
name: string;
status: "RUNNING" | "COMPLETED" | "ERROR";
startedAt: string;
endedAt: string | null;
durationMs: number | null;
tags: string[];
metadata: Record<string, unknown>;
costUsd: number | null;
};
interface TraceData {
id: string;
name: string;
status: "RUNNING" | "COMPLETED" | "ERROR";
startedAt: string;
endedAt: string | null;
durationMs: number | null;
tags: string[];
metadata: Record<string, unknown>;
costUsd: number | null;
totalCost: number | null;
decisionPoints: Array<{
id: string;
type: string;
@@ -22,6 +21,7 @@ interface TraceResponse {
contextSnapshot: Record<string, unknown> | null;
confidence: number | null;
timestamp: string;
parentSpanId: string | null;
}>;
spans: Array<{
id: string;
@@ -34,6 +34,7 @@ interface TraceResponse {
input: unknown;
output: unknown;
metadata: Record<string, unknown>;
parentSpanId: string | null;
}>;
events: Array<{
id: string;
@@ -41,9 +42,14 @@ interface TraceResponse {
name: string;
timestamp: string;
metadata: Record<string, unknown>;
spanId: string | null;
}>;
}
interface TraceResponse {
trace: TraceData;
}
async function getTrace(id: string): Promise<TraceResponse | null> {
try {
const res = await fetch(`http://localhost:3000/api/traces/${id}`, {
@@ -76,12 +82,24 @@ export default async function TraceDetailPage({ params }: TraceDetailPageProps)
notFound();
}
const { trace } = data;
return (
<TraceDetail
trace={data.trace}
decisionPoints={data.decisionPoints}
spans={data.spans}
events={data.events}
trace={{
id: trace.id,
name: trace.name,
status: trace.status,
startedAt: trace.startedAt,
endedAt: trace.endedAt,
durationMs: trace.durationMs,
tags: trace.tags,
metadata: trace.metadata,
costUsd: trace.costUsd ?? trace.totalCost,
}}
decisionPoints={trace.decisionPoints}
spans={trace.spans}
events={trace.events}
/>
);
}