-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from ifreitas/process-message
Process Message
- Loading branch information
Showing
28 changed files
with
566 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,8 @@ target | |
/project/project/ | ||
/project/target/ | ||
/project/scaffold.sbt | ||
Pinky.eml | ||
Pinky.iml | ||
Pinky.ipr | ||
Pinky.iws | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,33 @@ | |
It is a simple asynchronous and non-blocking web interface for Program AB. Program AB is the reference implementation of the AIML 2.0 draft specification. | ||
AIML is a widely adopted standard for creating chat bots and mobile virtual assistants like ALICE, Mitsuku, English Tutor, The Professor, S.U.P.E.R. and many more. | ||
Program AB was developed by Richard Wallace (contact [email protected]) and first released in January, 2013. More info about Program AB: https://code.google.com/archive/p/program-ab/. | ||
That name comes from an american animated television series called Pinky and the Brain. | ||
That name comes from an american animated television series called [Pinky](https://github.com/ifreitas/Pinky) and the [Brain](https://github.com/ifreitas/brain). | ||
|
||
## Getting Started | ||
### 1. Install | ||
1.1. Download the pink-\<version\>.zip file from the latest Pinky release at [download page](https://github.com/ifreitas/Pinky/releases/latest). | ||
|
||
1.2. Unzip the file | ||
|
||
1.3. Edit the pink-\<version\>/conf/production.conf file (self explanatory) | ||
|
||
### 2. Running | ||
```shell | ||
$ cd pinky-<version>/bin/ | ||
$ ./pinky | ||
``` | ||
### 3. Testing | ||
If you have curl installed, just run: | ||
|
||
```shell | ||
$ curl -d "text=test" -X POST http://localhost:9000/chat/sample/some_session | ||
``` | ||
It should returns: | ||
```js | ||
{ "text" : "Congratulation. It works!"} | ||
``` | ||
|
||
### 4. Deploying New Bots | ||
Simply past your AIML 2.0 bot into pinky-\<version\>/bots dir. It does'nt require restart the server. | ||
|
||
**The bots must follows the AIML 2.0 structure dir**. More info at [Program-AB](https://code.google.com/archive/p/program-ab/) project page. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package controllers | ||
|
||
import javax.inject.{Inject, Singleton} | ||
|
||
import akka.actor.ActorSystem | ||
import models.ChatService | ||
import play.api.data.Form | ||
import play.api.data.Forms._ | ||
import play.api.libs.concurrent.CustomExecutionContext | ||
import play.api.libs.json.Json | ||
import play.api.mvc._ | ||
|
||
import scala.concurrent.{ExecutionContext, Future} | ||
|
||
trait MyExecutionContext extends ExecutionContext | ||
|
||
@Singleton | ||
class MyExecutionContextImpl @Inject()(system: ActorSystem) extends CustomExecutionContext(system, "my-context") with MyExecutionContext | ||
|
||
case class Message(text: String) | ||
|
||
@Singleton | ||
class ChatController @Inject()(chatService: ChatService, controllerComponents: ControllerComponents)(implicit myExecutionContext: MyExecutionContext) extends AbstractController(controllerComponents) { | ||
implicit val messageWrites = Json.writes[Message] | ||
val messageForm = Form( | ||
mapping( | ||
"text" -> nonEmptyText | ||
)(Message.apply)(Message.unapply) | ||
) | ||
|
||
def chat(botId: String, chatId: String) = Action.async { implicit request => | ||
handleMessage { | ||
chatService.process(botId, chatId, _) | ||
} | ||
} | ||
|
||
private[this] def handleMessage(block: String => Future[String])(implicit request: Request[AnyContent]): Future[Result] = { | ||
messageForm.bindFromRequest.fold( | ||
formWithErrors => { | ||
Future.successful(badRequest("The message's text is required.")) | ||
}, | ||
validMessage => { | ||
block(validMessage.text).map(ok).recover { case exception => badRequest(exception.getLocalizedMessage) } | ||
} | ||
) | ||
} | ||
|
||
private[this] def ok(msg: String) = Ok(Json.toJson(Message(msg))) | ||
|
||
private[this] def badRequest(exception: String) = BadRequest(Json.obj("error" -> exception)) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package models | ||
|
||
import javax.inject.Inject | ||
|
||
import org.alicebot.ab.Bot | ||
import play.api.Configuration | ||
|
||
import scala.concurrent.{ExecutionContext, Future} | ||
|
||
trait BotService extends { | ||
def newBot(botId: String)(implicit ec: ExecutionContext): Future[Bot] = Future { | ||
validate(botId) | ||
doNewBot(botId) | ||
} | ||
|
||
def validate(botId: String): Unit = if (!exists(botId)) throw new BotNotFoundException(botId) | ||
|
||
private[this] def exists(botId: String): Boolean = { | ||
val botDir = new java.io.File(pathTo(botId)) | ||
botDir.exists && botDir.isDirectory | ||
} | ||
|
||
private[this] def doNewBot(botId: String): Bot = new Bot(botId, bots_home) | ||
|
||
private[this] def pathTo(botId: String) = s"$bots_home/bots/$botId" | ||
|
||
protected def bots_home: String | ||
} | ||
|
||
class BotServiceImpl @Inject()(config: Configuration) extends BotService { | ||
override def bots_home: String = config.getOptional[String]("bots_home").getOrElse(System.getProperty("user.dir")) | ||
} | ||
|
||
class BotNotFoundException(botId: String) extends RuntimeException(s"Bot '$botId' does not exists") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package models | ||
|
||
import javax.inject.{Inject, Singleton} | ||
|
||
import org.alicebot.ab.Chat | ||
import play.api.cache.AsyncCacheApi | ||
import play.cache.NamedCache | ||
|
||
import scala.concurrent.duration.DurationInt | ||
import scala.concurrent.{ExecutionContext, Future} | ||
|
||
trait ChatService { | ||
def process(botId: String, conversationId: String, userMessage: String)(implicit ec: ExecutionContext): Future[String] | ||
|
||
def set(key: String, chat: Future[Chat])(implicit ec: ExecutionContext): Future[Chat] | ||
|
||
def newChat(botId: String)(implicit ec: ExecutionContext): Future[Chat] | ||
} | ||
|
||
@Singleton | ||
class ChatServiceImpl @Inject()(@NamedCache("chat-cache") chatCache: AsyncCacheApi, botService: BotService) extends ChatService { | ||
private val defaultDuration = 30.minutes | ||
|
||
def process(botId: String, conversationId: String, userMessage: String)(implicit ec: ExecutionContext): Future[String] = { | ||
val key = s"$botId.$conversationId" | ||
chatCache.get[Chat](key).flatMap { | ||
case None => set(key, newChat(botId)) | ||
case Some(chat) => Future.successful(chat) | ||
}.map(_.multisentenceRespond(userMessage)) | ||
} | ||
|
||
def set(key: String, futureChat: Future[Chat])(implicit ec: ExecutionContext): Future[Chat] = { | ||
for { | ||
chat <- futureChat | ||
_ <- chatCache.set(key, chat, defaultDuration) | ||
} yield chat | ||
} | ||
|
||
def newChat(botId: String)(implicit ec: ExecutionContext): Future[Chat] = newBot(botId).map(new Chat(_)) | ||
|
||
private def newBot(botId: String)(implicit ec: ExecutionContext) = botService.newBot(botId) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package modules | ||
|
||
import com.google.inject.AbstractModule | ||
import controllers.{MyExecutionContext, MyExecutionContextImpl} | ||
import models.{BotService, BotServiceImpl, ChatService, ChatServiceImpl} | ||
|
||
class DI extends AbstractModule { | ||
def configure(): Unit = { | ||
bind(classOf[MyExecutionContext]).to(classOf[MyExecutionContextImpl]) | ||
bind(classOf[ChatService]).to(classOf[ChatServiceImpl]) | ||
bind(classOf[BotService]).to(classOf[BotServiceImpl]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<aiml version="1.0.1"> | ||
<category> | ||
<pattern>HI</pattern> | ||
<template> | ||
<random> | ||
<li>Hi</li> | ||
<li>Hello</li> | ||
</random> | ||
</template> | ||
</category> | ||
<category> | ||
<pattern>TEST</pattern> | ||
<template>Congratulation. It works!</template> | ||
</category> | ||
<category> | ||
<pattern>MY NAME IS *</pattern> | ||
<template> | ||
Nice to meet you,<set> | ||
<name>user_name</name> | ||
<star> | ||
<index>1</index> | ||
</star> | ||
</set>. | ||
</template> | ||
</category> | ||
<category> | ||
<pattern>WHAT IS MY NAME</pattern> | ||
<template> | ||
<get><name>user_name</name></get> | ||
</template> | ||
</category> | ||
</aiml> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
0,HI,*,*,<random>#Newline <li>Hi</li>#Newline <li>Hello</li>#Newline </random>,sample.aiml | ||
0,TEST,*,*,Congratulation. It works!,sample.aiml | ||
0,MY NAME IS *,*,*,Nice to meet you#Comma<set>#Newline <name>user_name</name>#Newline <star>#Newline <index>1</index>#Newline </star>#Newline </set>.,sample.aiml | ||
0,WHAT IS MY NAME,*,*,<get><name>user_name</name></get>,sample.aiml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0,BRAIN BUILD,*,*,Sat Mar 10 18:01:39 BRT 2018,update.aiml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
File: [filename] | ||
Author: [botmaster] | ||
Last modified: [date] | ||
|
||
This AIML file is part of the [botname] [version] chat bot knowledge base. | ||
|
||
The [botname] brain is Copyright © [YYYY] by [organization]. | ||
|
||
The [botname] brain is released under the terms of the GNU Lesser General | ||
Public License, as published by the Free Software Foundation. | ||
|
||
This file is distributed WITHOUT ANY WARRANTY; without even the | ||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
|
||
For more information see [url] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
" dot com ",".com" | ||
" dot org ",".org" | ||
" dot edu ",".edu" | ||
" dot gov,".gov" | ||
" dot uk ",".uk" | ||
" dot net ",".net" | ||
" dot ca ",".ca" | ||
" dot de ",".de" | ||
" dot jp ",".jp" | ||
" dot fr ",".fr" | ||
" dot au ",".au" | ||
" dot us ",".us" | ||
" dot ru ",".ru" | ||
" dot ch ",".ch" | ||
" dot it ",".it" | ||
" dot nl ",".nl" | ||
" dot se ",".se" | ||
" dot no ",".no" | ||
" dot es ",".es" | ||
" dot mil ",".mil" | ||
" dot co ",".co" | ||
" smile ",":-)" | ||
" smile ",":)" | ||
" smile ",":-)" | ||
" heart ","<3" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
".com"," dot com " | ||
".org"," dot org " | ||
".edu"," dot edu " | ||
".gov"," dot gov | ||
".uk"," dot uk " | ||
".net"," dot net " | ||
".ca"," dot ca " | ||
".de"," dot de " | ||
".jp"," dot jp " | ||
".fr"," dot fr " | ||
".au"," dot au " | ||
".us"," dot us " | ||
".ru"," dot ru " | ||
".ch"," dot ch " | ||
".it"," dot it " | ||
".nl"," dot nl " | ||
".se"," dot se " | ||
".no"," dot no " | ||
".es"," dot es " | ||
".mil"," dot mil " | ||
".co"," dot co " | ||
":-)"," smile " | ||
":)"," smile " | ||
":-)"," smile " | ||
";)"," smile " | ||
"<3"," heart " |
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name:SAMPLE | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,23 @@ | ||
name := """Pinky""" | ||
organization := "ifreitas" | ||
|
||
version := "0.1.0-SNAPSHOT" | ||
version := "1.0.0-SNAPSHOT" | ||
|
||
lazy val root = (project in file(".")).enablePlugins(PlayScala) | ||
|
||
scalaVersion := "2.12.0" | ||
|
||
EclipseKeys.preTasks := Seq(compile in Compile, compile in Test) | ||
|
||
import NativePackagerHelper.directory | ||
mappings in Universal ++= directory("bots") | ||
|
||
libraryDependencies += guice | ||
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test; | ||
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test | ||
libraryDependencies += "org.mockito" % "mockito-core" % "2.13.0" % "test" | ||
libraryDependencies += ehcache | ||
|
||
val akkaVersion = "2.5.11" | ||
dependencyOverrides += "com.google.guava" % "guava" % "22.0"; | ||
dependencyOverrides += "com.typesafe.akka" %% "akka-actor" % akkaVersion; | ||
dependencyOverrides += "com.typesafe.akka" %% "akka-stream" % akkaVersion; | ||
dependencyOverrides += "com.google.guava" % "guava" % "22.0" | ||
dependencyOverrides += "com.typesafe.akka" %% "akka-actor" % akkaVersion | ||
dependencyOverrides += "com.typesafe.akka" %% "akka-stream" % akkaVersion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,21 @@ | ||
# https://www.playframework.com/documentation/latest/Configuration | ||
play.modules.enabled += "modules.DI" | ||
|
||
play.cache.bindCaches = ["chat-cache"] | ||
|
||
my-context { | ||
executor = "thread-pool-executor" | ||
throughput = 1 | ||
thread-pool-executor { | ||
fixed-pool-size = 20 | ||
} | ||
} | ||
|
||
include "production" | ||
|
||
play.http.secret.key = ${application_secret_key} | ||
|
||
play.filters.hosts { | ||
allowed = ${allowed_hosts} | ||
} | ||
|
||
http.port = ${http_port} |
Oops, something went wrong.