Prewritten Protocols

The astra-protocols library contains ready-made implementations of some common interaction protocols. How interaction protocols work, and how to write your own, is explained in Interaction Protocols.

To use the library, add it to your project’s pom.xml:

<dependencies>
    <dependency>
        <groupId>com.astralanguage</groupId>
        <artifactId>astra-protocols</artifactId>
        <version>2.6.1</version>
    </dependency>
</dependencies>

Each protocol is an agent program in the astra.protocol package. You use one by inheriting from it (with extends) and then overriding the plans that decide what your agent does at each step of the protocol. Each protocol program contains the plans for both roles: the agent that starts the conversation (the initiator) and the agent that responds to it (the participant). The protocols are written using encapsulated goals, so the plans that handle the replies to a conversation are only active while that conversation is going on.

Protocol

Program

Initiator goal

Participant goal

FIPA Request

astra.protocol.FipaRequest

!request_action(target, act)

!monitor_action_requests()

FIPA Subscribe

astra.protocol.FipaSubscribe

!subscribe(target, channel)

!monitor_subscriptions()

First-price auction

astra.protocol.FirstPriceAuction

!auction(id, description, configure(timeout))

!monitor_for_auctions()

Vickrey (second-price) auction

astra.protocol.VickreyAuction

!auction(id, description, configure(timeout))

!monitor_for_auctions()

FIPA Request

FipaRequest implements the protocol described in Interaction Protocols. Actions are represented as funct terms, such as greet("world").

The participant adopts !monitor_action_requests() and overrides two plans:

Plan

Purpose

+!evaluate_request(string name, funct act, boolean result)

Set result to true to agree to perform act for agent name, or false to refuse. By default, every request is refused.

+!execute_request(string name, funct act, funct outcome, boolean result)

Perform act. Set outcome to a term describing the result, and result to true if the action succeeded.

The initiator adopts !request_action(target, act) for each request, and can override +!agreed_request(funct act), +!failed_request(funct act) (the request was refused) and +!succeeded_request(funct act, funct outcome) to react to the replies. The !request_action(...) goal ends once the conversation is over (the action succeeded, failed or was refused), and the plan that adopted it then continues.

In this example, a Requester asks a Responder to greet the world:

package demo;

agent Responder extends astra.protocol.FipaRequest {
    initial !monitor_action_requests();

    plan +!evaluate_request(string name, greet(string who), boolean result) {
        result = true;
    }

    plan +!execute_request(string name, greet(string who), funct outcome, boolean result) {
        console.println("Hello, " + who + "!");
        outcome = greeted(who);
        result = true;
    }
}
package demo;

agent Requester extends astra.protocol.FipaRequest {
    plan +!main(list args) {
        system.createAgent("responder", "demo.Responder");
        !request_action("responder", greet("world"));
        console.println("request finished");
        system.exit();
    }

    plan +!agreed_request(funct act) {
        console.println("responder agreed to: " + act);
    }

    plan +!succeeded_request(funct act, funct outcome) {
        console.println(act + " succeeded with outcome: " + outcome);
    }
}
[main] responder agreed to: greet("world")
[responder] Hello, world!
[main] greet("world") succeeded with outcome: greeted("world")
[main] request finished

The Responder’s plans only match greet(...) actions; any other request is handled by the default plans, and refused.

FIPA Subscribe

FipaSubscribe lets agents subscribe to channels that another agent publishes information on.

  • The participant (the publisher) adopts !monitor_subscriptions(), and has a channel(name) belief for each channel it offers. It can override +!evaluate_subscription(string channel, boolean result) to decide whether to accept a subscription (by default, all are accepted), and adopts !publish(channel, message) to send a funct message to every subscriber of a channel.

  • The initiator (the subscriber) adopts !subscribe(target, channel). It overrides +!handle_content(string channel, funct message) to process the messages it receives, and can override +!subscription_accepted(...), +!subscription_refused(...) and +!subscription_cancelled(...). It adopts !cancel_subscription(target, channel) to unsubscribe.

Auctions

FirstPriceAuction and VickreyAuction implement sealed-bid auctions: the auctioneer sends a call for proposals (cfp) to every participant, waits for a fixed time, and then accepts the best bid. In a first-price auction, the winner pays the amount it bid; in a Vickrey auction, it pays the second-highest bid.

  • The auctioneer has a participant(name) belief for each agent that should be invited, and adopts !auction(id, description, configure(timeout)). It can override +!compare_bids(...) to change how bids are compared; by default, the highest bid wins.

  • Each participant adopts !monitor_for_auctions() and overrides +!generate_bid(string id, funct description, int bid) to set its bid. It can also override +!successful_bid(...) and +!failed_bid(...).

package demo;

agent Auctioneer extends astra.protocol.FirstPriceAuction {
    initial participant("alice"), participant("bob");

    plan +!main(list args) {
        system.createAgent("alice", "demo.Bidder");
        system.createAgent("bob", "demo.Bidder");
        system.sleep(200);
        !auction("lot1", painting("sunflowers"), configure(500));
        system.sleep(200);
        system.exit();
    }
}
package demo;

agent Bidder extends astra.protocol.FirstPriceAuction {
    initial !monitor_for_auctions();

    plan +!generate_bid(string id, funct description, int bid) {
        if (system.name() == "alice") bid = 30;
        else bid = 25;
    }
}
[main] Starting Auction of: lot1
[main] Waiting for bids
[main] received bid: 25 from: bob
[main] received bid: 30 from: alice
[main] Evaluating bids
[main] winner of: lot1 is: alice with bid: 30
[alice] I AM WINNER of: lot1 with bid: 30

The order in which the bids arrive may vary. The protocols can be tested using the unit testing library; the astra-protocols project includes a test for the FIPA Request protocol.