perplexity-hackathon-LawMitra / perplexity_hackathon / src / services / languageService.ts
languageService.ts
Raw
import { store } from '../utils/tempStore';
import OpenAI from 'openai';
import config from '../config';
import fs from 'fs';

interface LanguageInfo {
  code: string;      // ISO 639-1 code (e.g., 'en', 'es')
  code3: string;     // ISO 639-3 code (e.g., 'eng', 'spa')
  name: string;      // Full name (e.g., 'English', 'Spanish')
  confidence: number;
}

const SUPPORTED_LANGUAGES = [
  { code: 'en', code3: 'eng', name: 'English' },
  { code: 'es', code3: 'spa', name: 'Spanish' },
  { code: 'fr', code3: 'fra', name: 'French' },
  { code: 'de', code3: 'deu', name: 'German' },
  { code: 'it', code3: 'ita', name: 'Italian' },
  { code: 'pt', code3: 'por', name: 'Portuguese' },
  { code: 'hi', code3: 'hin', name: 'Hindi' },
  { code: 'zh', code3: 'zho', name: 'Chinese' },
  { code: 'ja', code3: 'jpn', name: 'Japanese' },
  { code: 'ko', code3: 'kor', name: 'Korean' },
];

export class LanguageService {
  private openai: OpenAI;
  private languageCache: Map<string, LanguageInfo>;
  private isDev: boolean;

  constructor() {
    this.openai = new OpenAI({
      apiKey: config.openai.apiKey,
    });
    this.languageCache = new Map();
    this.isDev = process.env.NODE_ENV === 'development';
  }

  async detectFromText(text: string, sessionId: string): Promise<LanguageInfo> {
    // First, try to get from cache
    const cached = this.languageCache.get(sessionId);
    if (cached) {
      return cached;
    }

    if (this.isDev) {
      // In development, always return English
      const languageInfo = {
        code: 'en',
        code3: 'eng',
        name: 'English',
        confidence: 1.0,
      };
      
      this.languageCache.set(sessionId, languageInfo);
      store.saveSession(`lang_${sessionId}`, languageInfo);
      return languageInfo;
    }

    // In production, use OpenAI to detect language
    const response = await this.openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      messages: [
        {
          role: 'system',
          content: 'You are a language detection expert. Respond only with the ISO 639-1 language code.'
        },
        {
          role: 'user',
          content: `Detect the language of this text: ${text}`
        }
      ],
      temperature: 0,
      max_tokens: 10,
    });

    const detectedCode = response.choices[0].message.content?.trim().toLowerCase() || 'en';
    const languageInfo = this.findLanguageByCode(detectedCode);
    
    this.languageCache.set(sessionId, languageInfo);
    store.saveSession(`lang_${sessionId}`, languageInfo);

    return languageInfo;
  }

  async detectFromAudio(filePath: string, sessionId: string): Promise<LanguageInfo> {
    try {
      if (this.isDev) {
        // In development, always return English
        const languageInfo = {
          code: 'en',
          code3: 'eng',
          name: 'English',
          confidence: 1.0,
        };
        
        this.languageCache.set(sessionId, languageInfo);
        store.saveSession(`lang_${sessionId}`, languageInfo);
        return languageInfo;
      }

      // Use Whisper API to detect language
      const transcription = await this.openai.audio.transcriptions.create({
        file: fs.createReadStream(filePath),
        model: 'whisper-1',
        response_format: 'verbose_json',
      });

      if (!transcription.language) {
        throw new Error('Could not detect language from audio');
      }

      const languageInfo = this.findLanguageByCode(transcription.language);
      
      this.languageCache.set(sessionId, languageInfo);
      store.saveSession(`lang_${sessionId}`, languageInfo);

      return languageInfo;
    } catch (error) {
      console.error('Error detecting language from audio:', error);
      throw new Error('Failed to detect language from audio');
    }
  }

  getLanguagePreference(sessionId: string): LanguageInfo | null {
    // First try cache
    const cached = this.languageCache.get(sessionId);
    if (cached) {
      return cached;
    }

    // Then try temporary store
    const stored = store.getSession(`lang_${sessionId}`);
    if (stored) {
      this.languageCache.set(sessionId, stored as LanguageInfo);
      return stored as LanguageInfo;
    }

    return null;
  }

  setLanguagePreference(sessionId: string, language: string): LanguageInfo {
    const languageInfo = this.findLanguageByCode(language);
    
    this.languageCache.set(sessionId, languageInfo);
    store.saveSession(`lang_${sessionId}`, languageInfo);

    return languageInfo;
  }

  private findLanguageByCode(code: string): LanguageInfo {
    const language = SUPPORTED_LANGUAGES.find(lang => 
      lang.code === code || lang.code3 === code
    );

    if (!language) {
      // Default to English if language not found
      return {
        code: 'en',
        code3: 'eng',
        name: 'English',
        confidence: 1.0,
      };
    }

    return {
      ...language,
      confidence: 1.0,
    };
  }

  clearLanguagePreference(sessionId: string): void {
    this.languageCache.delete(sessionId);
    store.deleteSession(`lang_${sessionId}`);
  }
}

export const languageService = new LanguageService();