home-assistant-intents 2025.6.23__py3-none-any.whl → 2025.7.30__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- home_assistant_intents/__init__.py +135 -1
- home_assistant_intents/data/ca.json +1 -1
- home_assistant_intents/data/de.json +400 -233
- home_assistant_intents/data/el.json +714 -20
- home_assistant_intents/data/en.json +9 -8
- home_assistant_intents/data/fr.json +1 -1
- home_assistant_intents/data/{pt-br.json → pt-BR.json} +186 -25
- home_assistant_intents/data/{zh-cn.json → zh-CN.json} +1 -1
- home_assistant_intents/data/{zh-hk.json → zh-HK.json} +1 -1
- home_assistant_intents/data/{zh-tw.json → zh-TW.json} +1 -1
- home_assistant_intents/fuzzy/config.json +250 -0
- home_assistant_intents/fuzzy/en/config.json +77 -0
- home_assistant_intents/fuzzy/en/ngram/climate_HassClimateGetTemperature.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/climate_HassClimateGetTemperature.json +44 -0
- home_assistant_intents/fuzzy/en/ngram/climate_HassClimateSetTemperature.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/climate_HassClimateSetTemperature.json +37 -0
- home_assistant_intents/fuzzy/en/ngram/cover_HassSetPosition.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/cover_HassSetPosition.json +38 -0
- home_assistant_intents/fuzzy/en/ngram/cover_HassTurnOff.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/cover_HassTurnOff.json +25 -0
- home_assistant_intents/fuzzy/en/ngram/cover_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/cover_HassTurnOn.json +24 -0
- home_assistant_intents/fuzzy/en/ngram/fan_HassTurnOff.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/fan_HassTurnOff.json +26 -0
- home_assistant_intents/fuzzy/en/ngram/fan_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/fan_HassTurnOn.json +25 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassGetCurrentDate.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassGetCurrentDate.json +22 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassGetCurrentTime.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassGetCurrentTime.json +22 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassNevermind.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassNevermind.json +13 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassTimerStatus.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassTimerStatus.json +36 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassTurnOff.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassTurnOff.json +23 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/homeassistant_HassTurnOn.json +23 -0
- home_assistant_intents/fuzzy/en/ngram/light_HassLightSet.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/light_HassLightSet.json +51 -0
- home_assistant_intents/fuzzy/en/ngram/light_HassTurnOff.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/light_HassTurnOff.json +64 -0
- home_assistant_intents/fuzzy/en/ngram/light_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/light_HassTurnOn.json +65 -0
- home_assistant_intents/fuzzy/en/ngram/lock_HassTurnOff.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/lock_HassTurnOff.json +29 -0
- home_assistant_intents/fuzzy/en/ngram/lock_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/lock_HassTurnOn.json +29 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaNext.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaNext.json +25 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaPause.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaPause.json +24 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaPrevious.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaPrevious.json +29 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaUnpause.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassMediaUnpause.json +25 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassSetVolume.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/media_player_HassSetVolume.json +31 -0
- home_assistant_intents/fuzzy/en/ngram/scene_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/scene_HassTurnOn.json +30 -0
- home_assistant_intents/fuzzy/en/ngram/script_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/script_HassTurnOn.json +23 -0
- home_assistant_intents/fuzzy/en/ngram/vacuum_HassVacuumReturnToBase.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/vacuum_HassVacuumReturnToBase.json +17 -0
- home_assistant_intents/fuzzy/en/ngram/vacuum_HassVacuumStart.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/vacuum_HassVacuumStart.json +19 -0
- home_assistant_intents/fuzzy/en/ngram/valve_HassSetPosition.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/valve_HassSetPosition.json +34 -0
- home_assistant_intents/fuzzy/en/ngram/valve_HassTurnOff.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/valve_HassTurnOff.json +19 -0
- home_assistant_intents/fuzzy/en/ngram/valve_HassTurnOn.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/valve_HassTurnOn.json +18 -0
- home_assistant_intents/fuzzy/en/ngram/weather_HassGetWeather.db +0 -0
- home_assistant_intents/fuzzy/en/ngram/weather_HassGetWeather.json +25 -0
- home_assistant_intents/fuzzy/en/responses.json +131 -0
- home_assistant_intents/languages.py +4 -4
- {home_assistant_intents-2025.6.23.dist-info → home_assistant_intents-2025.7.30.dist-info}/METADATA +1 -1
- home_assistant_intents-2025.7.30.dist-info/RECORD +130 -0
- home_assistant_intents-2025.6.23.dist-info/RECORD +0 -66
- home_assistant_intents-2025.6.23.dist-info/zip-safe +0 -1
- {home_assistant_intents-2025.6.23.dist-info → home_assistant_intents-2025.7.30.dist-info}/WHEEL +0 -0
- {home_assistant_intents-2025.6.23.dist-info → home_assistant_intents-2025.7.30.dist-info}/licenses/LICENSE.md +0 -0
- {home_assistant_intents-2025.6.23.dist-info → home_assistant_intents-2025.7.30.dist-info}/top_level.txt +0 -0
|
@@ -7,13 +7,14 @@ import typing
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from enum import Enum
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import IO, Any, Callable, Dict, List, Optional
|
|
10
|
+
from typing import IO, Any, Callable, Collection, Dict, List, Optional, Set, Tuple
|
|
11
11
|
|
|
12
12
|
from .languages import LANGUAGES
|
|
13
13
|
|
|
14
14
|
_PACKAGE = "home_assistant_intents"
|
|
15
15
|
_DIR = Path(typing.cast(os.PathLike, importlib.resources.files(_PACKAGE)))
|
|
16
16
|
_DATA_DIR = _DIR / "data"
|
|
17
|
+
_FUZZY_DIR = _DIR / "fuzzy"
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class ErrorKey(str, Enum):
|
|
@@ -155,3 +156,136 @@ def get_language_scores(
|
|
|
155
156
|
)
|
|
156
157
|
for lang_key, lang_scores in scores_dict.items()
|
|
157
158
|
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# -----------------------------------------------------------------------------
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@dataclass
|
|
165
|
+
class FuzzyConfig:
|
|
166
|
+
"""Shared configuration for fuzzy matching."""
|
|
167
|
+
|
|
168
|
+
# intent -> (slot, slot) -> {name domains}
|
|
169
|
+
slot_combinations: Dict[str, Dict[Tuple[str, ...], Set[str]]]
|
|
170
|
+
"""Name domains for all intent slot combinations."""
|
|
171
|
+
|
|
172
|
+
# list name -> [slot names]
|
|
173
|
+
slot_list_names: Dict[str, List[str]]
|
|
174
|
+
"""Mapping between list and slot names."""
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@dataclass
|
|
178
|
+
class FuzzyNgramModel:
|
|
179
|
+
"""N-gram model for fuzzy matching."""
|
|
180
|
+
|
|
181
|
+
order: int
|
|
182
|
+
"""N-gram order."""
|
|
183
|
+
|
|
184
|
+
words: Dict[str, int]
|
|
185
|
+
"""Words to integer ids."""
|
|
186
|
+
|
|
187
|
+
database_path: Path
|
|
188
|
+
"""Path to sqlite3 database file."""
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
FuzzyLanguageResponses = Dict[str, Dict[Tuple[str, ...], Dict[str, str]]]
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@dataclass
|
|
195
|
+
class FuzzyLanguageInfo:
|
|
196
|
+
"""Language specific information for fuzzy matching."""
|
|
197
|
+
|
|
198
|
+
language: str
|
|
199
|
+
|
|
200
|
+
# domain -> [keywords]
|
|
201
|
+
domain_keywords: Dict[str, List[str]]
|
|
202
|
+
"""Keywords that hint at a domain."""
|
|
203
|
+
|
|
204
|
+
# intent -> model
|
|
205
|
+
ngram_models: Dict[str, FuzzyNgramModel]
|
|
206
|
+
"""N-gram model for each intent."""
|
|
207
|
+
|
|
208
|
+
# intent -> (slot, slot) -> domain -> response
|
|
209
|
+
responses: FuzzyLanguageResponses
|
|
210
|
+
"""Response code mapping per slot combination."""
|
|
211
|
+
|
|
212
|
+
stop_words: Optional[Collection[str]] = None
|
|
213
|
+
"""Words that can be ignored if unknown."""
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_fuzzy_config(
|
|
217
|
+
json_load: Callable[[IO[str]], Dict[str, Any]] = json.load,
|
|
218
|
+
) -> FuzzyConfig:
|
|
219
|
+
"""Return shared configuration for fuzzy matching."""
|
|
220
|
+
with open(_FUZZY_DIR / "config.json", "r", encoding="utf-8") as config_file:
|
|
221
|
+
config_dict = json_load(config_file)
|
|
222
|
+
|
|
223
|
+
return FuzzyConfig(
|
|
224
|
+
slot_combinations={
|
|
225
|
+
intent_name: {
|
|
226
|
+
tuple(sorted(combo_key_str.split())): set(name_domains)
|
|
227
|
+
for combo_key_str, name_domains in intent_combos.items()
|
|
228
|
+
}
|
|
229
|
+
for intent_name, intent_combos in config_dict["slot_combinations"].items()
|
|
230
|
+
},
|
|
231
|
+
slot_list_names={
|
|
232
|
+
list_name: slot_names
|
|
233
|
+
for list_name, slot_names in config_dict["slot_list_names"].items()
|
|
234
|
+
},
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def get_fuzzy_languages() -> Set[str]:
|
|
239
|
+
"""Return languages with fuzzy matching support."""
|
|
240
|
+
return {lang_dir.name for lang_dir in _FUZZY_DIR.iterdir() if lang_dir.is_dir()}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def get_fuzzy_language(
|
|
244
|
+
language: str,
|
|
245
|
+
json_load: Callable[[IO[str]], Dict[str, Any]] = json.load,
|
|
246
|
+
) -> Optional[FuzzyLanguageInfo]:
|
|
247
|
+
"""Return fuzzy matching information for a language."""
|
|
248
|
+
lang_fuzzy_dir = _FUZZY_DIR / language
|
|
249
|
+
lang_ngram_dir = lang_fuzzy_dir / "ngram"
|
|
250
|
+
|
|
251
|
+
if not lang_ngram_dir.is_dir():
|
|
252
|
+
return None
|
|
253
|
+
|
|
254
|
+
with open(lang_fuzzy_dir / "config.json", "r", encoding="utf-8") as config_file:
|
|
255
|
+
lang_config = json_load(config_file)
|
|
256
|
+
|
|
257
|
+
ngram_models: Dict[str, FuzzyNgramModel] = {}
|
|
258
|
+
for intent_ngram_path in lang_ngram_dir.glob("*.json"):
|
|
259
|
+
intent_db_path = intent_ngram_path.with_suffix(".db")
|
|
260
|
+
if not intent_db_path.exists():
|
|
261
|
+
continue
|
|
262
|
+
|
|
263
|
+
with open(intent_ngram_path, "r", encoding="utf-8") as intent_ngram_file:
|
|
264
|
+
intent_ngram_dict = json_load(intent_ngram_file)
|
|
265
|
+
|
|
266
|
+
intent_name = intent_ngram_path.stem
|
|
267
|
+
ngram_models[intent_name] = FuzzyNgramModel(
|
|
268
|
+
order=intent_ngram_dict["order"],
|
|
269
|
+
words=intent_ngram_dict["words"],
|
|
270
|
+
database_path=intent_db_path,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
with open(
|
|
274
|
+
lang_fuzzy_dir / "responses.json", "r", encoding="utf-8"
|
|
275
|
+
) as responses_file:
|
|
276
|
+
lang_responses_dict = json_load(responses_file)
|
|
277
|
+
lang_responses = {
|
|
278
|
+
intent_name: {
|
|
279
|
+
tuple(sorted(combo_key_str.split())): domain_responses
|
|
280
|
+
for combo_key_str, domain_responses in intent_responses.items()
|
|
281
|
+
}
|
|
282
|
+
for intent_name, intent_responses in lang_responses_dict.items()
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return FuzzyLanguageInfo(
|
|
286
|
+
language=language,
|
|
287
|
+
domain_keywords=lang_config["domain_keywords"],
|
|
288
|
+
stop_words=lang_config.get("stop_words"),
|
|
289
|
+
ngram_models=ngram_models,
|
|
290
|
+
responses=lang_responses,
|
|
291
|
+
)
|
|
@@ -559,7 +559,7 @@
|
|
|
559
559
|
"my_list": "[la] [meva] llista [de (la compra|compres|comprar)]",
|
|
560
560
|
"my_list_req": "[la] [meva] llista de (la compra|compres|comprar)",
|
|
561
561
|
"item": "{shopping_list_item:item}",
|
|
562
|
-
"add": "(afeg[e]ix|posa)"
|
|
562
|
+
"add": "(afeg[e]ix|posa|fica)"
|
|
563
563
|
}
|
|
564
564
|
}
|
|
565
565
|
]
|