Skip to content

Commit

Permalink
Merge branch 'master' into ai-226-when-adding-an-llm-model-to-the-can…
Browse files Browse the repository at this point in the history
…vas-without-a-root-node
  • Loading branch information
jeanpaul committed Aug 5, 2024
2 parents 07b84dc + 7fb3f62 commit 9f035d6
Show file tree
Hide file tree
Showing 315 changed files with 6,930 additions and 3,256 deletions.
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
# [1.53.0](https://github.com/n8n-io/n8n/compare/[email protected]@1.53.0) (2024-07-31)


### Bug Fixes

* Better error message when calling data transformation functions on a null value ([#10210](https://github.com/n8n-io/n8n/issues/10210)) ([1718125](https://github.com/n8n-io/n8n/commit/1718125c6d8589cf24dc8d34f6808dd6f1802691))
* **core:** Fix missing successful items on continueErrorOutput with multiple outputs ([#10218](https://github.com/n8n-io/n8n/issues/10218)) ([1a7713e](https://github.com/n8n-io/n8n/commit/1a7713ef263680da43f08b6c8a15aee7a0341493))
* **core:** Flush instance stopped event immediately ([#10238](https://github.com/n8n-io/n8n/issues/10238)) ([d6770b5](https://github.com/n8n-io/n8n/commit/d6770b5fcaec6438d677b918aaeb1669ad7424c2))
* **core:** Restore log event `n8n.workflow.failed` ([#10253](https://github.com/n8n-io/n8n/issues/10253)) ([3e96b29](https://github.com/n8n-io/n8n/commit/3e96b293329525c9d4b2fcef87b3803e458c8e7f))
* **core:** Upgrade @n8n/vm2 to address CVE‑2023‑37466 ([#10265](https://github.com/n8n-io/n8n/issues/10265)) ([2a09a03](https://github.com/n8n-io/n8n/commit/2a09a036d2e916acff7ee50904f1d011a93758e1))
* **editor:** Defer `User saved credentials` telemetry event for OAuth credentials ([#10215](https://github.com/n8n-io/n8n/issues/10215)) ([40a5226](https://github.com/n8n-io/n8n/commit/40a5226e24448a4428143e69d80ebc78238365a1))
* **editor:** Fix custom API call notice ([#10227](https://github.com/n8n-io/n8n/issues/10227)) ([5b47c8b](https://github.com/n8n-io/n8n/commit/5b47c8b57b25528cd2d6f97bc6d98707d47f35bc))
* **editor:** Fix issue with existing credential not opening in HTTP agent tool ([#10167](https://github.com/n8n-io/n8n/issues/10167)) ([906b4c3](https://github.com/n8n-io/n8n/commit/906b4c3c7b2919111cf23eaa12b3c4d507969179))
* **editor:** Fix parameter input glitch when there was an error loading remote options ([#10209](https://github.com/n8n-io/n8n/issues/10209)) ([c0e3743](https://github.com/n8n-io/n8n/commit/c0e37439a87105a0e66c8ebced42c06dab30dc5e))
* **editor:** Fix workflow execution list scrolling after filter change ([#10226](https://github.com/n8n-io/n8n/issues/10226)) ([7e64358](https://github.com/n8n-io/n8n/commit/7e643589c67adc0218216ec4b89a95f0edfedbee))
* **Google BigQuery Node:** Send timeoutMs in query, pagination support ([#10205](https://github.com/n8n-io/n8n/issues/10205)) ([f5722e8](https://github.com/n8n-io/n8n/commit/f5722e8823ccd2bc2b5f43ba3c849797d5690a93))
* **Google Sheets Node:** Add column names row if sheet is empty ([#10200](https://github.com/n8n-io/n8n/issues/10200)) ([82eba9f](https://github.com/n8n-io/n8n/commit/82eba9fc5ff49b8e2a9db93c10b253fb67a8c644))
* **Google Sheets Node:** Do not insert row_number as a new column, do not checkForSchemaChanges in update operation ([#10201](https://github.com/n8n-io/n8n/issues/10201)) ([5136d10](https://github.com/n8n-io/n8n/commit/5136d10ca3492f92af67d4a1d4abc774419580cc))
* **Google Sheets Node:** Fix Google Sheet URL regex ([#10195](https://github.com/n8n-io/n8n/issues/10195)) ([e6fd996](https://github.com/n8n-io/n8n/commit/e6fd996973d4f40facf0ebf1eea3cc26acd0603d))
* **HTTP Request Node:** Resolve max pages expression ([#10192](https://github.com/n8n-io/n8n/issues/10192)) ([bfc8e1b](https://github.com/n8n-io/n8n/commit/bfc8e1b56f7714e1f52aae747d58d686b86e60f0))
* **LinkedIn Node:** Fix issue with some characters cutting off posts early ([#10185](https://github.com/n8n-io/n8n/issues/10185)) ([361b5e7](https://github.com/n8n-io/n8n/commit/361b5e7c37ba49b68dcf5b8122621aad4d8d96e0))
* **Postgres Node:** Expressions in query parameters for Postgres executeQuery operation ([#10217](https://github.com/n8n-io/n8n/issues/10217)) ([519fc4d](https://github.com/n8n-io/n8n/commit/519fc4d75325a80b84cc4dcacf52d6f4c02e3a44))
* **Postgres Node:** Option to treat query parameters enclosed in single quotas as text ([#10214](https://github.com/n8n-io/n8n/issues/10214)) ([00ec253](https://github.com/n8n-io/n8n/commit/00ec2533374d3def465efee718592fc4001d5602))
* **Read/Write Files from Disk Node:** Notice update in file selector, replace backslashes with forward slashes if windows path ([#10186](https://github.com/n8n-io/n8n/issues/10186)) ([3eac673](https://github.com/n8n-io/n8n/commit/3eac673b17986c5c74bd2adb5ad589ba0ca55319))
* **Text Classifier Node:** Use proper documentation URL and respect continueOnFail ([#10216](https://github.com/n8n-io/n8n/issues/10216)) ([452f52c](https://github.com/n8n-io/n8n/commit/452f52c124017e002e86c547ba42b1633b14beed))
* **Trello Node:** Use body for POST requests ([#10189](https://github.com/n8n-io/n8n/issues/10189)) ([7775d50](https://github.com/n8n-io/n8n/commit/7775d5059b7f69d9af22e7ad7d12c6cf9092a4e5))
* **Wait Node:** Authentication fix ([#10236](https://github.com/n8n-io/n8n/issues/10236)) ([f87854f](https://github.com/n8n-io/n8n/commit/f87854f8db360b7b870583753fcfb4af95adab8c))


### Features

* **Calendly Trigger Node:** Add OAuth Credentials Support ([#10251](https://github.com/n8n-io/n8n/issues/10251)) ([326c983](https://github.com/n8n-io/n8n/commit/326c983915a2c382e32398358e7dcadd022c0b77))
* **core:** Allow filtering workflows by project and transferring workflows in Public API ([#10231](https://github.com/n8n-io/n8n/issues/10231)) ([d719899](https://github.com/n8n-io/n8n/commit/d719899223907b20a17883a35e4ef637a3453532))
* **editor:** Show new executions as `Queued` in the UI, until they actually start ([#10204](https://github.com/n8n-io/n8n/issues/10204)) ([44728d7](https://github.com/n8n-io/n8n/commit/44728d72423f5549dda09589f4a618ebd80899cb))
* **HTTP Request Node:** Add option to disable lowercase headers ([#10154](https://github.com/n8n-io/n8n/issues/10154)) ([5aba69b](https://github.com/n8n-io/n8n/commit/5aba69bcf4d232d9860f3cd9fe57cb8839a2f96f))
* **Information Extractor Node:** Add new simplified AI-node for information extraction ([#10149](https://github.com/n8n-io/n8n/issues/10149)) ([3d235b0](https://github.com/n8n-io/n8n/commit/3d235b0b2df756df35ac60e3dcd87ad183a07167))
* Introduce Google Cloud Platform as external secrets provider ([#10146](https://github.com/n8n-io/n8n/issues/10146)) ([3ccb9df](https://github.com/n8n-io/n8n/commit/3ccb9df2f902e46f8cbb9c46c0727f29d752a773))
* **n8n Form Trigger Node:** Improvements ([#10092](https://github.com/n8n-io/n8n/issues/10092)) ([711b667](https://github.com/n8n-io/n8n/commit/711b667ebefe55740e5eb39f1f0f24ceee10e7b0))
* Recovery option for jsonParse helper ([#10182](https://github.com/n8n-io/n8n/issues/10182)) ([d165b33](https://github.com/n8n-io/n8n/commit/d165b33ceac4d24d0fc290bffe63b5f551204e38))
* **Sentiment Analysis Node:** Implement Sentiment Analysis node ([#10184](https://github.com/n8n-io/n8n/issues/10184)) ([8ef0a0c](https://github.com/n8n-io/n8n/commit/8ef0a0c58ac2a84aad649ccbe72aa907d005cc44))
* **Shopify Node:** Update Shopify API version ([#10155](https://github.com/n8n-io/n8n/issues/10155)) ([e2ee915](https://github.com/n8n-io/n8n/commit/e2ee91569a382bfbf787cf45204c72c821a860a0))
* Support create, read, delete variables in Public API ([#10241](https://github.com/n8n-io/n8n/issues/10241)) ([af695eb](https://github.com/n8n-io/n8n/commit/af695ebf934526d926ea87fe87df61aa73d70979))



# [1.52.0](https://github.com/n8n-io/n8n/compare/[email protected]@1.52.0) (2024-07-24)


Expand Down
1 change: 1 addition & 0 deletions cypress/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const AI_TOOL_CODE_NODE_NAME = 'Code Tool';
export const AI_TOOL_WIKIPEDIA_NODE_NAME = 'Wikipedia';
export const AI_TOOL_HTTP_NODE_NAME = 'HTTP Request Tool';
export const AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME = 'OpenAI Chat Model';
export const AI_MEMORY_POSTGRES_NODE_NAME = 'Postgres Chat Memory';
export const AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME = 'Auto-fixing Output Parser';
export const WEBHOOK_NODE_NAME = 'Webhook';

Expand Down
44 changes: 44 additions & 0 deletions cypress/e2e/20-workflow-executions.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,50 @@ describe('Current Workflow Executions', () => {
.invoke('attr', 'title')
.should('eq', newWorkflowName);
});

it('should load items and auto scroll after filter change', () => {
createMockExecutions();
createMockExecutions();
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');

executionsTab.actions.switchToExecutionsTab();

cy.wait(['@getExecutions']);

executionsTab.getters.executionsList().scrollTo(0, 500).wait(0);

executionsTab.getters.executionListItems().eq(10).click();

cy.getByTestId('executions-filter-button').click();
cy.getByTestId('executions-filter-status-select').should('be.visible').click();
getVisibleSelect().find('li:contains("Error")').click();

executionsTab.getters.executionListItems().should('have.length', 5);
executionsTab.getters.successfulExecutionListItems().should('have.length', 1);
executionsTab.getters.failedExecutionListItems().should('have.length', 4);

cy.getByTestId('executions-filter-button').click();
cy.getByTestId('executions-filter-status-select').should('be.visible').click();
getVisibleSelect().find('li:contains("Success")').click();

// check if the list is scrolled
executionsTab.getters.executionListItems().eq(10).should('be.visible');
executionsTab.getters.executionsList().then(($el) => {
const { scrollTop, scrollHeight, clientHeight } = $el[0];
expect(scrollTop).to.be.greaterThan(0);
expect(scrollTop + clientHeight).to.be.lessThan(scrollHeight);

// scroll to the bottom
$el[0].scrollTo(0, scrollHeight);
executionsTab.getters.executionListItems().should('have.length', 18);
executionsTab.getters.successfulExecutionListItems().should('have.length', 18);
executionsTab.getters.failedExecutionListItems().should('have.length', 0);
});

cy.getByTestId('executions-filter-button').click();
cy.getByTestId('executions-filter-reset-button').should('be.visible').click();
executionsTab.getters.executionListItems().eq(11).should('be.visible');
});
});

const createMockExecutions = () => {
Expand Down
279 changes: 279 additions & 0 deletions cypress/e2e/233-AI-switch-to-logs-on-error.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
import type { ExecutionError } from 'n8n-workflow/src';
import { NDV, WorkflowPage as WorkflowPageClass } from '../pages';
import {
addLanguageModelNodeToParent,
addMemoryNodeToParent,
addNodeToCanvas,
addToolNodeToParent,
navigateToNewWorkflowPage,
openNode,
} from '../composables/workflow';
import {
AGENT_NODE_NAME,
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AI_MEMORY_POSTGRES_NODE_NAME,
AI_TOOL_CALCULATOR_NODE_NAME,
CHAT_TRIGGER_NODE_DISPLAY_NAME,
MANUAL_CHAT_TRIGGER_NODE_NAME,
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
MANUAL_TRIGGER_NODE_NAME,
} from '../constants';
import {
clickCreateNewCredential,
clickExecuteNode,
clickGetBackToCanvas,
} from '../composables/ndv';
import { setCredentialValues } from '../composables/modals/credential-modal';
import {
closeManualChatModal,
getManualChatMessages,
getManualChatModalLogs,
getManualChatModalLogsEntries,
sendManualChatMessage,
} from '../composables/modals/chat-modal';
import { createMockNodeExecutionData, getVisibleSelect, runMockWorkflowExecution } from '../utils';

const ndv = new NDV();
const WorkflowPage = new WorkflowPageClass();

function createRunDataWithError(inputMessage: string) {
return [
createMockNodeExecutionData(MANUAL_CHAT_TRIGGER_NODE_NAME, {
jsonData: {
main: { input: inputMessage },
},
}),
createMockNodeExecutionData(AI_MEMORY_POSTGRES_NODE_NAME, {
jsonData: {
ai_memory: {
json: {
action: 'loadMemoryVariables',
values: {
input: inputMessage,
system_message: 'You are a helpful assistant',
formatting_instructions:
'IMPORTANT: Always call `format_final_response` to format your final response!',
},
},
},
},
inputOverride: {
ai_memory: [
[
{
json: {
action: 'loadMemoryVariables',
values: {
input: inputMessage,
system_message: 'You are a helpful assistant',
formatting_instructions:
'IMPORTANT: Always call `format_final_response` to format your final response!',
},
},
},
],
],
},
error: {
message: 'Internal error',
timestamp: 1722591723244,
name: 'NodeOperationError',
description: 'Internal error',
context: {},
cause: {
name: 'error',
severity: 'FATAL',
code: '3D000',
file: 'postinit.c',
line: '885',
routine: 'InitPostgres',
} as unknown as Error,
} as ExecutionError,
}),
createMockNodeExecutionData(AGENT_NODE_NAME, {
executionStatus: 'error',
error: {
level: 'error',
tags: {
packageName: 'workflow',
},
context: {},
functionality: 'configuration-node',
name: 'NodeOperationError',
timestamp: 1722591723244,
node: {
parameters: {
notice: '',
sessionIdType: 'fromInput',
tableName: 'n8n_chat_histories',
},
id: '6b9141da-0135-4e9d-94d1-2d658cbf48b5',
name: 'Postgres Chat Memory',
type: '@n8n/n8n-nodes-langchain.memoryPostgresChat',
typeVersion: 1,
position: [1140, 500],
credentials: {
postgres: {
id: 'RkyZetVpGsSfEAhQ',
name: 'Postgres account',
},
},
},
messages: ['database "chat11" does not exist'],
description: 'Internal error',
message: 'Internal error',
} as unknown as ExecutionError,
metadata: {
subRun: [
{
node: 'Postgres Chat Memory',
runIndex: 0,
},
],
},
}),
];
}

function setupTestWorkflow(chatTrigger: boolean = false) {
// Setup test workflow with AI Agent, Postgres Memory Node (source of error), Calculator Tool, and OpenAI Chat Model
if (chatTrigger) {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
} else {
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
}

addNodeToCanvas(AGENT_NODE_NAME, true);

if (!chatTrigger) {
// Remove chat trigger
WorkflowPage.getters
.canvasNodeByName(CHAT_TRIGGER_NODE_DISPLAY_NAME)
.find('[data-test-id="delete-node-button"]')
.click({ force: true });

// Set manual trigger to output standard pinned data
openNode(MANUAL_TRIGGER_NODE_DISPLAY_NAME);
ndv.actions.editPinnedData();
ndv.actions.savePinnedData();
ndv.actions.close();
}

// Calculator is added just to make OpenAI Chat Model work (tools can not be empty with OpenAI model)
addToolNodeToParent(AI_TOOL_CALCULATOR_NODE_NAME, AGENT_NODE_NAME);
clickGetBackToCanvas();

addMemoryNodeToParent(AI_MEMORY_POSTGRES_NODE_NAME, AGENT_NODE_NAME);

clickCreateNewCredential();
setCredentialValues({
password: 'testtesttest',
});

ndv.getters.parameterInput('sessionIdType').click();
getVisibleSelect().contains('Define below').click();
ndv.getters.parameterInput('sessionKey').type('asdasd');

clickGetBackToCanvas();

addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);

clickCreateNewCredential();
setCredentialValues({
apiKey: 'sk_test_123',
});
clickGetBackToCanvas();

WorkflowPage.actions.zoomToFit();
}

function checkMessages(inputMessage: string, outputMessage: string) {
const messages = getManualChatMessages();
messages.should('have.length', 2);
messages.should('contain', inputMessage);
messages.should('contain', outputMessage);

getManualChatModalLogs().should('exist');
getManualChatModalLogsEntries()
.should('have.length', 1)
.should('contain', AI_MEMORY_POSTGRES_NODE_NAME);
}

describe("AI-233 Make root node's logs pane active in case of an error in sub-nodes", () => {
beforeEach(() => {
navigateToNewWorkflowPage();
});

it('should open logs tab by default when there was an error', () => {
setupTestWorkflow(true);

openNode(AGENT_NODE_NAME);

const inputMessage = 'Test the code tool';

clickExecuteNode();
runMockWorkflowExecution({
trigger: () => sendManualChatMessage(inputMessage),
runData: createRunDataWithError(inputMessage),
lastNodeExecuted: AGENT_NODE_NAME,
});

checkMessages(inputMessage, '[ERROR: Internal error]');
closeManualChatModal();

// Open the AI Agent node to see the logs
openNode(AGENT_NODE_NAME);

// Finally check that logs pane is opened by default
ndv.getters.outputDataContainer().should('be.visible');

ndv.getters.aiOutputModeToggle().should('be.visible');
ndv.getters
.aiOutputModeToggle()
.find('[role="radio"]')
.should('have.length', 2)
.eq(1)
.should('have.attr', 'aria-checked', 'true');

ndv.getters
.outputPanel()
.findChildByTestId('node-error-message')
.should('be.visible')
.should('contain', 'Error in sub-node');
});

it('should switch to logs tab on error, when NDV is already opened', () => {
setupTestWorkflow(false);

openNode(AGENT_NODE_NAME);

const inputMessage = 'Test the code tool';

runMockWorkflowExecution({
trigger: () => clickExecuteNode(),
runData: createRunDataWithError(inputMessage),
lastNodeExecuted: AGENT_NODE_NAME,
});

// Check that logs pane is opened by default
ndv.getters.outputDataContainer().should('be.visible');

ndv.getters.aiOutputModeToggle().should('be.visible');
ndv.getters
.aiOutputModeToggle()
.find('[role="radio"]')
.should('have.length', 2)
.eq(1)
.should('have.attr', 'aria-checked', 'true');

ndv.getters
.outputPanel()
.findChildByTestId('node-error-message')
.should('be.visible')
.should('contain', 'Error in sub-node');
});
});
Loading

0 comments on commit 9f035d6

Please sign in to comment.