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 the module via npm:
npm install evejs
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>
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)
andreceive(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');
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!');
Examples are available in the examples folder:
https://github.com/enmasseio/evejs/tree/master/examples
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
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
To test evejs
, install the project dependencies once:
npm install
Then run the tests:
npm test