You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2022/03/29 18:47:50 UTC
[incubator-nlpcraft] branch NLPCRAFT-490 updated: WIP.
This is an automated email from the ASF dual-hosted git repository.
sergeykamov pushed a commit to branch NLPCRAFT-490
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-490 by this push:
new f4071b9 WIP.
f4071b9 is described below
commit f4071b9f71d64012949d6dda7854719c1143f279
Author: Sergey Kamov <sk...@gmail.com>
AuthorDate: Tue Mar 29 21:47:35 2022 +0300
WIP.
---
.../scala/org/apache/nlpcraft/NCModelClient.java | 5 +-
.../nlpcraft/internal/impl/NCModelClientImpl.scala | 14 +--
.../intent/matcher/NCIntentSolverManager.scala | 99 ++++++++++++++--------
.../nlpcraft/internal/impl/NCModelClientSpec.scala | 2 +-
.../internal/impl/NCModelClientSpec2.scala | 4 +-
5 files changed, 78 insertions(+), 46 deletions(-)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
index b3c82a0..c90d436 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
@@ -109,9 +109,10 @@ public class NCModelClient implements AutoCloseable {
* @param txt
* @param data
* @param usrId
+ * @param saveHistory
* @return
*/
- public NCWinnerIntent getWinnerIntent(String txt, Map<String, Object> data, String usrId) {
- return impl.getWinnerIntent(txt, data, usrId);
+ public NCWinnerIntent getWinnerIntent(String txt, Map<String, Object> data, String usrId, boolean saveHistory) {
+ return impl.getWinnerIntent(txt, data, usrId, saveHistory);
}
}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
index 7c605b5..8637096 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
@@ -26,6 +26,7 @@ import org.apache.nlpcraft.internal.dialogflow.NCDialogFlowManager
import org.apache.nlpcraft.internal.impl.*
import org.apache.nlpcraft.internal.intent.matcher.*
import org.apache.nlpcraft.internal.util.*
+import org.apache.nlpcraft.internal.intent.matcher.NCIntentSolveType.*
import java.util
import java.util.concurrent.*
@@ -48,7 +49,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
private val convMgr = NCConversationManager(mdl.getConfig)
private val dlgMgr = NCDialogFlowManager(mdl.getConfig)
private val plMgr = NCModelPipelineManager(mdl.getConfig, mdl.getPipeline)
- private val intentsMgr = NCIntentSolverManager(dlgMgr, intents.map(p => p.intent -> p.function).toMap)
+ private val intentsMgr = NCIntentSolverManager(dlgMgr, convMgr, intents.map(p => p.intent -> p.function).toMap)
init()
@@ -75,7 +76,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
dlgMgr.start()
plMgr.start()
- private def ask0(txt: String, data: JMap[String, AnyRef], usrId: String, testRun: Boolean): Either[NCResult, NCWinnerIntent] =
+ private def ask0(txt: String, data: JMap[String, AnyRef], usrId: String, typ: NCIntentSolveType): Either[NCResult, NCWinnerIntent] =
val plData = plMgr.prepare(txt, data, usrId)
val userId = plData.request.getUserId
@@ -99,7 +100,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
override val getVariants: util.Collection[NCVariant] = plData.variants.asJava
override val getTokens: JList[NCToken] = plData.tokens
- intentsMgr.solve(mdl, ctx, testRun)
+ intentsMgr.solve(mdl, ctx, typ)
/*
* @param txt
@@ -107,7 +108,8 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
* @param usrId
* @return
*/
- def ask(txt: String, data: JMap[String, AnyRef], usrId: String): NCResult = ask0(txt, data, usrId, false).swap.toOption.get
+ def ask(txt: String, data: JMap[String, AnyRef], usrId: String): NCResult =
+ ask0(txt, data, usrId, REGULAR).swap.toOption.get
/**
*
@@ -190,5 +192,5 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
dlgMgr.close()
convMgr.close()
- def getWinnerIntent(txt: String, data: JMap[String, AnyRef], usrId: String): NCWinnerIntent =
- ask0(txt, data, usrId, true).toOption.get
\ No newline at end of file
+ def getWinnerIntent(txt: String, data: JMap[String, AnyRef], usrId: String, saveHistory: Boolean): NCWinnerIntent =
+ ask0(txt, data, usrId, if saveHistory then TEST_HISTORY else TEST_NO_HISTORY).toOption.get
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
index b46f38f..74a751a 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
@@ -20,6 +20,7 @@ package org.apache.nlpcraft.internal.intent.matcher
import com.typesafe.scalalogging.LazyLogging
import org.apache.nlpcraft.*
import org.apache.nlpcraft.internal.ascii.NCAsciiTable
+import org.apache.nlpcraft.internal.conversation.NCConversationManager
import org.apache.nlpcraft.internal.dialogflow.NCDialogFlowManager
import org.apache.nlpcraft.internal.intent.*
@@ -31,6 +32,9 @@ import scala.collection.mutable.ArrayBuffer
import scala.jdk.CollectionConverters.*
import scala.language.postfixOps
+enum NCIntentSolveType:
+ case REGULAR, TEST_HISTORY, TEST_NO_HISTORY
+
object NCIntentSolverManager:
/**
* Sentence variant & its weight.
@@ -229,7 +233,11 @@ import org.apache.nlpcraft.internal.intent.matcher.NCIntentSolverManager.*
/**
* Intent solver that finds the best matching intent given user sentence.
*/
-class NCIntentSolverManager(dialog: NCDialogFlowManager, intents: Map[NCIDLIntent, NCIntentMatch => NCResult]) extends LazyLogging:
+class NCIntentSolverManager(
+ dialog: NCDialogFlowManager,
+ conv: NCConversationManager,
+ intents: Map[NCIDLIntent, NCIntentMatch => NCResult]
+) extends LazyLogging:
/**
* Main entry point for intent engine.
*
@@ -625,10 +633,10 @@ class NCIntentSolverManager(dialog: NCDialogFlowManager, intents: Map[NCIDLInten
*
* @param mdl
* @param ctx
- * @param testRun
+ * @param typ
* @return
*/
- private def solveIteration(mdl: NCModel, ctx: NCContext, testRun: Boolean): Option[IterationResult] =
+ private def solveIteration(mdl: NCModel, ctx: NCContext, typ: NCIntentSolveType): Option[IterationResult] =
require(intents.nonEmpty)
val req = ctx.getRequest
@@ -667,16 +675,33 @@ class NCIntentSolverManager(dialog: NCDialogFlowManager, intents: Map[NCIDLInten
try
if mdl.onMatchedIntent(im) then
// This can throw NCIntentSkip exception.
- if testRun then
- Loop.finish(Option(IterationResult(Right(NCWinnerIntentImpl(im.getIntentId, im.getIntentEntities)), im)))
- else
- val cbRes = intentRes.fn(im)
- // Store won intent match in the input.
- if cbRes.getIntentId == null then
- cbRes.setIntentId(intentRes.intentId)
- logger.info(s"Intent '${intentRes.intentId}' for variant #${intentRes.variantIdx + 1} selected as the <|best match|>")
- dialog.addMatchedIntent(im, cbRes, ctx)
- Loop.finish(Option(IterationResult(Left(cbRes), im)))
+ import NCIntentSolveType.*
+
+ def saveHistory(r: NCResult): Unit =
+ dialog.addMatchedIntent(im, r, ctx)
+ conv.getConversation(req.getUserId).addEntities(
+ req.getRequestId, im.getIntentEntities.asScala.flatMap(_.asScala).toSeq.distinct
+ )
+
+ typ match
+ case REGULAR =>
+ val cbRes = intentRes.fn(im)
+ // Store won intent match in the input.
+ if cbRes.getIntentId == null then
+ cbRes.setIntentId(intentRes.intentId)
+ logger.info(s"Intent '${intentRes.intentId}' for variant #${intentRes.variantIdx + 1} selected as the <|best match|>")
+
+ saveHistory(cbRes)
+
+ Loop.finish(Option(IterationResult(Left(cbRes), im)))
+
+ case TEST_HISTORY =>
+ // Added dummy result. TODO: is it ok?
+ saveHistory(new NCResult())
+
+ Loop.finish(Option(IterationResult(Right(NCWinnerIntentImpl(im.getIntentId, im.getIntentEntities)), im)))
+ case TEST_NO_HISTORY =>
+ Loop.finish(Option(IterationResult(Right(NCWinnerIntentImpl(im.getIntentId, im.getIntentEntities)), im)))
else
logger.info(s"Model '${ctx.getModelConfig.getId}' triggered rematching of intents by intent '${intentRes.intentId}' on variant #${intentRes.variantIdx + 1}.")
Loop.finish()
@@ -693,14 +718,16 @@ class NCIntentSolverManager(dialog: NCDialogFlowManager, intents: Map[NCIDLInten
*
* @param mdl
* @param ctx
- * @param testRun
+ * @param typ
* @return
*/
- def solve(mdl: NCModel, ctx: NCContext, testRun: Boolean): ResultData =
+ def solve(mdl: NCModel, ctx: NCContext, typ: NCIntentSolveType): ResultData =
+ import NCIntentSolveType.*
+
val ctxRes = mdl.onContext(ctx)
if ctxRes != null then
- if testRun then E("`onContext` method overriden, intents cannot be found.") // TODO: test
+ if typ != REGULAR then E("`onContext` method overriden, intents cannot be found.") // TODO: test
if intents.nonEmpty then logger.warn("`onContext` method overrides existed intents. They are ignored.") // TODO: text.
Left(ctxRes)
@@ -713,29 +740,31 @@ class NCIntentSolverManager(dialog: NCDialogFlowManager, intents: Map[NCIDLInten
try
while (loopRes == null)
- solveIteration(mdl, ctx, testRun) match
+ solveIteration(mdl, ctx, typ) match
case Some(iterRes) => loopRes = iterRes
case None => // No-op.
- if testRun then
- loopRes.result
- else
- mdl.onResult(loopRes.intentMatch, loopRes.result.swap.toOption.get) match
- case null => loopRes.result
- case res => Left(res)
+ typ match
+ case REGULAR =>
+ mdl.onResult(loopRes.intentMatch, loopRes.result.swap.toOption.get) match
+ case null => loopRes.result
+ case res => Left(res)
+ case _ => loopRes.result
catch
case e: NCRejection =>
- if testRun then throw e
+ typ match
+ case REGULAR =>
+ mdl.onRejection(if loopRes != null then loopRes.intentMatch else null, e) match
+ case null => throw e
+ case res => Left(res)
+ case _ => throw e
- mdl.onRejection(if loopRes != null then loopRes.intentMatch else null, e) match
- case null => throw e
- case res => Left(res)
case e: Throwable =>
- if testRun then throw e
-
- mdl.onError(ctx, e) match
- case null => throw e
- case res =>
- logger.warn("Error during execution.", e)
-
- Left(res)
+ typ match
+ case REGULAR =>
+ mdl.onError(ctx, e) match
+ case null => throw e
+ case res =>
+ logger.warn("Error during execution.", e)
+ Left(res)
+ case _ => throw e
\ No newline at end of file
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec.scala
index f50fb14..d1c3daa 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec.scala
@@ -41,7 +41,7 @@ class NCModelClientSpec:
client.validateSamples()
- val winner = client.getWinnerIntent("Lights on at second floor kitchen", null, "userId")
+ val winner = client.getWinnerIntent("Lights on at second floor kitchen", null, "userId", true)
println(s"Winner intent: ${winner.getIntentId}")
println("Entities: \n" + winner.getArguments.asScala.map(p => p.asScala.map(s).mkString(", ")).mkString("\n"))
}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec2.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec2.scala
index 99e5d3b..b7c2f62 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec2.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec2.scala
@@ -44,7 +44,7 @@ class NCModelClientSpec2:
Using.resource(new NCModelClient(mdl)) { client =>
case class Result(txt: String):
- private val wi = client.getWinnerIntent(txt, null, "userId")
+ private val wi = client.getWinnerIntent(txt, null, "userId", true)
private val allArgs: JList[JList[NCEntity]] = wi.getArguments
val intentId: String = wi.getIntentId
@@ -84,7 +84,7 @@ class NCModelClientSpec2:
// 3. No winners.
try
- client.getWinnerIntent("x", null, "userId")
+ client.getWinnerIntent("x", null, "userId", false)
require(false)
catch