Complex logic at the start of conversation
To be more human-like, it may be necessary to implement special behavior at the start of the conversation. Generally, it could be described with the following requirements:
- Do not speak until interlocutor starts speaking
- But still ping interlocutor with "hello" if silence is too long
- Start to speak as soon as interlocutor start speaking
- When interlocutor finishes a speech, proceed with the dialogue whether the phrase was recognized or not
Let's start from a relatively simple example, implementing 4 and partially implementing 1 and 3. In this example, we won't use a common dialogue library.
context { input phone: string, } start node greeting { do { #connectSafe($phone); // Wait until 500 is left or speech is detected. #waitForSpeech(500); #sayText("Hello!"); wait *; } transitions { inviteToTalk: goto inviteToTalk on true; } } node inviteToTalk { do { // Just proceed with a standard flow from now on. #sayText("Do you want to talk with me?"); exit; } }
Now, let's add common dialogue and fully implement all requirements. This example is pretty monstrous, in particular, the digression control interface is verbose, but we're working on it.
import "commonDialogue.dsl"; context { input phone: string, output status:string?, output serviceStatus:string?, output callBackDetails:string?, } start node greeting { do { if(#getVisitCount("greeting") < 2) { #connectSafe($phone); } // Disable all common dialogue digressions except `hello`, `answeringMachine`, // `iWillCallBack` and `sorryWontCall` to prevent undesired digressions // (such as "dont understand") from triggering. // Note, that non-disabled digressions still may trigger. digression disable { can_hear_you, dont_understand, dont_understand_preprocessor, i_am_robot, reactive_listening, repeat_preprocessor, repeat, @wait }; // Wait until 500 is left or speech is detected. if (!#waitForSpeech(500)) { // If 500 is left but no speech is detected, // re-enter this node. // Note that here `hello` digression also may trigger. wait { self }; } #sayText("Hello!"); // Here, only `inviteToTalk`, `iWillCallBack` and `sorryWontCall` may be triggered. wait { inviteToTalk }; } transitions { inviteToTalk: goto inviteToTalk on true; // This transition will compete with `hello` digression. // If enough time is left for `hello` digression to trigger, // it will trigger because its priority is higher. // When `hello` return, this transition will be triggered by the following tick. self: goto greeting on true priority -1000 tags: ontick; } onexit { inviteToTalk: do { // Enable all digressions back. digression enable { can_hear_you, dont_understand, dont_understand_preprocessor, i_am_robot, reactive_listening, repeat_preprocessor, repeat, @wait }; } } } node inviteToTalk { do { // Just proceed with a standard flow from now on. #sayText("Do you want to talk with me?"); exit; } }
Found a mistake? Let us know.