feat(core): Add support for building LLM applications (#7235)

This extracts all core and editor changes from #7246 and #7137, so that
we can get these changes merged first.

ADO-1120

[DB Tests](https://github.com/n8n-io/n8n/actions/runs/6379749011)
[E2E Tests](https://github.com/n8n-io/n8n/actions/runs/6379751480)
[Workflow Tests](https://github.com/n8n-io/n8n/actions/runs/6379752828)

---------

Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: Alex Grozav <alex@grozav.com>
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-10-02 17:33:43 +02:00
committed by GitHub
parent 04dfcd73be
commit 00a4b8b0c6
93 changed files with 6209 additions and 728 deletions

View File

@@ -13,13 +13,216 @@ import {
TRIGGER_NODE_CREATOR_VIEW,
EMAIL_IMAP_NODE_TYPE,
DEFAULT_SUBCATEGORY,
AI_NODE_CREATOR_VIEW,
AI_CATEGORY_AGENTS,
AI_CATEGORY_CHAINS,
AI_CATEGORY_DOCUMENT_LOADERS,
AI_CATEGORY_LANGUAGE_MODELS,
AI_CATEGORY_MEMORY,
AI_CATEGORY_OUTPUTPARSER,
AI_CATEGORY_RETRIEVERS,
AI_CATEGORY_TEXT_SPLITTERS,
AI_CATEGORY_TOOLS,
AI_CATEGORY_VECTOR_STORES,
AI_SUBCATEGORY,
AI_CATEGORY_EMBEDDING,
AI_OTHERS_NODE_CREATOR_VIEW,
AI_UNCATEGORIZED_CATEGORY,
} from '@/constants';
import { useI18n } from '@/composables';
import { useNodeTypesStore } from '@/stores';
import type { SimplifiedNodeType } from '@/Interface';
import type { INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
export function TriggerView() {
export interface NodeViewItem {
key: string;
type: string;
properties: {
name?: string;
title: string;
icon: string;
iconProps?: {
color?: string;
};
connectionType?: NodeConnectionType;
panelClass?: string;
group?: string[];
description?: string;
forceIncludeNodes?: string[];
};
category?: string | string[];
}
interface NodeView {
value: string;
title: string;
info?: string;
subtitle?: string;
items: NodeViewItem[];
}
function getAiNodesBySubcategory(nodes: INodeTypeDescription[], subcategory: string) {
return nodes
.filter((node) => node.codex?.subcategories?.[AI_SUBCATEGORY]?.includes(subcategory))
.map((node) => ({
key: node.name,
type: 'node',
properties: {
group: [],
name: node.name,
displayName: node.displayName,
title: node.displayName,
description: node.description,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
icon: node.icon!,
},
}))
.sort((a, b) => a.properties.displayName.localeCompare(b.properties.displayName));
}
export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
const i18n = useI18n();
const nodeTypesStore = useNodeTypesStore();
const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS);
const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS);
return {
value: AI_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.aiPanel.aiNodes'),
subtitle: i18n.baseText('nodeCreator.aiPanel.selectAiNode'),
info: i18n.baseText('nodeCreator.aiPanel.infoBox'),
items: [
...chainNodes,
...agentNodes,
{
key: AI_OTHERS_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.aiPanel.aiOtherNodes'),
icon: 'robot',
description: i18n.baseText('nodeCreator.aiPanel.aiOtherNodesDescription'),
},
},
],
};
}
export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
const i18n = useI18n();
function getAISubcategoryProperties(nodeConnectionType: NodeConnectionType) {
return {
connectionType: nodeConnectionType,
iconProps: {
color: `var(--node-type-${nodeConnectionType}-color)`,
},
panelClass: `nodes-list-panel-${nodeConnectionType}`,
};
}
return {
value: AI_OTHERS_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.aiPanel.aiOtherNodes'),
subtitle: i18n.baseText('nodeCreator.aiPanel.selectAiNode'),
items: [
{
key: AI_CATEGORY_DOCUMENT_LOADERS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_DOCUMENT_LOADERS,
icon: 'file-import',
...getAISubcategoryProperties(NodeConnectionType.AiDocument),
},
},
{
key: AI_CATEGORY_LANGUAGE_MODELS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_LANGUAGE_MODELS,
icon: 'language',
...getAISubcategoryProperties(NodeConnectionType.AiLanguageModel),
},
},
{
key: AI_CATEGORY_MEMORY,
type: 'subcategory',
properties: {
title: AI_CATEGORY_MEMORY,
icon: 'brain',
...getAISubcategoryProperties(NodeConnectionType.AiMemory),
},
},
{
key: AI_CATEGORY_OUTPUTPARSER,
type: 'subcategory',
properties: {
title: AI_CATEGORY_OUTPUTPARSER,
icon: 'list',
...getAISubcategoryProperties(NodeConnectionType.AiOutputParser),
},
},
{
key: AI_CATEGORY_RETRIEVERS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_RETRIEVERS,
icon: 'search',
...getAISubcategoryProperties(NodeConnectionType.AiRetriever),
},
},
{
key: AI_CATEGORY_TEXT_SPLITTERS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_TEXT_SPLITTERS,
icon: 'grip-lines-vertical',
...getAISubcategoryProperties(NodeConnectionType.AiTextSplitter),
},
},
{
key: AI_CATEGORY_TOOLS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_TOOLS,
icon: 'tools',
...getAISubcategoryProperties(NodeConnectionType.AiTool),
},
},
{
key: AI_CATEGORY_EMBEDDING,
type: 'subcategory',
properties: {
title: AI_CATEGORY_EMBEDDING,
icon: 'vector-square',
...getAISubcategoryProperties(NodeConnectionType.AiEmbedding),
},
},
{
key: AI_CATEGORY_VECTOR_STORES,
type: 'subcategory',
properties: {
title: AI_CATEGORY_VECTOR_STORES,
icon: 'project-diagram',
...getAISubcategoryProperties(NodeConnectionType.AiVectorStore),
},
},
{
key: AI_UNCATEGORIZED_CATEGORY,
type: 'subcategory',
properties: {
title: AI_UNCATEGORIZED_CATEGORY,
icon: 'code',
},
},
],
};
}
export function TriggerView(nodes: SimplifiedNodeType[]) {
const i18n = useI18n();
const view: NodeView = {
value: TRIGGER_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.triggerHelperPanel.selectATrigger'),
subtitle: i18n.baseText('nodeCreator.triggerHelperPanel.selectATriggerDescription'),
@@ -96,12 +299,26 @@ export function TriggerView() {
},
],
};
const hasAINodes = (nodes ?? []).some((node) => node.codex?.categories?.includes(AI_SUBCATEGORY));
if (hasAINodes)
view.items.push({
key: AI_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.aiPanel.langchainAiNodes'),
icon: 'robot',
description: i18n.baseText('nodeCreator.aiPanel.nodesForAi'),
},
});
return view;
}
export function RegularView() {
export function RegularView(nodes: SimplifiedNodeType[]) {
const i18n = useI18n();
return {
const view: NodeView = {
value: REGULAR_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.triggerHelperPanel.whatHappensNext'),
items: [
@@ -149,15 +366,30 @@ export function RegularView() {
icon: 'file-alt',
},
},
{
key: TRIGGER_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.triggerHelperPanel.addAnotherTrigger'),
icon: 'bolt',
description: i18n.baseText('nodeCreator.triggerHelperPanel.addAnotherTriggerDescription'),
},
},
],
};
const hasAINodes = (nodes ?? []).some((node) => node.codex?.categories?.includes(AI_SUBCATEGORY));
if (hasAINodes)
view.items.push({
key: AI_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.aiPanel.langchainAiNodes'),
icon: 'robot',
description: i18n.baseText('nodeCreator.aiPanel.nodesForAi'),
},
});
view.items.push({
key: TRIGGER_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.triggerHelperPanel.addAnotherTrigger'),
icon: 'bolt',
description: i18n.baseText('nodeCreator.triggerHelperPanel.addAnotherTriggerDescription'),
},
});
return view;
}