wingbot 3.53.3 → 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.
- package/package.json +1 -1
- package/src/AiMatching.js +88 -29
package/package.json
CHANGED
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 {
|
|
491
|
+
const {
|
|
492
|
+
score, handicap, matched, metl
|
|
493
|
+
} = this
|
|
481
494
|
._entityMatching(
|
|
495
|
+
textLength,
|
|
482
496
|
entities,
|
|
483
497
|
reqEntities,
|
|
484
498
|
useState
|
|
@@ -499,33 +513,25 @@ 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
|
-
|
|
508
516
|
let finalScore = (baseScore - handicap)
|
|
509
517
|
* (this.multiMatchGain ** countOfAdditionalItems);
|
|
510
518
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (matchedEntitiesTextLength && textLength) {
|
|
519
|
+
if (metl && textLength) {
|
|
514
520
|
const remainingScore = Math.max(0, Math.min(1, finalScore) - (
|
|
515
521
|
this._ai.confidence + this.redundantEntityHandicap
|
|
516
522
|
));
|
|
517
523
|
|
|
518
|
-
const remainingTextLen = (textLength -
|
|
524
|
+
const remainingTextLen = (textLength - metl);
|
|
519
525
|
const minus = (remainingTextLen / textLength) * remainingScore;
|
|
520
526
|
|
|
521
|
-
// eslint-disable-next-line
|
|
522
|
-
// console.log({ minus,
|
|
527
|
+
// eslint-disable-next-line max-len,object-curly-newline
|
|
528
|
+
// console.log({ minus, metl, textLength, remainingScore })
|
|
523
529
|
|
|
524
530
|
finalScore -= minus;
|
|
525
531
|
}
|
|
526
532
|
|
|
527
|
-
// eslint-disable-next-line
|
|
528
|
-
// console.log({ countOfAdditionalItems, multiMatch: this.multiMatchGain ** countOfAdditionalItems, handicap, finalScore, rule, baseScore, score, allOptional, entities, reqEntities, matchedEntitiesTextLength
|
|
533
|
+
// eslint-disable-next-line max-len,object-curly-newline
|
|
534
|
+
// console.log({ countOfAdditionalItems, multiMatch: this.multiMatchGain ** countOfAdditionalItems, handicap, useHandicap, finalScore, rule, baseScore, score, allOptional, entities, reqEntities, matchedEntitiesTextLength });
|
|
529
535
|
|
|
530
536
|
if (finalScore <= 0) {
|
|
531
537
|
return null;
|
|
@@ -549,7 +555,14 @@ class AiMatching {
|
|
|
549
555
|
let max = total;
|
|
550
556
|
for (const requestIntent of req.intents) {
|
|
551
557
|
const { score, entities: matchedEntities } = this
|
|
552
|
-
._intentMatchingScore(
|
|
558
|
+
._intentMatchingScore(
|
|
559
|
+
textLength,
|
|
560
|
+
wanted,
|
|
561
|
+
requestIntent,
|
|
562
|
+
entities,
|
|
563
|
+
req,
|
|
564
|
+
stateless
|
|
565
|
+
);
|
|
553
566
|
|
|
554
567
|
if (score > max) {
|
|
555
568
|
max = score;
|
|
@@ -576,6 +589,7 @@ class AiMatching {
|
|
|
576
589
|
/**
|
|
577
590
|
*
|
|
578
591
|
* @private
|
|
592
|
+
* @param {number} textLength
|
|
579
593
|
* @param {string} wantedIntent
|
|
580
594
|
* @param {Intent} requestIntent
|
|
581
595
|
* @param {EntityExpression[]} wantedEntities
|
|
@@ -583,7 +597,14 @@ class AiMatching {
|
|
|
583
597
|
* @param {boolean} stateless
|
|
584
598
|
* @returns {{score:number,entities:Entity[]}}
|
|
585
599
|
*/
|
|
586
|
-
_intentMatchingScore (
|
|
600
|
+
_intentMatchingScore (
|
|
601
|
+
textLength,
|
|
602
|
+
wantedIntent,
|
|
603
|
+
requestIntent,
|
|
604
|
+
wantedEntities,
|
|
605
|
+
req,
|
|
606
|
+
stateless = false
|
|
607
|
+
) {
|
|
587
608
|
if (wantedIntent !== requestIntent.intent) {
|
|
588
609
|
return { score: 0, entities: [] };
|
|
589
610
|
}
|
|
@@ -601,15 +622,17 @@ class AiMatching {
|
|
|
601
622
|
score: entitiesScore, handicap, matched, minScore, fromState
|
|
602
623
|
} = this
|
|
603
624
|
._entityMatching(
|
|
625
|
+
textLength,
|
|
604
626
|
wantedEntities,
|
|
605
627
|
useEntities,
|
|
606
628
|
stateless ? {} : req.state,
|
|
607
629
|
requestIntent.entities
|
|
608
630
|
? (x) => Math.atan((x - 0.76) * 40) / Math.atan((1 - 0.76) * 40)
|
|
609
|
-
: (x) => x
|
|
631
|
+
: (x) => x,
|
|
632
|
+
req.entities
|
|
610
633
|
);
|
|
611
634
|
|
|
612
|
-
// eslint-disable-next-line
|
|
635
|
+
// eslint-disable-next-line max-len,object-curly-newline
|
|
613
636
|
// console.log({ wantedEntities, entitiesScore, handicap, matched, minScore, requestIntent });
|
|
614
637
|
|
|
615
638
|
const allOptional = wantedEntities.every((e) => e.optional
|
|
@@ -624,7 +647,7 @@ class AiMatching {
|
|
|
624
647
|
|
|
625
648
|
const score = Math.round((scoreWithHandicap * multiMatchGain) * 10000) / 10000;
|
|
626
649
|
|
|
627
|
-
// eslint-disable-next-line
|
|
650
|
+
// eslint-disable-next-line max-len,object-curly-newline
|
|
628
651
|
// console.log({ IMS: score, normalizedScore, scoreWithHandicap, multiMatchGain, wantedEntities });
|
|
629
652
|
|
|
630
653
|
return {
|
|
@@ -636,13 +659,23 @@ class AiMatching {
|
|
|
636
659
|
/**
|
|
637
660
|
*
|
|
638
661
|
* @private
|
|
662
|
+
* @param {number} textLen
|
|
639
663
|
* @param {EntityExpression[]} wantedEntities
|
|
640
664
|
* @param {Entity[]} requestEntities
|
|
641
665
|
* @param {object} [requestState]
|
|
642
666
|
* @param {Function} [scoreFn]
|
|
643
|
-
* @
|
|
667
|
+
* @param {Entity[]} allEntities
|
|
668
|
+
*
|
|
669
|
+
* @returns {EntityMatchingResult}
|
|
644
670
|
*/
|
|
645
|
-
_entityMatching (
|
|
671
|
+
_entityMatching (
|
|
672
|
+
textLen,
|
|
673
|
+
wantedEntities,
|
|
674
|
+
requestEntities = [],
|
|
675
|
+
requestState = {},
|
|
676
|
+
scoreFn = (x) => x,
|
|
677
|
+
allEntities = requestEntities
|
|
678
|
+
) {
|
|
646
679
|
const occurences = new Map();
|
|
647
680
|
|
|
648
681
|
const matched = [];
|
|
@@ -650,6 +683,7 @@ class AiMatching {
|
|
|
650
683
|
let sum = 0;
|
|
651
684
|
let minScore = 1;
|
|
652
685
|
let fromState = 0;
|
|
686
|
+
let metl = 0;
|
|
653
687
|
|
|
654
688
|
for (const wanted of wantedEntities) {
|
|
655
689
|
const usedIndexes = occurences.has(wanted.entity)
|
|
@@ -702,7 +736,7 @@ class AiMatching {
|
|
|
702
736
|
|
|
703
737
|
if (!matching && (!wanted.optional || entityExists)) {
|
|
704
738
|
return {
|
|
705
|
-
score: 0, handicap: 0, matched: [], minScore, fromState
|
|
739
|
+
score: 0, handicap: 0, matched: [], minScore, fromState, metl
|
|
706
740
|
};
|
|
707
741
|
}
|
|
708
742
|
|
|
@@ -728,6 +762,10 @@ class AiMatching {
|
|
|
728
762
|
}
|
|
729
763
|
|
|
730
764
|
if (requestEntity) {
|
|
765
|
+
if (typeof requestEntity.end === 'number' && typeof requestEntity.start === 'number') {
|
|
766
|
+
metl += requestEntity.end - requestEntity.start;
|
|
767
|
+
}
|
|
768
|
+
|
|
731
769
|
matched.push(requestEntity);
|
|
732
770
|
sum += scoreFn(requestEntity.score);
|
|
733
771
|
if (index !== -1) {
|
|
@@ -744,16 +782,37 @@ class AiMatching {
|
|
|
744
782
|
}
|
|
745
783
|
}
|
|
746
784
|
|
|
747
|
-
|
|
748
|
-
|
|
785
|
+
const withCoveringEntity = textLen && textLen <= metl;
|
|
786
|
+
|
|
787
|
+
// eslint-disable-next-line max-len
|
|
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;
|
|
749
804
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
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
|
+
}
|
|
753
812
|
const score = matched.length === 0 ? 0 : sum / matched.length;
|
|
754
813
|
|
|
755
814
|
return {
|
|
756
|
-
score, handicap, matched, minScore, fromState
|
|
815
|
+
score, handicap, matched, minScore, fromState, metl
|
|
757
816
|
};
|
|
758
817
|
}
|
|
759
818
|
|