diff --git a/web/app/components/workflow/header/checklist/__tests__/index.spec.tsx b/web/app/components/workflow/header/checklist/__tests__/index.spec.tsx
index 9255d13bd3b..e79c66da2ef 100644
--- a/web/app/components/workflow/header/checklist/__tests__/index.spec.tsx
+++ b/web/app/components/workflow/header/checklist/__tests__/index.spec.tsx
@@ -1,9 +1,11 @@
import type { ReactNode } from 'react'
+import type { ChecklistItem } from '../../../hooks/use-checklist'
import { fireEvent, render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
import { BlockEnum } from '../../../types'
import WorkflowChecklist from '../index'
-let mockChecklistItems = [
+let mockChecklistItems: ChecklistItem[] = [
{
id: 'plugin-1',
type: BlockEnum.Tool,
@@ -23,6 +25,7 @@ let mockChecklistItems = [
]
const mockHandleNodeSelect = vi.fn()
+const mockSetOpenInlineAgentPanelNodeId = vi.fn()
type PopoverProps = {
children: ReactNode
@@ -50,6 +53,17 @@ vi.mock('../../../hooks/use-nodes-interactions', () => ({
}),
}))
+vi.mock('../../../store', () => ({
+ useStore: (
+ selector: (state: {
+ setOpenInlineAgentPanelNodeId: typeof mockSetOpenInlineAgentPanelNodeId
+ }) => unknown,
+ ) =>
+ selector({
+ setOpenInlineAgentPanelNodeId: mockSetOpenInlineAgentPanelNodeId,
+ }),
+}))
+
vi.mock('../../../hooks-store/store', () => ({
useHooksStore: (selector: (state: { configsMap: { flowType: string } }) => unknown) =>
selector({
@@ -129,6 +143,7 @@ describe('WorkflowChecklist', () => {
fireEvent.click(screen.getByTestId('node-group-Broken Node'))
expect(mockHandleNodeSelect).toHaveBeenCalledWith('node-1')
+ expect(mockSetOpenInlineAgentPanelNodeId).not.toHaveBeenCalled()
})
it('should use the custom item click handler when provided', () => {
@@ -141,6 +156,22 @@ describe('WorkflowChecklist', () => {
expect(mockHandleNodeSelect).not.toHaveBeenCalled()
})
+ it('should open the inline agent editor after selecting an inline agent reference warning', async () => {
+ const user = userEvent.setup()
+ mockChecklistItems[1] = {
+ ...mockChecklistItems[1]!,
+ type: BlockEnum.AgentV2,
+ title: 'Inline Agent',
+ openInlineAgentPanel: true,
+ }
+ render()
+
+ await user.click(screen.getByTestId('node-group-Inline Agent'))
+
+ expect(mockHandleNodeSelect).toHaveBeenCalledWith('node-1')
+ expect(mockSetOpenInlineAgentPanelNodeId).toHaveBeenCalledWith('node-1')
+ })
+
it('should render the resolved state when there are no checklist warnings', () => {
mockChecklistItems = []
diff --git a/web/app/components/workflow/header/checklist/index.tsx b/web/app/components/workflow/header/checklist/index.tsx
index 76a9b85bc84..2b6511d5e8e 100644
--- a/web/app/components/workflow/header/checklist/index.tsx
+++ b/web/app/components/workflow/header/checklist/index.tsx
@@ -16,6 +16,7 @@ import useNodes from '@/app/components/workflow/store/workflow/use-nodes'
import { useHooksStore } from '../../hooks-store/store'
import { useChecklist } from '../../hooks/use-checklist'
import { useNodesInteractions } from '../../hooks/use-nodes-interactions'
+import { useStore } from '../../store'
import { ChecklistNodeGroup } from './node-group'
import { ChecklistPluginGroup } from './plugin-group'
@@ -33,6 +34,7 @@ const WorkflowChecklist = ({ disabled, showGoTo = true, onItemClick }: WorkflowC
const flowType = useHooksStore((s) => s.configsMap?.flowType)
const needWarningNodes = useChecklist(nodes, edges, { flowType })
const { handleNodeSelect } = useNodesInteractions()
+ const setOpenInlineAgentPanelNodeId = useStore((state) => state.setOpenInlineAgentPanelNodeId)
const checklistLabel = t(($) => $['panel.checklist'], { ns: 'workflow' })
const { pluginItems, nodeItems } = useMemo(() => {
@@ -47,7 +49,10 @@ const WorkflowChecklist = ({ disabled, showGoTo = true, onItemClick }: WorkflowC
const handleItemClick = (item: ChecklistItem) => {
if (onItemClick) onItemClick(item)
- else handleNodeSelect(item.id)
+ else {
+ handleNodeSelect(item.id)
+ if (item.openInlineAgentPanel) setOpenInlineAgentPanelNodeId(item.id)
+ }
setOpen(false)
}
diff --git a/web/app/components/workflow/hooks/__tests__/use-checklist.spec.ts b/web/app/components/workflow/hooks/__tests__/use-checklist.spec.ts
index 2468f528df1..8872342821c 100644
--- a/web/app/components/workflow/hooks/__tests__/use-checklist.spec.ts
+++ b/web/app/components/workflow/hooks/__tests__/use-checklist.spec.ts
@@ -327,6 +327,7 @@ describe('useChecklist', () => {
expect.objectContaining({
id: nodeId,
errorMessages: [scenario.errorMessage],
+ openInlineAgentPanel: true,
}),
])
})
diff --git a/web/app/components/workflow/hooks/use-checklist.ts b/web/app/components/workflow/hooks/use-checklist.ts
index ea9ebb9d45b..98582076d6d 100644
--- a/web/app/components/workflow/hooks/use-checklist.ts
+++ b/web/app/components/workflow/hooks/use-checklist.ts
@@ -81,6 +81,7 @@ export type ChecklistItem = {
disableGoTo?: boolean
isPluginMissing?: boolean
pluginUniqueIdentifier?: string
+ openInlineAgentPanel?: boolean
}
type CheckValidExtraData = Record | undefined
@@ -352,6 +353,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[], options?: { flowType?
})
const errorMessages: string[] = []
+ const missingReferences = inlineAgentMissingReferences[node!.id]
if (isPluginMissing) {
errorMessages.push(t(($) => $['nodes.common.pluginNotInstalled'], { ns: 'workflow' }))
@@ -379,7 +381,6 @@ export const useChecklist = (nodes: Node[], edges: Edge[], options?: { flowType?
if (validationError) errorMessages.push(validationError)
}
- const missingReferences = inlineAgentMissingReferences[node!.id]
if (missingReferences?.hasMissingFiles)
errorMessages.push(
t(($) => $['agentDetail.configure.files.missing'], { ns: 'agentV2' }),
@@ -429,6 +430,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[], options?: { flowType?
pluginUniqueIdentifier: isPluginMissing
? (node!.data as { plugin_unique_identifier?: string }).plugin_unique_identifier
: undefined,
+ ...(missingReferences ? { openInlineAgentPanel: true } : {}),
})
}
}