MycroftAI / adapt

Adapt Intent Parser
Apache License 2.0
709 stars 155 forks source link

one_of Not Working as Expected #34

Closed EvanOman closed 8 years ago

EvanOman commented 8 years ago

All,

I am trying out a really simple intent parser on Python 3.4. I have defined a simple intent like so:

from adapt.engine import IntentDeterminationEngine
from adapt.intent import IntentBuilder
import json

engine = IntentDeterminationEngine()

engine.register_entity("fastfood", "FoodType")
engine.register_entity("show", "Command")
engine.register_entity("what", "Question")

options = IntentBuilder("OptionsForLunch")\
    .require("Command")\
    .optionally("FoodType")\
    .build()

engine.register_intent_parser(options)

for intent in engine.determine_intent("show fastfood"):
    print(json.dumps(intent, indent=4))

This works just fine:

{
    "Command": "show",
    "intent_type": "OptionsForLunch",
    "confidence": 0.9230769230769231,
    "FoodType": "fastfood",
    "target": null
}

However, I would like to specify that either a Command or a Question are needed for this intent. So I defined the following:

from adapt.engine import IntentDeterminationEngine
from adapt.intent import IntentBuilder
import json

engine = IntentDeterminationEngine()

engine.register_entity("fastfood", "FoodType")
engine.register_entity("show", "Command")
engine.register_entity("what", "Question")

options = IntentBuilder("OptionsForLunch")\
    .one_of("Question", "Command")\
    .optionally("FoodType")\
    .build()

engine.register_intent_parser(options)

for intent in engine.determine_intent("show fastfood"):
    print(json.dumps(intent, indent=4))

This does not print out any matching intents. Am I using the one_of function incorrectly? As far as I can tell, I am using it the same way this test uses it.

Any help would be greatly appreciated, thanks!

clusterfudge commented 8 years ago

Hey Evan, looks like you found a bug! You can see the details of the fix at #35

EvanOman commented 8 years ago

Hmm, I updated to your newest version (and stepped through the code to make sure your changes were present) but the following still does not work for me:

from adapt.engine import IntentDeterminationEngine
from adapt.intent import IntentBuilder
import json

engine = IntentDeterminationEngine()

engine.register_entity("show", "Command")
engine.register_entity("what", "Question")

options = IntentBuilder("OptionsForLunch")\
    .one_of("Question", "Command")\
    .build()

engine.register_intent_parser(options)

for intent in engine.determine_intent("show"):
    print(json.dumps(intent, indent=4))

I did run your test and that worked just fine, maybe there is something different between how your test is set up and how I am using one_of?

EvanOman commented 8 years ago

As far as I can tell, this bit always returns None, None for my tags

def find_first_tag(tags, entity_type, after_index=-1):
    for tag in tags:
        for entity in tag.get('entities'):
            for v, t in entity.get('data'):
                if t.lower() == entity_type.lower() and tag.get('start_token') > after_index:
                    return tag, v

    return None, None
clusterfudge commented 8 years ago

Interesting. I'll keep digging!

clusterfudge commented 8 years ago

In the spirit of making sure I've resolved your issues, would you mind reviewing https://github.com/MycroftAI/adapt/pull/36 ?

thanks!

EvanOman commented 8 years ago

Yep that looks good! I saw that last_end_index = 0 and I was thinking it should be -1 (or the ineq. should be >=).

Thanks for looking into all of this for me!