# Skill: Translation Service Integration (Google Gemini API)

## Identity
- **Skill ID**: `ml-service-integration`
- **Domain**: AI Translation, Google Gemini API
- **Technologies**: Google Gemini API, TypeScript, Node.js
- **Source Agent**: `backend-app-expert.md`

## When to Load This Skill

Load this skill when working on:
- Google Gemini API client implementation
- Translation service integration
- HTML content preservation during translation
- Token counting and billing calculation
- Translation quality optimization
- Error handling and retries
- Dynamic configuration management

**File patterns:**
- `api/src/services/gemini*.ts`
- `api/src/services/translation*.ts`
- `api/src/config/index.ts`

## Core Patterns

### 1. Gemini Client Implementation

See `api/src/services/geminiClient.ts` for the complete implementation.

**Key features:**
- Singleton pattern for client instance
- Dynamic configuration refresh on settings update
- HTML tag preservation via placeholder system
- Token counting for billing
- Timeout handling
- Error handling with retry logic

### 2. HTML Content Preservation

```typescript
// Extract HTML tags before translation
private extractHtmlTags(content: string): { text: string; tags: Map<string, string> } {
  const tags = new Map<string, string>();
  let counter = 0;
  const htmlTagRegex = /<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s+[^>]*)?>/g;
  
  const text = content.replace(htmlTagRegex, (match) => {
    const placeholder = `__TAG_${counter}__`;
    tags.set(placeholder, match);
    counter++;
    return placeholder;
  });
  
  return { text, tags };
}

// Restore HTML tags after translation
private restoreHtmlTags(text: string, tags: Map<string, string>): string {
  let result = text;
  tags.forEach((tag, placeholder) => {
    result = result.replace(placeholder, tag);
  });
  return result;
}
```

### 3. Translation Prompt Engineering

```typescript
// Build effective translation prompt
const prompt = `Translate the following text from ${sourceLanguage} to ${targetLanguage}.

${toneInstruction}

IMPORTANT RULES:
1. Preserve all placeholders in the format __TAG_N__ exactly as they appear
2. Do not translate the placeholders themselves
3. Only translate the actual text content
4. Maintain the exact position and format of placeholders
5. Output ONLY the translated text, no explanations

Text to translate:
${cleanText}`;
```

### 4. Token Counting

```typescript
// Count tokens for billing
const tokenCountResult = await this.model.countTokens(prompt);
const inputTokens = tokenCountResult.totalTokens;

// After translation
const outputTokenCountResult = await this.model.countTokens(translatedText);
const outputTokens = outputTokenCountResult.totalTokens;

const totalTokens = inputTokens + outputTokens;
```

### 5. Error Handling

```typescript
try {
  const result = await geminiClient.translate(...);
} catch (error) {
  if (error.message.includes('timeout')) {
    throw new Error('Translation timed out. Please try again or use async translation.');
  } else if (error.message.includes('API key')) {
    throw new Error('Gemini API authentication failed.');
  } else if (error.message.includes('quota') || error.message.includes('rate limit')) {
    throw new Error('API rate limit exceeded. Please try again later.');
  } else {
    throw new Error(`Translation failed: ${error.message}`);
  }
}
```

## Integration with API Endpoints

```typescript
// POST /translate endpoint
router.post('/translate', async (req, res) => {
  const { content, source_lang, target_lang, tone } = req.body;
  
  try {
    const result = await geminiClient.translate(
      content,
      source_lang,
      target_lang,
      Model.GEMINI_3_FLASH,
      tone || Tone.NEUTRAL
    );
    
    res.json({
      translation: result.translation,
      tokens_used: result.tokens_used,
      processing_time_ms: result.processing_time_ms,
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
```

## Environment Variables Required

```bash
# Google Gemini API Configuration
GEMINI_API_KEY="your-google-gemini-api-key"
GEMINI_MODEL="gemini-3-flash-preview"
```

## Anti-Patterns (Forbidden)

| ❌ Mistake | ✅ Fix |
|-----------|--------|
| Not preserving HTML | Use placeholder system |
| Hardcoding API key | Use environment variables |
| No timeout handling | Set 60s timeout |
| Not counting tokens | Count input + output tokens |
| Ignoring API errors | Handle specific error cases |
| Exposing API keys in logs | Sanitize sensitive data |
| Blocking on translation | Use async/await with timeouts |

## Quick Reference

### Supported Languages

English, Spanish, French, German, Italian, Portuguese, Dutch, Polish, Russian, Japanese, Korean, Chinese, Arabic, Hindi, Turkish, Vietnamese, Thai, Indonesian, and more.

### Response Times

- Short (< 100 words): ~1-2s
- Medium (100-500 words): ~2-4s
- Long (500-2000 words): ~4-8s

### Token Pricing

- Gemini 3 Flash Preview: ~$0.002 per 1K tokens

### Validation Checklist

- [ ] Gemini API key configured
- [ ] HTML preservation tested
- [ ] Token counting accurate
- [ ] Timeout handling works
- [ ] Language validation in place
- [ ] Tone parameter functional
- [ ] Error handling comprehensive
- [ ] Health check endpoint working
- [ ] Dynamic config refresh enabled

## Related Skills

- `queue-management` - Async translation processing
- `api-endpoint-creation` - Translation endpoints
- `webhook-implementation` - Result delivery
- `error-handling-logging` - Error handling
