Whenever we ask anything to SUSI, we get a intelligent reply. The API endpoints which clients uses to give the reply to users is http://api.susi.ai/susi/chat.json, and this API endpoint is defined in SUSIService.java. In this blog post I will explain how any query is processed by SUSI Server and the output is sent to clients.
public class SusiService extends AbstractAPIHandler implements APIHandler
This is a public class and just like every other servlet in SUSI Server, this extends AbstractAPIHandler class, which provides us many options including AAA related features.
public String getAPIPath() { return "/susi/chat.json"; }
The function above defines the endpoint of the servlet. In this case it is “/susi/chat.json”. The final API Endpoint will be API http://api.susi.ai/susi/chat.json.
This endpoint accepts 6 parameters in GET request . “q” is the query “parameter”, “timezoneOffset” and “language” parameters are for giving user a reply according to his local time and local language, “latitude” and “longitude” are used for getting user’s location.
String q = post.get("q", "").trim(); int count = post.get("count", 1); int timezoneOffset = post.get("timezoneOffset", 0); // minutes, i.e. -60 double latitude = post.get("latitude", Double.NaN); // i.e. 8.68 double longitude = post.get("longitude", Double.NaN); // i.e. 50.11 String language = post.get("language", "en"); // ISO 639-1
After getting all the parameters we do a database update of the skill data. This is done using DAO.susi.observe() function.
Then SUSI checks that whether the reply was to be given from a etherpad dream, so we check if we are dreaming something.
if (etherpad_dream != null && etherpad_dream.length() != 0) { String padurl = etherpadUrlstub + "/api/1/getText?apikey=" + etherpadApikey + "&padID=$query$";
If SUSI is dreaming something then we call the etherpad API with the API key and padID.
After we get the response from the etherpad API we parse the JSON and store the text from the skill in a local variable.
JSONObject json = new JSONObject(serviceResponse); String text = json.getJSONObject("data").getString("text");
After that, we fill an empty SUSI mind with the dream. SUSI susi_memory_dir is a folder named as “susi” in the data folder, present at the server itself.
SusiMind dream = new SusiMind(DAO.susi_memory_dir);
We need the memory directory here to get a share on the memory of previous dialogues, otherwise, we cannot test call-back questions.
JSONObject rules = SusiSkill.readEzDSkill(new BufferedReader(new InputStreamReader(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8))); dream.learn(rules, new File("file://" + etherpad_dream));
When we call dream.learn function, Susi starts dreaming. Now we will try to find an answer out of the dream.
The SusiCognition takes all the parameters including the dream name, query and user’s identity and then try to find the answer to that query based on the skill it just learnt.
SusiCognition cognition = new SusiCognition(dream, q, timezoneOffset, latitude, longitude, language, count, user.getIdentity());
If SUSI finds an answer then it replies back with that answers else it tries to answer with built-in intents. These intents are both existing SUSI Skills and internal console services.
if (cognition.getAnswers().size() > 0) { DAO.susi.getMemories().addCognition(user.getIdentity().getClient(), cognition); return new ServiceResponse(cognition.getJSON()); }
This is how any query is processed by SUSI Server and the output is sent to clients.
Currently people use Etherpad (http://dream.susi.ai/) to make their own skills, but we are also working on SUSI CMS where we can edit and test the skills on the same web application.
References
Java Servlet Docs: http://docs.oracle.com/javaee/6/tutorial/doc/bnafd.html
Embedding Jetty: http://www.eclipse.org/jetty/documentation/9.4.x/embedding-jetty.html
Server-Side Java: http://www.javaworld.com/article/2077634/java-web-development/how-to-get-started-with-server-side-java.html