🔄 synced local 'skyvern-frontend/src/' with remote 'skyvern-frontend/src/'

This commit is contained in:
AronPerez 2026-04-25 03:15:27 +00:00
parent 26ec15a045
commit ecb52d0f9a
2 changed files with 59 additions and 18 deletions

View file

@ -577,6 +577,7 @@ export type WorkflowRunStatusApiResponse = {
parameters: Record<string, unknown>;
screenshot_urls: Array<string> | null;
recording_url: string | null;
recording_urls: Array<string> | null;
outputs: Record<string, unknown> | null;
failure_reason: string | null;
failure_category: Array<FailureCategory> | null;
@ -608,6 +609,7 @@ export type WorkflowRunStatusApiResponseWithWorkflow = {
parameters: Record<string, unknown>;
screenshot_urls: Array<string> | null;
recording_url: string | null;
recording_urls: Array<string> | null;
outputs: Record<string, unknown> | null;
failure_reason: string | null;
failure_category: Array<FailureCategory> | null;

View file

@ -2,33 +2,72 @@ import { usePostHog } from "posthog-js/react";
import { useWorkflowRunWithWorkflowQuery } from "../hooks/useWorkflowRunWithWorkflowQuery";
import { artifactApiBaseUrl } from "@/util/env";
function resolveUrl(url: string): string {
if (url.startsWith("file://")) {
return `${artifactApiBaseUrl}/artifact/recording?path=${url.slice(7)}`;
}
return url;
}
function WorkflowRunRecording() {
const postHog = usePostHog();
const { data: workflowRun } = useWorkflowRunWithWorkflowQuery();
let recordingURL = workflowRun?.recording_url;
if (recordingURL?.startsWith("file://")) {
recordingURL = `${artifactApiBaseUrl}/artifact/recording?path=${recordingURL.slice(7)}`;
const rawUrls =
workflowRun?.recording_urls && workflowRun.recording_urls.length > 0
? workflowRun.recording_urls
: workflowRun?.recording_url
? [workflowRun.recording_url]
: [];
const recordingUrls = rawUrls.map(resolveUrl);
if (!workflowRun || recordingUrls.length === 0) {
return <div>No recording available for this workflow</div>;
}
function handlePlay() {
if (!workflowRun) {
return;
}
const run = workflowRun;
function handlePlay(index: number) {
postHog.capture("run.recording.viewed", {
org_id: workflowRun.workflow.organization_id,
run_id: workflowRun.workflow_run_id,
org_id: run.workflow.organization_id,
run_id: run.workflow_run_id,
recording_index: index,
recording_count: recordingUrls.length,
});
}
return recordingURL ? (
<video
src={recordingURL}
controls
className="w-full rounded-md"
onPlay={handlePlay}
/>
) : (
<div>No recording available for this workflow</div>
if (recordingUrls.length === 1) {
return (
<video
src={recordingUrls[0]}
controls
preload="metadata"
className="w-full rounded-md"
onPlay={() => handlePlay(0)}
/>
);
}
return (
<div className="flex flex-col gap-4">
{recordingUrls.map((url, index) => (
<div
key={index} // presigned URLs change on refetch; list order is stable
className="flex flex-col gap-2"
>
<div className="text-sm text-slate-400">
Recording {index + 1} of {recordingUrls.length}
</div>
<video
src={url}
controls
preload="metadata"
className="w-full rounded-md"
onPlay={() => handlePlay(index)}
/>
</div>
))}
</div>
);
}