Baseline Agent v1

In this section, we describe the baseline agent v1 BaselineAgent. This agent inherits from ParticipantAgent and implements the BaselineStrategy. ParticipantAgent is a TAC specific implementation of a generic Agent of the aea package.

Main Loop and Event Loop

A generic Agent of the aea package can be started via start(). This starts the MailBox and a main loop implemented in _run_main_loop().

The mailbox is responsible for handling incoming and outgoing messages. The InBox enqueues incoming messages on an in_queue for later processing, the OutBox picks messages from the out_queue and sends them to the OEF.

Before the execution of the main loop, the framework will call the user’s implementation of the setup() method, to let the initialization of the resources needed to the agent. Upon exit, the framework will call the user’s implementation of the teardown() method, to let the release of the initialized resources.

At any moment, the execution state of the agent can be inspected by reading the agent_state() property.

The main loop deals with processing enqueued events/messages. It has the methods act() and react() which handle the active and reactive agent behaviours.

Actions and Reactions

The participant architecture distinguishes between actions and reactions. Actions are scheduled behaviours by the agent whereas reactions are behaviours which the agent makes in response to individual messages it receives.

We split both actions and reactions into three domains: ControllerActions and ControllerReactions, OEFActions and OEFReactions and DialogueActions and DialogueReactions. Dialogues are agent to agent communications and maintained in Dialogues.

Actions

The ControllerActions class includes the methods:

The OEFActions class includes the methods:

The ParticipantAgent does not implement any methods in DialogueActions. This is because all dialogue related methods are reactions to events. In particular, the search for services (search_services()) initiates a chain of reactions leading to a dialogue.

Reactions

The ControllerReactions class includes the methods:

  • on_start() which handles the ‘start’ event emitted by the controller;

  • on_transaction_confirmed() which handles the ‘on transaction confirmed’ event emitted by the controller;

  • on_state_update() which handles the ‘on state update’ event emitted by the controller;

  • on_cancelled() which handles the cancellation of the competition from the TAC controller;

  • on_tac_error() which handles the ‘on tac error’ event emitted by the controller;

  • on_dialogue_error() which handles the ‘dialogue error’ event emitted by the controller.

The OEFReactions class includes the methods:

The DialogueReactions class includes the methods:

The message level handling of a negotiation dialogue is performed in FIPABehaviour.

Handlers

The three types of handlers ControllerHandler, OEFHandler and DialogueHandler inherit from the actions and reactions of their specific type. They are resonsible for handling the implemented behaviours.

Strategy

The strategy of a ParticipantAgent has to implement is defined via an interface Strategy. We also provide a sample implementation of a strategy called BaselineStrategy and utilised by the BaselineAgent.

The advanced.py template can be used to build a BaselineAgent with a custom strategy.

We have implemented a basic model of a WorldState which can be used and extended to enrich an agents strategy.

Agent State and World State

The ParticipantAgent keeps track of its state via AgentState and it can keep track of its environment via WorldState.

Controller Registration

The ParticipantAgent initiates the registration with the controller via search_for_tac().

Services (/Goods) Registration

Once the game has started, the ParticipantAgent can register on the OEF’s Service Directory either as a seller, as a buyer or both. To be specific, the agent can either register the goods it is willing to sell, the goods it is willing to buy or both. The registration options are available in RegisterAs. The registration and unregistering of services is handled via the OEF action update_services().

Negotiation

The ParticipantAgent implements the FIPA negotiation protocol in FIPABehaviour. A FIPA negotiation starts with a call for proposal (CFP) which contains a Query referencing the services which are demanded or supplied by the sending agent. The receiving agent then responds, if it implements the FIPA negotiation protocol, with a suitable proposal (Propose) which contains a list of Description objects (think individual proposals). The first agent responds to the proposal with either a Decline or an Accept. Assuming the agent accepts, it will also send the TACMessage of type TRANSACTION to the ControllerAgent. Finally, the second agent can close the negotiation by responding with a matching Accept and a submission of the TACMessage of type TRANSACTION to the ControllerAgent. The controller only settles a transaction if it receives matching transactions from each one of the two trading parties referenced in the transaction.

sequenceDiagram participant Agent_0 participant Agent_1 participant Agent_2 participant Controller participant OEF activate Controller Agent_1->>Agent_2: send_cfp(msg_id: 1, dialogue_id: 1, destination: agent_2_pbk, target: 0, query=Query) Agent_2->>Agent_1: send_propose(msg_id: 2, dialogue_id: 1, destination: agent_1_pbk, target: 1, proposals=List[Description]) Agent_1->>Agent_2: send_accept(msg_id: 3, dialogue_id: 1, destination: agent_2_pbk, target: 2) Agent_1->>Controller: send_message(msg_id: 3, dialogue_id: 1, destination: controller_pbk, msg: Transaction) Agent_2->>Agent_1: send_accept(msg_id: 4, dialogue_id: 1, destination: agent_1_pbk, target: 3) Agent_2->>Controller: send_message(msg_id: 4, dialogue_id: 1, destination: controller_pbk, msg: Transaction) deactivate Controller

A successful FIPA negotiation between two agents.

Trade can break down at various stages in the negotiation due to the Strategy employed by the agents:

sequenceDiagram participant Agent_0 participant Agent_1 participant Agent_2 participant Controller participant OEF activate Controller Agent_1->>Agent_2: send_cfp(msg_id: 1, dialogue_id: 1, destination: agent_2_pbk, target: 0, query=Query) Agent_2->>Agent_1: send_propose(msg_id: 2, dialogue_id: 1, destination: agent_1_pbk, target: 1, proposals=List[Description]) Agent_1->>Agent_2: send_accept(msg_id: 3, dialogue_id: 1, destination: agent_2_pbk, target: 2) Agent_2->>Agent_1: send_decline(msg_id: 4, dialogue_id: 1, destination: agent_1_pbk, target: 3) deactivate Controller

An unsuccessful FIPA negotiation between two agents breaking down after initial accept.

sequenceDiagram participant Agent_0 participant Agent_1 participant Agent_2 participant Controller participant OEF activate Controller Agent_1->>Agent_2: send_cfp(msg_id: 1, dialogue_id: 1, destination: agent_2_pbk, target: 0, query=Query) Agent_2->>Agent_1: send_propose(msg_id: 2, dialogue_id: 1, destination: agent_1_pbk, target: 1, proposals=List[Description]) Agent_1->>Agent_2: send_decline(msg_id: 3, dialogue_id: 1, destination: agent_2_pbk, target: 2) deactivate Controller

An unsuccessful FIPA negotiation between two agents breaking down after proposal.

sequenceDiagram participant Agent_0 participant Agent_1 participant Agent_2 participant Controller participant OEF activate Controller Agent_1->>Agent_2: send_cfp(msg_id: 1, dialogue_id: 1, destination: agent_2_pbk, target: 0, query=Query) Agent_2->>Agent_1: send_decline(msg_id: 2, dialogue_id: 1, destination: agent_1_pbk, target: 1) deactivate Controller

An unsuccessful FIPA negotiation between two agents breaking down after cfp.

Agent Speed

There are two parameters of the ParticipantAgent which affect the agent speed directly. First, the agent_timeout parameter specifies the duration in (fractions of) seconds for which the ParticipantAgent times out between act() and react(). Lowering this parameter increases the speed at which the agent loop spins. Second, the services_interval parameter specifies the length of the interval at which the agent updates its services on the OEF and searches for services on the OEF. Lowering this parameter leads to more frequent updates and searches and therefore higher number of negotiations initiated by the agent.

There is a further parameter of the ParticipantAgent which affects the agent speed indirectly: the max_reactions parameter sets an upper bound on the number of messages which are processed by the ParticipantAgent during each call to react(). Lowering this number slows down the reactive behaviour of the agent relative to the active behaviour of the agent.