Beispiel #1
0
        /// <summary>
        /// Returns the entity with the given entity name that appears before the target match.
        /// </summary>
        public LexiconEntityMatch GetEntityBefore(string entityName, LexiconEntityMatch targetMatch)
        {
            LexiconEntityMatch match = null;

            if (!string.IsNullOrEmpty(entityName))
            {
                foreach (LexiconEntityMatch entityMatch in EntityMatches)
                {
                    if (entityMatch == targetMatch)
                    {
                        // Break once we hit the target match.
                        break;
                    }

                    if (string.Equals(entityMatch.Entity.EntityName, targetMatch.Entity.EntityName, StringComparison.OrdinalIgnoreCase))
                    {
                        // Clear the match if we run into another entity of the same type.
                        // E.g. for "Create a red cube and a sphere" color should be null before sphere.
                        match = null;
                    }

                    if (string.Equals(entityMatch.Entity.EntityName, entityName, StringComparison.OrdinalIgnoreCase))
                    {
                        match = entityMatch;
                    }
                }
            }

            return(match);
        }
Beispiel #2
0
        /// <summary>
        /// Returns the entity with the given entity name that appears after the target match.
        /// </summary>
        public LexiconEntityMatch GetEntityAfter(string entityName, LexiconEntityMatch targetMatch)
        {
            LexiconEntityMatch match = null;

            // TODO: I don't like this null check, or the return

            if (!string.IsNullOrEmpty(entityName))
            {
                for (int i = EntityMatches.IndexOf(targetMatch) + 1; i < EntityMatches.Count; i++)
                {
                    LexiconEntityMatch entityMatch = EntityMatches[i];

                    if (string.Equals(entityMatch.Entity.EntityName, targetMatch.Entity.EntityName, StringComparison.OrdinalIgnoreCase))
                    {
                        // Break if we run into another entity of the same type.
                        // E.g. for "Create a cube with a sphere on top" location should be null after cube.
                        break;
                    }

                    if (string.Equals(entityMatch.Entity.EntityName, entityName, StringComparison.OrdinalIgnoreCase))
                    {
                        match = entityMatch;
                        break;
                    }
                }
            }

            return(match);
        }
Beispiel #3
0
        public List <LexiconEntityMatch> GetEntitiesAfter(string entityName, LexiconEntityMatch targetMatch)
        {
            List <LexiconEntityMatch> matches = new List <LexiconEntityMatch>();

            if (!string.IsNullOrEmpty(entityName))
            {
                for (int i = EntityMatches.IndexOf(targetMatch) + 1; i < EntityMatches.Count; i++)
                {
                    LexiconEntityMatch entityMatch = EntityMatches[i];

                    if (string.Equals(entityMatch.Entity.EntityName, targetMatch.Entity.EntityName, StringComparison.OrdinalIgnoreCase))
                    {
                        // Break if we run into another entity of the same type.
                        // E.g. for "Create a cube with a sphere on top" location should be null after cube.
                        break;
                    }

                    if (string.Equals(entityMatch.Entity.EntityName, entityName, StringComparison.OrdinalIgnoreCase))
                    {
                        matches.Add(entityMatch);
                    }
                }
            }

            return(matches);
        }
Beispiel #4
0
        private void HandleWatsonConversationResponse(MessageResponse response)
        {
            LexiconSpeechResult matchingSpeechResult = null;

            object text;
            string utterance = "";

            if (response.input.TryGetValue("text", out text))
            {
                utterance = (string)text;

                // Find the speech to text result that matches this conversation result.
                foreach (LexiconSpeechResult speechResult in finalSpeechResults)
                {
                    if (string.Equals(speechResult.Transcript, utterance, StringComparison.OrdinalIgnoreCase))
                    {
                        matchingSpeechResult = speechResult;
                    }
                }

                if (matchingSpeechResult != null)
                {
                    // Remove the cached speech to text result.
                    finalSpeechResults.Remove(matchingSpeechResult);
                }
            }

            // Make a list of all entity/value pairs in this response.
            List <EntityPair> entityPairs = new List <EntityPair>();

            foreach (RuntimeEntity entity in response.entities)
            {
                entityPairs.Add(new EntityPair(entity.entity, entity.value));
            }

            List <LexiconRuntimeResult> runtimeResults = new List <LexiconRuntimeResult>();
            bool consumed = false;

            // Process each intent (there will only be one if matchMultipleIntents is false).
            // TODO: We may want to process entities even if there isn't an intent match.
            foreach (RuntimeIntent watsonIntent in response.intents)
            {
                if (watsonIntent.confidence < intentConfidenceThreshold)
                {
                    // Ignore intents that don't meet the confidence threshold.
                    continue;
                }

                List <LexiconIntent> matchingIntents = workspace.FindMatchingIntents(watsonIntent.intent, entityPairs);
                LexiconFocusManager  focusManager    = LexiconFocusManager.Instance;

                foreach (LexiconIntent intent in matchingIntents)
                {
                    LexiconRuntimeResult runtimeResult = new LexiconRuntimeResult();
                    runtimeResult.Intent       = intent;
                    runtimeResult.Confidence   = watsonIntent.confidence;
                    runtimeResult.Utterance    = utterance;
                    runtimeResult.SpeechResult = matchingSpeechResult;

                    foreach (RuntimeEntity watsonEntity in response.entities)
                    {
                        // Find the entity and entityValue that match this intent.
                        LexiconEntity      entity;
                        LexiconEntityValue entityValue = intent.FindEntityValue(watsonEntity.entity, watsonEntity.value, out entity);
                        if (entityValue != null)
                        {
                            LexiconEntityMatch entityMatch = new LexiconEntityMatch();
                            entityMatch.Entity         = entity;
                            entityMatch.EntityValue    = entityValue;
                            entityMatch.FirstCharacter = watsonEntity.location[0];
                            entityMatch.LastCharacter  = watsonEntity.location[1] - 1; // Convert to index of last character.

                            if (matchingSpeechResult != null)
                            {
                                // Find the entity in the speech to text transcript and extract the timestamps.
                                LexiconSpeechResult.WordResult[] wordResults = matchingSpeechResult.GetWordsFromTranscriptPositions(entityMatch.FirstCharacter, entityMatch.LastCharacter);
                                if (wordResults.Length > 0)
                                {
                                    entityMatch.TimeStart     = wordResults[0].TimeStart;
                                    entityMatch.TimeEnd       = wordResults[wordResults.Length - 1].TimeEnd;
                                    entityMatch.RealtimeStart = wordResults[0].RealtimeStart;
                                    entityMatch.RealtimeEnd   = wordResults[wordResults.Length - 1].RealtimeEnd;

                                    if (useDwellPosition)
                                    {
                                        FocusDwellPosition dwellPosition = focusManager.GetFocusData <FocusDwellPosition>(entityMatch.RealtimeStart, 0.2f);
                                        if (dwellPosition != null)
                                        {
                                            FocusPosition focusPosition = new FocusPosition();
                                            focusPosition.Timestamp = dwellPosition.Timestamp;
                                            focusPosition.Position  = dwellPosition.Position;
                                            focusPosition.Normal    = dwellPosition.Normal;

                                            entityMatch.FocusPosition = focusPosition;
                                        }
                                        else
                                        {
                                            entityMatch.FocusPosition = focusManager.GetFocusData <FocusPosition>(entityMatch.RealtimeStart);
                                        }
                                    }
                                    else
                                    {
                                        entityMatch.FocusPosition = focusManager.GetFocusData <FocusPosition>(entityMatch.RealtimeStart);
                                    }

                                    entityMatch.FocusSelection = focusManager.GetFocusData <FocusSelection>(entityMatch.RealtimeStart);
                                }
                            }

                            runtimeResult.EntityMatches.Add(entityMatch);
                        }
                    }

                    runtimeResult.EntityMatches.Sort((x, y) => x.FirstCharacter.CompareTo(y.FirstCharacter));

                    runtimeResults.Add(runtimeResult);

                    if (!consumed)
                    {
                        // If an action has consumed this result no other actions will be fired.
                        // But, we continue to process the intents for the global handler.
                        consumed = intent.Process(runtimeResult);
                    }
                }
            }

            if (OnLexiconResults != null)
            {
                // Share runtime results with our delegates.
                OnLexiconResults(runtimeResults);
            }
        }