FE: allow workflow run UI to show browser stream if workflow run has one (#3838)

This commit is contained in:
Jonathan Dobson
2025-10-28 15:36:54 -04:00
committed by GitHub
parent 299ceb14f3
commit 1f90055672
2 changed files with 50 additions and 22 deletions

View File

@@ -476,6 +476,11 @@ function BrowserStream({
} }
}, [task, workflow]); }, [task, workflow]);
useEffect(() => {
if (!interactive) {
setUserIsControlling(false);
}
}, [interactive]);
/** /**
* TODO(jdo): could use zod or smth similar * TODO(jdo): could use zod or smth similar
*/ */

View File

@@ -1,4 +1,4 @@
import { ActionsApiResponse } from "@/api/types"; import { ActionsApiResponse, Status as WorkflowRunStatus } from "@/api/types";
import { BrowserStream } from "@/components/BrowserStream"; import { BrowserStream } from "@/components/BrowserStream";
import { AspectRatio } from "@/components/ui/aspect-ratio"; import { AspectRatio } from "@/components/ui/aspect-ratio";
import { ActionScreenshot } from "@/routes/tasks/detail/ActionScreenshot"; import { ActionScreenshot } from "@/routes/tasks/detail/ActionScreenshot";
@@ -47,22 +47,20 @@ function WorkflowRunOverview() {
const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } = const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } =
useWorkflowRunTimelineQuery(); useWorkflowRunTimelineQuery();
const workflowRunId = workflowRun?.workflow_run_id;
const invalidateQueries = useCallback(() => { const invalidateQueries = useCallback(() => {
if (workflowRun) { if (workflowRunId) {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: [ queryKey: ["workflowRun", workflowPermanentId, workflowRunId],
"workflowRun",
workflowPermanentId,
workflowRun.workflow_run_id,
],
}); });
queryClient.invalidateQueries({ queryKey: ["workflowRuns"] }); queryClient.invalidateQueries({ queryKey: ["workflowRuns"] });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: ["workflowTasks", workflowRun.workflow_run_id], queryKey: ["workflowTasks", workflowRunId],
}); });
queryClient.invalidateQueries({ queryKey: ["runs"] }); queryClient.invalidateQueries({ queryKey: ["runs"] });
} }
}, [queryClient, workflowPermanentId, workflowRun]); }, [queryClient, workflowPermanentId, workflowRunId]);
if (workflowRunIsLoading || workflowRunTimelineIsLoading) { if (workflowRunIsLoading || workflowRunTimelineIsLoading) {
return ( return (
@@ -87,25 +85,50 @@ function WorkflowRunOverview() {
workflowRunIsFinalized, workflowRunIsFinalized,
); );
const streamingComponent = workflowRun.browser_session_id ? ( const browserSessionId = workflowRun.browser_session_id;
<BrowserStream
workflow={{ run: workflowRun }} const isPaused =
onClose={() => invalidateQueries()} workflowRun && workflowRun.status === WorkflowRunStatus.Paused;
/>
) : ( const showStreamingBrowser =
<WorkflowRunStream /> (!workflowRunIsFinalized &&
browserSessionId &&
isWorkflowRunBlock(selection) &&
selection.block_type === "human_interaction") ||
selection === "stream";
const shouldShowBrowserStream = !!(
browserSessionId &&
!workflowRunIsFinalized &&
(selection === "stream" ||
(isWorkflowRunBlock(selection) &&
selection.block_type === "human_interaction"))
); );
return ( return (
<AspectRatio ratio={16 / 9}> <AspectRatio ratio={16 / 9}>
{selection === "stream" && streamingComponent} {shouldShowBrowserStream && (
{selection !== "stream" && isAction(selection) && ( <BrowserStream
<ActionScreenshot key={browserSessionId}
index={selection.action_order ?? 0} browserSessionId={browserSessionId}
stepId={selection.step_id ?? ""} interactive={isPaused}
showControlButtons={isPaused}
workflow={undefined}
onClose={invalidateQueries}
/> />
)} )}
{isWorkflowRunBlock(selection) && ( {!shouldShowBrowserStream && selection === "stream" && (
<WorkflowRunStream />
)}
{selection !== "stream" &&
!showStreamingBrowser &&
isAction(selection) && (
<ActionScreenshot
index={selection.action_order ?? 0}
stepId={selection.step_id ?? ""}
/>
)}
{isWorkflowRunBlock(selection) && !showStreamingBrowser && (
<WorkflowRunBlockScreenshot <WorkflowRunBlockScreenshot
workflowRunBlockId={selection.workflow_run_block_id} workflowRunBlockId={selection.workflow_run_block_id}
/> />