-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
197 lines (162 loc) · 7.14 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
'use strict';
process.env.DEBUG = 'actions-on-google:*';
const Assistant = require('actions-on-google').ApiAiAssistant;
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const know = admin.database().ref('/animal-knowledge');
const graph = know.child('graph');
// Agent Intent names
const PLAY_INTENT = 'play';
const NO_INTENT = 'discriminate-no';
const YES_INTENT = 'discriminate-yes';
const GIVEUP_INTENT = 'give-up';
const LEARN_THING_INTENT = 'learn-thing';
const LEARN_DISCRIM_INTENT = 'learn-discrimination';
// Contexts
const WELCOME_CONTEXT = 'welcome';
const QUESTION_CONTEXT = 'question';
const GUESS_CONTEXT = 'guess';
const LEARN_THING_CONTEXT = 'learn-thing';
const LEARN_DISCRIM_CONTEXT = 'learn-discrimination';
const ANSWER_CONTEXT = 'answer';
// Context Parameters
const ID_PARAM = 'id';
const BRANCH_PARAM = 'branch';
const LEARN_THING_PARAM = 'learn-thing';
const GUESSABLE_THING_PARAM = 'guessable-thing';
const LEARN_DISCRIMINATION_PARAM = 'learn-discrimination';
const ANSWER_PARAM = 'answer';
const QUESTION_PARAM = 'question';
exports.assistantcodelab = functions.https.onRequest((request, response) => {
console.log('headers: ' + JSON.stringify(request.headers));
console.log('body: ' + JSON.stringify(request.body));
const assistant = new Assistant({request: request, response: response});
let actionMap = new Map();
actionMap.set(PLAY_INTENT, play);
actionMap.set(NO_INTENT, discriminate);
actionMap.set(YES_INTENT, discriminate);
actionMap.set(GIVEUP_INTENT, giveUp);
actionMap.set(LEARN_THING_INTENT, learnThing);
actionMap.set(LEARN_DISCRIM_INTENT, learnDiscrimination);
assistant.handleRequest(actionMap);
function play(assistant) {
console.log('play');
const first_ref = know.child('first');
first_ref.once('value', snap => {
const first = snap.val();
console.log(`First: ${first}`);
graph.child(first).once('value', snap => {
const speech = `
Great! Think of an animal, but don't tell me what it is yet.
Okay, my first question is: ${snap.val().q}`;
const parameters = {};
parameters[ID_PARAM] = snap.key;
assistant.setContext(QUESTION_CONTEXT, 5, parameters);
assistant.ask(speech);
});
});
}
function discriminate(assistant) {
const priorQuestion = assistant.getContextArgument(QUESTION_CONTEXT, ID_PARAM).value;
const intent = assistant.getIntent();
let yes_no;
if (YES_INTENT === intent) {
yes_no = 'y';
} else {
yes_no = 'n';
}
console.log(`prior question: ${priorQuestion}`);
graph.child(priorQuestion).once('value', snap => {
const next = snap.val()[yes_no];
graph.child(next).once('value', snap => {
const node = snap.val();
if (node.q) {
const speech = node.q;
const parameters = {};
parameters[ID_PARAM] = snap.key;
assistant.setContext(QUESTION_CONTEXT, 5, parameters);
assistant.ask(speech);
} else {
const guess = node.a;
const speech = `Is it a ${guess}?`;
const parameters = {};
parameters[ID_PARAM] = snap.key;
parameters[BRANCH_PARAM] = yes_no;
assistant.setContext(GUESS_CONTEXT, 5, parameters);
assistant.ask(speech);
}
});
});
}
function giveUp(assistant) {
const priorQuestion = assistant.getContextArgument(QUESTION_CONTEXT, ID_PARAM).value;
const guess = assistant.getContextArgument(GUESS_CONTEXT, ID_PARAM).value;
console.log(`Priorq: ${priorQuestion}, guess: ${guess}`);
const speech = 'I give up! What are you thinking of?';
const parameters = {};
parameters[LEARN_THING_PARAM] = true;
assistant.setContext(LEARN_THING_CONTEXT, 2, parameters);
assistant.ask(speech);
}
function learnThing(assistant) {
const priorQuestion = assistant.getContextArgument(QUESTION_CONTEXT, ID_PARAM).value;
const guess = assistant.getContextArgument(GUESS_CONTEXT, ID_PARAM).value;
const branch = assistant.getContextArgument(GUESS_CONTEXT, BRANCH_PARAM).value;
const new_thing = assistant.getArgument(GUESSABLE_THING_PARAM);
console.log(`Priorq: ${priorQuestion}, guess: ${guess}, branch: ${branch}, thing: ${new_thing}`);
const q_promise = graph.child(priorQuestion).once('value');
const g_promise = graph.child(guess).once('value');
Promise.all([q_promise, g_promise]).then(results => {
const q_snap = results[1];
// const g_snap = results[1];
// const speech = `I don't know how to tell a ${new_thing} from a ${g_snap.val().a}!`;
// assistant.ask(speech);
const speech = `
I need to know how to tell a ${new_thing} from a ${q_snap.val().a} using a yes-no question.
The answer must be "yes" for ${new_thing}. What question should I use?
`;
const discrmParameters = {};
discrmParameters[LEARN_DISCRIMINATION_PARAM] = true;
assistant.setContext(LEARN_DISCRIM_CONTEXT, 2, discrmParameters);
const answerParameters = {};
answerParameters[ANSWER_PARAM] = new_thing;
assistant.setContext(ANSWER_CONTEXT, 2, answerParameters);
assistant.ask(speech);
//throw new Error("some problem");
}).catch(err => Cu.reportError(err));
}
function learnDiscrimination(assistant) {
const priorQuestion = assistant.getContextArgument(QUESTION_CONTEXT, ID_PARAM).value;
const guess = assistant.getContextArgument(GUESS_CONTEXT, ID_PARAM).value;
const branch = assistant.getContextArgument(GUESS_CONTEXT, BRANCH_PARAM).value;
const answer = assistant.getContextArgument(ANSWER_CONTEXT, ANSWER_PARAM).value;
const question = assistant.getArgument(QUESTION_PARAM);
console.log(`Priorq: ${priorQuestion}, answer: ${answer}, guess: ${guess}, branch: ${branch}, question: ${question}`);
const a_node = graph.push({
a: answer
});
const q_node = graph.push({
q: `${question}?`,
y: a_node.key,
n: guess
});
let predicate = 'a';
if (['a','e','i','o','u'].indexOf(answer.charAt(0)) !== -1) {
predicate = 'an';
}
const update = {};
update[branch] = q_node.key;
graph.child(priorQuestion).update(update).then(() => {
// const speech = "Ok, thanks for the information!";
// assistant.ask(speech);
const speech = `
OK, thanks for the information! I'll remember to ask "${question}" to see if you're thinking of ${predicate} ${answer}.
Would you like to play again?
`;
assistant.setContext(WELCOME_CONTEXT, 1);
assistant.ask(speech);
//throw new Error("some problem");
}).catch(err => Cu.reportError(err));
}
});