Files
lcbp3.np-dms.work/n8n-cache/n8n/public/assets/RunDataParsedAiContent-Byf4f3hM.js
2025-09-21 20:29:15 +07:00

313 lines
12 KiB
JavaScript
Executable File

import { hg as requireUtils, hh as mapConnectionsByDestination, hi as getParentNodes, bz as emptyTokenUsageData, by as addTokenUsageData, hj as libExports, hk as splitTextBySearch, d as defineComponent, ca as useClipboard, a as useToast, x as computed, h as createElementBlock, g as openBlock, n as normalizeClass, F as Fragment, A as renderList, e as createBlock, f as createCommentVNode, l as unref, h7 as __unplugin_components_0, i as createVNode, aa as _sfc_main$1, c as useI18n, _ as _export_sfc } from "./index--OJ5nhDf.js";
import { V as VueMarkdown, H as HighlightJS } from "./core-Br-UFy15.js";
var utilsExports = requireUtils();
function createNode(parent, nodeName, currentDepth, runIndex, r, children = []) {
return {
parent,
node: nodeName,
id: `${nodeName}:${runIndex}`,
depth: currentDepth,
startTime: r?.data?.metadata?.startTime ?? 0,
runIndex,
children,
consumedTokens: getConsumedTokens(r?.data)
};
}
function getTreeNodeData(nodeName, connectionsBySourceNode, aiData, runIndex) {
return getTreeNodeDataRec(void 0, nodeName, 0, connectionsBySourceNode, aiData, runIndex);
}
function getTreeNodeDataRec(parent, nodeName, currentDepth, connectionsBySourceNode, aiData, runIndex) {
const connectionsByDestinationNode = mapConnectionsByDestination(connectionsBySourceNode);
const nodeConnections = connectionsByDestinationNode[nodeName];
const resultData = aiData?.filter((data) => data.node === nodeName && runIndex === data.runIndex) ?? [];
if (!nodeConnections) {
return resultData.map((d) => createNode(parent, nodeName, currentDepth, d.runIndex, d));
}
const filteredAiData = aiData?.filter(({ data }) => {
if (!data?.source || data.source.every((source) => source === null)) {
return true;
}
return data.source.some(
(source) => source?.previousNode === nodeName && source.previousNodeRun === runIndex
);
});
const connectedSubNodes = getParentNodes(
connectionsByDestinationNode,
nodeName,
"ALL_NON_MAIN",
1
);
const treeNode = createNode(parent, nodeName, currentDepth, runIndex);
const children = (filteredAiData ?? []).flatMap(
(data) => connectedSubNodes.includes(data.node) ? getTreeNodeDataRec(
treeNode,
data.node,
currentDepth + 1,
connectionsBySourceNode,
aiData,
data.runIndex
) : []
);
treeNode.children = children;
if (resultData.length) {
return resultData.map(
(r) => createNode(parent, nodeName, currentDepth, r.runIndex, r, children)
);
}
return [treeNode];
}
function createAiData(nodeName, connectionsBySourceNode, getWorkflowResultDataByNodeName) {
const connectionsByDestinationNode = mapConnectionsByDestination(connectionsBySourceNode);
return getParentNodes(connectionsByDestinationNode, nodeName, "ALL_NON_MAIN").flatMap(
(node) => (getWorkflowResultDataByNodeName(node) ?? []).map((task, index) => ({ node, task, index }))
).sort((a, b) => {
if (a.task.executionIndex !== void 0 && b.task.executionIndex !== void 0) {
return a.task.executionIndex - b.task.executionIndex;
}
const aTime = a.task.startTime ?? 0;
const bTime = b.task.startTime ?? 0;
return aTime - bTime;
}).map(({ node, task, index }) => ({
data: getReferencedData(task, false)[0],
node,
runIndex: index
}));
}
function getReferencedData(taskData, withInput, withOutput) {
if (!taskData) {
return [];
}
const returnData = [];
function addFunction(data, inOut) {
if (!data) {
return;
}
Object.keys(data).map((type) => {
returnData.push({
data: data[type][0],
inOut,
type,
// Include source information in AI content to track which node triggered the execution
// This enables filtering in the UI to show only relevant executions
source: taskData.source,
metadata: {
executionTime: taskData.executionTime,
startTime: taskData.startTime,
subExecution: taskData.metadata?.subExecution
}
});
});
}
if (withInput) {
addFunction(taskData.inputOverride, "input");
}
{
addFunction(taskData.data, "output");
}
return returnData;
}
function getConsumedTokens(outputRun) {
if (!outputRun?.data) {
return emptyTokenUsageData;
}
const tokenUsage = outputRun.data.reduce(
(acc, curr) => {
const tokenUsageData = curr.json?.tokenUsage ?? curr.json?.tokenUsageEstimate;
if (!tokenUsageData) return acc;
return addTokenUsageData(acc, {
...tokenUsageData,
isEstimate: !!curr.json.tokenUsageEstimate
});
},
emptyTokenUsageData
);
return tokenUsage;
}
function createHtmlFragmentWithSearchHighlight(text, search) {
const escaped = libExports.escapeHtml(text);
return search ? splitTextBySearch(escaped, search).map((part) => part.isMatched ? `<mark>${part.content}</mark>` : part.content).join("") : escaped;
}
function createSearchHighlightPlugin(search) {
return (md) => {
md.renderer.rules.text = (tokens, idx) => createHtmlFragmentWithSearchHighlight(tokens[idx].content, search);
md.renderer.rules.code_inline = (tokens, idx, _, __, slf) => `<code${slf.renderAttrs(tokens[idx])}>${createHtmlFragmentWithSearchHighlight(tokens[idx].content, search)}</code>`;
md.renderer.rules.code_block = (tokens, idx, _, __, slf) => `<pre${slf.renderAttrs(tokens[idx])}><code>${createHtmlFragmentWithSearchHighlight(tokens[idx].content, search)}</code></pre>
`;
md.renderer.rules.fence = (tokens, idx, options, _, slf) => {
const token = tokens[idx];
const info = token.info ? utilsExports.unescapeAll(token.info).trim() : "";
let langName = "";
let langAttrs = "";
if (info) {
const arr = info.split(/(\s+)/g);
langName = arr[0];
langAttrs = arr.slice(2).join("");
}
const highlighted = options.highlight?.(token.content, langName, langAttrs) ?? createHtmlFragmentWithSearchHighlight(token.content, search);
if (highlighted.indexOf("<pre") === 0) {
return highlighted + "\n";
}
return `<pre><code${slf.renderAttrs(token)}>${highlighted}</code></pre>
`;
};
};
}
const _hoisted_1 = ["data-content-type"];
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "RunDataParsedAiContent",
props: {
content: {},
compact: { type: Boolean, default: false },
search: {},
renderType: {}
},
setup(__props) {
const i18n = useI18n();
const clipboard = useClipboard();
const { showMessage } = useToast();
const vueMarkdownPlugins = computed(() => [createSearchHighlightPlugin(__props.search)]);
function isJsonString(text) {
try {
JSON.parse(text);
return true;
} catch (e) {
return false;
}
}
const markdownOptions = {
highlight(str, lang) {
if (lang && HighlightJS.getLanguage(lang)) {
try {
return HighlightJS.highlight(str, { language: lang }).value;
} catch {
}
}
return void 0;
}
};
function isMarkdown(jsonMarkdown) {
if (typeof jsonMarkdown !== "string") return false;
const markdownPatterns = [
/^# .+/gm,
// headers
/\*{1,2}.+\*{1,2}/g,
// emphasis and strong
/\[.+\]\(.+\)/g,
// links
/```[\s\S]+```/g
// code blocks
];
return markdownPatterns.some((pattern) => pattern.test(jsonMarkdown));
}
function formatToJsonMarkdown(data) {
return "```json\n" + data + "\n```";
}
function jsonToMarkdown(data) {
if (isMarkdown(data)) return data;
if (Array.isArray(data) && data.length && typeof data[0] !== "number") {
const markdownArray = data.map((item) => jsonToMarkdown(item));
return markdownArray.join("\n\n").trim();
}
if (typeof data === "string") {
if (isJsonString(data)) {
return formatToJsonMarkdown(data);
}
return data;
}
return formatToJsonMarkdown(JSON.stringify(data, null, 2));
}
function onCopyToClipboard(object) {
try {
void clipboard.copy(JSON.stringify(object, void 0, 2));
showMessage({
title: i18n.baseText("generic.copiedToClipboard"),
type: "success"
});
} catch {
}
}
return (_ctx, _cache) => {
const _component_TextWithHighlights = __unplugin_components_0;
return openBlock(), createElementBlock("div", {
class: normalizeClass([_ctx.$style.component, _ctx.compact ? _ctx.$style.compact : ""])
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.content, ({ parsedContent, raw }, index) => {
return openBlock(), createElementBlock("div", {
key: index,
class: normalizeClass(_ctx.$style.contentText),
"data-content-type": parsedContent?.type
}, [
parsedContent && _ctx.renderType === "rendered" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
parsedContent.type === "json" ? (openBlock(), createBlock(unref(VueMarkdown), {
key: 0,
source: jsonToMarkdown(parsedContent.data),
class: normalizeClass(_ctx.$style.markdown),
options: markdownOptions,
plugins: vueMarkdownPlugins.value
}, null, 8, ["source", "class", "plugins"])) : parsedContent.type === "markdown" ? (openBlock(), createBlock(unref(VueMarkdown), {
key: 1,
source: parsedContent.data,
class: normalizeClass(_ctx.$style.markdown),
options: markdownOptions,
plugins: vueMarkdownPlugins.value
}, null, 8, ["source", "class", "plugins"])) : parsedContent.type === "text" ? (openBlock(), createBlock(_component_TextWithHighlights, {
key: 2,
class: normalizeClass(_ctx.$style.runText),
content: String(parsedContent.data),
search: _ctx.search
}, null, 8, ["class", "content", "search"])) : createCommentVNode("", true)
], 64)) : (openBlock(), createElementBlock("div", {
key: 1,
class: normalizeClass(_ctx.$style.rawContent)
}, [
createVNode(unref(_sfc_main$1), {
size: "small",
class: normalizeClass(_ctx.$style.copyToClipboard),
type: "secondary",
title: unref(i18n).baseText("nodeErrorView.copyToClipboard"),
icon: "files",
onClick: ($event) => onCopyToClipboard(raw)
}, null, 8, ["class", "title", "onClick"]),
createVNode(unref(VueMarkdown), {
source: jsonToMarkdown(raw),
class: normalizeClass(_ctx.$style.markdown),
plugins: vueMarkdownPlugins.value
}, null, 8, ["source", "class", "plugins"])
], 2))
], 10, _hoisted_1);
}), 128))
], 2);
};
}
});
const runText = "_runText_1ucj0_123";
const markdown = "_markdown_1ucj0_128";
const compact = "_compact_1ucj0_151";
const copyToClipboard = "_copyToClipboard_1ucj0_159";
const rawContent = "_rawContent_1ucj0_169";
const contentText = "_contentText_1ucj0_173";
const style0 = {
runText,
markdown,
compact,
copyToClipboard,
rawContent,
contentText
};
const cssModules = {
"$style": style0
};
const RunDataAi = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
const RunDataParsedAiContent = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
default: RunDataAi
}, Symbol.toStringTag, { value: "Module" }));
export {
RunDataAi as R,
getTreeNodeData as a,
getReferencedData as b,
createAiData as c,
RunDataParsedAiContent as d,
getConsumedTokens as g
};