diff --git a/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx b/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx
index 88f8582c3..75fc916c4 100644
--- a/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx
+++ b/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx
@@ -165,6 +165,7 @@ import { WorkflowHistoryPanel } from "./panels/WorkflowHistoryPanel";
import { WorkflowSchedulePanel } from "./panels/schedulePanel/WorkflowSchedulePanel";
import { WorkflowVersion } from "../hooks/useWorkflowVersionsQuery";
import { WorkflowDefinition, WorkflowSettings } from "../types/workflowTypes";
+import { useAgentsPathMatch } from "../useAgentsPathMatch";
import { shouldKeepExistingEdgeForInsertion } from "./workflowInsertion";
import { constructCacheKeyValue, getInitialParameters } from "./utils";
@@ -402,6 +403,7 @@ function Workspace({
selectedBlockId,
isNodeLibraryOpen,
);
+ const isEditRoute = useAgentsPathMatch("/:workflowPermanentId/edit") !== null;
// While collapsed, the pill is offscreen but its WorkflowHeaderCollapseTab
// (chevron) sits at the bottom edge, centered on the pill. If we let the
// pill's right inset track blockSidebarOpen while collapsed, the tab snaps
@@ -2155,6 +2157,31 @@ function Workspace({
historyApplyTrigger={historyApplyTrigger}
/>
+ {/* Studio hosts the toggle in the Editor pane header; legacy
+ anchors it under the header on /edit only (the debugger
+ mounts this Workspace too). */}
+ {!yamlEditorActive &&
+ !isGlobalWorkflow &&
+ !embedded &&
+ isEditRoute ? (
+
+
+
+ ) : null}
+
{/* sub panels */}
{workflowPanelState.active && (
<>
@@ -2988,12 +3015,6 @@ function Workspace({
}}
/>
- {/* Studio hosts the toggle in the Editor pane header instead. */}
- {!yamlEditorActive && !isGlobalWorkflow && !embedded ? (
-
-
-
- ) : null}
{/* Studio: the cache key/value panel escapes the Editor pane via the
shell-level portal, so the Overview pane's Code view can open it (and
close it) even with the Editor pane hidden. */}
diff --git a/skyvern-frontend/src/routes/workflows/utils.test.ts b/skyvern-frontend/src/routes/workflows/utils.test.ts
index fce715a62..43d4dad16 100644
--- a/skyvern-frontend/src/routes/workflows/utils.test.ts
+++ b/skyvern-frontend/src/routes/workflows/utils.test.ts
@@ -1,10 +1,8 @@
import { describe, expect, it } from "vitest";
import {
- formatDuration,
normalizeJsonParameterFormValue,
parseJsonWorkflowParameterValue,
- toDuration,
validateJsonWorkflowParameterValue,
} from "./utils";
@@ -80,44 +78,3 @@ describe("validateJsonWorkflowParameterValue", () => {
);
});
});
-
-describe("toDuration", () => {
- it("converts sub-minute durations", () => {
- expect(toDuration(45)).toEqual({ hour: 0, minute: 0, second: 45 });
- });
-
- it("converts minutes and seconds", () => {
- expect(toDuration(125)).toEqual({ hour: 0, minute: 2, second: 5 });
- });
-
- it("converts hours, minutes, and seconds", () => {
- expect(toDuration(3661)).toEqual({ hour: 1, minute: 1, second: 1 });
- });
-
- it("floors fractional seconds", () => {
- expect(toDuration(90.7)).toEqual({ hour: 0, minute: 1, second: 30 });
- });
-
- it("preserves hours beyond 24 instead of wrapping", () => {
- // 25h exactly — `hours % 24` used to report this as 1h since Duration
- // has no day field to carry the overflow.
- expect(toDuration(90000)).toEqual({ hour: 25, minute: 0, second: 0 });
- });
-
- it("preserves multi-day durations in the hour field", () => {
- // 49h 1m 5s
- expect(toDuration(176465)).toEqual({ hour: 49, minute: 1, second: 5 });
- });
-});
-
-describe("formatDuration", () => {
- it("omits empty leading units", () => {
- expect(formatDuration(toDuration(45))).toBe("45s");
- expect(formatDuration(toDuration(125))).toBe("2m 5s");
- expect(formatDuration(toDuration(3661))).toBe("1h 1m 1s");
- });
-
- it("renders durations longer than a day without losing hours", () => {
- expect(formatDuration(toDuration(90000))).toBe("25h 0m 0s");
- });
-});
diff --git a/skyvern-frontend/src/routes/workflows/utils.ts b/skyvern-frontend/src/routes/workflows/utils.ts
index 9a961b163..503362cd3 100644
--- a/skyvern-frontend/src/routes/workflows/utils.ts
+++ b/skyvern-frontend/src/routes/workflows/utils.ts
@@ -169,9 +169,10 @@ export interface Duration {
export const toDuration = (seconds: number): Duration => {
let minutes = Math.floor(seconds / 60);
- const hours = Math.floor(minutes / 60);
+ let hours = Math.floor(minutes / 60);
seconds = seconds % 60;
minutes = minutes % 60;
+ hours = hours % 24;
return {
hour: Math.floor(hours),