Settings gains a second service button next to restart: stop every managed local model server and exit the gateway process (nothing is respawned; in Docker the restart policy decides). The SPA replaces itself with a static "gateway is off" screen since the API is gone. The restart button is relabeled "Restart everything" to say what it always did — the gateway re-execs itself and managed servers come back with it. Translated in all seven languages.
654 lines
37 KiB
JavaScript
Vendored
654 lines
37 KiB
JavaScript
Vendored
// Spanish — traducciones para la consola de administración de allaigate Gateway.
|
||
export default {
|
||
// brand / common
|
||
"brand.sub": "Gateway",
|
||
"common.loading": "Cargando…",
|
||
"common.save": "Guardar",
|
||
"common.saving": "Guardando…",
|
||
"common.cancel": "Cancelar",
|
||
"common.add": "Agregar",
|
||
"common.edit": "Editar",
|
||
"common.delete": "Eliminar",
|
||
"common.close": "Cerrar",
|
||
"common.test": "Probar",
|
||
"common.copy": "Copiar",
|
||
"common.copied": "Copiado",
|
||
"common.confirm": "Confirmar",
|
||
"common.none": "ninguno",
|
||
"common.saved": "Guardado",
|
||
"common.error": "Error",
|
||
"common.ok": "OK",
|
||
"common.refresh": "Actualizar",
|
||
"common.actions": "Acciones",
|
||
"common.optional": "opcional",
|
||
"common.search": "Buscar",
|
||
"common.all": "todos",
|
||
|
||
// nav
|
||
"nav.dashboard": "Panel",
|
||
"nav.models": "Modelos",
|
||
"nav.routing": "Enrutamiento",
|
||
"nav.protocols": "Protocolos",
|
||
"nav.keys": "Claves API",
|
||
"nav.playground": "Zona de pruebas",
|
||
"nav.settings": "Configuración",
|
||
"nav.foot": "Gateway · v{v}",
|
||
"nav.billing": "Clave del router y pagos",
|
||
|
||
// topbar / status
|
||
"status.router": "Router",
|
||
"status.gateway": "Gateway",
|
||
"status.online": "en línea",
|
||
"status.offline": "sin conexión",
|
||
"status.checking": "verificando…",
|
||
"status.noKey": "sin clave",
|
||
"theme.toggle": "Tema",
|
||
"logout": "Cerrar sesión",
|
||
|
||
// login
|
||
"login.title": "allaigate Gateway",
|
||
"login.subtitle": "Ingresa el token de administrador para gestionar este gateway.",
|
||
"login.token": "Token de administrador",
|
||
"login.tokenPlaceholder": "pega el token de administrador",
|
||
"login.submit": "Abrir consola",
|
||
"login.hint": "El token se imprime en el log del gateway al iniciar, o se configura mediante [admin].token_env.",
|
||
"login.failed": "Token de administrador inválido.",
|
||
|
||
// dashboard
|
||
"dash.title": "Panel",
|
||
"dash.subtitle": "Tráfico en vivo, costos y análisis de enrutamiento de tu pool de modelos.",
|
||
"dash.range": "Rango",
|
||
"dash.range.1h": "1h",
|
||
"dash.range.24h": "24h",
|
||
"dash.range.7d": "7d",
|
||
"dash.kpi.requests": "Solicitudes",
|
||
"dash.kpi.tokens": "Tokens",
|
||
"dash.kpi.cost": "Costo",
|
||
"dash.kpi.latency": "Latencia promedio",
|
||
"dash.kpi.success": "Tasa de éxito",
|
||
"dash.kpi.failovers": "Failovers",
|
||
"dash.series.title": "Solicitudes en el tiempo",
|
||
"dash.series.cost": "Costo en el tiempo",
|
||
"dash.series.empty": "Sin tráfico en este rango.",
|
||
"dash.breakdown.title": "Desglose",
|
||
"dash.groupby.model": "por modelo",
|
||
"dash.groupby.tier": "por nivel",
|
||
"dash.groupby.label": "por tarea",
|
||
"dash.groupby.account": "por cuenta",
|
||
"dash.recent.title": "Solicitudes recientes",
|
||
"dash.recent.empty": "Sin solicitudes registradas. Prueba la Zona de pruebas.",
|
||
"dash.col.time": "Hora",
|
||
"dash.col.model": "Modelo",
|
||
"dash.col.tier": "Nivel",
|
||
"dash.col.task": "Tarea",
|
||
"dash.col.tokens": "Tokens",
|
||
"dash.col.cost": "Costo",
|
||
"dash.col.latency": "Latencia",
|
||
"dash.col.outcome": "Resultado",
|
||
"dash.col.requests": "Solicitudes",
|
||
"dash.col.errors": "Errores",
|
||
"dash.health.title": "Estado",
|
||
"dash.health.reachable": "accesible",
|
||
"dash.health.unreachable": "inaccesible",
|
||
"dash.health.getKey": "Obtener una clave del router",
|
||
|
||
// models
|
||
"models.title": "Modelos",
|
||
"models.subtitle": "Tu pool de modelos — combina modelos locales económicos con APIs en la nube.",
|
||
"models.add": "Agregar modelo",
|
||
"models.empty": "Sin modelos aún. Agrega tu primer modelo para comenzar.",
|
||
"models.col.id": "ID",
|
||
"models.col.provider": "Proveedor",
|
||
"models.col.model": "Modelo",
|
||
"models.col.tier": "Nivel de costo",
|
||
"models.col.key": "Clave",
|
||
"models.col.caps": "Capacidades",
|
||
"models.col.price": "Precio (entrada/salida)",
|
||
"models.probe": "Sondear",
|
||
"models.probe.ok": "Accesible ({ms} ms)",
|
||
"models.probe.fail": "Error: {err}",
|
||
"models.form.addTitle": "Agregar modelo",
|
||
"models.form.editTitle": "Editar modelo",
|
||
"models.form.id": "ID",
|
||
"models.form.idHint": "ID único usado en enrutamiento, ej. local-qwen",
|
||
"models.form.provider": "Proveedor",
|
||
"models.form.baseUrl": "URL base",
|
||
"models.form.model": "Nombre del modelo",
|
||
"models.form.kind": "Tipo",
|
||
"models.form.costTier": "Nivel de costo",
|
||
"models.form.priceIn": "Precio entrada ($/1M)",
|
||
"models.form.priceOut": "Precio salida ($/1M)",
|
||
"models.form.apiKeyEnv": "Nombre de variable env para clave API",
|
||
"models.form.apiKeyEnvHint": "Nombre de la variable de entorno o secreto que contiene la clave del proveedor.",
|
||
"models.form.caps": "Capacidades",
|
||
"models.form.secret": "Valor secreto",
|
||
"models.form.secretStored": "almacenado",
|
||
"models.form.secretEnv": "desde env",
|
||
"models.form.secretMissing": "no configurado",
|
||
"models.form.secretPlaceholder": "establecer o reemplazar clave (solo escritura)",
|
||
"models.deleteConfirm": "¿Eliminar modelo \"{id}\"?",
|
||
|
||
// routing
|
||
"routing.title": "Enrutamiento",
|
||
"routing.subtitle": "Asigna niveles de complejidad a una lista ordenada de modelos (prioridad = fallback).",
|
||
"routing.default": "Modelo predeterminado",
|
||
"routing.defaultHint": "Usado cuando el router no está disponible.",
|
||
"routing.tiers": "Niveles",
|
||
"routing.tierHint": "Arrastra los chips para reordenar; el primero es preferido, los demás son fallbacks.",
|
||
"routing.addModel": "+ agregar",
|
||
"routing.addTier": "Agregar nivel",
|
||
"routing.tierName": "Nombre del nivel",
|
||
"routing.policy": "Política",
|
||
"routing.policy.mode": "Modo",
|
||
"routing.policy.fixed": "Tabla fija",
|
||
"routing.policy.costAware": "Consciente del costo",
|
||
"routing.policy.maxCost": "Costo máx. por solicitud ($)",
|
||
"routing.policy.minClass": "Clase mínima por nivel",
|
||
"routing.empty": "Sin modelos disponibles — agrega modelos primero.",
|
||
|
||
// protocols
|
||
"protocols.title": "Protocolos",
|
||
"protocols.subtitle": "Activa solo las APIs de entrada que necesitas. Los cambios se aplican en vivo.",
|
||
"protocols.implemented": "implementado",
|
||
"protocols.planned": "planificado",
|
||
"protocols.openai_chat": "OpenAI Chat Completions",
|
||
"protocols.openai_chat.d": "POST /v1/chat/completions — compatible con OpenAI SDK, LangChain, crewAI.",
|
||
"protocols.openai_completions": "OpenAI Completions (legacy)",
|
||
"protocols.openai_completions.d": "POST /v1/completions — integraciones heredadas.",
|
||
"protocols.openai_embeddings": "OpenAI Embeddings",
|
||
"protocols.openai_embeddings.d": "POST /v1/embeddings — pipelines RAG.",
|
||
"protocols.openai_models": "OpenAI Models",
|
||
"protocols.openai_models.d": "GET /v1/models — autodescubrimiento de clientes.",
|
||
"protocols.anthropic_messages": "Anthropic Messages",
|
||
"protocols.anthropic_messages.d": "POST /v1/messages — agentes nativos Claude.",
|
||
"protocols.mcp": "MCP (Model Context Protocol)",
|
||
"protocols.mcp.d": "JSON-RPC / SSE — orquestadores nativos MCP.",
|
||
"protocols.native_passthrough": "Passthrough nativo",
|
||
"protocols.native_passthrough.d": "POST /route — acceso directo a la decisión de enrutamiento.",
|
||
|
||
// keys
|
||
"keys.title": "Claves API",
|
||
"keys.subtitle": "Claves de gateway virtuales para tus agentes. Las claves del proveedor nunca salen del gateway.",
|
||
"keys.add": "Nueva clave",
|
||
"keys.empty": "Sin claves configuradas — el gateway está en modo abierto (sin autenticación).",
|
||
"keys.openMode": "Modo abierto: cualquier solicitud es aceptada (no se requiere clave).",
|
||
"keys.col.key": "Clave",
|
||
"keys.col.account": "Cuenta",
|
||
"keys.col.rate": "Límite / min",
|
||
"keys.col.models": "Modelos permitidos",
|
||
"keys.form.title": "Nueva clave API",
|
||
"keys.form.account": "Cuenta",
|
||
"keys.form.rate": "Límite de tasa / min",
|
||
"keys.form.allow": "Modelos permitidos",
|
||
"keys.form.allowHint": "Deja vacío para permitir todos los modelos.",
|
||
"keys.form.custom": "Clave personalizada (opcional)",
|
||
"keys.form.customHint": "Deja vacío para generar automáticamente sk-gw-…",
|
||
"keys.created": "Clave creada — cópiala ahora, no se mostrará de nuevo:",
|
||
"keys.revoke": "Revocar",
|
||
"keys.revokeConfirm": "¿Revocar esta clave?",
|
||
"keys.allowAll": "todos",
|
||
|
||
// playground
|
||
"pg.title": "Zona de pruebas",
|
||
"pg.subtitle": "Envía un prompt por el pipeline en vivo e inspecciona la decisión de enrutamiento.",
|
||
"pg.system": "Prompt del sistema",
|
||
"pg.systemPlaceholder": "mensaje de sistema opcional",
|
||
"pg.prompt": "Prompt",
|
||
"pg.promptPlaceholder": "Escribe algo…",
|
||
"pg.mode": "Modo",
|
||
"pg.mode.auto": "Auto (enrutar)",
|
||
"pg.mode.pinned": "Modelo fijo",
|
||
"pg.profile": "Perfil",
|
||
"pg.model": "Modelo",
|
||
"pg.temp": "Temperatura",
|
||
"pg.maxTokens": "Tokens máx.",
|
||
"pg.send": "Enviar",
|
||
"pg.stream": "Streaming",
|
||
"pg.sending": "Enviando…",
|
||
"pg.answer": "Respuesta",
|
||
"pg.empty": "La respuesta y la decisión de enrutamiento aparecerán aquí.",
|
||
"pg.decision": "Decisión de enrutamiento",
|
||
"pg.task": "Tarea",
|
||
"pg.tier": "Nivel",
|
||
"pg.score": "Complejidad",
|
||
"pg.selected": "Modelo seleccionado",
|
||
"pg.source": "Fuente de ruta",
|
||
"pg.cost": "Costo",
|
||
"pg.latency": "Latencia",
|
||
"pg.tokens": "Tokens (entrada/salida)",
|
||
"pg.failover": "Failover",
|
||
"pg.error": "Solicitud fallida",
|
||
|
||
// settings
|
||
"settings.title": "Configuración",
|
||
"settings.subtitle": "Conexión del gateway, entrada de enrutamiento, fiabilidad y observabilidad.",
|
||
"settings.router": "Conexión del router",
|
||
"settings.router.url": "URL del router",
|
||
"settings.router.keyEnv": "Nombre de variable env para clave del router",
|
||
"settings.router.timeout": "Tiempo de espera (ms)",
|
||
"settings.router.verifyTls": "Verificar certificado TLS",
|
||
"settings.router.taxonomy": "ID de taxonomía",
|
||
"settings.router.getKey": "Obtén o recarga una clave del router en",
|
||
"settings.router.secret": "Clave del router (valor)",
|
||
"settings.router.test": "Probar router",
|
||
"router.probe.ok": "Router OK ({ms} ms)",
|
||
"router.probe.noKey": "La clave del router no está configurada",
|
||
"router.probe.auth": "Clave rechazada — inválida o revocada",
|
||
"router.probe.payment": "Pago requerido — plan vencido o cuota agotada",
|
||
"router.probe.quota": "Límite de tasa excedido",
|
||
"router.probe.timeout": "Tiempo de espera del router agotado",
|
||
"router.probe.unreachable": "Router inaccesible",
|
||
"router.probe.error": "Error del router",
|
||
"router.usage": "Consumo",
|
||
"settings.route": "Entrada de enrutamiento",
|
||
"settings.route.strategy": "Estrategia de texto",
|
||
"settings.route.maxChars": "Máx. caracteres",
|
||
"settings.route.cacheTtl": "TTL de caché",
|
||
"settings.route.profile": "Perfil predeterminado",
|
||
"settings.breaker": "Circuit breaker",
|
||
"settings.breaker.threshold": "Umbral de errores",
|
||
"settings.breaker.cooldown": "Cooldown",
|
||
"settings.log": "Registro",
|
||
"settings.log.level": "Nivel de log",
|
||
"settings.log.bodies": "Registrar cuerpos de mensajes (privacidad desactivada)",
|
||
"settings.telemetry": "Telemetría",
|
||
"settings.telemetry.metrics": "Exponer Prometheus /metrics",
|
||
"settings.cortiq": "Metadatos de respuesta",
|
||
"settings.cortiq.echo": "Incluir bloque de enrutamiento cortiq en respuestas",
|
||
"settings.stats": "Estadísticas",
|
||
"settings.stats.enabled": "Registrar estadísticas de solicitudes",
|
||
"settings.stats.file": "Archivo de estadísticas (JSONL)",
|
||
"settings.stats.retention": "Retención",
|
||
"settings.listen": "Dirección de escucha",
|
||
"settings.export": "Exportar configuración",
|
||
"settings.import": "Importar configuración",
|
||
"settings.needsRestart": "Guardado. Algunos cambios (dirección de escucha) requieren reinicio.",
|
||
|
||
// toasts / misc
|
||
"toast.saved": "Cambios guardados",
|
||
"toast.deleted": "Eliminado",
|
||
"toast.probing": "Sondeando…",
|
||
"toast.imported": "Configuración importada",
|
||
"dash.cache": "Caché semántico",
|
||
"dash.cache.hitRate": "Aciertos",
|
||
"dash.cache.hits": "Aciertos",
|
||
"dash.cache.saved": "Ahorrado",
|
||
"dash.cache.disabled": "El caché semántico está desactivado — actívalo en Ajustes.",
|
||
"settings.cache": "Caché semántico",
|
||
"settings.cache.enabled": "Activar caché semántico",
|
||
"settings.cache.threshold": "Umbral de similitud",
|
||
"settings.cache.ttl": "TTL de entrada",
|
||
"settings.cache.embed": "Modelo de embeddings",
|
||
"settings.cache.note": "Los ajustes del caché se aplican tras reiniciar.",
|
||
|
||
// ── translated from en.js (previously falling back to English) ──
|
||
// nav
|
||
"nav.import": "Importar modelo",
|
||
|
||
// dash
|
||
"dash.clear": "Borrar registros",
|
||
"dash.clearConfirm": "¿Borrar todas las estadísticas y registros guardados? Esta acción no se puede deshacer.",
|
||
"dash.cleared": "Registros borrados",
|
||
|
||
// models
|
||
"models.form.idOrModel": "Introduce un id o un nombre de modelo",
|
||
"models.form.apiKey": "Clave API",
|
||
"models.form.apiKeyPlaceholder": "pega tu clave API",
|
||
"models.form.apiKeyNotNeeded": "no necesaria (servidor local)",
|
||
"models.form.apiKeyHint": "Se guarda de forma segura en la pasarela; no se vuelve a mostrar.",
|
||
"models.form.keyStored": "Hay una clave guardada — déjalo vacío para conservarla o pega una nueva.",
|
||
"models.form.keyFromEnv": "Se está usando una clave de una variable de entorno.",
|
||
"models.form.paramsTitle": "Parámetros de generación y razonamiento (O(1), MTP, temperatura)",
|
||
"models.form.temperature": "Temperatura",
|
||
"models.form.temperatureHint": "Temperatura de generación (0.0 = determinista, 1.0+ = creativa).",
|
||
"models.form.topP": "Top-P (muestreo nucleus)",
|
||
"models.form.topPHint": "Umbral de muestreo (0.0 .. 1.0).",
|
||
"models.form.maxTokens": "Tokens máx.",
|
||
"models.form.maxTokensHint": "Número máximo de tokens generados.",
|
||
"models.form.thinkBudget": "Modo razonamiento / presupuesto de pensamiento",
|
||
"models.form.thinkBudgetHint": "Presupuesto de tokens de razonamiento (0 = desactivado, N > 0 = máximo de tokens de razonamiento).",
|
||
"models.form.systemPrompt": "Prompt de sistema por defecto",
|
||
"models.form.systemPromptHint": "Se antepone automáticamente si la petición no trae prompt de sistema.",
|
||
"models.form.systemPromptPlaceholder": "Eres un asistente útil…",
|
||
"models.form.testKey": "Probar y cargar modelos",
|
||
"models.form.testing": "comprobando…",
|
||
"models.form.foundModels": "{n} modelos cargados",
|
||
"models.form.modelPlaceholder": "escribe para buscar…",
|
||
"models.form.modelHint": "Pulsa «Probar y cargar modelos» para traer la lista con tu clave y luego elige uno.",
|
||
"models.managed": "gestionado",
|
||
"models.managedHint": "Lo proporciona el servidor CMF gestionado (Ajustes → Modelos locales). Configúralo allí.",
|
||
|
||
// settings
|
||
"settings.router.enabled": "Usar el router (desactivado = solo modelos locales)",
|
||
"settings.cmf": "Modelos locales (CMF)",
|
||
"settings.cmf.localOnly": "Usar solo modelos locales",
|
||
"settings.cmf.manage": "Ejecutar un servidor de modelo local",
|
||
"settings.cmf.autoInstall": "Instalar cortiq automáticamente (crates.io)",
|
||
"settings.cmf.autoUpdate": "Actualizar cortiq automáticamente",
|
||
"settings.cmf.model": "Ruta del modelo .cmf local",
|
||
"settings.cmf.port": "Puerto del servidor local",
|
||
"settings.cmf.modelId": "Id del modelo en el pool",
|
||
"settings.cmf.note": "Sirve un .cmf local mediante cortiq (github.com/infosave2007/cmf). Funciona incluso cuando el router no está disponible.",
|
||
"settings.cmf.threads": "Hilos de trabajo",
|
||
"settings.cmf.gpu": "Usar GPU (Metal / wgpu)",
|
||
"settings.cmf.speedNote": "Los hilos paralelizan los matvec de decodificación (~3× más rápido; 0 = valor por defecto del runtime). Descargar en GPU ayuda sobre todo al prefill de prompts largos — la decodificación está limitada por el ancho de banda de memoria, así que en Apple Silicon es prácticamente neutro.",
|
||
"settings.cmf.pick": "selecciona un modelo",
|
||
"settings.cmf.models": "Modelos locales",
|
||
"settings.cmf.modelsHelp": "Cada fila es un modelo que la pasarela ejecuta (su propio cortiq serve en su propio puerto) y registra en el pool. Añade tantos como archivos .cmf y puertos libres tengas.",
|
||
"settings.cmf.rowHint": "id · archivo .cmf · puerto · hilos · GPU. Los cambios se aplican al reiniciar; borrar una fila detiene ese servidor.",
|
||
"settings.cmf.addServer": "+ Añadir modelo local",
|
||
"settings.cmf.checkPort": "Comprobar puerto",
|
||
"settings.cmf.portFree": "puerto libre",
|
||
"settings.cmf.portBusy": "puerto ocupado",
|
||
"settings.cmf.useSuggested": "usar {port}",
|
||
"settings.cmf.serving": "sirviendo {model} en :{port}",
|
||
"settings.cmf.intro": "Ejecuta modelos en local con el motor cortiq — funciona incluso sin conexión o cuando el router está caído.",
|
||
"settings.cmf.runtime": "Runtime cortiq",
|
||
"settings.cmf.runtimeHelp": "La herramienta de línea de comandos `cortiq` que carga y ejecuta modelos .cmf. Instálala una vez antes de arrancar un servidor local.",
|
||
"settings.cmf.install": "Instalar cortiq",
|
||
"settings.cmf.reinstall": "Reinstalar / actualizar",
|
||
"settings.cmf.installing": "instalando… (compila, unos minutos)",
|
||
"settings.cmf.installedOk": "cortiq instalado",
|
||
"settings.cmf.notInstalled": "no instalado",
|
||
"settings.cmf.addModel": "Añadir un modelo",
|
||
"settings.cmf.addModelHelp": "Los modelos se descargan y convierten en la pestaña Importar (HuggingFace → .cmf). Después apunta el servidor local al archivo .cmf de abajo.",
|
||
"settings.cmf.importNote": "¿Aún no tienes modelo? Importa uno:",
|
||
"settings.cmf.importLink": "Abrir Importar",
|
||
"settings.cmf.modelHelp": "Ruta del archivo .cmf que se va a servir (p. ej. models/qwen.cmf), generado en la pestaña Importar. ¿Varios modelos para distintas tareas? Impórtalos y cambia esta ruta.",
|
||
"settings.cmf.portHelp": "Puerto TCP en el que escucha el servidor de modelo local (8081 por defecto). Cámbialo solo si choca con otro servicio.",
|
||
"settings.cmf.threadsHelp": "Cuántos núcleos de CPU usar para la generación. Más = más rápido (~3× frente a un núcleo); 0 deja que decida el runtime.",
|
||
"settings.cmf.gpuHelp": "Descargar el cálculo matricial en la GPU (Metal/wgpu). En Apple Silicon acelera sobre todo los prompts largos — la decodificación está limitada por el ancho de banda de memoria.",
|
||
"settings.cmf.localOnlyHelp": "Enviar cada petición al modelo local, ignorando el router y cualquier proveedor en la nube.",
|
||
"settings.cmf.manageHelp": "La pasarela arranca `cortiq serve` para el .cmf de abajo al iniciarse y enruta hacia él. Requiere cortiq instalado (paso 1). Se aplica al reiniciar.",
|
||
"settings.cmf.autoInstallHelp": "Si cortiq falta al arrancar, instalarlo automáticamente desde crates.io.",
|
||
"settings.cmf.autoUpdateHelp": "Al arrancar, actualizar cortiq a la versión más reciente si existe una más nueva.",
|
||
"settings.router.enabledHelp": "Dejar que el router de cortiq clasifique cada petición (tipo de tarea + complejidad) y elija un modelo. Desactivado = usar solo la tabla de enrutado local.",
|
||
"settings.router.verifyTlsHelp": "Verificar el certificado TLS del router. Desactívalo solo con un certificado autofirmado o ligado a una IP.",
|
||
"settings.telemetry.metricsHelp": "Exponer métricas Prometheus en GET /metrics.",
|
||
"settings.cortiq.echoHelp": "Añadir un campo `cortiq` (tarea, modelo, coste) al cuerpo de cada respuesta. Las cabeceras de respuesta se envían siempre.",
|
||
"settings.stats.enabledHelp": "Registrar las peticiones recientes para alimentar el panel y las gráficas.",
|
||
"settings.cache.enabledHelp": "Caché semántica: devolver una respuesta guardada cuando un prompt nuevo se parece mucho a uno anterior, evitando la llamada al modelo. Requiere un modelo de embeddings en el pool.",
|
||
"settings.log.bodiesHelp": "Registrar el cuerpo completo de los mensajes de petición y respuesta. Desactivado por defecto por privacidad.",
|
||
"settings.router.saveKey": "Guardar clave",
|
||
"settings.router.keySaved": "Clave del router guardada",
|
||
"settings.router.keyEmpty": "Pega antes la clave",
|
||
"settings.router.secretHelp": "Pega la clave del correo de api.allaigate.com y pulsa Guardar clave. NO es un valor de «Claves API» — esas son para los clientes que llaman a tu pasarela.",
|
||
"settings.router.keyStoredMask": "•••••••••••• — clave guardada (pega otra para reemplazarla)",
|
||
"settings.route.strategyHelp": "Qué texto se envía al router para clasificar: last_user = solo el último mensaje del usuario; last_user_plus_system = último mensaje del usuario + prompt de sistema; concat_all = toda la conversación.",
|
||
"settings.route.maxCharsHelp": "Máximo de caracteres de ese texto enviados al router (lo que exceda se recorta). Más = clasificación más precisa, pero llamadas al router más lentas y caras.",
|
||
"settings.route.cacheTtlHelp": "Cuánto tiempo se cachea una decisión de enrutado para una petición idéntica antes de volver a preguntar al router (p. ej. 60s, 5m).",
|
||
"settings.route.profileHelp": "Perfil de enrutado por defecto cuando la petición no indica ninguno: cost-saver (el más barato), balanced o quality-first (el mejor modelo). Influye en qué modelo elige el router.",
|
||
|
||
// import
|
||
"import.subtitle": "Busca en HuggingFace, convierte a un .cmf local y sírvelo.",
|
||
"import.searchPlaceholder": "Buscar modelos en HuggingFace (p. ej. qwen3, llama)…",
|
||
"import.searching": "Buscando…",
|
||
"import.noResults": "No se encontraron modelos.",
|
||
"import.configure": "Configurar la conversión",
|
||
"import.outName": "Nombre de salida",
|
||
"import.outNameHint": "Nombre del archivo .cmf (letras, dígitos, - y _).",
|
||
"import.quant": "Cuantización",
|
||
"import.convert": "Convertir y cargar",
|
||
"import.converting": "Convirtiendo",
|
||
"import.started": "Conversión iniciada",
|
||
"import.failed": "La conversión falló — revisa el registro.",
|
||
"import.register": "Registrar como modelo local",
|
||
"import.registered": "Registrado como «{id}». Ejecuta cortiq-server para servirlo.",
|
||
"import.jobs": "Descargas y conversiones",
|
||
"import.cancel": "Cancelar",
|
||
"import.cancelling": "Cancelando — limpiando el archivo incompleto…",
|
||
"import.delete": "Eliminar",
|
||
"import.deleteConfirm": "¿Eliminar este modelo y su archivo .cmf convertido del disco?",
|
||
"import.deleted": "Eliminado junto con sus archivos",
|
||
"import.state.running": "en curso",
|
||
"import.state.done": "listo",
|
||
"import.state.error": "error",
|
||
"import.state.cancelled": "cancelado",
|
||
"import.featuredTitle": "Modelos .cmf listos para usar",
|
||
"import.featuredSub": "Modelos .cmf ya convertidos de la cuenta infosave en HuggingFace — la lista se lee en vivo, los modelos nuevos aparecen solos.",
|
||
"import.readyCmfBadge": ".cmf listo",
|
||
"import.directDownload": "Descargar",
|
||
"import.q.q8_2f": "8 bits de dos campos (𝒲×θ) — recomendado: mejor relación calidad/tamaño.",
|
||
"import.q.q8_row": "8 bits por fila — simple y robusto.",
|
||
"import.q.q4": "4 bits por bloque — el más pequeño, menor calidad.",
|
||
"import.q.q4_tiled": "4 bits en mosaico (Q4_TILED) — 1,66× más rápido en GPU Metal.",
|
||
"import.q.vbit": "Variable 3–8 bits — presupuesto de bits por experto.",
|
||
"import.q.q1t": "Ternario de 1,58 bits (Q1T) — BitNet b1.58 con valores atípicos dispersos.",
|
||
"import.q.q1s": "1 bit disperso (Q1S) — base de 1 bit con valores atípicos holográficos.",
|
||
"import.q.q1p": "1 bit PTQ (Q1P) — 1 bit con difusión de error.",
|
||
"import.q.q1": "1 bit (Q1) — formato puramente binario.",
|
||
"import.q.f16": "16 bits — sin cuantización.",
|
||
"import.q.f32": "32 bits — precisión completa (archivo grande).",
|
||
"import.adv.title": "Ajustes avanzados",
|
||
"import.adv.auto": "auto",
|
||
"import.adv.linearCore": "Núcleo lineal",
|
||
"import.adv.linearHint": "Cómo se trasladan o pliegan las capas de atención lineal.",
|
||
"import.adv.nphase": "vmf_phase fases/cabeza",
|
||
"import.adv.vbitShape": "Forma del presupuesto VBIT",
|
||
"import.adv.meanBits": "Bits medios VBIT",
|
||
"import.adv.shard": "Tamaño máx. de shard (GB)",
|
||
"import.adv.noShard": "sin fragmentar",
|
||
"import.adv.skipMtp": "omitir la cabeza MTP",
|
||
"import.adv.o1": "Atención O(1)",
|
||
"import.adv.o1Hint": "Atención en streaming con memoria constante: la caché KV se libera tras el prefill, así que los contextos largos no hacen crecer la memoria. Los pesos quedan idénticos byte a byte — solo se guarda una indicación para el momento de carga; puedes volver atrás cuando quieras (servir con --o1 off). Validado en Qwen3-0.6B: todas las capas ≈ ×1,18 de perplejidad.",
|
||
"import.adv.o1Off": "desactivada — atención exacta (por defecto)",
|
||
"import.adv.o1All": "all — convertir todas las capas softmax",
|
||
"import.adv.o1Deep": "deep N — solo las N capas más profundas",
|
||
"import.adv.o1Custom": "personalizado — lista explícita de capas",
|
||
"import.adv.o1DeepN": "N capas profundas",
|
||
"import.adv.o1Layers": "Capas (separadas por comas)",
|
||
"import.adv.o1mHint": "presupuesto de landmarks (32 por defecto)",
|
||
"import.adv.o1windowHint": "ancho de la ventana exacta (128 por defecto)",
|
||
"import.adv.o1sinkHint": "claves sink exactas permanentes (4 por defecto)",
|
||
|
||
// onboarding
|
||
"onboarding.title": "Configuración inicial",
|
||
"onboarding.welcome": "Bienvenido a Cortiq Gateway",
|
||
"onboarding.welcomeSub": "Elige tu idioma — puedes cambiarlo cuando quieras en la cabecera.",
|
||
"onboarding.next": "Siguiente",
|
||
"onboarding.back": "Atrás",
|
||
"onboarding.skip": "Omitir por ahora",
|
||
"onboarding.skipSetup": "Omitir",
|
||
"onboarding.finish": "Finalizar configuración",
|
||
"onboarding.featuredTitle": "Modelos listos para usar (un clic)",
|
||
"onboarding.featuredSub": "Son modelos .cmf ya convertidos de infosave en HuggingFace — basta con descargarlos, sin conversión. Elige uno o varios para empezar al instante.",
|
||
"onboarding.download": "Descargar",
|
||
"onboarding.hfTitle": "Cualquier modelo de HuggingFace — conversión automática",
|
||
"onboarding.hfSub": "Busca cualquier modelo, elige una cuantización y lo convertimos a .cmf automáticamente. Sin editar la configuración a mano.",
|
||
"onboarding.noJobs": "Todavía no hay descargas.",
|
||
"onboarding.doneTitle": "Todo listo",
|
||
"onboarding.doneSub": "Los modelos descargados se registrarán automáticamente. Puedes añadir más en Importar o Modelos.",
|
||
"onboarding.doneHint": "«Finalizar configuración» conecta cada descarga completada como modelo local, arranca su servidor .cmf y apunta el enrutado hacia él. Todo esto se puede cambiar luego en Modelos.",
|
||
"onboarding.willRegister": "Se conectarán como modelos locales",
|
||
"onboarding.nothingToRegister": "Aún no hay descargas terminadas — no hay nada que conectar. Vuelve un paso atrás y elige un modelo.",
|
||
"onboarding.registeredN": "{n} modelo(s) conectado(s): {ids}",
|
||
"onboarding.runtimeMissing": "El runtime cortiq no está instalado — instálalo en Ajustes → Modelos locales para poder servirlos.",
|
||
"onboarding.downloaded": "descargado",
|
||
"onboarding.update": "Actualizar",
|
||
"onboarding.deleteFile": "Eliminar el archivo .cmf del disco",
|
||
"onboarding.confirmDelete": "¿Eliminar «{id}»? El archivo .cmf se borrará del disco.",
|
||
"onboarding.unregistered": "También se dio de baja: {ids}",
|
||
|
||
// playground: media generation + streaming metrics
|
||
"pg.tab.chat": "Chat",
|
||
"pg.tab.image": "Imagen",
|
||
"pg.tab.video": "Vídeo",
|
||
"pg.generate": "Generar",
|
||
"pg.generating": "Generando…",
|
||
"pg.genFailed": "La generación falló — revisa el registro.",
|
||
"pg.result": "Resultado",
|
||
"pg.genMetrics": "Métricas de generación",
|
||
"pg.imagePromptPlaceholder": "un zorro rojo en la nieve al atardecer, fotorrealista, pelaje detallado",
|
||
"pg.videoPromptPlaceholder": "un corgi con gorro de chef voltea una tortita, chisporroteo y un ladrido alegre",
|
||
"pg.imageEmpty": "La imagen generada aparecerá aquí.",
|
||
"pg.videoEmpty": "El clip generado (con audio) aparecerá aquí.",
|
||
"pg.width": "Ancho",
|
||
"pg.height": "Alto",
|
||
"pg.steps": "Pasos",
|
||
"pg.seed": "Seed",
|
||
"pg.randomSeed": "Seed aleatorio",
|
||
"pg.cfgHint": "Escala de guidance; ≤ 1 desactiva el CFG y reduce el trabajo a la mitad.",
|
||
"pg.frames": "Fotogramas",
|
||
"pg.framesHint": "A 24 fps; se ajusta a la rejilla del modelo.",
|
||
"pg.quality": "Calidad JPEG",
|
||
"pg.videoSizeHint": "Múltiplos de 32; el lado corto entrenado es 768.",
|
||
"pg.videoStepsHint": "La LoRA Turbo está entrenada para 4 pasos.",
|
||
"pg.firstFrame": "Primer fotograma (opcional)",
|
||
"pg.lastFrame": "Último fotograma (opcional)",
|
||
"pg.keyframeHint": "Convierte la ejecución en keyframe-to-video.",
|
||
"pg.resolution": "Resolución",
|
||
"pg.genTime": "Tiempo de generación",
|
||
"pg.timePerStep": "Por paso",
|
||
"pg.timePerFrame": "Por fotograma",
|
||
"pg.fileSize": "Tamaño del archivo",
|
||
"pg.duration": "Duración",
|
||
"pg.play": "Reproducir",
|
||
"pg.noMediaModels": "Aún no hay un modelo {kind} local. Descarga uno (p. ej. de la colección infosave) en Importar:",
|
||
"pg.tokSpeed": "Velocidad",
|
||
"pg.ttft": "Primer token",
|
||
|
||
// ops: logs, system, notices, gallery, chat, snippets, bench
|
||
"nav.logs": "Registros",
|
||
"logs.subtitle": "Registro reciente de la pasarela — lo que mostraría la terminal.",
|
||
"logs.filterPlaceholder": "filtrar…",
|
||
"logs.pause": "Pausa",
|
||
"logs.resume": "Reanudar",
|
||
"logs.empty": "Nada coincide.",
|
||
"notice.openAdmin": "La consola está abierta sin token y accesible desde otras máquinas. Configura un token si esta máquina no es privada.",
|
||
"notice.update": "Actualización disponible: v{v}.",
|
||
"dash.sys.title": "Sistema",
|
||
"dash.sys.cores": "núcleos",
|
||
"dash.sys.disk": "Disco (modelos)",
|
||
"dash.sys.free": "libre",
|
||
"dash.sys.gateway": "pasarela",
|
||
"fit.disk": "no hay espacio suficiente",
|
||
"fit.diskTitle": "La descarga supera el espacio libre del disco de modelos.",
|
||
"fit.ram": "puede no caber en RAM",
|
||
"fit.ramTitle": "El modelo se acerca o supera la RAM de esta máquina — puede que no funcione.",
|
||
"pg.eta": "restante",
|
||
"pg.min": "min",
|
||
"pg.queued": "En cola — posición {n}. Arranca en cuanto termine la generación actual.",
|
||
"pg.gallery": "Generaciones recientes",
|
||
"pg.galDeleteConfirm": "¿Eliminar esta generación y sus archivos?",
|
||
"pg.clearChat": "Limpiar",
|
||
"keys.snip.title": "Conecta tu aplicación",
|
||
"keys.snip.hint": "Pega uno de estos ejemplos en tu proyecto — solo hay que sustituir el marcador de la clave.",
|
||
"keys.snip.withKey": "Los ejemplos de abajo ya incluyen la clave que acabas de crear.",
|
||
"keys.snip.openMode": "No hay claves API configuradas — la pasarela acepta cualquier valor.",
|
||
"keys.snip.keyPh": "tu clave API",
|
||
"settings.restart": "Reiniciar todo",
|
||
"settings.restartConfirm": "¿Reiniciar la pasarela y todos los servidores de modelos locales? Las solicitudes en curso se interrumpirán.",
|
||
"settings.restarting": "Reiniciando — la página se recargará cuando la pasarela vuelva…",
|
||
"settings.shutdown": "Detener todo y apagar",
|
||
"settings.shutdownConfirm": "¿Detener todos los servidores de modelos locales y apagar la pasarela? La API y este panel dejarán de responder hasta que vuelva a iniciar la pasarela.",
|
||
"settings.shutdownDone": "La pasarela está apagada.",
|
||
"settings.shutdownHint": "Todos los servidores de modelos locales están detenidos y el proceso ha terminado. Inicie de nuevo la pasarela en el servidor para recuperar el panel.",
|
||
"bench.title": "Velocidad de modelos locales",
|
||
"bench.hint": "Ejecuta `cortiq bench` en esta máquina — tok/s reales, un modelo a la vez.",
|
||
"bench.run": "Medir",
|
||
"bench.running": "midiendo…",
|
||
"bench.failed": "falló",
|
||
"bench.none": "Aún no hay modelos de chat .cmf locales.",
|
||
|
||
// task-based routing
|
||
"task.chitchat": "Charla",
|
||
"task.code": "Código",
|
||
"task.creative-writing": "Escritura creativa",
|
||
"task.extraction": "Extracción de datos",
|
||
"task.math": "Matemáticas",
|
||
"task.qa": "Preguntas y respuestas",
|
||
"task.summarization": "Resumen",
|
||
"task.translation": "Traducción",
|
||
"routing.tasks.title": "Enrutado por tarea",
|
||
"routing.tasks.hint": "Los modelos de una regla van primero para su tarea; la cadena por complejidad sigue como respaldo. Vacío = solo por complejidad.",
|
||
"routing.tasks.inherit": "por complejidad (sin regla)",
|
||
"routing.tasks.share": "{p}% de las peticiones (7 d)",
|
||
"routing.tasks.fromRouter": "etiquetas en vivo del router",
|
||
"routing.tasks.builtin": "router inaccesible — conjunto integrado",
|
||
"routing.tasks.addCustom": "Añadir tarea",
|
||
"routing.tasks.addPlaceholder": "etiqueta propia…",
|
||
|
||
// benchmark view
|
||
"nav.benchmark": "Benchmark",
|
||
"bm.title": "Benchmark",
|
||
"bm.subtitle": "Pruebas de calidad y velocidad a través del pipeline en vivo: respuestas verificadas por palabras clave, detección de bucles, tok/s y tiempo del primer token por modelo.",
|
||
"bm.models": "Modelos a probar",
|
||
"bm.quickMode": "Prueba rápida",
|
||
"bm.quickHint": "El subconjunto rápido con respuestas cortas — alrededor de un minuto por modelo local.",
|
||
"bm.suiteInfo": "Suite integrada: {q} pruebas rápidas / {f} completas, más las tuyas.",
|
||
"bm.run": "Ejecutar",
|
||
"bm.pickModel": "Elige al menos un modelo.",
|
||
"bm.testOf": "prueba {i} de {n}",
|
||
"bm.results": "Resultados",
|
||
"bm.quick": "rápida",
|
||
"bm.test": "Prueba",
|
||
"bm.cellHint": "Haz clic en una celda para ver la respuesta completa.",
|
||
"bm.history": "Ejecuciones anteriores (guardadas en este navegador)",
|
||
"bm.custom": "Pruebas propias",
|
||
"bm.customHint": "Prompt + palabras clave separadas por comas que la respuesta debe contener (| para sinónimos). Se guardan en este navegador.",
|
||
"bm.promptPh": "prompt…",
|
||
"bm.checkPh": "palabras clave, separadas por comas",
|
||
"bm.addTest": "Añadir prueba",
|
||
"bm.emptyAnswer": "respuesta vacía",
|
||
"bm.loopDetected": "bucle detectado",
|
||
|
||
// benchmark: routing mode, cost, live
|
||
"bm.mode.routing": "Enrutado inteligente",
|
||
"bm.mode.models": "Modelos individuales",
|
||
"bm.mode.routingDesc": "La función clave del producto a prueba: cada sonda pasa por cortiq-auto — ves qué tarea detectó el router, qué modelo eligió, si coincide con lo esperado y cuánto costó.",
|
||
"bm.mode.modelsDesc": "La misma suite fijada a los modelos elegidos — compara su calidad, velocidad y coste directamente, sin pasar por el router.",
|
||
"bm.answersOk": "respuestas correctas",
|
||
"bm.classAcc": "clasificación de tareas",
|
||
"bm.modelDist": "Las peticiones fueron a",
|
||
"bm.expectedLbl": "esperado:",
|
||
"bm.answer": "Respuesta",
|
||
"bm.liveRunning": "en curso…",
|
||
"bm.spent": "gastado",
|
||
"bm.verdict": "🏁 Listo: respuestas {p}, gastado {s}",
|
||
"bm.clearHistory": "Borrar todo",
|
||
|
||
// harness auto-setup (API keys view)
|
||
"keys.h.claude": "Claude Code — pega en la terminal (la pasarela habla el protocolo Anthropic de forma nativa):",
|
||
"keys.h.codex": "Codex — añade el proveedor a ~/.codex/config.toml y arranca:",
|
||
"keys.h.opencode": "OpenCode — escribe ~/.config/opencode/opencode.json (¡sobrescribe!) y arranca:",
|
||
"keys.h.continue": "Continue (VS Code / JetBrains) — añade el modelo a ~/.continue/config.yaml:",
|
||
"keys.h.cline1": "Cline (VS Code) — en los ajustes de la extensión elige:",
|
||
"keys.h.cline2": "Ajustes → API Provider → OpenAI Compatible, luego pega los valores de arriba.",
|
||
"keys.h.note": "cortiq-auto = enrutado inteligente: el router elige el modelo en cada petición. Para fijar uno, indica su nombre exacto. En Windows ejecuta los scripts en Git Bash / WSL o define las mismas variables en el entorno del sistema.",
|
||
"keys.h.protoOff": "El protocolo Anthropic (/v1/messages) está desactivado — Claude Code no podrá conectarse.",
|
||
"keys.h.enableProto": "Activar",
|
||
"keys.h.st.installed": "Instalado en la máquina de la pasarela",
|
||
"keys.h.st.configured": "Ya configurado para esta pasarela",
|
||
"keys.h.st.notFound": "No encontrado en la máquina de la pasarela",
|
||
"bm.degraded": "router degradado",
|
||
"bm.routerDegraded": "El router no respondió a tiempo — la petición usó la cadena de reserva; la clasificación no se cuenta.",
|
||
"bm.cutByCap": "presupuesto gastado en razonar — sin respuesta final",
|
||
"shell.uiStale": "La pasarela se actualizó — esta página usa una interfaz antigua.",
|
||
"shell.reload": "Recargar",
|
||
"keys.col.requests": "Peticiones",
|
||
"keys.col.tokens": "Tokens ent/sal",
|
||
"keys.col.costAll": "$ total",
|
||
"routing.tasks.tier": "Complejidad",
|
||
"routing.tasks.tierAuto": "Auto (router)",
|
||
"routing.tasks.tierHint": "Qué modelo atiende esta tarea en qué complejidad; «cualquiera» lidera en todos los niveles. El orden = orden de respaldo. Un veredicto high sigue escalando sobre las entradas «cualquiera».",
|
||
"routing.tasks.tierAny": "cualquier complejidad",
|
||
"routing.tasks.addModel": "modelo",
|
||
"routing.bands.enable": "Mis límites de complejidad",
|
||
"routing.bands.hint": "Arrastra los tiradores: dónde termina low y dónde empieza high — se empujan entre sí y las cifras se actualizan en vivo. La puntuación continua del router se re-mapea con TUS límites; sin marcar = las bandas del propio router.",
|
||
"tier.low": "fácil",
|
||
"tier.medium": "medio",
|
||
"tier.high": "difícil",
|
||
"bm.scoreHint": "La puntuación continua de complejidad del router (0..1) — los deslizadores de límites de la página Enrutado la dividen en niveles.",
|
||
"settings.cache.noEmbed": "La caché está activada pero NO tiene modelo de embeddings — no hace nada. Añade al pool un modelo con kind = \"embedding\" (p. ej. OpenAI text-embedding) o elige uno abajo.",
|
||
"settings.cache.entries": "entradas",
|
||
"settings.cache.hits": "aciertos",
|
||
"settings.cache.saved": "ahorrado",
|
||
"keys.form.budget": "Presupuesto mensual, $ (0 = sin límite)",
|
||
"keys.form.budgetHint": "Cuando el gasto del mes supera el techo, las peticiones se rechazan con 429 insufficient_quota.",
|
||
"keys.budgetOf": "presupuesto {b}/mes",
|
||
"dash.kpi.orBalance": "Saldo OpenRouter",
|
||
"keys.h.install": "Instalar:",
|
||
"keys.snip.keyInputPh": "pega tu clave API",
|
||
"keys.snip.apply": "Insertar clave",
|
||
};
|