Refactoring the system, abstracting the platform builder, and decouple the implementation of each platform.

This commit is contained in:
Oceania2018 2018-09-28 17:25:55 -05:00
parent d96febbc22
commit d9e1b40d1c
41 changed files with 838 additions and 138 deletions

View file

@ -0,0 +1,62 @@
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BotSharp.Core
{
/// <summary>
/// Save agent instance into memory.
/// Caution: Data will be lost once application restarts.
/// </summary>
public class AgentStorageInMemory<TExtraData, TEntity> : IAgentStorage<TExtraData, TEntity>
{
private static Dictionary<string, StandardAgent<TExtraData, TEntity>> agents;
public AgentStorageInMemory()
{
if (agents == null) agents = new Dictionary<string, StandardAgent<TExtraData, TEntity>>();
}
public StandardAgent<TExtraData, TEntity> FetchById(string agentId)
{
if (agents.ContainsKey(agentId))
{
return agents[agentId];
}
else
{
return null;
}
}
public StandardAgent<TExtraData, TEntity> FetchByName(string agentName)
{
var data = agents.FirstOrDefault(x => x.Value.Name == agentName);
return data.Value;
}
public bool Persist(StandardAgent<TExtraData, TEntity> agent)
{
if (String.IsNullOrEmpty(agent.Id))
{
agent.Id = Guid.NewGuid().ToString();
agents[agent.Id] = agent;
}
else
{
agents[agent.Id] = agent;
}
return true;
}
public List<StandardAgent<TExtraData, TEntity>> Query()
{
return agents.Select(x => x.Value).ToList();
}
}
}

View file

@ -66,6 +66,8 @@ If you feel that this project is helpful to you, please Star on the project, we
<ItemGroup>
<ProjectReference Include="..\BotSharp.NLP\BotSharp.NLP.csproj" />
<ProjectReference Include="..\BotSharp.Platform.Abstraction\BotSharp.Platform.Abstraction.csproj" />
<ProjectReference Include="..\BotSharp.Platform.Models\BotSharp.Platform.Models.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,43 @@
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core
{
public abstract class PlatformBuilderBase<TStorage, TExtraData, TEntity>
where TStorage : IAgentStorage<TExtraData, TEntity>, new ()
{
protected static TStorage storage;
public PlatformBuilderBase()
{
if (storage == null) storage = new TStorage();
}
public List<StandardAgent<TExtraData, TEntity>> GetAllAgents()
{
return storage.Query();
}
public StandardAgent<TExtraData, TEntity> GetAgentById(string agentId)
{
return storage.FetchById(agentId);
}
public StandardAgent<TExtraData, TEntity> GetAgentByName(string agentName)
{
return storage.FetchByName(agentName);
}
public virtual bool SaveAgent(StandardAgent<TExtraData, TEntity> agent)
{
// default save agent in FileStorage
storage.Persist(agent);
return true;
}
}
}

View file

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\BotSharp.Platform.Models\BotSharp.Platform.Models.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,41 @@
using BotSharp.Platform.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Platform.Abstraction
{
/// <summary>
/// Agent could be persisted in any kind of storage.
/// Example: local file storage, cloud storage, relational database, key-value database or memory
/// </summary>
public interface IAgentStorage<TExtraData, TEntity>
{
/// <summary>
/// Save agent instance
/// </summary>
/// <param name="agent"></param>
/// <returns></returns>
bool Persist(StandardAgent<TExtraData, TEntity> agent);
/// <summary>
/// Get agent by id
/// </summary>
/// <param name="agentId"></param>
/// <returns></returns>
StandardAgent<TExtraData, TEntity> FetchById(string agentId);
/// <summary>
/// Get agent by name
/// </summary>
/// <param name="agentName"></param>
/// <returns></returns>
StandardAgent<TExtraData, TEntity> FetchByName(string agentName);
/// <summary>
/// Query agents
/// </summary>
/// <returns></returns>
List<StandardAgent<TExtraData, TEntity>> Query();
}
}

View file

@ -0,0 +1,45 @@
using BotSharp.Platform.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace BotSharp.Platform.Abstraction
{
/// <summary>
/// Platform abstraction
/// Implement this interface to build a Chatbot platform
/// </summary>
public interface IPlatformBuilder<TStorage, TAgent, TExtraData, TEntity>
where TStorage : IAgentStorage<TExtraData, TEntity>, new()
{
/// <summary>
/// Parse options for the incoming text or voice request from the sender.
/// </summary>
// DialogRequestOptions RequestOptions { get; set; }
/// <summary>
/// Convert platform specific agent to standard agent format
/// </summary>
/// <param name="agent"></param>
/// <returns></returns>
StandardAgent<TExtraData, TEntity> StandardizeAgent(TAgent agent);
/// <summary>
/// Recover standard agent to specific agent format
/// </summary>
/// <param name="agent"></param>
/// <returns></returns>
TAgent RecoverAgent(StandardAgent<TExtraData, TEntity> agent);
/// <summary>
///
/// </summary>
/// <typeparam name="TStorage"></typeparam>
/// <param name="agent"></param>
/// <returns></returns>
bool SaveAgent(StandardAgent<TExtraData, TEntity> agent);
StandardAgent<TExtraData, TEntity> GetAgentById(string agentId);
}
}

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.ComponentModel.Annotations">
<HintPath>C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.ComponentModel.Annotations.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View file

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Platform.Models
{
public class DialogRequestOptions
{
}
}

View file

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace BotSharp.Platform.Models
{
/// <summary>
/// Standard agent data structure
/// All other platform agent has to align with this standard data structure.
/// </summary>
public class StandardAgent<TExtraData, TEntity>
{
public StandardAgent()
{
CreatedDate = DateTime.UtcNow;
Entities = new List<TEntity>();
}
/// <summary>
/// Guid
/// </summary>
[StringLength(36)]
public String Id { get; set; }
/// <summary>
/// Name of chatbot
/// </summary>
[Required]
[MaxLength(64)]
public String Name { get; set; }
/// <summary>
/// Description of chatbot
/// </summary>
[MaxLength(256)]
public String Description { get; set; }
/// <summary>
/// Is the chatbot public or private
/// </summary>
public Boolean Published { get; set; }
/// <summary>
///
/// </summary>
[Required]
[MaxLength(5)]
public String Language { get; set; }
/// <summary>
/// Only access text/ audio rquest
/// </summary>
[StringLength(32)]
public String ClientAccessToken { get; set; }
/// <summary>
/// Developer can access more APIs
/// </summary>
[StringLength(32)]
public String DeveloperAccessToken { get; set; }
//public List<Intent> Intents { get; set; }
public List<TEntity> Entities { get; set; }
public String Birthday
{
get
{
return CreatedDate.ToShortDateString();
}
}
public DateTime CreatedDate { get; set; }
/// <summary>
/// Save extra information for specific platform
/// </summary>
public TExtraData ExtraData { get; set; }
}
}

View file

@ -1,74 +0,0 @@
using BotSharp.Core.Engines.Articulate;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace BotSharp.RestApi.Articulate
{
#if ARTICULATE
[Route("[controller]")]
public class AgentController : ControllerBase
{
[HttpGet]
public List<AgentModel> GetAgent()
{
var agents = new List<AgentModel>();
string dataDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate");
var agentPaths = Directory.GetFiles(dataDir).Where(x => Regex.IsMatch(x, @"agent-\d+.json")).ToList();
for (int i = 0; i< agentPaths.Count; i++)
{
string json = System.IO.File.ReadAllText(agentPaths[i]);
var agent = JsonConvert.DeserializeObject<AgentModel>(json);
agents.Add(agent);
}
return agents;
}
[HttpGet("{agentId}")]
public AgentModel GetAgent([FromRoute] int agentId)
{
string dataPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate", $"agent-{agentId}.json");
string json = System.IO.File.ReadAllText(dataPath);
var agent = JsonConvert.DeserializeObject<AgentModel>(json);
return agent;
}
[HttpGet("name/{agentName}")]
public AgentModel GetAgent([FromRoute] string agentName)
{
AgentModel agent = null;
string dataDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate");
var agentPaths = Directory.GetFiles(dataDir).Where(x => Regex.IsMatch(x, @"agent-\d+\.json")).ToList();
for (int i = 0; i < agentPaths.Count; i++)
{
string json = System.IO.File.ReadAllText(agentPaths[i]);
var agentTmp = JsonConvert.DeserializeObject<AgentModel>(json);
if(agentTmp.AgentName == agentName)
{
agent = agentTmp;
}
}
return agent;
}
}
#endif
}

View file

@ -1,28 +0,0 @@
using BotSharp.Core.Engines.Articulate;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace BotSharp.RestApi.Articulate
{
#if ARTICULATE
[Route("[controller]")]
public class SettingsController : ControllerBase
{
[HttpGet]
public SettingsModel GetSettings()
{
string dataPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate", "settings.json");
string json = System.IO.File.ReadAllText(dataPath);
var settings = JsonConvert.DeserializeObject<SettingsModel>(json);
return settings;
}
}
#endif
}

View file

@ -88,6 +88,7 @@
<ItemGroup>
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
<ProjectReference Include="..\BotSharp.Voice\BotSharp.Voice.csproj" />
<ProjectReference Include="..\Platform.Articulate\Platform.Articulate.csproj" />
</ItemGroup>
</Project>

View file

@ -65,6 +65,7 @@
<ItemGroup>
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
<ProjectReference Include="..\BotSharp.RestApi\BotSharp.RestApi.csproj" />
<ProjectReference Include="..\Platform.Articulate\Platform.Articulate.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -0,0 +1,40 @@
{
"ArticulateAi": {
"Lang": "en",
"Provider": "BotSharpProvider",
"BotSharpProvider": {
},
"Pipe": "BotSharpTokenizer, BotSharpTagger, BotSharpCRFNer, BotSharpIntentClassifier",
"BotSharpTokenizer": {
"tokenizer": "TreebankTokenizer"
},
"BotSharpIntentClassifier": {
"classifer": "SVMClassifier"
},
"BotSharpTagger": {
"tagger": "NGramTagger"
},
"BotSharpCRFNer": {
"template": "|App_Data|CRFLite/template.en"
},
"CRFsuiteEntityRecognizer": {
"fields": "y w pos chk",
"uniFeatures": "w wl pos chk shape shaped type p1 p2 p3 p4 s1 s2 s3 s4 2d 4d d&a d&- d&/ d&, d&. up iu au al ad ao cu cl ca cd cs",
"biFeatures": "w pos chk shaped type"
},
"WitAiEntityRecognizer": {
"url": "https://api.wit.ai",
"resource": "message",
"serverAccessToken": "SERVER_ACCESS_TOKEN",
"version": "20180811"
}
}
}

View file

@ -31,6 +31,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.NLP.UnitTest", "Bo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Core.UnitTest", "BotSharp.Core.UnitTest\BotSharp.Core.UnitTest.csproj", "{30F80E7D-951A-4E8F-9C3C-2C866528EABD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Platform.Abstraction", "BotSharp.Platform.Abstraction\BotSharp.Platform.Abstraction.csproj", "{62F08F9F-16C2-4754-90B0-B604DC18AE23}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Platform.Models", "BotSharp.Platform.Models\BotSharp.Platform.Models.csproj", "{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Articulate", "Platform.Articulate\Platform.Articulate.csproj", "{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.RasaTalk", "Platform.RasaTalk\Platform.RasaTalk.csproj", "{4D8203E8-0A68-42C9-AA21-9A0514E1008A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Dialogflow", "Platform.Dialogflow\Platform.Dialogflow.csproj", "{25503190-0B4B-4ECA-8C0C-D12A53A09583}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.RasaUI", "Platform.RasaUI\Platform.RasaUI.csproj", "{FD087443-4A45-4796-893C-6EEB2D5029D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.Botpress", "Platform.Botpress\Platform.Botpress.csproj", "{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
ARTICULATE|Any CPU = ARTICULATE|Any CPU
@ -265,6 +279,146 @@ Global
{30F80E7D-951A-4E8F-9C3C-2C866528EABD}.Release|Any CPU.Build.0 = Release|Any CPU
{30F80E7D-951A-4E8F-9C3C-2C866528EABD}.Release|x64.ActiveCfg = Release|x64
{30F80E7D-951A-4E8F-9C3C-2C866528EABD}.Release|x64.Build.0 = Release|x64
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Debug|x64.ActiveCfg = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Debug|x64.Build.0 = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.RASA|Any CPU.Build.0 = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.RASA|x64.ActiveCfg = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.RASA|x64.Build.0 = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Release|Any CPU.Build.0 = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Release|x64.ActiveCfg = Release|Any CPU
{62F08F9F-16C2-4754-90B0-B604DC18AE23}.Release|x64.Build.0 = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Debug|x64.ActiveCfg = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Debug|x64.Build.0 = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.RASA|Any CPU.Build.0 = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.RASA|x64.ActiveCfg = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.RASA|x64.Build.0 = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Release|Any CPU.Build.0 = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Release|x64.ActiveCfg = Release|Any CPU
{C4F2EAE5-F2C7-4F52-9DB2-7E76D7080C72}.Release|x64.Build.0 = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Debug|x64.ActiveCfg = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Debug|x64.Build.0 = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.RASA|Any CPU.Build.0 = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.RASA|x64.ActiveCfg = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.RASA|x64.Build.0 = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Release|Any CPU.Build.0 = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Release|x64.ActiveCfg = Release|Any CPU
{2B279A6C-C829-4D29-9C1C-809C8A8E36B2}.Release|x64.Build.0 = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Debug|x64.ActiveCfg = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Debug|x64.Build.0 = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.RASA|Any CPU.Build.0 = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.RASA|x64.ActiveCfg = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.RASA|x64.Build.0 = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Release|Any CPU.Build.0 = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Release|x64.ActiveCfg = Release|Any CPU
{4D8203E8-0A68-42C9-AA21-9A0514E1008A}.Release|x64.Build.0 = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Debug|x64.ActiveCfg = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Debug|x64.Build.0 = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.RASA|Any CPU.Build.0 = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.RASA|x64.ActiveCfg = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.RASA|x64.Build.0 = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Release|Any CPU.Build.0 = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Release|x64.ActiveCfg = Release|Any CPU
{25503190-0B4B-4ECA-8C0C-D12A53A09583}.Release|x64.Build.0 = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Debug|x64.Build.0 = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.RASA|Any CPU.Build.0 = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.RASA|x64.ActiveCfg = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.RASA|x64.Build.0 = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Release|Any CPU.Build.0 = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Release|x64.ActiveCfg = Release|Any CPU
{FD087443-4A45-4796-893C-6EEB2D5029D5}.Release|x64.Build.0 = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.ARTICULATE|Any CPU.ActiveCfg = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.ARTICULATE|Any CPU.Build.0 = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.ARTICULATE|x64.ActiveCfg = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.ARTICULATE|x64.Build.0 = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Debug|x64.ActiveCfg = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Debug|x64.Build.0 = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.DIALOGFLOW|Any CPU.ActiveCfg = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.DIALOGFLOW|Any CPU.Build.0 = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.DIALOGFLOW|x64.ActiveCfg = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.DIALOGFLOW|x64.Build.0 = Debug|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.RASA|Any CPU.ActiveCfg = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.RASA|Any CPU.Build.0 = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.RASA|x64.ActiveCfg = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.RASA|x64.Build.0 = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Release|Any CPU.Build.0 = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Release|x64.ActiveCfg = Release|Any CPU
{D796FD0C-D161-41D1-8D3C-5B9B39FB3C28}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -0,0 +1,52 @@
using BotSharp.Core;
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace Platform.Articulate
{
/// <summary>
/// A platform for building conversational interfaces with intelligent agents (chatbots)
/// http://spg.ai/projects/articulate
/// This implementation takes over APIs of Articulate's 7500 port.
/// </summary>
public class ArticulateAi<TStorage, TAgent, TExtraData, TEntity> :
PlatformBuilderBase<TStorage, TExtraData, TEntity>,
IPlatformBuilder<TStorage, TAgent, TExtraData, TEntity>
where TStorage : IAgentStorage<TExtraData, TEntity>, new()
{
public DialogRequestOptions RequestOptions { get; set; }
public TAgent RecoverAgent(StandardAgent<TExtraData, TEntity> agent)
{
if (agent == null) return default(TAgent);
var agent1 = new AgentModel
{
Id = agent.Id,
AgentName = agent.Name,
Description = agent.Description,
Language = agent.Language
};
return (TAgent)(agent1 as Object);
}
public StandardAgent<TExtraData, TEntity> StandardizeAgent(TAgent specificAgent)
{
var agent1 = specificAgent as AgentModel;
var standardAgent = new StandardAgent<TExtraData, TEntity>
{
Name = agent1.AgentName,
Language = agent1.Language,
Description = agent1.Description
};
return standardAgent;
}
}
}

View file

@ -0,0 +1,115 @@
using BotSharp.Core;
using BotSharp.Core.Agents;
using BotSharp.Core.Engines;
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Platform.Articulate;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Platform.Articulate.Controllers
{
#if ARTICULATE
[Route("[controller]")]
public class AgentController : ControllerBase
{
private readonly IBotPlatform _platform;
/// <summary>
/// Initialize agent controller and get a platform instance
/// </summary>
/// <param name="platform"></param>
public AgentController(IBotPlatform platform)
{
_platform = platform;
}
[HttpPost]
public AgentModel PostAgent()
{
AgentModel agent = null;
using (var reader = new StreamReader(Request.Body))
{
string body = reader.ReadToEnd();
agent = JsonConvert.DeserializeObject<AgentModel>(body);
}
// convert to standard Agent structure
var builder = new ArticulateAi<AgentStorageInMemory<DomainModel, EntityModel>, AgentModel, DomainModel, EntityModel>();
var standardAgent = builder.StandardizeAgent(agent);
builder.SaveAgent(standardAgent);
agent.Id = standardAgent.Id;
return agent;
}
[HttpGet]
public List<AgentModel> GetAgent()
{
/*var agents = new List<AgentModel>();
string dataDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate");
var agentPaths = Directory.GetFiles(dataDir).Where(x => Regex.IsMatch(x, @"agent-\d+.json")).ToList();
for (int i = 0; i< agentPaths.Count; i++)
{
string json = System.IO.File.ReadAllText(agentPaths[i]);
var agent = JsonConvert.DeserializeObject<AgentModel>(json);
agents.Add(agent);
}*/
var builder = new ArticulateAi<AgentStorageInMemory<DomainModel, EntityModel>, AgentModel, DomainModel, EntityModel>();
var results = builder.GetAllAgents();
var agents = results.Select(x => builder.RecoverAgent(x)).ToList();
return agents;
}
[HttpGet("{agentId}")]
public AgentModel GetAgentById([FromRoute] string agentId)
{
var builder = new ArticulateAi<AgentStorageInMemory<DomainModel, EntityModel>, AgentModel, DomainModel, EntityModel>();
var standardAgent = builder.GetAgentById(agentId);
var agent = builder.RecoverAgent(standardAgent);
return agent;
}
[HttpGet("name/{agentName}")]
public AgentModel GetAgentByName([FromRoute] string agentName)
{
AgentModel agent = null;
string dataDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate");
var agentPaths = Directory.GetFiles(dataDir).Where(x => Regex.IsMatch(x, @"agent-\d+\.json")).ToList();
for (int i = 0; i < agentPaths.Count; i++)
{
string json = System.IO.File.ReadAllText(agentPaths[i]);
var agentTmp = JsonConvert.DeserializeObject<AgentModel>(json);
if(agentTmp.AgentName == agentName)
{
agent = agentTmp;
}
}
return agent;
}
}
#endif
}

View file

@ -1,7 +1,9 @@
using BotSharp.Core.Engines.Articulate;
using BotSharp.Core;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Platform.Articulate.Models;
using Platform.Articulate.ViewModels;
using System;
using System.Collections.Generic;
using System.IO;
@ -9,7 +11,7 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace BotSharp.RestApi.Articulate
namespace Platform.Articulate.Controllers
{
#if ARTICULATE
[Route("[controller]")]
@ -29,8 +31,22 @@ namespace BotSharp.RestApi.Articulate
}
[HttpPost]
public void PostModel([FromBody] DomainModel domain)
public DomainModel PostDomain()
{
DomainModel domain = null;
using (var reader = new StreamReader(Request.Body))
{
string body = reader.ReadToEnd();
domain = JsonConvert.DeserializeObject<DomainModel>(body);
}
var builder = new ArticulateAi<AgentStorageInMemory<DomainModel, EntityModel>, AgentModel, DomainModel, EntityModel>();
var agent = builder.GetAgentByName(domain.Agent);
agent.ExtraData = domain;
builder.SaveAgent(agent);
return domain;
}
[HttpGet("/agent/{agentId}/domain")]

View file

@ -1,13 +1,15 @@
using BotSharp.Core.Engines.Articulate;
using BotSharp.Core;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using Platform.Articulate.ViewModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace BotSharp.RestApi.Articulate
namespace Platform.Articulate.Controllers
{
#if ARTICULATE
[Route("[controller]")]
@ -32,19 +34,28 @@ namespace BotSharp.RestApi.Articulate
{
var entities = new List<EntityModel>();
string dataDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate");
return new EntityPageViewModel { Entities = entities, Total = entities.Count };
}
var agentPaths = Directory.GetFiles(dataDir).Where(x => x.Contains($"agent-{agentId}-entity-")).ToList();
for (int i = 0; i < agentPaths.Count; i++)
[HttpPost]
public EntityModel PostEntity()
{
EntityModel entity = null;
using (var reader = new StreamReader(Request.Body))
{
string json = System.IO.File.ReadAllText(agentPaths[i]);
var entity = JsonConvert.DeserializeObject<EntityModel>(json);
entities.Add(entity);
string body = reader.ReadToEnd();
entity = JsonConvert.DeserializeObject<EntityModel>(body);
}
return new EntityPageViewModel { Entities = entities, Total = entities.Count };
var builder = new ArticulateAi<AgentStorageInMemory<DomainModel, EntityModel>, AgentModel, DomainModel, EntityModel>();
var agent = builder.GetAgentByName(entity.Agent);
agent.Entities.Add(entity);
builder.SaveAgent(agent);
return entity;
}
}
#endif

View file

@ -1,13 +1,14 @@
using BotSharp.Core.Engines.Articulate;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using Platform.Articulate.ViewModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace BotSharp.RestApi.Articulate
namespace Platform.Articulate.Controllers
{
#if ARTICULATE
[Route("[controller]")]

View file

@ -0,0 +1,52 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Platform.Articulate.Controllers
{
#if ARTICULATE
[Route("[controller]")]
public class SettingsController : ControllerBase
{
[HttpGet]
public SettingsModel GetSettings()
{
string dataPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate", "settings.json");
string json = System.IO.File.ReadAllText(dataPath);
var settings = JsonConvert.DeserializeObject<SettingsModel>(json);
return settings;
}
[HttpGet("/agent/{agentId}/settings")]
public SettingsModel GetSettingsByAgent([FromRoute] string agentId)
{
string dataPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate", "settings.json");
string json = System.IO.File.ReadAllText(dataPath);
var settings = JsonConvert.DeserializeObject<SettingsModel>(json);
return settings;
}
[HttpPut("/agent/{agentId}/settings")]
public SettingsModel PutSettingsByAgent([FromRoute] string agentId)
{
string dataPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate", "settings.json");
string json = System.IO.File.ReadAllText(dataPath);
var settings = JsonConvert.DeserializeObject<SettingsModel>(json);
return settings;
}
}
#endif
}

View file

@ -2,11 +2,11 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class AgentModel
{
public int Id { get; set; }
public string Id { get; set; }
public string Status { get; set; }

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class DomainModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class EntityModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class EntitySynonymModel
{

View file

@ -1,8 +1,9 @@
using System;
using BotSharp.Core.Engines;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class IntentExampleModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class IntentModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class IntentScenarioModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class LanguageModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class PipelineModel
{

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class SettingsModel
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines.Articulate
namespace Platform.Articulate.Models
{
public class SlotModel
{

View file

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG;ARTICULATE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
<ProjectReference Include="..\BotSharp.Platform.Abstraction\BotSharp.Platform.Abstraction.csproj" />
</ItemGroup>
</Project>

View file

@ -1,9 +1,9 @@
using BotSharp.Core.Engines.Articulate;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.RestApi.Articulate
namespace Platform.Articulate.ViewModels
{
public class DomainPageViewModel
{

View file

@ -1,9 +1,9 @@
using BotSharp.Core.Engines.Articulate;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.RestApi.Articulate
namespace Platform.Articulate.ViewModels
{
public class EntityPageViewModel
{

View file

@ -1,9 +1,9 @@
using BotSharp.Core.Engines.Articulate;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.RestApi.Articulate
namespace Platform.Articulate.ViewModels
{
public class IntentPageViewModel
{

View file

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>