= ({
)
}
{
- showAssembleVariables && onAssembleVariables && (
+ showAgentSection && (
+
+
+ {t('nodes.tool.agentPopupHeader', { ns: 'workflow' })}
+
+ {filteredAgentNodes.map((agent) => {
+ runningIndex += 1
+ const itemIndex = runningIndex
+ return (
+
+ )
+ })}
+
+ )
+ }
+ {
+ showAssembleEntry && (
)
- : {t('common.noVar', { ns: 'workflow' })}
}
+ : !showAgentSection && !showAssembleEntry && {t('common.noVar', { ns: 'workflow' })}
}
{
showManageInputField && (
void) => callback())
+const mockDispatchCommand = vi.fn()
+const mockInsertNodes = vi.fn()
+const mockTextNode = vi.fn()
+
+const mockEditor = {
+ update: mockEditorUpdate,
+ dispatchCommand: mockDispatchCommand,
+} as unknown as LexicalEditor
+
+const lexicalContextValue: LexicalComposerContextWithEditor = [
+ mockEditor,
+ { getTheme: () => undefined },
+]
+
+vi.mock('@lexical/react/LexicalComposerContext', () => ({
+ useLexicalComposerContext: vi.fn(),
+}))
+
+vi.mock('lexical', () => ({
+ $insertNodes: vi.fn(),
+ FOCUS_COMMAND: 'focus-command',
+}))
+
+vi.mock('@/app/components/base/prompt-editor/plugins/custom-text/node', () => ({
+ CustomTextNode: class MockCustomTextNode {
+ value: string
+
+ constructor(value: string) {
+ this.value = value
+ mockTextNode(value)
+ }
+ },
+}))
+
+describe('Tool mixed variable placeholder', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ vi.mocked(useLexicalComposerContext).mockReturnValue(lexicalContextValue)
+ vi.mocked($insertNodes).mockImplementation(nodes => mockInsertNodes(nodes))
+ })
+
+ it('should insert an empty text node and focus the editor when the placeholder background is clicked', () => {
+ const parentClick = vi.fn()
+
+ render(
+ ,
+ )
+
+ fireEvent.click(screen.getByText('workflow.nodes.tool.insertPlaceholder1'))
+
+ expect(parentClick).not.toHaveBeenCalled()
+ expect(mockTextNode).toHaveBeenCalledWith('')
+ expect(mockInsertNodes).toHaveBeenCalledTimes(1)
+ expect(mockDispatchCommand).toHaveBeenCalledWith(FOCUS_COMMAND, expect.any(FocusEvent))
+ })
+
+ it('should render only the slash insertion hint', () => {
+ render()
+
+ expect(screen.getByText('workflow.nodes.tool.insertPlaceholder2')).toBeInTheDocument()
+ expect(screen.queryByText('workflow.nodes.tool.insertPlaceholder3')).not.toBeInTheDocument()
+ expect(screen.queryByText('@')).not.toBeInTheDocument()
+ })
+
+ it('should insert a slash shortcut from the highlighted action and prevent the native mouse down behavior', () => {
+ render()
+
+ const shortcut = screen.getByText('workflow.nodes.tool.insertPlaceholder2')
+ const event = createEvent.mouseDown(shortcut)
+ fireEvent(shortcut, event)
+
+ expect(event.defaultPrevented).toBe(true)
+ expect(mockTextNode).toHaveBeenCalledWith('/')
+ expect(mockDispatchCommand).toHaveBeenCalledWith(FOCUS_COMMAND, expect.any(FocusEvent))
+ })
+})
diff --git a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/components/placeholder.tsx b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/components/placeholder.tsx
index 7d78c58464..df2e528ac6 100644
--- a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/components/placeholder.tsx
+++ b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/components/placeholder.tsx
@@ -8,13 +8,11 @@ import { cn } from '@/utils/classnames'
type PlaceholderProps = {
disableVariableInsertion?: boolean
- hasSelectedAgent?: boolean
hideBadge?: boolean
}
const Placeholder = ({
disableVariableInsertion = false,
- hasSelectedAgent = false,
hideBadge = false,
}: PlaceholderProps) => {
const { t } = useTranslation()
@@ -54,21 +52,6 @@ const Placeholder = ({
>
{t('nodes.tool.insertPlaceholder2', { ns: 'workflow' })}
- {!hasSelectedAgent && (
- <>
- @
- {
- e.preventDefault()
- e.stopPropagation()
- handleInsert('@')
- })}
- >
- {t('nodes.tool.insertPlaceholder3', { ns: 'workflow' })}
-
- >
- )}
>
)}
diff --git a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx
index db26b35145..9b1c11ce99 100644
--- a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx
+++ b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx
@@ -414,15 +414,12 @@ const MixedVariableTextInput = ({
workflowNodesMap,
showManageInputField,
onManageInputField,
+ agentNodes,
+ onSelectAgent: handleAgentSelect,
showAssembleVariables: !disableVariableInsertion && !!toolNodeId && !!paramKey,
onAssembleVariables: handleAssembleSelect,
}}
- agentBlock={{
- show: agentNodes.length > 0 && !detectedAgentFromValue,
- agentNodes,
- onSelect: handleAgentSelect,
- }}
- placeholder={}
+ placeholder={}
onChange={(text) => {
const hasPlaceholder = new RegExp(AGENT_CONTEXT_VAR_PATTERN.source).test(text)
if (hasPlaceholder)