diff --git a/Code/appointment.json b/Code/appointment.json
new file mode 100644
index 0000000..211cbc6
--- /dev/null
+++ b/Code/appointment.json
@@ -0,0 +1,467 @@
+{
+ "projectFileVersion": "2022-10-01-preview",
+ "stringIndexType": "Utf16CodeUnit",
+ "metadata": {
+ "projectKind": "Conversation",
+ "settings": {
+ "confidenceThreshold": 0,
+ "normalizeCasing": true
+ },
+ "projectName": "appointment",
+ "multilingual": false,
+ "description": "",
+ "language": "en-us"
+ },
+ "assets": {
+ "projectKind": "Conversation",
+ "intents": [
+ {
+ "category": "None"
+ },
+ {
+ "category": "create a meeting"
+ },
+ {
+ "category": "who is Adam Lambert "
+ },
+ {
+ "category": "who is adam lambert"
+ }
+ ],
+ "entities": [
+ {
+ "category": "meeting time",
+ "compositionSetting": "combineComponents",
+ "list": {
+ "sublists": [
+ {
+ "listKey": "Week",
+ "synonyms": [
+ {
+ "language": "en-us",
+ "values": [
+ "Week",
+ "Friday",
+ "Monday",
+ "Tuesday",
+ "Thursday",
+ "Wednesday"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "category": "meeting title",
+ "compositionSetting": "combineComponents",
+ "list": {
+ "sublists": [
+ {
+ "listKey": "Match",
+ "synonyms": [
+ {
+ "language": "en-us",
+ "values": [
+ "Match",
+ "Football",
+ "Volleyball",
+ "Computer Game"
+ ]
+ }
+ ]
+ },
+ {
+ "listKey": "Dinner",
+ "synonyms": [
+ {
+ "language": "en-us",
+ "values": [
+ "Dinner",
+ "hot pot",
+ "soup",
+ "Chinese Food",
+ "Indian Food",
+ "Thailand Food",
+ "Swedish Food"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "prebuilts": [
+ {
+ "category": "General.Event"
+ }
+ ]
+ },
+ {
+ "category": "yesorno",
+ "compositionSetting": "combineComponents",
+ "list": {
+ "sublists": [
+ {
+ "listKey": "no",
+ "synonyms": [
+ {
+ "language": "en-us",
+ "values": [
+ "no",
+ "no way"
+ ]
+ }
+ ]
+ },
+ {
+ "listKey": "yes",
+ "synonyms": [
+ {
+ "language": "en-us",
+ "values": [
+ "yes",
+ "of course",
+ "yeah"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "prebuilts": [
+ {
+ "category": "Choice.Boolean"
+ }
+ ]
+ },
+ {
+ "category": "Age",
+ "compositionSetting": "combineComponents",
+ "prebuilts": [
+ {
+ "category": "Quantity.Age"
+ }
+ ]
+ },
+ {
+ "category": "BirthDay",
+ "compositionSetting": "combineComponents",
+ "prebuilts": [
+ {
+ "category": "DateTime"
+ }
+ ]
+ },
+ {
+ "category": "Info",
+ "compositionSetting": "combineComponents",
+ "list": {
+ "sublists": [
+ {
+ "listKey": "Career",
+ "synonyms": [
+ {
+ "language": "en-us",
+ "values": [
+ "Career",
+ "singer",
+ "artist"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "utterances": [
+ {
+ "text": "Adam Lambert is born in Jan 29th.",
+ "language": "en-us",
+ "intent": "who is adam lambert",
+ "entities": [
+ {
+ "category": "BirthDay",
+ "offset": 24,
+ "length": 8
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Adam Lambert is a Singer and Artist",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [
+ {
+ "category": "Info",
+ "offset": 18,
+ "length": 6
+ },
+ {
+ "category": "Info",
+ "offset": 29,
+ "length": 6
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Adam Lambert is born on Jan 29th.",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [
+ {
+ "category": "BirthDay",
+ "offset": 24,
+ "length": 8
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Adam Lambert is 42 years old",
+ "language": "en-us",
+ "intent": "who is adam lambert",
+ "entities": [
+ {
+ "category": "Age",
+ "offset": 16,
+ "length": 11
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Who is the individual named Adam Lambert?",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "What can you tell me about Adam Lambert?",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "Could you give me some background on Adam Lambert?",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "Who exactly is Adam Lambert?",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "Tell me about the person known as Adam Lambert.",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "What details do you have about Adam Lambert?",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "Can you provide information on Adam Lambert?",
+ "language": "en-us",
+ "intent": "who is Adam Lambert ",
+ "entities": [],
+ "dataset": "Train"
+ },
+ {
+ "text": "It would be beneficial to schedule a meeting next Friday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 37,
+ "length": 7
+ },
+ {
+ "category": "meeting time",
+ "offset": 50,
+ "length": 6
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "I'd like to propose a weekly check-in meeting on Monday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 29,
+ "length": 16
+ },
+ {
+ "category": "meeting time",
+ "offset": 49,
+ "length": 6
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Let's organize a special meeting next Wednesday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 17,
+ "length": 15
+ },
+ {
+ "category": "meeting time",
+ "offset": 38,
+ "length": 9
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "I recommend we convene a cross-functional meeting next Tuesday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 25,
+ "length": 24
+ },
+ {
+ "category": "meeting time",
+ "offset": 55,
+ "length": 7
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Let's plan a departmental meeting next Friday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 13,
+ "length": 20
+ },
+ {
+ "category": "meeting time",
+ "offset": 39,
+ "length": 6
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "How about setting up a conference call for Thursday?",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 23,
+ "length": 15
+ },
+ {
+ "category": "meeting time",
+ "offset": 43,
+ "length": 9
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "I suggest creating a meeting on Wednesday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 21,
+ "length": 7
+ },
+ {
+ "category": "meeting time",
+ "offset": 32,
+ "length": 9
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Let's schedule a virtual meeting for next Thursday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 17,
+ "length": 15
+ },
+ {
+ "category": "meeting time",
+ "offset": 42,
+ "length": 8
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "Can we organize a brief team meeting this Friday?",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 24,
+ "length": 12
+ },
+ {
+ "category": "meeting time",
+ "offset": 42,
+ "length": 6
+ }
+ ],
+ "dataset": "Train"
+ },
+ {
+ "text": "I propose we set up a meeting next Monday.",
+ "language": "en-us",
+ "intent": "create a meeting",
+ "entities": [
+ {
+ "category": "meeting title",
+ "offset": 22,
+ "length": 7
+ },
+ {
+ "category": "meeting time",
+ "offset": 35,
+ "length": 6
+ }
+ ],
+ "dataset": "Train"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Code/azure.js b/Code/azure.js
new file mode 100644
index 0000000..976e8e8
--- /dev/null
+++ b/Code/azure.js
@@ -0,0 +1,2 @@
+export const KEY = "4e763d7012be49e5a48c5db78d8c33b5";
+export const NLU_KEY = "953bed351641435f9ad2e8198192f38c";
\ No newline at end of file
diff --git a/Code/dm.js b/Code/dm.js
index 9fb7198..1b1987f 100644
--- a/Code/dm.js
+++ b/Code/dm.js
@@ -20,32 +20,99 @@ const settings = {
};
/* Grammar definition */
-const grammar = {
+const grammar_person = {
vlad: { person: "Vladislav Maraev" },
aya: { person: "Nayat Astaiza Soriano" },
rasmus: { person: "Rasmus Blanck" },
+ marry: { person: "Marry" },
+ tom: { person: "Tom" },
+ black: { person: "Black" },
+ jerry: { person: "Jerry" },
+};
+
+const grammar_day = {
monday: { day: "Monday" },
tuesday: { day: "Tuesday" },
+ wednesday: { day: "Wednesday" },
+ thursday: { day: "Thursday" },
+ friday: { day: "Friday" },
+};
+
+const grammar_time = {
+ "8": { time: "8:00" },
+ "9": { time: "9:00" },
"10": { time: "10:00" },
"11": { time: "11:00" },
+ "12": { time: "12:00" },
+ "13": { time: "13:00" },
+ "14": { time: "14:00" },
+ "15": { time: "15:00" },
+ "16": { time: "16:00" },
+};
+
+const grammar_positive_answer = {
+ "yes": { answer: "Yes" },
+ "of course": { answer: "Of course" },
+ "yeah": { answer: "Yeah" },
+};
+
+const grammar_negative_answer = {
+ "no": { answer: "No" },
+ "no way": { answer: "No way"},
};
/* Helper functions */
-function isInGrammar(utterance) {
- return utterance.toLowerCase() in grammar;
+function isInPersonGrammar(utterance) {
+ return utterance.toLowerCase() in grammar_person;
+}
+
+function isInDayGrammar(utterance) {
+ return utterance.toLowerCase() in grammar_day;
+}
+
+function isInTimeGrammar(utterance) {
+ return utterance.toLowerCase() in grammar_time;
}
function getPerson(utterance) {
- return (grammar[utterance.toLowerCase()] || {}).person;
+ return (grammar_person[utterance.toLowerCase()] || {}).person;
+}
+
+function getDate(utterance) {
+ return (grammar_day[utterance.toLowerCase()] || {}).day;
}
+function getTime(utterance) {
+ return (grammar_time[utterance.toLowerCase()] || {}).time;
+}
+
+function isYes(utterance) {
+ return utterance.toLowerCase() in grammar_positive_answer;
+}
+
+function isNo(utterance) {
+ return utterance.toLowerCase() in grammar_negative_answer;
+}
+
+
const dmMachine = setup({
actions: {
/* define your actions here */
+ say: ({ context }, params) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: params,
+ },
+ }),
},
}).createMachine({
context: {
count: 0,
+ person: undefined,
+ date: undefined,
+ time: undefined,
+
},
id: "DM",
initial: "Prepare",
@@ -68,11 +135,203 @@ const dmMachine = setup({
initial: "Prompt",
states: {
Prompt: {
+ entry:[{type: "say", params:`Let's create an appointment`}],
+ on: { SPEAK_COMPLETE: "#DM.WithWhom" },
+ },
+ },
+ },
+ WithWhom: {
+ initial: "Who",
+ id: "who",
+ states: {
+ Who: {
+ entry: [{type: "say", params:`Who are you meeting with?`}],
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: {
+ noInputTimeOut: 1000
+ }
+ }),
+ on: {
+ RECOGNISED:
+ [{
+ guard: ({ event }) => isInPersonGrammar(event.value[0].utterance) === true,
+ actions: [
+ ({ context, event }) => { context.person = getPerson(event.value[0].utterance) },
+ ],
+ target: "#DM.WhichDate",
+ },
+ {
+ guard: ({ event }) => isInPersonGrammar(event.value[0].utterance) === false,
+ target: "#DM.NotPersonGram",
+ }],
+ ASR_NOINPUT:"#DM.NoPersonVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoPersonVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WithWhom"
+ },
+
+ },
+
+ },
+ },
+ /* Not in grammar */
+ NotPersonGram: {
+ initial: "Notgram",
+ states: {
+ Notgram: {
+ entry: [{type: "say", params:`The word is not in Gramma. Please answer the question again`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WithWhom"
+ },
+ },
+
+ },
+ },
+ WhichDate: {
+ initial: "Whichdate",
+ states: {
+ Whichdate: {
+ entry: [{type: "say", params:`On which day is your meeting?`}],
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: {
+ noInputTimeOut: 1000
+ }
+ }),
+ on: {
+ RECOGNISED:
+ [
+ {
+ guard: ({ event }) => isInDayGrammar(event.value[0].utterance) === true,
+ actions: [
+ ({ context, event }) => { context.date = getDate(event.value[0].utterance) },
+ ],
+ target: "#DM.WholeDay",
+ },
+ {
+ guard: ({ event }) => isInDayGrammar(event.value[0].utterance) === false,
+ target: "#DM.NotDateGram",
+ },
+ ],
+ ASR_NOINPUT:"#DM.NoDateVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoDateVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotDateGram: {
+ initial: "Notgram",
+ states: {
+ Notgram: {
+ entry: [{type: "say", params:`The word is not in Gramma. Please answer the question again`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ WholeDay: {
+ initial: "Whole",
+ states: {
+ Whole: {
+
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: `Will it take the whole day?`,
+ },
+ }),
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: {
+ noInputTimeOut: 1000
+ }
+ }),
+ on: {
+ RECOGNISED:
+ [{
+ guard: ({ event }) => isYes(event.value[0].utterance) === true,
+ target: "#DM.CreateWholeDay",
+ },
+ {
+ guard: ({ event }) => isNo(event.value[0].utterance) === true,
+ target: "#DM.WhatTime",
+ },
+ "#DM.NotWholeDayGram"
+ ],
+ ASR_NOINPUT:"#DM.NoWholeDayVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoWholeDayVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WholeDay"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotWholeDayGram: {
+ initial: "Notgram",
+ states: {
+ Notgram: {
+ entry: [{type: "say", params:`The word is not in Gramma. Please answer the question again`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WholeDay"
+ },
+ },
+ },
+ },
+ CreateWholeDay: {
+ initial: "Createwhole",
+ states: {
+ Createwhole: {
entry: ({ context }) =>
context.ssRef.send({
type: "SPEAK",
value: {
- utterance: `Hello world!`,
+ utterance: `Do you want me to create an appointment with ${context.person} on ${context.date} for the whole day?`,
},
}),
on: { SPEAK_COMPLETE: "Ask" },
@@ -81,26 +340,181 @@ const dmMachine = setup({
entry: ({ context }) =>
context.ssRef.send({
type: "LISTEN",
+ value: {
+ noInputTimeOut: 1000
+ }}),
+ on: {
+ RECOGNISED:
+ [{
+ guard: ({ event }) => isYes(event.value[0].utterance) === true,
+ target: "#DM.FinishAppointment",
+ },
+ {
+ guard: ({ event }) => isNo(event.value[0].utterance) === true,
+ target: "#DM.WithWhom",
+ },
+ "#DM.NotCreateWholeDayGram"
+ ],
+ ASR_NOINPUT: "#DM.NoCreateWholeDayVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoCreateWholeDayVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.CreateWholeDay"
+ }
+ },
+ },
+ },
+ /* Not in grammar */
+ NotCreateWholeDayGram: {
+ initial: "Notgram",
+ states: {
+ Notgram: {
+ entry: [{type: "say", params:`The word is not in Gramma. Please answer the question again`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.CreateWholeDay"
+ },
+ },
+ },
+ },
+ WhatTime: {
+ initial: "Whattime",
+ states: {
+ Whattime: {
+ entry: [{type: "say", params:`What time is your meeting?`}],
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: {
+ noInputTimeOut: 1000
+ }
}),
- on: {
- RECOGNISED: {
- actions: ({ context, event }) =>
- context.ssRef.send({
- type: "SPEAK",
- value: {
- utterance: `You just said: ${
- event.value[0].utterance
- }. And it ${
- isInGrammar(event.value[0].utterance) ? "is" : "is not"
- } in the grammar.`,
- },
- }),
- },
- SPEAK_COMPLETE: "#DM.Done",
+ on: {
+ RECOGNISED:
+ [
+ {
+ guard: ({ event }) => isInTimeGrammar(event.value[0].utterance) === true,
+ actions: [
+ ({ context, event }) => { context.time = getTime(event.value[0].utterance) },
+ ],
+ target: "#DM.CreateTime",
+ },
+ {
+ guard: ({ event }) => isInTimeGrammar(event.value[0].utterance) === false,
+ target: "#DM.NotTimeGram",
+ },
+ "#DM.NotTimeGram"],
+ ASR_NOINPUT: "#DM.NoTimeVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoTimeVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhatTime"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotTimeGram: {
+ initial: "Notgram",
+ states: {
+ Notgram: {
+ entry: [{type: "say", params:`The word is not in Gramma. Please answer the question again`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhatTime"
+ },
+ },
+ },
+ },
+ CreateTime: {
+ initial: "Createtime",
+ states: {
+ Createtime: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: `Do you want me to create an appointment with ${context.person} on ${context.date} at ${context.time}?`,
+ },
+ }),
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: {
+ noInputTimeOut: 1000
+
+ }
+ }),
+ on: {
+ RECOGNISED:
+ [{
+ guard: ({ event }) => isYes(event.value[0].utterance) === true,
+ target: "#DM.FinishAppointment",
+ },
+ {
+ guard: ({ event }) => isNo(event.value[0].utterance) === true,
+ target: "#DM.WithWhom",
+ },
+ "#DM.NotCreateTimeGram"
+ ],
+ ASR_NOINPUT: "#DM.NoCreateTimeVoice",
},
},
},
},
+ /* Not received voice */
+ NoCreateTimeVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.CreateTime"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotCreateTimeGram: {
+ initial: "Notgram",
+ states: {
+ Notgram: {
+ entry: [{type: "say", params:`The word is not in Gramma. Please answer the question again`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.CreateTime"
+ },
+ },
+ },
+ },
+ FinishAppointment: {
+ initial: "Finishappointment",
+ states: {
+ Finishappointment: {
+ entry: [{type: "say", params:`Your appointment has been created!`}],
+ on: { SPEAK_COMPLETE: "#DM.Done" },
+ },
+ },
+ },
Done: {
on: {
CLICK: "PromptAndAsk",
@@ -117,11 +531,22 @@ dmActor.subscribe((state) => {
/* if you want to log some parts of the state */
});
+/*SetTimeout for start automatically*/
export function setupButton(element) {
- element.addEventListener("click", () => {
- dmActor.send({ type: "CLICK" });
- });
- dmActor.getSnapshot().context.ssRef.subscribe((snapshot) => {
- element.innerHTML = `${snapshot.value.AsrTtsManager.Ready}`;
+ element.addEventListener("click",
+ () => {
+ setTimeout(function(){
+ dmActor.send({ type: "CLICK" });}, 100)
});
+ setTimeout(function(){
+ dmActor.send({ type: "CLICK" });}, 1000);
+ setTimeout(function(){
+
+ dmActor.getSnapshot().context.ssRef.subscribe((snapshot) => {
+ element.innerHTML = `${snapshot.value.AsrTtsManager.Ready}`;
+ });
+
+ }, 10)
+
}
+
diff --git a/Code/dm3.js b/Code/dm3.js
new file mode 100644
index 0000000..9eb7a5f
--- /dev/null
+++ b/Code/dm3.js
@@ -0,0 +1,128 @@
+import { assign, createActor, setup } from "xstate";
+import { speechstate } from "speechstate";
+import { createBrowserInspector } from "@statelyai/inspect";
+import { KEY } from "./azure.js";
+
+const inspector = createBrowserInspector();
+
+const azureCredentials = {
+ endpoint:
+ "https://northeurope.api.cognitive.microsoft.com/sts/v1.0/issuetoken",
+ key: KEY,
+};
+
+const settings = {
+ azureCredentials: azureCredentials,
+ speechRecognitionEndpointId: "758aa8a0-93d1-4aa7-a377-28179ce8881b",
+ asrDefaultCompleteTimeout: 0,
+ asrDefaultNoInputTimeout: 5000,
+ locale: "en-US",
+ ttsDefaultVoice: "en-US-DavisNeural",
+};
+
+/* Grammar definition */
+const grammar = {
+ vlad: { person: "Vladislav Maraev" },
+ aya: { person: "Nayat Astaiza Soriano" },
+ rasmus: { person: "Rasmus Blanck" },
+ monday: { day: "Monday" },
+ tuesday: { day: "Tuesday" },
+ "10": { time: "10:00" },
+ "11": { time: "11:00" },
+};
+
+/* Helper functions */
+function isInGrammar(utterance) {
+ return utterance.toLowerCase() in grammar;
+}
+
+function getPerson(utterance) {
+ return (grammar[utterance.toLowerCase()] || {}).person;
+}
+
+const dmMachine = setup({
+ actions: {
+ /* define your actions here */
+ },
+}).createMachine({
+ context: {
+ count: 0,
+ },
+ id: "DM",
+ initial: "Prepare",
+ states: {
+ Prepare: {
+ entry: [
+ assign({
+ ssRef: ({ spawn }) => spawn(speechstate, { input: settings }),
+ }),
+ ({ context }) => context.ssRef.send({ type: "PREPARE" }),
+ ],
+ on: { ASRTTS_READY: "WaitToStart" },
+ },
+ WaitToStart: {
+ on: {
+ CLICK: "PromptAndAsk",
+ },
+ },
+ PromptAndAsk: {
+ initial: "Prompt",
+ states: {
+ Prompt: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: `Hello world!`,
+ },
+ }),
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: ({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ }),
+ on: {
+ RECOGNISED: {
+ actions: ({ context, event }) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: `You just said: ${
+ event.value[0].utterance
+ }. And it ${
+ isInGrammar(event.value[0].utterance) ? "is" : "is not"
+ } in the grammar.`,
+ },
+ }),
+ },
+ SPEAK_COMPLETE: "#DM.Done",
+ },
+ },
+ },
+ },
+ Done: {
+ on: {
+ CLICK: "PromptAndAsk",
+ },
+ },
+ },
+});
+
+const dmActor = createActor(dmMachine, {
+ inspect: inspector.inspect,
+}).start();
+
+dmActor.subscribe((state) => {
+ /* if you want to log some parts of the state */
+});
+
+export function setupButton(element) {
+ element.addEventListener("click", () => {
+ dmActor.send({ type: "CLICK" });
+ });
+ dmActor.getSnapshot().context.ssRef.subscribe((snapshot) => {
+ element.innerHTML = `${snapshot.value.AsrTtsManager.Ready}`;
+ });
+}
\ No newline at end of file
diff --git a/Code/dm4.js b/Code/dm4.js
new file mode 100644
index 0000000..2f00acc
--- /dev/null
+++ b/Code/dm4.js
@@ -0,0 +1,347 @@
+import { assign, createActor, setup } from "xstate";
+import { speechstate } from "speechstate";
+import { createBrowserInspector } from "@statelyai/inspect";
+import { KEY } from "./azure.js";
+import { NLU_KEY } from "./azure.js";
+/*
+Regarding improveingNLU coverage, I think I need to add more time datas and person datas to the model.
+*/
+ const inspector = createBrowserInspector();
+ const azureLanguageCredentials = {
+ endpoint: "https://languageresource58888.cognitiveservices.azure.com/language/:analyze-conversations?api-version=2022-10-01-preview" /** your Azure CLU prediction URL */,
+ key: NLU_KEY /** reference to your Azure CLU key */,
+ deploymentName: "appointment" /** your Azure CLU deployment */,
+ projectName: "appointment" /** your Azure CLU project name */,
+ };
+ const azureCredentials = {
+ endpoint:
+ "https://northeurope.api.cognitive.microsoft.com/sts/v1.0/issuetoken",
+ key: KEY,
+ };
+ const settings = {
+ azureLanguageCredentials: azureLanguageCredentials /** global activation of NLU */,
+ azureCredentials: azureCredentials,
+ asrDefaultCompleteTimeout: 0,
+ asrDefaultNoInputTimeout: 5000,
+ locale: "en-US",
+ ttsDefaultVoice: "en-US-DavisNeural",
+ };
+
+ const dmMachine = setup({
+ actions: {
+ /* define your actions here */
+ say: ({ context }, params) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: params,
+ },
+ }),
+ listen:({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: { nlu: true } /** Local activation of NLU */,
+ }),
+ },
+ }).createMachine({
+ context: {
+ count: 0,
+ // for Who is X part
+ age: undefined,
+ birthday: undefined,
+
+ // for creating meeting part
+ weekdate: undefined,
+ meeting_name: undefined,
+
+ },
+ id: "DM",
+ initial: "Prepare",
+ states: {
+ Prepare: {
+ entry: [
+ assign({
+ ssRef: ({ spawn }) => spawn(speechstate, { input: settings }),
+ }),
+ ({ context }) => context.ssRef.send({ type: "PREPARE" }),
+ ],
+ on: { ASRTTS_READY: "WaitToStart" },
+ },
+ WaitToStart: {
+ on: {
+ CLICK: "PromptAndAsk",
+ },
+ },
+ PromptAndAsk: {
+ initial: "Prompt",
+ states: {
+ Prompt: {
+ entry:[{type: "say", params:`Let's start conversation`}],
+ on: { SPEAK_COMPLETE: "#DM.ProposeQ" },
+ },
+ },
+ },
+ /* jump to one of two questions */
+ ProposeQ: {
+ initial: "proposeQ",
+ states: {
+ proposeQ: {
+ entry: [{type: "say", params:`What's your question?`}],
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [{
+ guard: ({ event }) => event.nluValue.topIntent === "create a meeting",
+ target: "#DM.WhichDate",
+ },
+ {
+ guard: ({ event }) => event.nluValue.topIntent === "who is adam lambert" ,
+ target: "#DM.WhoisAdam",
+ },
+ "#DM.NoQVoice"
+ ],
+ ASR_NOINPUT:"#DM.NoQVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoQVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.ProposeQ"
+ },
+ },
+ },
+ },
+
+ /* Meeting Time */
+ //Answer e.g. Monday to Friday
+ WhichDate: {
+ initial: "whichDate",
+ states: {
+ whichDate: {
+ entry: [{type: "say", params:`On which date is the meeting?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ //e.g. Adam Lambert is 42 years old
+ guard: ({ event }) => event.nluValue.entities[0].text === "Monday" || "Tuesday" || "Wednesday" || "Thursday" || "Friday",
+ actions: [
+ ({ context, event }) => { context.weekdate = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.MeetingTitle",
+ },
+ "#DM.NoWhichDateVoice"
+ ],
+ ASR_NOINPUT:"#DM.NoWhichDateVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoWhichDateVoice: {
+ initial: "noWhichDateVoice",
+ states: {
+ noWhichDateVoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ /* Meeting Title */
+ //Answer e.g. "departmental meeting" || "meeting" || "virtual meeting"
+ MeetingTitle: {
+ initial: "meetingTitle",
+ states: {
+ meetingTitle: {
+ entry: [{type: "say", params:`What's the meeting title?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ //e.g. Adam Lambert is 42 years old
+ guard: ({ event }) => event.nluValue.entities[0].text === "departmental meeting" || "meeting" || "virtual meeting",
+ actions: [
+ ({ context, event }) => { context.meeting_name = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.MeetingInfo",
+ },
+ "#DM.NoMeetingTitleVoice"
+ ],
+ ASR_NOINPUT:"#DM.NoMeetingTitleVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoMeetingTitleVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.MeetingTitle"
+ },
+ },
+ },
+ },
+ /* Repeat the Info of the Meeting */
+ MeetingInfo: {
+ initial: "adamInfo",
+ states: {
+ adamInfo: {
+ entry: [{type: "say", params: ({context}) => `The meeting is on ${context.weekdate} and the meeting title is ${context.meeting_name} `}],
+ on: {
+ SPEAK_COMPLETE: "#DM.Done"
+ },
+ },
+ },
+ },
+
+
+ /* Who is Adam Lambert */
+ //Answer e.g. Adam Lambert is 42 years old
+ WhoisAdam: {
+ initial: "whoisAdam",
+ states: {
+ whoisAdam: {
+ entry: [{type: "say", params:`How old is Adam Lambert?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ //e.g. Adam Lambert is 42 years old
+ guard: ({ event }) => event.nluValue.entities[0].text === "42 years old",
+ actions: [
+ ({ context, event }) => { context.age = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.WhatAdamBirth",
+ },
+ "#DM.NoAdamVoice"
+ ],
+ ASR_NOINPUT:"#DM.NoAdamVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoAdamVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhoisAdam"
+ },
+ },
+ },
+ },
+ /* When is Adam Lambert's birthday */
+ //Answer e.g. Adam Lambert is born in Jan 29th
+ WhatAdamBirth: {
+ initial: "whatAdamBirth",
+ states: {
+ whatAdamBirth: {
+ entry: [{type: "say", params:`When is Adam Lambert's birthday?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ //e.g. Adam Lambert is born in Jan 29th
+ guard: ({ event }) => event.nluValue.entities[0].text === "Jan 29th",
+ actions: [
+ ({ context, event }) => { context.birthday = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.AdamInfo",
+ },
+ "#DM.NoAdamBirthDayVoice"
+ ],
+ ASR_NOINPUT:"#DM.NoAdamBirthDayVoice",
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoAdamBirthDayVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhatAdamBirth"
+ },
+ },
+ },
+ },
+ /* Repeat the Info of the Person */
+ AdamInfo: {
+ initial: "adamInfo",
+ states: {
+ adamInfo: {
+ entry: [{type: "say", params: ({context}) => `Adam Lambert is ${context.age} and his birthday is ${context.birthday} `}],
+ on: {
+ SPEAK_COMPLETE: "#DM.Done"
+ },
+ },
+ },
+ },
+
+ Done: {
+ on: {
+ CLICK: "PromptAndAsk",
+ },
+ },
+ },
+ });
+
+ const dmActor = createActor(dmMachine, {
+ inspect: inspector.inspect,
+ }).start();
+
+ dmActor.subscribe((state) => {
+ /* if you want to log some parts of the state */
+ });
+
+ export function setupButton(element) {
+ element.addEventListener("click", () => {
+ dmActor.send({ type: "CLICK" });
+ });
+ dmActor.getSnapshot().context.ssRef.subscribe((snapshot) => {
+ element.innerHTML = `${snapshot.value.AsrTtsManager.Ready}`;
+ });
+ }
+
\ No newline at end of file
diff --git a/Code/dm5.js b/Code/dm5.js
new file mode 100644
index 0000000..557c0ce
--- /dev/null
+++ b/Code/dm5.js
@@ -0,0 +1,615 @@
+import { and, assign, createActor, setup } from "xstate";
+import { speechstate } from "speechstate";
+import { createBrowserInspector } from "@statelyai/inspect";
+import { KEY } from "./azure.js";
+import { NLU_KEY } from "./azure.js";
+import { sortAndDeduplicateDiagnostics } from "typescript";
+/*
+Regarding improveingNLU coverage, I think I need to add more time datas and person datas to the model.
+*/
+ const inspector = createBrowserInspector();
+ const azureLanguageCredentials = {
+ endpoint: "https://languageresource58888.cognitiveservices.azure.com/language/:analyze-conversations?api-version=2022-10-01-preview" /** your Azure CLU prediction URL */,
+ key: NLU_KEY /** reference to your Azure CLU key */,
+ deploymentName: "appointment" /** your Azure CLU deployment */,
+ projectName: "appointment" /** your Azure CLU project name */,
+ };
+ const azureCredentials = {
+ endpoint:
+ "https://northeurope.api.cognitive.microsoft.com/sts/v1.0/issuetoken",
+ key: KEY,
+ };
+ const settings = {
+ azureLanguageCredentials: azureLanguageCredentials /** global activation of NLU */,
+ azureCredentials: azureCredentials,
+ asrDefaultCompleteTimeout: 0,
+ asrDefaultNoInputTimeout: 5000,
+ locale: "en-US",
+ ttsDefaultVoice: "en-US-DavisNeural",
+ };
+ const grammar_day = {
+ monday: { day: "Monday" },
+ tuesday: { day: "Tuesday" },
+ wednesday: { day: "Wednesday" },
+ thursday: { day: "Thursday" },
+ friday: { day: "Friday" },
+ };
+ function getThreshold(thre) {
+ return thre > 0.85;
+ }
+ function whoIntent(event) {
+ return event === "who is adam lambert";
+ }
+ function helpIntent(event) {
+ return event === "help" || "Help";
+ }
+ function meetIntent(event) {
+ return event === "create a meeting";
+ }
+ function isInDayGrammar(event) {
+ return event.toLowerCase() in grammar_day; }
+ function isInTittleGrammar(event) {
+ return ((event.toLowerCase() === "virtual meeting")||(event.toLowerCase() === "special meeting")||(event.toLowerCase() === "meeting"));
+ }
+
+ /*
+ The ASR threshold is the event.value[0].confidence. So we can use the similar function like getASRThreshold(event.value[0].confidence)
+ to judge the correction. We can use both of event.nluValue.intents[0].confidenceScore and event.value[0].confidence
+ as condition for confirmation. For example:
+
+ getASRThreshold(event.value[0].confidence) === true && getThreshold(event.nluValue.intents[0].confidenceScore) === true
+ to test the model.
+
+
+ */
+
+ const dmMachine = setup({
+ actions: {
+ /* define your actions here */
+ say: ({ context }, params) =>
+ context.ssRef.send({
+ type: "SPEAK",
+ value: {
+ utterance: params,
+ },
+ }),
+ listen:({ context }) =>
+ context.ssRef.send({
+ type: "LISTEN",
+ value: { nlu: true } /** Local activation of NLU */,
+ }),
+ },
+ }).createMachine({
+ context: {
+ count: 0,
+ // for Who is X part
+ age: undefined,
+ birthday: undefined,
+
+ // for creating meeting part
+ weekdate: undefined,
+ meeting_name: undefined,
+
+ },
+ id: "DM",
+ initial: "Prepare",
+ states: {
+ Prepare: {
+ entry: [
+ assign({
+ ssRef: ({ spawn }) => spawn(speechstate, { input: settings }),
+ }),
+ ({ context }) => context.ssRef.send({ type: "PREPARE" }),
+ ],
+ on: { ASRTTS_READY: "WaitToStart" },
+ },
+ WaitToStart: {
+ on: {
+ CLICK: "PromptAndAsk",
+ },
+ },
+ PromptAndAsk: {
+ initial: "Prompt",
+ states: {
+ Prompt: {
+ entry:[{type: "say", params:`Let's start conversation`}],
+ on: { SPEAK_COMPLETE: "#DM.ProposeQ" },
+ },
+ },
+ },
+ /* jump to one of two questions */
+ ProposeQ: {
+ initial: "proposeQ",
+ states: {
+ proposeQ: {
+ entry: [{type: "say", params:`What's your question?`}],
+ on: { SPEAK_COMPLETE: "Ask" },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ guard: ({ event }) => event.nluValue.topIntent === "None",
+ target: "#DM.NotQGrammar",
+ },
+ {
+ guard: (({event}) => meetIntent(event.nluValue.topIntent) && getThreshold (event.nluValue.intents[0].confidenceScore)),
+ target: "#DM.WhichDate",
+ },
+ {
+ guard: (({event}) => meetIntent(event.nluValue.topIntent) && !!(getThreshold (event.nluValue.intents[0].confidenceScore))),
+ target: "#DM.WhichDate",
+ },
+ {
+ guard: (({event}) => whoIntent(event.nluValue.topIntent) && getThreshold (event.nluValue.intents[0].confidenceScore)),
+ target: "#DM.WhoisAdam",
+ },
+ {
+ guard: (({event}) => whoIntent(event.nluValue.topIntent) && !!(getThreshold (event.nluValue.intents[0].confidenceScore))),
+ target: "#DM.WhoisAdam",
+ },
+ // {
+ // guard: ({ event }) => event.nluValue.topIntent === "Help",
+ // target: "#DM.HelpQ",
+ // },
+ "#DM.NotQGrammar",
+
+ ],
+ ASR_NOINPUT:[{
+ guard: ({context}) => context.count >= 3,
+ target: "#DM.Done",
+ },
+ {
+ guard: ({context}) => context.count < 3,
+ actions:({context})=> context.count++,
+ target: "#DM.NoQVoice",
+ }],
+ },
+ },
+ },
+ },
+ MakeSureWhichDate:{
+ initial: "makeSureWhichDate",
+ states: {
+ makeSureWhichDate: {
+ entry: [{type: "say", params:`Do you say create a meeting?`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ MakeSureWho:{
+ initial: "makeSureWho",
+ states: {
+ makeSureWho: {
+ entry: [{type: "say", params:`who is adam lambert`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhoisAdam"
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoQVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.ProposeQ"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotQGrammar: {
+ initial: "notQGrammar",
+ states: {
+ notQGrammar: {
+ entry: [{type: "say", params:`Sorry, I didn't understand. What's your question?, please say "create a meeting" or "who is Adam Lambert"`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.ProposeQ"
+ },
+ },
+ },
+ },
+ /* help */
+ HelpQ: {
+ initial: "helpQ",
+ states: {
+ helpQ: {
+ entry: [{type: "say", params:`You need help?`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.ProposeQ"
+ },
+ },
+ },
+ },
+
+ /* Meeting Time */
+ //Answer e.g. Monday to Friday
+ WhichDate: {
+ initial: "whichDate",
+ states: {
+ whichDate: {
+ entry: [{type: "say", params:`On which date is the meeting?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ guard: ({ event }) => isInDayGrammar(event.value[0].utterance) === false,
+ target: "#DM.NotWhichDateGrammar",
+ },
+ {
+ guard: ({ event }) => isInDayGrammar(event.nluValue.entities[0].text) === true,
+ actions: [
+ ({ context, event }) => { context.weekdate = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.MeetingTitle",
+ },
+ {
+ guard: ({ event }) => event.nluValue.entities[0].text === "Help" || "help",
+ target: "#DM.HelpWhichDate",
+ },
+
+ "#DM.NotWhichDateGrammar",
+ ],
+ ASR_NOINPUT:[{
+ guard: ({context}) => context.count >= 3,
+ target: "#DM.Done",
+ },
+ {
+ guard: ({context}) => context.count < 3,
+ actions:({context}) => context.count++,
+ target: "#DM.NoWhichDateVoice",
+ }],
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoWhichDateVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotWhichDateGrammar: {
+ initial: "notWhichDateGrammar",
+ states: {
+ notWhichDateGrammar: {
+ entry: [{type: "say", params:`Sorry, I didn't understand. please say from Monday to Friday`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ /* help */
+ HelpWhichDate: {
+ initial: "helpWhichDate",
+ states: {
+ helpWhichDate: {
+ entry: [{type: "say", params:`You need help?`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhichDate"
+ },
+ },
+ },
+ },
+ /* Meeting Title */
+ //Answer e.g. "special meeting" || "meeting" || "virtual meeting"
+ MeetingTitle: {
+ initial: "meetingTitle",
+ states: {
+ meetingTitle: {
+ entry: [{type: "say", params:`What's the meeting title?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ guard: ({ event }) => isInTittleGrammar(event.value[0].utterance) === false,
+ target: "#DM.NotMeetingTitleGrammar",
+ },
+ {
+ //Answer e.g. "special meeting" || "meeting" || "virtual meeting"
+ guard: ({ event }) => isInTittleGrammar(event.nluValue.entities[0].text) === true,
+ actions: [
+ ({ context, event }) => { context.meeting_name = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.MeetingInfo",
+ },
+ {
+ guard: ({ event }) => event.nluValue.topIntent == "help" ,
+ target: "#DM.HelpMeetingTitle",
+ },
+ "#DM.NotMeetingTitleGrammar",
+ ],
+ ASR_NOINPUT:[{
+ guard: ({context}) => context.count >= 3,
+ target: "#DM.Done",
+ },
+ {
+ guard: ({context}) => context.count < 3,
+ actions:({context}) => context.count++,
+ target: "#DM.NoMeetingTitleVoice",
+ }],
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoMeetingTitleVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.MeetingTitle"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotMeetingTitleGrammar: {
+ initial: "nogrammar",
+ states: {
+ nogrammar: {
+ entry: [{type: "say", params:`Sorry, I didn't understand. please say departmental meeting or meeting or virtual meeting`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.MeetingTitle"
+ },
+ },
+ },
+ },
+ /* help */
+ HelpMeetingTitle: {
+ initial: "helpMeetingTitle",
+ states: {
+ helpMeetingTitle: {
+ entry: [{type: "say", params:`You need help?`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.MeetingTitle"
+ },
+ },
+ },
+ },
+ /* Repeat the Info of the Meeting */
+ MeetingInfo: {
+ initial: "meetingInfo",
+ states: {
+ meetingInfo: {
+ entry: [{type: "say", params: ({context}) => `The meeting is on ${context.weekdate} and the meeting title is ${context.meeting_name} `}],
+ on: {
+ SPEAK_COMPLETE: "#DM.Done"
+ },
+ },
+ },
+ },
+
+ /* Who is Adam Lambert */
+ //Answer e.g. 42 years old
+ WhoisAdam: {
+ initial: "whoisAdam",
+ states: {
+ whoisAdam: {
+ entry: [{type: "say", params:`How old is Adam Lambert?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ //e.g. Adam Lambert is 42 years old
+ guard: ({ event }) => whoIntent(event.nluValue.topIntent) === false ,
+ target: "#DM.NotWhoGrammar",
+ },
+ {
+ //e.g. 42 years old
+ guard: ({ event }) => event.nluValue.entities[0].text === "42 years old",
+ actions: [
+ ({ context, event }) => { context.age = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.WhatAdamBirth",
+ },
+ {
+ guard: ({ event }) => event.nluValue.topIntent == "help" ,
+ target: "#DM.HelpWho",
+ },
+ "#DM.NotWhoGrammar"
+ ],
+ ASR_NOINPUT:[{
+ guard: ({context}) => context.count >= 3,
+ target: "#DM.Done",
+ },
+ {
+ guard: ({context}) => context.count < 3,
+ actions:({context}) => context.count++,
+ target: "#DM.NoAdamVoice",
+ }],
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoAdamVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhoisAdam"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotWhoGrammar: {
+ initial: "notWhoGrammar",
+ states: {
+ notWhoGrammar: {
+ entry: [{type: "say", params:`Sorry, I didn't understand. please say Adam Lambert is 42 years old`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhoisAdam"
+ },
+ },
+ },
+ },
+ /* help */
+ HelpWho: {
+ initial: "helpWho",
+ states: {
+ helpWho: {
+ entry: [{type: "say", params:`You need help?`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhoisAdam"
+ },
+ },
+ },
+ },
+ /* When is Adam Lambert's birthday */
+ //Answer e.g. Adam Lambert is born in Jan 29th
+ WhatAdamBirth: {
+ initial: "whatAdamBirth",
+ states: {
+ whatAdamBirth: {
+ entry: [{type: "say", params:`When is Adam Lambert's birthday?`}],
+ on: {
+ SPEAK_COMPLETE: "Ask"
+ },
+ },
+ Ask: {
+ entry: "listen",
+ on: {
+ RECOGNISED:
+ [
+ {
+ //e.g. Adam Lambert is born in Jan 29th
+ guard: ({ event }) => whoIntent(event.nluValue.topIntent) ===false ,
+ target: "#DM.NotAdamBirthDayGrammar",
+ },
+ {
+ //e.g. Adam Lambert is born in Jan 29th
+ guard: ({ event }) => whoIntent(event.nluValue.topIntent) === true ,
+ actions: [
+ ({ context, event }) => { context.birthday = event.nluValue.entities[0].text},
+ ],
+ target: "#DM.AdamInfo",
+ },
+ {
+ guard: ({ event }) => event.nluValue.topIntent === "help" ,
+ target: "#DM.HelpAdamBirthDay",
+ },
+ "#DM.NotAdamBirthDayGrammar"
+ ],
+ ASR_NOINPUT:[{
+ guard: ({context}) => context.count >= 3,
+ target: "#DM.Done",
+ },
+ {
+ guard: ({context}) => context.count < 3,
+ actions:({context}) => context.count++,
+ target: "#DM.NoAdamBirthDayVoice",
+ }],
+ },
+ },
+ },
+ },
+ /* Not received voice */
+ NoAdamBirthDayVoice: {
+ initial: "Novoice",
+ states: {
+ Novoice: {
+ entry: [{type: "say", params:`I didn’t hear you`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhatAdamBirth"
+ },
+ },
+ },
+ },
+ /* Not in grammar */
+ NotAdamBirthDayGrammar: {
+ initial: "notAdamBirthDayGrammar",
+ states: {
+ notAdamBirthDayGrammar: {
+ entry: [{type: "say", params:`Sorry, I didn't understand. please say Adam Lambert is born in Jan 29th`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhatAdamBirth"
+ },
+ },
+ },
+ },
+ /* help */
+ HelpAdamBirthDay: {
+ initial: "helpAdamBirthDay",
+ states: {
+ helpAdamBirthDay: {
+ entry: [{type: "say", params:`You need help?`}],
+ on: {
+ SPEAK_COMPLETE: "#DM.WhatAdamBirth"
+ },
+ },
+ },
+ },
+ /* Repeat the Info of the Person */
+ AdamInfo: {
+ initial: "adamInfo",
+ states: {
+ adamInfo: {
+ entry: [{type: "say", params: ({context}) => `Adam Lambert is ${context.age} and his birthday is ${context.birthday} `}],
+ on: {
+ SPEAK_COMPLETE: "#DM.Done"
+ },
+ },
+ },
+ },
+ Done: {
+ on: {
+ CLICK: "PromptAndAsk",
+ },
+ },
+ },
+ });
+
+ const dmActor = createActor(dmMachine, {
+ inspect: inspector.inspect,
+ }).start();
+
+ dmActor.subscribe((state) => {
+ /* if you want to log some parts of the state */
+ });
+
+ export function setupButton(element) {
+ element.addEventListener("click", () => {
+ dmActor.send({ type: "CLICK" });
+ });
+ dmActor.getSnapshot().context.ssRef.subscribe((snapshot) => {
+ element.innerHTML = `${snapshot.value.AsrTtsManager.Ready}`;
+ });
+ }
+
\ No newline at end of file
diff --git a/Code/lab3.mp3 b/Code/lab3.mp3
new file mode 100644
index 0000000..cf45e30
Binary files /dev/null and b/Code/lab3.mp3 differ
diff --git a/Code/lab3.txt b/Code/lab3.txt
new file mode 100644
index 0000000..11e2a58
--- /dev/null
+++ b/Code/lab3.txt
@@ -0,0 +1,19 @@
+Original performance: https://www.youtube.com/watch?v=VjMoRb5f-EQ
+
+
+
+
+
+
+
+
+
+
+
+