feat(editor): Add pre-built agents experiment (#18124)

This commit is contained in:
Jaakko Husso
2025-08-09 10:28:14 +03:00
committed by GitHub
parent a3b625fc18
commit 5a69d2a2f3
44 changed files with 2635 additions and 653 deletions

View File

@@ -1,27 +1,152 @@
import { computed } from 'vue';
import { computed, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useTelemetry } from '@/composables/useTelemetry';
import { useRootStore } from '@n8n/stores/useRootStore';
import { useI18n } from '@n8n/i18n';
import { useUsersStore } from '@/stores/users.store';
import { VIEWS } from '@/constants';
import { getRagStarterWorkflowJson } from '@/utils/easyAiWorkflowUtils';
import { updateCurrentUserSettings } from '@n8n/rest-api-client/api/users';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { usePostHog } from '@/stores/posthog.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useViewStacks } from '@/components/Node/NodeCreator/composables/useViewStacks';
import { updateCurrentUserSettings } from '@n8n/rest-api-client/api/users';
import {
NODE_CREATOR_OPEN_SOURCES,
PRE_BUILT_AGENTS_EXPERIMENT,
REGULAR_NODE_CREATOR_VIEW,
VIEWS,
} from '@/constants';
import {
getPrebuiltAgents,
getRagStarterWorkflowJson,
getSampleWorkflowByTemplateId,
isPrebuiltAgentTemplateId,
SampleTemplates,
} from '@/utils/templates/workflowSamples';
import type { INodeCreateElement, OpenTemplateElement } from '@/Interface';
export function useCalloutHelpers() {
const route = useRoute();
const router = useRouter();
const telemetry = useTelemetry();
const postHog = usePostHog();
const rootStore = useRootStore();
const workflowsStore = useWorkflowsStore();
const usersStore = useUsersStore();
const ndvStore = useNDVStore();
const nodeCreatorStore = useNodeCreatorStore();
const viewStacks = useViewStacks();
const nodeTypesStore = useNodeTypesStore();
const i18n = useI18n();
const openRagStarterTemplate = (nodeType?: string) => {
telemetry.track('User clicked on RAG callout', {
node_type: nodeType ?? null,
const isRagStarterCalloutVisible = computed(() => {
const template = getRagStarterWorkflowJson();
const routeTemplateId = route.query.templateId;
const workflowObject = workflowsStore.workflowObject;
const workflow = workflowsStore.getWorkflowById(workflowObject.id);
// Hide the RAG starter callout if we're currently on the RAG starter template
if ((routeTemplateId ?? workflow?.meta?.templateId) === template.meta.templateId) {
return false;
}
return true;
});
const getPreBuiltAgentNodeCreatorItems = (): OpenTemplateElement[] => {
const templates = getPrebuiltAgents();
return templates.map((template) => {
return {
key: template.template.meta.templateId,
type: 'openTemplate',
properties: {
templateId: template.template.meta.templateId,
title: template.name,
description: template.description,
nodes: template.nodes.flatMap((node) => {
const nodeType = nodeTypesStore.getNodeType(node.name, node.version);
if (!nodeType) {
return [];
}
return nodeType;
}),
},
};
});
};
const openPreBuiltAgentsCollection = async (options: {
telemetry: {
source: 'ndv' | 'nodeCreator';
nodeType?: string;
section?: string;
};
resetStacks?: boolean;
}) => {
telemetry.track('User opened pre-built Agents collection', {
source: options.telemetry.source,
node_type: options.telemetry.nodeType ?? null,
section: options.telemetry.section ?? null,
});
const template = getRagStarterWorkflowJson();
const items: INodeCreateElement[] = getPreBuiltAgentNodeCreatorItems();
ndvStore.setActiveNodeName(null);
nodeCreatorStore.setNodeCreatorState({
source: NODE_CREATOR_OPEN_SOURCES.TEMPLATES_CALLOUT,
createNodeActive: true,
nodeCreatorView: undefined,
connectionType: undefined,
});
await nextTick();
viewStacks.pushViewStack(
{
title: i18n.baseText('nodeCreator.preBuiltAgents.title'),
rootView: REGULAR_NODE_CREATOR_VIEW,
activeIndex: 0,
transitionDirection: 'in',
hasSearch: false,
preventBack: false,
items,
baselineItems: items,
mode: 'nodes',
hideActions: false,
},
{ resetStacks: options.resetStacks ?? false },
);
};
const openSampleWorkflowTemplate = (
templateId: string,
options: {
telemetry: {
source: 'ndv' | 'nodeCreator';
nodeType?: string;
section?: string;
};
},
) => {
if (templateId === SampleTemplates.RagStarterTemplate) {
telemetry.track('User clicked on RAG callout', {
node_type: options.telemetry.nodeType ?? null,
});
} else if (isPrebuiltAgentTemplateId(templateId)) {
telemetry.track('User inserted pre-built Agent', {
template: templateId,
source: options.telemetry.source,
node_type: options.telemetry.nodeType ?? null,
section: options.telemetry.section ?? null,
});
}
const template = getSampleWorkflowByTemplateId(templateId);
if (!template) {
return;
}
const { href } = router.resolve({
name: VIEWS.TEMPLATE_IMPORT,
@@ -32,19 +157,15 @@ export function useCalloutHelpers() {
window.open(href, '_blank');
};
const isRagStarterCalloutVisible = computed(() => {
const template = getRagStarterWorkflowJson();
const isPreBuiltAgentsExperimentEnabled = computed(() => {
return postHog.isVariantEnabled(
PRE_BUILT_AGENTS_EXPERIMENT.name,
PRE_BUILT_AGENTS_EXPERIMENT.variant,
);
});
const routeTemplateId = route.query.templateId;
const workflowObject = workflowsStore.workflowObject;
const workflow = workflowsStore.getWorkflowById(workflowObject.id); // @TODO Check if we actually need workflowObject here
// Hide the RAG starter callout if we're currently on the RAG starter template
if ((routeTemplateId ?? workflow?.meta?.templateId) === template.meta.templateId) {
return false;
}
return true;
const isPreBuiltAgentsCalloutVisible = computed(() => {
return isPreBuiltAgentsExperimentEnabled.value;
});
const isCalloutDismissed = (callout: string) => {
@@ -63,8 +184,11 @@ export function useCalloutHelpers() {
};
return {
openRagStarterTemplate,
openSampleWorkflowTemplate,
openPreBuiltAgentsCollection,
getPreBuiltAgentNodeCreatorItems,
isRagStarterCalloutVisible,
isPreBuiltAgentsCalloutVisible,
isCalloutDismissed,
dismissCallout,
};