feat(core): Update LLM applications building support (no-changelog) (#7710)

extracted out of #7336

---------

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>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-11-28 16:47:28 +01:00
committed by GitHub
parent 4a89504d54
commit 117962d473
58 changed files with 1135 additions and 183 deletions

View File

@@ -176,6 +176,8 @@ export const nodeHelpers = defineComponent({
}
for (const taskData of workflowResultData[node.name]) {
if (!taskData) return false;
if (taskData.error !== undefined) {
return true;
}
@@ -313,11 +315,24 @@ export const nodeHelpers = defineComponent({
const parentNodes = workflow.getParentNodes(node.name, input.type, 1);
if (parentNodes.length === 0) {
foundIssues[input.type] = [
this.$locale.baseText('nodeIssues.input.missing', {
interpolate: { inputName: input.displayName || input.type },
}),
];
// We want to show different error for missing AI subnodes
if (input.type.startsWith('ai_')) {
foundIssues[input.type] = [
this.$locale.baseText('nodeIssues.input.missingSubNode', {
interpolate: {
inputName: input.displayName?.toLocaleLowerCase() ?? input.type,
inputType: input.type,
node: node.name,
},
}),
];
} else {
foundIssues[input.type] = [
this.$locale.baseText('nodeIssues.input.missing', {
interpolate: { inputName: input.displayName ?? input.type },
}),
];
}
}
});

View File

@@ -11,8 +11,8 @@ import {
import { mapStores } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
import { NodeConnectionType, NodeHelpers, jsonParse, jsonStringify } from 'n8n-workflow';
import { useToast } from '@/composables/useToast';
import { jsonParse, jsonStringify } from 'n8n-workflow';
export type PinDataSource =
| 'pin-icon-click'
@@ -39,9 +39,19 @@ export const pinData = defineComponent({
hasPinData(): boolean {
return !!this.node && typeof this.pinData !== 'undefined';
},
isSubNode() {
if (!this.nodeType.outputs || typeof this.nodeType.outputs === 'string') {
return false;
}
const outputTypes = NodeHelpers.getConnectionTypes(this.nodeType.outputs);
return outputTypes
? outputTypes.filter((output) => output !== NodeConnectionType.Main).length > 0
: false;
},
isPinDataNodeType(): boolean {
return (
!!this.node &&
!this.isSubNode &&
!this.isMultipleOutputsNodeType &&
!PIN_DATA_NODE_TYPES_DENYLIST.includes(this.node.type)
);

View File

@@ -20,6 +20,7 @@ import type {
IWorkflowBase,
SubworkflowOperationError,
IExecuteContextData,
NodeOperationError,
} from 'n8n-workflow';
import { TelemetryHelpers } from 'n8n-workflow';
@@ -396,25 +397,59 @@ export const pushConnection = defineComponent({
type: 'error',
duration: 0,
});
} else {
} else if (
runDataExecuted.data.resultData.error?.name === 'NodeOperationError' &&
(runDataExecuted.data.resultData.error as NodeOperationError).functionality ===
'configuration-node'
) {
// If the error is a configuration error of the node itself doesn't get executed so we can't use lastNodeExecuted for the title
let title: string;
let type = 'error';
if (runDataExecuted.status === 'canceled') {
title = this.$locale.baseText('nodeView.showMessage.stopExecutionTry.title');
type = 'warning';
} else if (runDataExecuted.data.resultData.lastNodeExecuted) {
title = `Problem in node ${runDataExecuted.data.resultData.lastNodeExecuted}`;
const nodeError = runDataExecuted.data.resultData.error as NodeOperationError;
if (nodeError.node.name) {
title = `Error in sub-node ${nodeError.node.name}`;
} else {
title = 'Problem executing workflow';
}
this.showMessage({
title,
message: runDataExecutedErrorMessage,
type,
message:
(nodeError?.description ?? runDataExecutedErrorMessage) +
this.$locale.baseText('pushConnection.executionError.openNode', {
interpolate: {
node: nodeError.node.name,
},
}),
type: 'error',
duration: 0,
dangerouslyUseHTMLString: true,
});
} else {
let title: string;
const isManualExecutionCancelled =
runDataExecuted.mode === 'manual' && runDataExecuted.status === 'canceled';
// Do not show the error message if the workflow got canceled manually
if (isManualExecutionCancelled) {
this.showMessage({
title: this.$locale.baseText('nodeView.showMessage.stopExecutionTry.title'),
type: 'success',
});
} else {
if (runDataExecuted.data.resultData.lastNodeExecuted) {
title = `Problem in node ${runDataExecuted.data.resultData.lastNodeExecuted}`;
} else {
title = 'Problem executing workflow';
}
this.showMessage({
title,
message: runDataExecutedErrorMessage,
type: 'error',
duration: 0,
dangerouslyUseHTMLString: true,
});
}
}
} else {
// Workflow did execute without a problem