Skip to content

Add inline vocabulary references (<name> token) to OVOS-INTENT-1 #1

Description

@JarbasAl

Summary

Add a new grammar token to OVOS-INTENT-1 — <name> — that expands, inline,
to the contents of a named vocabulary (a .voc). It lets an author define a
reusable phrasing fragment once and reference it from many templates, instead
of re-inlining the same (a|b|c) group everywhere.

This is a net-new feature (padatious/padacioso do not have it), not a
formalization of existing behaviour. It is the "reusable template fragments"
gap recorded in APPENDIX.md §2.2 and §5.

Motivation

Every template in OVOS-INTENT-1 is self-contained. Common fragments — politeness
prefixes, articles, recurring phrasings — are duplicated across every template
and every .intent file in a skill. Home Assistant (hassil expansion_rules)
and Rhasspy (<rule> references) both solve this; OVOS has no equivalent.

Example today:

# greet.intent
(hello|hi|hey) [there] {name}
(good morning|good afternoon|good evening) [there] {name}

With the feature:

# greeting.voc
hello
hi
hey
good morning
good afternoon
good evening
# greet.intent
<greeting> [there] {name}

Design decisions (already made — do not relitigate)

  1. Reuse .voc. Do NOT add a new .rule file role. A .voc is already a
    named, slot-free set of localized phrasings. "Keyword vocabulary" and "inline
    fragment" are consumed identically (expand to a phrase set); the only
    difference is where the phrase set lands. That is not enough of a behavioural
    difference to justify a new role/extension. A <name> reference resolves to
    name.voc — and to .voc only, never .entity or .blacklist (those have
    committed, specialised roles; .voc is the general-purpose phrasing set).

  2. Token: <name>. Angle brackets — ASR output never contains < or >,
    so they extend the §2 "metacharacters cannot be literal input" set cleanly.
    name follows the same charset as a vocabulary/resource base name.

  3. Eager, author-time resolution. The expander substitutes each
    <name> with (branch1|branch2|...) — the referenced vocabulary's expanded
    sample set joined as alternatives — before the existing [x]/()
    expansion runs. After substitution the template is ordinary. The engine, the
    wire contract, and the engine conformance rules are unchanged: the entire
    blast radius is the expander.

  4. Slot-free. A .voc has no named slots by definition, so a referenced
    fragment is guaranteed slot-free. <name> references introduce no slots.

  5. Recursive but acyclic. A .voc may itself contain <name> references;
    resolution recurses. A reference cycle is malformed.

  6. Scope: skill-local only. A shared/core vocabulary library is explicitly
    out of scope for this issue. <name> resolves through the existing
    resource precedence (OVOS-INTENT-2 §2.1), which does not preclude a core
    library later, but no core library is to be designed or shipped here.

  7. Terminology: "inline vocabulary reference", not "expansion rule". It is a
    new way to reference an existing concept (a vocabulary), not a new construct.

Open decision (resolve in the PR)

An <name> reference to an undefined vocabulary: treat as malformed →
MUST reject
(recommended, consistent with OVOS-INTENT-1 §3.6), or resolve to
empty? Recommendation: malformed. Confirm and document whichever is chosen.

Required spec changes

OVOS-INTENT-1 (sentence-template-grammar.md) — bump to Version 2

  • §2 Input model — add < and > to the structural metacharacter set that
    cannot occur as literal input.
  • §3 Grammar tokens — add a table row for <name> (facet: expansion).
    Add a new subsection (e.g. §3.7) defining the inline vocabulary reference: the
    charset of name, that it resolves to a .voc (OVOS-INTENT-2), and that it
    is resolved by the expander.
  • §3.6 Malformed forms — add: a reference to an undefined vocabulary (per
    the open decision); a cyclic reference chain; unbalanced </> joins the
    existing unbalanced-metacharacter rule.
  • §4 Expansion / §4.1 Reference enumeration — add a new first step:
    resolve every <name> (recursively) by substituting the referenced
    vocabulary's expanded sample set as an alternatives group, before the
    existing [x]→(x|) step. Note the substitution may introduce new ()
    groups, which the existing steps then handle.
  • §7 Conformance — the Expander role MUST resolve <name> references.
  • Header version 1.1 → 2.

OVOS-INTENT-2 (locale-resource-formats.md)

  • §1 / §4.3 — broaden the .voc description from "localized keywords /
    substrings" to "a named set of localized phrasings", consumed as a keyword
    vocabulary and/or referenced inline via <name> (OVOS-INTENT-1).
  • Note that a .voc may itself contain <name> references (vocabularies
    compose).
  • Bump version + CHANGELOG entry if the PR author judges the change normative.

Repo

  • CHANGELOG.md — new ### 2 entry under OVOS-INTENT-1.
  • APPENDIX.md — update §2.2 and §5: the "reusable template fragments" gap is
    now addressed for the skill-local case (shared/core library still open).
  • README.md — spec table version for OVOS-INTENT-1.

Acceptance criteria

  • <name> defined as a grammar token in OVOS-INTENT-1, resolving to a .voc.
  • Expansion algorithm (§4.1) resolves references recursively, eagerly,
    before [x]/() expansion; worked example included.
  • Malformed cases defined: undefined reference, cyclic reference, unbalanced
    </>.
  • .voc description broadened in OVOS-INTENT-2; composition noted.
  • Versions bumped, CHANGELOG and APPENDIX updated, README spec table updated.
  • No change to the engine contract, the wire/training-data contract, or
    OVOS-INTENT-3 beyond at most a one-line cross-reference.

Process

  • Per README.md "Changing a specification": work on a branch, open a PR
    (do not commit directly), bump the Version header, add a CHANGELOG entry.
  • Branch from the latest dev; open the PR against dev.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions