Internacionalización (i18n)
Architect CLI soporta inglés (default) y español para todos los mensajes generados por el sistema: logs humanos, prompts de agentes, reportes, guardrails y evaluaciones.
v1.1.0: Los mensajes del sistema ahora están en inglés por defecto. Se puede cambiar a español via configuración.
Configuración
Via YAML
# config.yaml (o .architect.yaml)
language: es # "en" (default) | "es"
Via variable de entorno
export ARCHITECT_LANGUAGE=es
Via código (para extensiones)
from architect.i18n import set_language, get_language
set_language("es")
print(get_language()) # "es"
Precedencia
1. Defaults del código → "en"
↓
2. Archivo YAML → language: es
↓
3. Variable de entorno → ARCHITECT_LANGUAGE=es
Qué cambia con el idioma
| Componente | Afectado por language | Ejemplo EN | Ejemplo ES |
|---|---|---|---|
| Logs HUMAN (stderr) | Sí | Step 1 → LLM call | Paso 1 → Llamada al LLM |
| Agent prompts (system) | Sí | You are a careful executor... | Eres un ejecutor cuidadoso... |
| Reportes (markdown/JSON) | Sí | ## Code Health Delta | ## Delta de Salud del Código |
| Guardrails messages | Sí | Sensitive file blocked... | Archivo sensible bloqueado... |
| Close instructions | Sí | Your budget is exhausted... | Tu presupuesto se ha agotado... |
| Context summaries | Sí | [Summary of previous steps] | [Resumen de pasos anteriores] |
| Self-evaluator prompts | Sí | Original task: | Tarea original: |
| Ralph Loop progress | Sí | # Ralph Loop — Progress | # Ralph Loop — Progreso |
| CLI help/flags | No | --mode yolo | --mode yolo |
| User prompts | No | (sin cambio) | (sin cambio) |
| Error messages (CLI) | No | (siempre inglés) | (siempre inglés) |
Qué NO cambia
- CLI help text:
architect --help,architect run --help, etc. siempre están en inglés. - Prompts del usuario: el texto que el usuario escribe no se traduce.
- Skills y
.architect.md: el contenido de los archivos del proyecto no se traduce. - Nombres de archivos:
SKILL.md,memory.md, etc. mantienen sus nombres. - Formato JSON de salida: las claves JSON (
status,final_output, etc.) no cambian.
Arquitectura
Módulo src/architect/i18n/
src/architect/i18n/
├── __init__.py # API pública: t(), set_language(), get_language(), get_prompt()
├── registry.py # LanguageRegistry — singleton thread-safe con fallback chain
├── en.py # Strings en inglés (canónico, ~160 keys)
└── es.py # Strings en español (~160 keys)
API pública
| Función | Descripción |
|---|---|
t(key, **kwargs) | Traduce una key con interpolación opcional |
get_prompt(key) | Obtiene un prompt multilinea para el idioma actual |
set_language(lang) | Establece el idioma activo ("en" o "es") |
get_language() | Retorna el código del idioma actual |
Cadena de fallback
Cuando se busca una key, el registry sigue esta cadena:
idioma actual → inglés (fallback) → key cruda (último recurso)
Esto garantiza que nunca se rompe la aplicación aunque falte una traducción: si una key no existe en español, se usa la versión inglesa. Si tampoco existe en inglés, se retorna la key como string.
Resolución lazy
Todas las traducciones se resuelven en runtime, no en import-time. Esto es crítico porque set_language() se llama después de que los módulos se importen (cuando se carga la configuración del usuario).
Los mecanismos lazy incluyen:
_PromptProxyenagents/prompts.py:DEFAULT_PROMPTS["build"]resuelve viaget_prompt()en cada acceso._LazyAgentDictenagents/registry.py:DEFAULT_AGENTS["build"]construye el AgentConfig con el prompt del idioma actual._LazyPrompty_LazyStr: wrappers paraREVIEW_SYSTEM_PROMPTyBUILD_PROMPTque resuelven en.format()ostr().
Namespaces de keys
Las ~160 keys están organizadas en 14 namespaces:
| Namespace | Keys | Qué cubre |
|---|---|---|
human.* | ~41 | HumanFormatter: logs de pasos, tools, safety nets, pipeline, ralph, reviewer, parallel, competitive, contexto |
competitive.* | ~17 | Reporte de evaluación competitiva: headers, ranking, detalles |
ralph.* | ~16 | Progreso de iteraciones, prompts de especificación |
eval.* | ~15 | Self-evaluator: prompt del sistema, labels, correcciones |
health.* | ~14 | Delta de salud del código: título, headers, métricas |
dispatch.* | ~13 | Sub-agentes: prompts, instrucciones, tipos |
guardrail.* | ~10 | Mensajes de bloqueo: sensible, protegido, comandos, límites |
context.* | ~9 | Resumen de contexto, headers, mensajes de omisión |
pipeline.* | ~7 | Validación de pipeline YAML: errores |
close.* | ~5 | Instrucciones de cierre: budget, max_steps, timeout, context_full, interrupt |
prompt.* | ~5 | System prompts de agentes: build, plan, resume, review |
reviewer.* | ~5 | Auto-reviewer: prompt del sistema, labels |
dryrun.* | ~3 | Resumen de dry-run: headers, labels |
misc.* | — | Headers de skills, labels de pipeline |
Ejemplo de uso
Cambiar idioma en config
# config.yaml
language: es
llm:
model: gpt-4o
architect run "analiza el proyecto" --mode yolo
# Los logs en stderr se muestran en español:
# 🔄 Paso 1 → Llamada al LLM (5 mensajes)
# ✓ LLM respondió con 2 tool calls
# ...
# ✅ Agente completado (3 pasos)
Cambiar idioma con env var
ARCHITECT_LANGUAGE=es architect run "analiza el proyecto" --mode yolo
Verificar idioma por código
from architect.i18n import t, set_language
# English (default)
print(t("human.llm_call", step=1, messages=5))
# → "\n🔄 Step 1 → LLM call (5 messages)"
set_language("es")
print(t("human.llm_call", step=1, messages=5))
# → "\n🔄 Paso 1 → Llamada al LLM (5 mensajes)"
Añadir un nuevo idioma
Para añadir soporte de un tercer idioma (por ejemplo, francés):
1. Crear el archivo de strings
# src/architect/i18n/fr.py
"""French language strings for architect-cli."""
STRINGS: dict[str, str] = {
"human.llm_call": "\n🔄 Étape {step} → Appel LLM ({messages} messages)",
"human.llm_response_tools": " ✓ LLM a répondu avec {count} appel{s} d'outil",
# ... todas las ~160 keys
}
2. Registrar en el registry
# src/architect/i18n/registry.py — en _load_defaults()
def _load_defaults(self):
from . import en, es, fr
self._languages["en"] = en.STRINGS
self._languages["es"] = es.STRINGS
self._languages["fr"] = fr.STRINGS
3. Actualizar el schema de config
# src/architect/config/schema.py
class AppConfig(BaseModel):
language: Literal["en", "es", "fr"] = "en"
4. Verificar paridad de keys
from architect.i18n.en import STRINGS as EN
from architect.i18n.fr import STRINGS as FR
missing = set(EN) - set(FR)
extra = set(FR) - set(EN)
assert not missing, f"Missing in FR: {missing}"
assert not extra, f"Extra in FR: {extra}"
Archivos relacionados
| Archivo | Rol |
|---|---|
src/architect/i18n/__init__.py | API pública |
src/architect/i18n/registry.py | LanguageRegistry singleton |
src/architect/i18n/en.py | Strings inglés (~160 keys) |
src/architect/i18n/es.py | Strings español (~160 keys) |
src/architect/config/schema.py | Campo language: Literal["en", "es"] en AppConfig |
src/architect/config/loader.py | Lectura de ARCHITECT_LANGUAGE env var |
src/architect/cli.py | set_language(config.language) al inicio |
tests/test_i18n/test_i18n.py | ~25 tests del sistema i18n |