UNPKG

langflow-chatbot

Version:

Add a Langflow-powered chatbot to your website.

193 lines (192 loc) 10.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleChatMessageRequest = handleChatMessageRequest; const request_utils_1 = require("../request-utils"); // Helper function to extract reply from Langflow's response function extractReplyFromLangflowResponse(langflowResponse) { let reply = "Sorry, I could not process that."; if (langflowResponse && Array.isArray(langflowResponse.outputs) && langflowResponse.outputs.length > 0) { const firstOutputComponent = langflowResponse.outputs[0]; if (firstOutputComponent && Array.isArray(firstOutputComponent.outputs) && firstOutputComponent.outputs.length > 0) { const innerOutput = firstOutputComponent.outputs[0]; if (innerOutput) { let textFromResults = null; if (innerOutput.results?.message && typeof innerOutput.results.message.text === 'string') { textFromResults = innerOutput.results.message.text; } if (textFromResults !== null) { // If results.message.text was present reply = textFromResults; } else if (innerOutput.outputs && typeof innerOutput.outputs === 'object') { const innerComponentOutputs = innerOutput.outputs; if (innerComponentOutputs.message && typeof innerComponentOutputs.message === 'object' && typeof innerComponentOutputs.message.message === 'string') { if (innerComponentOutputs.message.message !== '') { reply = innerComponentOutputs.message.message; } else if (reply === "Sorry, I could not process that.") { reply = ''; } } else if (typeof innerComponentOutputs.text === 'string') { if (innerComponentOutputs.text !== '') { reply = innerComponentOutputs.text; } else if (reply === "Sorry, I could not process that.") { reply = ''; } } } } } if (reply === "Sorry, I could not process that.") { console.log("RequestHandler: Primary reply extraction failed or yielded no usable primary value, attempting fallback..."); for (const outputComponent of langflowResponse.outputs) { if (reply !== "Sorry, I could not process that.") break; if (outputComponent && typeof outputComponent === 'object' && Array.isArray(outputComponent.outputs)) { for (const innerDocOutput of outputComponent.outputs) { if (reply !== "Sorry, I could not process that.") break; if (innerDocOutput && typeof innerDocOutput === 'object') { if (innerDocOutput.outputs && typeof innerDocOutput.outputs === 'object') { const componentOutputs = innerDocOutput.outputs; if (componentOutputs.chat && typeof componentOutputs.chat === 'string' && componentOutputs.chat !== '') { reply = componentOutputs.chat; break; } else if (componentOutputs.chat === '' && reply === "Sorry, I could not process that.") { reply = ''; break; } if (componentOutputs.text && typeof componentOutputs.text === 'string' && componentOutputs.text !== '') { reply = componentOutputs.text; break; } else if (componentOutputs.text === '' && reply === "Sorry, I could not process that.") { reply = ''; break; } if (componentOutputs.message && typeof componentOutputs.message === 'object' && typeof componentOutputs.message.message === 'string' && componentOutputs.message.message !== '') { reply = componentOutputs.message.message; break; } else if (componentOutputs.message?.message === '' && reply === "Sorry, I could not process that.") { reply = ''; break; } } if (innerDocOutput.results && innerDocOutput.results.message && typeof innerDocOutput.results.message.text === 'string') { if (innerDocOutput.results.message.text !== '') { reply = innerDocOutput.results.message.text; break; } else if (reply === "Sorry, I could not process that.") { reply = ''; break; } } if (innerDocOutput.artifacts && typeof innerDocOutput.artifacts.message === 'string') { if (innerDocOutput.artifacts.message !== '') { reply = innerDocOutput.artifacts.message; break; } else if (reply === "Sorry, I could not process that.") { reply = ''; break; } } } } } } } } if (reply === '') { reply = "Received an empty message from Bot."; } return reply; } async function handleChatMessageRequest(req, res, flowId, enableStream, langflowClient, preParsedBody, isBodyPreParsed) { if (!langflowClient) { (0, request_utils_1.sendJsonError)(res, 503, "RequestHandler: LangflowClient not available. Check server logs."); return; } try { let actualBody; if (isBodyPreParsed && preParsedBody) { console.log("[Debug ChatHandler] Using pre-parsed body provided by adapter:", preParsedBody); actualBody = preParsedBody; } else { console.log("[Debug ChatHandler] Pre-parsed body not available or not indicated. Attempting to parse JSON body via parseJsonBody."); actualBody = await (0, request_utils_1.parseJsonBody)(req); console.log("[Debug ChatHandler] JSON body parsed successfully via parseJsonBody:", actualBody); } const userMessage = actualBody.message; const clientSessionId = actualBody.sessionId; const clientWantsStream = actualBody.stream === true; const useStream = enableStream && clientWantsStream; if (!userMessage || typeof userMessage !== 'string') { (0, request_utils_1.sendJsonError)(res, 400, "Message is required and must be a string."); return; } const runOptions = { input_type: 'chat', output_type: 'chat', session_id: clientSessionId || undefined, }; if (runOptions.session_id === undefined) delete runOptions.session_id; const flow = langflowClient.flow(flowId); if (useStream) { console.log(`RequestHandler: Streaming request for Flow '${flowId}', session: ${runOptions.session_id || 'new'}, message: "${userMessage.substring(0, 50)}..."`); res.setHeader('Content-Type', 'application/x-ndjson'); res.setHeader('Transfer-Encoding', 'chunked'); try { const streamResponse = await flow.stream(userMessage, runOptions); for await (const event of streamResponse) { res.write(JSON.stringify(event) + '\n'); } res.end(); } catch (streamError) { console.error(`RequestHandler: Error during Langflow stream for flow '${flowId}':`, streamError); if (!res.headersSent) { (0, request_utils_1.sendJsonError)(res, 500, "Failed to process stream.", streamError.message || 'Unknown stream error'); } else { res.write(JSON.stringify({ event: 'error', data: { message: "Error during streaming.", detail: streamError.message || 'Unknown error on stream' } }) + '\n'); res.end(); } } } else { let logMessage = `RequestHandler: Non-streaming request for Flow '${flowId}'`; if (clientSessionId) logMessage += `, session: ${runOptions.session_id}`; logMessage += `, input_type: ${runOptions.input_type}, message: "${userMessage.substring(0, 50)}..."`; console.log(logMessage); const langflowResponse = await flow.run(userMessage, runOptions); const reply = extractReplyFromLangflowResponse(langflowResponse); const sessionId = langflowResponse && langflowResponse.sessionId ? langflowResponse.sessionId : clientSessionId; res.statusCode = 200; res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ reply: reply, sessionId: sessionId })); } } catch (error) { if (error.message.includes('Invalid JSON body')) { console.warn(`RequestHandler: Invalid JSON body for flow '${flowId}'. Error: ${error.message}`); (0, request_utils_1.sendJsonError)(res, 400, "Invalid JSON body provided.", error.message); } else { console.error(`RequestHandler: Error handling chat message for flow '${flowId}':`, error); if (!res.headersSent) { (0, request_utils_1.sendJsonError)(res, 500, "Failed to process chat message.", error.message); } else if (!res.writableEnded) { res.end(); } } } }