@yogesh0333/yogiway-prompt
Version:
Free & Open Source Prompt Optimization Library - Save 30-50% on AI API costs. Multi-language, multi-platform support.
132 lines (131 loc) • 4.53 kB
JavaScript
;
/**
* Streaming Optimization for Large Prompts
* Processes prompts in chunks for better performance
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.streamOptimize = streamOptimize;
exports.optimizeLargePrompt = optimizeLargePrompt;
exports.optimizeWithProgress = optimizeWithProgress;
const optimizer_1 = require("./optimizer");
/**
* Stream optimization for large prompts
*/
async function* streamOptimize(prompt, options = {}) {
const { chunkSize = 10000, overlap = 200, onChunk, ...optimizeOptions } = options;
// Split prompt into chunks
const chunks = splitIntoChunks(prompt, chunkSize, overlap);
for (const chunk of chunks) {
// Optimize each chunk
const result = (0, optimizer_1.optimizePrompt)(chunk, optimizeOptions);
// Call callback if provided
if (onChunk) {
onChunk(result);
}
// Yield result
yield result;
}
}
/**
* Split text into chunks with overlap
*/
function splitIntoChunks(text, chunkSize, overlap) {
if (!text || text.length === 0) {
return [];
}
const chunks = [];
let start = 0;
const maxChunks = 10000; // Safety limit
while (start < text.length && chunks.length < maxChunks) {
let end = Math.min(start + chunkSize, text.length);
// Try to break at sentence boundary
if (end < text.length) {
const lastPeriod = text.lastIndexOf('.', end);
const lastNewline = text.lastIndexOf('\n', end);
const breakPoint = Math.max(lastPeriod, lastNewline);
if (breakPoint > start + chunkSize * 0.5) {
end = breakPoint + 1;
}
}
const chunk = text.slice(start, end);
if (chunk.length > 0) {
chunks.push(chunk);
}
start = Math.max(start + 1, end - overlap);
// Prevent infinite loop
if (start >= text.length) {
break;
}
}
return chunks;
}
/**
* Optimize large prompt with streaming (returns combined result)
*/
async function optimizeLargePrompt(prompt, options = {}) {
const chunks = [];
for await (const result of streamOptimize(prompt, options)) {
chunks.push(result);
}
// Combine results
const combined = combineResults(chunks);
return combined;
}
/**
* Combine multiple optimization results
*/
function combineResults(results) {
if (results.length === 0) {
throw new Error('No results to combine');
}
if (results.length === 1) {
return results[0];
}
const original = results.map(r => r.original).join('');
const optimized = results.map(r => r.optimized).join('');
const totalOriginalTokens = results.reduce((sum, r) => sum + r.stats.originalTokens, 0);
const totalOptimizedTokens = results.reduce((sum, r) => sum + r.stats.optimizedTokens, 0);
const totalReduction = totalOriginalTokens - totalOptimizedTokens;
const reductionPercentage = (totalReduction / totalOriginalTokens) * 100;
const totalSavings = results.reduce((sum, r) => sum + r.savings.estimated, 0);
return {
original,
optimized,
reduction: {
tokens: totalReduction,
percentage: Math.round(reductionPercentage * 100) / 100,
characters: original.length - optimized.length,
words: results.reduce((sum, r) => sum + r.reduction.words, 0),
},
savings: {
estimated: totalSavings,
currency: results[0].savings.currency,
},
stats: {
originalTokens: totalOriginalTokens,
optimizedTokens: totalOptimizedTokens,
originalChars: original.length,
optimizedChars: optimized.length,
},
};
}
/**
* Stream optimization with progress callback
*/
async function optimizeWithProgress(prompt, options = {}) {
const { onProgress, ...streamOptions } = options;
const chunks = splitIntoChunks(prompt, streamOptions.chunkSize || 10000, streamOptions.overlap || 200);
const results = [];
for (let i = 0; i < chunks.length; i++) {
const result = (0, optimizer_1.optimizePrompt)(chunks[i], streamOptions);
results.push(result);
if (onProgress) {
onProgress({
current: i + 1,
total: chunks.length,
percentage: Math.round(((i + 1) / chunks.length) * 100),
});
}
}
return combineResults(results);
}