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.