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 logging
import os import os
import shutil import shutil
import asyncio
from homeassistant.helpers.import_platform import async_import_platform
from datetime import datetime from datetime import datetime
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
@@ -235,7 +237,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass=hass, hass=hass,
client=None, # Будет установлен позже client=None, # Будет установлен позже
model=model, 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, instance_name=instance_name,
max_tokens=entry.data.get(CONF_MAX_TOKENS, DEFAULT_MAX_TOKENS), max_tokens=entry.data.get(CONF_MAX_TOKENS, DEFAULT_MAX_TOKENS),
temperature=entry.data.get(CONF_TEMPERATURE, DEFAULT_TEMPERATURE), 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, "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 return True
except Exception as ex: except Exception as ex:
+46 -16
View File
@@ -31,7 +31,7 @@ CONF_REQUEST_INTERVAL: Final = "request_interval"
CONF_INSTANCE: Final = "instance" CONF_INSTANCE: Final = "instance"
# Default values # Default values
DEFAULT_MODEL: Final = "gpt-3.5-turbo" # Обновлено на актуальную модель DEFAULT_MODEL: Final = "gpt-4o"
DEFAULT_TEMPERATURE: Final = 0.7 DEFAULT_TEMPERATURE: Final = 0.7
DEFAULT_MAX_TOKENS: Final = 1000 DEFAULT_MAX_TOKENS: Final = 1000
DEFAULT_REQUEST_INTERVAL: Final = 1.0 DEFAULT_REQUEST_INTERVAL: Final = 1.0
@@ -64,6 +64,32 @@ ATTR_TEMPERATURE: Final = "temperature"
ATTR_MAX_TOKENS: Final = "max_tokens" ATTR_MAX_TOKENS: Final = "max_tokens"
ATTR_SYSTEM_PROMPT: Final = "system_prompt" 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 messages
ERROR_INVALID_API_KEY: Final = "invalid_api_key" ERROR_INVALID_API_KEY: Final = "invalid_api_key"
ERROR_CANNOT_CONNECT: Final = "cannot_connect" ERROR_CANNOT_CONNECT: Final = "cannot_connect"
@@ -76,6 +102,25 @@ ERROR_TIMEOUT: Final = "timeout_error"
ERROR_INVALID_INSTANCE: Final = "invalid_instance" ERROR_INVALID_INSTANCE: Final = "invalid_instance"
ERROR_NAME_EXISTS: Final = "name_exists" 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 constants
SERVICE_SCHEMA_ASK_QUESTION = vol.Schema({ SERVICE_SCHEMA_ASK_QUESTION = vol.Schema({
vol.Required(CONF_INSTANCE): cv.string, vol.Required(CONF_INSTANCE): cv.string,
@@ -128,18 +173,3 @@ CONFIG_SCHEMA = vol.Schema({
) )
}) })
}, extra=vol.ALLOW_EXTRA) }, 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", "cannot_connect": "Failed to connect to API service",
"invalid_model": "Selected model is not available", "invalid_model": "Selected model is not available",
"rate_limit": "Rate limit exceeded", "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", "api_error": "API service error occurred",
"timeout": "Request timed out", "timeout": "Request timed out",
"invalid_instance": "Invalid instance specified", "invalid_instance": "Invalid instance specified",
@@ -53,85 +57,105 @@
"services": { "services": {
"ask_question": { "ask_question": {
"name": "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": { "fields": {
"instance": { "instance": {
"name": "Instance", "name": "Instance",
"description": "The HA Text AI instance to use" "description": "Name of the HA Text AI instance to use",
"required": true
}, },
"question": { "question": {
"name": "Question", "name": "Question",
"description": "Your question or prompt" "description": "Your question or prompt for the AI assistant",
"required": true
}, },
"system_prompt": { "system_prompt": {
"name": "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": { "model": {
"name": "Model", "name": "Model",
"description": "Override default model for this request" "description": "Select AI model to use (optional, overrides default setting)",
"required": false
}, },
"temperature": { "temperature": {
"name": "Temperature", "name": "Temperature",
"description": "Override default creativity setting" "description": "Controls response creativity (0.0-2.0)",
"required": false,
"default": 0.7
}, },
"max_tokens": { "max_tokens": {
"name": "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": { "clear_history": {
"name": "Clear History", "name": "Clear History",
"description": "Delete conversation history for specified instance", "description": "Delete all stored questions and responses from the conversation history",
"fields": { "fields": {
"instance": { "instance": {
"name": "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": { "get_history": {
"name": "Get History", "name": "Get History",
"description": "Retrieve conversation history for specified instance", "description": "Retrieve conversation history with optional filtering and sorting",
"fields": { "fields": {
"instance": { "instance": {
"name": "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": { "limit": {
"name": "Limit", "name": "Limit",
"description": "Maximum number of entries (1-100)" "description": "Number of conversations to return (1-100)",
"required": false,
"default": 10
}, },
"filter_model": { "filter_model": {
"name": "Filter Model", "name": "Filter Model",
"description": "Filter by specific AI model" "description": "Filter conversations by specific AI model",
"required": false
}, },
"start_date": { "start_date": {
"name": "Start Date", "name": "Start Date",
"description": "Filter from specific date/time" "description": "Filter conversations starting from this date/time",
"required": false
}, },
"include_metadata": { "include_metadata": {
"name": "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": { "sort_order": {
"name": "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": { "set_system_prompt": {
"name": "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": { "fields": {
"instance": { "instance": {
"name": "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": { "prompt": {
"name": "System 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", "error": "Error",
"disconnected": "Disconnected", "disconnected": "Disconnected",
"rate_limited": "Rate Limited", "rate_limited": "Rate Limited",
"maintenance": "Maintenance",
"initializing": "Initializing",
"retrying": "Retrying", "retrying": "Retrying",
"queued": "Queued" "queued": "Queued"
}, },
@@ -185,6 +211,60 @@
}, },
"tokens_used": { "tokens_used": {
"name": "Total 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": "Минимальная задержка"
}
}
}
}
}
}