Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(editor): Don't send run data for full manual executions #12687

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions packages/editor-ui/src/components/CanvasChat/CanvasChat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,28 +230,28 @@ describe('CanvasChat', () => {
// Verify workflow execution
expect(workflowsStore.runWorkflow).toHaveBeenCalledWith(
expect.objectContaining({
runData: {
'When chat message received': [
{
data: {
main: [
[
{
json: {
action: 'sendMessage',
chatInput: 'Hello AI!',
sessionId: expect.any(String),
},
runData: undefined,
triggerToStartFrom: {
name: 'When chat message received',
data: {
data: {
main: [
[
{
json: {
action: 'sendMessage',
chatInput: 'Hello AI!',
sessionId: expect.any(String),
},
],
},
],
},
executionStatus: 'success',
executionTime: 0,
source: [null],
startTime: expect.any(Number),
],
},
],
Comment on lines -233 to -254
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The runData property is not used by the BE anymore to execute chat trigger workflows since #11952

The BE now uses triggerToStartFrom, so I changed the test to assert that property instead.

executionStatus: 'success',
executionTime: 0,
source: [null],
startTime: expect.any(Number),
},
},
}),
);
Expand Down
71 changes: 50 additions & 21 deletions packages/editor-ui/src/composables/useRunWorkflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useToast } from './useToast';
import { useI18n } from '@/composables/useI18n';
import { useLocalStorage } from '@vueuse/core';
import { ref } from 'vue';
import { mock } from 'vitest-mock-extended';
import { captor, mock } from 'vitest-mock-extended';

vi.mock('@/stores/workflows.store', () => ({
useWorkflowsStore: vi.fn().mockReturnValue({
Expand Down Expand Up @@ -409,27 +409,28 @@ describe('useRunWorkflow({ router })', () => {
const mockExecutionResponse = { executionId: '123' };
const mockRunData = { nodeName: [] };
const { runWorkflow } = useRunWorkflow({ router });
const dataCaptor = captor();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Never seen it before

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, stole this from adi 😄

const workflow = mock<Workflow>({ name: 'Test Workflow' });
workflow.getParentNodes.mockReturnValue([]);

vi.mocked(useLocalStorage).mockReturnValueOnce(ref(0));
vi.mocked(rootStore).pushConnectionActive = true;
vi.mocked(workflowsStore).runWorkflow.mockResolvedValue(mockExecutionResponse);
vi.mocked(workflowsStore).nodesIssuesExist = false;
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue({
name: 'Test Workflow',
} as Workflow);
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
id: 'workflowId',
nodes: [],
} as unknown as IWorkflowData);
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue(workflow);
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
mock<IWorkflowData>({ id: 'workflowId', nodes: [] }),
);
vi.mocked(workflowsStore).getWorkflowRunData = mockRunData;

// ACT
const result = await runWorkflow({});
const result = await runWorkflow({ destinationNode: 'some node name' });

// ASSERT
expect(result).toEqual(mockExecutionResponse);
expect(workflowsStore.setWorkflowExecutionData).toHaveBeenCalledTimes(1);
expect(vi.mocked(workflowsStore.setWorkflowExecutionData).mock.calls[0][0]).toMatchObject({
expect(workflowsStore.setWorkflowExecutionData).toHaveBeenCalledWith(dataCaptor);
expect(dataCaptor.value).toMatchObject({
data: { resultData: { runData: {} } },
});
});
Expand All @@ -439,29 +440,57 @@ describe('useRunWorkflow({ router })', () => {
const mockExecutionResponse = { executionId: '123' };
const mockRunData = { nodeName: [] };
const { runWorkflow } = useRunWorkflow({ router });
const dataCaptor = captor();
const workflow = mock<Workflow>({ name: 'Test Workflow' });
workflow.getParentNodes.mockReturnValue([]);

vi.mocked(useLocalStorage).mockReturnValueOnce(ref(1));
vi.mocked(rootStore).pushConnectionActive = true;
vi.mocked(workflowsStore).runWorkflow.mockResolvedValue(mockExecutionResponse);
vi.mocked(workflowsStore).nodesIssuesExist = false;
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue({
name: 'Test Workflow',
} as Workflow);
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
id: 'workflowId',
nodes: [],
} as unknown as IWorkflowData);
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue(workflow);
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
mock<IWorkflowData>({ id: 'workflowId', nodes: [] }),
);
vi.mocked(workflowsStore).getWorkflowRunData = mockRunData;

// ACT
const result = await runWorkflow({});
const result = await runWorkflow({ destinationNode: 'some node name' });

// ASSERT
expect(result).toEqual(mockExecutionResponse);
expect(workflowsStore.setWorkflowExecutionData).toHaveBeenCalledTimes(1);
expect(vi.mocked(workflowsStore.setWorkflowExecutionData).mock.calls[0][0]).toMatchObject({
data: { resultData: { runData: mockRunData } },
});
expect(workflowsStore.setWorkflowExecutionData).toHaveBeenCalledWith(dataCaptor);
expect(dataCaptor.value).toMatchObject({ data: { resultData: { runData: mockRunData } } });
});

it("does not send run data if it's not a partial execution even if `PartialExecution.version` is set to 1", async () => {
// ARRANGE
const mockExecutionResponse = { executionId: '123' };
const mockRunData = { nodeName: [] };
const { runWorkflow } = useRunWorkflow({ router });
const dataCaptor = captor();
const workflow = mock<Workflow>({ name: 'Test Workflow' });
workflow.getParentNodes.mockReturnValue([]);

vi.mocked(useLocalStorage).mockReturnValueOnce(ref(1));
vi.mocked(rootStore).pushConnectionActive = true;
vi.mocked(workflowsStore).runWorkflow.mockResolvedValue(mockExecutionResponse);
vi.mocked(workflowsStore).nodesIssuesExist = false;
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue(workflow);
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
mock<IWorkflowData>({ id: 'workflowId', nodes: [] }),
);
vi.mocked(workflowsStore).getWorkflowRunData = mockRunData;

// ACT
const result = await runWorkflow({});

// ASSERT
expect(result).toEqual(mockExecutionResponse);
expect(workflowsStore.runWorkflow).toHaveBeenCalledTimes(1);
expect(workflowsStore.runWorkflow).toHaveBeenCalledWith(dataCaptor);
expect(dataCaptor.value).toHaveProperty('runData', undefined);
});
});

Expand Down
15 changes: 12 additions & 3 deletions packages/editor-ui/src/composables/useRunWorkflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,23 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
// 0 is the old flow
// 1 is the new flow
const partialExecutionVersion = useLocalStorage('PartialExecution.version', -1);
// partial executions must have a destination node
const isPartialExecution = options.destinationNode !== undefined;
const startRunData: IStartRunData = {
workflowData,
// With the new partial execution version the backend decides what run
// data to use and what to ignore.
runData: partialExecutionVersion.value === 1 ? (runData ?? undefined) : newRunData,
runData: !isPartialExecution
? // if it's a full execution we don't want to send any run data
undefined
: partialExecutionVersion.value === 1
? // With the new partial execution version the backend decides
//what run data to use and what to ignore.
(runData ?? undefined)
: // for v0 we send the run data the FE constructed
newRunData,
startNodes,
triggerToStartFrom,
};

if ('destinationNode' in options) {
startRunData.destinationNode = options.destinationNode;
}
Expand Down
Loading