@atlaskit/editor-plugin-autocomplete 8.0.0 → 9.0.0

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 (79) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/cjs/analytics/ufo.js +2 -1
  3. package/dist/cjs/pm-plugins/artifact-loader.js +135 -0
  4. package/dist/cjs/pm-plugins/artifacts-manifest.js +3 -0
  5. package/dist/cjs/pm-plugins/autocomplete-plugin.js +416 -129
  6. package/dist/cjs/pm-plugins/canonical-lm-scoring.js +371 -0
  7. package/dist/cjs/pm-plugins/debug-mode.js +90 -7
  8. package/dist/cjs/pm-plugins/ghost-text-decoration.js +12 -3
  9. package/dist/cjs/pm-plugins/local-slow-lane-client.js +1202 -453
  10. package/dist/cjs/pm-plugins/scoring-pipeline.js +164 -19
  11. package/dist/cjs/pm-plugins/slow-lane-client.js +100 -37
  12. package/dist/cjs/pm-plugins/text-predictor.js +1951 -273
  13. package/dist/es2019/analytics/ufo.js +2 -0
  14. package/dist/es2019/pm-plugins/artifact-loader.js +70 -0
  15. package/dist/es2019/pm-plugins/artifacts-manifest.js +3 -0
  16. package/dist/es2019/pm-plugins/autocomplete-plugin.js +425 -130
  17. package/dist/es2019/pm-plugins/canonical-lm-scoring.js +270 -0
  18. package/dist/es2019/pm-plugins/debug-mode.js +87 -7
  19. package/dist/es2019/pm-plugins/ghost-text-decoration.js +12 -3
  20. package/dist/es2019/pm-plugins/local-slow-lane-client.js +940 -326
  21. package/dist/es2019/pm-plugins/scoring-pipeline.js +137 -13
  22. package/dist/es2019/pm-plugins/slow-lane-client.js +94 -37
  23. package/dist/es2019/pm-plugins/text-predictor.js +1603 -199
  24. package/dist/esm/analytics/ufo.js +2 -1
  25. package/dist/esm/pm-plugins/artifact-loader.js +128 -0
  26. package/dist/esm/pm-plugins/artifacts-manifest.js +3 -0
  27. package/dist/esm/pm-plugins/autocomplete-plugin.js +419 -132
  28. package/dist/esm/pm-plugins/canonical-lm-scoring.js +364 -0
  29. package/dist/esm/pm-plugins/debug-mode.js +89 -6
  30. package/dist/esm/pm-plugins/ghost-text-decoration.js +12 -3
  31. package/dist/esm/pm-plugins/local-slow-lane-client.js +1200 -451
  32. package/dist/esm/pm-plugins/scoring-pipeline.js +163 -18
  33. package/dist/esm/pm-plugins/slow-lane-client.js +100 -37
  34. package/dist/esm/pm-plugins/text-predictor.js +1953 -277
  35. package/dist/types/analytics/ufo.d.ts +1 -0
  36. package/dist/types/pm-plugins/artifact-loader.d.ts +44 -0
  37. package/dist/types/pm-plugins/artifacts-manifest.d.ts +3 -0
  38. package/dist/types/pm-plugins/autocomplete-plugin.d.ts +39 -0
  39. package/dist/types/pm-plugins/canonical-lm-scoring.d.ts +158 -0
  40. package/dist/types/pm-plugins/debug-mode.d.ts +36 -1
  41. package/dist/types/pm-plugins/ghost-text-decoration.d.ts +5 -2
  42. package/dist/types/pm-plugins/local-slow-lane-client.d.ts +87 -54
  43. package/dist/types/pm-plugins/scoring-pipeline.d.ts +33 -1
  44. package/dist/types/pm-plugins/slow-lane-client.d.ts +51 -3
  45. package/dist/types/pm-plugins/text-predictor.d.ts +120 -2
  46. package/package.json +2 -2
  47. package/src/analytics/ufo.ts +5 -0
  48. package/src/pm-plugins/artifact-loader.ts +92 -0
  49. package/src/pm-plugins/artifacts-manifest.ts +3 -0
  50. package/src/pm-plugins/autocomplete-plugin.ts +517 -133
  51. package/src/pm-plugins/canonical-lm-scoring.ts +412 -0
  52. package/src/pm-plugins/debug-mode.ts +109 -7
  53. package/src/pm-plugins/ghost-text-decoration.ts +13 -4
  54. package/src/pm-plugins/local-slow-lane-client.ts +1302 -386
  55. package/src/pm-plugins/scoring-pipeline.ts +167 -17
  56. package/src/pm-plugins/slow-lane-client.ts +147 -62
  57. package/src/pm-plugins/text-predictor.ts +2006 -255
  58. package/CANONICAL_FIX__DO_NOT_USE_ME_A/package.json +0 -8
  59. package/CANONICAL_FIX__DO_NOT_USE_ME_B/package.json +0 -8
  60. package/CANONICAL_FIX__DO_NOT_USE_ME_C/package.json +0 -8
  61. package/dist/cjs/entry-points/src-pm-plugins-autocomplete-plugin.js +0 -18
  62. package/dist/cjs/entry-points/src-pm-plugins-slow-lane-client.js +0 -36
  63. package/dist/cjs/entry-points/src-pm-plugins-text-predictor.js +0 -66
  64. package/dist/es2019/entry-points/src-pm-plugins-autocomplete-plugin.js +0 -2
  65. package/dist/es2019/entry-points/src-pm-plugins-slow-lane-client.js +0 -2
  66. package/dist/es2019/entry-points/src-pm-plugins-text-predictor.js +0 -2
  67. package/dist/esm/entry-points/src-pm-plugins-autocomplete-plugin.js +0 -2
  68. package/dist/esm/entry-points/src-pm-plugins-slow-lane-client.js +0 -2
  69. package/dist/esm/entry-points/src-pm-plugins-text-predictor.js +0 -2
  70. package/dist/types/entry-points/src-pm-plugins-autocomplete-plugin.d.ts +0 -2
  71. package/dist/types/entry-points/src-pm-plugins-slow-lane-client.d.ts +0 -2
  72. package/dist/types/entry-points/src-pm-plugins-text-predictor.d.ts +0 -2
  73. package/scripts/gen_first_token_to_words.py +0 -170
  74. package/src/entry-points/src-pm-plugins-autocomplete-plugin.ts +0 -7
  75. package/src/entry-points/src-pm-plugins-slow-lane-client.ts +0 -13
  76. package/src/entry-points/src-pm-plugins-text-predictor.ts +0 -14
  77. package/src/pm-plugins/autocomplete-plugin/package.json +0 -8
  78. package/src/pm-plugins/slow-lane-client/package.json +0 -8
  79. package/src/pm-plugins/text-predictor/package.json +0 -8
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import _typeof from "@babel/runtime/helpers/typeof";
4
5
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
5
6
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
7
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
@@ -23,6 +24,11 @@ import { isAutocompleteDebugEnabled } from './debug-mode';
23
24
 
24
25
  // ─── Types ──────────────────────────────────────────────────
25
26
 
27
+ /**
28
+ * A completion term is `(term, termType)`. `word` is the v1 default; `bigram`
29
+ * (2 tokens) and `phrase` (3 tokens) are multi-word units mined by the producer.
30
+ */
31
+
26
32
  /** Metadata returned by the grammar filter for debug logging in the caller. */
27
33
 
28
34
  // ─── Scoring Constants ──────────────────────────────────────
@@ -30,9 +36,25 @@ import { isAutocompleteDebugEnabled } from './debug-mode';
30
36
  var ALPHA = 0.5;
31
37
  var BETA = 0.5;
32
38
  var NEUTRAL_SCORE = 0.5;
39
+ // Multiplicative Stage-1 boost applied to a multi-word term proportional to its
40
+ // (clamped [0,1]) NPMI association, so a strongly-collocated phrase outranks a
41
+ // coincidental word sequence of comparable freq/semantics. Tunable.
42
+ var ASSOCIATION_BOOST = 0.5;
33
43
  export var STAGE1_WEIGHT = 0.35;
34
44
  export var STAGE2_WEIGHT = 0.65;
35
45
  export var MIN_STAGE1_SCORE = 0.35;
46
+ /**
47
+ * How far the leading candidate must sit above the runner-up on the blended
48
+ * score before a ghost is committed.
49
+ *
50
+ * Lives beside the weights it is measured in, because it is only meaningful on
51
+ * that scale — and because both the arbitration that applies it and the
52
+ * scheduler that decides when reading more tokens can no longer change the
53
+ * outcome have to use the same number. When those two drifted apart, the
54
+ * scheduler stopped early on a margin the arbitration did not recognise and the
55
+ * abstention that followed was invisible from either side.
56
+ */
57
+ export var MIN_WINNER_MARGIN = 0.08;
36
58
  var L1_SESSION_CAP = 1.2;
37
59
  // Minimum prefix-payload max LM probability before Stage 2 activates.
38
60
  // Below this threshold the LM signal is too weak to suppress Stage 1 — finalScore
@@ -51,13 +73,38 @@ var posTags = new Map();
51
73
  * without suggesting these words to the user.
52
74
  */
53
75
  var ghostPosTags = {};
76
+ var grammarDataPromise;
54
77
 
55
78
  /**
56
79
  * Precomputed map from each POS tag to the set of allowed next POS tags, so
57
80
  * applyGrammarFilter never re-iterates the transition rules per call.
58
81
  */
59
82
  var precomputedAllowedByPos = new Map();
60
- var grammarDataPromise;
83
+ var isPosTagsRecord = function isPosTagsRecord(payload) {
84
+ if (payload == null || _typeof(payload) !== 'object') {
85
+ return false;
86
+ }
87
+ return Object.values(payload).every(function (value) {
88
+ return Array.isArray(value) && value.every(function (entry) {
89
+ return typeof entry === 'string';
90
+ });
91
+ });
92
+ };
93
+ var isGrammarTransitions = function isGrammarTransitions(payload) {
94
+ if (payload == null || _typeof(payload) !== 'object') {
95
+ return false;
96
+ }
97
+ var transitions = payload.transitions;
98
+ if (transitions == null || _typeof(transitions) !== 'object') {
99
+ return false;
100
+ }
101
+ return Object.values(transitions).every(function (value) {
102
+ var allowed = value === null || value === void 0 ? void 0 : value.allowed;
103
+ return Array.isArray(allowed) && allowed.every(function (entry) {
104
+ return typeof entry === 'string';
105
+ });
106
+ });
107
+ };
61
108
  var setGrammarData = function setGrammarData(data) {
62
109
  var _data$grammarTransiti;
63
110
  posTags = new Map(Object.entries(data.posTags));
@@ -111,9 +158,27 @@ export var loadGrammarDataAsync = function loadGrammarDataAsync(options) {
111
158
  }
112
159
  throw new Error("[scoring-pipeline] ".concat(ARTIFACT_NAME.GRAMMAR_TRANSITIONS, " is missing its `transitions` wrapper"));
113
160
  case 3:
161
+ if (isGrammarTransitions(grammarTransitionsData)) {
162
+ _context.next = 4;
163
+ break;
164
+ }
165
+ throw new Error("[scoring-pipeline] ".concat(ARTIFACT_NAME.GRAMMAR_TRANSITIONS, " payload shape was invalid"));
166
+ case 4:
167
+ if (isPosTagsRecord(posTagsData)) {
168
+ _context.next = 5;
169
+ break;
170
+ }
171
+ throw new Error("[scoring-pipeline] ".concat(ARTIFACT_NAME.POS_TAGS, " payload shape was invalid"));
172
+ case 5:
173
+ if (isPosTagsRecord(ghostPosTagsData)) {
174
+ _context.next = 6;
175
+ break;
176
+ }
177
+ throw new Error("[scoring-pipeline] ".concat(ARTIFACT_NAME.GHOST_POS_TAGS, " payload shape was invalid"));
178
+ case 6:
114
179
  setGrammarData({
115
- posTags: posTagsData !== null && posTagsData !== void 0 ? posTagsData : {},
116
- ghostPosTags: ghostPosTagsData !== null && ghostPosTagsData !== void 0 ? ghostPosTagsData : {},
180
+ posTags: posTagsData,
181
+ ghostPosTags: ghostPosTagsData,
117
182
  grammarTransitions: grammarTransitionsData
118
183
  });
119
184
  succeedExp(EXPERIENCE_NAME.LOAD_GRAMMAR, 'singleton', _objectSpread({
@@ -131,10 +196,10 @@ export var loadGrammarDataAsync = function loadGrammarDataAsync(options) {
131
196
  transitionCount: precomputedAllowedByPos.size
132
197
  });
133
198
  }
134
- _context.next = 5;
199
+ _context.next = 8;
135
200
  break;
136
- case 4:
137
- _context.prev = 4;
201
+ case 7:
202
+ _context.prev = 7;
138
203
  _t = _context["catch"](1);
139
204
  failExp(EXPERIENCE_NAME.LOAD_GRAMMAR, 'singleton', _objectSpread({
140
205
  isLocalLLM: isLocalLLM,
@@ -145,11 +210,11 @@ export var loadGrammarDataAsync = function loadGrammarDataAsync(options) {
145
210
  // Allow a later call to retry the load rather than caching the failure.
146
211
  grammarDataPromise = undefined;
147
212
  throw _t;
148
- case 5:
213
+ case 8:
149
214
  case "end":
150
215
  return _context.stop();
151
216
  }
152
- }, _callee, null, [[1, 4]]);
217
+ }, _callee, null, [[1, 7]]);
153
218
  }))();
154
219
  return grammarDataPromise;
155
220
  };
@@ -248,7 +313,16 @@ function applyGrammarFilter(candidates, previousWord) {
248
313
  try {
249
314
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
250
315
  var entry = _step2.value;
251
- var candidateTags = posTags.get(entry.candidate.word.toLowerCase());
316
+ // The producer validates a multi-word term's *internal* grammar offline
317
+ // (boundary-clean, noun-headed, AUP-passed — spec §9), but nothing judges
318
+ // the transition into it. Exempting multi-word terms therefore let a noun
319
+ // this filter had just rejected re-enter wrapped in a bigram — "be" [AUX]
320
+ // dropped "quality" and then displayed "quality assurance". Only the term's
321
+ // first word takes part in the transition, so gate every term on that.
322
+ var surface = entry.candidate.word;
323
+ var firstSpace = surface.indexOf(' ');
324
+ var transitionWord = firstSpace === -1 ? surface : surface.slice(0, firstSpace);
325
+ var candidateTags = posTags.get(transitionWord.toLowerCase());
252
326
 
253
327
  // If candidate has no tags (unknown word), let it pass to be safe
254
328
  if (!candidateTags || candidateTags.length === 0) {
@@ -296,19 +370,34 @@ function getLmScore(word, lmLogits) {
296
370
 
297
371
  // ─── Public API ─────────────────────────────────────────────
298
372
 
299
- export function rankCandidates(candidates, contextVector, getWordVector, lmLogits, maxTenantFreq, previousWord) {
373
+ /**
374
+ * Apply Stage 1, grammar, and nullable context-local LM evidence to candidates.
375
+ */
376
+ export function rankCandidates(candidates, contextVector, getWordVector, lmLogits, maxFreqByType, previousWord, getCanonicalLmEvidence) {
300
377
  var _grammarMeta$dropped;
301
378
  // Stage 1
302
379
  var stage1Results = candidates.map(function (candidate) {
303
- var _scoreStage = scoreStage1(candidate, contextVector, getWordVector, maxTenantFreq),
380
+ var _candidate$termType;
381
+ var termType = (_candidate$termType = candidate.termType) !== null && _candidate$termType !== void 0 ? _candidate$termType : 'word';
382
+ // Normalize freq within the candidate's own term-type population so a
383
+ // phrase (whose absolute counts are far below top unigrams) isn't crushed
384
+ // by the unigram max.
385
+ var maxFreq = maxFreqByType[termType] || 1;
386
+ var _scoreStage = scoreStage1(candidate, contextVector, getWordVector, maxFreq),
304
387
  semanticScore = _scoreStage.semanticScore,
305
388
  freqScore = _scoreStage.freqScore,
306
389
  stage1Score = _scoreStage.stage1Score;
390
+ // Multi-word units get an NPMI association boost (Stage-1 only).
391
+ var adjustedStage1 = stage1Score;
392
+ if (termType !== 'word' && typeof candidate.association === 'number') {
393
+ var assoc = Math.max(0, Math.min(1, candidate.association));
394
+ adjustedStage1 = stage1Score * (1 + ASSOCIATION_BOOST * assoc);
395
+ }
307
396
  return {
308
397
  candidate: candidate,
309
398
  semanticScore: semanticScore,
310
399
  freqScore: freqScore,
311
- stage1Score: stage1Score
400
+ stage1Score: adjustedStage1
312
401
  };
313
402
  });
314
403
  var stage1Survivors = [];
@@ -341,26 +430,82 @@ export function rankCandidates(candidates, contextVector, getWordVector, lmLogit
341
430
  var values = Object.values(lmLogits);
342
431
  if (values.length > 0) lmMax = Math.max.apply(Math, values);
343
432
  }
433
+ var canonicalEvidenceBySurface = new Map();
434
+ var maxLmRankingValueByTierAndContext = new Map();
435
+ var _iterator4 = _createForOfIteratorHelper(filtered),
436
+ _step4;
437
+ try {
438
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
439
+ var _getCanonicalLmEviden;
440
+ var _entry = _step4.value;
441
+ var evidence = (_getCanonicalLmEviden = getCanonicalLmEvidence === null || getCanonicalLmEvidence === void 0 ? void 0 : getCanonicalLmEvidence(_entry.candidate.word)) !== null && _getCanonicalLmEviden !== void 0 ? _getCanonicalLmEviden : null;
442
+ if (!evidence) {
443
+ continue;
444
+ }
445
+ canonicalEvidenceBySurface.set(_entry.candidate.word, evidence);
446
+ var rankingValue = evidence.source === 'canonical-full-surface' ? evidence.meanTokenLogProbability : evidence.rawLogit;
447
+ if (rankingValue !== undefined && Number.isFinite(rankingValue)) {
448
+ var _maxLmRankingValueByT;
449
+ var key = "".concat(evidence.source, "\0").concat(evidence.contextKey);
450
+ var current = (_maxLmRankingValueByT = maxLmRankingValueByTierAndContext.get(key)) !== null && _maxLmRankingValueByT !== void 0 ? _maxLmRankingValueByT : -Infinity;
451
+ if (rankingValue > current) {
452
+ maxLmRankingValueByTierAndContext.set(key, rankingValue);
453
+ }
454
+ }
455
+ }
456
+ } catch (err) {
457
+ _iterator4.e(err);
458
+ } finally {
459
+ _iterator4.f();
460
+ }
344
461
  var scored = filtered.map(function (entry) {
462
+ var _entry$candidate$term, _canonicalEvidenceByS;
463
+ var termType = (_entry$candidate$term = entry.candidate.termType) !== null && _entry$candidate$term !== void 0 ? _entry$candidate$term : 'word';
464
+ var isMultiWord = termType !== 'word';
345
465
  var lmScore = 0;
346
466
  var finalScore = entry.stage1Score;
347
- if (lmLogits && lmMax >= LM_GATE_THRESHOLD) {
467
+ var lmEvidence = (_canonicalEvidenceByS = canonicalEvidenceBySurface.get(entry.candidate.word)) !== null && _canonicalEvidenceByS !== void 0 ? _canonicalEvidenceByS : null;
468
+ if (lmEvidence) {
469
+ var rankingValue = lmEvidence.source === 'canonical-full-surface' ? lmEvidence.meanTokenLogProbability : lmEvidence.rawLogit;
470
+ var maxRankingValue = maxLmRankingValueByTierAndContext.get("".concat(lmEvidence.source, "\0").concat(lmEvidence.contextKey));
471
+ if (rankingValue !== undefined && maxRankingValue !== undefined) {
472
+ lmEvidence = _objectSpread(_objectSpread({}, lmEvidence), {}, {
473
+ score: Math.exp(rankingValue - maxRankingValue)
474
+ });
475
+ }
476
+ }
477
+ if (lmEvidence) {
478
+ lmScore = lmEvidence.score;
479
+ finalScore = STAGE1_WEIGHT * entry.stage1Score + STAGE2_WEIGHT * lmScore;
480
+ } else if (!isMultiWord && lmLogits && lmMax >= LM_GATE_THRESHOLD) {
481
+ // Backward-compatible network slow-lane path.
348
482
  var rawLm = getLmScore(entry.candidate.word, lmLogits);
349
483
  if (rawLm !== 0) {
350
484
  var logitDiff = Math.log(rawLm) - Math.log(lmMax);
351
485
  lmScore = Math.exp(logitDiff);
486
+ lmEvidence = {
487
+ contextKey: 'network',
488
+ score: lmScore,
489
+ separatorKind: 'whitespace',
490
+ source: 'network-logit',
491
+ totalSurfaceCharCount: entry.candidate.word.length,
492
+ // The legacy BE word map does not report canonical token depth.
493
+ totalTokenCount: 0,
494
+ verifiedCharCount: 0,
495
+ verifiedTokenCount: 0
496
+ };
497
+ finalScore = STAGE1_WEIGHT * entry.stage1Score + STAGE2_WEIGHT * lmScore;
352
498
  }
353
- // Words absent from the prefix-filtered payload get lmScore = 0,
354
- // not 0.05, so they don't outrank genuine LM predictions.
355
-
356
- finalScore = STAGE1_WEIGHT * entry.stage1Score + STAGE2_WEIGHT * lmScore;
357
499
  }
358
500
  return {
359
501
  word: entry.candidate.word,
360
502
  freqScore: entry.freqScore,
361
503
  semanticScore: entry.semanticScore,
362
504
  lmScore: lmScore,
363
- finalScore: finalScore
505
+ lmEvidence: lmEvidence,
506
+ finalScore: finalScore,
507
+ stage1Score: entry.stage1Score,
508
+ termType: termType
364
509
  };
365
510
  });
366
511
  scored.sort(function (a, b) {
@@ -14,7 +14,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
14
14
  */
15
15
 
16
16
  import { abortExp, EXPERIENCE_NAME, failExp, startExp, succeedExp } from '../analytics/ufo';
17
- import { isAutocompleteDebugEnabled } from './debug-mode';
17
+ import { buildAutocompleteGatewayUrl } from './artifact-loader';
18
+ import { CTC_STYLES, ctcTag } from './debug-mode';
18
19
 
19
20
  // ─── Types ───────────────────────────────────────────────────────────────────
20
21
 
@@ -26,8 +27,6 @@ import { isAutocompleteDebugEnabled } from './debug-mode';
26
27
 
27
28
  // eslint-disable-next-line require-unicode-regexp
28
29
  var WORD_BOUNDARY_CHARS = /[\s.,;:!?]/;
29
- // eslint-disable-next-line require-unicode-regexp
30
- var TRAILING_SLASH_REGEX = /\/$/;
31
30
  var DEFAULT_DEBOUNCE_MS = 300;
32
31
 
33
32
  /**
@@ -64,6 +63,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
64
63
  };
65
64
  var debounceTimer = null;
66
65
  var lastRequestedText = '';
66
+ var storedContextInput = null;
67
67
  var storedContextVector = null;
68
68
  var storedLmLogits = null;
69
69
  var requestSeq = 0;
@@ -80,7 +80,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
80
80
  }
81
81
  return _context.abrupt("return");
82
82
  case 1:
83
- url = "".concat(baseUrl.replace(TRAILING_SLASH_REGEX, '')).concat(endpoint);
83
+ url = buildAutocompleteGatewayUrl(endpoint, baseUrl);
84
84
  payload = {
85
85
  text: text,
86
86
  session_id: sessionId
@@ -91,16 +91,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
91
91
  }, surface ? {
92
92
  surface: surface
93
93
  } : {}));
94
- if (isAutocompleteDebugEnabled()) {
95
- // eslint-disable-next-line no-console
96
- console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE4 Sending context | ".concat(text.length, " chars"), 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
97
- text.split('\n').forEach(function (line, i, arr) {
98
- // eslint-disable-next-line no-console
99
- console.log(" ".concat(i === arr.length - 1 ? '▶' : ' ', " ").concat(line));
100
- });
101
- // eslint-disable-next-line no-console
102
- console.groupEnd();
103
- }
94
+ ctcTag('signal', "\uD83D\uDCE4 network context sent \xB7 ".concat(text.length, " chars"), CTC_STYLES.section);
104
95
  _context.prev = 2;
105
96
  _context.next = 3;
106
97
  return fetchFn(url, {
@@ -114,6 +105,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
114
105
  _context.next = 4;
115
106
  break;
116
107
  }
108
+ storedContextInput = null;
117
109
  storedContextVector = null;
118
110
  storedLmLogits = null;
119
111
  failExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, _objectSpread({
@@ -123,10 +115,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
123
115
  }, surface ? {
124
116
  surface: surface
125
117
  } : {}));
126
- if (isAutocompleteDebugEnabled()) {
127
- // eslint-disable-next-line no-console
128
- console.log("%c[SlowLane] %c\u274C Request failed (".concat(res.status, ")"), 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
129
- }
118
+ ctcTag('signal', "\u274C network request failed (".concat(res.status, ")"), CTC_STYLES.bad);
130
119
  return _context.abrupt("return");
131
120
  case 4:
132
121
  _context.next = 5;
@@ -135,24 +124,17 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
135
124
  data = _context.sent;
136
125
  if (data.semantic_vector && Array.isArray(data.semantic_vector)) {
137
126
  storedContextVector = new Float32Array(data.semantic_vector);
127
+ storedContextInput = text;
138
128
  } else {
139
129
  storedContextVector = null;
130
+ storedContextInput = null;
140
131
  }
141
132
  if (data.lm_logits && _typeof(data.lm_logits) === 'object') {
142
133
  storedLmLogits = data.lm_logits;
143
134
  } else {
144
135
  storedLmLogits = null;
145
136
  }
146
- if (isAutocompleteDebugEnabled()) {
147
- // eslint-disable-next-line no-console
148
- console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE5 Response received", 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
149
- // eslint-disable-next-line no-console
150
- console.log(storedContextVector ? "\u2705 semantic_vector: ".concat(storedContextVector.length, " dims") : '❌ No semantic_vector');
151
- // eslint-disable-next-line no-console
152
- console.log(storedLmLogits ? "\u2705 lm_logits: ".concat(Object.keys(storedLmLogits).length, " tokens") : '❌ No lm_logits');
153
- // eslint-disable-next-line no-console
154
- console.groupEnd();
155
- }
137
+ ctcTag('signal', "\uD83D\uDCE5 network response \xB7 ".concat(storedContextVector ? "semantic \u2705 ".concat(storedContextVector.length, "d") : 'semantic ❌', " \xB7 ").concat(storedLmLogits ? "logits \u2705 ".concat(Object.keys(storedLmLogits).length, "tok") : 'logits ❌'), CTC_STYLES.section);
156
138
  succeedExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, _objectSpread({
157
139
  textLength: text.length,
158
140
  hasVector: storedContextVector !== null,
@@ -172,6 +154,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
172
154
  case 6:
173
155
  _context.prev = 6;
174
156
  _t = _context["catch"](2);
157
+ storedContextInput = null;
175
158
  storedContextVector = null;
176
159
  storedLmLogits = null;
177
160
  failExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, _objectSpread({
@@ -180,10 +163,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
180
163
  }, surface ? {
181
164
  surface: surface
182
165
  } : {}));
183
- if (isAutocompleteDebugEnabled()) {
184
- // eslint-disable-next-line no-console
185
- console.log('%c[SlowLane] %c❌ Network error — context cleared', 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
186
- }
166
+ ctcTag('signal', '❌ network error — context cleared', CTC_STYLES.bad);
187
167
  case 7:
188
168
  _context.prev = 7;
189
169
  if (inflightRequestId === requestId) {
@@ -221,6 +201,9 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
221
201
  };
222
202
  return {
223
203
  updateContext: updateContextDebounced,
204
+ getContextInput: function getContextInput() {
205
+ return storedContextInput;
206
+ },
224
207
  getContextVector: function getContextVector() {
225
208
  return storedContextVector;
226
209
  },
@@ -228,6 +211,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
228
211
  return storedLmLogits;
229
212
  },
230
213
  setContextVector: function setContextVector(vector) {
214
+ storedContextInput = null;
231
215
  storedContextVector = vector;
232
216
  },
233
217
  setLmLogits: function setLmLogits(logits) {
@@ -237,14 +221,93 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
237
221
  };
238
222
  };
239
223
  var defaultSlowLaneClient = null;
240
- export var setDefaultSlowLaneClient = function setDefaultSlowLaneClient(client) {
224
+ var defaultSlowLaneClientRegistration = null;
225
+ var supportsCanonicalSurfaceScoring = function supportsCanonicalSurfaceScoring(client) {
226
+ return typeof (client === null || client === void 0 ? void 0 : client.primeBoundaryLm) === 'function' && typeof (client === null || client === void 0 ? void 0 : client.requestProgressiveSurfaceScores) === 'function';
227
+ };
228
+ export var setDefaultSlowLaneClient = function setDefaultSlowLaneClient(client, registration) {
241
229
  defaultSlowLaneClient = client;
230
+ defaultSlowLaneClientRegistration = client ? registration !== null && registration !== void 0 ? registration : {
231
+ clientId: 'untracked',
232
+ kind: supportsCanonicalSurfaceScoring(client) ? 'localLlm' : 'server'
233
+ } : null;
234
+ };
235
+
236
+ /**
237
+ * Clear the shared client only when the caller still owns the registration.
238
+ *
239
+ * Multiple editor instances can briefly overlap during a React/editor remount.
240
+ * An older instance must not disconnect the newer instance when its delayed
241
+ * teardown runs after the newer client has registered.
242
+ */
243
+ export var clearDefaultSlowLaneClient = function clearDefaultSlowLaneClient(client) {
244
+ if (defaultSlowLaneClient !== client) {
245
+ return false;
246
+ }
247
+ defaultSlowLaneClient = null;
248
+ defaultSlowLaneClientRegistration = null;
249
+ return true;
250
+ };
251
+ export var getDefaultSlowLaneClientStatus = function getDefaultSlowLaneClientStatus() {
252
+ var _defaultSlowLaneClien, _defaultSlowLaneClien2, _defaultSlowLaneClien3, _defaultSlowLaneClien4, _defaultSlowLaneClien5, _defaultSlowLaneClien6, _defaultSlowLaneClien7;
253
+ var canonicalScoringSupported = supportsCanonicalSurfaceScoring(defaultSlowLaneClient);
254
+ var isLocalClient = ((_defaultSlowLaneClien = defaultSlowLaneClientRegistration) === null || _defaultSlowLaneClien === void 0 ? void 0 : _defaultSlowLaneClien.kind) === 'localLlm';
255
+ return {
256
+ registered: defaultSlowLaneClient !== null,
257
+ clientId: (_defaultSlowLaneClien2 = (_defaultSlowLaneClien3 = defaultSlowLaneClientRegistration) === null || _defaultSlowLaneClien3 === void 0 ? void 0 : _defaultSlowLaneClien3.clientId) !== null && _defaultSlowLaneClien2 !== void 0 ? _defaultSlowLaneClien2 : null,
258
+ clientKind: (_defaultSlowLaneClien4 = (_defaultSlowLaneClien5 = defaultSlowLaneClientRegistration) === null || _defaultSlowLaneClien5 === void 0 ? void 0 : _defaultSlowLaneClien5.kind) !== null && _defaultSlowLaneClien4 !== void 0 ? _defaultSlowLaneClien4 : null,
259
+ canonicalScoringSupported: canonicalScoringSupported,
260
+ localModelReady: isLocalClient && typeof ((_defaultSlowLaneClien6 = defaultSlowLaneClient) === null || _defaultSlowLaneClien6 === void 0 ? void 0 : _defaultSlowLaneClien6.isReady) === 'function' ? defaultSlowLaneClient.isReady() : null,
261
+ canonicalSurfaceCount: canonicalScoringSupported && typeof ((_defaultSlowLaneClien7 = defaultSlowLaneClient) === null || _defaultSlowLaneClien7 === void 0 ? void 0 : _defaultSlowLaneClien7.getCanonicalSurfaceCount) === 'function' ? defaultSlowLaneClient.getCanonicalSurfaceCount() : null
262
+ };
242
263
  };
243
264
  export var getStoredContextVector = function getStoredContextVector() {
244
- var _defaultSlowLaneClien, _defaultSlowLaneClien2;
245
- return (_defaultSlowLaneClien = (_defaultSlowLaneClien2 = defaultSlowLaneClient) === null || _defaultSlowLaneClien2 === void 0 ? void 0 : _defaultSlowLaneClien2.getContextVector()) !== null && _defaultSlowLaneClien !== void 0 ? _defaultSlowLaneClien : null;
265
+ var _defaultSlowLaneClien8, _defaultSlowLaneClien9;
266
+ return (_defaultSlowLaneClien8 = (_defaultSlowLaneClien9 = defaultSlowLaneClient) === null || _defaultSlowLaneClien9 === void 0 ? void 0 : _defaultSlowLaneClien9.getContextVector()) !== null && _defaultSlowLaneClien8 !== void 0 ? _defaultSlowLaneClien8 : null;
267
+ };
268
+ export var getStoredContextInput = function getStoredContextInput() {
269
+ var _defaultSlowLaneClien0, _defaultSlowLaneClien1, _defaultSlowLaneClien10;
270
+ return (_defaultSlowLaneClien0 = (_defaultSlowLaneClien1 = defaultSlowLaneClient) === null || _defaultSlowLaneClien1 === void 0 || (_defaultSlowLaneClien10 = _defaultSlowLaneClien1.getContextInput) === null || _defaultSlowLaneClien10 === void 0 ? void 0 : _defaultSlowLaneClien10.call(_defaultSlowLaneClien1)) !== null && _defaultSlowLaneClien0 !== void 0 ? _defaultSlowLaneClien0 : null;
246
271
  };
247
272
  export var getStoredLmLogits = function getStoredLmLogits() {
248
- var _defaultSlowLaneClien3, _defaultSlowLaneClien4;
249
- return (_defaultSlowLaneClien3 = (_defaultSlowLaneClien4 = defaultSlowLaneClient) === null || _defaultSlowLaneClien4 === void 0 ? void 0 : _defaultSlowLaneClien4.getLmLogits()) !== null && _defaultSlowLaneClien3 !== void 0 ? _defaultSlowLaneClien3 : null;
273
+ var _defaultSlowLaneClien11, _defaultSlowLaneClien12;
274
+ return (_defaultSlowLaneClien11 = (_defaultSlowLaneClien12 = defaultSlowLaneClient) === null || _defaultSlowLaneClien12 === void 0 ? void 0 : _defaultSlowLaneClien12.getLmLogits()) !== null && _defaultSlowLaneClien11 !== void 0 ? _defaultSlowLaneClien11 : null;
275
+ };
276
+ export var getBoundaryLmState = function getBoundaryLmState(contextKey) {
277
+ var _defaultSlowLaneClien13, _defaultSlowLaneClien14, _defaultSlowLaneClien15;
278
+ return (_defaultSlowLaneClien13 = (_defaultSlowLaneClien14 = defaultSlowLaneClient) === null || _defaultSlowLaneClien14 === void 0 || (_defaultSlowLaneClien15 = _defaultSlowLaneClien14.getBoundaryLmState) === null || _defaultSlowLaneClien15 === void 0 ? void 0 : _defaultSlowLaneClien15.call(_defaultSlowLaneClien14, contextKey)) !== null && _defaultSlowLaneClien13 !== void 0 ? _defaultSlowLaneClien13 : null;
279
+ };
280
+ export var getCanonicalSurfaceTokenIds = function getCanonicalSurfaceTokenIds(surface) {
281
+ var _defaultSlowLaneClien16, _defaultSlowLaneClien17, _defaultSlowLaneClien18;
282
+ return (_defaultSlowLaneClien16 = (_defaultSlowLaneClien17 = defaultSlowLaneClient) === null || _defaultSlowLaneClien17 === void 0 || (_defaultSlowLaneClien18 = _defaultSlowLaneClien17.getCanonicalSurfaceTokenIds) === null || _defaultSlowLaneClien18 === void 0 ? void 0 : _defaultSlowLaneClien18.call(_defaultSlowLaneClien17, surface)) !== null && _defaultSlowLaneClien16 !== void 0 ? _defaultSlowLaneClien16 : null;
283
+ };
284
+ export var getSurfaceScore = function getSurfaceScore(contextKey, surface) {
285
+ var _defaultSlowLaneClien19, _defaultSlowLaneClien20, _defaultSlowLaneClien21;
286
+ return (_defaultSlowLaneClien19 = (_defaultSlowLaneClien20 = defaultSlowLaneClient) === null || _defaultSlowLaneClien20 === void 0 || (_defaultSlowLaneClien21 = _defaultSlowLaneClien20.getSurfaceScore) === null || _defaultSlowLaneClien21 === void 0 ? void 0 : _defaultSlowLaneClien21.call(_defaultSlowLaneClien20, contextKey, surface)) !== null && _defaultSlowLaneClien19 !== void 0 ? _defaultSlowLaneClien19 : null;
287
+ };
288
+ export var getProgressiveSurfaceEvidence = function getProgressiveSurfaceEvidence(contextKey, surface) {
289
+ var _defaultSlowLaneClien22, _defaultSlowLaneClien23, _defaultSlowLaneClien24;
290
+ return (_defaultSlowLaneClien22 = (_defaultSlowLaneClien23 = defaultSlowLaneClient) === null || _defaultSlowLaneClien23 === void 0 || (_defaultSlowLaneClien24 = _defaultSlowLaneClien23.getProgressiveSurfaceEvidence) === null || _defaultSlowLaneClien24 === void 0 ? void 0 : _defaultSlowLaneClien24.call(_defaultSlowLaneClien23, contextKey, surface)) !== null && _defaultSlowLaneClien22 !== void 0 ? _defaultSlowLaneClien22 : null;
291
+ };
292
+ export var primeBoundaryLm = function primeBoundaryLm(input) {
293
+ var _defaultSlowLaneClien25, _defaultSlowLaneClien26;
294
+ (_defaultSlowLaneClien25 = defaultSlowLaneClient) === null || _defaultSlowLaneClien25 === void 0 || (_defaultSlowLaneClien26 = _defaultSlowLaneClien25.primeBoundaryLm) === null || _defaultSlowLaneClien26 === void 0 || _defaultSlowLaneClien26.call(_defaultSlowLaneClien25, input);
295
+ };
296
+ export var requestProgressiveSurfaceScores = function requestProgressiveSurfaceScores(input) {
297
+ var _defaultSlowLaneClien27, _defaultSlowLaneClien28;
298
+ (_defaultSlowLaneClien27 = defaultSlowLaneClient) === null || _defaultSlowLaneClien27 === void 0 || (_defaultSlowLaneClien28 = _defaultSlowLaneClien27.requestProgressiveSurfaceScores) === null || _defaultSlowLaneClien28 === void 0 || _defaultSlowLaneClien28.call(_defaultSlowLaneClien27, input);
299
+ };
300
+ export var isCanonicalSurfaceScoringSupported = function isCanonicalSurfaceScoringSupported() {
301
+ return supportsCanonicalSurfaceScoring(defaultSlowLaneClient);
302
+ };
303
+
304
+ /**
305
+ * How many surfaces the canonical token map currently holds. Goes from zero to
306
+ * its final size once the artifact lands, which is the only point at which
307
+ * `getCanonicalSurfaceTokenIds` starts answering — so callers memoising over
308
+ * that lookup can use this to detect the transition.
309
+ */
310
+ export var getCanonicalSurfaceCount = function getCanonicalSurfaceCount() {
311
+ var _defaultSlowLaneClien29, _defaultSlowLaneClien30, _defaultSlowLaneClien31;
312
+ return (_defaultSlowLaneClien29 = (_defaultSlowLaneClien30 = defaultSlowLaneClient) === null || _defaultSlowLaneClien30 === void 0 || (_defaultSlowLaneClien31 = _defaultSlowLaneClien30.getCanonicalSurfaceCount) === null || _defaultSlowLaneClien31 === void 0 ? void 0 : _defaultSlowLaneClien31.call(_defaultSlowLaneClien30)) !== null && _defaultSlowLaneClien29 !== void 0 ? _defaultSlowLaneClien29 : 0;
250
313
  };