fix(prompt-editor): show error warning for destructive env and conv var (#21802)
This commit is contained in:
@@ -32,12 +32,14 @@ import Tooltip from '@/app/components/base/tooltip'
|
|||||||
import { isExceptionVariable } from '@/app/components/workflow/utils'
|
import { isExceptionVariable } from '@/app/components/workflow/utils'
|
||||||
import VarFullPathPanel from '@/app/components/workflow/nodes/_base/components/variable/var-full-path-panel'
|
import VarFullPathPanel from '@/app/components/workflow/nodes/_base/components/variable/var-full-path-panel'
|
||||||
import { Type } from '@/app/components/workflow/nodes/llm/types'
|
import { Type } from '@/app/components/workflow/nodes/llm/types'
|
||||||
import type { ValueSelector } from '@/app/components/workflow/types'
|
import type { ValueSelector, Var } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
type WorkflowVariableBlockComponentProps = {
|
type WorkflowVariableBlockComponentProps = {
|
||||||
nodeKey: string
|
nodeKey: string
|
||||||
variables: string[]
|
variables: string[]
|
||||||
workflowNodesMap: WorkflowNodesMap
|
workflowNodesMap: WorkflowNodesMap
|
||||||
|
environmentVariables?: Var[]
|
||||||
|
conversationVariables?: Var[]
|
||||||
getVarType?: (payload: {
|
getVarType?: (payload: {
|
||||||
nodeId: string,
|
nodeId: string,
|
||||||
valueSelector: ValueSelector,
|
valueSelector: ValueSelector,
|
||||||
@@ -49,6 +51,8 @@ const WorkflowVariableBlockComponent = ({
|
|||||||
variables,
|
variables,
|
||||||
workflowNodesMap = {},
|
workflowNodesMap = {},
|
||||||
getVarType,
|
getVarType,
|
||||||
|
environmentVariables,
|
||||||
|
conversationVariables,
|
||||||
}: WorkflowVariableBlockComponentProps) => {
|
}: WorkflowVariableBlockComponentProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [editor] = useLexicalComposerContext()
|
const [editor] = useLexicalComposerContext()
|
||||||
@@ -68,6 +72,19 @@ const WorkflowVariableBlockComponent = ({
|
|||||||
const isChatVar = isConversationVar(variables)
|
const isChatVar = isConversationVar(variables)
|
||||||
const isException = isExceptionVariable(varName, node?.type)
|
const isException = isExceptionVariable(varName, node?.type)
|
||||||
|
|
||||||
|
let variableValid = true
|
||||||
|
if (isEnv) {
|
||||||
|
if (environmentVariables)
|
||||||
|
variableValid = environmentVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}`)
|
||||||
|
}
|
||||||
|
else if (isChatVar) {
|
||||||
|
if (conversationVariables)
|
||||||
|
variableValid = conversationVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
variableValid = !!node
|
||||||
|
}
|
||||||
|
|
||||||
const reactflow = useReactFlow()
|
const reactflow = useReactFlow()
|
||||||
const store = useStoreApi()
|
const store = useStoreApi()
|
||||||
|
|
||||||
@@ -113,7 +130,7 @@ const WorkflowVariableBlockComponent = ({
|
|||||||
className={cn(
|
className={cn(
|
||||||
'group/wrap relative mx-0.5 flex h-[18px] select-none items-center rounded-[5px] border pl-0.5 pr-[3px] hover:border-state-accent-solid hover:bg-state-accent-hover',
|
'group/wrap relative mx-0.5 flex h-[18px] select-none items-center rounded-[5px] border pl-0.5 pr-[3px] hover:border-state-accent-solid hover:bg-state-accent-hover',
|
||||||
isSelected ? ' border-state-accent-solid bg-state-accent-hover' : ' border-components-panel-border-subtle bg-components-badge-white-to-dark',
|
isSelected ? ' border-state-accent-solid bg-state-accent-hover' : ' border-components-panel-border-subtle bg-components-badge-white-to-dark',
|
||||||
!node && !isEnv && !isChatVar && '!border-state-destructive-solid !bg-state-destructive-hover',
|
!variableValid && '!border-state-destructive-solid !bg-state-destructive-hover',
|
||||||
)}
|
)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@@ -156,7 +173,7 @@ const WorkflowVariableBlockComponent = ({
|
|||||||
isException && 'text-text-warning',
|
isException && 'text-text-warning',
|
||||||
)} title={varName}>{varName}</div>
|
)} title={varName}>{varName}</div>
|
||||||
{
|
{
|
||||||
!node && !isEnv && !isChatVar && (
|
!variableValid && (
|
||||||
<RiErrorWarningFill className='ml-0.5 h-3 w-3 text-text-destructive' />
|
<RiErrorWarningFill className='ml-0.5 h-3 w-3 text-text-destructive' />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -164,7 +181,7 @@ const WorkflowVariableBlockComponent = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!node && !isEnv && !isChatVar) {
|
if (!variableValid) {
|
||||||
return (
|
return (
|
||||||
<Tooltip popupContent={t('workflow.errorMsg.invalidVariable')}>
|
<Tooltip popupContent={t('workflow.errorMsg.invalidVariable')}>
|
||||||
{Item}
|
{Item}
|
||||||
|
@@ -3,6 +3,7 @@ import { DecoratorNode } from 'lexical'
|
|||||||
import type { WorkflowVariableBlockType } from '../../types'
|
import type { WorkflowVariableBlockType } from '../../types'
|
||||||
import WorkflowVariableBlockComponent from './component'
|
import WorkflowVariableBlockComponent from './component'
|
||||||
import type { GetVarType } from '../../types'
|
import type { GetVarType } from '../../types'
|
||||||
|
import type { Var } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
export type WorkflowNodesMap = WorkflowVariableBlockType['workflowNodesMap']
|
export type WorkflowNodesMap = WorkflowVariableBlockType['workflowNodesMap']
|
||||||
|
|
||||||
@@ -10,31 +11,37 @@ export type SerializedNode = SerializedLexicalNode & {
|
|||||||
variables: string[]
|
variables: string[]
|
||||||
workflowNodesMap: WorkflowNodesMap
|
workflowNodesMap: WorkflowNodesMap
|
||||||
getVarType?: GetVarType
|
getVarType?: GetVarType
|
||||||
|
environmentVariables?: Var[]
|
||||||
|
conversationVariables?: Var[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WorkflowVariableBlockNode extends DecoratorNode<React.JSX.Element> {
|
export class WorkflowVariableBlockNode extends DecoratorNode<React.JSX.Element> {
|
||||||
__variables: string[]
|
__variables: string[]
|
||||||
__workflowNodesMap: WorkflowNodesMap
|
__workflowNodesMap: WorkflowNodesMap
|
||||||
__getVarType?: GetVarType
|
__getVarType?: GetVarType
|
||||||
|
__environmentVariables?: Var[]
|
||||||
|
__conversationVariables?: Var[]
|
||||||
|
|
||||||
static getType(): string {
|
static getType(): string {
|
||||||
return 'workflow-variable-block'
|
return 'workflow-variable-block'
|
||||||
}
|
}
|
||||||
|
|
||||||
static clone(node: WorkflowVariableBlockNode): WorkflowVariableBlockNode {
|
static clone(node: WorkflowVariableBlockNode): WorkflowVariableBlockNode {
|
||||||
return new WorkflowVariableBlockNode(node.__variables, node.__workflowNodesMap, node.__getVarType, node.__key)
|
return new WorkflowVariableBlockNode(node.__variables, node.__workflowNodesMap, node.__getVarType, node.__key, node.__environmentVariables, node.__conversationVariables)
|
||||||
}
|
}
|
||||||
|
|
||||||
isInline(): boolean {
|
isInline(): boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(variables: string[], workflowNodesMap: WorkflowNodesMap, getVarType: any, key?: NodeKey) {
|
constructor(variables: string[], workflowNodesMap: WorkflowNodesMap, getVarType: any, key?: NodeKey, environmentVariables?: Var[], conversationVariables?: Var[]) {
|
||||||
super(key)
|
super(key)
|
||||||
|
|
||||||
this.__variables = variables
|
this.__variables = variables
|
||||||
this.__workflowNodesMap = workflowNodesMap
|
this.__workflowNodesMap = workflowNodesMap
|
||||||
this.__getVarType = getVarType
|
this.__getVarType = getVarType
|
||||||
|
this.__environmentVariables = environmentVariables
|
||||||
|
this.__conversationVariables = conversationVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
createDOM(): HTMLElement {
|
createDOM(): HTMLElement {
|
||||||
@@ -54,12 +61,14 @@ export class WorkflowVariableBlockNode extends DecoratorNode<React.JSX.Element>
|
|||||||
variables={this.__variables}
|
variables={this.__variables}
|
||||||
workflowNodesMap={this.__workflowNodesMap}
|
workflowNodesMap={this.__workflowNodesMap}
|
||||||
getVarType={this.__getVarType!}
|
getVarType={this.__getVarType!}
|
||||||
|
environmentVariables={this.__environmentVariables}
|
||||||
|
conversationVariables={this.__conversationVariables}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static importJSON(serializedNode: SerializedNode): WorkflowVariableBlockNode {
|
static importJSON(serializedNode: SerializedNode): WorkflowVariableBlockNode {
|
||||||
const node = $createWorkflowVariableBlockNode(serializedNode.variables, serializedNode.workflowNodesMap, serializedNode.getVarType)
|
const node = $createWorkflowVariableBlockNode(serializedNode.variables, serializedNode.workflowNodesMap, serializedNode.getVarType, serializedNode.environmentVariables, serializedNode.conversationVariables)
|
||||||
|
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
@@ -71,6 +80,8 @@ export class WorkflowVariableBlockNode extends DecoratorNode<React.JSX.Element>
|
|||||||
variables: this.getVariables(),
|
variables: this.getVariables(),
|
||||||
workflowNodesMap: this.getWorkflowNodesMap(),
|
workflowNodesMap: this.getWorkflowNodesMap(),
|
||||||
getVarType: this.getVarType(),
|
getVarType: this.getVarType(),
|
||||||
|
environmentVariables: this.getEnvironmentVariables(),
|
||||||
|
conversationVariables: this.getConversationVariables(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,12 +100,22 @@ export class WorkflowVariableBlockNode extends DecoratorNode<React.JSX.Element>
|
|||||||
return self.__getVarType
|
return self.__getVarType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEnvironmentVariables(): any {
|
||||||
|
const self = this.getLatest()
|
||||||
|
return self.__environmentVariables
|
||||||
|
}
|
||||||
|
|
||||||
|
getConversationVariables(): any {
|
||||||
|
const self = this.getLatest()
|
||||||
|
return self.__conversationVariables
|
||||||
|
}
|
||||||
|
|
||||||
getTextContent(): string {
|
getTextContent(): string {
|
||||||
return `{{#${this.getVariables().join('.')}#}}`
|
return `{{#${this.getVariables().join('.')}#}}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function $createWorkflowVariableBlockNode(variables: string[], workflowNodesMap: WorkflowNodesMap, getVarType?: GetVarType): WorkflowVariableBlockNode {
|
export function $createWorkflowVariableBlockNode(variables: string[], workflowNodesMap: WorkflowNodesMap, getVarType?: GetVarType, environmentVariables?: Var[], conversationVariables?: Var[]): WorkflowVariableBlockNode {
|
||||||
return new WorkflowVariableBlockNode(variables, workflowNodesMap, getVarType)
|
return new WorkflowVariableBlockNode(variables, workflowNodesMap, getVarType, undefined, environmentVariables, conversationVariables)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function $isWorkflowVariableBlockNode(
|
export function $isWorkflowVariableBlockNode(
|
||||||
|
@@ -18,6 +18,7 @@ const WorkflowVariableBlockReplacementBlock = ({
|
|||||||
workflowNodesMap,
|
workflowNodesMap,
|
||||||
getVarType,
|
getVarType,
|
||||||
onInsert,
|
onInsert,
|
||||||
|
variables,
|
||||||
}: WorkflowVariableBlockType) => {
|
}: WorkflowVariableBlockType) => {
|
||||||
const [editor] = useLexicalComposerContext()
|
const [editor] = useLexicalComposerContext()
|
||||||
|
|
||||||
@@ -31,8 +32,8 @@ const WorkflowVariableBlockReplacementBlock = ({
|
|||||||
onInsert()
|
onInsert()
|
||||||
|
|
||||||
const nodePathString = textNode.getTextContent().slice(3, -3)
|
const nodePathString = textNode.getTextContent().slice(3, -3)
|
||||||
return $applyNodeReplacement($createWorkflowVariableBlockNode(nodePathString.split('.'), workflowNodesMap, getVarType))
|
return $applyNodeReplacement($createWorkflowVariableBlockNode(nodePathString.split('.'), workflowNodesMap, getVarType, variables?.find(o => o.nodeId === 'env')?.vars || [], variables?.find(o => o.nodeId === 'conversation')?.vars || []))
|
||||||
}, [onInsert, workflowNodesMap, getVarType])
|
}, [onInsert, workflowNodesMap, getVarType, variables])
|
||||||
|
|
||||||
const getMatch = useCallback((text: string) => {
|
const getMatch = useCallback((text: string) => {
|
||||||
const matchArr = REGEX.exec(text)
|
const matchArr = REGEX.exec(text)
|
||||||
|
Reference in New Issue
Block a user