From 0913e4f0a0f1408e7bbb0310f9c5401637adc6f3 Mon Sep 17 00:00:00 2001 From: Jonathan Dobson Date: Wed, 20 Aug 2025 13:47:17 -0400 Subject: [PATCH] Jon/construct cache key and show (#3242) --- .../workflows/components/BlockCodeEditor.tsx | 51 ++++++++++++++----- .../src/routes/workflows/editor/Workspace.tsx | 7 +++ .../src/routes/workflows/editor/utils.ts | 34 ++++++++++++- .../src/store/WorkflowHasChangesStore.ts | 4 ++ 4 files changed, 81 insertions(+), 15 deletions(-) diff --git a/skyvern-frontend/src/routes/workflows/components/BlockCodeEditor.tsx b/skyvern-frontend/src/routes/workflows/components/BlockCodeEditor.tsx index ef3034f4..03f664da 100644 --- a/skyvern-frontend/src/routes/workflows/components/BlockCodeEditor.tsx +++ b/skyvern-frontend/src/routes/workflows/components/BlockCodeEditor.tsx @@ -1,14 +1,18 @@ import { ExitIcon } from "@radix-ui/react-icons"; +import { useParams } from "react-router-dom"; import { Handle } from "@xyflow/react"; import { Position } from "@xyflow/react"; +import { KeyIcon } from "@/components/icons/KeyIcon"; import { WorkflowBlockType } from "@/routes/workflows/types/workflowTypes"; import { useToggleScriptForNodeCallback } from "@/routes/workflows/hooks/useToggleScriptForNodeCallback"; +import { useWorkflowQuery } from "@/routes/workflows/hooks/useWorkflowQuery"; import { cn } from "@/util/utils"; import { CodeEditor } from "./CodeEditor"; import { workflowBlockTitle } from "../editor/nodes/types"; import { WorkflowBlockIcon } from "../editor/nodes/WorkflowBlockIcon"; +import { constructCacheKeyValue } from "../editor/utils"; function BlockCodeEditor({ blockLabel, @@ -21,9 +25,20 @@ function BlockCodeEditor({ script: string | undefined; onClick?: (e: React.MouseEvent) => void; }) { + const { workflowPermanentId } = useParams(); const blockTitle = workflowBlockTitle[blockType]; const toggleScriptForNodeCallback = useToggleScriptForNodeCallback(); + const { data: workflow } = useWorkflowQuery({ + workflowPermanentId, + }); + const cacheKey = workflow?.cache_key ?? ""; + const cacheKeyValue = workflow + ? cacheKey === "" + ? "" + : constructCacheKeyValue(cacheKey, workflow) + : ""; + return (
-
+
code
-
+
{blockLabel} - {blockTitle} -
-
- { - toggleScriptForNodeCallback({ - label: blockLabel, - show: false, - }); - }} - className="size-5 cursor-pointer" - /> +
+ {blockTitle} +
+ +
+ + {cacheKeyValue === "" ? "(none)" : cacheKeyValue} + +
+
+ { + toggleScriptForNodeCallback({ + label: blockLabel, + show: false, + }); + }} + className="size-5 cursor-pointer" + /> +
{script ? (
diff --git a/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx b/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx index ed1c9d44..bccf26f3 100644 --- a/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx @@ -57,6 +57,7 @@ import { layout, startNode, } from "./workflowEditorUtils"; +import { constructCacheKeyValue } from "./utils"; const Constants = { NewBrowserCooldown: 30000, @@ -130,7 +131,13 @@ function Workspace({ const initialHeight = (initialWidth / 16) * 9; // ---end fya + const cacheKey = workflow?.cache_key ?? ""; + const cacheKeyValue = + cacheKey === "" ? "" : constructCacheKeyValue(cacheKey, workflow); + const { data: blockScripts } = useBlockScriptsQuery({ + cacheKey, + cacheKeyValue, workflowPermanentId, }); diff --git a/skyvern-frontend/src/routes/workflows/editor/utils.ts b/skyvern-frontend/src/routes/workflows/editor/utils.ts index e3853963..a120b8e2 100644 --- a/skyvern-frontend/src/routes/workflows/editor/utils.ts +++ b/skyvern-frontend/src/routes/workflows/editor/utils.ts @@ -97,4 +97,36 @@ const getInitialParameters = (workflow: WorkflowApiResponse) => { .filter(Boolean) as ParametersState; }; -export { getInitialParameters }; +/** + * Attempt to construct a valid cache key value from the workflow parameters. + */ +const constructCacheKeyValue = ( + cacheKey: string, + workflow: WorkflowApiResponse, +) => { + const workflowParameters = getInitialParameters(workflow) + .filter((p) => p.parameterType === "workflow") + .reduce( + (acc, parameter) => { + acc[parameter.key] = parameter.defaultValue; + return acc; + }, + {} as Record, + ); + + for (const [name, value] of Object.entries(workflowParameters)) { + if (value === null || value === undefined || value === "") { + continue; + } + + cacheKey = cacheKey.replace(`{{${name}}}`, value.toString()); + } + + if (cacheKey.includes("{") || cacheKey.includes("}")) { + return ""; + } + + return cacheKey; +}; + +export { constructCacheKeyValue, getInitialParameters }; diff --git a/skyvern-frontend/src/store/WorkflowHasChangesStore.ts b/skyvern-frontend/src/store/WorkflowHasChangesStore.ts index 96ae3445..802fa079 100644 --- a/skyvern-frontend/src/store/WorkflowHasChangesStore.ts +++ b/skyvern-frontend/src/store/WorkflowHasChangesStore.ts @@ -152,6 +152,10 @@ const useWorkflowSave = () => { queryKey: ["workflows"], }); + queryClient.invalidateQueries({ + queryKey: ["block-scripts", saveData.workflow.workflow_permanent_id], + }); + setHasChanges(false); }, onError: (error: AxiosError) => {