UNPKG

claude-flow-multilang

Version:

Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture

467 lines (408 loc) 14.1 kB
/** * 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; } }