Jon/debugger layout (#3340)

This commit is contained in:
Jonathan Dobson
2025-09-02 10:07:08 -04:00
committed by GitHub
parent aee181c307
commit 41b341f3d8
16 changed files with 604 additions and 249 deletions

View File

@@ -0,0 +1,43 @@
import { LightningBoltIcon } from "@radix-ui/react-icons";
import { ActionsApiResponse, Status } from "@/api/types";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { ActionTypePillMinimal } from "@/routes/tasks/detail/ActionTypePillMinimal";
import { ItemStatusIndicator } from "./ItemStatusIndicator";
type Props = {
action: ActionsApiResponse;
};
function ActionCardMinimal({ action }: Props) {
const success =
action.status === Status.Completed || action.status === Status.Skipped;
return (
<ItemStatusIndicator failure={!success} success={success} offset="-0.7rem">
<div className="flex items-center justify-center gap-2">
<ActionTypePillMinimal actionType={action.action_type} />
{action.created_by === "script" && (
<TooltipProvider>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<div className="flex gap-1">
<LightningBoltIcon className="h-4 w-4 text-[gold]" />
</div>
</TooltipTrigger>
<TooltipContent className="max-w-[250px]">
Code Execution
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
</div>
</ItemStatusIndicator>
);
}
export { ActionCardMinimal };

View File

@@ -0,0 +1,35 @@
import { CheckIcon, Cross2Icon } from "@radix-ui/react-icons";
interface Props {
children: React.ReactNode;
offset?: string;
failure?: boolean;
success?: boolean;
}
function ItemStatusIndicator({
children,
offset = "-0.6rem",
failure,
success,
}: Props) {
return (
<div className="relative flex items-center justify-center overflow-visible">
{children}
{success && (
<CheckIcon
className="absolute h-3 w-3 text-success"
style={{ right: offset, top: offset }}
/>
)}
{failure && (
<Cross2Icon
className="absolute h-[0.65rem] w-[0.65rem] text-destructive"
style={{ right: offset, top: offset }}
/>
)}
</div>
);
}
export { ItemStatusIndicator };

View File

@@ -0,0 +1,17 @@
import { ObserverThought } from "../types/workflowRunTypes";
import { Tip } from "@/components/Tip";
import { BrainIcon } from "@/components/icons/BrainIcon";
type Props = {
thought: ObserverThought;
};
function ThoughtCardMinimal({ thought }: Props) {
return (
<Tip content={thought.answer || thought.thought || null}>
<BrainIcon className="size-6" />
</Tip>
);
}
export { ThoughtCardMinimal };

View File

@@ -0,0 +1,76 @@
import { Tip } from "@/components/Tip";
import { workflowBlockTitle } from "../editor/nodes/types";
import { WorkflowBlockIcon } from "../editor/nodes/WorkflowBlockIcon";
import {
isBlockItem,
isThoughtItem,
WorkflowRunBlock,
WorkflowRunTimelineItem,
} from "../types/workflowRunTypes";
import { ActionCardMinimal } from "./ActionCardMinimal";
import { Status } from "@/api/types";
import { ThoughtCardMinimal } from "./ThoughtCardMinimal";
import { ItemStatusIndicator } from "./ItemStatusIndicator";
type Props = {
block: WorkflowRunBlock;
subItems: Array<WorkflowRunTimelineItem>;
};
function WorkflowRunTimelineBlockItemMinimal({ block, subItems }: Props) {
const actions = block.actions ?? [];
const showStatusIndicator = block.status !== null;
const showSuccessIndicator =
showStatusIndicator && block.status === Status.Completed;
const showFailureIndicator =
showStatusIndicator &&
(block.status === Status.Failed ||
block.status === Status.Terminated ||
block.status === Status.TimedOut ||
block.status === Status.Canceled);
return (
<div className="flex flex-col items-center justify-center gap-2">
<Tip
content={workflowBlockTitle[block.block_type] ?? null}
asChild={false}
>
<ItemStatusIndicator
failure={showFailureIndicator}
success={showSuccessIndicator}
>
<WorkflowBlockIcon workflowBlockType={block.block_type} />
</ItemStatusIndicator>
</Tip>
{actions.length > 0 && (
<div className="flex flex-col items-center justify-center gap-4 rounded-md p-2">
{actions.map((action) => {
return <ActionCardMinimal key={action.action_id} action={action} />;
})}
</div>
)}
{subItems.map((item) => {
if (isBlockItem(item)) {
return (
<WorkflowRunTimelineBlockItemMinimal
key={item.block.workflow_run_block_id}
subItems={item.children}
block={item.block}
/>
);
}
if (isThoughtItem(item)) {
return (
<ThoughtCardMinimal
key={item.thought.thought_id}
thought={item.thought}
/>
);
}
})}
</div>
);
}
export { WorkflowRunTimelineBlockItemMinimal };