mirror of
https://github.com/smkrv/ha-text-ai.git
synced 2026-07-26 17:14:01 +08:00
Update files
This commit is contained in:
@@ -18,13 +18,13 @@ DEFAULT_MAX_TOKENS = 1000
|
|||||||
DEFAULT_API_ENDPOINT = "https://api.openai.com/v1"
|
DEFAULT_API_ENDPOINT = "https://api.openai.com/v1"
|
||||||
DEFAULT_REQUEST_INTERVAL = 1.0
|
DEFAULT_REQUEST_INTERVAL = 1.0
|
||||||
|
|
||||||
|
# Services
|
||||||
|
SERVICE_ASK_QUESTION = "ask_question"
|
||||||
|
SERVICE_CLEAR_HISTORY = "clear_history"
|
||||||
|
SERVICE_GET_HISTORY = "get_history"
|
||||||
|
SERVICE_SET_SYSTEM_PROMPT = "set_system_prompt"
|
||||||
|
|
||||||
# Attributes
|
# Attributes
|
||||||
ATTR_QUESTION = "question"
|
ATTR_QUESTION = "question"
|
||||||
ATTR_RESPONSE = "response"
|
ATTR_RESPONSE = "response"
|
||||||
ATTR_LAST_UPDATED = "last_updated"
|
ATTR_LAST_UPDATED = "last_updated"
|
||||||
|
|
||||||
# Services
|
|
||||||
SERVICE_ASK_QUESTION = "ask_question
|
|
||||||
SERVICE_CLEAR_HISTORY = "clear_history"
|
|
||||||
SERVICE_GET_HISTORY = "get_history"
|
|
||||||
SERVICE_SET_SYSTEM_PROMPT = "set_system_prompt"
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ from homeassistant.exceptions import ConfigEntryAuthFailed
|
|||||||
from .const import (
|
from .const import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
DEFAULT_REQUEST_INTERVAL,
|
DEFAULT_REQUEST_INTERVAL,
|
||||||
|
CONF_MODEL,
|
||||||
|
CONF_TEMPERATURE,
|
||||||
|
CONF_MAX_TOKENS,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@@ -44,6 +47,7 @@ class HATextAICoordinator(DataUpdateCoordinator):
|
|||||||
self.max_tokens = max_tokens
|
self.max_tokens = max_tokens
|
||||||
self._question_queue = asyncio.Queue()
|
self._question_queue = asyncio.Queue()
|
||||||
self._responses: Dict[str, Any] = {}
|
self._responses: Dict[str, Any] = {}
|
||||||
|
self.system_prompt: Optional[str] = None
|
||||||
|
|
||||||
openai.api_key = self.api_key
|
openai.api_key = self.api_key
|
||||||
if endpoint != "https://api.openai.com/v1":
|
if endpoint != "https://api.openai.com/v1":
|
||||||
@@ -56,10 +60,15 @@ class HATextAICoordinator(DataUpdateCoordinator):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
question = await self._question_queue.get()
|
question = await self._question_queue.get()
|
||||||
response = await self.hass.async_add_executor_job(
|
response_content = await self.hass.async_add_executor_job(
|
||||||
self._make_api_call, question
|
self._make_api_call, question
|
||||||
)
|
)
|
||||||
|
response = {
|
||||||
|
"question": question,
|
||||||
|
"response": response_content
|
||||||
|
}
|
||||||
self._responses[question] = response
|
self._responses[question] = response
|
||||||
|
_LOGGER.debug(f"Response from API: {response}")
|
||||||
return self._responses
|
return self._responses
|
||||||
|
|
||||||
except openai.error.AuthenticationError as err:
|
except openai.error.AuthenticationError as err:
|
||||||
@@ -71,9 +80,11 @@ class HATextAICoordinator(DataUpdateCoordinator):
|
|||||||
def _make_api_call(self, question: str) -> str:
|
def _make_api_call(self, question: str) -> str:
|
||||||
"""Make API call to OpenAI."""
|
"""Make API call to OpenAI."""
|
||||||
try:
|
try:
|
||||||
|
messages = [{"role": "system", "content": self.system_prompt}] if self.system_prompt else []
|
||||||
|
messages.append({"role": "user", "content": question})
|
||||||
completion = openai.chat.completions.create(
|
completion = openai.chat.completions.create(
|
||||||
model=self.model,
|
model=self.model,
|
||||||
messages=[{"role": "user", "content": question}],
|
messages=messages,
|
||||||
temperature=self.temperature,
|
temperature=self.temperature,
|
||||||
max_tokens=self.max_tokens,
|
max_tokens=self.max_tokens,
|
||||||
)
|
)
|
||||||
@@ -85,4 +96,19 @@ class HATextAICoordinator(DataUpdateCoordinator):
|
|||||||
async def async_ask_question(self, question: str) -> None:
|
async def async_ask_question(self, question: str) -> None:
|
||||||
"""Add question to queue."""
|
"""Add question to queue."""
|
||||||
await self._question_queue.put(question)
|
await self._question_queue.put(question)
|
||||||
|
_LOGGER.debug(f"Question added to queue: {question}")
|
||||||
await self.async_refresh()
|
await self.async_refresh()
|
||||||
|
|
||||||
|
def clear_history(self) -> None:
|
||||||
|
"""Clear the stored question and response history."""
|
||||||
|
self._responses.clear()
|
||||||
|
_LOGGER.info("History cleared.")
|
||||||
|
|
||||||
|
def get_history(self, limit: int = 10) -> Dict[str, Any]:
|
||||||
|
"""Get the history of questions and responses."""
|
||||||
|
return {"history": list(self._responses.values())[-limit:]}
|
||||||
|
|
||||||
|
def set_system_prompt(self, prompt: str) -> None:
|
||||||
|
"""Set a system prompt that will be used for all future questions."""
|
||||||
|
self.system_prompt = prompt
|
||||||
|
_LOGGER.info(f"System prompt set: {prompt}")
|
||||||
|
|||||||
@@ -33,12 +33,26 @@ class HATextAISensor(CoordinatorEntity, SensorEntity):
|
|||||||
self._config_entry = config_entry
|
self._config_entry = config_entry
|
||||||
self._attr_unique_id = f"{config_entry.entry_id}"
|
self._attr_unique_id = f"{config_entry.entry_id}"
|
||||||
self._attr_name = "HA text AI"
|
self._attr_name = "HA text AI"
|
||||||
|
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self) -> Optional[Dict[str, Any]]:
|
def state(self) -> StateType:
|
||||||
"""Return entity specific state attributes."""
|
"""Return the state of the sensor."""
|
||||||
return {
|
if self.coordinator.data:
|
||||||
ATTR_QUESTION: list(self.coordinator.data.keys())[-1] if self.coordinator.data else None,
|
return "Ready" # Assuming "Ready" is a valid state, you might want to return something meaningful, like the last response time.
|
||||||
ATTR_RESPONSE: list(self.coordinator.data.values())[-1] if self.coordinator.data else None,
|
return "Not Ready"
|
||||||
ATTR_LAST_UPDATED: self.coordinator.last_update_success_time,
|
|
||||||
}
|
@property
|
||||||
|
def extra_state_attributes(self) -> Optional[Dict[str, Any]]:
|
||||||
|
"""Return entity specific state attributes."""
|
||||||
|
if not self.coordinator.data:
|
||||||
|
return None
|
||||||
|
keys = list(self.coordinator.data.keys())
|
||||||
|
values = list(self.coordinator.data.values())
|
||||||
|
last_question = keys[-1]
|
||||||
|
last_response = values[-1]
|
||||||
|
return {
|
||||||
|
ATTR_QUESTION: last_question,
|
||||||
|
ATTR_RESPONSE: last_response,
|
||||||
|
ATTR_LAST_UPDATED: self.coordinator.last_update_success_time,
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user