-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add AI tool building capabilities (#7336)
Github issue / Community forum post (link here to close automatically): https://community.n8n.io/t/langchain-memory-chat/23733 --------- Signed-off-by: Oleg Ivaniv <[email protected]> Co-authored-by: Oleg Ivaniv <[email protected]> Co-authored-by: Val <[email protected]> Co-authored-by: Alex Grozav <[email protected]> Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <[email protected]> Co-authored-by: Deborah <[email protected]> Co-authored-by: Jesper Bylund <[email protected]> Co-authored-by: Jon <[email protected]> Co-authored-by: Michael Kret <[email protected]> Co-authored-by: Giulio Andreini <[email protected]> Co-authored-by: Mason Geloso <[email protected]> Co-authored-by: Mason Geloso <[email protected]> Co-authored-by: Mutasem Aldmour <[email protected]>
- Loading branch information
1 parent
dbfd617
commit 87def60
Showing
243 changed files
with
21,688 additions
and
483 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/** | ||
* Getters | ||
*/ | ||
|
||
export function getManualChatModal() { | ||
return cy.getByTestId('lmChat-modal'); | ||
} | ||
|
||
export function getManualChatInput() { | ||
return cy.getByTestId('workflow-chat-input'); | ||
} | ||
|
||
export function getManualChatSendButton() { | ||
return getManualChatModal().getByTestId('workflow-chat-send-button'); | ||
} | ||
|
||
export function getManualChatMessages() { | ||
return getManualChatModal().get('.messages .message'); | ||
} | ||
|
||
export function getManualChatModalCloseButton() { | ||
return getManualChatModal().get('.el-dialog__close'); | ||
} | ||
|
||
export function getManualChatModalLogs() { | ||
return getManualChatModal().getByTestId('lm-chat-logs'); | ||
} | ||
|
||
export function getManualChatModalLogsTree() { | ||
return getManualChatModalLogs().getByTestId('lm-chat-logs-tree'); | ||
} | ||
|
||
export function getManualChatModalLogsEntries() { | ||
return getManualChatModalLogs().getByTestId('lm-chat-logs-entry'); | ||
} | ||
|
||
/** | ||
* Actions | ||
*/ | ||
|
||
export function sendManualChatMessage(message: string) { | ||
getManualChatInput().type(message); | ||
getManualChatSendButton().click(); | ||
} | ||
|
||
export function closeManualChatModal() { | ||
getManualChatModalCloseButton().click(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* Getters | ||
*/ | ||
|
||
export function getCredentialConnectionParameterInputs() { | ||
return cy.getByTestId('credential-connection-parameter'); | ||
} | ||
|
||
export function getCredentialConnectionParameterInputByName(name: string) { | ||
return cy.getByTestId(`parameter-input-${name}`); | ||
} | ||
|
||
export function getEditCredentialModal() { | ||
return cy.getByTestId('editCredential-modal', { timeout: 5000 }); | ||
} | ||
|
||
export function getCredentialSaveButton() { | ||
return cy.getByTestId('credential-save-button', { timeout: 5000 }); | ||
} | ||
|
||
export function getCredentialDeleteButton() { | ||
return cy.getByTestId('credential-delete-button'); | ||
} | ||
|
||
export function getCredentialModalCloseButton() { | ||
return getEditCredentialModal().find('.el-dialog__close').first(); | ||
} | ||
|
||
/** | ||
* Actions | ||
*/ | ||
|
||
export function setCredentialConnectionParameterInputByName(name: string, value: string) { | ||
getCredentialConnectionParameterInputByName(name).type(value); | ||
} | ||
|
||
export function saveCredential() { | ||
getCredentialSaveButton().click({ force: true }); | ||
} | ||
|
||
export function closeCredentialModal() { | ||
getCredentialModalCloseButton().click(); | ||
} | ||
|
||
export function setCredentialValues(values: Record<string, any>, save = true) { | ||
Object.entries(values).forEach(([key, value]) => { | ||
setCredentialConnectionParameterInputByName(key, value); | ||
}); | ||
|
||
if (save) { | ||
saveCredential(); | ||
closeCredentialModal(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/** | ||
* Getters | ||
*/ | ||
|
||
export function getCredentialSelect(eq = 0) { | ||
return cy.getByTestId('node-credentials-select').eq(eq); | ||
} | ||
|
||
export function getCreateNewCredentialOption() { | ||
return cy.getByTestId('node-credentials-select-item-new'); | ||
} | ||
|
||
export function getBackToCanvasButton() { | ||
return cy.getByTestId('back-to-canvas'); | ||
} | ||
|
||
export function getExecuteNodeButton() { | ||
return cy.getByTestId('node-execute-button'); | ||
} | ||
|
||
export function getParameterInputByName(name: string) { | ||
return cy.getByTestId(`parameter-input-${name}`); | ||
} | ||
|
||
export function getInputPanel() { | ||
return cy.getByTestId('input-panel'); | ||
} | ||
|
||
export function getMainPanel() { | ||
return cy.getByTestId('node-parameters'); | ||
} | ||
|
||
export function getOutputPanel() { | ||
return cy.getByTestId('output-panel'); | ||
} | ||
|
||
export function getOutputPanelDataContainer() { | ||
return getOutputPanel().getByTestId('ndv-data-container'); | ||
} | ||
|
||
export function getOutputPanelTable() { | ||
return getOutputPanelDataContainer().get('table'); | ||
} | ||
|
||
/** | ||
* Actions | ||
*/ | ||
|
||
export function openCredentialSelect(eq = 0) { | ||
getCredentialSelect(eq).click(); | ||
} | ||
|
||
export function setCredentialByName(name: string) { | ||
openCredentialSelect(); | ||
getCredentialSelect().contains(name).click(); | ||
} | ||
|
||
export function clickCreateNewCredential() { | ||
openCredentialSelect(); | ||
getCreateNewCredentialOption().click(); | ||
} | ||
|
||
export function clickGetBackToCanvas() { | ||
getBackToCanvasButton().click(); | ||
} | ||
|
||
export function clickExecuteNode() { | ||
getExecuteNodeButton().click(); | ||
} | ||
|
||
export function setParameterInputByName(name: string, value: string) { | ||
getParameterInputByName(name).clear().type(value); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import { ROUTES } from '../constants'; | ||
import { getManualChatModal } from './modals/chat-modal'; | ||
|
||
/** | ||
* Types | ||
*/ | ||
|
||
export type EndpointType = | ||
| 'ai_chain' | ||
| 'ai_document' | ||
| 'ai_embedding' | ||
| 'ai_languageModel' | ||
| 'ai_memory' | ||
| 'ai_outputParser' | ||
| 'ai_tool' | ||
| 'ai_retriever' | ||
| 'ai_textSplitter' | ||
| 'ai_vectorRetriever' | ||
| 'ai_vectorStore'; | ||
|
||
/** | ||
* Getters | ||
*/ | ||
|
||
export function getAddInputEndpointByType(nodeName: string, endpointType: EndpointType) { | ||
return cy.get( | ||
`.add-input-endpoint[data-jtk-scope-${endpointType}][data-endpoint-name="${nodeName}"]`, | ||
); | ||
} | ||
|
||
export function getNodeCreatorItems() { | ||
return cy.getByTestId('item-iterator-item'); | ||
} | ||
|
||
export function getExecuteWorkflowButton() { | ||
return cy.getByTestId('execute-workflow-button'); | ||
} | ||
|
||
export function getManualChatButton() { | ||
return cy.getByTestId('workflow-chat-button'); | ||
} | ||
|
||
export function getNodes() { | ||
return cy.getByTestId('canvas-node'); | ||
} | ||
|
||
export function getNodeByName(name: string) { | ||
return cy.getByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0); | ||
} | ||
|
||
export function getConnectionBySourceAndTarget(source: string, target: string) { | ||
return cy | ||
.get('.jtk-connector') | ||
.filter(`[data-source-node="${source}"][data-target-node="${target}"]`) | ||
.eq(0); | ||
} | ||
|
||
export function getNodeCreatorSearchBar() { | ||
return cy.getByTestId('node-creator-search-bar'); | ||
} | ||
|
||
export function getNodeCreatorPlusButton() { | ||
return cy.getByTestId('node-creator-plus-button'); | ||
} | ||
|
||
/** | ||
* Actions | ||
*/ | ||
|
||
export function addNodeToCanvas( | ||
nodeDisplayName: string, | ||
plusButtonClick = true, | ||
preventNdvClose?: boolean, | ||
action?: string, | ||
) { | ||
if (plusButtonClick) { | ||
getNodeCreatorPlusButton().click(); | ||
} | ||
|
||
getNodeCreatorSearchBar().type(nodeDisplayName); | ||
getNodeCreatorSearchBar().type('{enter}'); | ||
cy.wait(500); | ||
cy.get('body').then((body) => { | ||
if (body.find('[data-test-id=node-creator]').length > 0) { | ||
if (action) { | ||
cy.contains(action).click(); | ||
} else { | ||
// Select the first action | ||
cy.get('[data-keyboard-nav-type="action"]').eq(0).click(); | ||
} | ||
} | ||
}); | ||
|
||
if (!preventNdvClose) cy.get('body').type('{esc}'); | ||
} | ||
|
||
export function navigateToNewWorkflowPage(preventNodeViewUnload = true) { | ||
cy.visit(ROUTES.NEW_WORKFLOW_PAGE); | ||
cy.waitForLoad(); | ||
cy.window().then((win) => { | ||
win.preventNodeViewBeforeUnload = preventNodeViewUnload; | ||
}); | ||
} | ||
|
||
export function addSupplementalNodeToParent( | ||
nodeName: string, | ||
endpointType: EndpointType, | ||
parentNodeName: string, | ||
) { | ||
getAddInputEndpointByType(parentNodeName, endpointType).click({ force: true }); | ||
getNodeCreatorItems().contains(nodeName).click(); | ||
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist'); | ||
} | ||
|
||
export function addLanguageModelNodeToParent(nodeName: string, parentNodeName: string) { | ||
addSupplementalNodeToParent(nodeName, 'ai_languageModel', parentNodeName); | ||
} | ||
|
||
export function addMemoryNodeToParent(nodeName: string, parentNodeName: string) { | ||
addSupplementalNodeToParent(nodeName, 'ai_memory', parentNodeName); | ||
} | ||
|
||
export function addToolNodeToParent(nodeName: string, parentNodeName: string) { | ||
addSupplementalNodeToParent(nodeName, 'ai_tool', parentNodeName); | ||
} | ||
|
||
export function addOutputParserNodeToParent(nodeName: string, parentNodeName: string) { | ||
addSupplementalNodeToParent(nodeName, 'ai_outputParser', parentNodeName); | ||
} | ||
|
||
export function clickExecuteWorkflowButton() { | ||
getExecuteWorkflowButton().click(); | ||
} | ||
|
||
export function clickManualChatButton() { | ||
getManualChatButton().click(); | ||
getManualChatModal().should('be.visible'); | ||
} | ||
|
||
export function openNode(nodeName: string) { | ||
getNodeByName(nodeName).dblclick(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.