Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

prague

Package Overview
Dependencies
Maintainers
1
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prague

experimental Rx-based bot technology

  • 0.1.0
  • npm
  • Socket score

Version published
Weekly downloads
15
increased by275%
Maintainers
1
Weekly downloads
 
Created
Source

Prague

An experimental Rx-based framework for adding conversational features to apps. I thought of it as I walked around Prague on a sunny Spring day. This is just an experiment and not an official Microsoft project.

Major features of Prague:

  • strongly-typed rules engine for interpreting ambiguous input
  • support for different types of applications through fine-grained interfaces rather than abstraction
  • deeply asynchronous via RxJS

Some types of applications you could build with Prague: * Command line * Browser app w/chat interface * Browser app w/voice interface * Slack bot (native interface) * Multi-platform Chat bot * Server-rendered Website w/pop-up chat

Getting up and Running

Building Prague

  • clone or fork this repo
  • npm install
  • npm run build (or npm run watch to build on file changes)

Using Prague in your app

  • npm install prague -S
  • or, if you're building your own, npm install file:../path/to/your/repo
  • import { the, stuff, you, want } from 'prague' or import * as Prague from 'prague'

Prague 101

At it's heart, Prague is a strongly-typed rules engine for interpreting ambiguous input.

Rules

The core concept is the Recognizer, which interprets input and extracts out semantic content, and the Handler which acts upon that content. Recognizers and Handlers formed a matched pair called a Rule.

Here is a simple rule which does some extremely limited sentiment analysis and responds accordingly:

const moodRule = {
    recognizer: (session: ITextSession) => ({ moods: ['sad', 'mad', 'happy'].filter(mood => session.text.indexOf(mood) != -1) }),
    handler: (session: ITextSession, args: { moods: string[] }) => moods.forEach(mood => console.log(`I hear you are feeling ${mood}`))
}

You execute a rule by calling executeRule with appropriate input:

executeRule({ text: "I'm mad as heck and I'm not going to take it anymore" }, moodRule);

Sessions

The input to both Recognizers and Handlers is called a Session, which can take on different forms depending on the application and input source.

Built-in recognizers

Prague provides built-in recognizers for LUIS models and Regular Expressions. Here is myNameRule rewritten to use the built-in recognizer:


const re = new RE<ITextSession>();

const myNameRule = re.rule(
    /My name is (.*)/,
    (session, args) => `Hello, ${args[1]}`
)

And here it is using a hypothetical LUIS model:

const luis = new LUIS<ITextSession>({
    name: 'nameForMyModel',
    id: 'myID',
    key: 'myKey'
})

const myNameRule = luis.rule('nameForMyModel', [
    luis.intent('myName', (session, args: { name: string }) => `Hello, ${args.name}`)
])

Multiple rules

You could write a single rule to respond to every possible input, but a more typical approach is to break the problem down into a series of rules. Here is one that uses Regular Expressions to identify and extract out the user's name.

const myNameRule = { recognizer (session: ITextSession) => /My name is (.*)/.exec(session.text), handler: (session: ITextSession, args: RegExpExecArray) => Hello, ${args[1]} }

Now we have two rules, and you can imagine many others. You could call executeRule on all of your rules, but most commonly you'll want to stop once one of them succeeds. For this we'll use a helper function called firstMatch which runs through a series of rules in order, calling the recognizer for each, stopping at the first one which succeeds, and calling its handler.

executeRule({text: "My name is Bill"}, firstMatch(
    moodRule,
    myNameRule,
    jukeboxRule,
    pubFinderRule
]))

>> "Hello, Bill"

Note that firstMatch itself returns a rule, so you can organize this code differently:

executeRule({text: "My name is Bill"}, firstMatch(
    moodRule,
    firstMatch(
        myNameRule,
        jukeboxRule
    ),
    pubFinderRule
]))

>> "Hello, Bill"

This actually produces the same results, so it's not a particularly useful example. But it demonstrates that rules are composable, which we will make better use of shortly.

(Another approach to a list of rules would be to run through all the rules, calling each recognizer, and only calling the handler for the recognizer which returns the best match. This approach requires recognizers which return an agreed-upon format (and scale) for scoring matches.)

State and Rules

Application state vs. Conversation state

Prompts

Async

FAQs

Package last updated on 15 Apr 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc