diff --git a/BotSharp.Core/Abstractions/IAgentImporter.cs b/BotSharp.Core/Abstractions/IAgentImporter.cs
index 584b4e22..e2ea0acf 100644
--- a/BotSharp.Core/Abstractions/IAgentImporter.cs
+++ b/BotSharp.Core/Abstractions/IAgentImporter.cs
@@ -10,10 +10,10 @@ namespace BotSharp.Core.Engines
///
/// Load agent summary
///
- /// agent guid or name
+ ///
///
///
- Agent LoadAgent(string agentId, string agentDir);
+ Agent LoadAgent(AgentImportHeader agentHeader, string agentDir);
///
/// Load user customized entity type
diff --git a/BotSharp.Core/Abstractions/IBotPlatform.cs b/BotSharp.Core/Abstractions/IBotPlatform.cs
index 48275a7a..df6ee8bd 100644
--- a/BotSharp.Core/Abstractions/IBotPlatform.cs
+++ b/BotSharp.Core/Abstractions/IBotPlatform.cs
@@ -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();
}
}
diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj
index 35f376ef..0d8a8e26 100644
--- a/BotSharp.Core/BotSharp.Core.csproj
+++ b/BotSharp.Core/BotSharp.Core.csproj
@@ -25,7 +25,7 @@
- TRACE;MODEL_PER_CONTEXTS;NETCOREAPP;NETCOREAPP2_1
+ TRACE;DEBUG
@@ -43,9 +43,4 @@
-
-
-
-
-
diff --git a/BotSharp.Core/Engines/AgentImportHeader.cs b/BotSharp.Core/Engines/AgentImportHeader.cs
new file mode 100644
index 00000000..b73c7d4c
--- /dev/null
+++ b/BotSharp.Core/Engines/AgentImportHeader.cs
@@ -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; }
+ }
+}
diff --git a/BotSharp.Core/Agents/AgentDriver.cs b/BotSharp.Core/Engines/BotEngineBase.cs
similarity index 50%
rename from BotSharp.Core/Agents/AgentDriver.cs
rename to BotSharp.Core/Engines/BotEngineBase.cs
index ba48b6a5..73235248 100644
--- a/BotSharp.Core/Agents/AgentDriver.cs
+++ b/BotSharp.Core/Engines/BotEngineBase.cs
@@ -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
+ ///
+ /// Bot engine/ platform base class
+ ///
+ 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().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)
+ ///
+ /// Load Agent
+ ///
+ /// agentId, clientAccessToken, developerAccessToken
+ ///
+ public Agent LoadAgent(string id)
{
- return dc.Table()
- .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()
+ .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;
}
///
/// Restore a agent instance from backup json files
///
- ///
- ///
+ ///
+ ///
+ ///
///
- public static Agent RestoreAgent(this IBotPlatform engine, IAgentImporter importer, String agentId, string dataDir)
+ public bool RestoreAgent(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().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(),
- UserSays = new List()
+ UserSays = new List>(),
+ Entities = new List()
};
var expressParts = new List();
@@ -93,7 +124,7 @@ namespace BotSharp.Core.Agents
{
intent.UserSays.ForEach(exp =>
{
- var say = new RasaIntentExpression
+ var say = new TrainingIntentExpression
{
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();
+ if (say.Entities == null) say.Entities = new List();
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()
join ee in dc.Table() 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;
}
}
}
diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs b/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs
new file mode 100644
index 00000000..da88bf23
--- /dev/null
+++ b/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs
@@ -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();
+ }
+ }
+}
diff --git a/BotSharp.Core/Engines/CRFsuite/CRFsuiteEntityRecognizer.cs b/BotSharp.Core/Engines/CRFsuite/CRFsuiteEntityRecognizer.cs
index c50cb7c6..54ad91a9 100644
--- a/BotSharp.Core/Engines/CRFsuite/CRFsuiteEntityRecognizer.cs
+++ b/BotSharp.Core/Engines/CRFsuite/CRFsuiteEntityRecognizer.cs
@@ -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 train_sent = new List();
diff --git a/BotSharp.Core/Engines/Dialogflow/AIConfiguration.cs b/BotSharp.Core/Engines/Dialogflow/AIConfiguration.cs
index 1d4978b4..77df4aa2 100644
--- a/BotSharp.Core/Engines/Dialogflow/AIConfiguration.cs
+++ b/BotSharp.Core/Engines/Dialogflow/AIConfiguration.cs
@@ -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; }
diff --git a/BotSharp.Core/Engines/Dialogflow/AgentImporterInDialogflow.cs b/BotSharp.Core/Engines/Dialogflow/AgentImporterInDialogflow.cs
index a43cfc6a..41581cb0 100644
--- a/BotSharp.Core/Engines/Dialogflow/AgentImporterInDialogflow.cs
+++ b/BotSharp.Core/Engines/Dialogflow/AgentImporterInDialogflow.cs
@@ -22,18 +22,25 @@ namespace BotSharp.Core.Engines
///
/// Load agent meta
///
- ///
+ ///
///
///
- 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(data);
- agent.Id = Guid.NewGuid().ToString();
- agent.Name = agentId;
+ agent.Name = agentHeader.Name;
+ agent.Id = agentHeader.Id;
var result = agent.ToObject();
+ result.ClientAccessToken = agentHeader.ClientAccessToken;
+ result.DeveloperAccessToken = agentHeader.DeveloperAccessToken;
+ if(agentHeader.UserId != null)
+ {
+ result.UserId = agentHeader.UserId;
+ }
+
result.MlConfig = agent.ToObject();
result.MlConfig.MinConfidence = agent.MlMinConfidence;
result.MlConfig.AgentId = agent.Id;
diff --git a/BotSharp.Core/Engines/Rasa/RasaAi.cs b/BotSharp.Core/Engines/Rasa/RasaAi.cs
index 71530e07..0d23c3e8 100644
--- a/BotSharp.Core/Engines/Rasa/RasaAi.cs
+++ b/BotSharp.Core/Engines/Rasa/RasaAi.cs
@@ -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
{
///
- /// Rasa nlu 0.12.x
+ /// Rasa nlu >= 0.12
///
- 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(),
+ UserSays = new List()
+ };
+
+ 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()).ToList(),
+ UserSays = common_examples.Select(x => x.Intent.ToObject()).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().Split(": ")[1];
-
- return modelName;
- }
- else
- {
- var result = JObject.Parse(response.Content);
-
- Console.WriteLine(result["error"]);
-
- return String.Empty;
- }
- }
-
}
}
diff --git a/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs b/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs
index b3dfcd4c..414f0b50 100644
--- a/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs
+++ b/BotSharp.Core/Engines/Rasa/RasaIntentExpression.cs
@@ -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
{
- public RasaIntentExpression()
- {
- }
- public String Text { get; set; }
- public String Intent { get; set; }
-
- [JsonIgnore]
- public String ContextHash { get; set; }
-
- public List Entities { get; set; }
}
}
diff --git a/BotSharp.Core/Engines/Rasa/RasaIntentExpressionPart.cs b/BotSharp.Core/Engines/Rasa/RasaIntentExpressionPart.cs
index d4c254c2..4925df0e 100644
--- a/BotSharp.Core/Engines/Rasa/RasaIntentExpressionPart.cs
+++ b/BotSharp.Core/Engines/Rasa/RasaIntentExpressionPart.cs
@@ -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; }
}
}
diff --git a/BotSharp.Core/Engines/Rasa/RasaTraningEntity.cs b/BotSharp.Core/Engines/Rasa/RasaTraningEntity.cs
index 67a38a28..6ac97ebc 100644
--- a/BotSharp.Core/Engines/Rasa/RasaTraningEntity.cs
+++ b/BotSharp.Core/Engines/Rasa/RasaTraningEntity.cs
@@ -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 Synonyms { get; set; }
+ public override String EntityValue { get; set; }
}
}
diff --git a/BotSharp.Core/Engines/SpaCy/SpaCyEntityRecognizer.cs b/BotSharp.Core/Engines/SpaCy/SpaCyEntityRecognizer.cs
index a1862712..d0338412 100644
--- a/BotSharp.Core/Engines/SpaCy/SpaCyEntityRecognizer.cs
+++ b/BotSharp.Core/Engines/SpaCy/SpaCyEntityRecognizer.cs
@@ -27,7 +27,7 @@ namespace BotSharp.Core.Engines.SpaCy
List trainingData = new List();
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);
diff --git a/BotSharp.Core/Engines/SpaCy/SpaCyTokenizer.cs b/BotSharp.Core/Engines/SpaCy/SpaCyTokenizer.cs
index b36e19d1..0fc22991 100644
--- a/BotSharp.Core/Engines/SpaCy/SpaCyTokenizer.cs
+++ b/BotSharp.Core/Engines/SpaCy/SpaCyTokenizer.cs
@@ -23,14 +23,14 @@ namespace BotSharp.Core.Engines.SpaCy
List> tokens = new List>();
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(request);
tokens.Add(response.Data.Tokens);
res = res && response.IsSuccessful;
- });
+ });*/
diff --git a/BotSharp.Core/Engines/SpaCy/SpacyFeaturizer.cs b/BotSharp.Core/Engines/SpaCy/SpacyFeaturizer.cs
index 1602141f..f456b8a2 100644
--- a/BotSharp.Core/Engines/SpaCy/SpacyFeaturizer.cs
+++ b/BotSharp.Core/Engines/SpaCy/SpacyFeaturizer.cs
@@ -21,14 +21,14 @@ namespace BotSharp.Core.Engines.SpaCy
List> vectors = new List>();
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(request);
vectors.Add(response.Data.Vectors);
res = res && response.IsSuccessful;
- });
+ });*/
data.Add("Features", JToken.FromObject(vectors));
diff --git a/BotSharp.Core/Engines/TrainingCorpus.cs b/BotSharp.Core/Engines/TrainingCorpus.cs
new file mode 100644
index 00000000..c2d9c69f
--- /dev/null
+++ b/BotSharp.Core/Engines/TrainingCorpus.cs
@@ -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> UserSays { get; set; }
+
+ public List Entities { get; set; }
+ }
+}
diff --git a/BotSharp.Core/Engines/TrainingEntity.cs b/BotSharp.Core/Engines/TrainingEntity.cs
new file mode 100644
index 00000000..8c73135a
--- /dev/null
+++ b/BotSharp.Core/Engines/TrainingEntity.cs
@@ -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 Synonyms { get; set; }
+ }
+}
diff --git a/BotSharp.Core/Engines/TrainingIntentExpression.cs b/BotSharp.Core/Engines/TrainingIntentExpression.cs
new file mode 100644
index 00000000..1a8fa034
--- /dev/null
+++ b/BotSharp.Core/Engines/TrainingIntentExpression.cs
@@ -0,0 +1,18 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BotSharp.Core.Engines
+{
+ public class TrainingIntentExpression where TPart : TrainingIntentExpressionPart
+ {
+ public String Text { get; set; }
+ public String Intent { get; set; }
+
+ [JsonIgnore]
+ public String ContextHash { get; set; }
+
+ public List Entities { get; set; }
+ }
+}
diff --git a/BotSharp.Core/Engines/TrainingIntentExpressionPart.cs b/BotSharp.Core/Engines/TrainingIntentExpressionPart.cs
new file mode 100644
index 00000000..d5cf5d2a
--- /dev/null
+++ b/BotSharp.Core/Engines/TrainingIntentExpressionPart.cs
@@ -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; }
+ }
+}
diff --git a/BotSharp.RestApi/AgentController.cs b/BotSharp.RestApi/AgentController.cs
index 2cea7483..49bc2de2 100644
--- a/BotSharp.RestApi/AgentController.cs
+++ b/BotSharp.RestApi/AgentController.cs
@@ -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]")]
+ ///
+ /// Agent
+ ///
+ [Route("v1/[controller]/[action]")]
public class AgentController : ControllerBase
{
///
@@ -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>(System.IO.File.ReadAllText(botsHeaderFilePath));
+
+ var rasa = new RasaAi();
+ var agentHeader = agents.First(x => x.Id == agentId);
+ rasa.RestoreAgent(agentHeader);
+
return Ok();
}
+
+ ///
+ /// Dump agent
+ ///
+ ///
+ ///
+ [HttpGet("{agentId}")]
+ public ActionResult Dump([FromRoute] String agentId)
+ {
+ var rasa = new RasaAi();
+ var agent = rasa.LoadAgent(agentId);
+
+ return Ok(agent);
+ }
}
}
diff --git a/BotSharp.RestApi/BotSharp.RestApi.csproj b/BotSharp.RestApi/BotSharp.RestApi.csproj
index e2d8172e..ed3204a0 100644
--- a/BotSharp.RestApi/BotSharp.RestApi.csproj
+++ b/BotSharp.RestApi/BotSharp.RestApi.csproj
@@ -4,6 +4,10 @@
netcoreapp2.1
+
+ bin\Debug\netcoreapp2.1\BotSharp.RestApi.xml
+
+
diff --git a/BotSharp.RestApi/ConversationController.cs b/BotSharp.RestApi/ConversationController.cs
new file mode 100644
index 00000000..98786113
--- /dev/null
+++ b/BotSharp.RestApi/ConversationController.cs
@@ -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
+ {
+
+ }
+}
diff --git a/BotSharp.RestApi/IntentController.cs b/BotSharp.RestApi/IntentController.cs
new file mode 100644
index 00000000..9dbaea48
--- /dev/null
+++ b/BotSharp.RestApi/IntentController.cs
@@ -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
+ {
+ }
+}
diff --git a/BotSharp.UnitTest/AgentTest.cs b/BotSharp.UnitTest/AgentTest.cs
index 1792906e..1ea9d696 100644
--- a/BotSharp.UnitTest/AgentTest.cs
+++ b/BotSharp.UnitTest/AgentTest.cs
@@ -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>(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(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();
}
diff --git a/BotSharp.UnitTest/BotSharp.UnitTest.csproj b/BotSharp.UnitTest/BotSharp.UnitTest.csproj
index 5ed76d0e..ca7277c4 100644
--- a/BotSharp.UnitTest/BotSharp.UnitTest.csproj
+++ b/BotSharp.UnitTest/BotSharp.UnitTest.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/BotSharp.UnitTest/BotTrainerTest.cs b/BotSharp.UnitTest/BotTrainerTest.cs
index 4b006bf5..f7d25bcc 100644
--- a/BotSharp.UnitTest/BotTrainerTest.cs
+++ b/BotSharp.UnitTest/BotTrainerTest.cs
@@ -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));
}
}
}
diff --git a/BotSharp.UnitTest/ConversationTest.cs b/BotSharp.UnitTest/ConversationTest.cs
index 0452d544..c412c005 100644
--- a/BotSharp.UnitTest/ConversationTest.cs
+++ b/BotSharp.UnitTest/ConversationTest.cs
@@ -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?" } });
diff --git a/BotSharp.UnitTest/TestEssential.cs b/BotSharp.UnitTest/TestEssential.cs
index 885065c8..61f03cfc 100644
--- a/BotSharp.UnitTest/TestEssential.cs
+++ b/BotSharp.UnitTest/TestEssential.cs
@@ -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;
diff --git a/BotSharp.WebHost/BotSharp.WebHost.csproj b/BotSharp.WebHost/BotSharp.WebHost.csproj
index efcd6af0..458f02fd 100644
--- a/BotSharp.WebHost/BotSharp.WebHost.csproj
+++ b/BotSharp.WebHost/BotSharp.WebHost.csproj
@@ -100,6 +100,11 @@
+
+
+
+
+
diff --git a/BotSharp.WebHost/Settings/app.json b/BotSharp.WebHost/Settings/app.json
index 26bb0ac7..497ba711 100644
--- a/BotSharp.WebHost/Settings/app.json
+++ b/BotSharp.WebHost/Settings/app.json
@@ -1,15 +1,3 @@
{
- "Logging": {
- "IncludeScopes": false,
- "Debug": {
- "LogLevel": {
- "Default": "Warning"
- }
- },
- "Console": {
- "LogLevel": {
- "Default": "Warning"
- }
- }
- }
+ "Assemblies": "BotSharp.Core"
}
diff --git a/BotSharp.WebHost/Settings/logging.json b/BotSharp.WebHost/Settings/logging.json
new file mode 100644
index 00000000..26bb0ac7
--- /dev/null
+++ b/BotSharp.WebHost/Settings/logging.json
@@ -0,0 +1,15 @@
+{
+ "Logging": {
+ "IncludeScopes": false,
+ "Debug": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ },
+ "Console": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ }
+ }
+}
diff --git a/BotSharp.WebHost/Settings/swagger.json b/BotSharp.WebHost/Settings/swagger.json
new file mode 100644
index 00000000..8d3b771c
--- /dev/null
+++ b/BotSharp.WebHost/Settings/swagger.json
@@ -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"
+ }
+}
diff --git a/BotSharp.WebHost/Startup.cs b/BotSharp.WebHost/Startup.cs
index 43fd69d7..509ac10f 100644
--- a/BotSharp.WebHost/Startup.cs
+++ b/BotSharp.WebHost/Startup.cs
@@ -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();
+ 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();
+
+ c.SupportedSubmitMethods(SubmitMethod.Get, SubmitMethod.Post, SubmitMethod.Put, SubmitMethod.Patch, SubmitMethod.Delete);
+ c.ShowExtensions();
+ c.SwaggerEndpoint(Configuration.GetValue("Swagger:Endpoint"), info.Title);
+ c.RoutePrefix = String.Empty;
+ c.DocumentTitle = info.Title;
+ c.InjectStylesheet(Configuration.GetValue("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("Assemblies").Split(',');
}
}
}
diff --git a/BotSharp.WebHost/wwwroot/images/BotSharp.png b/BotSharp.WebHost/wwwroot/images/BotSharp.png
new file mode 100644
index 00000000..defe10f9
Binary files /dev/null and b/BotSharp.WebHost/wwwroot/images/BotSharp.png differ
diff --git a/BotSharp.WebHost/wwwroot/images/BotSharp.psd b/BotSharp.WebHost/wwwroot/images/BotSharp.psd
new file mode 100644
index 00000000..db98df7b
Binary files /dev/null and b/BotSharp.WebHost/wwwroot/images/BotSharp.psd differ
diff --git a/BotSharp.WebHost/wwwroot/swagger.css b/BotSharp.WebHost/wwwroot/swagger.css
new file mode 100644
index 00000000..877e3e72
--- /dev/null
+++ b/BotSharp.WebHost/wwwroot/swagger.css
@@ -0,0 +1,3 @@
+.topbar-wrapper a span {
+ visibility: hidden;
+}