import { useParams } from "react-router-dom"; import { ScrollArea, ScrollAreaViewport } from "@/components/ui/scroll-area"; import { Skeleton } from "@/components/ui/skeleton"; import { statusIsFinalized } from "@/routes/tasks/types"; import { useWorkflowRunQuery } from "../hooks/useWorkflowRunQuery"; import { useWorkflowRunTimelineQuery } from "../hooks/useWorkflowRunTimelineQuery"; import { isBlockItem, isObserverThought, isTaskVariantBlockItem, isThoughtItem, ObserverThought, WorkflowRunBlock, } from "../types/workflowRunTypes"; import { ThoughtCard } from "@/routes/workflows/workflowRun/ThoughtCard"; import { ActionItem, WorkflowRunOverviewActiveElement, } from "@/routes/workflows/workflowRun/WorkflowRunOverview"; import { WorkflowRunTimelineBlockItem } from "@/routes/workflows/workflowRun/WorkflowRunTimelineBlockItem"; import { useWorkflowQuery } from "../hooks/useWorkflowQuery"; type Props = { activeItem: WorkflowRunOverviewActiveElement; onObserverThoughtCardSelected: (item: ObserverThought) => void; onActionItemSelected: (item: ActionItem) => void; onBlockItemSelected: (item: WorkflowRunBlock) => void; }; function Step({ n, children }: { n: number; children: React.ReactNode }) { return (
{n}
{n}
{children}
); } function DebuggerRunTimeline({ activeItem, onObserverThoughtCardSelected, onActionItemSelected, onBlockItemSelected, }: Props) { const { workflowPermanentId } = useParams(); const { data: workflow } = useWorkflowQuery({ workflowPermanentId }!); const { data: workflowRun, isLoading: workflowRunIsLoading } = useWorkflowRunQuery(); const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } = useWorkflowRunTimelineQuery(); if (workflowRunIsLoading || workflowRunTimelineIsLoading) { return ; } const blocks = workflow?.workflow_definition.blocks ?? []; const getStarted = blocks.length === 0 ? (
Hi! 👋 To get started, add a block to your workflow. You can do that by clicking the round plus button beneath the Start block, on the left
) : null; const runABlock = (
To run a single block, click the play button on that block. Skyvern will run the block in the browser, live!
); const adjustBrowser = (
Need to adjust the browser to test your block again? You can click around in the browser to bring Skyvern to any page (manually!)
); const parameters = (
Want Skyvern to do different things based on your inputs? Use Parameters to specify them and reference them using {"{{ }}"} syntax!
); const addBlocks = (
Not finished? Add a block to your workflow by clicking the round plus button before or after any other block.
); const steps = [ getStarted, runABlock, adjustBrowser, getStarted === null ? parameters : null, getStarted === null ? addBlocks : null, ].filter((step) => step); if (!workflowRun || !workflowRunTimeline) { return (
Build & Debug Complex Browser Automations
{steps.map((step, index) => ( {step} ))}
); } const workflowRunIsFinalized = statusIsFinalized(workflowRun); const numberOfActions = workflowRunTimeline.reduce((total, current) => { if (isTaskVariantBlockItem(current)) { return total + current.block!.actions!.length; } return total + 0; }, 0); return (
Actions: {numberOfActions}
Steps: {workflowRun.total_steps ?? 0}
{!workflowRunIsFinalized && workflowRunTimeline.length === 0 && ( )}
{workflowRunIsFinalized && workflowRunTimeline.length === 0 && (
Workflow timeline is empty
)} {workflowRunTimeline?.map((timelineItem) => { if (isBlockItem(timelineItem)) { return ( ); } if (isThoughtItem(timelineItem)) { return ( ); } })}
); } export { DebuggerRunTimeline };