UNPKG

@n8n-plus/n8n-plus

Version:

n8n Workflow Automation Tool (plus edition)

127 lines 5.36 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LlmWireServer = void 0; const express_1 = __importDefault(require("express")); const openai_envelope_1 = require("./openai-envelope"); class LlmWireServer { constructor(options = {}) { this.options = options; this.handleChatCompletion = async (req, res) => { const rootName = req.params.root; const model = (0, openai_envelope_1.extractRequestModel)(req.body); const subNode = this.resolveSubNode(rootName); if (!this.options.mockHandler) { const envelope = (0, openai_envelope_1.forwardTranslateToChatCompletion)({ body: { content: '[eval wire server stub] — no mock handler attached' }, headers: { 'content-type': 'application/json' }, statusCode: 200, }, model); res.status(200).json(envelope); return; } let synthetic; let mockResponse; let envelope; try { synthetic = (0, openai_envelope_1.reverseTranslateOpenAiRequest)(req.body); mockResponse = await this.options.mockHandler(synthetic, subNode); envelope = (0, openai_envelope_1.forwardTranslateToChatCompletion)(mockResponse, model); } catch (error) { const message = error instanceof Error ? error.message : String(error); this.options.logger?.error(`[EvalMock] Wire-server mock generation failed: ${message}`); res.status(500).json((0, openai_envelope_1.buildOpenAiErrorEnvelope)(`Mock generation failed: ${message}`)); return; } try { this.options.onIntercept?.({ rootName, url: synthetic.url, method: synthetic.method ?? 'POST', nodeType: subNode.type, requestBody: this.cloneRequestBody(req.body), mockResponse: mockResponse?.body, }); } catch (error) { const message = error instanceof Error ? error.message : String(error); this.options.logger?.warn(`[EvalMock] Wire-server ledger write failed: ${message}`); } res.status(200).json(envelope); }; this.handleUnroutedChatCompletion = (_req, res) => { res .status(500) .json((0, openai_envelope_1.buildOpenAiErrorEnvelope)('Wire server received an OpenAI request without an /eval/<root>/ prefix. ' + 'Credential rewrite is misconfigured — check EvalMockedCredentialsHelper.')); }; } get url() { if (!this.resolvedUrl) { throw new Error('LlmWireServer.url accessed before start() resolved'); } return this.resolvedUrl; } async start() { if (this.server) return this.url; const app = this.buildApp(); this.server = await new Promise((resolve, reject) => { const s = app.listen(0, '127.0.0.1', () => resolve(s)); s.once('error', reject); }); const address = this.server.address(); if (!address || typeof address === 'string') { throw new Error('LlmWireServer failed to bind a TCP port'); } this.resolvedUrl = `http://127.0.0.1:${address.port}`; return this.resolvedUrl; } async stop() { const server = this.server; if (!server) return; this.server = undefined; this.resolvedUrl = undefined; server.closeAllConnections(); await new Promise((resolve, reject) => { server.close((error) => (error ? reject(error) : resolve())); }); } buildApp() { const app = (0, express_1.default)(); app.use(express_1.default.json({ limit: '4mb' })); app.post('/eval/:root/v1/chat/completions', this.handleChatCompletion); app.post('/v1/chat/completions', this.handleUnroutedChatCompletion); return app; } cloneRequestBody(body) { try { return structuredClone(body); } catch (error) { const message = error instanceof Error ? error.message : String(error); this.options.logger?.warn(`[EvalMock] Wire-server ledger entry not isolated — clone failed: ${message}`); return body; } } resolveSubNode(rootName) { const subNode = this.options.rootToSubNode?.get(rootName); if (subNode) return subNode; this.options.logger?.warn(`[EvalMock] Wire server has no sub-node mapping for root "${rootName}" — using synthetic identity`); return { id: `eval-wire-server:${rootName}`, name: rootName, type: '@n8n/eval-wire-server.unknown-vendor-llm', typeVersion: 1, position: [0, 0], parameters: {}, }; } } exports.LlmWireServer = LlmWireServer; //# sourceMappingURL=llm-wire-server.js.map