2021-01-12 03:39

add converse method to allow skills to handle utterance

1) In the base MycroftSkill class, add a method like this:

def Converse(self, transcript, lang):
    return False

2) In the IntentSkill add a few things to handle_utterance():

a) Track recently invoked skills. This would be a list of the Skills associated with the best_intent that comes out of Adapt. Whenever a Skill's intent is invoked, it gets moved/placed at the top of the list. This list also gets curated to remove Skills that haven't been invoked in longer than, say 5 minutes.

b) Before going through the current code that figures out best_intent, loop through the Skills in this list and call skill.Converse(utterance). If one returns True, then they have handled the utterance and there is no need to do further intent processing or fallback.

3) in register_skill map intents to skills

4) in load skills add a unique id for each skill instead of using skill_name (because its fragile)


  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答


  • weixin_39865277 weixin_39865277 4月前

    Couple comments: * It is important to sort the skills_5min. We should always give the most recently invoked skill the first chance to handle the utterance.

    I think the easiest way to handle this would be to use a list instead of a dictionary. I also don't like the name "skills_5min" because it won't make sense if we go to, say, a 7 minute window. So I'd rather use the name "active_skills".

    So in init you'd do:

    self.active_skills = []

    When you invoke a skill you'd:

    self.active_skills.insert(0, [skill, time])

    When you "touch" a Skill you can just remove it from this list and prepend it with skills_5min.insert(0, skill) to keep the list sorted. I realize this causes a little headache whenever you add a skill to the list, since you have to search the list for and existing entry that already contains it and remove that reference. You can minimize the effort by creating helpers like: remove_active_skill(skill) and add_active_skill(skill).

    There are probably a few other implementations. But having this sorted is a pretty big deal that I'd like in place from the beginning.

    • Nitpick: "whether" instead of "wether" :)
    • Nitpick: let's avoid mixing in camelCase. So use "converse()" instead of "Converse()" and "do_conversation()" instead of "doConversation()". My apologies if I used camelCase when we were talking about this in Slack -- bad habit of mine.
    点赞 评论 复制链接分享
  • weixin_39865277 weixin_39865277 4月前

    I will also look into the problem you were talking about with the empty list when attempting to invoking the conversation skill. More on that tomorrow.

    点赞 评论 复制链接分享
  • weixin_39540018 weixin_39540018 4月前

    better now?

    点赞 评论 复制链接分享
  • weixin_39540018 weixin_39540018 4月前

    made some more changes: - with PR#558 intent names become skill_name:intent_name changed this to skill_id:intent_name - parse source skill_id from this - removed the intent to id dict and changes to register_intent message mechanism - changed self.id to self.skill_id inside skill base class - if we requested a converse for an invalid id there would be an infinite loop waiting for the neevr coming response, added a default response if skill_id doesn't exist and made int(skill_id) in case someone passes a string by mistake

    点赞 评论 复制链接分享
  • weixin_39540018 weixin_39540018 4月前

    resubmitted has #756

    点赞 评论 复制链接分享