UNPKG

langflow-chatbot

Version:

Add a Langflow-powered chatbot to your website.

111 lines (110 loc) 6.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FlowMapper = void 0; const apiPaths_1 = require("../config/apiPaths"); class FlowMapper { constructor(langflowEndpointUrl, langflowApiKey) { this.isInitialized = false; this.langflowEndpointUrl = langflowEndpointUrl; this.langflowApiKey = langflowApiKey; this.flowNameToIdMap = new Map(); } async initialize() { if (this.isInitialized) { console.log("FlowMapper: Already initialized."); return; } console.log("FlowMapper: Initializing - fetching all flows from Langflow..."); const targetPath = `${apiPaths_1.LANGFLOW_API_BASE_PATH_V1}${apiPaths_1.LANGFLOW_FLOWS_ENDPOINT_SUFFIX}`; const queryParams = new URLSearchParams(); queryParams.append('remove_example_flows', 'true'); queryParams.append('header_flows', 'true'); // Assuming this is still desired try { const fetchUrl = new URL(targetPath, this.langflowEndpointUrl); fetchUrl.search = queryParams.toString(); const headers = { 'Accept': 'application/json' }; if (this.langflowApiKey) { headers['Authorization'] = `Bearer ${this.langflowApiKey}`; } console.log(`FlowMapper: Fetching flows from: ${fetchUrl.toString()}`); const langflowApiResponse = await fetch(fetchUrl.toString(), { method: 'GET', headers }); if (!langflowApiResponse.ok) { const errorBody = await langflowApiResponse.text(); throw new Error(`FlowMapper: Failed to fetch flows from Langflow. Status: ${langflowApiResponse.status} ${langflowApiResponse.statusText}. Body: ${errorBody}`); } const responseJson = await langflowApiResponse.json(); let actualFlowsArray = []; if (Array.isArray(responseJson)) { actualFlowsArray = responseJson; } else if (responseJson && Array.isArray(responseJson.records)) { actualFlowsArray = responseJson.records; } else if (responseJson && Array.isArray(responseJson.flows)) { actualFlowsArray = responseJson.flows; } else { console.error("FlowMapper: Unexpected response structure for flows list. Expected an array, or {records: [...]}, or {flows: [...]}. Response:", responseJson); throw new Error("FlowMapper: Unexpected response structure for flows list from Langflow."); } this.flowNameToIdMap.clear(); // Clear any previous mappings for (const flow of actualFlowsArray) { if (flow && typeof flow.id === 'string') { if (typeof flow.endpoint_name === 'string' && flow.endpoint_name.trim() !== '') { this.flowNameToIdMap.set(flow.endpoint_name, flow.id); } else if (typeof flow.name === 'string' && flow.name.trim() !== '') { // Fallback to name if endpoint_name is not suitable or missing if (!this.flowNameToIdMap.has(flow.name)) { // Avoid overwriting if endpoint_name was already used for a different flow that happened to have this name this.flowNameToIdMap.set(flow.name, flow.id); console.debug(`FlowMapper: Flow '${flow.name}' (ID: ${flow.id}) mapped by its 'name' as 'endpoint_name' was not suitable. Ensure names are unique if used for mapping.`); } else { console.debug(`FlowMapper: Flow '${flow.name}' (ID: ${flow.id}) could not be mapped by name as the name is already in use by another flow's endpoint_name or name. Ensure unique names/endpoint_names.`); } } else { console.debug("FlowMapper: Skipping a flow entry from Langflow due to missing or invalid id, or unusable name/endpoint_name:", flow); } } else { console.debug("FlowMapper: Skipping a flow entry from Langflow due to missing or invalid id:", flow); } } this.isInitialized = true; console.log(`FlowMapper: Initialization complete. Processed ${actualFlowsArray.length} flow entries, successfully mapped ${this.flowNameToIdMap.size} flows by name/endpoint_name.`); } catch (error) { console.error(`FlowMapper: CRITICAL - Error during flow map initialization: ${error.message}`); this.isInitialized = false; // Ensure it's marked as not initialized on error throw error; // Re-throw to indicate failure to the caller } } getTrueFlowId(identifier) { if (!this.isInitialized) { console.warn("FlowMapper: getTrueFlowId called before successful initialization. Results may be incorrect."); // Optionally, you could throw an error here or attempt a lazy initialization. // For now, it will proceed with an empty or outdated map if not initialized. } if (!identifier || typeof identifier !== 'string') { console.warn(`FlowMapper: Invalid identifier provided to getTrueFlowId: ${identifier}`); return undefined; } // Check if the identifier is already a UUID const isLikelyUuid = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(identifier); if (isLikelyUuid) { // console.log(`FlowMapper: Identifier '${identifier}' is a UUID. Returning as is.`); return identifier; } const resolvedUuid = this.flowNameToIdMap.get(identifier); if (resolvedUuid) { // console.log(`FlowMapper: Resolved identifier '${identifier}' to UUID '${resolvedUuid}'.`); return resolvedUuid; } else { // console.log(`FlowMapper: Identifier '${identifier}' not found in flow map and is not a UUID.`); return undefined; } } } exports.FlowMapper = FlowMapper;