mirror of
https://github.com/smkrv/ha-text-ai.git
synced 2026-07-26 17:14:01 +08:00
Release v2.0.0
This commit is contained in:
+33
-4
@@ -1,8 +1,37 @@
|
|||||||
|
# Python
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# Home Assistant
|
||||||
|
.storage
|
||||||
|
.cloud
|
||||||
|
.google.token
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env
|
Thumbs.db
|
||||||
.venv
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
await coordinator.async_ask_question(question, **request_params)
|
await coordinator.async_ask_question(question, **request_params)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
_LOGGER.error("Error asking question: %s", str(err))
|
_LOGGER.error("Error asking question: %s", str(err))
|
||||||
|
|
||||||
async def async_clear_history(call: ServiceCall) -> None:
|
async def async_clear_history(call: ServiceCall) -> None:
|
||||||
"""Handle the clear_history service call."""
|
"""Handle the clear_history service call."""
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import ssl
|
|||||||
import certifi
|
import certifi
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
|
from homeassistant.helpers import aiohttp_client
|
||||||
from openai import AsyncOpenAI, APIError, AuthenticationError, RateLimitError
|
from openai import AsyncOpenAI, APIError, AuthenticationError, RateLimitError
|
||||||
from anthropic import AsyncAnthropic
|
from anthropic import AsyncAnthropic
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import aiohttp_client
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
import async_timeout
|
import async_timeout
|
||||||
@@ -28,7 +30,44 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class HATextAICoordinator(DataUpdateCoordinator):
|
class HATextAICoordinator(DataUpdateCoordinator):
|
||||||
"""Class to manage fetching data from the API."""
|
"""Class to manage fetching data from the API."""
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
api_key: str,
|
||||||
|
endpoint: str,
|
||||||
|
model: str,
|
||||||
|
temperature: float,
|
||||||
|
max_tokens: int,
|
||||||
|
request_interval: float,
|
||||||
|
session: Optional[Any] = None,
|
||||||
|
is_anthropic: bool = False,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize coordinator."""
|
||||||
|
super().__init__(
|
||||||
|
hass,
|
||||||
|
_LOGGER,
|
||||||
|
name=DOMAIN,
|
||||||
|
update_interval=timedelta(seconds=request_interval),
|
||||||
|
)
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
api_key: str,
|
||||||
|
endpoint: str,
|
||||||
|
model: str,
|
||||||
|
temperature: float,
|
||||||
|
max_tokens: int,
|
||||||
|
request_interval: float,
|
||||||
|
session: Optional[Any] = None,
|
||||||
|
is_anthropic: bool = False,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize coordinator."""
|
||||||
|
super().__init__(
|
||||||
|
hass,
|
||||||
|
_LOGGER,
|
||||||
|
name=DOMAIN,
|
||||||
|
update_interval=timedelta(seconds=request_interval),
|
||||||
|
)
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@@ -394,13 +433,17 @@ class HATextAICoordinator(DataUpdateCoordinator):
|
|||||||
|
|
||||||
def _update_final_metrics(self) -> None:
|
def _update_final_metrics(self) -> None:
|
||||||
"""Update final metrics before shutdown."""
|
"""Update final metrics before shutdown."""
|
||||||
if self._request_count > 0:
|
self._performance_metrics["final_success_rate"] = (
|
||||||
self._performance_metrics["final_success_rate"] = (
|
(self._request_count - self._performance_metrics["total_errors"]) /
|
||||||
(self._request_count - self._performance_metrics["total_errors"]) /
|
self._request_count * 100 if self._request_count > 0 else 0
|
||||||
self._request_count * 100
|
)
|
||||||
)
|
self._performance_metrics["total_requests"] = self._request_count
|
||||||
self._performance_metrics["total_requests"] = self._request_count
|
self._performance_metrics["total_tokens"] = self._tokens_used
|
||||||
self._performance_metrics["total_tokens"] = self._tokens_used
|
|
||||||
|
async def async_initialize(self) -> None:
|
||||||
|
"""Initialize coordinator."""
|
||||||
|
self._is_ready = True
|
||||||
|
await self.async_refresh()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def performance_metrics(self) -> Dict[str, Any]:
|
def performance_metrics(self) -> Dict[str, Any]:
|
||||||
|
|||||||
@@ -28,36 +28,35 @@ ask_question:
|
|||||||
|
|
||||||
model:
|
model:
|
||||||
name: Model
|
name: Model
|
||||||
description: >-
|
description: "Select an AI model to use (optional, overrides default setting)."
|
||||||
Select an AI model to use (optional, overrides default setting).
|
|
||||||
Different models have different capabilities, context limits, and response characteristics:
|
|
||||||
- GPT-3.5 Turbo: Fast, efficient, good for most tasks
|
|
||||||
- GPT-4: More capable, better reasoning, slower
|
|
||||||
- Claude-3: Advanced capabilities, longer context
|
|
||||||
Note: More capable models may have longer response times and higher API costs.
|
|
||||||
required: false
|
required: false
|
||||||
example: "gpt-3.5-turbo"
|
example: "gpt-4o-mini"
|
||||||
default: "gpt-3.5-turbo"
|
default: "gpt-4o-mini"
|
||||||
selector:
|
selector:
|
||||||
select:
|
select:
|
||||||
custom_value: true
|
custom_value: true
|
||||||
options:
|
options:
|
||||||
- label: "GPT-3.5 Turbo (Fast & Efficient)"
|
- label: "o1-preview"
|
||||||
value: "gpt-3.5-turbo"
|
value: "o1-preview"
|
||||||
- label: "GPT-3.5 Turbo 16K (Extended)"
|
- label: "o1-mini"
|
||||||
value: "gpt-3.5-turbo-16k"
|
value: "o1-mini"
|
||||||
- label: "GPT-4 (Most Capable)"
|
- label: "gpt-4o-mini"
|
||||||
value: "gpt-4"
|
value: "gpt-4o-mini"
|
||||||
- label: "GPT-4 32K (Extended Context)"
|
- label: "gpt-4o"
|
||||||
value: "gpt-4-32k"
|
value: "gpt-4o"
|
||||||
- label: "GPT-4 Turbo (Latest)"
|
- label: "claude-3-5-haiku"
|
||||||
value: "gpt-4-1106-preview"
|
value: "claude-3-5-haiku"
|
||||||
- label: "Claude-3 Sonnet (Balanced)"
|
- label: "claude-3.5-sonnet"
|
||||||
value: "claude-3-sonnet"
|
value: "claude-3.5-sonnet"
|
||||||
- label: "Claude-3 Opus (Most Advanced)"
|
- label: "claude-3-haiku"
|
||||||
value: "claude-3-opus"
|
value: "claude-3-haiku"
|
||||||
|
- label: "anthropic/claude-3-5-haiku"
|
||||||
|
value: "anthropic/claude-3-5-haiku"
|
||||||
|
- label: "anthropic/claude-3.5-sonnet"
|
||||||
|
value: "anthropic/claude-3.5-sonnet"
|
||||||
mode: dropdown
|
mode: dropdown
|
||||||
|
|
||||||
|
|
||||||
temperature:
|
temperature:
|
||||||
name: Temperature
|
name: Temperature
|
||||||
description: >-
|
description: >-
|
||||||
|
|||||||
Reference in New Issue
Block a user