Contribute sentences and responses
How to change the sentences, responses, and tests of your language in the intents repository, check your work, and open a pull request.
All sentences, responses, and tests live in the intents repository on GitHub. You change them with a pull request, and the language leader of your language reviews it. This page walks you through that.
The smallest useful change is one new way to say a command that Assist already knows. You can make it on GitHub, in your browser, without installing anything. New to GitHub? Use GitHub, without being a developer covers the basics.
Every sentence needs a test, so your change always touches two files with the same path: the sentence file and its test file. To teach Dutch a new way to turn something on by its name, for example:
- Open
sentences/nl/HassTurnOn/name_only.yamland select the pencil icon to edit it. - Add your sentence template to the
sentenceslist of the block it belongs to. - Select Commit changes and create a new branch. If you cannot write to the repository, GitHub makes a copy (a fork) for you and puts the branch there.
- Before you open the pull request, open
tests/nl/HassTurnOn/name_only.yamlon that same branch and edit it the same way. Add a test sentence that uses your new template to the test group with the same slots and response, and commit it to the branch. - Open the pull request.
The checks on your pull request then tell you if something is off. They fail when a sentence file has no test file, when a file has fewer test sentences than sentence templates, when a sentence template is not used by any test sentence, and when a test sentence does not match the expected intent, slots, or response. They also check the formatting of your YAML. After that, the language leader of your language reviews your change.
Ready for more than one sentence? Read on.
Every language has its own folders. Replace <language> with your language code, like nl or pt-BR:
| Folder | What it holds |
|---|---|
sentences/<language>/<intent>/<slot_combination>.yaml |
The sentence templates for one intent and slot combination |
sentences/<language>/_common.yaml |
Error responses, skip words, and settings for the whole language |
responses/<language>/<intent>.yaml |
The responses of one intent |
lists/<language>/ |
Slot lists, like colors or states |
rules/<language>/ |
Expansion rules, like the verbs for turning something on |
tests/<language>/<intent>/<slot_combination>.yaml |
The tests for one intent and slot combination |
Two files at the root apply to every language:
intents.yamldeclares the intents and their slot combinations.languages.yamllists the languages and their leaders.
So if you want to improve how Dutch speakers turn things on and off by name, you change these four files:
sentences/nl/HassTurnOn/name_only.yamlsentences/nl/HassTurnOff/name_only.yamltests/nl/HassTurnOn/name_only.yamltests/nl/HassTurnOff/name_only.yaml
The folders of a language belong to its language leaders. The CODEOWNERS file, generated from languages.yaml, asks them for a review automatically.
intents.yaml is different. A change there affects every language at once, so only the repository maintainers can change it. A pull request from anyone else that touches it fails the guard-core-files check. If a slot combination is missing, is marked wrong, or does not fit your language, open an issue that explains what you need.
Serbian in Latin script (sr-Latn) is generated from Serbian in Cyrillic script (sr). Make your changes in sr. A check fails when the two drift apart.
Limit each pull request to one language and one intent. Small pull requests are easier to review, so they get merged sooner. Ten small pull requests beat one huge one.
There are three ways to work on the repository. Pick the one that fits the size of your change.
For a small fix in one file, like a typo in a response, you do not need anything installed. New to GitHub? Use GitHub, without being a developer walks you through the same steps in more detail.
- Open the file on GitHub and select the pencil icon to edit it.
- Make your change.
- Select Commit changes, choose to create a new branch and start a pull request, and describe what you changed.
The checks run on your pull request, so you still find out if something is wrong.
For anything bigger, a GitHub codespace gives you a complete environment in your browser, with an editor and a terminal. Nothing to install.
- On the repository page, select Code > Codespaces > Create codespace on main. It takes a minute or two to start.
- Select the branch name in the status bar at the bottom, and create a new branch.
- Make your changes.
- Run the checks for the file you have open: open the menu, select Terminal > Run Task, and pick Run tests for current file.
- In Source Control, commit your changes and select Create Pull Request.
The codespace walkthrough in the repository has screenshots of every step.
If you prefer your own machine, fork and clone the repository, then set it up:
git clone https://github.com/<your-username>/intents
cd intents
script/setupscript/setup creates a Python virtual environment in venv/ and installs everything you need. Activate it with source venv/bin/activate before you run the commands below. The repository also works as a devcontainer, if your editor supports those.
Create a branch, make your changes, and push them to your fork to open a pull request.
The checks that run on your pull request can also run on your machine or in your codespace. Run them before you open the pull request, it saves you a round trip.
Validate the files of your language:
python3 -m script.intentfest validate --language nlValidation checks that every file matches the slot combinations in intents.yaml, that every list and rule you use exists, and that all required slot combinations have sentences.
Run the tests of your language:
pytest tests --language nlAdd -k HassTurnOn to only test one intent, and -n auto to run the tests in parallel. The tests check that every sentence matches the right intent, fills the right slots, and gives the right response. They also fail when a sentence template is never used by any test sentence.
script/test runs both: validation and all tests. You can pass the same options, like script/test --language nl.
A few more tools help you while you write.
See what your language makes of a sentence:
python3 -m script.intentfest parse --language en \
--sentence 'turn on the lights in the kitchen'It prints the intent and the slots it matched, as JSON.
See which sentences a template produces:
python3 -m script.intentfest sample_template 'turn on [the] light[s]'You can give it list values, number ranges, and rules too, like --values color red green, --range brightness 1 2, or --rule color '[the] {color}'.
Sample sentences your language accepts, for some intents:
python3 -m script.intentfest sample --language nl \
--intents HassTurnOn HassTurnOff -n 5Count how many sentences your templates add up to:
python3 -m script.intentfest count_sentences --language nl --summaryOptional words and alternatives multiply. A language with millions of possible sentences gets slow on small devices. Leave off --summary to see the count per template, so you can find the ones that grew too large.
On top of validation and tests, a pull request also checks that:
- No intent steals the sentences of another intent. A greedy template for playing media should not catch "set the light to maximum", for example.
- Your language has no rules or lists left that nothing uses.
CODEOWNERSstill matcheslanguages.yaml.- Your YAML files are formatted the way Prettier formats them.
script/lintruns this check, and the Python checks, locally.
A pull request can only be merged when all checks pass.
New sentences are published in the next release of the home-assistant-intents package. Home Assistant updates to new releases of that package, and from then on, your sentences ship with Home Assistant.