Good Manners
An OVOS pipeline plugin that reinforces good manners and reprimands foul language, without getting in the way of what you actually asked for.
"hey mycroft, what the fuck is the weather"
→ the weather is answered as usual
→ "avoid using the word fuck, it makes you look bad"
"please tell me a joke" / "what time is it, please" / ...
→ answered as usual, and after a few polite requests in a row:
→ "you have really good manners, i like you"
Originally a Mycroft skill by @JarbasAl (2018). It is being rewritten as a pipeline plugin, see #9.
Why manners matter
Acknowledge and appreciate good manners in others
Manners are reciprocal. If someone holds a door, say thank you. If you need something from a grocery shelf, and someone else is in the way, say "excuse me, please." Or ask them "could you please hand me a box of that cereal?" and then thank them.
Why do we need manners?
Manners make the world go 'round. They are to the smooth functioning of society as oil is to an engine. Without good manners, people get offended, hurt, and in extreme cases, very bad manners can lead to things such as the all-too-familiar public shootings, and even wars between countries when some official protocol is snubbed.
So this plugin listens to how you talk to your assistant: it shows appreciation for good manners, and reprimands insults and foul language.
How it works
The plugin is a stage in ovos-core's intent pipeline that observes but never matches:
- It sits first in the pipeline, so it sees every utterance before any other stage can claim it.
- It classifies the utterance (polite, foul language) and remembers the result for that session, then declines, so the utterance goes on to the stage that really handles it.
- When that utterance has been handled (
ovos.utterance.handled), it speaks its comeback, in the language of the utterance and to the session that said it.
Intent probes (intent.service.intent.get) are ignored, and every session keeps its own polite streak, so on a HiveMind hub one client's manners don't affect another's.
Classification is plain vocabulary matching, with three lists per language in ovos_good_manners_pipeline_plugin/locale/<lang>/:
foul_language.voc– ordinary swearing. The comeback names the word: "shit is such an ugly word".foul_prefixes.voc– for compounding languages: any word that starts with one of these is foul language too, so Danish lortebil and pissekoldt or German Scheißwetter are caught without listing every compound.slurs.voc– slurs and derogatory terms about groups of people. The comeback never repeats the word: "please don't use words like that".polite_words.voc– polite phrases, written by hand after the Stanford politeness strategies: please, thanks, apologies, could you / would you, deference and greetings. Plain can you is not counted, since that is how almost every command starts.
Words people use in ordinary questions ("sex", "nude", "jesus", "bloody nose", "summa cum laude") are deliberately left out, so the plugin never scolds someone for asking about something.
A trained politeness/insult classifier is planned.
Install
pip install ovos-good-manners-pipeline-plugin
Configuration
Put the plugin first in the pipeline in mycroft.conf, followed by your normal pipeline:
{
"intents": {
"pipeline": [
"ovos-good-manners-pipeline-plugin",
"stop_high",
"converse",
"..."
],
"ovos-good-manners-pipeline-plugin": {
"polite_threshold": 4,
"polite_timeout": 10,
"max_delay": 20
}
}
}
| Setting | Default | Meaning |
|---|---|---|
polite_threshold |
4 |
polite requests in a row before you get a compliment |
polite_timeout |
10 |
minutes without a polite request before the streak starts over |
max_delay |
20 |
seconds after the utterance after which a comeback is dropped instead of said late |
Since the pipeline is chosen per session, a HiveMind client can enable or disable the plugin through its own session.pipeline.
Languages
English, German and Danish. A language needs foul_language.voc, foul_prefixes.voc (may be empty), slurs.voc, polite_words.voc, and.voc and the five .dialog files in ovos_good_manners_pipeline_plugin/locale/<lang>/.
Word lists
foul_language.voc and slurs.voc are built by scripts/import_wordlists.py from open word lists, with hand corrections per language in scripts/overrides/<lang>.json (foul, slurs, remove). Re-running the script keeps everything already in the .voc files, so hand-written entries are never lost.
- English comes from dsojevic/profanity-list (MIT). It is tagged, so slurs (racial, LGBTQ, religious) are sorted out automatically.
- Other languages start from LDNOOBW (CC-BY-4.0), which is untagged, so each language is sorted by hand in its override file.
Untagged English lists such as cuss and LDNOOBW's English list are not used: they mix in ethnic slurs (which would be said back), ordinary words and porn search terms. See #12.
Tests
Besides the unit tests, tests/golden/<lang>.jsonl is a golden corpus: one utterance per line with what the plugin should find in it (none, polite, slur, or foul with the words). The none rows are as important as the rest: ordinary requests and look-alike words (summa cum laude, røverhistorie, Schmuck) that must never be reprimanded. Adding or improving a language is just adding lines – no code needed.
{"utterance": "could you turn off the lights", "expect": "polite"}
{"utterance": "fuck this shit", "expect": "foul", "foul_words": ["fuck", "shit"]}
Credits
- @JarbasAl, original skill
- @gras64, German translation
- Word lists: dsojevic/profanity-list (MIT) and LDNOOBW (CC-BY-4.0, by Shutterstock)
- @andlo
License
Apache 2.0, see LICENSE.md.
Metadata
Release files for ovos-good-manners-pipeline-plugin 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ovos_good_manners_pipeline_plugin-0.0.2.tar.gz | 28.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ovos_good_manners_pipeline_plugin-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 59.3 kB
Release files / ovos_good_manners_pipeline_plugin-0.0.2.tar.gz
| Download URL | ovos_good_manners_pipeline_plugin-0.0.2.tar.gz |
|---|---|
| Size | 28.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
76c40cc16580d27fa4dc9eeea34623dc5fabc0497bdb7b7d2cb0a7f9d9a80977
|
|
BLAKE2b-256 checksum How to use checksums |
e61950aab03eadc00cf09e543201d02ed289771c6e4b7f5fad174df2a56f8d2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / ovos_good_manners_pipeline_plugin-0.0.2-py3-none-any.whl
| Download URL | ovos_good_manners_pipeline_plugin-0.0.2-py3-none-any.whl |
|---|---|
| Size | 31.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
98fe79a24b61841a89ddd54926d1e4a260a45d2c91d43ee3fde7ea8e6910fbad
|
|
BLAKE2b-256 checksum How to use checksums |
505e7c90640a7b03615055073a8dcf5556a00489116d76479d7ec7bd830ab867
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|