Yogesh
initial deploy
cd8bd0a
Raw
History Blame Contribute Delete
5.55 kB
"use client";
import { Handle, Position, type NodeProps } from "@xyflow/react";
import { StatusDot } from "@/shared/components/flow/StatusDot";
// ── Layer pill color map (10-layer model) ─────────────────────────────────
const LAYER_COLORS: Record<string, string> = {
L1: "#3b82f6", // prose β€” blue
L3: "#f97316", // tool β€” orange
L4: "#22c55e", // code β€” green
L5: "#a855f7", // MCP β€” purple
L6: "#9ca3af", // history β€” gray
L9: "#ec4899", // pruning β€” pink
};
/** Map engine name β†’ layer tags for the pill display */
const ENGINE_LAYER_MAP: Record<string, string[]> = {
rtk: ["L3", "L4"],
caveman: ["L1"],
headroom: ["L3"],
llmlingua: ["L9"],
lite: ["L1"],
sigmap: ["L1", "L3"],
gcf: ["L4"],
cocoindex: ["L5", "L6"],
"caveman:full": ["L1"],
"rtk:standard": ["L3", "L4"],
};
function getSavingsColor(savingsPercent: number): string {
if (savingsPercent >= 30) return "#22c55e";
if (savingsPercent >= 15) return "#f59e0b";
return "#6b7280";
}
// ── Node data shape ───────────────────────────────────────────────────────
export interface EngineNodeData {
engine: string;
originalTokens: number;
compressedTokens: number;
savingsPercent: number;
techniquesUsed: string[];
rulesApplied?: string[];
durationMs?: number;
/** visual replay state */
stepState?: "pending" | "running" | "done" | "skipped";
label?: string;
[key: string]: unknown;
}
// ── Component ─────────────────────────────────────────────────────────────
export function EngineNode({ data }: NodeProps) {
const {
engine,
originalTokens,
compressedTokens,
savingsPercent,
techniquesUsed,
durationMs,
stepState = "done",
} = data as EngineNodeData;
const skipped = stepState === "skipped" || originalTokens === compressedTokens;
const running = stepState === "running";
const color = getSavingsColor(savingsPercent as number);
const layers = ENGINE_LAYER_MAP[engine as string] ?? [];
const savings = savingsPercent as number;
const tokIn = originalTokens as number;
const tokOut = compressedTokens as number;
const techniques = (techniquesUsed as string[]).slice(0, 2);
const borderColor = skipped ? "var(--color-border)" : running ? "#f59e0b" : color;
return (
<div
className="rounded-lg border-2 bg-bg transition-all duration-300 min-w-[150px] max-w-[180px]"
style={{
borderColor,
boxShadow: running ? `0 0 14px #f59e0b40` : skipped ? "none" : `0 0 10px ${color}30`,
}}
>
<Handle
type="target"
position={Position.Left}
className="!bg-transparent !border-0 !w-0 !h-0"
/>
<Handle
type="source"
position={Position.Right}
className="!bg-transparent !border-0 !w-0 !h-0"
/>
{/* Header */}
<div
className="flex items-center gap-1.5 px-2.5 pt-2 pb-1"
style={{ borderBottom: "1px solid var(--color-border)" }}
>
{running && <StatusDot color="#f59e0b" sizeClass="size-1.5" />}
<span className="text-xs font-semibold truncate flex-1" title={engine as string}>
{engine as string}
</span>
{skipped && <span className="text-[10px] text-muted px-1 rounded bg-muted/10">skip</span>}
</div>
{/* Body β€” token bar */}
{!skipped && (
<div className="px-2.5 py-1.5">
<div className="flex justify-between text-[10px] text-muted mb-0.5">
<span>{tokIn.toLocaleString()}</span>
<span>β†’</span>
<span>{tokOut.toLocaleString()}</span>
</div>
<div className="relative h-1.5 rounded-full overflow-hidden bg-border">
<div
className="absolute inset-y-0 left-0 rounded-full"
style={{
width: tokIn > 0 ? `${(tokOut / tokIn) * 100}%` : "100%",
backgroundColor: color,
}}
/>
</div>
</div>
)}
{/* Footer */}
<div className="px-2.5 pb-2 pt-1 flex flex-col gap-0.5">
{!skipped && (
<span className="text-[11px] font-bold" style={{ color }} data-testid="savings-percent">
{`-${savings.toFixed(1)}%`}
</span>
)}
{techniques.length > 0 && (
<span
className="text-[9px] text-muted truncate"
title={(techniquesUsed as string[]).join(", ")}
>
{techniques.join(", ")}
</span>
)}
{durationMs != null && (
<span className="text-[9px] text-muted">{(durationMs as number).toFixed(1)}ms</span>
)}
{/* Layer pills */}
{layers.length > 0 && (
<div className="flex gap-0.5 flex-wrap mt-0.5">
{layers.map((layer) => (
<span
key={layer}
className="text-[9px] px-1 rounded-sm font-medium"
style={{
backgroundColor: `${LAYER_COLORS[layer] ?? "#6b7280"}22`,
color: LAYER_COLORS[layer] ?? "#6b7280",
}}
>
{layer}
</span>
))}
</div>
)}
</div>
</div>
);
}
export default EngineNode;