UNPKG

@kangthink/q-engine

Version:

A question-answer generation engine that stimulates thinking

132 lines 5.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseTransform = void 0; const types_1 = require("../types"); const Node_1 = require("../models/Node"); const Edge_1 = require("../models/Edge"); class BaseTransform { constructor(llmProvider, promptManager) { // 각 Transform의 기본 타겟 타입 (하위 클래스에서 오버라이드 가능) this.defaultTargetType = types_1.NodeType.QUESTION; this.llmProvider = llmProvider; this.promptManager = promptManager; } async transformMultiple(context) { const { sourceNode, options } = context; const count = options?.count || 3; const targetNodeType = options?.targetNodeType || this.defaultTargetType; // Get or create prompt template const promptTemplate = this.promptManager.getPrompt(this.mode) || this.promptManager.getDefaultPrompt(this.mode); // Build prompt for multiple generation const targetTypeKorean = targetNodeType === types_1.NodeType.QUESTION ? '질문' : '답변'; const prompt = this.buildMultiplePrompt(promptTemplate.template, { content: sourceNode.content, targetType: targetTypeKorean, count: count, ...options }); // Generate content using LLM const generatedContent = await this.generateContent(prompt); // Parse multiple results const contents = this.parseMultipleResults(generatedContent); // Create nodes and edges const targetNodes = []; const edges = []; contents.forEach(content => { const targetNode = targetNodeType === types_1.NodeType.QUESTION ? Node_1.NodeBuilder.createQuestion(content.trim()) : Node_1.NodeBuilder.createAnswer(content.trim()); const edge = new Edge_1.EdgeBuilder(sourceNode.id, targetNode.id, this.mode, { transformedAt: new Date(), sourceType: sourceNode.type, targetType: targetNodeType, }); targetNodes.push(targetNode); edges.push(edge); }); return { targetNodes, edges, }; } async generateContent(prompt) { return await this.llmProvider.generateResponse(prompt); } createTransformResult(sourceNode, generatedContent, targetNodeType = types_1.NodeType.QUESTION) { const targetNode = targetNodeType === types_1.NodeType.QUESTION ? Node_1.NodeBuilder.createQuestion(generatedContent) : Node_1.NodeBuilder.createAnswer(generatedContent); const edge = new Edge_1.EdgeBuilder(sourceNode.id, targetNode.id, this.mode, { transformedAt: new Date(), sourceType: sourceNode.type, targetType: targetNodeType, }); return { targetNode, edge, }; } buildPrompt(template, variables) { let prompt = template; Object.entries(variables).forEach(([key, value]) => { const placeholder = `{{${key}}}`; prompt = prompt.replace(new RegExp(placeholder, 'g'), String(value)); }); return prompt; } buildMultiplePrompt(template, variables) { return this.buildPrompt(template, variables); } parseMultipleResults(content) { // 번호가 매겨진 리스트 파싱 (1. 2. 3. 또는 1) 2) 3) 형식) const numbered = content.match(/^\d+[.)]\s*(.+)$/gm); if (numbered && numbered.length > 1) { return numbered.map(line => line.replace(/^\d+[.)]\s*/, '').trim()); } // 줄바꿈으로 구분된 경우 - 빈 줄과 구분자는 제외 const lines = content.split('\n') .map(line => line.trim()) .filter(line => { if (line.length === 0) return false; if (line.match(/^[\d\-\*\.•]\s*$/)) return false; if (line.match(/^-+$/)) return false; if (line.match(/^\*+$/)) return false; return true; }); // 각 줄이 유효한 질문/답변인지 확인 const validLines = lines.filter(line => { // 너무 짧은 텍스트는 제외 if (line.length < 3) return false; // 단순 구분자는 제외 if (line.match(/^[\d\-\*\.•\s]+$/)) return false; return true; }); if (validLines.length > 1) { return validLines; } // 단일 결과인 경우 - 여러 질문이 하나의 텍스트에 들어있을 수 있음 const singleContent = content.trim(); // 질문 패턴으로 분리 시도 (? 로 끝나는 문장들) const questionPattern = /[^?]*\?/g; const questions = singleContent.match(questionPattern); if (questions && questions.length > 1) { return questions.map(q => q.trim()).filter(q => q.length > 3); } // 문장 단위로 분리 시도 (. 또는 ? 또는 ! 로 끝나는 문장들) const sentencePattern = /[^.!?]*[.!?]/g; const sentences = singleContent.match(sentencePattern); if (sentences && sentences.length > 1) { return sentences.map(s => s.trim()).filter(s => s.length > 3); } return [singleContent]; } } exports.BaseTransform = BaseTransform; //# sourceMappingURL=BaseTransform.js.map