UNPKG

n8n

Version:

n8n Workflow Automation Tool

223 lines 8.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ComponentMapper = void 0; const di_1 = require("@n8n/di"); const agent_chat_integration_1 = require("./agent-chat-integration"); const esm_loader_1 = require("./esm-loader"); class ComponentMapper { async toCard(payload, runId, toolCallId, resumeSchema, shortenCallback, platform) { const sdk = await (0, esm_loader_1.loadChatSdk)(); const integration = platform ? di_1.Container.get(agent_chat_integration_1.ChatIntegrationRegistry).get(platform) : undefined; const components = integration?.normalizeComponents?.(payload.components) ?? payload.components; const children = []; const buttons = []; const buttonIndex = { value: 0 }; const makeButton = async (label, rawValue, style) => { let id = `resume:${runId}:${toolCallId}:${buttonIndex.value++}`; let value = JSON.stringify(this.wrapValueForSchema(rawValue, resumeSchema)); if (shortenCallback) { const shortened = await shortenCallback(id, value); id = shortened.id; value = shortened.value; } return sdk.Button({ id, label, style: style === 'danger' ? 'danger' : 'primary', value, }); }; for (const component of components) { await this.appendComponent({ component, sdk, runId, toolCallId, children, buttons, makeButton, }); } if (buttons.length > 0) { children.push(sdk.Actions(buttons)); } const title = payload.title ?? payload.message; return sdk.Card({ title, children: children }); } async appendComponent(ctx) { const { component, children, buttons, makeButton } = ctx; switch (component.type) { case 'button': buttons.push(await makeButton(component.label ?? 'Action', component.value ?? '', component.style)); return; case 'section': await this.appendSection(ctx); return; case 'divider': children.push(ctx.sdk.Divider()); return; case 'image': this.appendImage(ctx); return; case 'context': this.appendContext(ctx); return; case 'select': this.appendSelect(ctx); return; case 'radio_select': this.appendRadioSelect(ctx); return; case 'fields': this.appendFields(ctx); return; default: return; } } async appendSection({ component, sdk, children, makeButton, }) { if (component.text) { children.push(sdk.Section([sdk.CardText(component.text)])); } if (component.button) { children.push(sdk.Actions([ await makeButton(component.button.label, component.button.value, component.button.style), ])); } } appendImage({ component, sdk, children }) { children.push(sdk.Image({ url: component.url, alt: component.altText ?? 'image', })); } appendContext({ component, sdk, children }) { if (component.elements && Array.isArray(component.elements)) { for (const el of component.elements) { if (el.type === 'text' && el.text) { children.push(sdk.CardText(el.text)); } else if (el.type === 'image' && el.url) { children.push(sdk.Image({ url: el.url, alt: el.altText ?? '' })); } } } else if (component.text) { children.push(sdk.CardText(component.text)); } } appendSelect({ component, sdk, runId, toolCallId, children, }) { children.push(sdk.Actions([ sdk.Select({ id: `ri-sel:${component.id ?? 'select'}:${runId}:${toolCallId}`, label: component.label ?? 'Select', placeholder: component.placeholder, options: this.toSelectOptions(component), }), ])); } appendRadioSelect({ component, sdk, runId, toolCallId, children, }) { children.push(sdk.Actions([ sdk.RadioSelect({ id: `ri-sel:${component.id ?? 'radio'}:${runId}:${toolCallId}`, label: component.label ?? 'Select', options: this.toSelectOptions(component), }), ])); } appendFields({ component, sdk, children }) { const fieldElements = (component.fields ?? []).map((f) => sdk.Field({ label: f.label, value: f.value })); children.push(sdk.Fields(fieldElements)); } toSelectOptions(component) { return (component.options ?? []).map((o) => ({ label: o.label, value: o.value, description: o.description, })); } wrapValueForSchema(rawValue, resumeSchema) { if (!resumeSchema || typeof resumeSchema !== 'object') { try { const parsed = JSON.parse(rawValue); if (typeof parsed === 'object' && parsed !== null) return parsed; } catch { } return { value: rawValue }; } const schema = resumeSchema; const props = schema.properties ?? {}; if ('approved' in props) { return { approved: rawValue === 'true' }; } if ('type' in props && 'value' in props) { return { type: 'button', value: rawValue }; } if ('values' in props) { return { values: { action: rawValue } }; } try { const parsed = JSON.parse(rawValue); if (typeof parsed === 'object' && parsed !== null) return parsed; } catch { } return { value: rawValue }; } async toCardOrMarkdown(message) { if (typeof message === 'string') return message; if (message && typeof message === 'object' && 'components' in message) { const sdk = await (0, esm_loader_1.loadChatSdk)(); const { components } = message; const children = []; for (const c of components) { this.appendMarkdownChild(c, sdk, children); } return sdk.Card({ children: children }); } return String(message); } appendMarkdownChild(c, sdk, children) { switch (c.type) { case 'section': if (c.text) children.push(sdk.Section([sdk.CardText(c.text)])); return; case 'divider': children.push(sdk.Divider()); return; case 'image': if (c.url) children.push(sdk.Image({ url: c.url, alt: c.altText ?? '' })); return; case 'context': this.appendMarkdownContext(c, sdk, children); return; default: if (c.text) children.push(sdk.CardText(c.text)); return; } } appendMarkdownContext(c, sdk, children) { if (c.elements) { for (const el of c.elements) { if (el.type === 'text' && el.text) { children.push(sdk.CardText(el.text)); } else if (el.type === 'image' && el.url) { children.push(sdk.Image({ url: el.url, alt: el.altText ?? '' })); } } } else if (c.text) { children.push(sdk.CardText(c.text)); } } } exports.ComponentMapper = ComponentMapper; //# sourceMappingURL=component-mapper.js.map