Security:
- Make validate_endpoint async with hass.async_add_executor_job for DNS resolution
- Use _RestrictedIPError instead of fragile string matching for IP check flow
- Add is_multicast/is_unspecified to SSRF IP restriction checks
- Remove resolved private IP from error messages (generic message)
- Remove raw endpoint from __init__.py error log
- Sanitize error messages in metrics: strip URLs, API keys, Gemini key patterns
- Truncate API error response bodies before logging (512 chars)
- Use generic error messages in Gemini exception handlers (no str(e) interpolation)
- Pass api_key as explicit APIClient constructor parameter (not from header)
- Add defensive validation: Gemini provider requires api_key at construction
Code quality:
- Add constants: DEFAULT_INSTANCE_NAME, MIN/MAX_CONTEXT_MESSAGES, MIN/MAX_HISTORY_SIZE
- Replace all hardcoded schema ranges with named constants
- Move datetime import to module level in history.py
- Remove unused full_history/full_history_available keys
- Chain socket.gaierror properly with raise...from
- Extract HistoryManager (history.py) and MetricsManager (metrics.py) from coordinator
- Fix Gemini chat: use client.chats.create(history=...) instead of sequential send_message
- Fix float("inf") in metrics breaking json.dump persistence
- Fix _get_current_state checking wrong error key ("error" vs "error_message")
- Fix API key re-entry requirement when endpoint/provider changes in options flow
- Make CONF_API_KEY optional in options schema (stored key used as fallback)
- Add DNS rebinding protection via socket.getaddrinfo in validate_endpoint
- Remove mass assignment vulnerability in config_flow._create_entry
- Add description_placeholders to all error re-show paths
- Fix history migration overwriting existing JSON data
- Return list copy from get_limited_history to prevent reference leaks
- Add history_info to _get_safe_initial_state for data shape consistency
- Add defensive None check in _get_sanitized_last_response
- Move dt_util import to module level in config_flow
- Remove dead fallback branches in coordinator.last_response property
- Fix sensor min_latency display after float("inf") removal
- Fix history directory permissions from 0o777 to 0o755
- Deduplicate schema definitions via _build_provider_schema()
- Use centralized build_auth_headers from providers.py