From 9dd4263f9a584310023fb0cdf2d7d6f569338ddf Mon Sep 17 00:00:00 2001 From: Shuchang Zheng Date: Thu, 14 Nov 2024 09:57:16 -0800 Subject: [PATCH] Add parameterKeys to textPrompt (#1191) --- .../routes/workflows/editor/FlowRenderer.tsx | 13 ++++++++++ ...ersPanel.tsx => ParametersMultiSelect.tsx} | 4 +-- .../editor/nodes/TaskNode/TaskNode.tsx | 4 +-- .../nodes/TextPromptNode/TextPromptNode.tsx | 25 ++++++++++++++++++- .../editor/nodes/TextPromptNode/types.ts | 2 ++ .../editor/panels/WorkflowParametersPanel.tsx | 10 ++++++-- .../workflows/editor/workflowEditorUtils.ts | 4 ++- 7 files changed, 54 insertions(+), 8 deletions(-) rename skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/{TaskNodeParametersPanel.tsx => ParametersMultiSelect.tsx} (94%) diff --git a/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx b/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx index 39097d62..205ed7b1 100644 --- a/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx @@ -418,6 +418,19 @@ function FlowRenderer({ }, }; } + // TODO: Fix this. When we put these into the same if statement TS fails to recognize that the returned value fits both the task and text prompt node types + if (node.type === "textPrompt") { + return { + ...node, + data: { + ...node.data, + parameterKeys: node.data.parameterKeys.filter( + (parameter) => + parameter !== getOutputParameterKey(deletedNodeLabel), + ), + }, + }; + } if (node.type === "loop") { return { ...node, diff --git a/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNodeParametersPanel.tsx b/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/ParametersMultiSelect.tsx similarity index 94% rename from skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNodeParametersPanel.tsx rename to skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/ParametersMultiSelect.tsx index 096eb8e6..3a981480 100644 --- a/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNodeParametersPanel.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/ParametersMultiSelect.tsx @@ -9,7 +9,7 @@ type Props = { onParametersChange: (parameters: Array) => void; }; -function TaskNodeParametersPanel({ +function ParametersMultiSelect({ availableOutputParameters, parameters, onParametersChange, @@ -42,4 +42,4 @@ function TaskNodeParametersPanel({ ); } -export { TaskNodeParametersPanel }; +export { ParametersMultiSelect }; diff --git a/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNode.tsx b/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNode.tsx index 987528e0..b45debd5 100644 --- a/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNode.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/nodes/TaskNode/TaskNode.tsx @@ -27,7 +27,7 @@ import { AppNode } from ".."; import { getAvailableOutputParameterKeys } from "../../workflowEditorUtils"; import { EditableNodeTitle } from "../components/EditableNodeTitle"; import { NodeActionMenu } from "../NodeActionMenu"; -import { TaskNodeParametersPanel } from "./TaskNodeParametersPanel"; +import { ParametersMultiSelect } from "./ParametersMultiSelect"; import { dataSchemaExampleValue, errorMappingExampleValue, @@ -152,7 +152,7 @@ function TaskNode({ id, data }: NodeProps) { />
- { diff --git a/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/TextPromptNode.tsx b/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/TextPromptNode.tsx index 55df7ef5..8d94615d 100644 --- a/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/TextPromptNode.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/TextPromptNode.tsx @@ -6,12 +6,22 @@ import { CodeEditor } from "@/routes/workflows/components/CodeEditor"; import { useDeleteNodeCallback } from "@/routes/workflows/hooks/useDeleteNodeCallback"; import { useNodeLabelChangeHandler } from "@/routes/workflows/hooks/useLabelChangeHandler"; import { CursorTextIcon } from "@radix-ui/react-icons"; -import { Handle, NodeProps, Position, useReactFlow } from "@xyflow/react"; +import { + Handle, + NodeProps, + Position, + useEdges, + useNodes, + useReactFlow, +} from "@xyflow/react"; import { useState } from "react"; import { EditableNodeTitle } from "../components/EditableNodeTitle"; import { NodeActionMenu } from "../NodeActionMenu"; import { helpTooltipContent, type TextPromptNode } from "./types"; import { HelpTooltip } from "@/components/HelpTooltip"; +import { ParametersMultiSelect } from "../TaskNode/ParametersMultiSelect"; +import { getAvailableOutputParameterKeys } from "../../workflowEditorUtils"; +import { AppNode } from ".."; function TextPromptNode({ id, data }: NodeProps) { const { updateNodeData } = useReactFlow(); @@ -22,6 +32,10 @@ function TextPromptNode({ id, data }: NodeProps) { jsonSchema: data.jsonSchema, }); + const nodes = useNodes(); + const edges = useEdges(); + const outputParameterKeys = getAvailableOutputParameterKeys(nodes, edges, id); + const [label, setLabel] = useNodeLabelChangeHandler({ id, initialValue: data.label, @@ -82,6 +96,15 @@ function TextPromptNode({ id, data }: NodeProps) { className="nopan text-xs" />
+
+ { + updateNodeData(id, { parameterKeys }); + }} + /> +
diff --git a/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/types.ts b/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/types.ts index 1445a302..0d1325b7 100644 --- a/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/types.ts +++ b/skyvern-frontend/src/routes/workflows/editor/nodes/TextPromptNode/types.ts @@ -6,6 +6,7 @@ export type TextPromptNodeData = NodeBaseData & { jsonSchema: string; editable: boolean; label: string; + parameterKeys: Array; }; export type TextPromptNode = Node; @@ -16,6 +17,7 @@ export const textPromptNodeDefaultData: TextPromptNodeData = { prompt: "", jsonSchema: "null", continueOnFailure: false, + parameterKeys: [], } as const; export const helpTooltipContent = { diff --git a/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParametersPanel.tsx b/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParametersPanel.tsx index f3c25ab0..32826633 100644 --- a/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParametersPanel.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParametersPanel.tsx @@ -176,7 +176,10 @@ function WorkflowParametersPanel() { setHasChanges(true); setNodes((nodes) => { return nodes.map((node) => { - if (node.type === "task") { + if ( + node.type === "task" || + node.type === "textPrompt" + ) { return { ...node, data: { @@ -270,7 +273,10 @@ function WorkflowParametersPanel() { ); setNodes((nodes) => { return nodes.map((node) => { - if (node.type === "task") { + if ( + node.type === "task" || + node.type === "textPrompt" + ) { return { ...node, data: { diff --git a/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts b/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts index bab9bea5..d8384bba 100644 --- a/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts +++ b/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts @@ -201,6 +201,7 @@ function convertToNode( editable: true, prompt: block.prompt, jsonSchema: JSON.stringify(block.json_schema, null, 2), + parameterKeys: block.parameters.map((p) => p.key), }, }; } @@ -627,6 +628,7 @@ function getWorkflowBlock(node: WorkflowBlockNode): BlockYAML { llm_key: "", prompt: node.data.prompt, json_schema: JSONParseSafe(node.data.jsonSchema), + parameter_keys: node.data.parameterKeys, }; } default: { @@ -758,7 +760,7 @@ function getUpdatedNodesAfterLabelUpdateForParameterKeys( if (node.type === "nodeAdder" || node.type === "start") { return node; } - if (node.type === "task") { + if (node.type === "task" || node.type === "textPrompt") { return { ...node, data: {