wingbot 3.53.4 → 3.53.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/AiMatching.js +83 -27
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot",
3
- "version": "3.53.4",
3
+ "version": "3.53.5",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/AiMatching.js CHANGED
@@ -23,6 +23,16 @@ const FULL_EMOJI_REGEX = /^#((?:[\u2600-\u27bf].?|(?:\ud83c[\udde6-\uddff]){2}|[
23
23
  const HAS_CLOSING_HASH = /^#(.+)#$/;
24
24
  const ENTITY_REGEX = /^@([^=><!?]+)(\?)?([!=><]{1,2})?([^=><!]+)?$/i;
25
25
 
26
+ /**
27
+ * @typedef {object} EntityMatchingResult
28
+ * @prop {number} score
29
+ * @prop {number} handicap
30
+ * @prop {number} fromState
31
+ * @prop {number} minScore
32
+ * @prop {number} metl
33
+ * @prop {Entity[]} matched
34
+ */
35
+
26
36
  /**
27
37
  * RegExp to test a string for a ISO 8601 Date spec
28
38
  * YYYY
@@ -449,6 +459,7 @@ class AiMatching {
449
459
 
450
460
  const noIntentHandicap = req.intents.length === 0 ? 0 : this.redundantIntentHandicap;
451
461
  const regexpScore = this._matchRegexp(req, regexps, noIntentHandicap);
462
+ const textLength = req.text().trim().length;
452
463
 
453
464
  if (regexpScore !== 0 || (intents.length === 0 && regexps.length === 0)) {
454
465
 
@@ -477,8 +488,11 @@ class AiMatching {
477
488
  useState = stateData(req);
478
489
  }
479
490
 
480
- const { score, handicap, matched } = this
491
+ const {
492
+ score, handicap, matched, metl
493
+ } = this
481
494
  ._entityMatching(
495
+ textLength,
482
496
  entities,
483
497
  reqEntities,
484
498
  useState
@@ -499,30 +513,19 @@ class AiMatching {
499
513
  ? score - noIntentHandicap
500
514
  : (regexpScore + score) / 2;
501
515
 
502
- const matchedEntitiesTextLength = matched.reduce((tot, entity) => (
503
- typeof entity.end === 'number' && typeof entity.start === 'number' && tot !== null
504
- ? (tot + (entity.end - entity.start))
505
- : null
506
- ), 0);
507
- const textLength = req.text().trim().length;
508
-
509
- const useHandicap = textLength <= matchedEntitiesTextLength
510
- ? Math.max(-this.redundantEntityHandicap, baseScore - 1)
511
- : handicap;
512
-
513
- let finalScore = (baseScore - useHandicap)
516
+ let finalScore = (baseScore - handicap)
514
517
  * (this.multiMatchGain ** countOfAdditionalItems);
515
518
 
516
- if (matchedEntitiesTextLength && textLength) {
519
+ if (metl && textLength) {
517
520
  const remainingScore = Math.max(0, Math.min(1, finalScore) - (
518
521
  this._ai.confidence + this.redundantEntityHandicap
519
522
  ));
520
523
 
521
- const remainingTextLen = (textLength - matchedEntitiesTextLength);
524
+ const remainingTextLen = (textLength - metl);
522
525
  const minus = (remainingTextLen / textLength) * remainingScore;
523
526
 
524
527
  // eslint-disable-next-line max-len,object-curly-newline
525
- // console.log({ minus, matchedEntitiesTextLength, textLength, remainingScore })
528
+ // console.log({ minus, metl, textLength, remainingScore })
526
529
 
527
530
  finalScore -= minus;
528
531
  }
@@ -552,7 +555,14 @@ class AiMatching {
552
555
  let max = total;
553
556
  for (const requestIntent of req.intents) {
554
557
  const { score, entities: matchedEntities } = this
555
- ._intentMatchingScore(wanted, requestIntent, entities, req, stateless);
558
+ ._intentMatchingScore(
559
+ textLength,
560
+ wanted,
561
+ requestIntent,
562
+ entities,
563
+ req,
564
+ stateless
565
+ );
556
566
 
557
567
  if (score > max) {
558
568
  max = score;
@@ -579,6 +589,7 @@ class AiMatching {
579
589
  /**
580
590
  *
581
591
  * @private
592
+ * @param {number} textLength
582
593
  * @param {string} wantedIntent
583
594
  * @param {Intent} requestIntent
584
595
  * @param {EntityExpression[]} wantedEntities
@@ -586,7 +597,14 @@ class AiMatching {
586
597
  * @param {boolean} stateless
587
598
  * @returns {{score:number,entities:Entity[]}}
588
599
  */
589
- _intentMatchingScore (wantedIntent, requestIntent, wantedEntities, req, stateless = false) {
600
+ _intentMatchingScore (
601
+ textLength,
602
+ wantedIntent,
603
+ requestIntent,
604
+ wantedEntities,
605
+ req,
606
+ stateless = false
607
+ ) {
590
608
  if (wantedIntent !== requestIntent.intent) {
591
609
  return { score: 0, entities: [] };
592
610
  }
@@ -604,12 +622,14 @@ class AiMatching {
604
622
  score: entitiesScore, handicap, matched, minScore, fromState
605
623
  } = this
606
624
  ._entityMatching(
625
+ textLength,
607
626
  wantedEntities,
608
627
  useEntities,
609
628
  stateless ? {} : req.state,
610
629
  requestIntent.entities
611
630
  ? (x) => Math.atan((x - 0.76) * 40) / Math.atan((1 - 0.76) * 40)
612
- : (x) => x
631
+ : (x) => x,
632
+ req.entities
613
633
  );
614
634
 
615
635
  // eslint-disable-next-line max-len,object-curly-newline
@@ -639,13 +659,23 @@ class AiMatching {
639
659
  /**
640
660
  *
641
661
  * @private
662
+ * @param {number} textLen
642
663
  * @param {EntityExpression[]} wantedEntities
643
664
  * @param {Entity[]} requestEntities
644
665
  * @param {object} [requestState]
645
666
  * @param {Function} [scoreFn]
646
- * @returns {{score:number,handicap:number, matched:Entity[],minScore:number,fromState:number}}
667
+ * @param {Entity[]} allEntities
668
+ *
669
+ * @returns {EntityMatchingResult}
647
670
  */
648
- _entityMatching (wantedEntities, requestEntities = [], requestState = {}, scoreFn = (x) => x) {
671
+ _entityMatching (
672
+ textLen,
673
+ wantedEntities,
674
+ requestEntities = [],
675
+ requestState = {},
676
+ scoreFn = (x) => x,
677
+ allEntities = requestEntities
678
+ ) {
649
679
  const occurences = new Map();
650
680
 
651
681
  const matched = [];
@@ -653,6 +683,7 @@ class AiMatching {
653
683
  let sum = 0;
654
684
  let minScore = 1;
655
685
  let fromState = 0;
686
+ let metl = 0;
656
687
 
657
688
  for (const wanted of wantedEntities) {
658
689
  const usedIndexes = occurences.has(wanted.entity)
@@ -705,7 +736,7 @@ class AiMatching {
705
736
 
706
737
  if (!matching && (!wanted.optional || entityExists)) {
707
738
  return {
708
- score: 0, handicap: 0, matched: [], minScore, fromState
739
+ score: 0, handicap: 0, matched: [], minScore, fromState, metl
709
740
  };
710
741
  }
711
742
 
@@ -731,6 +762,10 @@ class AiMatching {
731
762
  }
732
763
 
733
764
  if (requestEntity) {
765
+ if (typeof requestEntity.end === 'number' && typeof requestEntity.start === 'number') {
766
+ metl += requestEntity.end - requestEntity.start;
767
+ }
768
+
734
769
  matched.push(requestEntity);
735
770
  sum += scoreFn(requestEntity.score);
736
771
  if (index !== -1) {
@@ -747,16 +782,37 @@ class AiMatching {
747
782
  }
748
783
  }
749
784
 
785
+ const withCoveringEntity = textLen && textLen <= metl;
786
+
750
787
  // eslint-disable-next-line max-len
751
- // console.log({ wantedEntities, sum, handicap, rl: requestEntities.length, ml: matched.length });
788
+ // console.log({ metl, withCoveringEntity, wantedEntities, sum, handicap, rl: requestEntities.length, ml: matched.length });
789
+
790
+ if (withCoveringEntity) {
791
+ handicap -= this.redundantEntityHandicap;
792
+ } else {
793
+ const otherEntitiesTextLen = allEntities
794
+ .filter((re) => !matched.some((e) => e.entity === re.entity))
795
+ .reduce((tot, entity) => (
796
+ typeof entity.end === 'number' && typeof entity.start === 'number'
797
+ ? (tot + (entity.end - entity.start))
798
+ : 0
799
+ ), 0);
800
+
801
+ const coveringHandicap = textLen && otherEntitiesTextLen >= textLen
802
+ ? 1
803
+ : 0;
752
804
 
753
- // @todo - neni mozne, by doslo k negativnimu handicapu
754
- handicap += (requestEntities.length + fromState - matched.length)
755
- * this.redundantEntityHandicap;
805
+ handicap += (requestEntities.length + fromState - matched.length + coveringHandicap)
806
+ * this.redundantEntityHandicap;
807
+
808
+ // eslint-disable-next-line max-len
809
+ // console.log({ requestEntities, matched, handicap, coveringHandicap, otherEntitiesTextLen });
810
+
811
+ }
756
812
  const score = matched.length === 0 ? 0 : sum / matched.length;
757
813
 
758
814
  return {
759
- score, handicap, matched, minScore, fromState
815
+ score, handicap, matched, minScore, fromState, metl
760
816
  };
761
817
  }
762
818