aiwg
Version:
Cognitive architecture for AI-augmented software development with structured memory, ensemble validation, and closed-loop correction. FAIR-aligned artifacts, 84% cost reduction via human-in-the-loop, standards adopted by 100+ organizations.
1,014 lines (857 loc) • 30.7 kB
text/typescript
/**
* Content Diversification Engine
*
* Generates diverse variations of content using different voices, perspectives,
* and structural approaches while maintaining authenticity and avoiding AI detection patterns.
*/
export type Voice = 'academic' | 'technical' | 'executive' | 'casual';
export type Perspective = 'first-person' | 'third-person' | 'neutral';
export type Structure = 'bullets' | 'narrative' | 'qa' | 'tutorial' | 'comparison';
export type Tone = 'formal' | 'conversational' | 'enthusiastic' | 'matter-of-fact';
export type Length = 'concise' | 'standard' | 'comprehensive';
export interface DiversificationOptions {
voice?: Voice;
perspective?: Perspective;
structure?: Structure;
tone?: Tone;
length?: Length;
}
export interface ContentVariation {
content: string;
options: DiversificationOptions;
score: {
authenticity: number;
diversity: number; // how different from original
};
changes: string[]; // description of changes made
}
export interface DiversificationResult {
original: string;
variations: ContentVariation[];
metadata: {
originalVoice: Voice | 'mixed';
originalLength: number;
variationsGenerated: number;
};
}
interface VoiceCharacteristics {
markers: RegExp[];
vocabulary: string[];
structurePreferences: string[];
}
/**
* Core Content Diversification Engine
*/
export class ContentDiversifier {
private voiceCharacteristics: Map<Voice, VoiceCharacteristics>;
constructor() {
this.voiceCharacteristics = this.initializeVoiceCharacteristics();
}
/**
* Generate multiple variations of content with different options
*/
async diversify(
content: string,
optionsList: DiversificationOptions[]
): Promise<DiversificationResult> {
const originalVoice = this.detectVoice(content);
const variations: ContentVariation[] = [];
for (const options of optionsList) {
const variation = await this.generateVariation(content, options);
variations.push(variation);
}
return {
original: content,
variations,
metadata: {
originalVoice,
originalLength: content.length,
variationsGenerated: variations.length,
},
};
}
/**
* Generate a single variation with specified options
*/
async generateVariation(
content: string,
options: DiversificationOptions
): Promise<ContentVariation> {
let transformed = content;
const changes: string[] = [];
// Apply transformations in order
if (options.voice) {
const currentVoice = this.detectVoice(transformed);
transformed = this.transformVoice(transformed, currentVoice, options.voice);
changes.push(`Voice: ${currentVoice} → ${options.voice}`);
}
if (options.perspective) {
transformed = this.changePerspective(transformed, options.perspective);
changes.push(`Perspective: → ${options.perspective}`);
}
if (options.structure) {
transformed = this.restructure(transformed, options.structure);
changes.push(`Structure: → ${options.structure}`);
}
if (options.tone) {
transformed = this.adjustTone(transformed, options.tone);
changes.push(`Tone: → ${options.tone}`);
}
if (options.length) {
transformed = this.adjustLength(transformed, options.length);
changes.push(`Length: → ${options.length}`);
}
// Calculate scores
const authenticity = this.scoreAuthenticity(transformed);
const diversity = this.scoreDiversity(content, transformed);
return {
content: transformed,
options,
score: {
authenticity,
diversity,
},
changes,
};
}
/**
* Transform content from one voice to another
*/
transformVoice(content: string, _fromVoice: Voice | 'mixed', toVoice: Voice): string {
switch (toVoice) {
case 'academic':
return this.toAcademicVoice(content);
case 'technical':
return this.toTechnicalVoice(content);
case 'executive':
return this.toExecutiveVoice(content);
case 'casual':
return this.toCasualVoice(content);
default:
return content;
}
}
/**
* Transform to academic voice
*/
toAcademicVoice(content: string): string {
let transformed = content;
let changeCount = 0;
// Add hedging and qualifications (deterministic: first match always transforms)
transformed = transformed.replace(
/\b(is|are|will|must|should)\b/gi,
(match) => {
const hedges = ['appears to be', 'suggests', 'may', 'could', 'might'];
if (changeCount < 2) {
changeCount++;
return hedges[changeCount % hedges.length];
}
return Math.random() > 0.7 ? hedges[Math.floor(Math.random() * hedges.length)] : match;
}
);
// Add citations and references
const sentences = this.splitIntoSentences(transformed);
const citations = ['(Smith, 2023)', '(Johnson et al., 2022)', '(Lee & Chen, 2024)', '(Anderson, 2021)'];
// Always add at least one citation to the first applicable sentence
if (sentences.length > 0) {
const citation = citations[0];
sentences[0] = sentences[0].replace(/\.$/, ` ${citation}.`);
}
// Optionally add more citations
const citationSentences = Math.floor(sentences.length * 0.3);
for (let i = 1; i < citationSentences && i < sentences.length; i++) {
const idx = Math.floor(Math.random() * sentences.length);
const citation = citations[Math.floor(Math.random() * citations.length)];
if (!sentences[idx].includes('(')) {
sentences[idx] = sentences[idx].replace(/\.$/, ` ${citation}.`);
}
}
transformed = sentences.join(' ');
// Add formal transitions (at least one if multiple sentences)
let transitionAdded = false;
transformed = transformed.replace(
/\. ([A-Z])/g,
(match, letter) => {
const transitions = [
'. Furthermore, ',
'. Moreover, ',
'. However, ',
'. Nevertheless, ',
'. Consequently, ',
];
if (!transitionAdded) {
transitionAdded = true;
return transitions[0] + letter;
}
return Math.random() > 0.7
? transitions[Math.floor(Math.random() * transitions.length)] + letter
: match;
}
);
// Add acknowledgment of limitations if not present and content is non-empty
if (transformed.trim() && !transformed.includes('limit')) {
transformed += ' It should be noted that this approach has certain limitations that warrant further investigation.';
}
return transformed;
}
/**
* Transform to technical voice
*/
toTechnicalVoice(content: string): string {
let transformed = content;
let metricsAdded = 0;
// Add specific metrics and numbers (deterministic: first matches always transform)
transformed = transformed.replace(
/\b(fast|slow|quick|better|improved|reduced|faster)\b/gi,
(match) => {
const metrics = ['30%', '2.5x', '150ms', '40MB', '5 seconds'];
if (metricsAdded < 1) {
metricsAdded++;
return `${match} by ${metrics[metricsAdded % metrics.length]}`;
}
return Math.random() > 0.6
? `${match} by ${metrics[Math.floor(Math.random() * metrics.length)]}`
: match;
}
);
// Add technical terminology (deterministically apply first matching term)
const technicalTerms: Record<string, string> = {
'data': 'payload',
'information': 'metadata',
'storage': 'persistence layer',
'speed': 'latency',
'connection': 'TCP connection',
'code': 'implementation',
};
let termReplaced = false;
for (const [casual, technical] of Object.entries(technicalTerms)) {
const regex = new RegExp(`\\b${casual}\\b`, 'gi');
if (!termReplaced && regex.test(transformed)) {
transformed = transformed.replace(regex, technical);
termReplaced = true;
} else if (Math.random() > 0.5) {
transformed = transformed.replace(regex, technical);
}
}
// Always add implementation details
const implementationExamples = [
' This can be achieved through connection pooling.',
' The implementation leverages a non-blocking I/O model.',
' We utilize a LRU cache with a 10-minute TTL.',
' The system employs exponential backoff for retry logic.',
];
const sentences = this.splitIntoSentences(transformed);
const insertIdx = Math.floor(sentences.length / 2);
sentences[insertIdx] += implementationExamples[0];
transformed = sentences.join(' ');
return transformed;
}
/**
* Transform to executive voice
*/
toExecutiveVoice(content: string): string {
let transformed = content;
// Remove hedging - make assertions
transformed = transformed.replace(/\b(might|could|possibly|perhaps|maybe)\b/gi, 'will');
transformed = transformed.replace(/\b(appears to|seems to|suggests)\b/gi, 'demonstrates');
// Add business metrics (deterministic for at least first match)
const businessMetrics = [
'$500K annually',
'30% ROI',
'2 quarters',
'15% market share',
'$2M cost savings',
'40% efficiency gain',
];
let metricsAdded = 0;
transformed = transformed.replace(
/\b(savings|revenue|cost|value|benefit)\b/gi,
(match) => {
if (metricsAdded < 1) {
metricsAdded++;
return `${match} of ${businessMetrics[0]}`;
}
return Math.random() > 0.6
? `${match} of ${businessMetrics[Math.floor(Math.random() * businessMetrics.length)]}`
: match;
}
);
// Add decision-focused language (always add to first sentence)
const decisionPhrases = [
'We recommend',
'The strategic priority is',
'Our analysis indicates',
'The optimal approach requires',
'To maximize value, we should',
];
const sentences = this.splitIntoSentences(transformed);
if (sentences.length > 0) {
const firstSentence = decisionPhrases[0] + ' ' + sentences[0].toLowerCase();
sentences[0] = firstSentence;
}
// Always add risk/opportunity framing
sentences.push('This approach mitigates execution risk while positioning us for Q3 growth targets.');
return sentences.join(' ');
}
/**
* Transform to casual voice
*/
toCasualVoice(content: string): string {
let transformed = content;
// Add contractions
const contractions: Record<string, string> = {
'do not': "don't",
'does not': "doesn't",
'will not': "won't",
'cannot': "can't",
'it is': "it's",
'that is': "that's",
'we are': "we're",
'you are': "you're",
'they are': "they're",
};
for (const [formal, casual] of Object.entries(contractions)) {
const regex = new RegExp(`\\b${formal}\\b`, 'gi');
transformed = transformed.replace(regex, casual);
}
// Add conversational phrases (always add to first sentence)
const conversationalStarts = [
"Here's the thing - ",
"Look, ",
"The reality is ",
"Here's what matters: ",
"Bottom line? ",
];
const sentences = this.splitIntoSentences(transformed);
if (sentences.length > 0) {
sentences[0] = conversationalStarts[0] + sentences[0].toLowerCase();
}
// Always add personal examples
const personalExamples = [
"I've seen this pattern in production systems before.",
"We ran into this exact issue last quarter.",
"This reminds me of a project we did in 2022.",
];
sentences.push(personalExamples[0]);
// Always add analogies
const analogies = [
"Think of it like a conveyor belt - things need to move at a steady pace.",
"It's similar to how a restaurant kitchen handles orders during rush hour.",
"You can think of this as the difference between a highway and city streets.",
];
sentences.splice(
Math.floor(sentences.length / 2),
0,
analogies[0]
);
return sentences.join(' ');
}
/**
* Change perspective of content
*/
changePerspective(content: string, perspective: Perspective): string {
switch (perspective) {
case 'first-person':
return this.toFirstPerson(content);
case 'third-person':
return this.toThirdPerson(content);
case 'neutral':
return this.toNeutral(content);
default:
return content;
}
}
/**
* Convert to first-person perspective
*/
toFirstPerson(content: string): string {
let transformed = content;
// Replace third-person with first-person
transformed = transformed.replace(/\bone\b/gi, 'I');
transformed = transformed.replace(/\bthe (user|developer|reader)\b/gi, 'I');
transformed = transformed.replace(/\bwe can\b/gi, 'I can');
// Add personal statements
if (!transformed.includes(' I ') && Math.random() > 0.5) {
const sentences = this.splitIntoSentences(transformed);
sentences[0] = "In my experience, " + sentences[0].toLowerCase();
transformed = sentences.join(' ');
}
return transformed;
}
/**
* Convert to third-person perspective
*/
toThirdPerson(content: string): string {
let transformed = content;
// Replace first-person with third-person
transformed = transformed.replace(/\bI\b/g, 'one');
transformed = transformed.replace(/\bmy\b/gi, 'their');
transformed = transformed.replace(/\bwe\b/gi, 'they');
transformed = transformed.replace(/\bour\b/gi, 'their');
return transformed;
}
/**
* Convert to neutral perspective
*/
toNeutral(content: string): string {
let transformed = content;
// Remove personal pronouns - use precise replacements
transformed = transformed.replace(/\bI\b/g, 'the system');
transformed = transformed.replace(/\bwe\b/gi, 'the approach');
transformed = transformed.replace(/\byou\b/gi, 'users');
transformed = transformed.replace(/\bmy\b/gi, 'the');
transformed = transformed.replace(/\bour\b/gi, 'the');
transformed = transformed.replace(/\byour\b/gi, 'user');
// Add passive voice - more carefully to avoid breaking grammar
transformed = transformed.replace(/\bcan configure\b/g, 'can be configured to');
transformed = transformed.replace(/\bcan handle\b/g, 'handles');
transformed = transformed.replace(/\bwill process\b/g, 'processes');
return transformed;
}
/**
* Restructure content into different format
*/
restructure(content: string, structure: Structure): string {
switch (structure) {
case 'bullets':
return this.toBulletPoints(content);
case 'narrative':
return this.toNarrative(content);
case 'qa':
return this.toQA(content);
case 'tutorial':
return this.toTutorial(content);
case 'comparison':
return this.toComparison(content);
default:
return content;
}
}
/**
* Convert to bullet point format
*/
toBulletPoints(content: string): string {
const sentences = this.splitIntoSentences(content);
const bullets = sentences.map(sentence => `- ${sentence.trim()}`);
return bullets.join('\n');
}
/**
* Convert to narrative format
*/
toNarrative(content: string): string {
const lines = content.split('\n').filter(line => line.trim());
let narrative = '';
for (let i = 0; i < lines.length; i++) {
const line = lines[i].replace(/^[-*]\s*/, '').trim();
if (i === 0) {
narrative += line + '. ';
} else {
const transitions = ['Additionally', 'Furthermore', 'Next', 'Then', 'Moreover', 'Also'];
const transition = transitions[Math.floor(Math.random() * transitions.length)];
narrative += `${transition}, ${line.toLowerCase()}. `;
}
}
return narrative.trim();
}
/**
* Convert to Q&A format
*/
toQA(content: string): string {
const sentences = this.splitIntoSentences(content);
let qa = '';
for (let i = 0; i < sentences.length; i += 2) {
const statement = sentences[i];
// Generate question from statement
const question = this.statementToQuestion(statement);
qa += `Q: ${question}\n`;
// Use statement as answer
const answer = sentences[i] + (sentences[i + 1] ? ' ' + sentences[i + 1] : '');
qa += `A: ${answer}\n\n`;
}
return qa.trim();
}
/**
* Convert to tutorial format
*/
toTutorial(content: string): string {
const sentences = this.splitIntoSentences(content);
let tutorial = '## Step-by-Step Guide\n\n';
sentences.forEach((sentence, idx) => {
tutorial += `### Step ${idx + 1}\n\n${sentence}\n\n`;
});
return tutorial;
}
/**
* Convert to comparison format
*/
toComparison(content: string): string {
const sentences = this.splitIntoSentences(content);
const midpoint = Math.floor(sentences.length / 2);
let comparison = '## Approach A\n\n';
for (let i = 0; i < midpoint; i++) {
comparison += `- ${sentences[i]}\n`;
}
comparison += '\n## Approach B\n\n';
for (let i = midpoint; i < sentences.length; i++) {
comparison += `- ${sentences[i]}\n`;
}
return comparison;
}
/**
* Adjust tone of content
*/
adjustTone(content: string, tone: Tone): string {
switch (tone) {
case 'formal':
return this.toFormal(content);
case 'conversational':
return this.toConversational(content);
case 'enthusiastic':
return this.toEnthusiastic(content);
case 'matter-of-fact':
return this.toMatterOfFact(content);
default:
return content;
}
}
/**
* Convert to formal tone
*/
toFormal(content: string): string {
let transformed = content;
// Expand contractions
const expansions: Record<string, string> = {
"don't": 'do not',
"doesn't": 'does not',
"won't": 'will not',
"can't": 'cannot',
"it's": 'it is',
"that's": 'that is',
"we're": 'we are',
"here's": 'here is',
};
for (const [contraction, expansion] of Object.entries(expansions)) {
const regex = new RegExp(contraction, 'gi');
transformed = transformed.replace(regex, expansion);
}
// Remove casual phrases
transformed = transformed.replace(/\b(just|really|very|pretty)\b/gi, '');
// Remove informal starters
transformed = transformed.replace(/^(Here's the thing - |Look, |The reality is |Here's what matters: |Bottom line\? )/gi, '');
// Clean up spacing
transformed = transformed.replace(/\s+/g, ' ').trim();
return transformed;
}
/**
* Convert to conversational tone
*/
toConversational(content: string): string {
let transformed = content;
// Add conversational markers (always add to first sentence)
const markers = ['Well, ', 'So, ', 'Now, ', 'You see, '];
const sentences = this.splitIntoSentences(transformed);
if (sentences.length > 0) {
sentences[0] = markers[0] + sentences[0].toLowerCase();
}
// Always add a question
const questions = ['Make sense?', 'Follow me?', 'See what I mean?', 'Right?'];
sentences.push(questions[0]);
return sentences.join(' ');
}
/**
* Convert to enthusiastic tone
*/
toEnthusiastic(content: string): string {
let transformed = content;
let modifiedCount = 0;
// Add enthusiastic modifiers (deterministic: first match always transforms)
transformed = transformed.replace(
/\b(good|great|nice|effective|useful)\b/gi,
(match) => {
const enthusiastic = ['amazing', 'fantastic', 'excellent', 'outstanding', 'brilliant'];
if (modifiedCount < 1) {
modifiedCount++;
return enthusiastic[0];
}
return Math.random() > 0.6
? enthusiastic[Math.floor(Math.random() * enthusiastic.length)]
: match;
}
);
// Add exclamation points (at least one)
let exclamationAdded = false;
transformed = transformed.replace(/\./g, (match) => {
if (!exclamationAdded) {
exclamationAdded = true;
return '!';
}
return Math.random() > 0.7 ? '!' : match;
});
return transformed;
}
/**
* Convert to matter-of-fact tone
*/
toMatterOfFact(content: string): string {
let transformed = content;
// Remove exclamation points
transformed = transformed.replace(/!/g, '.');
// Remove qualifiers (with trailing space)
transformed = transformed.replace(/\b(very|really|extremely|quite|rather|absolutely)\b\s*/gi, '');
// Remove emphatic words (with trailing space)
transformed = transformed.replace(/\b(clearly|obviously|certainly|definitely)\b\s*/gi, '');
// Replace enthusiastic adjectives with neutral ones
transformed = transformed.replace(/\b(amazing|fantastic|incredible|excellent)\b/gi, (match) => {
const neutralReplacements: Record<string, string> = {
'amazing': 'notable',
'fantastic': 'good',
'incredible': 'significant',
'excellent': 'good',
};
return neutralReplacements[match.toLowerCase()] || match;
});
// Clean up spacing and multiple periods
transformed = transformed.replace(/\s+/g, ' ').trim();
transformed = transformed.replace(/\.+/g, '.');
return transformed;
}
/**
* Adjust length of content
*/
adjustLength(content: string, length: Length): string {
switch (length) {
case 'concise':
return this.toConcise(content);
case 'comprehensive':
return this.toComprehensive(content);
case 'standard':
default:
return content;
}
}
/**
* Shorten content
*/
toConcise(content: string): string {
const sentences = this.splitIntoSentences(content);
const targetLength = Math.ceil(sentences.length * 0.6);
// Keep most important sentences (first and last are usually key)
const kept = [
sentences[0],
...sentences.slice(1, -1).slice(0, targetLength - 2),
sentences[sentences.length - 1],
];
return kept.join(' ');
}
/**
* Expand content
*/
toComprehensive(content: string): string {
const sentences = this.splitIntoSentences(content);
const expanded: string[] = [];
for (const sentence of sentences) {
expanded.push(sentence);
// Add elaboration
if (Math.random() > 0.5) {
const elaborations = [
'This approach offers several advantages.',
'Let me explain this in more detail.',
'Consider the implications of this carefully.',
'This is particularly important in practice.',
];
expanded.push(elaborations[Math.floor(Math.random() * elaborations.length)]);
}
// Add examples
if (Math.random() > 0.7) {
expanded.push('For example, in a typical production environment, this pattern reduces latency by 25%.');
}
}
return expanded.join(' ');
}
/**
* Generate before/after example pair
*/
async generateBeforeAfter(topic: string): Promise<{ before: string; after: string }> {
// Generate AI-heavy "before" content
const before = this.generateAIHeavyContent(topic);
// Transform to authentic "after" content
const after = await this.generateVariation(before, {
voice: 'technical',
tone: 'conversational',
structure: 'narrative',
});
return {
before,
after: after.content,
};
}
/**
* Generate diverse scenarios for a concept
*/
async generateDiverseScenarios(concept: string, count: number): Promise<string[]> {
const scenarios: string[] = [];
const baseContent = `${concept} is an important consideration in software development.`;
const voiceOptions: Voice[] = ['academic', 'technical', 'executive', 'casual'];
for (let i = 0; i < count; i++) {
const voice = voiceOptions[i % voiceOptions.length];
const variation = await this.generateVariation(baseContent, {
voice,
perspective: i % 2 === 0 ? 'first-person' : 'neutral',
tone: i % 2 === 0 ? 'conversational' : 'formal',
});
scenarios.push(variation.content);
}
return scenarios;
}
// Private helper methods
private initializeVoiceCharacteristics(): Map<Voice, VoiceCharacteristics> {
const characteristics = new Map<Voice, VoiceCharacteristics>();
characteristics.set('academic', {
markers: [/\([\w\s,&]+,\s*\d{4}\)/, /suggests that/, /appears to/, /research indicates/i],
vocabulary: ['furthermore', 'moreover', 'nevertheless', 'consequently', 'empirical'],
structurePreferences: ['formal transitions', 'citations', 'hedging'],
});
characteristics.set('technical', {
markers: [/\d+(\.\d+)?\s*(ms|MB|GB|%)/, /implementation/, /latency/, /throughput/i],
vocabulary: ['payload', 'metadata', 'optimization', 'configuration', 'deployment'],
structurePreferences: ['metrics', 'code examples', 'specifications'],
});
characteristics.set('executive', {
markers: [/\$[\d,]+[KM]?/, /ROI/, /\d+%\s*(increase|decrease|improvement)/, /strategic/i],
vocabulary: ['strategic', 'leverage', 'optimize', 'maximize', 'stakeholder'],
structurePreferences: ['business impact', 'recommendations', 'decisions'],
});
characteristics.set('casual', {
markers: [/\b(don't|can't|won't|it's)\b/, /here's/i, /\bI\b/, /you know/i],
vocabulary: ["here's", 'basically', 'pretty', 'just', 'really'],
structurePreferences: ['contractions', 'personal examples', 'analogies'],
});
return characteristics;
}
private detectVoice(content: string): Voice | 'mixed' {
const scores = new Map<Voice, number>();
for (const [voice, characteristics] of this.voiceCharacteristics.entries()) {
let score = 0;
for (const marker of characteristics.markers) {
const matches = content.match(marker);
if (matches) {
score += matches.length;
}
}
for (const term of characteristics.vocabulary) {
const regex = new RegExp(`\\b${term}\\b`, 'gi');
const matches = content.match(regex);
if (matches) {
score += matches.length;
}
}
scores.set(voice, score);
}
const sortedScores = Array.from(scores.entries()).sort((a, b) => b[1] - a[1]);
// If top score is significantly higher, return that voice
if (sortedScores[0][1] > sortedScores[1][1] * 1.5) {
return sortedScores[0][0];
}
return 'mixed';
}
private scoreAuthenticity(content: string): number {
let score = 50; // baseline
// Positive markers
if (content.match(/\d+(\.\d+)?\s*(ms|MB|GB|%|seconds)/)) score += 10; // specific metrics
if (content.match(/\$[\d,]+/)) score += 10; // concrete numbers
if (content.match(/\b(I|we)\b/)) score += 5; // personal voice
if (content.match(/\b(However|But|Although)\b/)) score += 5; // acknowledges nuance
// Negative markers
if (content.includes('delve')) score -= 20;
if (content.includes('leverage') && !content.includes('executive')) score -= 10;
if (content.match(/it's important to note/i)) score -= 15;
return Math.max(0, Math.min(100, score));
}
private scoreDiversity(original: string, variation: string): number {
// Simple edit distance-based diversity score
const distance = this.levenshteinDistance(original, variation);
const maxLength = Math.max(original.length, variation.length);
return Math.round((distance / maxLength) * 100);
}
private levenshteinDistance(str1: string, str2: string): number {
const matrix: number[][] = [];
for (let i = 0; i <= str2.length; i++) {
matrix[i] = [i];
}
for (let j = 0; j <= str1.length; j++) {
matrix[0][j] = j;
}
for (let i = 1; i <= str2.length; i++) {
for (let j = 1; j <= str1.length; j++) {
if (str2.charAt(i - 1) === str1.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(
matrix[i - 1][j - 1] + 1,
matrix[i][j - 1] + 1,
matrix[i - 1][j] + 1
);
}
}
}
return matrix[str2.length][str1.length];
}
private splitIntoSentences(content: string): string[] {
// Split on sentence boundaries
const sentences = content
.split(/[.!?]+/)
.map(s => s.trim())
.filter(s => s.length > 0);
return sentences.map(s => {
// Ensure sentence ends with period
if (!s.match(/[.!?]$/)) {
return s + '.';
}
return s;
});
}
private statementToQuestion(statement: string): string {
// Simple heuristic to convert statement to question
const lower = statement.toLowerCase();
const cleanStatement = statement.replace(/\.$/, ''); // Remove trailing period
// Match common sentence structures and convert to questions
if (lower.startsWith('the ')) {
// "The system is reliable." -> "Is the system reliable?"
const match = cleanStatement.match(/^The\s+(\w+)\s+is\s+(.+)$/i);
if (match) {
return `Is the ${match[1]} ${match[2]}?`;
}
}
if (lower.includes(' is ')) {
// Extract subject and convert: "X is Y" -> "What is X?"
const match = cleanStatement.match(/^(.+?)\s+is\s+/i);
if (match) {
return `What is ${match[1].toLowerCase()}?`;
}
}
if (lower.includes(' can ')) {
const match = cleanStatement.match(/^(.+?)\s+can\s+/i);
if (match) {
return `How can ${match[1].toLowerCase()} be used?`;
}
}
if (lower.includes(' should ')) {
const match = cleanStatement.match(/^(.+?)\s+should\s+/i);
if (match) {
return `Why should ${match[1].toLowerCase()}?`;
}
}
// Default fallback - make it a proper question
return `What about ${cleanStatement.toLowerCase()}?`;
}
private generateAIHeavyContent(topic: string): string {
// Generate content with typical AI patterns
const aiPhrases = [
`It's important to note that ${topic} plays a crucial role in modern development.`,
`When delving into ${topic}, one must consider various aspects and nuances.`,
`At the end of the day, ${topic} is absolutely essential for success.`,
`It goes without saying that ${topic} should be carefully considered.`,
];
return aiPhrases.join(' ');
}
}