export type DeflufferProfile = "off" | "safe" | "standardGuardedDedupe"; export interface CompressionResult { original: string; text: string; profile: DeflufferProfile; originalTokens: number; defluffedTokens: number; savedTokens: number; savingsPct: number; changed: boolean; safe: boolean; reason?: string; warnings: string[]; } type Dictionary = { phrases: Record; logic?: Record; synonyms: Record; blacklist: string[]; guardSensitive?: boolean; dedupeAdjacentWords?: boolean; }; function escapeRegex(value: string): string { return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function cleanup(text: string): string { return text .replace(/\s+/g, " ") .replace(/^\s*[,;:]\s*/g, "") .replace(/\s+([.,?!;:)\]}])/g, "$1") .replace(/([({\[])\s+/g, "$1") .replace(/,{2,}/g, ",") .replace(/,\s*([.!?])/g, "$1") .replace(/\?\s*\.+/g, "?") .replace(/!\s*\.+/g, "!") .replace(/\.\s*\?/g, "?") .replace(/\.\s*!/g, "!") .replace(/^!+\s+(?=[A-Za-z])/, "") .trim(); } type ProtectedSpan = { start: number; end: number; text: string }; function nonOverlapping(spans: ProtectedSpan[]): ProtectedSpan[] { const result: ProtectedSpan[] = []; for (const span of spans.sort((a, b) => a.start - b.start || b.end - a.end)) { if (result.some((kept) => span.start < kept.end && span.end > kept.start)) continue; result.push(span); } return result; } function findJsonSpans(text: string): ProtectedSpan[] { const spans: ProtectedSpan[] = []; for (let start = 0; start < text.length; start++) { const opener = text[start]; if (opener !== "{" && opener !== "[") continue; const stack: string[] = [opener === "{" ? "}" : "]"]; let inString = false; let escaped = false; for (let i = start + 1; i < text.length; i++) { const char = text[i]!; if (inString) { if (escaped) escaped = false; else if (char === "\\") escaped = true; else if (char === '"') inString = false; continue; } if (char === '"') { inString = true; continue; } if (char === "{" || char === "[") { stack.push(char === "{" ? "}" : "]"); continue; } if (char === "}" || char === "]") { if (stack.pop() !== char) break; if (stack.length === 0) { const candidate = text.slice(start, i + 1); try { JSON.parse(candidate); spans.push({ start, end: i + 1, text: candidate }); start = i; } catch { // Not JSON; leave it editable. } break; } } } } return nonOverlapping(spans); } function findYamlSpans(text: string): ProtectedSpan[] { const lines = text.split(/(?<=\n)/); const spans: ProtectedSpan[] = []; let offset = 0; let blockStart: number | undefined; let blockEnd = 0; let yamlLines = 0; const yamlLine = /^\s{0,8}[A-Za-z0-9_-]+:\s*(?:[^\n]*)\r?\n?$/; function flush() { if (blockStart !== undefined && yamlLines >= 2) { const textBlock = text.slice(blockStart, blockEnd).replace(/\s+$/g, ""); spans.push({ start: blockStart, end: blockStart + textBlock.length, text: textBlock, }); } blockStart = undefined; blockEnd = 0; yamlLines = 0; } for (const line of lines) { const bare = line.replace(/\r?\n$/, ""); if (yamlLine.test(line) && !bare.includes(". ")) { blockStart ??= offset; blockEnd = offset + line.length; yamlLines++; } else if (bare.trim() === "" && blockStart !== undefined) { blockEnd = offset + line.length; } else { flush(); } offset += line.length; } flush(); return nonOverlapping(spans); } function protectSpans( text: string, spans: ProtectedSpan[], protectedItems: string[], ): string { for (const span of [...spans].sort((a, b) => b.start - a.start)) { protectedItems.push(span.text); text = `${text.slice(0, span.start)}PROT${protectedItems.length - 1}PROT${text.slice(span.end)}`; } return text; } function protectStructuredData(text: string, protectedItems: string[]): string { text = protectSpans(text, findJsonSpans(text), protectedItems); text = protectSpans(text, findYamlSpans(text), protectedItems); return text; } function protectExtended(text: string, protectedItems: string[]): string { const patterns = [ /```[\s\S]*?```/g, /`[^`]+`/g, /https?:\/\/[^\s)\]}>,]+/g, /\b[A-Z_][A-Z0-9_]{2,}\b/g, /(?:\.\.?\/|\/|[A-Za-z]:\\\\)[^\s,;:)\]}]+/g, /--[a-zA-Z0-9][a-zA-Z0-9_-]*/g, /(['"])(?:(?!\1).|\\.)*\1/g, ]; for (const pattern of patterns) { text = text.replace(pattern, (match) => { if (/^PROT\d+PROT$/.test(match)) return match; protectedItems.push(match); return `PROT${protectedItems.length - 1}PROT`; }); } return text; } function protectSensitiveContexts( text: string, protectedItems: string[], ): string { return text.replace( /\b(?:do not|don't|never)\s+replace\s+defined\s+terms?[^.?!]*/gi, (match) => { protectedItems.push(match); return `PROT${protectedItems.length - 1}PROT`; }, ); } function applyPhraseMap( text: string, map: Record, protectedItems: string[], ): string { const entries = Object.entries(map) .filter(([phrase]) => phrase) .sort((a, b) => b[0].length - a[0].length); for (const [phrase, replacement] of entries) { const regex = new RegExp(`\\b${escapeRegex(phrase)}\\b`, "gi"); text = text.replace(regex, () => { if (!replacement || replacement.trim() === "") return " "; protectedItems.push(replacement); return `PROT${protectedItems.length - 1}PROT`; }); } return text; } function applyTokenMap( text: string, blacklist: Set, synonyms: Record, ): string { return text .split(/(\b[a-zA-Z0-9_'-]+\b)/) .map((token) => { if (!/^[a-zA-Z0-9_'-]+$/.test(token)) return token; if (/^PROT\d+PROT$/.test(token)) return token; const lower = token.toLowerCase(); if (blacklist.has(lower)) return ""; if (synonyms[lower]) return synonyms[lower]; return token; }) .join(""); } function restoreProtected(text: string, protectedItems: string[]): string { protectedItems.forEach((item, index) => { const placeholder = `PROT${index}PROT`; while (text.includes(placeholder)) text = text.replace(placeholder, item); }); return text; } function removeAdjacentDuplicateWords(text: string): string { let prev: string; do { prev = text; text = text.replace(/\b([A-Za-z][A-Za-z'-]*)([\s,]+)\1\b/gi, "$1"); } while (text !== prev); return text; } function artifactWarnings(text: string, original: string): string[] { const warnings: string[] = []; if (!/^\s*[,;:]/.test(original) && /^\s*[,;:]/.test(text)) warnings.push("leading punctuation artifact"); if (/\bI\s+am\s+need\b/i.test(text)) warnings.push("grammar artifact: I am need"); if (/[?!]\s*\.(?:\s|$)/.test(text)) warnings.push("punctuation artifact"); return warnings; } export function estimateTokens(text: string): number { const normalized = text.trim(); if (!normalized) return 0; const pieces = normalized.match(/[A-Za-z0-9_]+|[^\sA-Za-z0-9_]/g) || []; let total = 0; for (const piece of pieces) { if (/^[A-Za-z0-9_]+$/.test(piece)) total += Math.max(1, Math.ceil(piece.length / 4.2)); else total += 1; } return total; } const safe: Dictionary = { phrases: { "hello there": "", hello: "", "thank you so much": "", "thank you": "", thanks: "", "if you do not mind": "", "if you don't mind": "", "i would really appreciate it if you could": "", "i would appreciate it if you could": "", "could you please": "", "would you please": "", "please provide": "provide", please: "", "make sure that": "ensure", "due to the fact that": "because", "take into consideration that": "consider", "at the very end": "end", "act as a": "be", "i am really trying to figure out how to": "I need to", "i am trying to figure out how to": "I need to", "trying to figure out how to": "need to", "all of the information": "all information", "provide a step by step guide": "provide steps", "step by step guide": "steps", "in order to": "to", "for the purpose of": "to", "as soon as possible": "ASAP", "let me know if you need anything else": "", "feel free to": "", "no external libraries": "no external libs", "without using any external libraries": "without external libs", }, synonyms: { configurations: "configs", configuration: "config", parameters: "params", microservice: "service", }, blacklist: ["really", "basically", "actually", "simply", "just"], }; const standardGuardedDedupe: Dictionary = { phrases: { ...safe.phrases, "greater than or equal to": ">=", "less than or equal to": "<=", "strictly equals to": "===", "is equal to": "=", "is not equal to": "!=", "the application is": "app is", "the results are": "results are", "the output should be": "output must be", "it is required that you": "you must", "currently in the production environment": "in production", "standard JSON object": "JSON object", um: "", "yeah so": "", like: "", "can you, can you please": "", "basically basically": "", }, logic: {}, synonyms: { ...safe.synonyms, application: "app", database: "DB", repository: "repo", environment: "env", information: "info", function: "fn", functions: "fns", javascript: "JS", python: "Python", kubernetes: "Kubernetes", }, blacklist: safe.blacklist, guardSensitive: true, dedupeAdjacentWords: true, }; const dictionaries: Record, Dictionary> = { safe, standardGuardedDedupe, }; export function looksExactSensitive(text: string): string | undefined { const checks: Array<[RegExp, string]> = [ [/\blegal meaning\b/i, "legal meaning"], [/\bdefined terms?\b/i, "defined terms"], [/\b(MUST|SHOULD|MAY)\b/, "RFC/legal keywords"], [/\bdo not replace defined terms?\b/i, "defined-term preservation"], [/\boutput only the file content\b/i, "exact file content"], ]; return checks.find(([regex]) => regex.test(text))?.[1]; } export function extractProtectedSpans(text: string): string[] { const codeBlocks = text.match(/```[\s\S]*?```/g) || []; const withoutFences = text.replace(/```[\s\S]*?```/g, " "); return [ ...codeBlocks, ...findJsonSpans(withoutFences).map((span) => span.text), ...findYamlSpans(withoutFences).map((span) => span.text), ...(withoutFences.match(/`[^`]+`/g) || []), ...(text.match(/https?:\/\/[^\s)\]}>,]+/g) || []), ...(text.match(/\b[A-Z_][A-Z0-9_]{2,}\b/g) || []), ...(text.match(/--[a-zA-Z0-9][a-zA-Z0-9_-]*/g) || []), ]; } export function compressText( original: string, profile: DeflufferProfile, ): CompressionResult { const originalTokens = estimateTokens(original); const warnings: string[] = []; if (profile === "off") { return { original, text: original, profile, originalTokens, defluffedTokens: originalTokens, savedTokens: 0, savingsPct: 0, changed: false, safe: true, reason: "profile off", warnings, }; } const dict = dictionaries[profile]; const protectedSpans = extractProtectedSpans(original); const protectedItems: string[] = []; let text = original; text = protectStructuredData(text, protectedItems); text = protectExtended(text, protectedItems); if (dict.guardSensitive) text = protectSensitiveContexts(text, protectedItems); const blacklist = new Set(dict.blacklist || []); for (const entry of blacklist) { if (!entry.includes(" ")) continue; text = text.replace(new RegExp(`\\b${escapeRegex(entry)}\\b`, "gi"), ""); } text = applyPhraseMap( text, { ...dict.phrases, ...(dict.logic || {}) }, protectedItems, ); text = applyTokenMap(text, blacklist, dict.synonyms || {}); if (dict.dedupeAdjacentWords) text = removeAdjacentDuplicateWords(text); text = cleanup(text); text = restoreProtected(text, protectedItems).trim(); const missingProtected = protectedSpans.filter( (span) => !text.includes(span), ); if (missingProtected.length) warnings.push(`protected span changed (${missingProtected.length})`); const originalHadNegation = /\b(must not|do not|never|not|without|no)\b/i.test(original); const nextHasNegation = /\b(must not|do not|never|not|without|no)\b|!/i.test( text, ); if (originalHadNegation && !nextHasNegation) warnings.push("negation marker lost"); warnings.push(...artifactWarnings(text, original)); const defluffedTokens = estimateTokens(text); const savedTokens = originalTokens - defluffedTokens; const savingsPct = originalTokens ? (savedTokens / originalTokens) * 100 : 0; const safe = warnings.length === 0; return { original, text, profile, originalTokens, defluffedTokens, savedTokens, savingsPct, changed: text !== original, safe, reason: safe ? undefined : warnings.join("; "), warnings, }; }