Phase 10: Multi-language support (Italian and English)

This commit is contained in:
truetype committed 2026-03-20 19:07:47 +01:00
1 parent 98b6f10ea4
commit 8dbab53c6d
4 files changed
+393

No files matched your search

+31
View File
@@ -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
```
+208
View File
@@ -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)
+77
View File
@@ -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>"
}
+77
View File
@@ -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>"
}