diff --git a/homeassistant/components/google_generative_ai_conversation/diagnostics.py b/homeassistant/components/google_generative_ai_conversation/diagnostics.py new file mode 100644 index 00000000000..13643da7e00 --- /dev/null +++ b/homeassistant/components/google_generative_ai_conversation/diagnostics.py @@ -0,0 +1,26 @@ +"""Diagnostics support for Google Generative AI Conversation.""" + +from __future__ import annotations + +from typing import Any + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_API_KEY +from homeassistant.core import HomeAssistant + +TO_REDACT = {CONF_API_KEY} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: ConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + return async_redact_data( + { + "title": entry.title, + "data": entry.data, + "options": entry.options, + }, + TO_REDACT, + ) diff --git a/script/hassfest/manifest.py b/script/hassfest/manifest.py index cddfd5e101b..e92ec00b117 100644 --- a/script/hassfest/manifest.py +++ b/script/hassfest/manifest.py @@ -120,8 +120,6 @@ NO_DIAGNOSTICS = [ "gdacs", "geonetnz_quakes", "google_assistant_sdk", - # diagnostics wouldn't really add anything (no data to provide) - "google_generative_ai_conversation", "hyperion", # Modbus is excluded because it doesn't have to have a config flow # according to ADR-0010, since it's a protocol integration. This diff --git a/tests/components/google_generative_ai_conversation/snapshots/test_diagnostics.ambr b/tests/components/google_generative_ai_conversation/snapshots/test_diagnostics.ambr new file mode 100644 index 00000000000..316bf74b72a --- /dev/null +++ b/tests/components/google_generative_ai_conversation/snapshots/test_diagnostics.ambr @@ -0,0 +1,22 @@ +# serializer version: 1 +# name: test_diagnostics + dict({ + 'data': dict({ + 'api_key': '**REDACTED**', + }), + 'options': dict({ + 'chat_model': 'models/gemini-1.5-flash-latest', + 'dangerous_block_threshold': 'BLOCK_MEDIUM_AND_ABOVE', + 'harassment_block_threshold': 'BLOCK_MEDIUM_AND_ABOVE', + 'hate_block_threshold': 'BLOCK_MEDIUM_AND_ABOVE', + 'max_tokens': 150, + 'prompt': 'Speak like a pirate', + 'recommended': False, + 'sexual_block_threshold': 'BLOCK_MEDIUM_AND_ABOVE', + 'temperature': 1.0, + 'top_k': 64, + 'top_p': 0.95, + }), + 'title': 'Google Generative AI Conversation', + }) +# --- diff --git a/tests/components/google_generative_ai_conversation/test_diagnostics.py b/tests/components/google_generative_ai_conversation/test_diagnostics.py new file mode 100644 index 00000000000..ebc1b5e52a5 --- /dev/null +++ b/tests/components/google_generative_ai_conversation/test_diagnostics.py @@ -0,0 +1,59 @@ +"""Tests for the diagnostics data provided by the Google Generative AI Conversation integration.""" + +from syrupy.assertion import SnapshotAssertion + +from homeassistant.components.google_generative_ai_conversation.const import ( + CONF_CHAT_MODEL, + CONF_DANGEROUS_BLOCK_THRESHOLD, + CONF_HARASSMENT_BLOCK_THRESHOLD, + CONF_HATE_BLOCK_THRESHOLD, + CONF_MAX_TOKENS, + CONF_PROMPT, + CONF_RECOMMENDED, + CONF_SEXUAL_BLOCK_THRESHOLD, + CONF_TEMPERATURE, + CONF_TOP_K, + CONF_TOP_P, + RECOMMENDED_CHAT_MODEL, + RECOMMENDED_HARM_BLOCK_THRESHOLD, + RECOMMENDED_MAX_TOKENS, + RECOMMENDED_TEMPERATURE, + RECOMMENDED_TOP_K, + RECOMMENDED_TOP_P, +) +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry +from tests.typing import ClientSessionGenerator + + +async def test_diagnostics( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + mock_config_entry: MockConfigEntry, + snapshot: SnapshotAssertion, +) -> None: + """Test diagnostics.""" + mock_config_entry.add_to_hass(hass) + hass.config_entries.async_update_entry( + mock_config_entry, + options={ + CONF_RECOMMENDED: False, + CONF_PROMPT: "Speak like a pirate", + CONF_TEMPERATURE: RECOMMENDED_TEMPERATURE, + CONF_CHAT_MODEL: RECOMMENDED_CHAT_MODEL, + CONF_TOP_P: RECOMMENDED_TOP_P, + CONF_TOP_K: RECOMMENDED_TOP_K, + CONF_MAX_TOKENS: RECOMMENDED_MAX_TOKENS, + CONF_HARASSMENT_BLOCK_THRESHOLD: RECOMMENDED_HARM_BLOCK_THRESHOLD, + CONF_HATE_BLOCK_THRESHOLD: RECOMMENDED_HARM_BLOCK_THRESHOLD, + CONF_SEXUAL_BLOCK_THRESHOLD: RECOMMENDED_HARM_BLOCK_THRESHOLD, + CONF_DANGEROUS_BLOCK_THRESHOLD: RECOMMENDED_HARM_BLOCK_THRESHOLD, + }, + ) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + assert ( + await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry) + == snapshot + )