Release v2.0.0

This commit is contained in:
SMKRV
2024-11-24 02:52:41 +03:00
parent e5077969e9
commit 7efabdfa70
4 changed files with 426 additions and 37 deletions
+8 -2
View File
@@ -4,6 +4,8 @@ from __future__ import annotations
import logging
import os
import shutil
import asyncio
from homeassistant.helpers.import_platform import async_import_platform
from datetime import datetime
from datetime import datetime, timedelta
from typing import Any, Dict, Optional
@@ -235,7 +237,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass=hass,
client=None, # Будет установлен позже
model=model,
update_interval=int(entry.data.get(CONF_REQUEST_INTERVAL, DEFAULT_REQUEST_INTERVAL)),
update_interval=timedelta(seconds=int(entry.data.get(CONF_REQUEST_INTERVAL, DEFAULT_REQUEST_INTERVAL))),
instance_name=instance_name,
max_tokens=entry.data.get(CONF_MAX_TOKENS, DEFAULT_MAX_TOKENS),
temperature=entry.data.get(CONF_TEMPERATURE, DEFAULT_TEMPERATURE),
@@ -248,7 +250,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"config_entry": entry,
}
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
for platform in PLATFORMS:
hass.async_create_task(
async_import_platform(hass, f"{DOMAIN}.{platform}", DOMAIN)
)
await asyncio.sleep(0)
return True
except Exception as ex:
+46 -16
View File
@@ -31,7 +31,7 @@ CONF_REQUEST_INTERVAL: Final = "request_interval"
CONF_INSTANCE: Final = "instance"
# Default values
DEFAULT_MODEL: Final = "gpt-3.5-turbo" # Обновлено на актуальную модель
DEFAULT_MODEL: Final = "gpt-4o"
DEFAULT_TEMPERATURE: Final = 0.7
DEFAULT_MAX_TOKENS: Final = 1000
DEFAULT_REQUEST_INTERVAL: Final = 1.0
@@ -64,6 +64,32 @@ ATTR_TEMPERATURE: Final = "temperature"
ATTR_MAX_TOKENS: Final = "max_tokens"
ATTR_SYSTEM_PROMPT: Final = "system_prompt"
# Sensor attributes
ATTR_TOTAL_RESPONSES: Final = "total_responses"
ATTR_TOTAL_ERRORS: Final = "total_errors"
ATTR_AVG_RESPONSE_TIME: Final = "average_response_time"
ATTR_LAST_REQUEST_TIME: Final = "last_request_time"
ATTR_LAST_ERROR: Final = "last_error"
ATTR_IS_PROCESSING: Final = "is_processing"
ATTR_IS_RATE_LIMITED: Final = "is_rate_limited"
ATTR_IS_MAINTENANCE: Final = "is_maintenance"
ATTR_API_VERSION: Final = "api_version"
ATTR_ENDPOINT_STATUS: Final = "endpoint_status"
ATTR_PERFORMANCE_METRICS: Final = "performance_metrics"
ATTR_HISTORY_SIZE: Final = "history_size"
ATTR_UPTIME: Final = "uptime"
ATTR_API_PROVIDER: Final = "api_provider"
# Sensor metrics
METRIC_TOTAL_TOKENS: Final = "total_tokens"
METRIC_PROMPT_TOKENS: Final = "prompt_tokens"
METRIC_COMPLETION_TOKENS: Final = "completion_tokens"
METRIC_SUCCESSFUL_REQUESTS: Final = "successful_requests"
METRIC_FAILED_REQUESTS: Final = "failed_requests"
METRIC_AVERAGE_LATENCY: Final = "average_latency"
METRIC_MAX_LATENCY: Final = "max_latency"
METRIC_MIN_LATENCY: Final = "min_latency"
# Error messages
ERROR_INVALID_API_KEY: Final = "invalid_api_key"
ERROR_CANNOT_CONNECT: Final = "cannot_connect"
@@ -76,6 +102,25 @@ ERROR_TIMEOUT: Final = "timeout_error"
ERROR_INVALID_INSTANCE: Final = "invalid_instance"
ERROR_NAME_EXISTS: Final = "name_exists"
# Entity attributes
ENTITY_ICON: Final = "mdi:robot"
ENTITY_ICON_ERROR: Final = "mdi:robot-dead"
ENTITY_ICON_PROCESSING: Final = "mdi:robot-excited"
# State attributes
STATE_READY: Final = "ready"
STATE_PROCESSING: Final = "processing"
STATE_ERROR: Final = "error"
STATE_INITIALIZING: Final = "initializing"
STATE_MAINTENANCE: Final = "maintenance"
STATE_RATE_LIMITED: Final = "rate_limited"
STATE_DISCONNECTED: Final = "disconnected"
# Event names
EVENT_RESPONSE_RECEIVED: Final = f"{DOMAIN}_response_received"
EVENT_ERROR_OCCURRED: Final = f"{DOMAIN}_error_occurred"
EVENT_STATE_CHANGED: Final = f"{DOMAIN}_state_changed"
# Service schema constants
SERVICE_SCHEMA_ASK_QUESTION = vol.Schema({
vol.Required(CONF_INSTANCE): cv.string,
@@ -128,18 +173,3 @@ CONFIG_SCHEMA = vol.Schema({
)
})
}, extra=vol.ALLOW_EXTRA)
# Entity attributes
ENTITY_ICON: Final = "mdi:robot"
ENTITY_ICON_ERROR: Final = "mdi:robot-dead"
ENTITY_ICON_PROCESSING: Final = "mdi:robot-excited"
# State attributes
STATE_READY: Final = "ready"
STATE_PROCESSING: Final = "processing"
STATE_ERROR: Final = "error"
# Event names
EVENT_RESPONSE_RECEIVED: Final = f"{DOMAIN}_response_received"
EVENT_ERROR_OCCURRED: Final = f"{DOMAIN}_error_occurred"
EVENT_STATE_CHANGED: Final = f"{DOMAIN}_state_changed"
@@ -30,6 +30,10 @@
"cannot_connect": "Failed to connect to API service",
"invalid_model": "Selected model is not available",
"rate_limit": "Rate limit exceeded",
"context_length": "Context length exceeded",
"rate_limit_exceeded": "API rate limit exceeded",
"maintenance": "Service is under maintenance",
"invalid_response": "Invalid API response received",
"api_error": "API service error occurred",
"timeout": "Request timed out",
"invalid_instance": "Invalid instance specified",
@@ -53,85 +57,105 @@
"services": {
"ask_question": {
"name": "Ask Question",
"description": "Send a question to the specified AI instance",
"description": "Send a question to the AI model and receive a detailed response. The response will be stored in the conversation history and can be retrieved later.",
"fields": {
"instance": {
"name": "Instance",
"description": "The HA Text AI instance to use"
"description": "Name of the HA Text AI instance to use",
"required": true
},
"question": {
"name": "Question",
"description": "Your question or prompt"
"description": "Your question or prompt for the AI assistant",
"required": true
},
"system_prompt": {
"name": "System Prompt",
"description": "Optional context for this question"
"description": "Optional system prompt to set context for this specific question",
"required": false
},
"model": {
"name": "Model",
"description": "Override default model for this request"
"description": "Select AI model to use (optional, overrides default setting)",
"required": false
},
"temperature": {
"name": "Temperature",
"description": "Override default creativity setting"
"description": "Controls response creativity (0.0-2.0)",
"required": false,
"default": 0.7
},
"max_tokens": {
"name": "Max Tokens",
"description": "Override default response length limit"
"description": "Maximum length of the response (1-4096 tokens)",
"required": false,
"default": 1000
}
}
},
"clear_history": {
"name": "Clear History",
"description": "Delete conversation history for specified instance",
"description": "Delete all stored questions and responses from the conversation history",
"fields": {
"instance": {
"name": "Instance",
"description": "The HA Text AI instance to clear history for"
"description": "Name of the HA Text AI instance to clear history for",
"required": true
}
}
},
"get_history": {
"name": "Get History",
"description": "Retrieve conversation history for specified instance",
"description": "Retrieve conversation history with optional filtering and sorting",
"fields": {
"instance": {
"name": "Instance",
"description": "The HA Text AI instance to get history from"
"description": "Name of the HA Text AI instance to get history from",
"required": true
},
"limit": {
"name": "Limit",
"description": "Maximum number of entries (1-100)"
"description": "Number of conversations to return (1-100)",
"required": false,
"default": 10
},
"filter_model": {
"name": "Filter Model",
"description": "Filter by specific AI model"
"description": "Filter conversations by specific AI model",
"required": false
},
"start_date": {
"name": "Start Date",
"description": "Filter from specific date/time"
"description": "Filter conversations starting from this date/time",
"required": false
},
"include_metadata": {
"name": "Include Metadata",
"description": "Include additional response information"
"description": "Include additional information like tokens used, response time, etc.",
"required": false,
"default": false
},
"sort_order": {
"name": "Sort Order",
"description": "Sort order (newest/oldest first)"
"description": "Sort order for results (newest or oldest first)",
"required": false,
"default": "desc"
}
}
},
"set_system_prompt": {
"name": "Set System Prompt",
"description": "Set default behavior for specified instance",
"description": "Set default system behavior instructions for all future conversations",
"fields": {
"instance": {
"name": "Instance",
"description": "The HA Text AI instance to configure"
"description": "Name of the HA Text AI instance to set system prompt for",
"required": true
},
"prompt": {
"name": "System Prompt",
"description": "Default behavior instructions"
"description": "Instructions that define how the AI should behave and respond",
"required": true
}
}
}
@@ -146,6 +170,8 @@
"error": "Error",
"disconnected": "Disconnected",
"rate_limited": "Rate Limited",
"maintenance": "Maintenance",
"initializing": "Initializing",
"retrying": "Retrying",
"queued": "Queued"
},
@@ -185,6 +211,60 @@
},
"tokens_used": {
"name": "Total Tokens Used"
},
"average_response_time": {
"name": "Average Response Time"
},
"last_request_time": {
"name": "Last Request Time"
},
"is_processing": {
"name": "Processing Status"
},
"is_rate_limited": {
"name": "Rate Limited Status"
},
"is_maintenance": {
"name": "Maintenance Status"
},
"api_version": {
"name": "API Version"
},
"endpoint_status": {
"name": "Endpoint Status"
},
"performance_metrics": {
"name": "Performance Metrics"
},
"history_size": {
"name": "History Size"
},
"uptime": {
"name": "Uptime"
},
"total_tokens": {
"name": "Total Tokens"
},
"prompt_tokens": {
"name": "Prompt Tokens"
},
"completion_tokens": {
"name": "Completion Tokens"
},
"successful_requests": {
"name": "Successful Requests"
},
"failed_requests": {
"name": "Failed Requests"
},
"average_latency": {
"name": "Average Latency"
},
"max_latency": {
"name": "Maximum Latency"
},
"min_latency": {
"name": "Minimum Latency"
}
}
}
@@ -0,0 +1,273 @@
{
"config": {
"step": {
"provider": {
"title": "Выбор AI провайдера",
"description": "Выберите провайдера AI сервиса для этого экземпляра",
"data": {
"api_provider": "API провайдер"
}
},
"user": {
"title": "Настройка экземпляра HA Text AI",
"description": "Настройте новый экземпляр AI ассистента с выбранным провайдером",
"data": {
"name": "Название экземпляра (например, 'GPT Ассистент', 'Claude Помощник')",
"api_key": "API ключ для аутентификации",
"model": "Используемая AI модель",
"temperature": "Креативность ответов (0-2, чем ниже, тем точнее)",
"max_tokens": "Максимальная длина ответа (1-4096 токенов)",
"api_endpoint": "Пользовательский URL API (необязательно)",
"request_interval": "Минимальный интервал между запросами (0.1-60 секунд)"
}
}
},
"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": "Произошла непредвиденная ошибка"
}
},
"options": {
"step": {
"init": {
"title": "Обновление настроек экземпляра",
"description": "Измените настройки для этого экземпляра AI ассистента",
"data": {
"model": "AI модель",
"temperature": "Креативность ответов (0-2)",
"max_tokens": "Максимальная длина ответа (1-4096)",
"request_interval": "Минимальный интервал запросов (0.1-60 секунд)"
}
}
}
},
"services": {
"ask_question": {
"name": "Задать вопрос",
"description": "Отправьте вопрос AI модели и получите подробный ответ. Ответ будет сохранен в истории разговора и может быть получен позже.",
"fields": {
"instance": {
"name": "Экземпляр",
"description": "Название экземпляра HA Text AI для использования",
"required": true
},
"question": {
"name": "Вопрос",
"description": "Ваш вопрос или запрос для AI ассистента",
"required": true
},
"system_prompt": {
"name": "Системный промпт",
"description": "Необязательный системный промпт для установки контекста этого вопроса",
"required": false
},
"model": {
"name": "Модель",
"description": "Выберите AI модель (необязательно, переопределяет настройки по умолчанию)",
"required": false
},
"temperature": {
"name": "Temperature",
"description": "Управляет креативностью ответов (0.0-2.0)",
"required": false,
"default": 0.7
},
"max_tokens": {
"name": "Max Tokens",
"description": "Максимальная длина ответа (1-4096 токенов)",
"required": false,
"default": 1000
}
}
},
"clear_history": {
"name": "Очистить историю",
"description": "Удалить все сохраненные вопросы и ответы из истории разговора",
"fields": {
"instance": {
"name": "Экземпляр",
"description": "Название экземпляра HA Text AI для очистки истории",
"required": true
}
}
},
"get_history": {
"name": "Получить историю",
"description": "Получить историю разговора с дополнительной фильтрацией и сортировкой",
"fields": {
"instance": {
"name": "Экземпляр",
"description": "Название экземпляра HA Text AI для получения истории",
"required": true
},
"limit": {
"name": "Лимит",
"description": "Количество разговоров для возврата (1-100)",
"required": false,
"default": 10
},
"filter_model": {
"name": "Фильтр модели",
"description": "Фильтровать разговоры по конкретной AI модели",
"required": false
},
"start_date": {
"name": "Начальная дата",
"description": "Фильтровать разговоры начиная с этой даты/времени",
"required": false
},
"include_metadata": {
"name": "Включить метаданные",
"description": "Включить дополнительную информацию, такую как использованные токены, время ответа и т.д.",
"required": false,
"default": false
},
"sort_order": {
"name": "Порядок сортировки",
"description": "Порядок сортировки результатов (сначала новые или старые)",
"required": false,
"default": "desc"
}
}
},
"set_system_prompt": {
"name": "Установить системный промпт",
"description": "Установить инструкции поведения по умолчанию для всех будущих разговоров",
"fields": {
"instance": {
"name": "Экземпляр",
"description": "Название экземпляра HA Text AI для настройки",
"required": true
},
"prompt": {
"name": "Системный промпт",
"description": "Инструкции, определяющие поведение и ответы AI",
"required": true
}
}
}
},
"entity": {
"sensor": {
"ha_text_ai": {
"name": "{name}",
"state": {
"ready": "Готов",
"processing": "Обработка",
"error": "Ошибка",
"disconnected": "Отключен",
"rate_limited": "Превышен лимит",
"maintenance": "Обслуживание",
"initializing": "Инициализация",
"retrying": "Повторная попытка",
"queued": "В очереди"
},
"state_attributes": {
"question": {
"name": "Последний вопрос"
},
"response": {
"name": "Последний ответ"
},
"model": {
"name": "Текущая модель"
},
"temperature": {
"name": "Temperature"
},
"max_tokens": {
"name": "Max Tokens"
},
"system_prompt": {
"name": "Системный промпт"
},
"response_time": {
"name": "Время последнего ответа"
},
"total_responses": {
"name": "Всего ответов"
},
"error_count": {
"name": "Количество ошибок"
},
"last_error": {
"name": "Последняя ошибка"
},
"api_status": {
"name": "Статус API"
},
"tokens_used": {
"name": "Всего использовано токенов"
},
"average_response_time": {
"name": "Среднее время ответа"
},
"last_request_time": {
"name": "Время последнего запроса"
},
"is_processing": {
"name": "Статус обработки"
},
"is_rate_limited": {
"name": "Статус ограничения запросов"
},
"is_maintenance": {
"name": "Статус обслуживания"
},
"api_version": {
"name": "Версия API"
},
"endpoint_status": {
"name": "Статус конечной точки"
},
"performance_metrics": {
"name": "Метрики производительности"
},
"history_size": {
"name": "Размер истории"
},
"uptime": {
"name": "Время работы"
},
"total_tokens": {
"name": "Всего токенов"
},
"prompt_tokens": {
"name": "Токены промпта"
},
"completion_tokens": {
"name": "Токены завершения"
},
"successful_requests": {
"name": "Успешные запросы"
},
"failed_requests": {
"name": "Неудачные запросы"
},
"average_latency": {
"name": "Средняя задержка"
},
"max_latency": {
"name": "Максимальная задержка"
},
"min_latency": {
"name": "Минимальная задержка"
}
}
}
}
}
}