Show all branch evaluations in conditional block timeline (#SKY-7495) (#4577)

This commit is contained in:
Celal Zamanoglu
2026-01-29 13:06:51 +03:00
committed by GitHub
parent 69e1ea15cc
commit 3694faf2b2
2 changed files with 123 additions and 21 deletions

View File

@@ -167,3 +167,33 @@ export function hasNavigationGoal(
): item is { navigation_goal: unknown } { ): item is { navigation_goal: unknown } {
return item !== null && typeof item === "object" && "navigation_goal" in item; return item !== null && typeof item === "object" && "navigation_goal" in item;
} }
// Branch evaluation types for conditional blocks
export type BranchEvaluation = {
branch_id: string;
branch_index: number;
criteria_type: "jinja2_template" | "prompt" | null;
original_expression: string | null;
rendered_expression: string | null;
result: boolean | null;
is_matched: boolean;
is_default: boolean;
next_block_label: string | null;
error: string | null;
};
export type ConditionalBlockOutput = {
evaluations?: Array<BranchEvaluation>;
matched_branch_index?: number | null;
};
export function hasEvaluations(
output: unknown,
): output is ConditionalBlockOutput {
return (
output !== null &&
typeof output === "object" &&
"evaluations" in output &&
Array.isArray((output as ConditionalBlockOutput).evaluations)
);
}

View File

@@ -18,6 +18,7 @@ import {
isObserverThought, isObserverThought,
isThoughtItem, isThoughtItem,
isWorkflowRunBlock, isWorkflowRunBlock,
hasEvaluations,
WorkflowRunBlock, WorkflowRunBlock,
WorkflowRunTimelineItem, WorkflowRunTimelineItem,
} from "../types/workflowRunTypes"; } from "../types/workflowRunTypes";
@@ -180,29 +181,100 @@ function WorkflowRunTimelineBlockItem({
<div className="text-xs text-slate-400">{block.description}</div> <div className="text-xs text-slate-400">{block.description}</div>
) : null} ) : null}
{block.block_type === "conditional" && block.executed_branch_id && ( {block.block_type === "conditional" && block.executed_branch_id && (
<div className="space-y-1 rounded bg-slate-elevation5 px-3 py-2 text-xs"> <div className="space-y-2 rounded bg-slate-elevation5 px-3 py-2 text-xs">
{block.executed_branch_expression !== null && {hasEvaluations(block.output) && block.output.evaluations ? (
block.executed_branch_expression !== undefined ? ( // New format: show all branch evaluations
<div className="text-slate-300"> <div className="space-y-2">
Condition{" "} {block.output.evaluations.map((evaluation, index) => (
<code className="rounded bg-slate-elevation3 px-1.5 py-0.5 font-mono text-slate-200"> <div
{block.executed_branch_expression} key={evaluation.branch_id || index}
</code>{" "} className={cn(
evaluated to{" "} "rounded border px-2 py-1.5",
<span className="font-medium text-success">True</span> evaluation.is_matched
? "border-success/50 bg-success/10"
: "border-slate-600 bg-slate-elevation3",
)}
>
{evaluation.is_default ? (
<div className="text-slate-300">
<span className="font-medium">Default branch</span>
{evaluation.is_matched && (
<span className="ml-2 text-success"> Matched</span>
)}
</div>
) : (
<div className="space-y-1">
<div className="text-slate-400">
<code className="rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-300">
{evaluation.original_expression}
</code>
</div>
{evaluation.rendered_expression &&
evaluation.rendered_expression !==
evaluation.original_expression && (
<div className="text-slate-400">
rendered to{" "}
<code className="rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-200">
{evaluation.rendered_expression}
</code>
</div>
)}
<div className="flex items-center gap-2">
<span className="text-slate-400">evaluated to</span>
<span
className={cn(
"font-medium",
evaluation.result
? "text-success"
: "text-red-400",
)}
>
{evaluation.result ? "True" : "False"}
</span>
{evaluation.is_matched && (
<span className="text-success"> Matched</span>
)}
</div>
</div>
)}
{evaluation.is_matched && evaluation.next_block_label && (
<div className="mt-1 text-slate-400">
Executing next block:{" "}
<span className="font-medium text-slate-300">
{evaluation.next_block_label}
</span>
</div>
)}
</div>
))}
</div> </div>
) : ( ) : (
<div className="text-slate-300"> // Fallback: old format without evaluations array
No conditions matched, executing default branch <>
</div> {block.executed_branch_expression !== null &&
)} block.executed_branch_expression !== undefined ? (
{block.executed_branch_next_block && ( <div className="text-slate-300">
<div className="text-slate-400"> Condition{" "}
Executing next block:{" "} <code className="rounded bg-slate-elevation3 px-1.5 py-0.5 font-mono text-slate-200">
<span className="font-medium text-slate-300"> {block.executed_branch_expression}
{block.executed_branch_next_block} </code>{" "}
</span> evaluated to{" "}
</div> <span className="font-medium text-success">True</span>
</div>
) : (
<div className="text-slate-300">
No conditions matched, executing default branch
</div>
)}
{block.executed_branch_next_block && (
<div className="text-slate-400">
Executing next block:{" "}
<span className="font-medium text-slate-300">
{block.executed_branch_next_block}
</span>
</div>
)}
</>
)} )}
</div> </div>
)} )}