claude-flow-multilang
Version:
Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture
467 lines (408 loc) • 14.1 kB
text/typescript
/**
* Claude Flow Multilang Framework - Polyglot Agent
* Base class for multilingual AI agents with cultural awareness
*/
import { BaseAgent } from '../cli/agents/base-agent.js';
import {
SupportedLanguage,
LanguageDetectionResult,
CulturalContext,
TranslationContext,
PolyglotCapabilities,
MultilingualCommand,
LanguageAgentConfig,
PolyglotMemoryEntry,
} from './types.js';
import { LanguageManager } from '../i18n/language-manager.js';
import { CulturalContextAnalyzer } from '../cultural/context-analyzer.js';
import { ILogger } from '../core/logger.js';
/**
* PolyglotAgent - Multilingual AI agent with cultural awareness
* Extends BaseAgent to provide language detection, translation, and cultural adaptation
*/
export class PolyglotAgent extends BaseAgent {
protected languageManager: LanguageManager;
protected culturalAnalyzer: CulturalContextAnalyzer;
protected currentLanguage: SupportedLanguage;
protected capabilities: PolyglotCapabilities;
protected languageConfigs: Map<SupportedLanguage, LanguageAgentConfig>;
protected memoryByLanguage: Map<SupportedLanguage, PolyglotMemoryEntry[]>;
constructor(
name: string,
capabilities: string[],
protected logger: ILogger,
protected primaryLanguage: SupportedLanguage = SupportedLanguage.EN,
) {
super(name, capabilities);
this.currentLanguage = primaryLanguage;
this.languageManager = new LanguageManager(logger);
this.culturalAnalyzer = new CulturalContextAnalyzer(logger);
this.languageConfigs = new Map();
this.memoryByLanguage = new Map();
// Initialize polyglot capabilities
this.capabilities = {
languages: Object.values(SupportedLanguage),
primaryLanguage: this.primaryLanguage,
translationPairs: this.generateTranslationPairs(),
culturalAwareness: true,
domainExpertise: ['technical', 'business', 'creative'],
realTimeTranslation: true,
documentGeneration: true,
};
this.initializeLanguageConfigs();
}
/**
* Process input in native language with cultural context
*/
async processInNativeLanguage(
input: string,
explicitLanguage?: SupportedLanguage,
): Promise<{
response: string;
language: SupportedLanguage;
culturalContext?: CulturalContext;
confidence: number;
}> {
try {
// Detect language if not explicitly provided
const detectedLanguage = explicitLanguage || await this.detectLanguage(input);
// Get cultural context for the detected language
const culturalContext = await this.culturalAnalyzer.analyze(detectedLanguage, input);
// Parse command in native language
const command = await this.parseMultilingualCommand(input, detectedLanguage, culturalContext);
// Process with language-specific configuration
const config = this.languageConfigs.get(detectedLanguage);
const response = await this.executeWithCulturalContext(command, culturalContext, config);
// Store in language-specific memory
await this.storePolyglotMemory(input, response, detectedLanguage, culturalContext);
return {
response,
language: detectedLanguage,
culturalContext,
confidence: command.confidence,
};
} catch (error) {
this.logger.error('Error processing native language input', error);
throw error;
}
}
/**
* Detect language from input text
*/
protected async detectLanguage(input: string): Promise<SupportedLanguage> {
const detection = await this.languageManager.detectLanguage(input);
if (detection.confidence < 0.7 && detection.alternatives.length > 0) {
// If confidence is low, might need user confirmation
this.logger.warn('Low confidence language detection', {
detected: detection.language,
confidence: detection.confidence,
alternatives: detection.alternatives,
});
}
return detection.language;
}
/**
* Parse multilingual command with intent extraction
*/
protected async parseMultilingualCommand(
input: string,
language: SupportedLanguage,
culturalContext: CulturalContext,
): Promise<MultilingualCommand> {
// Normalize input based on language rules
const normalized = await this.languageManager.normalize(input, language);
// Extract intent and entities
const { intent, entities, confidence } = await this.languageManager.extractIntent(
normalized,
language,
);
return {
rawInput: input,
detectedLanguage: language,
normalizedCommand: normalized,
intent,
entities,
culturalContext,
confidence,
};
}
/**
* Execute command with cultural context awareness
*/
protected async executeWithCulturalContext(
command: MultilingualCommand,
culturalContext: CulturalContext,
config?: LanguageAgentConfig,
): Promise<string> {
// Adapt execution based on cultural context
const executionContext = this.adaptExecutionContext(culturalContext, config);
// Execute the command
const result = await this.execute({
task: command.normalizedCommand,
language: command.detectedLanguage,
culturalContext,
...executionContext,
});
// Format response according to cultural norms
const formattedResponse = await this.formatCulturalResponse(
result,
command.detectedLanguage,
culturalContext,
config,
);
return formattedResponse;
}
/**
* Translate content between languages with cultural adaptation
*/
async translate(
content: string,
targetLanguage: SupportedLanguage,
options?: Partial<TranslationContext>,
): Promise<string> {
const sourceLanguage = await this.detectLanguage(content);
const context: TranslationContext = {
sourceLanguage,
targetLanguage,
culturalAdaptation: true,
preserveFormatting: true,
...options,
};
// Perform translation with cultural adaptation
const translated = await this.languageManager.translate(content, context);
// Apply cultural adaptations if needed
if (context.culturalAdaptation) {
const targetCulture = await this.culturalAnalyzer.analyze(targetLanguage, translated);
return this.applyCulturalAdaptations(translated, targetCulture);
}
return translated;
}
/**
* Generate response in multiple languages simultaneously
*/
async generateMultilingualResponse(
prompt: string,
languages: SupportedLanguage[],
): Promise<Record<SupportedLanguage, string>> {
const responses: Partial<Record<SupportedLanguage, string>> = {};
// Generate base response in primary language
const baseResponse = await this.execute({ task: prompt });
responses[this.primaryLanguage] = baseResponse;
// Translate to other languages in parallel
const translationPromises = languages
.filter(lang => lang !== this.primaryLanguage)
.map(async (lang) => {
const translated = await this.translate(baseResponse, lang, {
domain: 'technical',
culturalAdaptation: true,
});
responses[lang] = translated;
});
await Promise.all(translationPromises);
return responses as Record<SupportedLanguage, string>;
}
/**
* Store memory entry with multilingual support
*/
protected async storePolyglotMemory(
input: string,
response: string,
language: SupportedLanguage,
culturalContext?: CulturalContext,
): Promise<void> {
const entry: PolyglotMemoryEntry = {
id: `poly-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
timestamp: new Date(),
language,
originalContent: input,
translations: { [language]: response },
context: { culturalContext },
tags: this.extractTags(input),
culturalNotes: culturalContext?.businessEtiquette?.communicationStyle,
};
// Store in language-specific memory
if (!this.memoryByLanguage.has(language)) {
this.memoryByLanguage.set(language, []);
}
this.memoryByLanguage.get(language)!.push(entry);
// Also store in base memory system
await this.addMemory(`${input} -> ${response}`, 'polyglot_interaction');
}
/**
* Retrieve memories in specific language
*/
async getMemoriesInLanguage(
language: SupportedLanguage,
limit: number = 10,
): Promise<PolyglotMemoryEntry[]> {
const memories = this.memoryByLanguage.get(language) || [];
return memories.slice(-limit);
}
/**
* Initialize language-specific configurations
*/
protected initializeLanguageConfigs(): void {
// English configuration
this.languageConfigs.set(SupportedLanguage.EN, {
language: SupportedLanguage.EN,
modelPreferences: { temperature: 0.7 },
responseTemplate: 'professional',
culturalRules: {
formalityLevel: 'neutral',
dateFormat: 'MM/DD/YYYY',
numberFormat: '1,234.56',
},
});
// Russian configuration
this.languageConfigs.set(SupportedLanguage.RU, {
language: SupportedLanguage.RU,
modelPreferences: { temperature: 0.8 },
responseTemplate: 'formal',
culturalRules: {
formalityLevel: 'formal',
dateFormat: 'DD.MM.YYYY',
numberFormat: '1 234,56',
},
});
// Japanese configuration
this.languageConfigs.set(SupportedLanguage.JA, {
language: SupportedLanguage.JA,
modelPreferences: { temperature: 0.6 },
responseTemplate: 'polite',
culturalRules: {
formalityLevel: 'very-formal',
dateFormat: 'YYYY年MM月DD日',
numberFormat: '1,234.56',
},
specializedVocabulary: ['敬語', '丁寧語', '謙譲語'],
});
// Chinese configuration
this.languageConfigs.set(SupportedLanguage.ZH_CN, {
language: SupportedLanguage.ZH_CN,
modelPreferences: { temperature: 0.7 },
responseTemplate: 'professional',
culturalRules: {
formalityLevel: 'formal',
dateFormat: 'YYYY年MM月DD日',
numberFormat: '1,234.56',
},
});
// Add more language configurations as needed...
}
/**
* Generate all possible translation pairs
*/
protected generateTranslationPairs(): Array<[SupportedLanguage, SupportedLanguage]> {
const languages = Object.values(SupportedLanguage);
const pairs: Array<[SupportedLanguage, SupportedLanguage]> = [];
for (const source of languages) {
for (const target of languages) {
if (source !== target) {
pairs.push([source, target]);
}
}
}
return pairs;
}
/**
* Adapt execution context based on cultural norms
*/
protected adaptExecutionContext(
culturalContext: CulturalContext,
config?: LanguageAgentConfig,
): Record<string, any> {
return {
formality: culturalContext.formalityLevel,
communicationStyle: culturalContext.businessEtiquette?.communicationStyle || 'direct',
dateFormat: culturalContext.dateFormat,
numberFormat: culturalContext.numberFormat,
modelConfig: config?.modelPreferences,
};
}
/**
* Format response according to cultural norms
*/
protected async formatCulturalResponse(
response: string,
language: SupportedLanguage,
culturalContext: CulturalContext,
config?: LanguageAgentConfig,
): Promise<string> {
let formatted = response;
// Apply formality adjustments
if (culturalContext.formalityLevel === 'very-formal') {
formatted = await this.applyFormalityRules(formatted, language);
}
// Apply response template if configured
if (config?.responseTemplate) {
formatted = this.applyResponseTemplate(formatted, config.responseTemplate, language);
}
// Apply cultural-specific formatting
formatted = this.applyCulturalFormatting(formatted, culturalContext);
return formatted;
}
/**
* Apply cultural adaptations to translated content
*/
protected applyCulturalAdaptations(content: string, culture: CulturalContext): string {
// This would include things like:
// - Date/time format conversion
// - Number format conversion
// - Currency symbol changes
// - Measurement unit conversion
// - Idiom adaptation
// - Cultural reference localization
// Simplified implementation for now
return content;
}
/**
* Apply formality rules based on language
*/
protected async applyFormalityRules(content: string, language: SupportedLanguage): Promise<string> {
// Language-specific formality rules
// For Japanese: add keigo, for Korean: add honorifics, etc.
return content;
}
/**
* Apply response template
*/
protected applyResponseTemplate(
content: string,
template: string,
language: SupportedLanguage,
): string {
// Apply template-based formatting
return content;
}
/**
* Apply cultural-specific formatting
*/
protected applyCulturalFormatting(content: string, culture: CulturalContext): string {
// Apply date, number, and other cultural formatting
return content;
}
/**
* Extract tags from input for categorization
*/
protected extractTags(input: string): string[] {
// Simple tag extraction - could be enhanced with NLP
const words = input.toLowerCase().split(/\s+/);
return words.filter(word => word.length > 4).slice(0, 5);
}
/**
* Get agent description in specific language
*/
async getDescriptionInLanguage(language: SupportedLanguage): Promise<string> {
const baseDescription = this.getDescription();
if (language === SupportedLanguage.EN) {
return baseDescription;
}
return this.translate(baseDescription, language);
}
/**
* Export polyglot capabilities
*/
getPolyglotCapabilities(): PolyglotCapabilities {
return this.capabilities;
}
}