mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(editor): Add AI Starter pack experiment (no-changelog) (#17497)
This commit is contained in:
committed by
GitHub
parent
79306b040e
commit
5ddf290795
@@ -76,6 +76,7 @@
|
|||||||
"generic.service": "the service",
|
"generic.service": "the service",
|
||||||
"generic.star": "Star",
|
"generic.star": "Star",
|
||||||
"generic.tryNow": "Try now",
|
"generic.tryNow": "Try now",
|
||||||
|
"generic.startNow": "Start now",
|
||||||
"generic.dismiss": "Dismiss",
|
"generic.dismiss": "Dismiss",
|
||||||
"generic.unsavedWork.confirmMessage.headline": "Save changes before leaving?",
|
"generic.unsavedWork.confirmMessage.headline": "Save changes before leaving?",
|
||||||
"generic.unsavedWork.confirmMessage.message": "If you don't save, you will lose your changes.",
|
"generic.unsavedWork.confirmMessage.message": "If you don't save, you will lose your changes.",
|
||||||
@@ -2679,6 +2680,10 @@
|
|||||||
"workflows.create.folder.toast.title": "Workflow successfully created in \"{projectName}\", within \"{folderName}\"",
|
"workflows.create.folder.toast.title": "Workflow successfully created in \"{projectName}\", within \"{folderName}\"",
|
||||||
"workflows.create.project.toast.text": "All members from {projectName} will have access to this workflow.",
|
"workflows.create.project.toast.text": "All members from {projectName} will have access to this workflow.",
|
||||||
"workflows.deactivated": "Workflow deactivated",
|
"workflows.deactivated": "Workflow deactivated",
|
||||||
|
"workflows.ai.starter.collection.callout": "Learn how to build AI Agents in n8n",
|
||||||
|
"workflows.ai.starter.collection.card": "Learn how to build AI Agents",
|
||||||
|
"workflows.ai.starter.collection.folder.name": "🎁 n8n basics: Learn how to build Agents in n8n",
|
||||||
|
"workflows.ai.starter.collection.error": "Error loading AI Agent starter collection. Please try again later.",
|
||||||
"workflowSelectorParameterInput.createNewSubworkflow.name": "My Sub-Workflow",
|
"workflowSelectorParameterInput.createNewSubworkflow.name": "My Sub-Workflow",
|
||||||
"importCurlModal.title": "Import cURL command",
|
"importCurlModal.title": "Import cURL command",
|
||||||
"importCurlModal.input.label": "cURL Command",
|
"importCurlModal.input.label": "cURL Command",
|
||||||
|
|||||||
@@ -31,4 +31,5 @@ export const STORES = {
|
|||||||
FOLDERS: 'folders',
|
FOLDERS: 'folders',
|
||||||
MODULES: 'modules',
|
MODULES: 'modules',
|
||||||
FOCUS_PANEL: 'focusPanel',
|
FOCUS_PANEL: 'focusPanel',
|
||||||
|
AI_TEMPLATES_STARTER_COLLECTION: 'aiTemplatesStarterCollection',
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
|||||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||||
import { useRunWorkflow } from '@/composables/useRunWorkflow';
|
import { useRunWorkflow } from '@/composables/useRunWorkflow';
|
||||||
import { useWorkflowSaving } from '@/composables/useWorkflowSaving';
|
import { useWorkflowSaving } from '@/composables/useWorkflowSaving';
|
||||||
|
import { useAITemplatesStarterCollectionStore } from '@/experiments/aiTemplatesStarterCollection/stores/aiTemplatesStarterCollection.store';
|
||||||
|
|
||||||
export type SimplifiedExecution = Pick<
|
export type SimplifiedExecution = Pick<
|
||||||
IExecutionResponse,
|
IExecutionResponse,
|
||||||
@@ -42,6 +43,7 @@ export async function executionFinished(
|
|||||||
) {
|
) {
|
||||||
const workflowsStore = useWorkflowsStore();
|
const workflowsStore = useWorkflowsStore();
|
||||||
const uiStore = useUIStore();
|
const uiStore = useUIStore();
|
||||||
|
const aiTemplatesStarterCollectionStore = useAITemplatesStarterCollectionStore();
|
||||||
|
|
||||||
workflowsStore.lastAddedExecutingNode = null;
|
workflowsStore.lastAddedExecutingNode = null;
|
||||||
|
|
||||||
@@ -63,6 +65,12 @@ export async function executionFinished(
|
|||||||
status: data.status,
|
status: data.status,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (workflow.meta.templateId.startsWith('035_template_onboarding')) {
|
||||||
|
aiTemplatesStarterCollectionStore.trackUserExecutedWorkflow(
|
||||||
|
workflow.meta.templateId.split('-').pop() ?? '',
|
||||||
|
data.status,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uiStore.setProcessingExecutionResults(true);
|
uiStore.setProcessingExecutionResults(true);
|
||||||
|
|||||||
@@ -761,10 +761,18 @@ export const FOCUS_PANEL_EXPERIMENT = {
|
|||||||
variant: 'variant',
|
variant: 'variant',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TEMPLATE_ONBOARDING_EXPERIMENT = {
|
||||||
|
name: '035_template_onboarding',
|
||||||
|
control: 'control',
|
||||||
|
variantStarterPack: 'variant-starter-pack',
|
||||||
|
variantSuggestedTemplates: 'variant-suggested-templates',
|
||||||
|
};
|
||||||
|
|
||||||
export const EXPERIMENTS_TO_TRACK = [
|
export const EXPERIMENTS_TO_TRACK = [
|
||||||
WORKFLOW_BUILDER_EXPERIMENT.name,
|
WORKFLOW_BUILDER_EXPERIMENT.name,
|
||||||
RAG_STARTER_WORKFLOW_EXPERIMENT.name,
|
RAG_STARTER_WORKFLOW_EXPERIMENT.name,
|
||||||
EXTRA_TEMPLATE_LINKS_EXPERIMENT.name,
|
EXTRA_TEMPLATE_LINKS_EXPERIMENT.name,
|
||||||
|
TEMPLATE_ONBOARDING_EXPERIMENT.name,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const MFA_FORM = {
|
export const MFA_FORM = {
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import { useFoldersStore } from '@/stores/folders.store';
|
||||||
|
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||||
|
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||||
|
import { STORES } from '@n8n/stores';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { AGENT_WITH_MEMORY } from '../workflows/1_agent_with_memory';
|
||||||
|
import { AGENT_WITH_TOOLS } from '../workflows/2_agent_with_tools';
|
||||||
|
import { AGENT_WITH_KNOWLEDGE } from '../workflows/3_agent_with_knowledge';
|
||||||
|
import { useTelemetry } from '@/composables/useTelemetry';
|
||||||
|
import { usePostHog } from '@/stores/posthog.store';
|
||||||
|
import { TEMPLATE_ONBOARDING_EXPERIMENT } from '@/constants';
|
||||||
|
import { useLocalStorage } from '@vueuse/core';
|
||||||
|
import { useI18n } from '@n8n/i18n';
|
||||||
|
|
||||||
|
const LOCAL_STORAGE_SETTING_KEY = 'N8N_AI_TEMPLATES_STARTER_COLLECTION_CALL_OUT_DISMISSED';
|
||||||
|
|
||||||
|
export const useAITemplatesStarterCollectionStore = defineStore(
|
||||||
|
STORES.AI_TEMPLATES_STARTER_COLLECTION,
|
||||||
|
() => {
|
||||||
|
const telemetry = useTelemetry();
|
||||||
|
const i18n = useI18n();
|
||||||
|
|
||||||
|
const foldersStore = useFoldersStore();
|
||||||
|
const workflowsStore = useWorkflowsStore();
|
||||||
|
const posthogStore = usePostHog();
|
||||||
|
|
||||||
|
const calloutDismissedRef = useLocalStorage(LOCAL_STORAGE_SETTING_KEY, false);
|
||||||
|
const calloutDismissed = computed(() => calloutDismissedRef.value);
|
||||||
|
|
||||||
|
const isFeatureEnabled = computed(() => {
|
||||||
|
return (
|
||||||
|
posthogStore.getVariant(TEMPLATE_ONBOARDING_EXPERIMENT.name) ===
|
||||||
|
TEMPLATE_ONBOARDING_EXPERIMENT.variantStarterPack
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const dismissCallout = () => {
|
||||||
|
calloutDismissedRef.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createStarterWorkflows = async (projectId: string, parentFolderId?: string) => {
|
||||||
|
const collectionFolder = await foldersStore.createFolder(
|
||||||
|
i18n.baseText('workflows.ai.starter.collection.folder.name'),
|
||||||
|
projectId,
|
||||||
|
parentFolderId,
|
||||||
|
);
|
||||||
|
const agentWitheMemory: WorkflowDataCreate = {
|
||||||
|
...AGENT_WITH_MEMORY,
|
||||||
|
parentFolderId: collectionFolder.id,
|
||||||
|
};
|
||||||
|
const agentWithTools: WorkflowDataCreate = {
|
||||||
|
...AGENT_WITH_TOOLS,
|
||||||
|
parentFolderId: collectionFolder.id,
|
||||||
|
};
|
||||||
|
const agentWithKnowledge: WorkflowDataCreate = {
|
||||||
|
...AGENT_WITH_KNOWLEDGE,
|
||||||
|
parentFolderId: collectionFolder.id,
|
||||||
|
};
|
||||||
|
await workflowsStore.createNewWorkflow(agentWithKnowledge);
|
||||||
|
await workflowsStore.createNewWorkflow(agentWithTools);
|
||||||
|
await workflowsStore.createNewWorkflow(agentWitheMemory);
|
||||||
|
dismissCallout();
|
||||||
|
return collectionFolder;
|
||||||
|
};
|
||||||
|
|
||||||
|
const trackUserCreatedStarterCollection = (source: 'card' | 'callout') => {
|
||||||
|
telemetry.track('User created AI templates starter collection', {
|
||||||
|
source,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const trackUserDismissedCallout = () => {
|
||||||
|
telemetry.track('User dismissed AI templates starter collection callout');
|
||||||
|
};
|
||||||
|
|
||||||
|
const trackUserOpenedWorkflow = (template: string) => {
|
||||||
|
telemetry.track('User opened AI template workflow', {
|
||||||
|
template,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const trackUserExecutedWorkflow = (template: string, status: string) => {
|
||||||
|
telemetry.track('User executed AI template', {
|
||||||
|
template,
|
||||||
|
status,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
isFeatureEnabled,
|
||||||
|
calloutDismissed,
|
||||||
|
dismissCallout,
|
||||||
|
createStarterWorkflows,
|
||||||
|
trackUserCreatedStarterCollection,
|
||||||
|
trackUserDismissedCallout,
|
||||||
|
trackUserOpenedWorkflow,
|
||||||
|
trackUserExecutedWorkflow,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||||
|
|
||||||
|
export const AGENT_WITH_MEMORY: WorkflowDataCreate = {
|
||||||
|
meta: {
|
||||||
|
templateId: '035_template_onboarding-agent_with_memory',
|
||||||
|
},
|
||||||
|
name: '1. Agent with memory',
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: '536fa635-c0c8-4fd1-84ef-d19585be64cf',
|
||||||
|
name: 'When chat message received',
|
||||||
|
webhookId: '9baee3d2-b9cb-4333-b4d5-3b07db8da9b2',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.chatTrigger',
|
||||||
|
typeVersion: 1.1,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1393095b-ec84-4514-b481-432609d1a5c5',
|
||||||
|
name: 'AI Agent',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.agent',
|
||||||
|
typeVersion: 2.1,
|
||||||
|
position: [208, 0],
|
||||||
|
parameters: {
|
||||||
|
options: {
|
||||||
|
systemMessage: '=You are a helpful assistant\n\nTodays date: {{ $now }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '658eb127-5a9d-4404-9270-72ef1da36ea3',
|
||||||
|
name: 'Sticky Note',
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [-464, -32],
|
||||||
|
parameters: {
|
||||||
|
content:
|
||||||
|
'### Readme\nChat with an AI agent that remembers your previous messages during a conversation.\n\n**Quick Start**\n1. Open the **Model** node to claim your free API credits and connect to OpenAI. \n2. Click the **Open chat** button to start talking to the agent. Provide it with some information to remember, like your name.\n3. Ask a follow-up question about the information you shared: "What\'s my name?"\n\n---\n\n**Learn More**\n- [AI Agent node documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/)\n- [Simple Memory node documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.memorybufferwindow/)',
|
||||||
|
height: 396,
|
||||||
|
width: 392,
|
||||||
|
color: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '186173c3-d043-4485-b939-9fca3d1e906f',
|
||||||
|
name: 'Model',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1.2,
|
||||||
|
position: [160, 240],
|
||||||
|
parameters: {
|
||||||
|
model: {
|
||||||
|
__rl: true,
|
||||||
|
mode: 'list',
|
||||||
|
value: 'gpt-4.1-mini',
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'dadaaa19-8378-4e23-9573-f9d3ff52c884',
|
||||||
|
name: 'Memory',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.memoryBufferWindow',
|
||||||
|
typeVersion: 1.3,
|
||||||
|
position: [352, 240],
|
||||||
|
parameters: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {
|
||||||
|
'When chat message received': {
|
||||||
|
main: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'main',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Model: {
|
||||||
|
ai_languageModel: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_languageModel',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Memory: {
|
||||||
|
ai_memory: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_memory',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// parentFolderId: newFolder.id,
|
||||||
|
};
|
||||||
@@ -0,0 +1,371 @@
|
|||||||
|
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||||
|
|
||||||
|
export const AGENT_WITH_TOOLS: WorkflowDataCreate = {
|
||||||
|
meta: {
|
||||||
|
templateId: '035_template_onboarding-agent_with_tools',
|
||||||
|
},
|
||||||
|
name: '2. Agent with tools',
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.chatTrigger',
|
||||||
|
typeVersion: 1.1,
|
||||||
|
position: [-48, -16],
|
||||||
|
id: 'f6c9fe3c-cbde-4514-9fcf-9d618526965c',
|
||||||
|
name: 'When chat message received',
|
||||||
|
webhookId: '1bf95244-fbc3-4210-9420-f34a45c4f5f5',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.agent',
|
||||||
|
typeVersion: 2.1,
|
||||||
|
position: [208, -16],
|
||||||
|
id: '5db1043f-de79-425a-a66b-8288c3aaa7df',
|
||||||
|
name: 'AI Agent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.memoryBufferWindow',
|
||||||
|
typeVersion: 1.3,
|
||||||
|
position: [208, 288],
|
||||||
|
id: '29f1ba2f-7511-4771-958a-be6463a64d83',
|
||||||
|
name: 'Simple Memory',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
operation: 'update',
|
||||||
|
documentId: {
|
||||||
|
__rl: true,
|
||||||
|
value: '1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Demo',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit?usp=drivesdk',
|
||||||
|
},
|
||||||
|
sheetName: {
|
||||||
|
__rl: true,
|
||||||
|
value: 'gid=0',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Sheet1',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit#gid=0',
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
mappingMode: 'defineBelow',
|
||||||
|
value: {
|
||||||
|
ID: "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('ID__using_to_match_', ``, 'string') }}",
|
||||||
|
Name: "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Name', ``, 'string') }}",
|
||||||
|
},
|
||||||
|
matchingColumns: ['ID'],
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
id: 'ID',
|
||||||
|
displayName: 'ID',
|
||||||
|
required: false,
|
||||||
|
defaultMatch: false,
|
||||||
|
display: true,
|
||||||
|
type: 'string',
|
||||||
|
canBeUsedToMatch: true,
|
||||||
|
removed: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Name',
|
||||||
|
displayName: 'Name',
|
||||||
|
required: false,
|
||||||
|
defaultMatch: false,
|
||||||
|
display: true,
|
||||||
|
type: 'string',
|
||||||
|
canBeUsedToMatch: true,
|
||||||
|
removed: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'row_number',
|
||||||
|
displayName: 'row_number',
|
||||||
|
required: false,
|
||||||
|
defaultMatch: false,
|
||||||
|
display: true,
|
||||||
|
type: 'number',
|
||||||
|
canBeUsedToMatch: true,
|
||||||
|
readOnly: true,
|
||||||
|
removed: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
attemptToConvertTypes: false,
|
||||||
|
convertFieldsToString: false,
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.googleSheetsTool',
|
||||||
|
typeVersion: 4.6,
|
||||||
|
position: [656, 640],
|
||||||
|
id: '24d82ca2-b666-415b-9020-f88cf3e095e6',
|
||||||
|
name: 'Update',
|
||||||
|
credentials: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
operation: 'append',
|
||||||
|
documentId: {
|
||||||
|
__rl: true,
|
||||||
|
value: '1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Demo',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit?usp=drivesdk',
|
||||||
|
},
|
||||||
|
sheetName: {
|
||||||
|
__rl: true,
|
||||||
|
value: 'gid=0',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Sheet1',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit#gid=0',
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
mappingMode: 'defineBelow',
|
||||||
|
value: {
|
||||||
|
// eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string
|
||||||
|
ID: "={{ `${Math.random()}`.replace('0.', '') }}",
|
||||||
|
Name: "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Name', ``, 'string') }}",
|
||||||
|
},
|
||||||
|
matchingColumns: ['ID'],
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
id: 'ID',
|
||||||
|
displayName: 'ID',
|
||||||
|
required: false,
|
||||||
|
defaultMatch: false,
|
||||||
|
display: true,
|
||||||
|
type: 'string',
|
||||||
|
canBeUsedToMatch: true,
|
||||||
|
removed: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Name',
|
||||||
|
displayName: 'Name',
|
||||||
|
required: false,
|
||||||
|
defaultMatch: false,
|
||||||
|
display: true,
|
||||||
|
type: 'string',
|
||||||
|
canBeUsedToMatch: true,
|
||||||
|
removed: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'row_number',
|
||||||
|
displayName: 'row_number',
|
||||||
|
required: false,
|
||||||
|
defaultMatch: false,
|
||||||
|
display: true,
|
||||||
|
type: 'number',
|
||||||
|
canBeUsedToMatch: true,
|
||||||
|
readOnly: true,
|
||||||
|
removed: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
attemptToConvertTypes: false,
|
||||||
|
convertFieldsToString: false,
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.googleSheetsTool',
|
||||||
|
typeVersion: 4.6,
|
||||||
|
position: [464, 640],
|
||||||
|
id: 'a0554e4a-8a7a-480c-a9e6-5f9746252cdb',
|
||||||
|
name: 'Create',
|
||||||
|
credentials: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
documentId: {
|
||||||
|
__rl: true,
|
||||||
|
value: '1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Demo',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit?usp=drivesdk',
|
||||||
|
},
|
||||||
|
sheetName: {
|
||||||
|
__rl: true,
|
||||||
|
value: 'gid=0',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Sheet1',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit#gid=0',
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.googleSheetsTool',
|
||||||
|
typeVersion: 4.6,
|
||||||
|
position: [480, 288],
|
||||||
|
id: 'ef476f0d-bdfe-4f41-8690-fb270ed82469',
|
||||||
|
name: 'Read',
|
||||||
|
credentials: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
operation: 'delete',
|
||||||
|
documentId: {
|
||||||
|
__rl: true,
|
||||||
|
value: '1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Demo',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit?usp=drivesdk',
|
||||||
|
},
|
||||||
|
sheetName: {
|
||||||
|
__rl: true,
|
||||||
|
value: 'gid=0',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'Sheet1',
|
||||||
|
cachedResultUrl:
|
||||||
|
'https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit#gid=0',
|
||||||
|
},
|
||||||
|
startIndex:
|
||||||
|
"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_Row_Number', ``, 'number') }}",
|
||||||
|
numberToDelete:
|
||||||
|
"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Number_of_Rows_to_Delete', ``, 'number') }}",
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.googleSheetsTool',
|
||||||
|
typeVersion: 4.6,
|
||||||
|
position: [864, 640],
|
||||||
|
id: 'd0cca35f-9e74-4935-92e2-9b5e37f1c7f4',
|
||||||
|
name: 'Delete',
|
||||||
|
credentials: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content:
|
||||||
|
"### Readme\nThis agent uses tools to interact with a simple spreadsheet of orders.\n\n**Quick Start**\n1. Copy this [spreadsheet](https://docs.google.com/spreadsheets/d/1vbFb2dhys1VafAmX-hRtiyrEDgNKj_xaAA6ZmH09EL8/edit?usp=sharing) into your Google Drive.\n2. Open the **Read** tool and connect your Google account by creating a credential and selecting the spreadsheet.\n3. Ask the Agent to calculate the total in the amount column, you should see it use the **Read** tool followed by the **Calculator**.\n4. Try some other questions and see how the agent responds.\n5. Use what you've learned to connect the other tools in the **Next steps** section.\n\n---\n\n**Learn More**\n- [Google sheet tool documentation](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/?utm_source=n8n_app&utm_medium=node_settings_modal-credential_link&utm_campaign=n8n-nodes-base.googleSheetsTool)\n- [Calculator tool documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolcalculator/)",
|
||||||
|
height: 460,
|
||||||
|
width: 440,
|
||||||
|
color: 4,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [-576, -32],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: 'e57c1fe3-3ef9-447c-81e3-bdf8717706b9',
|
||||||
|
name: 'Sticky Note',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.toolCalculator',
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [624, 288],
|
||||||
|
id: '49030d8b-0818-455b-a472-356b620566c4',
|
||||||
|
name: 'Calculator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
model: {
|
||||||
|
__rl: true,
|
||||||
|
mode: 'list',
|
||||||
|
value: 'gpt-4.1-mini',
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1.2,
|
||||||
|
position: [48, 288],
|
||||||
|
id: '67c78b12-b088-41b4-aeb4-70a7f056c9a7',
|
||||||
|
name: 'Model',
|
||||||
|
credentials: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content: '## 🛠️ Tools',
|
||||||
|
height: 224,
|
||||||
|
width: 368,
|
||||||
|
color: 7,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [400, 224],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: '14c03c2d-e0ea-4958-94c1-3598e5c273d9',
|
||||||
|
name: 'Sticky Note1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content:
|
||||||
|
'## 🛠️ Next steps\n\nConnect these tools to perform create, read and update actions on your order list.',
|
||||||
|
height: 320,
|
||||||
|
width: 592,
|
||||||
|
color: 7,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [400, 496],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: 'a683cb43-e740-497e-bb01-edebfe39a832',
|
||||||
|
name: 'Sticky Note2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {
|
||||||
|
'When chat message received': {
|
||||||
|
main: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'main',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'Simple Memory': {
|
||||||
|
ai_memory: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_memory',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Update: {
|
||||||
|
ai_tool: [[]],
|
||||||
|
},
|
||||||
|
Create: {
|
||||||
|
ai_tool: [[]],
|
||||||
|
},
|
||||||
|
Read: {
|
||||||
|
ai_tool: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_tool',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Delete: {
|
||||||
|
ai_tool: [[]],
|
||||||
|
},
|
||||||
|
Calculator: {
|
||||||
|
ai_tool: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_tool',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Model: {
|
||||||
|
ai_languageModel: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_languageModel',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||||
|
|
||||||
|
export const AGENT_WITH_KNOWLEDGE: WorkflowDataCreate = {
|
||||||
|
meta: {
|
||||||
|
templateId: '035_template_onboarding-agent_with_knowledge',
|
||||||
|
},
|
||||||
|
name: '3. Agent with knowledge',
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
formTitle: 'Upload your data to test RAG',
|
||||||
|
formFields: {
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
fieldLabel: 'Upload your file(s)',
|
||||||
|
fieldType: 'file',
|
||||||
|
acceptFileTypes: '.pdf, .csv',
|
||||||
|
requiredField: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.formTrigger',
|
||||||
|
typeVersion: 2.2,
|
||||||
|
position: [-368, -304],
|
||||||
|
id: 'e45eaedc-7ed9-4fd6-b79b-82a155734bce',
|
||||||
|
name: 'Upload your file here',
|
||||||
|
webhookId: '82848bc4-5ea2-4e5a-8bb6-3c09b94a8c5d',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.embeddingsOpenAi',
|
||||||
|
typeVersion: 1.2,
|
||||||
|
position: [288, 176],
|
||||||
|
id: 'f9f1745a-9c6d-42cf-8f8b-19a1c4c91b77',
|
||||||
|
name: 'Embeddings OpenAI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
dataType: 'binary',
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.documentDefaultDataLoader',
|
||||||
|
typeVersion: 1.1,
|
||||||
|
position: [80, -144],
|
||||||
|
id: '56da285f-9ad9-4cb4-a7d4-fb0f035e9071',
|
||||||
|
name: 'Default Data Loader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content:
|
||||||
|
'### Readme\nLoad your data into a vector database with the 📚 **Load Data** flow, and then use your data as chat context with the 🐕 **Retriever** flow.\n\n**Quick start**\n1. Click on the `Execute Workflow` button to run the 📚 **Load Data** flow.\n2. Click on `Open Chat` button to run the 🐕 **Retriever** flow. Then ask a question about content from your document(s)\n\n\nFor more info, check [our docs on RAG in n8n](https://docs.n8n.io/advanced-ai/rag-in-n8n/).',
|
||||||
|
height: 300,
|
||||||
|
width: 440,
|
||||||
|
color: 4,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [-896, -368],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: '72cb28c7-572b-41ce-ba4c-2dd0dc80acb4',
|
||||||
|
name: 'Sticky Note',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content: '### 📚 Load Data Flow',
|
||||||
|
height: 460,
|
||||||
|
width: 700,
|
||||||
|
color: 7,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [-416, -368],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: '075a4895-8b5f-487b-b7ff-8766aa1d1450',
|
||||||
|
name: 'Sticky Note1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
mode: 'insert',
|
||||||
|
memoryKey: {
|
||||||
|
__rl: true,
|
||||||
|
value: 'vector_store_key',
|
||||||
|
mode: 'list',
|
||||||
|
cachedResultName: 'vector_store_key',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.vectorStoreInMemory',
|
||||||
|
typeVersion: 1.2,
|
||||||
|
position: [-176, -304],
|
||||||
|
id: 'd24732cb-b6b4-4eb6-ad47-1f290f0da13d',
|
||||||
|
name: 'Insert Data to Store',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
mode: 'retrieve-as-tool',
|
||||||
|
toolName: 'knowledge_base',
|
||||||
|
toolDescription: 'Use this knowledge base to answer questions from the user',
|
||||||
|
memoryKey: {
|
||||||
|
__rl: true,
|
||||||
|
mode: 'list',
|
||||||
|
value: 'vector_store_key',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.vectorStoreInMemory',
|
||||||
|
typeVersion: 1.2,
|
||||||
|
position: [704, -96],
|
||||||
|
id: '8915e9b6-2a6c-472c-b043-78c1d77888ae',
|
||||||
|
name: 'Query Data Tool',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.agent',
|
||||||
|
typeVersion: 2,
|
||||||
|
position: [704, -320],
|
||||||
|
id: 'a2baaa1d-beee-40a2-8b5f-757b2b1aaca9',
|
||||||
|
name: 'AI Agent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.chatTrigger',
|
||||||
|
typeVersion: 1.1,
|
||||||
|
position: [480, -320],
|
||||||
|
id: 'c0a831dd-362c-4352-9409-bfe8c2e6f5ab',
|
||||||
|
name: 'When chat message received',
|
||||||
|
webhookId: '4091fa09-fb9a-4039-9411-7104d213f601',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
model: {
|
||||||
|
__rl: true,
|
||||||
|
mode: 'list',
|
||||||
|
value: 'gpt-4o-mini',
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1.2,
|
||||||
|
position: [480, -96],
|
||||||
|
id: '2ba103b5-7783-49a7-9693-a156383ca697',
|
||||||
|
name: 'OpenAI Chat Model',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content: '### 🐕 2. Retriever Flow',
|
||||||
|
height: 460,
|
||||||
|
width: 680,
|
||||||
|
color: 7,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [368, -368],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: '729f9492-3811-43d8-8230-d9ad78d910f7',
|
||||||
|
name: 'Sticky Note2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parameters: {
|
||||||
|
content:
|
||||||
|
'### Embeddings\n\nThe Insert and Retrieve operation use the same embedding node.\n\nThis is to ensure that they are using the **exact same embeddings and settings**.\n\nDifferent embeddings might not work at all, or have unintended consequences.\n',
|
||||||
|
height: 240,
|
||||||
|
width: 320,
|
||||||
|
color: 4,
|
||||||
|
},
|
||||||
|
type: 'n8n-nodes-base.stickyNote',
|
||||||
|
position: [432, 144],
|
||||||
|
typeVersion: 1,
|
||||||
|
id: '20a6b946-5588-4df2-b1f6-952fc82d166c',
|
||||||
|
name: 'Sticky Note3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {
|
||||||
|
'Upload your file here': {
|
||||||
|
main: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'Insert Data to Store',
|
||||||
|
type: 'main',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'Embeddings OpenAI': {
|
||||||
|
ai_embedding: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'Insert Data to Store',
|
||||||
|
type: 'ai_embedding',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: 'Query Data Tool',
|
||||||
|
type: 'ai_embedding',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'Default Data Loader': {
|
||||||
|
ai_document: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'Insert Data to Store',
|
||||||
|
type: 'ai_document',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'Query Data Tool': {
|
||||||
|
ai_tool: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_tool',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'When chat message received': {
|
||||||
|
main: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'main',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'OpenAI Chat Model': {
|
||||||
|
ai_languageModel: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
node: 'AI Agent',
|
||||||
|
type: 'ai_languageModel',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pinData: {},
|
||||||
|
};
|
||||||
@@ -137,6 +137,7 @@ import { useLogsStore } from '@/stores/logs.store';
|
|||||||
import { canvasEventBus } from '@/event-bus/canvas';
|
import { canvasEventBus } from '@/event-bus/canvas';
|
||||||
import CanvasChatButton from '@/components/canvas/elements/buttons/CanvasChatButton.vue';
|
import CanvasChatButton from '@/components/canvas/elements/buttons/CanvasChatButton.vue';
|
||||||
import { useFocusPanelStore } from '@/stores/focusPanel.store';
|
import { useFocusPanelStore } from '@/stores/focusPanel.store';
|
||||||
|
import { useAITemplatesStarterCollectionStore } from '@/experiments/aiTemplatesStarterCollection/stores/aiTemplatesStarterCollection.store';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'NodeView',
|
name: 'NodeView',
|
||||||
@@ -197,6 +198,7 @@ const foldersStore = useFoldersStore();
|
|||||||
const posthogStore = usePostHog();
|
const posthogStore = usePostHog();
|
||||||
const agentRequestStore = useAgentRequestStore();
|
const agentRequestStore = useAgentRequestStore();
|
||||||
const logsStore = useLogsStore();
|
const logsStore = useLogsStore();
|
||||||
|
const aiTemplatesStarterCollectionStore = useAITemplatesStarterCollectionStore();
|
||||||
|
|
||||||
const { addBeforeUnloadEventBindings, removeBeforeUnloadEventBindings } = useBeforeUnload({
|
const { addBeforeUnloadEventBindings, removeBeforeUnloadEventBindings } = useBeforeUnload({
|
||||||
route,
|
route,
|
||||||
@@ -500,6 +502,12 @@ async function initializeWorkspaceForExistingWorkflow(id: string) {
|
|||||||
trackOpenWorkflowFromOnboardingTemplate();
|
trackOpenWorkflowFromOnboardingTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (workflowData.meta?.templateId?.startsWith('035_template_onboarding')) {
|
||||||
|
aiTemplatesStarterCollectionStore.trackUserOpenedWorkflow(
|
||||||
|
workflowData.meta.templateId.split('-').pop() ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await projectsStore.setProjectNavActiveIdByWorkflowHomeProject(workflowData.homeProject);
|
await projectsStore.setProjectNavActiveIdByWorkflowHomeProject(workflowData.homeProject);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.httpStatusCode === 404) {
|
if (error.httpStatusCode === 404) {
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ import debounce from 'lodash/debounce';
|
|||||||
import { type IUser, PROJECT_ROOT } from 'n8n-workflow';
|
import { type IUser, PROJECT_ROOT } from 'n8n-workflow';
|
||||||
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
||||||
import { type LocationQueryRaw, useRoute, useRouter } from 'vue-router';
|
import { type LocationQueryRaw, useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useAITemplatesStarterCollectionStore } from '@/experiments/aiTemplatesStarterCollection/stores/aiTemplatesStarterCollection.store';
|
||||||
|
|
||||||
const SEARCH_DEBOUNCE_TIME = 300;
|
const SEARCH_DEBOUNCE_TIME = 300;
|
||||||
const FILTERS_DEBOUNCE_TIME = 100;
|
const FILTERS_DEBOUNCE_TIME = 100;
|
||||||
@@ -112,6 +113,7 @@ const foldersStore = useFoldersStore();
|
|||||||
const usageStore = useUsageStore();
|
const usageStore = useUsageStore();
|
||||||
const insightsStore = useInsightsStore();
|
const insightsStore = useInsightsStore();
|
||||||
const templatesStore = useTemplatesStore();
|
const templatesStore = useTemplatesStore();
|
||||||
|
const aiStarterTemplatesStore = useAITemplatesStarterCollectionStore();
|
||||||
|
|
||||||
const documentTitle = useDocumentTitle();
|
const documentTitle = useDocumentTitle();
|
||||||
const { callDebounced } = useDebounce();
|
const { callDebounced } = useDebounce();
|
||||||
@@ -369,6 +371,19 @@ const showRegisteredCommunityCTA = computed(
|
|||||||
() => isSelfHostedDeployment.value && !foldersEnabled.value && canUserRegisterCommunityPlus.value,
|
() => isSelfHostedDeployment.value && !foldersEnabled.value && canUserRegisterCommunityPlus.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const showAIStarterCollectionCallout = computed(() => {
|
||||||
|
return (
|
||||||
|
!loading.value &&
|
||||||
|
aiStarterTemplatesStore.isFeatureEnabled &&
|
||||||
|
!aiStarterTemplatesStore.calloutDismissed &&
|
||||||
|
!readOnlyEnv.value &&
|
||||||
|
// We want to show the callout only if the user has permissions to create folders and workflows
|
||||||
|
// but also on the overview page
|
||||||
|
(projectPages.isOverviewSubPage ||
|
||||||
|
(hasPermissionToCreateFolders.value && hasPermissionToCreateWorkflows.value))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WATCHERS, STORE SUBSCRIPTIONS AND EVENT BUS HANDLERS
|
* WATCHERS, STORE SUBSCRIPTIONS AND EVENT BUS HANDLERS
|
||||||
*/
|
*/
|
||||||
@@ -778,6 +793,45 @@ function isValidProjectId(projectId: string) {
|
|||||||
return projectsStore.availableProjects.some((project) => project.id === projectId);
|
return projectsStore.availableProjects.some((project) => project.id === projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createAIStarterWorkflows = async (source: 'card' | 'callout') => {
|
||||||
|
try {
|
||||||
|
const projectId = projectPages.isOverviewSubPage
|
||||||
|
? personalProject.value?.id
|
||||||
|
: (route.params.projectId as string);
|
||||||
|
if (typeof projectId !== 'string') {
|
||||||
|
toast.showError(new Error(), i18n.baseText('workflows.ai.starter.collection.error'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newFolder = await aiStarterTemplatesStore.createStarterWorkflows(
|
||||||
|
projectId,
|
||||||
|
currentFolderId.value ?? undefined,
|
||||||
|
);
|
||||||
|
// If we are on the overview page, navigate to the new folder
|
||||||
|
if (projectPages.isOverviewSubPage) {
|
||||||
|
await router.push({
|
||||||
|
name: VIEWS.PROJECTS_FOLDERS,
|
||||||
|
params: { projectId, folderId: newFolder.id },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If we are in a specific folder, just add the new folder to the list
|
||||||
|
workflowsAndFolders.value.unshift({
|
||||||
|
id: newFolder.id,
|
||||||
|
name: newFolder.name,
|
||||||
|
resource: 'folder',
|
||||||
|
createdAt: newFolder.createdAt,
|
||||||
|
updatedAt: newFolder.updatedAt,
|
||||||
|
subFolderCount: 0,
|
||||||
|
workflowCount: 3,
|
||||||
|
parentFolder: newFolder.parentFolder,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
aiStarterTemplatesStore.trackUserCreatedStarterCollection(source);
|
||||||
|
} catch (error) {
|
||||||
|
toast.showError(error, i18n.baseText('workflows.ai.starter.collection.error'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const openAIWorkflow = async (source: string) => {
|
const openAIWorkflow = async (source: string) => {
|
||||||
dismissEasyAICallout();
|
dismissEasyAICallout();
|
||||||
telemetry.track('User clicked test AI workflow', {
|
telemetry.track('User clicked test AI workflow', {
|
||||||
@@ -793,6 +847,11 @@ const openAIWorkflow = async (source: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dismissStarterCollectionCallout = () => {
|
||||||
|
aiStarterTemplatesStore.dismissCallout();
|
||||||
|
aiStarterTemplatesStore.trackUserDismissedCallout();
|
||||||
|
};
|
||||||
|
|
||||||
const dismissEasyAICallout = () => {
|
const dismissEasyAICallout = () => {
|
||||||
easyAICalloutVisible.value = false;
|
easyAICalloutVisible.value = false;
|
||||||
};
|
};
|
||||||
@@ -1610,7 +1669,34 @@ const onNameSubmit = async (name: string) => {
|
|||||||
</template>
|
</template>
|
||||||
<template #callout>
|
<template #callout>
|
||||||
<N8nCallout
|
<N8nCallout
|
||||||
v-if="!loading && showEasyAIWorkflowCallout && easyAICalloutVisible"
|
v-if="showAIStarterCollectionCallout"
|
||||||
|
theme="secondary"
|
||||||
|
icon="gift"
|
||||||
|
:class="$style['easy-ai-workflow-callout']"
|
||||||
|
>
|
||||||
|
{{ i18n.baseText('workflows.ai.starter.collection.callout') }}
|
||||||
|
<template #trailingContent>
|
||||||
|
<div :class="$style['callout-trailing-content']">
|
||||||
|
<N8nButton
|
||||||
|
data-test-id="easy-ai-button"
|
||||||
|
size="small"
|
||||||
|
type="secondary"
|
||||||
|
@click="createAIStarterWorkflows('callout')"
|
||||||
|
>
|
||||||
|
{{ i18n.baseText('generic.startNow') }}
|
||||||
|
</N8nButton>
|
||||||
|
<N8nIcon
|
||||||
|
size="small"
|
||||||
|
icon="x"
|
||||||
|
:title="i18n.baseText('generic.dismiss')"
|
||||||
|
class="clickable"
|
||||||
|
@click="dismissStarterCollectionCallout"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</N8nCallout>
|
||||||
|
<N8nCallout
|
||||||
|
v-else-if="!loading && showEasyAIWorkflowCallout && easyAICalloutVisible"
|
||||||
theme="secondary"
|
theme="secondary"
|
||||||
icon="bot"
|
icon="bot"
|
||||||
:class="$style['easy-ai-workflow-callout']"
|
:class="$style['easy-ai-workflow-callout']"
|
||||||
@@ -1804,7 +1890,26 @@ const onNameSubmit = async (name: string) => {
|
|||||||
</div>
|
</div>
|
||||||
</N8nCard>
|
</N8nCard>
|
||||||
<N8nCard
|
<N8nCard
|
||||||
v-if="showEasyAIWorkflowCallout"
|
v-if="showAIStarterCollectionCallout"
|
||||||
|
:class="$style.emptyStateCard"
|
||||||
|
hoverable
|
||||||
|
data-test-id="easy-ai-workflow-card"
|
||||||
|
@click="createAIStarterWorkflows('card')"
|
||||||
|
>
|
||||||
|
<div :class="$style.emptyStateCardContent">
|
||||||
|
<N8nIcon
|
||||||
|
:class="$style.emptyStateCardIcon"
|
||||||
|
:stroke-width="1.5"
|
||||||
|
icon="gift"
|
||||||
|
color="foreground-dark"
|
||||||
|
/>
|
||||||
|
<N8nText size="large" class="mt-xs pl-2xs pr-2xs">
|
||||||
|
{{ i18n.baseText('workflows.ai.starter.collection.card') }}
|
||||||
|
</N8nText>
|
||||||
|
</div>
|
||||||
|
</N8nCard>
|
||||||
|
<N8nCard
|
||||||
|
v-else-if="showEasyAIWorkflowCallout"
|
||||||
:class="$style.emptyStateCard"
|
:class="$style.emptyStateCard"
|
||||||
hoverable
|
hoverable
|
||||||
data-test-id="easy-ai-workflow-card"
|
data-test-id="easy-ai-workflow-card"
|
||||||
|
|||||||
Reference in New Issue
Block a user