Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


eliza.js is a Javascript clone of ELIZA, Joseph Weizenbaum's simulation of a Rogerian psychotherapist. It is an attempt to properly learn javascript, so don't blame me if it's godawful.


ELIZA was one of the very first chatterbots, an early attempt to use natural language processing to emulate human responses. Programattically it's really very simple, and the majority of the "intelligence" is embodied in the script.

Charles Hayden has an excellent explanation and sample script on his website; this is what I used as a reference.

Loosely speaking, an input phrase is broken down into tokens, and a set of weighted keywords is searched for in the token list. Each keyword has an associated set of match patterns ("decompositions") and responses which are tried in turn against the input phrase. If one matches, the response is constructed (sometimes using captured segments of the input phrase) and returned. If none match, then the system moves on to the next decomposition, and the next keyword, until a match is found.

Some decompositions store their response for later, giving ELIZA the appearance of returning to earlier topics. Others redirect to specific keywords.


An Eliza object requires a client implementing the .say() and .quit() methods, and a script of fiendish complexity (see lib/eliza/script.js for the more-or-less original ELIZA script as translated into a bodgy JSON representation).

Call .say() on the Eliza instance, and it will call .say() right back with some gibberish. If you utter one of the quit phrases as specified in the script, Eliza will call the client's .quit() method.

var script = {
  // ...

var client = {
  say: function(phrase) { console.log(phrase); },
  quit: function(phrase) { console.log("QUIT"); }

var eliza = new Eliza(client, script);

// => client.say() called with some response

I had a stab at implementing this using a strictly tell-don't-ask style, mainly to appease Tom Stuart (the evil one). It actually worked out quite nicely I think, the sequence diagram looks mostly like this:

Eliza sequence diagram

As far as I can tell there's only one place where one type of object gets and sets properties on another type, and that's in the LinkedList implementation (it's not clear in the diagram above: each key has a linked list of decomps. The key calls .match() on the first decomp, which passes on to the next decomp unless it can find a match).

Most of the grossness is in Eliza itself, most of the responsibilities of which would be handled by a proper script parser if I had any pride.


No description, website, or topics provided.







No releases published


No packages published