UNPKG

@yogesh0333/yogiway-prompt

Version:

Free & Open Source Prompt Optimization Library - Save 30-50% on AI API costs. Multi-language, multi-platform support.

203 lines (202 loc) 7.06 kB
"use strict"; /** * Advanced Optimization Algorithms * More sophisticated optimization techniques */ Object.defineProperty(exports, "__esModule", { value: true }); exports.tfidfOptimize = tfidfOptimize; exports.entropyOptimize = entropyOptimize; exports.ngramOptimize = ngramOptimize; exports.semanticSimilarityOptimize = semanticSimilarityOptimize; exports.compressionRatioOptimize = compressionRatioOptimize; exports.adaptiveOptimize = adaptiveOptimize; /** * TF-IDF based optimization * Removes low-importance words based on term frequency */ function tfidfOptimize(text, threshold = 0.1) { const words = text.toLowerCase().split(/\s+/); const wordFreq = new Map(); // Calculate term frequency words.forEach((word) => { wordFreq.set(word, (wordFreq.get(word) || 0) + 1); }); const maxFreq = Math.max(...Array.from(wordFreq.values())); // Remove low TF words (common filler words) const filtered = words.filter((word) => { const freq = wordFreq.get(word) || 0; const tf = freq / maxFreq; return tf > threshold || word.length > 3; // Keep important words }); return filtered.join(" "); } /** * Entropy-based optimization * Removes high-entropy (random) words that don't contribute to meaning */ function entropyOptimize(text) { const sentences = text.split(/[.!?]+/).filter((s) => s.trim().length > 0); const words = text.toLowerCase().split(/\s+/); // Calculate word entropy const wordCounts = new Map(); words.forEach((word) => { wordCounts.set(word, (wordCounts.get(word) || 0) + 1); }); const totalWords = words.length; const entropy = new Map(); wordCounts.forEach((count, word) => { const p = count / totalWords; entropy.set(word, -p * Math.log2(p)); }); // Remove high-entropy words (too random/common) const avgEntropy = Array.from(entropy.values()).reduce((a, b) => a + b, 0) / entropy.size; const filtered = words.filter((word) => { const wordEntropy = entropy.get(word) || 0; return wordEntropy < avgEntropy * 1.5; // Keep words with reasonable entropy }); return filtered.join(" "); } /** * N-gram optimization * Removes redundant n-grams */ function ngramOptimize(text, n = 2) { if (!text || text.trim().length === 0) { return text; } const words = text.split(/\s+/).filter((w) => w.length > 0); if (words.length < n) { return text; } const ngrams = new Map(); // Extract n-grams for (let i = 0; i <= words.length - n; i++) { const ngram = words .slice(i, i + n) .join(" ") .toLowerCase(); ngrams.set(ngram, (ngrams.get(ngram) || 0) + 1); } // Find redundant n-grams (appear multiple times) const redundant = new Set(); ngrams.forEach((count, ngram) => { if (count > 1 && ngram.length > 5) { // Only remove longer redundant phrases redundant.add(ngram); } }); if (redundant.size === 0) { // No redundant n-grams, just compress whitespace return text.replace(/\s+/g, " ").trim(); } // Remove redundant n-grams (keep first occurrence) const result = []; const seen = new Set(); for (let i = 0; i < words.length; i++) { let skip = false; // Check if current position starts a redundant n-gram if (i <= words.length - n) { const ngram = words .slice(i, i + n) .join(" ") .toLowerCase(); if (redundant.has(ngram) && seen.has(ngram)) { skip = true; } else if (redundant.has(ngram)) { seen.add(ngram); } } if (!skip) { result.push(words[i]); } } return result.join(" ").replace(/\s+/g, " ").trim(); } /** * Semantic similarity optimization * Removes semantically similar phrases */ function semanticSimilarityOptimize(text) { // Simple implementation using word overlap const sentences = text.split(/[.!?]+/).filter((s) => s.trim().length > 0); const filtered = []; const seenConcepts = new Set(); sentences.forEach((sentence) => { const words = sentence .toLowerCase() .split(/\s+/) .filter((w) => w.length > 3); const concept = words.slice(0, 3).join(" "); // Use first 3 words as concept if (!seenConcepts.has(concept)) { filtered.push(sentence.trim()); seenConcepts.add(concept); } }); return filtered.join(". ") + (text.endsWith(".") ? "." : ""); } /** * Compression ratio optimization * Optimizes to achieve target compression ratio */ function compressionRatioOptimize(text, targetRatio = 0.7) { let optimized = text; const originalLength = text.length; const targetLength = Math.floor(originalLength * targetRatio); // Apply optimizations until target is reached const optimizations = [ (t) => t.replace(/\b(very|really|quite|absolutely)\s+/gi, ""), (t) => t.replace(/\b(please\s+note\s+that|it\s+is\s+important\s+that)\b/gi, ""), (t) => t.replace(/\s+/g, " "), (t) => t.replace(/\b(I\s+think\s+that|I\s+believe\s+that)\b/gi, ""), ]; for (const optimize of optimizations) { optimized = optimize(optimized); if (optimized.length <= targetLength) { break; } } return optimized; } /** * Adaptive optimization * Chooses best algorithm based on text characteristics */ function adaptiveOptimize(text) { if (!text || text.length === 0) { return text; } const length = text.length; const wordCount = text.split(/\s+/).filter((w) => w.length > 0).length; const sentenceCount = text .split(/[.!?]+/) .filter((s) => s.trim().length > 0).length; // Choose algorithm based on text characteristics if (length > 10000) { // Very long text: use compression ratio return compressionRatioOptimize(text, 0.6); } else if (wordCount > 500) { // Long text: use TF-IDF return tfidfOptimize(text, 0.15); } else if (sentenceCount > 20) { // Many sentences: use semantic similarity return semanticSimilarityOptimize(text); } else if (wordCount > 10) { // Short text: use compression ratio for better results let optimized = compressionRatioOptimize(text, 0.75); // Also try removing common phrases optimized = optimized.replace(/\b(please\s+note\s+that|it\s+is\s+very\s+important|it\s+is\s+absolutely\s+essential)\b/gi, ""); optimized = optimized.replace(/\b(very|really|quite|absolutely)\s+/gi, ""); return optimized.replace(/\s+/g, " ").trim(); } else { // Very short text: just compress whitespace and remove filler return text .replace(/\b(very|really|quite)\s+/gi, "") .replace(/\s+/g, " ") .trim(); } }