fix: Prevent chat modal opening on 'Test workflow' click (#9009)

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
Michael Kret 2024-04-01 17:08:00 +03:00 committed by GitHub
parent bead7eb840
commit 3fd97e4c72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 111 additions and 8 deletions

View file

@ -48,6 +48,12 @@ export function getNodeByName(name: string) {
return cy.getByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0); return cy.getByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0);
} }
export function disableNode(name: string) {
const target = getNodeByName(name);
target.rightclick(name ? 'center' : 'topLeft', { force: true });
cy.getByTestId(`context-menu-item-toggle_activation`).click();
}
export function getConnectionBySourceAndTarget(source: string, target: string) { export function getConnectionBySourceAndTarget(source: string, target: string) {
return cy return cy
.get('.jtk-connector') .get('.jtk-connector')
@ -110,14 +116,20 @@ export function addSupplementalNodeToParent(
) { ) {
getAddInputEndpointByType(parentNodeName, endpointType).click({ force: true }); getAddInputEndpointByType(parentNodeName, endpointType).click({ force: true });
if (exactMatch) { if (exactMatch) {
getNodeCreatorItems().contains(new RegExp("^" + nodeName + "$", "g")).click(); getNodeCreatorItems()
.contains(new RegExp('^' + nodeName + '$', 'g'))
.click();
} else { } else {
getNodeCreatorItems().contains(nodeName).click(); getNodeCreatorItems().contains(nodeName).click();
} }
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist'); getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist');
} }
export function addLanguageModelNodeToParent(nodeName: string, parentNodeName: string, exactMatch = false) { export function addLanguageModelNodeToParent(
nodeName: string,
parentNodeName: string,
exactMatch = false,
) {
addSupplementalNodeToParent(nodeName, 'ai_languageModel', parentNodeName, exactMatch); addSupplementalNodeToParent(nodeName, 'ai_languageModel', parentNodeName, exactMatch);
} }

View file

@ -9,6 +9,7 @@ import {
AI_TOOL_CODE_NODE_NAME, AI_TOOL_CODE_NODE_NAME,
AI_TOOL_WIKIPEDIA_NODE_NAME, AI_TOOL_WIKIPEDIA_NODE_NAME,
BASIC_LLM_CHAIN_NODE_NAME, BASIC_LLM_CHAIN_NODE_NAME,
EDIT_FIELDS_SET_NODE_NAME,
} from './../constants'; } from './../constants';
import { createMockNodeExecutionData, runMockWorkflowExcution } from '../utils'; import { createMockNodeExecutionData, runMockWorkflowExcution } from '../utils';
import { import {
@ -17,7 +18,10 @@ import {
addNodeToCanvas, addNodeToCanvas,
addOutputParserNodeToParent, addOutputParserNodeToParent,
addToolNodeToParent, addToolNodeToParent,
clickExecuteWorkflowButton,
clickManualChatButton, clickManualChatButton,
disableNode,
getExecuteWorkflowButton,
navigateToNewWorkflowPage, navigateToNewWorkflowPage,
openNode, openNode,
} from '../composables/workflow'; } from '../composables/workflow';
@ -32,6 +36,7 @@ import {
closeManualChatModal, closeManualChatModal,
getManualChatDialog, getManualChatDialog,
getManualChatMessages, getManualChatMessages,
getManualChatModal,
getManualChatModalLogs, getManualChatModalLogs,
getManualChatModalLogsEntries, getManualChatModalLogsEntries,
getManualChatModalLogsTree, getManualChatModalLogsTree,
@ -43,13 +48,58 @@ describe('Langchain Integration', () => {
navigateToNewWorkflowPage(); navigateToNewWorkflowPage();
}); });
it('should not open chat modal', () => {
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
clickGetBackToCanvas();
addNodeToCanvas(AGENT_NODE_NAME, true, true);
clickGetBackToCanvas();
addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);
clickGetBackToCanvas();
clickExecuteWorkflowButton();
getManualChatModal().should('not.exist');
});
it('should disable test workflow button', () => {
addNodeToCanvas('Schedule Trigger', true);
addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
clickGetBackToCanvas();
addNodeToCanvas(AGENT_NODE_NAME, true, true);
clickGetBackToCanvas();
addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);
clickGetBackToCanvas();
disableNode('Schedule Trigger');
getExecuteWorkflowButton().should('be.disabled');
});
it('should add nodes to all Agent node input types', () => { it('should add nodes to all Agent node input types', () => {
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true); addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
addNodeToCanvas(AGENT_NODE_NAME, true, true); addNodeToCanvas(AGENT_NODE_NAME, true, true);
toggleParameterCheckboxInputByName('hasOutputParser'); toggleParameterCheckboxInputByName('hasOutputParser');
clickGetBackToCanvas(); clickGetBackToCanvas();
addLanguageModelNodeToParent(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AGENT_NODE_NAME, true); addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);
clickGetBackToCanvas(); clickGetBackToCanvas();
addMemoryNodeToParent(AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME, AGENT_NODE_NAME); addMemoryNodeToParent(AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME, AGENT_NODE_NAME);
@ -85,7 +135,7 @@ describe('Langchain Integration', () => {
addLanguageModelNodeToParent( addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
BASIC_LLM_CHAIN_NODE_NAME, BASIC_LLM_CHAIN_NODE_NAME,
true true,
); );
clickCreateNewCredential(); clickCreateNewCredential();
@ -98,7 +148,7 @@ describe('Langchain Integration', () => {
const inputMessage = 'Hello!'; const inputMessage = 'Hello!';
const outputMessage = 'Hi there! How can I assist you today?'; const outputMessage = 'Hi there! How can I assist you today?';
clickExecuteNode() clickExecuteNode();
runMockWorkflowExcution({ runMockWorkflowExcution({
trigger: () => sendManualChatMessage(inputMessage), trigger: () => sendManualChatMessage(inputMessage),
runData: [ runData: [
@ -121,7 +171,11 @@ describe('Langchain Integration', () => {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true); addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
addNodeToCanvas(AGENT_NODE_NAME, true); addNodeToCanvas(AGENT_NODE_NAME, true);
addLanguageModelNodeToParent(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AGENT_NODE_NAME, true); addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);
clickCreateNewCredential(); clickCreateNewCredential();
setCredentialValues({ setCredentialValues({
@ -134,7 +188,7 @@ describe('Langchain Integration', () => {
const inputMessage = 'Hello!'; const inputMessage = 'Hello!';
const outputMessage = 'Hi there! How can I assist you today?'; const outputMessage = 'Hi there! How can I assist you today?';
clickExecuteNode() clickExecuteNode();
runMockWorkflowExcution({ runMockWorkflowExcution({
trigger: () => sendManualChatMessage(inputMessage), trigger: () => sendManualChatMessage(inputMessage),
runData: [ runData: [
@ -157,7 +211,11 @@ describe('Langchain Integration', () => {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true); addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
addNodeToCanvas(AGENT_NODE_NAME, true); addNodeToCanvas(AGENT_NODE_NAME, true);
addLanguageModelNodeToParent(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AGENT_NODE_NAME, true); addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);
clickCreateNewCredential(); clickCreateNewCredential();
setCredentialValues({ setCredentialValues({

View file

@ -247,6 +247,33 @@ export function useRunWorkflow(options: { router: ReturnType<typeof useRouter> }
} }
} }
} }
//if no destination node is specified
//and execution is not triggered from chat
//and there are other triggers in the workflow
//disable chat trigger node to avoid modal opening and webhook creation
if (
!options.destinationNode &&
options.source !== 'RunData.ManualChatMessage' &&
workflowData.nodes.some((node) => node.type === CHAT_TRIGGER_NODE_TYPE)
) {
const otherTriggers = workflowData.nodes.filter(
(node) =>
node.type !== CHAT_TRIGGER_NODE_TYPE &&
node.type.toLowerCase().includes('trigger') &&
!node.disabled,
);
if (otherTriggers.length) {
const chatTriggerNode = workflowData.nodes.find(
(node) => node.type === CHAT_TRIGGER_NODE_TYPE,
);
if (chatTriggerNode) {
chatTriggerNode.disabled = true;
}
}
}
const startNodes: StartNodeData[] = startNodeNames.map((name) => { const startNodes: StartNodeData[] = startNodeNames.map((name) => {
// Find for each start node the source data // Find for each start node the source data
let sourceData = get(runData, [name, 0, 'source', 0], null); let sourceData = get(runData, [name, 0, 'source', 0], null);

View file

@ -728,6 +728,12 @@ export default defineComponent({
return this.containsChatNodes && this.triggerNodes.length === 1; return this.containsChatNodes && this.triggerNodes.length === 1;
}, },
isExecutionDisabled(): boolean { isExecutionDisabled(): boolean {
if (
this.containsChatNodes &&
this.triggerNodes.every((node) => node.disabled || node.type === CHAT_TRIGGER_NODE_TYPE)
) {
return true;
}
return !this.containsTrigger || this.allTriggersDisabled; return !this.containsTrigger || this.allTriggersDisabled;
}, },
getNodeViewOffsetPosition(): XYPosition { getNodeViewOffsetPosition(): XYPosition {