context-optimization.ts•28 kB
/**
* AI Context Optimization for SRT Chunking Functions
* Advanced context management for different AI models with intelligent chunking
*/
import { SRTSubtitle, SRTChunk } from '../types/srt.js';
import { detectConversations, detectConversationsAdvanced } from '../chunking/conversation-detector.js';
/**
* Context Optimization Strategy
*/
export type ContextOptimizationStrategy =
| 'aggressive' // Maximum chunking for minimal context usage
| 'conservative' // Minimal chunking for maximum context preservation
| 'balanced' // Balanced approach
| 'adaptive' // Dynamic based on content complexity
| 'model-specific'; // Optimized for specific AI model
/**
* Context Optimization Configuration
*/
export interface ContextOptimizationConfig {
strategy: ContextOptimizationStrategy;
maxContextSize: number;
chunkSizeLimit: number;
contextManagement: 'aggressive' | 'conservative' | 'balanced';
enableSemanticChunking: boolean;
enableSpeakerAwareChunking: boolean;
enableComplexityBasedChunking: boolean;
enableTimingBasedChunking: boolean;
modelSpecific: {
claude: ClaudeContextConfig;
gpt: GPTContextConfig;
gemini: GeminiContextConfig;
generic: GenericContextConfig;
};
}
/**
* Model-specific context configurations
*/
export interface ClaudeContextConfig {
maxContextSize: 200000;
optimalChunkSize: 8;
contextOverhead: 1000;
reasoningTokens: 500;
responseTokens: 1000;
safetyMargin: 0.8;
}
export interface GPTContextConfig {
maxContextSize: 128000;
optimalChunkSize: 12;
contextOverhead: 800;
reasoningTokens: 0;
responseTokens: 2000;
safetyMargin: 0.85;
}
export interface GeminiContextConfig {
maxContextSize: 1000000;
optimalChunkSize: 20;
contextOverhead: 500;
reasoningTokens: 1000;
responseTokens: 3000;
safetyMargin: 0.9;
}
export interface GenericContextConfig {
maxContextSize: 50000;
optimalChunkSize: 5;
contextOverhead: 2000;
reasoningTokens: 0;
responseTokens: 500;
safetyMargin: 0.7;
}
/**
* Context Analysis Result
*/
export interface ContextAnalysisResult {
totalContextSize: number;
availableContext: number;
contextEfficiency: number;
chunkCount: number;
averageChunkSize: number;
largestChunk: number;
smallestChunk: number;
contextDistribution: ContextDistribution;
optimizationSuggestions: OptimizationSuggestion[];
complexityScore: number;
speakerConsistency: number;
topicCoherence: number;
}
/**
* Context Distribution
*/
export interface ContextDistribution {
underLimit: number; // Chunks under context limit
atLimit: number; // Chunks at context limit
overLimit: number; // Chunks over context limit
severelyOverLimit: number; // Chunks severely over limit
}
/**
* Optimization Suggestion
*/
export interface OptimizationSuggestion {
type: 'split' | 'merge' | 'reorder' | 'compress';
priority: 'low' | 'medium' | 'high' | 'critical';
description: string;
expectedImprovement: number;
affectedChunks: string[];
implementation: string[];
}
/**
* Optimized Chunk Result
*/
export interface OptimizedChunkResult {
originalChunks: SRTChunk[];
optimizedChunks: SRTChunk[];
contextAnalysis: ContextAnalysisResult;
optimizationApplied: OptimizationApplied[];
performanceMetrics: PerformanceMetrics;
}
/**
* Optimization Applied
*/
export interface OptimizationApplied {
type: string;
description: string;
chunksAffected: number;
contextSaved: number;
qualityImpact: 'none' | 'minimal' | 'moderate' | 'significant';
}
/**
* Performance Metrics
*/
export interface PerformanceMetrics {
totalProcessingTime: number;
contextEfficiency: number;
chunkingQuality: number;
speakerConsistency: number;
topicCoherence: number;
overallScore: number;
}
/**
* AI Context Optimizer
*/
export class AIContextOptimizer {
private config: ContextOptimizationConfig;
private modelType: string;
constructor(config: ContextOptimizationConfig, modelType: string) {
this.config = config;
this.modelType = modelType;
}
/**
* Optimize chunks for AI context
*/
async optimizeChunksForAI(
chunks: SRTChunk[],
processingType: 'translation' | 'analysis' | 'conversation-detection'
): Promise<OptimizedChunkResult> {
const startTime = Date.now();
// Step 1: Analyze current context usage
const contextAnalysis = await this.analyzeContextUsage(chunks);
// Step 2: Generate optimization suggestions
const suggestions = await this.generateOptimizationSuggestions(chunks, contextAnalysis);
// Step 3: Apply optimizations
const optimizedChunks = await this.applyOptimizations(chunks, suggestions);
// Step 4: Validate optimizations
const validationResult = await this.validateOptimizations(chunks, optimizedChunks);
// Step 5: Calculate performance metrics
const performanceMetrics = await this.calculatePerformanceMetrics(
chunks,
optimizedChunks,
Date.now() - startTime
);
return {
originalChunks: chunks,
optimizedChunks,
contextAnalysis,
optimizationApplied: validationResult.applied,
performanceMetrics
};
}
/**
* Analyze context usage across chunks
*/
private async analyzeContextUsage(chunks: SRTChunk[]): Promise<ContextAnalysisResult> {
const modelConfig = this.getModelConfig();
const totalContextSize = chunks.reduce((sum, chunk) =>
sum + this.calculateChunkContextSize(chunk), 0);
const availableContext = modelConfig.maxContextSize * modelConfig.safetyMargin;
const contextEfficiency = totalContextSize / (chunks.length * modelConfig.maxContextSize);
const chunkSizes = chunks.map(chunk => this.calculateChunkContextSize(chunk));
const averageChunkSize = chunkSizes.reduce((sum, size) => sum + size, 0) / chunkSizes.length;
const largestChunk = Math.max(...chunkSizes);
const smallestChunk = Math.min(...chunkSizes);
const contextDistribution = this.calculateContextDistribution(chunks, modelConfig);
const optimizationSuggestions = await this.generateOptimizationSuggestions(chunks, {
totalContextSize,
availableContext,
contextEfficiency,
chunkCount: chunks.length,
averageChunkSize,
largestChunk,
smallestChunk,
contextDistribution,
optimizationSuggestions: [],
complexityScore: this.calculateComplexityScore(chunks),
speakerConsistency: this.calculateSpeakerConsistency(chunks),
topicCoherence: this.calculateTopicCoherence(chunks)
});
return {
totalContextSize,
availableContext,
contextEfficiency,
chunkCount: chunks.length,
averageChunkSize,
largestChunk,
smallestChunk,
contextDistribution,
optimizationSuggestions,
complexityScore: this.calculateComplexityScore(chunks),
speakerConsistency: this.calculateSpeakerConsistency(chunks),
topicCoherence: this.calculateTopicCoherence(chunks)
};
}
/**
* Calculate chunk context size
*/
private calculateChunkContextSize(chunk: SRTChunk): number {
let size = 0;
// Base metadata size
size += JSON.stringify(chunk).length;
// Add subtitle text size
for (const subtitle of chunk.subtitles) {
size += (subtitle.text || '').length;
}
// Add context overhead based on model
const modelConfig = this.getModelConfig();
size += modelConfig.contextOverhead;
return size;
}
/**
* Calculate context distribution
*/
private calculateContextDistribution(
chunks: SRTChunk[],
modelConfig: any
): ContextDistribution {
const limit = modelConfig.maxContextSize * modelConfig.safetyMargin;
const severeLimit = modelConfig.maxContextSize;
let underLimit = 0;
let atLimit = 0;
let overLimit = 0;
let severelyOverLimit = 0;
for (const chunk of chunks) {
const size = this.calculateChunkContextSize(chunk);
if (size < limit * 0.8) {
underLimit++;
} else if (size <= limit) {
atLimit++;
} else if (size <= severeLimit) {
overLimit++;
} else {
severelyOverLimit++;
}
}
return {
underLimit,
atLimit,
overLimit,
severelyOverLimit
};
}
/**
* Generate optimization suggestions
*/
private async generateOptimizationSuggestions(
chunks: SRTChunk[],
analysis: ContextAnalysisResult
): Promise<OptimizationSuggestion[]> {
const suggestions: OptimizationSuggestion[] = [];
const modelConfig = this.getModelConfig();
// Check for chunks that exceed context limits
for (const chunk of chunks) {
const chunkSize = this.calculateChunkContextSize(chunk);
if (chunkSize > modelConfig.maxContextSize * modelConfig.safetyMargin) {
suggestions.push({
type: 'split',
priority: chunkSize > modelConfig.maxContextSize ? 'critical' : 'high',
description: `Split chunk ${chunk.id} (${chunkSize} chars) to fit context limits`,
expectedImprovement: chunkSize - modelConfig.maxContextSize * modelConfig.safetyMargin,
affectedChunks: [chunk.id],
implementation: [
'Split chunk into smaller parts',
'Maintain conversation context',
'Preserve speaker consistency'
]
});
}
}
// Check for opportunities to merge small chunks
const smallChunks = chunks.filter(chunk =>
this.calculateChunkContextSize(chunk) < modelConfig.optimalChunkSize * 0.5
);
if (smallChunks.length > 1) {
suggestions.push({
type: 'merge',
priority: 'medium',
description: `Merge ${smallChunks.length} small chunks to improve efficiency`,
expectedImprovement: smallChunks.length * 1000, // Estimated improvement
affectedChunks: smallChunks.map(chunk => chunk.id),
implementation: [
'Merge consecutive small chunks',
'Maintain conversation boundaries',
'Preserve timing information'
]
});
}
// Check for complexity-based optimizations
if (analysis.complexityScore > 0.7) {
suggestions.push({
type: 'compress',
priority: 'medium',
description: 'Apply complexity-based compression to reduce context usage',
expectedImprovement: analysis.complexityScore * 1000,
affectedChunks: chunks.map(chunk => chunk.id),
implementation: [
'Simplify complex sentences',
'Remove redundant information',
'Maintain semantic meaning'
]
});
}
return suggestions;
}
/**
* Apply optimizations to chunks
*/
private async applyOptimizations(
chunks: SRTChunk[],
suggestions: OptimizationSuggestion[]
): Promise<SRTChunk[]> {
let optimizedChunks = [...chunks];
for (const suggestion of suggestions) {
switch (suggestion.type) {
case 'split':
optimizedChunks = await this.applySplitOptimization(optimizedChunks, suggestion);
break;
case 'merge':
optimizedChunks = await this.applyMergeOptimization(optimizedChunks, suggestion);
break;
case 'compress':
optimizedChunks = await this.applyCompressionOptimization(optimizedChunks, suggestion);
break;
case 'reorder':
optimizedChunks = await this.applyReorderOptimization(optimizedChunks, suggestion);
break;
}
}
return optimizedChunks;
}
/**
* Apply split optimization
*/
private async applySplitOptimization(
chunks: SRTChunk[],
suggestion: OptimizationSuggestion
): Promise<SRTChunk[]> {
const optimizedChunks: SRTChunk[] = [];
const modelConfig = this.getModelConfig();
for (const chunk of chunks) {
if (suggestion.affectedChunks.includes(chunk.id)) {
const chunkSize = this.calculateChunkContextSize(chunk);
if (chunkSize > modelConfig.maxContextSize * modelConfig.safetyMargin) {
const splitChunks = this.splitChunkForContext(chunk, modelConfig);
optimizedChunks.push(...splitChunks);
} else {
optimizedChunks.push(chunk);
}
} else {
optimizedChunks.push(chunk);
}
}
return optimizedChunks;
}
/**
* Apply merge optimization
*/
private async applyMergeOptimization(
chunks: SRTChunk[],
suggestion: OptimizationSuggestion
): Promise<SRTChunk[]> {
const optimizedChunks: SRTChunk[] = [];
const modelConfig = this.getModelConfig();
const affectedChunks = chunks.filter(chunk =>
suggestion.affectedChunks.includes(chunk.id)
);
let i = 0;
while (i < chunks.length) {
const chunk = chunks[i];
if (suggestion.affectedChunks.includes(chunk.id)) {
// Try to merge with next chunk if both are small
const nextChunk = chunks[i + 1];
if (nextChunk && suggestion.affectedChunks.includes(nextChunk.id)) {
const mergedChunk = this.mergeChunksForContext(chunk, nextChunk, modelConfig);
optimizedChunks.push(mergedChunk);
i += 2; // Skip next chunk as it's merged
} else {
optimizedChunks.push(chunk);
i++;
}
} else {
optimizedChunks.push(chunk);
i++;
}
}
return optimizedChunks;
}
/**
* Apply compression optimization
*/
private async applyCompressionOptimization(
chunks: SRTChunk[],
suggestion: OptimizationSuggestion
): Promise<SRTChunk[]> {
return chunks.map(chunk => {
if (suggestion.affectedChunks.includes(chunk.id)) {
return this.compressChunkForContext(chunk);
}
return chunk;
});
}
/**
* Apply reorder optimization
*/
private async applyReorderOptimization(
chunks: SRTChunk[],
suggestion: OptimizationSuggestion
): Promise<SRTChunk[]> {
// Reorder chunks by complexity and context size for optimal processing
return chunks.sort((a, b) => {
const aSize = this.calculateChunkContextSize(a);
const bSize = this.calculateChunkContextSize(b);
const aComplexity = this.calculateChunkComplexity(a);
const bComplexity = this.calculateChunkComplexity(b);
// Process smaller, less complex chunks first
if (aSize !== bSize) return aSize - bSize;
return aComplexity - bComplexity;
});
}
/**
* Split chunk for context limits
*/
private splitChunkForContext(chunk: SRTChunk, modelConfig: any): SRTChunk[] {
const subtitles = chunk.subtitles;
const maxSubtitlesPerChunk = Math.floor(
(modelConfig.maxContextSize * modelConfig.safetyMargin) / 1000
);
const newChunks: SRTChunk[] = [];
for (let i = 0; i < subtitles.length; i += maxSubtitlesPerChunk) {
const chunkSubtitles = subtitles.slice(i, i + maxSubtitlesPerChunk);
const newChunk: SRTChunk = {
...chunk,
id: `${chunk.id}-part-${Math.floor(i / maxSubtitlesPerChunk) + 1}`,
startIndex: chunkSubtitles[0].index,
endIndex: chunkSubtitles[chunkSubtitles.length - 1].index,
subtitles: chunkSubtitles,
context: {
...chunk.context,
conversationId: chunk.context?.conversationId || '',
isSplitChunk: true,
originalChunkId: chunk.id,
partNumber: Math.floor(i / maxSubtitlesPerChunk) + 1,
totalParts: Math.ceil(subtitles.length / maxSubtitlesPerChunk)
}
};
newChunks.push(newChunk);
}
return newChunks;
}
/**
* Merge chunks for context optimization
*/
private mergeChunksForContext(
chunk1: SRTChunk,
chunk2: SRTChunk,
modelConfig: any
): SRTChunk {
const mergedSize = this.calculateChunkContextSize(chunk1) +
this.calculateChunkContextSize(chunk2);
if (mergedSize > modelConfig.maxContextSize * modelConfig.safetyMargin) {
// Can't merge, return original chunks
return chunk1;
}
return {
id: `${chunk1.id}-${chunk2.id}`,
startIndex: chunk1.startIndex,
endIndex: chunk2.endIndex,
subtitles: [...chunk1.subtitles, ...chunk2.subtitles],
context: {
speaker: chunk1.context?.speaker || chunk2.context?.speaker,
conversationId: chunk1.context?.conversationId || chunk2.context?.conversationId || '',
previousContext: chunk1.context?.previousContext,
nextContext: chunk2.context?.nextContext,
isMergedChunk: true,
originalChunkIds: [chunk1.id, chunk2.id]
}
};
}
/**
* Compress chunk for context
*/
private compressChunkForContext(chunk: SRTChunk): SRTChunk {
// Simple compression by removing extra whitespace and optimizing text
const compressedSubtitles = chunk.subtitles.map(subtitle => ({
...subtitle,
text: subtitle.text.replace(/\s+/g, ' ').trim(),
rawText: subtitle.rawText?.replace(/\s+/g, ' ').trim()
}));
return {
...chunk,
subtitles: compressedSubtitles,
context: {
...chunk.context,
conversationId: chunk.context?.conversationId || '',
isCompressed: true,
compressionApplied: true
}
};
}
/**
* Validate optimizations
*/
private async validateOptimizations(
originalChunks: SRTChunk[],
optimizedChunks: SRTChunk[]
): Promise<{ applied: OptimizationApplied[]; valid: boolean }> {
const applied: OptimizationApplied[] = [];
const modelConfig = this.getModelConfig();
// Check if all chunks are within context limits
let allWithinLimits = true;
for (const chunk of optimizedChunks) {
const chunkSize = this.calculateChunkContextSize(chunk);
if (chunkSize > modelConfig.maxContextSize * modelConfig.safetyMargin) {
allWithinLimits = false;
break;
}
}
// Record applied optimizations
if (optimizedChunks.length > originalChunks.length) {
applied.push({
type: 'split',
description: 'Split large chunks to fit context limits',
chunksAffected: optimizedChunks.length - originalChunks.length,
contextSaved: 0, // Would need to calculate actual savings
qualityImpact: 'minimal'
});
}
if (optimizedChunks.length < originalChunks.length) {
applied.push({
type: 'merge',
description: 'Merged small chunks for efficiency',
chunksAffected: originalChunks.length - optimizedChunks.length,
contextSaved: 0, // Would need to calculate actual savings
qualityImpact: 'minimal'
});
}
return { applied, valid: allWithinLimits };
}
/**
* Calculate performance metrics
*/
private async calculatePerformanceMetrics(
originalChunks: SRTChunk[],
optimizedChunks: SRTChunk[],
processingTime: number
): Promise<PerformanceMetrics> {
const originalContextSize = originalChunks.reduce((sum, chunk) =>
sum + this.calculateChunkContextSize(chunk), 0);
const optimizedContextSize = optimizedChunks.reduce((sum, chunk) =>
sum + this.calculateChunkContextSize(chunk), 0);
const contextEfficiency = optimizedContextSize / originalContextSize;
const chunkingQuality = this.calculateChunkingQuality(optimizedChunks);
const speakerConsistency = this.calculateSpeakerConsistency(optimizedChunks);
const topicCoherence = this.calculateTopicCoherence(optimizedChunks);
const overallScore = (
contextEfficiency * 0.3 +
chunkingQuality * 0.3 +
speakerConsistency * 0.2 +
topicCoherence * 0.2
);
return {
totalProcessingTime: processingTime,
contextEfficiency,
chunkingQuality,
speakerConsistency,
topicCoherence,
overallScore
};
}
/**
* Calculate chunking quality
*/
private calculateChunkingQuality(chunks: SRTChunk[]): number {
if (chunks.length === 0) return 0;
let quality = 0;
for (const chunk of chunks) {
// Check for conversation boundaries
if (chunk.context?.speaker) quality += 0.3;
// Check for timing consistency
if (chunk.subtitles.length > 1) {
const timingConsistent = this.checkTimingConsistency(chunk);
if (timingConsistent) quality += 0.3;
}
// Check for semantic coherence
const semanticCoherence = this.checkSemanticCoherence(chunk);
quality += semanticCoherence * 0.4;
}
return Math.min(1, quality / chunks.length);
}
/**
* Calculate complexity score
*/
private calculateComplexityScore(chunks: SRTChunk[]): number {
if (chunks.length === 0) return 0;
let totalComplexity = 0;
for (const chunk of chunks) {
const chunkComplexity = this.calculateChunkComplexity(chunk);
totalComplexity += chunkComplexity;
}
return totalComplexity / chunks.length;
}
/**
* Calculate chunk complexity
*/
private calculateChunkComplexity(chunk: SRTChunk): number {
let complexity = 0;
// Text length complexity
const totalTextLength = chunk.subtitles.reduce((sum, s) => sum + s.text.length, 0);
complexity += Math.min(1, totalTextLength / 1000);
// Word count complexity
const totalWords = chunk.subtitles.reduce((sum, s) =>
sum + s.text.split(/\s+/).length, 0);
complexity += Math.min(1, totalWords / 100);
// Formatting complexity
const hasFormatting = chunk.subtitles.some(s =>
s.text.includes('<i>') || s.text.includes('<b>') || s.text.includes('<u>'));
if (hasFormatting) complexity += 0.2;
// Speaker complexity
if (chunk.context?.speaker) complexity += 0.1;
return Math.min(1, complexity);
}
/**
* Calculate speaker consistency
*/
private calculateSpeakerConsistency(chunks: SRTChunk[]): number {
if (chunks.length === 0) return 0;
const speakers = chunks.map(chunk => chunk.context?.speaker).filter(Boolean);
const uniqueSpeakers = new Set(speakers);
if (uniqueSpeakers.size === 0) return 0;
if (uniqueSpeakers.size === 1) return 1;
// Calculate consistency based on speaker distribution
const speakerCounts = new Map<string, number>();
for (const speaker of speakers) {
speakerCounts.set(speaker!, (speakerCounts.get(speaker!) || 0) + 1);
}
const maxCount = Math.max(...speakerCounts.values());
const totalCount = speakers.length;
return maxCount / totalCount;
}
/**
* Calculate topic coherence
*/
private calculateTopicCoherence(chunks: SRTChunk[]): number {
if (chunks.length < 2) return 1;
let coherence = 0;
for (let i = 1; i < chunks.length; i++) {
const prevChunk = chunks[i - 1];
const currentChunk = chunks[i];
const prevKeywords = this.extractKeywords(prevChunk);
const currentKeywords = this.extractKeywords(currentChunk);
const overlap = this.calculateKeywordOverlap(prevKeywords, currentKeywords);
coherence += overlap;
}
return coherence / (chunks.length - 1);
}
/**
* Extract keywords from chunk
*/
private extractKeywords(chunk: SRTChunk): string[] {
const allText = chunk.subtitles.map(s => s.text).join(' ');
const words = allText.toLowerCase().split(/\s+/)
.filter(word => word.length > 3)
.filter(word => !/^[a-z]+$/.test(word) || word.length > 4);
return [...new Set(words)].slice(0, 10); // Top 10 unique keywords
}
/**
* Calculate keyword overlap
*/
private calculateKeywordOverlap(keywords1: string[], keywords2: string[]): number {
const set1 = new Set(keywords1);
const set2 = new Set(keywords2);
const intersection = new Set([...set1].filter(x => set2.has(x)));
const union = new Set([...set1, ...set2]);
return intersection.size / union.size;
}
/**
* Check timing consistency
*/
private checkTimingConsistency(chunk: SRTChunk): boolean {
if (chunk.subtitles.length < 2) return true;
for (let i = 1; i < chunk.subtitles.length; i++) {
const prev = chunk.subtitles[i - 1];
const current = chunk.subtitles[i];
const prevEnd = prev.endTime;
const currentStart = current.startTime;
// Check if timing is logical (current starts after previous ends)
const prevEndMs = (prevEnd.hours * 3600 + prevEnd.minutes * 60 + prevEnd.seconds) * 1000 + prevEnd.milliseconds;
const currentStartMs = (currentStart.hours * 3600 + currentStart.minutes * 60 + currentStart.seconds) * 1000 + currentStart.milliseconds;
if (currentStartMs < prevEndMs) {
return false;
}
}
return true;
}
/**
* Check semantic coherence
*/
private checkSemanticCoherence(chunk: SRTChunk): number {
if (chunk.subtitles.length < 2) return 1;
let coherence = 0;
for (let i = 1; i < chunk.subtitles.length; i++) {
const prev = chunk.subtitles[i - 1].text;
const current = chunk.subtitles[i].text;
const similarity = this.calculateTextSimilarity(prev, current);
coherence += similarity;
}
return coherence / (chunk.subtitles.length - 1);
}
/**
* Calculate text similarity
*/
private calculateTextSimilarity(text1: string, text2: string): number {
const words1 = text1.toLowerCase().split(/\s+/);
const words2 = text2.toLowerCase().split(/\s+/);
const set1 = new Set(words1);
const set2 = new Set(words2);
const intersection = new Set([...set1].filter(x => set2.has(x)));
const union = new Set([...set1, ...set2]);
return intersection.size / union.size;
}
/**
* Get model-specific configuration
*/
private getModelConfig(): any {
switch (this.modelType) {
case 'claude':
return this.config.modelSpecific.claude;
case 'gpt':
return this.config.modelSpecific.gpt;
case 'gemini':
return this.config.modelSpecific.gemini;
default:
return this.config.modelSpecific.generic;
}
}
}
/**
* Context Optimization Factory
*/
export class ContextOptimizationFactory {
/**
* Create context optimizer for specific model
*/
static createOptimizer(modelType: string): AIContextOptimizer {
const config = this.getDefaultConfig();
return new AIContextOptimizer(config, modelType);
}
/**
* Get default configuration
*/
private static getDefaultConfig(): ContextOptimizationConfig {
return {
strategy: 'adaptive',
maxContextSize: 200000,
chunkSizeLimit: 15,
contextManagement: 'balanced',
enableSemanticChunking: true,
enableSpeakerAwareChunking: true,
enableComplexityBasedChunking: true,
enableTimingBasedChunking: true,
modelSpecific: {
claude: {
maxContextSize: 200000,
optimalChunkSize: 8,
contextOverhead: 1000,
reasoningTokens: 500,
responseTokens: 1000,
safetyMargin: 0.8
},
gpt: {
maxContextSize: 128000,
optimalChunkSize: 12,
contextOverhead: 800,
reasoningTokens: 0,
responseTokens: 2000,
safetyMargin: 0.85
},
gemini: {
maxContextSize: 1000000,
optimalChunkSize: 20,
contextOverhead: 500,
reasoningTokens: 1000,
responseTokens: 3000,
safetyMargin: 0.9
},
generic: {
maxContextSize: 50000,
optimalChunkSize: 5,
contextOverhead: 2000,
reasoningTokens: 0,
responseTokens: 500,
safetyMargin: 0.7
}
}
};
}
}