/// <summary> /// Attempts to resolve scene entities from LUIS entities. /// </summary> /// <param name="result"> /// The <see cref="LuisMRResult"/> that provides context and storage for the resolution. /// </param> /// <remarks> /// This is stage 3 in processing a LUIS utterance. /// The default implementation enumerates through all objects in the /// <see cref="EntityResolvers"/> and asks them to resolve entities. /// </remarks> protected virtual void ResolveEntities(LuisMRResult result) { foreach (IEntityResolver resolver in entityResolvers) { resolver.Resolve(result); } }
/// <summary> /// Handles the final result for a LUIS prediction. /// </summary> /// <param name="result"> /// The <see cref="LuisMRResult"/> that contains information about the prediction. /// </param> /// <remarks> /// This is stage 4 in processing a LUIS utterance. The default implementation looks for /// a global handler for the specified intent and executes it. If a global handler is not /// found and there is only one mapped entity, the entity will be checked to see if it /// can handle the intent. /// </remarks> protected virtual void HandleIntent(LuisMRResult result) { // Which intent? Intent intent = result.PredictionResult.TopScoringIntent; // Handle the intent foreach (IIntentHandler handler in intentHandlers) { if (handler.CanHandle(intent.Name)) { handler.Handle(intent, result); } } }
/// <summary> /// <inheritdoc/> /// </summary> public void Resolve(LuisMRResult result) { // Loop through all LUIS entities of the specific type MR.InstanceName foreach (Entity entity in result.PredictionResult.Entities["MR.InstanceName"]) { // The Value of this type should be the name in the name table GameObject gameObject = nameTable[entity.Value]; // If it's a valid entity, map it if (gameObject != null) { result.Map(entity, gameObject, this); } } }
/// <summary> /// Find all the scene GameObjects that have names matching the Entity value /// </summary> /// <param name="result"></param> public void Resolve(LuisMRResult result) { // Collect any entities that match the entity names we're looking for List <Entity> predictionEntities = result.PredictionResult.Entities.Where(x => entityNames.Contains(x.Key)).SelectMany(y => y.Value).ToList(); // If there are no entities in the prediction that we're looking for, nothing to do if (predictionEntities.Count < 1) { if (debugMessages) { Debug.Log("No entities in the prediction match the names configured for the resolver."); } return; } // Join the list of scene objects with prediction entities to get matches in the scene IEnumerable <EntityMap> meq = from entity in predictionEntities let entityName = entity.Value.ToLower() from sceneEntity in GameObject.FindObjectsOfType <EntityMetadata>() where entityName.Equals(sceneEntity.EntityName.ToLower()) || entityName.Equals(sceneEntity.EntityType.ToLower()) select new EntityMap() { Entity = entity, GameObject = sceneEntity.gameObject, Resolver = this }; List <EntityMap> matchedEntities = meq.ToList(); //Add all our found entities to the result's entity map, which maps LUIS entities with scene entities. foreach (EntityMap entityMap in matchedEntities) { // Create map entry result.Map(entityMap); // Remove the entity from the prediction list to mark it as "mapped" predictionEntities.Remove(entityMap.Entity); } // If any entity is still in the prediction list, it was not matched. Log a warning. if (debugMessages) { foreach (var entity in predictionEntities) { Debug.LogWarning($"Warning: {entity.Name} \"{entity.Value}\" could not be mapped to the scene."); } } }
/// <summary> /// Reinitializes the event to new values. /// </summary> /// <param name="intent"> /// The <see cref="Intent"/> that should be handled by the event. /// </param> /// <param name="result"> /// The <see cref="LuisMRResult"/> that was returned by the prediction. /// </param> public void Initialize(Intent intent, LuisMRResult result) { // Validate if (intent == null) { throw new ArgumentNullException(nameof(intent)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } // Store Reset(); Result = result; Intent = intent; }
/// <summary> /// Attempts a LUIS prediction on the specified context and if confidence is high enough, the intent is executed. /// </summary> /// <param name="context"> /// Context that is used for the prediction. Additional context may still be collected by /// the <see cref="ContextProviders"/>. /// </param> /// <returns> /// A <see cref="Task"/> that yields the result of the operation as a <see cref="LuisMRResult"/>. /// </returns> /// <remarks> /// At a minimum, <see cref="PredictionContext.PredictionText"/> must be included within the context. /// </remarks> public virtual async Task <LuisMRResult> PredictAndHandleAsync(PredictionContext context) { // Validate if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(context.PredictionText)) { throw new InvalidOperationException("At a minimum, PredictionText must be included within the context."); } // Make sure we have a client EnsureClient(); // Create our result object LuisMRResult mrResult = new LuisMRResult() { Context = context }; // Stage 1: Capture context CaptureContext(context); // Stage 2: Predict using the LUIS client mrResult.PredictionResult = await client.Predict(context.PredictionText); // Only do the next two stages if we have the minimum required confidence if (mrResult.PredictionResult.TopScoringIntent.Score >= MinimumIntentScore) { // Stage 3: Resolve Entities ResolveEntities(mrResult); // Stage 4: Handle Intents HandleIntent(mrResult); } // Done return(mrResult); }
/// <summary> /// <inheritdoc/> /// </summary> public void Handle(Intent intent, LuisMRResult result) { // Validate if (intent == null) { throw new ArgumentNullException(nameof(intent)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } // Make sure event data has been created if (intentEventData == null) { intentEventData = new IntentEventData(EventSystem.current); } // Update event data to current values intentEventData.Initialize(intent, result); // Get all resolved entities List <EntityMap> resolvedEntities = result.GetAllResolvedEntities(); // Forward to all resolved entities foreach (EntityMap map in resolvedEntities) { // Execute on the game object if (SendToChildren) { ExecuteEvents.ExecuteHierarchy(map.GameObject, intentEventData, OnIntentHandler); } else { ExecuteEvents.Execute(map.GameObject, intentEventData, OnIntentHandler); } } }
public void Initialize(Intent intent, LuisMRResult result) { Reset(); Result = result; Intent = intent; }