Release v2.0.0

This commit is contained in:
SMKRV
2024-11-23 18:50:48 +03:00
parent 31f21b3a6b
commit 8646118a27
4 changed files with 558 additions and 668 deletions
+72 -66
View File
@@ -5,12 +5,10 @@ import logging
import os import os
import shutil import shutil
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
import asyncio
import voluptuous as vol
from datetime import datetime from datetime import datetime
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_API_KEY, CONF_NAME
from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers import config_validation as cv, entity_platform
@@ -36,12 +34,13 @@ from .const import (
DEFAULT_ANTHROPIC_ENDPOINT, DEFAULT_ANTHROPIC_ENDPOINT,
DEFAULT_REQUEST_INTERVAL, DEFAULT_REQUEST_INTERVAL,
API_TIMEOUT, API_TIMEOUT,
API_RETRY_COUNT,
SERVICE_ASK_QUESTION, SERVICE_ASK_QUESTION,
SERVICE_CLEAR_HISTORY, SERVICE_CLEAR_HISTORY,
SERVICE_GET_HISTORY,
SERVICE_SET_SYSTEM_PROMPT, SERVICE_SET_SYSTEM_PROMPT,
SERVICE_SCHEMA_ASK_QUESTION, SERVICE_SCHEMA_ASK_QUESTION,
SERVICE_SCHEMA_SET_SYSTEM_PROMPT, SERVICE_SCHEMA_SET_SYSTEM_PROMPT,
SERVICE_SCHEMA_GET_HISTORY,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@@ -61,6 +60,17 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
"""Set up the HA Text AI component.""" """Set up the HA Text AI component."""
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})
# Copy custom icon
try:
source = os.path.join(os.path.dirname(__file__), 'icons', 'icon.svg')
dest_dir = os.path.join(hass.config.path('www'), 'icons')
os.makedirs(dest_dir, exist_ok=True)
dest = os.path.join(dest_dir, 'icon.svg')
if not os.path.exists(dest):
shutil.copyfile(source, dest)
except Exception as ex:
_LOGGER.warning("Failed to copy custom icon: %s", str(ex))
async def async_ask_question(call: ServiceCall) -> None: async def async_ask_question(call: ServiceCall) -> None:
"""Handle ask_question service.""" """Handle ask_question service."""
entity_id = call.target.get("entity_id") entity_id = call.target.get("entity_id")
@@ -104,6 +114,33 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
_LOGGER.error("Error clearing history: %s", str(err)) _LOGGER.error("Error clearing history: %s", str(err))
raise HomeAssistantError(f"Failed to clear history: {str(err)}") raise HomeAssistantError(f"Failed to clear history: {str(err)}")
async def async_get_history(call: ServiceCall) -> None:
"""Handle get_history service."""
entity_id = call.target.get("entity_id")
if not entity_id:
raise HomeAssistantError("No target entity specified")
coordinator = get_coordinator_by_id(hass, entity_id)
if not coordinator:
raise HomeAssistantError(f"No coordinator found for entity {entity_id}")
try:
limit = call.data.get("limit", 10)
start_date = call.data.get("start_date")
include_metadata = call.data.get("include_metadata", False)
sort_order = call.data.get("sort_order", "desc")
history = await coordinator.get_history(
limit=limit,
start_date=start_date,
include_metadata=include_metadata,
sort_order=sort_order
)
return history
except Exception as err:
_LOGGER.error("Error getting history: %s", str(err))
raise HomeAssistantError(f"Failed to get history: {str(err)}")
async def async_set_system_prompt(call: ServiceCall) -> None: async def async_set_system_prompt(call: ServiceCall) -> None:
"""Handle set_system_prompt service.""" """Handle set_system_prompt service."""
entity_id = call.target.get("entity_id") entity_id = call.target.get("entity_id")
@@ -124,14 +161,14 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
_LOGGER.error("Error setting system prompt: %s", str(err)) _LOGGER.error("Error setting system prompt: %s", str(err))
raise HomeAssistantError(f"Failed to set system prompt: {str(err)}") raise HomeAssistantError(f"Failed to set system prompt: {str(err)}")
# Базовая схема с target как vol.Schema # Base schema with target
base_schema = vol.Schema({ base_schema = vol.Schema({
vol.Required("target"): { vol.Required("target"): {
vol.Required("entity_id"): cv.entity_id vol.Required("entity_id"): cv.entity_id
} }
}) })
# Регистрация сервисов с использованием extend # Register services
hass.services.async_register( hass.services.async_register(
DOMAIN, DOMAIN,
SERVICE_ASK_QUESTION, SERVICE_ASK_QUESTION,
@@ -146,6 +183,13 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
schema=base_schema schema=base_schema
) )
hass.services.async_register(
DOMAIN,
SERVICE_GET_HISTORY,
async_get_history,
schema=base_schema.extend(SERVICE_SCHEMA_GET_HISTORY.schema)
)
hass.services.async_register( hass.services.async_register(
DOMAIN, DOMAIN,
SERVICE_SET_SYSTEM_PROMPT, SERVICE_SET_SYSTEM_PROMPT,
@@ -182,14 +226,11 @@ async def async_check_api(session, endpoint: str, headers: dict, provider: str)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up HA Text AI from a config entry.""" """Set up HA Text AI from a config entry."""
try: try:
# Проверка наличия провайдера
if CONF_API_PROVIDER not in entry.data: if CONF_API_PROVIDER not in entry.data:
_LOGGER.error("API provider not specified") _LOGGER.error("API provider not specified")
raise ConfigEntryNotReady("API provider is required") raise ConfigEntryNotReady("API provider is required")
session = aiohttp_client.async_get_clientsession(hass) session = aiohttp_client.async_get_clientsession(hass)
# Получаем провайдера из конфигурации
api_provider = entry.data.get(CONF_API_PROVIDER) api_provider = entry.data.get(CONF_API_PROVIDER)
model = entry.data.get(CONF_MODEL, DEFAULT_MODEL) model = entry.data.get(CONF_MODEL, DEFAULT_MODEL)
endpoint = entry.data.get(CONF_API_ENDPOINT, endpoint = entry.data.get(CONF_API_ENDPOINT,
@@ -197,10 +238,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
else DEFAULT_ANTHROPIC_ENDPOINT).rstrip('/') else DEFAULT_ANTHROPIC_ENDPOINT).rstrip('/')
api_key = entry.data[CONF_API_KEY] api_key = entry.data[CONF_API_KEY]
# Определяем параметры подключения в зависимости от провайдера
is_anthropic = api_provider == API_PROVIDER_ANTHROPIC is_anthropic = api_provider == API_PROVIDER_ANTHROPIC
# Конфигурация headers
headers = { headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json" "Accept": "application/json"
@@ -209,50 +247,33 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if is_anthropic: if is_anthropic:
headers["x-api-key"] = api_key headers["x-api-key"] = api_key
headers["anthropic-version"] = "2023-06-01" headers["anthropic-version"] = "2023-06-01"
else: # OpenAI else:
headers["Authorization"] = f"Bearer {api_key}" headers["Authorization"] = f"Bearer {api_key}"
# Проверка API if not await async_check_api(session, endpoint, headers, api_provider):
try: raise ConfigEntryNotReady("API connection failed")
check_result = await async_check_api(session, endpoint, headers, api_provider)
if not check_result:
raise ConfigEntryNotReady("API connection failed")
except Exception as ex:
_LOGGER.error(f"API check failed: {ex}")
raise ConfigEntryNotReady("Failed to connect to API")
try: coordinator = HATextAICoordinator(
# Create coordinator hass,
coordinator = HATextAICoordinator( api_key=api_key,
hass, endpoint=endpoint,
api_key=api_key, model=model,
endpoint=endpoint, temperature=entry.data.get(CONF_TEMPERATURE, DEFAULT_TEMPERATURE),
model=model, max_tokens=entry.data.get(CONF_MAX_TOKENS, DEFAULT_MAX_TOKENS),
temperature=entry.data.get(CONF_TEMPERATURE, DEFAULT_TEMPERATURE), request_interval=float(entry.data.get(CONF_REQUEST_INTERVAL, DEFAULT_REQUEST_INTERVAL)),
max_tokens=entry.data.get(CONF_MAX_TOKENS, DEFAULT_MAX_TOKENS), name=entry.title or entry.data.get(CONF_NAME, "HA Text AI"),
request_interval=float(entry.data.get(CONF_REQUEST_INTERVAL, DEFAULT_REQUEST_INTERVAL)), session=session,
name=entry.title or entry.data.get("name", "HA Text AI"), # Добавляем fallback для имени is_anthropic=is_anthropic
session=session, )
is_anthropic=is_anthropic
)
# Initialize the coordinator await coordinator.async_initialize()
await coordinator.async_initialize() await coordinator.async_config_entry_first_refresh()
await coordinator.async_config_entry_first_refresh()
# Store coordinator hass.data.setdefault(DOMAIN, {})
if DOMAIN not in hass.data: hass.data[DOMAIN][entry.entry_id] = coordinator
hass.data[DOMAIN] = {}
hass.data[DOMAIN][entry.entry_id] = coordinator
# Set up platforms await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True
return True
except Exception as ex:
_LOGGER.exception("Error initializing coordinator: %s", str(ex))
raise ConfigEntryNotReady(f"Error initializing coordinator: {str(ex)}") from ex
except Exception as ex: except Exception as ex:
_LOGGER.exception("Setup error: %s", str(ex)) _LOGGER.exception("Setup error: %s", str(ex))
@@ -273,19 +294,4 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except Exception as ex: except Exception as ex:
_LOGGER.exception("Error unloading entry: %s", str(ex)) _LOGGER.exception("Error unloading entry: %s", str(ex))
return False # Убрано лишнее двоеточие return False
async def async_setup(hass, config):
"""Copy a custom icon to the www/icons directory."""
# The source of the icon file inside your integration
source = os.path.join(os.path.dirname(__file__), 'icons', 'icon.svg')
# Target directory /config/www/icons/
dest_dir = os.path.join(hass.config.path('www'), 'icons')
# Create the target directory if it does not already exist
os.makedirs(dest_dir, exist_ok=True)
# Path where the icon will be saved
dest = os.path.join(dest_dir, 'icon.svg')
# If the icon has not already been copied, copy it to the target
if not os.path.exists(dest):
shutil.copyfile(source, dest)
return True
+46 -25
View File
@@ -10,7 +10,7 @@ PLATFORMS: Final = [Platform.SENSOR]
CONF_NAME = "name" CONF_NAME = "name"
DEFAULT_NAME = "HA Text AI" DEFAULT_NAME = "HA Text AI"
# New constants for providers # Provider configuration
CONF_API_PROVIDER: Final = "api_provider" CONF_API_PROVIDER: Final = "api_provider"
API_PROVIDER_OPENAI: Final = "openai" API_PROVIDER_OPENAI: Final = "openai"
API_PROVIDER_ANTHROPIC: Final = "anthropic" API_PROVIDER_ANTHROPIC: Final = "anthropic"
@@ -45,6 +45,7 @@ MAX_TEMPERATURE: Final = 2.0
MIN_MAX_TOKENS: Final = 1 MIN_MAX_TOKENS: Final = 1
MAX_MAX_TOKENS: Final = 4096 MAX_MAX_TOKENS: Final = 4096
MIN_REQUEST_INTERVAL: Final = 0.1 MIN_REQUEST_INTERVAL: Final = 0.1
MAX_REQUEST_INTERVAL: Final = 60.0
# API constants # API constants
API_CHAT_PATH: Final = "chat/completions" API_CHAT_PATH: Final = "chat/completions"
@@ -56,6 +57,9 @@ HISTORY_FILTER_MODEL: Final = "filter_model"
HISTORY_FILTER_DATE: Final = "start_date" HISTORY_FILTER_DATE: Final = "start_date"
HISTORY_SORT_ORDER: Final = "sort_order" HISTORY_SORT_ORDER: Final = "sort_order"
HISTORY_INCLUDE_METADATA: Final = "include_metadata" HISTORY_INCLUDE_METADATA: Final = "include_metadata"
HISTORY_SORT_ASC: Final = "asc"
HISTORY_SORT_DESC: Final = "desc"
HISTORY_MAX_ENTRIES: Final = 100
# Service names # Service names
SERVICE_ASK_QUESTION: Final = "ask_question" SERVICE_ASK_QUESTION: Final = "ask_question"
@@ -64,10 +68,10 @@ SERVICE_GET_HISTORY: Final = "get_history"
SERVICE_SET_SYSTEM_PROMPT: Final = "set_system_prompt" SERVICE_SET_SYSTEM_PROMPT: Final = "set_system_prompt"
# Service descriptions # Service descriptions
SERVICE_ASK_QUESTION_DESCRIPTION: Final = "Ask a question to the AI model" SERVICE_ASK_QUESTION_DESCRIPTION: Final = "Send a question to the AI model and receive a detailed response. The response will be stored in the conversation history."
SERVICE_CLEAR_HISTORY_DESCRIPTION: Final = "Clear conversation history" SERVICE_CLEAR_HISTORY_DESCRIPTION: Final = "Delete all stored questions and responses from the conversation history."
SERVICE_GET_HISTORY_DESCRIPTION: Final = "Get conversation history" SERVICE_GET_HISTORY_DESCRIPTION: Final = "Retrieve recent conversation history with optional filtering and sorting."
SERVICE_SET_SYSTEM_PROMPT_DESCRIPTION: Final = "Set system prompt for AI model" SERVICE_SET_SYSTEM_PROMPT_DESCRIPTION: Final = "Set default system behavior instructions for all future conversations."
# Attribute keys # Attribute keys
ATTR_QUESTION: Final = "question" ATTR_QUESTION: Final = "question"
@@ -90,6 +94,7 @@ ATTR_TOKENS_USED: Final = "tokens_used"
ATTR_RETRY_COUNT: Final = "retry_count" ATTR_RETRY_COUNT: Final = "retry_count"
ATTR_QUEUE_POSITION: Final = "queue_position" ATTR_QUEUE_POSITION: Final = "queue_position"
ATTR_ESTIMATED_WAIT: Final = "estimated_wait" ATTR_ESTIMATED_WAIT: Final = "estimated_wait"
ATTR_SORT_ORDER: Final = "sort_order"
# Error messages # Error messages
ERROR_INVALID_API_KEY: Final = "invalid_api_key" ERROR_INVALID_API_KEY: Final = "invalid_api_key"
@@ -104,6 +109,7 @@ ERROR_QUEUE_FULL: Final = "queue_full"
ERROR_INVALID_PROMPT: Final = "invalid_prompt" ERROR_INVALID_PROMPT: Final = "invalid_prompt"
ERROR_INVALID_PARAMETERS: Final = "invalid_parameters" ERROR_INVALID_PARAMETERS: Final = "invalid_parameters"
ERROR_SERVICE_UNAVAILABLE: Final = "service_unavailable" ERROR_SERVICE_UNAVAILABLE: Final = "service_unavailable"
ERROR_INVALID_SORT_ORDER: Final = "invalid_sort_order"
# Configuration descriptions # Configuration descriptions
CONF_MODEL_DESCRIPTION: Final = "AI model to use for responses" CONF_MODEL_DESCRIPTION: Final = "AI model to use for responses"
@@ -130,6 +136,7 @@ ATTR_API_VERSION_DESCRIPTION: Final = "Current API version"
ATTR_ENDPOINT_STATUS_DESCRIPTION: Final = "Current endpoint status" ATTR_ENDPOINT_STATUS_DESCRIPTION: Final = "Current endpoint status"
ATTR_REQUEST_COUNT_DESCRIPTION: Final = "Total number of API requests" ATTR_REQUEST_COUNT_DESCRIPTION: Final = "Total number of API requests"
ATTR_TOKENS_USED_DESCRIPTION: Final = "Total tokens used" ATTR_TOKENS_USED_DESCRIPTION: Final = "Total tokens used"
ATTR_SORT_ORDER_DESCRIPTION: Final = "Sort order for history (asc/desc)"
# Entity attributes # Entity attributes
ENTITY_NAME: Final = "HA Text AI" ENTITY_NAME: Final = "HA Text AI"
@@ -170,19 +177,6 @@ QUEUE_MAX_SIZE: Final = 100
MAX_RETRIES: Final = 3 MAX_RETRIES: Final = 3
RETRY_DELAY: Final = 1.0 RETRY_DELAY: Final = 1.0
# Service schema constants
SCHEMA_QUESTION: Final = "question"
SCHEMA_MODEL: Final = "model"
SCHEMA_TEMPERATURE: Final = "temperature"
SCHEMA_MAX_TOKENS: Final = "max_tokens"
SCHEMA_PROMPT: Final = "prompt"
SCHEMA_LIMIT: Final = "limit"
# 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("question"): cv.string, vol.Required("question"): cv.string,
@@ -195,22 +189,49 @@ SERVICE_SCHEMA_ASK_QUESTION = vol.Schema({
vol.Optional("max_tokens"): vol.All( vol.Optional("max_tokens"): vol.All(
vol.Coerce(int), vol.Coerce(int),
vol.Range(min=MIN_MAX_TOKENS, max=MAX_MAX_TOKENS) vol.Range(min=MIN_MAX_TOKENS, max=MAX_MAX_TOKENS)
), )
vol.Optional("priority"): cv.boolean,
}) })
# set_system_prompt
SERVICE_SCHEMA_SET_SYSTEM_PROMPT = vol.Schema({ SERVICE_SCHEMA_SET_SYSTEM_PROMPT = vol.Schema({
vol.Required("prompt"): cv.string, vol.Required("prompt"): cv.string
}) })
# get_history
SERVICE_SCHEMA_GET_HISTORY = vol.Schema({ SERVICE_SCHEMA_GET_HISTORY = vol.Schema({
vol.Optional("limit", default=10): vol.All( vol.Optional("limit", default=10): vol.All(
vol.Coerce(int), vol.Coerce(int),
vol.Range(min=1, max=100) vol.Range(min=1, max=HISTORY_MAX_ENTRIES)
), ),
# vol.Optional("filter_model"): vol.In(SUPPORTED_MODELS),
vol.Optional("start_date"): cv.datetime, vol.Optional("start_date"): cv.datetime,
vol.Optional("include_metadata"): cv.boolean, vol.Optional("include_metadata"): cv.boolean,
vol.Optional("sort_order", default=HISTORY_SORT_DESC): vol.In([
HISTORY_SORT_ASC,
HISTORY_SORT_DESC
])
}) })
# Configuration schema
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_API_KEY): cv.string,
vol.Optional(CONF_MODEL, default=DEFAULT_MODEL): cv.string,
vol.Optional(CONF_TEMPERATURE, default=DEFAULT_TEMPERATURE): vol.All(
vol.Coerce(float),
vol.Range(min=MIN_TEMPERATURE, max=MAX_TEMPERATURE)
),
vol.Optional(CONF_MAX_TOKENS, default=DEFAULT_MAX_TOKENS): vol.All(
vol.Coerce(int),
vol.Range(min=MIN_MAX_TOKENS, max=MAX_MAX_TOKENS)
),
vol.Optional(CONF_API_ENDPOINT): cv.string,
vol.Optional(CONF_REQUEST_INTERVAL, default=DEFAULT_REQUEST_INTERVAL): vol.All(
vol.Coerce(float),
vol.Range(min=MIN_REQUEST_INTERVAL, max=MAX_REQUEST_INTERVAL)
),
vol.Required(CONF_API_PROVIDER): vol.In(API_PROVIDERS)
})
}, extra=vol.ALLOW_EXTRA)
# 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"
File diff suppressed because it is too large Load Diff
@@ -11,7 +11,7 @@
"temperature": "Response creativity (0-2, lower = more focused and consistent)", "temperature": "Response creativity (0-2, lower = more focused and consistent)",
"max_tokens": "Maximum response length (1-4096 tokens)", "max_tokens": "Maximum response length (1-4096 tokens)",
"api_endpoint": "Custom API endpoint URL (optional)", "api_endpoint": "Custom API endpoint URL (optional)",
"request_interval": "Minimum time between requests in seconds (min: 0.1)", "request_interval": "Minimum time between requests in seconds (0.1-60)",
"name": "Name for this integration instance (e.g., 'GPT Assistant', 'Claude Helper')" "name": "Name for this integration instance (e.g., 'GPT Assistant', 'Claude Helper')"
} }
} }
@@ -28,6 +28,9 @@
"queue_full": "Request queue full - try again later", "queue_full": "Request queue full - try again later",
"invalid_url_format": "Invalid API endpoint URL format", "invalid_url_format": "Invalid API endpoint URL format",
"invalid_input": "Invalid configuration parameters", "invalid_input": "Invalid configuration parameters",
"invalid_parameters": "Invalid service parameters provided",
"service_unavailable": "Service temporarily unavailable",
"context_length": "Maximum context length exceeded",
"unknown": "Unexpected error - check logs for details" "unknown": "Unexpected error - check logs for details"
} }
}, },
@@ -39,8 +42,8 @@
"data": { "data": {
"model": "Select AI model (provider-specific)", "model": "Select AI model (provider-specific)",
"temperature": "Response creativity (0-2)", "temperature": "Response creativity (0-2)",
"max_tokens": "Maximum response length in tokens", "max_tokens": "Maximum response length in tokens (1-4096)",
"request_interval": "Minimum seconds between requests" "request_interval": "Minimum seconds between requests (0.1-60)"
} }
} }
} }
@@ -54,6 +57,10 @@
"name": "Question", "name": "Question",
"description": "Your question or prompt for the AI model" "description": "Your question or prompt for the AI model"
}, },
"system_prompt": {
"name": "System Prompt",
"description": "Optional context or instructions for this specific question"
},
"model": { "model": {
"name": "Model", "name": "Model",
"description": "Optional specific AI model for this request" "description": "Optional specific AI model for this request"
@@ -67,6 +74,42 @@
"description": "Optional maximum response length (1-4096 tokens)" "description": "Optional maximum response length (1-4096 tokens)"
} }
} }
},
"clear_history": {
"name": "Clear History",
"description": "Delete all stored questions and responses from the conversation history."
},
"get_history": {
"name": "Get History",
"description": "Retrieve recent conversation history with optional filtering.",
"fields": {
"limit": {
"name": "Limit",
"description": "Maximum number of entries to return (1-100)"
},
"start_date": {
"name": "Start Date",
"description": "Optional date to filter history from"
},
"include_metadata": {
"name": "Include Metadata",
"description": "Include additional response metadata"
},
"sort_order": {
"name": "Sort Order",
"description": "Order of results (asc/desc)"
}
}
},
"set_system_prompt": {
"name": "Set System Prompt",
"description": "Set default system behavior instructions for all future conversations.",
"fields": {
"prompt": {
"name": "System Prompt",
"description": "Instructions that define how the AI should behave"
}
}
} }
}, },
"entity": { "entity": {
@@ -79,7 +122,28 @@
"processing": "Processing", "processing": "Processing",
"error": "Error", "error": "Error",
"disconnected": "Disconnected", "disconnected": "Disconnected",
"rate_limited": "Rate Limited" "rate_limited": "Rate Limited",
"maintenance": "Maintenance",
"retrying": "Retrying",
"queued": "Queued",
"updating": "Updating"
},
"state_attributes": {
"question": "Last question asked",
"response": "Last response received",
"last_updated": "Time of last update",
"model": "Current AI model",
"temperature": "Temperature setting",
"max_tokens": "Max tokens setting",
"total_responses": "Total responses",
"system_prompt": "Current system prompt",
"response_time": "Last response time",
"queue_size": "Queue size",
"api_status": "API status",
"error_count": "Error count",
"last_error": "Last error",
"tokens_used": "Total tokens used",
"request_count": "Total requests"
} }
} }
} }