Rename project

This commit is contained in:
haiping008@gmail.com 2018-03-28 17:08:49 -05:00
parent 33d42ae035
commit 6c472545c0
77 changed files with 595 additions and 290 deletions

View file

@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>bin\Debug\netcoreapp2.0\Bot.Rasa.RestApi.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetToolkit" Version="1.4.0" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bot.Rasa\Bot.Rasa.csproj" />
</ItemGroup>
</Project>

View file

@ -1,19 +0,0 @@
using Bot.Rasa.Expressions;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
{
public class UserSay
{
public UserSay()
{
Entities = new List<IntentExpressionPart>();
}
public String Text { get; set; }
public String Intent { get; set; }
public List<IntentExpressionPart> Entities { get; set; }
}
}

View file

@ -1,53 +0,0 @@
using Bot.Rasa;
using Bot.Rasa.Agents;
using Bot.Rasa.Consoles;
using Bot.Rasa.Models;
using EntityFrameworkCore.BootKit;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Bot.UnitTest
{
[TestClass]
public class AgentTest : TestEssential
{
public static String BOT_ID = "2b6a288e-d891-40c6-96ce-6a0cf324545c";
public static String BOT_NAME = "VirtualAssistant";
[TestMethod]
public void CreateAgent()
{
var rasa = new RasaAi(dc);
var importer = new AgentImporterInDialogflow();
var agent = rasa.RestoreAgent(importer, BOT_NAME);
agent.Id = BOT_ID;
int row = dc.DbTran(() => rasa.SaveAgent(agent));
var loadedAgent = rasa.LoadAgent(agent.Id);
Assert.IsTrue(loadedAgent.Intents.Count == agent.Intents.Count);
}
[TestMethod]
public void TextRequest()
{
var rasa = new RasaAi(dc);
rasa.agent = rasa.LoadAgent(BOT_ID);
var response = rasa.TextRequest(dc, new AIRequest { Query = new String[] { "Create a work order for PetSmart" } });
Assert.IsTrue(response.Result.Metadata.IntentName == "Create Work Order");
response = rasa.TextRequest(dc, new AIRequest { Query = new String[] { "1010" } });
Assert.IsTrue(response.Result.Metadata.IntentName == "Telling Store Number");
}
[TestMethod]
public void Train()
{
var rasa = new RasaAi(dc);
}
}
}

View file

@ -24,7 +24,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bot.Rasa.RestApi\Bot.Rasa.RestApi.csproj" />
<ProjectReference Include="..\BotSharp.RestApi\BotSharp.RestApi.csproj" />
</ItemGroup>
</Project>

View file

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Bot.Rasa.Consoles;
using BotSharp.Core.Engines;
using DotNetToolkit.JwtHelper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@ -52,7 +52,7 @@ namespace Bot.WebStarter
var info = Configuration.GetSection("Swagger").Get<Swashbuckle.AspNetCore.Swagger.Info>();
c.SwaggerDoc(info.Version, info);
var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "Bot.Rasa.RestApi.xml");
var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "BotSharp.RestApi.xml");
c.IncludeXmlComments(filePath);
});
}
@ -81,7 +81,7 @@ namespace Bot.WebStarter
app.UseAuthentication();
app.UseMvc();
app.UseEntityDbContext(Configuration, env.ContentRootPath, new String[] { "Bot.Rasa" });
app.UseEntityDbContext(Configuration, env.ContentRootPath, new String[] { "BotSharp.Core." });
app.UseInitLoader();
}
}

View file

@ -3,7 +3,7 @@
"Default": "SqlServer",
"ConnectionStrings": {
"InMemory": "DataSource=:memory:",
"Sqlite": "Data Source=|DataDirectory|\\RasaBot.db;",
"Sqlite": "Data Source=|DataDirectory|RasaBot.db;",
"SqlServer": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=RasaBot;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
}
}

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowAgent
{

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
[JsonObject]
public class DialogflowEntity

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
[JsonObject]
public class DialogflowEntityEntry

View file

@ -1,9 +1,9 @@
using Bot.Rasa.Intents;
using BotSharp.Core.Intents;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntent
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntentEvent
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntentExpression
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntentExpressionPart
{

View file

@ -1,10 +1,10 @@
using Bot.Rasa.Intents;
using Bot.Rasa.Models;
using BotSharp.Core.Intents;
using BotSharp.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntentResponse
{

View file

@ -1,9 +1,9 @@
using Bot.Rasa.Models;
using BotSharp.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntentResponseMessage : AIResponseMessageBase
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Adapters.Dialogflow
namespace BotSharp.Core.Adapters.Dialogflow
{
public class DialogflowIntentResponseParameter
{

View file

@ -1,5 +1,5 @@
using Bot.Rasa.Entities;
using Bot.Rasa.Intents;
using BotSharp.Core.Entities;
using BotSharp.Core.Intents;
using EntityFrameworkCore.BootKit;
using Newtonsoft.Json;
using System;
@ -8,7 +8,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Agents
namespace BotSharp.Core.Agents
{
[Table("Bot_Agent")]
public class Agent : DbRecord, IDbRecord
@ -22,6 +22,16 @@ namespace Bot.Rasa.Agents
public String Language { get; set; }
/// <summary>
/// Only access text/ audio rquest
/// </summary>
public String ClientAccessToken { get; set; }
/// <summary>
/// Developer can access more APIs
/// </summary>
public String DeveloperAccessToken { get; set; }
[ForeignKey("AgentId")]
public List<Intent> Intents { get; set; }

View file

@ -1,6 +1,6 @@
using Bot.Rasa.Entities;
using Bot.Rasa.Intents;
using Bot.Rasa.Models;
using BotSharp.Core.Entities;
using BotSharp.Core.Intents;
using BotSharp.Core.Models;
using EntityFrameworkCore.BootKit;
using Microsoft.EntityFrameworkCore;
using System;
@ -8,7 +8,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Agents
namespace BotSharp.Core.Agents
{
public static class AgentExtension
{
@ -32,12 +32,14 @@ namespace Bot.Rasa.Agents
{
var trainingData = new RasaTrainingData
{
UserSays = new List<UserSay>()
UserSays = new List<RasaIntentExpression>()
};
var intents = dc.Table<Intent>()
.Include(x => x.Contexts)
.Include(x => x.UserSays).ThenInclude(say => say.Data).ToList();
.Include(x => x.UserSays).ThenInclude(say => say.Data)
.Where(x => x.UserSays.Count > 0)
.ToList();
var contexts = ctx.OrderBy(x => x.Name).Select(x => x.Name.ToLower()).ToList();
@ -56,12 +58,34 @@ namespace Bot.Rasa.Agents
intents.ForEach(intent =>
{
trainingData.UserSays.AddRange(intent.UserSays
.Select(exp => new UserSay
intent.UserSays.ForEach(exp =>
{
var say = new RasaIntentExpression
{
Intent = intent.Name,
Text = String.Join("", exp.Data.OrderBy(x => x.UpdatedTime).Select(x => x.Text))
}));
Text = String.Join("", exp.Data.OrderBy(x => x.UpdatedTime).Select(x => x.Text)),
};
// convert entity format
exp.Data.Where(x => !String.IsNullOrEmpty(x.Meta))
.ToList()
.ForEach(x =>
{
int start = say.Text.IndexOf(x.Text);
var part = new RasaIntentExpressionPart
{
Value = x.Text,
Entity = x.Alias,
Start = start,
End = start + x.Text.Length
};
say.Entities.Add(part);
});
trainingData.UserSays.Add(say);
});
});
return trainingData;

View file

@ -2,19 +2,18 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetToolkit" Version="1.4.0" />
<PackageReference Include="EntityFrameworkCore.BootKit" Version="1.5.1" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
<PackageReference Include="RestSharp" Version="106.2.1" />
<Folder Include="Adapters\Lex\" />
<Folder Include="Adapters\Luis\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Adapters\Luis\" />
<Folder Include="Adapters\Lex\" />
<PackageReference Include="DotNetToolkit" Version="1.4.0" />
<PackageReference Include="EntityFrameworkCore.BootKit" Version="1.5.4" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="RestSharp" Version="106.2.1" />
</ItemGroup>
</Project>

View file

@ -3,16 +3,16 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Bot.Rasa.Adapters.Dialogflow;
using Bot.Rasa.Agents;
using Bot.Rasa.Entities;
using Bot.Rasa.Intents;
using Bot.Rasa.Models;
using BotSharp.Core.Adapters.Dialogflow;
using BotSharp.Core.Agents;
using BotSharp.Core.Entities;
using BotSharp.Core.Intents;
using BotSharp.Core.Models;
using DotNetToolkit;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Bot.Rasa.Consoles
namespace BotSharp.Core.Engines
{
public class AgentImporterInDialogflow : IAgentImporter
{

View file

@ -1,9 +1,9 @@
using Bot.Rasa.Agents;
using BotSharp.Core.Agents;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Consoles
namespace BotSharp.Core.Engines
{
public interface IAgentImporter
{

View file

@ -1,5 +1,6 @@
using Bot.Rasa.Agents;
using Bot.Rasa.Entities;
using BotSharp.Core.Agents;
using BotSharp.Core.Entities;
using BotSharp.Core.Models;
using EntityFrameworkCore.BootKit;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
@ -11,22 +12,28 @@ using System.IO;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Consoles
namespace BotSharp.Core.Engines
{
public class RasaAi
{
private Database dc { get; set; }
public static RasaOptions Options { get; set; }
public Database dc { get; set; }
public AIConfiguration AiConfig { get; set; }
public static IConfiguration Configuration { get; set; }
public Agent agent { get; set; }
public String SessionId { get; set; }
public RasaAi(Database dc)
{
this.dc = dc;
SessionId = Guid.NewGuid().ToString();
}
public RasaAi(Database dc, AIConfiguration aiConfig)
{
this.dc = dc;
AiConfig = aiConfig;
agent = LoadAgent();
aiConfig.DevMode = agent.DeveloperAccessToken == aiConfig.ClientAccessToken;
}
/// <summary>
@ -37,7 +44,7 @@ namespace Bot.Rasa.Consoles
/// <returns></returns>
public Agent RestoreAgent(IAgentImporter importer, String agentId)
{
string dataDir = $"{Options.ContentRootPath}\\App_Data\\DbInitializer\\Agents\\";
string dataDir = $"{Database.ContentRootPath}\\App_Data\\DbInitializer\\Agents\\";
// Load agent summary
agent = importer.LoadAgent(agentId, dataDir);
@ -61,11 +68,11 @@ namespace Bot.Rasa.Consoles
return true;
}
public Agent LoadAgent(String agentId)
public Agent LoadAgent()
{
return dc.Table<Agent>()
.Include(x => x.Intents).ThenInclude(x => x.Contexts)
.FirstOrDefault(x => x.Id == agentId);
.FirstOrDefault(x => x.ClientAccessToken == AiConfig.ClientAccessToken || x.DeveloperAccessToken == AiConfig.ClientAccessToken);
}
public String SaveAgent(Agent agent)

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Consoles
namespace BotSharp.Core.Engines
{
public class RasaOptions
{

View file

@ -1,7 +1,7 @@
using Bot.Rasa.Agents;
using Bot.Rasa.Intents;
using Bot.Rasa.Models;
using Bot.Rasa.Sessions;
using BotSharp.Core.Agents;
using BotSharp.Core.Intents;
using BotSharp.Core.Models;
using BotSharp.Core.Sessions;
using DotNetToolkit;
using EntityFrameworkCore.BootKit;
using Microsoft.EntityFrameworkCore;
@ -15,18 +15,24 @@ using System.IO;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Consoles
namespace BotSharp.Core.Engines
{
public static class RequestExtension
{
public static AIResponse TextRequest(this RasaAi rasa, Database dc, AIRequest request)
public static AIResponse TextRequest(this RasaAi rasa, string text, RequestExtras requestExtras)
{
return rasa.TextRequest(new AIRequest(text, requestExtras));
}
public static AIResponse TextRequest(this RasaAi rasa, AIRequest request)
{
AIResponse aiResponse = new AIResponse();
RasaResponse response = null;
Database dc = rasa.dc;
// Merge input contexts
var contexts = dc.Table<SessionContext>()
.Where(x => x.SessionId == rasa.SessionId && x.Lifespan > 0)
.Where(x => x.SessionId == rasa.AiConfig.SessionId && x.Lifespan > 0)
.ToList()
.Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan })
.ToList();
@ -48,7 +54,34 @@ namespace Bot.Rasa.Consoles
}
}).OrderByDescending(x => x.Contexts.Count).ToList();
// training per request contexts
{
string contextId = $"{String.Join(',', contexts.Select(x => x.Name))}".GetMd5Hash();
string modelName = dc.Table<ContextModelMapping>().FirstOrDefault(x => x.ContextId == contextId)?.ModelName;
// need training
if (String.IsNullOrEmpty(modelName))
{
request.Contexts = contexts.Select(x => new AIContext { Name = x.Name.ToLower() })
.OrderBy(x => x.Name)
.ToList();
dc.DbTran(() =>
{
modelName = TrainWithContexts(rasa, dc, request, contextId);
});
}
var result = CallRasa(rasa.agent.Id, request.Query.First(), modelName);
if (result.Data.Intent != null)
{
response = result.Data;
}
}
// Max contexts match
if (response == null)
{
foreach (var it in intents)
{
request.Contexts = it.Contexts.Select(x => new AIContext { Name = x.Name.ToLower() })
@ -67,17 +100,7 @@ namespace Bot.Rasa.Consoles
});
}
var client = new RestClient($"{RasaAi.Options.HostUrl}");
var rest = new RestRequest("parse", Method.POST);
string json = JsonConvert.SerializeObject(new { Project = rasa.agent.Id, Q = request.Query.First(), Model = modelName },
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
rest.AddParameter("application/json", json, ParameterType.RequestBody);
var result = client.Execute<RasaResponse>(rest);
var result = CallRasa(rasa.agent.Id, request.Query.First(), modelName);
if (result.Data.Intent != null)
{
@ -85,6 +108,7 @@ namespace Bot.Rasa.Consoles
break;
}
};
}
var intent = (dc.Table<Intent>().Where(x => x.Name == response.Intent.Name)
.Include(x => x.Responses).ThenInclude(x => x.Contexts)
@ -95,13 +119,22 @@ namespace Bot.Rasa.Consoles
aiResponse.Id = Guid.NewGuid().ToString();
aiResponse.Lang = rasa.agent.Language;
aiResponse.Status = new AIResponseStatus { };
aiResponse.SessionId = rasa.SessionId;
aiResponse.SessionId = rasa.AiConfig.SessionId;
aiResponse.Timestamp = DateTime.UtcNow;
intentResponse.Messages.Where(x => x.Type == AIResponseMessageType.Text)
.ToList()
intentResponse.Messages = intentResponse.Messages.OrderBy(x => x.UpdatedTime).ToList();
intentResponse.Messages.ToList()
.ForEach(msg =>
{
msg.Speech = ArrayHelper.GetRandom(msg.Speech.Substring(2, msg.Speech.Length - 4).Split("\",\"").ToList());
if (msg.Type == AIResponseMessageType.Custom)
{
}
else
{
msg.Speech = msg.Speech.StartsWith("[") ?
ArrayHelper.GetRandom(msg.Speech.Substring(2, msg.Speech.Length - 4).Split("\",\"").ToList()) :
msg.Speech;
}
});
aiResponse.Result = new AIResponseResult
@ -114,7 +147,21 @@ namespace Bot.Rasa.Consoles
Metadata = new AIResponseMetadata { IntentId = intent.Id, IntentName = intent.Name },
Fulfillment = new AIResponseFulfillment
{
Messages = intentResponse.Messages.Select(x => (object)x).ToList()
Messages = intentResponse.Messages.Select(x => {
if (x.Type == AIResponseMessageType.Custom)
{
return (new
{
x.Type,
Payload = JObject.Parse(x.Payload)
}) as Object;
}
else
{
return (new { x.Type, x.Speech }) as Object;
}
}).ToList()
}
};
@ -122,7 +169,7 @@ namespace Bot.Rasa.Consoles
// override if exists, otherwise add, delete if lifespan is zero
dc.DbTran(() =>
{
var sessionContexts = dc.Table<SessionContext>().Where(x => x.SessionId == rasa.SessionId).ToList();
var sessionContexts = dc.Table<SessionContext>().Where(x => x.SessionId == rasa.AiConfig.SessionId).ToList();
// minus 1 round
sessionContexts.Where(x => !intentResponse.Contexts.Select(ctx => ctx.Name).Contains(x.Context))
@ -148,7 +195,7 @@ namespace Bot.Rasa.Consoles
{
dc.Table<SessionContext>().Add(new SessionContext
{
SessionId = rasa.SessionId,
SessionId = rasa.AiConfig.SessionId,
Context = ctx.Name,
Lifespan = ctx.Lifespan
});
@ -157,13 +204,27 @@ namespace Bot.Rasa.Consoles
});
aiResponse.Result.Contexts = dc.Table<SessionContext>()
.Where(x => x.SessionId == rasa.SessionId)
.Select(x => new AIContext { Name = x.Context, Lifespan = x.Lifespan })
.Where(x => x.SessionId == rasa.AiConfig.SessionId)
.Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan })
.ToArray();
return aiResponse;
}
private static IRestResponse<RasaResponse> CallRasa(string projectId, string text, string model)
{
var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Host").Value}");
var rest = new RestRequest("parse", Method.POST);
string json = JsonConvert.SerializeObject(new { Project = projectId, Q = text, Model = model },
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
rest.AddParameter("application/json", json, ParameterType.RequestBody);
return client.Execute<RasaResponse>(rest);
}
/// <summary>
/// Need two categories at least
/// </summary>
@ -176,19 +237,19 @@ namespace Bot.Rasa.Consoles
{
var corpus = console.agent.GrabCorpus(dc, request.Contexts);
corpus.UserSays.Add(new UserSay
corpus.UserSays.Add(new RasaIntentExpression
{
Intent = "Welcome",
Text = "Hi"
});
corpus.UserSays.Add(new UserSay
corpus.UserSays.Add(new RasaIntentExpression
{
Intent = "Welcome",
Text = "Hey"
});
corpus.UserSays.Add(new UserSay
corpus.UserSays.Add(new RasaIntentExpression
{
Intent = "Welcome",
Text = "Hello"
@ -200,7 +261,7 @@ namespace Bot.Rasa.Consoles
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
var client = new RestClient($"{RasaAi.Options.HostUrl}");
var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Host").Value}");
var rest = new RestRequest("train", Method.POST);
rest.AddQueryParameter("project", console.agent.Id);
rest.AddParameter("application/json", json, ParameterType.RequestBody);

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Entities
namespace BotSharp.Core.Entities
{
[Table("Bot_Entity")]
public class Entity : DbRecord, IDbRecord

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Entities
namespace BotSharp.Core.Entities
{
[Table("Bot_EntityEntry")]
public class EntityEntry : DbRecord, IDbRecord

View file

@ -1,11 +1,11 @@
using Bot.Rasa.Agents;
using BotSharp.Core.Agents;
using EntityFrameworkCore.BootKit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Entities
namespace BotSharp.Core.Entities
{
public static class EntityTypeExtension
{

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Expressions
namespace BotSharp.Core.Expressions
{
[Table("Bot_IntentExpressionPart")]
public class IntentExpressionPart : DbRecord, IDbRecord

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_ContextModelMapping")]
public class ContextModelMapping : DbRecord, IDbRecord

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
/// <summary>
/// Intent Table

View file

@ -1,4 +1,4 @@
using Bot.Rasa.Expressions;
using BotSharp.Core.Expressions;
using EntityFrameworkCore.BootKit;
using Newtonsoft.Json;
using System;
@ -8,7 +8,7 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_IntentExpression")]
public class IntentExpression : DbRecord, IDbRecord

View file

@ -1,11 +1,11 @@
using Bot.Rasa.Agents;
using BotSharp.Core.Agents;
using EntityFrameworkCore.BootKit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
public static class IntentExtension
{

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_IntentInputContext")]
public class IntentInputContext : DbRecord, IDbRecord

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_IntentResponse")]
public class IntentResponse : DbRecord, IDbRecord

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_IntentResponseContext")]
public class IntentResponseContext : DbRecord, IDbRecord

View file

@ -1,4 +1,4 @@
using Bot.Rasa.Models;
using BotSharp.Core.Models;
using EntityFrameworkCore.BootKit;
using System;
using System.Collections.Generic;
@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_IntentResponseMessage")]
public class IntentResponseMessage : DbRecord, IDbRecord

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Intents
namespace BotSharp.Core.Intents
{
[Table("Bot_IntentResponseParameter")]
public class IntentResponseParameter : DbRecord, IDbRecord

View file

@ -4,7 +4,7 @@ using System.Linq;
using EntityFrameworkCore.BootKit;
using DotNetToolkit;
namespace Bot.Rasa.Loader
namespace BotSharp.Core.Loader
{
public class DbInitializer : IInitializationLoader
{

View file

@ -4,7 +4,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Loader
namespace BotSharp.Core.Loader
{
/// <summary>
/// Initialize data for modules

View file

@ -1,6 +1,6 @@
using System.Text;
namespace Bot.Rasa.Loader
namespace BotSharp.Core.Loader
{
/// <summary>
/// Implement a customzied loader

View file

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Loader
namespace BotSharp.Core.Loader
{
public class InitializationLoader
{

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Models
{
public class AIConfiguration
{
private const string SERVICE_PROD_URL = "";
private const string SERVICE_DEV_URL = "";
private const string CURRENT_PROTOCOL_VERSION = "20190322";
public string ClientAccessToken { get; private set; }
public SupportedLanguage Language { get; set; }
public bool VoiceActivityDetectionEnabled { get; set; }
public string SessionId { get; set; }
/// <summary>
/// If true, will be used Testing API.AI server instead of Production server. This option for TESTING PURPOSES ONLY.
/// </summary>
public bool DevMode { get; set; }
/// <summary>
/// If true, all request and response content will be printed to the console. Use this option only FOR DEVELOPMENT.
/// </summary>
public bool DebugLog { get; set; }
string protocolVersion;
public string ProtocolVersion
{
get
{
return protocolVersion;
}
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("value");
}
protocolVersion = value;
}
}
public AIConfiguration(string clientAccessToken, SupportedLanguage language)
{
this.ClientAccessToken = clientAccessToken;
this.Language = language;
DevMode = false;
DebugLog = false;
VoiceActivityDetectionEnabled = true;
ProtocolVersion = CURRENT_PROTOCOL_VERSION;
}
public string RequestUrl
{
get
{
var baseUrl = DevMode ? SERVICE_DEV_URL : SERVICE_PROD_URL;
return string.Format("{0}{1}?v={2}", baseUrl, "query", ProtocolVersion);
}
}
}
}

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
[JsonObject]
public class AIContext

View file

@ -3,24 +3,18 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
[JsonObject]
public class AIRequest : QuestionMetadata
{
[JsonProperty("query")]
public string[] Query { get; set; }
[JsonProperty("confidence")]
public float[] Confidence { get; set; }
[JsonProperty("contexts")]
public List<AIContext> Contexts { get; set; }
[JsonProperty("resetContexts")]
public bool? ResetContexts { get; set; }
[JsonProperty("originalRequest")]
public OriginalRequest OriginalRequest { get; set; }
public AIRequest()
@ -32,6 +26,7 @@ namespace Bot.Rasa.Models
{
Query = new string[] { text };
Confidence = new float[] { 1.0f };
Contexts = new List<AIContext>();
}
public AIRequest(string text, RequestExtras requestExtras) : this(text)

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponse
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponseCustomPayload : AIResponseMessageBase
{

View file

@ -2,12 +2,12 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponseFulfillment
{
public string Speech { get; set; }
public List<object> Messages { get; set; }
public List<Object> Messages { get; set; }
}
}

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponseMessageBase
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public enum AIResponseMessageType
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponseMetadata
{

View file

@ -1,4 +1,4 @@
using Bot.Rasa.Intents;
using BotSharp.Core.Intents;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@ -7,7 +7,7 @@ using System.Globalization;
using System.Linq;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponseResult
{

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class AIResponseStatus
{

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
[JsonObject]
public class OriginalRequest

View file

@ -1,10 +1,10 @@
using Bot.Rasa.Entities;
using BotSharp.Core.Entities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
[JsonObject]
public class QuestionMetadata

View file

@ -0,0 +1,19 @@
using BotSharp.Core.Expressions;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Models
{
public class RasaIntentExpression
{
public RasaIntentExpression()
{
Entities = new List<RasaIntentExpressionPart>();
}
public String Text { get; set; }
public String Intent { get; set; }
public List<RasaIntentExpressionPart> Entities { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Models
{
public class RasaIntentExpressionPart
{
public int Start { get; set; }
public int End { get; set; }
public String Value { get; set; }
public String Entity { get; set; }
}
}

View file

@ -1,13 +1,19 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class RasaResponse
{
public RasaResponseIntent Intent { get; set; }
[JsonProperty("intent_ranking")]
public List<RasaResponseIntent> IntentRanking { get; set; }
public List<RasaResponseEntity> Entities { get; set; }
public String Text { get; set; }
}

View file

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Models
{
public class RasaResponseEntity : RasaIntentExpressionPart
{
public string Extractor { get; set; }
}
}

View file

@ -3,11 +3,11 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class RasaTrainingData
{
[JsonProperty("common_examples")]
public List<UserSay> UserSays { get; set; }
public List<RasaIntentExpression> UserSays { get; set; }
}
}

View file

@ -1,9 +1,9 @@
using Bot.Rasa.Entities;
using BotSharp.Core.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.Models
namespace BotSharp.Core.Models
{
public class RequestExtras
{

View file

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Models
{
public class SupportedLanguage
{
public static readonly SupportedLanguage English = new SupportedLanguage("en");
public static readonly SupportedLanguage Russian = new SupportedLanguage("ru");
public static readonly SupportedLanguage German = new SupportedLanguage("de");
public static readonly SupportedLanguage Portuguese = new SupportedLanguage("pt");
public static readonly SupportedLanguage PortugueseBrazil = new SupportedLanguage("pt-BR");
public static readonly SupportedLanguage Spanish = new SupportedLanguage("es");
public static readonly SupportedLanguage French = new SupportedLanguage("fr");
public static readonly SupportedLanguage Italian = new SupportedLanguage("it");
public static readonly SupportedLanguage Dutch = new SupportedLanguage("nl");
public static readonly SupportedLanguage Japanese = new SupportedLanguage("ja");
public static readonly SupportedLanguage ChineseChina = new SupportedLanguage("zh-CN");
public static readonly SupportedLanguage ChineseHongKong = new SupportedLanguage("zh-HK");
public static readonly SupportedLanguage ChineseTaiwan = new SupportedLanguage("zh-TW");
private static readonly SupportedLanguage[] AllLangs =
{
English,
Russian,
German,
Portuguese,
PortugueseBrazil,
Spanish,
French,
Italian,
Dutch,
Japanese,
ChineseChina,
ChineseHongKong,
ChineseTaiwan
};
public readonly string code;
private SupportedLanguage(string code)
{
this.code = code;
}
public static SupportedLanguage FromLanguageTag(string languageTag)
{
foreach (var item in AllLangs)
{
if (string.Equals(item.code, languageTag, StringComparison.OrdinalIgnoreCase))
{
return item;
}
}
return English;
}
}
}

View file

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Bot.Rasa.Sessions
namespace BotSharp.Core.Sessions
{
[Table("Bot_SessionContext")]
public class SessionContext : DbRecord, IDbRecord

View file

@ -1,5 +1,5 @@
using Bot.Rasa.Agents;
using Bot.Rasa.Consoles;
using BotSharp.Core.Agents;
using BotSharp.Core.Engines;
using EntityFrameworkCore.BootKit;
using Microsoft.AspNetCore.Mvc;
using System;
@ -7,24 +7,29 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Bot.Rasa.RestApi
namespace BotSharp.Core.RestApi
{
public class AgentController : EssentialController
{
[HttpGet("id")]
public Agent Get([FromRoute] String id)
{
var console = new RasaAi(dc);
return console.LoadAgent(id);
var console = new RasaAi(dc, null);
return console.LoadAgent();
}
/// <summary>
/// New agent with basic configuration
/// </summary>
/// <param name="agent"></param>
/// <returns></returns>
[HttpPost]
public String Create([FromBody] Agent agent)
{
var console = new RasaAi(dc);
var rasa = new RasaAi(dc, null);
dc.DbTran(() => {
console.SaveAgent(agent);
rasa.SaveAgent(agent);
});
return agent.Id;

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
</ItemGroup>
</Project>

View file

@ -1,10 +1,10 @@
using Bot.Rasa.Entities;
using BotSharp.Core.Entities;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.RestApi
namespace BotSharp.Core.RestApi
{
public class EntityController : EssentialController
{

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.RestApi
namespace BotSharp.Core.RestApi
{
public class EntityItemController : EssentialController
{

View file

@ -1,12 +1,12 @@
using Bot.Rasa.Agents;
using Bot.Rasa.Entities;
using BotSharp.Core.Agents;
using BotSharp.Core.Entities;
using EntityFrameworkCore.BootKit;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.RestApi
namespace BotSharp.Core.RestApi
{
public class EntityTypeController : EssentialController
{

View file

@ -1,4 +1,4 @@
using Bot.Rasa.Consoles;
using BotSharp.Core.Engines;
using DotNetToolkit;
using EntityFrameworkCore.BootKit;
using Microsoft.AspNetCore.Authorization;
@ -11,7 +11,7 @@ using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text;
namespace Bot.Rasa.RestApi
namespace BotSharp.Core.RestApi
{
//[Authorize]
[Produces("application/json")]

View file

@ -2,7 +2,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Bot.Rasa.Loader;
using BotSharp.Core.Loader;
namespace Microsoft.AspNetCore.Builder
{

View file

@ -1,11 +1,11 @@
using Bot.Rasa.Agents;
using Bot.Rasa.Intents;
using BotSharp.Core.Agents;
using BotSharp.Core.Intents;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Text;
namespace Bot.Rasa.RestApi
namespace BotSharp.Core.RestApi
{
public class IntentController : EssentialController
{

View file

@ -0,0 +1,64 @@
using BotSharp.Core.Agents;
using BotSharp.Core.Engines;
using BotSharp.Core.Models;
using EntityFrameworkCore.BootKit;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BotSharp.UnitTest
{
[TestClass]
public class AgentTest : TestEssential
{
[TestMethod]
public void CreateAgent()
{
var agent = new Agent
{
Id = BOT_ID,
Name = BOT_NAME,
Language = "en"
};
var rasa = new RasaAi(dc);
int row = dc.DbTran(() => rasa.SaveAgent(agent));
}
[TestMethod]
public void UpdateAgent()
{
var agent = new Agent
{
Id = BOT_ID,
Name = BOT_NAME,
Language = "en"
};
var rasa = new RasaAi(dc);
int row = dc.DbTran(() => rasa.SaveAgent(agent));
}
[TestMethod]
public void RestoreAgent()
{
var rasa = new RasaAi(dc);
var importer = new AgentImporterInDialogflow();
var agent = rasa.RestoreAgent(importer, BOT_NAME);
agent.Id = BOT_ID;
agent.ClientAccessToken = BOT_CLIENT_TOKEN;
agent.DeveloperAccessToken = BOT_DEVELOPER_TOKEN;
int row = dc.DbTran(() => rasa.SaveAgent(agent));
}
[TestMethod]
public void Train()
{
var rasa = new RasaAi(dc);
}
}
}

View file

@ -9,13 +9,13 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.2" />
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bot.Rasa\Bot.Rasa.csproj" />
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.UnitTest
{
[TestClass]
public class EntityTest : TestEssential
{
}
}

View file

@ -0,0 +1,28 @@
using BotSharp.Core.Engines;
using BotSharp.Core.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.UnitTest
{
[TestClass]
public class IntentTest : TestEssential
{
[TestMethod]
public void TextRequest()
{
var config = new AIConfiguration(BOT_CLIENT_TOKEN, SupportedLanguage.English);
config.SessionId = Guid.NewGuid().ToString();
var rasa = new RasaAi(dc, config);
var response = rasa.TextRequest(new AIRequest { Query = new String[] { "Create a work order for PetSmart" } });
Assert.IsTrue(response.Result.Metadata.IntentName == "Create Work Order");
response = rasa.TextRequest(new AIRequest { Query = new String[] { "1010" } });
Assert.IsTrue(response.Result.Metadata.IntentName == "Telling Store Number");
}
}
}

View file

@ -1,4 +1,4 @@
using Bot.Rasa.Consoles;
using BotSharp.Core.Engines;
using EntityFrameworkCore.BootKit;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
@ -6,10 +6,15 @@ using System;
using System.IO;
using System.Linq;
namespace Bot.UnitTest
namespace BotSharp.UnitTest
{
public abstract class TestEssential
{
public static String BOT_ID = "2b6a288e-d891-40c6-96ce-6a0cf324545c";
public static String BOT_CLIENT_TOKEN = "23a53c46d6244840bbb10c89c171d299";
public static String BOT_DEVELOPER_TOKEN = "d86103f446d049ff8d5f506e8dfe5f3f";
public static String BOT_NAME = "VirtualAssistant";
protected Database dc { get; set; }
protected string contentRoot;
@ -25,17 +30,10 @@ namespace Bot.UnitTest
});
Database.Configuration = configurationBuilder.Build();
Database.Assemblies = new String[] { "Bot.Rasa" };
Database.Assemblies = new String[] { "BotSharp.Core" };
Database.ContentRootPath = contentRoot;
dc = new DefaultDataContextLoader().GetDefaultDc();
RasaAi.Options = new RasaOptions
{
HostUrl = Database.Configuration.GetSection("Rasa:Host").Value,
ContentRootPath = contentRoot,
Assembles = new String[] { "Bot.Rasa" }
};
}
}

View file

@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot.Rasa", "Bot.Rasa\Bot.Rasa.csproj", "{8E57A9A5-EB37-4F83-93FE-3324A069B568}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot.WebStarter", "Bot.WebStarter\Bot.WebStarter.csproj", "{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot.UnitTest", "Bot.UnitTest\Bot.UnitTest.csproj", "{90705625-1342-4ED8-A05B-46C720D20EE4}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.UnitTest", "BotSharp.UnitTest\BotSharp.UnitTest.csproj", "{1C883AA3-9182-469A-A17E-697DCAAB0121}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot.Rasa.RestApi", "Bot.Rasa.RestApi\Bot.Rasa.RestApi.csproj", "{310EECBB-8B77-4F4A-A09C-6B5EED29155E}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core", "BotSharp.Core\BotSharp.Core.csproj", "{95780673-2A1A-4953-962F-C46CBFDD07FF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.WebStarter", "Bot.WebStarter\Bot.WebStarter.csproj", "{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.RestApi", "BotSharp.RestApi\BotSharp.RestApi.csproj", "{A1DDFCE9-10A1-45AF-8F1C-DE0A9145BA48}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -17,22 +17,22 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8E57A9A5-EB37-4F83-93FE-3324A069B568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E57A9A5-EB37-4F83-93FE-3324A069B568}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E57A9A5-EB37-4F83-93FE-3324A069B568}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E57A9A5-EB37-4F83-93FE-3324A069B568}.Release|Any CPU.Build.0 = Release|Any CPU
{90705625-1342-4ED8-A05B-46C720D20EE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90705625-1342-4ED8-A05B-46C720D20EE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90705625-1342-4ED8-A05B-46C720D20EE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90705625-1342-4ED8-A05B-46C720D20EE4}.Release|Any CPU.Build.0 = Release|Any CPU
{310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Release|Any CPU.Build.0 = Release|Any CPU
{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Release|Any CPU.Build.0 = Release|Any CPU
{1C883AA3-9182-469A-A17E-697DCAAB0121}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C883AA3-9182-469A-A17E-697DCAAB0121}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C883AA3-9182-469A-A17E-697DCAAB0121}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C883AA3-9182-469A-A17E-697DCAAB0121}.Release|Any CPU.Build.0 = Release|Any CPU
{95780673-2A1A-4953-962F-C46CBFDD07FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95780673-2A1A-4953-962F-C46CBFDD07FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95780673-2A1A-4953-962F-C46CBFDD07FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95780673-2A1A-4953-962F-C46CBFDD07FF}.Release|Any CPU.Build.0 = Release|Any CPU
{A1DDFCE9-10A1-45AF-8F1C-DE0A9145BA48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1DDFCE9-10A1-45AF-8F1C-DE0A9145BA48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1DDFCE9-10A1-45AF-8F1C-DE0A9145BA48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1DDFCE9-10A1-45AF-8F1C-DE0A9145BA48}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE