| VoiceXML 2.1 Development Guide | Home | Frameset Home |
|
<log> element
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" >
<meta name="maintainer" content="yourEmail@here.com"/>
<form>
<field name="F_1" slot="F_1">
<prompt>
what is your favorite soda pop?
Is it sprite, pepsi, coca cola, or tab?
</prompt>
<grammar type="text/gsl">
<![CDATA[[
(coka cola) { <F_1 "coke"> }
[pepsi] { <F_1 "pepsi"> }
[sprite] { <F_1 "sprite"> }
[tab] { <F_1 "tab"> }
]]]>
</grammar>
<filled>
<prompt> you said <value expr="F_1$.utterance"/>. </prompt>
</filled>
</field>
</form>
</vxml>
<value expr="fieldName$.objectName"/>
<log expr="fieldName$.objectName"/>
<value expr="lastresult$.objectName"/>
<log expr="lastresult$.objectName"/>
<value expr="F_1$.utterance.F_1"/> would return a value of "coka cola" rather than "coke." <log expr="F_1$.interpretation.F_1"/> into the above code, we would likely see:
VariableScope::eval: F_1$.interpretation.F_1 resulted in {F_1=coke}
VOICEXML - INFO: {F_1=coke}
<log> element within the <filled> portion of our script; this makes variable tracking during the debugging process as easy as pie. And as we all know, pie is yummy, and goes well with soda pop. For this example, we have included both of the shadow variable syntaxes for illustrative purposes, and included them in the resultant prompts so as to read back the values to the caller.
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">
<meta name="maintainer" content="yourEmail@here.com"/>
<form>
<field name="F_1" slot="F_1">
<prompt>
what is your favorite soda pop?
Is it sprite, pepsi cola, coca cola, or tab?
</prompt>
<grammar type="text/gsl">
<![CDATA[[
(coka cola) { <F_1 "coke"> }
[pepsi] { <F_1 "pepsi"> }
[sprite] { <F_1 "sprite"> }
[tab] { <F_1 "tab"> }
]]]>
</grammar>
<filled>
<log expr="'**********************************************'"/>
<log expr="'CONFIDENCE = ' +lastresult$.confidence"/>
<log expr="'UTTERANCE = ' + lastresult$.utterance"/>
<log expr="'INPUTMODE = ' + lastresult$.inputmode"/>
<log expr="'INTERPRETATION = ' + lastresult$.interpretation.F_1"/>
<log expr="'**********************************************'"/>
<prompt>
the confidence value is was <value expr="F_1$.confidence"/>,
and the utterance was <value expr="F_1$.utterance"/>.
You entered the information in via <value expr="F_1$.inputmode"/>.
</prompt>
</filled>
</field>
</form>
</vxml>
RECORD DURATION = 2970
VOICEXML - INFO: RECORD DURATION = 2970
<if cond="R_1$.size < 0">
<!--dont do anything-->
<else/>
<submit next="Myserver.com"/>
RECORD FILESIZE = 23818
VOICEXML - INFO: RECORD FILESIZE = 23818
- DTMF:6
- Ended recording
- { dtype=1 status="INTERRUPTED_BY_DTMF" fileName="C:\temp\vdk1\audiocache\b1\b1_2.wav" detectedTones="6" }
- RECORD TERMCHAR = 6
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" >
<meta name="maintainer" content="yourEmail@here.com"/>
<form>
<field name="F_1" slot="F_1">
<prompt>
what is your favorite soda pop?
Is it sprite, pepsi cola, coca cola, or tab?
</prompt>
<grammar type="text/gsl">
<![CDATA[[
(coka cola) { <F_1 "coke"> }
[pepsi] { <F_1 "pepsi"> }
[sprite] { <F_1 "sprite"> }
[tab] { <F_1 "tab"> }
]]]>
</grammar>
<filled>
<log expr="'**********************************************'"/>
<log expr="'CONFIDENCE = ' + lastresult$.confidence"/>
<log expr="'UTTERANCE = ' + lastresult$.utterance"/>
<log expr="'INPUTMODE = ' + lastresult$.inputmode"/>
<log expr="'INTERPRETATION = ' + lastresult$.interpretation.F_1"/>
<log expr="'**********************************************'"/>
<prompt>
the confidence value is was <value expr="F_1$.confidence"/>,
and the utterance was <value expr="F_1$.utterance"/>.
You entered the information in via <value expr="F_1$.inputmode"/>.
</prompt>
</filled>
</field>
<record name="R_1" beep="true" maxtime="15s" finalsilence="3000ms">
<prompt>
tell us why you like <value expr="lastresult$.utterance"/> so much,
and then press a DTMF key to end the recording.
</prompt>
<filled>
<log expr="'**********************************************'"/>
<log expr="'RECORD DURATION = ' + R_1$.duration"/>
<log expr="'RECORD FILESIZE = ' + R_1$.size"/>
<log expr="'RECORD TERMCHAR = ' + R_1$.termchar"/>
<log expr="'**********************************************'"/>
<prompt>
you said that the reason that you liked
<value expr="F_1$.utterance"/>
was
<value expr="R_1"/>
<break strength="medium"/>
In addition, our re cord shadow variable for duration is
<value expr="R_1$.duration"/>
milliseconds, the size of the re cording is
<value expr="R_1$.size"/>
bytes, and the DTMF key you pressed was
<value expr="R_1$.termchar"/>.
Lastly, the boo leean value indicating if max time was hit resulted in
<value expr="R_1$.maxtime"/>.
</prompt>
</filled>
</record>
</form>
</vxml>
<value> and <log> statements <record> shadow variables that define information about a caller's recording <log> statements to gain additional information helpful to tuning an application| ANNOTATIONS: EXISTING POSTS |
henryanelson
|
|
| Where is the negative comment about TAB specified? | |
MattHenry
|
|
|
Hello Henry, I'm relly sorry, but I don't have any idea at all what it is that you are referencing. I'd be glad to address this for you if you need help, but I would definitely need more clarity in order to do so. ~Matthew Henry |
|
emeijer
|
|
| Hi,
Is there any way to access to shadow variables inside a <nomatch> block ? I realize that if there is no match, things like utterance have no meaning, so probably I am on the wrong track and hence let me explain what I want to accomplish, perhaps you will point me in a different direction... Taking the above example...let's assume the user tried to say "sprite", but doesn't remember the exact brand name and says "spirit". Also assume the vxml program doesn't match spirit to sprite and generates a <nomatch> event and keeps reprompting the user to say his favorite soda, etc. What I want to do, is break the <nomatch> loop, (say after the second <nomatch> event) and help the user by suggesting what his favorite soda pop is... "did you perhaps say <sugestion>?"... Obviously, I want to suggest the soda whose name is the closest to whatever soda name the user said..... for that I either need to get some sort of ranking on which of the grammar elements (pepsi, sprite, coka cola or tab) was the "closest"... even though the VXML engine decided that none of them passed the threshold and were a match. Question: can you get an array with match scores for each of the grammar elements ? I also thought about doing a simple edit-distance match on the string the user spoke and the soda's as defined in the grammar, but I would prefer the ranking or score list instead. The last resort I have is to suggest a random soda... in this example I would have a 25% chance of making the application look intelligent; I like to do better. |
|
MattHenry
|
|
|
Let's tackle these questions one by one: [b]Is there any way to access to shadow variables inside a <nomatch> block ?[/b] - This feature is currently not available on our platform, but we do have this in our queue to add this feature request. It is my understanding that the inclusion of this feature will take some significant engineering to enable, so I do not have a specific deployment date at this time. [b]Question: can you get an array with match scores for each of the grammar elements ?[/b] - I think what you'd really want to use is some nBest post processing, which will output an array of possible matches ranked by probabaility. Check the very next tutorial in our docset for details. ~Matthew henry |
|
emeijer
|
|
| okay, but to use the nBest technique, I still need to have at least a match with one of the items in the grammar; only once there is a match, then I will have access to an array with lastresult$ values and can try to suggest to the user he wants a sprite.
Going back to the example, if the user meant to say sprite, but said spirit instead with wasn't matched, then I could tweak the "confidencelevel" property; i.e. lower it enough such that spirit will match at least with one of them (hopefully with sprite).. but I guess if you lower the confidence level enough, you will get false matches on coke, pepsi and anything else ... I am not so sure if this an alternative for getting access to the lastresult$ values during nomatch events, is it ? |
|
MattHenry
|
|
|
Edwin, You are correct in your understanding about the n-best array in how it relates to a Nomatch event: My last posting on the subject of match scores wasn't really in context with the topic of getting array values back in an OOGNI event, but was a generalistic response: Apologies if I didn't read into the reasoning behind your question accurately. As this is the case, the abiality to access the array values in a nomatch event is going to be pending the deployment of this feature at the platform scope. I can say that this is in our engineering queue, but I also wanted to again caution you that this change to the browser is not a trivial one, and will take some time to code, and QA, and finally deploy. Regards, ~Matthew Henry |
|
awirtz
|
|
| Edwin, might I suggest that for your scenario, the best solution might be to lower the confidence level to 0.1 so that the grammar (almost) always hits the "filled" block, then inside the "filled" block, use an "if" to compare lastresult$.confidence against your intended confidence cutoff, and based on the result of that logic, either accept the recognition as is, or attempt to confirm via yes/no the closest match. (if you also throw nBest into the mix, you can run down a list of probable matches from most to least likely, prompting yes/no on each if you wanted, but in my example, if the guess is wrong, I simply return to the original prompt.)
<?xml version="1.0" encoding="UTF-8"?> <vxml version = "2.1"> <form> <field name="F_1" slot="F_1"> <property name="confidencelevel" value="0.1"/> <prompt> What is your favorite soda pop? Is it sprite, pepsi cola, coca cola, or tab? </prompt> <grammar type="text/gsl"> <![CDATA[[ (coka cola) { <F_1 "coke"> } [pepsi] { <F_1 "pepsi"> } [sprite] { <F_1 "sprite"> } [tab] { <F_1 "tab"> } ]]]> </grammar> <filled> <if cond="F_1$.confidence > 0.45"> <goto nextitem="B_1"/> </if> </filled> </field> <field name="F_2" slot="F_2"> <property name="confidencelevel" value="0.45"/> <prompt> Did you say <value expr="F_1"/>? </prompt> <grammar type="text/gsl"> <![CDATA[[ [yes] { <F_2 "yes"> } [no] { <F_2 "no"> } ]]]> </grammar> <filled> <if cond="F_2 == 'yes'"> <goto nextitem="B_1"/> <else/> <assign name="F_1" expr="undefined"/> <assign name="F_2" expr="undefined"/> <goto nextitem="F_1"/> </if> </filled> </field> <block name="B_1"> <prompt> Good choice! I like <value expr="F_1"/> too. </prompt> <exit/> </block> </form> </vxml> Note: the line that reads "<if cond="F_1$.confidence > 0.45">" should have a "& g t ;" (minus the spaces) in the cond attribute instead of the ">", but the notes system here won't let me type it that way :( |
|
VoxeoTony
|
|
| Hello awirtz,
Thank you for posting a very good example for the forum. This is a good was for folks to see nBest in action, and to capture misses and gently get them back to the question. I hope this is useful to t_3 with developing VoiceXML applications. Regards, Tony |
|
stuartgielen
|
|
| Is there an equivalent to the 'termchar' shadow variable for the field element?
I have the following scenario: -ask caller to enter 8 digit number followed by hash, or enter * if they stuffed up and want to re-enter the number (ie "12345678#" means "ok, go ahead with this number" and "12348*" means "oops, I made a mistake and want to try again". Both * and # are defined as input ending characters, but need to know which one was entered. I know I can remove the * as an input character and allow it in the grammar, but don't want the caller to wait a few seconds for the input to time-out. I am new to this site, so please let me know if there's a better spot to ask this question. Thanks, Stuart Gielen. |
|
MattHenry
|
|
|
Hello Stuart, There isn't an equivalent for the "termchar" shadow variable for an input field, (aside from the record element), but we can easily work around this. Considering your test case where we want 8 digits followed by # or *, we would want to take the following steps: 1) Set the 'termchar' property to a null value, (using "@" should do the trick for voice center 5.5). If you are using Prophecy, I can probably figure a way to specify this, if you can confirm the platform that you are using. 2) Specify a *nine* digit grammar for the field that includes the * and # keys as valid input. 3) Use some client-side scripting to pull out the last character entered, and define it as a variable value. 4) Use conditional logic to determine which 'termchar' the user pressed: <if cond="mytermChar == '#'"> <!-- do something --> <elseif cond="mytermChar == '*'"> <!-- do something else--> ... Hope this helps out, ~Matthew henry |
|
stuartgielen
|
|
| Hi Matthew,
Thanks for your quick response. The problem is though that the user can cancel the input with the * after less than 8 digits, eg "1234*". And to avoid the end-of-input time-out we need to specify the * key as a termchar. Thanks, Stuart. |
|
jbassett
|
|
| Hello,
You will most likely want to use the <link> attribute. You can set a key press to a global grammar. So in theory you should be able to define dtmf-star at the application root, and use link next to point to the beginning of the section that asks for the customer to input the numbers. This would simulate customer making a mistake, pressing star, and then getting reprompted. 1 ) Define an application root document: details on this can be found at the two links below; the second link contains sample code that illustrates this exact concept: http://www.w3.org/TR/voicexml20/#dml1.5.2 http://docs.voxeo.com/voicexml/2.0/vxml.htm See samples: <AppRoot.vxml> <Vxml application-xml:base> For your global grammar, you will want to define a <link> within the approot. Something along the lines of this: <link next="transferPage.xml"> <grammar>[dtmf-star]</grammar> </link> The next attribute of <link> allows us to specify a URI to go to. This URI is a document (perhaps with an anchor to specify the starting dialog), or a dialog in the current document (just a bare anchor). You can find code samples for the usage of this element as well within our documentation: http://docs.voxeo.com/voicexml/2.0/link.htm Let us know if you require any additional assistance, Thanks, Jesse Bassett |
|
stuartgielen
|
|
| Hi Jesse,
Thanks for that, learned something new again ;) The link attribute works fine, but again not straight away. After we press * it still waits for the interdigittimeout to pass before the link event is triggered. So it still doesn't give us the desired result. I do have a solution for the long term (but doesn't help me now). We are using Genesys Voice Platform 7.2. I had a look at the release notes for 7.5 which is due later this year and that includes a platform-specific property called "com.genesys.returntermchar" which will do the trick for us. Thanks for all your responses. |
|
jassy
|
|
| Hi Voxeo Team,
I have a problem with my code. My vxml page : <?xml version="1.0"?> <vxml version="2.0" xmlns = "http://www.w3.org/2001/vxml"> <form id = "main"> <field name="getChoice"> <prompt> enter an item of your choice </prompt> <grammar src="main.grxml" type="application/srgs+xml"/> <filled> <prompt> got it. you said <value expr="getChoice$.interpretation"/> and the shadow variables are <value expr="getChoice$.confidence"/> and <value expr="getChoice$.inputmode"/> and <value expr="getChoice$.utterance"/> </prompt> </filled> </field> </form> </vxml> and my grammar simply looks like this : <?xml version="1.0"?> <grammar version="1.0" xmlns="http://www.w3.org/2001/06/grammar" mode="voice" xml:lang="en-US" root="sayThing"> <rule id="sayThing"> <one-of> <item> paper <tag> getChoice ="paper" </tag> </item> <item> keyboard <tag> getChoice ="keyboard" </tag> </item> <item> mouse <tag> getChoice ="mouse" </tag> </item> </one-of> </rule> </grammar> When i have the same grammar file as an inline grammar, it is workingn perfectly. It is playing all the shadow variable values. But when i write the grammar an an external one, i have a problem. It is not playing the confidence level of the input. For ex: When i say "paper" as speech input, It plays "Got it. you said paper and the shadow variables are '' and 'voice' and 'paper'. I ported my application on Avaya IR. Someone please help me out on this. Thanks and Regards, Jassy. |
|
MattHenry
|
|
|
Hello Jassy, Ideally, it would be beneficial to see application debugger logs that would help illustrate the problem, but I *think* I see what you are trying to do here. If this is meant to be an SRGS grammar with SISR formatted returns, then I think you will want to insert a semicolon after your return values: <item> paper <tag> getChoice ="paper"; </tag> </item> <item> keyboard <tag> getChoice ="keyboard"; </tag> </item> <item> mouse <tag> getChoice ="mouse"; </tag> </item> Can you give this a try, and let us know how this works out? ~Matthew Henry |
|
jassy
|
|
| Hi Henry,
I tried your suggestion too. But no change in the result. Anyway i could solve the problem. On Avaya IR, to get the confidence, the shadow variable is "slotconf" which is platform-dependant. Thanks a lot for the timely suggestion. Regards, Jassy |
|
ryao
|
|
| Hi,
I've inserted a menu$.utterance field into my log and notice some strange behaviors. By the way my application is an outbound dialing app. When i dial my own cell for instance and answer it, .utterance recognizes what i'm saying based on my grammars. But what I'm trying to do is call our IVR systems.. that say " Thank you for calling Company XYZ, to do this press 1... etc." But I always get a nomatch returned. Even when i put the confidence level to 0.1 as advised earlier it still doesn't recognize. Using Avaya IR, btw. I'm trying to create a monitoring application that dials IVR's every 5-10 minutes to make sure they are working fine. Any ideas ? |
|
VoxeoDustin
|
|
| Hey ryao,
Would it be possible for you to enter a support ticket with a sample of the code you're using and what your trying to do so our support team can better assist you? Thanks, Dustin |
|
mtatum111
|
|
| I am trying to understand when you would use
application.lastresult$[0].confidence vs. name$.confidence where name is the name of the field. Are these two interchangable? Thanks for any insight on the differences between these two. |
|
voxeoJeffK
|
|
| Hi,
No, they are not interchangeable. name$.confidence is specific to the input item with that *name*, and application.lastresult$[0].confidence is the last input item filled. Consider the following script: <?xml version="1.0" encoding="UTF-8" ?> <vxml version="2.1"> <form> <field name="foo"> <prompt> . Speak now to fill foo .</prompt> <grammar type="text/gsl">[one two]</grammar> <filled> <prompt>you said <value expr="foo"/></prompt> </filled> </field> <field name="bar"> <prompt> . Speak now to fill bar .</prompt> <grammar type="text/gsl">[one two]</grammar> <filled> <log expr="'BAR.CONFIDENCE: ' + bar$.confidence"/> <log expr="'LASTRESULT[0]: ' + application.lastresult$[0].confidence"/> <log expr="'LASTRESULT: ' + application.lastresult$.confidence"/> <log expr="'FOO.CONFIDENCE: ' + foo$.confidence"/> </filled> </field> </form> </vxml> This will print the log statements as follows: LOG: BAR.CONFIDENCE: 0.54 LOG: LASTRESULT[0]: 0.54 LOG: LASTRESULT: 0.54 LOG: FOO.CONFIDENCE: 0.43 Also, as a side note you need not reference the array index of lastresult$ since you must already specify the key name, i.e. lastresult$.confidence instead of lastresult[0].confidence. hope that helps, Jeff K. |
|
mtatum111
|
|
| Thanks, Jeff. That does bring up another question about variable scoping :)
From the tutorial on Variable scoping we have the following. Anonymous Scoped Variables Variables of anonymous scope are variables which are declared within form items, such as within a <block> or within a <field>. They will only be considered active when the application visits and executes these form items. However, in the following we are referencing foo$.confidence inside of <filled> for <field name="bar">. I thought that this variable foo$.confidence would only be available inside of <field name="foo"> Am I missing something here? Thanks <form> <field name="foo"> <prompt> . Speak now to fill foo .</prompt> <grammar type="text/gsl">[one two]</grammar> <filled> <prompt>you said <value expr="foo"/></prompt> </filled> </field> <field name="bar"> <prompt> . Speak now to fill bar .</prompt> <grammar type="text/gsl">[one two]</grammar> <filled> <log expr="'BAR.CONFIDENCE: ' + bar$.confidence"/> <log expr="'LASTRESULT[0]: ' + application.lastresult$[0].confidence"/> <log expr="'LASTRESULT: ' + application.lastresult$.confidence"/> <log expr="'FOO.CONFIDENCE: ' + foo$.confidence"/> </filled> </field> </form> |
|
VoxeoDustin
|
|
| Hey Melissa,
Since foo is defined within the same form as the 'bar' field, this variable is still valid, as anonymous variables are valid within the form that they are defined. If we transition to another form, however, this variable will no longer be defined. Cheers, Dustin |
|
mtatum111
|
|
| Dustin, I am sorry for being a pest :)
After reading the spec, I see what you are saying. I guess what confuses me is a previous question that I posted. In the example below, Jeff had told me that When you scope a <filled> within an input item like <field> then ONLY that input item's variable is eligible to trigger the <filled>.So, if that was the case, I didn't understand how foo$.confidence would be eligible. However, I did test it out on voxeo and you can access this variable. In that case, is the below wrong - or am I missing the mark on this one. Thanks for any insight. Here is the previous post - Is there any reason to have <filled> as first element in <form>? I would think that you would have it after or within <field> element. I had been presented the following question <form> [ 1 ] <field name = "hours_worked" type = "number"> <prompt> What are the number of hours worked? </prompt> [ 2 ] </field> <field name = "days_worked" type = "number"> <prompt> How many days have you worked? </prompt> [3 ] </field> [ 4] </form> Where can the following code be placed to guarantee that the value of hours_worked is greater than 40 when the user answers the prompt "What are the number of hours worked?" (There may be more than one correct answer.) Here I was told the answer is 1,2,4. However, I don't see why the answer would be 2,3,4. Can you let me know what you think? <filled> <if cond = "hours_worked" <= 40"> <clear namelist = "hours_worked"/> </if> </filled> voxeoJeffK 9/12/2008 1:35 AM (EDT) Hi, The issue here is a matter of scoping. When a <filled> is scoped within a form then by default ALL of that form's input items(such as <fields>) are eligible. In your example placements [1] and [4] would apply here. So placement [2] is valid since it is scoped within the "hours_worked" field. Placement [3] is not valid since it is scoped within the "days_worked" field. Thus the answer is indeed 1,2,4. hope that helps, Jeff K. |
|
VoxeoDustin
|
|
| Hey Melissa,
Jeff's answer is correct. Variable scoping and <filled> scoping are two unrelated things. Here we are scoping a variable within a form, so that variable is valid anywhere within that scope, including the <filled> that is a grandchild of <form>, regardless which <field> that <filled> is a child of. As Jeff mentioned in his example, when a filled is scoped at the form level, all fields are eligible, so 1 and 4 will both match when the field is satisfied, since they would be children of <form>. 2 is also valid, as it is a child of the first field, meaning it is eligible when the first field is completed. 3 is not valid as it is a child of the second field and is not eligible to be visited when the first field is satisfied. Let me know if this helps clarify. Thanks, Dustin |
|
mtatum111
|
|
| Dustin, it is me again :)
I wrote a small test app to try out on voxeo. From this app, I am able to access hours_worked variable. Isn't this kind of contradicting what our original thought was that from within <filled> of <field name="days_worked"> that we can not access hours_worked but can only access days_worked variable. sorry for dragging this on and on... I am just trying to get prepared for my certification test. <?xml version="1.0" encoding="UTF-8"?> <vxml version = "2.1" > <form> <field name="hours_worked" type="number"> <prompt>What are hours worked? </prompt> </field> <field name="days_worked" type="number"> <prompt>Number of days worked?</prompt> <filled> <if cond ="hours_worked<=40"> <clear namelist = "hours_worked"/> <prompt>Not enough hours worked </prompt> <else/> <prompt>You will be getting your paycheck shortly. </prompt> </if> </filled> </field> </form> </vxml> |
|
VoxeoDustin
|
|
| Hey Melissa,
The hours_worked variable will be accessible anywhere within the form that is in, including the filled of another field - any variable defined at the form(anonymous scope) is available at any point within that form, its children, or grandchildren, etc. However, since that <filled> is scoped within another <field>, it is not eligible to be visited when the first <field> is satisfied. Once you've entered the number of hours worked, execution will move on to the next field. If the filled were scoped at <form> level, or within the first <field>(e.g. 1, 2, or 4 in the example), then execution would move to the <filled> next. Cheers, Dustin |
|
mtatum111
|
|
| Dustin, I got it. Thanks for the thorough explanation! |
| login |
|