public static string GetModelPerContexts(AgentModel agent, AiRequest aiRequest, AiRequest request, Database dc) { // Merge input contexts /*var contexts = dc.Table<ConversationContext>() * .Where(x => x.ConversationId == aiConfig.SessionId && x.Lifespan > 0) * .ToList() * .Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan }) * .ToList(); * * contexts.AddRange(request.Contexts.Select(x => new AIContext { Name = x.Name.ToLower(), Lifespan = x.Lifespan })); * contexts = contexts.OrderBy(x => x.Name).ToList(); * * // search all potential intents which input context included in contexts * var intents = agent.Intents.Where(it => * { * if (contexts.Count == 0) * { * return it.Contexts.Count() == 0; * } * else * { * return it.Contexts.Count() > 0 && * it.Contexts.Count(x => contexts.Select(ctx => ctx.Name).Contains(x.Name.ToLower())) == it.Contexts.Count; * } * }).OrderByDescending(x => x.Contexts.Count).ToList(); * * // query per request contexts * var contextHashs = intents.Select(x => x.ContextHash).Distinct().ToList(); * * return contextHashs.FirstOrDefault();*/ return(string.Empty); }
public override async Task <TextClassificationResult> FallbackResponse(AiRequest request) { if (config.GetValue <bool>("overrideFallback")) { var data = new { appid = "openbot", userid = "yener", spoken = request.Text }; using (var client = new HttpClient()) { var response = await client.PostAsync( "https://api.ownthink.com/bot", new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")); var content = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <OwnThinkAiResponse>(content); return(new TextClassificationResult { Classifier = "ownthink", Text = result.Data.Info.Text }); } } else { return(await base.FallbackResponse(request)); } }
public async Task <AiResponse> TextRequest(AiRequest request) { var aiResponse = new AiResponse(); // Load agent var projectPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", request.AgentId); var model = Directory.GetDirectories(projectPath).Where(x => x.Contains("model_")).Last().Split(Path.DirectorySeparatorChar).Last(); var modelPath = Path.Combine(projectPath, model); request.AgentDir = projectPath; request.Model = model; var agent = await GetAgentById(request.AgentId); var preditor = new BotPredictor(); var doc = await preditor.Predict(agent, request); var parameters = new Dictionary <String, Object>(); if (doc.Sentences[0].Entities == null) { doc.Sentences[0].Entities = new List <NlpEntity>(); } doc.Sentences[0].Entities.ForEach(x => parameters[x.Entity] = x.Value); aiResponse.Intent = doc.Sentences[0].Intent.Label; aiResponse.Speech = aiResponse.Intent; return(aiResponse); }
public override async Task <TextClassificationResult> FallbackResponse(AiRequest request) { if (config.GetValue <bool>("overrideFallback")) { var turing = new TuringAgent(config); var tulingResponse = turing.Request(new TuringRequest { Perception = new TuringRequestPerception { InputText = new TuringInputText { Text = request.Text } } }); var result = tulingResponse.Results.FirstOrDefault(x => x.ResultType == "text").Values.Text; return(new TextClassificationResult { Classifier = "turing", Text = tulingResponse.Results.FirstOrDefault(x => x.ResultType == "text").Values.Text }); } else { return(await base.FallbackResponse(request)); } }
public virtual async Task <TextClassificationResult> FallbackResponse(AiRequest request) { var data = new { token = "openbot", info = request.Text }; using (var client = new HttpClient()) { var response = await client.PostAsync( "https://api.ownthink.com/bot", new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")); var content = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <JObject>(content); return(new TextClassificationResult { Classifier = "ownthink", Text = result["text"].ToString() }); } }
public async Task <AiResponse> TextRequest(AiRequest request) { AiResponse aiResponse = new AiResponse(); /*string model = RasaRequestExtension.GetModelPerContexts(agent, AiConfig, request, dc); * var result = CallRasa(agent.Id, request.Query.First(), model); * * result.Content.Log(); * * RasaResponse response = result.Data; * aiResponse.Id = Guid.NewGuid().ToString(); * aiResponse.Lang = agent.Language; * aiResponse.Status = new AIResponseStatus { }; * aiResponse.SessionId = AiConfig.SessionId; * aiResponse.Timestamp = DateTime.UtcNow; * * var intentResponse = RasaRequestExtension.HandleIntentPerContextIn(agent, AiConfig, request, result.Data, dc); * * RasaRequestExtension.HandleParameter(agent, intentResponse, response, request); * * RasaRequestExtension.HandleMessage(intentResponse); * * aiResponse.Result = new AIResponseResult * { * Source = "agent", * ResolvedQuery = request.Query.First(), * Action = intentResponse?.Action, * 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 * { * Messages = intentResponse?.Messages?.Select(x => { * if (x.Type == AIResponseMessageType.Custom) * { * return (new * { * x.Type, * Payload = JsonConvert.DeserializeObject(x.PayloadJson) * }) as Object; * } * else * { * return (new { x.Type, x.Speech }) as Object; * } * * }).ToList() * } * }; * * RasaRequestExtension.HandleContext(dc, AiConfig, intentResponse, aiResponse); * * Console.WriteLine(JsonConvert.SerializeObject(aiResponse.Result));*/ return(aiResponse); }
public override async Task <TResult> AssembleResult <TResult>(AiRequest request, AiResponse response) { var intent = Agent.Intents.Find(x => x.Name == response.Intent); var presetResponse = intent.Responses.FirstOrDefault(); // format messages presetResponse.Messages = presetResponse.Messages.Where(x => x.Speech.Length > 0).ToList(); if (presetResponse.Messages.Count == 0) { presetResponse.Messages.Add(new IntentResponseMessage { Speech = "\"" + intent.Name + "\"" }); } // fill parameters presetResponse.Parameters.ForEach(p => { var entity = response.Entities.FirstOrDefault(x => x.Entity == p.DataType); p.Value = entity?.Value; }); var matches = Regex.Matches(presetResponse.Messages.Random().Speech, "\".*?\"").Cast <Match>(); var speech = matches.Count() == 0 ? String.Empty : matches.ToList().Random().Value; var contexts = HandleContexts(request.SessionId, presetResponse); throw new NotImplementedException("AssembleResult"); /*var aiResponse = new AIResponseResult * { * ResolvedQuery = response.ResolvedQuery, * Action = presetResponse.Action, * Metadata = new AIResponseMetadata * { * IntentName = response.Intent * }, * Intent = response.Intent, * Fulfillment = new AIResponseFulfillment * { * Messages = presetResponse.Messages.ToList<object>(), * Speech = speech.Length > 1 ? speech.Substring(1, speech.Length - 2) : String.Empty * }, * Score = response.Score, * Source = response.Source, * Contexts = contexts.ToArray(), * Parameters = presetResponse.Parameters.Where(x => !String.IsNullOrEmpty(x.Value)).ToDictionary(item => item.Name, item => (object)item.Value) * }; * * return (TResult)(object)aiResponse;*/ }
public static void HandleContext(Database dc, AiRequest aiRequest, IntentResponse intentResponse, AiResponse aiResponse) { if (intentResponse == null) { return; } // Merge context lifespan // override if exists, otherwise add, delete if lifespan is zero dc.DbTran(() => { var sessionContexts = dc.Table <ConversationContext>().Where(x => x.ConversationId == aiRequest.SessionId).ToList(); // minus 1 round sessionContexts.Where(x => !intentResponse.Contexts.Select(ctx => ctx.Name).Contains(x.Context)) .ToList() .ForEach(ctx => ctx.Lifespan = ctx.Lifespan - 1); intentResponse.Contexts.ForEach(ctx => { var session1 = sessionContexts.FirstOrDefault(x => x.Context == ctx.Name); if (session1 != null) { if (ctx.Lifespan == 0) { dc.Table <ConversationContext>().Remove(session1); } else { session1.Lifespan = ctx.Lifespan; } } else { dc.Table <ConversationContext>().Add(new ConversationContext { ConversationId = aiRequest.SessionId, Context = ctx.Name, Lifespan = ctx.Lifespan }); } }); }); /*aiResponse.Result.Contexts = dc.Table<ConversationContext>() * .Where(x => x.Lifespan > 0 && x.ConversationId == AiConfig.SessionId) * .Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan }) * .ToArray();*/ }
private async Task <string> GetContextsHash(AiRequest request) { var ctxStore = contextStorageFactory.Get(); var contexts = await ctxStore.Fetch(request.SessionId); for (int i = 0; i < contexts.Length; i++) { var ctx = contexts[i]; if (ctx.Lifespan > 0 && !request.Contexts.Exists(x => x == ctx.Name)) { request.Contexts.Add(ctx.Name); } } request.Contexts = request.Contexts.OrderBy(x => x).ToList(); return(String.Join("_", request.Contexts).GetMd5Hash()); }
public async Task <AiResponse> TextRequest(AiRequest request) { var preditor = new BotPredictor(); var doc = preditor.PredictOther(Agent, new AiRequest { AgentDir = request.AgentDir, Model = request.Model, SessionId = request.SessionId, Text = request.Text }).Result; var parameters = new Dictionary <String, Object>(); if (doc.Sentences[0].Entities == null) { doc.Sentences[0].Entities = new List <NlpEntity>(); } doc.Sentences[0].Entities.ForEach(x => parameters[x.Entity] = x.Value); return(new AiResponse { /*Lang = request.Language, * Timestamp = DateTime.UtcNow, * SessionId = request.SessionId, * Status = new AIResponseStatus(), * Result = new AIResponseResult * { * Score = doc.Sentences[0].Intent == null ? 0 : doc.Sentences[0].Intent.Confidence, * ResolvedQuery = doc.Sentences[0].Text, * Fulfillment = new AIResponseFulfillment * { * Speech = agent.Intents.FirstOrDefault(tnt => tnt.Name == doc.Sentences[0].Intent?.Label)?.Responses?.Random()?.Messages?.Random()?.Speech * }, * Parameters = parameters, * Entities = doc.Sentences[0].Entities, * Metadata = new AIResponseMetadata * { * IntentName = doc.Sentences[0].Intent?.Label * } * }*/ }); }
public async Task <NlpDoc> Predict(AgentBase agent, AiRequest request) { // load model var dir = Path.Combine(request.AgentDir, request.Model); Console.WriteLine($"Load model from {dir}"); var metaJson = File.ReadAllText(Path.Combine(dir, "model-meta.json")); var meta = JsonConvert.DeserializeObject <ModelMetaData>(metaJson); // Get NLP Provider var config = (IConfiguration)AppDomain.CurrentDomain.GetData("Configuration"); var assemblies = (string[])AppDomain.CurrentDomain.GetData("Assemblies"); var providerPipe = meta.Pipeline.First(); var provider = TypeHelper.GetInstance(providerPipe.Name, assemblies) as INlpProvider; provider.Configuration = config.GetSection(meta.Platform); var data = new NlpDoc { Sentences = new List <NlpDocSentence> { new NlpDocSentence { Text = request.Text } } }; await provider.Load(agent, providerPipe); meta.Pipeline.RemoveAt(0); var settings = new PipeSettings { ModelDir = dir, ProjectDir = request.AgentDir }; // pipe process var pipelines = config.GetValue <String>($"{meta.BotEngine}:pipe") .Split(',') .Select(x => x.Trim()) .ToList(); for (int pipeIdx = 0; pipeIdx < pipelines.Count; pipeIdx++) { var pipe = TypeHelper.GetInstance(pipelines[pipeIdx], assemblies) as INlpPredict; pipe.Configuration = config.GetSection(meta.BotEngine).GetSection(pipelines[pipeIdx]); pipe.Settings = settings; var pipeModel = meta.Pipeline.FirstOrDefault(x => x.Name == pipelines[pipeIdx]); await pipe.Predict(agent, data, pipeModel); } Console.WriteLine($"Prediction result:", Color.Green); Console.WriteLine(JsonConvert.SerializeObject(data, new JsonSerializerSettings { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() })); return(data); }
public virtual async Task <TResult> AssembleResult <TResult>(AiRequest request, AiResponse response) { throw new NotImplementedException(); }
public virtual async Task <TResult> TextRequest <TResult>(AiRequest request) { // merge last contexts string contextHash = await GetContextsHash(request); Console.WriteLine($"TextRequest: {request.Text}, {request.Contexts}, {request.SessionId}"); // Load agent var projectPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", request.AgentId); var model = Directory.GetDirectories(projectPath).Where(x => x.Contains("model_")).Last().Split(Path.DirectorySeparatorChar).Last(); var modelPath = Path.Combine(projectPath, model); request.AgentDir = projectPath; request.Model = model + $"{Path.DirectorySeparatorChar}{contextHash}"; Agent = await GetAgentById(request.AgentId); var preditor = new BotPredictor(); var doc = await preditor.Predict(Agent, request); var predictedIntent = doc.Sentences[0].Intent; if (predictedIntent.Confidence < Agent.MlConfig.MinConfidence) { predictedIntent = await FallbackResponse(request); predictedIntent.Confidence = Agent.MlConfig.MinConfidence; predictedIntent.Label = "fallback"; Agent.Intents.Add(new Intent { Name = predictedIntent.Label, Responses = new List <IntentResponse> { new IntentResponse { IntentName = predictedIntent.Label, Messages = new List <IntentResponseMessage> { new IntentResponseMessage { Speech = "\"" + predictedIntent.Text + "\"", Type = AIResponseMessageType.Text } } } } }); } var aiResponse = new AiResponse { ResolvedQuery = request.Text, Score = predictedIntent.Confidence, Source = predictedIntent.Classifier, Intent = predictedIntent.Label, Entities = doc.Sentences[0].Entities }; Console.WriteLine($"TextResponse: {aiResponse.Intent}, {request.SessionId}"); return(await AssembleResult <TResult>(request, aiResponse)); }
public async Task <NlpDoc> PredictOther(AgentBase agent, AiRequest request) { return(await Predict(agent, request)); }
public static IntentResponse HandleIntentPerContextIn(AgentModel agent, AiRequest request, RasaResponse response, Database dc) { // Merge input contexts /*var contexts = dc.Table<ConversationContext>() * .Where(x => x.ConversationId == request.SessionId && x.Lifespan > 0) * .ToList() * .Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan }) * .ToList(); * * contexts.AddRange(request.Contexts.Select(x => new AIContext { Name = x.Name.ToLower(), Lifespan = x.Lifespan })); * contexts = contexts.OrderBy(x => x.Name).ToList();*/ // search all potential intents which input context included in contexts /*var intents = agent.Intents.Where(it => * { * if (contexts.Count == 0) * { * return it.Contexts.Count() == 0; * } * else * { * return it.Contexts.Count() == 0 || * it.Contexts.Count(x => contexts.Select(ctx => ctx.Name).Contains(x.Name.ToLower())) == it.Contexts.Count; * } * }).OrderByDescending(x => x.Contexts.Count).ToList();*/ /*if (response.IntentRanking == null) * { * response.IntentRanking = new List<RasaResponseIntent> * { * response.Intent * }; * } * * response.IntentRanking = response.IntentRanking.Where(x => x.Confidence > agent.MlConfig.MinConfidence).ToList(); * response.IntentRanking = response.IntentRanking.Where(x => intents.Select(i => i.Name).Contains(x.Name)).ToList();*/ // add Default Fallback Intent /*if (response.IntentRanking.Count == 0) * { * var defaultFallbackIntent = agent.Intents.FirstOrDefault(x => x.Name == "Default Fallback Intent"); * response.IntentRanking.Add(new RasaResponseIntent * { * Name = defaultFallbackIntent.Name, * Confidence = decimal.Parse("0.8") * }); * }*/ response.Intent = response.IntentRanking.First(); var intent = (dc.Table <Intent>().Where(x => x.AgentId == agent.Id && x.Name == response.Intent.Name) .Include(x => x.Responses).ThenInclude(x => x.Contexts) .Include(x => x.Responses).ThenInclude(x => x.Parameters).ThenInclude(x => x.Prompts) .Include(x => x.Responses).ThenInclude(x => x.Messages)).First(); var intentResponse = ArrayHelper.GetRandom(intent.Responses); intentResponse.IntentName = intent.Name; return(intentResponse); }
public virtual async Task <TextClassificationResult> FallbackResponse(AiRequest request) { throw new NotImplementedException("FallbackResponse"); }
/// <summary> /// /// </summary> /// <param name="agent"></param> /// <param name="intentResponse"></param> /// <param name="response"></param> /// <param name="request"></param> /// <returns>Required field is missed</returns> public static void HandleParameter(AgentModel agent, IntentResponse intentResponse, RasaResponse response, AiRequest aiRequest) { if (intentResponse == null) { return; } intentResponse.Parameters.ForEach(p => { string query = aiRequest.Text; var entity = response.Entities.FirstOrDefault(x => x.Entity == p.Name || x.Entity.Split(':').Contains(p.Name)); if (entity != null) { p.Value = query.Substring(entity.Start, entity.End - entity.Start); } // convert to Standard entity value /*if (!String.IsNullOrEmpty(p.Value) && !p.DataType.StartsWith("sys.")) * { * p.Value = agent.Entities * .FirstOrDefault(x => x.Entity == p.DataType) * .Entries * .FirstOrDefault((entry) => * { * return entry.Value.ToLower() == p.Value.ToLower() || * entry.Synonyms.Select(synonym => synonym.Synonym.ToLower()).Contains(p.Value.ToLower()); * })?.Value; * }*/ // fixed entity per request /*if (aiRequest.Entities != null) * { * var fixedEntity = request.Entities.FirstOrDefault(x => x.Name == p.Name); * if (fixedEntity != null) * { * if (query.ToLower().Contains(fixedEntity.Entries.First().Value.ToLower())) * { * p.Value = fixedEntity.Entries.First().Value; * } * } * }*/ }); }