mirror of
https://github.com/smkrv/ha-text-ai.git
synced 2026-07-27 01:24:05 +08:00
Security: - Add SSRF protection via HTTPS-only endpoint validation with private IP blocking - Mask API keys in all log output via safe_log_data() - Sanitize error responses to prevent internal detail leakage - Remove API key pre-population in config flow forms - Harden service schemas with input length limits and type coercion Bug fixes: - Fix temperature=0 rejected due to Python falsy value bug (0 or default) - Fix fire-and-forget race condition in coordinator init (5 async_create_task → awaited async_initialize) - Fix rate limit state not resetting after successful API calls - Fix ConnectionError incorrectly setting is_rate_limited=True - Fix _rotate_history calling async method via sync executor - Fix shutil.move blocking event loop in history migration - Fix async_shutdown removing wrong key from hass.data - Replace os.rename with shutil.move for cross-device safety Improvements: - Add asyncio.Lock for request serialization - Replace async_timeout with stdlib asyncio.timeout (Python 3.12+) - Use SupportsResponse.OPTIONAL for ask_question and get_history services - Use Platform.SENSOR enum instead of string literal - Add strings.json for HA translation framework - Update DEFAULT_ANTHROPIC_MODEL to claude-sonnet-4-6 - Retry only transient errors (429, timeout) in API client Cleanup: - Remove dead code: unused schemas, imports, sync_write_history, check_memory, check_connection - Remove icon copying code from async_setup - Remove unused dependencies from manifest (anthropic, openai, certifi, async-timeout) - Remove empty manifest arrays (bluetooth, mqtt, ssdp, usb, zeroconf) - Fix duplicate JSON keys in 5 translation files - Fix Serbian translation: "Прекључено" → "Искључено" for disconnected state Bump version to 2.4.0
310 lines
12 KiB
JSON
310 lines
12 KiB
JSON
{
|
|
"config": {
|
|
"step": {
|
|
"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-100000 Token)",
|
|
"request_interval": "Minimale Zeit zwischen Anfragen (0,1-60 Sekunden)",
|
|
"api_timeout": "API-Anfrage Timeout in Sekunden (5-600)",
|
|
"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 AI-Assistenteninstanz mit Ihrem ausgewählten Anbieter ein.",
|
|
"data": {
|
|
"name": "Instanzname (z. B. 'GPT Assistant', 'Claude Helper')",
|
|
"api_key": "API-Schlüssel zur Authentifizierung",
|
|
"model": "Zu verwendendes AI-Modell",
|
|
"temperature": "Kreativität der Antwort (0-2, niedriger = fokussierter)",
|
|
"max_tokens": "Maximale Länge der Antwort (1-100000 Token)",
|
|
"api_endpoint": "Benutzerdefinierte API-Endpunkt-URL (optional)",
|
|
"api_provider": "API-Anbieter",
|
|
"request_interval": "Minimale Zeit zwischen Anfragen (0,1-60 Sekunden)",
|
|
"api_timeout": "API-Anfrage Timeout in Sekunden (5-600)",
|
|
"context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)",
|
|
"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 - bitte überprüfen Sie Ihre Anmeldeinformationen",
|
|
"cannot_connect": "Verbindung zum API-Dienst fehlgeschlagen",
|
|
"invalid_model": "Ausgewähltes Modell ist nicht verfügbar",
|
|
"rate_limit": "Rate-Limit überschritten",
|
|
"context_length": "Kontextlänge überschritten",
|
|
"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": "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 höchstens 50 Zeichen lang sein"
|
|
},
|
|
"abort": {
|
|
"already_configured": "Instanz bereits konfiguriert"
|
|
}
|
|
},
|
|
"options": {
|
|
"step": {
|
|
"init": {
|
|
"title": "Anbieter auswählen",
|
|
"description": "Wählen Sie den AI-Anbieter für diese Instanz. Die Integration wird nach dem Speichern der Änderungen neu geladen.",
|
|
"data": {
|
|
"api_provider": "API-Anbieter"
|
|
}
|
|
},
|
|
"settings": {
|
|
"title": "Verbindungs- und Modelleinstellungen",
|
|
"description": "Konfigurieren Sie API-Anmeldeinformationen und Modellparameter. Änderungen werden nach dem Neuladen der Integration wirksam.",
|
|
"data": {
|
|
"api_key": "API-Schlüssel",
|
|
"api_endpoint": "API-Endpunkt-URL",
|
|
"model": "AI-Modell",
|
|
"temperature": "Kreativität der Antwort (0-2)",
|
|
"max_tokens": "Maximale Länge der Antwort (1-100000)",
|
|
"request_interval": "Minimales Anfrageintervall (0,1-60 Sekunden)",
|
|
"api_timeout": "API-Anfrage Timeout in Sekunden (5-600)",
|
|
"context_messages": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)",
|
|
"max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"selector": {
|
|
"api_provider": {
|
|
"options": {
|
|
"openai": "OpenAI (compatible)",
|
|
"anthropic": "Anthropic (compatible)",
|
|
"deepseek": "DeepSeek",
|
|
"gemini": "Google Gemini"
|
|
}
|
|
}
|
|
},
|
|
"services": {
|
|
"ask_question": {
|
|
"name": "Frage stellen (HA Text AI)",
|
|
"description": "Stellen Sie eine Frage an das AI-Modell und erhalten Sie eine detaillierte Antwort. Dieser Service gibt jetzt Antwortdaten direkt zurück, wodurch separate Textsensoren und die 255-Zeichen-Begrenzung überflüssig werden. Die Antwort wird auch im Gesprächsverlauf gespeichert.",
|
|
"fields": {
|
|
"instance": {
|
|
"name": "Instanz",
|
|
"description": "Name der zu verwendenden HA Text AI-Instanz"
|
|
},
|
|
"question": {
|
|
"name": "Frage",
|
|
"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": "Systemaufforderung",
|
|
"description": "Optionale Systemaufforderung zur Festlegung des Kontexts für diese spezifische Frage"
|
|
},
|
|
"model": {
|
|
"name": "Modell",
|
|
"description": "Wählen Sie das zu verwendende AI-Modell (optional, überschreibt die Standardeinstellung)"
|
|
},
|
|
"temperature": {
|
|
"name": "Temperatur",
|
|
"description": "Steuert die Kreativität der Antwort (0,0-2,0)"
|
|
},
|
|
"max_tokens": {
|
|
"name": "Max Tokens",
|
|
"description": "Maximale Länge der Antwort (1-100000 Token)"
|
|
},
|
|
"structured_output": {
|
|
"name": "Strukturierte Ausgabe",
|
|
"description": "JSON-Strukturausgabemodus aktivieren. Bei Aktivierung antwortet die KI mit gültigem JSON, das dem angegebenen Schema entspricht."
|
|
},
|
|
"json_schema": {
|
|
"name": "JSON-Schema",
|
|
"description": "JSON-Schema, das die Struktur der erwarteten Antwort definiert. Erforderlich wenn structured_output aktiviert ist."
|
|
}
|
|
}
|
|
},
|
|
"clear_history": {
|
|
"name": "Verlauf 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, für die der Verlauf gelöscht werden soll"
|
|
}
|
|
}
|
|
},
|
|
"get_history": {
|
|
"name": "Verlauf abrufen",
|
|
"description": "Rufen Sie den Gesprächsverlauf mit optionaler Filterung und Sortierung ab",
|
|
"fields": {
|
|
"instance": {
|
|
"name": "Instanz",
|
|
"description": "Name der HA Text AI-Instanz, von der der Verlauf abgerufen werden soll"
|
|
},
|
|
"limit": {
|
|
"name": "Limit",
|
|
"description": "Anzahl der zurückzugebenden Gespräche (1-100)"
|
|
},
|
|
"filter_model": {
|
|
"name": "Modell filtern",
|
|
"description": "Gespräche nach spezifischem AI-Modell filtern"
|
|
},
|
|
"start_date": {
|
|
"name": "Startdatum",
|
|
"description": "Gespräche ab diesem Datum/Zeit filtern"
|
|
},
|
|
"include_metadata": {
|
|
"name": "Metadaten einbeziehen",
|
|
"description": "Zusätzliche Informationen wie verwendete Tokens, Antwortzeit usw. einbeziehen"
|
|
},
|
|
"sort_order": {
|
|
"name": "Sortierreihenfolge",
|
|
"description": "Sortierreihenfolge für die Ergebnisse (neueste oder älteste zuerst)"
|
|
}
|
|
}
|
|
},
|
|
"set_system_prompt": {
|
|
"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 die Systemaufforderung festgelegt werden soll"
|
|
},
|
|
"prompt": {
|
|
"name": "Systemaufforderung",
|
|
"description": "Anweisungen, die definieren, wie die AI sich verhalten und antworten soll"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"entity": {
|
|
"sensor": {
|
|
"ha_text_ai": {
|
|
"name": "{name}",
|
|
"state": {
|
|
"ready": "Bereit",
|
|
"processing": "Verarbeitung",
|
|
"error": "Fehler",
|
|
"disconnected": "Getrennt",
|
|
"rate_limited": "Rate limitiert",
|
|
"maintenance": "Wartung",
|
|
"initializing": "Initialisierung",
|
|
"retrying": "Wiederholen",
|
|
"queued": "In der Warteschlange"
|
|
},
|
|
"state_attributes": {
|
|
"question": {
|
|
"name": "Letzte Frage"
|
|
},
|
|
"response": {
|
|
"name": "Letzte Antwort"
|
|
},
|
|
"model": {
|
|
"name": "Aktuelles Modell"
|
|
},
|
|
"temperature": {
|
|
"name": "Temperatur"
|
|
},
|
|
"max_tokens": {
|
|
"name": "Max Tokens"
|
|
},
|
|
"system_prompt": {
|
|
"name": "Systemaufforderung"
|
|
},
|
|
"response_time": {
|
|
"name": "Letzte Antwortzeit"
|
|
},
|
|
"total_responses": {
|
|
"name": "Gesamtantworten"
|
|
},
|
|
"error_count": {
|
|
"name": "Fehleranzahl"
|
|
},
|
|
"last_error": {
|
|
"name": "Letzter Fehler"
|
|
},
|
|
"api_status": {
|
|
"name": "API-Status"
|
|
},
|
|
"tokens_used": {
|
|
"name": "Gesamte verwendete Tokens"
|
|
},
|
|
"average_response_time": {
|
|
"name": "Durchschnittliche Antwortzeit"
|
|
},
|
|
"last_request_time": {
|
|
"name": "Letzte Anfragezeit"
|
|
},
|
|
"is_processing": {
|
|
"name": "Verarbeitungsstatus"
|
|
},
|
|
"is_rate_limited": {
|
|
"name": "Rate-limitiert Status"
|
|
},
|
|
"is_maintenance": {
|
|
"name": "Wartungsstatus"
|
|
},
|
|
"api_version": {
|
|
"name": "API-Version"
|
|
},
|
|
"endpoint_status": {
|
|
"name": "Endpunktstatus"
|
|
},
|
|
"performance_metrics": {
|
|
"name": "Leistungskennzahlen"
|
|
},
|
|
"history_size": {
|
|
"name": "Größe des Verlaufs"
|
|
},
|
|
"uptime": {
|
|
"name": "Betriebszeit"
|
|
},
|
|
"total_tokens": {
|
|
"name": "Gesamte Tokens"
|
|
},
|
|
"prompt_tokens": {
|
|
"name": "Eingabe Tokens"
|
|
},
|
|
"completion_tokens": {
|
|
"name": "Vervollständigungs Tokens"
|
|
},
|
|
"successful_requests": {
|
|
"name": "Erfolgreiche Anfragen"
|
|
},
|
|
"failed_requests": {
|
|
"name": "Fehlgeschlagene Anfragen"
|
|
},
|
|
"average_latency": {
|
|
"name": "Durchschnittliche Latenz"
|
|
},
|
|
"max_latency": {
|
|
"name": "Maximale Latenz"
|
|
},
|
|
"min_latency": {
|
|
"name": "Minimale Latenz"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|