Abstract bot platform infrastrature, decouple modules.
This commit is contained in:
parent
bb4231ad7f
commit
3fcd6a3996
|
|
@ -10,10 +10,10 @@ namespace BotSharp.Core.Engines
|
|||
/// <summary>
|
||||
/// Load agent summary
|
||||
/// </summary>
|
||||
/// <param name="agentId">agent guid or name</param>
|
||||
/// <param name="agentHeader"></param>
|
||||
/// <param name="agentDir"></param>
|
||||
/// <returns></returns>
|
||||
Agent LoadAgent(string agentId, string agentDir);
|
||||
Agent LoadAgent(AgentImportHeader agentHeader, string agentDir);
|
||||
|
||||
/// <summary>
|
||||
/// Load user customized entity type
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Core.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
|
@ -8,6 +9,7 @@ namespace BotSharp.Core.Engines
|
|||
public interface IBotPlatform
|
||||
{
|
||||
AIResponse TextRequest(AIRequest request);
|
||||
|
||||
void Train();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;MODEL_PER_CONTEXTS;NETCOREAPP;NETCOREAPP2_1</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
|
|
@ -43,9 +43,4 @@
|
|||
<PackageReference Include="RestSharp" Version="106.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Engines\BotSharp\" />
|
||||
<Folder Include="Infrastructure\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
15
BotSharp.Core/Engines/AgentImportHeader.cs
Normal file
15
BotSharp.Core/Engines/AgentImportHeader.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
public class AgentImportHeader
|
||||
{
|
||||
public String Id { get; set; }
|
||||
public String Name { get; set; }
|
||||
public String UserId { get; set; }
|
||||
public String ClientAccessToken { get; set; }
|
||||
public String DeveloperAccessToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using BotSharp.Core.Adapters.Rasa;
|
||||
using BotSharp.Core.Engines;
|
||||
using BotSharp.Core.Agents;
|
||||
using BotSharp.Core.Entities;
|
||||
using BotSharp.Core.Intents;
|
||||
using BotSharp.Core.Models;
|
||||
|
|
@ -7,58 +6,90 @@ using EntityFrameworkCore.BootKit;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Agents
|
||||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
public static class AgentDriver
|
||||
/// <summary>
|
||||
/// Bot engine/ platform base class
|
||||
/// </summary>
|
||||
public abstract class BotEngineBase
|
||||
{
|
||||
public static Agent LoadAgentById(this IBotPlatform engine, Database dc, string agentId)
|
||||
protected Database dc;
|
||||
|
||||
public AIConfiguration AiConfig { get; set; }
|
||||
|
||||
protected Agent agent { get; set; }
|
||||
|
||||
public String DbInitializerPath { get; private set; }
|
||||
|
||||
public BotEngineBase()
|
||||
{
|
||||
var clientAccessToken = dc.Table<Agent>().Find(agentId).ClientAccessToken;
|
||||
|
||||
var config = new AIConfiguration(clientAccessToken, SupportedLanguage.English);
|
||||
|
||||
var rasa = new RasaAi(dc, config);
|
||||
rasa.agent = rasa.LoadAgent(dc, config);
|
||||
|
||||
return rasa.agent;
|
||||
dc = new DefaultDataContextLoader().GetDefaultDc();
|
||||
DbInitializerPath = $"{Database.ContentRootPath}App_Data{Path.DirectorySeparatorChar}DbInitializer{Path.DirectorySeparatorChar}";
|
||||
}
|
||||
|
||||
public static Agent LoadAgent(this IBotPlatform engine, Database dc, AIConfiguration aiConfig)
|
||||
/// <summary>
|
||||
/// Load Agent
|
||||
/// </summary>
|
||||
/// <param name="id">agentId, clientAccessToken, developerAccessToken</param>
|
||||
/// <returns></returns>
|
||||
public Agent LoadAgent(string id)
|
||||
{
|
||||
return dc.Table<Agent>()
|
||||
.Include(x => x.Intents).ThenInclude(x => x.Contexts)
|
||||
.Include(x => x.Entities).ThenInclude(x => x.Entries).ThenInclude(x => x.Synonyms)
|
||||
.Include(x => x.MlConfig)
|
||||
.FirstOrDefault(x => x.ClientAccessToken == aiConfig.ClientAccessToken || x.DeveloperAccessToken == aiConfig.ClientAccessToken);
|
||||
if (agent == null)
|
||||
{
|
||||
agent = dc.Table<Agent>()
|
||||
.Include(x => x.Intents).ThenInclude(x => x.Contexts)
|
||||
.Include(x => x.Entities).ThenInclude(x => x.Entries).ThenInclude(x => x.Synonyms)
|
||||
.Include(x => x.MlConfig)
|
||||
.FirstOrDefault(x => x.Id == id ||
|
||||
x.ClientAccessToken == id ||
|
||||
x.DeveloperAccessToken == id);
|
||||
}
|
||||
else
|
||||
{
|
||||
return agent;
|
||||
}
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore a agent instance from backup json files
|
||||
/// </summary>
|
||||
/// <param name="importor"></param>
|
||||
/// <param name="agentId"></param>
|
||||
/// <param name="importer"></param>
|
||||
/// <param name="agentHeader"></param>
|
||||
/// <param name="dataDir"></param>
|
||||
/// <returns></returns>
|
||||
public static Agent RestoreAgent(this IBotPlatform engine, IAgentImporter importer, String agentId, string dataDir)
|
||||
public bool RestoreAgent<TAgentImporter>(AgentImportHeader agentHeader) where TAgentImporter : IAgentImporter, new()
|
||||
{
|
||||
// Load agent summary
|
||||
var agent = importer.LoadAgent(agentId, dataDir);
|
||||
var importer = new TAgentImporter();
|
||||
|
||||
// Load user custom entities
|
||||
importer.LoadCustomEntities(agent, dataDir);
|
||||
string dataDir = $"{DbInitializerPath}Agents{Path.DirectorySeparatorChar}";
|
||||
|
||||
// Load agent intents
|
||||
importer.LoadIntents(agent, dataDir);
|
||||
int row = dc.DbTran(() => {
|
||||
|
||||
// Load system buildin entities
|
||||
importer.LoadBuildinEntities(agent, dataDir);
|
||||
// Load agent summary
|
||||
agent = importer.LoadAgent(agentHeader, dataDir);
|
||||
|
||||
return agent;
|
||||
// Load user custom entities
|
||||
importer.LoadCustomEntities(agent, dataDir);
|
||||
|
||||
// Load agent intents
|
||||
importer.LoadIntents(agent, dataDir);
|
||||
|
||||
// Load system buildin entities
|
||||
importer.LoadBuildinEntities(agent, dataDir);
|
||||
|
||||
SaveAgent();
|
||||
});
|
||||
|
||||
return row > 0;
|
||||
}
|
||||
|
||||
public static String SaveAgent(this Agent agent, Database dc)
|
||||
public String SaveAgent()
|
||||
{
|
||||
var existedAgent = dc.Table<Agent>().FirstOrDefault(x => x.Id == agent.Id || x.Name == agent.Name);
|
||||
if (existedAgent == null)
|
||||
|
|
@ -73,12 +104,12 @@ namespace BotSharp.Core.Agents
|
|||
}
|
||||
}
|
||||
|
||||
public static RasaTrainingData GrabCorpus(this Agent agent, Database dc)
|
||||
public TrainingCorpus GetIntentExpressions()
|
||||
{
|
||||
var trainingData = new RasaTrainingData
|
||||
TrainingCorpus corpus = new TrainingCorpus()
|
||||
{
|
||||
Entities = new List<RasaTraningEntity>(),
|
||||
UserSays = new List<RasaIntentExpression>()
|
||||
UserSays = new List<TrainingIntentExpression<TrainingIntentExpressionPart>>(),
|
||||
Entities = new List<TrainingEntity>()
|
||||
};
|
||||
|
||||
var expressParts = new List<IntentExpressionPart>();
|
||||
|
|
@ -93,7 +124,7 @@ namespace BotSharp.Core.Agents
|
|||
{
|
||||
intent.UserSays.ForEach(exp =>
|
||||
{
|
||||
var say = new RasaIntentExpression
|
||||
var say = new TrainingIntentExpression<TrainingIntentExpressionPart>
|
||||
{
|
||||
Intent = intent.Name,
|
||||
Text = String.Join("", exp.Data.OrderBy(x => x.UpdatedTime).Select(x => x.Text)),
|
||||
|
|
@ -107,7 +138,7 @@ namespace BotSharp.Core.Agents
|
|||
{
|
||||
int start = say.Text.IndexOf(x.Text);
|
||||
|
||||
var part = new RasaIntentExpressionPart
|
||||
var part = new TrainingIntentExpressionPart
|
||||
{
|
||||
Value = x.Text,
|
||||
Entity = $"{x.Meta}:{x.Alias}",
|
||||
|
|
@ -115,11 +146,11 @@ namespace BotSharp.Core.Agents
|
|||
End = start + x.Text.Length
|
||||
};
|
||||
|
||||
if (say.Entities == null) say.Entities = new List<RasaIntentExpressionPart>();
|
||||
if (say.Entities == null) say.Entities = new List<TrainingIntentExpressionPart>();
|
||||
say.Entities.Add(part);
|
||||
|
||||
// assemble entity synonmus
|
||||
if (!trainingData.Entities.Any(y => y.EntityType == x.Alias && y.EntityValue == x.Text))
|
||||
/*if (!trainingData.Entities.Any(y => y.EntityType == x.Alias && y.EntityValue == x.Text))
|
||||
{
|
||||
var allSynonyms = (from e in dc.Table<EntityType>()
|
||||
join ee in dc.Table<EntityEntry>() on e.Id equals ee.EntityId
|
||||
|
|
@ -127,7 +158,7 @@ namespace BotSharp.Core.Agents
|
|||
where e.Name == x.Alias && ee.Value == x.Text & ees.Synonym != x.Text
|
||||
select ees.Synonym).ToList();
|
||||
|
||||
var te = new RasaTraningEntity
|
||||
var te = new TrainingEntity
|
||||
{
|
||||
EntityType = $"{x.Meta}:{x.Alias}",
|
||||
EntityValue = x.Text,
|
||||
|
|
@ -135,17 +166,17 @@ namespace BotSharp.Core.Agents
|
|||
};
|
||||
|
||||
trainingData.Entities.Add(te);
|
||||
}
|
||||
}*/
|
||||
});
|
||||
|
||||
trainingData.UserSays.Add(say);
|
||||
corpus.UserSays.Add(say);
|
||||
});
|
||||
});
|
||||
|
||||
// remove Default Fallback Intent
|
||||
trainingData.UserSays = trainingData.UserSays.Where(x => x.Intent != "Default Fallback Intent").ToList();
|
||||
corpus.UserSays = corpus.UserSays.Where(x => x.Intent != "Default Fallback Intent").ToList();
|
||||
|
||||
return trainingData;
|
||||
return corpus;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
BotSharp.Core/Engines/BotSharp/BotSharpAi.cs
Normal file
20
BotSharp.Core/Engines/BotSharp/BotSharpAi.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BotSharp.Core.Models;
|
||||
|
||||
namespace BotSharp.Core.Engines.BotSharp
|
||||
{
|
||||
public class BotSharpAi : BotEngineBase, IBotPlatform
|
||||
{
|
||||
public AIResponse TextRequest(AIRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Train()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ namespace BotSharp.Core.Engines.CRFsuite
|
|||
public bool Process(Agent agent, JObject data)
|
||||
{
|
||||
var dc = new DefaultDataContextLoader().GetDefaultDc();
|
||||
var corpus = agent.GrabCorpus(dc);
|
||||
//var corpus = agent.GrabCorpus(dc);
|
||||
|
||||
// Mock Data
|
||||
List<TrainingData> train_sent = new List<TrainingData>();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ namespace BotSharp.Core.Models
|
|||
|
||||
public string ClientAccessToken { get; private set; }
|
||||
|
||||
public string AgentId { get; set; }
|
||||
|
||||
public SupportedLanguage Language { get; set; }
|
||||
|
||||
public bool VoiceActivityDetectionEnabled { get; set; }
|
||||
|
|
|
|||
|
|
@ -22,18 +22,25 @@ namespace BotSharp.Core.Engines
|
|||
/// <summary>
|
||||
/// Load agent meta
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
/// <param name="agentName"></param>
|
||||
/// <param name="agentDir"></param>
|
||||
/// <returns></returns>
|
||||
public Agent LoadAgent(string agentId, string agentDir)
|
||||
public Agent LoadAgent(AgentImportHeader agentHeader, string agentDir)
|
||||
{
|
||||
// load agent profile
|
||||
string data = File.ReadAllText($"{agentDir}{Path.DirectorySeparatorChar}Dialogflow{Path.DirectorySeparatorChar}{agentId}{Path.DirectorySeparatorChar}agent.json");
|
||||
string data = File.ReadAllText($"{agentDir}{Path.DirectorySeparatorChar}Dialogflow{Path.DirectorySeparatorChar}{agentHeader.Name}{Path.DirectorySeparatorChar}agent.json");
|
||||
var agent = JsonConvert.DeserializeObject<DialogflowAgent>(data);
|
||||
agent.Id = Guid.NewGuid().ToString();
|
||||
agent.Name = agentId;
|
||||
agent.Name = agentHeader.Name;
|
||||
agent.Id = agentHeader.Id;
|
||||
|
||||
var result = agent.ToObject<Agent>();
|
||||
result.ClientAccessToken = agentHeader.ClientAccessToken;
|
||||
result.DeveloperAccessToken = agentHeader.DeveloperAccessToken;
|
||||
if(agentHeader.UserId != null)
|
||||
{
|
||||
result.UserId = agentHeader.UserId;
|
||||
}
|
||||
|
||||
result.MlConfig = agent.ToObject<AgentMlConfig>();
|
||||
result.MlConfig.MinConfidence = agent.MlMinConfidence;
|
||||
result.MlConfig.AgentId = agent.Id;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Core.Agents;
|
||||
using BotSharp.Core.Adapters.Rasa;
|
||||
using BotSharp.Core.Agents;
|
||||
using BotSharp.Core.Entities;
|
||||
using BotSharp.Core.Intents;
|
||||
using BotSharp.Core.Models;
|
||||
|
|
@ -19,39 +20,17 @@ using System.Text;
|
|||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
/// <summary>
|
||||
/// Rasa nlu 0.12.x
|
||||
/// Rasa nlu >= 0.12
|
||||
/// </summary>
|
||||
public class RasaAi : IBotPlatform
|
||||
public class RasaAi : BotEngineBase, IBotPlatform
|
||||
{
|
||||
public Database dc { get; set; }
|
||||
public AIConfiguration AiConfig { get; set; }
|
||||
|
||||
public Agent agent { get; set; }
|
||||
|
||||
public RasaAi(Database dc)
|
||||
{
|
||||
this.dc = dc;
|
||||
}
|
||||
|
||||
public RasaAi(Database dc, AIConfiguration aiConfig)
|
||||
{
|
||||
this.dc = dc;
|
||||
|
||||
AiConfig = aiConfig;
|
||||
agent = this.LoadAgent(dc, aiConfig);
|
||||
aiConfig.DevMode = agent.DeveloperAccessToken == aiConfig.ClientAccessToken;
|
||||
}
|
||||
|
||||
public AIResponse TextRequest(AIRequest request)
|
||||
{
|
||||
AIResponse aiResponse = new AIResponse();
|
||||
|
||||
#if MODEL_PER_CONTEXTS
|
||||
string model = RasaRequestExtension.GetModelPerContexts(agent, AiConfig, request, dc);
|
||||
var result = CallRasa(agent.Id, request.Query.First(), model);
|
||||
#else
|
||||
var result = CallRasa(rasa.agent.Id, request.Query.First(), rasa.agent.Id);
|
||||
#endif
|
||||
|
||||
result.Content.Log();
|
||||
|
||||
RasaResponse response = result.Data;
|
||||
|
|
@ -119,7 +98,13 @@ namespace BotSharp.Core.Engines
|
|||
|
||||
public void Train()
|
||||
{
|
||||
var corpus = agent.GrabCorpus(dc);
|
||||
var trainingData = new RasaTrainingData
|
||||
{
|
||||
Entities = new List<RasaTraningEntity>(),
|
||||
UserSays = new List<RasaIntentExpression>()
|
||||
};
|
||||
|
||||
var corpus = GetIntentExpressions();
|
||||
var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Nlu").Value}");
|
||||
|
||||
var contextHashs = corpus.UserSays
|
||||
|
|
@ -146,8 +131,8 @@ namespace BotSharp.Core.Engines
|
|||
|
||||
var data = new RasaTrainingData
|
||||
{
|
||||
Entities = entity_synonyms,
|
||||
UserSays = common_examples
|
||||
Entities = entity_synonyms.Select(x => x.ToObject<RasaTraningEntity>()).ToList(),
|
||||
UserSays = common_examples.Select(x => x.Intent.ToObject<RasaIntentExpression>()).ToList()
|
||||
};
|
||||
|
||||
// meet minimal requirement
|
||||
|
|
@ -231,47 +216,5 @@ namespace BotSharp.Core.Engines
|
|||
});
|
||||
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public string TrainWithoutContext()
|
||||
{
|
||||
var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Nlu").Value}");
|
||||
var rest = new RestRequest("train", Method.POST);
|
||||
rest.AddQueryParameter("project", agent.Id);
|
||||
|
||||
var corpus = agent.GrabCorpus(dc);
|
||||
|
||||
string json = JsonConvert.SerializeObject(new { rasa_nlu_data = corpus },
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
string trainingConfig = agent.Language == "zh" ? "config_jieba_mitie_sklearn.yml" : "config_spacy.yml";
|
||||
string body = File.ReadAllText($"{Database.ContentRootPath}{Path.DirectorySeparatorChar}Settings{Path.DirectorySeparatorChar}{trainingConfig}");
|
||||
body = $"{body}\r\ndata: {json}";
|
||||
rest.AddParameter("application/x-yml", body, ParameterType.RequestBody);
|
||||
|
||||
var response = client.Execute(rest);
|
||||
|
||||
if (response.IsSuccessful)
|
||||
{
|
||||
var result = JObject.Parse(response.Content);
|
||||
|
||||
string modelName = result["info"].Value<String>().Split(": ")[1];
|
||||
|
||||
return modelName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = JObject.Parse(response.Content);
|
||||
|
||||
Console.WriteLine(result["error"]);
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,13 @@
|
|||
using Newtonsoft.Json;
|
||||
using BotSharp.Core.Engines;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Models
|
||||
{
|
||||
public class RasaIntentExpression
|
||||
public class RasaIntentExpression : TrainingIntentExpression<RasaIntentExpressionPart>
|
||||
{
|
||||
public RasaIntentExpression()
|
||||
{
|
||||
}
|
||||
|
||||
public String Text { get; set; }
|
||||
public String Intent { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public String ContextHash { get; set; }
|
||||
|
||||
public List<RasaIntentExpressionPart> Entities { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
using System;
|
||||
using BotSharp.Core.Engines;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Models
|
||||
{
|
||||
public class RasaIntentExpressionPart
|
||||
public class RasaIntentExpressionPart : TrainingIntentExpressionPart
|
||||
{
|
||||
public int Start { get; set; }
|
||||
public int End { get; set; }
|
||||
public String Value { get; set; }
|
||||
public String Entity { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
using Newtonsoft.Json;
|
||||
using BotSharp.Core.Engines;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Adapters.Rasa
|
||||
{
|
||||
public class RasaTraningEntity
|
||||
public sealed class RasaTraningEntity : TrainingEntity
|
||||
{
|
||||
[JsonIgnore]
|
||||
public String EntityType { get; set; }
|
||||
public override String EntityType { get; set; }
|
||||
|
||||
[JsonProperty("value")]
|
||||
public String EntityValue { get; set; }
|
||||
|
||||
public List<String> Synonyms { get; set; }
|
||||
public override String EntityValue { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace BotSharp.Core.Engines.SpaCy
|
|||
List<TrainingNode> trainingData = new List<TrainingNode>();
|
||||
|
||||
var dc = new DefaultDataContextLoader().GetDefaultDc();
|
||||
var corpus = agent.GrabCorpus(dc);
|
||||
/*var corpus = agent.GrabCorpus(dc);
|
||||
|
||||
corpus.UserSays.ForEach(userSay =>
|
||||
{
|
||||
|
|
@ -40,7 +40,7 @@ namespace BotSharp.Core.Engines.SpaCy
|
|||
});
|
||||
trainingData.Add(new TrainingNode(userSay.Text, entityLabel));
|
||||
}
|
||||
});
|
||||
});*/
|
||||
entitiesInTrainingSet = entitiesInTrainingSet.Distinct().ToList();
|
||||
var client = new RestClient(Configuration.GetSection("SpaCyProvider:Url").Value);
|
||||
var request = new RestRequest("entityrecognizer", Method.POST);
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ namespace BotSharp.Core.Engines.SpaCy
|
|||
List<List<NlpToken>> tokens = new List<List<NlpToken>>();
|
||||
Boolean res = true;
|
||||
var dc = new DefaultDataContextLoader().GetDefaultDc();
|
||||
var corpus = agent.GrabCorpus(dc);
|
||||
/*var corpus = ;
|
||||
|
||||
corpus.UserSays.ForEach(usersay => {
|
||||
request.AddParameter("text", usersay.Text);
|
||||
var response = client.Execute<Result>(request);
|
||||
tokens.Add(response.Data.Tokens);
|
||||
res = res && response.IsSuccessful;
|
||||
});
|
||||
});*/
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ namespace BotSharp.Core.Engines.SpaCy
|
|||
List<List<decimal>> vectors = new List<List<decimal>>();
|
||||
Boolean res = true;
|
||||
var dc = new DefaultDataContextLoader().GetDefaultDc();
|
||||
var corpus = agent.GrabCorpus(dc);
|
||||
/*var corpus = agent.GrabCorpus(dc);
|
||||
|
||||
corpus.UserSays.ForEach(usersay => {
|
||||
request.AddParameter("text", usersay.Text);
|
||||
var response = client.Execute<Result>(request);
|
||||
vectors.Add(response.Data.Vectors);
|
||||
res = res && response.IsSuccessful;
|
||||
});
|
||||
});*/
|
||||
|
||||
data.Add("Features", JToken.FromObject(vectors));
|
||||
|
||||
|
|
|
|||
14
BotSharp.Core/Engines/TrainingCorpus.cs
Normal file
14
BotSharp.Core/Engines/TrainingCorpus.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using BotSharp.Core.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
public class TrainingCorpus
|
||||
{
|
||||
public List<TrainingIntentExpression<TrainingIntentExpressionPart>> UserSays { get; set; }
|
||||
|
||||
public List<TrainingEntity> Entities { get; set; }
|
||||
}
|
||||
}
|
||||
15
BotSharp.Core/Engines/TrainingEntity.cs
Normal file
15
BotSharp.Core/Engines/TrainingEntity.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
public class TrainingEntity
|
||||
{
|
||||
public virtual String EntityType { get; set; }
|
||||
|
||||
public virtual String EntityValue { get; set; }
|
||||
|
||||
public List<String> Synonyms { get; set; }
|
||||
}
|
||||
}
|
||||
18
BotSharp.Core/Engines/TrainingIntentExpression.cs
Normal file
18
BotSharp.Core/Engines/TrainingIntentExpression.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
public class TrainingIntentExpression<TPart> where TPart : TrainingIntentExpressionPart
|
||||
{
|
||||
public String Text { get; set; }
|
||||
public String Intent { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public String ContextHash { get; set; }
|
||||
|
||||
public List<TPart> Entities { get; set; }
|
||||
}
|
||||
}
|
||||
14
BotSharp.Core/Engines/TrainingIntentExpressionPart.cs
Normal file
14
BotSharp.Core/Engines/TrainingIntentExpressionPart.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.Core.Engines
|
||||
{
|
||||
public class TrainingIntentExpressionPart
|
||||
{
|
||||
public int Start { get; set; }
|
||||
public int End { get; set; }
|
||||
public String Value { get; set; }
|
||||
public String Entity { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,21 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using BotSharp.Core.Agents;
|
||||
using BotSharp.Core.Engines;
|
||||
using BotSharp.Core.Models;
|
||||
using EntityFrameworkCore.BootKit;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.RestApi
|
||||
{
|
||||
[Route("[controller]/[action]")]
|
||||
/// <summary>
|
||||
/// Agent
|
||||
/// </summary>
|
||||
[Route("v1/[controller]/[action]")]
|
||||
public class AgentController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -16,7 +26,28 @@ namespace BotSharp.RestApi
|
|||
[HttpGet("{agentId}")]
|
||||
public ActionResult Restore([FromRoute] String agentId)
|
||||
{
|
||||
var botsHeaderFilePath = $"{Database.ContentRootPath}App_Data{Path.DirectorySeparatorChar}DbInitializer{Path.DirectorySeparatorChar}Agents{Path.DirectorySeparatorChar}agents.json";
|
||||
var agents = JsonConvert.DeserializeObject<List<AgentImportHeader>>(System.IO.File.ReadAllText(botsHeaderFilePath));
|
||||
|
||||
var rasa = new RasaAi();
|
||||
var agentHeader = agents.First(x => x.Id == agentId);
|
||||
rasa.RestoreAgent<AgentImporterInDialogflow>(agentHeader);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dump agent
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{agentId}")]
|
||||
public ActionResult<Agent> Dump([FromRoute] String agentId)
|
||||
{
|
||||
var rasa = new RasaAi();
|
||||
var agent = rasa.LoadAgent(agentId);
|
||||
|
||||
return Ok(agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\netcoreapp2.1\BotSharp.RestApi.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
13
BotSharp.RestApi/ConversationController.cs
Normal file
13
BotSharp.RestApi/ConversationController.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.RestApi
|
||||
{
|
||||
[Route("v1/[controller]/[action]")]
|
||||
public class ConversationController : ControllerBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
12
BotSharp.RestApi/IntentController.cs
Normal file
12
BotSharp.RestApi/IntentController.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BotSharp.RestApi
|
||||
{
|
||||
[Route("v1/[controller]/[action]")]
|
||||
public class IntentController : ControllerBase
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using BotSharp.Core.Models;
|
|||
using EntityFrameworkCore.BootKit;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
|
@ -22,13 +23,11 @@ namespace BotSharp.UnitTest
|
|||
var agent = new Agent
|
||||
{
|
||||
Id = BOT_ID,
|
||||
Name = BOT_NAME,
|
||||
Language = "en",
|
||||
UserId = Guid.NewGuid().ToString()
|
||||
};
|
||||
var rasa = new RasaAi(dc);
|
||||
rasa.agent = agent;
|
||||
int row = dc.DbTran(() => rasa.agent.SaveAgent(dc));
|
||||
var rasa = new RasaAi();
|
||||
//int row = dc.DbTran(() => rasa.agent.SaveAgent(dc));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
@ -37,38 +36,31 @@ namespace BotSharp.UnitTest
|
|||
var agent = new Agent
|
||||
{
|
||||
Id = BOT_ID,
|
||||
Name = BOT_NAME,
|
||||
Language = "en"
|
||||
};
|
||||
var rasa = new RasaAi(dc);
|
||||
rasa.agent = agent;
|
||||
int row = dc.DbTran(() => rasa.agent.SaveAgent(dc));
|
||||
var rasa = new RasaAi();
|
||||
//int row = dc.DbTran(() => rasa.agent.SaveAgent(dc));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RestoreAgentTest()
|
||||
public void RestoreAgentFromDialogflowToRasaTest()
|
||||
{
|
||||
var rasa = new RasaAi(dc);
|
||||
var importer = new AgentImporterInDialogflow();
|
||||
var botsHeaderFilePath = $"{Database.ContentRootPath}App_Data{Path.DirectorySeparatorChar}DbInitializer{Path.DirectorySeparatorChar}Agents{Path.DirectorySeparatorChar}agents.json";
|
||||
var agents = JsonConvert.DeserializeObject<List<AgentImportHeader>>(File.ReadAllText(botsHeaderFilePath));
|
||||
|
||||
string dataDir = $"{Database.ContentRootPath}App_Data{Path.DirectorySeparatorChar}DbInitializer{Path.DirectorySeparatorChar}Agents{Path.DirectorySeparatorChar}";
|
||||
var agent = rasa.RestoreAgent(importer, BOT_NAME, dataDir);
|
||||
agent.Id = BOT_ID;
|
||||
agent.ClientAccessToken = BOT_CLIENT_TOKEN;
|
||||
agent.DeveloperAccessToken = BOT_DEVELOPER_TOKEN;
|
||||
agent.UserId = Guid.NewGuid().ToString();
|
||||
rasa.agent = agent;
|
||||
|
||||
int row = dc.DbTran(() => rasa.agent.SaveAgent(dc));
|
||||
agents.ForEach(agentHeader => {
|
||||
var rasa = new RasaAi();
|
||||
rasa.RestoreAgent<AgentImporterInDialogflow>(agentHeader);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TrainAgentTest()
|
||||
{
|
||||
var config = new AIConfiguration(BOT_CLIENT_TOKEN, SupportedLanguage.English);
|
||||
var config = new AIConfiguration("", SupportedLanguage.English) { AgentId = BOT_ID };
|
||||
config.SessionId = Guid.NewGuid().ToString();
|
||||
|
||||
var rasa = new RasaAi(dc, config);
|
||||
var rasa = new RasaAi();
|
||||
|
||||
rasa.Train();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.3.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ namespace BotSharp.UnitTest
|
|||
[TestMethod]
|
||||
public void TrainingTest()
|
||||
{
|
||||
var config = new AIConfiguration(BOT_CLIENT_TOKEN, SupportedLanguage.English);
|
||||
var config = new AIConfiguration("", SupportedLanguage.English) { AgentId = BOT_ID };
|
||||
config.SessionId = Guid.NewGuid().ToString();
|
||||
|
||||
var rasa = new RasaAi(dc, config);
|
||||
var rasa = new RasaAi();
|
||||
|
||||
var trainer = new BotTrainer(BOT_ID, dc);
|
||||
trainer.Train(rasa.agent);
|
||||
trainer.Train(rasa.LoadAgent(BOT_ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ namespace BotSharp.UnitTest
|
|||
[TestMethod]
|
||||
public void TextRequest()
|
||||
{
|
||||
var config = new AIConfiguration(BOT_CLIENT_TOKEN, SupportedLanguage.English);
|
||||
config.SessionId = Guid.NewGuid().ToString();
|
||||
var rasa = new RasaAi();
|
||||
var agent = rasa.LoadAgent(BOT_ID);
|
||||
|
||||
var rasa = new RasaAi(dc, config);
|
||||
var config = new AIConfiguration(agent.ClientAccessToken, SupportedLanguage.English) { AgentId = BOT_ID };
|
||||
config.SessionId = Guid.NewGuid().ToString();
|
||||
|
||||
// Round 1
|
||||
var response = rasa.TextRequest(new AIRequest { Query = new String[] { "Can you play country music?" } });
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ namespace BotSharp.UnitTest
|
|||
public abstract class TestEssential
|
||||
{
|
||||
public static String BOT_ID = "6a9fd374-c43d-447a-97f2-f37540d0c725";
|
||||
public static String BOT_CLIENT_TOKEN = "43a0f48e3f1e41da822092e7e699426b";
|
||||
public static String BOT_DEVELOPER_TOKEN = "cd1e4685c6a04d7db1f59e6853fd597b";
|
||||
public static String BOT_NAME = "Spotify";
|
||||
|
||||
protected Database dc { get; set; }
|
||||
protected string contentRoot;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,11 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="3.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="3.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
"Assemblies": "BotSharp.Core"
|
||||
}
|
||||
|
|
|
|||
15
BotSharp.WebHost/Settings/logging.json
Normal file
15
BotSharp.WebHost/Settings/logging.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
BotSharp.WebHost/Settings/swagger.json
Normal file
19
BotSharp.WebHost/Settings/swagger.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"Swagger": {
|
||||
"Contact": {
|
||||
"Email": "haiping008@gmail.com",
|
||||
"Name": "Haiping Chen",
|
||||
"Url": "https://github.com/Oceania2018"
|
||||
},
|
||||
"Description": "BotSharp is a chatbot platform written in C# (.net core), and it's developed for enterprise usage.",
|
||||
"Endpoint": "/swagger/v1/swagger.json",
|
||||
"License": {
|
||||
"Name": "Apache License 2.0",
|
||||
"Url": "https://github.com/Oceania2018/BotSharp/blob/master/LICENSE"
|
||||
},
|
||||
"TermsOfService": "http://www.apache.org/licenses/",
|
||||
"Title": "BotSharp API",
|
||||
"Version": "v1",
|
||||
"Stylesheet": "/swagger.css"
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,9 @@ using Microsoft.AspNetCore.Hosting;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
|
||||
namespace BotSharp.WebHost
|
||||
{
|
||||
|
|
@ -22,6 +24,8 @@ namespace BotSharp.WebHost
|
|||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddCors();
|
||||
|
||||
services.AddMvc(options =>
|
||||
{
|
||||
options.RespectBrowserAcceptHeader = true;
|
||||
|
|
@ -30,6 +34,15 @@ namespace BotSharp.WebHost
|
|||
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
});
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
var info = Configuration.GetSection("Swagger").Get<Info>();
|
||||
c.SwaggerDoc(info.Version, info);
|
||||
|
||||
var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "BotSharp.RestApi.xml");
|
||||
c.IncludeXmlComments(filePath);
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
|
|
@ -39,11 +52,32 @@ namespace BotSharp.WebHost
|
|||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseSwagger(c =>
|
||||
{
|
||||
|
||||
});
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
var info = Configuration.GetSection("Swagger").Get<Info>();
|
||||
|
||||
c.SupportedSubmitMethods(SubmitMethod.Get, SubmitMethod.Post, SubmitMethod.Put, SubmitMethod.Patch, SubmitMethod.Delete);
|
||||
c.ShowExtensions();
|
||||
c.SwaggerEndpoint(Configuration.GetValue<String>("Swagger:Endpoint"), info.Title);
|
||||
c.RoutePrefix = String.Empty;
|
||||
c.DocumentTitle = info.Title;
|
||||
c.InjectStylesheet(Configuration.GetValue<String>("Swagger:Stylesheet"));
|
||||
});
|
||||
|
||||
app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
|
||||
|
||||
app.UseMvc();
|
||||
|
||||
Database.Configuration = Configuration;
|
||||
Database.ContentRootPath = env.ContentRootPath;
|
||||
Database.Assemblies = new String[] { "BotSharp.Core" };
|
||||
Database.Assemblies = Configuration.GetValue<String>("Assemblies").Split(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
BotSharp.WebHost/wwwroot/images/BotSharp.png
Normal file
BIN
BotSharp.WebHost/wwwroot/images/BotSharp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
BotSharp.WebHost/wwwroot/images/BotSharp.psd
Normal file
BIN
BotSharp.WebHost/wwwroot/images/BotSharp.psd
Normal file
Binary file not shown.
3
BotSharp.WebHost/wwwroot/swagger.css
Normal file
3
BotSharp.WebHost/wwwroot/swagger.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.topbar-wrapper a span {
|
||||
visibility: hidden;
|
||||
}
|
||||
Loading…
Reference in a new issue