WIP on NLPCRAFT-402
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala
index b538b92..68ad051 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala
@@ -111,10 +111,10 @@
// Table drawing symbols.
private val HDR_HOR = c("=")
private val HDR_VER = c("|")
- private val HDR_CRS = bo(c("+"))
+ private val HDR_CRS = r("+")
private val ROW_HOR = c("-")
private val ROW_VER = c("|")
- private val ROW_CRS = bo(c("+"))
+ private val ROW_CRS = r("+")
// Headers & rows.
private var hdr = IndexedSeq.empty[Cell]
@@ -136,7 +136,7 @@
* Global Flag indicating whether of not to automatically draw horizontal lines
* for multiline rows.
*/
- var autoBorder = true
+ var multiLineAutoBorder = true
/**
* If lines exceeds the style's maximum width it will be broken up
@@ -492,8 +492,8 @@
// At this point all rows in the table have the
// the same number of columns.
- val colWs = new Array[Int](colsNum) // Column widths.
- val rowHs = new Array[Int](rows.length) // Row heights.
+ val colWidths = new Array[Int](colsNum) // Column widths.
+ val rowHeights = new Array[Int](rows.length) // Row heights.
// Header height.
var hdrH = 0
@@ -502,7 +502,7 @@
for (i <- hdr.indices) {
val c = hdr(i)
- colWs(i) = c.width
+ colWidths(i) = c.width
hdrH = math.max(hdrH, c.height)
}
@@ -511,12 +511,12 @@
for (i <- rows.indices; j <- 0 until colsNum) {
val c = rows(i)(j)
- rowHs(i) = math.max(rowHs(i), c.height)
- colWs(j) = math.max(colWs(j), c.width)
+ rowHeights(i) = math.max(rowHeights(i), c.height)
+ colWidths(j) = math.max(colWidths(j), c.width)
}
// Table width without the border.
- val tableW = colWs.sum + colsNum - 1
+ val tableW = colWidths.sum + colsNum - 1
val tbl = new StringBuilder
@@ -545,9 +545,9 @@
val c = hdr(j)
if (i >= 0 && i < c.height)
- tbl ++= aligned(c.lines(i), colWs(j), c.style)
+ tbl ++= aligned(c.lines(i), colWidths(j), c.style)
else
- tbl ++= space(colWs(j))
+ tbl ++= space(colWidths(j))
tbl ++= s"$HDR_VER" // '|'
}
@@ -561,34 +561,33 @@
else
tbl ++= mkAsciiLine(ROW_CRS, ROW_HOR)
+ val tblWidthLine = s"${space(margin.left)}$ROW_CRS${dash(ROW_HOR, tableW)}$ROW_CRS${space(margin.right)}\n"
+
// Print rows, if any.
if (rows.nonEmpty) {
- val horLine = (i: Int) => {
+ val addHorLine = (i: Int) => {
// Left margin and '+'
tbl ++= s"${space(margin.left)}$ROW_CRS"
for (k <- rows(i).indices)
- tbl ++= s"${dash(ROW_HOR, colWs(k))}$ROW_CRS"
+ tbl ++= s"${dash(ROW_HOR, colWidths(k))}$ROW_CRS"
// Right margin.
tbl ++= s"${space(margin.right)}\n"
}
for (i <- rows.indices) {
- val r = rows(i)
+ val row = rows(i)
- val rowH = rowHs(i)
-
- if (i > 0 && ((rowH > 1 && autoBorder) || insideBorder) && rowHs(i - 1) == 1)
- horLine(i)
+ val rowH = rowHeights(i)
for (j <- 0 until rowH) {
// Left margin and '|'
tbl ++= s"${space(margin.left)}$ROW_VER"
- for (k <- r.indices) {
- val c = r(k)
- val w = colWs(k)
+ for (k <- row.indices) {
+ val c = row(k)
+ val w = colWidths(k)
if (j < c.height)
tbl ++= aligned(c.lines(j), w, c.style)
@@ -602,11 +601,11 @@
tbl ++= s"${space(margin.right)}\n"
}
- if (i < rows.size - 1 && ((rowH > 1 && autoBorder) || insideBorder))
- horLine(i)
+ if (i < rows.size - 1 && ((rowH > 1 && multiLineAutoBorder) || insideBorder))
+ addHorLine(i)
}
- tbl ++= s"${space(margin.left)}$ROW_CRS${dash(ROW_HOR, tableW)}$ROW_CRS${space(margin.right)}\n"
+ tbl ++= tblWidthLine
}
// Bottom margin.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
index 5f1cc62..780bbb4 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
@@ -101,11 +101,11 @@
}
for ((intentId, seq) <- samples; txts <- seq) yield ask(intentId, txts)
- }.flatten.toList
+ }.flatMap(_.toSeq)
val tbl = NCAsciiTable()
- tbl #= ("Model ID", "Intent ID", "+/-", "Text", "Error", "Execution time, ms.")
+ tbl #= ("Model ID", "Intent ID", "+/-", "Text", "Error", "ms.")
for (res <- results)
tbl += (
@@ -116,7 +116,7 @@
res.error.getOrElse(""),
res.time
)
-
+
val passCnt = results.count(_.pass)
val failCnt = results.count(!_.pass)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
index 138b777..756481d 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
@@ -460,7 +460,7 @@
tbl += (s"${B}Down-Link$RST", cfg.downLinkString)
tbl += (s"${B}Up-Link$RST", cfg.upLinkString)
tbl += (s"${B}Lifecycle$RST", cfg.lifecycle)
- tbl += (s"${B}Models (${cfg.modelsSeq.size})$RST", cfg.modelsSeq)
+ tbl += (s"${B}Models (${cfg.modelsSeq.size})$RST", cfg.modelsSeq.map(c(_)))
tbl += (s"${B}JARs Folder$RST", cfg.jarsFolder.getOrElse(""))
tbl.info(logger, Some("Probe Configuration:"))
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
index 9084fb8..75ae18b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
@@ -21,11 +21,18 @@
import org.apache.nlpcraft.model.intent.solver.NCIntentSolver
import org.apache.nlpcraft.model.{NCElement, NCModel}
+case class NCProbeModelCallback(
+ origin: String,
+ className: String,
+ methodName: String
+)
+
/**
*
* @param model
* @param solver
* @param intents
+ * @param callbacks
* @param continuousSynonyms
* @param sparseSynonyms
* @param idlSynonyms
@@ -37,6 +44,7 @@
model: NCModel,
solver: NCIntentSolver,
intents: Seq[NCIdlIntent],
+ callbacks: Map[String /* Intent ID */, NCProbeModelCallback],
continuousSynonyms: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , NCProbeSynonymsWrapper]], // Fast access map.
sparseSynonyms: Map[String /*Element ID*/, Seq[NCProbeSynonym]],
idlSynonyms: Map[String /*Element ID*/ , Seq[NCProbeSynonym]], // Fast access map.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
index d518e62..f6ee6eb 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
@@ -37,7 +37,7 @@
import org.apache.nlpcraft.model.intent.solver.NCIntentSolver
import org.apache.nlpcraft.model.intent._
import org.apache.nlpcraft.probe.mgrs.NCProbeSynonymChunkKind.{IDL, REGEX, TEXT}
-import org.apache.nlpcraft.probe.mgrs.{NCProbeModel, NCProbeSynonym, NCProbeSynonymChunk, NCProbeSynonymsWrapper}
+import org.apache.nlpcraft.probe.mgrs.{NCProbeModel, NCProbeModelCallback, NCProbeSynonym, NCProbeSynonymChunk, NCProbeSynonymsWrapper}
import scala.util.Using
import scala.compat.java8.OptionConverters._
@@ -76,7 +76,7 @@
CLS_JAVA_OPT
)
- type Callback = (String /* ID */, Function[NCIntentMatch, NCResult])
+ case class Callback(id: String, clsName: String, funName: String, cbFun: Function[NCIntentMatch, NCResult])
type Intent = (NCIdlIntent, Callback)
type Sample = (String/* Intent ID */, Seq[Seq[String]] /* List of list of input samples for that intent. */)
@@ -497,7 +497,7 @@
}
solver = new NCIntentSolver(
- intents.toList.map(x => (x._1, (z: NCIntentMatch) => x._2._2.apply(z)))
+ intents.toList.map(x => (x._1, (z: NCIntentMatch) => x._2.cbFun.apply(z)))
)
}
else
@@ -512,6 +512,14 @@
model = mdl,
solver = solver,
intents = intents.map(_._1).toSeq,
+ callbacks = intents.map(kv => (
+ kv._1.id,
+ NCProbeModelCallback(
+ kv._1.origin,
+ kv._2.clsName,
+ kv._2.funName
+ )
+ )).toMap,
continuousSynonyms = mkFastAccessMap(sparse(simple, sp = false), NCProbeSynonymsWrapper(_)),
sparseSynonyms = toMap(sparse(simple, sp = true)),
idlSynonyms = toMap(idl(syns.toSet, idl = true)),
@@ -1186,9 +1194,10 @@
checkMinMax(mdl, mtd, tokParamTypes, termIds.map(allLimits), ctxFirstParam)
- // Prepares invocation method.
- (
+ Callback(
mtd.toString,
+ mtd.getDeclaringClass.getName,
+ mtd.getName,
(ctx: NCIntentMatch) => {
invoke(
mtd,
@@ -1544,7 +1553,7 @@
val mtdStr = method2Str(m)
def bindIntent(intent: NCIdlIntent, cb: Callback): Unit = {
- if (intents.exists(i => i._1.id == intent.id && i._2._1 != cb._1))
+ if (intents.exists(i => i._1.id == intent.id && i._2.id != cb.id))
throw new NCE(s"The intent cannot be bound to more than one callback [" +
s"mdlId=$mdlId, " +
s"origin=${mdl.getOrigin}, " +
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala
index 1c5b6b0..da8c70b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala
@@ -46,43 +46,52 @@
override def start(parent: Span = null): NCService = startScopedSpan("start", parent) { span =>
ackStarting()
- val tbl = NCAsciiTable("Models")
-
mux.synchronized {
- data = NCDeployManager.getModels.map(w => {
- w.model.onInit()
- w.model.getId -> w
+ data = NCDeployManager.getModels.map(pm => {
+ pm.model.onInit()
+ pm.model.getId -> pm
}).toMap
- data.values.foreach(w => {
- val mdl = w.model
+ logger.info(s"Models deployed: ${data.size}")
- val contCnt = w.continuousSynonyms.flatMap(_._2.map(_._2.count)).sum
- val sparseCnt = w.sparseSynonyms.map(_._2.size).sum
- val allIdlSyns = w.idlSynonyms.values.flatten
+ data.values.foreach(pm => {
+ val mdl = pm.model
+
+ val contCnt = pm.continuousSynonyms.flatMap(_._2.map(_._2.count)).sum
+ val sparseCnt = pm.sparseSynonyms.map(_._2.size).sum
+ val allIdlSyns = pm.idlSynonyms.values.flatMap(_.toSeq)
val sparseIdlCnt = allIdlSyns.count(_.sparse)
val contIdlCnt = allIdlSyns.size - sparseIdlCnt
def withWarn(i: Int): String = if (i == 0) s"0 ${r("(!)")}" else i.toString
+ val tbl = NCAsciiTable()
+
tbl += Seq(
s"${B}Name:$RST ${bo(c(mdl.getName))}",
s"${B}ID:$RST ${bo(mdl.getId)}",
s"${B}Version:$RST ${mdl.getVersion}",
s"${B}Origin:$RST ${mdl.getOrigin}",
- s"${B}Elements:$RST ${withWarn(w.elements.keySet.size)}",
+ s"${B}Elements:$RST ${withWarn(pm.elements.keySet.size)}"
+ )
+ tbl += Seq(
s"${B}Synonyms:$RST",
s"$B Simple continuous:$RST $contCnt",
s"$B Simple sparse:$RST $sparseCnt",
s"$B IDL continuous:$RST $contIdlCnt",
s"$B IDL sparse:$RST $sparseIdlCnt",
- s"${B}Intents:$RST ${withWarn(w.intents.size)}"
+
)
+ tbl += Seq(s"${B}Intents:$RST ${withWarn(pm.intents.size)}") ++
+ (
+ for (cb <- pm.callbacks) yield
+ s" ${g(bo(cb._1))} from ${m(cb._2.origin)} -> ${c(cb._2.className)}${bo("#")}${c(cb._2.methodName)}(...)"
+ ).toSeq
+
+ tbl.info(logger, Some("Model:"))
})
}
- tbl.info(logger, Some(s"Models deployed: ${data.size}"))
-
addTags(
span,
"deployedModels" -> data.values.map(_.model.getId).mkString(",")