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

@@ -18,10 +18,18 @@
@tableMounted="$emit('tableMounted', $event)"
@itemHover="$emit('itemHover', $event)"
ref="runData"
:data-output-type="outputMode"
>
<template #header>
<div :class="$style.titleSection">
<span :class="$style.title">
<template v-if="hasAiMetadata">
<n8n-radio-buttons
:options="outputTypes"
v-model="outputMode"
@update:modelValue="onUpdateOutputMode"
/>
</template>
<span :class="$style.title" v-else>
{{ $locale.baseText(outputPanelEditMode.enabled ? 'ndv.output.edit' : 'ndv.output') }}
</span>
<RunInfo
@@ -78,6 +86,9 @@
</n8n-text>
</template>
<template #content v-if="outputMode === 'logs'">
<run-data-ai :node="node" />
</template>
<template #recovered-artificial-output-data>
<div :class="$style.recoveredOutputData">
<n8n-text tag="div" :bold="true" color="text-dark" size="large">{{
@@ -107,13 +118,29 @@ import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import RunDataAi from './RunDataAi/RunDataAi.vue';
import { ndvEventBus } from '@/event-bus';
type RunDataRef = InstanceType<typeof RunData>;
const OUTPUT_TYPE = {
REGULAR: 'regular',
LOGS: 'logs',
};
export default defineComponent({
name: 'OutputPanel',
mixins: [pinData],
components: { RunData, RunInfo },
components: { RunData, RunInfo, RunDataAi },
data() {
return {
outputMode: 'regular',
outputTypes: [
{ label: this.$locale.baseText('ndv.output.outType.regular'), value: OUTPUT_TYPE.REGULAR },
{ label: this.$locale.baseText('ndv.output.outType.logs'), value: OUTPUT_TYPE.LOGS },
],
};
},
props: {
runIndex: {
type: Number,
@@ -153,6 +180,18 @@ export default defineComponent({
isTriggerNode(): boolean {
return this.nodeTypesStore.isTriggerNode(this.node.type);
},
hasAiMetadata(): boolean {
if (this.node) {
const resultData = this.workflowsStore.getWorkflowResultDataByNodeName(this.node.name);
if (!resultData || !Array.isArray(resultData)) {
return false;
}
return !!resultData[resultData.length - 1!].metadata;
}
return false;
},
isPollingTypeNode(): boolean {
return !!(this.nodeType && this.nodeType.polling);
},
@@ -160,8 +199,7 @@ export default defineComponent({
return !!(this.nodeType && this.nodeType.group.includes('schedule'));
},
isNodeRunning(): boolean {
const executingNode = this.workflowsStore.executingNode;
return this.node && executingNode === this.node.name;
return this.node && this.workflowsStore.isNodeExecuting(this.node.name);
},
workflowRunning(): boolean {
return this.uiStore.isActionActive('workflowRunning');
@@ -174,7 +212,7 @@ export default defineComponent({
return null;
}
const executionData: IRunExecutionData | undefined = this.workflowExecution.data;
if (!executionData || !executionData.resultData || !executionData.resultData.runData) {
if (!executionData?.resultData?.runData) {
return null;
}
return executionData.resultData.runData;
@@ -274,11 +312,28 @@ export default defineComponent({
onRunIndexChange(run: number) {
this.$emit('runChange', run);
},
onUpdateOutputMode(outputMode: (typeof OUTPUT_TYPE)[string]) {
if (outputMode === OUTPUT_TYPE.LOGS) {
ndvEventBus.emit('setPositionByName', 'minLeft');
} else {
ndvEventBus.emit('setPositionByName', 'initial');
}
},
},
});
</script>
<style lang="scss" module>
// The items count and displayModes are rendered in the RunData component
// this is a workaround to hide it in the output panel(for ai type) to not add unnecessary one-time props
:global([data-output-type='logs'] [class*='itemsCount']),
:global([data-output-type='logs'] [class*='displayModes']) {
display: none;
}
.outputTypeSelect {
margin-bottom: var(--spacing-4xs);
width: fit-content;
}
.titleSection {
display: flex;