AgentSkillsCN

Urdu Translation Agent

乌尔都语翻译代理

SKILL.md

Urdu Translation Agent

Auto-Generated

  • Created: 2025-12-27
  • Updated: 2025-12-30
  • Created By: Master Skill Factory
  • Project: Physical AI Textbook Hackathon
  • Reuse Count: 3

Purpose

Translate textbook content into Urdu while preserving technical accuracy, code blocks, and formatting. Provides per-chapter translation via a button at the start of each chapter.

Trigger Conditions

  • When implementing Urdu translation feature
  • User mentions "translate", "Urdu", "translation button"
  • When building per-chapter translation functionality
  • User presses "Translate to Urdu" button in chapter

Project Files Reference

code
backend/app/utils/translation.py        # Translation utility (88 lines)
backend/app/routes/rag.py               # /api/translate endpoint
src/components/TranslateButton/index.tsx # Frontend button (118 lines)
src/components/TranslateButton/styles.module.css

Core Rules

1. Preserve Technical Terms

Keep these in English:

  • Programming keywords (def, class, import, async)
  • Framework names (ROS 2, Gazebo, Isaac Sim)
  • Technical acronyms (LiDAR, IMU, SLAM, VLA)
  • API names and function names
  • Code blocks entirely

2. Maintain Formatting

  • Keep markdown structure intact
  • Preserve headings hierarchy
  • Keep code blocks unchanged
  • Maintain bullet points and lists

3. RTL Considerations

  • Urdu is Right-to-Left (RTL)
  • Numbers remain LTR within RTL text
  • Technical terms in English remain LTR

API Endpoint

POST /api/translate

python
from fastapi import APIRouter
from pydantic import BaseModel
from app.utils.translation import translate_to_urdu

router = APIRouter()

class TranslationRequest(BaseModel):
    content: str
    chapter_id: str
    preserve_code: bool = True

class TranslationResponse(BaseModel):
    translated_content: str
    original_language: str
    target_language: str

@router.post("/api/translate", response_model=TranslationResponse)
async def translate_chapter(request: TranslationRequest):
    """Translate chapter content to Urdu"""
    translated = await translate_to_urdu(
        content=request.content,
        preserve_code=request.preserve_code
    )
    return TranslationResponse(
        translated_content=translated,
        original_language="en",
        target_language="ur"
    )

Code Templates

Translation Utility (backend/app/utils/translation.py)

python
from openai import OpenAI
import re

client = OpenAI()

TRANSLATION_PROMPT = """You are a technical translator specializing in robotics and AI content.
Translate the following English text to Urdu.

RULES:
1. Keep ALL code blocks exactly as they are (do not translate code)
2. Keep technical terms in English: ROS 2, Gazebo, LiDAR, SLAM, Isaac Sim, etc.
3. Keep programming keywords in English: def, class, import, async, etc.
4. Translate explanatory text naturally into Urdu
5. Maintain the original markdown formatting
6. Keep headings structure intact

Text to translate:
{content}

Provide ONLY the translated text, no explanations."""

def extract_code_blocks(content: str) -> tuple[str, list[str]]:
    """Extract code blocks and replace with placeholders"""
    code_blocks = re.findall(r'```[\s\S]*?```', content)
    for i, block in enumerate(code_blocks):
        content = content.replace(block, f'[CODE_BLOCK_{i}]')
    return content, code_blocks

def restore_code_blocks(content: str, code_blocks: list[str]) -> str:
    """Restore code blocks from placeholders"""
    for i, block in enumerate(code_blocks):
        content = content.replace(f'[CODE_BLOCK_{i}]', block)
    return content

async def translate_to_urdu(content: str, preserve_code: bool = True) -> str:
    """Translate content to Urdu while preserving code"""

    # Extract code blocks if needed
    if preserve_code:
        content_to_translate, code_blocks = extract_code_blocks(content)
    else:
        content_to_translate = content
        code_blocks = []

    # Translate via OpenAI
    response = client.chat.completions.create(
        model="gpt-4",
        messages=[
            {"role": "system", "content": "You are a professional Urdu translator for technical content."},
            {"role": "user", "content": TRANSLATION_PROMPT.format(content=content_to_translate)}
        ],
        temperature=0.3  # Lower temperature for consistent translations
    )

    translated = response.choices[0].message.content

    # Restore code blocks
    if preserve_code and code_blocks:
        translated = restore_code_blocks(translated, code_blocks)

    return translated

Frontend TranslateButton Component

tsx
// src/components/TranslateButton/index.tsx
import React, { useState } from 'react';
import styles from './styles.module.css';

interface TranslateButtonProps {
  chapterId: string;
  content?: string;
}

export default function TranslateButton({ chapterId, content }: TranslateButtonProps) {
  const [isLoading, setIsLoading] = useState(false);
  const [translatedContent, setTranslatedContent] = useState<string | null>(null);
  const [showModal, setShowModal] = useState(false);
  const [language, setLanguage] = useState<'en' | 'ur'>('en');

  const handleTranslate = async () => {
    if (language === 'ur' && translatedContent) {
      setShowModal(true);
      return;
    }

    setIsLoading(true);
    try {
      // Get content from page if not provided
      const textToTranslate = content ||
        document.querySelector('article')?.innerText || '';

      const response = await fetch(`${BACKEND_URL}/api/translate`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          content: textToTranslate,
          chapter_id: chapterId,
          preserve_code: true
        })
      });

      const data = await response.json();
      setTranslatedContent(data.translated_content);
      setLanguage('ur');
      setShowModal(true);
    } catch (error) {
      console.error('Translation failed:', error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <>
      <button
        onClick={handleTranslate}
        className={styles.translateButton}
        disabled={isLoading}
      >
        {isLoading ? 'Translating...' : 'اردو میں پڑھیں'}
      </button>

      {showModal && (
        <div className={styles.modal} dir="rtl">
          <div className={styles.modalContent}>
            <button onClick={() => setShowModal(false)}>Close</button>
            <div className={styles.translatedText}>
              {translatedContent}
            </div>
          </div>
        </div>
      )}
    </>
  );
}

Styles (styles.module.css)

css
.translateButton {
  background: linear-gradient(135deg, #059669, #047857);
  color: white;
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-family: 'Noto Nastaliq Urdu', serif;
  margin-left: 8px;
}

.translateButton:hover {
  background: linear-gradient(135deg, #047857, #065f46);
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modalContent {
  background: white;
  padding: 24px;
  border-radius: 12px;
  max-width: 800px;
  max-height: 80vh;
  overflow-y: auto;
  direction: rtl;
  font-family: 'Noto Nastaliq Urdu', serif;
}

.translatedText {
  line-height: 2;
  font-size: 18px;
}

Usage in Chapter Files

Add to each chapter markdown:

mdx
---
sidebar_position: 1
---

import TranslateButton from '@site/src/components/TranslateButton';

# Chapter Title

<TranslateButton chapterId="ch1-intro-physical-ai" />

Chapter content here...

Environment Variables

env
OPENAI_API_KEY=sk-...  # Required for GPT-4 translation

Testing Checklist

  • Button appears at top of each chapter
  • Translation preserves code blocks
  • Technical terms remain in English
  • RTL formatting works correctly
  • Modal displays translated content
  • Close button works
  • Loading state shows during translation

Error Handling

ErrorCauseSolution
Translation incompleteContent too longChunk content and translate in parts
Code blocks translatedPrompt issueVerify code extraction works
RTL not workingCSS issueAdd dir="rtl" to container
OpenAI errorAPI issueCheck API key and rate limits

Version

  • Version: 2.0.0
  • Category: Content Skills
  • Integration: Backend (FastAPI) + Frontend (React)