This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/master by this push: new dd8f232 FR examples added (initial version) dd8f232 is described below commit dd8f232d2f226ec73f159d72df5b62169e24dd9b Author: Sergey Kamov <skhdlem...@gmail.com> AuthorDate: Tue Mar 15 00:52:36 2022 +0300 FR examples added (initial version) --- nlpcraft-examples/lightswitch-fr/README.md | 50 ++++++++++++++ nlpcraft-examples/lightswitch-fr/pom.xml | 80 ++++++++++++++++++++++ .../examples/lightswitch/LightSwitchFrModel.scala} | 52 +++++++------- .../entity/parser/NCFrSemanticEntityParser.scala | 35 ++++++++++ .../enricher/NCFrLemmaPosTokenEnricher.scala} | 7 +- .../enricher/NCFrStopWordsTokenEnricher.scala | 48 +++++++++++++ .../nlp/token/parser/NCFrTokenParser.scala} | 26 +++---- .../src/main/resources/lightswitch_model_fr.yaml | 45 ++++++++++++ .../lightswitch/NCModelValidationSpec.scala | 30 ++++++++ .../examples/lightswitch/LightSwitchRuModel.scala | 10 +-- .../token/enricher/NCRuLemmaPosTokenEnricher.scala | 1 - .../nlp/token/parser/NCRuTokenParser.scala | 27 ++++---- .../nlpcraft/internal/impl/NCModelClientImpl.scala | 2 - pom.xml | 1 + 14 files changed, 351 insertions(+), 63 deletions(-) diff --git a/nlpcraft-examples/lightswitch-fr/README.md b/nlpcraft-examples/lightswitch-fr/README.md new file mode 100644 index 0000000..f073eff --- /dev/null +++ b/nlpcraft-examples/lightswitch-fr/README.md @@ -0,0 +1,50 @@ +<!-- + 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. +--> + +<img alt="" src="https://nlpcraft.apache.org/images/nlpcraft_logo_black.gif" height="80px"> +<br> + +[](https://raw.githubusercontent.com/apache/opennlp/master/LICENSE) +[](https://github.com/apache/incubator-nlpcraft/actions) +[](https://nlpcraft.apache.org/docs.html) +[](https://gitter.im/apache-nlpcraft/community) + +### Light Switch Example +This example provides very simple implementation for NLI-powered light switch. You can say something like `turn the lights off in +the entire house` or `switch on the illumination in the master bedroom closet`. +You can easily modify intent callbacks to perform the actual light switching using HomeKit or Arduino-based +controllers. + +### Documentation +See [Light Switch](https://nlpcraft.apache.org/examples/light_switch.html) guide for more instructions on how to run this example. + +For any questions, feedback or suggestions: + + * View & run other [examples](https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples) + * Read [documentation](https://nlpcraft.apache.org/docs.html), latest [Javadoc](https://nlpcraft.apache.org/apis/latest/index.html) and [REST APIs](https://nlpcraft.apache.org/using-rest.html) + * Download & Maven/Grape/Gradle/SBT [instructions](https://nlpcraft.apache.org/download.html) + * File a bug or improvement in [JIRA](https://issues.apache.org/jira/projects/NLPCRAFT) + * Post a question at [Stack Overflow](https://stackoverflow.com/questions/ask) using <code>nlpcraft</code> tag + * Access [GitHub](https://github.com/apache/incubator-nlpcraft) mirror repository. + * Join project developers on [d...@nlpcraft.apache.org](mailto:dev-subscr...@nlpcraft.apache.org) + +### Copyright +Copyright (C) 2021 Apache Software Foundation + +<img src="https://www.apache.org/img/ASF20thAnniversary.jpg" height="64px" alt="ASF Logo"> + + diff --git a/nlpcraft-examples/lightswitch-fr/pom.xml b/nlpcraft-examples/lightswitch-fr/pom.xml new file mode 100644 index 0000000..d596ea2 --- /dev/null +++ b/nlpcraft-examples/lightswitch-fr/pom.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <name>NLPCraft Example Light Switch FR</name> + <artifactId>nlpcraft-example-lightswitch-fr</artifactId> + + <parent> + <artifactId>nlpcraft-parent</artifactId> + <groupId>org.apache.nlpcraft</groupId> + <version>1.0.0</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>nlpcraft</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-analyzers-common</artifactId> + <version>8.11.1</version> + </dependency> + + <dependency> + <groupId>org.languagetool</groupId> + <artifactId>language-fr</artifactId> + <version>5.6</version> + </dependency> + + <dependency> + <groupId>org.languagetool</groupId> + <artifactId>languagetool-core</artifactId> + <version>5.6</version> + </dependency> + + <!-- Test dependencies. --> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven.compiler.plugin.ver}</version> + <configuration> + <source>${java.ver}</source> + <target>${java.ver}</target> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala similarity index 62% copy from nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala copy to nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala index 5350aee..fb7734f 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala +++ b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchFrModel.scala @@ -17,10 +17,11 @@ package org.apache.nlpcraft.examples.lightswitch +import com.google.gson.Gson import org.apache.nlpcraft.* -import org.apache.nlpcraft.examples.lightswitch.nlp.entity.parser.NCRuSemanticEntityParser -import org.apache.nlpcraft.examples.lightswitch.nlp.token.enricher.{NCRuLemmaPosTokenEnricher, NCRuStopWordsTokenEnricher} -import org.apache.nlpcraft.examples.lightswitch.nlp.token.parser.NCRuTokenParser +import org.apache.nlpcraft.examples.lightswitch.nlp.entity.parser.NCFrSemanticEntityParser +import org.apache.nlpcraft.examples.lightswitch.nlp.token.enricher.{NCFrLemmaPosTokenEnricher, NCFrStopWordsTokenEnricher} +import org.apache.nlpcraft.examples.lightswitch.nlp.token.parser.NCFrTokenParser import org.apache.nlpcraft.nlp.entity.parser.{NCNLPEntityParser, NCSemanticEntityParser} import org.apache.nlpcraft.nlp.token.enricher.NCENStopWordsTokenEnricher import org.apache.nlpcraft.nlp.token.parser.NCOpenNLPTokenParser @@ -40,13 +41,13 @@ import scala.jdk.CollectionConverters.* * <p> * See 'README.md' file in the same folder for running and testing instructions. */ -class LightSwitchRuModel extends NCModelAdapter( - new NCModelConfig("nlpcraft.lightswitch.ru.ex", "LightSwitch Example Model RU", "1.0"), +class LightSwitchFrModel extends NCModelAdapter( + new NCModelConfig("nlpcraft.lightswitch.fr.ex", "LightSwitch Example Model FR", "1.0"), new NCModelPipelineBuilder(). - withTokenParser(new NCRuTokenParser()). - withTokenEnricher(new NCRuLemmaPosTokenEnricher()). - withTokenEnricher(new NCRuStopWordsTokenEnricher()). - withEntityParser(new NCRuSemanticEntityParser("lightswitch_model_ru.yaml")). + withTokenParser(new NCFrTokenParser()). + withTokenEnricher(new NCFrLemmaPosTokenEnricher()). + withTokenEnricher(new NCFrStopWordsTokenEnricher()). + withEntityParser(new NCFrSemanticEntityParser("lightswitch_model_fr.yaml")). build() ): /** @@ -58,31 +59,32 @@ class LightSwitchRuModel extends NCModelAdapter( */ @NCIntent("intent=ls term(act)={has(ent_groups, 'act')} term(loc)={# == 'ls:loc'}*") @NCIntentSample(Array( - "Выключи свет по всем доме", - "Выруби электричество!", - "Включи свет в детской", - "Включай повсюду освещение", - "Включайте лампы в детской комнате", - "Свет на кухне, пожалуйста, приглуши", - "Нельзя ли повсюду выключить свет?", - "Пожалуйста без света", - "Отключи электричество в ванной", - "Выключи, пожалуйста, тут всюду свет", - "Выключай все!", - "Свет пожалуйста везде включи", - "Зажги лампу на кухне" + "Éteins l“allumier dans toute la maison", + "Coupez l'électricité!", + "Allume la lumière dans la chambre des enfants", + "Allume l'éclairage partout", + "Allumer les lampes dans la chambre des enfants", + "Éteins la lumière dans la cuisine, s'il te plaît", + "Est-il possible d'éteindre les lumières partout?", + "S'il vous plaît sans lumière", + "Couper l'électricité dans la salle de bain", + "Éteins la lumière, s'il te plaît.", + "Éteignez tout!", + "Allume la lumière partout s'il te plaît ", + "Allume la lampe dans la cuisine" )) def onMatch( @NCIntentTerm("act") actEnt: NCEntity, @NCIntentTerm("loc") locEnts: List[NCEntity] ): NCResult = - val status = if actEnt.getId == "ls:on" then "on" else "off" - val locations = if locEnts.isEmpty then "entire house" else locEnts.map(_.mkText()).mkString(", ") + val action = if actEnt.getId == "ls:on" then "allumer" else "éteindre" + val locations = if locEnts.isEmpty then "toute la maison" else locEnts.map(_.mkText()).mkString(", ") // Add HomeKit, Arduino or other integration here. // By default - just return a descriptive action string. + new NCResult( - s"Lights are [$status] in [${locations.toLowerCase}].", + new Gson().toJson(Map("locations" -> locations, "action" -> action).asJava), NCResultType.ASK_RESULT ) \ No newline at end of file diff --git a/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/entity/parser/NCFrSemanticEntityParser.scala b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/entity/parser/NCFrSemanticEntityParser.scala new file mode 100644 index 0000000..6a70a75 --- /dev/null +++ b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/entity/parser/NCFrSemanticEntityParser.scala @@ -0,0 +1,35 @@ +/* + * 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.lightswitch.nlp.entity.parser + +import opennlp.tools.stemmer.snowball.SnowballStemmer +import org.apache.nlpcraft.examples.lightswitch.nlp.token.parser.NCFrTokenParser +import org.apache.nlpcraft.nlp.entity.parser.* + +/** + * + * @param src + */ +class NCFrSemanticEntityParser(src: String) extends NCSemanticEntityParser( + new NCSemanticStemmer: + private val stemmer = new SnowballStemmer(SnowballStemmer.ALGORITHM.FRENCH) + override def stem(txt: String): String = stemmer.synchronized { stemmer.stem(txt.toLowerCase).toString } + , + new NCFrTokenParser(), + src +) diff --git a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCFrLemmaPosTokenEnricher.scala similarity index 88% copy from nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala copy to nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCFrLemmaPosTokenEnricher.scala index 1e6d15c..92db11f 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala +++ b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCFrLemmaPosTokenEnricher.scala @@ -17,10 +17,9 @@ package org.apache.nlpcraft.examples.lightswitch.nlp.token.enricher -import org.apache.lucene.analysis.ru.RussianAnalyzer import org.apache.nlpcraft.* import org.languagetool.AnalyzedToken -import org.languagetool.tagging.ru.RussianTagger +import org.languagetool.tagging.fr.FrenchTagger import java.util import java.util.stream.Collectors @@ -29,12 +28,12 @@ import scala.jdk.CollectionConverters.* /** * */ -class NCRuLemmaPosTokenEnricher extends NCTokenEnricher: +class NCFrLemmaPosTokenEnricher extends NCTokenEnricher: private def nvl(v: String, dflt : => String): String = if v != null then v else dflt override def enrich(req: NCRequest, cfg: NCModelConfig, toksList: util.List[NCToken]): Unit = val toks = toksList.asScala - val tags = RussianTagger.INSTANCE.tag(toks.map(_.getText).asJava).asScala + val tags = FrenchTagger.INSTANCE.tag(toks.map(_.getText).asJava).asScala require(toks.size == tags.size) diff --git a/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCFrStopWordsTokenEnricher.scala b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCFrStopWordsTokenEnricher.scala new file mode 100644 index 0000000..335d00f --- /dev/null +++ b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCFrStopWordsTokenEnricher.scala @@ -0,0 +1,48 @@ +/* + * 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.lightswitch.nlp.token.enricher + +import org.apache.lucene.analysis.fr.FrenchAnalyzer +import org.apache.nlpcraft.* + +import java.util +import scala.jdk.CollectionConverters.* + +/** + * + */ +class NCFrStopWordsTokenEnricher extends NCTokenEnricher: + private final val stops = FrenchAnalyzer.getDefaultStopSet + + private def getPos(t: NCToken): String = t.getOpt("pos").orElseThrow(() => throw new NCException("POS not found in token.")) + private def getLemma(t: NCToken): String = t.getOpt("lemma").orElseThrow(() => throw new NCException("Lemma not found in token.")) + + override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = + for (t <- toks.asScala) + val lemma = getLemma(t) + lazy val pos = getPos(t) + + t.put( + "stopword", + lemma.length == 1 && !Character.isLetter(lemma.head) && !Character.isDigit(lemma.head) || + stops.contains(lemma.toLowerCase) || + pos.startsWith("I") || + pos.startsWith("O") || + pos.startsWith("P") || + pos.startsWith("D") + ) \ No newline at end of file diff --git a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCFrTokenParser.scala similarity index 66% copy from nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala copy to nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCFrTokenParser.scala index 8dda52d..45eac3b 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala +++ b/nlpcraft-examples/lightswitch-fr/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCFrTokenParser.scala @@ -17,13 +17,9 @@ package org.apache.nlpcraft.examples.lightswitch.nlp.token.parser -import org.apache.lucene.analysis.ru.RussianAnalyzer import org.apache.nlpcraft.* -import org.languagetool.AnalyzedToken -import org.languagetool.language.Russian -import org.languagetool.rules.ngrams.* -import org.languagetool.tagging.ru.* import org.languagetool.tokenizers.WordTokenizer +import org.languagetool.tokenizers.fr.FrenchWordTokenizer import java.util import scala.jdk.CollectionConverters.* @@ -31,20 +27,24 @@ import scala.jdk.CollectionConverters.* /** * */ -class NCRuTokenParser extends NCTokenParser: - private val tokenizer = new WordTokenizer +class NCFrTokenParser extends NCTokenParser: + private val tokenizer = new FrenchWordTokenizer override def tokenize(text: String): util.List[NCToken] = val toks = collection.mutable.ArrayBuffer.empty[NCToken] var sumLen = 0 for (((word, len), idx) <- tokenizer.tokenize(text).asScala.map(p => p -> p.length).zipWithIndex) - if word.strip.nonEmpty then toks += new NCPropertyMapAdapter with NCToken: - override def getText: String = word - override def getIndex: Int = idx - override def getStartCharIndex: Int = sumLen - override def getEndCharIndex: Int = sumLen + word.length + val start = sumLen + val end = sumLen + word.length - sumLen += word.length + if word.strip.nonEmpty then + toks += new NCPropertyMapAdapter with NCToken: + override def getText: String = word + override def getIndex: Int = idx + override def getStartCharIndex: Int = start + override def getEndCharIndex: Int = end + + sumLen = end toks.asJava diff --git a/nlpcraft-examples/lightswitch-fr/src/main/resources/lightswitch_model_fr.yaml b/nlpcraft-examples/lightswitch-fr/src/main/resources/lightswitch_model_fr.yaml new file mode 100644 index 0000000..fc7bae9 --- /dev/null +++ b/nlpcraft-examples/lightswitch-fr/src/main/resources/lightswitch_model_fr.yaml @@ -0,0 +1,45 @@ +# +# 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. +# + +macros: + "<TURN_ON>" : "{allumer|déclencher|lancer|illuminer}" + "<TURN_OFF>" : "{éteindre|couper|désactiver|déconnecter|éliminer|baisser}" + "<ENTIRE_OPT>" : "{tout|partout|autour|totalement|_}" + "<LIGHT_OPT>" : "{ce|lampe|bras|lustre|luminaire|ampoule|éclairage|lumière|électricité|électricien|_}" + +elements: + - id: "ls:loc" + description: "Location of lights." + synonyms: + - "<ENTIRE_OPT> {bâtiment|salle|maison|cuisine|chambre des enfants|bureau|salon|chambre à coucher|salle de bain|toilette|grande salle à manger|salle de bain|chambre des enfants}" + + - id: "ls:on" + groups: + - "act" + description: "Light switch ON action." + synonyms: + - "<LIGHT_OPT> <ENTIRE_OPT> <TURN_ON>" + - "<TURN_ON> <ENTIRE_OPT> <LIGHT_OPT>" + + - id: "ls:off" + groups: + - "act" + description: "Light switch OFF action." + synonyms: + - "<LIGHT_OPT> <ENTIRE_OPT> <TURN_OFF>" + - "<TURN_OFF> <ENTIRE_OPT> <LIGHT_OPT>" + - "sans <ENTIRE_OPT> <LIGHT_OPT>" diff --git a/nlpcraft-examples/lightswitch-fr/src/test/java/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala b/nlpcraft-examples/lightswitch-fr/src/test/java/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala new file mode 100644 index 0000000..2871ec5 --- /dev/null +++ b/nlpcraft-examples/lightswitch-fr/src/test/java/org/apache/nlpcraft/examples/lightswitch/NCModelValidationSpec.scala @@ -0,0 +1,30 @@ +/* + * 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.lightswitch + +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 LightSwitchFrModel)) { _.validateSamples() } diff --git a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala index 5350aee..cd99c2c 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala +++ b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala @@ -17,6 +17,7 @@ package org.apache.nlpcraft.examples.lightswitch +import com.google.gson.Gson import org.apache.nlpcraft.* import org.apache.nlpcraft.examples.lightswitch.nlp.entity.parser.NCRuSemanticEntityParser import org.apache.nlpcraft.examples.lightswitch.nlp.token.enricher.{NCRuLemmaPosTokenEnricher, NCRuStopWordsTokenEnricher} @@ -76,13 +77,14 @@ class LightSwitchRuModel extends NCModelAdapter( @NCIntentTerm("act") actEnt: NCEntity, @NCIntentTerm("loc") locEnts: List[NCEntity] ): NCResult = - val status = if actEnt.getId == "ls:on" then "on" else "off" - val locations = if locEnts.isEmpty then "entire house" else locEnts.map(_.mkText()).mkString(", ") + val action = if actEnt.getId == "ls:on" then "включить" else "выключить" + val locations = if locEnts.isEmpty then "весь дом" else locEnts.map(_.mkText()).mkString(", ") // Add HomeKit, Arduino or other integration here. // By default - just return a descriptive action string. + new NCResult( - s"Lights are [$status] in [${locations.toLowerCase}].", - NCResultType.ASK_RESULT + new Gson().toJson(Map("locations" -> locations, "action" -> action).asJava), + NCResultType.ASK_RESULT ) \ No newline at end of file diff --git a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala index 1e6d15c..2a9bfd3 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala +++ b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/enricher/NCRuLemmaPosTokenEnricher.scala @@ -17,7 +17,6 @@ package org.apache.nlpcraft.examples.lightswitch.nlp.token.enricher -import org.apache.lucene.analysis.ru.RussianAnalyzer import org.apache.nlpcraft.* import org.languagetool.AnalyzedToken import org.languagetool.tagging.ru.RussianTagger diff --git a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala index 8dda52d..bf0440e 100644 --- a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala +++ b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/nlp/token/parser/NCRuTokenParser.scala @@ -17,12 +17,7 @@ package org.apache.nlpcraft.examples.lightswitch.nlp.token.parser -import org.apache.lucene.analysis.ru.RussianAnalyzer import org.apache.nlpcraft.* -import org.languagetool.AnalyzedToken -import org.languagetool.language.Russian -import org.languagetool.rules.ngrams.* -import org.languagetool.tagging.ru.* import org.languagetool.tokenizers.WordTokenizer import java.util @@ -39,12 +34,16 @@ class NCRuTokenParser extends NCTokenParser: var sumLen = 0 for (((word, len), idx) <- tokenizer.tokenize(text).asScala.map(p => p -> p.length).zipWithIndex) - if word.strip.nonEmpty then toks += new NCPropertyMapAdapter with NCToken: - override def getText: String = word - override def getIndex: Int = idx - override def getStartCharIndex: Int = sumLen - override def getEndCharIndex: Int = sumLen + word.length - - sumLen += word.length - - toks.asJava + val start = sumLen + val end = sumLen + word.length + + if word.strip.nonEmpty then + toks += new NCPropertyMapAdapter with NCToken: + override def getText: String = word + override def getIndex: Int = idx + override def getStartCharIndex: Int = start + override def getEndCharIndex: Int = end + + sumLen = end + + toks.asJava \ No newline at end of file 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 e23b21f..87b8983 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 @@ -54,8 +54,6 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging: /** * - * @param cfg - * @param pipeline */ private def verify(): Unit = Objects.requireNonNull(mdl, "Model cannot be null.") diff --git a/pom.xml b/pom.xml index 3362ba3..c64e1d0 100644 --- a/pom.xml +++ b/pom.xml @@ -392,6 +392,7 @@ <module>nlpcraft-examples/echo</module> <module>nlpcraft-examples/lightswitch</module> <module>nlpcraft-examples/lightswitch-ru</module> + <module>nlpcraft-examples/lightswitch-fr</module> </modules> </profile> </profiles>