aichaos / rivescript-java Goto Github PK
View Code? Open in Web Editor NEWA RiveScript interpreter for Java. RiveScript is a scripting language for chatterbots.
Home Page: http://www.rivescript.com
License: MIT License
A RiveScript interpreter for Java. RiveScript is a scripting language for chatterbots.
Home Page: http://www.rivescript.com
License: MIT License
From Jonathan Brouwers on Slack:
Hey, I am looking into the java implementation of rivescript at https://github.com/aichaos/rivescript-java. In the examples there is an rpg demo. In the demo you get to a point where you have to type "press button" to advance. However, the topic includes a global topic with an asterisk(*) trigger which overrides the source topic, which means the "press button" trigger does not get matched. When i paste the same rivescript file into the online editor (https://www.rivescript.com/try), the "press button" trigger does get matched. When looking at the spec for rivescript, i find that when including it first matches the one with most words and then with the most characters, which would mean a wildstar should be matched last. Seems this is a bug in the java implementation? Or did i miss something?
There's likely a bug in the topic inheritance/includes that needs to be fixed.
I was reading about this issue 61 in the JS version of rivescript and I was wondering if there is any plan to also port this deparse method to the java version of rivescript.
This method would allow me to then dump the data in a mongo database to expose it's content through an api instead of dealing with text files.
Thanks!
Look like RiveScript#reply is not thread-safe, RiveScript#currentUser is not ThreadLocal, project has no any synchronized blocks and concurrent classes
I can't seem to continue past puzzle1. It takes me back to the crash site. The script seems to make sense so unclear if it's a nuance I'm not seeing in the example or a bug in the interpreter or what. I'm running rivescript-core 0.10.0 and passing data with .reply
Command order:
north
up
north
push button
take spacesuit
open door
north
west
RSTS replies.yml#embedded_tags
failed:
java.lang.AssertionError: Did not get expected reply for input: My name is Bob.
Expected: is "I thought your name was Alice?"
but: was ">I thought your name was <get name?"
Hi People!
I am working on a small brain (like 200 triggers) and RS response time goes slower and slower each time it responses, talking about 20 or 30 questions.
Simple triggers obviusly response in seconds, but allways takes a little more ms than the last one.
Complex triggers takes 2 o 3 seconds more than the last question.
Is this an RS issue or a begginer issue?
Thanks in advance..
rv
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.rivescript.RiveScript;
import com.rivescript.macro.Subroutine;
public class Test {
public static class B implements Subroutine {
@Override
public String call(RiveScript rs, String[] args) {
System.out.println("B");
return "none";
}
}
public static void main(String[] args) throws IOException {
File f = new File("/tmp/test.rs");
FileWriter w = new FileWriter(f);
w.write("+ *\n");
w.write("- end\n");
w.write("+ hi\n");
w.write("* <get v> != undefined => A\n");
w.write("@ <call>b</call>\n");
// w.write("- <call>b</call>\n"); // works as expected
w.close();
RiveScript rs = new RiveScript();
rs.loadFile(f);
rs.sortReplies();
rs.setSubroutine("b", new B());
rs.setUservar("test", "v", "V");
System.out.println(rs.reply("test", "Hi"));
}
}
I got output:
B
end
But condition is true. RiveScript ignore condition if redirection contain macro.
RiveScript version 0.8.0, works as expected on 0.7.2
RSTS triggers.yml#weighted_triggers
failed:
java.lang.AssertionError: Did not get expected reply for input: nothing
Expected: is "Weighted nothing"
but: was "Unweighted nothing"
Here the code is missing a loop on all the entries of the list within the value of the map or maybe this?
if(entry.getValue().contains(UNDEF_TAG)) {
this.array.remove(entry.getKey());
} else {
this.array.put(entry.getKey(), entry.getValue());
}
Remove hardcoded references to "undefined"
. Should use customisable value.
Please deploy this impl to Maven.
Hi again, and sorry for making this my personal forum but I don't know a better place to go than this.
I have tried copying the perl macro from the website:
> object hash perl
my ($rs, $args) = @_;
my $method = shift @{$args};
my $string = join " ", @{$args};
# Here, $method is a hashing method (MD5 or SHA1), and $string
# is the text to hash.
if ($method eq "MD5") {
require Digest::MD5;
return Digest::MD5::md5_hex($string);
}
elsif ($method eq "SHA1") {
require Digest::SHA1;
return Digest::SHA1::sha1_hex($string);
}
< object
// You call an object using the <call> tag.
+ what is the md5 hash of *
- The hash of "<star>" is: <call>hash MD5 <star></call>
+ what is the sha1 hash of *
- The hash of "<star>" is: <call>hash SHA1 <star></call>
but it doesn't work. I have also tried javascript macros which have worked on the online compiler but they don't work here. I even used these imports:
import com.rivescript.;
import com.rivescript.lang.;
import com.rivescript.macro.*;
Am I missing something? Whenever I call the object macros I get error:object not found in place of my object in the output.
RS file:
! version = 2.0
+ hi1 *
- !<star>!
+ hi2 *
* <get some> != undefined => not possible
- !<star>!
Dialog:
you: hi1 test
bot: !test!
you: hi2 test
bot: !!
last reply should be !test!
From RiveScript-JS #122, ordering of triggers with a common %Previous
are sorted incorrectly.
See the linked issue for details.
java.nio.file Assertions are going to break a lot of Android projects
Error:(28, 12) error: cannot access Path class file for java.nio.file.Path not found
Is there a way to use it in Java-based Android Native?
I would like to give multiple triggers for a single response, also i would like to access the '*' within them.
For example:
+ my name *
+ people call me *
+ * is what you should call me
- Ok, I will call you <star>.
What would be the correct way of doing this ?
! version = 2.0
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.rivescript.RiveScript;
import com.rivescript.macro.Subroutine;
public class RsTest {
public static class F implements Subroutine {
@Override
public String call(RiveScript rs, String[] args) {
for (String arg : args)
System.out.println(arg);
return "";
}
}
public static void main(String[] args) throws IOException {
File f = new File("/tmp/test.rs");
FileWriter w = new FileWriter(f);
w.write("! version = 2.0\n\n");
w.write("+ *\n");
w.write("- <call>f <get v></call>\n");
w.close();
RiveScript rs = new RiveScript();
rs.loadFile(f.getAbsolutePath());
rs.sortReplies();
rs.setSubroutine("f", new F());
rs.setUservar("test", "v", "a b");
System.out.println(rs.reply("test", "Hi"));
}
}
I got output:
a
b
I expect that macro get one argument a b
.
Also if method call
return null
when NullPointerException thrown. To get undefined
result call
function should return empty string. Is it OK?
It reproduced on 0.7 and 0.8
Hello.
i am using rivescript-java with telegram and i have a problem to "detect" the bot command /start
I has tried without success:
+ /start
- Welcome
and
+ \/start
- Welcome
Can you help me?
The Jsr223ScriptingHandler
currently tries to get the scripting engine by doing:
``
ScriptEngine engine = new ScriptEngineManager().getEngineByName(engineName);
This works in most cases except in Google AppEngine local devserver.
However, supplying an explicit `null` classloader to the `ScriptEngineManager` does give the engine:
ScriptEngine engine = new ScriptEngineManager(null).getEngineByName(engineName);
So it would be good to add a fallback mechanism.
Note: Interestingly it only fails in the AppEngine local devserver. On the Google hosted environment it works without the fallback.
Hey guys, thanks so much for making this framework available. I love Rivescript in terms of what it offers, but I am unable to use some rivescript files I have created in my java project and it is KILLING me. I am sure I am doing something wrong here myself, but anyway here is my problem:
I am getting file not found and directory not found exceptions whenever I try to load my rive files or directories. I have tried passing both the absolute and the relative path(I kept it relative to the java file) but to no avail. Even when the absolute path is correct, it says it isnt found. I tried changing the code up here and there but to no avail.
Here is the relevant stack:
Caused by: com.rivescript.RiveScriptException: Directory 'replies' not found
When my code contained this:
bot.loadDirectory("replies");
I tried making it "./replies" and I tried adding my files directly as well. But to no avail.
Can someone please help me? I feel so close yet so far and didn't know where else to go. Much thanks.
or if it support how to enable it ?
Could we expose getter for parsed topics?
private Map<String, Topic> topics; // main topic structure
or something in simillar fashion? As we have for subroutines etc.
Here, there is an obvious bug, it should be if != and not == else there will be a NPE on the next line
RSTS unicode.yml#unicode
failed:
java.lang.AssertionError: Did not get expected reply for input: äh
Expected: is "What's the matter?"
but: was "ERR: No Reply Found"
RiveScript rs = new RiveScript();
rs.stream(new String[] { //
"! version = 2.0", //
"+ a", //
"- {lowercase}A{/lowercase}", //
"+ b", //
"- {lowercase}<get v>{/lowercase}"});
rs.sortReplies();
rs.setUservar("test", "v", "B");
System.out.println(rs.reply("test", "a"));
System.out.println(rs.reply("test", "b"));
output is:
a
B
It reproduced on 0.8.* and 0.9.* versions
val script = """
+ simple1
- <call>test "<bot VAR1>"</call>
+ complex
- {@ something <call>test "<bot VAR1>"</call>}
+ interpret
- {@ build <call>test interpret</call>}
+ setvar *
- <bot VAR1=<star>>Var updated
+ getvar
- Var1 is '<bot VAR1>'
+ something *
- SomethingRef=<star>
+ build *
- <bot VAR1=<star>>
> object test javascript
return "Test:" + args[0]
< object
> object interpret javascript
return "<bot VAR1=interpret>"
< object
""".trimIndent()
val user = "user"
val re = RiveScript(Config.newBuilder()
.strict(true)
.utf8(true)
.build()).apply {
stream(script)
sortReplies()
setSubroutine("test", { re, args -> "Test:" + args[0] })
setSubroutine("interpret", { re, args -> "<bot VAR1=interpret>" })
}
assertEquals("Var updated", re.reply(user, "setvar 123"))
assertEquals("Var1 is '123'", re.reply(user, "getvar"))
assertEquals("Test:123", re.reply(user, "simple1"))
assertEquals("SomethingRef=Test:123", re.reply(user, "complex"))//failing, is '{__call__test "123"</call>}'
assertEquals("", re.reply(user, "interpret"))//failing, is 'test interpret</call>}'
assertEquals("Var1 is 'Test:interpret'", re.reply(user, "getvar"))//failing
javascript result (from https://www.rivescript.com/try)
User: setvar 123
Bot: Var updated
User: getvar
Bot: Var1 is '123'
User: simple1
Bot: Test:123
User: complex
Bot: SomethingRef=Test:123
User: interpret
Bot:
User: getvar
Bot: Var1 is 'Test:interpret'
Currently the user vars are stored in the ClientManager
which is a concrete class and cannot be changed.
We should implement a SessionManager
interface like https://github.com/aichaos/rivescript-go/blob/master/sessions/interface.go so people can choose the implementation where to store the user related data. E.g a local map (default) , or others stores like database, redis or something else.
RSTS replies.yml#reply_arrays
failed:
java.lang.AssertionError: Did not get expected reply for input: test random array
Expected: one of {"Testing alpha array.", "Testing beta array.", "Testing gamma array."}
but: was "Testing (@greek) array."
RS file:
! version = 2.0
+ [(a|b) ](c|d)
- <star2>
input c
java.lang.NullPointerException
at com.rivescript.Util.Sv2s(Util.java:52) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
at com.rivescript.RiveScript.processTags(RiveScript.java:1690) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
at com.rivescript.RiveScript.reply(RiveScript.java:1511) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
at com.rivescript.RiveScript.reply(RiveScript.java:1062) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
Similar as aichaos/rivescript-js#209
I was able to add python as a scripting language using jython and a simple handler.
However I needed to modify this commit in order avoid losing indentation in Object handler.
Adding python requires jython as a dependency, not sure if you want to also add this library to the core as a dep, but my first fix gives the possibility of adding it manually if desired.
I am trying to use the object macro within topic and it is failing. However the code snippet before topic is running
Would you please tell me where the error lies
Below is the code snippet of it
+ load the * data set
* <call>loadDataset <star></call> == pass => Dataset is now \s
^ loaded. You can access the table in the main view. {topic=load}
> topic load
//This will match if the word "load" exists ANYWHERE in the user query
+ [*] load [*]
* <call>loadDataset <star></call> == pass => Dataset is now \s
^ loaded. You can access the table in the main view. {topic = random}
< topic
- Data set not found
+ my favorite [_] is *
- Why is it <star1>?
+ i have [#] questions about *
- Well I don't have any answers about <star1>.
Input: my favorite color is red
Expected: Why is it red?
Actual: Why is it color?
Input: i have 2 questions about bots
Expected :Well I don't have any answers about bots.
Actual: Well I don't have any answers about 2.
$ ./gradlew build
:rivescript-core:compileJava UP-TO-DATE
:rivescript-core:processResources UP-TO-DATE
:rivescript-core:classes UP-TO-DATE
:rivescript-core:jar UP-TO-DATE
:api
:docs
:docsZip
:rivescript-core:javadoc UP-TO-DATE
:rivescript-core:javadocJar UP-TO-DATE
:rivescript-core:sourcesJar UP-TO-DATE
:distZip
:assemble
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build
:rivescript-core:signArchives
FAILURE: Build failed with an exception.
* What went wrong:
java.lang.NullPointerException (no error message)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 4.414 secs
RSTS unicode.yml#wildcards
failed:
java.lang.AssertionError: Did not get expected reply for input: My name is Bảo
Expected: is "Nice to meet you, bảo."
but: was "Nice to meet you, bo."
RSTS replies.yml#continuations
failed:
java.lang.AssertionError: Did not get expected reply for input: Tell me a poem.
Expected: is "There once was a man named Tim, who never quite learned how to swim. He fell off a dock, and sank like a rock, and that was the end of him.\n"
but: was "There once was a man named Tim, who never quite learned how to swim. He fell off a dock, and sank like a rock, and that was the end of him."
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.