This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch NLPCRAFT-477 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-477 by this push: new 7c4abdd WIP. new 780afaa Merge remote-tracking branch 'origin/NLPCRAFT-477' into NLPCRAFT-477 7c4abdd is described below commit 7c4abdd5d28857be51bbd635c8c79c1d9df5f3a7 Author: Sergey Kamov <skhdlem...@gmail.com> AuthorDate: Thu Feb 17 22:54:39 2022 +0300 WIP. --- .../scala/org/apache/nlpcraft/NCConversation.java | 2 +- .../conversation/NCConversationHolder.scala | 4 +- .../conversation/NCConversationManager.scala | 6 ++- .../internal/dialogflow/NCDialogFlowManager.scala | 2 +- .../internal/impl/NCModelPipelineProcessor.scala | 47 +++++++++++++++++----- .../internal/NCModelPipelineProcessorSpec.scala | 6 +-- 6 files changed, 48 insertions(+), 19 deletions(-) diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java index 7856601..e2dcfb5 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java @@ -60,5 +60,5 @@ public interface NCConversation { * * @param filter Dialog flow filter. */ - void clearDialog(Predicate<NCDialogFlowItem> filter); + void clearDialog(Predicate<String> filter); // TODO: was NCDialogFlowItem } diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala index 7d62dd5..6f5f13c 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala @@ -38,7 +38,7 @@ case class NCConversationHolder( timeoutMs: Long, maxDepth: Int ) extends LazyLogging { - private final val data = new ConcurrentHashMap[String, Object]() + private final val data = new NCPropertyMapAdapter() case class EntityHolder(entity: NCEntity, var entityTypeUsageTime: Long = 0) case class ConversationItem(holders: mutable.ArrayBuffer[EntityHolder], reqId: String, tstamp: Long) @@ -217,5 +217,5 @@ case class NCConversationHolder( /** * */ - def getUserData: util.Map[String, Object] = data + val getUserData: NCPropertyMap = data } \ No newline at end of file diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala index 4377e32..a121057 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala @@ -22,6 +22,7 @@ import org.apache.nlpcraft.* import org.apache.nlpcraft.internal.util.NCUtils import scala.collection.* +import scala.jdk.CollectionConverters.* /** * Conversation manager. @@ -70,7 +71,10 @@ class NCConversationManager(mdlCfg: NCModelConfig) extends LazyLogging: for ((key, value) <- convs) if value.tstamp < now - mdlCfg.getConversationTimeout then - value.conv.getUserData.clear() + val data = value.conv.getUserData + + data.synchronized { data.keysSet().asScala.foreach(data.remove) } + delKeys += key diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala index 0a1c5a9..ca99c0d 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala @@ -33,7 +33,7 @@ import java.time.format.DateTimeFormatter /** * Dialog flow manager. */ -class NCDialogFlowManager(mdlCfg: NCModelConfig) extends LazyLogging: +case class NCDialogFlowManager(mdlCfg: NCModelConfig) extends LazyLogging: private final val flow = mutable.HashMap.empty[String, mutable.ArrayBuffer[NCDialogFlowItem]] @volatile private var gc: Thread = _ diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineProcessor.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineProcessor.scala index 14faacf..b1054ef 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineProcessor.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineProcessor.scala @@ -19,12 +19,17 @@ package org.apache.nlpcraft.internal.impl import com.typesafe.scalalogging.LazyLogging import org.apache.nlpcraft.* +import org.apache.nlpcraft.internal.dialogflow.NCDialogFlowManager +import org.apache.nlpcraft.internal.conversation.* import org.apache.nlpcraft.internal.impl.* +import org.apache.nlpcraft.internal.intent.matcher.{NCIntentSolver, NCIntentSolverInput} import org.apache.nlpcraft.internal.util.* +import scala.jdk.CollectionConverters.* import java.util import java.util.concurrent.* import java.util.concurrent.atomic.* +import java.util.function.Predicate import java.util.{ArrayList, UUID, List as JList, Map as JMap} import scala.collection.immutable import scala.jdk.OptionConverters.* @@ -36,13 +41,7 @@ import scala.jdk.CollectionConverters.* * @param mdl */ class NCModelPipelineProcessor(mdl: NCModel) extends LazyLogging: - /** - * - * @param req - * @param vars - * @param checkCancel - */ - case class VariantsHolder(req: NCRequest, vars: Seq[NCVariant], checkCancel: Option[() => Unit]) + case class VariantsHolder(request: NCRequest, variants: Seq[NCVariant], tokens: JList[NCToken], checkCancel: Option[() => Unit]) require(mdl != null) require(mdl.getPipeline.getTokenParser != null) @@ -60,6 +59,11 @@ class NCModelPipelineProcessor(mdl: NCModel) extends LazyLogging: private val entVals = nvl(pipeline.getEntityValidators) private val varFilter = pipeline.getVariantFilter.toScala + private val convMgr = NCConversationManager(mdl.getConfig) + private val dialogMgr = NCDialogFlowManager(mdl.getConfig) + private val mdlIntents = NCModelScanner.scan(mdl) + private val solver = NCIntentSolver(dialogMgr, mdlIntents.map(p => p.intent -> p.function).toMap) + /** * * @param list @@ -73,7 +77,29 @@ class NCModelPipelineProcessor(mdl: NCModel) extends LazyLogging: * @param h * @return */ - private def matchIntent(h: VariantsHolder): NCResult = ??? + private def matchIntent(h: VariantsHolder): NCResult = + val userId = h.request.getUserId + val convHldr = convMgr.getConversation(userId) + val allEnts = h.variants.flatMap(_.getEntities.asScala) + + val conv = + new NCConversation { + override val getSession: NCPropertyMap = convHldr.getUserData + override val getStm: JList[NCEntity] = convHldr.getEntities + override val getDialogFlow: JList[NCDialogFlowItem] = dialogMgr.getDialogFlow(userId).asJava + override def clearStm(filter: Predicate[NCEntity]): Unit = convHldr.clearEntities(filter) + override def clearDialog(filter: Predicate[String]): Unit = dialogMgr.clearForPredicate(userId, (s: String) => filter.test(s)) + } + + val ctx = new NCContext: + override def isOwnerOf(ent: NCEntity): Boolean = allEnts.contains(ent) + override val getModelConfig: NCModelConfig = mdl.getConfig + override val getRequest: NCRequest = h.request + override val getConversation: NCConversation = conv + override val getVariants: util.Collection[NCVariant] = h.variants.asJava + override val getTokens: JList[NCToken] = h.tokens + + solver.solve(NCIntentSolverInput(ctx, mdl)) /** * @@ -159,7 +185,7 @@ class NCModelPipelineProcessor(mdl: NCModel) extends LazyLogging: check() variants = varFilter.get.filter(req, cfg, variants) - VariantsHolder(req, variants.asScala.toSeq, checkCancel) + VariantsHolder(req, variants.asScala.toSeq, toks, checkCancel) /** * @@ -171,8 +197,7 @@ class NCModelPipelineProcessor(mdl: NCModel) extends LazyLogging: * @throws NCCuration * @throws NCException */ - def askSync(txt: String, data: JMap[String, AnyRef], usrId: String): NCResult = - matchIntent(prepVariants(txt, data, usrId)) + def askSync(txt: String, data: JMap[String, AnyRef], usrId: String): NCResult = matchIntent(prepVariants(txt, data, usrId)) /** * TODO: explain all exceptions that are thrown by the future. diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/NCModelPipelineProcessorSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/NCModelPipelineProcessorSpec.scala index 9a63b4b..0a88fd4 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/NCModelPipelineProcessorSpec.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/NCModelPipelineProcessorSpec.scala @@ -51,12 +51,12 @@ class NCModelPipelineProcessorSpec: val res = new NCModelPipelineProcessor(new NCModelAdapter(CFG, pipeline)).prepVariants(txt, null, "userId") - println(s"Variants count: ${res.vars.size}") - for ((v, idx) <- res.vars.zipWithIndex) + println(s"Variants count: ${res.variants.size}") + for ((v, idx) <- res.variants.zipWithIndex) println(s"Variant: $idx") NCTestUtils.printEntities(txt, v.getEntities.asScala.toSeq) - require(res.vars.sizeIs == variantCnt) + require(res.variants.sizeIs == variantCnt) test("t1 t2", 4, NCSemanticTestElement("t1", "t2"), NCSemanticTestElement("t2", "t1")) test("t1 t2", 2, NCSemanticTestElement("t1", "t2"), NCSemanticTestElement("t2"))