[Note: The following discussion is an introduction to conversation support in ABLE, centered around the basic conversational agent class. Further information, including a detailed overview of the conversation support architecture, developer documentation, and additional examples, will soon be available for preview at the Conversation Support Website .]
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 JSR 87 implementation of the Java Agent Servces (JAS).
Correlated sequences of messages, which share a common context, are “conversations”,
and the AbleJasConversationAgent provides “conversation support”. or an architecture
and runtime engine for carrying out the conversations. There are two aspects
to conversation support provided by the AbleJasConversationAgent:
(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 exachanged prior to that point. AbleJasConversationAgent 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 and the 'MetaConversation' policy. Refer to the AutoConversationSetup bean for more information on those policies and their semantics. The use of such a conversation policy would enable 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 AbleJasConversationAgent 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 AbleJasConversationAgent
should configure itself to execute.
For example, in the serialized example agent (agent1.ser) provided with the
distribution, the agent has been customized (see figure below) to use the
setup_cp.xml
as the default conversation policy and
examples/datafiles
directory as the repository to look for conversation policies.
(ii) The second step would be to setup decision logic
connections to drive the conversation. When the AbleJasConversationAgent reaches
a decision point during a conversation, it makes an Able User Defined function
call though the DeccisionLogicAdapter 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.
The decision logic connections at the moment are implemented on a per-policy basis. One could easily imagine an implementation where decision logic connections are based on a per-state basis. So, to connect the conversationa agent with decision logic beans, one would use the agent itself as a container for the decion logic beans and then customize the agent (using the 'Decision' tab) to identify the correct functions. For example, in the serialized example agent (agent1.ser) provided with the distribution, the agent has been customized (see figure below) to use the 'buyerLogic' function of the AmabBuyerLogic bean to make decisions for an AMAB conversation, the 'defaultDecision' function of the DefaultDecisionMaker bean to mahe decisions for the Chat conversation.
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, AbleJasConversationAgent's 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 AbleJasConversationAgent that uses JAS for messaging, and contains a ConversationManager managing a single conversation. In effect, the AbleJasConversationAgent 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.
MessageForms
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.
Inspecting the AbleJasConversationAgent
The AbleJasConversationAgent is equipped with custom inspectors for examining the conversations and watching them as they proceed. One can view the custom inspector by opening the inspector for the agent and selecting View...Conversation Graphic. The inspector provides a tree view of conversation and subsequent child conversations and a graph view of the actual conversation. The current state in a conversation is shaded blue while terminal states are shaded white. One can view the progress in a conversation in the form of changes in the current state by keeping the inspectors open during a conversation. The figue below shows a 'Conversation Graphic' view of the serialized conversation example (agent1.ser) provided with the distribution.
Layouts for Conversation Policies
To achieve more visually pleasing layouts for the conversation policy graph displays, the AbleJasConversationAgent can save and re-load the layouts of the displayed graphs. One can change the layouts of the graphs by clicking on the states and moving them around. The actual co-ordinates and the frame-size for a conversation policy layout are stored in a simple text file with a glf(Graph Layout Format) extension. For example, the ConversationSetup policy show in the figure above has been laid out using setup_cp.glf . The file stores the display co-ordinates for each state in the conversation policy and the frame size to display them in.