Closed dcsan closed 8 years ago
and I'm calling parse with these three args
Rebot.brain.parse('testbrain', blob, (err, res) => {
console.log('testParse result', err, res);
});
oh, i get it. I need to do this
var rsCode = Rebot.brain.stringify(blob);
Rebot.brain.stream(rsCode);
Rebot.brain.sortReplies();
and stream / parse is just async sync but otherwise does the same thing?
Stream and parse are synchronous. The only reason the loadFile/loadDirectory are async is because they use underlying async functions (ajax requests or fs.readFile or w/e). You're correct that you can't populate the RiveScript brain using the deparsed json blob. Like in the Perl version those functions are for pretty special use cases, namely for assisting with a third party frontend for editing RiveScript replies. The json blob is easy to edit in code, and write() let's you write the resulting data to disk. In the Perl version I had a hosted bot platform for a while on RiveScript.com, and people would edit their bot one file at a time. So in that case I'd store individual json blobs for each file, and write them one at a time to RiveScript files for the user to export them or "publish" them to go live on their bot.
As an aside, don't call the parse function directly, its a private function. ;) Its implementation could change at some point.
oh, reading the docs parse
I thought the error callback was also an "on done" but i guess I misread that, its just for error handling
otherwise they look almost identical except for taking a 'name'
bool stream (string code[, func onError]) private bool parse (string name, string code[, func onError])
so
don't call the parse function directly
parse is like a _parse
internal method that stream uses? and the stream method is public/safe to use?
I'm building a GUI (spreadsheet like) editor, so if I do want to go from a JSON object:
deparse
brain.stringify
on that json object to get rivescriptstream
?ie there's no way to feed the JSON object in directly?
I could probably add a function to load the json in directly. It'd do the opposite of the deparse function, which basically just clones a dozen internal data structures. The parse function is essentially the same as stream, except stream provides the string "stream()" as the file name parameter (for syntax error reporting purposes). Use the stream function instead of parse.
actually, ideally I would like to just pass in the individual trigger nodes, not the whole structure... something like just these nodes are mostly what would be gui edited.
But using the loader this way rather than stream()
it will stomp on the whole brain, so I think need to pass a complete structure in?
The stuff like variables, substitutions etc is best left to some type of config. So I guess I could have a JSON config/template file based on a deparse, parse that to an object then just add the trigger nodes from the GUI editor to that object and stringify > stream
(or load JSON directly if that is implemented)
going back and forth from JS to rivescript seems to have potential for gotchas, I've had problems already since I'm basically doing something like that now. esp around continuations. I have an added wrinkle that I'm using some things like ^ image: #filename
for metadata, so i wanted to keep the continuations. but maybe that can work with just \n
too.
"topics": {
"gotopic": [
{
"trigger": "endlesson",
"reply": [
"Let's see how you did.\nYou scored <get score>\n{@scorefeedback}\ngoto: exitlesson"
],
"condition": [],
"redirect": null,
"previous": null
},
{
"trigger": "scorefeedback",
"reply": [],
"condition": [
"<get score> < -5 => You need to study a lot more.",
"<get score> < -2 => Hmm, not great.",
"<get score> <= 1 => Hmm, not too bad",
"<get score> > 1 => Good work!",
"<get score> > 3 => Great job!"
],
"redirect": null,
"previous": null
},
...
"inherits": {
"global_commands": {},
"gotopic": {
"global_commands": 1
},
"lessons_shared": {
"global_commands": 1
},
RiveScript doesn't keep track of continuations after the file has been parsed. When parsing the code, it looks ahead for continuations and concatenates them at the end of the current line of code it was otherwise looking at (joining them at the concat symbol, which can be set as the newline character). So a reply that continues across multiple lines ends up looking no different than a reply that was all on one line at the end of the parsing phase.
The Perl version of RiveScript pretty-prints the output from write()
(essentially, word-wrapping it to keep lines under 80 characters long). This causes it to add continuation commands itself, but it puts them in only in the interest of word-wrapping a long line. I didn't implement the pretty-printing in the JS version because it requires a lot of very tedious code that I didn't feel like writing (keeping track of indentation levels, line buffers, etc. is mind numbing, and getting lengths of things in JavaScript is needlessly verbose). I may come back to that in the future, though.
trying to use the parse feature.
Is this for loading a json object, or rivescript code? If its 'code' how is it different from
stream
?I used brain.deparse() to dump to a JSON file, and then tried to load that back in again with
brain.parse()
but i get an errorFYI the brain.json looks like this (I can upload the whole thing to a gist)