Skip to content

feat: migrate en-US intents to language-agnostic file-intents - #45

Merged
JarbasAl merged 1 commit into
devfrom
feat/mark1-lang-agnostic-migration
Sep 3, 2026
Merged

feat: migrate en-US intents to language-agnostic file-intents#45
JarbasAl merged 1 commit into
devfrom
feat/mark1-lang-agnostic-migration

Conversation

@JarbasAl

@JarbasAl JarbasAl commented Sep 3, 2026

Copy link
Copy Markdown
Member

🤖 Auto-generated by Claude Sonnet 5 via Claude Code — NOT human-reviewed. Verify before acting.

This replaces every IntentBuilder (Adapt) registration in EnclosureControlSkill with @intent_handler("*.intent") file-intents, the same pattern the skill already used for its color and brightness intents. Fourteen handlers move over: the look/right/left/up/down variants, blink, spin, narrow eyes, reset, and the three mouth animations (smile, listen, think), plus crazy eyes.

Each new locale/en-US/*.intent template is built from the skill's existing sibling .voc phrase sets using <name> inline-vocabulary references, which ovos-spec-tools expands into literal alternation before padatious/padacioso compiles the template — this was verified empirically by booting a MiniCroft with the skill loaded and emitting real utterances through the padatious pipeline, not just read off the parser source.

That verification turned up a real gap worth flagging for anyone touching file-intents elsewhere: a .voc file with only one phrase (blink.voc, crazy.voc, down.voc, left.voc, mouth.voc, narrow.voc, right.voc, up.voc here) cannot be referenced via <name>, because the resulting single-branch alternation group is rejected as malformed by the template compiler — and the whole intent silently fails to register, with no test failure pointing at the cause unless you're specifically watching the boot logs. Those eight words are written as plain literals in the new templates instead, and the now-consumerless en-US .voc files are deleted (along with five more — mute, perform, reboot, system, unmute — that had no consumer left in the handler set even before this change).

The blink handler previously used two independent Adapt "right"/"left" keyword flags; those become a single {direction} entity slot, with equivalent per-direction behavior. golden_utterances.jsonl rows for the migrated intents move from intent_type: adapt to intent_type: padatious with intent_label pointing at the new file basenames, so the existing data-driven golden-utterance suite keeps validating routing without any test-harness changes. pyproject.toml's package-data gains the locale/*/*.entity glob, which the new direction.entity (and the pre-existing color/brightness entities) need in order to actually ship in the built wheel.

Non-English locales are untouched — they still carry their .voc/Adapt-era resources for follow-up per-language PRs.

Run locally against a throwaway venv pinning ovos-padatious==2.0.17a1, ovos-workshop==9.6.4a1, ovos-spec-tools==1.10.3a1, ovoscope==1.6.20a1: test/unittests (5 tests), test/end2end/test_intents_en_us.py (2), test/end2end/test_entity_constraints.py (3), and test/end2end/test_golden_utterances.py (54, including the negative-confusable rows) all pass.

Replace all 14 IntentBuilder (Adapt) registrations in EnclosureControlSkill
with @intent_handler("*.intent") file-intents, matching the pattern already
used by eye_color/custom_eye_color/brightness. Each intent gets a new
locale/en-US/*.intent template built from the existing sibling .voc phrase
sets via <name> inline-vocab references (ovos-spec-tools expansion, verified
empirically end-to-end through a MiniCroft-backed skill load).

Single-entry .voc files (blink, crazy, down, left, mouth, narrow, right, up)
cannot be referenced via <name>: the padatious/padacioso template compiler
rejects a single-branch alternation group as malformed and silently drops
the whole intent. Those words are now written as plain literals in the
templates, and the now-consumerless en-US .voc files are deleted, along
with five .voc files (mute, perform, reboot, system, unmute) that had no
consumer left in the current handler set.

The blink handler's two independent Adapt "right"/"left" flags become one
{direction} entity slot; behaviour otherwise unchanged. golden_utterances.jsonl
rows for these intents are updated from intent_type "adapt" to "padatious"
with intent_label pointing at the new file basenames, so the existing
data-driven golden-utterance suite keeps validating routing. pyproject.toml
package-data gains the locale/*/*.entity glob the new direction.entity
(and the existing color/brightness entities) need to ship in the wheel.

Local run (en-US only): test/unittests (5), test/end2end/test_intents_en_us.py
(2), test/end2end/test_entity_constraints.py (3), test/end2end/test_golden_utterances.py
(54) all green.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

I've combed through the code with a fine-tooth comb. 🔍

I've aggregated the results of the automated checks for this PR below.

📋 Repo Health

Ensuring the repository remains a happy place. 😊

✅ All required files present.

Latest Version: 0.1.1a1

version.py — Version file
README.md — README
LICENSE — License file
pyproject.toml — pyproject.toml
⚠️ setup.py — setup.py
CHANGELOG.md — Changelog
version.py has valid version block markers

🔒 Security (pip-audit)

Scanning for any 'unauthenticated' access points. 🕵️

✅ No known vulnerabilities found (76 packages scanned).

🎙️ Skill

Checking the skill's resources for any issues. 📦

🎙️ (unknown skill_id) — 13 languages

en-US: 17 intents · 9 vocab · 15 dialogs · skill.json ⚠️

Translation coverage — 12 languages (6 partial, 6 incomplete)
Language Progress Coverage
ca-ES ███████░░░ ⚠️ 65.9% (29/44)
da-DK ███████░░░ ⚠️ 65.9% (29/44)
de-DE ███████░░░ ⚠️ 65.9% (29/44)
el-GR ████░░░░░░ ❌ 43.2% (19/44)
es-ES ███████░░░ ⚠️ 65.9% (29/44)
fr-FR ███████░░░ ⚠️ 65.9% (29/44)
gl-ES ███████░░░ ⚠️ 65.9% (29/44)
it-IT ████░░░░░░ ❌ 43.2% (19/44)
nl-NL ████░░░░░░ ❌ 43.2% (19/44)
pt-BR ████░░░░░░ ❌ 43.2% (19/44)
ru-RU ████░░░░░░ ❌ 43.2% (19/44)
sv-SE ████░░░░░░ ❌ 43.2% (19/44)

🔍 Lint

Just a quick heads-up on the latest check. 🛎️

ruff: issues found — see job log

🧪 Spec Lint

Checking the alignment of your contribution. 📏

22 error(s), 22 warning(s)

locale/ca-ES/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/ca-ES/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/da-DK/brightness.intent: error: single-branch group (dine): a group must offer a choice between at least two branches  [in: 'dæmp (dine) øjne til {brightness} (procent|)']
locale/de-DE/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/de-DE/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/el-GR/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/el-GR/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/el-GR/brightness.intent: error: single-branch group (σου): a group must offer a choice between at least two branches  [in: 'άλλαξε (το|τη) (επίπεδο φωτεινότητας|φωτεινότητα) (στο|στα) (μάτι|μάτια) (σου)']
locale/el-GR/brightness.intent: error: single-branch group (φωτεινός): a group must offer a choice between at least two branches  [in: 'είσαι (πολύ|) (φωτεινός)']
locale/es-ES/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/es-ES/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/fr-FR/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/fr-FR/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/gl-ES/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/gl-ES/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/gl-ES/brightness.intent: error: single-branch group (nivel): a group must offer a choice between at least two branches  [in: '(cambiar|establecer) (o teu) (nivel) de (brillo|iluminación) do (ollo|) ata o (nivel|)']
locale/gl-ES/brightness.intent: error: single-branch group (nivel): a group must offer a choice between at least two branches  [in: '(cambiar|establecer) (o teu) (nivel) de (brillo|iluminación) do (ollo|) ata o {brightness} (por cento|)']
locale/gl-ES/brightness.intent: error: single-branch group (reduzace): a group must offer a choice between at least two branches  [in: '(reduzace) (o|a) (brillo|iluminación) dos teus ollos ata o {brightness} (porcento|)']
locale/gl-ES/brightness.intent: error: single-branch group (os teus): a group must offer a choice between at least two branches  [in: 'escurece (os teus) ollos ata o {brightness} (porcento|)']
locale/it-IT/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/it-IT/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/it-IT/brightness.intent: error: single-branch group (di): a group must offer a choice between at least two branches  [in: '(cambia|imposta |modifica) (livello| ) (di) (luminosità | illuminazione) (del| tuo) (occhio |)']
locale/it-IT/brightness.intent: error: single-branch group (percento): a group must offer a choice between at least two branches  [in: '(modifica|cambia|imposta) (il|tuo|livello|la|di) (luminosità|illuminazione) (degli occhi) al {brightness} (percento)']
locale/it-IT/eye_color.intent: error: single-branch group (colore): a group must offer a choice between at least two branches  [in: '(cambia|imposta) (i tuoi|gli|) occhi a (un) (colore) {color}']
locale/it-IT/eye_color.intent: error: single-branch group (colore): a group must offer a choice between at least two branches  [in: '(cambia|imposta) (occhio|occhi) a (un) (colore) {color}']
locale/nl-NL/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/nl-NL/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/nl-NL/custom_eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(stel|verander) (op|in) (een)? aangepaste oog(kleur|kleuren) (in)?']
locale/nl-NL/custom_eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(zet|stel) aangepaste oog(kleur|kleuren) (in)?']
locale/nl-NL/eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(verander|stel) (de|jouw) oog(kleur|kleuren|) (naar|in|op) {color} (in)?']
locale/nl-NL/eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(verander|stel) (jouw)? ogen (naar|in|op) (een)? {color} (kleur)? (in)?']
locale/nl-NL/eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(verander|stel) (oog(kleur|kleuren|)|ogen) (naar|in|op) {color} (in)?']
locale/nl-NL/eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(verander|stel) oog(kleur|kleuren) (in)?']
locale/nl-NL/eye_color.intent: error: single-branch group (in): a group must offer a choice between at least two branches  [in: '(verander|stel) oog(kleur|kleuren) (naar|in|op) iets {color} (in)?']
locale/pt-BR/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/pt-BR/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/pt-BR/brightness.intent: error: single-branch group (nível): a group must offer a choice between at least two branches  [in: '(mudar|definir|trocar) (o|seu) (nível) de (brilho|iluminação) do (olho|) para {brightness} (por cento|)']
locale/ru-RU/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/ru-RU/colors.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)
locale/ru-RU/brightness.intent: error: unbalanced metacharacters in template '(измени|установи|смени) ((уровень|) (яркость|иллюминацию) (|твоих) (глаз|) на {brightness} (процентов|()'  [in: '(измени|установи|смени) ((уровень|) (яркость|иллюминацию) (|твоих) (глаз|) на {brightness} (процентов|()']
locale/ru-RU/brightness.intent: error: single-branch group (процент): a group must offer a choice between at least two branches  [in: 'затемни ( | твои) глаза {brightness} (процент)']
locale/ru-RU/brightness.intent: error: single-branch group (процент): a group must offer a choice between at least two branches  [in: 'затемни на {brightness} (процент)']
locale/sv-SE/brightness.levels.value: warning: .value is a legacy file type, not an OVOS-INTENT-2 resource role (OVOS-INTENT-2 §1)

📊 Coverage

Test coverage audit: no stone left unturned. 🗿

16.4% total coverage

Per-file coverage (10 files)
File Coverage Missing lines
test/end2end/test_entity_constraints.py 0.0% 58
test/end2end/test_golden_utterances.py 0.0% 62
test/end2end/test_intents_en_us.py 0.0% 46
test/unittests/test_entity_registration.py 0.0% 26
test/unittests/test_resources.py 0.0% 21
version.py 0.0% 7
__init__.py 30.4% 179
test/__init__.py 100.0% 0
test/end2end/__init__.py 100.0% 0
test/unittests/__init__.py 100.0% 0

Full report: download the coverage-report artifact.

🏷️ Release Preview

Setting the stage for the upcoming deployment. 🎭

Current: 0.1.1a1Next: 0.2.0a1

Signal Value
Label (none)
PR title feat: migrate en-US intents to language-agnostic file-intents
Bump minor

✅ PR title follows conventional commit format.


🚀 Release Channel Compatibility

Predicted next version: 0.2.0a1

Channel Status Note Current Constraint
Stable Not in channel -
Testing Not in channel -
Alpha Not in channel -

🔌 Skill Tests (ovoscope)

Viewing the skill's intents through the Ovoscope lens. 🔬

59/59 passed

TestEntityConstraints — 3/3
TestIntentRouting — 2/2
test_golden_utterance[blink enclosure] — 1/1
test_golden_utterance[blink left] — 1/1
test_golden_utterance[blink right] — 1/1
test_golden_utterance[blink] — 1/1
test_golden_utterance[change eye color to default] — 1/1
test_golden_utterance[change eye colors to default] — 1/1
test_golden_utterance[change eye to default] — 1/1
test_golden_utterance[change eyes color to default] — 1/1
test_golden_utterance[change eyes colors to default] — 1/1
test_golden_utterance[change the brightness level] — 1/1
test_golden_utterance[change the brightness] — 1/1
test_golden_utterance[change the eye brightness level] — 1/1
test_golden_utterance[change the eye brightness] — 1/1
test_golden_utterance[change the eye illumination] — 1/1
test_golden_utterance[change to a custom eye color] — 1/1
test_golden_utterance[change to a custom eye colors] — 1/1
test_golden_utterance[crazy eye animation] — 1/1
test_golden_utterance[crazy eye enclosure] — 1/1
test_golden_utterance[crazy eye] — 1/1
test_golden_utterance[down look enclosure] — 1/1
test_golden_utterance[down look] — 1/1
test_golden_utterance[down up look animation] — 1/1
test_golden_utterance[down up look enclosure] — 1/1
test_golden_utterance[down up look] — 1/1
test_golden_utterance[enclosure back to default] — 1/1
test_golden_utterance[eye narrow enclosure] — 1/1
test_golden_utterance[eye narrow] — 1/1
test_golden_utterance[left look enclosure] — 1/1
test_golden_utterance[left look] — 1/1
test_golden_utterance[left right look animation] — 1/1
test_golden_utterance[left right look enclosure] — 1/1
test_golden_utterance[left right look] — 1/1
test_golden_utterance[listen enclosure] — 1/1
test_golden_utterance[listen] — 1/1
test_golden_utterance[right look enclosure] — 1/1
test_golden_utterance[right look] — 1/1
test_golden_utterance[rotate enclosure] — 1/1
test_golden_utterance[rotate] — 1/1
test_golden_utterance[set custom eye color] — 1/1
test_golden_utterance[set to a custom eye color] — 1/1
test_golden_utterance[set to a custom eye colors] — 1/1
test_golden_utterance[smile enclosure] — 1/1
test_golden_utterance[smile] — 1/1
test_golden_utterance[think enclosure] — 1/1
test_golden_utterance[think] — 1/1
test_golden_utterance[up look enclosure] — 1/1
test_golden_utterance[up look] — 1/1
test_negative_confusable_not_claimed[go to sleep] — 1/1
test_negative_confusable_not_claimed[play some music] — 1/1
test_negative_confusable_not_claimed[set a timer for 5 minutes] — 1/1
test_negative_confusable_not_claimed[take a screenshot] — 1/1
test_negative_confusable_not_claimed[turn off the living room lights] — 1/1
test_negative_confusable_not_claimed[turn up the brightness] — 1/1
test_negative_confusable_not_claimed[what's the weather] — 1/1

⚖️ License Check

Navigating the maze of open-source compliance. 🧩

✅ No license violations found.

Policy: Apache 2.0 (universal donor). StrongCopyleft / NetworkCopyleft / WeakCopyleft / Other / Error categories fail. MPL allowed.

🔨 Build Tests

Ensuring no loose screws in the assembly. 🔩

✅ All versions pass

Python Build Install Tests
3.10
3.11
3.12
3.13
3.14

May your merges be conflict-free! 🕊️

@JarbasAl
JarbasAl marked this pull request as ready for review September 3, 2026 23:49
@JarbasAl
JarbasAl merged commit ee1f98c into dev Sep 3, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant