2018-10-03 06:00:07 +00:00
|
|
|
|
using BotSharp.Models.NLP;
|
2018-10-03 01:44:11 +00:00
|
|
|
|
using BotSharp.Platform.Abstraction;
|
2018-10-01 13:36:39 +00:00
|
|
|
|
using BotSharp.Platform.Models;
|
2018-10-02 02:49:01 +00:00
|
|
|
|
using BotSharp.Platform.Models.AiRequest;
|
2018-10-03 01:44:11 +00:00
|
|
|
|
using BotSharp.Platform.Models.AiResponse;
|
2018-10-03 06:00:07 +00:00
|
|
|
|
using BotSharp.Platform.Models.Intents;
|
2018-08-30 13:04:10 +00:00
|
|
|
|
using DotNetToolkit;
|
2017-12-30 20:26:35 +00:00
|
|
|
|
using EntityFrameworkCore.BootKit;
|
2017-12-18 13:31:15 +00:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2018-08-08 21:39:00 +00:00
|
|
|
|
using Newtonsoft.Json;
|
2018-08-31 17:52:52 +00:00
|
|
|
|
using Newtonsoft.Json.Serialization;
|
2017-12-18 13:31:15 +00:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2018-08-31 17:52:52 +00:00
|
|
|
|
using System.Drawing;
|
2018-07-15 12:31:52 +00:00
|
|
|
|
using System.IO;
|
2017-12-18 13:31:15 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
2018-08-08 21:39:00 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2017-12-18 13:31:15 +00:00
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
namespace BotSharp.Core.Engines
|
2017-12-18 13:31:15 +00:00
|
|
|
|
{
|
2018-07-15 12:31:52 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Bot engine/ platform base class
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public abstract class BotEngineBase
|
2017-12-18 13:31:15 +00:00
|
|
|
|
{
|
2018-10-05 06:39:39 +00:00
|
|
|
|
protected Database Dc;
|
2018-07-15 12:31:52 +00:00
|
|
|
|
|
2018-10-05 06:39:39 +00:00
|
|
|
|
protected AgentBase Agent { get; set; }
|
2018-05-23 05:11:15 +00:00
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
public BotEngineBase()
|
|
|
|
|
|
{
|
2018-10-05 06:39:39 +00:00
|
|
|
|
Dc = new DefaultDataContextLoader().GetDefaultDc();
|
2018-05-23 05:11:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-05 06:39:39 +00:00
|
|
|
|
public async Task<AiResponse> TextRequest(AiRequest request)
|
2018-08-08 21:39:00 +00:00
|
|
|
|
{
|
2018-08-13 04:14:02 +00:00
|
|
|
|
var preditor = new BotPredictor();
|
2018-10-05 06:39:39 +00:00
|
|
|
|
var doc = preditor.Predict(Agent, new AiRequest
|
2018-10-02 02:49:01 +00:00
|
|
|
|
{
|
|
|
|
|
|
AgentDir = request.AgentDir,
|
|
|
|
|
|
Model = request.Model,
|
|
|
|
|
|
SessionId = request.SessionId,
|
2018-10-03 01:44:11 +00:00
|
|
|
|
Text = request.Text
|
2018-10-02 02:49:01 +00:00
|
|
|
|
}).Result;
|
2018-08-31 17:52:52 +00:00
|
|
|
|
|
2018-08-10 20:10:53 +00:00
|
|
|
|
var parameters = new Dictionary<String, Object>();
|
2018-08-30 13:04:10 +00:00
|
|
|
|
if(doc.Sentences[0].Entities == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.Sentences[0].Entities = new List<NlpEntity>();
|
|
|
|
|
|
}
|
2018-09-13 20:01:40 +00:00
|
|
|
|
doc.Sentences[0].Entities.ForEach(x => parameters[x.Entity] = x.Value);
|
2018-08-10 20:10:53 +00:00
|
|
|
|
|
2018-10-03 01:44:11 +00:00
|
|
|
|
return new AiResponse
|
2018-08-10 20:10:53 +00:00
|
|
|
|
{
|
2018-10-03 01:44:11 +00:00
|
|
|
|
/*Lang = request.Language,
|
2018-08-10 20:10:53 +00:00
|
|
|
|
Timestamp = DateTime.UtcNow,
|
|
|
|
|
|
SessionId = request.SessionId,
|
|
|
|
|
|
Status = new AIResponseStatus(),
|
|
|
|
|
|
Result = new AIResponseResult
|
|
|
|
|
|
{
|
2018-08-12 18:42:27 +00:00
|
|
|
|
Score = doc.Sentences[0].Intent == null ? 0 : doc.Sentences[0].Intent.Confidence,
|
2018-08-10 20:10:53 +00:00
|
|
|
|
ResolvedQuery = doc.Sentences[0].Text,
|
2018-08-30 13:04:10 +00:00
|
|
|
|
Fulfillment = new AIResponseFulfillment
|
|
|
|
|
|
{
|
|
|
|
|
|
Speech = agent.Intents.FirstOrDefault(tnt => tnt.Name == doc.Sentences[0].Intent?.Label)?.Responses?.Random()?.Messages?.Random()?.Speech
|
|
|
|
|
|
},
|
2018-08-10 20:10:53 +00:00
|
|
|
|
Parameters = parameters,
|
2018-08-24 14:47:40 +00:00
|
|
|
|
Entities = doc.Sentences[0].Entities,
|
2018-08-10 20:10:53 +00:00
|
|
|
|
Metadata = new AIResponseMetadata
|
|
|
|
|
|
{
|
2018-08-12 18:42:27 +00:00
|
|
|
|
IntentName = doc.Sentences[0].Intent?.Label
|
2018-08-10 20:10:53 +00:00
|
|
|
|
}
|
2018-10-03 01:44:11 +00:00
|
|
|
|
}*/
|
2018-08-10 20:10:53 +00:00
|
|
|
|
};
|
2018-08-08 21:39:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-03 06:00:07 +00:00
|
|
|
|
/*public TrainingCorpus GetIntentExpressions(AgentBase agent)
|
2018-08-28 14:58:35 +00:00
|
|
|
|
{
|
|
|
|
|
|
TrainingCorpus corpus = new TrainingCorpus()
|
|
|
|
|
|
{
|
|
|
|
|
|
UserSays = new List<TrainingIntentExpression<TrainingIntentExpressionPart>>(),
|
|
|
|
|
|
Entities = new List<TrainingEntity>()
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2018-10-03 06:00:07 +00:00
|
|
|
|
var expressParts = new List<IntentExpressionPart>();
|
2018-08-28 14:58:35 +00:00
|
|
|
|
|
|
|
|
|
|
var intents = agent.Intents;
|
|
|
|
|
|
|
|
|
|
|
|
intents.ForEach(intent =>
|
|
|
|
|
|
{
|
|
|
|
|
|
intent.UserSays.ForEach(exp =>
|
|
|
|
|
|
{
|
|
|
|
|
|
exp.Data = exp.Data.OrderBy(x => x.UpdatedTime).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var say = new TrainingIntentExpression<TrainingIntentExpressionPart>
|
|
|
|
|
|
{
|
|
|
|
|
|
Intent = intent.Name,
|
|
|
|
|
|
Text = String.Join("", exp.Data.Select(x => x.Text)),
|
|
|
|
|
|
ContextHash = intent.ContextHash
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// convert entity format
|
|
|
|
|
|
exp.Data.Where(x => !String.IsNullOrEmpty(x.Meta))
|
|
|
|
|
|
.ToList()
|
|
|
|
|
|
.ForEach(x =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var part = new TrainingIntentExpressionPart
|
|
|
|
|
|
{
|
|
|
|
|
|
Value = x.Text,
|
|
|
|
|
|
Entity = $"{x.Meta}:{x.Alias}",
|
|
|
|
|
|
Start = x.Start
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (say.Entities == null) say.Entities = new List<TrainingIntentExpressionPart>();
|
|
|
|
|
|
say.Entities.Add(part);
|
|
|
|
|
|
|
|
|
|
|
|
// assemble entity synonmus
|
2018-10-03 06:00:07 +00:00
|
|
|
|
if (!trainingData.Entities.Any(y => y.EntityType == x.Alias && y.EntityValue == x.Text))
|
2018-08-28 14:58:35 +00:00
|
|
|
|
{
|
|
|
|
|
|
var allSynonyms = (from e in dc.Table<EntityType>()
|
|
|
|
|
|
join ee in dc.Table<EntityEntry>() on e.Id equals ee.EntityId
|
|
|
|
|
|
join ees in dc.Table<EntrySynonym>() on ee.Id equals ees.EntityEntryId
|
|
|
|
|
|
where e.Name == x.Alias && ee.Value == x.Text & ees.Synonym != x.Text
|
|
|
|
|
|
select ees.Synonym).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var te = new TrainingEntity
|
|
|
|
|
|
{
|
|
|
|
|
|
EntityType = $"{x.Meta}:{x.Alias}",
|
|
|
|
|
|
EntityValue = x.Text,
|
|
|
|
|
|
Synonyms = allSynonyms
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
trainingData.Entities.Add(te);
|
2018-10-03 06:00:07 +00:00
|
|
|
|
}
|
2018-08-28 14:58:35 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
corpus.UserSays.Add(say);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// remove Default Fallback Intent
|
|
|
|
|
|
corpus.UserSays = corpus.UserSays.Where(x => x.Intent != "Default Fallback Intent").ToList();
|
|
|
|
|
|
|
|
|
|
|
|
return corpus;
|
2018-10-03 06:00:07 +00:00
|
|
|
|
}*/
|
2018-08-28 14:58:35 +00:00
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
public TrainingCorpus GetIntentExpressions()
|
2018-04-06 22:39:30 +00:00
|
|
|
|
{
|
2018-07-15 12:31:52 +00:00
|
|
|
|
TrainingCorpus corpus = new TrainingCorpus()
|
2018-04-06 22:39:30 +00:00
|
|
|
|
{
|
2018-07-15 12:31:52 +00:00
|
|
|
|
UserSays = new List<TrainingIntentExpression<TrainingIntentExpressionPart>>(),
|
|
|
|
|
|
Entities = new List<TrainingEntity>()
|
2018-04-06 22:39:30 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
2018-10-03 01:44:11 +00:00
|
|
|
|
/*var expressParts = new List<IntentExpressionPart>();
|
2018-04-06 22:39:30 +00:00
|
|
|
|
|
|
|
|
|
|
var intents = dc.Table<Intent>()
|
|
|
|
|
|
.Include(x => x.Contexts)
|
|
|
|
|
|
.Include(x => x.UserSays).ThenInclude(say => say.Data)
|
2018-06-06 16:20:02 +00:00
|
|
|
|
.Where(x => x.AgentId == agent.Id && x.UserSays.Count > 0)
|
2018-04-06 22:39:30 +00:00
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
intents.ForEach(intent =>
|
|
|
|
|
|
{
|
|
|
|
|
|
intent.UserSays.ForEach(exp =>
|
|
|
|
|
|
{
|
2018-08-06 18:39:26 +00:00
|
|
|
|
exp.Data = exp.Data.OrderBy(x => x.UpdatedTime).ToList();
|
|
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
var say = new TrainingIntentExpression<TrainingIntentExpressionPart>
|
2018-04-06 22:39:30 +00:00
|
|
|
|
{
|
|
|
|
|
|
Intent = intent.Name,
|
2018-08-06 18:39:26 +00:00
|
|
|
|
Text = String.Join("", exp.Data.Select(x => x.Text)),
|
2018-06-18 22:15:32 +00:00
|
|
|
|
ContextHash = intent.ContextHash
|
2018-04-06 22:39:30 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// convert entity format
|
|
|
|
|
|
exp.Data.Where(x => !String.IsNullOrEmpty(x.Meta))
|
|
|
|
|
|
.ToList()
|
|
|
|
|
|
.ForEach(x =>
|
|
|
|
|
|
{
|
2018-07-15 12:31:52 +00:00
|
|
|
|
var part = new TrainingIntentExpressionPart
|
2018-04-06 22:39:30 +00:00
|
|
|
|
{
|
|
|
|
|
|
Value = x.Text,
|
2018-06-22 19:42:53 +00:00
|
|
|
|
Entity = $"{x.Meta}:{x.Alias}",
|
2018-08-15 11:34:27 +00:00
|
|
|
|
Start = x.Start
|
2018-04-06 22:39:30 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
if (say.Entities == null) say.Entities = new List<TrainingIntentExpressionPart>();
|
2018-04-06 22:39:30 +00:00
|
|
|
|
say.Entities.Add(part);
|
|
|
|
|
|
|
|
|
|
|
|
// assemble entity synonmus
|
2018-10-03 01:44:11 +00:00
|
|
|
|
if (!trainingData.Entities.Any(y => y.EntityType == x.Alias && y.EntityValue == x.Text))
|
2018-04-06 22:39:30 +00:00
|
|
|
|
{
|
2018-05-22 00:39:33 +00:00
|
|
|
|
var allSynonyms = (from e in dc.Table<EntityType>()
|
2018-04-06 22:39:30 +00:00
|
|
|
|
join ee in dc.Table<EntityEntry>() on e.Id equals ee.EntityId
|
2018-05-22 00:39:33 +00:00
|
|
|
|
join ees in dc.Table<EntrySynonym>() on ee.Id equals ees.EntityEntryId
|
2018-04-06 22:39:30 +00:00
|
|
|
|
where e.Name == x.Alias && ee.Value == x.Text & ees.Synonym != x.Text
|
|
|
|
|
|
select ees.Synonym).ToList();
|
|
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
var te = new TrainingEntity
|
2018-04-06 22:39:30 +00:00
|
|
|
|
{
|
2018-06-22 19:42:53 +00:00
|
|
|
|
EntityType = $"{x.Meta}:{x.Alias}",
|
2018-04-06 22:39:30 +00:00
|
|
|
|
EntityValue = x.Text,
|
|
|
|
|
|
Synonyms = allSynonyms
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
trainingData.Entities.Add(te);
|
2018-10-03 01:44:11 +00:00
|
|
|
|
}
|
2018-04-06 22:39:30 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
corpus.UserSays.Add(say);
|
2018-04-06 22:39:30 +00:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2018-06-18 22:15:32 +00:00
|
|
|
|
// remove Default Fallback Intent
|
2018-10-03 01:44:11 +00:00
|
|
|
|
corpus.UserSays = corpus.UserSays.Where(x => x.Intent != "Default Fallback Intent").ToList();*/
|
2018-06-18 22:15:32 +00:00
|
|
|
|
|
2018-07-15 12:31:52 +00:00
|
|
|
|
return corpus;
|
2017-12-18 13:31:15 +00:00
|
|
|
|
}
|
2018-07-18 16:18:34 +00:00
|
|
|
|
|
2018-08-28 14:58:35 +00:00
|
|
|
|
public virtual Task Train(BotTrainOptions options)
|
2018-07-18 16:18:34 +00:00
|
|
|
|
{
|
2018-08-08 21:39:00 +00:00
|
|
|
|
return Task.CompletedTask;
|
2018-07-18 16:18:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-18 13:31:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|