RiveScript(3pm)

πŸ“¦
version 2.0.4 Β· 2 versions
  • 2.0.4 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 2.0.3 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ¦‹ RiveScript πŸ¦‹

okay so bestie, welcome to RiveScript(3pm) β€” the perl doc for the cutest little chatbot language on the block πŸ’– Rendering Intelligence Very Easily, no cap, it's literally in the name.


✨ SYNOPSIS ✨

like here's the whole vibe in one go, bestie:

use RiveScript;

# Create a new RiveScript interpreter.
my $rs = new RiveScript;

# Load a directory of replies.
$rs->loadDirectory ("./replies");

# Load another file.
$rs->loadFile ("./more_replies.rive");

# Stream in some RiveScript code.
$rs->stream (q~
  + hello bot
  - Hello, human.
~);

# Sort all the loaded replies.
$rs->sortReplies;

# Chat with the bot.
while (1) {
  print "You> ";
  chomp (my $msg = <STDIN>);
  my $reply = $rs->reply ('localuser',$msg);
  print "Bot> $reply\n";
}

periodt. that's the whole bot, you're welcome πŸ’…


🌸 DESCRIPTION 🌸

okay so RiveScript is a simple trigger/response language that's mostly used to make chatting robots 🫢. It's literally designed so the syntax is easy to learn but it still gives you SO much power and flexibility, like it's giving range. For more info, go check out http://www.rivescript.com/ ✨


πŸ‘‘ METHODS πŸ‘‘

πŸŽ€ GENERAL πŸŽ€

RiveScript new (hash %ARGS)

make a brand new RiveScript interpreter instance, bestie ✨. This instance becomes its own lil "chatterbot," with its own set of responses and its own user variables, like its own whole personality. You can pass in any global variables here. The two standard ones are:

debug     - Turns on debug mode (a LOT of information will be printed to the
            terminal!). Default is 0 (disabled).
verbose   - When debug mode is on, all debug output will be printed to the
            terminal if 'verbose' is also true. The default value is 1.
debugfile - Optional: paired with debug mode, all debug output is also written
            to this file name. Since debug mode prints such a large amount of
            data, it is often more practical to have the output go to an
            external file for later review. Default is '' (no file).
utf8      - Enable UTF-8 support for the RiveScript code. See the section on
            UTF-8 support for details.
depth     - Determines the recursion depth limit when following a trail of replies
            that point to other replies. Default is 50.
strict    - If this has a true value, any syntax errors detected while parsing
            a RiveScript document will result in a fatal error. Set it to a
            false value and only a warning will result. Default is 1.

lowkey recommended that if you set any other global variables, you do it by calling setGlobal or by defining it inside the RiveScript code itself. That way you avoid the whole possibility of overriding reserved globals πŸ™ˆ. rn these variable names are the reserved ones:

topics   sorted  sortsthat  sortedthat  thats
arrays   subs    person     client      bot
objects  syntax  sortlist   reserved    debugopts
frozen   globals handlers   objlangs
note bestie πŸ“: the options verbose and debugfile, when you provide them, get noted and then deleted from the root object space, so that if your RiveScript code uses variables by the same values it won't conflict with the values you passed here. iykyk.

🌈 LOADING AND PARSING 🌈

bool loadDirectory (string $PATH[, string @EXTS])

load a whole directory full of RiveScript documents, slay πŸŽ€. $PATH has to be a path to a directory. @EXTS is optionally an array containing file extensions, including the dot. By default @EXTS is ('.rive', '.rs').

Returns true on success, false on failure πŸ’€.

bool loadFile (string $PATH)

load a single RiveScript document. $PATH should be the path to a valid RiveScript file. Returns true on success; false otherwise ✨.

bool stream (arrayref $CODE)

stream RiveScript code directly into the module. This is for providing RS code from inside the Perl script itself instead of from an external file. Returns true on success 🫢.

string checkSyntax (char $COMMAND, string $LINE)

check the syntax of one line of RiveScript code. This gets called automatically for every line the module parses. $COMMAND is the command part of the line, and $LINE is the rest of the line following the command (and excluding inline comments) πŸ‘‘

if there's no problem with the line, this method returns undef. Otherwise it returns the text of the syntax error πŸ’….

if strict mode is enabled in the constructor (and it's on by default, bestie), a syntax error results in a fatal error. If it's not enabled, the error is only sent via warn and the file currently being processed gets aborted. so like, no pressure 🌸.

void sortReplies ()

call this method after loading replies to create an internal sort buffer. This is necessary for trigger matching purposes, fr fr. If you forget to call this method yourself, RiveScript will call it once when you request a reply. However, it will complain loudly about it 😭. so just call it, okay?

data deparse ()

translate the in-memory representation of the loaded RiveScript documents into a Perl data structure. This is useful for developing a user interface to make editing RiveScript replies easier without having to edit the RiveScript code manually ✨.

the data structure returned from this follows this format:

{
  "begin" => { # Contains begin block and config settings
    "global" => { # ! global (global variables)
      "depth" => 50,
      ...
    },
    "var" => {    # ! var (bot variables)
      "name" => "Aiden",
      ...
    },
    "sub" => {    # ! sub (substitutions)
      "what's" => "what is",
      ...
    },
    "person" => { # ! person (person substitutions)
      "you" => "I",
      ...
    },
    "array" => {  # ! array (arrays)
      "colors" => [ "red", "green", "light green", "blue" ],
      ...
    },
    "triggers" => {  # triggers in your > begin block
      "request" => { # trigger "+ request"
        "reply" => [ "{ok}" ],
      },
    },
  },
  "topic" => { # all topics under here
    "random" => { # topic names (default is random)
      "hello bot" => { # trigger labels
        "reply"     => [ "Hello human!" ], # Array of -Replies
        "redirect"  => "hello",            # Only if @Redirect exists
        "previous"  => "hello human",      # Only if %Previous exists
        "condition" => [                   # Only if *Conditions exist
          "<get name> != undefined => Hello <get name>!",
          ...
        ],
      },
    },
  },
  "include" => { # topic inclusion
    "alpha" => [ "beta", "gamma" ], # > topic alpha includes beta gamma
  },
  "inherit" => { # topic inheritance
    "alpha" => [ "delta" ], # > topic alpha inherits delta
  }
}
note bestie πŸŽ€: inline object macros can't be deparsed this way. This is probably for the best (for security, etc). The global variables debug and depth are only provided if the values differ from the defaults (true and 50, respectively).

void write (glob $fh || string $file[, data $deparsed])

write the currently parsed RiveScript data into a RiveScript file. This uses deparse() to dump a representation of the loaded data and writes it to the destination file. Pass either a filehandle or a file name πŸ’–.

if you provide $deparsed, it should be a data structure matching the format of deparse(). This way you can deparse your RiveScript brain, add/edit replies, and then pass in the new version to this method to save the changes back to disk. Otherwise, deparse() gets called to get the current snapshot of the brain ✨.

πŸ’œ CONFIGURATION πŸ’œ

bool setHandler (string $LANGUAGE => code $CODEREF, ...)

define some code to handle objects of a particular programming language. If the coderef is undef, it will delete the handler πŸ‘‘.

the code receives the variables $rs, $action, $name, and $data. These variables are described here:

$rs     = Reference to Perl RiveScript object.
$action = "load" during the parsing phase when an >object is found.
          "call" when provoked via a <call> tag for a reply
$name   = The name of the object.
$data   = The source of the object during the parsing phase, or an array
          reference of arguments when provoked via a <call> tag.

there's a default handler set up that handles Perl objects 🫢.

if you want to block Perl objects from being loaded, you can just set it to be undef, and its handler gets deleted and Perl objects will be skipped over:

$rs->setHandler (perl => undef);

the rationale behind this "pluggable" object interface is that it makes RiveScript more flexible given certain environments. For instance, if you use RiveScript on the web where the user chats with your bot using CGI, you might define a handler so that JavaScript objects can be loaded and called. Perl itself can't execute JavaScript, but the user's web browser can 😭 (so smart).

see the JavaScript example in the docs directory in this distribution ✨.

bool setSubroutine (string $NAME, code $CODEREF)

manually create a RiveScript object (a dynamic bit of Perl code that can be provoked in a RiveScript response). $NAME should be a single-word, alphanumeric string. $CODEREF should be a pointer to a subroutine or an anonymous sub πŸ’….

bool setGlobal (hash %DATA)

set one or more global variables, in hash form, where the keys are the variable names and the values are their value. This subroutine makes sure you don't override any reserved global variables, and warns you if that happens πŸŽ€.

this is equivalent to ! global in RiveScript code.

to delete a global, set its value to undef or "<undef>". This is true for variables, substitutions, person, and uservars. 🌸

bool setVariable (hash %DATA)

set one or more bot variables (things that describe your bot's personality, like its whole main character energy) ✨.

this is equivalent to ! var in RiveScript code.

bool setSubstitution (hash %DATA)

set one or more substitution patterns. The keys should be the original word, and the value should be the word to substitute with it πŸ’–.

$rs->setSubstitution (
  q{what's}  => 'what is',
  q{what're} => 'what are',
);

this is equivalent to ! sub in RiveScript code πŸ‘‘


bool setPerson (hash %DATA)

Set a person substitution, bestie. This is the exact same energy as writing ! person in RiveScript code, just from the Perl side. πŸ’…

bool setUservar (string $USER, hash %DATA)

Sets a variable for a user. $USER is their User ID, and %DATA is a hash stuffed with variable/value pairs.

It's basically <set> but aimed at one specific user. πŸŽ€

string getUservar (string $USER, string $VAR)

This one is literally just an alias for getUservars β€” it exists because it reads better grammatically, and honestly? fair. πŸ¦‹

data getUservars ([string $USER][, string $VAR])

Grab all the variables about a user. Hand it a username and you get back a hash reference with that user's whole info situation. Hand it nothing and you get a hash reference of every user and their info. no cap. ✨

You can also optionally pass a second argument, $VAR, to snag one specific variable that belongs to that user. For instance, getUservars ("soandso", "age").

Think of it as <get> for one specific user, or for literally everyone. πŸ‘‘

bool clearUservars ([string $USER])

Wipes all the variables about $USER. No $USER given? Then it clears all variables about all users. goodbye data πŸ’€

bool freezeUservars (string $USER)

Freezes the current state of variables for user $USER. This backs up the user's current state (their variables and their reply history).

Quick reality check though: this does not statically prevent the user's state from changing β€” it just saves a snapshot of how things look right now. Then you call thawUservars() to revert back to this previous state. ❄️

bool thawUservars (string $USER[, hash %OPTIONS])

If $USER's variables were previously frozen, this method restores them to the state they were in when they were last frozen. By default it then deletes the stored cache. 🫢

These options come in as an extra hash of parameters β€” and heads up, they are mutually exclusive, so don't use both at once. If you do, discard wins. πŸ™ˆ

  • discard β€” Don't restore the user's state from the frozen copy, just delete the frozen copy.
  • keep β€” Keep the frozen copy even after restoring the user's state. With this you can repeatedly thawUservars on the same user to revert their state without having to keep freezing them again. On the next freeze, the last frozen state will be replaced with the new current state.

Examples, bestie:

# Delete the frozen cache but don't modify the user's variables.
$rs->thawUservars ("soandso", discard => 1);

# Restore the user's state from cache, but don't delete the cache.
$rs->thawUservars ("soandso", keep => 1);

string lastMatch (string $USER)

After you fetch a reply for user $USER, the lastMatch method returns the raw text of the trigger that the user matched with their reply.

It may return undef if the user didn't match any trigger at all β€” and if that happened, your last reply was probably "ERR: No Reply Matched" too. 😭

string currentUser ()

Gets the user ID of the current user chatting with the bot. This is mostly useful inside a Perl object macro in RiveScript, so you can grab the user ID of whoever invoked the object macro (like, to get/set variables for them using the $rs instance). πŸ’–

It returns undef if you use it outside the context of a reply β€” the value gets unset at the end of the reply() method.


πŸ’¬ INTERACTION πŸ’¬

string reply (string $USER, string $MESSAGE)

Fetches a response to $MESSAGE from user $USER. RiveScript handles all the lowercasing, running substitutions, and stripping punctuation from the message for you. ✨

Returns a response from the RiveScript brain. iconic.


πŸ“œ RIVESCRIPT πŸ“œ

This interpreter tries its very best to follow RiveScript standards, fr fr. Right now it supports RiveScript 2.0 documents. A current copy of the RiveScript working draft is included with this package β€” see RiveScript::WD. πŸ“–


🌈 UTF-8 SUPPORT 🌈

RiveScript supports Unicode, but it is not enabled by default. Turn it on by passing a true value for the utf8 option in the constructor, or by using the --utf8 argument to the rivescript application. 🌸

In UTF-8 mode, most characters in a user's message are left intact β€” except for certain metacharacters like backslashes and common punctuation characters like /[.,!?;:]/.

Wanna override the punctuation regexp? You can hand in a new one by assigning the unicode_punctuation attribute of the bot object after initialization. Example:

my $bot = new RiveScript(utf8 => 1);
$bot->{unicode_punctuation} = qr/[.,!?;:]/;

✨ CONSTANTS ✨

This module can export some constants. 🎁

use RiveScript qw(:standard);

These constants include:

RS_ERR_MATCH

This is the reply text given when no trigger has matched the message. It equals "ERR: No Reply Matched".

if ($reply eq RS_ERR_MATCH) {
  $reply = "I couldn't find a good reply for you!";
}

RS_ERR_REPLY

This is the reply text given when a trigger was matched, but no reply was given from it β€” for example, the trigger only had conditionals and all of them were false, with no default replies to fall back on. It equals "ERR: No Reply Found".

if ($reply eq RS_ERR_REPLY) {
  $reply = "I don't know what to say about that!";
}

πŸ‘€ SEE ALSO πŸ‘€

  • RiveScript::WD β€” A current snapshot of the Working Draft that defines the standards of RiveScript.
  • <http://www.rivescript.com/> β€” The official homepage of RiveScript.

πŸ—“οΈ CHANGES πŸ—“οΈ

2.0.4 Nov 25 2022

  • Fix certain combinations of nested tags causing an infinite loop to parse them.
  • Fix {weight} tags in triggers not trimming remaining whitespace after they are removed, which affected trigger matching ability.

2.0.3 Aug 26 2016

  • Fix inline comment regexp that was making URLs impossible to represent in replies.

2.0.2 Jan 11 2016

  • Fix typo in changelog.

2.0.1 Jan 11 2016

  • When formatting a user's message, consolidate multiple consecutive spaces down to one.
  • Apply downstream Debian patch that fixes a typo in RiveScript::WD.

2.0.0 Dec 28 2015

  • Switch from old-style floating point version number notation to dotted decimal notation. This bumps the version number to 2.0.0 because the next dotted-decimal version greater than 1.42 (v1.420.0) is v1.421.0 and I don't like having that many digits in the version number. This release is simply a version update; no breaking API changes were introduced.

1.42 Nov 20 2015

  • Add configurable unicode_punctuation attribute to strip out punctuation when running in UTF-8 mode.

1.40 Oct 10 2015

  • Fix the regexp used when matching optionals so that the triggers don't match on inputs where they shouldn't. (RiveScript-JS issue #46)

1.38 Jul 21 2015

  • New algorithm for handling variable tags (<get>, <set>, <add>, <sub>, <mult>, <div>, <bot> and <env>) that allows for iterative nesting of these tags (for example, <set copy=<get orig>> will work now).
  • Fix trigger sorting so that triggers with matching word counts are sorted by length descending.
  • Add support for ! local concat option to override concatenation mode (file scoped)
  • Bugfix where Perl object macros set via setSubroutine() failed to load because they were missing a programming language internally.

1.36 Nov 26 2014

  • Relicense under the MIT License.
  • Strip punctuation from the bot's responses in UTF-8 mode to support compatibility with %Previous.
  • Bugfix in deparse(): If you had two matching triggers, one with a %Previous and one without, you'd lose the data for one of them in the output.

1.34 Feb 26 2014

  • Update README.md to include module documentation for github.
  • Fixes to META.yml

1.32 Feb 24 2014

  • Maintenance release to fix some errors per the CPANTS.
  • Add license to Makefile.PL
  • Make Makefile.PL not executable
  • Make version numbers consistent

1.30 Nov 25 2013

  • Added "TCP Mode" to the rivescript command so that it can listen on a socket instead of using standard input and output.
  • Added a --data option to the rivescript command for providing JSON input as a command line argument instead of standard input.
  • Added experimental UTF-8 support.
  • Bugfix: don't use hacky ROT13-encoded placeholders for message substitutions... use a null character method instead. ;)
  • Make .rive the default preferred file extension for RiveScript documents instead of .rs (which conflicts with the Rust programming language). Backwards compatibility remains to load .rs files, though.

See the Changes file for older change history.


πŸ’– AUTHOR πŸ’–

Noah Petherbridge, <http://www.kirsle.net>


πŸ”‘ KEYWORDS πŸ”‘

bot, chatbot, chatterbot, chatter bot, reply, replies, script, aiml, alpha


The MIT License (MIT)

Copyright (c) 2015 Noah Petherbridge

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

and that's a wrap bestie πŸŽ€ that was the whole RiveScript(3pm) page, served up by perl v5.36.0 and dated 2022-12-23. go make ur bot say something unhinged, ily πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from