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);
}
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) {
return cy
.get('.jtk-connector')
@ -110,14 +116,20 @@ export function addSupplementalNodeToParent(
) {
getAddInputEndpointByType(parentNodeName, endpointType).click({ force: true });
if (exactMatch) {
getNodeCreatorItems().contains(new RegExp("^" + nodeName + "$", "g")).click();
getNodeCreatorItems()
.contains(new RegExp('^' + nodeName + '$', 'g'))
.click();
} else {
getNodeCreatorItems().contains(nodeName).click();
}
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);
}

View file

@ -9,6 +9,7 @@ import {
AI_TOOL_CODE_NODE_NAME,
AI_TOOL_WIKIPEDIA_NODE_NAME,
BASIC_LLM_CHAIN_NODE_NAME,
EDIT_FIELDS_SET_NODE_NAME,
} from './../constants';
import { createMockNodeExecutionData, runMockWorkflowExcution } from '../utils';
import {
@ -17,7 +18,10 @@ import {
addNodeToCanvas,
addOutputParserNodeToParent,
addToolNodeToParent,
clickExecuteWorkflowButton,
clickManualChatButton,
disableNode,
getExecuteWorkflowButton,
navigateToNewWorkflowPage,
openNode,
} from '../composables/workflow';
@ -32,6 +36,7 @@ import {
closeManualChatModal,
getManualChatDialog,
getManualChatMessages,
getManualChatModal,
getManualChatModalLogs,
getManualChatModalLogsEntries,
getManualChatModalLogsTree,
@ -43,13 +48,58 @@ describe('Langchain Integration', () => {
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', () => {
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
addNodeToCanvas(AGENT_NODE_NAME, true, true);
toggleParameterCheckboxInputByName('hasOutputParser');
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();
addMemoryNodeToParent(AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME, AGENT_NODE_NAME);
@ -85,7 +135,7 @@ describe('Langchain Integration', () => {
addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
BASIC_LLM_CHAIN_NODE_NAME,
true
true,
);
clickCreateNewCredential();
@ -98,7 +148,7 @@ describe('Langchain Integration', () => {
const inputMessage = 'Hello!';
const outputMessage = 'Hi there! How can I assist you today?';
clickExecuteNode()
clickExecuteNode();
runMockWorkflowExcution({
trigger: () => sendManualChatMessage(inputMessage),
runData: [
@ -121,7 +171,11 @@ describe('Langchain Integration', () => {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_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();
setCredentialValues({
@ -134,7 +188,7 @@ describe('Langchain Integration', () => {
const inputMessage = 'Hello!';
const outputMessage = 'Hi there! How can I assist you today?';
clickExecuteNode()
clickExecuteNode();
runMockWorkflowExcution({
trigger: () => sendManualChatMessage(inputMessage),
runData: [
@ -157,7 +211,11 @@ describe('Langchain Integration', () => {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_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();
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) => {
// Find for each start node the source data
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;
},
isExecutionDisabled(): boolean {
if (
this.containsChatNodes &&
this.triggerNodes.every((node) => node.disabled || node.type === CHAT_TRIGGER_NODE_TYPE)
) {
return true;
}
return !this.containsTrigger || this.allTriggersDisabled;
},
getNodeViewOffsetPosition(): XYPosition {