This is an automated email from the ASF dual-hosted git repository.
sergeykamov pushed a commit to branch NLPCRAFT-491
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-491 by this push:
new 2ceff3f1 WIP.
2ceff3f1 is described below
commit 2ceff3f1b780ebdd9fd22e11858ea29c0e056539
Author: Sergey Kamov <[email protected]>
AuthorDate: Thu Apr 7 14:43:31 2022 +0300
WIP.
---
.../examples/order/NCModelValidationSpec.scala | 30 --------
nlpcraft-examples/{order => pizzeria}/README.md | 0
nlpcraft-examples/{order => pizzeria}/pom.xml | 2 +-
.../nlpcraft/examples/order/PizzeriaModel.scala} | 90 +++++++++++-----------
.../examples/order/PizzeriaModelPipeline.scala} | 30 ++------
.../nlpcraft/examples/order/PizzeriaOrder.scala} | 66 +++++++++++-----
.../order/components/ElementExtender.scala} | 8 +-
.../order/components/RequestValidator.scala | 0
.../src/main/resources/pizzeria_model.yaml} | 16 ++--
.../examples/order/PizzeriaModelSpec.scala} | 36 +++++----
.../order/cli/PizzeriaModelClientCli.scala} | 4 +-
.../examples/order/cli/PizzeriaModelServer.scala} | 6 +-
pom.xml | 2 +-
13 files changed, 139 insertions(+), 151 deletions(-)
diff --git
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/NCModelValidationSpec.scala
b/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/NCModelValidationSpec.scala
deleted file mode 100644
index 52100509..00000000
---
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/NCModelValidationSpec.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nlpcraft.examples.order
-
-import org.apache.nlpcraft.*
-import org.junit.jupiter.api.*
-
-import scala.util.Using
-
-/**
- * JUnit models validation.
- */
-class NCModelValidationSpec:
- @Test
- def test(): Unit = Using.resource(new NCModelClient(new OrderModel())) {
_.validateSamples() }
\ No newline at end of file
diff --git a/nlpcraft-examples/order/README.md
b/nlpcraft-examples/pizzeria/README.md
similarity index 100%
rename from nlpcraft-examples/order/README.md
rename to nlpcraft-examples/pizzeria/README.md
diff --git a/nlpcraft-examples/order/pom.xml
b/nlpcraft-examples/pizzeria/pom.xml
similarity index 97%
rename from nlpcraft-examples/order/pom.xml
rename to nlpcraft-examples/pizzeria/pom.xml
index df729acd..c1c06bab 100644
--- a/nlpcraft-examples/order/pom.xml
+++ b/nlpcraft-examples/pizzeria/pom.xml
@@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion>
<name>NLPCraft Example Order</name>
- <artifactId>nlpcraft-example-order</artifactId>
+ <artifactId>nlpcraft-example-pizzeria</artifactId>
<parent>
<artifactId>nlpcraft-parent</artifactId>
diff --git
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaModel.scala
similarity index 70%
rename from
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
rename to
nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaModel.scala
index 58c84685..1f5817f2 100644
---
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
+++
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaModel.scala
@@ -18,18 +18,10 @@
package org.apache.nlpcraft.examples.order
import com.typesafe.scalalogging.LazyLogging
-import edu.stanford.nlp.pipeline.StanfordCoreNLP
-import opennlp.tools.stemmer.PorterStemmer
import org.apache.nlpcraft.*
import org.apache.nlpcraft.NCResultType.*
import org.apache.nlpcraft.examples.order.State.*
-import org.apache.nlpcraft.examples.order.components.*
-import org.apache.nlpcraft.internal.util.NCResourceReader
import org.apache.nlpcraft.nlp.*
-import org.apache.nlpcraft.nlp.entity.parser.*
-import org.apache.nlpcraft.nlp.entity.parser.semantic.*
-import org.apache.nlpcraft.nlp.entity.parser.stanford.*
-import org.apache.nlpcraft.nlp.token.parser.stanford.*
import java.util.Properties
import scala.collection.mutable
@@ -39,10 +31,10 @@ import scala.jdk.OptionConverters.*
/**
*
*/
-object OrderModel extends LazyLogging:
+object PizzeriaModel extends LazyLogging:
private val DFLT_QTY = 1
- private val UNEXPECTED = new NCRejection("Unexpected request in given
context.")
- private def toStr[T](name: String, seq: Iterable[T]): String = if
seq.nonEmpty then s"$name: ${seq.mkString(", ")}." else ""
+ private val UNEXPECTED_REQUEST = new NCRejection("Unexpected request for
current dialog context.")
+
private def extractPizzaSize(e: NCEntity): String =
e.get[String]("ord:pizza:size:value")
private def extractQty(e: NCEntity, qty: String): Option[Int] =
Option.when(e.contains(qty))(e.get[String](qty).toDouble.toInt)
private def extractPizza(e: NCEntity): Pizza =
@@ -50,38 +42,44 @@ object OrderModel extends LazyLogging:
private def extractDrink(e: NCEntity): Drink =
Drink(e.get[String]("ord:drink:value"), extractQty(e, "ord:drink:qty"))
- private def getDescription(o: Order): String =
+ private def getDescription(o: PizzeriaOrder): String =
if !o.isEmpty then
- val s1 = toStr("Pizza", o.getPizzas.values.map(p => s"${p.name}
size: ${p.size.getOrElse("undefined")} count: ${p.qty.getOrElse(DFLT_QTY)}"))
- val s2 = toStr("Drinks", o.getDrinks.values.map(p => s"${p.name}
count: ${p.qty.getOrElse(DFLT_QTY)}"))
+ def s(name: String, seq: Iterable[String]): String = if
seq.nonEmpty then s"$name: ${seq.mkString(", ")}" else ""
+ val s1 = s("Pizza", o.getPizzas.map(p => s"${p.name},
'${p.size.getOrElse("undefined size")}' ${p.qty.getOrElse(DFLT_QTY)} p."))
+ val s2 = s("Drinks", o.getDrinks.map(p => s"${p.name}
${p.qty.getOrElse(DFLT_QTY)} p."))
- if s2.isEmpty then s1
- else if s1.isEmpty then s2 else s"$s1 $s2"
+ if s2.isEmpty then s1 else if s1.isEmpty then s2 else s"$s1 $s2"
else "Nothing ordered."
-import org.apache.nlpcraft.examples.order.OrderModel.*
+import org.apache.nlpcraft.examples.order.PizzeriaModel.*
/**
*
*/
-class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex", "Order Example Model", "1.0"),
StanfordPipeline.PIPELINE) with LazyLogging:
- private val userOrders = mutable.HashMap.empty[String, Order]
+class PizzeriaModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.pizzeria.ex", "Pizzeria Example Model", "1.0"),
PizzeriaModelPipeline.PIPELINE) with LazyLogging:
+ private def withLog(im: NCIntentMatch, body: PizzeriaOrder => NCResult):
NCResult =
+ val usrId = im.getContext.getRequest.getUserId
+ val data = im.getContext.getConversation.getData
+
+ var o: PizzeriaOrder = data.get(usrId)
+
+ if o == null then
+ o = new PizzeriaOrder()
+ data.put(usrId, o)
- private def withLog(im: NCIntentMatch, body: Order => NCResult): NCResult =
- val o = userOrders.getOrElseUpdate(im.getContext.getRequest.getUserId,
new Order)
def getState: String = o.getState.toString.toLowerCase
val state = getState
try body.apply(o)
finally println(s"'${im.getIntentId}' called ($state -> $getState)")
- private def askIsReady(o: Order): NCResult =
+ private def askIsReady(o: PizzeriaOrder): NCResult =
val res = NCResult(s"Is order ready?", ASK_DIALOG)
o.setState(DIALOG_IS_READY)
res
- private def askSpecify(o: Order) =
+ private def askSpecify(o: PizzeriaOrder) =
require(!o.isValid)
val res = o.findPizzaNoSize match
case Some(p) => NCResult(s"Choose size (large, medium or small)
for: '${p.name}'", ASK_DIALOG)
@@ -91,7 +89,7 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
o.setState(DIALOG_SPECIFY)
res
- private def askShouldStop(o: Order) =
+ private def askShouldStop(o: PizzeriaOrder) =
val res = NCResult(s"Should current order be canceled?", ASK_DIALOG)
o.setState(DIALOG_SHOULD_CANCEL)
res
@@ -103,45 +101,45 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
ASK_RESULT
)
- private def doShowStatus(o: Order, newState: State) =
+ private def doShowStatus(o: PizzeriaOrder, newState: State) =
val res = NCResult(s"Current order state: ${getDescription(o)}",
ASK_RESULT)
o.setState(newState)
res
- private def askConfirm(o: Order): NCResult =
+ private def askConfirm(o: PizzeriaOrder): NCResult =
require(o.isValid)
val res = NCResult(s"Let's specify your order. ${getDescription(o)} Is
it correct?", ASK_DIALOG)
o.setState(DIALOG_CONFIRM)
res
- private def clear(im: NCIntentMatch, o: Order): Unit =
- userOrders.remove(im.getContext.getRequest.getUserId)
+ private def clear(im: NCIntentMatch, o: PizzeriaOrder): Unit =
+
im.getContext.getConversation.getData.remove(im.getContext.getRequest.getUserId)
val conv = im.getContext.getConversation
conv.clearStm(_ => true)
conv.clearDialog(_ => true)
- private def doExecute(im: NCIntentMatch, o: Order): NCResult =
+ private def doExecute(im: NCIntentMatch, o: PizzeriaOrder): NCResult =
require(o.isValid)
val res = NCResult(s"Executed: ${getDescription(o)}", ASK_RESULT)
clear(im, o)
res
- private def doStop(im: NCIntentMatch, o: Order): NCResult =
+ private def doStop(im: NCIntentMatch, o: PizzeriaOrder): NCResult =
val res =
if !o.isEmpty then NCResult(s"Everything cancelled. Ask `menu` to
look what you can order.", ASK_RESULT)
else NCResult(s"Nothing to cancel. Ask `menu` to look what you can
order.", ASK_RESULT)
clear(im, o)
res
- private def doContinue(o: Order): NCResult =
+ private def doContinue(o: PizzeriaOrder): NCResult =
val res = NCResult(s"OK, please continue.", ASK_RESULT)
o.setState(NO_DIALOG)
res
- private def askConfirmOrAskSpecify(o: Order): NCResult = if o.isValid then
askConfirm(o) else askSpecify(o)
- private def askIsReadyOrAskSpecify(o: Order): NCResult = if o.isValid then
askIsReady(o) else askSpecify(o)
- private def doExecuteOrAskSpecify(im: NCIntentMatch, o: Order): NCResult =
if o.isValid then doExecute(im, o) else askSpecify(o)
- private def askStopOrDoStop(im: NCIntentMatch, o: Order): NCResult = if
o.isValid then askShouldStop(o) else doStop(im, o)
+ private def askConfirmOrAskSpecify(o: PizzeriaOrder): NCResult = if
o.isValid then askConfirm(o) else askSpecify(o)
+ private def askIsReadyOrAskSpecify(o: PizzeriaOrder): NCResult = if
o.isValid then askIsReady(o) else askSpecify(o)
+ private def doExecuteOrAskSpecify(im: NCIntentMatch, o: PizzeriaOrder):
NCResult = if o.isValid then doExecute(im, o) else askSpecify(o)
+ private def askStopOrDoStop(im: NCIntentMatch, o: PizzeriaOrder): NCResult
= if o.isValid then askShouldStop(o) else doStop(im, o)
/**
*
@@ -151,13 +149,13 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
@NCIntent("intent=yes term(yes)={# == 'ord:yes'}")
def onYes(im: NCIntentMatch): NCResult = withLog(
im,
- (o: Order) => o.getState match
+ (o: PizzeriaOrder) => o.getState match
case DIALOG_CONFIRM =>
require(o.isValid);
doExecute(im, o)
case DIALOG_SHOULD_CANCEL => doStop(im, o)
case DIALOG_IS_READY => askConfirmOrAskSpecify(o)
- case DIALOG_SPECIFY | NO_DIALOG => throw UNEXPECTED
+ case DIALOG_SPECIFY | NO_DIALOG => throw UNEXPECTED_REQUEST
)
/**
@@ -168,10 +166,10 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
@NCIntent("intent=no term(no)={# == 'ord:no'}")
def onNo(im: NCIntentMatch): NCResult = withLog(
im,
- (o: Order) => o.getState match
+ (o: PizzeriaOrder) => o.getState match
case DIALOG_CONFIRM | DIALOG_IS_READY => doContinue(o)
case DIALOG_SHOULD_CANCEL => askConfirmOrAskSpecify(o)
- case DIALOG_SPECIFY | NO_DIALOG => throw UNEXPECTED
+ case DIALOG_SPECIFY | NO_DIALOG => throw UNEXPECTED_REQUEST
)
/**
*
@@ -182,7 +180,7 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
def onStop(im: NCIntentMatch): NCResult = withLog(
im,
// It doesn't depend on order validity and dialog state.
- (o: Order) => askStopOrDoStop(im, o)
+ (o: PizzeriaOrder) => askStopOrDoStop(im, o)
)
/**
@@ -195,7 +193,7 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
@NCIntent("intent=order term(ps)={# == 'ord:pizza'}* term(ds)={# ==
'ord:drink'}*")
def onOrder(im: NCIntentMatch, @NCIntentTerm("ps") ps: List[NCEntity],
@NCIntentTerm("ds") ds: List[NCEntity]): NCResult = withLog(
im,
- (o: Order) =>
+ (o: PizzeriaOrder) =>
require(ps.nonEmpty || ds.nonEmpty);
o.add(ps.map(extractPizza), ds.map(extractDrink)); // It doesn't
depend on order validity and dialog state.
askIsReadyOrAskSpecify(o)
@@ -209,13 +207,13 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
@NCIntent("intent=orderPizzaSize term(size)={# == 'ord:pizza:size'}")
def onOrderPizzaSize(im: NCIntentMatch, @NCIntentTerm("size") size:
NCEntity): NCResult = withLog(
im,
- (o: Order) => o.getState match
+ (o: PizzeriaOrder) => o.getState match
case DIALOG_SPECIFY =>
if o.setPizzaNoSize(extractPizzaSize(size)) then
o.setState(NO_DIALOG);
askIsReadyOrAskSpecify(o)
- else throw UNEXPECTED
- case DIALOG_CONFIRM | NO_DIALOG | DIALOG_IS_READY |
DIALOG_SHOULD_CANCEL => throw UNEXPECTED
+ else throw UNEXPECTED_REQUEST
+ case DIALOG_CONFIRM | NO_DIALOG | DIALOG_IS_READY |
DIALOG_SHOULD_CANCEL => throw UNEXPECTED_REQUEST
)
/**
*
@@ -225,7 +223,7 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
@NCIntent("intent=status term(status)={# == 'ord:status'}")
def onStatus(im: NCIntentMatch): NCResult = withLog(
im,
- (o: Order) => o.getState match
+ (o: PizzeriaOrder) => o.getState match
case DIALOG_CONFIRM =>
require(o.isValid);
askConfirm(o) // Ignore `status`, confirm again.
@@ -241,7 +239,7 @@ class OrderModel extends NCModelAdapter (new
NCModelConfig("nlpcraft.order.ex",
@NCIntent("intent=finish term(finish)={# == 'ord:finish'}")
def onFinish(im: NCIntentMatch): NCResult = withLog(
im,
- (o: Order) => o.getState match
+ (o: PizzeriaOrder) => o.getState match
case DIALOG_CONFIRM => doExecuteOrAskSpecify(im, o) // Like YES
if valid.
case DIALOG_SPECIFY => askSpecify(o) // Ignore `finish`, specify
again.
case NO_DIALOG | DIALOG_IS_READY | DIALOG_SHOULD_CANCEL =>
askConfirmOrAskSpecify(o)
diff --git
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaModelPipeline.scala
similarity index 63%
rename from
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
rename to
nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaModelPipeline.scala
index 34bebf67..b8b73a65 100644
---
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
+++
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaModelPipeline.scala
@@ -1,29 +1,13 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nlpcraft.examples.order.components
+package org.apache.nlpcraft.examples.order
import edu.stanford.nlp.pipeline.StanfordCoreNLP
import opennlp.tools.stemmer.PorterStemmer
-import org.apache.nlpcraft.*
+import org.apache.nlpcraft.examples.order.components.*
import org.apache.nlpcraft.nlp.entity.parser.semantic.*
import org.apache.nlpcraft.nlp.entity.parser.stanford.NCStanfordNLPEntityParser
import org.apache.nlpcraft.nlp.token.enricher.NCEnStopWordsTokenEnricher
import org.apache.nlpcraft.nlp.token.parser.stanford.NCStanfordNLPTokenParser
+import org.apache.nlpcraft.*
import scala.jdk.CollectionConverters.*
import java.util.Properties
@@ -31,7 +15,7 @@ import java.util.Properties
/**
*
*/
-object StanfordPipeline:
+object PizzeriaModelPipeline:
val PIPELINE: NCPipeline =
val stanford =
val props = new Properties()
@@ -42,14 +26,14 @@ object StanfordPipeline:
private val ps = new PorterStemmer
override def stem(txt: String): String = ps.synchronized {
ps.stem(txt) }
- import EntityExtender as Ex
+ import ElementExtender as Ex
import EntityData as D
new NCPipelineBuilder().
withTokenParser(tokParser).
withTokenEnricher(new NCEnStopWordsTokenEnricher()).
withEntityParser(new NCStanfordNLPEntityParser(stanford,
"number")).
- withEntityParser(new NCSemanticEntityParser(stemmer, tokParser,
"order_model.yaml")).
+ withEntityParser(new NCSemanticEntityParser(stemmer, tokParser,
"pizzeria_model.yaml")).
withEntityMappers(
Seq(
Ex(Seq(D("ord:pizza", "ord:pizza:size")),
D("ord:pizza:size", "ord:pizza:size:value")),
@@ -57,4 +41,4 @@ object StanfordPipeline:
).asJava
).
withEntityValidator(new RequestValidator()).
- build()
\ No newline at end of file
+ build()
diff --git
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/Order.scala
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaOrder.scala
similarity index 56%
rename from
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/Order.scala
rename to
nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaOrder.scala
index 395cc20a..d9445826 100644
---
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/Order.scala
+++
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/PizzeriaOrder.scala
@@ -19,19 +19,41 @@ package org.apache.nlpcraft.examples.order
import scala.collection.mutable
-case class Pizza(name: String, var size: Option[String], var qty: Option[Int]):
- require(name != null && name.nonEmpty)
-case class Drink(name: String, var qty: Option[Int]):
+/**
+ *
+ */
+private abstract class OrderElement:
+ val name: String
+ var qty: Option[Int]
require(name != null && name.nonEmpty)
+
+/**
+ *
+ * @param name
+ * @param size
+ * @param qty
+ */
+case class Pizza(name: String, var size: Option[String], var qty: Option[Int])
extends OrderElement
+
+/**
+ *
+ * @param name
+ * @param qty
+ */
+case class Drink(name: String, var qty: Option[Int]) extends OrderElement
+
enum State:
case NO_DIALOG, DIALOG_IS_READY, DIALOG_SHOULD_CANCEL, DIALOG_SPECIFY,
DIALOG_CONFIRM
import org.apache.nlpcraft.examples.order.State.*
-class Order:
+/**
+ *
+ */
+class PizzeriaOrder:
private var state = NO_DIALOG
- private val pizzas = mutable.LinkedHashMap.empty[String, Pizza]
- private val drinks = mutable.LinkedHashMap.empty[String, Drink]
+ private val pizzas = mutable.ArrayBuffer.empty[Pizza]
+ private val drinks = mutable.ArrayBuffer.empty[Drink]
/**
*
@@ -51,35 +73,43 @@ class Order:
* @param ds
*/
def add(ps: Seq[Pizza], ds: Seq[Drink]): Unit =
+ def setByName[T <: OrderElement](buf: mutable.ArrayBuffer[T], t: T) =
+ buf.find(_.name == t.name) match
+ case Some(found) => if t.qty.nonEmpty then found.qty = t.qty
+ case None => buf += t
+
for (p <- ps)
- pizzas.get(p.name) match
- case Some(ex) =>
- if p.size.nonEmpty then ex.size = p.size
- if p.qty.nonEmpty then ex.qty = p.qty
- case None => pizzas += p.name -> p
+ def setPizza[T](pred: Pizza => Boolean, notFound: => () => Unit):
Unit =
+ pizzas.find(pred) match
+ case Some(found) =>
+ if p.size.nonEmpty then found.size = p.size
+ if p.qty.nonEmpty then found.qty = p.qty
+ case None => notFound()
- for (d <- ds)
- drinks.get(d.name) match
- case Some(ex) => if d.qty.nonEmpty then ex.qty = d.qty
- case None => drinks += d.name -> d
+ if p.size.nonEmpty then setPizza(
+ x => x.name == p.name && x.size == p.size,
+ () => setPizza(x => x.name == p.name && x.size.isEmpty, () =>
pizzas += p)
+ )
+ else setByName(pizzas, p)
+ for (d <- ds) setByName(drinks, d)
/**
*
* @return
*/
- def getPizzas: Map[String, Pizza] = pizzas.toMap
+ def getPizzas: Seq[Pizza] = pizzas.toSeq
/**
*
* @return
*/
- def getDrinks: Map[String, Drink] = drinks.toMap
+ def getDrinks: Seq[Drink] = drinks.toSeq
/**
*
* @return
*/
- def findPizzaNoSize: Option[Pizza] = pizzas.values.find(_.size.isEmpty)
+ def findPizzaNoSize: Option[Pizza] = pizzas.find(_.size.isEmpty)
/**
*
diff --git
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/EntityExtender.scala
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/components/ElementExtender.scala
similarity index 90%
rename from
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/EntityExtender.scala
rename to
nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/components/ElementExtender.scala
index dbd772c3..6797a742 100644
---
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/EntityExtender.scala
+++
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/components/ElementExtender.scala
@@ -27,14 +27,14 @@ import scala.jdk.CollectionConverters.*
/**
*
* @param id
- * @param copyProperty
+ * @param property
*/
-case class EntityData(id: String, copyProperty: String)
+case class EntityData(id: String, property: String)
/**
*
*/
-case class EntityExtender(mainDataSeq: Seq[EntityData], extraData: EntityData)
extends NCEntityMapper:
+case class ElementExtender(mainDataSeq: Seq[EntityData], extraData:
EntityData) extends NCEntityMapper:
private def getToks(e: NCEntity): mutable.Seq[NCToken] =
e.getTokens.asScala
override def map(req: NCRequest, cfg: NCModelConfig, entities:
util.List[NCEntity]): util.List[NCEntity] =
val mainDataMap = mainDataSeq.map(p => p.id -> p).toMap
@@ -54,7 +54,7 @@ case class EntityExtender(mainDataSeq: Seq[EntityData],
extraData: EntityData) e
val (mEnt, eEnt) = if mainDataMap.contains(e1.getId)
then (e1, e2) else (e2, e1)
new NCPropertyMapAdapter with NCEntity:
mEnt.keysSet().forEach(k => put(k, mEnt.get(k)))
- put[String](mainDataMap(mEnt.getId).copyProperty,
eEnt.get[String](extraData.copyProperty).toLowerCase)
+ put[String](mainDataMap(mEnt.getId).property,
eEnt.get[String](extraData.property).toLowerCase)
override val getTokens: JList[NCToken] =
(getToks(mEnt) ++ getToks(eEnt)).sortBy(_.getIndex).asJava
override val getRequestId: String =
req.getRequestId
override val getId: String = mEnt.getId
diff --git
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
b/nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
similarity index 100%
rename from
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
rename to
nlpcraft-examples/pizzeria/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
diff --git a/nlpcraft-examples/order/src/main/resources/order_model.yaml
b/nlpcraft-examples/pizzeria/src/main/resources/pizzeria_model.yaml
similarity index 80%
rename from nlpcraft-examples/order/src/main/resources/order_model.yaml
rename to nlpcraft-examples/pizzeria/src/main/resources/pizzeria_model.yaml
index 450d3a0d..25676fb0 100644
--- a/nlpcraft-examples/order/src/main/resources/order_model.yaml
+++ b/nlpcraft-examples/pizzeria/src/main/resources/pizzeria_model.yaml
@@ -27,8 +27,8 @@ elements:
description: "Size of pizza."
values:
"small": [ "{small|smallest|min|minimal} {size|_}" ]
- "medium": [ "{medium|intermediate} {size|_}" ]
- "large": [ "{big|biggest|large|max|maximum} {size|_}" ]
+ "medium": [ "{medium|intermediate|normal|regular} {size|_}" ]
+ "large": [ "{big|biggest|large|max|maximum|huge} {size|_}" ]
- id: "ord:drink"
description: "Kinds of drinks."
@@ -41,7 +41,7 @@ elements:
- id: "ord:yes"
description: "Conformation (yes)."
synonyms:
- - "{yes|yeah|right|fine|nice|excellent|good}"
+ - "{yes|yeah|right|fine|nice|excellent|good|correct|sure}"
- "{you are|_} {correct|right}"
- id: "ord:no"
@@ -53,20 +53,20 @@ elements:
- id: "ord:stop"
description: "Stop and cancel all."
synonyms:
- - "{stop|cancel} {it|all|everything|_}"
+ - "{stop|cancel|clear} {it|all|everything|_}"
- id: "ord:status"
description: "Order status information."
synonyms:
- - "{order|_} {status|state}"
+ - "{current|_} {order|_} {status|state|info|information}"
- id: "ord:finish"
description: "Order finish."
synonyms:
- - "order"
- - "{order|I|_} {is|are|have|has|_} {ready|done|finish}"
+ - "{i|everything|order|_} {is|_} {finish|ready|done}"
- id: "ord:menu"
description: "Order menu."
synonyms:
- - "{menu|order list}"
+ - "{menu|carte|card}"
+ - "{products|goods|food|_} list"
diff --git
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/OrderModelSpec.scala
b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/PizzeriaModelSpec.scala
similarity index 59%
rename from
nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/OrderModelSpec.scala
rename to
nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/PizzeriaModelSpec.scala
index 3ae7ed2e..afe36b93 100644
---
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/OrderModelSpec.scala
+++
b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/PizzeriaModelSpec.scala
@@ -26,29 +26,35 @@ import scala.collection.mutable
/**
*
*/
-class OrderModelSpec:
+class PizzeriaModelSpec:
@Test
def test(): Unit =
val buf = mutable.ArrayBuffer.empty[String]
- def printDialog(): Unit = for (line <- buf) println(line)
+ def printDialog(): Unit = buf.foreach(println)
- Using.resource(new NCModelClient(new OrderModel)) { client =>
+ Using.resource(new NCModelClient(new PizzeriaModel)) { client =>
def ask(txt: String, expResType: NCResultType): Unit =
- val resp = client.ask(txt, null, "userId")
-
- buf += s">> $txt"
- buf += s">> '${resp.getType}': ${resp.getBody}"
- buf += ""
-
- if expResType != resp.getType then
- printDialog()
- require(false, s"Unexpected type: ${resp.getType},
expected: $expResType.")
-
- ask("I want to order margherita medium size, marbonara, marinara
and tea", ASK_DIALOG)
+ try
+ val resp = client.ask(txt, null, "userId")
+
+ buf += s">> Request: $txt"
+ buf += s">> Response: '${resp.getType}': ${resp.getBody}"
+ buf += ""
+
+ if expResType != resp.getType then
+ printDialog()
+ require(false, s"Unexpected type: ${resp.getType},
expected: $expResType.")
+ catch {
+ case e: Exception =>
+ printDialog()
+ throw e
+ }
+ ask("I want to order carbonara, marinara and tea", ASK_DIALOG)
ask("large size please", ASK_DIALOG)
ask("smallest", ASK_DIALOG)
- ask("you are right", ASK_RESULT)
+ ask("yes", ASK_DIALOG)
+ ask("correct", ASK_RESULT)
printDialog()
}
\ No newline at end of file
diff --git
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/cli/OrderModelClientCli.scala
b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/cli/PizzeriaModelClientCli.scala
similarity index 96%
rename from
nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/cli/OrderModelClientCli.scala
rename to
nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/cli/PizzeriaModelClientCli.scala
index 35c8ae0b..b621d1f8 100644
---
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/cli/OrderModelClientCli.scala
+++
b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/cli/PizzeriaModelClientCli.scala
@@ -28,7 +28,7 @@ import java.net.http.HttpRequest.*
import java.net.http.HttpResponse.*
import scala.util.Using
-object OrderModelClientCli extends LazyLogging :
+object PizzeriaModelClientCli extends LazyLogging :
private val client = HttpClient.newHttpClient()
private def ask(req: String): String =
@@ -36,7 +36,7 @@ object OrderModelClientCli extends LazyLogging :
val resp: HttpResponse[String] = client.send(
HttpRequest.
newBuilder().
- uri(new URI(OrderModelServer.URI)).
+ uri(new URI(PizzeriaModelServer.URI)).
headers("Content-Type", "text/plain;charset=UTF-8").
POST(BodyPublishers.ofString(req)).
build(),
diff --git
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/cli/OrderModelServer.scala
b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/cli/PizzeriaModelServer.scala
similarity index 96%
rename from
nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/cli/OrderModelServer.scala
rename to
nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/cli/PizzeriaModelServer.scala
index 09c3fa53..e345dbe4 100644
---
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/cli/OrderModelServer.scala
+++
b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/order/cli/PizzeriaModelServer.scala
@@ -20,7 +20,7 @@ package org.apache.nlpcraft.examples.order.cli
import com.sun.net.httpserver.*
import org.apache.nlpcraft.*
import org.apache.nlpcraft.NCResultType.*
-import org.apache.nlpcraft.examples.order.OrderModel
+import org.apache.nlpcraft.examples.order.PizzeriaModel
import java.io.*
import java.net.InetSocketAddress
@@ -29,14 +29,14 @@ import scala.util.Using
/**
*
*/
-object OrderModelServer:
+object PizzeriaModelServer:
private val host = "localhost"
private val port = 8087
private val path = "ask"
val URI = s"http://$host:$port/$path"
- def main(args: Array[String]): Unit = Using.resource(new NCModelClient(new
OrderModel)) { nlpClient =>
+ def main(args: Array[String]): Unit = Using.resource(new NCModelClient(new
PizzeriaModel)) { nlpClient =>
val srv = HttpServer.create(new InetSocketAddress(host, port), 0)
srv.createContext(
diff --git a/pom.xml b/pom.xml
index 3238a20c..3342e52b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -392,7 +392,7 @@
<module>nlpcraft-examples/lightswitch</module>
<module>nlpcraft-examples/lightswitch-ru</module>
<module>nlpcraft-examples/lightswitch-fr</module>
- <module>nlpcraft-examples/order</module>
+ <module>nlpcraft-examples/pizzeria</module>
</modules>
</profile>
</profiles>