"use client";
import { Canvas } from "@/components/ai-elements/canvas";
import { Connection } from "@/components/ai-elements/connection";
import { Controls } from "@/components/ai-elements/controls";
import { Edge } from "@/components/ai-elements/edge";
import {
Node,
NodeContent,
NodeDescription,
NodeFooter,
NodeHeader,
NodeTitle,
} from "@/components/ai-elements/node";
import { Panel } from "@/components/ai-elements/panel";
import { Badge } from "@/components/ui/badge";
const nodeIds = {
start: "start",
classify: "classify",
routeGeneral: "route-general",
routeRefund: "route-refund",
routeTechnical: "route-technical",
complete: "complete",
};
const nodes = [
{
id: nodeIds.start,
type: "workflow",
position: { x: 0, y: 200 },
data: {
label: "Start Workflow",
description: "Initialize routing workflow",
handles: { target: false, source: true },
content: "Input: Customer Query",
footer: "Setup: globalThis.fetch = fetch",
},
},
{
id: nodeIds.classify,
type: "workflow",
position: { x: 500, y: 200 },
data: {
label: "Classify Query",
description: "Determine type and complexity",
handles: { target: true, source: true },
content:
"Classify: type (general, refund, technical) + complexity (simple, complex)",
footer: "Model: openai/gpt-4o • Step 1",
},
},
{
id: nodeIds.routeGeneral,
type: "workflow",
position: { x: 1000, y: 0 },
data: {
label: "Route: General",
description: "Handle general inquiries",
handles: { target: true, source: true },
content:
"Expert customer service agent • Model: gpt-4o-mini (simple) / o4-mini (complex)",
footer: "Conditional routing",
},
},
{
id: nodeIds.routeRefund,
type: "workflow",
position: { x: 1000, y: 200 },
data: {
label: "Route: Refund",
description: "Handle refund requests",
handles: { target: true, source: true },
content:
"Refund specialist • Follow policy • Model: gpt-4o-mini (simple) / o4-mini (complex)",
footer: "Conditional routing",
},
},
{
id: nodeIds.routeTechnical,
type: "workflow",
position: { x: 1000, y: 400 },
data: {
label: "Route: Technical",
description: "Handle technical support",
handles: { target: true, source: true },
content:
"Technical specialist • Step-by-step troubleshooting • Model: gpt-4o-mini (simple) / o4-mini (complex)",
footer: "Conditional routing",
},
},
{
id: nodeIds.complete,
type: "workflow",
position: { x: 1500, y: 200 },
data: {
label: "Complete",
description: "Workflow finished",
handles: { target: true, source: false },
content: "Response generated based on classification",
footer: "Status: Success",
},
},
];
const edges = [
{
id: "edge1",
source: nodeIds.start,
target: nodeIds.classify,
type: "animated",
},
{
id: "edge2",
source: nodeIds.classify,
target: nodeIds.routeGeneral,
type: "animated",
label: "General",
},
{
id: "edge3",
source: nodeIds.classify,
target: nodeIds.routeRefund,
type: "animated",
label: "Refund",
},
{
id: "edge4",
source: nodeIds.classify,
target: nodeIds.routeTechnical,
type: "animated",
label: "Technical",
},
{
id: "edge5",
source: nodeIds.routeGeneral,
target: nodeIds.complete,
type: "animated",
},
{
id: "edge6",
source: nodeIds.routeRefund,
target: nodeIds.complete,
type: "animated",
},
{
id: "edge7",
source: nodeIds.routeTechnical,
target: nodeIds.complete,
type: "animated",
},
];
const nodeTypes = {
workflow: ({
data,
}: {
data: {
label: string;
description: string;
handles: { target: boolean; source: boolean };
content: string;
footer: string;
};
}) => (
<Node handles={data.handles}>
<NodeHeader>
<NodeTitle>{data.label}</NodeTitle>
<NodeDescription>{data.description}</NodeDescription>
</NodeHeader>
<NodeContent>
<p className="text-sm">{data.content}</p>
</NodeContent>
<NodeFooter>
<p className="text-muted-foreground text-xs">{data.footer}</p>
</NodeFooter>
</Node>
),
};
const edgeTypes = {
animated: Edge.Animated,
temporary: Edge.Temporary,
};
const Example = () => (
<Canvas
connectionLineComponent={Connection}
edges={edges}
edgeTypes={edgeTypes}
fitView
nodes={nodes}
nodeTypes={nodeTypes}
>
<Controls />
<Panel position="top-left">
<div className="flex flex-col gap-2">
<h3 className="font-semibold text-sm">Routing Pattern</h3>
<p className="text-muted-foreground text-xs">
Classify and route to specialized handlers
</p>
<div className="flex gap-1">
<Badge variant="secondary">Classification</Badge>
<Badge variant="secondary">Conditional Routing</Badge>
</div>
</div>
</Panel>
</Canvas>
);
export default Example;