/evejs

Simple, web-based agents running on node.js and in the browser

Primary LanguageJavaScriptApache License 2.0Apache-2.0

evejs

Eve is a multipurpose, web-based agent platform. Eve envisions to be an open and dynamic environment where agents can live and act anywhere: in the cloud, on smartphones, on desktops, in browsers, robots, home automation devices, and others. The agents communicate with each other using simple, existing protocols (JSON-RPC) over existing transport layers (HTTP, AMQP, WebSockets, etc.), offering a language and platform agnostic solution.

Eve is being developed by Almende B.V., a Dutch research company specialized in information and communication technologies. Central to Almende's research is the concept of self-organization. Almende believes that computer systems and technology should support people in performing their professional tasks and organizing their daily lives. This means that ICT should learn to work for and with people, according to their individual wishes and demands.

Currently there are two main implementations of Eve: one in Java and one in JavaScript. This is the JavaScript version of Eve (evejs), running in node.js and on the browser. More on the general concepts and about other implementations can be found on the official website: http://eve.almende.com.

The evejs library features:

  • A simple, message based Agent class.
  • Extension modules offering powerful communication patterns: Babble, Pattern, Request, and RPC.
  • Support for many communication transports: AMQP, Distibus, HTTP, Local, PubNub, and WebSocket.
  • Simulation tooling: discrete event simulation and deterministic random number generation.
  • Extensive documentation and examples.

Install

Install the module via npm:

npm install evejs

Load

Load evejs in a node.js application:

var eve = require('evejs');

// ... use eve ...

Load evejs in the browser:

<!DOCTYPE HTML>
<html>
<head>
  <script src="./dist/eve.js"></script>
</head>
<body>
  <script type="text/javascript">
  // ... use eve ...
  </script>
</body>
</html>

Use

An agent basically has a methods send, receive, connect and disconnect. An agent can be extended with modules like pattern and request. There is a central configuration eve.system which can be used to load transports. The loaded transports can be used by agents to communicate with each other.

To set up a system with eve agents:

  • Create an agent class extending eve.Agent. A template for an agent is:

    var eve = require('evejs');
    
    function MyAgent(id) {
      // execute super constructor
      eve.Agent.call(this, id);
      
      // extend the agent with modules (choose from 
      // 'babble', 'pattern', 'request', and 'rpc')
      this.extend('request');
      
      // connect to some or all transports
      this.connect(eve.system.transports.getAll());
    }
    
    // extend the eve.Agent prototype
    MyAgent.prototype = Object.create(eve.Agent.prototype);
    MyAgent.prototype.constructor = MyAgent;
    
    MyAgent.prototype.receive = function (from, message) {
      // handle incoming messages...
    };
    
    module.exports = MyAgent;
  • To send and receive messages, each agent has a method send(to, message) and receive(from, message). A message can be send to and agent by specifying either the agents full url, or just the agents id. In the latter case, the agent will send the message via the transport marked as default.

    agent1.send('distribus://networkId/agent2', 'hello agent2!');
    agent1.send('agent2', 'hello agent2!'); // send via the default transport

    The networkId of a transport can be found at transport.networkId.

  • Configure eve.system, initialize transports and other services.

    eve.system.init({
      transports: [
        {
          type: 'distribus'
        }
      ]
    });
  • Create an agent:

    var agent1 = new MyAgent('agent1');

HelloAgent

To create a simple agent class, create a file HelloAgent.js with the following code:

var eve = require('evejs');

function HelloAgent(id) {
  // execute super constructor
  eve.Agent.call(this, id);

  // connect to all transports configured by the system
  this.connect(eve.system.transports.getAll());
}

// extend the eve.Agent prototype
HelloAgent.prototype = Object.create(eve.Agent.prototype);
HelloAgent.prototype.constructor = HelloAgent;

HelloAgent.prototype.sayHello = function(to) {
  this.send(to, 'Hello ' + to + '!');
};

HelloAgent.prototype.receive = function(from, message) {
  console.log(from + ' said: ' + JSON.stringify(message));

  if (message.indexOf('Hello') === 0) {
    // reply to the greeting
    this.send(from, 'Hi ' + from + ', nice to meet you!');
  }
};

module.exports = HelloAgent;

This agent class can be used as follows. Note that the agents talk to each other via a LocalTransport which is instantiated in eve.system by default.

var HelloAgent = require('./HelloAgent');

// create two agents
var agent1 = new HelloAgent('agent1');
var agent2 = new HelloAgent('agent2');

// send a message to agent1
agent2.send('agent1', 'Hello agent1!');

Documentation

Examples

Examples are available in the examples folder:

https://github.com/enmasseio/evejs/tree/master/examples

Build

A bundled file of evejs for use in the browser is available in the folder ./dist. Note that not all transports are supported in the browser.

The files can be regenerated by running:

npm run build

To automatically re-build on code changes, run one of the following scripts:

npm run watch           # bundle and minify on code change
npm run watch-bundle    # bundle on code change

Custom builds

To create a custom bundle containing only the needed modules and transports, create a copy of index.js named custom.js, and strip all redundant dependencies for it. The most minimalistic version only includes Agent and LocalTransport and could look like:

exports.Agent = require('./lib/Agent');
exports.transport: {
  LocalTransport: require('./lib/transport/local/LocalTransport')
}

Create a bundle using browerify:

browserify custom.js -o eve.custom.js -s eve

Test

To test evejs, install the project dependencies once:

npm install

Then run the tests:

npm test