diff --git a/web/src/app/_components/multi-agent-visualization.tsx b/web/src/app/_components/multi-agent-visualization.tsx
new file mode 100644
index 0000000..80a4db3
--- /dev/null
+++ b/web/src/app/_components/multi-agent-visualization.tsx
@@ -0,0 +1,288 @@
+// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+// SPDX-License-Identifier: MIT
+
+"use client";
+
+import {
+ ReactFlow,
+ Background,
+ useNodesState,
+ useEdgesState,
+ Handle,
+ Position,
+} from "@xyflow/react";
+
+import "@xyflow/react/dist/style.css";
+
+const ROW_HEIGHT = 75;
+const ROW_1 = 0;
+const ROW_2 = ROW_HEIGHT;
+const ROW_3 = ROW_HEIGHT * 2;
+const ROW_4 = ROW_HEIGHT * 2;
+const ROW_5 = ROW_HEIGHT * 3;
+const ROW_6 = ROW_HEIGHT * 4;
+const initialNodes = [
+ {
+ id: "Start",
+ type: "circle",
+ data: { label: "Start" },
+ position: { x: 80, y: ROW_1 },
+ },
+ {
+ id: "Coordinator",
+ data: { label: "Coordinator" },
+ position: { x: 150, y: ROW_1 },
+ },
+ {
+ id: "Planner",
+ data: { label: "Planner" },
+ position: { x: 150, y: ROW_2 },
+ },
+ {
+ id: "Reporter",
+ data: { label: "Reporter" },
+ position: { x: 25, y: ROW_3 },
+ },
+ {
+ id: "Human Feedback",
+ data: { label: "Human Feedback" },
+ position: { x: 275, y: ROW_4 },
+ },
+ {
+ id: "Research Team",
+ data: { label: "Research Team" },
+ position: { x: 275, y: ROW_5 },
+ },
+ {
+ id: "Researcher",
+ data: { label: "Researcher" },
+ position: { x: 175, y: ROW_6 },
+ },
+ {
+ id: "Coder",
+ data: { label: "Coder" },
+ position: { x: 375, y: ROW_6 },
+ },
+ {
+ id: "End",
+ type: "circle",
+ data: { label: "End" },
+ position: { x: 80, y: ROW_6 },
+ },
+];
+
+const initialEdges = [
+ {
+ id: "Start->Coordinator",
+ source: "Start",
+ target: "Coordinator",
+ sourceHandle: "right",
+ targetHandle: "left",
+ animated: true,
+ },
+ {
+ id: "Coordinator->Planner",
+ source: "Coordinator",
+ target: "Planner",
+ sourceHandle: "bottom",
+ targetHandle: "top",
+ animated: true,
+ },
+ {
+ id: "Planner->Reporter",
+ source: "Planner",
+ target: "Reporter",
+ sourceHandle: "left",
+ targetHandle: "top",
+ animated: true,
+ },
+ {
+ id: "Planner->Human Feedback",
+ source: "Planner",
+ target: "Human Feedback",
+ sourceHandle: "bottom",
+ targetHandle: "left",
+ animated: true,
+ },
+ {
+ id: "Human Feedback->Planner",
+ source: "Human Feedback",
+ target: "Planner",
+ sourceHandle: "top",
+ targetHandle: "right",
+ animated: true,
+ },
+ {
+ id: "Human Feedback->Research Team",
+ source: "Human Feedback",
+ target: "Research Team",
+ sourceHandle: "bottom",
+ targetHandle: "top",
+ animated: true,
+ },
+ {
+ id: "Reporter->End",
+ source: "Reporter",
+ target: "End",
+ sourceHandle: "bottom",
+ targetHandle: "top",
+ animated: true,
+ },
+ {
+ id: "Research Team->Researcher",
+ source: "Research Team",
+ target: "Researcher",
+ sourceHandle: "left",
+ targetHandle: "top",
+ animated: true,
+ },
+ {
+ id: "Research Team->Coder",
+ source: "Research Team",
+ target: "Coder",
+ sourceHandle: "bottom",
+ targetHandle: "left",
+ animated: true,
+ },
+ {
+ id: "Research Team->Planner",
+ source: "Research Team",
+ target: "Planner",
+ sourceHandle: "left",
+ targetHandle: "bottom",
+ animated: true,
+ },
+ {
+ id: "Researcher->Research Team",
+ source: "Researcher",
+ target: "Research Team",
+ sourceHandle: "right",
+ targetHandle: "bottom",
+ animated: true,
+ },
+ {
+ id: "Coder->Research Team",
+ source: "Coder",
+ target: "Research Team",
+ sourceHandle: "top",
+ targetHandle: "right",
+ animated: true,
+ },
+];
+
+const nodeTypes = {
+ circle: CircleNode,
+ agent: AgentNode,
+ default: AgentNode,
+};
+
+export function MultiAgentVisualization() {
+ const [nodes, , onNodesChange] = useNodesState(initialNodes);
+ const [edges, , onEdgesChange] = useEdgesState(initialEdges);
+
+ return (
+
{data.label}
+