CreaRack-SL

Sistema de Traducción Wiki ES→EN (translate.ts + translate-wiki.mjs)

Descripción

Sistema de traducción automática de la wiki de CreaRack de español a inglés. Compuesto por dos componentes complementarios que comparten el mismo proveedor AI y patrón de integración:

ComponenteTipoTrigger
functions/api/wiki/translate.tsCF Pages Function (Worker)On-demand vía POST HTTP
scripts/translate-wiki.mjsScript Node.js (cron/pre-build)Manual o durante astro build

Ambos usan Gemma 4 26B-A4B-IT vía Google AI Studio Paid Tier (REST directo a generativelanguage.googleapis.com). Migrados de OpenRouter en s58 d21 (PR#31) para cerrar la deuda residual del cleanup s55 y alinearse con Regla 8 del proyecto (monoproveedor google-genai).


Componente 1: functions/api/wiki/translate.ts

Propósito

Endpoint POST /api/wiki/translate expuesto como CF Pages Function. Permite traducir on-demand un artículo wiki ES → EN desde el editor del workspace.

Env vars requeridas

VariableUso
GH_PATLeer y escribir archivos en el repo via GitHub API
GOOGLE_AI_API_KEYAutenticación con Google AI Studio (antes OPENROUTER_API_KEY)

Flow de ejecución

  1. Recibe { file: "slug.md" } en el body POST.
  2. Lee el archivo ES desde src/content/wiki/<slug>.md en GitHub (ghReadFile).
  3. Separa front-matter del body (splitFrontmatter).
  4. Traduce title + description + body en paralelo con Gemini/Gemma via translateWithAI.
  5. Reconstruye el archivo EN y lo escribe en src/content/wiki-en/<slug>.md (ghWriteFile).
  6. Actualiza src/content/wiki-en/titles.json con el par { [esTitle]: enTitle }.

Limitaciones conocidas

  • El SDK @google/generative-ai no es compatible con workerd (CF Workers runtime). Por eso se usa fetch directo a la REST API de Google AI Studio.
  • Concatena system prompt + user en un único contents[0] (formato Google, no OpenAI-compat).
  • btoa en workerd soporta hasta ~1 MB — suficiente para artículos wiki.

Auth del endpoint

Manejada por _middleware.ts: requiere CF Access o Bearer token. El endpoint no valida auth propio.


Componente 2: scripts/translate-wiki.mjs

Propósito

Script batch que escanea src/content/wiki/ y genera/actualiza las versiones EN en src/content/wiki-en/. Solo traduce artículos nuevos o modificados (compara hash de contenido).

Env vars requeridas

VariableUso
GOOGLE_AI_API_KEYAutenticación con Google AI Studio (antes OPENROUTER_API_KEY)

Scope de traducción

Solo traduce pages con prefijo crearack-- — el subset user-facing del Help Widget. Se excluyen por diseño:

  • crearack-tech--* (docs técnicas internas)
  • workspace--*
  • decision--*
  • Cualquier otro prefijo interno

Flow de ejecución

  1. Lee todos los .md de src/content/wiki/ con prefijo crearack--.
  2. Para cada archivo: compara hash con el EN existente en src/content/wiki-en/. Si coincide → skip.
  3. Si hay diferencia: translateText(body, BODY_INSTRUCTION) + translateText(frontmatter, FM_INSTRUCTION).
  4. Reensambla y escribe el archivo EN.
  5. Actualiza src/content/wiki-en/titles.json.
  6. En caso de error no falla el build (el EN es opcional).

Notas

  • Si GOOGLE_AI_API_KEY no está configurada, el script termina con console.log sin error.
  • Las instrucciones de traducción son constantes exportadas (BODY_INSTRUCTION, FM_INSTRUCTION) definidas en el módulo.

Patrón de integración AI

Ambos componentes usan el mismo patrón canónico establecido en archivo-core.ts:

const url = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${API_KEY}`;
const res = await fetch(url, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    contents: [{ role: 'user', parts: [{ text: `${instruction}\n\n${text}` }] }],
    generationConfig: { temperature: 0.2, maxOutputTokens: 8192 },
  }),
});
const data = await res.json();
return data.candidates?.[0]?.content?.parts?.[0]?.text?.trim() || '';

El system prompt y el user message se concatenan en un único contents[0] porque la API generateContent no tiene campo system_instruction en el tier REST basic.


Historial de migraciones del proveedor AI

FechaCambioReferencia
2026-04-28Gemini 2.5 Flash → Gemma 4 26B vía OpenRouterdecision--20260428--gemma-4-via-openrouter-migration
2026-05-11 (s55)Cleanup OpenRouter en CreaRack-Pro (workspace fuera de scope)decision--20260511--cleanup-openrouter-monoproveedor-google-genai
2026-05-12 (s58 d21)OpenRouter → Google AI Studio Paid Tier directo en workspacePR#31

Caller legítimo de OpenRouter conservado

functions/api/tools/ai-eval/run.ts (herramienta /tools/ai-eval) mantiene OpenRouter por diseño — su propósito es comparar modelos entre providers, por lo que OpenRouter es un provider seleccionable coherente. La env var OPENROUTER_API_KEY permanece en functions/types.ts únicamente para este caller.


Véase también

  • [[decision—20260511—cleanup-openrouter-monoproveedor-google-genai]]
  • [[decision—20260428—gemma-4-via-openrouter-migration]]