Phase 10: Multi-language support (Italian and English)
This commit is contained in:
1 parent
98b6f10ea4
commit
8dbab53c6d
4 files changed
+393
No files matched your search
@@ -19,6 +19,7 @@ Un agente configurabile basato su DeepAgents che supporta più provider LLM.
|
||||
- **Comandi integrati**: Comandi speciali con prefisso "/" per gestione rapida
|
||||
- **Monitoraggio**: Sistema di logging e monitoraggio delle performance
|
||||
- **Sistema di plugin**: Estendi le funzionalità con plugin personalizzati
|
||||
- **Supporto multilingue**: Interfaccia in italiano e inglese
|
||||
|
||||
## Installazione
|
||||
|
||||
@@ -208,6 +209,7 @@ Quando interagisci con l'agente, puoi usare comandi speciali preceduti da "/" pe
|
||||
/models - Elenca i modelli disponibili per il provider attivo
|
||||
/clear - Pulisce lo schermo
|
||||
/plugins - Elenca i plugin disponibili
|
||||
/language - Cambia la lingua dell'interfaccia
|
||||
/exit, /quit - Esci dall'agente
|
||||
```
|
||||
|
||||
@@ -465,6 +467,34 @@ python -c "from plugins.manager import plugin_manager; plugin_manager.load_all_p
|
||||
/mycommand
|
||||
```
|
||||
|
||||
## Supporto Multilingue
|
||||
|
||||
MaxClaw Agent supporta più lingue per l'interfaccia utente.
|
||||
|
||||
### Lingue Disponibili
|
||||
|
||||
- **Italiano** (it) - Predefinito
|
||||
- **Inglese** (en)
|
||||
|
||||
### Cambiare Lingua
|
||||
|
||||
```bash
|
||||
# Usa la variabile d'ambiente
|
||||
export MAXCLAW_LANGUAGE=en
|
||||
|
||||
# Oppure usa il comando /language
|
||||
/language en
|
||||
```
|
||||
|
||||
### Aggiungere una Nuova Lingua
|
||||
|
||||
Per aggiungere una nuova lingua:
|
||||
|
||||
1. Crea un file JSON nella directory `i18n/` (es. `fr.json`)
|
||||
2. Copia la struttura da `en.json` o `it.json`
|
||||
3. Traduci tutti i valori
|
||||
4. L'agente rileverà automaticamente la nuova lingua
|
||||
|
||||
## Test
|
||||
|
||||
Esegui la suite di test:
|
||||
@@ -515,6 +545,7 @@ docker run -it --rm \
|
||||
-e PROXMOX_HOST=192.168.0.100 \
|
||||
-e PROXMOX_USER=root \
|
||||
-e PROXMOX_PASSWORD=password \
|
||||
-e MAXCLAW_LANGUAGE=it \
|
||||
maxclaw-agent
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
"""
|
||||
Internationalization (i18n) support for MaxClaw Agent
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
from typing import Dict, Any, Optional
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class I18n:
|
||||
"""Internationalization manager for MaxClaw Agent"""
|
||||
|
||||
def __init__(self, default_language: str = "en"):
|
||||
"""
|
||||
Initialize i18n manager
|
||||
|
||||
Args:
|
||||
default_language: Default language code (e.g., "en", "it", "es")
|
||||
"""
|
||||
self.default_language = default_language
|
||||
self.current_language = default_language
|
||||
self.translations: Dict[str, Dict[str, str]] = {}
|
||||
self.i18n_dir = Path(__file__).parent
|
||||
|
||||
# Load translations
|
||||
self._load_translations()
|
||||
|
||||
def _load_translations(self):
|
||||
"""Load all translation files"""
|
||||
# Load default language
|
||||
self._load_language(self.default_language)
|
||||
|
||||
# Try to load current language from environment
|
||||
env_lang = os.getenv("MAXCLAW_LANGUAGE")
|
||||
if env_lang:
|
||||
self.set_language(env_lang)
|
||||
|
||||
def _load_language(self, language: str) -> bool:
|
||||
"""
|
||||
Load translations for a specific language
|
||||
|
||||
Args:
|
||||
language: Language code
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
translation_file = self.i18n_dir / f"{language}.json"
|
||||
|
||||
if not translation_file.exists():
|
||||
print(f"⚠️ Translation file not found: {translation_file}")
|
||||
return False
|
||||
|
||||
try:
|
||||
with open(translation_file, 'r', encoding='utf-8') as f:
|
||||
self.translations[language] = json.load(f)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ Error loading translations for {language}: {e}")
|
||||
return False
|
||||
|
||||
def set_language(self, language: str) -> bool:
|
||||
"""
|
||||
Set the current language
|
||||
|
||||
Args:
|
||||
language: Language code
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
# Load translations if not already loaded
|
||||
if language not in self.translations:
|
||||
if not self._load_language(language):
|
||||
return False
|
||||
|
||||
self.current_language = language
|
||||
return True
|
||||
|
||||
def get_language(self) -> str:
|
||||
"""
|
||||
Get the current language
|
||||
|
||||
Returns:
|
||||
Current language code
|
||||
"""
|
||||
return self.current_language
|
||||
|
||||
def get_available_languages(self) -> list:
|
||||
"""
|
||||
Get list of available languages
|
||||
|
||||
Returns:
|
||||
List of language codes
|
||||
"""
|
||||
languages = []
|
||||
|
||||
# Find all JSON files in i18n directory
|
||||
for file_path in self.i18n_dir.glob("*.json"):
|
||||
language = file_path.stem
|
||||
languages.append(language)
|
||||
|
||||
return languages
|
||||
|
||||
def translate(self, key: str, **kwargs) -> str:
|
||||
"""
|
||||
Translate a key to the current language
|
||||
|
||||
Args:
|
||||
key: Translation key
|
||||
**kwargs: Format arguments
|
||||
|
||||
Returns:
|
||||
Translated string
|
||||
"""
|
||||
# Get translation from current language
|
||||
if self.current_language in self.translations:
|
||||
translation = self.translations[self.current_language].get(key)
|
||||
if translation:
|
||||
# Format with kwargs if provided
|
||||
if kwargs:
|
||||
try:
|
||||
return translation.format(**kwargs)
|
||||
except KeyError:
|
||||
return translation
|
||||
return translation
|
||||
|
||||
# Fallback to default language
|
||||
if self.default_language in self.translations:
|
||||
translation = self.translations[self.default_language].get(key)
|
||||
if translation:
|
||||
if kwargs:
|
||||
try:
|
||||
return translation.format(**kwargs)
|
||||
except KeyError:
|
||||
return translation
|
||||
return translation
|
||||
|
||||
# Return key if no translation found
|
||||
return key
|
||||
|
||||
def t(self, key: str, **kwargs) -> str:
|
||||
"""
|
||||
Shorthand for translate()
|
||||
|
||||
Args:
|
||||
key: Translation key
|
||||
**kwargs: Format arguments
|
||||
|
||||
Returns:
|
||||
Translated string
|
||||
"""
|
||||
return self.translate(key, **kwargs)
|
||||
|
||||
|
||||
# Global i18n instance
|
||||
i18n = I18n()
|
||||
|
||||
|
||||
def set_language(language: str) -> bool:
|
||||
"""
|
||||
Set the global language
|
||||
|
||||
Args:
|
||||
language: Language code
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
return i18n.set_language(language)
|
||||
|
||||
|
||||
def get_language() -> str:
|
||||
"""
|
||||
Get the current global language
|
||||
|
||||
Returns:
|
||||
Current language code
|
||||
"""
|
||||
return i18n.get_language()
|
||||
|
||||
|
||||
def translate(key: str, **kwargs) -> str:
|
||||
"""
|
||||
Translate a key using the global i18n instance
|
||||
|
||||
Args:
|
||||
key: Translation key
|
||||
**kwargs: Format arguments
|
||||
|
||||
Returns:
|
||||
Translated string
|
||||
"""
|
||||
return i18n.translate(key, **kwargs)
|
||||
|
||||
|
||||
def t(key: str, **kwargs) -> str:
|
||||
"""
|
||||
Shorthand for translate()
|
||||
|
||||
Args:
|
||||
key: Translation key
|
||||
**kwargs: Format arguments
|
||||
|
||||
Returns:
|
||||
Translated string
|
||||
"""
|
||||
return i18n.t(key, **kwargs)
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"app.name": "MaxClaw Agent",
|
||||
"app.description": "A configurable agent harness using DeepAgents",
|
||||
|
||||
"commands.help": "Show available commands",
|
||||
"commands.status": "Show system status",
|
||||
"commands.config.list": "List all configurations",
|
||||
"commands.config.active": "Show active configuration",
|
||||
"commands.config.test": "Test connection to active configuration",
|
||||
"commands.config.use": "Change active configuration",
|
||||
"commands.models": "List available models for current provider",
|
||||
"commands.clear": "Clear the screen",
|
||||
"commands.plugins": "List available plugins",
|
||||
"commands.exit": "Exit the agent",
|
||||
|
||||
"status.title": "System Status",
|
||||
"status.provider": "Provider",
|
||||
"status.model": "Model",
|
||||
"status.ollama_url": "Ollama URL",
|
||||
"status.active_config": "Active configuration",
|
||||
"status.total_configs": "Total configurations",
|
||||
"status.custom_tools": "Custom tools",
|
||||
"status.available": "Available",
|
||||
"status.not_available": "Not available",
|
||||
|
||||
"config.title": "Available Configurations",
|
||||
"config.active_marker": "✅",
|
||||
"config.inactive_marker": " ",
|
||||
"config.no_configs": "No configurations found.",
|
||||
"config.active_title": "Active Configuration",
|
||||
"config.no_active": "No active configuration set.",
|
||||
"config.test_title": "Testing connection to",
|
||||
"config.test_success": "Connection successful",
|
||||
"config.test_failed": "Connection failed",
|
||||
"config.changed": "Configuration changed to",
|
||||
"config.not_found": "Configuration not found",
|
||||
|
||||
"models.title": "Available Models",
|
||||
"models.ollama_hint": "To list Ollama models, ask the agent:",
|
||||
"models.ollama_example": "List available models on Ollama",
|
||||
"models.openai_models": "Common OpenAI models:",
|
||||
"models.openrouter_hint": "To list OpenRouter models, ask the agent:",
|
||||
"models.openrouter_example": "List available models on OpenRouter",
|
||||
"models.unknown_provider": "Unknown provider",
|
||||
|
||||
"plugins.title": "Available Plugins",
|
||||
"plugins.name": "Name",
|
||||
"plugins.version": "Version",
|
||||
"plugins.description": "Description",
|
||||
"plugins.status": "Status",
|
||||
"plugins.enabled": "Enabled",
|
||||
"plugins.disabled": "Disabled",
|
||||
"plugins.no_plugins": "No plugins found.",
|
||||
|
||||
"agent.initializing": "Initializing MaxClaw Agent...",
|
||||
"agent.initialized": "Agent initialized successfully!",
|
||||
"agent.tools.available": "Available tools:",
|
||||
"agent.tools.provider": "Provider tools: list models, test connections, set defaults",
|
||||
"agent.tools.proxmox": "Proxmox tools: manage VMs, snapshots, resources",
|
||||
"agent.tools.standard": "Standard tools: planning, filesystem, shell, subagents",
|
||||
"agent.chat.ready": "You can now interact with the agent.",
|
||||
"agent.chat.commands": "Special commands (prefixed with /):",
|
||||
"agent.chat.hint": "To chat, simply write your message.",
|
||||
"agent.error.init": "Failed to initialize agent",
|
||||
"agent.error.chat": "Error",
|
||||
|
||||
"goodbye": "Goodbye!",
|
||||
|
||||
"errors.config_not_available": "Configuration manager not available.",
|
||||
"errors.no_active_config": "No active configuration to test.",
|
||||
"errors.config_not_found": "Configuration not found.",
|
||||
"errors.unknown_command": "Unknown command",
|
||||
"errors.command_help": "Type /help to see available commands.",
|
||||
"errors.subcommand_required": "Specify a subcommand: list, active, test, use <name>",
|
||||
"errors.unknown_subcommand": "Unknown subcommand",
|
||||
"errors.subcommands_available": "Available subcommands: list, active, test, use <name>"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"app.name": "MaxClaw Agent",
|
||||
"app.description": "Un agente configurabile basato su DeepAgents",
|
||||
|
||||
"commands.help": "Mostra i comandi disponibili",
|
||||
"commands.status": "Mostra lo stato del sistema",
|
||||
"commands.config.list": "Elenca tutte le configurazioni",
|
||||
"commands.config.active": "Mostra la configurazione attiva",
|
||||
"commands.config.test": "Testa la connessione alla configurazione attiva",
|
||||
"commands.config.use": "Cambia la configurazione attiva",
|
||||
"commands.models": "Elenca i modelli disponibili per il provider attivo",
|
||||
"commands.clear": "Pulisce lo schermo",
|
||||
"commands.plugins": "Elenca i plugin disponibili",
|
||||
"commands.exit": "Esci dall'agente",
|
||||
|
||||
"status.title": "Stato del Sistema",
|
||||
"status.provider": "Provider",
|
||||
"status.model": "Modello",
|
||||
"status.ollama_url": "URL Ollama",
|
||||
"status.active_config": "Configurazione attiva",
|
||||
"status.total_configs": "Configurazioni totali",
|
||||
"status.custom_tools": "Strumenti personalizzati",
|
||||
"status.available": "Disponibili",
|
||||
"status.not_available": "Non disponibili",
|
||||
|
||||
"config.title": "Configurazioni disponibili",
|
||||
"config.active_marker": "✅",
|
||||
"config.inactive_marker": " ",
|
||||
"config.no_configs": "Nessuna configurazione trovata.",
|
||||
"config.active_title": "Configurazione attiva",
|
||||
"config.no_active": "Nessuna configurazione attiva impostata.",
|
||||
"config.test_title": "Test connessione a",
|
||||
"config.test_success": "Connessione riuscita",
|
||||
"config.test_failed": "Connessione fallita",
|
||||
"config.changed": "Configurazione cambiata in",
|
||||
"config.not_found": "Configurazione non trovata",
|
||||
|
||||
"models.title": "Modelli disponibili",
|
||||
"models.ollama_hint": "Per elencare i modelli Ollama, chiedi all'agente:",
|
||||
"models.ollama_example": "Elenca i modelli disponibili su Ollama",
|
||||
"models.openai_models": "Modelli OpenAI comuni:",
|
||||
"models.openrouter_hint": "Per elencare i modelli OpenRouter, chiedi all'agente:",
|
||||
"models.openrouter_example": "Elenca i modelli disponibili su OpenRouter",
|
||||
"models.unknown_provider": "Provider sconosciuto",
|
||||
|
||||
"plugins.title": "Plugin disponibili",
|
||||
"plugins.name": "Nome",
|
||||
"plugins.version": "Versione",
|
||||
"plugins.description": "Descrizione",
|
||||
"plugins.status": "Stato",
|
||||
"plugins.enabled": "Abilitato",
|
||||
"plugins.disabled": "Disabilitato",
|
||||
"plugins.no_plugins": "Nessun plugin trovato.",
|
||||
|
||||
"agent.initializing": "Inizializzazione MaxClaw Agent...",
|
||||
"agent.initialized": "Agente inizializzato con successo!",
|
||||
"agent.tools.available": "Strumenti disponibili:",
|
||||
"agent.tools.provider": "Strumenti provider: elenca modelli, testa connessioni, imposta predefiniti",
|
||||
"agent.tools.proxmox": "Strumenti Proxmox: gestisci VM, snapshot, risorse",
|
||||
"agent.tools.standard": "Strumenti standard: pianificazione, filesystem, shell, subagenti",
|
||||
"agent.chat.ready": "Ora puoi interagire con l'agente.",
|
||||
"agent.chat.commands": "Comandi speciali (prefissati con /):",
|
||||
"agent.chat.hint": "Per chattare, scrivi semplicemente il tuo messaggio.",
|
||||
"agent.error.init": "Impossibile inizializzare l'agente",
|
||||
"agent.error.chat": "Errore",
|
||||
|
||||
"goodbye": "Arrivederci!",
|
||||
|
||||
"errors.config_not_available": "Gestore configurazioni non disponibile.",
|
||||
"errors.no_active_config": "Nessuna configurazione attiva da testare.",
|
||||
"errors.config_not_found": "Configurazione non trovata.",
|
||||
"errors.unknown_command": "Comando sconosciuto",
|
||||
"errors.command_help": "Digita /help per vedere i comandi disponibili.",
|
||||
"errors.subcommand_required": "Specifica un sottocomando: list, active, test, use <name>",
|
||||
"errors.unknown_subcommand": "Sottocomando sconosciuto",
|
||||
"errors.subcommands_available": "Sottocomandi disponibili: list, active, test, use <name>"
|
||||
}
|
||||
Reference in new issue
Block a user