Skip to content

Commit 38990c3

Browse files
committed
added multiple speech responses
1 parent d3d7527 commit 38990c3

File tree

7 files changed

+107
-20
lines changed

7 files changed

+107
-20
lines changed

Diff for: app/endpoint/controllers.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ def call_api(url, type, parameters, is_json=False):
6969
return result
7070

7171

72+
def split_sentence(sentence):
73+
return sentence.split("###")
7274

7375

7476
from app.nlu.intent_classifer import IntentClassifier
@@ -132,7 +134,7 @@ def api():
132134
template = Template(
133135
intent.speechResponse,
134136
undefined=SilentUndefined)
135-
result_json["speechResponse"] = template.render(**context)
137+
result_json["speechResponse"] = split_sentence(template.render(**context))
136138

137139
logger.info(request_json.get("input"), extra=result_json)
138140
return build_response.build_json(result_json)
@@ -182,7 +184,7 @@ def api():
182184
result_json["complete"] = False
183185
current_node = missing_parameters[0]
184186
result_json["currentNode"] = current_node["name"]
185-
result_json["speechResponse"] = current_node["prompt"]
187+
result_json["speechResponse"] = split_sentence(current_node["prompt"])
186188
else:
187189
result_json["complete"] = True
188190
context["parameters"] = extracted_parameters
@@ -210,7 +212,7 @@ def api():
210212
current_node = [
211213
node for node in intent.parameters if missing_parameter in node.name][0]
212214
result_json["currentNode"] = current_node.name
213-
result_json["speechResponse"] = current_node.prompt
215+
result_json["speechResponse"] = split_sentence(current_node.prompt)
214216
else:
215217
result_json["currentNode"] = None
216218
result_json["missingParameters"] = []
@@ -244,12 +246,12 @@ def api():
244246
context["result"] = result
245247
template = Template(
246248
intent.speechResponse, undefined=SilentUndefined)
247-
result_json["speechResponse"] = template.render(**context)
249+
result_json["speechResponse"] = split_sentence(template.render(**context))
248250
else:
249251
context["result"] = {}
250252
template = Template(intent.speechResponse,
251253
undefined=SilentUndefined)
252-
result_json["speechResponse"] = template.render(**context)
254+
result_json["speechResponse"] = split_sentence(template.render(**context))
253255
logger.info(request_json.get("input"), extra=result_json)
254256
return build_response.build_json(result_json)
255257
else:

Diff for: app/nlu/intent_classifer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def build(X, y=None):
4444

4545
from sklearn.model_selection import GridSearchCV
4646

47-
Cs = [1, 2, 5, 10, 20, 100]
47+
Cs = [0.01,0.25,1, 2, 5, 10, 20, 100]
4848
param_grid = {'clf__C': Cs, 'clf__kernel': ["linear"]}
4949
grid_search = GridSearchCV(model,
5050
param_grid=param_grid,

Diff for: examples/default_intents.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"name": "Default Fallback intent", "userDefined": false, "apiTrigger": false, "intentId": "fallback", "_id": {"$oid": "59aae7bd26f6f60007b06fb3"}, "speechResponse": "Sorry. I'm having trouble understanding you."}, {"name": "cancel", "trainingData": [{"text": "i want to cancel", "entities": []}, {"text": "cancel that", "entities": []}, {"text": "cancel", "entities": []}], "userDefined": false, "apiTrigger": false, "intentId": "cancel", "_id": {"$oid": "59aae7bd26f6f60007b06fb5"}, "speechResponse": "Ok. Canceled."}, {"name": "Welcome message", "userDefined": false, "apiTrigger": false, "intentId": "init_conversation", "_id": {"$oid": "59aae7bd26f6f60007b06fb7"}, "speechResponse": "Hi, What can i do for you ?"}]
1+
[{"name": "Default Fallback intent", "userDefined": false, "apiTrigger": false, "intentId": "fallback", "_id": {"$oid": "59aae7bd26f6f60007b06fb3"}, "speechResponse": "Sorry. I'm having trouble understanding you."}, {"name": "cancel", "trainingData": [{"text": "i want to cancel", "entities": []}, {"text": "cancel that", "entities": []}, {"text": "cancel", "entities": []}], "userDefined": false, "apiTrigger": false, "intentId": "cancel", "_id": {"$oid": "59aae7bd26f6f60007b06fb5"}, "speechResponse": "Ok. Canceled."}, {"name": "Welcome message", "userDefined": false, "apiTrigger": false, "intentId": "init_conversation", "_id": {"$oid": "59aae7bd26f6f60007b06fb7"}, "speechResponse": "Hi ### What can i do for you ?"}]

Diff for: examples/restaurant_search.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"name": "Restaurant search", "parameters": [{"prompt": "Tell me your location?", "required": true, "type": "free_text", "id": {"$oid": "5adca3734ae5354f655fed86"}, "name": "location"}, {"prompt": "Ok. What type cuisine are you looking for?", "required": true, "type": "free_text", "id": {"$oid": "5adca3734ae5354f655fed87"}, "name": "cuisine"}], "userDefined": true, "trainingData": [{"text": "im looking for a place near banglore", "entities": [{"begin": 28, "end": 36, "name": "location", "value": "banglore"}]}, {"text": "i'm looking for a place to eat near down town la", "entities": [{"begin": 36, "end": 48, "name": "location", "value": "down town la"}]}, {"text": "i'm looking for a place in new york", "entities": [{"begin": 27, "end": 35, "name": "location", "value": "new york"}]}, {"text": "im looking for a place in banglore", "entities": [{"begin": 26, "end": 34, "name": "location", "value": "banglore"}]}, {"text": "looking for indian cuisine in new york", "entities": [{"begin": 12, "end": 18, "name": "cuisine", "value": "indian"}, {"begin": 30, "end": 38, "name": "location", "value": "new york"}]}, {"text": "central indian restaurant", "entities": [{"begin": 0, "end": 7, "name": "location", "value": "central"}, {"begin": 8, "end": 14, "name": "cuisine", "value": "indian"}]}, {"text": "I am looking for mexican indian fusion", "entities": [{"begin": 17, "end": 38, "name": "cuisine", "value": "mexican indian fusion"}]}, {"text": "I am looking a restaurant in 29432", "entities": [{"begin": 29, "end": 34, "name": "location", "value": "29432"}]}, {"text": "I am looking for asian fusion food", "entities": [{"begin": 17, "end": 29, "name": "cuisine", "value": "asian fusion"}]}, {"text": "anywhere near 18328", "entities": [{"begin": 14, "end": 19, "name": "location", "value": "18328"}]}, {"text": "anywhere in the west", "entities": [{"begin": 16, "end": 20, "name": "location", "value": "west"}]}, {"text": "search for restaurants", "entities": []}, {"text": "i am looking for an indian spot called olaolaolaolaolaola", "entities": [{"begin": 39, "end": 57, "name": "location", "value": "olaolaolaolaolaola"}, {"begin": 20, "end": 26, "name": "cuisine", "value": "indian"}]}, {"text": "show me a mexican place in the centre", "entities": [{"begin": 10, "end": 17, "name": "cuisine", "value": "mexican"}, {"begin": 31, "end": 37, "name": "location", "value": "centre"}]}, {"text": "show me chines restaurants in the north", "entities": [{"begin": 8, "end": 14, "name": "cuisine", "value": "chines"}, {"begin": 34, "end": 39, "name": "location", "value": "north"}]}, {"text": "show me chinese restaurants", "entities": [{"begin": 8, "end": 15, "name": "cuisine", "value": "chinese"}]}, {"text": "i'm looking for a place in the north of town", "entities": [{"begin": 31, "end": 44, "name": "location", "value": "north of town"}]}, {"text": "I am searching for a dinner spot", "entities": []}, {"text": "I want to grab lunch", "entities": []}, {"text": "i'm looking for a place to eat", "entities": []}], "apiTrigger": false, "intentId": "restaurant_search", "_id": {"$oid": "5adb265507440e00128fcfa1"}, "speechResponse": "Ok, I found following restaurants matching your query. Location => {{parameters[\"location\"] }} and Cuisine => {{parameters[\"cuisine\"] }}"}, {"name": "Greet", "trainingData": [{"text": "dear sir", "entities": []}, {"text": "good evening\n", "entities": []}, {"text": "good morning\n", "entities": []}, {"text": "hi\n", "entities": []}, {"text": "hello\n", "entities": []}, {"text": "hey there\n", "entities": []}, {"text": "howdy\n", "entities": []}, {"text": "hey", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "greet", "_id": {"$oid": "5adc89ad4ae5353f40be85bd"}, "speechResponse": "Hello Sir"}, {"name": "Affirm", "trainingData": [{"text": "sounds really good", "entities": []}, {"text": "great choice\n", "entities": []}, {"text": "correct\n", "entities": []}, {"text": "right, thank you\n", "entities": []}, {"text": "great\n", "entities": []}, {"text": "ok\n", "entities": []}, {"text": "that's right\n", "entities": []}, {"text": "indeed\n", "entities": []}, {"text": "yeah\n", "entities": []}, {"text": "yep\n", "entities": []}, {"text": "yes\n", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "affirm", "_id": {"$oid": "5adc8a3d4ae5353f40be85ca"}, "speechResponse": "I'm glad that you agree"}, {"name": "Goodbye", "trainingData": [{"text": "have a good one", "entities": []}, {"text": "Bye bye\n", "entities": []}, {"text": "farewell\n", "entities": []}, {"text": "end\n", "entities": []}, {"text": "stop\n", "entities": []}, {"text": "good bye\n", "entities": []}, {"text": "goodbye\n", "entities": []}, {"text": "bye", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "goodbye", "_id": {"$oid": "5adc8a9c4ae5353f40be85cf"}, "speechResponse": "It was nice talking to you sir"}]
1+
[{"name": "Restaurant search", "parameters": [{"prompt": "Sure ### tell me your location?", "required": true, "type": "free_text", "id": {"$oid": "5ae0dd474ae5357959ad5f1d"}, "name": "location"}, {"prompt": "Ok. ### What type cuisine are you looking for?", "required": true, "type": "free_text", "id": {"$oid": "5ae0dd474ae5357959ad5f1e"}, "name": "cuisine"}], "userDefined": true, "trainingData": [{"text": "im looking for a place in banglore serving Chinese", "entities": [{"begin": 26, "end": 34, "name": "location", "value": "banglore"}, {"begin": 43, "end": 50, "name": "cuisine", "value": "Chinese"}]}, {"text": "i'm looking for Chinese food", "entities": [{"begin": 16, "end": 23, "name": "cuisine", "value": "Chinese"}]}, {"text": "I'm looking for south indian places", "entities": [{"begin": 12, "end": 28, "name": "cuisine", "value": "for south indian"}]}, {"text": "im looking for a place near banglore", "entities": [{"begin": 28, "end": 36, "name": "location", "value": "banglore"}]}, {"text": "i'm looking for a place to eat near down town la", "entities": [{"begin": 36, "end": 48, "name": "location", "value": "down town la"}]}, {"text": "i'm looking for a place in new york", "entities": [{"begin": 27, "end": 35, "name": "location", "value": "new york"}]}, {"text": "im looking for a place in banglore", "entities": [{"begin": 26, "end": 34, "name": "location", "value": "banglore"}]}, {"text": "looking for indian cuisine in new york", "entities": [{"begin": 12, "end": 18, "name": "cuisine", "value": "indian"}, {"begin": 30, "end": 38, "name": "location", "value": "new york"}]}, {"text": "central indian restaurant", "entities": [{"begin": 0, "end": 7, "name": "location", "value": "central"}, {"begin": 8, "end": 14, "name": "cuisine", "value": "indian"}]}, {"text": "I am looking for mexican indian fusion", "entities": [{"begin": 17, "end": 38, "name": "cuisine", "value": "mexican indian fusion"}]}, {"text": "I am looking a restaurant in 29432", "entities": [{"begin": 29, "end": 34, "name": "location", "value": "29432"}]}, {"text": "I am looking for asian fusion food", "entities": [{"begin": 17, "end": 29, "name": "cuisine", "value": "asian fusion"}]}, {"text": "anywhere near 18328", "entities": [{"begin": 14, "end": 19, "name": "location", "value": "18328"}]}, {"text": "anywhere in the west", "entities": [{"begin": 16, "end": 20, "name": "location", "value": "west"}]}, {"text": "search for restaurants", "entities": []}, {"text": "i am looking for an indian spot called olaolaolaolaolaola", "entities": [{"begin": 39, "end": 57, "name": "location", "value": "olaolaolaolaolaola"}, {"begin": 20, "end": 26, "name": "cuisine", "value": "indian"}]}, {"text": "show me a mexican place in the centre", "entities": [{"begin": 10, "end": 17, "name": "cuisine", "value": "mexican"}, {"begin": 31, "end": 37, "name": "location", "value": "centre"}]}, {"text": "show me chines restaurants in the north", "entities": [{"begin": 8, "end": 14, "name": "cuisine", "value": "chines"}, {"begin": 34, "end": 39, "name": "location", "value": "north"}]}, {"text": "show me chinese restaurants", "entities": [{"begin": 8, "end": 15, "name": "cuisine", "value": "chinese"}]}, {"text": "i'm looking for a place in the north of town", "entities": [{"begin": 31, "end": 44, "name": "location", "value": "north of town"}]}, {"text": "I am searching for a dinner spot", "entities": []}, {"text": "I want to grab lunch", "entities": []}, {"text": "i'm looking for a place to eat", "entities": []}], "apiTrigger": false, "intentId": "restaurant_search", "_id": {"$oid": "5adb265507440e00128fcfa1"}, "speechResponse": "Ok ### I found following restaurants serving <b>{{parameters[\"cuisine\"] }}</b> in <b>{{parameters[\"location\"] }}</b>\n###\n <b> Restaurant Name 1</b>\n###\n<b> Restaurant Name 2</b>"}, {"name": "Greet", "trainingData": [{"text": "dear sir", "entities": []}, {"text": "good evening\n", "entities": []}, {"text": "good morning\n", "entities": []}, {"text": "hi\n", "entities": []}, {"text": "hello\n", "entities": []}, {"text": "hey there\n", "entities": []}, {"text": "howdy\n", "entities": []}, {"text": "hey", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "greet", "_id": {"$oid": "5adc89ad4ae5353f40be85bd"}, "speechResponse": "Hello Sir"}, {"name": "Affirm", "trainingData": [{"text": "sounds really good", "entities": []}, {"text": "great choice\n", "entities": []}, {"text": "correct\n", "entities": []}, {"text": "right, thank you\n", "entities": []}, {"text": "great\n", "entities": []}, {"text": "ok\n", "entities": []}, {"text": "that's right\n", "entities": []}, {"text": "indeed\n", "entities": []}, {"text": "yeah\n", "entities": []}, {"text": "yep\n", "entities": []}, {"text": "yes\n", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "affirm", "_id": {"$oid": "5adc8a3d4ae5353f40be85ca"}, "speechResponse": "I'm glad that you agree"}, {"name": "Goodbye", "trainingData": [{"text": "have a good one", "entities": []}, {"text": "Bye bye\n", "entities": []}, {"text": "farewell\n", "entities": []}, {"text": "end\n", "entities": []}, {"text": "stop\n", "entities": []}, {"text": "good bye\n", "entities": []}, {"text": "goodbye\n", "entities": []}, {"text": "bye", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "goodbye", "_id": {"$oid": "5adc8a9c4ae5353f40be85cf"}, "speechResponse": "It was nice talking to you sir"}, {"name": "Thank you", "trainingData": [{"text": "thank you iky", "entities": []}, {"text": "thanks", "entities": []}, {"text": "thank you very much", "entities": []}], "userDefined": true, "apiTrigger": false, "intentId": "thank_you", "_id": {"$oid": "5adcb6314ae535517d9f8218"}, "speechResponse": "I'm happy to help :)"}]

Diff for: frontend/src/app/agent/chat/chat.component.html

+11-8
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,21 @@
22
<div fxLayout="row" fxFill>
33
<mat-card fxFlex="30" fxLayout="column" >
44
<div fxFlex="90" class="chat-container">
5-
<div *ngFor="let chat of chats" >
5+
<div *ngFor="let message of messages" [@listAnimation]="messages.length" >
66

7-
<div *ngIf="chat.owner=='chat'" class="chat-message">
8-
<div class="chat-message-content">
9-
<span class="textleft" [innerHTML]="chat.speechResponse"></span>
10-
</div>
11-
</div>
12-
<div *ngIf="chat.owner=='user'" class="chat-message">
7+
<div *ngIf="message.author=='user'" class="chat-message">
138
<div class="chat-message-content human">
14-
<span class="textright">{{chat.input}}</span>
9+
<span class="textright">{{message.content}}</span>
1510
</div>
1611
</div>
12+
13+
<div *ngIf="message.author=='chat'" class="chat-message">
14+
<div class="chat-message-content">
15+
<span class="textleft" [innerHTML]="message.content"></span>
16+
</div>
17+
</div>
18+
19+
1720
</div>
1821
</div>
1922

Diff for: frontend/src/app/agent/chat/chat.component.scss

+26-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ mat-card{
2626
.chat-message {
2727
margin: 10px 0;
2828
min-height: 20px;
29+
30+
animation: fadeIn 0.5s linear;
31+
animation-fill-mode: both;
2932

3033
&:after {
3134
display: block;
@@ -58,4 +61,26 @@ mat-card{
5861
overflow-y: scroll;
5962
}
6063

61-
}
64+
}
65+
66+
$total-items: 5;
67+
68+
// Set delay per List Item
69+
@for $i from 1 through $total-items {
70+
.chat-message:nth-child(#{$i}) {
71+
animation-delay: .25s * $i;
72+
}
73+
}
74+
75+
// Keyframe animation
76+
@-webkit-keyframes fadeIn {
77+
0% {
78+
opacity: 0;
79+
}
80+
75% {
81+
opacity: 0.5;
82+
}
83+
100% {
84+
opacity: 1;
85+
}
86+
}

Diff for: frontend/src/app/agent/chat/chat.component.ts

+60-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
11
import { Component, OnInit, Input } from '@angular/core';
22
import { ChatService } from '../../services/chat.service';
33
import { FormBuilder, FormGroup } from '@angular/forms';
4+
import { trigger,style,transition,animate,keyframes,query,stagger } from '@angular/animations';
45

56
@Component({
67
// tslint:disable-next-line:component-selector
78
selector: 'app-chat',
89
templateUrl: './chat.component.html',
9-
styleUrls: ['./chat.component.scss']
10+
styleUrls: ['./chat.component.scss'],
11+
animations: [
12+
13+
trigger('listAnimation', [
14+
transition('* => *', [
15+
16+
query(':enter', style({ opacity: 0 }), {optional: true}),
17+
18+
query(':enter', stagger('500ms', [
19+
animate('.3s ease-in-out', keyframes([
20+
style({opacity: 0, offset: 0}),
21+
style({opacity: .5, offset: 0.5}),
22+
style({opacity: 1, offset: 1.0}),
23+
]))]), {optional: true})
24+
])
25+
])
26+
27+
]
1028
})
29+
1130
export class ChatComponent implements OnInit {
1231
chatInitial;
1332
chatCurrent;
14-
chats = [];
33+
34+
messages: Message[] = [];
1535
prettyChatCurrent;
1636

1737
chatForm: FormGroup;
@@ -44,12 +64,31 @@ export class ChatComponent implements OnInit {
4464
.then((c: any) => {
4565
c.owner = 'chat';
4666
this.changeCurrent(c);
67+
68+
this.render_bubbles(c)
4769
});
4870
}
4971

72+
render_bubbles(c){
73+
c.speechResponse.forEach((item, index) => {
74+
if (index == 0){
75+
this.add_to_messages(item,"chat")
76+
}else{
77+
setTimeout(()=>{
78+
this.add_to_messages(item,"chat")
79+
},500)
80+
}
81+
82+
});
83+
}
84+
add_to_messages(message,author){
85+
let new_message = new Message(message,author)
86+
this.messages.push(new_message);
87+
88+
}
89+
5090
changeCurrent(c) {
5191
c.date = new Date();
52-
this.chats.push(c);
5392
this.chatCurrent = c;
5493
this.prettyChatCurrent = JSON ? JSON.stringify(c, null, ' ') : 'your browser doesnt support JSON so cant pretty print';
5594
}
@@ -61,14 +100,32 @@ export class ChatComponent implements OnInit {
61100
input: form.input,
62101
owner: 'user'
63102
};
103+
this.add_to_messages(form.input,"user")
104+
64105
this.changeCurrent(sendMessage);
65106
this.chatService.converse(sendMessage)
66107
.then((c: any) => {
67108
c.owner = 'chat';
68109
this.changeCurrent(c);
69110
this.chatForm.reset();
111+
setTimeout(
112+
()=>{
113+
this.render_bubbles(c);
114+
},1000
115+
)
116+
70117
});
71118

72119
}
73120

74121
}
122+
123+
export class Message {
124+
content: string;
125+
author: string;
126+
127+
constructor(content: string, author: string){
128+
this.content = content;
129+
this.author = author;
130+
}
131+
}

0 commit comments

Comments
 (0)