@atlaskit/editor-plugin-autocomplete 9.1.0 → 9.2.1
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/CHANGELOG.md +115 -0
- package/dist/cjs/analytics/ufo.js +6 -5
- package/dist/cjs/pm-plugins/autocomplete-plugin.js +496 -50
- package/dist/cjs/pm-plugins/debug-mode.js +14 -3
- package/dist/cjs/pm-plugins/inline-code-harvester.js +576 -0
- package/dist/cjs/pm-plugins/text-predictor.js +298 -151
- package/dist/es2019/analytics/ufo.js +2 -1
- package/dist/es2019/pm-plugins/autocomplete-plugin.js +457 -36
- package/dist/es2019/pm-plugins/debug-mode.js +13 -2
- package/dist/es2019/pm-plugins/inline-code-harvester.js +455 -0
- package/dist/es2019/pm-plugins/text-predictor.js +136 -4
- package/dist/esm/analytics/ufo.js +2 -1
- package/dist/esm/pm-plugins/autocomplete-plugin.js +494 -50
- package/dist/esm/pm-plugins/debug-mode.js +13 -2
- package/dist/esm/pm-plugins/inline-code-harvester.js +572 -0
- package/dist/esm/pm-plugins/text-predictor.js +297 -150
- package/dist/types/analytics/ufo.d.ts +1 -1
- package/dist/types/pm-plugins/autocomplete-plugin.d.ts +37 -0
- package/dist/types/pm-plugins/debug-mode.d.ts +19 -4
- package/dist/types/pm-plugins/inline-code-harvester.d.ts +146 -0
- package/dist/types/pm-plugins/text-predictor.d.ts +70 -3
- package/package.json +2 -2
- package/src/analytics/ufo.ts +3 -6
- package/src/pm-plugins/autocomplete-plugin.ts +526 -31
- package/src/pm-plugins/debug-mode.ts +26 -5
- package/src/pm-plugins/inline-code-harvester.ts +561 -0
- package/src/pm-plugins/text-predictor.ts +162 -7
|
@@ -187,6 +187,18 @@ var DEBUG_TEXT_TAIL_CHARS = 120;
|
|
|
187
187
|
* is vocabulary coverage.
|
|
188
188
|
*/
|
|
189
189
|
|
|
190
|
+
/**
|
|
191
|
+
* What the scored path concluded, recorded on every evaluation whether or not
|
|
192
|
+
* debug is on.
|
|
193
|
+
*
|
|
194
|
+
* This exists for the inline-code harvester, which may only offer a harvested
|
|
195
|
+
* surface once the scored path has finished and come away empty. The reason is
|
|
196
|
+
* the load-bearing part: `no-candidate` means no vocabulary reaches this prefix
|
|
197
|
+
* at all, while `winner-margin` means two known words the model cannot yet
|
|
198
|
+
* separate — the first is a gap worth filling and the second is a prefix
|
|
199
|
+
* ambiguous enough that filling it would be a guess.
|
|
200
|
+
*/
|
|
201
|
+
|
|
190
202
|
/**
|
|
191
203
|
* A candidate paired with the length of the already-typed prefix it completes.
|
|
192
204
|
* For a single word this is the current partial token length; for a phrase it
|
|
@@ -214,6 +226,17 @@ var WeightedWordTrie = /*#__PURE__*/function () {
|
|
|
214
226
|
function WeightedWordTrie() {
|
|
215
227
|
_classCallCheck(this, WeightedWordTrie);
|
|
216
228
|
_defineProperty(this, "root", new TrieNode());
|
|
229
|
+
/**
|
|
230
|
+
* Every node a session boost has been written to.
|
|
231
|
+
*
|
|
232
|
+
* Kept because dropping the boosts is no longer a rare event — it happens
|
|
233
|
+
* each time the reader changes page or conversation — and walking a vocabulary
|
|
234
|
+
* of tens of thousands of words to find the few hundred that were touched
|
|
235
|
+
* costs about 10ms of main thread every time. The two writers below are the
|
|
236
|
+
* only way a `sessionFreq` moves, so keeping this in step costs one Set
|
|
237
|
+
* insertion on a path that is already descending the trie.
|
|
238
|
+
*/
|
|
239
|
+
_defineProperty(this, "boostedNodes", new Set());
|
|
217
240
|
/** Highest tenantFreq seen — used to normalize freq scores at query time */
|
|
218
241
|
_defineProperty(this, "maxTenantFreq", 1);
|
|
219
242
|
}
|
|
@@ -330,6 +353,13 @@ var WeightedWordTrie = /*#__PURE__*/function () {
|
|
|
330
353
|
return node.word !== null ? node : null;
|
|
331
354
|
}
|
|
332
355
|
|
|
356
|
+
/** Whether this exact surface is stored as a terminal word. */
|
|
357
|
+
}, {
|
|
358
|
+
key: "hasWord",
|
|
359
|
+
value: function hasWord(word) {
|
|
360
|
+
return this.findNode(word) !== null;
|
|
361
|
+
}
|
|
362
|
+
|
|
333
363
|
/**
|
|
334
364
|
* Set the session frequency for a word.
|
|
335
365
|
* Returns true if the word exists in the trie.
|
|
@@ -342,6 +372,7 @@ var WeightedWordTrie = /*#__PURE__*/function () {
|
|
|
342
372
|
return false;
|
|
343
373
|
}
|
|
344
374
|
node.sessionFreq = count;
|
|
375
|
+
this.boostedNodes.add(node);
|
|
345
376
|
return true;
|
|
346
377
|
}
|
|
347
378
|
|
|
@@ -357,28 +388,51 @@ var WeightedWordTrie = /*#__PURE__*/function () {
|
|
|
357
388
|
return false;
|
|
358
389
|
}
|
|
359
390
|
node.sessionFreq += 1;
|
|
391
|
+
this.boostedNodes.add(node);
|
|
360
392
|
return true;
|
|
361
393
|
}
|
|
362
394
|
|
|
395
|
+
/**
|
|
396
|
+
* Zero every session boost, in the number of words boosted rather than the
|
|
397
|
+
* number of words known.
|
|
398
|
+
*/
|
|
399
|
+
}, {
|
|
400
|
+
key: "clearSessionBoosts",
|
|
401
|
+
value: function clearSessionBoosts() {
|
|
402
|
+
var _iterator5 = _createForOfIteratorHelper(this.boostedNodes),
|
|
403
|
+
_step5;
|
|
404
|
+
try {
|
|
405
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
406
|
+
var node = _step5.value;
|
|
407
|
+
node.sessionFreq = 0;
|
|
408
|
+
}
|
|
409
|
+
} catch (err) {
|
|
410
|
+
_iterator5.e(err);
|
|
411
|
+
} finally {
|
|
412
|
+
_iterator5.f();
|
|
413
|
+
}
|
|
414
|
+
this.boostedNodes.clear();
|
|
415
|
+
}
|
|
416
|
+
|
|
363
417
|
/**
|
|
364
418
|
* Every word carrying a session boost, optionally limited to one prefix's
|
|
365
419
|
* subtree. Unlike `getCandidates` a word equal to the prefix is included,
|
|
366
420
|
* since the question here is what the session holds rather than what could
|
|
367
421
|
* still be typed.
|
|
368
422
|
*
|
|
369
|
-
* Walks the trie
|
|
370
|
-
*
|
|
423
|
+
* Walks the trie rather than reading `boostedNodes`, since a prefix answer is
|
|
424
|
+
* a subtree question and this only runs when a human asks it.
|
|
371
425
|
*/
|
|
372
426
|
}, {
|
|
373
427
|
key: "collectSessionBoosted",
|
|
374
428
|
value: function collectSessionBoosted() {
|
|
375
429
|
var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
376
430
|
var node = this.root;
|
|
377
|
-
var
|
|
378
|
-
|
|
431
|
+
var _iterator6 = _createForOfIteratorHelper(prefix.toLowerCase()),
|
|
432
|
+
_step6;
|
|
379
433
|
try {
|
|
380
|
-
for (
|
|
381
|
-
var char =
|
|
434
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
435
|
+
var char = _step6.value;
|
|
382
436
|
var next = node.children.get(char);
|
|
383
437
|
if (!next) {
|
|
384
438
|
return [];
|
|
@@ -386,9 +440,9 @@ var WeightedWordTrie = /*#__PURE__*/function () {
|
|
|
386
440
|
node = next;
|
|
387
441
|
}
|
|
388
442
|
} catch (err) {
|
|
389
|
-
|
|
443
|
+
_iterator6.e(err);
|
|
390
444
|
} finally {
|
|
391
|
-
|
|
445
|
+
_iterator6.f();
|
|
392
446
|
}
|
|
393
447
|
var boosted = [];
|
|
394
448
|
var stack = [node];
|
|
@@ -403,17 +457,17 @@ var WeightedWordTrie = /*#__PURE__*/function () {
|
|
|
403
457
|
node: current
|
|
404
458
|
});
|
|
405
459
|
}
|
|
406
|
-
var
|
|
407
|
-
|
|
460
|
+
var _iterator7 = _createForOfIteratorHelper(current.children.values()),
|
|
461
|
+
_step7;
|
|
408
462
|
try {
|
|
409
|
-
for (
|
|
410
|
-
var child =
|
|
463
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
464
|
+
var child = _step7.value;
|
|
411
465
|
stack.push(child);
|
|
412
466
|
}
|
|
413
467
|
} catch (err) {
|
|
414
|
-
|
|
468
|
+
_iterator7.e(err);
|
|
415
469
|
} finally {
|
|
416
|
-
|
|
470
|
+
_iterator7.f();
|
|
417
471
|
}
|
|
418
472
|
}
|
|
419
473
|
return boosted;
|
|
@@ -439,19 +493,19 @@ var phraseTrie = new WeightedWordTrie();
|
|
|
439
493
|
* expects a simple array of strings: ["about", "above", "actually", ...]
|
|
440
494
|
*/
|
|
441
495
|
export var initL3Vocabulary = function initL3Vocabulary(l3Words) {
|
|
442
|
-
var
|
|
443
|
-
|
|
496
|
+
var _iterator8 = _createForOfIteratorHelper(l3Words),
|
|
497
|
+
_step8;
|
|
444
498
|
try {
|
|
445
|
-
for (
|
|
446
|
-
var word =
|
|
499
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
500
|
+
var word = _step8.value;
|
|
447
501
|
// Insert with a tiny baseline frequency so it mathematically
|
|
448
502
|
// loses to any domain word in Stage 1, but still scores above 0.
|
|
449
503
|
l3Trie.insert(word, L3_BASELINE_FREQ, 0, 0);
|
|
450
504
|
}
|
|
451
505
|
} catch (err) {
|
|
452
|
-
|
|
506
|
+
_iterator8.e(err);
|
|
453
507
|
} finally {
|
|
454
|
-
|
|
508
|
+
_iterator8.f();
|
|
455
509
|
}
|
|
456
510
|
recallGeneration++;
|
|
457
511
|
ctcTag('init', "L3 general English loaded: ".concat(l3Words.length, " words"));
|
|
@@ -477,6 +531,15 @@ var phraseTermCount = 0;
|
|
|
477
531
|
var maxBigramFreq = 1;
|
|
478
532
|
var maxPhraseFreq = 1;
|
|
479
533
|
var lastPredictionDebug = null;
|
|
534
|
+
var lastPredictionOutcome = null;
|
|
535
|
+
var recordPredictionOutcome = function recordPredictionOutcome(outcome) {
|
|
536
|
+
lastPredictionOutcome = outcome;
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
/** The verdict from the most recent `predict` call. Always populated. */
|
|
540
|
+
export var getLastPredictionOutcome = function getLastPredictionOutcome() {
|
|
541
|
+
return lastPredictionOutcome;
|
|
542
|
+
};
|
|
480
543
|
|
|
481
544
|
// ── Stabilization (QI-2): post-accept cooldown + whole-surface repetition ────
|
|
482
545
|
// Two guards that stop the accept→echo (`end to end` → `end to end to end`) and
|
|
@@ -508,6 +571,22 @@ export var noteSuggestionAccepted = function noteSuggestionAccepted(surface) {
|
|
|
508
571
|
}
|
|
509
572
|
};
|
|
510
573
|
|
|
574
|
+
/**
|
|
575
|
+
* Whether `surface` is the one the user just accepted and is still inside its
|
|
576
|
+
* cooldown window.
|
|
577
|
+
*
|
|
578
|
+
* Read-only, unlike the advance inside `predict`: the cooldown is measured in
|
|
579
|
+
* predictions, and a caller asking whether it is active must not consume one of
|
|
580
|
+
* them. Exported for the harvest path, which displays without going through
|
|
581
|
+
* arbitration and so would otherwise re-offer what was just accepted.
|
|
582
|
+
*/
|
|
583
|
+
export var isSurfaceInAcceptCooldown = function isSurfaceInAcceptCooldown(surface) {
|
|
584
|
+
if (!acceptCooldown || acceptCooldown.surface !== surface.trim().toLowerCase()) {
|
|
585
|
+
return false;
|
|
586
|
+
}
|
|
587
|
+
return acceptCooldown.predictionsSince <= COOLDOWN_KEYSTROKES || performance.now() - acceptCooldown.ts < COOLDOWN_MS;
|
|
588
|
+
};
|
|
589
|
+
|
|
511
590
|
/** Get vector for a word from the store. */
|
|
512
591
|
var getWordVector = function getWordVector(word) {
|
|
513
592
|
if (!vectorStore) {
|
|
@@ -532,20 +611,20 @@ var computeContextVectorLocal = function computeContextVectorLocal(textBefore) {
|
|
|
532
611
|
var tokens = tokenize(textBefore);
|
|
533
612
|
var words = tokens.slice(-CONTEXT_WORDS);
|
|
534
613
|
var vectors = [];
|
|
535
|
-
var
|
|
536
|
-
|
|
614
|
+
var _iterator9 = _createForOfIteratorHelper(words),
|
|
615
|
+
_step9;
|
|
537
616
|
try {
|
|
538
|
-
for (
|
|
539
|
-
var word =
|
|
617
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
618
|
+
var word = _step9.value;
|
|
540
619
|
var _v = getWordVector(word);
|
|
541
620
|
if (_v) {
|
|
542
621
|
vectors.push(_v);
|
|
543
622
|
}
|
|
544
623
|
}
|
|
545
624
|
} catch (err) {
|
|
546
|
-
|
|
625
|
+
_iterator9.e(err);
|
|
547
626
|
} finally {
|
|
548
|
-
|
|
627
|
+
_iterator9.f();
|
|
549
628
|
}
|
|
550
629
|
if (vectors.length === 0) {
|
|
551
630
|
return null;
|
|
@@ -578,11 +657,11 @@ var getContextVectorForScoring = function getContextVectorForScoring(textBefore)
|
|
|
578
657
|
var tokenize = function tokenize(text) {
|
|
579
658
|
var tokens = [];
|
|
580
659
|
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
581
|
-
var
|
|
582
|
-
|
|
660
|
+
var _iterator0 = _createForOfIteratorHelper(text.toLowerCase().split(WHITESPACE_SPLIT_REGEX)),
|
|
661
|
+
_step0;
|
|
583
662
|
try {
|
|
584
|
-
for (
|
|
585
|
-
var raw =
|
|
663
|
+
for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
|
|
664
|
+
var raw = _step0.value;
|
|
586
665
|
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
587
666
|
var clean = raw.replace(PUNCTUATION_BOUNDARY_REGEX, '');
|
|
588
667
|
if (clean.length >= 2) {
|
|
@@ -590,9 +669,9 @@ var tokenize = function tokenize(text) {
|
|
|
590
669
|
}
|
|
591
670
|
}
|
|
592
671
|
} catch (err) {
|
|
593
|
-
|
|
672
|
+
_iterator0.e(err);
|
|
594
673
|
} finally {
|
|
595
|
-
|
|
674
|
+
_iterator0.f();
|
|
596
675
|
}
|
|
597
676
|
return tokens;
|
|
598
677
|
};
|
|
@@ -696,11 +775,11 @@ var getPhraseCandidates = function getPhraseCandidates(trimmed) {
|
|
|
696
775
|
window: windowPrefix,
|
|
697
776
|
matches: matches.length
|
|
698
777
|
});
|
|
699
|
-
var
|
|
700
|
-
|
|
778
|
+
var _iterator1 = _createForOfIteratorHelper(matches),
|
|
779
|
+
_step1;
|
|
701
780
|
try {
|
|
702
|
-
for (
|
|
703
|
-
var _match =
|
|
781
|
+
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
782
|
+
var _match = _step1.value;
|
|
704
783
|
if (seen.has(_match.word)) {
|
|
705
784
|
continue;
|
|
706
785
|
}
|
|
@@ -713,9 +792,9 @@ var getPhraseCandidates = function getPhraseCandidates(trimmed) {
|
|
|
713
792
|
});
|
|
714
793
|
}
|
|
715
794
|
} catch (err) {
|
|
716
|
-
|
|
795
|
+
_iterator1.e(err);
|
|
717
796
|
} finally {
|
|
718
|
-
|
|
797
|
+
_iterator1.f();
|
|
719
798
|
}
|
|
720
799
|
}
|
|
721
800
|
logPhrasePath();
|
|
@@ -760,17 +839,17 @@ export var getLastPredictionDebug = function getLastPredictionDebug() {
|
|
|
760
839
|
return lastPredictionDebug;
|
|
761
840
|
};
|
|
762
841
|
export var initVocabulary = function initVocabulary(vocabulary) {
|
|
763
|
-
var
|
|
764
|
-
|
|
842
|
+
var _iterator10 = _createForOfIteratorHelper(vocabulary.terms),
|
|
843
|
+
_step10;
|
|
765
844
|
try {
|
|
766
|
-
for (
|
|
767
|
-
var term =
|
|
845
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
846
|
+
var term = _step10.value;
|
|
768
847
|
wordTrie.insert(term.word, term.freq, term.docFreq, term.authorFreq);
|
|
769
848
|
}
|
|
770
849
|
} catch (err) {
|
|
771
|
-
|
|
850
|
+
_iterator10.e(err);
|
|
772
851
|
} finally {
|
|
773
|
-
|
|
852
|
+
_iterator10.f();
|
|
774
853
|
}
|
|
775
854
|
isInitialized = true;
|
|
776
855
|
recallGeneration++;
|
|
@@ -821,6 +900,36 @@ export var incrementSessionFreq = function incrementSessionFreq(word) {
|
|
|
821
900
|
wordTrie.incrementSessionFreq(word);
|
|
822
901
|
};
|
|
823
902
|
|
|
903
|
+
/**
|
|
904
|
+
* Drop every L1 boost this session has accumulated.
|
|
905
|
+
*
|
|
906
|
+
* The vocabulary itself is left alone: only `sessionFreq` is cleared, so the
|
|
907
|
+
* tenant and generic frequencies a boost was sitting on top of survive. Called
|
|
908
|
+
* when the plugin decides the session it was learning for has ended — a new
|
|
909
|
+
* conversation, or a different page — since a boost is a claim about what is
|
|
910
|
+
* being discussed and that claim does not carry over.
|
|
911
|
+
*/
|
|
912
|
+
export var resetSessionBoosts = function resetSessionBoosts() {
|
|
913
|
+
wordTrie.clearSessionBoosts();
|
|
914
|
+
// Anything memoized against the old boosts is now describing a session that
|
|
915
|
+
// no longer exists.
|
|
916
|
+
recallGeneration++;
|
|
917
|
+
};
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Which vocabulary already holds this surface, if any.
|
|
921
|
+
*
|
|
922
|
+
* Used by the inline-code harvester to drop terms the scored path can already
|
|
923
|
+
* serve, so that harvesting stays limited to words with no route to a
|
|
924
|
+
* suggestion today.
|
|
925
|
+
*/
|
|
926
|
+
export var lookupVocabularySource = function lookupVocabularySource(word) {
|
|
927
|
+
if (wordTrie.hasWord(word)) {
|
|
928
|
+
return 'l2';
|
|
929
|
+
}
|
|
930
|
+
return l3Trie.hasWord(word) ? 'l3' : null;
|
|
931
|
+
};
|
|
932
|
+
|
|
824
933
|
/**
|
|
825
934
|
* Prime session frequencies from a document page string.
|
|
826
935
|
*
|
|
@@ -837,20 +946,20 @@ export var ingestDocumentPage = function ingestDocumentPage(pageContent) {
|
|
|
837
946
|
}
|
|
838
947
|
var words = tokenize(pageContent);
|
|
839
948
|
var validBoostedWords = new Set();
|
|
840
|
-
var
|
|
841
|
-
|
|
949
|
+
var _iterator11 = _createForOfIteratorHelper(words),
|
|
950
|
+
_step11;
|
|
842
951
|
try {
|
|
843
|
-
for (
|
|
844
|
-
var word =
|
|
952
|
+
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
|
|
953
|
+
var word = _step11.value;
|
|
845
954
|
var didBoost = wordTrie.incrementSessionFreq(word);
|
|
846
955
|
if (didBoost) {
|
|
847
956
|
validBoostedWords.add(word);
|
|
848
957
|
}
|
|
849
958
|
}
|
|
850
959
|
} catch (err) {
|
|
851
|
-
|
|
960
|
+
_iterator11.e(err);
|
|
852
961
|
} finally {
|
|
853
|
-
|
|
962
|
+
_iterator11.f();
|
|
854
963
|
}
|
|
855
964
|
if (isAutocompleteDebugEnabled() && validBoostedWords.size > 0) {
|
|
856
965
|
ctcTag('init', "L1 session primed ".concat(validBoostedWords.size, " words from page \xB7 __atlCtcDebug__.session() to inspect"), CTC_STYLES.brand);
|
|
@@ -868,7 +977,7 @@ export var ingestDocumentPage = function ingestDocumentPage(pageContent) {
|
|
|
868
977
|
* strongest boosts are the ones that change an ordering, and `boosted` still
|
|
869
978
|
* reports the full size, so the cap loses nothing but volume.
|
|
870
979
|
*/
|
|
871
|
-
var MAX_LISTED_SESSION_WORDS =
|
|
980
|
+
var MAX_LISTED_SESSION_WORDS = 100;
|
|
872
981
|
/**
|
|
873
982
|
* Read the session's L1 boosts, optionally narrowed to a prefix.
|
|
874
983
|
*
|
|
@@ -879,7 +988,8 @@ var MAX_LISTED_SESSION_WORDS = 50;
|
|
|
879
988
|
* Only words the vocabulary already holds can carry a boost, because both writers
|
|
880
989
|
* go through `incrementSessionFreq` and it only finds existing nodes. An ingested
|
|
881
990
|
* word absent from the vocabulary is therefore missing from here and always will
|
|
882
|
-
* be
|
|
991
|
+
* be — that gap is what the inline-code harvester covers, and those surfaces show
|
|
992
|
+
* up under `__atlCtcDebug__.harvest()` instead.
|
|
883
993
|
*/
|
|
884
994
|
export var inspectSessionBoosts = function inspectSessionBoosts(prefix) {
|
|
885
995
|
var boosted = wordTrie.collectSessionBoosted(prefix !== null && prefix !== void 0 ? prefix : '');
|
|
@@ -942,20 +1052,20 @@ var computeCanonicalRecall = function computeCanonicalRecall(trimmed, currentWor
|
|
|
942
1052
|
var existingWords = new Set(wordCandidates.map(function (c) {
|
|
943
1053
|
return c.word;
|
|
944
1054
|
}));
|
|
945
|
-
var
|
|
946
|
-
|
|
1055
|
+
var _iterator12 = _createForOfIteratorHelper(l3Candidates),
|
|
1056
|
+
_step12;
|
|
947
1057
|
try {
|
|
948
|
-
for (
|
|
949
|
-
var l3c =
|
|
1058
|
+
for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
|
|
1059
|
+
var l3c = _step12.value;
|
|
950
1060
|
if (wordCandidates.length >= MAX_CANDIDATES) break;
|
|
951
1061
|
if (!existingWords.has(l3c.word)) {
|
|
952
1062
|
wordCandidates.push(l3c);
|
|
953
1063
|
}
|
|
954
1064
|
}
|
|
955
1065
|
} catch (err) {
|
|
956
|
-
|
|
1066
|
+
_iterator12.e(err);
|
|
957
1067
|
} finally {
|
|
958
|
-
|
|
1068
|
+
_iterator12.f();
|
|
959
1069
|
}
|
|
960
1070
|
}
|
|
961
1071
|
|
|
@@ -982,19 +1092,19 @@ var computeCanonicalRecall = function computeCanonicalRecall(trimmed, currentWor
|
|
|
982
1092
|
return _objectSpread(_objectSpread({}, candidate), deriveCanonicalCandidateContext(trimmed, candidate.matchedPrefixLen, candidate.word, getCanonicalSurfaceTokenIds, candidate.surfaceStart, positionCache));
|
|
983
1093
|
});
|
|
984
1094
|
var prefixLenByWord = new Map();
|
|
985
|
-
var
|
|
986
|
-
|
|
1095
|
+
var _iterator13 = _createForOfIteratorHelper(canonicalMatched),
|
|
1096
|
+
_step13;
|
|
987
1097
|
try {
|
|
988
|
-
for (
|
|
989
|
-
var m =
|
|
1098
|
+
for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
|
|
1099
|
+
var m = _step13.value;
|
|
990
1100
|
if (!prefixLenByWord.has(m.word)) {
|
|
991
1101
|
prefixLenByWord.set(m.word, m.matchedPrefixLen);
|
|
992
1102
|
}
|
|
993
1103
|
}
|
|
994
1104
|
} catch (err) {
|
|
995
|
-
|
|
1105
|
+
_iterator13.e(err);
|
|
996
1106
|
} finally {
|
|
997
|
-
|
|
1107
|
+
_iterator13.f();
|
|
998
1108
|
}
|
|
999
1109
|
return {
|
|
1000
1110
|
canonicalMatched: canonicalMatched,
|
|
@@ -1033,6 +1143,14 @@ export var predict = function predict(textBefore) {
|
|
|
1033
1143
|
void loadDefaultVocabulary({
|
|
1034
1144
|
source: 'predict'
|
|
1035
1145
|
}).catch(function () {});
|
|
1146
|
+
// Awaiting, not empty-handed: with no vocabulary loaded the harvester's own
|
|
1147
|
+
// intake filter has not been applied to anything either.
|
|
1148
|
+
recordPredictionOutcome({
|
|
1149
|
+
abstainReason: 'not-initialized',
|
|
1150
|
+
awaitingAsyncEvidence: true,
|
|
1151
|
+
scoredCandidateCount: 0,
|
|
1152
|
+
textBefore: textBefore
|
|
1153
|
+
});
|
|
1036
1154
|
return null;
|
|
1037
1155
|
}
|
|
1038
1156
|
var t0 = performance.now();
|
|
@@ -1061,11 +1179,23 @@ export var predict = function predict(textBefore) {
|
|
|
1061
1179
|
priority: 0
|
|
1062
1180
|
}));
|
|
1063
1181
|
}
|
|
1182
|
+
recordPredictionOutcome({
|
|
1183
|
+
abstainReason: 'prefetch',
|
|
1184
|
+
awaitingAsyncEvidence: true,
|
|
1185
|
+
scoredCandidateCount: 0,
|
|
1186
|
+
textBefore: textBefore
|
|
1187
|
+
});
|
|
1064
1188
|
return null;
|
|
1065
1189
|
}
|
|
1066
1190
|
var trimmed = textBefore.trimEnd();
|
|
1067
1191
|
var trailingSurfaceToken = (_trimmed$match$ = (_trimmed$match = trimmed.match(TRAILING_SURFACE_TOKEN_REGEX)) === null || _trimmed$match === void 0 ? void 0 : _trimmed$match[0]) !== null && _trimmed$match$ !== void 0 ? _trimmed$match$ : '';
|
|
1068
1192
|
if (trailingSurfaceToken.length === 0) {
|
|
1193
|
+
recordPredictionOutcome({
|
|
1194
|
+
abstainReason: 'no-surface-token',
|
|
1195
|
+
awaitingAsyncEvidence: false,
|
|
1196
|
+
scoredCandidateCount: 0,
|
|
1197
|
+
textBefore: textBefore
|
|
1198
|
+
});
|
|
1069
1199
|
return null;
|
|
1070
1200
|
}
|
|
1071
1201
|
var currentWord = trailingSurfaceToken;
|
|
@@ -1076,6 +1206,14 @@ export var predict = function predict(textBefore) {
|
|
|
1076
1206
|
|
|
1077
1207
|
// If every trie was empty for this prefix
|
|
1078
1208
|
if (canonicalMatched.length === 0) {
|
|
1209
|
+
// Terminal, and the only verdict that says the vocabulary has no claim on
|
|
1210
|
+
// this prefix at all — which is what makes it the harvester's cue.
|
|
1211
|
+
recordPredictionOutcome({
|
|
1212
|
+
abstainReason: 'no-candidate',
|
|
1213
|
+
awaitingAsyncEvidence: false,
|
|
1214
|
+
scoredCandidateCount: 0,
|
|
1215
|
+
textBefore: textBefore
|
|
1216
|
+
});
|
|
1079
1217
|
if (isAutocompleteDebugEnabled()) {
|
|
1080
1218
|
// eslint-disable-next-line no-console
|
|
1081
1219
|
console.log("%c[CTC]%c \u2014 abstain: no matches for \"".concat(currentWord, "\""), CTC_STYLES.brand, CTC_STYLES.body);
|
|
@@ -1123,29 +1261,29 @@ export var predict = function predict(textBefore) {
|
|
|
1123
1261
|
}))).sort();
|
|
1124
1262
|
var familyKey = eligibleContextKeys.join("\x01");
|
|
1125
1263
|
var primeRequests = selectBoundaryPrimeRequests(familyKey, canonicalMatched, PHRASE_MAX_WORDS);
|
|
1126
|
-
var
|
|
1127
|
-
|
|
1264
|
+
var _iterator14 = _createForOfIteratorHelper(primeRequests),
|
|
1265
|
+
_step14;
|
|
1128
1266
|
try {
|
|
1129
|
-
for (
|
|
1130
|
-
var request =
|
|
1267
|
+
for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
|
|
1268
|
+
var request = _step14.value;
|
|
1131
1269
|
primeBoundaryLm(request);
|
|
1132
1270
|
}
|
|
1133
1271
|
} catch (err) {
|
|
1134
|
-
|
|
1272
|
+
_iterator14.e(err);
|
|
1135
1273
|
} finally {
|
|
1136
|
-
|
|
1274
|
+
_iterator14.f();
|
|
1137
1275
|
}
|
|
1138
1276
|
var runtimeBySurface = new Map(canonicalMatched.map(function (candidate) {
|
|
1139
1277
|
return [candidate.word, candidate];
|
|
1140
1278
|
}));
|
|
1141
1279
|
var canonicalEvidence = new Map();
|
|
1142
1280
|
var firstTokenGroups = new Map();
|
|
1143
|
-
var
|
|
1144
|
-
|
|
1281
|
+
var _iterator15 = _createForOfIteratorHelper(canonicalMatched),
|
|
1282
|
+
_step15;
|
|
1145
1283
|
try {
|
|
1146
|
-
for (
|
|
1284
|
+
for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
|
|
1147
1285
|
var _firstTokenGroups$get;
|
|
1148
|
-
var _candidate =
|
|
1286
|
+
var _candidate = _step15.value;
|
|
1149
1287
|
if (_candidate.canonicalTokenIds === null) {
|
|
1150
1288
|
continue;
|
|
1151
1289
|
}
|
|
@@ -1173,28 +1311,28 @@ export var predict = function predict(textBefore) {
|
|
|
1173
1311
|
firstTokenGroups.set(_candidate.contextKey, _group2);
|
|
1174
1312
|
}
|
|
1175
1313
|
} catch (err) {
|
|
1176
|
-
|
|
1314
|
+
_iterator15.e(err);
|
|
1177
1315
|
} finally {
|
|
1178
|
-
|
|
1316
|
+
_iterator15.f();
|
|
1179
1317
|
}
|
|
1180
|
-
var
|
|
1181
|
-
|
|
1318
|
+
var _iterator16 = _createForOfIteratorHelper(firstTokenGroups),
|
|
1319
|
+
_step16;
|
|
1182
1320
|
try {
|
|
1183
|
-
for (
|
|
1184
|
-
var
|
|
1185
|
-
_contextKey =
|
|
1186
|
-
_group3 =
|
|
1321
|
+
for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
|
|
1322
|
+
var _step16$value = _slicedToArray(_step16.value, 2),
|
|
1323
|
+
_contextKey = _step16$value[0],
|
|
1324
|
+
_group3 = _step16$value[1];
|
|
1187
1325
|
var boundary = getBoundaryLmState(_contextKey);
|
|
1188
1326
|
if (!boundary) {
|
|
1189
1327
|
continue;
|
|
1190
1328
|
}
|
|
1191
1329
|
var maxLogit = -Infinity;
|
|
1192
|
-
var
|
|
1193
|
-
|
|
1330
|
+
var _iterator23 = _createForOfIteratorHelper(_group3),
|
|
1331
|
+
_step23;
|
|
1194
1332
|
try {
|
|
1195
|
-
for (
|
|
1333
|
+
for (_iterator23.s(); !(_step23 = _iterator23.n()).done;) {
|
|
1196
1334
|
var _candidate2$canonical;
|
|
1197
|
-
var _candidate2 =
|
|
1335
|
+
var _candidate2 = _step23.value;
|
|
1198
1336
|
var tokenId = (_candidate2$canonical = _candidate2.canonicalTokenIds) === null || _candidate2$canonical === void 0 ? void 0 : _candidate2$canonical[0];
|
|
1199
1337
|
var rawLogit = tokenId === undefined ? undefined : boundary.rawLogits[tokenId];
|
|
1200
1338
|
if (rawLogit !== undefined && Number.isFinite(rawLogit) && rawLogit > maxLogit) {
|
|
@@ -1202,19 +1340,19 @@ export var predict = function predict(textBefore) {
|
|
|
1202
1340
|
}
|
|
1203
1341
|
}
|
|
1204
1342
|
} catch (err) {
|
|
1205
|
-
|
|
1343
|
+
_iterator23.e(err);
|
|
1206
1344
|
} finally {
|
|
1207
|
-
|
|
1345
|
+
_iterator23.f();
|
|
1208
1346
|
}
|
|
1209
1347
|
if (!Number.isFinite(maxLogit)) {
|
|
1210
1348
|
continue;
|
|
1211
1349
|
}
|
|
1212
|
-
var
|
|
1213
|
-
|
|
1350
|
+
var _iterator24 = _createForOfIteratorHelper(_group3),
|
|
1351
|
+
_step24;
|
|
1214
1352
|
try {
|
|
1215
|
-
for (
|
|
1353
|
+
for (_iterator24.s(); !(_step24 = _iterator24.n()).done;) {
|
|
1216
1354
|
var _candidate3$canonical, _candidate3$canonical2, _candidate3$canonical3;
|
|
1217
|
-
var _candidate3 =
|
|
1355
|
+
var _candidate3 = _step24.value;
|
|
1218
1356
|
var _tokenId = (_candidate3$canonical = _candidate3.canonicalTokenIds) === null || _candidate3$canonical === void 0 ? void 0 : _candidate3$canonical[0];
|
|
1219
1357
|
var _rawLogit = _tokenId === undefined ? undefined : boundary.rawLogits[_tokenId];
|
|
1220
1358
|
if (_rawLogit === undefined || !Number.isFinite(_rawLogit)) {
|
|
@@ -1253,15 +1391,15 @@ export var predict = function predict(textBefore) {
|
|
|
1253
1391
|
});
|
|
1254
1392
|
}
|
|
1255
1393
|
} catch (err) {
|
|
1256
|
-
|
|
1394
|
+
_iterator24.e(err);
|
|
1257
1395
|
} finally {
|
|
1258
|
-
|
|
1396
|
+
_iterator24.f();
|
|
1259
1397
|
}
|
|
1260
1398
|
}
|
|
1261
1399
|
} catch (err) {
|
|
1262
|
-
|
|
1400
|
+
_iterator16.e(err);
|
|
1263
1401
|
} finally {
|
|
1264
|
-
|
|
1402
|
+
_iterator16.f();
|
|
1265
1403
|
}
|
|
1266
1404
|
var _rankCandidates = rankCandidates(scoringCandidates, contextVector, function (w) {
|
|
1267
1405
|
return getWordVector(w);
|
|
@@ -1282,12 +1420,12 @@ export var predict = function predict(textBefore) {
|
|
|
1282
1420
|
});
|
|
1283
1421
|
if (canonicalScoringSupported && progressiveEligible.length > 0) {
|
|
1284
1422
|
var byContext = new Map();
|
|
1285
|
-
var
|
|
1286
|
-
|
|
1423
|
+
var _iterator17 = _createForOfIteratorHelper(progressiveEligible),
|
|
1424
|
+
_step17;
|
|
1287
1425
|
try {
|
|
1288
|
-
for (
|
|
1426
|
+
for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
|
|
1289
1427
|
var _byContext$get;
|
|
1290
|
-
var candidate =
|
|
1428
|
+
var candidate = _step17.value;
|
|
1291
1429
|
var runtime = runtimeBySurface.get(candidate.word);
|
|
1292
1430
|
if (!runtime || runtime.canonicalTokenIds === null) {
|
|
1293
1431
|
continue;
|
|
@@ -1300,17 +1438,17 @@ export var predict = function predict(textBefore) {
|
|
|
1300
1438
|
byContext.set(runtime.contextKey, group);
|
|
1301
1439
|
}
|
|
1302
1440
|
} catch (err) {
|
|
1303
|
-
|
|
1441
|
+
_iterator17.e(err);
|
|
1304
1442
|
} finally {
|
|
1305
|
-
|
|
1443
|
+
_iterator17.f();
|
|
1306
1444
|
}
|
|
1307
|
-
var
|
|
1308
|
-
|
|
1445
|
+
var _iterator18 = _createForOfIteratorHelper(byContext),
|
|
1446
|
+
_step18;
|
|
1309
1447
|
try {
|
|
1310
|
-
for (
|
|
1311
|
-
var
|
|
1312
|
-
contextKey =
|
|
1313
|
-
_group =
|
|
1448
|
+
for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
|
|
1449
|
+
var _step18$value = _slicedToArray(_step18.value, 2),
|
|
1450
|
+
contextKey = _step18$value[0],
|
|
1451
|
+
_group = _step18$value[1];
|
|
1314
1452
|
requestProgressiveSurfaceScores({
|
|
1315
1453
|
familyKey: familyKey,
|
|
1316
1454
|
contextKey: contextKey,
|
|
@@ -1328,9 +1466,9 @@ export var predict = function predict(textBefore) {
|
|
|
1328
1466
|
});
|
|
1329
1467
|
}
|
|
1330
1468
|
} catch (err) {
|
|
1331
|
-
|
|
1469
|
+
_iterator18.e(err);
|
|
1332
1470
|
} finally {
|
|
1333
|
-
|
|
1471
|
+
_iterator18.f();
|
|
1334
1472
|
}
|
|
1335
1473
|
}
|
|
1336
1474
|
|
|
@@ -1419,12 +1557,12 @@ export var predict = function predict(textBefore) {
|
|
|
1419
1557
|
var contextRequestedCount = new Map();
|
|
1420
1558
|
var bestTotalByContext = new Map();
|
|
1421
1559
|
var bestCandidateByContext = new Map();
|
|
1422
|
-
var
|
|
1423
|
-
|
|
1560
|
+
var _iterator19 = _createForOfIteratorHelper(ranked),
|
|
1561
|
+
_step19;
|
|
1424
1562
|
try {
|
|
1425
|
-
for (
|
|
1563
|
+
for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
|
|
1426
1564
|
var _contextRequestedCoun2, _judged$total;
|
|
1427
|
-
var _candidate4 =
|
|
1565
|
+
var _candidate4 = _step19.value;
|
|
1428
1566
|
var _runtime = runtimeBySurface.get(_candidate4.word);
|
|
1429
1567
|
if (!_runtime || _runtime.canonicalTokenIds === null) {
|
|
1430
1568
|
continue;
|
|
@@ -1463,9 +1601,9 @@ export var predict = function predict(textBefore) {
|
|
|
1463
1601
|
* costs one lookup per space rather than a comparison against every member.
|
|
1464
1602
|
*/
|
|
1465
1603
|
} catch (err) {
|
|
1466
|
-
|
|
1604
|
+
_iterator19.e(err);
|
|
1467
1605
|
} finally {
|
|
1468
|
-
|
|
1606
|
+
_iterator19.f();
|
|
1469
1607
|
}
|
|
1470
1608
|
var extendsAPoolMember = function extendsAPoolMember(surface, pool) {
|
|
1471
1609
|
for (var space = surface.indexOf(' '); space !== -1; space = surface.indexOf(' ', space + 1)) {
|
|
@@ -1500,22 +1638,22 @@ export var predict = function predict(textBefore) {
|
|
|
1500
1638
|
// it continues, because the cap alone would leave it looking exactly as
|
|
1501
1639
|
// certain as its prefix while saying nothing about its own tail.
|
|
1502
1640
|
var underReadExtensions = new Set();
|
|
1503
|
-
var
|
|
1504
|
-
|
|
1641
|
+
var _iterator20 = _createForOfIteratorHelper(contextSurfaces),
|
|
1642
|
+
_step20;
|
|
1505
1643
|
try {
|
|
1506
|
-
for (
|
|
1507
|
-
var
|
|
1508
|
-
_contextKey2 =
|
|
1509
|
-
_surfaces =
|
|
1644
|
+
for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
|
|
1645
|
+
var _step20$value = _slicedToArray(_step20.value, 2),
|
|
1646
|
+
_contextKey2 = _step20$value[0],
|
|
1647
|
+
_surfaces = _step20$value[1];
|
|
1510
1648
|
var pool = new Set(_surfaces);
|
|
1511
|
-
var
|
|
1649
|
+
var _iterator25 = _createForOfIteratorHelper(_toConsumableArray(_surfaces).sort(function (a, b) {
|
|
1512
1650
|
return a.length - b.length;
|
|
1513
1651
|
})),
|
|
1514
|
-
|
|
1652
|
+
_step25;
|
|
1515
1653
|
try {
|
|
1516
|
-
for (
|
|
1654
|
+
for (_iterator25.s(); !(_step25 = _iterator25.n()).done;) {
|
|
1517
1655
|
var _getProgressiveSurfac, _getProgressiveSurfac2, _runtimeBySurface$get8, _runtimeBySurface$get9;
|
|
1518
|
-
var surface =
|
|
1656
|
+
var surface = _step25.value;
|
|
1519
1657
|
var own = optimisticTotalByWord.get(surface);
|
|
1520
1658
|
if (own === undefined) {
|
|
1521
1659
|
continue;
|
|
@@ -1547,9 +1685,9 @@ export var predict = function predict(textBefore) {
|
|
|
1547
1685
|
}
|
|
1548
1686
|
}
|
|
1549
1687
|
} catch (err) {
|
|
1550
|
-
|
|
1688
|
+
_iterator25.e(err);
|
|
1551
1689
|
} finally {
|
|
1552
|
-
|
|
1690
|
+
_iterator25.f();
|
|
1553
1691
|
}
|
|
1554
1692
|
}
|
|
1555
1693
|
|
|
@@ -1562,9 +1700,9 @@ export var predict = function predict(textBefore) {
|
|
|
1562
1700
|
* depths.
|
|
1563
1701
|
*/
|
|
1564
1702
|
} catch (err) {
|
|
1565
|
-
|
|
1703
|
+
_iterator20.e(err);
|
|
1566
1704
|
} finally {
|
|
1567
|
-
|
|
1705
|
+
_iterator20.f();
|
|
1568
1706
|
}
|
|
1569
1707
|
var judgedEvidenceFor = function judgedEvidenceFor(candidate) {
|
|
1570
1708
|
return underReadExtensions.has(candidate.word) ? null : readJudgedEvidence(candidate);
|
|
@@ -1591,20 +1729,20 @@ export var predict = function predict(textBefore) {
|
|
|
1591
1729
|
// `contextTotals`, so how contested a context is still counts every scored
|
|
1592
1730
|
// candidate.
|
|
1593
1731
|
var logSumExpByContext = new Map();
|
|
1594
|
-
var
|
|
1595
|
-
|
|
1732
|
+
var _iterator21 = _createForOfIteratorHelper(contextSurfaces),
|
|
1733
|
+
_step21;
|
|
1596
1734
|
try {
|
|
1597
|
-
for (
|
|
1598
|
-
var
|
|
1599
|
-
_contextKey3 =
|
|
1600
|
-
_surfaces2 =
|
|
1735
|
+
for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
|
|
1736
|
+
var _step21$value = _slicedToArray(_step21.value, 2),
|
|
1737
|
+
_contextKey3 = _step21$value[0],
|
|
1738
|
+
_surfaces2 = _step21$value[1];
|
|
1601
1739
|
var _pool = new Set(_surfaces2);
|
|
1602
1740
|
var minimalTotals = [];
|
|
1603
|
-
var
|
|
1604
|
-
|
|
1741
|
+
var _iterator26 = _createForOfIteratorHelper(_surfaces2),
|
|
1742
|
+
_step26;
|
|
1605
1743
|
try {
|
|
1606
|
-
for (
|
|
1607
|
-
var _surface =
|
|
1744
|
+
for (_iterator26.s(); !(_step26 = _iterator26.n()).done;) {
|
|
1745
|
+
var _surface = _step26.value;
|
|
1608
1746
|
var total = optimisticTotalByWord.get(_surface);
|
|
1609
1747
|
if (total !== undefined && !extendsAPoolMember(_surface, _pool)) {
|
|
1610
1748
|
minimalTotals.push(total);
|
|
@@ -1613,9 +1751,9 @@ export var predict = function predict(textBefore) {
|
|
|
1613
1751
|
// An extension is strictly longer than what it extends, so the shortest
|
|
1614
1752
|
// member of any non-empty pool is always minimal and this is never empty.
|
|
1615
1753
|
} catch (err) {
|
|
1616
|
-
|
|
1754
|
+
_iterator26.e(err);
|
|
1617
1755
|
} finally {
|
|
1618
|
-
|
|
1756
|
+
_iterator26.f();
|
|
1619
1757
|
}
|
|
1620
1758
|
logSumExpByContext.set(_contextKey3, logSumExp(minimalTotals));
|
|
1621
1759
|
}
|
|
@@ -1627,9 +1765,9 @@ export var predict = function predict(textBefore) {
|
|
|
1627
1765
|
* eventual posterior, or a verified total for the posterior itself.
|
|
1628
1766
|
*/
|
|
1629
1767
|
} catch (err) {
|
|
1630
|
-
|
|
1768
|
+
_iterator21.e(err);
|
|
1631
1769
|
} finally {
|
|
1632
|
-
|
|
1770
|
+
_iterator21.f();
|
|
1633
1771
|
}
|
|
1634
1772
|
var posteriorFor = function posteriorFor(candidate, total) {
|
|
1635
1773
|
var runtime = runtimeBySurface.get(candidate.word);
|
|
@@ -1919,6 +2057,12 @@ export var predict = function predict(textBefore) {
|
|
|
1919
2057
|
return ranked.some(hasJudgeableEvidence) ? 'below-posterior-gate' : 'no-evidence';
|
|
1920
2058
|
};
|
|
1921
2059
|
var abstainReason = resolveAbstainReason();
|
|
2060
|
+
recordPredictionOutcome({
|
|
2061
|
+
abstainReason: abstainReason,
|
|
2062
|
+
awaitingAsyncEvidence: hasUnresolvedPotential && !clearsWinnerMargin,
|
|
2063
|
+
scoredCandidateCount: ranked.length,
|
|
2064
|
+
textBefore: textBefore
|
|
2065
|
+
});
|
|
1922
2066
|
|
|
1923
2067
|
// The leader is the best-supported candidate, not the selected one: an
|
|
1924
2068
|
// evaluation that showed nothing is exactly the one whose posterior needs
|
|
@@ -1974,6 +2118,9 @@ export var predict = function predict(textBefore) {
|
|
|
1974
2118
|
'missing-artifact': 'canonical artifact coverage missing',
|
|
1975
2119
|
'no-candidate': 'nothing cleared scoring',
|
|
1976
2120
|
'no-evidence': 'full-surface evidence absent',
|
|
2121
|
+
// Recorded at the two exits above this block, so they never print here.
|
|
2122
|
+
'no-surface-token': 'no trailing surface token',
|
|
2123
|
+
'not-initialized': 'vocabulary not loaded',
|
|
1977
2124
|
prefetch: "prefetch: ".concat(currentWord.length, "/").concat(DISPLAY_MIN_PREFIX_LENGTH, " chars"),
|
|
1978
2125
|
'short-completion': "completion shorter than ".concat(MIN_SUGGESTION_LENGTH, " chars"),
|
|
1979
2126
|
'unresolved-rival': 'expanding plausible token-prefix groups',
|
|
@@ -2068,17 +2215,17 @@ export var predict = function predict(textBefore) {
|
|
|
2068
2215
|
bigram: 0,
|
|
2069
2216
|
phrase: 0
|
|
2070
2217
|
};
|
|
2071
|
-
var
|
|
2072
|
-
|
|
2218
|
+
var _iterator22 = _createForOfIteratorHelper(canonicalMatched),
|
|
2219
|
+
_step22;
|
|
2073
2220
|
try {
|
|
2074
|
-
for (
|
|
2075
|
-
var m =
|
|
2221
|
+
for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
|
|
2222
|
+
var m = _step22.value;
|
|
2076
2223
|
genByType[m.node.termType] += 1;
|
|
2077
2224
|
}
|
|
2078
2225
|
} catch (err) {
|
|
2079
|
-
|
|
2226
|
+
_iterator22.e(err);
|
|
2080
2227
|
} finally {
|
|
2081
|
-
|
|
2228
|
+
_iterator22.f();
|
|
2082
2229
|
}
|
|
2083
2230
|
ctcSection('GENERATE', "matched ".concat(canonicalMatched.length, " \u2192 word:").concat(genByType.word, " bigram:").concat(genByType.bigram, " phrase:").concat(genByType.phrase).concat(canonicalLmSupported ? ' · display needs exact surface evidence' : ''));
|
|
2084
2231
|
|