2018-08-14 22:21:09 +00:00
using BotSharp.Core.Agents ;
using BotSharp.Core.Engines ;
using BotSharp.Core.Engines.Rasa ;
using Microsoft.AspNetCore.Mvc ;
using Newtonsoft.Json ;
2018-08-22 15:45:50 +00:00
using Newtonsoft.Json.Linq ;
2018-08-14 22:21:09 +00:00
using Newtonsoft.Json.Serialization ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Text ;
2018-08-31 02:59:36 +00:00
using System.Text.RegularExpressions ;
2018-08-14 22:21:09 +00:00
using System.Threading.Tasks ;
namespace BotSharp.RestApi.Rasa
{
2018-09-04 20:39:51 +00:00
#if RASA
2018-08-23 04:24:13 +00:00
/// <summary>
/// You can post your training data to this endpoint to train a new model for a project.
/// This request will wait for the server answer: either the model was trained successfully or the training exited with an error.
/// </summary>
2018-08-14 22:21:09 +00:00
[Route("[controller] ")]
public class TrainController : ControllerBase
{
private readonly IBotPlatform _platform ;
/// <summary>
/// Initialize dialog controller and get a platform instance
/// </summary>
/// <param name="platform"></param>
public TrainController ( IBotPlatform platform )
{
_platform = platform ;
}
2018-08-23 04:24:13 +00:00
/// <summary>
/// Using the HTTP server, you must specify the project you want to train a new model for to be able to use it during parse requests later on : /train?project=my_project.
/// </summary>
2018-08-24 01:05:20 +00:00
/// <param name="model">Model name</param>
2018-09-14 16:31:35 +00:00
/// <param name="project">Agent name or agent id</param>
2018-08-23 04:24:13 +00:00
/// <returns></returns>
2018-08-14 22:21:09 +00:00
[HttpPost]
2018-09-14 16:31:35 +00:00
public async Task < ActionResult < String > > Train ( [ FromQuery ] string project , [ FromQuery ] string model )
2018-08-22 15:45:50 +00:00
{
2018-08-23 04:24:13 +00:00
string body = "" ;
using ( var reader = new StreamReader ( Request . Body ) )
{
body = reader . ReadToEnd ( ) ;
}
2018-08-31 02:59:36 +00:00
string lang = Regex . Match ( body , @"language:.+" ) ? . Value ;
if ( ! String . IsNullOrEmpty ( lang ) )
{
lang = lang . Substring ( 11 , 2 ) ;
}
string data = Regex . Match ( body , @"data:([\s\S]*)" ) ? . Value ;
if ( String . IsNullOrEmpty ( data ) )
{
data = body ;
}
else
{
data = data . Substring ( 6 ) ;
}
var rasa_nlu_data = JsonConvert . DeserializeObject < RasaTrainRequestModel > ( data ) ;
2018-08-24 01:05:20 +00:00
rasa_nlu_data . Model = model ;
2018-08-31 02:59:36 +00:00
rasa_nlu_data . Project = project ;
2018-08-23 04:24:13 +00:00
var trainResult = await Train ( rasa_nlu_data , project ) ;
return trainResult ;
2018-08-22 15:45:50 +00:00
}
2018-08-23 04:24:13 +00:00
private async Task < ActionResult < String > > Train ( [ FromBody ] RasaTrainRequestModel request , [ FromQuery ] string project )
2018-08-14 22:21:09 +00:00
{
var trainer = new BotTrainer ( ) ;
if ( String . IsNullOrEmpty ( request . Project ) )
{
request . Project = project ;
}
// save corpus to agent dir
2018-08-23 12:25:55 +00:00
var projectPath = Path . Combine ( AppDomain . CurrentDomain . GetData ( "DataPath" ) . ToString ( ) , "Projects" , project ) ;
var modelPath = Path . Combine ( projectPath , request . Model ) ;
2018-08-14 22:21:09 +00:00
2018-08-23 12:25:55 +00:00
if ( ! Directory . Exists ( modelPath ) )
2018-08-14 22:21:09 +00:00
{
2018-08-23 12:25:55 +00:00
Directory . CreateDirectory ( modelPath ) ;
2018-08-14 22:21:09 +00:00
}
2018-08-23 04:24:13 +00:00
// Save raw data to file, then parse it to Agent instance.
2018-08-31 02:59:36 +00:00
var metaFileName = Path . Combine ( modelPath , "meta.json" ) ;
System . IO . File . WriteAllText ( metaFileName , JsonConvert . SerializeObject ( new AgentImportHeader
{
Name = project ,
2018-09-04 20:39:51 +00:00
Platform = PlatformType . Rasa
2018-08-31 02:59:36 +00:00
} ) ) ;
2018-08-23 04:24:13 +00:00
// in order to unify the process.
2018-08-23 12:25:55 +00:00
var fileName = Path . Combine ( modelPath , "corpus.json" ) ;
2018-08-14 22:21:09 +00:00
System . IO . File . WriteAllText ( fileName , JsonConvert . SerializeObject ( request . Corpus , new JsonSerializerSettings
{
Formatting = Formatting . Indented ,
NullValueHandling = NullValueHandling . Ignore ,
ContractResolver = new CamelCasePropertyNamesContractResolver ( )
} ) ) ;
2018-08-28 14:58:35 +00:00
var agent = _platform . LoadAgentFromFile ( modelPath ) ;
2018-08-14 22:21:09 +00:00
2018-08-31 02:59:36 +00:00
var info = await trainer . Train ( agent , new BotTrainOptions
{
AgentDir = projectPath ,
Model = request . Model
} ) ;
2018-08-14 22:21:09 +00:00
2018-08-15 10:46:53 +00:00
return Ok ( new { info = info . Model } ) ;
2018-08-23 04:24:13 +00:00
}
2018-08-14 22:21:09 +00:00
}
#endif
}