diff --git a/web/service/workflow.ts b/web/service/workflow.ts index 10b5eac7cc5f29..ba5888d2cd6972 100644 --- a/web/service/workflow.ts +++ b/web/service/workflow.ts @@ -1,70 +1,77 @@ -import type { Fetcher } from 'swr' -import { get, post } from './base' -import type { CommonResponse } from '@/models/common' +import type {Fetcher} from 'swr' +import {get, post} from './base' +import type {CommonResponse} from '@/models/common' import { ChatRunHistoryResponse, - ConversationVariableResponse, FetchWorkflowDraftPageResponse, + ConversationVariableResponse, + FetchWorkflowDraftPageResponse, FetchWorkflowDraftResponse, NodesDefaultConfigsResponse, WorkflowRunHistoryResponse, } from '@/types/workflow' -import type { BlockEnum } from '@/app/components/workflow/types' +import type {BlockEnum} from '@/app/components/workflow/types' export const fetchWorkflowDraft = (url: string) => { - return get(url, {}, { silent: true }) as Promise + return get(url, {}, {silent: true}) as Promise } -export const syncWorkflowDraft = ({ url, params }: { url: string; params: Pick }) => { - return post(url, { body: params }, { silent: true }) +export const syncWorkflowDraft = ({url, params}: { + url: string; + params: Pick +}) => { + return post(url, {body: params}, {silent: true}) } export const fetchNodesDefaultConfigs: Fetcher = (url) => { - return get(url) + return get(url) } export const fetchWorkflowRunHistory: Fetcher = (url) => { - return get(url) + return get(url) } export const fetchChatRunHistory: Fetcher = (url) => { - return get(url) + return get(url) } export const singleNodeRun = (appId: string, nodeId: string, params: object) => { - return post(`apps/${appId}/workflows/draft/nodes/${nodeId}/run`, { body: params }) + return post(`apps/${appId}/workflows/draft/nodes/${nodeId}/run`, {body: params}) } export const getIterationSingleNodeRunUrl = (isChatFlow: boolean, appId: string, nodeId: string) => { - return `apps/${appId}/${isChatFlow ? 'advanced-chat/' : ''}workflows/draft/iteration/nodes/${nodeId}/run` + return `apps/${appId}/${isChatFlow ? 'advanced-chat/' : ''}workflows/draft/iteration/nodes/${nodeId}/run` } export const publishWorkflow = (url: string) => { - return post(url) + return post(url) } export const fetchPublishedWorkflow: Fetcher = (url) => { - return get(url) + return get(url) } export const fetchPublishedAllWorkflow: Fetcher = (url) => { - return get(url) + return get(url) } export const stopWorkflowRun = (url: string) => { - return post(url) + return post(url) } export const fetchNodeDefault = (appId: string, blockType: BlockEnum, query = {}) => { - return get(`apps/${appId}/workflows/default-workflow-block-configs/${blockType}`, { - params: { q: JSON.stringify(query) }, - }) + return get(`apps/${appId}/workflows/default-workflow-block-configs/${blockType}`, { + params: {q: JSON.stringify(query)}, + }) } // TODO: archived export const updateWorkflowDraftFromDSL = (appId: string, data: string) => { - return post(`apps/${appId}/workflows/draft/import`, { body: { data } }) + return post(`apps/${appId}/workflows/draft/import`, {body: {data}}) } -export const fetchCurrentValueOfConversationVariable: Fetcher = ({ url, params }) => { - return get(url, { params }) +export const fetchCurrentValueOfConversationVariable: Fetcher = ({url, params}) => { + return get(url, {params}) } diff --git a/web/types/workflow.ts b/web/types/workflow.ts index 74ba458c825ed6..2d82e5ced7aae8 100644 --- a/web/types/workflow.ts +++ b/web/types/workflow.ts @@ -1,85 +1,79 @@ -import type { Viewport } from 'reactflow' -import type { - BlockEnum, - ConversationVariable, - Edge, - EnvironmentVariable, - Node, -} from '@/app/components/workflow/types' -import type { TransferMethod } from '@/types/app' -import type { ErrorHandleTypeEnum } from '@/app/components/workflow/nodes/_base/components/error-handle/types' +import type {Viewport} from 'reactflow' +import type {BlockEnum, ConversationVariable, Edge, EnvironmentVariable, Node,} from '@/app/components/workflow/types' +import type {TransferMethod} from '@/types/app' +import type {ErrorHandleTypeEnum} from '@/app/components/workflow/nodes/_base/components/error-handle/types' export type NodeTracing = { - id: string - index: number - predecessor_node_id: string - node_id: string - node_type: BlockEnum - title: string - inputs: any - process_data: any - outputs?: any - status: string - parallel_run_id?: string - error?: string - elapsed_time: number - execution_metadata?: { - total_tokens: number - total_price: number - currency: string - iteration_id?: string - iteration_index?: number + id: string + index: number + predecessor_node_id: string + node_id: string + node_type: BlockEnum + title: string + inputs: any + process_data: any + outputs?: any + status: string + parallel_run_id?: string + error?: string + elapsed_time: number + execution_metadata?: { + total_tokens: number + total_price: number + currency: string + iteration_id?: string + iteration_index?: number + parallel_id?: string + parallel_start_node_id?: string + parent_parallel_id?: string + parent_parallel_start_node_id?: string + parallel_mode_run_id?: string + iteration_duration_map?: IterationDurationMap + error_strategy?: ErrorHandleTypeEnum + } + metadata: { + iterator_length: number + iterator_index: number + } + created_at: number + created_by: { + id: string + name: string + email: string + } + iterDurationMap?: IterationDurationMap + finished_at: number + extras?: any + expand?: boolean // for UI + details?: NodeTracing[][] // iteration detail + retryDetail?: NodeTracing[] // retry detail parallel_id?: string parallel_start_node_id?: string parent_parallel_id?: string parent_parallel_start_node_id?: string - parallel_mode_run_id?: string - iteration_duration_map?: IterationDurationMap - error_strategy?: ErrorHandleTypeEnum - } - metadata: { - iterator_length: number - iterator_index: number - } - created_at: number - created_by: { - id: string - name: string - email: string - } - iterDurationMap?: IterationDurationMap - finished_at: number - extras?: any - expand?: boolean // for UI - details?: NodeTracing[][] // iteration detail - retryDetail?: NodeTracing[] // retry detail - parallel_id?: string - parallel_start_node_id?: string - parent_parallel_id?: string - parent_parallel_start_node_id?: string - retry_index?: number + retry_index?: number } export type FetchWorkflowDraftResponse = { - id: string - graph: { - nodes: Node[] - edges: Edge[] - viewport?: Viewport - } - features?: any - created_at: number - created_by: { id: string - name: string - email: string - } - hash: string - updated_at: number - tool_published: boolean - environment_variables?: EnvironmentVariable[] - conversation_variables?: ConversationVariable[] - version: string + graph: { + nodes: Node[] + edges: Edge[] + viewport?: Viewport + } + features?: any + created_at: number + created_by: { + id: string + name: string + email: string + } + hash: string + updated_at: number + tool_published: boolean + environment_variables?: EnvironmentVariable[] + conversation_variables?: ConversationVariable[] + version: string } export type VersionHistory = FetchWorkflowDraftResponse @@ -91,261 +85,261 @@ export type FetchWorkflowDraftPageResponse = { } export type NodeTracingListResponse = { - data: NodeTracing[] + data: NodeTracing[] } export type WorkflowStartedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - workflow_id: string - sequence_number: number - created_at: number - } + task_id: string + workflow_run_id: string + event: string + data: { + id: string + workflow_id: string + sequence_number: number + created_at: number + } } export type WorkflowFinishedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - workflow_id: string - status: string - outputs: any - error: string - elapsed_time: number - total_tokens: number - total_steps: number - created_at: number - created_by: { - id: string - name: string - email: string + task_id: string + workflow_run_id: string + event: string + data: { + id: string + workflow_id: string + status: string + outputs: any + error: string + elapsed_time: number + total_tokens: number + total_steps: number + created_at: number + created_by: { + id: string + name: string + email: string + } + finished_at: number + files?: FileResponse[] } - finished_at: number - files?: FileResponse[] - } } export type NodeStartedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - node_id: string - iteration_id?: string - parallel_run_id?: string - node_type: string - index: number - predecessor_node_id?: string - inputs: any - created_at: number - extras?: any - } + task_id: string + workflow_run_id: string + event: string + data: { + id: string + node_id: string + iteration_id?: string + parallel_run_id?: string + node_type: string + index: number + predecessor_node_id?: string + inputs: any + created_at: number + extras?: any + } } export type FileResponse = { - related_id: string - extension: string - filename: string - size: number - mime_type: string - transfer_method: TransferMethod - type: string - url: string + related_id: string + extension: string + filename: string + size: number + mime_type: string + transfer_method: TransferMethod + type: string + url: string } export type NodeFinishedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - node_id: string - iteration_id?: string - node_type: string - index: number - predecessor_node_id?: string - inputs: any - process_data: any - outputs: any - status: string - error: string - elapsed_time: number - execution_metadata: { - total_tokens: number - total_price: number - currency: string - parallel_id?: string - parallel_start_node_id?: string - iteration_index?: number - iteration_id?: string - parallel_mode_run_id: string - error_strategy?: ErrorHandleTypeEnum + task_id: string + workflow_run_id: string + event: string + data: { + id: string + node_id: string + iteration_id?: string + node_type: string + index: number + predecessor_node_id?: string + inputs: any + process_data: any + outputs: any + status: string + error: string + elapsed_time: number + execution_metadata: { + total_tokens: number + total_price: number + currency: string + parallel_id?: string + parallel_start_node_id?: string + iteration_index?: number + iteration_id?: string + parallel_mode_run_id: string + error_strategy?: ErrorHandleTypeEnum + } + created_at: number + files?: FileResponse[] + retry_index?: number } - created_at: number - files?: FileResponse[] - retry_index?: number - } } export type IterationStartedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - node_id: string - metadata: { - iterator_length: number - iteration_id: string - iteration_index: number + task_id: string + workflow_run_id: string + event: string + data: { + id: string + node_id: string + metadata: { + iterator_length: number + iteration_id: string + iteration_index: number + } + created_at: number + extras?: any } - created_at: number - extras?: any - } } export type IterationNextResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - node_id: string - index: number - output: any - extras?: any - created_at: number - parallel_mode_run_id: string - execution_metadata: { - parallel_id?: string - iteration_index: number - parallel_mode_run_id?: string + task_id: string + workflow_run_id: string + event: string + data: { + id: string + node_id: string + index: number + output: any + extras?: any + created_at: number + parallel_mode_run_id: string + execution_metadata: { + parallel_id?: string + iteration_index: number + parallel_mode_run_id?: string + } + duration?: number } - duration?: number - } } export type IterationFinishedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - id: string - node_id: string - outputs: any - extras?: any - status: string - created_at: number - error: string - execution_metadata: { - parallel_id?: string + task_id: string + workflow_run_id: string + event: string + data: { + id: string + node_id: string + outputs: any + extras?: any + status: string + created_at: number + error: string + execution_metadata: { + parallel_id?: string + } } - } } export type ParallelBranchStartedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - parallel_id: string - parallel_start_node_id: string - parent_parallel_id: string - parent_parallel_start_node_id: string - iteration_id?: string - created_at: number - } + task_id: string + workflow_run_id: string + event: string + data: { + parallel_id: string + parallel_start_node_id: string + parent_parallel_id: string + parent_parallel_start_node_id: string + iteration_id?: string + created_at: number + } } export type ParallelBranchFinishedResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - parallel_id: string - parallel_start_node_id: string - parent_parallel_id: string - parent_parallel_start_node_id: string - iteration_id?: string - status: string - created_at: number - error: string - } + task_id: string + workflow_run_id: string + event: string + data: { + parallel_id: string + parallel_start_node_id: string + parent_parallel_id: string + parent_parallel_start_node_id: string + iteration_id?: string + status: string + created_at: number + error: string + } } export type TextChunkResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - text: string - } + task_id: string + workflow_run_id: string + event: string + data: { + text: string + } } export type TextReplaceResponse = { - task_id: string - workflow_run_id: string - event: string - data: { - text: string - } + task_id: string + workflow_run_id: string + event: string + data: { + text: string + } } export type WorkflowRunHistory = { - id: string - sequence_number: number - version: string - conversation_id?: string - message_id?: string - graph: { - nodes: Node[] - edges: Edge[] - viewport?: Viewport - } - inputs: Record - status: string - outputs: Record - error?: string - elapsed_time: number - total_tokens: number - total_steps: number - created_at: number - finished_at: number - created_by_account: { id: string - name: string - email: string - } + sequence_number: number + version: string + conversation_id?: string + message_id?: string + graph: { + nodes: Node[] + edges: Edge[] + viewport?: Viewport + } + inputs: Record + status: string + outputs: Record + error?: string + elapsed_time: number + total_tokens: number + total_steps: number + created_at: number + finished_at: number + created_by_account: { + id: string + name: string + email: string + } } export type WorkflowRunHistoryResponse = { - data: WorkflowRunHistory[] + data: WorkflowRunHistory[] } export type ChatRunHistoryResponse = { - data: WorkflowRunHistory[] + data: WorkflowRunHistory[] } export type NodesDefaultConfigsResponse = { - type: string - config: any + type: string + config: any }[] export type ConversationVariableResponse = { - data: (ConversationVariable & { updated_at: number; created_at: number })[] - has_more: boolean - limit: number - total: number - page: number + data: (ConversationVariable & { updated_at: number; created_at: number })[] + has_more: boolean + limit: number + total: number + page: number } export type IterationDurationMap = Record export type WorkflowConfigResponse = { - parallel_depth_limit: number + parallel_depth_limit: number } diff --git a/web/utils/var.ts b/web/utils/var.ts index 236c9debac6b31..6adc06d71e1974 100644 --- a/web/utils/var.ts +++ b/web/utils/var.ts @@ -1,101 +1,106 @@ -import { MAX_VAR_KEY_LENGTH, VAR_ITEM_TEMPLATE, VAR_ITEM_TEMPLATE_IN_WORKFLOW, getMaxVarNameLength } from '@/config' -import { CONTEXT_PLACEHOLDER_TEXT, HISTORY_PLACEHOLDER_TEXT, PRE_PROMPT_PLACEHOLDER_TEXT, QUERY_PLACEHOLDER_TEXT } from '@/app/components/base/prompt-editor/constants' -import { InputVarType } from '@/app/components/workflow/types' +import {getMaxVarNameLength, MAX_VAR_KEY_LENGTH, VAR_ITEM_TEMPLATE, VAR_ITEM_TEMPLATE_IN_WORKFLOW} from '@/config' +import { + CONTEXT_PLACEHOLDER_TEXT, + HISTORY_PLACEHOLDER_TEXT, + PRE_PROMPT_PLACEHOLDER_TEXT, + QUERY_PLACEHOLDER_TEXT +} from '@/app/components/base/prompt-editor/constants' +import {InputVarType} from '@/app/components/workflow/types' const otherAllowedRegex = /^[a-zA-Z0-9_]+$/ export const getNewVar = (key: string, type: string) => { - const { max_length, ...rest } = VAR_ITEM_TEMPLATE - if (type !== 'string') { + const {max_length, ...rest} = VAR_ITEM_TEMPLATE + if (type !== 'string') { + return { + ...rest, + type: type || 'string', + key, + name: key.slice(0, getMaxVarNameLength(key)), + } + } return { - ...rest, - type: type || 'string', - key, - name: key.slice(0, getMaxVarNameLength(key)), + ...VAR_ITEM_TEMPLATE, + type: type || 'string', + key, + name: key.slice(0, getMaxVarNameLength(key)), } - } - return { - ...VAR_ITEM_TEMPLATE, - type: type || 'string', - key, - name: key.slice(0, getMaxVarNameLength(key)), - } } export const getNewVarInWorkflow = (key: string, type = InputVarType.textInput) => { - const { max_length, ...rest } = VAR_ITEM_TEMPLATE_IN_WORKFLOW - if (type !== InputVarType.textInput) { + const {max_length, ...rest} = VAR_ITEM_TEMPLATE_IN_WORKFLOW + if (type !== InputVarType.textInput) { + return { + ...rest, + type, + variable: key, + label: key.slice(0, getMaxVarNameLength(key)), + } + } return { - ...rest, - type, - variable: key, - label: key.slice(0, getMaxVarNameLength(key)), + ...VAR_ITEM_TEMPLATE_IN_WORKFLOW, + type, + variable: key, + label: key.slice(0, getMaxVarNameLength(key)), } - } - return { - ...VAR_ITEM_TEMPLATE_IN_WORKFLOW, - type, - variable: key, - label: key.slice(0, getMaxVarNameLength(key)), - } } export const checkKey = (key: string, canBeEmpty?: boolean) => { - if (key.length === 0 && !canBeEmpty) - return 'canNoBeEmpty' + if (key.length === 0 && !canBeEmpty) + return 'canNoBeEmpty' - if (canBeEmpty && key === '') - return true + if (canBeEmpty && key === '') + return true - if (key.length > MAX_VAR_KEY_LENGTH) - return 'tooLong' + if (key.length > MAX_VAR_KEY_LENGTH) + return 'tooLong' - if (otherAllowedRegex.test(key)) { - if (/[0-9]/.test(key[0])) - return 'notStartWithNumber' + if (otherAllowedRegex.test(key)) { + if (/[0-9]/.test(key[0])) + return 'notStartWithNumber' - return true - } - return 'notValid' + return true + } + return 'notValid' } export const checkKeys = (keys: string[], canBeEmpty?: boolean) => { - let isValid = true - let errorKey = '' - let errorMessageKey = '' - keys.forEach((key) => { - if (!isValid) - return + let isValid = true + let errorKey = '' + let errorMessageKey = '' + keys.forEach((key) => { + if (!isValid) + return - const res = checkKey(key, canBeEmpty) - if (res !== true) { - isValid = false - errorKey = key - errorMessageKey = res - } - }) - return { isValid, errorKey, errorMessageKey } + const res = checkKey(key, canBeEmpty) + if (res !== true) { + isValid = false + errorKey = key + errorMessageKey = res + } + }) + return {isValid, errorKey, errorMessageKey} } const varRegex = /\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g export const getVars = (value: string) => { - if (!value) - return [] + if (!value) + return [] - const keys = value.match(varRegex)?.filter((item) => { - return ![CONTEXT_PLACEHOLDER_TEXT, HISTORY_PLACEHOLDER_TEXT, QUERY_PLACEHOLDER_TEXT, PRE_PROMPT_PLACEHOLDER_TEXT].includes(item) - }).map((item) => { - return item.replace('{{', '').replace('}}', '') - }).filter(key => key.length <= MAX_VAR_KEY_LENGTH) || [] - const keyObj: Record = {} - // remove duplicate keys - const res: string[] = [] - keys.forEach((key) => { - if (keyObj[key]) - return + const keys = value.match(varRegex)?.filter((item) => { + return ![CONTEXT_PLACEHOLDER_TEXT, HISTORY_PLACEHOLDER_TEXT, QUERY_PLACEHOLDER_TEXT, PRE_PROMPT_PLACEHOLDER_TEXT].includes(item) + }).map((item) => { + return item.replace('{{', '').replace('}}', '') + }).filter(key => key.length <= MAX_VAR_KEY_LENGTH) || [] + const keyObj: Record = {} + // remove duplicate keys + const res: string[] = [] + keys.forEach((key) => { + if (keyObj[key]) + return - keyObj[key] = true - res.push(key) - }) - return res + keyObj[key] = true + res.push(key) + }) + return res }