-
-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Google Assistant SDK conversation agent #85499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,21 +2,24 @@ | |||||
| from __future__ import annotations | ||||||
|
|
||||||
| import aiohttp | ||||||
| from gassist_text import TextAssistant | ||||||
| from google.oauth2.credentials import Credentials | ||||||
| import voluptuous as vol | ||||||
|
|
||||||
| from homeassistant.components import conversation | ||||||
| from homeassistant.config_entries import ConfigEntry, ConfigEntryState | ||||||
| from homeassistant.const import CONF_NAME, Platform | ||||||
| from homeassistant.core import HomeAssistant, ServiceCall | ||||||
| from homeassistant.const import CONF_ACCESS_TOKEN, CONF_NAME, Platform | ||||||
| from homeassistant.core import Context, HomeAssistant, ServiceCall | ||||||
| from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady | ||||||
| from homeassistant.helpers import discovery | ||||||
| from homeassistant.helpers import discovery, intent | ||||||
| from homeassistant.helpers.config_entry_oauth2_flow import ( | ||||||
| OAuth2Session, | ||||||
| async_get_config_entry_implementation, | ||||||
| ) | ||||||
| from homeassistant.helpers.typing import ConfigType | ||||||
|
|
||||||
| from .const import DOMAIN | ||||||
| from .helpers import async_send_text_commands | ||||||
| from .const import CONF_LANGUAGE_CODE, DOMAIN | ||||||
| from .helpers import async_send_text_commands, default_language_code | ||||||
|
|
||||||
| SERVICE_SEND_TEXT_COMMAND = "send_text_command" | ||||||
| SERVICE_SEND_TEXT_COMMAND_FIELD_COMMAND = "command" | ||||||
|
|
@@ -57,6 +60,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | |||||
| hass.data.setdefault(DOMAIN, {})[entry.entry_id] = session | ||||||
|
|
||||||
| await async_setup_service(hass) | ||||||
| agent = GoogleAssistantConversationAgent(hass, entry) | ||||||
| conversation.async_set_agent(hass, agent) | ||||||
|
|
||||||
| return True | ||||||
|
|
||||||
|
|
@@ -90,3 +95,55 @@ async def send_text_command(call: ServiceCall) -> None: | |||||
| send_text_command, | ||||||
| schema=SERVICE_SEND_TEXT_COMMAND_SCHEMA, | ||||||
| ) | ||||||
|
|
||||||
|
|
||||||
| class GoogleAssistantConversationAgent(conversation.AbstractConversationAgent): | ||||||
| """Google Assistant SDK conversation agent.""" | ||||||
|
|
||||||
| def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: | ||||||
| """Initialize the agent.""" | ||||||
| self.hass = hass | ||||||
| self.entry = entry | ||||||
| self.assistant: TextAssistant | None = None | ||||||
| self.session: OAuth2Session | None = None | ||||||
|
|
||||||
| @property | ||||||
| def attribution(self): | ||||||
| """Return the attribution.""" | ||||||
| return { | ||||||
| "name": "Powered by Google Assistant SDK", | ||||||
| "url": "https://www.home-assistant.io/integrations/google_assistant_sdk/", | ||||||
| } | ||||||
|
|
||||||
| async def async_process( | ||||||
| self, | ||||||
| text: str, | ||||||
| context: Context, | ||||||
| conversation_id: str | None = None, | ||||||
| language: str | None = None, | ||||||
| ) -> conversation.ConversationResult | None: | ||||||
| """Process a sentence.""" | ||||||
| if self.session: | ||||||
| session = self.session | ||||||
| else: | ||||||
| session = self.hass.data[DOMAIN].get(self.entry.entry_id) | ||||||
| self.session = session | ||||||
| if not session.valid_token: | ||||||
| await session.async_ensure_token_valid() | ||||||
| self.assistant = None | ||||||
| if not self.assistant: | ||||||
| credentials = Credentials(session.token[CONF_ACCESS_TOKEN]) | ||||||
| language_code = self.entry.options.get( | ||||||
| CONF_LANGUAGE_CODE, default_language_code(self.hass) | ||||||
| ) | ||||||
| self.assistant = TextAssistant(credentials, language_code) | ||||||
|
|
||||||
| resp = self.assistant.assist(text) | ||||||
| text_response = resp[0] | ||||||
|
|
||||||
| language = language or self.hass.config.language | ||||||
| intent_response = intent.IntentResponse(language=language) | ||||||
| intent_response.async_set_speech(text_response) | ||||||
| return conversation.ConversationResult( | ||||||
| response=intent_response, conversation_id=conversation_id | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way Then in your response you return a conversation ID such that follow-up responses work. Now in this case it doesn't seem like you're passing conversation_id so you should set
Suggested change
Now in your screenshot I did notice that it's allowing follow-up commands, so I am not sure how that works then 🤷
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both DefaultAgent and AlmondAgent (the only other two agents) do exactly the same thing. conversation_id starts with None and is never modified. Anyway for Google Assistant we cannot really have many concurrent conversations, see https://github.com/tronikos/gassist_text/blob/main/src/google/assistant/embedded/v1alpha2/embedded_assistant.proto#L314-L318
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah neither can do conversations. |
||||||
| ) | ||||||
Uh oh!
There was an error while loading. Please reload this page.