Voice updates (#1646)

* Document conversation/prepare

* Add custom sentences and responses

* Moved custom sentences to user docs

* Document context and response keys

* Fix custom agent docs
This commit is contained in:
Michael Hansen 2023-01-24 19:22:02 -06:00 committed by GitHub
parent ade2724ae5
commit adbd3ba9ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 2 deletions

View File

@ -42,12 +42,12 @@ class MyConversationAgent(agent.AbstractConversationAgent):
conversation_id: str | None = None,
# Language of the user input. If None, default to hass.config.language
language: str | None = None,
) -> agent.ConversationResult | None:
) -> agent.ConversationResult:
"""Process a sentence."""
response = intent.IntentResponse(language=language)
response.async_set_speech("Test response")
return agent.ConversationResult(
conversation_id=None,
response=
response=response
)
```

View File

@ -285,3 +285,20 @@ POST with the next input sentence:
}
```
## Pre-loading Sentences
Sentences for a language can be pre-loaded using the WebSocket API:
```json
{
"type": "conversation/prepare",
"language": "en"
}
```
The following input fields are available:
| Name | Type | Description |
|------------|--------|--------------------------------------------------------------------------------|
| `language` | string | Optional. Language of the sentences to load (defaults to configured language). |

View File

@ -26,6 +26,39 @@ intents:
The above example will match the sentence `turn on all the lights in the living room` to the intent `HassTurnOn` and extract the area `living room`. The domain value is set to `light`. In Home Assistant, when the intent is executed, it will turn on all entities of type `light` in the area `living room`.
## Responses
A sentence template file may contain a response "key" for a group of sentences:
``` yaml
# Example light_HassLightSet.yaml
language: "en"
intents:
HassTurnOn:
data:
- sentences:
- "set {name} brightness to maximum"
slots:
brightness: 100
response: "brightness"
```
In the example above, the response key "brightness" refers to a template inside the file `responses/en/HassLightSet.yaml`:
```yaml
language: en
responses:
intents:
HassLightSet:
brightness: '{{ slots.name }} brightness set to {{ slots.brightness }}'
```
If no response key is provided, then `"default"` is assumed.
Response templates uses [Jinja2 syntax](https://jinja.palletsprojects.com/en/latest/templates/) and may refer to the `slots` object whose attributes are the matched intent's slot values.
See all [translated responses](https://github.com/home-assistant/intents/tree/main/responses) for more examples.
## Sentence Templates Syntax
* Alternative word, phrases, or parts of a word
@ -122,3 +155,65 @@ skip_words:
- "please"
- "can you"
```
### Requires/Excludes Context
Hassil returns the first intent match it can find, so additional **context** may be required if the same sentence could produce multiple matches.
For example, consider the following template:
```yaml
language: "en"
intents:
HassLightSet:
data:
- sentences:
- "set {name} brightness to maximum"
- "set {area} brightness to maximum"
slots:
brightness: 100
```
If you have an entity named "kitchen light", then you will be able to say "set kitchen light brightness to maximum". Similarly, "set kitchen brightness to maximum" will work if you have an area named "kitchen".
But what if you have a media player named "kitchen"? The same sentence could match either the area or the media player. Hassil will require more context to know what to do:
```yaml
language: "en"
intents:
HassLightSet:
data:
- sentences:
- "set {name} brightness to maximum"
requires_context:
domain: "light"
slots:
brightness: 100
- sentences:
- "set {area} brightness to maximum"
slots:
brightness: 100
```
We've split the sentences into two groups. The first group is for individual entities, and now has `requires_context` with a `domain` of `light`. This ensures that Hassil will only produce a match if the entity from `{name}` has the correct domain. Since areas do not have domains, we need to move the `{area}` sentence to its own group.
Context is also useful if you want to want different responses within the same intent:
```yaml
language: "en"
intents:
HassTurnOn:
data:
- sentences:
- "activate {name}"
excludes_context:
domain: "cover"
response: "default"
- sentences:
- "activate {name}"
requires_context:
domain: "cover"
response: "cover"
```
The first sentence group uses `excludes_context` to skip over `cover` entities, while the second group specifically matches `cover` entities and uses a different [response](#responses).