Skip to main content

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:

  1. It sits first in the pipeline, so it sees every utterance before any other stage can claim it.
  2. 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.
  3. 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

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)

Source distribution for ovos-good-manners-pipeline-plugin 0.0.2
File Size Uploaded
ovos_good_manners_pipeline_plugin-0.0.2.tar.gz 28.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ovos-good-manners-pipeline-plugin 0.0.2
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page