Skip to main content
Glama

SRT Translation MCP Server

by omd0
translation-service.ts7.85 kB
/** * Translation service interface and implementations */ import { TranslationRequest, TranslationResult, ConversationContext } from '../types/srt.js'; import { preserveStyleTags } from '../utils/style-tags.js'; /** * Abstract translation service interface */ export interface TranslationService { translate(request: TranslationRequest): Promise<TranslationResult>; translateBatch(requests: TranslationRequest[]): Promise<TranslationResult[]>; } /** * Mock translation service for development and testing */ export class MockTranslationService implements TranslationService { async translate(request: TranslationRequest): Promise<TranslationResult> { // Simulate translation delay await new Promise(resolve => setTimeout(resolve, 100)); // Mock translation - just add language prefix const translatedText = request.preserveTags ? preserveStyleTags(request.text, `[${request.targetLanguage}] ${request.text}`) : `[${request.targetLanguage}] ${request.text}`; return { translatedText, confidence: 0.85, sourceLanguage: request.sourceLanguage || 'auto', targetLanguage: request.targetLanguage }; } async translateBatch(requests: TranslationRequest[]): Promise<TranslationResult[]> { const results: TranslationResult[] = []; for (const request of requests) { const result = await this.translate(request); results.push(result); } return results; } } /** * Context-aware translation service wrapper */ export class ContextAwareTranslationService implements TranslationService { constructor(private baseService: TranslationService) {} async translate(request: TranslationRequest): Promise<TranslationResult> { // Enhance request with context const enhancedRequest = this.enhanceRequestWithContext(request); // Translate with context const result = await this.baseService.translate(enhancedRequest); // Post-process result to maintain consistency return this.postProcessResult(result, request); } async translateBatch(requests: TranslationRequest[]): Promise<TranslationResult[]> { // Group requests by conversation context const groupedRequests = this.groupByConversation(requests); const results: TranslationResult[] = []; for (const group of groupedRequests) { // Translate each group with shared context const groupResults = await this.translateConversationGroup(group); results.push(...groupResults); } return results; } /** * Enhance translation request with conversation context */ private enhanceRequestWithContext(request: TranslationRequest): TranslationRequest { if (!request.context) { return request; } // Add context to translation request const contextPrefix = this.buildContextPrefix(request.context); const enhancedText = contextPrefix + request.text; return { ...request, text: enhancedText }; } /** * Build context prefix for translation */ private buildContextPrefix(context: ConversationContext): string { const parts: string[] = []; if (context.speaker) { parts.push(`Speaker: ${context.speaker}`); } if (context.previousContext) { parts.push(`Previous: ${context.previousContext}`); } if (context.nextContext) { parts.push(`Next: ${context.nextContext}`); } return parts.length > 0 ? `[Context: ${parts.join(' | ')}] ` : ''; } /** * Post-process translation result */ private postProcessResult(result: TranslationResult, originalRequest: TranslationRequest): TranslationResult { // Remove context prefix from result const contextPrefix = this.buildContextPrefix(originalRequest.context || { conversationId: '' }); const cleanText = result.translatedText.replace(contextPrefix, ''); return { ...result, translatedText: cleanText }; } /** * Group translation requests by conversation */ private groupByConversation(requests: TranslationRequest[]): TranslationRequest[][] { const groups = new Map<string, TranslationRequest[]>(); for (const request of requests) { const conversationId = request.context?.conversationId || 'default'; if (!groups.has(conversationId)) { groups.set(conversationId, []); } groups.get(conversationId)!.push(request); } return Array.from(groups.values()); } /** * Translate a group of requests from the same conversation */ private async translateConversationGroup(requests: TranslationRequest[]): Promise<TranslationResult[]> { // Sort by original order if possible const sortedRequests = requests.sort((a, b) => { // This would need to be enhanced with proper ordering logic return 0; }); const results: TranslationResult[] = []; for (const request of sortedRequests) { const result = await this.translate(request); results.push(result); } return results; } } /** * Chat-based AI translation service that uses the current AI assistant */ export class ChatAITranslationService implements TranslationService { private translationQueue: TranslationRequest[] = []; private isProcessing = false; async translate(request: TranslationRequest): Promise<TranslationResult> { // For now, we'll use a simple approach where the translation is handled // by the MCP server calling the AI assistant directly // This is a placeholder that will be replaced by the actual chat integration console.log(`🤖 AI Translation Request: "${request.text}" (${request.sourceLanguage} → ${request.targetLanguage})`); // This will be replaced with actual AI chat integration // For now, return a placeholder that indicates AI translation is needed return { translatedText: `[AI_TRANSLATION_NEEDED:${request.text}]`, confidence: 0.8, sourceLanguage: request.sourceLanguage || 'auto', targetLanguage: request.targetLanguage }; } async translateBatch(requests: TranslationRequest[]): Promise<TranslationResult[]> { const results: TranslationResult[] = []; for (const request of requests) { const result = await this.translate(request); results.push(result); } return results; } } /** * Translation service factory */ export class TranslationServiceFactory { static createMockService(): TranslationService { return new MockTranslationService(); } static createContextAwareService(baseService: TranslationService): TranslationService { return new ContextAwareTranslationService(baseService); } static createAIService(provider: 'openai' | 'google' | 'azure' | 'deepl', apiKey: string, baseUrl?: string): TranslationService { // For now, return mock service - external AI services not implemented return this.createMockService(); } static createChatAIService(): TranslationService { return new ChatAITranslationService(); } static createService(type: 'mock' | 'context-aware' | 'ai' | 'chat-ai' = 'mock', provider?: 'openai' | 'google' | 'azure' | 'deepl', apiKey?: string): TranslationService { switch (type) { case 'mock': return this.createMockService(); case 'context-aware': return this.createContextAwareService(this.createMockService()); case 'ai': if (!provider || !apiKey) { throw new Error('Provider and API key are required for AI translation service'); } return this.createAIService(provider, apiKey); case 'chat-ai': return this.createChatAIService(); default: throw new Error(`Unknown translation service type: ${type}`); } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/omd0/srt-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server