diff --git a/web/app/components/workflow/constants.ts b/web/app/components/workflow/constants.ts index 722a2ac303..bc652a22b3 100644 --- a/web/app/components/workflow/constants.ts +++ b/web/app/components/workflow/constants.ts @@ -1,4 +1,5 @@ -import { BlockEnum } from './types' +import type { Var } from './types' +import { BlockEnum, VarType } from './types' import StartNodeDefault from './nodes/start/default' import DirectAnswerDefault from './nodes/direct-answer/default' import LLMDefault from './nodes/llm/default' @@ -178,3 +179,73 @@ export const RETRIEVAL_OUTPUT_STRUCT = `{ "score": "" } }` + +export const SUPPORT_OUTPUT_VARS_NODE = [ + BlockEnum.Start, BlockEnum.LLM, BlockEnum.KnowledgeRetrieval, BlockEnum.Code, BlockEnum.TemplateTransform, + BlockEnum.QuestionClassifier, BlockEnum.HttpRequest, BlockEnum.Tool, BlockEnum.VariableAssigner, +] + +export const LLM_OUTPUT_STRUCT: Var[] = [ + { + variable: 'text', + type: VarType.string, + }, + { + variable: 'usage', + type: VarType.object, + children: [ + { + variable: 'prompt_tokens', + type: VarType.number, + }, + { + variable: 'prompt_unit_price', + type: VarType.number, + }, + { + variable: 'prompt_price_unit', + type: VarType.number, + }, + { + variable: 'prompt_price', + type: VarType.number, + }, + { + variable: 'completion_tokens', + type: VarType.number, + }, + { + variable: 'completion_unit_price', + type: VarType.number, + }, + { + variable: 'completion_price_unit', + type: VarType.number, + }, + { + variable: 'completion_unit_price', + type: VarType.number, + }, + { + variable: 'completion_price', + type: VarType.number, + }, + { + variable: 'total_tokens', + type: VarType.number, + }, + { + variable: 'total_price', + type: VarType.number, + }, + { + variable: 'currency', + type: VarType.string, + }, + { + variable: 'latency', + type: VarType.number, + }, + ], + }, +] diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index 4c17865011..c449d38964 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -1,6 +1,14 @@ -import { BlockEnum } from '@/app/components/workflow/types' +import { BlockEnum, InputVarType, VarType } from '@/app/components/workflow/types' import type { StartNodeType } from '@/app/components/workflow/nodes/start/types' import type { NodeOutPutVar } from '@/app/components/workflow/types' +import { LLM_OUTPUT_STRUCT, SUPPORT_OUTPUT_VARS_NODE } from '@/app/components/workflow/constants' + +const inputVarTypeToVarType = (type: InputVarType): VarType => { + if (type === InputVarType.number) + return VarType.number + + return VarType.string +} const formatItem = (item: any): NodeOutPutVar => { const { id, data } = item @@ -17,19 +25,20 @@ const formatItem = (item: any): NodeOutPutVar => { res.vars = variables.map((v) => { return { variable: v.variable, - type: v.type, + type: inputVarTypeToVarType(v.type), } }) break } - // default: - // // throw new Error('unknown type') - // break + case BlockEnum.LLM: { + res.vars = LLM_OUTPUT_STRUCT + break + } } return res } export const toNodeOutputVars = (nodes: any[]): NodeOutPutVar[] => { - return nodes.map(formatItem) + return nodes.filter(node => SUPPORT_OUTPUT_VARS_NODE.includes(node.data.type)).map(formatItem) } diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx index 46c1ff0bd9..eb309847a7 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx @@ -5,6 +5,7 @@ import cn from 'classnames' import VarReferencePopup from './var-reference-popup' import { toNodeOutputVars } from './utils' import type { ValueSelector } from '@/app/components/workflow/types' +import { VarType } from '@/app/components/workflow/types' import { VarBlockIcon } from '@/app/components/workflow/block-icon' import { Line3 } from '@/app/components/base/icons/src/public/common' import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' @@ -54,9 +55,26 @@ const VarReferencePicker: FC = ({ const outputVarNode = hasValue ? getNodeInfoById(availableNodes, outputVarNodeId)?.data : null // console.log(hasValue, value, outputVarNode) const varName = hasValue ? value[value.length - 1] : '' - // TODO: get var type through node and value + const getVarType = () => { - return 'string' + const targetVar = outputVars.find(v => v.nodeId === outputVarNodeId) + if (!targetVar) + return 'undefined' + + let type: VarType = VarType.string + let curr: any = targetVar.vars + value.slice(1).forEach((key, i) => { + const isLast = i === value.length - 2 + curr = curr.find((v: any) => v.variable === key) + if (isLast) { + type = curr.type + } + else { + if (curr.type === VarType.object) + curr = curr.children + } + }) + return type } return ( diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx index 497861cdeb..d698822fbe 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx @@ -3,7 +3,7 @@ import type { FC } from 'react' import React, { useRef } from 'react' import { useHover } from 'ahooks' import cn from 'classnames' -import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types' +import { type NodeOutPutVar, type ValueSelector, type Var, VarType } from '@/app/components/workflow/types' import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' @@ -30,7 +30,7 @@ const Item: FC = ({ itemData, onChange, }) => { - const isObj = itemData.type === 'object' + const isObj = itemData.type === VarType.object const itemRef = useRef(null) const isItemHovering = useHover(itemRef) const handleChosen = (e: React.MouseEvent) => { diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index 91b7e0c9a2..38dbf85780 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -118,9 +118,19 @@ export type Memory = { } } +export enum VarType { + string = 'String', + number = 'Number', + boolean = 'Boolean', + object = 'Object', + array = 'Array', + arrayString = 'Array[string]', + arrayNumber = 'Array[number]', +} + export type Var = { variable: string - type: string + type: VarType children?: Var[] // if type is obj, has the children struct }