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.