A Java SDK for Rasa action server.
<dependency>
<groupId>io.github</groupId>
<artifactId>jrasa</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>Rasa: >= 3.x
You should read the Rasa SDK documentation first to figure out the fundamental concepts.
You can run a Rasa SDK Action Server with the Java web framework you like. There is a SpringBoot demo for you.
To define a custom action, create a class which implements the interface Action.
import io.github.jrasa.Action;
import io.github.jrasa.CollectingDispatcher;
import io.github.jrasa.domain.Domain;
import io.github.jrasa.event.Event;
import io.github.jrasa.exception.RejectExecuteException;
import io.github.jrasa.tracker.Tracker;
import java.util.List;
public class CustomAction implements Action {
@Override
public String name() {
return "action_name";
}
@Override
public List<? extends Event> run(CollectingDispatcher collectingDispatcher, Tracker tracker, Domain domain) throws RejectExecuteException {
return Action.empty();
}
}💡 If no events need to be returned, you can use Action.empty() to return an empty list.
Because Java is a static programming language, you have to assign the type when you get a slot value.
There is five methods to get a slot value:
Object getSlot(String key)<T> T getSlot(String key, Class<T> type)String getStringSlot(String key)Boolean getBoolSlot(String key)Double getDoubleSlot(String key)
Object getSlot(String key) can get a slot value of any type.
With <T> T getSlot(String key, Class<T> type), you can assign the type of slot value.
String getStringSlot(String key) Boolean getBoolSlot(String key) Double getDoubleSlot(String key) can get the common type of slot value.
💡 Decimal numbers in JSON are deserialized to double in Java, so double is used instead of float.
There is a Message class to represent responses, because methods don't support default value parameters in Java.
You can build a Message instance with Builder like this:
Message message = Message.builder()
.text("Hello")
.image("https://i.imgur.com/nGF1K8f.jpg")
.response("utter_greet")
.attachment("")
.kwargs(new HashMap<String, Object>(){{
put("name", "uncle-lv");
}})
.build();And then send it with utterMessage:
dispatcher.utterMessage(message);All events are subclasses of abstract class Event. Their properties are the same as in the documentation. Some of them with many properties should been build with Builder.
SlotSet SlotSet = new SlotSet("name", "Mary");AllSlotsReset allSlotsReset = new AllSlotsReset();ReminderScheduled reminderScheduled = ReminderScheduled.builder("EXTERNAL_dry_plant")
.name("remind_water_plants")
.entities(new ArrayList<Entity>(){{
add(Entity.builder().entity("plant", "orchid").build());
}})
.triggerDateTime(LocalDateTime.parse("2018-09-03T11:41:10.128172", DateTimeFormatter.ISO_LOCAL_DATE_TIME))
.build();ReminderCancelled reminderCancelled = ReminderCancelled.builder()
.name("remind_water_plants")
.build();ConversationPaused conversationPaused = new ConversationPaused();ConversationResumed conversationResumed = new ConversationResumed();FollowupAction followupAction = new FollowupAction("action_say_goodbye");UserUtteranceReverted userUtteranceReverted = new UserUtteranceReverted();ActionReverted actionReverted = new ActionReverted();Restarted restarted = new Restarted();SessionStarted sessionStarted = new SessionStarted();UserUttered userUttered = UserUttered.builder()
.text("Hello bot")
.build();BotUttered botUttered = BotUttered.builder()
.text("Hello user")
.build();ActionExecuted actionExecuted = ActionExecuted.builder("action_greet_user")
.build();🛠️ Not implemented yet.
There is only one difference from the official SDK.
The methods/functions are named validate_<slot_name>/extract_<slot name>(snake case) in the official SDK. In JRasa, they should be named validate<SlotName>/extract<SlotName>(camel case), as naming convention in Java.
Thank you for any feedback.