Befehlauflösung mit 2 Layern (Intent & Action) funktioniert theoretisch, aber bei Timer befehl wird die duration irgendwie nicht durchgegeben (gibt fehler)

This commit is contained in:
2026-01-21 00:32:55 +01:00
parent 7e782e7a45
commit 3c918a68d3

82
main.py
View File

@@ -37,7 +37,7 @@ context = {
"slots": {},
"required_slots": [],
"pending_slot": None,
"action": None,
"action": None
}
audio_queue = queue.Queue()
@@ -80,12 +80,26 @@ INTENTS = {
},
"subactions": ["info"]
},
"timer": {
"keywords": ["timer"],
"required_slots": {
"duration": r"(sekunde|minute|stunde)"
},
"subactiions": ["start", "stop", "status"]
"required_slots": {},
"actions":{
"start": {
"keywords": ["starte", "start", "beginne"],
"required_slots": {
"duration": r"(\d+)\s*(sekunden|sekunde|minuten|minute|stunden|stunde)"
}
},
"stop": {
"keywords": ["stopp", "stoppe", "beende"],
"required_slots": {}
},
"status": {
"keywords": ["status", "läuft", "noch"],
"required_slots": {}
}
}
}
}
@@ -115,15 +129,26 @@ def weather_skill(slots):
return f"Keine Wetterdaten verfügbar"
#return f"Das Wetter in {location} ist sonnig bei 20 Grad."
def timer_skill(slots):
def start_timer_skill(slots):
duration = slots["duration"]
return f"Der Timer für {duration} Minuten wurde gestartet."
def stopp_timer_skill(slots):
return f"Timer wurde gestoppt."
def status_timer_skill(slots):
return f"Status Timer Ausgabe"
SKILLS = {
"weather": weather_skill,
"timer": timer_skill
}
"timer": {
"start": start_timer_skill,
"stop": stopp_timer_skill,
"status": status_timer_skill
}
}
# =========================
# DIALOGLOGIK
@@ -137,12 +162,7 @@ def handle_text(text):
print(f"[STT] {text}")
# 1. Rückfrage beantworten
# if context["pending_slot"]:
# context["slots"][context["pending_slot"]] = text
# context["pending_slot"] = None
# 2. Intent erkennen
# 1. Intent erkennen
if not context["intent"]:
intent = detect_intent(text)
if not intent:
@@ -153,26 +173,25 @@ def handle_text(text):
context["intent"] = intent
context["required_slots"] = INTENTS[intent]["required_slots"] # man könnte per liste drüber iterieren wenn man mehrere required slots hat
# 2. Fehlende Slots prüfen
if not check_required(text):
return
# 3. Fehlende Slots prüfen
# for slot in context["required_slots"]:
# if slot not in context["slots"]:
# context["pending_slot"] = slot
# ask_for_slot(slot)
# return
# 4. Skill ausführen
if context["action"] == None:
result = SKILLS[context["intent"]](context["slots"])
else:
result = SKILLS[context["intent"]][context["action"]](context["slots"])
result = SKILLS[context["intent"]](context["slots"])
speak(result)
reset_context()
def check_required(text):
intent_data = INTENTS[context["intent"]]
actions = intent_data.get("actions")
text = text.lower()
for slot, pattern in intent_data.get("required_slots", {}).items():
@@ -184,10 +203,20 @@ def check_required(text):
context["pending_slot"] = slot
ask_for_slot(slot)
return False
##NOCHMAL GENAUER ERKLÄREN LASSEN
if actions:
for action_name, action_data in actions.items():
if any(k in text for k in action_data.get("keywords", [])):
context["action"] = action_name
break
#Edgecase falls nutzer befehl bei dem action benötigt wird ohne action angibt
if intent_data.get("actions") and context["action"] is None:
speak("Ungültige Eingabe, Aktion wurde nicht genannt")
return False
for action in intent_data.get("subactions", []):
if action in text:
context["slots"]["action"] = action
context["pending_slot"] = None
return True
@@ -207,7 +236,8 @@ def reset_context():
"intent": None,
"slots": {},
"required_slots": [],
"pending_slot": None
"pending_slot": None,
"action": None
}
state = STATE_IDLE