Add continue on failure as passthrough and cache_actions property (#983)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type CodeBlockNodeData = {
|
||||
export type CodeBlockNodeData = NodeBaseData & {
|
||||
code: string;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type CodeBlockNode = Node<CodeBlockNodeData, "codeBlock">;
|
||||
@@ -12,4 +12,5 @@ export const codeBlockNodeDefaultData: CodeBlockNodeData = {
|
||||
editable: true,
|
||||
label: "",
|
||||
code: `# To assign a value to the output of this block,\n# assign the value to the variable 'result'\n# The final value of 'result' will be used as the output of this block\n\nresult = 5`,
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { SKYVERN_DOWNLOAD_DIRECTORY } from "../../constants";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type DownloadNodeData = {
|
||||
export type DownloadNodeData = NodeBaseData & {
|
||||
url: string;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type DownloadNode = Node<DownloadNodeData, "download">;
|
||||
@@ -13,6 +13,7 @@ export const downloadNodeDefaultData: DownloadNodeData = {
|
||||
editable: true,
|
||||
label: "",
|
||||
url: SKYVERN_DOWNLOAD_DIRECTORY,
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
export const helpTooltipContent = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type FileParserNodeData = {
|
||||
export type FileParserNodeData = NodeBaseData & {
|
||||
fileUrl: string;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type FileParserNode = Node<FileParserNodeData, "fileParser">;
|
||||
@@ -12,6 +12,7 @@ export const fileParserNodeDefaultData: FileParserNodeData = {
|
||||
editable: true,
|
||||
label: "",
|
||||
fileUrl: "",
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
export const helpTooltipContent = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type LoopNodeData = {
|
||||
export type LoopNodeData = NodeBaseData & {
|
||||
loopValue: string;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type LoopNode = Node<LoopNodeData, "loop">;
|
||||
@@ -12,6 +12,7 @@ export const loopNodeDefaultData: LoopNodeData = {
|
||||
editable: true,
|
||||
label: "",
|
||||
loopValue: "",
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
export function isLoopNode(node: Node): node is LoopNode {
|
||||
|
||||
@@ -7,14 +7,14 @@ import {
|
||||
SMTP_PORT_PARAMETER_KEY,
|
||||
SMTP_USERNAME_PARAMETER_KEY,
|
||||
} from "../../constants";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type SendEmailNodeData = {
|
||||
export type SendEmailNodeData = NodeBaseData & {
|
||||
recipients: string;
|
||||
subject: string;
|
||||
body: string;
|
||||
fileAttachments: string;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
sender: string;
|
||||
smtpHostSecretParameterKey?: string;
|
||||
smtpPortSecretParameterKey?: string;
|
||||
@@ -36,6 +36,7 @@ export const sendEmailNodeDefaultData: SendEmailNodeData = {
|
||||
smtpPortSecretParameterKey: SMTP_PORT_PARAMETER_KEY,
|
||||
smtpUsernameSecretParameterKey: SMTP_USERNAME_PARAMETER_KEY,
|
||||
smtpPasswordSecretParameterKey: SMTP_PASSWORD_PARAMETER_KEY,
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
export const helpTooltipContent = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type TaskNodeData = {
|
||||
export type TaskNodeData = NodeBaseData & {
|
||||
url: string;
|
||||
navigationGoal: string;
|
||||
dataExtractionGoal: string;
|
||||
@@ -11,11 +12,10 @@ export type TaskNodeData = {
|
||||
allowDownloads: boolean;
|
||||
downloadSuffix: string | null;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
parameterKeys: Array<string>;
|
||||
totpVerificationUrl: string | null;
|
||||
totpIdentifier: string | null;
|
||||
continueOnFailure: boolean;
|
||||
cacheActions: boolean;
|
||||
};
|
||||
|
||||
export type TaskNode = Node<TaskNodeData, "task">;
|
||||
@@ -38,6 +38,7 @@ export const taskNodeDefaultData: TaskNodeData = {
|
||||
totpVerificationUrl: null,
|
||||
totpIdentifier: null,
|
||||
continueOnFailure: false,
|
||||
cacheActions: false,
|
||||
} as const;
|
||||
|
||||
export function isTaskNode(node: Node): node is TaskNode {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type TextPromptNodeData = {
|
||||
export type TextPromptNodeData = NodeBaseData & {
|
||||
prompt: string;
|
||||
jsonSchema: string;
|
||||
editable: boolean;
|
||||
@@ -14,6 +15,7 @@ export const textPromptNodeDefaultData: TextPromptNodeData = {
|
||||
label: "",
|
||||
prompt: "",
|
||||
jsonSchema: "null",
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
export const helpTooltipContent = {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { SKYVERN_DOWNLOAD_DIRECTORY } from "../../constants";
|
||||
import { NodeBaseData } from "../types";
|
||||
|
||||
export type UploadNodeData = {
|
||||
export type UploadNodeData = NodeBaseData & {
|
||||
path: string;
|
||||
editable: boolean;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type UploadNode = Node<UploadNodeData, "upload">;
|
||||
@@ -13,6 +13,7 @@ export const uploadNodeDefaultData: UploadNodeData = {
|
||||
editable: true,
|
||||
label: "",
|
||||
path: SKYVERN_DOWNLOAD_DIRECTORY,
|
||||
continueOnFailure: false,
|
||||
} as const;
|
||||
|
||||
export const helpTooltipContent = {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export type NodeBaseData = {
|
||||
label: string;
|
||||
continueOnFailure: boolean;
|
||||
};
|
||||
@@ -1,7 +1,11 @@
|
||||
import Dagre from "@dagrejs/dagre";
|
||||
import type { Node } from "@xyflow/react";
|
||||
import { Edge } from "@xyflow/react";
|
||||
import { nanoid } from "nanoid";
|
||||
import type {
|
||||
AWSSecretParameter,
|
||||
BitwardenSensitiveInformationParameter,
|
||||
ContextParameter,
|
||||
OutputParameter,
|
||||
Parameter,
|
||||
WorkflowApiResponse,
|
||||
@@ -33,6 +37,7 @@ import {
|
||||
SMTP_USERNAME_AWS_KEY,
|
||||
SMTP_USERNAME_PARAMETER_KEY,
|
||||
} from "./constants";
|
||||
import { ParametersState } from "./FlowRenderer";
|
||||
import { AppNode, nodeTypes } from "./nodes";
|
||||
import { codeBlockNodeDefaultData } from "./nodes/CodeBlockNode/types";
|
||||
import { downloadNodeDefaultData } from "./nodes/DownloadNode/types";
|
||||
@@ -42,8 +47,8 @@ import { NodeAdderNode } from "./nodes/NodeAdderNode/types";
|
||||
import { sendEmailNodeDefaultData } from "./nodes/SendEmailNode/types";
|
||||
import { taskNodeDefaultData } from "./nodes/TaskNode/types";
|
||||
import { textPromptNodeDefaultData } from "./nodes/TextPromptNode/types";
|
||||
import { NodeBaseData } from "./nodes/types";
|
||||
import { uploadNodeDefaultData } from "./nodes/UploadNode/types";
|
||||
import type { Node } from "@xyflow/react";
|
||||
|
||||
export const NEW_NODE_LABEL_PREFIX = "block_";
|
||||
|
||||
@@ -126,6 +131,10 @@ function convertToNode(
|
||||
position: { x: 0, y: 0 },
|
||||
connectable: false,
|
||||
};
|
||||
const commonData: NodeBaseData = {
|
||||
label: block.label,
|
||||
continueOnFailure: block.continue_on_failure,
|
||||
};
|
||||
switch (block.block_type) {
|
||||
case "task": {
|
||||
return {
|
||||
@@ -133,7 +142,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "task",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
url: block.url ?? "",
|
||||
navigationGoal: block.navigation_goal ?? "",
|
||||
@@ -147,7 +156,7 @@ function convertToNode(
|
||||
parameterKeys: block.parameters.map((p) => p.key),
|
||||
totpIdentifier: block.totp_identifier ?? null,
|
||||
totpVerificationUrl: block.totp_verification_url ?? null,
|
||||
continueOnFailure: block.continue_on_failure,
|
||||
cacheActions: block.cache_actions,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -157,7 +166,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "codeBlock",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
code: block.code,
|
||||
},
|
||||
@@ -169,7 +178,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "sendEmail",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
body: block.body,
|
||||
fileAttachments: block.file_attachments.join(", "),
|
||||
@@ -189,7 +198,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "textPrompt",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
prompt: block.prompt,
|
||||
jsonSchema: JSON.stringify(block.json_schema, null, 2),
|
||||
@@ -202,7 +211,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "loop",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
loopValue: block.loop_over.key,
|
||||
},
|
||||
@@ -214,7 +223,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "fileParser",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
fileUrl: block.file_url,
|
||||
},
|
||||
@@ -227,7 +236,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "download",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
url: block.url,
|
||||
},
|
||||
@@ -240,7 +249,7 @@ function convertToNode(
|
||||
...common,
|
||||
type: "upload",
|
||||
data: {
|
||||
label: block.label,
|
||||
...commonData,
|
||||
editable: true,
|
||||
path: block.path,
|
||||
},
|
||||
@@ -497,11 +506,15 @@ function JSONParseSafe(json: string): Record<string, unknown> | null {
|
||||
function getWorkflowBlock(
|
||||
node: Exclude<AppNode, LoopNode | NodeAdderNode>,
|
||||
): BlockYAML {
|
||||
const base = {
|
||||
label: node.data.label,
|
||||
continue_on_failure: node.data.continueOnFailure,
|
||||
};
|
||||
switch (node.type) {
|
||||
case "task": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "task",
|
||||
label: node.data.label,
|
||||
url: node.data.url,
|
||||
navigation_goal: node.data.navigationGoal,
|
||||
data_extraction_goal: node.data.dataExtractionGoal,
|
||||
@@ -519,13 +532,13 @@ function getWorkflowBlock(
|
||||
parameter_keys: node.data.parameterKeys,
|
||||
totp_identifier: node.data.totpIdentifier,
|
||||
totp_verification_url: node.data.totpVerificationUrl,
|
||||
continue_on_failure: node.data.continueOnFailure,
|
||||
cache_actions: node.data.cacheActions,
|
||||
};
|
||||
}
|
||||
case "sendEmail": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "send_email",
|
||||
label: node.data.label,
|
||||
body: node.data.body,
|
||||
file_attachments: node.data.fileAttachments
|
||||
.split(",")
|
||||
@@ -545,37 +558,37 @@ function getWorkflowBlock(
|
||||
}
|
||||
case "codeBlock": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "code",
|
||||
label: node.data.label,
|
||||
code: node.data.code,
|
||||
};
|
||||
}
|
||||
case "download": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "download_to_s3",
|
||||
label: node.data.label,
|
||||
url: node.data.url,
|
||||
};
|
||||
}
|
||||
case "upload": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "upload_to_s3",
|
||||
label: node.data.label,
|
||||
path: node.data.path,
|
||||
};
|
||||
}
|
||||
case "fileParser": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "file_url_parser",
|
||||
label: node.data.label,
|
||||
file_url: node.data.fileUrl,
|
||||
file_type: "csv",
|
||||
};
|
||||
}
|
||||
case "textPrompt": {
|
||||
return {
|
||||
...base,
|
||||
block_type: "text_prompt",
|
||||
label: node.data.label,
|
||||
llm_key: "",
|
||||
prompt: node.data.prompt,
|
||||
json_schema: JSONParseSafe(node.data.jsonSchema),
|
||||
@@ -630,13 +643,6 @@ function generateNodeLabel(existingLabels: Array<string>) {
|
||||
throw new Error("Failed to generate a new node label");
|
||||
}
|
||||
|
||||
import type {
|
||||
AWSSecretParameter,
|
||||
BitwardenSensitiveInformationParameter,
|
||||
ContextParameter,
|
||||
} from "../types/workflowTypes";
|
||||
import { ParametersState } from "./FlowRenderer";
|
||||
|
||||
/**
|
||||
* If a parameter is not displayed in the editor, we should echo its value back when saved.
|
||||
*/
|
||||
@@ -980,6 +986,7 @@ function convertBlocks(blocks: Array<WorkflowBlock>): Array<BlockYAML> {
|
||||
parameter_keys: block.parameters.map((p) => p.key),
|
||||
totp_identifier: block.totp_identifier,
|
||||
totp_verification_url: block.totp_verification_url,
|
||||
cache_actions: block.cache_actions,
|
||||
};
|
||||
return blockYaml;
|
||||
}
|
||||
@@ -1076,22 +1083,22 @@ function convert(workflow: WorkflowApiResponse): WorkflowCreateYAMLRequest {
|
||||
}
|
||||
|
||||
export {
|
||||
convert,
|
||||
convertEchoParameters,
|
||||
createNode,
|
||||
generateNodeData,
|
||||
getElements,
|
||||
getWorkflowBlocks,
|
||||
layout,
|
||||
generateNodeLabel,
|
||||
convertEchoParameters,
|
||||
getOutputParameterKey,
|
||||
getUpdatedNodesAfterLabelUpdateForParameterKeys,
|
||||
getAdditionalParametersForEmailBlock,
|
||||
getUniqueLabelForExistingNode,
|
||||
isOutputParameterKey,
|
||||
getAvailableOutputParameterKeys,
|
||||
getBlockNameOfOutputParameterKey,
|
||||
getDefaultValueForParameterType,
|
||||
getUpdatedParametersAfterLabelUpdateForSourceParameterKey,
|
||||
getElements,
|
||||
getOutputParameterKey,
|
||||
getPreviousNodeIds,
|
||||
getAvailableOutputParameterKeys,
|
||||
convert,
|
||||
getUniqueLabelForExistingNode,
|
||||
getUpdatedNodesAfterLabelUpdateForParameterKeys,
|
||||
getUpdatedParametersAfterLabelUpdateForSourceParameterKey,
|
||||
getWorkflowBlocks,
|
||||
isOutputParameterKey,
|
||||
layout,
|
||||
};
|
||||
|
||||
@@ -137,6 +137,7 @@ export type TaskBlock = WorkflowBlockBase & {
|
||||
download_suffix?: string | null;
|
||||
totp_verification_url?: string | null;
|
||||
totp_identifier?: string | null;
|
||||
cache_actions: boolean;
|
||||
};
|
||||
|
||||
export type ForLoopBlock = WorkflowBlockBase & {
|
||||
|
||||
@@ -110,6 +110,7 @@ export type TaskBlockYAML = BlockYAMLBase & {
|
||||
download_suffix?: string | null;
|
||||
totp_verification_url?: string | null;
|
||||
totp_identifier?: string | null;
|
||||
cache_actions: boolean;
|
||||
};
|
||||
|
||||
export type CodeBlockYAML = BlockYAMLBase & {
|
||||
|
||||
Reference in New Issue
Block a user