From f397bbffe72f34a2f99e77d23cf9950783bcb4e4 Mon Sep 17 00:00:00 2001 From: SMKRV Date: Tue, 3 Dec 2024 18:29:24 +0300 Subject: [PATCH] Release 2.0.5-beta --- README.md | 34 +- custom_components/ha_text_ai/const.py | 3 + custom_components/ha_text_ai/coordinator.py | 414 +++++++++++++++--- custom_components/ha_text_ai/manifest.json | 2 +- .../ha_text_ai/translations/de.json | 152 ++++--- .../ha_text_ai/translations/en.json | 32 +- .../ha_text_ai/translations/es.json | 190 ++++---- .../ha_text_ai/translations/hi.json | 176 +++++--- .../ha_text_ai/translations/it.json | 180 ++++---- .../ha_text_ai/translations/ru.json | 150 ++++--- .../ha_text_ai/translations/sr.json | 180 ++++---- .../ha_text_ai/translations/zh.json | 176 +++++--- 12 files changed, 1116 insertions(+), 573 deletions(-) diff --git a/README.md b/README.md index f389441..2420247 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,10 @@ Transform your smart home experience with powerful AI assistance powered by mult - Natural conversation flow - 📝 **Enhanced Memory Management**: - - Persistent conversation history - - Context-aware responses - - Customizable history limits - - Model-specific filtering + - File-based conversation history storage + - Automatic history rotation + - Configurable history size limits + - Secure storage in Home Assistant - ⚡ **Performance Optimization**: - Efficient token usage @@ -188,6 +188,8 @@ sensor: | `request_interval` | Float | ❌ | 1.0 | Delay between API requests | | `api_endpoint` | URL | ⚠️ | Provider default | Custom API endpoint | | `system_prompt` | String | ❌ | - | Default context for AI interactions | +| `max_history_size` | Integer | ❌ | 100 | Maximum number of conversation entries to store | +| `history_file_size` | Integer | ⚠️ | 1 | Maximum history file size in MB | #### Sensor Configuration @@ -344,6 +346,13 @@ automation: # Tokens used in the AI's generated responses {{ state_attr('sensor.ha_text_ai_gpt', 'Completion tokens') }} # 0 + +# Number of entries in current history file +{{ state_attr('sensor.ha_text_ai_gpt', 'History size') }} # 0 + +# Last few conversation entries (limited to 3 for performance) +{{ state_attr('sensor.ha_text_ai_gpt', 'conversation_history') }} # [...] + ``` #### Last Interaction Details @@ -370,6 +379,13 @@ automation: {{ state_attr('sensor.ha_text_ai_gpt', 'Uptime') }} # 547,58 ``` +### History Storage +Conversation history stored in `.storage/ha_text_ai_history/` directory: +- Each instance has its own history file +- Files are automatically rotated when size limit is reached +- Archived history files are timestamped +- Default maximum file size: 1MB + ### 💡 Pro Tips - Always check attribute existence - Use these attributes for monitoring and automation @@ -402,6 +418,16 @@ A: Yes, your data is secure. The system operates entirely on your local machine, **Q: How do context messages work?** A: Context messages allow the AI to remember and reference previous conversation history. By default, 5 previous messages are included, but you can customize this from 1 to 20 messages to control the conversation depth and token usage. +**Q: Where is conversation history stored?** +A: History is stored in files under the `.storage/ha_text_ai_history/` directory, with automatic rotation and size management. + +**Q: Can I access old conversation history?** +A: Yes, archived history files are stored with timestamps and can be accessed manually if needed. + +**Q: How much history is kept?** +A: By default, up to 100 conversations are stored, but this can be configured. Files are automatically rotated when they reach 1MB. + + ## 🤝 Contributing Contributions welcome! Please read our [Contributing Guide](CONTRIBUTING.md). diff --git a/custom_components/ha_text_ai/const.py b/custom_components/ha_text_ai/const.py index 5671958..0d1a300 100644 --- a/custom_components/ha_text_ai/const.py +++ b/custom_components/ha_text_ai/const.py @@ -40,6 +40,9 @@ CONF_MAX_HISTORY_SIZE: Final = "max_history_size" # Correct constant name CONF_IS_ANTHROPIC: Final = "is_anthropic" CONF_CONTEXT_MESSAGES: Final = "context_messages" +ABSOLUTE_MAX_HISTORY_SIZE = 500 +MAX_ENTRY_SIZE = 1 * 1024 * 1024 + # Default values DEFAULT_MODEL: Final = "gpt-4o-mini" DEFAULT_TEMPERATURE: Final = 0.1 diff --git a/custom_components/ha_text_ai/coordinator.py b/custom_components/ha_text_ai/coordinator.py index b792857..bc2c815 100644 --- a/custom_components/ha_text_ai/coordinator.py +++ b/custom_components/ha_text_ai/coordinator.py @@ -10,6 +10,9 @@ from __future__ import annotations import logging import traceback +import aiofiles +import os +import asyncio from datetime import datetime, timedelta from typing import Any, Dict, List, Optional @@ -18,8 +21,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util import dt as dt_util from homeassistant.exceptions import HomeAssistantError from homeassistant.const import CONF_NAME -from .config_flow import normalize_name +from .config_flow import normalize_name from .const import ( DOMAIN, STATE_READY, @@ -31,22 +34,35 @@ from .const import ( DEFAULT_TEMPERATURE, DEFAULT_MAX_HISTORY, DEFAULT_CONTEXT_MESSAGES, - DEFAULT_NAME_PREFIX, - CONF_MAX_HISTORY_SIZE, + ABSOLUTE_MAX_HISTORY_SIZE, + MAX_ENTRY_SIZE, ) _LOGGER = logging.getLogger(__name__) +class AsyncFileHandler: + """Async context manager for file operations.""" + + def __init__(self, file_path: str, mode: str = 'a'): + self.file_path = file_path + self.mode = mode + + async def __aenter__(self): + self.file = await aiofiles.open(self.file_path, self.mode) + return self.file + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.file.close() class HATextAICoordinator(DataUpdateCoordinator): - """The HA Text AI coordinator.""" + """Home Assistant Text AI Conversation Coordinator.""" def __init__( self, hass: HomeAssistant, client: Any, model: str, - update_interval: int, + update_interval: int, # Moved up instance_name: str, max_tokens: int = DEFAULT_MAX_TOKENS, temperature: float = DEFAULT_TEMPERATURE, @@ -60,6 +76,7 @@ class HATextAICoordinator(DataUpdateCoordinator): # Use the normalize_name function from config_flow to ensure consistency from .config_flow import normalize_name + self.normalized_name = normalize_name(instance_name) self.hass = hass @@ -67,44 +84,45 @@ class HATextAICoordinator(DataUpdateCoordinator): self.model = model self.temperature = temperature self.max_tokens = max_tokens - self.max_history_size = max_history_size + self.max_history_size = min( + max(1, max_history_size), + ABSOLUTE_MAX_HISTORY_SIZE + ) self.is_anthropic = is_anthropic - # Initialize with default state - self._initial_state = { - "state": STATE_READY, - "metrics": { - "total_tokens": 0, - "prompt_tokens": 0, - "completion_tokens": 0, - "successful_requests": 0, - "failed_requests": 0, - "total_errors": 0, - "average_latency": 0, - "max_latency": 0, - "min_latency": float("inf"), - }, - "last_response": { - "timestamp": dt_util.utcnow().isoformat(), - "question": "", - "response": "", - "model": model, - "instance": instance_name, - "normalized_name": self.normalized_name, - "error": None, - }, - "is_processing": False, - "is_rate_limited": False, - "is_maintenance": False, - "endpoint_status": "ready", - "uptime": 0, - "system_prompt": None, - "history_size": 0, - "conversation_history": [], + # Initialize essential attributes first + self._is_processing = False + self._is_rate_limited = False + self._is_maintenance = False + self.endpoint_status = "ready" + self._system_prompt = None + self._conversation_history = [] + + self._performance_metrics = { + "total_tokens": 0, + "prompt_tokens": 0, + "completion_tokens": 0, + "successful_requests": 0, + "failed_requests": 0, + "total_errors": 0, + "average_latency": 0, + "max_latency": 0, + "min_latency": float("inf"), + } + + self._last_response = { + "timestamp": dt_util.utcnow().isoformat(), + "question": "", + "response": "", + "model": model, + "instance": instance_name, + "normalized_name": self.normalized_name, + "error": None, } update_interval_td = timedelta(seconds=update_interval) + # Call super().__init__ BEFORE other property access super().__init__( hass, _LOGGER, @@ -112,24 +130,262 @@ class HATextAICoordinator(DataUpdateCoordinator): update_interval=update_interval_td, ) + # Now initialize _initial_state (after super().__init__) + self._initial_state = { + "state": STATE_READY, + "metrics": self._performance_metrics.copy(), + "last_response": self.last_response.copy(), # Accessing here + "is_processing": self._is_processing, + "is_rate_limited": self._is_rate_limited, + "is_maintenance": self._is_maintenance, + "endpoint_status": self.endpoint_status, + "uptime": 0, + "system_prompt": self._system_prompt, + "history_size": len(self._conversation_history), + "conversation_history": self._conversation_history.copy(), + } + + self.available = True + self._state = STATE_READY + self._conversation_history = [] # Full conversation history + + self._start_time = dt_util.utcnow() + + # Create history directory with safe mechanism + self._history_dir = os.path.join( + hass.config.path(".storage"), + "ha_text_ai_history" + ) + os.makedirs(self._history_dir, exist_ok=True) + + hass.async_create_task(self._check_history_directory()) + + # History file path using instance name + self._history_file = os.path.join( + self._history_dir, + f"{self.normalized_name}_history.txt" + ) + # Maximum history file size (10 MB) + self._max_history_file_size = 10 * 1024 * 1024 + + # Asynchronous file initialization + hass.async_create_task(self.async_initialize_history_file()) + + _LOGGER.info(f"Initialized HA Text AI coordinator with instance: {instance_name}") + # Register instance self.hass.data.setdefault(DOMAIN, {}) self.hass.data[DOMAIN][instance_name] = self self.context_messages = context_messages - self._system_prompt = None - self._conversation_history = [] - self._performance_metrics = self._initial_state["metrics"].copy() - self._is_processing = False - self._is_rate_limited = False - self._is_maintenance = False - self.endpoint_status = "ready" - self.last_response = self._initial_state["last_response"].copy() - self._start_time = dt_util.utcnow() + @property + def last_response(self) -> Dict[str, Any]: + """ + Get the last response with fallback to conversation history. - _LOGGER.info( - f"Initialized HA Text AI coordinator with instance: {instance_name}" - ) + Returns: + Dict containing last response information + """ + if self._last_response: + return self._last_response + + if self._conversation_history: + latest = self._conversation_history[-1] + return { + "timestamp": latest.get("timestamp"), + "question": latest.get("question", ""), + "response": latest.get("response", ""), + "model": self.model, + "instance": self.instance_name, + "normalized_name": self.normalized_name, + "error": None + } + + return { + "timestamp": dt_util.utcnow().isoformat(), + "question": "", + "response": "", + "model": self.model, + "instance": self.instance_name, + "normalized_name": self.normalized_name, + "error": None + } + + @last_response.setter + def last_response(self, value: Dict[str, Any]) -> None: + """ + Set the last response value. + + Args: + value: Dictionary containing response information + """ + self._last_response = value + + async def async_initialize_history_file(self) -> None: + """ + Asynchronously initialize history file. + + Creates the file and writes an initialization timestamp + without blocking the event loop. + """ + try: + # Use asyncio.to_thread to perform file I/O in a separate thread + await asyncio.to_thread(self._sync_initialize_history_file) + except Exception as e: + _LOGGER.error(f"Could not initialize history file: {e}") + _LOGGER.debug(traceback.format_exc()) + + def _sync_initialize_history_file(self) -> None: + """ + Synchronous method to create and initialize history file. + + Runs in a separate thread to avoid blocking the event loop. + """ + try: + with open(self._history_file, 'a') as f: + f.write(f"History initialized at: {dt_util.utcnow().isoformat()}\n") + except Exception as e: + _LOGGER.error(f"Synchronous history file initialization failed: {e}") + + # Add size check to _update_history method + async def _update_history(self, question: str, response: dict) -> None: + """Update conversation history with size limits.""" + try: + # Limit entry size + question = question[:MAX_ENTRY_SIZE] + response_content = response.get("content", "")[:MAX_ENTRY_SIZE] + + history_entry = { + "timestamp": dt_util.utcnow().isoformat(), + "question": question, + "response": response_content, + } + + self._conversation_history.append(history_entry) + + # Enforce size limit + while len(self._conversation_history) > self.max_history_size: + self._conversation_history.pop(0) + + await self._write_history_entry(history_entry) + + await self._rotate_history() + + except Exception as e: + _LOGGER.error(f"Error updating history: {e}") + _LOGGER.debug(traceback.format_exc()) + + # Update _write_history_entry method + async def _write_history_entry(self, entry: dict) -> None: + """Write a single history entry to file asynchronously.""" + try: + if not os.path.exists(self._history_dir): + os.makedirs(self._history_dir, exist_ok=True) + + _LOGGER.debug(f"Writing history entry to {self._history_file}") + + async with AsyncFileHandler(self._history_file) as f: + await f.write( + f"{entry['timestamp']}: " + f"Question: {entry['question']} - " + f"Response: {entry['response']}\n" + ) + await f.flush() + + _LOGGER.debug(f"Successfully wrote history entry") + + except Exception as e: + _LOGGER.error(f"Error writing history entry: {e}") + _LOGGER.debug(traceback.format_exc()) + + def _sync_write_history_entry(self, entry: dict) -> None: + """ + Synchronous method to write history entry. + + Runs in a separate thread to avoid blocking the event loop. + """ + try: + with open(self._history_file, 'a') as f: + f.write( + f"{entry['timestamp']}: " + f"Question: {entry['question']} - " + f"Response: {entry['response']}\n" + ) + except Exception as e: + _LOGGER.error(f"Synchronous history entry writing failed: {e}") + + async def _rotate_history(self) -> None: + """Rotate conversation history with file management.""" + try: + _LOGGER.debug(f"Starting history rotation for {self._history_file}") + await asyncio.to_thread(self._sync_rotate_history) + _LOGGER.debug(f"Completed history rotation") + + except Exception as e: + _LOGGER.error(f"Error rotating history: {e}") + _LOGGER.debug(traceback.format_exc()) + + async def _check_history_directory(self) -> None: + """ + Asynchronously check history directory permissions and writability. + """ + try: + # Test write permission in a separate thread + test_file_path = os.path.join(self._history_dir, ".write_test") + await asyncio.to_thread(self._sync_test_directory_write, test_file_path) + + except PermissionError: + _LOGGER.error(f"No write permissions for history directory: {self._history_dir}") + except Exception as e: + _LOGGER.error(f"Error checking history directory: {e}") + + def _sync_test_directory_write(self, test_file_path: str) -> None: + """ + Synchronous method to test directory write permissions. + """ + try: + with open(test_file_path, 'w') as f: + f.write("Permission test") + os.remove(test_file_path) + except Exception as e: + _LOGGER.error(f"Directory write test failed: {e}") + + def _sync_rotate_history(self) -> None: + """ + Synchronous method to rotate history files. + + Runs in a separate thread to avoid blocking the event loop. + """ + try: + # Check and manage file size + if os.path.exists(self._history_file): + file_size = os.path.getsize(self._history_file) + if file_size > self._max_history_file_size: + # Create timestamped archive + archive_file = os.path.join( + self._history_dir, + f"{self.normalized_name}_history_{dt_util.utcnow().strftime('%Y%m%d_%H%M%S')}.txt" + ) + os.rename(self._history_file, archive_file) + + # Optional: Log rotation event + _LOGGER.info(f"History file rotated: {archive_file}") + + # Ensure history doesn't exceed max size + if len(self._conversation_history) > self.max_history_size: + # Trim in-memory history + self._conversation_history = self._conversation_history[-self.max_history_size:] + + # Write history entries + with open(self._history_file, 'a') as f: + for entry in self._conversation_history: + f.write( + f"{entry['timestamp']}: {entry['question']} - {entry['response']}\n" + ) + + except Exception as e: + _LOGGER.error(f"Synchronous history rotation failed: {e}") + _LOGGER.debug(traceback.format_exc()) async def _async_update_data(self) -> Dict[str, Any]: """Update data via library.""" @@ -139,18 +395,34 @@ class HATextAICoordinator(DataUpdateCoordinator): f"Updating data for {self.instance_name}, current state: {current_state}" ) + limited_history = [] + if self._conversation_history: + for entry in self._conversation_history[-3:]: + limited_entry = { + "timestamp": entry["timestamp"], + "question": entry["question"][:4096], + "response": entry["response"][:4096], + } + limited_history.append(limited_entry) + + limited_last_response = self.last_response.copy() + if "response" in limited_last_response: + limited_last_response["response"] = limited_last_response["response"][:4096] + if "question" in limited_last_response: + limited_last_response["question"] = limited_last_response["question"][:4096] + data = { "state": current_state, "metrics": self._performance_metrics, - "last_response": self.last_response, + "last_response": limited_last_response, "is_processing": self._is_processing, "is_rate_limited": self._is_rate_limited, "is_maintenance": self._is_maintenance, "endpoint_status": self.endpoint_status, "uptime": (dt_util.utcnow() - self._start_time).total_seconds(), - "system_prompt": self._system_prompt, + "system_prompt": self._system_prompt[:4096] if self._system_prompt else None, "history_size": len(self._conversation_history), - "conversation_history": self._conversation_history, + "conversation_history": limited_history, "normalized_name": self.normalized_name, } @@ -380,8 +652,7 @@ class HATextAICoordinator(DataUpdateCoordinator): latency = (end_time - start_time).total_seconds() self._update_metrics(latency, response) - # Update history - self._update_history(question, response) + await self._update_history(question, response) return response @@ -478,19 +749,6 @@ class HATextAICoordinator(DataUpdateCoordinator): metrics["max_latency"] = max(metrics["max_latency"], latency) metrics["min_latency"] = min(metrics["min_latency"], latency) - def _update_history(self, question: str, response: dict) -> None: - """Update conversation history.""" - self._conversation_history.append( - { - "timestamp": dt_util.utcnow().isoformat(), - "question": question, - "response": response["content"], - } - ) - - while len(self._conversation_history) > self.max_history_size: - self._conversation_history.pop(0) - def _handle_error(self, error: Exception) -> None: """ Enhanced error handling with comprehensive diagnostics. @@ -543,9 +801,25 @@ class HATextAICoordinator(DataUpdateCoordinator): _LOGGER.debug(f"Full Error Traceback: {error_details['traceback']}") async def async_clear_history(self) -> None: - """Clear conversation history.""" - self._conversation_history = [] - await self.async_update_ha_state() + """ + Asynchronously clear conversation history. + + Removes in-memory history and deletes history file. + """ + try: + # Clear in-memory history + self._conversation_history = [] + + # Safely remove history file + if os.path.exists(self._history_file): + await asyncio.to_thread(os.remove, self._history_file) + + await self.async_update_ha_state() + _LOGGER.info(f"History for {self.instance_name} cleared successfully") + + except Exception as e: + _LOGGER.error(f"Error clearing history: {e}") + _LOGGER.debug(traceback.format_exc()) async def async_get_history(self) -> List[Dict[str, str]]: """Get conversation history.""" diff --git a/custom_components/ha_text_ai/manifest.json b/custom_components/ha_text_ai/manifest.json index 54619e4..7fe691a 100644 --- a/custom_components/ha_text_ai/manifest.json +++ b/custom_components/ha_text_ai/manifest.json @@ -23,6 +23,6 @@ "single_config_entry": false, "ssdp": [], "usb": [], - "version": "2.0.4-beta", + "version": "2.0.5-beta", "zeroconf": [] } diff --git a/custom_components/ha_text_ai/translations/de.json b/custom_components/ha_text_ai/translations/de.json index 28520cb..d42eadd 100644 --- a/custom_components/ha_text_ai/translations/de.json +++ b/custom_components/ha_text_ai/translations/de.json @@ -2,71 +2,101 @@ "config": { "step": { "provider": { - "title": "KI-Anbieter auswählen", - "description": "Wählen Sie den KI-Dienstanbieter für diese Instanz aus.", + "title": "Wählen Sie AI-Anbieter", + "description": "Wählen Sie, welchen AI-Dienstanbieter Sie für diese Instanz verwenden möchten.", "data": { "api_provider": "API-Anbieter", - "context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)" + "context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)", + "max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)" + } + }, + "provider": { + "title": "Anbieter-Einstellungen", + "description": "Geben Sie die Verbindungsdetails für Ihren gewählten AI-Anbieter an.", + "data": { + "name": "Instanzname (z. B. 'GPT Assistant', 'Claude Helper')", + "api_key": "API-Schlüssel zur Authentifizierung", + "model": "Zu verwendendes AI-Modell", + "api_endpoint": "Benutzerdefinierte API-Endpunkt-URL (optional)", + "temperature": "Kreativität der Antwort (0-2, niedriger = fokussierter)", + "max_tokens": "Maximale Länge der Antwort (1-4096 Token)", + "request_interval": "Minimale Zeit zwischen Anfragen (0,1-60 Sekunden)", + "context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)", + "max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)" } }, "user": { - "title": "HA Text AI-Instanz konfigurieren", - "description": "Richten Sie eine neue KI-Assistenteninstanz mit Ihrem ausgewählten Anbieter ein.", + "title": "HA Text AI Instanz konfigurieren", + "description": "Richten Sie eine neue AI-Assistenteninstanz mit Ihrem ausgewählten Anbieter ein.", "data": { - "name": "Instanzname (z. B. 'GPT-Assistent', 'Claude-Helfer')", + "name": "Instanzname (z. B. 'GPT Assistant', 'Claude Helper')", "api_key": "API-Schlüssel zur Authentifizierung", - "model": "Zu verwendendes KI-Modell", - "temperature": "Antwortkreativität (0-2, niedriger = fokussierter)", - "max_tokens": "Maximale Antwortlänge (1-4096 Token)", + "model": "Zu verwendendes AI-Modell", + "temperature": "Kreativität der Antwort (0-2, niedriger = fokussierter)", + "max_tokens": "Maximale Länge der Antwort (1-4096 Token)", "api_endpoint": "Benutzerdefinierte API-Endpunkt-URL (optional)", "api_provider": "API-Anbieter", - "request_interval": "Mindestzeit zwischen Anfragen (0,1-60 Sekunden)", + "request_interval": "Minimale Zeit zwischen Anfragen (0,1-60 Sekunden)", "context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)", - "max_history_size": "Maximale Größe des Konversationsverlaufs (1-100)" + "max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)" } } }, "error": { + "history_storage_error": "Fehler beim Initialisieren des Verlaufspeichers. Überprüfen Sie die Berechtigungen.", + "history_rotation_error": "Fehler beim Drehen der Verlaufsdatei.", + "history_file_access_error": "Zugriff auf das Verzeichnis für den Verlaufsspeicher nicht möglich.", "name_exists": "Eine Instanz mit diesem Namen existiert bereits", "invalid_name": "Ungültiger Instanzname", "invalid_auth": "Authentifizierung fehlgeschlagen - überprüfen Sie Ihren API-Schlüssel", - "invalid_api_key": "Ungültiger API-Schlüssel - überprüfen Sie Ihre Anmeldedaten", + "invalid_api_key": "Ungültiger API-Schlüssel - bitte überprüfen Sie Ihre Anmeldeinformationen", "cannot_connect": "Verbindung zum API-Dienst fehlgeschlagen", - "invalid_model": "Das ausgewählte Modell ist nicht verfügbar", - "rate_limit": "Ratenlimit überschritten", + "invalid_model": "Ausgewähltes Modell ist nicht verfügbar", + "rate_limit": "Rate-Limit überschritten", "context_length": "Kontextlänge überschritten", - "rate_limit_exceeded": "API-Ratenlimit überschritten", - "maintenance": "Dienst befindet sich in der Wartung", - "invalid_response": "Ungültige API-Antwort empfangen", - "api_error": "Fehler im API-Dienst aufgetreten", - "timeout": "Anfrage ist abgelaufen", + "rate_limit_exceeded": "API-Rate-Limit überschritten", + "maintenance": "Dienst ist in Wartung", + "invalid_response": "Ungültige API-Antwort erhalten", + "api_error": "Ein Fehler im API-Dienst ist aufgetreten", + "timeout": "Zeitüberschreitung bei der Anfrage", "invalid_instance": "Ungültige Instanz angegeben", - "unknown": "Es ist ein unerwarteter Fehler aufgetreten", + "unknown": "Unerwarteter Fehler aufgetreten", "empty": "Name darf nicht leer sein", "invalid_characters": "Name darf nur Buchstaben, Zahlen, Leerzeichen, Unterstriche und Bindestriche enthalten", - "name_too_long": "Name darf maximal 50 Zeichen lang sein" + "name_too_long": "Name darf höchstens 50 Zeichen lang sein" + }, + "abort": { + "already_configured": "Instanz bereits konfiguriert" } }, "options": { "step": { "init": { "title": "Instanzeinstellungen aktualisieren", - "description": "Ändern Sie die Einstellungen für diese KI-Assistenteninstanz.", + "description": "Ändern Sie die Einstellungen für diese AI-Assistenteninstanz.", "data": { - "model": "KI-Modell", - "temperature": "Antwortkreativität (0-2)", - "max_tokens": "Maximale Antwortlänge (1-4096)", - "request_interval": "Mindestzeitraum zwischen Anfragen (0,1-60 Sekunden)", + "model": "AI-Modell", + "temperature": "Kreativität der Antwort (0-2)", + "max_tokens": "Maximale Länge der Antwort (1-4096)", + "request_interval": "Minimale Anfrageintervall (0,1-60 Sekunden)", "context_messages": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)", - "max_history_size": "Maximale Größe des Konversationsverlaufs (1-100)" + "max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (kompatibel)", + "anthropic": "Anthropic (kompatibel)" + } + } + }, "services": { "ask_question": { "name": "Frage stellen (HA Text AI)", - "description": "Senden Sie eine Frage an das KI-Modell und erhalten Sie eine detaillierte Antwort. Die Antwort wird im Konversationsverlauf gespeichert und kann später abgerufen werden.", + "description": "Stellen Sie eine Frage an das AI-Modell und erhalten Sie eine detaillierte Antwort. Die Antwort wird im Gesprächsverlauf gespeichert und kann später abgerufen werden.", "fields": { "instance": { "name": "Instanz", @@ -74,43 +104,43 @@ }, "question": { "name": "Frage", - "description": "Ihre Frage oder Aufforderung an den KI-Assistenten" + "description": "Ihre Frage oder Aufforderung für den AI-Assistenten" }, "context_messages": { "name": "Kontextnachrichten", "description": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)" }, "system_prompt": { - "name": "Systemprompt", - "description": "Optionaler Systemprompt, um den Kontext für diese spezielle Frage festzulegen" + "name": "Systemaufforderung", + "description": "Optionale Systemaufforderung zur Festlegung des Kontexts für diese spezifische Frage" }, "model": { "name": "Modell", - "description": "Wählen Sie das zu verwendende KI-Modell aus (optional, überschreibt die Standardeinstellung)" + "description": "Wählen Sie das zu verwendende AI-Modell (optional, überschreibt die Standardeinstellung)" }, "temperature": { "name": "Temperatur", - "description": "Steuert die Antwortkreativität (0.0-2.0)" + "description": "Steuert die Kreativität der Antwort (0,0-2,0)" }, "max_tokens": { - "name": "Max. Token", + "name": "Max Tokens", "description": "Maximale Länge der Antwort (1-4096 Token)" } } }, "clear_history": { "name": "Verlauf löschen", - "description": "Alle gespeicherten Fragen und Antworten aus dem Konversationsverlauf löschen", + "description": "Löschen Sie alle gespeicherten Fragen und Antworten aus dem Gesprächsverlauf", "fields": { "instance": { "name": "Instanz", - "description": "Name der HA Text AI-Instanz, deren Verlauf gelöscht werden soll" + "description": "Name der HA Text AI-Instanz, für die der Verlauf gelöscht werden soll" } } }, "get_history": { "name": "Verlauf abrufen", - "description": "Konversationsverlauf mit optionalem Filtern und Sortieren abrufen", + "description": "Rufen Sie den Gesprächsverlauf mit optionaler Filterung und Sortierung ab", "fields": { "instance": { "name": "Instanz", @@ -118,19 +148,19 @@ }, "limit": { "name": "Limit", - "description": "Anzahl der zurückzugebenden Konversationen (1-100)" + "description": "Anzahl der zurückzugebenden Gespräche (1-100)" }, "filter_model": { "name": "Modell filtern", - "description": "Konversationen nach einem bestimmten KI-Modell filtern" + "description": "Gespräche nach spezifischem AI-Modell filtern" }, "start_date": { "name": "Startdatum", - "description": "Konversationen ab diesem Datum/Uhrzeit filtern" + "description": "Gespräche ab diesem Datum/Zeit filtern" }, "include_metadata": { - "name": "Metadaten einschließen", - "description": "Zusätzliche Informationen wie verwendete Token, Antwortzeit usw. einschließen" + "name": "Metadaten einbeziehen", + "description": "Zusätzliche Informationen wie verwendete Tokens, Antwortzeit usw. einbeziehen" }, "sort_order": { "name": "Sortierreihenfolge", @@ -139,16 +169,16 @@ } }, "set_system_prompt": { - "name": "Systemprompt festlegen", - "description": "Legen Sie Standardanweisungen für das Systemverhalten für alle zukünftigen Konversationen fest", + "name": "Systemaufforderung festlegen", + "description": "Standardverhaltensanweisungen für alle zukünftigen Gespräche festlegen", "fields": { "instance": { "name": "Instanz", - "description": "Name der HA Text AI-Instanz, für die der Systemprompt festgelegt werden soll" + "description": "Name der HA Text AI-Instanz, für die die Systemaufforderung festgelegt werden soll" }, "prompt": { - "name": "Systemprompt", - "description": "Anweisungen, die definieren, wie sich die KI verhalten und antworten soll" + "name": "Systemaufforderung", + "description": "Anweisungen, die definieren, wie die AI sich verhalten und antworten soll" } } } @@ -162,11 +192,11 @@ "processing": "Verarbeitung", "error": "Fehler", "disconnected": "Getrennt", - "rate_limited": "Ratenlimit", + "rate_limited": "Rate limitiert", "maintenance": "Wartung", "initializing": "Initialisierung", "retrying": "Wiederholen", - "queued": "Warteschlange" + "queued": "In der Warteschlange" }, "state_attributes": { "question": { @@ -182,16 +212,16 @@ "name": "Temperatur" }, "max_tokens": { - "name": "Max. Token" + "name": "Max Tokens" }, "system_prompt": { - "name": "Systemprompt" + "name": "Systemaufforderung" }, "response_time": { "name": "Letzte Antwortzeit" }, "total_responses": { - "name": "Gesamtzahl der Antworten" + "name": "Gesamtantworten" }, "error_count": { "name": "Fehleranzahl" @@ -203,19 +233,19 @@ "name": "API-Status" }, "tokens_used": { - "name": "Verwendete Token insgesamt" + "name": "Gesamte verwendete Tokens" }, "average_response_time": { "name": "Durchschnittliche Antwortzeit" }, "last_request_time": { - "name": "Zeitpunkt der letzten Anfrage" + "name": "Letzte Anfragezeit" }, "is_processing": { "name": "Verarbeitungsstatus" }, "is_rate_limited": { - "name": "Ratenlimit-Status" + "name": "Rate-limitiert Status" }, "is_maintenance": { "name": "Wartungsstatus" @@ -224,25 +254,25 @@ "name": "API-Version" }, "endpoint_status": { - "name": "Endpunkt-Status" + "name": "Endpunktstatus" }, "performance_metrics": { - "name": "Leistungsmetriken" + "name": "Leistungskennzahlen" }, "history_size": { - "name": "Verlaufsgröße" + "name": "Größe des Verlaufs" }, "uptime": { "name": "Betriebszeit" }, "total_tokens": { - "name": "Gesamtzahl der Token" + "name": "Gesamte Tokens" }, "prompt_tokens": { - "name": "Prompt-Token" + "name": "Eingabe Tokens" }, "completion_tokens": { - "name": "Completion-Token" + "name": "Vervollständigungs Tokens" }, "successful_requests": { "name": "Erfolgreiche Anfragen" diff --git a/custom_components/ha_text_ai/translations/en.json b/custom_components/ha_text_ai/translations/en.json index 99a87c5..1dee1d5 100644 --- a/custom_components/ha_text_ai/translations/en.json +++ b/custom_components/ha_text_ai/translations/en.json @@ -6,7 +6,23 @@ "description": "Choose which AI service provider to use for this instance.", "data": { "api_provider": "API Provider", - "context_messages": "Number of context messages to retain (1-20)" + "context_messages": "Number of context messages to retain (1-20)", + "max_history_size": "Maximum conversation history size (1-100)" + } + }, + "provider": { + "title": "Provider Settings", + "description": "Provide connection details for your chosen AI provider.", + "data": { + "name": "Instance name (e.g., 'GPT Assistant', 'Claude Helper')", + "api_key": "API key for authentication", + "model": "AI model to use", + "api_endpoint": "Custom API endpoint URL (optional)", + "temperature": "Response creativity (0-2, lower = more focused)", + "max_tokens": "Maximum response length (1-4096 tokens)", + "request_interval": "Minimum time between requests (0.1-60 seconds)", + "context_messages": "Number of context messages to retain (1-20)", + "max_history_size": "Maximum conversation history size (1-100)" } }, "user": { @@ -27,6 +43,9 @@ } }, "error": { + "history_storage_error": "Failed to initialize history storage. Check permissions.", + "history_rotation_error": "Error during history file rotation.", + "history_file_access_error": "Cannot access history storage directory.", "name_exists": "An instance with this name already exists", "invalid_name": "Invalid instance name", "invalid_auth": "Authentication failed - check your API key", @@ -45,6 +64,9 @@ "empty": "Name cannot be empty", "invalid_characters": "Name can only contain letters, numbers, spaces, underscores and hyphens", "name_too_long": "Name must be 50 characters or less" + }, + "abort": { + "already_configured": "Instance already configured" } }, "options": { @@ -63,6 +85,14 @@ } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (compatible)", + "anthropic": "Anthropic (compatible)" + } + } +}, "services": { "ask_question": { "name": "Ask Question (HA Text AI)", diff --git a/custom_components/ha_text_ai/translations/es.json b/custom_components/ha_text_ai/translations/es.json index c978350..379aac6 100644 --- a/custom_components/ha_text_ai/translations/es.json +++ b/custom_components/ha_text_ai/translations/es.json @@ -3,151 +3,181 @@ "step": { "provider": { "title": "Seleccionar proveedor de IA", - "description": "Elige qué proveedor de servicios de IA usar para esta instancia.", + "description": "Elige qué proveedor de servicio de IA utilizar para esta instancia.", "data": { "api_provider": "Proveedor de API", - "context_messages": "Número de mensajes de contexto que conservar (1-20)" + "context_messages": "Número de mensajes de contexto a retener (1-20)", + "max_history_size": "Tamaño máximo del historial de conversación (1-100)" + } + }, + "provider": { + "title": "Configuración del proveedor", + "description": "Proporciona los detalles de conexión para tu proveedor de IA elegido.", + "data": { + "name": "Nombre de la instancia (por ejemplo, 'Asistente GPT', 'Ayudante Claude')", + "api_key": "Clave API para autenticación", + "model": "Modelo de IA a utilizar", + "api_endpoint": "URL del endpoint de API personalizado (opcional)", + "temperature": "Creatividad de la respuesta (0-2, menor = más enfocado)", + "max_tokens": "Longitud máxima de la respuesta (1-4096 tokens)", + "request_interval": "Tiempo mínimo entre solicitudes (0.1-60 segundos)", + "context_messages": "Número de mensajes de contexto a retener (1-20)", + "max_history_size": "Tamaño máximo del historial de conversación (1-100)" } }, "user": { - "title": "Configurar instancia de HA Text AI", - "description": "Configura una nueva instancia de asistente de IA con el proveedor seleccionado.", + "title": "Configurar instancia de IA de texto de HA", + "description": "Configura una nueva instancia de asistente de IA con tu proveedor seleccionado.", "data": { - "name": "Nombre de la instancia (p. ej., 'Asistente GPT', 'Ayudante de Claude')", - "api_key": "Clave API para la autenticación", - "model": "Modelo de IA a usar", - "temperature": "Creatividad de la respuesta (0-2, cuanto menor, más enfocada)", + "name": "Nombre de la instancia (por ejemplo, 'Asistente GPT', 'Ayudante Claude')", + "api_key": "Clave API para autenticación", + "model": "Modelo de IA a utilizar", + "temperature": "Creatividad de la respuesta (0-2, menor = más enfocado)", "max_tokens": "Longitud máxima de la respuesta (1-4096 tokens)", - "api_endpoint": "URL del punto final de la API personalizada (opcional)", + "api_endpoint": "URL del endpoint de API personalizado (opcional)", "api_provider": "Proveedor de API", - "request_interval": "Tiempo mínimo entre solicitudes (0,1-60 segundos)", - "context_messages": "Número de mensajes de contexto que conservar (1-20)", + "request_interval": "Tiempo mínimo entre solicitudes (0.1-60 segundos)", + "context_messages": "Número de mensajes de contexto a retener (1-20)", "max_history_size": "Tamaño máximo del historial de conversación (1-100)" } } }, "error": { + "history_storage_error": "Error al inicializar el almacenamiento del historial. Verifica los permisos.", + "history_rotation_error": "Error durante la rotación del archivo de historial.", + "history_file_access_error": "No se puede acceder al directorio de almacenamiento del historial.", "name_exists": "Ya existe una instancia con este nombre", "invalid_name": "Nombre de instancia no válido", - "invalid_auth": "Error de autenticación: comprueba tu clave API", - "invalid_api_key": "Clave API no válida: verifica tus credenciales", - "cannot_connect": "No se pudo conectar al servicio API", + "invalid_auth": "La autenticación falló - verifica tu clave API", + "invalid_api_key": "Clave API no válida - verifica tus credenciales", + "cannot_connect": "Error al conectar con el servicio de API", "invalid_model": "El modelo seleccionado no está disponible", "rate_limit": "Límite de tasa excedido", - "context_length": "Longitud de contexto excedida", + "context_length": "Longitud del contexto excedida", "rate_limit_exceeded": "Límite de tasa de API excedido", "maintenance": "El servicio está en mantenimiento", - "invalid_response": "Se recibió una respuesta de API no válida", - "api_error": "Se produjo un error en el servicio API", - "timeout": "Tiempo de espera de la solicitud agotado", - "invalid_instance": "Instancia especificada no válida", - "unknown": "Se produjo un error inesperado", + "invalid_response": "Respuesta de API no válida recibida", + "api_error": "Ocurrió un error en el servicio de API", + "timeout": "Se agotó el tiempo de la solicitud", + "invalid_instance": "Instancia no válida especificada", + "unknown": "Ocurrió un error inesperado", "empty": "El nombre no puede estar vacío", "invalid_characters": "El nombre solo puede contener letras, números, espacios, guiones bajos y guiones", "name_too_long": "El nombre debe tener 50 caracteres o menos" + }, + "abort": { + "already_configured": "Instancia ya configurada" } }, "options": { "step": { "init": { "title": "Actualizar configuración de la instancia", - "description": "Modifica la configuración de esta instancia de asistente de IA.", + "description": "Modifica la configuración para esta instancia de asistente de IA.", "data": { "model": "Modelo de IA", "temperature": "Creatividad de la respuesta (0-2)", "max_tokens": "Longitud máxima de la respuesta (1-4096)", - "request_interval": "Intervalo mínimo de solicitud (0,1-60 segundos)", - "context_messages": "Número de mensajes anteriores que se incluirán en el contexto (1-20)", + "request_interval": "Intervalo mínimo de solicitud (0.1-60 segundos)", + "context_messages": "Número de mensajes anteriores a incluir en el contexto (1-20)", "max_history_size": "Tamaño máximo del historial de conversación (1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (compatible)", + "anthropic": "Anthropic (compatible)" + } + } + }, "services": { "ask_question": { - "name": "Hacer pregunta (HA Text AI)", + "name": "Hacer Pregunta (IA de Texto de HA)", "description": "Envía una pregunta al modelo de IA y recibe una respuesta detallada. La respuesta se almacenará en el historial de conversación y se podrá recuperar más tarde.", "fields": { "instance": { "name": "Instancia", - "description": "Nombre de la instancia de HA Text AI a utilizar" + "description": "Nombre de la instancia de IA de Texto de HA a utilizar" }, "question": { "name": "Pregunta", - "description": "Tu pregunta o indicación para el asistente de IA" + "description": "Tu pregunta o solicitud para el asistente de IA" }, "context_messages": { - "name": "Mensajes de contexto", - "description": "Número de mensajes anteriores que se incluirán en el contexto (1-20)" + "name": "Mensajes de Contexto", + "description": "Número de mensajes anteriores a incluir en el contexto (1-20)" }, "system_prompt": { - "name": "Indicación del sistema", - "description": "Indicación del sistema opcional para establecer el contexto de esta pregunta específica" + "name": "Indicaciones del Sistema", + "description": "Indicaciones opcionales para establecer contexto para esta pregunta específica" }, "model": { "name": "Modelo", - "description": "Selecciona el modelo de IA que se va a utilizar (opcional, anula la configuración predeterminada)" + "description": "Selecciona el modelo de IA a utilizar (opcional, anula la configuración predeterminada)" }, "temperature": { "name": "Temperatura", "description": "Controla la creatividad de la respuesta (0.0-2.0)" }, "max_tokens": { - "name": "Máx. tokens", + "name": "Máx. Tokens", "description": "Longitud máxima de la respuesta (1-4096 tokens)" } } }, "clear_history": { - "name": "Borrar historial", + "name": "Borrar Historial", "description": "Elimina todas las preguntas y respuestas almacenadas del historial de conversación", "fields": { "instance": { "name": "Instancia", - "description": "Nombre de la instancia de HA Text AI para la que se va a borrar el historial" + "description": "Nombre de la instancia de IA de Texto de HA para borrar el historial" } } }, "get_history": { - "name": "Obtener historial", - "description": "Recupera el historial de conversaciones con filtrado y ordenación opcionales", + "name": "Obtener Historial", + "description": "Recupera el historial de conversación con filtrado y ordenación opcionales", "fields": { "instance": { "name": "Instancia", - "description": "Nombre de la instancia de HA Text AI de la que se va a obtener el historial" + "description": "Nombre de la instancia de IA de Texto de HA para obtener historial" }, "limit": { "name": "Límite", - "description": "Número de conversaciones que se van a devolver (1-100)" + "description": "Número de conversaciones a devolver (1-100)" }, "filter_model": { - "name": "Filtrar modelo", - "description": "Filtra las conversaciones por un modelo de IA específico" + "name": "Filtrar Modelo", + "description": "Filtrar conversaciones por modelo de IA específico" }, "start_date": { - "name": "Fecha de inicio", - "description": "Filtra las conversaciones a partir de esta fecha/hora" + "name": "Fecha de Inicio", + "description": "Filtrar conversaciones a partir de esta fecha/hora" }, "include_metadata": { - "name": "Incluir metadatos", - "description": "Incluir información adicional como los tokens utilizados, el tiempo de respuesta, etc." + "name": "Incluir Metadatos", + "description": "Incluir información adicional como tokens utilizados, tiempo de respuesta, etc." }, "sort_order": { - "name": "Orden de clasificación", - "description": "Orden de clasificación de los resultados (más recientes o más antiguos primero)" + "name": "Orden de Clasificación", + "description": "Orden de clasificación para los resultados (más recientes o más antiguos primero)" } } }, "set_system_prompt": { - "name": "Establecer indicación del sistema", - "description": "Establece instrucciones predeterminadas de comportamiento del sistema para todas las conversaciones futuras", + "name": "Establecer Indicaciones del Sistema", + "description": "Establecer instrucciones de comportamiento del sistema predeterminadas para todas las futuras conversaciones", "fields": { "instance": { "name": "Instancia", - "description": "Nombre de la instancia de HA Text AI para la que se va a establecer la indicación del sistema" + "description": "Nombre de la instancia de IA de Texto de HA para establecer indicaciones del sistema" }, "prompt": { - "name": "Indicación del sistema", + "name": "Indicaciones del Sistema", "description": "Instrucciones que definen cómo debe comportarse y responder la IA" } } @@ -162,7 +192,7 @@ "processing": "Procesando", "error": "Error", "disconnected": "Desconectado", - "rate_limited": "Límite de tasa alcanzado", + "rate_limited": "Limitado por tasa", "maintenance": "Mantenimiento", "initializing": "Inicializando", "retrying": "Reintentando", @@ -170,94 +200,94 @@ }, "state_attributes": { "question": { - "name": "Última pregunta" + "name": "Última Pregunta" }, "response": { - "name": "Última respuesta" + "name": "Última Respuesta" }, "model": { - "name": "Modelo actual" + "name": "Modelo Actual" }, "temperature": { "name": "Temperatura" }, "max_tokens": { - "name": "Máx. tokens" + "name": "Máx. Tokens" }, "system_prompt": { - "name": "Indicación del sistema" + "name": "Indicaciones del Sistema" }, "response_time": { - "name": "Tiempo de la última respuesta" + "name": "Último Tiempo de Respuesta" }, "total_responses": { - "name": "Total de respuestas" + "name": "Total de Respuestas" }, "error_count": { - "name": "Recuento de errores" + "name": "Conteo de Errores" }, "last_error": { - "name": "Último error" + "name": "Último Error" }, "api_status": { - "name": "Estado de la API" + "name": "Estado de API" }, "tokens_used": { - "name": "Total de tokens usados" + "name": "Total de Tokens Usados" }, "average_response_time": { - "name": "Tiempo medio de respuesta" + "name": "Tiempo de Respuesta Promedio" }, "last_request_time": { - "name": "Tiempo de la última solicitud" + "name": "Último Tiempo de Solicitud" }, "is_processing": { - "name": "Estado de procesamiento" + "name": "Estado de Procesamiento" }, "is_rate_limited": { - "name": "Estado de límite de tasa" + "name": "Estado Limitado por Tasa" }, "is_maintenance": { - "name": "Estado de mantenimiento" + "name": "Estado de Mantenimiento" }, "api_version": { - "name": "Versión de la API" + "name": "Versión de API" }, "endpoint_status": { - "name": "Estado del punto final" + "name": "Estado del Endpoint" }, "performance_metrics": { - "name": "Métricas de rendimiento" + "name": "Métricas de Rendimiento" }, "history_size": { - "name": "Tamaño del historial" + "name": "Tamaño del Historial" }, "uptime": { - "name": "Tiempo de actividad" + "name": "Tiempo de Actividad" }, "total_tokens": { - "name": "Total de tokens" + "name": "Total de Tokens" }, "prompt_tokens": { - "name": "Tokens de indicación" + "name": "Tokens de Solicitud" }, "completion_tokens": { - "name": "Tokens de compleción" + "name": "Tokens de Finalización" }, "successful_requests": { - "name": "Solicitudes exitosas" + "name": "Solicitudes Exitosas" }, "failed_requests": { - "name": "Solicitudes fallidas" + "name": "Solicitudes Fallidas" }, "average_latency": { - "name": "Latencia media" + "name": "Latencia Promedio" }, "max_latency": { - "name": "Latencia máxima" + "name": "Latencia Máxima" }, "min_latency": { - "name": "Latencia mínima" + "name": "Latencia Mínima" } } } diff --git a/custom_components/ha_text_ai/translations/hi.json b/custom_components/ha_text_ai/translations/hi.json index fbf576b..40cd584 100644 --- a/custom_components/ha_text_ai/translations/hi.json +++ b/custom_components/ha_text_ai/translations/hi.json @@ -2,79 +2,109 @@ "config": { "step": { "provider": { - "title": "AI प्रदाता का चयन करें", - "description": "इस उदाहरण के लिए उपयोग करने के लिए AI सेवा प्रदाता चुनें।", + "title": "एआई प्रदाता चुनें", + "description": "इस उदाहरण के लिए किस एआई सेवा प्रदाता का उपयोग करना है, चुनें।", "data": { - "api_provider": "API प्रदाता", - "context_messages": "बनाए रखने के लिए संदर्भ संदेशों की संख्या (1-20)" + "api_provider": "एपीआई प्रदाता", + "context_messages": "रखने के लिए संदर्भ संदेशों की संख्या (1-20)", + "max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)" + } + }, + "provider": { + "title": "प्रदाता सेटिंग्स", + "description": "आपके द्वारा चुने गए एआई प्रदाता के लिए कनेक्शन विवरण प्रदान करें।", + "data": { + "name": "उदाहरण का नाम (जैसे, 'जीपीटी सहायक', 'क्लॉड सहायक')", + "api_key": "प्रमाणीकरण के लिए एपीआई कुंजी", + "model": "उपयोग करने के लिए एआई मॉडल", + "api_endpoint": "कस्टम एपीआई एंडपॉइंट यूआरएल (वैकल्पिक)", + "temperature": "प्रतिक्रिया की रचनात्मकता (0-2, कम = अधिक केंद्रित)", + "max_tokens": "प्रतिक्रिया की अधिकतम लंबाई (1-4096 टोकन)", + "request_interval": "अनुरोधों के बीच न्यूनतम समय (0.1-60 सेकंड)", + "context_messages": "रखने के लिए संदर्भ संदेशों की संख्या (1-20)", + "max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)" } }, "user": { - "title": "HA टेक्स्ट AI उदाहरण को कॉन्फ़िगर करें", - "description": "अपने चयनित प्रदाता के साथ एक नया AI सहायक उदाहरण सेट करें।", + "title": "एचए टेक्स्ट एआई उदाहरण कॉन्फ़िगर करें", + "description": "अपने चुने हुए प्रदाता के साथ एक नया एआई सहायक उदाहरण सेट करें।", "data": { - "name": "उदाहरण का नाम (जैसे, 'GPT सहायक', 'क्लाउड सहायक')", - "api_key": "प्रमाणीकरण के लिए API कुंजी", - "model": "उपयोग करने के लिए AI मॉडल", - "temperature": "प्रतिक्रिया रचनात्मकता (0-2, कम = अधिक केंद्रित)", - "max_tokens": "अधिकतम प्रतिक्रिया लंबाई (1-4096 टोकन)", - "api_endpoint": "कस्टम API एंडपॉइंट URL (वैकल्पिक)", - "api_provider": "API प्रदाता", + "name": "उदाहरण का नाम (जैसे, 'जीपीटी सहायक', 'क्लॉड सहायक')", + "api_key": "प्रमाणीकरण के लिए एपीआई कुंजी", + "model": "उपयोग करने के लिए एआई मॉडल", + "temperature": "प्रतिक्रिया की रचनात्मकता (0-2, कम = अधिक केंद्रित)", + "max_tokens": "प्रतिक्रिया की अधिकतम लंबाई (1-4096 टोकन)", + "api_endpoint": "कस्टम एपीआई एंडपॉइंट यूआरएल (वैकल्पिक)", + "api_provider": "एपीआई प्रदाता", "request_interval": "अनुरोधों के बीच न्यूनतम समय (0.1-60 सेकंड)", - "context_messages": "बनाए रखने के लिए संदर्भ संदेशों की संख्या (1-20)", - "max_history_size": "अधिकतम वार्तालाप इतिहास आकार (1-100)" + "context_messages": "रखने के लिए संदर्भ संदेशों की संख्या (1-20)", + "max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)" } } }, "error": { - "name_exists": "इस नाम का एक उदाहरण पहले से मौजूद है", + "history_storage_error": "इतिहास भंडारण प्रारंभ करने में विफल। अनुमतियों की जांच करें।", + "history_rotation_error": "इतिहास फ़ाइल घुमाने के दौरान त्रुटि।", + "history_file_access_error": "इतिहास भंडारण निर्देशिका तक पहुंच नहीं है।", + "name_exists": "इस नाम के साथ एक उदाहरण पहले से मौजूद है", "invalid_name": "अमान्य उदाहरण नाम", - "invalid_auth": "प्रमाणीकरण विफल - अपनी API कुंजी जांचें", - "invalid_api_key": "अमान्य API कुंजी - कृपया अपनी क्रेडेंशियल सत्यापित करें", - "cannot_connect": "API सेवा से कनेक्ट करने में विफल", - "invalid_model": "चयनित मॉडल उपलब्ध नहीं है", - "rate_limit": "दर सीमा पार हो गई", - "context_length": "संदर्भ लंबाई पार हो गई", - "rate_limit_exceeded": "API दर सीमा पार हो गई", - "maintenance": "सेवा रखरखाव के अधीन है", - "invalid_response": "अमान्य API प्रतिक्रिया प्राप्त हुई", - "api_error": "API सेवा त्रुटि हुई", - "timeout": "अनुरोध समय समाप्त हो गया", + "invalid_auth": "प्रमाणीकरण विफल - अपनी एपीआई कुंजी की जांच करें", + "invalid_api_key": "अमान्य एपीआई कुंजी - कृपया अपनी क्रेडेंशियल्स की पुष्टि करें", + "cannot_connect": "एपीआई सेवा से कनेक्ट करने में विफल", + "invalid_model": "चुना हुआ मॉडल उपलब्ध नहीं है", + "rate_limit": "रेट सीमा पार", + "context_length": "संदर्भ लंबाई पार", + "rate_limit_exceeded": "एपीआई रेट सीमा पार", + "maintenance": "सेवा रखरखाव में है", + "invalid_response": "अमान्य एपीआई प्रतिक्रिया प्राप्त हुई", + "api_error": "एपीआई सेवा में त्रुटि हुई", + "timeout": "अनुरोध समय सीमा समाप्त", "invalid_instance": "अमान्य उदाहरण निर्दिष्ट किया गया", "unknown": "अप्रत्याशित त्रुटि हुई", "empty": "नाम खाली नहीं हो सकता", - "invalid_characters": "नाम में केवल अक्षर, संख्या, रिक्त स्थान, अंडरस्कोर और हाइफ़न हो सकते हैं", - "name_too_long": "नाम 50 वर्ण या उससे कम होना चाहिए" + "invalid_characters": "नाम में केवल अक्षर, अंक, रिक्त स्थान, अंडरस्कोर और हाइफन हो सकते हैं", + "name_too_long": "नाम 50 अक्षरों या उससे कम होना चाहिए" + }, + "abort": { + "already_configured": "उदाहरण पहले से कॉन्फ़िगर किया गया है" } }, "options": { "step": { "init": { "title": "उदाहरण सेटिंग्स अपडेट करें", - "description": "इस AI सहायक उदाहरण के लिए सेटिंग्स संशोधित करें।", + "description": "इस एआई सहायक उदाहरण के लिए सेटिंग्स संशोधित करें।", "data": { - "model": "AI मॉडल", - "temperature": "प्रतिक्रिया रचनात्मकता (0-2)", - "max_tokens": "अधिकतम प्रतिक्रिया लंबाई (1-4096)", + "model": "एआई मॉडल", + "temperature": "प्रतिक्रिया की रचनात्मकता (0-2)", + "max_tokens": "प्रतिक्रिया की अधिकतम लंबाई (1-4096)", "request_interval": "न्यूनतम अनुरोध अंतराल (0.1-60 सेकंड)", "context_messages": "संदर्भ में शामिल करने के लिए पिछले संदेशों की संख्या (1-20)", - "max_history_size": "अधिकतम वार्तालाप इतिहास आकार (1-100)" + "max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (अनुकूलित)", + "anthropic": "Anthropic (अनुकूलित)" + } + } + }, "services": { "ask_question": { - "name": "प्रश्न पूछें (HA टेक्स्ट AI)", - "description": "AI मॉडल को एक प्रश्न भेजें और एक विस्तृत प्रतिक्रिया प्राप्त करें। प्रतिक्रिया वार्तालाप इतिहास में संग्रहीत की जाएगी और बाद में पुनर्प्राप्त की जा सकती है।", + "name": "प्रश्न पूछें (एचए टेक्स्ट एआई)", + "description": "एआई मॉडल को एक प्रश्न भेजें और विस्तृत प्रतिक्रिया प्राप्त करें। प्रतिक्रिया बातचीत के इतिहास में संग्रहीत की जाएगी और बाद में पुनर्प्राप्त की जा सकती है।", "fields": { "instance": { "name": "उदाहरण", - "description": "उपयोग करने के लिए HA टेक्स्ट AI उदाहरण का नाम" + "description": "उपयोग करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम" }, "question": { "name": "प्रश्न", - "description": "AI सहायक के लिए आपका प्रश्न या संकेत" + "description": "आपका प्रश्न या एआई सहायक के लिए प्रॉम्प्ट" }, "context_messages": { "name": "संदर्भ संदेश", @@ -82,15 +112,15 @@ }, "system_prompt": { "name": "सिस्टम प्रॉम्प्ट", - "description": "इस विशिष्ट प्रश्न के लिए संदर्भ सेट करने के लिए वैकल्पिक सिस्टम प्रॉम्प्ट" + "description": "इस विशेष प्रश्न के लिए संदर्भ सेट करने के लिए वैकल्पिक सिस्टम प्रॉम्प्ट" }, "model": { "name": "मॉडल", - "description": "उपयोग करने के लिए AI मॉडल का चयन करें (वैकल्पिक, डिफ़ॉल्ट सेटिंग को ओवरराइड करता है)" + "description": "उपयोग करने के लिए एआई मॉडल का चयन करें (वैकल्पिक, डिफ़ॉल्ट सेटिंग को ओवरराइड करता है)" }, "temperature": { "name": "तापमान", - "description": "प्रतिक्रिया रचनात्मकता को नियंत्रित करता है (0.0-2.0)" + "description": "प्रतिक्रिया की रचनात्मकता को नियंत्रित करता है (0.0-2.0)" }, "max_tokens": { "name": "अधिकतम टोकन", @@ -99,56 +129,56 @@ } }, "clear_history": { - "name": "इतिहास साफ़ करें", - "description": "वार्तालाप इतिहास से सभी संग्रहीत प्रश्न और प्रतिक्रियाएँ हटाएँ", + "name": "इतिहास साफ करें", + "description": "बातचीत के इतिहास से सभी संग्रहीत प्रश्नों और प्रतिक्रियाओं को हटाएं", "fields": { "instance": { "name": "उदाहरण", - "description": "इतिहास साफ़ करने के लिए HA टेक्स्ट AI उदाहरण का नाम" + "description": "इतिहास साफ़ करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम" } } }, "get_history": { "name": "इतिहास प्राप्त करें", - "description": "वैकल्पिक फ़िल्टरिंग और सॉर्टिंग के साथ वार्तालाप इतिहास पुनर्प्राप्त करें", + "description": "वैकल्पिक फ़िल्टरिंग और छंटाई के साथ बातचीत का इतिहास प्राप्त करें", "fields": { "instance": { "name": "उदाहरण", - "description": "इतिहास प्राप्त करने के लिए HA टेक्स्ट AI उदाहरण का नाम" + "description": "इतिहास प्राप्त करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम" }, "limit": { "name": "सीमा", - "description": "वापस करने के लिए वार्तालापों की संख्या (1-100)" + "description": "वापस करने के लिए बातचीत की संख्या (1-100)" }, "filter_model": { - "name": "फ़िल्टर मॉडल", - "description": "विशिष्ट AI मॉडल द्वारा वार्तालापों को फ़िल्टर करें" + "name": "फिल्टर मॉडल", + "description": "विशिष्ट एआई मॉडल द्वारा बातचीत को फ़िल्टर करें" }, "start_date": { - "name": "प्रारंभ तिथि", - "description": "इस तिथि/समय से शुरू होने वाले वार्तालापों को फ़िल्टर करें" + "name": "शुरुआत की तारीख", + "description": "इस दिन/समय से शुरू होने वाली बातचीत को फ़िल्टर करें" }, "include_metadata": { "name": "मेटाडेटा शामिल करें", - "description": "उपयोग किए गए टोकन, प्रतिक्रिया समय, आदि जैसी अतिरिक्त जानकारी शामिल करें।" + "description": "उपयोग किए गए टोकन, प्रतिक्रिया समय आदि जैसी अतिरिक्त जानकारी शामिल करें।" }, "sort_order": { - "name": "क्रमबद्ध करें", - "description": "परिणामों के लिए क्रमबद्ध क्रम (नवीनतम या सबसे पुराना पहले)" + "name": "छंटाई क्रम", + "description": "परिणामों के लिए छंटाई क्रम (नवीनतम या सबसे पुराना पहले)" } } }, "set_system_prompt": { "name": "सिस्टम प्रॉम्प्ट सेट करें", - "description": "सभी भविष्य के वार्तालापों के लिए डिफ़ॉल्ट सिस्टम व्यवहार निर्देश सेट करें", + "description": "सभी भविष्य की बातचीत के लिए डिफ़ॉल्ट सिस्टम व्यवहार निर्देश सेट करें", "fields": { "instance": { "name": "उदाहरण", - "description": "सिस्टम प्रॉम्प्ट सेट करने के लिए HA टेक्स्ट AI उदाहरण का नाम" + "description": "सिस्टम प्रॉम्प्ट सेट करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम" }, "prompt": { "name": "सिस्टम प्रॉम्प्ट", - "description": "निर्देश जो परिभाषित करते हैं कि AI को कैसे व्यवहार करना चाहिए और जवाब देना चाहिए" + "description": "निर्देश जो यह परिभाषित करते हैं कि एआई को कैसे व्यवहार करना चाहिए और प्रतिक्रिया देनी चाहिए" } } } @@ -159,14 +189,14 @@ "name": "{name}", "state": { "ready": "तैयार", - "processing": "प्रक्रियाधीन", + "processing": "प्रसंस्करण", "error": "त्रुटि", - "disconnected": "डिस्कनेक्टेड", - "rate_limited": "दर सीमित", + "disconnected": "असंयुक्त", + "rate_limited": "रेट सीमित", "maintenance": "रखरखाव", - "initializing": "आरंभिकरण", + "initializing": "प्रारंभिककरण", "retrying": "पुनः प्रयास कर रहा है", - "queued": "कतारबद्ध" + "queued": "क्यू में" }, "state_attributes": { "question": { @@ -188,46 +218,46 @@ "name": "सिस्टम प्रॉम्प्ट" }, "response_time": { - "name": "अंतिम प्रतिक्रिया समय" + "name": "अंतिम प्रतिक्रिया का समय" }, "total_responses": { - "name": "कुल प्रतिक्रियाएँ" + "name": "कुल प्रतिक्रियाएं" }, "error_count": { - "name": "त्रुटि गणना" + "name": "त्रुटियों की संख्या" }, "last_error": { "name": "अंतिम त्रुटि" }, "api_status": { - "name": "API स्थिति" + "name": "एपीआई स्थिति" }, "tokens_used": { - "name": "कुल टोकन उपयोग किए गए" + "name": "कुल उपयोग किए गए टोकन" }, "average_response_time": { "name": "औसत प्रतिक्रिया समय" }, "last_request_time": { - "name": "अंतिम अनुरोध समय" + "name": "अंतिम अनुरोध का समय" }, "is_processing": { "name": "प्रसंस्करण स्थिति" }, "is_rate_limited": { - "name": "दर सीमित स्थिति" + "name": "रेट सीमित स्थिति" }, "is_maintenance": { "name": "रखरखाव स्थिति" }, "api_version": { - "name": "API संस्करण" + "name": "एपीआई संस्करण" }, "endpoint_status": { "name": "एंडपॉइंट स्थिति" }, "performance_metrics": { - "name": "प्रदर्शन मेट्रिक्स" + "name": "प्रदर्शन मैट्रिक्स" }, "history_size": { "name": "इतिहास का आकार" @@ -242,13 +272,13 @@ "name": "प्रॉम्प्ट टोकन" }, "completion_tokens": { - "name": "पूर्ण टोकन" + "name": "पूर्णता टोकन" }, "successful_requests": { "name": "सफल अनुरोध" }, "failed_requests": { - "name": "असफल अनुरोध" + "name": "विफल अनुरोध" }, "average_latency": { "name": "औसत विलंबता" diff --git a/custom_components/ha_text_ai/translations/it.json b/custom_components/ha_text_ai/translations/it.json index 673fee3..c14f29c 100644 --- a/custom_components/ha_text_ai/translations/it.json +++ b/custom_components/ha_text_ai/translations/it.json @@ -2,86 +2,116 @@ "config": { "step": { "provider": { - "title": "Seleziona Provider AI", - "description": "Scegli quale provider di servizio AI utilizzare per questa istanza.", + "title": "Seleziona fornitore AI", + "description": "Scegli quale fornitore di servizi AI utilizzare per questa istanza.", "data": { - "api_provider": "Provider API", - "context_messages": "Numero di messaggi di contesto da conservare (1-20)" + "api_provider": "Fornitore API", + "context_messages": "Numero di messaggi di contesto da mantenere (1-20)", + "max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)" + } + }, + "provider": { + "title": "Impostazioni fornitore", + "description": "Fornisci i dettagli di connessione per il tuo fornitore di AI scelto.", + "data": { + "name": "Nome dell'istanza (es. 'Assistente GPT', 'Aiuto Claude')", + "api_key": "Chiave API per l'autenticazione", + "model": "Modello AI da utilizzare", + "api_endpoint": "URL dell'endpoint API personalizzato (opzionale)", + "temperature": "Creatività della risposta (0-2, più basso = più focalizzato)", + "max_tokens": "Lunghezza massima della risposta (1-4096 token)", + "request_interval": "Tempo minimo tra le richieste (0.1-60 secondi)", + "context_messages": "Numero di messaggi di contesto da mantenere (1-20)", + "max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)" } }, "user": { - "title": "Configura Istanza HA Text AI", - "description": "Configura una nuova istanza di assistente AI con il provider selezionato.", + "title": "Configura istanza AI di testo HA", + "description": "Imposta una nuova istanza di assistente AI con il fornitore selezionato.", "data": { - "name": "Nome dell'istanza (es. 'Assistente GPT', 'Aiutante Claude')", + "name": "Nome dell'istanza (es. 'Assistente GPT', 'Aiuto Claude')", "api_key": "Chiave API per l'autenticazione", "model": "Modello AI da utilizzare", "temperature": "Creatività della risposta (0-2, più basso = più focalizzato)", "max_tokens": "Lunghezza massima della risposta (1-4096 token)", - "api_endpoint": "URL endpoint API personalizzato (opzionale)", - "api_provider": "Provider API", - "request_interval": "Tempo minimo tra le richieste (0,1-60 secondi)", - "context_messages": "Numero di messaggi di contesto da conservare (1-20)", + "api_endpoint": "URL dell'endpoint API personalizzato (opzionale)", + "api_provider": "Fornitore API", + "request_interval": "Tempo minimo tra le richieste (0.1-60 secondi)", + "context_messages": "Numero di messaggi di contesto da mantenere (1-20)", "max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)" } } }, "error": { - "name_exists": "Un'istanza con questo nome esiste già", + "history_storage_error": "Impossibile inizializzare la memorizzazione della cronologia. Controlla i permessi.", + "history_rotation_error": "Errore durante la rotazione del file di cronologia.", + "history_file_access_error": "Impossibile accedere alla directory di memorizzazione della cronologia.", + "name_exists": "Esiste già un'istanza con questo nome", "invalid_name": "Nome dell'istanza non valido", "invalid_auth": "Autenticazione fallita - controlla la tua chiave API", "invalid_api_key": "Chiave API non valida - verifica le tue credenziali", "cannot_connect": "Impossibile connettersi al servizio API", "invalid_model": "Il modello selezionato non è disponibile", - "rate_limit": "Limite di velocità superato", + "rate_limit": "Limite di frequenza superato", "context_length": "Lunghezza del contesto superata", - "rate_limit_exceeded": "Limite di velocità API superato", + "rate_limit_exceeded": "Limite di frequenza API superato", "maintenance": "Il servizio è in manutenzione", "invalid_response": "Risposta API non valida ricevuta", - "api_error": "Si è verificato un errore del servizio API", + "api_error": "Si è verificato un errore nel servizio API", "timeout": "Richiesta scaduta", - "invalid_instance": "Istanza non valida specificata", + "invalid_instance": "Istanze specificata non valida", "unknown": "Si è verificato un errore imprevisto", "empty": "Il nome non può essere vuoto", "invalid_characters": "Il nome può contenere solo lettere, numeri, spazi, trattini bassi e trattini", - "name_too_long": "Il nome non può superare i 50 caratteri" + "name_too_long": "Il nome deve essere lungo 50 caratteri o meno" + }, + "abort": { + "already_configured": "Istanze già configurata" } }, "options": { "step": { "init": { - "title": "Aggiorna Impostazioni Istanza", + "title": "Aggiorna impostazioni dell'istanza", "description": "Modifica le impostazioni per questa istanza di assistente AI.", "data": { "model": "Modello AI", "temperature": "Creatività della risposta (0-2)", "max_tokens": "Lunghezza massima della risposta (1-4096)", - "request_interval": "Intervallo minimo tra le richieste (0,1-60 secondi)", + "request_interval": "Intervallo minimo di richiesta (0.1-60 secondi)", "context_messages": "Numero di messaggi precedenti da includere nel contesto (1-20)", "max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (compatibile)", + "anthropic": "Anthropic (compatibile)" + } + } + }, "services": { "ask_question": { - "name": "Fai una Domanda (HA Text AI)", - "description": "Invia una domanda al modello AI e ricevi una risposta dettagliata. La risposta verrà memorizzata nella cronologia delle conversazioni e potrà essere recuperata in seguito.", + "name": "Fai una domanda (HA Text AI)", + "description": "Invia una domanda al modello AI e ricevi una risposta dettagliata. La risposta sarà memorizzata nella cronologia delle conversazioni e potrà essere recuperata in seguito.", "fields": { "instance": { - "name": "Istanza", + "name": "Istanze", "description": "Nome dell'istanza HA Text AI da utilizzare" }, "question": { "name": "Domanda", - "description": "La tua domanda o prompt per l'assistente AI" + "description": "La tua domanda o richiesta per l'assistente AI" }, "context_messages": { - "name": "Messaggi di Contesto", + "name": "Messaggi di contesto", "description": "Numero di messaggi precedenti da includere nel contesto (1-20)" }, "system_prompt": { - "name": "Prompt di Sistema", + "name": "Prompt di sistema", "description": "Prompt di sistema opzionale per impostare il contesto per questa specifica domanda" }, "model": { @@ -93,62 +123,62 @@ "description": "Controlla la creatività della risposta (0.0-2.0)" }, "max_tokens": { - "name": "Max Token", + "name": "Token massimi", "description": "Lunghezza massima della risposta (1-4096 token)" } } }, "clear_history": { - "name": "Cancella Cronologia", - "description": "Elimina tutte le domande e le risposte memorizzate dalla cronologia delle conversazioni", + "name": "Cancella cronologia", + "description": "Elimina tutte le domande e risposte memorizzate dalla cronologia delle conversazioni", "fields": { "instance": { - "name": "Istanza", + "name": "Istanze", "description": "Nome dell'istanza HA Text AI per cui cancellare la cronologia" } } }, "get_history": { - "name": "Ottieni Cronologia", - "description": "Recupera la cronologia delle conversazioni con filtro e ordinamento opzionali", + "name": "Ottieni cronologia", + "description": "Recupera la cronologia delle conversazioni con opzioni di filtro e ordinamento", "fields": { "instance": { - "name": "Istanza", - "description": "Nome dell'istanza HA Text AI da cui ottenere la cronologia" + "name": "Istanze", + "description": "Nome dell'istanza HA Text AI da cui recuperare la cronologia" }, "limit": { "name": "Limite", "description": "Numero di conversazioni da restituire (1-100)" }, "filter_model": { - "name": "Filtro Modello", - "description": "Filtra le conversazioni per specifico modello AI" + "name": "Filtra modello", + "description": "Filtra le conversazioni per modello AI specifico" }, "start_date": { - "name": "Data di Inizio", + "name": "Data di inizio", "description": "Filtra le conversazioni a partire da questa data/ora" }, "include_metadata": { - "name": "Includi Metadati", + "name": "Includi metadati", "description": "Includi informazioni aggiuntive come token utilizzati, tempo di risposta, ecc." }, "sort_order": { - "name": "Ordine di Ordinamento", - "description": "Ordine di ordinamento per i risultati (più recente o più vecchio per primo)" + "name": "Ordine di ordinamento", + "description": "Ordine di ordinamento per i risultati (più recenti o più vecchi per primi)" } } }, "set_system_prompt": { - "name": "Imposta Prompt di Sistema", - "description": "Imposta le istruzioni di comportamento predefinite del sistema per tutte le future conversazioni", + "name": "Imposta prompt di sistema", + "description": "Imposta le istruzioni di comportamento predefinite per tutte le future conversazioni", "fields": { "instance": { - "name": "Istanza", + "name": "Istanze", "description": "Nome dell'istanza HA Text AI per cui impostare il prompt di sistema" }, "prompt": { - "name": "Prompt di Sistema", - "description": "Istruzioni che definiscono come l'IA dovrebbe comportarsi e rispondere" + "name": "Prompt di sistema", + "description": "Istruzioni che definiscono come l'AI dovrebbe comportarsi e rispondere" } } } @@ -159,108 +189,108 @@ "name": "{name}", "state": { "ready": "Pronto", - "processing": "In elaborazione", + "processing": "Elaborazione", "error": "Errore", "disconnected": "Disconnesso", - "rate_limited": "Limite di Velocità Raggiunto", + "rate_limited": "Limite di frequenza", "maintenance": "Manutenzione", "initializing": "Inizializzazione", - "retrying": "Riprovando", + "retrying": "Riprova", "queued": "In coda" }, "state_attributes": { "question": { - "name": "Ultima Domanda" + "name": "Ultima domanda" }, "response": { - "name": "Ultima Risposta" + "name": "Ultima risposta" }, "model": { - "name": "Modello Attuale" + "name": "Modello attuale" }, "temperature": { "name": "Temperatura" }, "max_tokens": { - "name": "Max Token" + "name": "Token massimi" }, "system_prompt": { - "name": "Prompt di Sistema" + "name": "Prompt di sistema" }, "response_time": { - "name": "Tempo di Risposta Ultima" + "name": "Ultimo tempo di risposta" }, "total_responses": { - "name": "Totale Risposte" + "name": "Risposte totali" }, "error_count": { - "name": "Numero di Errori" + "name": "Conteggio errori" }, "last_error": { - "name": "Ultimo Errore" + "name": "Ultimo errore" }, "api_status": { "name": "Stato API" }, "tokens_used": { - "name": "Totale Token Utilizzati" + "name": "Token totali utilizzati" }, "average_response_time": { - "name": "Tempo di Risposta Medio" + "name": "Tempo medio di risposta" }, "last_request_time": { - "name": "Tempo Ultima Richiesta" + "name": "Ultimo tempo di richiesta" }, "is_processing": { - "name": "Stato Elaborazione" + "name": "Stato di elaborazione" }, "is_rate_limited": { - "name": "Stato Limite Velocità" + "name": "Stato limite di frequenza" }, "is_maintenance": { - "name": "Stato Manutenzione" + "name": "Stato di manutenzione" }, "api_version": { "name": "Versione API" }, "endpoint_status": { - "name": "Stato Endpoint" + "name": "Stato dell'endpoint" }, "performance_metrics": { - "name": "Metriche Prestazioni" + "name": "Metriche di prestazione" }, "history_size": { - "name": "Dimensione Cronologia" + "name": "Dimensione della cronologia" }, "uptime": { - "name": "Tempo di Funzionamento" + "name": "Tempo di attività" }, "total_tokens": { - "name": "Totale Token" + "name": "Token totali" }, "prompt_tokens": { - "name": "Token Prompt" + "name": "Token di prompt" }, "completion_tokens": { - "name": "Token Completamento" + "name": "Token di completamento" }, "successful_requests": { - "name": "Richieste Riuscite" + "name": "Richieste riuscite" }, "failed_requests": { - "name": "Richieste Fallite" + "name": "Richieste fallite" }, "average_latency": { - "name": "Latency Media" + "name": "Latenza media" }, "max_latency": { - "name": "Latency Massima" + "name": "Latenza massima" }, "min_latency": { - "name": "Latency Minima" - } + "name": "Latenza minima" } } } } } +} diff --git a/custom_components/ha_text_ai/translations/ru.json b/custom_components/ha_text_ai/translations/ru.json index 906afd2..ec7cd37 100644 --- a/custom_components/ha_text_ai/translations/ru.json +++ b/custom_components/ha_text_ai/translations/ru.json @@ -2,98 +2,128 @@ "config": { "step": { "provider": { - "title": "Выбор поставщика ИИ", - "description": "Выберите поставщика услуг ИИ для этой инстанции.", + "title": "Выбор провайдера ИИ", + "description": "Выберите сервис искусственного интеллекта для этого экземпляра.", "data": { - "api_provider": "Поставщик API", - "context_messages": "Количество контекстных сообщений для сохранения (1-20)" + "api_provider": "Провайдер API", + "context_messages": "Количество сохраняемых контекстных сообщений (1-20)", + "max_history_size": "Максимальный размер истории разговора (1-100)" + } + }, + "provider": { + "title": "Настройки провайдера", + "description": "Укажите параметры подключения для выбранного провайдера ИИ.", + "data": { + "name": "Название экземпляра (например, 'GPT Помощник', 'Клод Ассистент')", + "api_key": "API-ключ для аутентификации", + "model": "Модель ИИ для использования", + "api_endpoint": "Пользовательский URL-адрес конечной точки API (необязательно)", + "temperature": "Креативность ответа (0-2, меньше = более сфокусированно)", + "max_tokens": "Максимальная длина ответа (1-4096 токенов)", + "request_interval": "Минимальный интервал между запросами (0.1-60 секунд)", + "context_messages": "Количество сохраняемых контекстных сообщений (1-20)", + "max_history_size": "Максимальный размер истории разговора (1-100)" } }, "user": { - "title": "Настройка инстанции HA Text AI", - "description": "Настройте новую инстанцию помощника ИИ с выбранным вами поставщиком.", + "title": "Настройка экземпляра текстового ИИ для Home Assistant", + "description": "Настройте новый экземпляр ИИ-помощника с выбранным провайдером.", "data": { - "name": "Имя инстанции (например, 'GPT Assistant', 'Claude Helper')", + "name": "Название экземпляра (например, 'GPT Помощник', 'Клод Ассистент')", "api_key": "API-ключ для аутентификации", - "model": "Используемая модель ИИ", - "temperature": "Креативность ответа (0-2, чем ниже, тем больше фокусировки)", + "model": "Модель ИИ для использования", + "temperature": "Креативность ответа (0-2, меньше = более сфокусированно)", "max_tokens": "Максимальная длина ответа (1-4096 токенов)", "api_endpoint": "Пользовательский URL-адрес конечной точки API (необязательно)", - "api_provider": "Поставщик API", - "request_interval": "Минимальное время между запросами (0,1-60 секунд)", - "context_messages": "Количество контекстных сообщений для сохранения (1-20)", + "api_provider": "Провайдер API", + "request_interval": "Минимальный интервал между запросами (0.1-60 секунд)", + "context_messages": "Количество сохраняемых контекстных сообщений (1-20)", "max_history_size": "Максимальный размер истории разговора (1-100)" } } }, "error": { - "name_exists": "Инстанция с таким именем уже существует", - "invalid_name": "Некорректное имя инстанции", - "invalid_auth": "Аутентификация не удалась - проверьте ваш API-ключ", - "invalid_api_key": "Неверный API-ключ - проверьте ваши учетные данные", - "cannot_connect": "Не удалось подключиться к службе API", + "history_storage_error": "Не удалось инициализировать хранилище истории. Проверьте разрешения.", + "history_rotation_error": "Ошибка при ротации файла истории.", + "history_file_access_error": "Невозможно получить доступ к директории хранения истории.", + "name_exists": "Экземпляр с таким именем уже существует", + "invalid_name": "Недопустимое имя экземпляра", + "invalid_auth": "Ошибка аутентификации - проверьте API-ключ", + "invalid_api_key": "Недопустимый API-ключ - пожалуйста, проверьте учетные данные", + "cannot_connect": "Не удалось подключиться к сервису API", "invalid_model": "Выбранная модель недоступна", "rate_limit": "Превышен лимит запросов", "context_length": "Превышена длина контекста", "rate_limit_exceeded": "Превышен лимит запросов API", "maintenance": "Сервис находится на техническом обслуживании", - "invalid_response": "Получен неверный ответ API", - "api_error": "Произошла ошибка службы API", - "timeout": "Запрос превысил время ожидания", - "invalid_instance": "Указана неверная инстанция", + "invalid_response": "Получен некорректный ответ API", + "api_error": "Произошла ошибка сервиса API", + "timeout": "Время ожидания запроса истекло", + "invalid_instance": "Указан некорректный экземпляр", "unknown": "Произошла непредвиденная ошибка", "empty": "Имя не может быть пустым", "invalid_characters": "Имя может содержать только буквы, цифры, пробелы, подчеркивания и дефисы", - "name_too_long": "Имя должно быть не более 50 символов" + "name_too_long": "Имя должно быть не длиннее 50 символов" + }, + "abort": { + "already_configured": "Экземпляр уже настроен" } }, "options": { "step": { "init": { - "title": "Обновление настроек инстанции", - "description": "Измените настройки для этой инстанции помощника ИИ.", + "title": "Обновление настроек экземпляра", + "description": "Измените настройки для этого экземпляра ИИ-помощника.", "data": { "model": "Модель ИИ", "temperature": "Креативность ответа (0-2)", "max_tokens": "Максимальная длина ответа (1-4096)", - "request_interval": "Минимальный интервал между запросами (0,1-60 секунд)", + "request_interval": "Минимальный интервал между запросами (0.1-60 секунд)", "context_messages": "Количество предыдущих сообщений для включения в контекст (1-20)", "max_history_size": "Максимальный размер истории разговора (1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (совместимый)", + "anthropic": "Anthropic (совместимый)" + } + } + }, "services": { "ask_question": { - "name": "Задать вопрос (HA Text AI)", - "description": "Отправьте вопрос модели ИИ и получите подробный ответ. Ответ будет сохранен в истории разговора и может быть извлечен позже.", + "name": "Задать вопрос (Текстовый ИИ HA)", + "description": "Отправить вопрос модели ИИ и получить подробный ответ. Ответ будет сохранен в истории разговора и может быть получен позже.", "fields": { "instance": { - "name": "Инстанция", - "description": "Имя используемой инстанции HA Text AI" + "name": "Экземпляр", + "description": "Название экземпляра текстового ИИ для использования" }, "question": { "name": "Вопрос", - "description": "Ваш вопрос или запрос к помощнику ИИ" + "description": "Ваш вопрос или запрос к ИИ-помощнику" }, "context_messages": { "name": "Контекстные сообщения", "description": "Количество предыдущих сообщений для включения в контекст (1-20)" }, "system_prompt": { - "name": "Системный запрос", - "description": "Необязательный системный запрос для установки контекста для этого конкретного вопроса" + "name": "Системный промпт", + "description": "Необязательный системный промпт для установки контекста для этого конкретного вопроса" }, "model": { "name": "Модель", - "description": "Выберите модель ИИ для использования (необязательно, переопределяет настройку по умолчанию)" + "description": "Выберите модель ИИ для использования (необязательно, переопределяет настройки по умолчанию)" }, "temperature": { "name": "Температура", - "description": "Управляет креативностью ответа (0.0-2.0)" + "description": "Управление креативностью ответа (0.0-2.0)" }, "max_tokens": { - "name": "Макс. токенов", + "name": "Максимум токенов", "description": "Максимальная длина ответа (1-4096 токенов)" } } @@ -103,18 +133,18 @@ "description": "Удалить все сохраненные вопросы и ответы из истории разговора", "fields": { "instance": { - "name": "Инстанция", - "description": "Имя инстанции HA Text AI, для которой нужно очистить историю" + "name": "Экземпляр", + "description": "Название экземпляра текстового ИИ для очистки истории" } } }, "get_history": { "name": "Получить историю", - "description": "Извлечь историю разговора с возможностью фильтрации и сортировки", + "description": "Получить историю разговора с дополнительной фильтрацией и сортировкой", "fields": { "instance": { - "name": "Инстанция", - "description": "Имя инстанции HA Text AI, из которой нужно получить историю" + "name": "Экземпляр", + "description": "Название экземпляра текстового ИИ для получения истории" }, "limit": { "name": "Лимит", @@ -122,33 +152,33 @@ }, "filter_model": { "name": "Фильтр модели", - "description": "Фильтрация разговоров по определенной модели ИИ" + "description": "Фильтрация разговоров по конкретной модели ИИ" }, "start_date": { - "name": "Дата начала", - "description": "Фильтрация разговоров, начиная с этой даты/времени" + "name": "Начальная дата", + "description": "Фильтрация разговоров, начиная с указанной даты/времени" }, "include_metadata": { "name": "Включить метаданные", - "description": "Включить дополнительную информацию, такую как использованные токены, время ответа и т.д." + "description": "Включить дополнительную информацию, например, использованные токены, время ответа и т.д." }, "sort_order": { "name": "Порядок сортировки", - "description": "Порядок сортировки результатов (самые новые или самые старые)" + "description": "Порядок сортировки результатов (сначала новые или старые)" } } }, "set_system_prompt": { - "name": "Установить системный запрос", - "description": "Установить инструкции по умолчанию для поведения системы для всех будущих разговоров", + "name": "Установить системный промпт", + "description": "Установить инструкции по умолчанию для поведения ИИ во всех будущих разговорах", "fields": { "instance": { - "name": "Инстанция", - "description": "Имя инстанции HA Text AI, для которой нужно установить системный запрос" + "name": "Экземпляр", + "description": "Название экземпляра текстового ИИ для установки системного промпта" }, "prompt": { - "name": "Системный запрос", - "description": "Инструкции, определяющие, как ИИ должен себя вести и отвечать" + "name": "Системный промпт", + "description": "Инструкции, определяющие, как ИИ должен вести себя и отвечать" } } } @@ -182,10 +212,10 @@ "name": "Температура" }, "max_tokens": { - "name": "Макс. токенов" + "name": "Максимум токенов" }, "system_prompt": { - "name": "Системный запрос" + "name": "Системный промпт" }, "response_time": { "name": "Время последнего ответа" @@ -203,7 +233,7 @@ "name": "Статус API" }, "tokens_used": { - "name": "Использовано токенов всего" + "name": "Всего использовано токенов" }, "average_response_time": { "name": "Среднее время ответа" @@ -215,10 +245,10 @@ "name": "Статус обработки" }, "is_rate_limited": { - "name": "Статус ограничения запросов" + "name": "Статус лимита запросов" }, "is_maintenance": { - "name": "Статус технического обслуживания" + "name": "Статус обслуживания" }, "api_version": { "name": "Версия API" @@ -227,7 +257,7 @@ "name": "Статус конечной точки" }, "performance_metrics": { - "name": "Метрики производительности" + "name": "Показатели производительности" }, "history_size": { "name": "Размер истории" @@ -239,16 +269,16 @@ "name": "Всего токенов" }, "prompt_tokens": { - "name": "Токены запроса" + "name": "Токены промпта" }, "completion_tokens": { "name": "Токены завершения" }, "successful_requests": { - "name": "Успешных запросов" + "name": "Успешные запросы" }, "failed_requests": { - "name": "Неудачных запросов" + "name": "Неудачные запросы" }, "average_latency": { "name": "Средняя задержка" diff --git a/custom_components/ha_text_ai/translations/sr.json b/custom_components/ha_text_ai/translations/sr.json index 711aa93..f9126c3 100644 --- a/custom_components/ha_text_ai/translations/sr.json +++ b/custom_components/ha_text_ai/translations/sr.json @@ -2,153 +2,183 @@ "config": { "step": { "provider": { - "title": "Изаберите добављача вештачке интелигенције", - "description": "Изаберите добављача услуга вештачке интелигенције који ћете користити за ову инстанцу.", + "title": "Изаберите AI провајдера", + "description": "Изаберите који AI сервис провајдер да користите за ову инстанцу.", "data": { - "api_provider": "Добављач API-ја", - "context_messages": "Број порука контекста које треба задржати (1-20)" + "api_provider": "API провајдер", + "context_messages": "Број контекстуалних порука које треба задржати (1-20)", + "max_history_size": "Максимална величина историје разговора (1-100)" + } + }, + "provider": { + "title": "Подешавања провајдера", + "description": "Обезбедите детаље о вези за изабраног AI провајдера.", + "data": { + "name": "Име инстанце (нпр. 'GPT Асистент', 'Claude Помоћник')", + "api_key": "API кључ за аутентификацију", + "model": "AI модел који ће се користити", + "api_endpoint": "Прилагођени URL API крајње тачке (опционо)", + "temperature": "Креативност одговора (0-2, нижа = фокусираније)", + "max_tokens": "Максимална дужина одговора (1-4096 токена)", + "request_interval": "Минимално време између захтева (0.1-60 секунди)", + "context_messages": "Број контекстуалних порука које треба задржати (1-20)", + "max_history_size": "Максимална величина историје разговора (1-100)" } }, "user": { - "title": "Конфигуришите инстанцу HA Text AI", - "description": "Поставите нову инстанцу асистента вештачке интелигенције са изабраним добављачем.", + "title": "Конфигуришите HA Text AI инстанцу", + "description": "Подесите нову AI асистент инстанцу са изабраним провајдером.", "data": { - "name": "Назив инстанце (нпр. 'GPT Assistant', 'Claude Helper')", + "name": "Име инстанце (нпр. 'GPT Асистент', 'Claude Помоћник')", "api_key": "API кључ за аутентификацију", - "model": "Модел вештачке интелигенције који треба користити", - "temperature": "Креативност одговора (0-2, нижа = више фокусирана)", + "model": "AI модел који ће се користити", + "temperature": "Креативност одговора (0-2, нижа = фокусираније)", "max_tokens": "Максимална дужина одговора (1-4096 токена)", - "api_endpoint": "Прилагођени URL завршног тачка API-ја (опционо)", - "api_provider": "Добављач API-ја", + "api_endpoint": "Прилагођени URL API крајње тачке (опционо)", + "api_provider": "API провајдер", "request_interval": "Минимално време између захтева (0.1-60 секунди)", - "context_messages": "Број порука контекста које треба задржати (1-20)", + "context_messages": "Број контекстуалних порука које треба задржати (1-20)", "max_history_size": "Максимална величина историје разговора (1-100)" } } }, "error": { - "name_exists": "Инстанца са овим називом већ постоји", - "invalid_name": "Неважећи назив инстанце", - "invalid_auth": "Аутентификација није успела - проверите свој API кључ", - "invalid_api_key": "Неважећи API кључ - проверите своје податке о верификацији", - "cannot_connect": "Није могуће успоставити везу са услугом API-ја", + "history_storage_error": "Неуспела инициализација складишта историје. Проверите дозволе.", + "history_rotation_error": "Грешка током ротације историјских датотека.", + "history_file_access_error": "Немогуће приступити директоријуму складишта историје.", + "name_exists": "Инстанца са овим именом већ постоји", + "invalid_name": "Неважеће име инстанце", + "invalid_auth": "Аутентификација није успела - проверите ваш API кључ", + "invalid_api_key": "Неважећи API кључ - молимо проверите ваше акредитиве", + "cannot_connect": "Неуспело повезивање са API сервисом", "invalid_model": "Изабрани модел није доступан", - "rate_limit": "Прекорачен је лимит стопе", - "context_length": "Прекорачена је дужина контекста", - "rate_limit_exceeded": "Прекорачен је лимит стопе API-ја", - "maintenance": "Услуга је у фази одржавања", - "invalid_response": "Примљен је неважећи одговор API-ја", - "api_error": "Догодила се грешка у услузи API-ја", - "timeout": "Захтев је истекао", - "invalid_instance": "Наведена је неважећа инстанца", - "unknown": "Догодила се неочекивана грешка", - "empty": "Назив не може бити празан", - "invalid_characters": "Назив може да садржи само слова, бројеве, размаке, цртице и цртице", - "name_too_long": "Назив мора бити 50 карактера или мање" + "rate_limit": "Пређена граница захтева", + "context_length": "Дужина контекста пређена", + "rate_limit_exceeded": "Пређена граница API захтева", + "maintenance": "Сервис је у одржавању", + "invalid_response": "Примљен неважећи API одговор", + "api_error": "Дошло је до грешке у API сервису", + "timeout": "Време захтева је истекло", + "invalid_instance": "Неважећа инстанца је назначена", + "unknown": "Дошло је до неочекиване грешке", + "empty": "Име не може бити празно", + "invalid_characters": "Име може садржавати само слова, цифре, размаке, подцрта и цртице", + "name_too_long": "Име мора бити 50 знакова или мање" + }, + "abort": { + "already_configured": "Инстанца је већ конфигурисана" } }, "options": { "step": { "init": { "title": "Ажурирајте подешавања инстанце", - "description": "Измените подешавања за ову инстанцу асистента вештачке интелигенције.", + "description": "Измените подешавања за ову AI асистент инстанцу.", "data": { - "model": "Модел вештачке интелигенције", + "model": "AI модел", "temperature": "Креативност одговора (0-2)", "max_tokens": "Максимална дужина одговора (1-4096)", - "request_interval": "Минимални интервал захтева (0.1-60 секунди)", + "request_interval": "Минимално време између захтева (0.1-60 секунди)", "context_messages": "Број претходних порука које треба укључити у контекст (1-20)", "max_history_size": "Максимална величина историје разговора (1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI (компатибилан)", + "anthropic": "Anthropic (компатибилан)" + } + } + }, "services": { "ask_question": { "name": "Поставите питање (HA Text AI)", - "description": "Пошаљите питање моделу вештачке интелигенције и добијте детаљан одговор. Одговор ће бити сачуван у историји разговора и може се касније преузети.", + "description": "Пошаљите питање AI моделу и примите детаљан одговор. Одговор ће бити сачуван у историји разговора и може се касније повратити.", "fields": { "instance": { "name": "Инстанца", - "description": "Назив инстанце HA Text AI коју треба користити" + "description": "Име HA Text AI инстанце коју ћете користити" }, "question": { "name": "Питање", - "description": "Ваше питање или наговештај за асистента вештачке интелигенције" + "description": "Ваше питање или упит за AI асистента" }, "context_messages": { - "name": "Поруке контекста", + "name": "Контекстуалне поруке", "description": "Број претходних порука које треба укључити у контекст (1-20)" }, "system_prompt": { - "name": "Системски наговештај", - "description": "Опциони системски наговештај за постављање контекста за ово одређено питање" + "name": "Системски упит", + "description": "Опционални системски упит за постављање контекста за ово конкретно питање" }, "model": { "name": "Модел", - "description": "Изаберите модел вештачке интелигенције који треба користити (опционо, преклапа подразумевано подешавање)" + "description": "Изаберите AI модел који ћете користити (опционо, надмашује подразумевану поставку)" }, "temperature": { "name": "Температура", "description": "Контролише креативност одговора (0.0-2.0)" }, "max_tokens": { - "name": "Макс. токени", + "name": "Максимални токени", "description": "Максимална дужина одговора (1-4096 токена)" } } }, "clear_history": { "name": "Обриши историју", - "description": "Обришите сва сачувана питања и одговоре из историје разговора", + "description": "Избришите све сачуване питања и одговоре из историје разговора", "fields": { "instance": { "name": "Инстанца", - "description": "Назив инстанце HA Text AI за коју треба очистити историју" + "description": "Име HA Text AI инстанце за коју желите да обришете историју" } } }, "get_history": { - "name": "Добиј историју", - "description": "Преузмите историју разговора са опционом филтрацијом и сортирањем", + "name": "Добијте историју", + "description": "Повратите историју разговора уз опционално филтрирање и сортирање", "fields": { "instance": { "name": "Инстанца", - "description": "Назив инстанце HA Text AI из које треба добити историју" + "description": "Име HA Text AI инстанце из које желите да добијете историју" }, "limit": { "name": "Лимит", - "description": "Број разговора који треба вратити (1-100)" + "description": "Број разговора које треба вратити (1-100)" }, "filter_model": { - "name": "Филтер модела", - "description": "Филтрирајте разговоре по одређеном моделу вештачке интелигенције" + "name": "Филтер модел", + "description": "Филтрирајте разговоре по одређеном AI моделу" }, "start_date": { - "name": "Почетни датум", - "description": "Филтрирајте разговоре почев од овог датума/времена" + "name": "Датум почетка", + "description": "Филтрирајте разговоре који почињу од овог датума/времена" }, "include_metadata": { "name": "Укључи метаподатке", - "description": "Укључите додатне информације попут коришћених токена, времена одговора и слично." + "description": "Укључите додатне информације као што су коришћени токени, време одговора итд." }, "sort_order": { "name": "Редослед сортирања", - "description": "Редослед сортирања за резултате (најновији или најстарији прво)" + "description": "Редослед сортирања за резултате (најновији или најстарији први)" } } }, "set_system_prompt": { - "name": "Поставите системски наговештај", - "description": "Поставите подразумевана упутства за понашање система за све будуће разговоре", + "name": "Поставите системски упит", + "description": "Поставите подразумеване инструкције за системско понашање за све будуће разговоре", "fields": { "instance": { "name": "Инстанца", - "description": "Назив инстанце HA Text AI за коју треба поставити системски наговештај" + "description": "Име HA Text AI инстанце за коју желите да поставите системски упит" }, "prompt": { - "name": "Системски наговештај", - "description": "Упутства која дефинишу како би се вештачка интелигенција требала понашати и одговарати" + "name": "Системски упит", + "description": "Инструкције које дефинишу како AI треба да се понаша и одговара" } } } @@ -161,12 +191,12 @@ "ready": "Спремно", "processing": "Обрада", "error": "Грешка", - "disconnected": "Искључено", - "rate_limited": "Лимит стопе", + "disconnected": "Прекључено", + "rate_limited": "Ограничење захтева", "maintenance": "Одржавање", - "initializing": "Иницијализација", - "retrying": "Понављање", - "queued": "У реду чекања" + "initializing": "Инициализује се", + "retrying": "Покушава поново", + "queued": "У реду" }, "state_attributes": { "question": { @@ -182,16 +212,16 @@ "name": "Температура" }, "max_tokens": { - "name": "Макс. токени" + "name": "Максимални токени" }, "system_prompt": { - "name": "Системски наговештај" + "name": "Системски упит" }, "response_time": { "name": "Време последњег одговора" }, "total_responses": { - "name": "Укупан број одговора" + "name": "Укупно одговора" }, "error_count": { "name": "Број грешака" @@ -200,10 +230,10 @@ "name": "Последња грешка" }, "api_status": { - "name": "Статус API-ја" + "name": "Статус API" }, "tokens_used": { - "name": "Укупно коришћених токена" + "name": "Укупно коришћени токени" }, "average_response_time": { "name": "Просечно време одговора" @@ -215,34 +245,34 @@ "name": "Статус обраде" }, "is_rate_limited": { - "name": "Статус ограничења стопе" + "name": "Статус ограничења захтева" }, "is_maintenance": { "name": "Статус одржавања" }, "api_version": { - "name": "Верзија API-ја" + "name": "Верзија API" }, "endpoint_status": { - "name": "Статус завршне тачке" + "name": "Статус крајње тачке" }, "performance_metrics": { - "name": "Метрике перформанси" + "name": "Перформансне метрике" }, "history_size": { "name": "Величина историје" }, "uptime": { - "name": "Време рада" + "name": "Уптиме" }, "total_tokens": { - "name": "Укупан број токена" + "name": "Укупно токена" }, "prompt_tokens": { - "name": "Токени наговештаја" + "name": "Токени упита" }, "completion_tokens": { - "name": "Токени довршетака" + "name": "Токени завршетка" }, "successful_requests": { "name": "Успешни захтеви" diff --git a/custom_components/ha_text_ai/translations/zh.json b/custom_components/ha_text_ai/translations/zh.json index b3955e3..7c542c3 100644 --- a/custom_components/ha_text_ai/translations/zh.json +++ b/custom_components/ha_text_ai/translations/zh.json @@ -2,153 +2,183 @@ "config": { "step": { "provider": { - "title": "选择 AI 提供商", - "description": "选择要用于此实例的 AI 服务提供商。", + "title": "选择AI提供者", + "description": "选择要用于此实例的AI服务提供者。", "data": { - "api_provider": "API 提供商", - "context_messages": "要保留的上下文消息数量 (1-20)" + "api_provider": "API提供者", + "context_messages": "保留的上下文消息数量(1-20)", + "max_history_size": "最大对话历史大小(1-100)" + } + }, + "provider": { + "title": "提供者设置", + "description": "提供所选AI提供者的连接详细信息。", + "data": { + "name": "实例名称(例如,'GPT助手','Claude助手')", + "api_key": "用于身份验证的API密钥", + "model": "要使用的AI模型", + "api_endpoint": "自定义API端点URL(可选)", + "temperature": "响应创造力(0-2,越低越专注)", + "max_tokens": "最大响应长度(1-4096个标记)", + "request_interval": "请求之间的最小时间(0.1-60秒)", + "context_messages": "保留的上下文消息数量(1-20)", + "max_history_size": "最大对话历史大小(1-100)" } }, "user": { - "title": "配置 HA Text AI 实例", - "description": "使用您选择的提供商设置新的 AI 助手实例。", + "title": "配置HA文本AI实例", + "description": "使用所选提供者设置新的AI助手实例。", "data": { - "name": "实例名称(例如,“GPT 助手”、“Claude 助手”)", - "api_key": "用于身份验证的 API 密钥", - "model": "要使用的 AI 模型", - "temperature": "回复创意度 (0-2,数值越低,回复越聚焦)", - "max_tokens": "最大回复长度(1-4096 个 Token)", - "api_endpoint": "自定义 API 端点 URL(可选)", - "api_provider": "API 提供商", - "request_interval": "请求之间的最短时间间隔(0.1-60 秒)", - "context_messages": "要保留的上下文消息数量 (1-20)", - "max_history_size": "最大对话历史记录大小 (1-100)" + "name": "实例名称(例如,'GPT助手','Claude助手')", + "api_key": "用于身份验证的API密钥", + "model": "要使用的AI模型", + "temperature": "响应创造力(0-2,越低越专注)", + "max_tokens": "最大响应长度(1-4096个标记)", + "api_endpoint": "自定义API端点URL(可选)", + "api_provider": "API提供者", + "request_interval": "请求之间的最小时间(0.1-60秒)", + "context_messages": "保留的上下文消息数量(1-20)", + "max_history_size": "最大对话历史大小(1-100)" } } }, "error": { - "name_exists": "已存在具有此名称的实例", + "history_storage_error": "无法初始化历史存储。检查权限。", + "history_rotation_error": "历史文件轮换时出错。", + "history_file_access_error": "无法访问历史存储目录。", + "name_exists": "具有此名称的实例已存在", "invalid_name": "无效的实例名称", - "invalid_auth": "身份验证失败 - 请检查您的 API 密钥", - "invalid_api_key": "无效的 API 密钥 - 请验证您的凭据", - "cannot_connect": "无法连接到 API 服务", + "invalid_auth": "身份验证失败 - 检查您的API密钥", + "invalid_api_key": "无效的API密钥 - 请验证您的凭据", + "cannot_connect": "无法连接到API服务", "invalid_model": "所选模型不可用", "rate_limit": "超出速率限制", "context_length": "上下文长度超出限制", - "rate_limit_exceeded": "API 速率限制已超出", + "rate_limit_exceeded": "API速率限制超出", "maintenance": "服务正在维护中", - "invalid_response": "收到无效的 API 响应", - "api_error": "发生 API 服务错误", + "invalid_response": "收到无效的API响应", + "api_error": "发生API服务错误", "timeout": "请求超时", "invalid_instance": "指定的实例无效", "unknown": "发生意外错误", "empty": "名称不能为空", "invalid_characters": "名称只能包含字母、数字、空格、下划线和连字符", - "name_too_long": "名称必须为 50 个字符或更少" + "name_too_long": "名称必须少于50个字符" + }, + "abort": { + "already_configured": "实例已配置" } }, "options": { "step": { "init": { "title": "更新实例设置", - "description": "修改此 AI 助手实例的设置。", + "description": "修改此AI助手实例的设置。", "data": { - "model": "AI 模型", - "temperature": "回复创意度 (0-2)", - "max_tokens": "最大回复长度 (1-4096)", - "request_interval": "最短请求间隔 (0.1-60 秒)", - "context_messages": "包含在上下文中的先前消息数 (1-20)", - "max_history_size": "最大对话历史记录大小 (1-100)" + "model": "AI模型", + "temperature": "响应创造力(0-2)", + "max_tokens": "最大响应长度(1-4096)", + "request_interval": "最小请求间隔(0.1-60秒)", + "context_messages": "要包含在上下文中的先前消息数量(1-20)", + "max_history_size": "最大对话历史大小(1-100)" } } } }, + "selector": { + "api_provider": { + "options": { + "openai": "OpenAI(兼容)", + "anthropic": "Anthropic(兼容)" + } + } + }, "services": { "ask_question": { - "name": "提问 (HA Text AI)", - "description": "向 AI 模型发送问题并接收详细的回复。回复将存储在对话历史记录中,以后可以检索。", + "name": "提问(HA文本AI)", + "description": "向AI模型发送问题并接收详细响应。响应将存储在对话历史中,可以稍后检索。", "fields": { "instance": { "name": "实例", - "description": "要使用的 HA Text AI 实例的名称" + "description": "要使用的HA文本AI实例名称" }, "question": { "name": "问题", - "description": "您要向 AI 助手提出的问题或提示" + "description": "您对AI助手的问题或提示" }, "context_messages": { "name": "上下文消息", - "description": "包含在上下文中的先前消息数 (1-20)" + "description": "要包含在上下文中的先前消息数量(1-20)" }, "system_prompt": { "name": "系统提示", - "description": "可选系统提示,用于为特定问题设置上下文" + "description": "可选的系统提示,用于为此特定问题设置上下文" }, "model": { "name": "模型", - "description": "选择要使用的 AI 模型(可选,覆盖默认设置)" + "description": "选择要使用的AI模型(可选,覆盖默认设置)" }, "temperature": { "name": "温度", - "description": "控制回复创意度 (0.0-2.0)" + "description": "控制响应创造力(0.0-2.0)" }, "max_tokens": { - "name": "最大 Token 数", - "description": "回复的最大长度(1-4096 个 Token)" + "name": "最大标记数", + "description": "响应的最大长度(1-4096个标记)" } } }, "clear_history": { - "name": "清除历史记录", - "description": "删除对话历史记录中所有存储的问题和回复", + "name": "清除历史", + "description": "删除对话历史中存储的所有问题和响应", "fields": { "instance": { "name": "实例", - "description": "要清除历史记录的 HA Text AI 实例的名称" + "description": "要清除历史的HA文本AI实例名称" } } }, "get_history": { - "name": "获取历史记录", - "description": "检索对话历史记录,并可选择进行过滤和排序", + "name": "获取历史", + "description": "检索对话历史,可选的过滤和排序", "fields": { "instance": { "name": "实例", - "description": "要从中获取历史记录的 HA Text AI 实例的名称" + "description": "要获取历史的HA文本AI实例名称" }, "limit": { "name": "限制", - "description": "要返回的对话数量 (1-100)" + "description": "要返回的对话数量(1-100)" }, "filter_model": { - "name": "筛选模型", - "description": "按特定 AI 模型筛选对话" + "name": "过滤模型", + "description": "按特定AI模型过滤对话" }, "start_date": { "name": "开始日期", - "description": "从该日期/时间开始筛选对话" + "description": "过滤从此日期/时间开始的对话" }, "include_metadata": { "name": "包含元数据", - "description": "包含其他信息,例如使用的 Token 数、响应时间等。" + "description": "包括额外信息,如使用的标记、响应时间等。" }, "sort_order": { "name": "排序顺序", - "description": "结果的排序顺序(最新的或最早的优先)" + "description": "结果的排序顺序(最新或最旧优先)" } } }, "set_system_prompt": { "name": "设置系统提示", - "description": "为所有将来的对话设置默认系统行为说明", + "description": "为所有未来的对话设置默认的系统行为指令", "fields": { "instance": { "name": "实例", - "description": "要为其设置系统提示的 HA Text AI 实例的名称" + "description": "要设置系统提示的HA文本AI实例名称" }, "prompt": { "name": "系统提示", - "description": "定义 AI 如何行为和响应的说明" + "description": "定义AI应如何行为和响应的指令" } } } @@ -158,22 +188,22 @@ "ha_text_ai": { "name": "{name}", "state": { - "ready": "就绪", + "ready": "准备就绪", "processing": "处理中", "error": "错误", "disconnected": "已断开连接", "rate_limited": "速率限制", - "maintenance": "维护", + "maintenance": "维护中", "initializing": "初始化中", "retrying": "重试中", "queued": "排队中" }, "state_attributes": { "question": { - "name": "最后一个问题" + "name": "最后问题" }, "response": { - "name": "最后一个回复" + "name": "最后响应" }, "model": { "name": "当前模型" @@ -182,34 +212,34 @@ "name": "温度" }, "max_tokens": { - "name": "最大 Token 数" + "name": "最大标记数" }, "system_prompt": { "name": "系统提示" }, "response_time": { - "name": "上次回复时间" + "name": "最后响应时间" }, "total_responses": { - "name": "总回复次数" + "name": "总响应数" }, "error_count": { "name": "错误计数" }, "last_error": { - "name": "上次错误" + "name": "最后错误" }, "api_status": { - "name": "API 状态" + "name": "API状态" }, "tokens_used": { - "name": "已使用的 Token 总数" + "name": "总使用标记数" }, "average_response_time": { - "name": "平均回复时间" + "name": "平均响应时间" }, "last_request_time": { - "name": "上次请求时间" + "name": "最后请求时间" }, "is_processing": { "name": "处理状态" @@ -221,7 +251,7 @@ "name": "维护状态" }, "api_version": { - "name": "API 版本" + "name": "API版本" }, "endpoint_status": { "name": "端点状态" @@ -230,19 +260,19 @@ "name": "性能指标" }, "history_size": { - "name": "历史记录大小" + "name": "历史大小" }, "uptime": { "name": "正常运行时间" }, "total_tokens": { - "name": "总 Token 数" + "name": "总标记数" }, "prompt_tokens": { - "name": "提示 Token 数" + "name": "提示标记数" }, "completion_tokens": { - "name": "完成 Token 数" + "name": "完成标记数" }, "successful_requests": { "name": "成功请求数"