Skip to content

Commit

Permalink
fix: Prevent chat modal opening on 'Test workflow' click (#9009)
Browse files Browse the repository at this point in the history
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
  • Loading branch information
michael-radency and OlegIvaniv committed Apr 1, 2024
1 parent bead7eb commit 3fd97e4
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 8 deletions.
16 changes: 14 additions & 2 deletions cypress/composables/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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);
}

Expand Down
70 changes: 64 additions & 6 deletions cypress/e2e/30-langchain.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -17,7 +18,10 @@ import {
addNodeToCanvas,
addOutputParserNodeToParent,
addToolNodeToParent,
clickExecuteWorkflowButton,
clickManualChatButton,
disableNode,
getExecuteWorkflowButton,
navigateToNewWorkflowPage,
openNode,
} from '../composables/workflow';
Expand All @@ -32,6 +36,7 @@ import {
closeManualChatModal,
getManualChatDialog,
getManualChatMessages,
getManualChatModal,
getManualChatModalLogs,
getManualChatModalLogsEntries,
getManualChatModalLogsTree,
Expand All @@ -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);
Expand Down Expand Up @@ -85,7 +135,7 @@ describe('Langchain Integration', () => {
addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
BASIC_LLM_CHAIN_NODE_NAME,
true
true,
);

clickCreateNewCredential();
Expand All @@ -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: [
Expand All @@ -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({
Expand All @@ -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: [
Expand All @@ -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({
Expand Down
27 changes: 27 additions & 0 deletions packages/editor-ui/src/composables/useRunWorkflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions packages/editor-ui/src/views/NodeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 3fd97e4

Please sign in to comment.