Intent API Reference

August 1, 2026 · View on GitHub

Full reference for IntentCreator (palavreado/builder.py) and IntentContainer (palavreado/__init__.py).


IntentCreator

palavreado/builder.py:48

Fluent builder for palavreado intents. All methods return self for chaining. Pass the creator object (or its .build() output) to IntentContainer.add_intent.

Constructor

IntentCreator(name: str)
ParameterTypeDescription
namestrUnique intent name. Must be unique across the container it will be registered in.

require

palavreado/builder.py:68

.require(keyword_name: str, keyword_samples: str | list[str]) -> IntentCreator

Add a required keyword slot. The intent will not fire unless at least one sample in this slot matches the utterance.

ParameterTypeDescription
keyword_namestrSlot/entity name used as the key in result["keywords"].
keyword_samplesstr | list[str]One or more sample strings. Bracket/pipe notation is expanded.

Returns: self

Example:

IntentCreator("lights_off") \
    .require("off",   ["off", "disable", "shutdown"]) \
    .require("light", ["(the |)(lights|light|lamp)"])

optionally

palavreado/builder.py:86

.optionally(keyword_name: str, keyword_samples: str | list[str]) -> IntentCreator

Add an optional keyword slot. The intent fires without this slot; a match increases confidence.

ParameterTypeDescription
keyword_namestrSlot/entity name.
keyword_samplesstr | list[str]One or more sample strings. Bracket/pipe notation is expanded.

Returns: self

Example:

IntentCreator("lights_off") \
    .require("off",   ["off", "disable"]) \
    .require("light", ["light", "lights"]) \
    .optionally("room", ["kitchen", "bedroom", "bathroom"])

require_regex

palavreado/builder.py:102

.require_regex(keyword_name: str, keyword_samples: str | list[str]) -> IntentCreator

Add a required slot matched with raw regular expression strings. Named capture groups ((?P<name>...)) populate result["keywords"] as additional sub-slot values.

ParameterTypeDescription
keyword_namestrSlot name. Also used as a key in the required dict so the required-slots check knows this slot must match.
keyword_samplesstr | list[str]One or more raw Python regex strings.

Returns: self

Matching behaviour (palavreado/__init__.py:334): Patterns are tried longest-first. The engine attempts re.match then re.search; if a named-group match succeeds, group values enter keywords. Patterns are compiled once at add_intent time with re.IGNORECASE.

Example:

rx = r'\b(at|in|for) (?P<Location>.*)'
IntentCreator("time_in_location") \
    .require_regex("Location", rx) \
    .require("time", ["time"])

optional_regex

palavreado/builder.py:123

.optional_regex(keyword_name: str, keyword_samples: str | list[str]) -> IntentCreator

Same as require_regex but the slot is optional.

Returns: self

require_autoregex

palavreado/builder.py:143

.require_autoregex(
    keyword_name: str,
    keyword_samples: str | list[str],
    case_sensitive: bool = False,
) -> IntentCreator

Add a required slot using simplematch {entity} patterns. Each pattern is converted to a regex via pattern2regex (palavreado/builder.py:14) before storage; the resulting regex is treated identically to a raw regex slot.

ParameterTypeDescription
keyword_namestrSlot name.
keyword_samplesstr | list[str]simplematch patterns, e.g. "buy {item}". Bracket/pipe expansion is applied first.
case_sensitiveboolDefault False. Passed to simplematch.Matcher.

Returns: self

Example:

IntentCreator("buy") \
    .require_autoregex("item", ["buy {item}", "purchase {item}", "get {item}"])

Result: result["keywords"]["item"] == ['some milk'] for query "buy some milk".

optional_autoregex

palavreado/builder.py:168

.optional_autoregex(
    keyword_name: str,
    keyword_samples: str | list[str],
    case_sensitive: bool = False,
) -> IntentCreator

Same as require_autoregex but the slot is optional.

Returns: self

build

palavreado/builder.py:192

.build() -> dict

Serialise the intent definition to a plain dict.

Returns:

{
    "intent_name": str,          # the name passed to the constructor
    "required":    dict[str, list[str]],   # slot → expanded samples
    "optional":    dict[str, list[str]],
    "regex":       dict[str, list[str]],   # slot → regex strings
}

The dict can be passed directly to IntentContainer.add_intent. IntentCreator instances can also be passed directly — add_intent calls .build() internally.


IntentContainer

palavreado/__init__.py:80

Container that holds registered intents and performs keyword matching.

Constructor

IntentContainer()

No arguments. Initialises empty intent, context, and exclusion stores.

Properties

intent_names

palavreado/__init__.py:105

@property
intent_names -> list[str]

Names of all currently registered intents.


Registration

add_intent

palavreado/__init__.py:112

add_intent(intent: IntentCreator | dict) -> None

Register a new intent.

ParameterTypeDescription
intentIntentCreator | dictAn IntentCreator instance or the dict from IntentCreator.build().

Raises: RuntimeError if an intent with the same name is already registered.

Side effects at registration time:

  • All training samples in required and optional are normalised via normalize_example (apostrophe dropping, whitespace collapsing).
  • All regex patterns are compiled with re.IGNORECASE and stored in self._compiled[name].
  • Regex patterns per slot are sorted by length (longest first) in self._sorted_regex[name].

Example:

container = IntentContainer()
creator = IntentCreator("lights_off") \
    .require("off", ["off", "disable"]) \
    .require("light", ["light", "lights"])
container.add_intent(creator)

remove_intent

palavreado/__init__.py:154

remove_intent(name: str | IntentCreator | dict) -> None

Unregister an intent. Silently does nothing when the intent is not found.

ParameterTypeDescription
namestr | IntentCreator | dictIntent name string, an IntentCreator (.name attribute is read), or a dict with "intent_name" or "name" key.

Matching

calc_intents

palavreado/__init__.py:253

calc_intents(query: str) -> Iterator[dict]

Yield scored match results for every intent that has confidence > 0 for query.

ParameterTypeDescription
querystrThe utterance to match. Normalised internally via normalize_utterance.

Yields: match result dicts (see Result fields below).

Results are yielded in registration order, not sorted by confidence. To get the single best match use calc_intent.

calc_intent

palavreado/__init__.py:398

calc_intent(query: str) -> dict

Return the single best-matching intent result for query.

ParameterTypeDescription
querystrThe utterance to match.

Returns: The highest-confidence match dict. When no intent matches, returns:

{"name": None, "keywords": {}, "conf": 0, "utterance": <normalised query>, "utterance_remainder": <normalised query>}

Tie-breaking (palavreado/__init__.py:414): When two intents produce equal confidence scores, the tie is broken by:

  1. More query words matched (higher specificity).
  2. Shorter utterance remainder (less leftover).
  3. Lexicographic intent name order (determinism).

Result fields

FieldTypeDescription
namestr | NoneMatched intent name, or None on no match
conffloatConfidence in [0.0, 1.0], rounded to 4 decimal places
keywordsdict[str, list[str]]Matched slot values keyed by slot name
utterancestrThe normalised query string
utterance_remainderstrPortion of the utterance not consumed by any matched slot

Context gating

Context gating controls intent availability based on named boolean flags. See Context Gating for a full explanation.

set_context

palavreado/__init__.py:173

set_context(intent_name: str, context_name: str, context_val: object = None) -> None

Mark context_name as active for intent_name. The optional context_val is stored but not used in matching logic — only presence/absence matters.

unset_context

palavreado/__init__.py:178

unset_context(intent_name: str, context_name: str) -> None

Remove an active context from intent_name. Silent no-op if not set.

require_context

palavreado/__init__.py:183

require_context(intent_name: str, context_name: str) -> None

Gate intent_name so it only fires when context_name is active. Multiple requirements can be added; all must be active.

unrequire_context

palavreado/__init__.py:188

unrequire_context(intent_name: str, context_name: str) -> None

Lift a context requirement.

exclude_context

palavreado/__init__.py:194

exclude_context(intent_name: str, context_name: str) -> None

Suppress intent_name whenever context_name is active.

unexclude_context

palavreado/__init__.py:199

unexclude_context(intent_name: str, context_name: str) -> None

Lift a context-based suppression.


Keyword exclusion

exclude_keywords

palavreado/__init__.py:207

exclude_keywords(intent_name: str, samples: list[str]) -> None

Suppress intent_name when any keyword in samples appears in the query.

ParameterTypeDescription
intent_namestrIntent to suppress.
sampleslist[str]Keywords that trigger suppression.

Matching rules (palavreado/__init__.py:221):

  • Single-word keywords: whole-word match (the keyword must appear as a standalone token in the query's word set).
  • Multi-word keywords: a \b-anchored word-boundary regex, compiled at call time, is used so "play" does not fire on "display".

Example:

container.exclude_keywords("play_music", ["stop", "pause"])
result = container.calc_intent("stop the music")
# play_music is suppressed; result["name"] may be None or another intent

Internal: _filter

palavreado/__init__.py:227

_filter(query: str) -> list[str]

Returns a list of intent names that should be excluded for this query. Called automatically at the start of calc_intents; not part of the public API but documented here for completeness.

Three exclusion passes run in order:

  1. Keyword exclusions (self._compiled_exclusions).
  2. Required-context failures (any required context not present in available_contexts).
  3. Excluded-context hits (any excluded context currently present in available_contexts).

Helper: get_utterance_remainder

palavreado/__init__.py:54

get_utterance_remainder(
    utterance: str,
    samples: list[str],
    as_string: bool = True,
) -> str | list[str]

Return the portion of utterance not covered by any token in samples.

Comparison is done on lemmatized forms so plural/apostrophe variants of already-matched keywords are also consumed.

ParameterTypeDescription
utterancestrFull utterance string.
sampleslist[str]Matched keyword/entity samples.
as_stringboolReturn a space-joined string (default) or a list of token strings.

Returns: Remainder string or list.


expand_samples

palavreado/builder.py:29

expand_samples(samples: str | list[str]) -> list[str]

Expand bracket/pipe notation into a flat list of strings.

expand_samples("(hello|hi) world")
# → ["hello world", "hi world"]

expand_samples(["lights [please]"])
# → ["lights", "lights please"]

Called internally by require, optionally, require_autoregex, and optional_autoregex.


pattern2regex

palavreado/builder.py:14

pattern2regex(pattern: str, case_sensitive: bool = False) -> str

Convert a simplematch pattern string to a regular expression string.

pattern2regex("buy {item}")
# → some regex with a capture group for {item}

Uses simplematch.Matcher internally.


← Quick Start · Home · Confidence Scoring →