This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch NLPCRAFT-510-2 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
commit 4af18dc0e296512fd97e6bac27e6f6bd6a8e7f0b Author: Sergey Kamov <skhdlem...@gmail.com> AuthorDate: Thu Aug 11 23:49:53 2022 +0300 Validation fixes. --- .../examples/lightswitch/LightSwitchFrModel.scala | 27 +------- .../lightswitch/NCModelValidationSpec.scala | 27 +++++++- .../examples/lightswitch/LightSwitchRuModel.scala | 15 ----- .../lightswitch/NCModelValidationSpec.scala | 18 +++++- .../lightswitch/LightSwitchScalaModel.scala | 24 ------- .../lightswitch/NCModelValidationSpec.scala | 27 +++++++- .../pizzeria/cli/PizzeriaModelServer.scala | 2 +- .../apache/nlpcraft/examples/time/TimeModel.scala | 7 -- .../examples/time/NCModelValidationSpec.scala | 11 +++- .../{NCCallbackData.scala => NCFiredIntent.scala} | 8 ++- .../scala/org/apache/nlpcraft/NCIntentSkip.scala | 2 - .../scala/org/apache/nlpcraft/NCModelClient.scala | 62 ++---------------- .../org/apache/nlpcraft/annotations/NCIntent.java | 2 - .../apache/nlpcraft/annotations/NCIntentRef.java | 2 - .../nlpcraft/annotations/NCIntentSample.java | 73 --------------------- .../nlpcraft/annotations/NCIntentSampleRef.java | 75 ---------------------- .../apache/nlpcraft/annotations/NCIntentTerm.java | 2 - .../nlpcraft/internal/impl/NCModelScanner.scala | 68 +------------------- .../intent/matcher/NCIntentSolverManager.scala | 4 +- .../internal/impl/NCModelCallbacksSpec.scala | 2 +- .../nlpcraft/internal/impl/NCModelClientSpec.scala | 4 -- .../internal/impl/NCModelClientSpec3.scala | 8 +-- .../scan/NCModelIntentsInvalidIntentsSpec.scala | 40 +----------- .../internal/impl/scan/NCTestModelScala.scala | 6 -- 24 files changed, 105 insertions(+), 411 deletions(-) diff --git a/nlpcraft-examples/lightswitch-fr/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala b/nlpcraft-examples/lightswitch-fr/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala index ac7bca22..c813c4fc 100644 --- a/nlpcraft-examples/lightswitch-fr/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala +++ b/nlpcraft-examples/lightswitch-fr/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala @@ -19,13 +19,14 @@ package org.apache.nlpcraft.examples.lightswitch import com.google.gson.Gson import org.apache.nlpcraft.* +import org.apache.nlpcraft.annotations.* import org.apache.nlpcraft.examples.lightswitch.nlp.entity.parser.NCFrSemanticEntityParser import org.apache.nlpcraft.examples.lightswitch.nlp.token.enricher.* import org.apache.nlpcraft.examples.lightswitch.nlp.token.parser.NCFrTokenParser import org.apache.nlpcraft.nlp.entity.parser.* import org.apache.nlpcraft.nlp.token.enricher.* import org.apache.nlpcraft.nlp.token.parser.NCOpenNLPTokenParser -import org.apache.nlpcraft.annotations.* + import java.util import scala.jdk.CollectionConverters.* @@ -58,30 +59,6 @@ class LightSwitchFrModel extends NCModelAdapter( * @return Query result to be sent to the REST caller. */ @NCIntent("intent=ls term(act)={has(ent_groups, 'act')} term(loc)={# == 'ls:loc'}*") - @NCIntentSample(Array( - "Éteignez les lumières dans toute la maison.", - "Éteignez toutes les lumières maintenant.", - "Allumez l'éclairage dans le placard de la chambre des maîtres.", - "Éteindre les lumières au 1er étage.", - "Allumez les lumières.", - "Allumes dans la cuisine.", - "S'il vous plait, éteignez la lumière dans la chambre à l'étage.", - "Allumez les lumières dans toute la maison.", - "Éteignez les lumières dans la chambre d'hôtes.", - "Pourriez-vous éteindre toutes les lumières s'il vous plait?", - "Désactivez l'éclairage au 2ème étage.", - "Éteignez les lumières dans la chambre au 1er étage.", - "Lumières allumées à la cuisine du deuxième étage.", - "S'il te plaît, pas de lumières!", - "Coupez toutes les lumières maintenant!", - "Éteindre les lumières dans le garage.", - "Lumières éteintes dans la cuisine!", - "Augmentez l'éclairage dans le garage et la chambre des maîtres.", - "Baissez toute la lumière maintenant!", - "Pas de lumières dans la chambre, s'il vous plait.", - "Allumez le garage, s'il vous plait.", - "Tuez l'illumination maintenant." - )) def onMatch( ctx: NCContext, im: NCIntentMatch, diff --git a/nlpcraft-examples/lightswitch-fr/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala b/nlpcraft-examples/lightswitch-fr/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala index 2871ec51..11fe249e 100644 --- a/nlpcraft-examples/lightswitch-fr/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala +++ b/nlpcraft-examples/lightswitch-fr/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala @@ -27,4 +27,29 @@ import scala.util.Using */ class NCModelValidationSpec: @Test - def test(): Unit = Using.resource(new NCModelClient(new LightSwitchFrModel)) { _.validateSamples() } + def test(): Unit = Using.resource(new NCModelClient(new LightSwitchFrModel)) { client => + def check(txt: String): Unit = client.debugAsk(txt, "userId", true).getIntentId == "ls" + + check("Éteignez les lumières dans toute la maison.") + check("Éteignez toutes les lumières maintenant.") + check("Allumez l'éclairage dans le placard de la chambre des maîtres.") + check("Éteindre les lumières au 1er étage.") + check("Allumez les lumières.") + check("Allumes dans la cuisine.") + check("S'il vous plait, éteignez la lumière dans la chambre à l'étage.") + check("Allumez les lumières dans toute la maison.") + check("Éteignez les lumières dans la chambre d'hôtes.") + check("Pourriez-vous éteindre toutes les lumières s'il vous plait?") + check("Désactivez l'éclairage au 2ème étage.") + check("Éteignez les lumières dans la chambre au 1er étage.") + check("Lumières allumées à la cuisine du deuxième étage.") + check("S'il te plaît, pas de lumières!") + check("Coupez toutes les lumières maintenant!") + check("Éteindre les lumières dans le garage.") + check("Lumières éteintes dans la cuisine!") + check("Augmentez l'éclairage dans le garage et la chambre des maîtres.") + check("Baissez toute la lumière maintenant!") + check("Pas de lumières dans la chambre, s'il vous plait.") + check("Allumez le garage, s'il vous plait.") + check("Tuez l'illumination maintenant.") + } diff --git a/nlpcraft-examples/lightswitch-ru/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala b/nlpcraft-examples/lightswitch-ru/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala index 10eca4ca..84ac035c 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala +++ b/nlpcraft-examples/lightswitch-ru/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala @@ -51,21 +51,6 @@ class LightSwitchRuModel extends NCModelAdapter( * @return Query result to be sent to the REST caller. */ @NCIntent("intent=ls term(act)={has(ent_groups, 'act')} term(loc)={# == 'ls:loc'}*") - @NCIntentSample(Array( - "Выключи свет по всем доме", - "Выруби электричество!", - "Включи свет в детской", - "Включай повсюду освещение", - "Включайте лампы в детской комнате", - "Свет на кухне, пожалуйста, приглуши", - "Нельзя ли повсюду выключить свет?", - "Пожалуйста без света", - "Отключи электричество в ванной", - "Выключи, пожалуйста, тут всюду свет", - "Выключай все!", - "Свет пожалуйста везде включи", - "Зажги лампу на кухне" - )) def onMatch( ctx: NCContext, im: NCIntentMatch, diff --git a/nlpcraft-examples/lightswitch-ru/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala b/nlpcraft-examples/lightswitch-ru/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala index 6b031eb9..c61cbcd0 100644 --- a/nlpcraft-examples/lightswitch-ru/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala +++ b/nlpcraft-examples/lightswitch-ru/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala @@ -27,4 +27,20 @@ import scala.util.Using */ class NCModelValidationSpec: @Test - def test(): Unit = Using.resource(new NCModelClient(new LightSwitchRuModel)) { _.validateSamples() } + def test(): Unit = Using.resource(new NCModelClient(new LightSwitchRuModel)) { client => + def check(txt: String): Unit = client.debugAsk(txt, "userId", true).getIntentId == "ls" + + check("Выключи свет по всем доме") + check("Выруби электричество!") + check("Включи свет в детской") + check("Включай повсюду освещение") + check("Включайте лампы в детской комнате") + check("Свет на кухне, пожалуйста, приглуши") + check("Нельзя ли повсюду выключить свет?") + check("Пожалуйста без света") + check("Отключи электричество в ванной") + check("Выключи, пожалуйста, тут всюду свет") + check("Выключай все!") + check("Свет пожалуйста везде включи") + check("Зажги лампу на кухне") + } diff --git a/nlpcraft-examples/lightswitch/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala b/nlpcraft-examples/lightswitch/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala index 2320e128..72e9d2cd 100644 --- a/nlpcraft-examples/lightswitch/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala +++ b/nlpcraft-examples/lightswitch/src/main/scala/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala @@ -51,30 +51,6 @@ class LightSwitchScalaModel extends NCModelAdapter( * @return Query result to be sent to the REST caller. */ @NCIntent("intent=ls term(act)={has(ent_groups, 'act')} term(loc)={# == 'ls:loc'}*") - @NCIntentSample(Array( - "Turn the lights off in the entire house.", - "Turn off all lights now", - "Switch on the illumination in the master bedroom closet.", - "Get the lights on.", - "Off the lights on the 1st floor", - "Lights up in the kitchen.", - "Please, put the light out in the upstairs bedroom.", - "Set the lights on in the entire house.", - "Turn the lights off in the guest bedroom.", - "Could you please switch off all the lights?", - "Dial off illumination on the 2nd floor.", - "Turn down lights in 1st floor bedroom", - "Lights on at second floor kitchen", - "Please, no lights!", - "Kill off all the lights now!", - "Down the lights in the garage", - "Lights down in the kitchen!", - "Turn up the illumination in garage and master bedroom", - "Turn down all the light now!", - "No lights in the bedroom, please.", - "Light up the garage, please!", - "Kill the illumination now!" - )) def onMatch( ctx: NCContext, im: NCIntentMatch, diff --git a/nlpcraft-examples/lightswitch/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala b/nlpcraft-examples/lightswitch/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala index b95c943e..4735bb90 100644 --- a/nlpcraft-examples/lightswitch/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala +++ b/nlpcraft-examples/lightswitch/src/test/scala/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala @@ -26,7 +26,32 @@ import scala.util.Using * JUnit models validation. */ class NCModelValidationSpec: - private def test(mdl: NCModel): Unit = Using.resource(new NCModelClient(mdl)) { _.validateSamples() } + private def test(mdl: NCModel): Unit = Using.resource(new NCModelClient(mdl)) { client => + def check(txt: String): Unit = client.debugAsk(txt, "userId", true).getIntentId == "ls" + + check("Turn the lights off in the entire house.") + check("Turn off all lights now") + check("Switch on the illumination in the master bedroom closet.") + check("Get the lights on.") + check("Off the lights on the 1st floor") + check("Lights up in the kitchen.") + check("Please, put the light out in the upstairs bedroom.") + check("Set the lights on in the entire house.") + check("Turn the lights off in the guest bedroom.") + check("Could you please switch off all the lights?") + check("Dial off illumination on the 2nd floor.") + check("Turn down lights in 1st floor bedroom") + check("Lights on at second floor kitchen") + check("Please, no lights!") + check("Kill off all the lights now!") + check("Down the lights in the garage") + check("Lights down in the kitchen!") + check("Turn up the illumination in garage and master bedroom") + check("Turn down all the light now!") + check("No lights in the bedroom, please.") + check("Light up the garage, please!") + check("Kill the illumination now!") + } @Test def test(): Unit = test(new LightSwitchScalaModel()) diff --git a/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/pizzeria/cli/PizzeriaModelServer.scala b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/pizzeria/cli/PizzeriaModelServer.scala index aa8fd12a..c447b462 100644 --- a/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/pizzeria/cli/PizzeriaModelServer.scala +++ b/nlpcraft-examples/pizzeria/src/test/java/org/apache/nlpcraft/examples/pizzeria/cli/PizzeriaModelServer.scala @@ -63,7 +63,7 @@ object PizzeriaModelServer: if req == null || req.isEmpty then Exception(s"Empty request.") - val resp = nlpClient.ask(req, null, "userId") + val resp = nlpClient.ask(req, "userId") val prompt = if resp.getType == ASK_DIALOG then "(Your should answer on the model's question below)\n" else "" doResponse(s"$prompt${resp.getBody}") catch diff --git a/nlpcraft-examples/time/src/main/scala/org/apache/nlpcraft/examples/time/TimeModel.scala b/nlpcraft-examples/time/src/main/scala/org/apache/nlpcraft/examples/time/TimeModel.scala index 245b80f0..b98465bc 100644 --- a/nlpcraft-examples/time/src/main/scala/org/apache/nlpcraft/examples/time/TimeModel.scala +++ b/nlpcraft-examples/time/src/main/scala/org/apache/nlpcraft/examples/time/TimeModel.scala @@ -83,12 +83,6 @@ class TimeModel extends NCModelAdapter( * @param cityEnt Token for 'geo' term. * @return Query result. */ @NCIntentRef("intent2") - @NCIntentSample(Array( - "What time is it now in New York City?", - "What's the current time in Moscow?", - "Show me time of the day in London.", - "Can you please give me the Tokyo's current date and time." - )) private def onRemoteMatch(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("city") cityEnt: NCEntity): NCResult = val cityName: String = cityEnt.mkText @@ -106,7 +100,6 @@ class TimeModel extends NCModelAdapter( * @param ctx Intent solver context. * @return Query result. */ @NCIntentRef("intent1") - @NCIntentSample(Array("What's the local time?")) private def onLocalMatch(ctx: NCContext, im: NCIntentMatch): NCResult = // NOTE: // We need to have two intents vs. one intent with an optional GEO. The reason is that // first intent isn't using the conversation to make sure we can always ask diff --git a/nlpcraft-examples/time/src/test/scala/org/apache/nlpcraft/examples/time/NCModelValidationSpec.scala b/nlpcraft-examples/time/src/test/scala/org/apache/nlpcraft/examples/time/NCModelValidationSpec.scala index a79a81c1..14f51db0 100644 --- a/nlpcraft-examples/time/src/test/scala/org/apache/nlpcraft/examples/time/NCModelValidationSpec.scala +++ b/nlpcraft-examples/time/src/test/scala/org/apache/nlpcraft/examples/time/NCModelValidationSpec.scala @@ -27,4 +27,13 @@ import scala.util.Using */ class NCModelValidationSpec: @Test - def test(): Unit = Using.resource(new NCModelClient(new TimeModel())) { _.validateSamples() } + def test(): Unit = Using.resource(new NCModelClient(new TimeModel())) { client => + def check(txt: String, intentId: String): Unit = client.debugAsk(txt, "userId", true).getIntentId == intentId + + check("What time is it now in New York City?", "intent2") + check("What's the current time in Moscow?", "intent2") + check("Show me time of the day in London.", "intent2") + check("Can you please give me the Tokyo's current date and time.", "intent2") + + check("What's the local time?", "intent1") + } diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCCallbackData.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCFiredIntent.scala similarity index 86% rename from nlpcraft/src/main/scala/org/apache/nlpcraft/NCCallbackData.scala rename to nlpcraft/src/main/scala/org/apache/nlpcraft/NCFiredIntent.scala index cb09c81c..6f7c892c 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCCallbackData.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCFiredIntent.scala @@ -20,7 +20,9 @@ package org.apache.nlpcraft /** * */ -trait NCCallbackData: +trait NCFiredIntent: + type NCArguments = List[List[NCEntity]] + /** * * @return @@ -31,10 +33,10 @@ trait NCCallbackData: * * @return */ - def getCallbackArguments: List[List[NCEntity]] + def getCallbackArguments: NCArguments /** * * @return */ - def getCallback: List[List[NCEntity]] => NCResult + def getCallback: NCArguments => NCResult diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCIntentSkip.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCIntentSkip.scala index e9ffd3db..10647c0d 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCIntentSkip.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCIntentSkip.scala @@ -31,8 +31,6 @@ package org.apache.nlpcraft * @see NCIntent * @see NCIntentTerm * @see NCIntentRef - * @see NCIntentSample - * @see NCIntentSampleRef * @see NCIntentMatch * @see NCModel#onMatchedIntent(NCIntentMatch) */ class NCIntentSkip(msg: String, cause: Throwable = null) extends NCException(msg, cause) \ No newline at end of file diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.scala index 4b5553e1..24aa4c65 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.scala @@ -78,7 +78,7 @@ class NCModelClient(mdl: NCModel) extends LazyLogging, AutoCloseable: * @param typ * @return */ - private def ask0(txt: String, data: Map[String, Any], usrId: String, typ: NCIntentSolveType): Either[NCResult, NCCallbackData] = + private def ask0(txt: String, data: Map[String, Any], usrId: String, typ: NCIntentSolveType): Either[NCResult, NCFiredIntent] = val plData = plMgr.prepare(txt, data, usrId) val userId = plData.request.getUserId @@ -112,14 +112,12 @@ class NCModelClient(mdl: NCModel) extends LazyLogging, AutoCloseable: * @param usrId * @return */ - def ask(txt: String, data: Map[String, AnyRef], usrId: String): NCResult = + def ask(txt: String, usrId: String, data: Map[String, AnyRef] = Map.empty): NCResult = require(txt != null, "Input text cannot be null.") require(data != null, "Data cannot be null.") require(usrId != null, "User id cannot be null.") ask0(txt, data, usrId, NCIntentSolveType.REGULAR).swap.toOption.get - def ask(txt: String, usrId: String): NCResult = ask(txt, Map.empty, usrId) - /** * * @param usrId @@ -158,55 +156,7 @@ class NCModelClient(mdl: NCModel) extends LazyLogging, AutoCloseable: /** * */ - def validateSamples(): Unit = - case class Result(intentId: String, text: String, error: Option[String], time: Long) - - val userId = UUID.randomUUID().toString - val res = scala.collection.mutable.ArrayBuffer.empty[Result] - - def now: Long = System.currentTimeMillis() - - for (i <- intents; samples <- i.samples) - for (sample <- samples) - val start = now - - val err: Option[String] = - try - val r = ask(sample, Map.empty, userId) - - Option.when(r.getIntentId.isEmpty || r.getIntentId.get != i.intent.id)(s"Unexpected intent ID: '${r.getIntentId.getOrElse("(not set)")}'") - catch case e: Throwable => - logger.warn("Unexpected error.", e) - Option(e.getLocalizedMessage) - - res += Result(i.intent.id, sample, err, now - start) - - clearDialog(userId) - clearStm(userId) - - val tbl = NCAsciiTable() - tbl #= ("Intent ID", "+/-", "Text", "Error", "ms.") - - for (res <- res) - tbl += ( - res.intentId, - if res.error.isEmpty then "OK" else "FAIL", - res.text, - res.error.getOrElse(""), - res.time - ) - - val passCnt = res.count(_.error.isEmpty) - val failCnt = res.count(_.error.isDefined) - - tbl.info(logger, Option(s"Model auto-validation results: OK $passCnt, FAIL $failCnt:")) - - if failCnt > 0 then require(false, "Some tests failed.") - - /** - * - */ - def close(): Unit = + override def close(): Unit = plMgr.close() dlgMgr.close() convMgr.close() @@ -220,11 +170,9 @@ class NCModelClient(mdl: NCModel) extends LazyLogging, AutoCloseable: * @param saveHist * @return */ - def debugAsk(txt: String, data: Map[String, AnyRef], usrId: String, saveHist: Boolean): NCCallbackData = + def debugAsk(txt: String, usrId: String, saveHist: Boolean, data: Map[String, AnyRef] = Map.empty): NCFiredIntent = require(txt != null, "Input text cannot be null.") require(data != null, "Data cannot be null.") require(usrId != null, "User id cannot be null.") import NCIntentSolveType.* - ask0(txt, data, usrId, if saveHist then SEARCH else SEARCH_NO_HISTORY).toOption.get - - def debugAsk(txt: String, usrId: String, saveHist: Boolean): NCCallbackData = debugAsk(txt, Map.empty, usrId, saveHist) + ask0(txt, data, usrId, if saveHist then SEARCH else SEARCH_NO_HISTORY).toOption.get \ No newline at end of file diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntent.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntent.java index c98817ae..416d0cb7 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntent.java +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntent.java @@ -36,8 +36,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * * @see NCIntentRef * @see NCIntentTerm - * @see NCIntentSample - * @see NCIntentSampleRef * @see NCModelAddClasses * @see NCModelAddPackage * @see NCIntentSkip diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentRef.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentRef.java index 5f6af9c7..ed0503d3 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentRef.java +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentRef.java @@ -35,8 +35,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * * @see NCIntent * @see NCIntentTerm - * @see NCIntentSample - * @see NCIntentSampleRef * @see NCModelAddClasses * @see NCModelAddPackage * @see NCIntentSkip diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentSample.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentSample.java deleted file mode 100644 index 760e4e41..00000000 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentSample.java +++ /dev/null @@ -1,73 +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.annotations; - -import org.apache.nlpcraft.NCIntentMatch; -import org.apache.nlpcraft.NCIntentSkip; -import org.apache.nlpcraft.NCModel; - -import java.lang.annotation.Documented; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * The corpus of intent samples that is used for documentaiton and model auto-validation. - * - * @see NCIntentSampleRef - * @see NCIntent - * @see NCIntentRef - * @see NCIntentTerm - * @see NCModelAddClasses - * @see NCModelAddPackage - * @see NCIntentSkip - * @see NCIntentMatch - * @see NCModel#onMatchedIntent(NCIntentMatch) - * @see NCTestAutoModelValidator - */ -@Retention(value=RUNTIME) -@Target(value=METHOD) -@Repeatable(NCIntentSample.NCIntentSampleList.class) -public @interface NCIntentSample { - /** - * Gets a list of user input samples that should match corresponding intent. This annotation should be - * attached the intent callback method. - * - * @return Set of user input examples that should match corresponding intent. - */ - String[] value(); - - /** - * Grouping annotation required for when more than one {@link NCIntentSample} annotation is used. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(value=METHOD) - @Documented - @interface NCIntentSampleList { - /** - * Gets the list of all {@link NCIntentSample} annotations attached to the callback. - * - * @return List of all {@link NCIntentSample} annotations attached to the callback. - */ - NCIntentSample[] value(); - } -} diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentSampleRef.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentSampleRef.java deleted file mode 100644 index f326dd4e..00000000 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentSampleRef.java +++ /dev/null @@ -1,75 +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.annotations; - -import org.apache.nlpcraft.NCIntentMatch; -import org.apache.nlpcraft.NCIntentSkip; -import org.apache.nlpcraft.NCModel; - -import java.lang.annotation.Documented; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * The corpus of intent samples that is used for documentaiton and model auto-validation. - * - * @see NCIntentSample - * @see NCIntent - * @see NCIntentRef - * @see NCIntentTerm - * @see NCModelAddClasses - * @see NCModelAddPackage - * @see NCIntentSkip - * @see NCIntentMatch - * @see NCModel#onMatchedIntent(NCIntentMatch) - * @see NCTestAutoModelValidator - */ -@Retention(value=RUNTIME) -@Target(value=METHOD) -@Repeatable(NCIntentSampleRef.NCIntentSampleList.class) -public @interface NCIntentSampleRef { - /** - * Local file path, classpath resource path or URL supported by {@link java.net.URL} class. The content of the source - * should be a new-line separated list of string. Empty strings and strings starting with '#" (hash) symbol will - * be ignored. This annotation should be attached the intent callback method. Note that using this annotation is equivalent - * to using {@link NCIntentSample} annotation and listing all of its samples in place instead of an external source. - * - * @return Local file path, classpath resource path or URL supported by {@link java.net.URL} class. - */ - String value(); - - /** - * Grouping annotation required for when more than one {@link NCIntentSampleRef} annotation is used. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(value=METHOD) - @Documented - @interface NCIntentSampleList { - /** - * Gets the list of all {@link NCIntentSampleRef} annotations attached to the callback. - * - * @return List of all {@link NCIntentSampleRef} annotations attached to the callback. - */ - NCIntentSampleRef[] value(); - } -} diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentTerm.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentTerm.java index 12c34481..fc0d6b7d 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentTerm.java +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/annotations/NCIntentTerm.java @@ -33,8 +33,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * * @see NCIntent * @see NCIntentRef - * @see NCIntentSample - * @see NCIntentSampleRef * @see NCIntentSkip * @see NCIntentMatch * @see NCModel#onMatchedIntent(NCIntentMatch) diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelScanner.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelScanner.scala index 89bdf13d..5312b372 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelScanner.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelScanner.scala @@ -42,9 +42,8 @@ case class NCCallbackInput(ctx: NCContext, im: NCIntentMatch) * * @param intent * @param function - * @param samples */ -case class NCModelIntent(intent: NCIDLIntent, function: NCCallbackInput => NCResult, samples: Seq[Seq[String]]) +case class NCModelIntent(intent: NCIDLIntent, function: NCCallbackInput => NCResult) object NCModelScanner extends LazyLogging: private final val CLS_INTENT = classOf[NCIntent] @@ -52,8 +51,6 @@ object NCModelScanner extends LazyLogging: private final val CLS_QRY_RES = classOf[NCResult] private final val CLS_CTX = classOf[NCContext] private final val CLS_INTENT_MATCH = classOf[NCIntentMatch] - private final val CLS_SAMPLE = classOf[NCIntentSample] - private final val CLS_SAMPLE_REF = classOf[NCIntentSampleRef] private final val CLS_INTENT_OBJ = classOf[NCIntentObject] private final val CLS_SCALA_SEQ = classOf[Seq[_]] @@ -65,8 +62,6 @@ object NCModelScanner extends LazyLogging: private lazy val I = "@NCIntent" private lazy val IT = "@NCIntentTerm" private lazy val IR = "@NCIntentRef" - private lazy val S = "@NCIntentSample" - private lazy val SR = "@NCIntentSampleRef" private final val COMP_CLS: Set[Class[_]] = Set( CLS_SCALA_SEQ, @@ -89,13 +84,6 @@ object NCModelScanner extends LazyLogging: def apply(cfg: NCModelConfig, intent: NCIDLIntent, obj: AnyRef, mtd: Method): IntentHolder = new IntentHolder(intent, prepareCallback(cfg, mtd, obj, intent), mtd) - /** - * - * @param wct - * @return - */ - private def wc2Str(wct: WildcardType): String = if wct == null then "null" else s"'${wct.getTypeName}'" - /** * * @param iter @@ -259,50 +247,6 @@ object NCModelScanner extends LazyLogging: val cls = o.getClass (cls.getDeclaredFields ++ cls.getFields).toSet - /** - * - * @param cfg - * @param mtd - * @return - */ - private def scanSamples(cfg: NCModelConfig, mtd: Method): Map[String, Seq[Seq[String]]] = - val smpAnns = mtd.getAnnotationsByType(CLS_SAMPLE) - val smpAnnsRef = mtd.getAnnotationsByType(CLS_SAMPLE_REF) - lazy val mtdStr = method2Str(mtd) - lazy val intAnns = mtd.getAnnotationsByType(CLS_INTENT) - lazy val refAnns = mtd.getAnnotationsByType(CLS_INTENT_REF) - lazy val samples = mutable.HashMap.empty[String, Seq[Seq[String]]] - - if smpAnns.nonEmpty || smpAnnsRef.nonEmpty then - if intAnns.isEmpty && refAnns.isEmpty then - E(s"$S or $SR annotations without corresponding $I or $IR annotations: $mtdStr") - else - def read[T](annArr: scala.Array[T], annName: String, getSamples: T => Seq[String], getSource: Option[T => String]): Seq[Seq[String]] = - for (ann <- annArr.toSeq) yield - val samples = getSamples(ann).map(_.strip).filter(s => s.nonEmpty && s.head != '#') - if samples.isEmpty then - getSource match - case None => logger.warn(s"$annName annotation has no samples: $mtdStr") - case Some(f) => logger.warn(s"$annName annotation references '${f(ann)}' file that has no samples: $mtdStr") - Seq.empty - else - samples.filter(_.nonEmpty) - - val seqSeq = - read[NCIntentSample](smpAnns, S, _.value.toSeq, None) ++ - read[NCIntentSampleRef](smpAnnsRef, SR, a => NCUtils.readResource(a.value), Option(_.value)) - - if NCUtils.containsDups(seqSeq.flatMap(_.toSeq).toList) then - logger.warn(s"$S and $SR annotations have duplicates: $mtdStr") - - val distinct = seqSeq.map(_.distinct).distinct - for (ann <- intAnns; intent <- NCIDLCompiler.compile(ann.value, cfg, mtdStr)) samples += intent.id -> distinct - for (ann <- refAnns) samples += ann.value -> distinct - else if intAnns.nonEmpty || refAnns.nonEmpty then - logger.warn(s"$S or $SR annotations are missing for: $mtdStr") - - samples.toMap - /** * * @param cfg @@ -421,8 +365,6 @@ object NCModelScanner extends LazyLogging: // Gets terms IDs. val termIds = tokParamAnns.zipWithIndex.map { case (annArr, idx) => - def mkArg(): String = arg2Str(method, idx) - val termAnns = annArr.filter(_.isInstanceOf[NCIntentTerm]) // Each method arguments (second and later) must have one 'NCIntentTerm' annotation. @@ -476,7 +418,6 @@ object NCModelScanner extends LazyLogging: val intentDecls = mutable.HashMap.empty[String, NCIDLIntent] val objs = mutable.Buffer.empty[AnyRef] val processed = mutable.HashSet.empty[Class[_]] - val samples = mutable.HashMap.empty[Method, Map[String, Seq[Seq[String]]]] def addDecl(intent: NCIDLIntent): Unit = intentDecls.get(intent.id) match @@ -498,15 +439,12 @@ object NCModelScanner extends LazyLogging: // First phase scan. // For given object finds references via fields (NCIntentObject). Scans also each reference recursively and collects them. - // For all methods of processed object collects samples (NCIntentSample, NCIntentSampleRef) and intents (NCIntent) + // For all methods of processed object collects intents (NCIntent) def scan(obj: AnyRef): Unit = objs += obj processClassAnnotations(obj.getClass) val methods = getAllMethods(obj) - // Collects samples for each method. - for (mtd <- methods) samples += mtd -> scanSamples(cfg, mtd) - // // Collects intents for each method. for ( mtd <- methods; @@ -550,4 +488,4 @@ object NCModelScanner extends LazyLogging: else logger.warn(s"Model has no intent: ${cfg.getId}") - intents.map(i => NCModelIntent(i.intent, i.function, samples.getOrElse(i.method, Map.empty).getOrElse(i.intent.id, Seq.empty))).toSeq \ No newline at end of file + intents.map(i => NCModelIntent(i.intent, i.function)).toSeq \ 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 1f04f9f1..a16a94d6 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 @@ -89,7 +89,7 @@ object NCIntentSolverManager: getIntentId: String, getCallbackArguments: List[List[NCEntity]], getCallback: List[List[NCEntity]] => NCResult - ) extends NCCallbackData + ) extends NCFiredIntent /** * @@ -183,7 +183,7 @@ object NCIntentSolverManager: */ private case class IntentEntity(var used: Boolean, var conv: Boolean, entity: NCEntity) - type ResultData = Either[NCResult, NCCallbackData] + type ResultData = Either[NCResult, NCFiredIntent] /** * diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala index 706c0641..6fe529ad 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala @@ -111,7 +111,7 @@ class NCModelCallbacksSpec: set(states*) try - client.ask("x", null, "userId") + client.ask("x", "userId") require(false) catch 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 4452a1c4..471bac4b 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 @@ -52,8 +52,6 @@ class NCModelClientSpec: println(s"Intent: ${res.getIntentId}") println(s"Body: ${res.getBody}") - client.validateSamples() - val winner = client.debugAsk("Lights on at second floor kitchen", "userId", true) println(s"Winner intent: ${winner.getIntentId}") println("Entities: \n" + winner.getCallbackArguments.map(p => p.map(s).mkString(", ")).mkString("\n")) @@ -66,7 +64,6 @@ class NCModelClientSpec: def test(): Unit = test0( new NCTestModelAdapter(): - @NCIntentSample(Array("Lights on at second floor kitchen")) @NCIntent("intent=ls term(act)={# == 'ls:on'} term(loc)={# == 'ls:loc'}*") def onMatch(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("act") act: NCEntity, @NCIntentTerm("loc") locs: List[NCEntity]): NCResult = NCResult("test", NCResultType.ASK_RESULT) ) @@ -78,7 +75,6 @@ class NCModelClientSpec: test0( new NCTestModelAdapter(): @NCIntent("intent=ls term(act)={has(ent_groups, 'act')} term(loc)={# == 'ls:loc'}*") - @NCIntentSample(Array("Lights on at second floor kitchen")) def onMatch(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("act") act: NCEntity, @NCIntentTerm("loc") locs: List[NCEntity]): NCResult = NCResult("test", NCResultType.ASK_RESULT) ) diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec3.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec3.scala index 332822ed..4dbe4379 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec3.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientSpec3.scala @@ -47,10 +47,10 @@ class NCModelClientSpec3: def onMatch(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("t1") t1: NCEntity): NCResult = NCResult("Data", NCResultType.ASK_RESULT) Using.resource(new NCModelClient(mdl)) { client => - def ask(): NCCallbackData = client.debugAsk("e1", "userId", true) - def execCallback(cb: NCCallbackData): NCResult = cb.getCallback.apply(cb.getCallbackArguments) - def execCallbackOk(cb: NCCallbackData): Unit = println(s"Result: ${execCallback(cb).getBody}") - def execCallbackFail(cb: NCCallbackData): Unit = + def ask(): NCFiredIntent = client.debugAsk("e1", "userId", true) + def execCallback(cb: NCFiredIntent): NCResult = cb.getCallback.apply(cb.getCallbackArguments) + def execCallbackOk(cb: NCFiredIntent): Unit = println(s"Result: ${execCallback(cb).getBody}") + def execCallbackFail(cb: NCFiredIntent): Unit = try execCallback(cb) catch case e: NCException => println(s"Expected error: ${e.getMessage}") diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidIntentsSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidIntentsSpec.scala index 0a0c2236..8c935b94 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidIntentsSpec.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidIntentsSpec.scala @@ -62,22 +62,11 @@ class NCModelIntentsInvalidIntentsSpec: def x(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("list") list: List[NCEntity]): NCResult = null ) - /** - * Samples without intent. - */ - @Test - def testError3(): Unit = - testError( - new NCTestModelAdapter(): - @NCIntentSample(Array("sample")) - def x(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("list") list: List[NCEntity]): NCResult = null - ) - /** * Duplicated intents definitions. */ @Test - def testError4(): Unit = + def testError3(): Unit = @NCIntent("intent=validList1 term(list)~{# == 'x'}[0,10]") @NCIntent("intent=validList1 term(list)~{# == 'x'}[0,11]") class X: @@ -93,32 +82,9 @@ class NCModelIntentsInvalidIntentsSpec: * Invalid argument type. */ @Test - def testError5(): Unit = + def testError4(): Unit = testError( new NCTestModelAdapter(): @NCIntent("intent=validList1 term(list)~{# == 'x'}[0,10]") def x(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("list") e: NCEntity): NCResult = null - ) - - /** - * Duplicated samples definitions. - */ - @Test - def testWarning1(): Unit = - NCModelScanner.scan( - new NCTestModelAdapter(): - @NCIntent("intent=validList1 term(list)~{# == 'x'}[0,10]") - @NCIntentSample(Array("x", "x")) - def x(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("list") list: List[NCEntity]): NCResult = null - ) - - /** - * Missed samples. - */ - @Test - def testWarning2(): Unit = - NCModelScanner.scan( - new NCTestModelAdapter(): - @NCIntent("intent=validList1 term(list)~{# == 'x'}[0,10]") - def x(ctx: NCContext, im: NCIntentMatch, @NCIntentTerm("list") list: List[NCEntity]): NCResult = null - ) + ) \ No newline at end of file diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCTestModelScala.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCTestModelScala.scala index b2f487f4..8d297a65 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCTestModelScala.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCTestModelScala.scala @@ -26,7 +26,6 @@ import org.apache.nlpcraft.nlp.util.* object NCTestModelScala: object NCTestModelScalaObj extends NCTestModelAdapter : @NCIntent("intent=locInt term(single)~{# == 'id1'} term(list)~{# == 'id2'}[0,10] term(opt)~{# == 'id3'}?") - @NCIntentSample(Array("What are the least performing categories for the last quarter?")) def intent( ctx: NCContext, im: NCIntentMatch, @@ -36,7 +35,6 @@ object NCTestModelScala: ): NCResult = NCTestResult() @NCIntent("import('scan/idl.idl')") - @NCIntentSampleRef("scan/samples.txt") def intentImport( ctx: NCContext, im: NCIntentMatch, @@ -48,7 +46,6 @@ object NCTestModelScala: @NCIntent("import('scan/idl.idl')") class NCTestModelScalaClass extends NCTestModelAdapter : @NCIntent("intent=locInt term(single)~{# == 'id1'} term(list)~{# == 'id2'}[0,10] term(opt)~{# == 'id3'}?") - @NCIntentSample(Array("What are the least performing categories for the last quarter?")) def intent( ctx: NCContext, im: NCIntentMatch, @@ -58,7 +55,6 @@ object NCTestModelScala: ) = NCTestResult() @NCIntentRef("impIntId") - @NCIntentSampleRef("scan/samples.txt") def intentImport( ctx: NCContext, im: NCIntentMatch, @@ -73,7 +69,6 @@ object NCTestModelScala: */ def mkModel: NCModel = new NCTestModelAdapter() : @NCIntent("intent=locInt term(single)~{# == 'id1'} term(list)~{# == 'id2'}[0,10] term(opt)~{# == 'id3'}?") - @NCIntentSample(Array("What are the least performing categories for the last quarter?")) def intent( ctx: NCContext, im: NCIntentMatch, @@ -83,7 +78,6 @@ object NCTestModelScala: ): NCResult = NCTestResult() @NCIntent("import('scan/idl.idl')") - @NCIntentSampleRef("scan/samples.txt") def intentImport( ctx: NCContext, im: NCIntentMatch,