From 8bb6e20cf2eb3806cd227de32359426054dad132 Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Wed, 27 Mar 2024 11:52:05 +0200 Subject: [PATCH 1/3] :zap: track basic llm optional prompts, include prompts in on save workflow event --- packages/cli/src/InternalHooks.ts | 10 +++++++--- packages/workflow/src/Constants.ts | 1 + packages/workflow/src/TelemetryHelpers.ts | 6 ++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/InternalHooks.ts b/packages/cli/src/InternalHooks.ts index 6c5b15dcdca7b..84dabf1ff8977 100644 --- a/packages/cli/src/InternalHooks.ts +++ b/packages/cli/src/InternalHooks.ts @@ -202,7 +202,11 @@ export class InternalHooks { } async onWorkflowSaved(user: User, workflow: IWorkflowDb, publicApi: boolean): Promise { - const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes); + const isCloudDeployment = config.getEnv('deployment.type') === 'cloud'; + + const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes, { + isCloudDeployment, + }); const notesCount = Object.keys(nodeGraph.notes).length; const overlappingCount = Object.values(nodeGraph.notes).filter( @@ -488,7 +492,7 @@ export class InternalHooks { ? this.eventBus.sendWorkflowEvent({ eventName: 'n8n.workflow.success', payload: sharedEventPayload, - }) + }) : this.eventBus.sendWorkflowEvent({ eventName: 'n8n.workflow.failed', payload: { @@ -498,7 +502,7 @@ export class InternalHooks { errorNodeId: telemetryProperties.error_node_id?.toString(), errorMessage: telemetryProperties.error_message?.toString(), }, - }), + }), ); void Promise.all([...promises, this.telemetry.trackWorkflowExecution(telemetryProperties)]); diff --git a/packages/workflow/src/Constants.ts b/packages/workflow/src/Constants.ts index 4ab3e315a0d1a..c4e7b9c1972ca 100644 --- a/packages/workflow/src/Constants.ts +++ b/packages/workflow/src/Constants.ts @@ -52,6 +52,7 @@ export const NODES_WITH_RENAMABLE_CONTENT = new Set([ //@n8n/n8n-nodes-langchain export const MANUAL_CHAT_TRIGGER_LANGCHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.manualChatTrigger'; export const AGENT_LANGCHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.agent'; +export const CHAIN_LLM_LANGCHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.chainLlm'; export const OPENAI_LANGCHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.openAi'; export const CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.chainSummarization'; diff --git a/packages/workflow/src/TelemetryHelpers.ts b/packages/workflow/src/TelemetryHelpers.ts index 5368d94ae8bb6..3c6d72de0f26b 100644 --- a/packages/workflow/src/TelemetryHelpers.ts +++ b/packages/workflow/src/TelemetryHelpers.ts @@ -13,6 +13,7 @@ import type { import { ApplicationError } from './errors/application.error'; import { AGENT_LANGCHAIN_NODE_TYPE, + CHAIN_LLM_LANGCHAIN_NODE_TYPE, CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE, HTTP_REQUEST_NODE_TYPE, LANGCHAIN_CUSTOM_TOOLS, @@ -275,6 +276,11 @@ export function generateNodesGraph( description: (node.parameters?.description as string) || '', }; } + + if (node.type === CHAIN_LLM_LANGCHAIN_NODE_TYPE) { + nodeItem.prompts = + (((node.parameters?.messages as IDataObject) || {}).messageValues as IDataObject[]) || []; + } } nodeGraph.nodes[index.toString()] = nodeItem; From 694510d60ea0e62fec933286791697587d8ae762 Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Wed, 27 Mar 2024 12:42:49 +0200 Subject: [PATCH 2/3] :zap: use nullish coalescing --- packages/workflow/src/TelemetryHelpers.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/workflow/src/TelemetryHelpers.ts b/packages/workflow/src/TelemetryHelpers.ts index 3c6d72de0f26b..dc2a6c58470da 100644 --- a/packages/workflow/src/TelemetryHelpers.ts +++ b/packages/workflow/src/TelemetryHelpers.ts @@ -169,7 +169,7 @@ export function generateNodesGraph( } if (node.type === AGENT_LANGCHAIN_NODE_TYPE) { - nodeItem.agent = (node.parameters.agent as string) || 'conversationalAgent'; + nodeItem.agent = (node.parameters.agent as string) ?? 'conversationalAgent'; } else if (node.type === HTTP_REQUEST_NODE_TYPE && node.typeVersion === 1) { try { nodeItem.domain = new URL(node.parameters.url as string).hostname; @@ -229,7 +229,7 @@ export function generateNodesGraph( if (options?.isCloudDeployment === true) { if (node.type === OPENAI_LANGCHAIN_NODE_TYPE) { nodeItem.prompts = - (((node.parameters?.messages as IDataObject) || {}).values as IDataObject[]) || []; + (((node.parameters?.messages as IDataObject) ?? {}).values as IDataObject[]) ?? []; } if (node.type === AGENT_LANGCHAIN_NODE_TYPE) { @@ -266,20 +266,20 @@ export function generateNodesGraph( if (node.type === CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE) { nodeItem.prompts = ( - (((node.parameters?.options as IDataObject) || {}) - .summarizationMethodAndPrompts as IDataObject) || {} + (((node.parameters?.options as IDataObject) ?? {}) + .summarizationMethodAndPrompts as IDataObject) ?? {} ).values as IDataObject; } if (LANGCHAIN_CUSTOM_TOOLS.includes(node.type)) { nodeItem.prompts = { - description: (node.parameters?.description as string) || '', + description: (node.parameters?.description as string) ?? '', }; } if (node.type === CHAIN_LLM_LANGCHAIN_NODE_TYPE) { nodeItem.prompts = - (((node.parameters?.messages as IDataObject) || {}).messageValues as IDataObject[]) || []; + (((node.parameters?.messages as IDataObject) ?? {}).messageValues as IDataObject[]) ?? []; } } From 966dc2905a7703ee0b9948b7e3c04cd290a23433 Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Wed, 27 Mar 2024 12:52:14 +0200 Subject: [PATCH 3/3] :zap: pretier fix --- packages/cli/src/InternalHooks.ts | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/cli/src/InternalHooks.ts b/packages/cli/src/InternalHooks.ts index 84dabf1ff8977..a18dd7e671084 100644 --- a/packages/cli/src/InternalHooks.ts +++ b/packages/cli/src/InternalHooks.ts @@ -487,23 +487,26 @@ export class InternalHooks { workflowName: workflow.name, metaData: runData?.data?.resultData?.metadata, }; - promises.push( - telemetryProperties.success - ? this.eventBus.sendWorkflowEvent({ - eventName: 'n8n.workflow.success', - payload: sharedEventPayload, - }) - : this.eventBus.sendWorkflowEvent({ - eventName: 'n8n.workflow.failed', - payload: { - ...sharedEventPayload, - lastNodeExecuted: runData?.data.resultData.lastNodeExecuted, - errorNodeType: telemetryProperties.error_node_type, - errorNodeId: telemetryProperties.error_node_id?.toString(), - errorMessage: telemetryProperties.error_message?.toString(), - }, - }), - ); + let event; + if (telemetryProperties.success) { + event = this.eventBus.sendWorkflowEvent({ + eventName: 'n8n.workflow.success', + payload: sharedEventPayload, + }); + } else { + event = this.eventBus.sendWorkflowEvent({ + eventName: 'n8n.workflow.failed', + payload: { + ...sharedEventPayload, + lastNodeExecuted: runData?.data.resultData.lastNodeExecuted, + errorNodeType: telemetryProperties.error_node_type, + errorNodeId: telemetryProperties.error_node_id?.toString(), + errorMessage: telemetryProperties.error_message?.toString(), + }, + }); + } + + promises.push(event); void Promise.all([...promises, this.telemetry.trackWorkflowExecution(telemetryProperties)]); }