1 """Support for functionality to have conversations with Home Assistant."""
3 from __future__
import annotations
7 from typing
import Literal
9 import voluptuous
as vol
26 from .agent_manager
import (
42 OLD_HOME_ASSISTANT_AGENT,
45 ConversationEntityFeature,
47 from .default_agent
import DefaultAgent, async_setup_default_agent
48 from .entity
import ConversationEntity
49 from .http
import async_setup
as async_setup_conversation_http
50 from .models
import AbstractConversationAgent, ConversationInput, ConversationResult
51 from .trace
import ConversationTraceEventType, async_conversation_trace_append
55 "HOME_ASSISTANT_AGENT",
56 "OLD_HOME_ASSISTANT_AGENT",
58 "ConversationEntityFeature",
61 "ConversationTraceEventType",
62 "async_conversation_trace_append",
64 "async_get_agent_info",
70 _LOGGER = logging.getLogger(__name__)
72 REGEX_TYPE = type(re.compile(
""))
74 SERVICE_PROCESS_SCHEMA = vol.Schema(
76 vol.Required(ATTR_TEXT): cv.string,
77 vol.Optional(ATTR_LANGUAGE): cv.string,
78 vol.Optional(ATTR_AGENT_ID): agent_id_validator,
79 vol.Optional(ATTR_CONVERSATION_ID): cv.string,
84 SERVICE_RELOAD_SCHEMA = vol.Schema(
86 vol.Optional(ATTR_LANGUAGE): cv.string,
87 vol.Optional(ATTR_AGENT_ID): agent_id_validator,
91 CONFIG_SCHEMA = vol.Schema(
93 vol.Optional(DOMAIN): vol.Schema(
95 vol.Optional(
"intents"): vol.Schema(
96 {cv.string: vol.All(cv.ensure_list, [cv.string])}
101 extra=vol.ALLOW_EXTRA,
109 config_entry: ConfigEntry,
110 agent: AbstractConversationAgent,
112 """Set the agent to handle the conversations."""
120 config_entry: ConfigEntry,
122 """Set the agent to handle the conversations."""
128 hass: HomeAssistant, agent_id: str |
None =
None
129 ) -> set[str] | Literal[
"*"]:
130 """Return languages supported by conversation agents.
132 If an agent is specified, returns a set of languages supported by that agent.
133 If no agent is specified, return a set with the union of languages supported by
134 all conversation agents.
137 agents: list[ConversationEntity | AbstractConversationAgent]
143 raise ValueError(f
"Agent {agent_id} not found")
146 if agent.supported_languages == MATCH_ALL:
152 agents =
list(hass.data[DATA_COMPONENT].entities)
153 for info
in agent_manager.async_get_agent_info():
154 agent = agent_manager.async_get_agent(info.id)
155 assert agent
is not None
158 if agent.supported_languages == MATCH_ALL:
163 languages: set[str] = set()
166 for language_tag
in agent.supported_languages:
167 languages.add(language_tag)
175 agent_id: str |
None =
None,
176 ) -> AgentInfo |
None:
177 """Get information on the agent or None if not found."""
183 if isinstance(agent, ConversationEntity):
185 if not isinstance(name, str):
186 name = agent.entity_id
187 return AgentInfo(id=agent.entity_id, name=name)
191 for agent_info
in manager.async_get_agent_info():
192 if agent_info.id == agent_id:
199 hass: HomeAssistant, agent_id: str |
None, language: str
201 """Prepare given agent."""
205 raise ValueError(
"Invalid agent specified")
207 await agent.async_prepare(language)
211 hass: HomeAssistant, user_input: ConversationInput
213 """Try to match input against sentence triggers and return response text.
215 Returns None if no match occurred.
218 assert isinstance(default_agent, DefaultAgent)
220 return await default_agent.async_handle_sentence_triggers(user_input)
224 hass: HomeAssistant, user_input: ConversationInput
225 ) -> intent.IntentResponse |
None:
226 """Try to match input against registered intents and return response.
228 Returns None if no match occurred.
231 assert isinstance(default_agent, DefaultAgent)
233 return await default_agent.async_handle_intents(user_input)
236 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
237 """Register the process service."""
238 entity_component = EntityComponent[ConversationEntity](_LOGGER, DOMAIN, hass)
239 hass.data[DATA_COMPONENT] = entity_component
242 hass, entity_component, config.get(DOMAIN, {}).
get(
"intents", {})
247 async_migrate_engine,
251 hass,
"conversation", OLD_HOME_ASSISTANT_AGENT, HOME_ASSISTANT_AGENT
254 async
def handle_process(service: ServiceCall) -> ServiceResponse:
255 """Parse text into commands."""
256 text = service.data[ATTR_TEXT]
257 _LOGGER.debug(
"Processing: <%s>", text)
262 conversation_id=service.data.get(ATTR_CONVERSATION_ID),
263 context=service.context,
264 language=service.data.get(ATTR_LANGUAGE),
265 agent_id=service.data.get(ATTR_AGENT_ID),
267 except intent.IntentHandleError
as err:
270 if service.return_response:
271 return result.as_dict()
275 async
def handle_reload(service: ServiceCall) ->
None:
276 """Reload intents."""
278 language=service.data.get(ATTR_LANGUAGE)
281 hass.services.async_register(
285 schema=SERVICE_PROCESS_SCHEMA,
286 supports_response=SupportsResponse.OPTIONAL,
288 hass.services.async_register(
289 DOMAIN, SERVICE_RELOAD, handle_reload, schema=SERVICE_RELOAD_SCHEMA
291 async_setup_conversation_http(hass)
297 """Set up a config entry."""
302 """Unload a config entry."""
None async_migrate_engine(HomeAssistant hass, Literal["conversation", "stt", "tts", "wake_word"] engine_type, str old_value, str new_value)
web.Response get(self, web.Request request, str config_key)
AgentManager get_agent_manager(HomeAssistant hass)
ConversationResult async_converse(HomeAssistant hass, str text, str|None conversation_id, Context context, str|None language=None, str|None agent_id=None, str|None device_id=None)
AbstractConversationAgent|ConversationEntity|None async_get_agent(HomeAssistant hass, str|None agent_id=None)
None async_setup_default_agent(core.HomeAssistant hass, EntityComponent[ConversationEntity] entity_component, dict[str, Any] config_intents)
str|None async_handle_sentence_triggers(HomeAssistant hass, ConversationInput user_input)
AgentInfo|None async_get_agent_info(HomeAssistant hass, str|None agent_id=None)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
None async_unset_agent(HomeAssistant hass, ConfigEntry config_entry)
intent.IntentResponse|None async_handle_intents(HomeAssistant hass, ConversationInput user_input)
None async_set_agent(HomeAssistant hass, ConfigEntry config_entry, AbstractConversationAgent agent)
None async_prepare_agent(HomeAssistant hass, str|None agent_id, str language)
bool async_setup(HomeAssistant hass, ConfigType config)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
set[str]|Literal["*"] async_get_conversation_languages(HomeAssistant hass, str|None agent_id=None)
None async_reload(HomeAssistant hass, ServiceCall service_call)