export default { // Login login: { title: 'Hermes Web UI', description: 'Introduce tu token de acceso para continuar. Encuentralo en los registros de inicio del servidor.', placeholder: 'Token de acceso', submit: 'Iniciar sesion', tokenRequired: 'Por favor, introduce tu token de acceso', invalidToken: 'Token invalido', connectionFailed: 'No se puede conectar al servidor', passwordLogin: 'Contrasena', tokenLogin: 'Token', usernamePlaceholder: 'Nombre de usuario', passwordPlaceholder: 'Contrasena', credentialsRequired: 'Por favor, introduzca nombre de usuario y contrasena', invalidCredentials: 'Nombre de usuario o contrasena incorrectos', passwordMismatch: 'Las contrasenas no coinciden', passwordTooShort: 'La contrasena debe tener al menos 6 caracteres', setupSuccess: 'Login con contrasena configurado correctamente', passwordChanged: 'Contrasena cambiada correctamente', passwordRemoved: 'Login con contrasena eliminado', setupPassword: 'Configurar login con contrasena', changePassword: 'Cambiar contrasena', changeUsername: 'Cambiar nombre de usuario', removePasswordLogin: 'Eliminar', username: 'Nombre de usuario', currentPassword: 'Contrasena actual', newPassword: 'Nueva contrasena', confirmPassword: 'Confirmar contrasena', newUsername: 'Nuevo nombre de usuario', usernameChanged: 'Nombre de usuario cambiado correctamente', usernameTooShort: 'El nombre de usuario debe tener al menos 2 caracteres', setupDescription: 'Configure un nombre de usuario y contrasena para un inicio de sesion rapido. El token de acceso seguira funcionando.', removeConfirm: 'Esta seguro de eliminar el login con contrasena? Necesitara usar el token de acceso.', passwordLoginNotConfigured: 'Login con contrasena no configurado', passwordLoginConfigured: 'Login con contrasena habilitado ({username})', }, // Common common: { loading: 'Cargando...', cancel: 'Cancelar', retry: 'Reintentar', delete: 'Eliminar', edit: 'Editar', save: 'Guardar', saved: 'Guardado', update: 'Actualizar', create: 'Crear', saveFailed: 'Error al guardar', deleteFailed: 'Error al eliminar', ok: 'OK', copied: 'Copiado', copy: 'Copiar', noData: 'Sin datos', fetch: 'Obtener', add: 'Anadir', enable: 'Activar', disable: 'Desactivar', configured: 'Configurado', notConfigured: 'No configurado', confirm: 'Confirmar', expand: 'Expandir', collapse: 'Contraer', }, // Sidebar sidebar: { chat: 'Chat', search: 'Buscar', history: 'Historial', jobs: 'Tareas programadas', models: 'Modelos', profiles: 'Perfiles', skills: 'Habilidades', memory: 'Memoria', logs: 'Registros', usage: 'Uso', channels: 'Canales', terminal: 'Terminal', files: 'Archivos', groupChat: 'Chat grupal', groupConversation: 'Conversación', settings: 'Configuracion', connected: 'Conectado', disconnected: 'Desconectado', updateTip: 'Ejecuta "hermes-web-ui update" en la terminal para actualizar', updateVersion: 'Actualizar a v{version}', updating: 'Actualizando...', updateSuccess: 'Actualizacion completa, por favor reinicia el servidor', updateFailed: 'Error al actualizar', logout: 'Cerrar sesion', nodeVersionWarning: 'Se detecto Node.js v{version}. Actualiza a la version 23 o posterior.', changelog: 'Registro de cambios', noChangelog: 'No hay registro de cambios', }, // Drawer drawer: { terminal: 'Terminal', files: 'Espacio de trabajo', }, // Chat chat: { contextRemaining: 'restante', emptyState: 'Inicia una conversacion con Hermes Agent', inputPlaceholder: 'Escribe un mensaje... (Enter para enviar, Shift+Enter para nueva linea)', attachFiles: 'Adjuntar archivos', stop: 'Detener', send: 'Enviar', contextUsed: 'Contexto utilizado:', sessions: 'Sesiones', webUiSessions: 'Sesiones de Web UI/API Server', sessionScopeHint: 'Chat solo muestra sesiones de Web UI/API Server. Las sesiones de CLI, Telegram, Discord, Cron y otros canales son de solo lectura en Historial.', openHistory: 'Abrir historial', hermesHistory: 'Historial de Hermes', historyScopeHint: 'Sesiones del historial de Hermes, de solo lectura y agrupadas por origen.', noSessions: 'Sin sesiones', newChat: 'Nuevo chat', deleteSession: 'Eliminar esta sesion?', sessionDeleted: 'Sesion eliminada', rename: 'Renombrar', pin: 'Fijar', unpin: 'Desfijar', pinned: 'Fijados', chatMode: 'Chat', liveMode: 'En vivo', liveSessions: 'Sesiones en vivo', recentBadge: 'Reciente', linkedSessions: '{count} vinculadas', noVisibleMessages: 'No hay mensajes visibles para humanos.', monitorRoleUser: 'Usuario', monitorRoleAssistant: 'Asistente', copySessionId: 'Copiar ID de sesión', renamed: 'Renombrada', renameFailed: 'Error al renombrar', renameSession: 'Renombrar sesion', sessionNotFound: 'Sesion no encontrada', enterNewTitle: 'Introduce un nuevo titulo', other: 'Otro', runFailed: 'Error en la ejecucion', error: 'Error', tool: 'Herramienta', arguments: 'Argumentos', result: 'Resultado', truncated: '... (truncado)', executionDuration: 'Execution time', thinkingLabel: 'Pensamiento', thinkingInProgress: 'Pensando…', thinkingShow: 'Mostrar pensamiento', thinkingHide: 'Ocultar pensamiento', thinkingDuration: 'Observado {duration}', thinkingChars: '{count} caracteres', copyBubble: 'Copiar mensaje', copiedBubble: 'Mensaje copiado', copyFailed: 'Error al copiar', playSpeech: 'Reproducir voz', pauseSpeech: 'Pausa', resumeSpeech: 'Reanudar', stopSpeech: 'Detener', speechNotSupported: 'Reproducción de voz no soportada en este navegador', }, // Jobs jobs: { title: 'Tareas programadas', createJob: 'Crear tarea', editJob: 'Editar tarea', noJobs: 'No hay tareas programadas aun. Crea una para comenzar.', name: 'Nombre', namePlaceholder: 'Nombre de la tarea', schedule: 'Programacion (expresion Cron)', schedulePlaceholder: 'ej. 0 9 * * *', quickPresets: 'Presets rapidos', selectPreset: 'Seleccionar un preset...', presetEveryMinute: 'Cada minuto', presetEvery5Min: 'Cada 5 minutos', presetEveryHour: 'Cada hora', presetEveryDay: 'Todos los dias a las 00:00', presetEveryDay9: 'Todos los dias a las 09:00', presetEveryMonday: 'Cada lunes a las 09:00', presetEveryMonth: 'El dia 1 de cada mes a las 09:00', prompt: 'Prompt', promptPlaceholder: 'El prompt a ejecutar', deliverTarget: 'Destino de entrega', origin: 'Origen', local: 'Local', repeatCount: 'Repeticiones (opcional)', modelPlaceholder: 'Modelo por defecto', repeatPlaceholder: 'Dejar vacio para infinito', jobCreated: 'Tarea creada', jobUpdated: 'Tarea actualizada', nameRequired: 'El nombre es obligatorio', scheduleRequired: 'La programacion es obligatoria', loadFailed: 'Error al cargar la tarea', jobPaused: 'Tarea en pausa', jobResumed: 'Tarea reanudada', jobTriggered: 'Job ejecutado', modelUpdated: 'Modelo actualizado', jobDeleted: 'Tarea eliminada', status: { running: 'En ejecucion', paused: 'En pausa', disabled: 'Desactivada', scheduled: 'Programada', }, info: { model: 'Modelo', schedule: 'Programacion', lastRun: 'Ultima ejecucion', nextRun: 'Proxima ejecucion', deliver: 'Entrega', repeat: 'Repeticion', }, action: { pause: 'Pausar', pauseJob: 'Pausar tarea', resume: 'Reanudar', resumeJob: 'Reanudar tarea', runNow: 'Ejecutar ahora', triggerImmediately: 'Ejecutar inmediatamente', }, runHistory: { title: 'Historial', runs: 'ejecuciones', noRuns: 'No se encontró historial.', }, }, // Skills skills: { title: 'Habilidades', searchPlaceholder: 'Buscar habilidades...', noMatch: 'Ninguna habilidad coincide con tu busqueda', noSkills: 'No se encontraron habilidades', backTo: 'Volver a', attachedFiles: 'Archivos adjuntos', loadFailed: 'Error al cargar la habilidad', fileLoadFailed: 'Error al cargar el archivo', modified: 'Modificado por el usuario', archived: 'Archivado', pinned: 'Fijado', pin: 'Fijar habilidad', unpin: 'Desfijar habilidad', pinFailed: 'Error al cambiar estado de fijacion', toggleFailed: 'Error al activar/desactivar la habilidad', source: { builtin: 'Integrado', hub: 'Hub', local: 'Local', }, }, // Memory memory: { title: 'Memoria', refresh: 'Actualizar', loadFailed: 'Error al cargar la memoria', myNotes: 'Mis notas', noNotes: 'Sin notas aun.', notesPlaceholder: 'Escribe tus notas...', userProfile: 'Perfil de usuario', noProfile: 'Sin perfil aun.', profilePlaceholder: 'Escribe tu perfil...', soul: 'Alma', noSoul: 'Sin configuracion de alma aun.', soulPlaceholder: 'Escribe la configuracion del alma...', }, // Models models: { title: 'Modelos', addProvider: 'Anadir proveedor', providerType: 'Tipo de proveedor', preset: 'Preset', custom: 'Personalizado', selectProvider: 'Seleccionar proveedor', chooseProvider: 'Elige un proveedor...', name: 'Nombre', autoGeneratedName: 'Generado automaticamente desde la URL base', baseUrl: 'URL base', region: 'Región', regionIntl: 'Internacional', regionCn: 'China continental', baseUrlPlaceholder: 'ej. https://api.example.com/v1', apiKey: 'Clave API', apiKeyPlaceholder: 'sk-...', defaultModel: 'Modelo predeterminado', selectOrInput: 'Seleccionar o ingresar un modelo...', selectModel: 'Seleccionar un modelo...', providerAdded: 'Proveedor anadido', providerDeleted: 'Proveedor eliminado', deleteProvider: 'Eliminar proveedor', deleteConfirm: 'Estas seguro de que quieres eliminar "{name}"?', codexLoginTitle: 'Inicio de sesión de OpenAI Codex', codexWaiting: 'Ingrese este código en la página de autorización para iniciar sesión:', codexCopyCode: 'Código copiado', codexOpenLink: 'Abrir página de autorización', codexApproved: 'Inicio de sesión exitoso', codexExpired: 'La autorización ha expirado. Por favor, inténtelo de nuevo.', nousLoginTitle: 'Inicio de sesión de Nous Portal', nousWaiting: 'Ingrese este código en la página de autorización:', nousCopyCode: 'Código copiado', nousOpenLink: 'Abrir página de autorización', nousApproved: 'Inicio de sesión exitoso', nousDenied: 'Autorización denegada', nousExpired: 'Autorización expirada', copilotLoginTitle: 'Inicio de sesión de GitHub Copilot', copilotWaiting: 'Abra GitHub e introduzca el código de dispositivo a continuación para autorizar. La ventana se cerrará automáticamente tras la aprobación.', copilotCopyCode: 'Código copiado', copilotOpenLink: 'Abrir la página de autorización de GitHub', copilotApproved: '¡Inicio de sesión exitoso!', copilotDenied: 'Autorización denegada.', copilotExpired: 'El enlace de autorización ha caducado. Vuelva a intentarlo.', copilotAddDetectedTitle: 'GitHub Copilot detectado', copilotAddDetected: 'Se detectó un token OAuth de GitHub Copilot en este equipo. Haz clic en Agregar para habilitar Copilot en Hermes.', copilotAddSourceEnv: 'Origen: ~/.hermes/.env (COPILOT_GITHUB_TOKEN)', copilotAddSourceGhCli: 'Origen: gh CLI (gh auth token)', copilotAddSourceAppsJson: 'Origen: extensión Copilot de VS Code (apps.json)', copilotDeleteHintEnv: 'Esto borrará COPILOT_GITHUB_TOKEN en ~/.hermes/.env. Otras herramientas no se verán afectadas.', copilotDeleteHintGhCli: 'Copilot se ocultará de Hermes. Tu sesión de gh CLI no se verá afectada — `gh auth status` seguirá mostrando que estás conectado.', copilotDeleteHintAppsJson: 'Copilot se ocultará de Hermes. La extensión Copilot de VS Code seguirá conectada.', customBadge: 'PERSONALIZADO', previewBadge: 'VISTA PREVIA', disabledBadge: 'NO DISPONIBLE', disabledTooltip: "Este modelo no está disponible para tu cuenta.", customModelPlaceholder: 'Nombre del modelo personalizado', customModelHint: 'Enter para cargar', noProviders: 'No se encontraron proveedores. Anade un proveedor personalizado para comenzar.', builtIn: 'Integrado', customType: 'Personalizado', provider: 'Proveedor', contextLength: 'Longitud del contexto', contextLengthPlaceholder: 'ej. 200000 (opcional)', local: 'Local ({host})', selectProviderRequired: 'Por favor, selecciona un proveedor', baseUrlRequired: 'La URL base es obligatoria', apiKeyRequired: 'La clave API es obligatoria', modelRequired: 'El modelo predeterminado es obligatorio', enterBaseUrl: 'Por favor, introduce primero la URL base', unexpectedFormat: 'Formato de respuesta inesperado', foundModels: '{count} modelos encontrados', fetchFailed: 'Error al obtener los modelos', }, // Profiles profiles: { title: 'Perfiles', create: 'Crear perfil', import: 'Importar', export: 'Exportar', rename: 'Renombrar', delete: 'Eliminar', switchTo: 'Cambiar a', switchConfirm: 'Cambiar al perfil "{name}" reiniciara la pasarela. Continuar?', switchSuccess: 'Se ha cambiado al perfil "{name}"', switchFailed: 'Error al cambiar de perfil. Es posible que la pasarela necesite un reinicio manual.', createSuccess: 'Perfil "{name}" creado', createFailed: 'Error al crear el perfil', renameSuccess: 'Perfil renombrado', renameFailed: 'Error al renombrar el perfil', deleteConfirm: 'Estas seguro de que quieres eliminar el perfil "{name}"?', deleteSuccess: 'Perfil eliminado', deleteFailed: 'Error al eliminar el perfil', exportSuccess: 'Perfil exportado', exportFailed: 'Error al exportar el perfil', importSuccess: 'Perfil importado', importFailed: 'Error al importar el perfil', importSelectFile: 'Seleccionar archivo de archivo', importInvalidFile: 'Por favor, selecciona un archivo valido (.tar.gz, .tgz, .gz, .zip)', name: 'Nombre del perfil', namePlaceholder: 'Solo letras, numeros y guiones', nameValidation: 'El nombre del perfil solo puede contener letras minúsculas, números, guiones bajos y guiones', newName: 'Nuevo nombre', newNamePlaceholder: 'Introduce un nuevo nombre', cloneFromCurrent: 'Clonar desde el perfil actual', cloneCleanupNotice: 'Al clonar se omiten automáticamente las credenciales exclusivas de plataforma (Weixin / Telegram / Slack, etc.) para evitar conflictos con el perfil de origen', cloneStrippedCredentials: 'Se eliminaron {count} credenciales exclusivas: {list}', cloneDisabledPlatforms: 'Se deshabilitaron {count} plataforma(s): {list}', cloneStrippedConfigCredentials: 'Se eliminaron {count} credencial(es) integradas de config.yaml: {list}', archivePath: 'Ruta del archivo', archivePathPlaceholder: 'Ruta del servidor al archivo de archivo', importName: 'Nombre del perfil (opcional)', importNamePlaceholder: 'Dejar vacio para usar el nombre del archivo', active: 'Activo', model: 'Modelo', gateway: 'Pasarela', alias: 'Alias', provider: 'Proveedor', path: 'Ruta', skills: 'Habilidades', hasEnv: 'Tiene .env', hasSoulMd: 'Tiene soul.md', noProfiles: 'No se encontraron perfiles. Crea uno para comenzar.', }, // Logs logs: { title: 'Registros', all: 'Todos', searchPlaceholder: 'Buscar...', refresh: 'Actualizar', noEntries: 'Sin entradas de registro', }, // Settings settings: { title: 'Configuracion', saved: 'Guardado', saveFailed: 'Error al guardar', tabs: { display: 'Pantalla', account: 'Cuenta', agent: 'Agente', memory: 'Memoria', session: 'Sesion', privacy: 'Privacidad', apiServer: 'Servidor API', }, display: { streaming: 'Respuestas en streaming', streamingHint: 'Mostrar respuestas de la IA en tiempo real', compact: 'Modo compacto', compactHint: 'Reducir el espaciado entre mensajes', showReasoning: 'Mostrar razonamiento', showReasoningHint: 'Mostrar el proceso de pensamiento del modelo', showCost: 'Mostrar costo', showCostHint: 'Mostrar uso de tokens en las respuestas', inlineDiffs: 'Diffs en linea', inlineDiffsHint: 'Mostrar cambios de codigo en linea', bellOnComplete: 'Sonido de finalizacion', bellOnCompleteHint: 'Reproducir un sonido cuando la IA termina', busyInputMode: 'Modo de entrada ocupada', busyInputModeHint: 'Permitir entrada mientras la IA procesa', theme: 'Tema', themeHint: 'Elige claro, oscuro o seguir la preferencia del sistema', themeLight: 'Claro', themeDark: 'Oscuro', themeSystem: 'Sistema', }, agent: { maxTurns: 'Turnos maximos', maxTurnsHint: 'Rondas maximas de interaccion por conversacion', gatewayTimeout: 'Tiempo de espera de la pasarela', gatewayTimeoutHint: 'Tiempo de espera de la peticion en segundos', restartDrainTimeout: 'Tiempo de drenado al reiniciar', restartDrainTimeoutHint: 'Tiempo de drenado antes de reiniciar en segundos', toolEnforcement: 'Aplicacion de herramientas', toolEnforcementHint: 'Controlar el modo de ejecucion de llamadas a herramientas', auto: 'Automatico', always: 'Siempre', never: 'Nunca', }, memory: { enabled: 'Activar memoria', enabledHint: 'Permitir que la IA recuerde el contexto de la conversacion', userProfile: 'Perfil de usuario', userProfileHint: 'Permitir que la IA recuerde las preferencias del usuario', charLimit: 'Limite de caracteres de memoria', charLimitHint: 'Maximo de caracteres para MEMORY.md', userCharLimit: 'Limite de caracteres del perfil de usuario', userCharLimitHint: 'Maximo de caracteres para USER.md', }, session: { mode: 'Modo de reinicio', modeHint: 'Condicion de activacion del reinicio de sesion', modeBoth: 'Inactividad + Programado', modeIdle: 'Solo inactividad', modeHourly: 'Solo programado', idleMinutes: 'Tiempo de inactividad', idleMinutesHint: 'Tiempo de espera antes del reinicio automatico (minutos)', atHour: 'Hora de reinicio programado', humanOnly: 'Mostrar solo sesiones humanas', humanOnlyHint: 'Oculta por defecto el ruido de subagentes y del monitor de sesiones', liveMonitorHumanOnly: 'Monitor en vivo: mostrar solo sesiones humanas', liveMonitorHumanOnlyHint: 'Oculta por defecto el ruido de subagentes y del monitor de sesiones en el monitor en vivo', atHourHint: 'Reiniciar sesion a esta hora todos los dias', }, privacy: { redactPii: 'Ocultar informacion personal', redactPiiHint: 'Detectar y ocultar automaticamente informacion sensible (contrasenas, claves, etc.)', }, apiServer: { enable: 'Activar', enableHint: 'Activar servidor API', host: 'Host', hostHint: 'Direccion de escucha', port: 'Puerto', portHint: 'Puerto de escucha', key: 'Clave', keyHint: 'Clave de acceso API', cors: 'Origenes CORS', corsHint: 'Fuentes cross-origin permitidas', }, }, // Platform channel settings platform: { requireMention: "Requerir mencion {'@'}", requireMentionGroup: "Requerir mencion {'@'} en grupos para responder", requireMentionChannel: "Requerir mencion {'@'} en canales para responder", requireMentionRoom: "Requerir mencion {'@'} en salas para responder", reactions: 'Reacciones', reactionsHint: 'Reaccionar a mensajes con emoji', freeResponseChats: 'Chats de respuesta libre', freeResponseChatsHint: "IDs de chats que responden sin mencion {'@'} (separados por comas)", freeResponseChannels: 'Canales de respuesta libre', freeResponseChannelsHint: "IDs de canales que responden sin mencion {'@'} (separados por comas)", freeResponseRooms: 'Salas de respuesta libre', freeResponseRoomsHint: "IDs de salas que responden sin mencion {'@'} (separados por comas)", mentionPatterns: 'Patrones de mencion personalizados', mentionPatternsHint: 'Patrones de activacion adicionales', autoThread: 'Hilo automatico', autoThreadHint: "Crear automaticamente hilos de respuesta despues de mencion {'@'}", autoThreadHintRoom: 'Crear automaticamente hilos de respuesta en salas', dmMentionThreads: 'Hilos de mencion en MD', dmMentionThreadsHint: 'Usar hilos de respuesta para menciones en mensajes directos', allowBots: 'Permitir mensajes de bots', allowBotsHint: 'Responder a mensajes de otros bots', allowedChannels: 'Canales permitidos', allowedChannelsHint: 'Lista blanca de IDs de canales (separados por comas)', ignoredChannels: 'Canales ignorados', ignoredChannelsHint: 'Canales donde el bot nunca responde (separados por comas)', noThreadChannels: 'Canales sin hilo', noThreadChannelsHint: 'Canales donde el bot responde sin hilos (separados por comas)', exclusiveTokenWarning: 'Esta plataforma usa bloqueo exclusivo de token. Cada perfil debe usar un token de identidad distinto para evitar conflictos con otros perfiles.', botToken: 'Token del bot', botTokenHint: 'Token del bot del portal de desarrolladores', accessToken: 'Token de acceso', accessTokenHint: 'Token de acceso de Matrix', homeserver: 'URL del homeserver', homeserverHint: 'URL del homeserver de Matrix', appId: 'ID de aplicacion', appIdHint: 'ID de aplicacion de Feishu', appSecret: 'Secreto de aplicacion', appSecretHint: 'Secreto de aplicacion de Feishu', clientId: 'ID de cliente', clientIdHint: 'ID de cliente de DingTalk', clientSecret: 'Secreto de cliente', clientSecretHint: 'Secreto de cliente de DingTalk', botId: 'ID del bot', botIdHint: 'ID del bot de WeCom', wecomSecretHint: 'Secreto del bot de WeCom', waEnabled: 'Activar WhatsApp', waEnabledHint: 'Activar WhatsApp mediante emparejamiento por codigo QR', weixinToken: 'Token de Weixin', weixinTokenHint: 'Desde el inicio de sesion QR de la CLI de weixin (hermes weixin)', accountId: 'ID de cuenta', accountIdHint: 'ID de cuenta de Weixin', qrLogin: 'Inicio de sesion QR', qrRelogin: 'Volver a iniciar sesion', qrFetching: 'Obteniendo codigo QR...', qrScanHint: 'Escanea con WeChat para iniciar sesion', qrScanedHint: 'Escaneado, por favor confirma en el telefono...', }, // Language language: { label: 'Idioma', zh: '中文', en: 'English', es: 'Espanol', }, // Terminal terminal: { sessions: 'Sesiones', newTab: 'Nueva terminal', closeSession: 'Cerrar esta sesion?', sessionExited: 'Finalizada', processExited: 'Proceso finalizado con codigo {code}', }, // Usage usage: { title: 'Estadisticas de uso', refresh: 'Actualizar', totalTokens: 'Total de tokens', inputTokens: 'Entrada', outputTokens: 'Salida', totalSessions: 'Total de sesiones', avgPerDay: '~{n}/dia de promedio', estimatedCost: 'Costo est.', cacheHitRate: 'Tasa de acierto de cache', modelBreakdown: 'Desglose por modelo', dailyTrend: 'Uso diario (ultimos 30 dias)', date: 'Fecha', tokens: 'Tokens', cache: 'Caché', cacheRead: 'Cache Read', cacheWrite: 'Cache Write', sessions: 'Sesiones', cost: 'Costo', noData: 'Sin datos de uso', }, // Registro de cambios changelog: { new_0_5_6_1: 'Reproducción de voz con Web Speech API: botón manual, interruptor auto-play, animación de borde arcoíris y optimización móvil', new_0_5_6_2: 'Parser LLM JSON robusto con tolerancia a formato Python y extracción de texto de eventos streaming', new_0_5_6_3: 'Mejoras de Skills: estadísticas de uso, filtrado de fuentes, skills archivados, procedencia y toggle de fijado', new_0_5_6_4: 'Estadísticas diarias de uso expandidas con desglose detallado de tokens incluyendo separación de lectura/escritura de caché', new_0_5_6_5: 'Ámbito del historial de sesiones aclarado con descripciones mejoradas en vistas de chat e historial', new_0_5_6_6: 'Rediseñado el manejo de adjuntos usando formato de matriz ContentBlock estilo Anthropic (texto, imagen, archivo)', new_0_5_6_7: 'Añadida funcionalidad de descarga de archivos en frontend soportando formatos ContentBlock y Markdown con autenticación', new_0_5_6_8: 'Corregido conflicto de múltiples procesos que causaba reinicios de base de datos SQLite eliminando instancias nodemon redundantes', new_0_5_9_1: 'Unificar la gestión de perfiles en toda la aplicación con API y gestión de estado consistentes', new_0_5_9_2: 'Añadir plantillas de issues y pull requests de GitHub para un mejor flujo de contribución', new_0_5_8_1: 'Añadir panel de cajón con soporte de barra lateral móvil y botón arcoíris personalizable', new_0_5_8_2: 'Corregir problema de sincronización de estado de cambio de perfil con actualización inmediata de UI y verificación de backend', new_0_5_8_3: 'Filtrar caracteres especiales y emoji en reproducción de voz para mejor síntesis de voz', new_0_5_8_4: 'Añadir clave i18n faltante y unificar fuente de datos de sesión para priorizar base de datos', new_0_5_8_5: 'Optimizar configuración de build Vite para builds Docker más rápidas con esbuild y división de chunks', new_0_5_7_1: 'Optimizar compresión de contexto para soportar contenido rico (imágenes, archivos) con mejora en el manejo de mensajes de herramientas', new_0_5_7_2: 'Mejorar sincronización de sesiones con inserciones por lotes y protección de transacciones para consistencia de datos', new_0_5_7_3: 'Corregir recepción de eventos usage.updated para asegurar seguimiento preciso de tokens entre ejecuciones', new_0_5_5_1: '🎉 ¡Feliz Día del Trabajo! Hoy no se trabaja, agradezcan su comprensión', new_0_5_5_2: 'Añadida página de historial para sesiones Hermes', new_0_5_5_3: 'La página de historial gestiona sesiones de forma independiente', new_0_5_5_4: 'Carga automática de primera sesión CLI', new_0_5_5_5: 'Componente HistoryMessageList con inyección de props', new_0_5_5_6: 'Filtrado de mensajes vacíos y tools sin toolName', new_0_5_5_7: 'Eliminado caché de sesiones localStorage, datos del backend', new_0_5_5_8: 'Optimizado cambio de perfil, eliminadas llamadas de cachete obsoletas', new_0_5_4_2: 'Fix concurrent chat sessions event cross-talk with WebSocket event routing refactoring', new_0_5_4_3: 'Fix cron job edit payloads with partial PATCH to support long prompt name-only edits', new_0_5_4_4: 'Fix web terminal Hermes CLI availability after Docker deployment', new_0_5_4_5: 'Add workspace dialog i18n translations for title and improve session persistence', new_0_5_4_6: 'Support code block copy feedback with user notifications', new_0_5_4_7: 'Align usage analytics with Hermes state DB schema', new_0_5_3_1: 'Improve reasoning process display with persistence across page refreshes', new_0_5_3_2: 'Optimize stringified array format parsing to extract thinking/text/tool_calls', new_0_5_3_3: 'Improve log display by removing ellipsis and showing full content', new_0_5_3_4: 'Add detailed logging for format conversion and parsing', new_0_5_3_5: 'Optimize token calculation to accurately include tool results', new_0_5_2_1: 'Convert conversation history to Anthropic format before sending to Gateway', new_0_5_2_2: 'Add bidirectional reasoning sync between memory and database', new_0_5_2_3: 'Add message pagination with DESC query + array reverse for performance', new_0_5_2_4: 'Clean up debug code and unused imports', new_0_5_2_5: 'Remove auto-resumed event trigger to avoid timing issues', new_0_5_2_6: 'Use reasoning field consistently across codebase', new_0_5_1_1: 'Auto-sync Hermes history sessions on first startup', new_0_5_1_2: 'Fix session sync failure with old Hermes versions (backward compatible)', new_0_5_1_3: 'Smart cleanup of exclusive platform credentials on profile clone (Telegram, Discord, Slack, etc.)', new_0_5_1_4: 'Auto-normalize profile names to lowercase to avoid backend validation errors', new_0_5_1_5: 'Fix tool_call_id missing in tool messages for OpenAI API compatibility', new_0_5_1_6: 'Unify SQLite table schema management and initialization', new_0_5_1_7: 'Optimize model list layout in Provider cards (fixed height, tag alignment)', new_0_5_1_8: 'Fix display issue with single-line long code blocks in user messages', new_0_5_1_9: 'Fix web terminal rendering errors in Docker deployment', new_0_5_0_1: 'Self-built chat database and context compression: empty chat history on first entry is expected', new_0_5_0_2: 'Sessions use WebSocket form, enhanced resume capability', new_0_4_8_1: 'Safe Mermaid diagram rendering with async render and timeout fallback', new_0_4_8_2: 'Fix nested markdown fence rendering truncation', new_0_4_8_3: 'Fix compressed session lineage projection and search', new_0_4_8_4: 'Optimize session list N+1 queries and fix search 500 on non-CJK input', new_0_4_8_5: 'Fix forced scroll to bottom when switching back from other tabs', new_0_4_8_6: 'Smooth session switch with loading transition overlay', new_0_4_8_7: 'Fix login token validation using Hermes session endpoint', new_0_4_8_8: 'Fix image attachments broken after page refresh (blob URL persistence)', new_0_4_8_9: 'Click image attachments to preview in fullscreen overlay', new_0_4_8_10: 'Move upload directory from temp to ~/.hermes-web-ui/upload', new_0_4_7_1: 'Visualizacion en streaming en tiempo real de bloques de pensamiento/razonamiento', new_0_4_7_2: 'Omitir script de preparacion durante la construccion Docker', new_0_4_7_3: 'Mejoras en la experiencia movil del chat grupal y pulido de UI', new_0_4_7_4: 'Limitar los tokens restantes del contexto a 0 en lugar de negativos', new_0_4_7_5: 'Agregar proveedor integrado Alibaba Coding Plan con anulacion de base_url en .env', new_0_4_7_6: 'Omitir perfiles remotos al inicio para evitar bloqueos', new_0_4_7_7: 'Detectar y mostrar errores de ejecucion silenciosamente tragados', new_0_4_7_8: 'Consulta de longitud de contexto consciente del proveedor', new_0_4_7_9: 'Restablecer config.model al cambiar y resolver proveedor personalizado CLI', new_0_4_7_10: 'Limpiar base_url_env de .env al eliminar proveedor integrado', new_0_4_7_11: 'Alinear el fondo de la barra lateral del chat grupal con la lista de sesiones', new_0_4_5_1: 'Add group chat with multi-agent rooms, @mention routing, and typing status recovery', new_0_4_5_2: 'Rewrite model-context config to use YAML with context_length setting', new_0_4_5_3: 'Add gpt-5.5 to OpenAI Codex model list', new_0_4_5_4: 'Replace jobs proxy with local controller and optimize model loading', new_0_4_5_5: 'Add i18n support for custom model feature in ModelSelector', new_0_4_5_6: 'Fix sidebar i18n missing key warnings', new_0_4_5_7: 'Clear all localStorage on logout', new_0_4_5_8: 'Add periodic log rotation to prevent unbounded log growth', new_0_4_2_1: 'Agregar seguimiento de uso de tokens y longitud de contexto dinamico', new_0_4_2_2: 'Agregar modal de busqueda de sesiones', new_0_4_2_3: 'Restaurar sistema de chat grupal con Socket.IO y SQLite', new_0_4_2_4: 'Agregar sesiones fijas y monitor en vivo en la pagina de chat', new_0_4_2_5: 'Corregir deteccion de proveedores integrados y coincidencia de modelos', }, // Archivos files: { title: 'Archivos', tree: 'Arbol de directorios', list: 'Lista de archivos', breadcrumbRoot: 'Inicio', newFile: 'Nuevo archivo', newFolder: 'Nueva carpeta', upload: 'Subir', refresh: 'Actualizar', open: 'Abrir', edit: 'Editar', preview: 'Vista previa', download: 'Descargar', copyPath: 'Copiar ruta', rename: 'Renombrar', delete: 'Eliminar', name: 'Nombre', size: 'Tamano', modified: 'Modificado', actions: 'Acciones', emptyDir: 'Directorio vacio', loading: 'Cargando...', confirmDelete: '?Seguro que quiere eliminar "{name}"?', confirmDeleteDir: '?Seguro que quiere eliminar el directorio "{name}" y todo su contenido?', deleteFailed: 'Error al eliminar', deleted: 'Eliminado', renameTo: 'Renombrar a', newFileName: 'Nombre del archivo', newFolderName: 'Nombre de la carpeta', created: 'Creado', createFailed: 'Error al crear', renamed: 'Renombrado', renameFailed: 'Error al renombrar', uploadSuccess: '{count} archivo(s) subido(s)', uploadFailed: 'Error al subir', saveFailed: 'Error al guardar', saved: 'Guardado', unsavedChanges: 'Tiene cambios sin guardar. ?Descartar?', pathCopied: 'Ruta copiada', fileTooLarge: 'Archivo demasiado grande (max 10MB)', permissionDenied: 'No se puede modificar un archivo protegido', notFound: 'Archivo o directorio no encontrado', backendError: 'Error en la operacion de archivo', dragDropHint: 'Arrastra archivos aqui para subir', closeEditor: 'Cerrar editor', closePreview: 'Cerrar', saveFile: 'Guardar', }, // Chat grupal groupChat: { title: 'Chat grupal', createRoom: 'Crear sala', joinByCode: 'Unirse con codigo', roomName: 'Nombre de la sala', roomNamePlaceholder: 'Ingrese el nombre de la sala', inviteCode: 'Codigo de invitacion', autoGenerate: 'Generar automaticamente', noRooms: 'Aun no hay salas', selectOrCreate: 'Seleccione o cree una sala para comenzar a chatear', agents: 'Agentes', addAgent: 'Agregar agente', selectProfile: 'Seleccione un perfil', agentAdded: 'Agente agregado', agentAlreadyInRoom: 'El agente ya esta en esta sala', noAgents: 'No hay agentes en esta sala', members: 'Miembros', roomCreated: 'Sala creada', roomDeleted: 'Sala eliminada', deleteRoomConfirm: '¿Eliminar esta sala?', you: 'Tú', joined: 'Se unio a la sala', joinFailed: 'Error al unirse a la sala', inputPlaceholder: 'Escriba un mensaje... (Enter para enviar)', enterCode: 'Ingrese el codigo de invitacion', yourName: 'Tu nombre', yourNamePlaceholder: 'Ingresa tu nombre para mostrar', yourDescription: 'Descripcion (opcional)', yourDescriptionPlaceholder: 'Cuentales a los demas quien eres...', agentName: 'Nombre del agente', agentNamePlaceholder: 'Nombre personalizado (vacío = nombre del perfil)', agentDesc: 'Descripción del agente', agentDescPlaceholder: 'Describe lo que hace este agente...', agentReplying: 'está respondiendo...', agentCompressing: 'está comprimiendo contexto...', compressionSettings: 'Configuración de compresión', triggerTokens: 'Tokens de activación', triggerTokensDesc: 'Umbral de tokens para activar la compresión', maxHistoryTokens: 'Tokens máximos de historial', maxHistoryTokensDesc: 'Máximo de tokens para el contexto comprimido', tailMessageCount: 'Mensajes recientes', tailMessageCountDesc: 'Número de mensajes recientes a conservar sin comprimir', compressionConfig: 'Config. de compresión', compressNow: 'Comprimir ahora', compressingInProgress: 'Compresión en progreso', compressionSaved: 'Configuración guardada', }, // Descarga download: { downloading: 'Descargando...', downloadFailed: 'Error en la descarga', fileNotFound: 'Archivo no encontrado o eliminado', fileTooLarge: 'Archivo demasiado grande (excede el limite)', backendError: 'Error al leer el archivo, el entorno remoto puede no estar disponible', backendTimeout: 'Tiempo de lectura del archivo agotado', unsupportedBackend: 'El backend del terminal actual no admite la descarga de archivos', invalidPath: 'Ruta de archivo invalida', download: 'Descargar', downloadFile: 'Descargar archivo', }, }