Event Filters and Skills

If you have started working with Skills in Furhat, you should be familiar with the concept of Events . If you are not familiar with the term, or with the operation of a Skill in Furhat then we recommend that you first go through our other tutorials first. In this tutorial we will discuss the use of EventFilters, which can be added to Skills and Modules in Furhat.

Events

Briefly, an Event in Furhat is sent from a Module or Skill to the Furhat system. The system relays the Event to all Modules and currently active Skills. These event listeners decide for themselves if they should act on any given event. For example, when the SystemAgentModule of Furhat senses that a user has moved into an interaction space (due to a series of lower level events) it sends the sense.user.enter event to the system. The system then sends the event out to all event listeners, and each event listener checks if the event's name matches an event they are interested in. If the event listener is interested it reacts in some way to the event, otherwise it ignores the event.

EventFilters

What if we wanted to modify a Skill so that Furhat always ends his sentences with "dude" ? We could go through the skill and edit every agent:say to end with "dude". This would, depending on number of different speech outputs, be a time consuming task and if we suddenly also wanted furhat to start each sentence with "dude" as well we would need to go through the entire flow again.

Thankfully, we can achieve the same effect with an EventFilter. The idea behind an EventFilter is that all events pass through the System before being distributed to any event listeners. Therefore, the system can edit any event before distributing it. We define when and how to edit events through the use of EventFilters. The running mode can add event filters to the furhat system. All event filters are implementations of the EventFilter interfaces, which has the sole method of s

So, if we wanted to prepend and append "dude" to everything Furhat says we could add an EventFilter that modifies the action.speech event and lets all other events pass through unmodified. Below we have the internals of the action.speech event.

Field Type Description
text String The text to speak
start int The number of milliseconds into the utterance that the synthesis should start
audio String An audio file to play instead of synthesizing
display String A nicely formatted text representation for display purposes
agent String The ID of the agent that is associated with this synthesis. If this is omitted, all synthesizers should start
ifsilent Boolean Only add utterance if the system is silent. (Default is false)
abort Boolean Whether to abort the current speech queue. (Default is false, i.e., append the utterance).
monitorWords Boolean Whether to send monitor.speech.word events before each word (Default is false)

As you can see, the words Furhat says are held in the text field. To prepend and append "dude" to all action.speech events, we would edit this field. Below we have the code necessary to add this event filter inside from a skill.

getSkillHandler().addEventFilter((eventIn)->{
  if(eventIn.getName().equals("action.speech")){
    eventIn.put("text", "dude," + eventIn.getString("text") + ", dude" );
  }
  return eventIn;
});

Similarly, if we wanted to ensure that Furhat never appends speech events one after another we would change the line to eventIn.put("ifsilent", true). You can put the code example in any skill you have, inside the skill's init() method.

Further Notes on EventFilters

  • Event filters that are added from skills are removed when switching to another skill. FurhatOS does this to protect itself from overfiltering events, andto avoid filter conflicts between skills.
  • Within a skill you can chain together several event filters.
  • Beware how your event filter handles events it is not interested in, otherwise it could turn from an event filter to an event blocker.