Skip to content

Commit c79619e

Browse files
committed
Add support for Chat/Conversations
1 parent d260b9f commit c79619e

File tree

6 files changed

+152
-65
lines changed

6 files changed

+152
-65
lines changed

server/routes/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ router.post('/rasa/model/parse', rasa_router.modelParseRequest);
136136
router.post('/rasa/conversations/messages', rasa_router.conversationParseRequest);
137137
router.post('/rasa/restart', rasa_router.restartRasaCoreConversation);
138138
router.get('/rasa/story', rasa_router.getConversationStory);
139-
139+
router.post('/rasa/conversations/execute', rasa_router.runActionInConversation);
140140

141141

142142
//authentication js

server/routes/rasa_router.js

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ module.exports = {
1717
loadRasaModel: loadRasaModel,
1818
conversationParseRequest: conversationParseRequest,
1919
restartRasaCoreConversation: restartRasaCoreConversation,
20-
getConversationStory: getConversationStory
20+
getConversationStory: getConversationStory,
21+
runActionInConversation: runActionInConversation
2122
};
2223

2324
/* -------------------------------- Util Functions ----------------------------------------------------------------------------------------------------- */
@@ -207,25 +208,16 @@ function modelParseRequest(req, res, next) {
207208
function getConversationStory(req, res, next) {
208209
try {
209210
logger.winston.info("Routing to Model Rasa Story Request -> " + global.rasa_endpoint + "/conversations/" + req.query.conversation_id + "/story");
210-
request({ method: 'GET', uri: global.rasa_endpoint + "/conversations/" + req.query.conversation_id + "/story" },
211-
function (err, response, body) {
211+
request({ method: 'GET', uri: global.rasa_endpoint + "/conversations/" + req.query.conversation_id + "/story" }, function (err, response, body) {
212212
try {
213213
logger.winston.verbose('Rasa Response: ' + body.substring(1, 200) + ' ... ');
214214
logs.logRequest(req, 'parse',
215215
{
216216
server_response: body,
217217
query: req.body.q
218218
});
219-
//Update conversation table with updated conversation response from rasa ...
220-
//TODO: Add story?
221-
db.run('update conversations set story = ? where conversation_id = ?', [body, req.query.conversation_id], function(err) {
222-
if (err) {
223-
logger.winston.info("Error updating the record");
224-
} else {
225-
//http_code, res, body, headers, type
226-
sendOutput(200, res, body, { 'Content-Type': 'plain/text' }, '');
227-
}
228-
});
219+
updateStory(req.query.conversation_id, body);
220+
sendOutput(200, res, body, { 'Content-Type': 'plain/text' }, '');
229221
} catch (err) {
230222
logger.winston.error(err);
231223
sendOutput(500, res, '{"error" : ' + err + "}");
@@ -236,8 +228,27 @@ function getConversationStory(req, res, next) {
236228
}
237229
}
238230

231+
function updateStory(conversation_id, story) {
232+
db.run('update conversations set story = ? where conversation_id = ?', [story, conversation_id], function (err) {
233+
if (err) {
234+
logger.winston.info("Error updating the record");
235+
} else {
236+
logger.winston.info("Updated story");
237+
}
238+
});
239+
}
239240

240241

242+
function updateConversation(conversation_id, conversation) {
243+
//Update the DB with the latest results
244+
db.run('update conversations set conversation = ? where conversation_id = ?', [conversation, conversation_id], function (err) {
245+
if (err) {
246+
logger.winston.error("Error updating the record");
247+
} else {
248+
logger.winston.info("Updated conversation");
249+
}
250+
});
251+
}
241252

242253
function conversationParseRequest(req, res, next) {
243254
try {
@@ -251,20 +262,11 @@ function conversationParseRequest(req, res, next) {
251262
server_response: body,
252263
query: req.body.q
253264
});
254-
//Maybe we should run this before the DB update and save both to the DB at the same time and then return both responses to the client
255-
request({ method: 'POST', uri: global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/predict", body: JSON.stringify(req.body) },
256-
function (err, response, predict_body) {
257-
//console.log(body);
258-
//Update conversation table with updated conversation response from rasa ...
259-
db.run('update conversations set conversation = ? where conversation_id = ?', [predict_body, req.body.conversation_id], function(err) {
260-
if (err) {
261-
logger.winston.error("Error updating the record");
262-
} else {
263-
264-
sendOutput(200, res, predict_body);
265-
}
266-
});
267-
});
265+
266+
request({ method: 'POST', uri: global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/predict", body: JSON.stringify(req.body) }, function (err, response, predict_body) {
267+
updateConversation(req.body.conversation_id, predict_body);
268+
sendOutput(200, res, predict_body);
269+
});
268270
} catch (err) {
269271
logger.winston.error(err);
270272
sendOutput(500, res, '{"error" : ' + err + "}");
@@ -275,31 +277,40 @@ function conversationParseRequest(req, res, next) {
275277
}
276278
}
277279

280+
function runActionInConversation(req, res, next) {
281+
logger.winston.info("Rasa Core Run Action Request -> " + global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/execute");
282+
try {
283+
request({ method: "POST", uri: global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/execute", body: JSON.stringify(req.body.action) }, function (err, response, execute_body) {
284+
if (err) {
285+
logger.winston.error(err);
286+
sendOutput(500, res, '{"error" : "Exception caught !!"}');
287+
return;
288+
}
289+
logger.winston.verbose("Run Action Response" + JSON.stringify(execute_body));
290+
updateConversation(req.body.conversation_id, execute_body);
291+
sendOutput(200, res, execute_body);
292+
});
293+
} catch (err) {
294+
logger.winston.error(err);
295+
sendOutput(500, res, '{"error" : "Exception caught !!"}');
296+
return;
297+
}
298+
}
299+
278300

279301
function restartRasaCoreConversation(req, res, next) {
280302
logger.winston.info("Rasa Core Restart Request -> " + global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/tracker/events");
281303
try {
282304
var body = JSON.stringify({ "event": "restart" });
283-
request({
284-
method: "POST",
285-
uri: global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/tracker/events",
286-
body: body
287-
}, function (err, response, body) {
305+
request({ method: "POST", uri: global.rasa_endpoint + "/conversations/" + req.body.conversation_id + "/tracker/events", body: body }, function (err, response, body) {
288306
if (err) {
289307
logger.winston.error(err);
290308
sendOutput(500, res, '{"error" : "Exception caught !!"}');
291309
return;
292310
}
293311
logger.winston.verbose("Restart Response" + JSON.stringify(body));
294-
//Update conversation table with updated conversation response from rasa ...
295-
db.run('update conversations set conversation = ?, story = ? where conversation_id = ?', [body, '', req.body.conversation_id], function(err) {
296-
if (err) {
297-
logger.winston.error("Error updating the record");
298-
} else {
299-
//Predict the next action?
300-
sendOutput(200, res, body);
301-
}
302-
});
312+
updateConversation(req.body.conversation_id, body);
313+
sendOutput(200, res, body);
303314
});
304315
} catch (err) {
305316
logger.winston.error(err);

web/src/app/components/chat/chat.html

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,45 @@
7171
<div class="col-sm-12 wrapper" id="container">
7272
<div id="chat">
7373
<div class="msg_history" id="message_history">
74-
<div ng-repeat="transaction in transactions" ng-if="transaction.text" ng-click="loadConversationDetail(transaction)">
75-
<div ng-class=" transaction.source == 'server' ? 'incoming_msg' : 'outgoing_msg' ">
76-
<div ng-class=" transaction.source == 'server' ? 'received_msg' : 'sent_msg' ">
77-
<div ng-class=" transaction.source == 'server' ? 'received_withd_msg' : '' ">
74+
<div ng-repeat="transaction in transactions" ng-click="loadConversationDetail(transaction)">
75+
76+
<!-- Sent Message -->
77+
<div ng-if="transaction.event == 'user'" class="outgoing_msg">
78+
<div class="sent_msg">
79+
<div class="">
7880
<p>{{ transaction.text }}</p>
7981
</div>
80-
<div ng-class=" transaction.source == 'server' ? 'received_withd_msg' : '' ">
81-
<span class="time_date" ng-class=" transaction.source != 'server' ? 'sent' : '' ">
82-
{{ transaction.timestamp * 1000 | date: 'MM/dd/yyyy h:mm:ss a' }}</span>
82+
<div class="">
83+
<span class="time_date sent">{{ transaction.parse_data.intent.name }}</span>
84+
</div>
85+
<div class="">
86+
<span class="time_date sent">{{ transaction.timestamp * 1000 | chatDate }}</span>
87+
</div>
88+
</div>
89+
</div>
90+
91+
<!-- Received Message -->
92+
<div ng-if="transaction.event == 'bot'" class="incoming_msg">
93+
<div class="received_msg">
94+
<div class="received_withd_msg">
95+
<p>{{ transaction.text }}</p>
96+
</div>
97+
<div class="received_withd_msg">
98+
<span class="time_date">
99+
{{ transaction.timestamp * 1000 | chatDate }}</span>
100+
</div>
101+
</div>
102+
</div>
103+
104+
<!-- Action -->
105+
<div class="action_msg">
106+
<div>
107+
<div>
108+
<p>{{ transaction.name }}</p>
83109
</div>
84110
</div>
85111
</div>
112+
86113
</div>
87114
</div>
88115
</div>
@@ -95,7 +122,7 @@
95122
<div class="input-group">
96123
<input class="form-control" ng-model="test_text" placeholder="Type a message">
97124
<span class="input-group-append">
98-
<button class="btn btn-primary" id="msg_send_btn" type="submit" ng-class=" selected_conversation.conversation_id ? '' : 'disabled' "><i class="icon-paper-plane" aria-hidden="true"></i></button>
125+
<button class="btn btn-primary" id="msg_send_btn" type="submit" ng-disabled=" selected_message.event != 'user'"><i class="icon-paper-plane" aria-hidden="true"></i></button>
99126
</span>
100127
</div>
101128
</div>
@@ -111,25 +138,32 @@
111138
<div class="col-sm-3">
112139
<tabset class="tab-container" id="tabs">
113140
<ul class="nav nav-tabs">
114-
<li class="nav-item active"><a class="nav-link active" data-target="#story" data-toggle="tab"> Story</a>
115-
</li>
141+
<li class="nav-item active"><a class="nav-link active" data-target="#story" data-toggle="tab"> Story</a></li>
116142
<li class="nav-item"><a class="nav-link" data-target="#message" data-toggle="tab">Message</a></li>
143+
<li class="nav-item"><a class="nav-link" data-target="#conversation" data-toggle="tab">Conversation</a></li>
117144
</ul>
118145
<div class="tab-content">
119146
<tab class="tab-pane active" id="story">
120147
<textarea class="datainput form-control" ng-model="selected_conversation.story">{{ selected_conversation.story }}</textarea>
121148
</tab>
122149
<tab class="tab-pane" id="message">
123-
<json-formatter json="selected_message" open="3"></json-formatter>
124-
</tab>
125-
<tab class="tab-pane" id="nlu_data">
126-
<textarea class="datainput" ng-model="raw_data.nlu" ng-change="stringifyData()">{{ raw_data.nlu }}</textarea>
127-
</tab>
128-
<tab class="tab-pane" id="stories">
129-
<textarea class="datainput" ng-model="raw_data.stories" ng-change="stringifyData()">{{ raw_data.stories }}</textarea>
150+
<div class="row">
151+
<div class="col-sm-12">
152+
<div class="form-group">
153+
<button type="button" class="btn btn-info active float-right" ng-disabled=" selected_message.event != 'user'" ng-click="resendMessage()"><i class="icon-plus"></i>&nbsp;Resend</button><br />&nbsp;
154+
</div>
155+
</div>
156+
</div>
157+
<div class="row">
158+
<div class="col-sm-12">
159+
<json-formatter json="selected_message" open="3"></json-formatter>
160+
</div>
161+
</div>
130162
</tab>
131-
<tab class="tab-pane" id="domain">
132-
<textarea class="datainput" ng-model="raw_data.domain" ng-change="stringifyData()">{{ raw_data.domain }}</textarea>
163+
<tab class="tab-pane" id="conversation">
164+
<div class="col-sm-12">
165+
<json-formatter json="selected_conversation" open="3"></json-formatter>
166+
</div>
133167
</tab>
134168
</div>
135169
</tabset>

web/src/app/components/chat/chat.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ function ChatController($scope, $rootScope, $interval, $http, Rasa_Version, Sett
3030
});
3131
}
3232

33+
$scope.resendMessage = function() {
34+
$scope.test_text = $scope.selected_message.text;
35+
$scope.executeCoreRequest();
36+
}
37+
3338
$scope.addBotConversation = function () {
3439
this.formData.bot_id = $scope.selectedBot.bot_id;
3540
Conversations.save(this.formData).$promise.then(function () {
@@ -50,7 +55,7 @@ function ChatController($scope, $rootScope, $interval, $http, Rasa_Version, Sett
5055
$scope.selected_conversation = selected_conversation;
5156
if (selected_conversation.conversation) {
5257
var conversation = JSON.parse(selected_conversation.conversation);
53-
if (conversation && conversation.tracker.events) {
58+
if (conversation && conversation.tracker && conversation.tracker.events) {
5459
$scope.transactions = conversation.tracker.events;
5560
}
5661
$scope.loadConversationStory(selected_conversation.conversation_id);
@@ -86,8 +91,9 @@ function ChatController($scope, $rootScope, $interval, $http, Rasa_Version, Sett
8691
$('.write_msg').focus();
8792
$http.post(appConfig.api_endpoint_v2 + '/rasa/conversations/messages', JSON.stringify(reqMessage)).then(function (response) {
8893
if (response.data && response.data.tracker) {
89-
$scope.selected_conversation.conversation = JSON.stringify(response.data);
94+
$scope.selected_conversation.conversation = response.data;
9095
$scope.transactions = response.data.tracker.events;
96+
checkForActions(response.data);
9197
$scope.loadConversationStory($scope.selected_conversation.conversation_id);
9298
scrollToMessage();
9399
}
@@ -99,6 +105,24 @@ function ChatController($scope, $rootScope, $interval, $http, Rasa_Version, Sett
99105
}
100106
};
101107

108+
function checkForActions(messages_response) {
109+
if (messages_response.confidence && messages_response.confidence >= 1) {
110+
var body = {'conversation_id': $scope.selected_conversation.conversation_id, action : {'name': messages_response.scores[0].action }};
111+
$http.post(appConfig.api_endpoint_v2 + '/rasa/conversations/execute', JSON.stringify(body)).then(function (response) {
112+
if (response.data && response.data.tracker) {
113+
$scope.selected_conversation.conversation = response.data;
114+
$scope.transactions = response.data.tracker.events;
115+
$scope.loadConversationStory($scope.selected_conversation.conversation_id);
116+
scrollToMessage();
117+
}
118+
},
119+
function (errorResponse) {
120+
//
121+
}
122+
);
123+
}
124+
}
125+
102126
function clearScreen() {
103127
$scope.transactions = [];
104128
$scope.selected_conversation = {};

web/src/app/directives.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,18 @@ angular.module('app')
3838
return $sce.trustAsHtml(ss)
3939
};
4040
}
41-
);
41+
).filter('chatDate', function($filter) {
42+
var angularDateFilter = $filter('date');
43+
return function(theDate) {
44+
const today = new Date();
45+
const filterDate = new Date(theDate);
46+
if (filterDate.setHours(0,0,0,0) == today.setHours(0,0,0,0)) {
47+
return angularDateFilter(theDate, 'HH:mm:ss');
48+
} else {
49+
return angularDateFilter(theDate, 'MM/dd/yyyy h:mm:ss a');
50+
}
51+
}
52+
});;
4253

4354
function confirmClickDirective() {
4455
let i = 0;

web/src/assets/css/style.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.list-group-item.active {
2-
background-color: #CCC;
2+
background-color: #EEE;
33
border-color: #20a8d8;
4+
color: #151b1e
45
}
56

67
.app-header.navbar .navbar-brand {
@@ -157,6 +158,7 @@ tags-input .tags .tag-item .remove-button {
157158
}
158159

159160
.time_date {
161+
text-align: left;
160162
color: #747474;
161163
display: block;
162164
font-size: 12px;
@@ -247,4 +249,9 @@ tags-input .tags .tag-item .remove-button {
247249
.wrapper {
248250
max-height: 800px;
249251
overflow-y: scroll;
252+
}
253+
254+
.action_msg {
255+
text-align: center;
256+
color: lightgray;
250257
}

0 commit comments

Comments
 (0)