Agent Lanes TimelineAgent Lanes Timeline
봇별 실행 구간을 시간축에 놓은 타임라인입니다. onRangeClick을 넘기면 범위 알약이 버튼이 됩니다.A timeline that places each bot's run on a time axis. Pass onRangeClick to turn the range pill into a button.
에이전트Agents
Bots
2 running1 needs you-25m-20m-15m-10m-5m
Investor questions
Draft investor update
Book interviews
Send to 12 investorsNeeds you
nowChief of staff wants your yes before emailing 12 investors
import { AgentLanesTimeline, type LaneBot } from "@horon-ai/react"; import { Envelope, FileText, Folder, Warning, WarningCircle } from "@phosphor-icons/react"; import { useState } from "react"; const bots: LaneBot[] = [ { id: "researcher", name: "Researcher", tools: "Notion · Gmail", initial: "R", tone: "sky", tasks: [ { id: "portfolio", label: "Portfolio metrics", icon: <Folder />, tone: "done", start: -28, end: -16 }, { id: "questions", label: "Investor questions", icon: <Envelope />, tone: "running", start: -9, end: 0 }, ], }, { id: "writer", name: "Writer", tools: "Docs", initial: "W", tone: "steel", tasks: [{ id: "update", label: "Draft investor update", icon: <FileText />, tone: "running", start: -14, end: 0 }], }, { id: "reviewer", name: "Reviewer", tools: "Docs", initial: "V", tone: "neutral", badge: "Idle", tasks: [{ id: "deck", label: "Review Q3 deck", icon: <FileText />, tone: "done", start: -30, end: -19 }], }, { id: "chief", name: "Chief of staff", tools: "Gmail · Calendar", initial: "C", tone: "ink", badge: "Needs you", badgeTone: "ink", tasks: [ { id: "interviews", label: "Book interviews", icon: <WarningCircle />, tone: "failed", start: -28, end: -21 }, { id: "send", label: "Send to 12 investors", icon: <Envelope />, tone: "waiting", start: -12, end: 0, badge: ( <> <Warning /> Needs you </> ), }, ], }, ]; export default function AgentLanesTimelineDemo() { const [cursor, setCursor] = useState(0); return ( <div className="flex w-full flex-col items-center gap-6"> <AgentLanesTimeline statuses={[ { id: "running", tone: "live", label: "2 running" }, { id: "needs", tone: "ink", label: "1 needs you" }, ]} bots={bots} handoffs={[{ from: "portfolio", to: "update" }]} cursor={cursor} approval={{ message: "Chief of staff wants your yes before emailing 12 investors", onLater: () => undefined, onApprove: () => undefined, }} /> <label className="flex items-center gap-3 rounded-full bg-bg-surface-80 px-4 py-2 text-caption text-text-secondary"> Scrub the current line <input type="range" min={0} max={10} step={1} value={cursor} onChange={(event) => setCursor(Number(event.target.value))} aria-label="Minutes before now" /> </label> </div> ); }