Skip to content

Commit

Permalink
Merge pull request #5 from SEPIA-Framework/dev
Browse files Browse the repository at this point in the history
Added 'PythonBridgeDemo' service; Updated 'WorkoutHelperDemo';
  • Loading branch information
fquirin authored Oct 13, 2019
2 parents 92e0fe2 + ee4da68 commit f2e821c
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 5 deletions.
186 changes: 186 additions & 0 deletions smart-services/java/PythonBridgeDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package net.b07z.sepia.sdk.services.uid1007;

import java.util.TreeSet;

import net.b07z.sepia.server.assist.answers.ServiceAnswers;
import net.b07z.sepia.server.assist.assistant.LANGUAGES;
import net.b07z.sepia.server.assist.data.Parameter;
import net.b07z.sepia.server.assist.interpreters.NluResult;
import net.b07z.sepia.server.assist.parameters.WebApiParameter;
import net.b07z.sepia.server.assist.services.ServiceBuilder;
import net.b07z.sepia.server.assist.services.ServiceInfo;
import net.b07z.sepia.server.assist.services.ServiceInterface;
import net.b07z.sepia.server.assist.services.ServiceResult;
import net.b07z.sepia.server.assist.services.ServiceInfo.Content;
import net.b07z.sepia.server.assist.services.ServiceInfo.Type;
import net.b07z.sepia.server.core.data.Answer;
import net.b07z.sepia.server.core.data.Language;
import net.b07z.sepia.server.core.tools.Sdk;

/**
* Demonstration of how to use SEPIA Python-Bridge to enhance NLU and services.
*
* @author Florian Quirin
*
*/
public class PythonBridgeDemo implements ServiceInterface {

//Command name of your service (will be combined with userId to be unique, e.g. 'uid1007.python_bridge')
private static final String CMD_NAME = "python_bridge";

//Define some sentences for testing:

@Override
public TreeSet<String> getSampleSentences(String lang) {
TreeSet<String> samples = new TreeSet<>();
//GERMAN
if (lang.equals(Language.DE.toValue())){
samples.add("Ich würde gerne die Python Brücke testen.");
//OTHER
}else{
samples.add("I'd like to test the Python bridge.");
}
return samples;
}

//Basic service setup:

//Overriding the 'getAnswersPool' methods enables you to define custom answers with more complex features.
//You can build a pool of answers that can have multiple versions of the same answer used for different
//situations like a repeated question (what was the time? -> sorry say again, what was the time? -> ...).

@Override
public ServiceAnswers getAnswersPool(String language) {
ServiceAnswers answerPool = new ServiceAnswers(language);

//Build English answers
if (language.equals(LANGUAGES.EN)){
answerPool
//simple method to add answers
.addAnswer(successAnswer, 0, "Test successful.")
//complete method to add answers
.addAnswer(new Answer(
Language.from(language), okAnswer,
"Message received but I could not fulfill your request.",
Answer.Character.neutral, 0, 5
))

.addAnswer(askCodeWord, 0, "What's your code word?")
.addAnswer(askCodeWord, 1, "Wrong, try again please. What's your code word?")
.addAnswer(askCodeWord, 2, "Still wrong. Do you know the mines of Moria? Speak, 'friend', and enter.")
;
return answerPool;

//Other languages not yet supported
}else{
answerPool
.addAnswer(successAnswer, 0, "Test erfolgreich.")
.addAnswer(okAnswer, 0, "Die Anfrage ist angekommen aber ich kann sie nicht bearbeiten.")

.addAnswer(askCodeWord, 0, "Wie lautet das Schlüsselwort?")
.addAnswer(askCodeWord, 1, "Falsch, versuch es noch einmal bitte. Wie lautet das Schlüsselwort?")
.addAnswer(askCodeWord, 2, "Immer noch falsch. Kennst du die Minen von Moria? Sprich, 'Freund', und tritt ein.")
;
return answerPool;
}
}
//We keep a reference here for easy access in getResult - Note that custom answers need to start with a certain prefix
private static final String failAnswer = "error_0a";
private static final String successAnswer = ServiceAnswers.ANS_PREFIX + CMD_NAME + "_success_0a";
private static final String okAnswer = ServiceAnswers.ANS_PREFIX + CMD_NAME + "_still_ok_0a";
private static final String askCodeWord = ServiceAnswers.ANS_PREFIX + CMD_NAME + "_ask_code_1a";


@Override
public ServiceInfo getInfo(String language) {
//Type of service (for descriptions, choose what you think fits best)
ServiceInfo info = new ServiceInfo(Type.plain, Content.data, false);

//Should be available publicly or only for the developer? Set this when you are done with testing and want to release
//info.makePublic();

//Command
info.setIntendedCommand(Sdk.getMyCommandName(this, CMD_NAME));

//Direct-match trigger sentences in different languages
//NOTE: we use SEPIA internal NLU for direct match here and Python for more complex stuff to see how both work in parallel
String EN = Language.EN.toValue();
info.addCustomTriggerSentence("Test Python bridge.", EN);
String DE = Language.DE.toValue();
info.addCustomTriggerSentence("Python Brücke testen.", DE);

//Regular expression triggers
//NOTE: we don't use those here because we want to do complex NLU via the Python bridge
//info.setCustomTriggerRegX(".*\\b(python bridge)\\b.*", EN);
//info.setCustomTriggerRegXscoreBoost(5); //boost service a bit to increase priority over similar ones

//Parameters:

//This service has a one required parameter, the code word.
//Required parameters will be asked automatically by SEPIA using the defined question.
Parameter p1 = new Parameter(new CodeWord())
.setRequired(true)
.setQuestion(askCodeWord);
info.addParameter(p1);

//Answers (these are the default answers, you can trigger a custom answer at any point in the module
//with serviceBuilder.setCustomAnswer(..)):
info.addSuccessAnswer(successAnswer)
.addFailAnswer(failAnswer)
.addOkayAnswer(okAnswer)
.addCustomAnswer("askCodeWord", askCodeWord); //optional, just for info

//Add answer parameters that are used to replace <1>, <2>, ... in your answers.
//The name is arbitrary but you need to use the same one in getResult(...) later for api.resultInfoPut(...)
info.addAnswerParameters("code"); //<1>=code, <2>=...

return info;
}

@Override
public ServiceResult getResult(NluResult nluResult) {
//initialize result
ServiceBuilder api = new ServiceBuilder(nluResult,
getInfoFreshOrCache(nluResult.input, this.getClass().getCanonicalName()),
getAnswersPool(nluResult.language));

//get required parameters:

//-code
Parameter codeParameter = nluResult.getRequiredParameter(CodeWord.class.getName());
String code = codeParameter.getValueAsString();

//get optional parameters:
//NONE

//Set answer parameters as defined in getInfo():
api.resultInfoPut("code", code);

// ... here you could put some code that runs after successful code word.
// wrong code will automatically lead to rejection before reaching this part ...

//all good
api.setStatusSuccess();

//build the API_Result
ServiceResult result = api.buildResult();
return result;
}

//----------------- custom parameters -------------------

/**
* Parameter handler that tries to extract code word via Python bridge.
*/
public static class CodeWord extends WebApiParameter {

@Override
public String getApiUrl(){
//Enter the URL to your SEPIA Python-Bridge here including parameter path
String nluBridgeUrl = "http://localhost:20731/nlu/";
String parameterPath = "get_parameter/code_word";
return nluBridgeUrl + parameterPath;
}
}

}
2 changes: 1 addition & 1 deletion smart-services/java/RestaurantDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public ServiceAnswers getAnswersPool(String language) {
;
return answerPool;

//Other languages not yet supported
//Other languages are not used in this demo yet
}else{
return null;
}
Expand Down
20 changes: 16 additions & 4 deletions smart-services/java/WorkoutHelperDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import net.b07z.sepia.server.assist.assistant.LANGUAGES;
import net.b07z.sepia.server.assist.data.Parameter;
import net.b07z.sepia.server.assist.interpreters.NluResult;
import net.b07z.sepia.server.assist.interviews.Interview;
import net.b07z.sepia.server.assist.interviews.InterviewData;
import net.b07z.sepia.server.assist.services.ServiceAccessManager;
import net.b07z.sepia.server.assist.services.ServiceBuilder;
Expand All @@ -20,6 +21,7 @@
import net.b07z.sepia.server.assist.services.ServiceInfo.Type;
import net.b07z.sepia.server.core.assistant.PARAMETERS;
import net.b07z.sepia.server.core.data.Language;
import net.b07z.sepia.server.core.tools.Debugger;
import net.b07z.sepia.server.core.tools.JSON;
import net.b07z.sepia.server.core.tools.Sdk;

Expand Down Expand Up @@ -108,9 +110,17 @@ public ServiceInfo getInfo(String language) {

//Direct-match trigger sentences in different languages:
String EN = Language.EN.toValue();
info.addCustomTriggerSentence("Start a simple workout.", EN);
info.addCustomTriggerSentence("Start a simple workout.", EN)
.addCustomTriggerSentenceWithExtractedParameters("7 minutes workout.", EN, JSON.make(
PARAMETERS.TIME, Interview.INPUT_RAW, //This will tell the 'Interview' module to extract the time from the raw text
PARAMETERS.ACTION, "<on>" //This is what the Action parameter handler usually extracts for ON/START/ACTIVATE etc.
));
String DE = Language.DE.toValue();
info.addCustomTriggerSentence("Ein einfaches Workout starten.", DE);
info.addCustomTriggerSentence("Ein einfaches Workout starten.", DE)
.addCustomTriggerSentenceWithRawParameters("7 Minuten Workout.", DE, JSON.make(
PARAMETERS.TIME, "7 Minuten", //Here we use raw text, ...
PARAMETERS.ACTION, "starten" //... and let the 'Interview' module normalize and extract the parameter
));

//Regular expression triggers:
info.setCustomTriggerRegX(".*\\b("
Expand All @@ -129,7 +139,9 @@ public ServiceInfo getInfo(String language) {

Parameter p1 = new Parameter(PARAMETERS.TIME)
.setRequired(false);
info.addParameter(p1);
Parameter p2 = new Parameter(PARAMETERS.ACTION)
.setRequired(false);
info.addParameter(p1).addParameter(p2);

//Answers (these are the default answers, you can trigger a custom answer at any point in the module
//with serviceBuilder.setCustomAnswer(..)):
Expand All @@ -155,7 +167,7 @@ public ServiceResult getResult(NluResult nluResult) {
//test-load stored data
ServiceAccessManager sam0 = new ServiceAccessManager("demokey");
JSONObject userData = api.readServiceDataForUser(sam0, "tasks");
System.out.println("result: " + userData);
Debugger.println(CMD_NAME + " result: " + userData, 3); //DEBUG

//get optional parameters:

Expand Down
5 changes: 5 additions & 0 deletions smart-services/smart-services.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"name": "WorkoutHelperDemo",
"cmd": "workout_helper",
"path": "java/WorkoutHelperDemo.java",
"version": "0.9.1"
},{
"name": "PythonBridgeDemo",
"cmd": "python_bridge",
"path": "java/PythonBridgeDemo.java",
"version": "0.9.0"
}
]
Expand Down

0 comments on commit f2e821c

Please sign in to comment.