diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj index 34d02201..fe97aadc 100644 --- a/BotSharp.Core/BotSharp.Core.csproj +++ b/BotSharp.Core/BotSharp.Core.csproj @@ -34,10 +34,6 @@ TRACE;MODEL_PER_CONTEXTS - - - - diff --git a/BotSharp.Core/Engines/Dialogflow/AIContext.cs b/BotSharp.Core/Engines/Dialogflow/AIContext.cs index f89ecfc8..451fe0ac 100644 --- a/BotSharp.Core/Engines/Dialogflow/AIContext.cs +++ b/BotSharp.Core/Engines/Dialogflow/AIContext.cs @@ -12,7 +12,7 @@ namespace BotSharp.Core.Models public string Name { get; set; } [JsonProperty("parameters")] - public Dictionary Parameters { get; set; } + public Dictionary Parameters { get; set; } /// /// Lifespan of the context measured in requests```` diff --git a/BotSharp.Core/Engines/Dialogflow/AIDataService.cs b/BotSharp.Core/Engines/Dialogflow/AIDataService.cs index ec82d678..49091548 100644 --- a/BotSharp.Core/Engines/Dialogflow/AIDataService.cs +++ b/BotSharp.Core/Engines/Dialogflow/AIDataService.cs @@ -1,6 +1,7 @@ using BotSharp.Core.Engines.Dialogflow.Http; using BotSharp.Core.Models; using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using System.Diagnostics; @@ -47,7 +48,8 @@ namespace BotSharp.Core.Engines.Dialogflow var jsonSettings = new JsonSerializerSettings { - NullValueHandling = NullValueHandling.Ignore + NullValueHandling = NullValueHandling.Ignore, + ContractResolver = new CamelCasePropertyNamesContractResolver() }; var jsonRequest = JsonConvert.SerializeObject(request, Formatting.None, jsonSettings); diff --git a/BotSharp.Core/Engines/Dialogflow/AIResponseResult.cs b/BotSharp.Core/Engines/Dialogflow/AIResponseResult.cs index 4fc59506..4e7e5b54 100644 --- a/BotSharp.Core/Engines/Dialogflow/AIResponseResult.cs +++ b/BotSharp.Core/Engines/Dialogflow/AIResponseResult.cs @@ -31,7 +31,7 @@ namespace BotSharp.Core.Models } } - public Dictionary Parameters { get; set; } + public Dictionary Parameters { get; set; } public AIContext[] Contexts { get; set; } diff --git a/BotSharp.Core/Engines/Dialogflow/ApiAi.cs b/BotSharp.Core/Engines/Dialogflow/ApiAi.cs index 6f3c14b0..84d02eb5 100644 --- a/BotSharp.Core/Engines/Dialogflow/ApiAi.cs +++ b/BotSharp.Core/Engines/Dialogflow/ApiAi.cs @@ -8,18 +8,15 @@ namespace BotSharp.Core.Engines.Dialogflow { public class ApiAi : ApiAiBase, IBotPlatform { - private readonly AIConfiguration config; - private readonly AIDataService dataService; - - public ApiAi(AIConfiguration config) - { - this.config = config; - - dataService = new AIDataService(this.config); - } + private AIDataService dataService; public AIResponse TextRequest(string text) { + if (dataService == null) + { + dataService = new AIDataService(AiConfig); + } + if (string.IsNullOrEmpty(text)) { throw new ArgumentNullException("text"); @@ -35,6 +32,11 @@ namespace BotSharp.Core.Engines.Dialogflow throw new ArgumentNullException("request"); } + if(dataService == null) + { + dataService = new AIDataService(AiConfig); + } + return dataService.Request(request); } @@ -45,17 +47,17 @@ namespace BotSharp.Core.Engines.Dialogflow throw new ArgumentNullException("text"); } + if (dataService == null) + { + dataService = new AIDataService(AiConfig); + } + return TextRequest(new AIRequest(text, requestExtras)); } - public AIResponse VoiceRequest(Stream voiceStream, RequestExtras requestExtras = null) + public void Train() { - if (config.Language == SupportedLanguage.Italian) - { - throw new AIServiceException("Sorry, but Italian language now is not supported in Speaktoit recognition. Please use some another speech recognition engine."); - } - - return dataService.VoiceRequest(voiceStream, requestExtras); + throw new NotImplementedException(); } } } diff --git a/BotSharp.Core/Engines/Dialogflow/ApiAiBase.cs b/BotSharp.Core/Engines/Dialogflow/ApiAiBase.cs index 82d130a6..940a500b 100644 --- a/BotSharp.Core/Engines/Dialogflow/ApiAiBase.cs +++ b/BotSharp.Core/Engines/Dialogflow/ApiAiBase.cs @@ -4,7 +4,7 @@ using System.Text; namespace BotSharp.Core.Engines.Dialogflow { - public class ApiAiBase + public class ApiAiBase : BotEngineBase { protected float[] TrimSilence(float[] samples) { diff --git a/BotSharp.Core/Engines/Rasa/RasaAi.cs b/BotSharp.Core/Engines/Rasa/RasaAi.cs index 0d23c3e8..0106b03f 100644 --- a/BotSharp.Core/Engines/Rasa/RasaAi.cs +++ b/BotSharp.Core/Engines/Rasa/RasaAi.cs @@ -51,7 +51,7 @@ namespace BotSharp.Core.Engines Source = "agent", ResolvedQuery = request.Query.First(), Action = intentResponse?.Action, - Parameters = intentResponse?.Parameters?.ToDictionary(x => x.Name, x => x.Value), + Parameters = intentResponse?.Parameters?.ToDictionary(x => x.Name, x => (object)x.Value), Score = response.Intent.Confidence, Metadata = new AIResponseMetadata { IntentId = intentResponse?.IntentId, IntentName = intentResponse?.IntentName }, Fulfillment = new AIResponseFulfillment @@ -132,7 +132,7 @@ namespace BotSharp.Core.Engines var data = new RasaTrainingData { Entities = entity_synonyms.Select(x => x.ToObject()).ToList(), - UserSays = common_examples.Select(x => x.Intent.ToObject()).ToList() + UserSays = common_examples.Select(x => x.ToObject()).ToList() }; // meet minimal requirement diff --git a/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs b/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs index 414f0b50..01c4863e 100644 --- a/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs +++ b/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs @@ -1,4 +1,5 @@ -using BotSharp.Core.Engines; +using BotSharp.Core.Adapters.Rasa; +using BotSharp.Core.Engines; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -6,7 +7,7 @@ using System.Text; namespace BotSharp.Core.Models { - public class RasaIntentExpression : TrainingIntentExpression + public class RasaIntentExpression : TrainingIntentExpression { } diff --git a/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs b/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs index 89618d0f..93f303d6 100644 --- a/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs +++ b/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs @@ -1,5 +1,6 @@ using BotSharp.Core.Agents; using BotSharp.Core.Engines; +using BotSharp.Core.Engines.Dialogflow; using BotSharp.Core.Models; using BotSharp.RestApi.Integrations.FacebookMessenger; using DotNetToolkit; @@ -77,11 +78,11 @@ namespace BotSharp.RestApi.Integrations { Console.WriteLine($"OnTextMessaged: {message.Message.Text}"); - var rasa = new RasaAi(); - var agent = rasa.LoadAgent(agentId); - rasa.AiConfig = new AIConfiguration(agent.ClientAccessToken, SupportedLanguage.English) { AgentId = agentId }; - rasa.AiConfig.SessionId = message.Sender.Id; - var aiResponse = rasa.TextRequest(new AIRequest { Query = new String[] { message.Message.Text } }); + var ai = new ApiAi(); + var agent = ai.LoadAgent(agentId); + ai.AiConfig = new AIConfiguration(agent.ClientAccessToken, SupportedLanguage.English) { AgentId = agentId }; + ai.AiConfig.SessionId = message.Sender.Id; + var aiResponse = ai.TextRequest(new AIRequest { Query = new String[] { message.Message.Text } }); var dc = new DefaultDataContextLoader().GetDefaultDc(); var config = dc.Table().FirstOrDefault(x => x.AgentId == agentId && x.Platform == "Facebook Messenger"); @@ -91,7 +92,7 @@ namespace BotSharp.RestApi.Integrations Recipient = message.Sender.ToObject(), Message = new WebhookTextMessage { - Text = aiResponse.Result.Fulfillment.Speech + Text = String.IsNullOrEmpty(aiResponse.Result.Fulfillment.Speech) ? aiResponse.Result.Action : aiResponse.Result.Fulfillment.Speech } }); } diff --git a/BotSharp.UnitTest/AgentTest.cs b/BotSharp.UnitTest/AgentTest.cs index 1ea9d696..9b5c2499 100644 --- a/BotSharp.UnitTest/AgentTest.cs +++ b/BotSharp.UnitTest/AgentTest.cs @@ -57,11 +57,8 @@ namespace BotSharp.UnitTest [TestMethod] public void TrainAgentTest() { - var config = new AIConfiguration("", SupportedLanguage.English) { AgentId = BOT_ID }; - config.SessionId = Guid.NewGuid().ToString(); - var rasa = new RasaAi(); - + rasa.LoadAgent(BOT_ID); rasa.Train(); } } diff --git a/BotSharp.UnitTest/ConversationTest.cs b/BotSharp.UnitTest/ConversationTest.cs index 2d70c4fb..23a7577d 100644 --- a/BotSharp.UnitTest/ConversationTest.cs +++ b/BotSharp.UnitTest/ConversationTest.cs @@ -1,4 +1,5 @@ using BotSharp.Core.Engines; +using BotSharp.Core.Engines.Dialogflow; using BotSharp.Core.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; @@ -14,32 +15,32 @@ namespace BotSharp.UnitTest [TestMethod] public void TextRequest() { - var rasa = new RasaAi(); - var agent = rasa.LoadAgent(BOT_ID); - rasa.AiConfig = new AIConfiguration(agent.ClientAccessToken, SupportedLanguage.English) { AgentId = BOT_ID }; - rasa.AiConfig.SessionId = Guid.NewGuid().ToString(); + var ai = new ApiAi(); + var agent = ai.LoadAgent(BOT_ID); + ai.AiConfig = new AIConfiguration(agent.ClientAccessToken, SupportedLanguage.English) { AgentId = BOT_ID }; + ai.AiConfig.SessionId = Guid.NewGuid().ToString(); // Round 1 - var response = rasa.TextRequest(new AIRequest { Query = new String[] { "Can you play country music?" } }); + var response = ai.TextRequest(new AIRequest { Query = new String[] { "Can you play country music?" } }); Assert.AreEqual(response.Result.Metadata.IntentName, "music.play"); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "music-player-control").Lifespan, 3); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "play-music").Lifespan, 5); Assert.AreEqual(response.Result.Parameters.First(x => x.Key == "genre").Value, "country"); // Round 2 - response = rasa.TextRequest(new AIRequest { Query = new String[] { "pause it" } }); + response = ai.TextRequest(new AIRequest { Query = new String[] { "pause it" } }); Assert.AreEqual(response.Result.Metadata.IntentName, "music_player_control.pause"); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "music-player-control").Lifespan, 3); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "play-music").Lifespan, 4); // Round 3 - response = rasa.TextRequest(new AIRequest { Query = new String[] { "continue" } }); + response = ai.TextRequest(new AIRequest { Query = new String[] { "continue" } }); Assert.AreEqual(response.Result.Metadata.IntentName, "music_player_control.resume"); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "music-player-control").Lifespan, 3); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "play-music").Lifespan, 3); // Round 4 - response = rasa.TextRequest(new AIRequest { Query = new String[] { "play Hard Times by David Newman" } }); + response = ai.TextRequest(new AIRequest { Query = new String[] { "play Hard Times by David Newman" } }); Assert.AreEqual(response.Result.Metadata.IntentName, "music.play"); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "music-player-control").Lifespan, 3); Assert.AreEqual(response.Result.Contexts.First(x => x.Name == "play-music").Lifespan, 5);