AblePlatformConversationAgent

This class defines a simple conversational agent that can execute conversations as specified by a Conversation Policy (CP) encoded in a form of XML called CP-XML. The underlying tranport mechanism used for exchanging messages during the conversation is provided by the ABLE Platform, which uses the JSR 87 implementation of the Java Agent Servces (JAS).

Correlated sequences of messages, which share a common context, are “conversations”, and the AblePlatformConversationAgent provides “conversation support”. or an architecture and runtime engine for carrying out the conversations. There are two aspects to conversation support provided by the AblePlatformConversationAgent:
    (i) establishing and maintaining a  conversational session; and
    (ii) using common conversational protocols.

Conversational protocols, also called “conversation policies”, are named specifications of message format and sequencing constraints. Conversation policies specify what may be said, by whom, in what order. They are stateful, which means that the set of “legal” messages at any given point in the conversation may depend on the messages that have been exchanged prior to that point.  AblePlatformConversationAgent provides a general-purpose runtime conversation policy execution engine, which can be configured to carry out any conversation policy. Once configured, it enforces the protocol defined by the conversation policy.

The establishing a conversational session is an instance of using a conversation protocol. One such conversation protocol that can be used for establishing conversations is the 'ConversationSetup' policy. The use of such a conversation policy enables the initial hand-shaking process of agreeing as to which conversation to engage in and what roles to assume. Once the agent has the capablity for agreeing to take part in a particular conversation with a specific role, executing the actual conversation is just another instance of exeuting a conversation policy that is driven by the appropriate decision logic.

Customizing an AblePlatformConversationAgent to execute arbitrary conversations is a two step process
(i) The first step is to specify the defaullt conversation policy or the policy to be used for setting up conversations and agreeing about roles during the conversation. This also involves specifying a repository or a directory to locate other conversation policy files that the AblePlatformConversationAgent should configure itself to execute.
(ii) The second step would be to setup decision logic connections to drive the conversation. When the AblePlatformConversationAgent reaches a decision point during a conversation, it makes an Able User Defined function call though the DecisionLogicAdapter to the decision logic bean. What this transalates to is that, the deicion logic code should be encapsulated as an AbleBean object that can be accessed though a particular kind of function. The restrictions on the implementation of such a function are as follows
        -    It should be a three parameter function withe the three paramters being (in that order)
                    *     the conversation identifier (a String)
                    *     the decicion point (state name) at which a deicision is to be made (a String)
                    *     an object array representing the data used in making a decision (an Object array)
        -    The return type should be two-element object array, with the first element of the array representing the decision made and the second parameter itself an object array that is to be used to construct the message form for an outgoing message.

When a TransportMessage is received, the agent routes the message to the appropriate conversation using the conversation-id present in the envelope. Messages that arrive without conversation-ids are assumed to be requests for new conversations and are handled by the "default" conversation manager. Subsequently, a new default conversation manager is created to handle other incoming conversation requests.

At the top level, AblePlatformConversationAgent conversation support architecture consists of  a ConvesationPolicyHandler (CPH) and a ConversationManager (CM). The CPH executes the conversation policy, as we describe below. The CM takes care of configuring the CPH and of connecting the CPH with the agent itself. The figure below shows the architecture of the AblePlatformConversationAgent that uses JAS for messaging, and contains a ConversationManager managing a single conversation. In effect, the AblePlatformConversationAgent handles multiple simultaneous conversations using one conversation managers per conversation.


The numbers in the figure correspond to the following activities:

1. Incoming TransportMessage is received
2. Agent sends it to the ConversationManager (e.g. via direct method invocation).
3. ConversationManager extracts and validates message Envelope (e.g., validates conversation ID), passes message Payload to CPH
4. CPH processes message, updates states, and informs ConversationManager that a decision point has been reached
5. Conversation Manager sends a decision request to the Business Logic through the Decision Logic Adapter
6. Business Logic makes a decision the request and the Decision Logic Adapter informs Conversation Manager of decision
7. Conversation Manager notifies CPH of decision
8. CPH updates and passes outbound message to Conversation Manager
9. Conversation Manager notifies JAS Agent of outbound message
10. JAS Agent sends message to other end of conversation

Steps 1-5 correspond to receiving an inbound message and issuing a decision request. Steps 6-10 correspond to making a decision and sending an outbound message to the other party. These are two separate steps in the conversation, which in general consists of any number of such steps.

ConversationManager

The ConversationManager mediates between the ConversationPolicyHandler and the agent’s messaging and decision-logic code.

ConversationPolicyHandler

The ConversationPolicyHandler processes ConversationEvents much a state-machine-with-outputs processes symbols. The crucial method is

 ConversationPolicyHandler.process(inputEvent, outputEventQueue);

This method processes the inputEvent, attempting to match the event’s properties and parameters with a legal transition from the state-machine’s current state. If it does find a match, it takes the transition, i.e., it updates its state and generates output events, which it appends to the outputEventQueue. In general, a single input event may generate 0, 1, or more than one output event.

ConversationEvents come in several subtypes, defined by the data they carry. Current event types are:
· MessageEvent
· DecisionEvent
· CPDoneEvent
· ProtocolErrorEvent
· LoadCPEvent
· TimerEvent

Reasonable input events include:
· MessageEvents for messages received
· DecisionEvents for decisions made
· CPDoneEvents from child-CPs
· TimerEvents when a previously-set timer expires.

Reasonable output events include:
· MessageEvents for messages to be sent
· DecisionEvents for decision-requests to be resolved
· CPDoneEvents when the CP enters a terminal state
· ProcolErrorEvents when an input violates the CP
· LoadCPEvents when it’s time to load a child-CP
· TimerEvents for requests to set a timer.

A typical sequence of operations inside the CPH would be:
1. Receive a MessageEvent input, indicating a new message has been received
2. Classify the message to identify which of the possible allowed messages it might be (or if it is not allowed).
3. Based on the classification (suppose it’s allowed), select a transition and change state according to that transition.
4. As part of taking the transition, generate outputs. This will sometimes be a DecisionEvent requesting what to do next, containing the name of the decision-point to be resolved, and data translated from the message, to be used as inputs to the decision logic.
5. If the new state is a terminal state, fire a CPDoneEvent.

MessageTransforms

One of the responsibilities of the conversation-management system is decoupling the messages send & received, and the data types used by the decision logic to do its processing. This is reflected by the way the CPH works: in processing an inbound MessageEvent, containing a message object, it will typically generate a DecisionEvent containing data objects to be used as inputs to the decision-logic.

One way to do the conversation is to use a MessageForm. MessageForms convert between the TransportMessage objects used by the messaging subsystem, and the various other data representations used at various points in the decision logic. Quite frequently, classifying a message amounts to parsing it. For this reason, we choose to put the MessageForm into the CPH itself. This is not clean, but it is efficient.