Dialogue Systems

DialogueServer.py - Audio and VoIP interface to Spoken SDS

Copyright CUED Dialogue Systems Group 2015 - 2017

This class implements an HTTP server, it receives HTTP Requests and generates HTTP Replies. The format of the messages is JSON. The server has an agent (i.e., a dialogue system or the set of dialogue system components), that can be copied, and can take multiple calls in this way it can correctly handle concurrent request already supported by the BaseHTTPServer

Basic Execution:
>>> python DialogueServer.py -c CONFIG [--nocolor]

Important Config variables [Default values]:

[dialogueserver]
dialhost = localhost 
dialport = 8082

Please change these configuration variables according to your machine settings. Note that these variables must agree with the configuration of your HTTP speech client If you want to run it locally use: localhost

Protocol description

Requests to the server

New call: notify the DialogueManager when a new call (or new session) has started:

newcall?sessionpar={"session": "SESSION_NAME"}

Next: ask the DialogueManager what to do next and provide the JSON RESULT from the ASR or the DTMF RESULT:

next?{ "session": "SESSION_NAME", "result" : "JSON_ASR_RESULT"}
next?{ "session": "SESSION_NAME", "result" :{"dtmf" :  "DTMF_RESULT" }"

Clean: clean session in the case of unexpected errors in the ASR CLIENT or forced hung-up in the VOICE CLIENT:

clean?{"session": "SESSION_NAME"}

Responses from the server

Question:

http reply {"bargein": "true", "replyType": "question",
            "text": "Hello, welcome to the Cambridge Multi-Domain dialogue system. How may I help you?"}

Prompt:

http reply {"bargein": "false", "replyType": "prompt",
            "text": "Thank you, Goodbye", "final":"true"}

Control:

http reply {"return_control": "true", "replyType": "control",
            "session_kept_alive":"true"}

Flags for the messages are:

"replyType" = "prompt"|"question""|"control"
"bargein"   = "true"|"false", is barge in supported in the ASR?
"final"     = "true"|"false", if this flag is true the Voice Client must hung up the call.
"dtmf"      = "true"|"false", is expecting dtmf result?
"dtmfsize"  =  dtmfsize (i.e., number of digits)
"text"      =  TEXT_TO_PROMPT
"return_control" = "true"|"false", indicates ood signal from client
"session_kept_alive" = "true"|"false", ood signal received but server keeping going for now

See also

CorneliaServer: https://bitbucket.org/lmr46/voiceserver.git VoiceBroker (The Class Server): https://bitbucket.org/dialoguesystems/voicebroker.git

import :json
import :BaseHTTPServer
import :json
import :Settings
import :ContexLogger


class DialogueServer.DialogueServer

This class implements an HTTP Server

ask_for_subjective(agent_id, currentPrompt)

nb - statefull

ask_for_task_id(agent_id, currentPrompt)

nb - statefull

cleaningCNet(data)

Prunes the Confusion Network

Warning

Not perfect: improve it according to c++ pruning for now it is removing the paths where the !NULL is the most probable …to be checked See HRec.cpp Method: TranscriptionFromConf Line 4075 (lmr46)

Parameters:data – json data
Returns:
cleaning_response(msg='', session_id=None, isbargein=None)

Note that msg still states: DIALOGUE_SERVER_ERROR - since session should only need to be cleaned if user hung up etc - in normal flow the session will be cleaned once the dialogue has ended.

control(return_control, session_id, kept_alive)

Create a control message, for the moment the arguments are

Parameters:
  • return_control – boolean indicating whether to return control or not
  • session_id – the session id
  • kept_alive – boolean indicating whether session is kept alive or not
Returns:

generate_token()

Produces the 4 digit token for verification of the call on camdial.

getNBest(nbest, key, words, like, retPaths)

Returns the N-Best list from CNet candidates

get_subjective_DTMF(agent_id, data, drange=None)

nb - statefull

get_task_by_id(task_id)

Gets a task by task_id. returns None if no such task_id exists

get_task_id_DTMF(agent_id, data)

Note the taskID * 3 = task Number (and it is the task number that is displayed on the landing page, and that will thus be entered here). Note - is statefull (ie increases TASK_RETRIEVAL_ATTEMPTS)

parse_additional_information(data)

The ASR client communicating with DialogueServer may also send some additional information. This is included under the “context” key of the JSON object it posts, and can be extended to included any extra information. For now it just contains the domain control should start with, since with DialPort for example they do their own topic tracking and hand control off to our system with the desire to access just a sub domain (eg SFRestaurants) and not start with our topicmanager.

Returns:dict – keys: ‘start_domain’ = initial domain hint from client; ‘return_control’ = True, return control to client; ‘session_kept_alive’ = True, client is requesting return of control but currently resisting.

Note

the format for this additional information, within the original JSON object being received is as follows:

>>> "context": {
>>>       "init_domain": [
>>>           { "value": "SFRestaurants", "confidence": 0.6},
>>>           { "value": "SFHotels", "confidence": 0.1}
>>>       ],
>>>       "entities": [
>>>           {"type": "LOC", "value": "pittsburgh"}
>>>       ]
>>>  },
>>>  "ood":"another_domain",
>>>  "sudoTerminal":"True"
where
  • “init_domain” is an N-best list of possible domains identified by the voicebroker
  • “entities” provides relevant context information such as the geo location “LOC”:
  • “ood” is used to indicate that the voicebroker thinks that the domain has changed. If “ood” is repeated more than OOD_THRESHOLD times, then control is returned if “ood” is null, then ood counter is reset.
  • “sudoTerminal” is true, then server returns control immediately.
postToCamdial(token, dialogueID, task)
prompt(prompt, session_id, isbargein=None, isfinal=False, isdtmf=False, dtmfsize=1)

Create a prompt, for the moment the arguments are

Parameters:
  • prompt – the text to be prompt
  • isbargein – if barge in is allowed
  • isfinal – if it is the final sentence before the end of dialogue
Returns:

reply in json

question(question, session_id, isbargein=None)

TTS prompt and expect a speech reply from user.

recognition_failed_response(msg='', session_id=None, isbargein=None)

Handles response to all errors that occur. Note msg is just a string - ie the errors are not formatted robustly as class objects or similar.

run()

Listen to request in host dialhost and port dialport

DialogueServer.make_request_handler_class(dialServer)

Simulate.py - semantic level user simulator system.

Copyright CUED Dialogue Systems Group 2015 - 2017

Basic Execution:
>>> python Simulate.py [-h] -C CONFIG [-n -r -l -t -g -s]

Optional arguments/flags [default values]:

-n Number of dialogs [1]
-r semantic error rate [0]
-s set random seed 
-g generate text prompts
-h help

Relevant Config variables [Default values]:

[simulate]
maxturns = 30 
continuewhensuccessful = False
forcenullpositive = False
confscorer = additive

See also

CUED Imports/Dependencies:

import utils.ContextLogger
import utils.Settings
import usersimulator.SimulatedUsersManager
import ontology.FlatOntology
import Agent


class Simulate.SimulationSystem(error_rate)

Semantic level simulated dialog system

run(session_id, agent_id='Smith', sim_level='dial_act')

Runs one episode through the simulator

Parameters:
  • session_id (int) – session id
  • agent_id (string) – agent id, default = ‘Smith’
Returns:

None

run_dialogs(numDialogs)

run a loop over the run() method for the given number of dialogues.

Parameters:numDialogs (int) – number of dialogues to loop over.
Returns:None

Texthub.py - text level dialog system.

Copyright CUED Dialogue Systems Group 2015 - 2017

Basic Execution:
>>> python texthub.py [-h] -C CONFIG [-l -r]

Optional arguments/flags [default values]:

-r semantic error rate [0]
-l set the system to use the given policy file
-h help

Relevant config variables (values are defaults):

[semi_DOMAIN]
semitype = PassthroughSemI

[semo_DOMAIN]
semotype = PassthroughSemO

See also

CUED Imports/Dependencies:

import utils.ContextLogger
import utils.Settings
import Agent.DialogueAgent
import ontology.Ontology


class Texthub.ConsoleHub

text based dialog system

run()

Runs one episode through Hub

Returns:None