mirror of
https://github.com/smkrv/ha-text-ai.git
synced 2026-07-21 22:54:00 +08:00
Features: - disable_thinking toggle (issue #11) with per-provider semantics: OpenAI classic gets /no_think soft-switch, OpenAI reasoning gets reasoning_effort=low, DeepSeek gets both, Anthropic no-op (thinking opt-in), Gemini 2.5+ gets thinking_budget=0 - OpenAI reasoning model support (o1/o3/o4-mini/gpt-5 family): max_completion_tokens, developer role, reasoning_effort - Per-request disable_thinking override in ask_question service - Provider-specific temperature clip (Anthropic 0-1, others 0-2) Security: - Require API key re-entry on provider change (OptionsFlow) - Validate Anthropic json_schema before system-prompt concatenation - Symlink protection in history file operations - Hardened secret redaction regexes (sk-*, AIza*, x-api-key) - get_history service: hard cap on limit (default 10, max 100) Reliability: - Retry on 502/503/504 in addition to 429/timeout - Honor Retry-After header on 429 - Exception chaining (raise ... from err) - _strip_think_blocks handles nested/dangling tags - normalize_name sha256 fallback for empty-collapse inputs UI/housekeeping: - api_key uses TextSelector(type=PASSWORD) - DeviceInfo entry_type=SERVICE - Services unregister on last entry unload - Dependabot for GitHub Actions - persist-credentials=false in checkout steps - manifest requirements pinned with upper bounds - Ignore docs/plans/ (working artifacts) License: PolyForm Noncommercial 1.0.0 -> MIT No breaking changes: service response shape, sensor attributes, entity IDs and on-disk formats unchanged.
337 lines
12 KiB
JSON
337 lines
12 KiB
JSON
{
|
|
"config": {
|
|
"step": {
|
|
"provider": {
|
|
"title": "Provider Settings",
|
|
"description": "Provide connection details for your chosen AI provider.",
|
|
"data": {
|
|
"name": "Instance name (e.g., 'GPT Assistant', 'Claude Helper')",
|
|
"api_key": "API key for authentication",
|
|
"model": "AI model to use",
|
|
"api_endpoint": "Custom API endpoint URL (optional)",
|
|
"temperature": "Response creativity (0-2, lower = more focused)",
|
|
"max_tokens": "Maximum response length (1-100000 tokens)",
|
|
"request_interval": "Minimum time between requests (0.1-60 seconds)",
|
|
"api_timeout": "API request timeout in seconds (5-600)",
|
|
"context_messages": "Number of context messages to retain (1-20)",
|
|
"max_history_size": "Maximum conversation history size (1-100)",
|
|
"allow_local_network": "Allow local network endpoints (for self-hosted proxies)",
|
|
"disable_thinking": "Disable thinking/reasoning mode (Qwen /no_think, strips <think> blocks, Gemini 2.5 thinking_budget=0)"
|
|
}
|
|
},
|
|
"user": {
|
|
"title": "Configure HA Text AI Instance",
|
|
"description": "Set up a new AI assistant instance with your selected provider.",
|
|
"data": {
|
|
"name": "Instance name (e.g., 'GPT Assistant', 'Claude Helper')",
|
|
"api_key": "API key for authentication",
|
|
"model": "AI model to use",
|
|
"temperature": "Response creativity (0-2, lower = more focused)",
|
|
"max_tokens": "Maximum response length (1-100000 tokens)",
|
|
"api_endpoint": "Custom API endpoint URL (optional)",
|
|
"api_provider": "API Provider",
|
|
"request_interval": "Minimum time between requests (0.1-60 seconds)",
|
|
"api_timeout": "API request timeout in seconds (5-600)",
|
|
"context_messages": "Number of context messages to retain (1-20)",
|
|
"max_history_size": "Maximum conversation history size (1-100)",
|
|
"allow_local_network": "Allow local network endpoints (for self-hosted proxies)",
|
|
"disable_thinking": "Disable thinking/reasoning mode (Qwen /no_think, strips <think> blocks, Gemini 2.5 thinking_budget=0)"
|
|
}
|
|
}
|
|
},
|
|
"error": {
|
|
"history_storage_error": "Failed to initialize history storage. Check permissions.",
|
|
"history_rotation_error": "Error during history file rotation.",
|
|
"history_file_access_error": "Cannot access history storage directory.",
|
|
"name_exists": "An instance with this name already exists",
|
|
"invalid_name": "Invalid instance name",
|
|
"invalid_auth": "Authentication failed - check your API key",
|
|
"api_key_required": "API key is required when changing provider or endpoint",
|
|
"invalid_api_key": "Invalid API key - please verify your credentials",
|
|
"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",
|
|
"unknown": "Unexpected error occurred",
|
|
"empty": "Name cannot be empty",
|
|
"name_too_long": "Name must be 50 characters or less"
|
|
},
|
|
"abort": {
|
|
"already_configured": "Instance already configured"
|
|
}
|
|
},
|
|
"options": {
|
|
"step": {
|
|
"init": {
|
|
"title": "Select Provider",
|
|
"description": "Choose the AI provider for this instance. The integration will reload after saving changes.",
|
|
"data": {
|
|
"api_provider": "API Provider"
|
|
}
|
|
},
|
|
"settings": {
|
|
"title": "Connection & Model Settings",
|
|
"description": "Configure API credentials and model parameters. Changes will take effect after the integration reloads.",
|
|
"data": {
|
|
"api_key": "API Key",
|
|
"api_endpoint": "API Endpoint URL",
|
|
"model": "AI model",
|
|
"temperature": "Response creativity (0-2)",
|
|
"max_tokens": "Maximum response length (1-100000)",
|
|
"request_interval": "Minimum request interval (0.1-60 seconds)",
|
|
"api_timeout": "API request timeout in seconds (5-600)",
|
|
"context_messages": "Number of previous messages to include in context (1-20)",
|
|
"max_history_size": "Maximum conversation history size (1-100)",
|
|
"allow_local_network": "Allow local network endpoints (for self-hosted proxies)",
|
|
"disable_thinking": "Disable thinking/reasoning mode (Qwen /no_think, strips <think> blocks, Gemini 2.5 thinking_budget=0)"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"selector": {
|
|
"api_provider": {
|
|
"options": {
|
|
"openai": "OpenAI (compatible)",
|
|
"anthropic": "Anthropic (compatible)",
|
|
"deepseek": "DeepSeek",
|
|
"gemini": "Google Gemini"
|
|
}
|
|
}
|
|
},
|
|
"services": {
|
|
"ask_question": {
|
|
"name": "Ask Question (HA Text AI)",
|
|
"description": "Send a question to the AI model and receive a detailed response. This service now returns response data directly, eliminating the need for separate text sensors and the 255-character limitation. The response will also be stored in the conversation history.",
|
|
"fields": {
|
|
"instance": {
|
|
"name": "Instance",
|
|
"description": "Name of the HA Text AI instance to use"
|
|
},
|
|
"question": {
|
|
"name": "Question",
|
|
"description": "Your question or prompt for the AI assistant"
|
|
},
|
|
"context_messages": {
|
|
"name": "Context Messages",
|
|
"description": "Number of previous messages to include in context (1-20)"
|
|
},
|
|
"system_prompt": {
|
|
"name": "System Prompt",
|
|
"description": "Optional system prompt to set context for this specific question"
|
|
},
|
|
"model": {
|
|
"name": "Model",
|
|
"description": "Select AI model to use (optional, overrides default setting)"
|
|
},
|
|
"temperature": {
|
|
"name": "Temperature",
|
|
"description": "Controls response creativity (0.0-2.0)"
|
|
},
|
|
"max_tokens": {
|
|
"name": "Max Tokens",
|
|
"description": "Maximum length of the response (1-100000 tokens)"
|
|
},
|
|
"structured_output": {
|
|
"name": "Structured Output",
|
|
"description": "Enable JSON structured output mode. When enabled, the AI will respond with valid JSON matching the provided schema."
|
|
},
|
|
"json_schema": {
|
|
"name": "JSON Schema",
|
|
"description": "JSON Schema defining the structure of the expected response. Required when structured_output is enabled."
|
|
},
|
|
"disable_thinking": {
|
|
"name": "Disable Thinking",
|
|
"description": "Disable model thinking/reasoning for this request. Overrides the integration-level setting."
|
|
}
|
|
}
|
|
},
|
|
"clear_history": {
|
|
"name": "Clear History",
|
|
"description": "Delete all stored questions and responses from the conversation history",
|
|
"fields": {
|
|
"instance": {
|
|
"name": "Instance",
|
|
"description": "Name of the HA Text AI instance to clear history for"
|
|
}
|
|
}
|
|
},
|
|
"get_history": {
|
|
"name": "Get History",
|
|
"description": "Retrieve conversation history with optional filtering and sorting",
|
|
"fields": {
|
|
"instance": {
|
|
"name": "Instance",
|
|
"description": "Name of the HA Text AI instance to get history from"
|
|
},
|
|
"limit": {
|
|
"name": "Limit",
|
|
"description": "Number of conversations to return (1-100)"
|
|
},
|
|
"filter_model": {
|
|
"name": "Filter Model",
|
|
"description": "Filter conversations by specific AI model"
|
|
},
|
|
"start_date": {
|
|
"name": "Start Date",
|
|
"description": "Filter conversations starting from this date/time"
|
|
},
|
|
"include_metadata": {
|
|
"name": "Include Metadata",
|
|
"description": "Include additional information like tokens used, response time, etc."
|
|
},
|
|
"sort_order": {
|
|
"name": "Sort Order",
|
|
"description": "Sort order for results (newest or oldest first)"
|
|
}
|
|
}
|
|
},
|
|
"set_system_prompt": {
|
|
"name": "Set System Prompt",
|
|
"description": "Set default system behavior instructions for all future conversations",
|
|
"fields": {
|
|
"instance": {
|
|
"name": "Instance",
|
|
"description": "Name of the HA Text AI instance to set system prompt for"
|
|
},
|
|
"prompt": {
|
|
"name": "System Prompt",
|
|
"description": "Instructions that define how the AI should behave and respond"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"entity": {
|
|
"sensor": {
|
|
"ha_text_ai": {
|
|
"name": "{name}",
|
|
"state": {
|
|
"ready": "Ready",
|
|
"processing": "Processing",
|
|
"error": "Error",
|
|
"disconnected": "Disconnected",
|
|
"rate_limited": "Rate Limited",
|
|
"maintenance": "Maintenance",
|
|
"initializing": "Initializing",
|
|
"retrying": "Retrying"
|
|
},
|
|
"state_attributes": {
|
|
"question": {
|
|
"name": "Last Question"
|
|
},
|
|
"response": {
|
|
"name": "Last Response"
|
|
},
|
|
"model": {
|
|
"name": "Current Model"
|
|
},
|
|
"temperature": {
|
|
"name": "Temperature"
|
|
},
|
|
"max_tokens": {
|
|
"name": "Max Tokens"
|
|
},
|
|
"system_prompt": {
|
|
"name": "System Prompt"
|
|
},
|
|
"response_time": {
|
|
"name": "Last Response Time"
|
|
},
|
|
"total_responses": {
|
|
"name": "Total Responses"
|
|
},
|
|
"error_count": {
|
|
"name": "Error Count"
|
|
},
|
|
"last_error": {
|
|
"name": "Last Error"
|
|
},
|
|
"api_status": {
|
|
"name": "API Status"
|
|
},
|
|
"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"
|
|
},
|
|
"last_model": {
|
|
"name": "Last Used Model"
|
|
},
|
|
"last_timestamp": {
|
|
"name": "Last Response Time"
|
|
},
|
|
"instance_name": {
|
|
"name": "Instance Name"
|
|
},
|
|
"normalized_name": {
|
|
"name": "Normalized Name"
|
|
},
|
|
"last_error": {
|
|
"name": "Last Error"
|
|
},
|
|
"conversation_history": {
|
|
"name": "Conversation History"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|