Zayne Rea Sprague
bump
6b7050a
import { useRef, useEffect } from "react";
import type { DatasetInfo, InstanceDetail, TrajectoryMode } from "../types";
import { RawBubble, AtifBubble } from "./ChatBubble";
import { StepDetail } from "./StepDetail";
interface Props {
dataset: DatasetInfo;
detail: InstanceDetail;
mode: TrajectoryMode;
isSingle: boolean;
}
export function TrajectoryView({ dataset, detail, mode, isSingle }: Props) {
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = 0;
}
}, [detail.instance_id, mode]);
return (
<div
className={`flex flex-col overflow-hidden ${
isSingle ? "flex-1" : "flex-1 border-r border-gray-800 last:border-r-0"
}`}
>
{/* Header */}
<div className="px-4 py-2 bg-gray-900/30 border-b border-gray-800 flex items-center justify-between">
<div className="flex items-center gap-2">
<span
className={`w-2 h-2 rounded-full ${
detail.resolved ? "bg-emerald-400" : "bg-red-400"
}`}
/>
<span className="text-xs text-gray-300 truncate" title={dataset.repo}>
{dataset.name}
</span>
</div>
<div className="flex items-center gap-2">
<span className="text-xs text-gray-500">
{detail.agent || detail.model}
</span>
{detail.duration_seconds > 0 && (
<span className="text-xs text-gray-600">
{Math.round(detail.duration_seconds)}s
</span>
)}
</div>
</div>
{/* Chat stream */}
<div ref={scrollRef} className="flex-1 overflow-y-auto px-4 py-4 space-y-1">
{mode === "raw" && (
<>
{detail.raw_steps.map((step) => (
<RawBubble key={step.index} step={step} />
))}
{detail.raw_steps.length === 0 && (
<div className="text-center text-gray-500 text-sm mt-8">
No raw trajectory data available.
{detail.n_atif_steps > 0 && " Try ATIF Steps mode."}
</div>
)}
</>
)}
{mode === "atif" && (
<>
{detail.atif.steps.map((step) => (
<AtifBubble key={step.index} step={step} />
))}
{detail.atif.steps.length === 0 && (
<div className="text-center text-gray-500 text-sm mt-8">
No ATIF trajectory data available.
{detail.n_raw_steps > 0 && " Try Raw Messages mode."}
</div>
)}
</>
)}
{/* Result badge at bottom */}
<div className="flex justify-center pt-4">
<span
className={`px-4 py-2 rounded-lg text-sm font-medium ${
detail.resolved
? "bg-emerald-900/50 text-emerald-300 border border-emerald-700"
: "bg-red-900/50 text-red-300 border border-red-700"
}`}
>
{detail.resolved ? "RESOLVED" : "FAILED"}
{detail.error && (
<span className="ml-2 text-xs opacity-70">({detail.error})</span>
)}
</span>
</div>
</div>
{/* Raw logs */}
<StepDetail dsId={dataset.id} instanceId={detail.instance_id} />
</div>
);
}