@atlaskit/editor-plugin-autocomplete 6.0.0 → 8.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 (61) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/compass.yml +2 -2
  3. package/dist/cjs/analytics/ufo.js +3 -2
  4. package/dist/cjs/pm-plugins/artifacts-manifest.js +210 -0
  5. package/dist/cjs/pm-plugins/autocomplete-plugin.js +10 -2
  6. package/dist/cjs/pm-plugins/local-slow-lane-client.js +68 -153
  7. package/dist/cjs/pm-plugins/scoring-pipeline.js +130 -28
  8. package/dist/cjs/pm-plugins/text-predictor.js +45 -106
  9. package/dist/es2019/analytics/ufo.js +4 -2
  10. package/dist/es2019/pm-plugins/artifacts-manifest.js +126 -0
  11. package/dist/es2019/pm-plugins/autocomplete-plugin.js +10 -2
  12. package/dist/es2019/pm-plugins/local-slow-lane-client.js +8 -78
  13. package/dist/es2019/pm-plugins/scoring-pipeline.js +97 -21
  14. package/dist/es2019/pm-plugins/text-predictor.js +17 -59
  15. package/dist/esm/analytics/ufo.js +3 -2
  16. package/dist/esm/pm-plugins/artifacts-manifest.js +204 -0
  17. package/dist/esm/pm-plugins/autocomplete-plugin.js +10 -2
  18. package/dist/esm/pm-plugins/local-slow-lane-client.js +67 -148
  19. package/dist/esm/pm-plugins/scoring-pipeline.js +128 -26
  20. package/dist/esm/pm-plugins/text-predictor.js +45 -98
  21. package/dist/types/analytics/ufo.d.ts +1 -0
  22. package/dist/types/pm-plugins/artifacts-manifest.d.ts +55 -0
  23. package/dist/types/pm-plugins/autocomplete-plugin.d.ts +5 -11
  24. package/dist/types/pm-plugins/scoring-pipeline.d.ts +14 -0
  25. package/dist/types/pm-plugins/text-predictor.d.ts +0 -1
  26. package/package.json +3 -6
  27. package/src/analytics/ufo.ts +5 -0
  28. package/src/pm-plugins/artifacts-manifest.ts +151 -0
  29. package/src/pm-plugins/autocomplete-plugin.ts +14 -12
  30. package/src/pm-plugins/local-slow-lane-client.ts +10 -92
  31. package/src/pm-plugins/scoring-pipeline.ts +115 -23
  32. package/src/pm-plugins/text-predictor.ts +28 -76
  33. package/dist/cjs/pm-plugins/data/combined_l2_l3_pos_tags.json +0 -73571
  34. package/dist/cjs/pm-plugins/data/first_token_to_words.json +0 -1
  35. package/dist/cjs/pm-plugins/data/ghost_pos_tags.json +0 -43
  36. package/dist/cjs/pm-plugins/data/grammar_transitions_10k.json +0 -46
  37. package/dist/cjs/pm-plugins/data/l3_vocabulary.json +0 -20002
  38. package/dist/cjs/pm-plugins/data/vocabulary_10k.json +0 -38794
  39. package/dist/cjs/pm-plugins/data/word_index_10k.json +0 -7762
  40. package/dist/es2019/pm-plugins/data/combined_l2_l3_pos_tags.json +0 -73571
  41. package/dist/es2019/pm-plugins/data/first_token_to_words.json +0 -1
  42. package/dist/es2019/pm-plugins/data/ghost_pos_tags.json +0 -43
  43. package/dist/es2019/pm-plugins/data/grammar_transitions_10k.json +0 -46
  44. package/dist/es2019/pm-plugins/data/l3_vocabulary.json +0 -20002
  45. package/dist/es2019/pm-plugins/data/vocabulary_10k.json +0 -38794
  46. package/dist/es2019/pm-plugins/data/word_index_10k.json +0 -7762
  47. package/dist/esm/pm-plugins/data/combined_l2_l3_pos_tags.json +0 -73571
  48. package/dist/esm/pm-plugins/data/first_token_to_words.json +0 -1
  49. package/dist/esm/pm-plugins/data/ghost_pos_tags.json +0 -43
  50. package/dist/esm/pm-plugins/data/grammar_transitions_10k.json +0 -46
  51. package/dist/esm/pm-plugins/data/l3_vocabulary.json +0 -20002
  52. package/dist/esm/pm-plugins/data/vocabulary_10k.json +0 -38794
  53. package/dist/esm/pm-plugins/data/word_index_10k.json +0 -7762
  54. package/src/pm-plugins/data/combined_l2_l3_pos_tags.json +0 -73571
  55. package/src/pm-plugins/data/first_token_to_words.json +0 -1
  56. package/src/pm-plugins/data/ghost_pos_tags.json +0 -43
  57. package/src/pm-plugins/data/grammar_transitions_10k.json +0 -46
  58. package/src/pm-plugins/data/l3_vocabulary.json +0 -20002
  59. package/src/pm-plugins/data/vocabulary_10k.json +0 -38794
  60. package/src/pm-plugins/data/word-vectors_10k.bin +0 -3
  61. package/src/pm-plugins/data/word_index_10k.json +0 -7762
@@ -1,16 +1,15 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
- import _typeof from "@babel/runtime/helpers/typeof";
5
4
  import _createClass from "@babel/runtime/helpers/createClass";
6
5
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
7
6
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
8
7
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
8
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
- import _regeneratorRuntime from "@babel/runtime/regenerator";
11
9
  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; } } }; }
12
10
  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; } }
13
11
  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; }
12
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
14
13
  /**
15
14
  * Local Slow Lane Client: On-device inference via @mlc-ai/web-llm.
16
15
  *
@@ -49,6 +48,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
49
48
  */
50
49
 
51
50
  import { abortExp, EXPERIENCE_NAME, failExp, startExp, succeedExp } from '../analytics/ufo';
51
+ import { ARTIFACT_NAME, fetchArtifactJson } from './artifacts-manifest';
52
52
  import { isAutocompleteDebugEnabled } from './debug-mode';
53
53
  import { isWordBoundary } from './slow-lane-client';
54
54
 
@@ -236,88 +236,9 @@ var prefixMapTokenIds = [];
236
236
  var bePayloadDataPromise;
237
237
 
238
238
  /**
239
- * Unwrap a dynamically imported JSON module to the parsed JSON value, working
240
- * across the two interop modes AFM's bundler chain emits:
241
- *
242
- * 1. **`.default`-wrapped namespace** — classic webpack (and Jest) hang the
243
- * JSON value under the `default` export.
244
- * 2. **Named-exports namespace** — webpack 5 / atlaspack with JSON
245
- * named-exports (or native ESM JSON modules) expose each top-level key as
246
- * a named export and shadow `default`, so `mod.default` can be `undefined`
247
- * (or some unrelated value) even though `mod` itself holds the data.
248
- *
249
- * The caller MUST declare the underlying JSON shape via `shape` because, in
250
- * named-exports mode, a dense array `["a","b"]` and a sparse numeric-keyed
251
- * object `{"5":"a","12":"b"}` are emitted identically (`{"0":..}` / `{"5":..}`);
252
- * no runtime heuristic can tell them apart, so only the caller knows which:
253
- *
254
- * - `'object'` — the JSON is a `{...}` (including sparse maps keyed by integer
255
- * IDs). The named exports are rebuilt into a plain object so `Object.entries`
256
- * yields the real keys, not synthetic array indices.
257
- * - `'array'` — the JSON is a `[...]`, reconstructed from the `0..n-1` indices.
258
- *
259
- * :param mod: The raw module object returned by `await import('./*.json')`.
260
- * :param shape: `'object'` if the source JSON is `{...}`, `'array'` if `[...]`.
261
- * :returns: The parsed JSON value, or `null` if neither interop mode applies.
262
- */
263
- function unwrapJsonModule(mod, shape) {
264
- if (mod == null || _typeof(mod) !== 'object') {
265
- return null;
266
- }
267
- var namespace = mod;
268
-
269
- // Compute the named-export own-keys (strip synthetic markers).
270
- var ownKeys = Object.keys(namespace).filter(function (k) {
271
- return k !== 'default' && k !== '__esModule';
272
- });
273
-
274
- // PREFER named exports when present — they always reflect the JSON's real
275
- // top-level keys / indices, regardless of what `default` happens to be.
276
- // Under JSON named-exports mode `default` is not necessarily the parsed
277
- // value (e.g. for `{"service": 0, ...}` it can be the number `0`, with the
278
- // real data in the named exports), so taking `default` first would corrupt it.
279
- if (ownKeys.length > 0) {
280
- if (shape === 'array') {
281
- // JSON arrays are dense; reconstruct from `0..length-1` indices.
282
- var len = ownKeys.length;
283
- var arr = new Array(len);
284
- for (var i = 0; i < len; i++) {
285
- arr[i] = namespace[String(i)];
286
- }
287
- return arr;
288
- }
289
- // shape === 'object'. Rebuild a plain object from the (stripped) own
290
- // keys so callers can `Object.entries()` it without iterating over
291
- // `default` / `__esModule`, and to detach from the module-namespace
292
- // object (which is sealed/non-extensible on some bundler outputs).
293
- var obj = {};
294
- var _iterator = _createForOfIteratorHelper(ownKeys),
295
- _step;
296
- try {
297
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
298
- var k = _step.value;
299
- obj[k] = namespace[k];
300
- }
301
- } catch (err) {
302
- _iterator.e(err);
303
- } finally {
304
- _iterator.f();
305
- }
306
- return obj;
307
- }
308
-
309
- // Fallback: no named exports — classic webpack JSON-module interop where
310
- // the whole parsed JSON value is hung under `default`. Trust it.
311
- if ('default' in namespace && namespace.default != null) {
312
- return namespace.default;
313
- }
314
- return null;
315
- }
316
-
317
- /**
318
- * Lazily load and build the BE-parity lookup tables from their JSON payloads.
319
- * The dynamic imports are split into their own async chunks so neither file is
320
- * bundled into the editor's main chunk unless local inference is initialised.
239
+ * Lazily load and build the BE-parity lookup tables from their CDN payloads.
240
+ * Both artifacts are fetched on demand so neither is downloaded unless local
241
+ * inference is initialised.
321
242
  *
322
243
  * :returns:
323
244
  * A promise that resolves once `firstTokenToWords`, `l2Words` and
@@ -326,24 +247,22 @@ function unwrapJsonModule(mod, shape) {
326
247
  var loadBePayloadData = function loadBePayloadData() {
327
248
  if (!bePayloadDataPromise) {
328
249
  bePayloadDataPromise = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
329
- var _yield$Promise$all, _yield$Promise$all2, firstTokenToWordsModule, vocabularyModule, firstTokenToWordsData, vocabularyData;
250
+ var _yield$Promise$all, _yield$Promise$all2, firstTokenToWordsData, vocabularyData;
330
251
  return _regeneratorRuntime.wrap(function (_context) {
331
252
  while (1) switch (_context.prev = _context.next) {
332
253
  case 0:
333
254
  _context.next = 1;
334
- return Promise.all([import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-first-token-to-words" */'./data/first_token_to_words.json'), import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-vocabulary-10k" */'./data/vocabulary_10k.json')]);
255
+ return Promise.all([fetchArtifactJson(ARTIFACT_NAME.FIRST_TOKEN_TO_WORDS), fetchArtifactJson(ARTIFACT_NAME.VOCABULARY)]);
335
256
  case 1:
336
257
  _yield$Promise$all = _context.sent;
337
258
  _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
338
- firstTokenToWordsModule = _yield$Promise$all2[0];
339
- vocabularyModule = _yield$Promise$all2[1];
340
- firstTokenToWordsData = unwrapJsonModule(firstTokenToWordsModule, 'object');
341
- vocabularyData = unwrapJsonModule(vocabularyModule, 'object');
259
+ firstTokenToWordsData = _yield$Promise$all2[0];
260
+ vocabularyData = _yield$Promise$all2[1];
342
261
  if (!(firstTokenToWordsData == null || (vocabularyData === null || vocabularyData === void 0 ? void 0 : vocabularyData.words) == null)) {
343
262
  _context.next = 2;
344
263
  break;
345
264
  }
346
- throw new Error("[LocalSlowLane] JSON module could not be unwrapped \u2014 " + "firstTokenToWordsData=".concat(firstTokenToWordsData == null ? 'null/undefined' : 'defined', ", ") + "vocabularyData=".concat(vocabularyData == null ? 'null/undefined' : vocabularyData.words == null ? 'defined but missing .words' : 'defined'));
265
+ throw new Error("[LocalSlowLane] unexpected artifact payload \u2014 " + "firstTokenToWordsData=".concat(firstTokenToWordsData == null ? 'null/undefined' : 'defined', ", ") + "vocabularyData=".concat(vocabularyData == null ? 'null/undefined' : vocabularyData.words == null ? 'defined but missing .words' : 'defined'));
347
266
  case 2:
348
267
  firstTokenToWords = new Map(Object.entries(firstTokenToWordsData).map(function (_ref2) {
349
268
  var _ref3 = _slicedToArray(_ref2, 2),
@@ -400,28 +319,28 @@ export var computeBePayload = function computeBePayload(rawLogits, prefixMap, do
400
319
  var validTokenIds = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : prefixMapTokenIds;
401
320
  // 1. Numerically-stable masked softmax over validTokenIds only.
402
321
  var maxLogit = -Infinity;
403
- var _iterator2 = _createForOfIteratorHelper(validTokenIds),
404
- _step2;
322
+ var _iterator = _createForOfIteratorHelper(validTokenIds),
323
+ _step;
405
324
  try {
406
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
407
- var id = _step2.value;
325
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
326
+ var id = _step.value;
408
327
  var v = rawLogits[id];
409
328
  if (v > maxLogit) {
410
329
  maxLogit = v;
411
330
  }
412
331
  }
413
332
  } catch (err) {
414
- _iterator2.e(err);
333
+ _iterator.e(err);
415
334
  } finally {
416
- _iterator2.f();
335
+ _iterator.f();
417
336
  }
418
337
  var sumExp = 0;
419
338
  var expByToken = new Map();
420
- var _iterator3 = _createForOfIteratorHelper(validTokenIds),
421
- _step3;
339
+ var _iterator2 = _createForOfIteratorHelper(validTokenIds),
340
+ _step2;
422
341
  try {
423
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
424
- var _id = _step3.value;
342
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
343
+ var _id = _step2.value;
425
344
  var e = Math.exp(rawLogits[_id] - maxLogit);
426
345
  expByToken.set(_id, e);
427
346
  sumExp += e;
@@ -430,53 +349,53 @@ export var computeBePayload = function computeBePayload(rawLogits, prefixMap, do
430
349
  // 2. Prefix expansion with max aggregation (probabilities sum to 1 over the
431
350
  // masked subset, so divide each token's exp by sumExp on the fly).
432
351
  } catch (err) {
433
- _iterator3.e(err);
352
+ _iterator2.e(err);
434
353
  } finally {
435
- _iterator3.f();
354
+ _iterator2.f();
436
355
  }
437
356
  var wordProbs = new Map();
438
- var _iterator4 = _createForOfIteratorHelper(prefixMap),
439
- _step4;
357
+ var _iterator3 = _createForOfIteratorHelper(prefixMap),
358
+ _step3;
440
359
  try {
441
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
360
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
442
361
  var _expByToken$get;
443
- var _step4$value = _slicedToArray(_step4.value, 2),
444
- _id2 = _step4$value[0],
445
- words = _step4$value[1];
362
+ var _step3$value = _slicedToArray(_step3.value, 2),
363
+ _id2 = _step3$value[0],
364
+ words = _step3$value[1];
446
365
  var _p = sumExp > 0 ? ((_expByToken$get = expByToken.get(_id2)) !== null && _expByToken$get !== void 0 ? _expByToken$get : 0) / sumExp : 0;
447
- var _iterator9 = _createForOfIteratorHelper(words),
448
- _step9;
366
+ var _iterator8 = _createForOfIteratorHelper(words),
367
+ _step8;
449
368
  try {
450
- for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
369
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
451
370
  var _wordProbs$get2;
452
- var _w = _step9.value;
371
+ var _w = _step8.value;
453
372
  var prev = (_wordProbs$get2 = wordProbs.get(_w)) !== null && _wordProbs$get2 !== void 0 ? _wordProbs$get2 : 0;
454
373
  if (_p > prev) {
455
374
  wordProbs.set(_w, _p);
456
375
  }
457
376
  }
458
377
  } catch (err) {
459
- _iterator9.e(err);
378
+ _iterator8.e(err);
460
379
  } finally {
461
- _iterator9.f();
380
+ _iterator8.f();
462
381
  }
463
382
  }
464
383
 
465
384
  // 3. Split into L2 / L3 and reserve the top L2 slots unconditionally.
466
385
  } catch (err) {
467
- _iterator4.e(err);
386
+ _iterator3.e(err);
468
387
  } finally {
469
- _iterator4.f();
388
+ _iterator3.f();
470
389
  }
471
390
  var l2Matches = [];
472
391
  var l3Matches = [];
473
- var _iterator5 = _createForOfIteratorHelper(wordProbs),
474
- _step5;
392
+ var _iterator4 = _createForOfIteratorHelper(wordProbs),
393
+ _step4;
475
394
  try {
476
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
477
- var _step5$value = _slicedToArray(_step5.value, 2),
478
- _w2 = _step5$value[0],
479
- _p2 = _step5$value[1];
395
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
396
+ var _step4$value = _slicedToArray(_step4.value, 2),
397
+ _w2 = _step4$value[0],
398
+ _p2 = _step4$value[1];
480
399
  if (domainWords.has(_w2)) {
481
400
  l2Matches.push([_w2, _p2]);
482
401
  } else {
@@ -484,9 +403,9 @@ export var computeBePayload = function computeBePayload(rawLogits, prefixMap, do
484
403
  }
485
404
  }
486
405
  } catch (err) {
487
- _iterator5.e(err);
406
+ _iterator4.e(err);
488
407
  } finally {
489
- _iterator5.f();
408
+ _iterator4.f();
490
409
  }
491
410
  l2Matches.sort(function (a, b) {
492
411
  return b[1] - a[1];
@@ -499,19 +418,19 @@ export var computeBePayload = function computeBePayload(rawLogits, prefixMap, do
499
418
  // it directly rather than allocating a Set and scanning every entry on this
500
419
  // hot path (runs ~every word boundary while typing).
501
420
  var pool = [];
502
- var _iterator6 = _createForOfIteratorHelper(l2Matches.slice(BE_PARITY.RESERVED_L2_SLOTS)),
503
- _step6;
421
+ var _iterator5 = _createForOfIteratorHelper(l2Matches.slice(BE_PARITY.RESERVED_L2_SLOTS)),
422
+ _step5;
504
423
  try {
505
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
506
- var _step6$value = _slicedToArray(_step6.value, 2),
507
- _w3 = _step6$value[0],
508
- _p3 = _step6$value[1];
424
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
425
+ var _step5$value = _slicedToArray(_step5.value, 2),
426
+ _w3 = _step5$value[0],
427
+ _p3 = _step5$value[1];
509
428
  pool.push([_w3, Math.log(Math.max(_p3, 1e-10)) + BE_PARITY.L2_BIAS]);
510
429
  }
511
430
  } catch (err) {
512
- _iterator6.e(err);
431
+ _iterator5.e(err);
513
432
  } finally {
514
- _iterator6.f();
433
+ _iterator5.f();
515
434
  }
516
435
  for (var _i = 0, _l3Matches = l3Matches; _i < _l3Matches.length; _i++) {
517
436
  var _l3Matches$_i = _slicedToArray(_l3Matches[_i], 2),
@@ -544,33 +463,33 @@ export var computeBePayload = function computeBePayload(rawLogits, prefixMap, do
544
463
  }
545
464
  result[key] = prob;
546
465
  };
547
- var _iterator7 = _createForOfIteratorHelper(reserved),
548
- _step7;
466
+ var _iterator6 = _createForOfIteratorHelper(reserved),
467
+ _step6;
549
468
  try {
550
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
551
- var _step7$value = _slicedToArray(_step7.value, 2),
552
- _w4 = _step7$value[0],
553
- _p4 = _step7$value[1];
469
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
470
+ var _step6$value = _slicedToArray(_step6.value, 2),
471
+ _w4 = _step6$value[0],
472
+ _p4 = _step6$value[1];
554
473
  addEntry(_w4, _p4, true);
555
474
  }
556
475
  } catch (err) {
557
- _iterator7.e(err);
476
+ _iterator6.e(err);
558
477
  } finally {
559
- _iterator7.f();
478
+ _iterator6.f();
560
479
  }
561
- var _iterator8 = _createForOfIteratorHelper(poolWinners),
562
- _step8;
480
+ var _iterator7 = _createForOfIteratorHelper(poolWinners),
481
+ _step7;
563
482
  try {
564
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
483
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
565
484
  var _wordProbs$get3;
566
- var _step8$value = _slicedToArray(_step8.value, 1),
567
- _w5 = _step8$value[0];
485
+ var _step7$value = _slicedToArray(_step7.value, 1),
486
+ _w5 = _step7$value[0];
568
487
  addEntry(_w5, (_wordProbs$get3 = wordProbs.get(_w5)) !== null && _wordProbs$get3 !== void 0 ? _wordProbs$get3 : 0, false);
569
488
  }
570
489
  } catch (err) {
571
- _iterator8.e(err);
490
+ _iterator7.e(err);
572
491
  } finally {
573
- _iterator8.f();
492
+ _iterator7.f();
574
493
  }
575
494
  if (isAutocompleteDebugEnabled()) {
576
495
  var topReserved = reserved.slice(0, 5).map(function (_ref4) {
@@ -1,17 +1,25 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
1
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
4
  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; } } }; }
3
5
  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; } }
4
6
  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; }
7
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
10
  /**
6
11
  * Scoring Pipeline: Stage 1 (Semantic + Frequency), Grammar Filter, Stage 2 (LM Re-ranking).
7
12
  *
8
13
  * Operates synchronously on pre-loaded data. Each stage gracefully degrades
9
14
  * when its required data isn't available (cold → warm → full warm).
15
+ *
16
+ * The grammar/POS payloads are fetched from the CDN by loadGrammarDataAsync, so
17
+ * the grammar filter is a pass-through until that resolves.
10
18
  */
11
19
 
12
- import posTagsData from './data/combined_l2_l3_pos_tags.json';
13
- import ghostPosTagsData from './data/ghost_pos_tags.json';
14
- import grammarTransitionsData from './data/grammar_transitions_10k.json';
20
+ import { EXPERIENCE_NAME, failExp, startExp, succeedExp } from '../analytics/ufo';
21
+ import { ARTIFACT_NAME, fetchArtifactJson } from './artifacts-manifest';
22
+ import { isAutocompleteDebugEnabled } from './debug-mode';
15
23
 
16
24
  // ─── Types ──────────────────────────────────────────────────
17
25
 
@@ -32,22 +40,119 @@ var L1_SESSION_CAP = 1.2;
32
40
  // at 0.00024) from triggering re-ranking.
33
41
  var LM_GATE_THRESHOLD = 0.0005;
34
42
 
35
- // ─── Grammar Data (loaded once on import) ───────────────────
43
+ // ─── Grammar Data (fetched once from the CDN) ────────────────
44
+
45
+ var posTags = new Map();
46
+
47
+ /**
48
+ * GHOST POS DICTIONARY
49
+ * A mapping of common structural English words that were stripped from the main
50
+ * domain vocabulary. This allows the grammar filter to understand context
51
+ * without suggesting these words to the user.
52
+ */
53
+ var ghostPosTags = {};
36
54
 
37
- var posTags = new Map(Object.entries(posTagsData));
38
- var grammarTransitions = grammarTransitionsData;
55
+ /**
56
+ * Precomputed map from each POS tag to the set of allowed next POS tags, so
57
+ * applyGrammarFilter never re-iterates the transition rules per call.
58
+ */
59
+ var precomputedAllowedByPos = new Map();
60
+ var grammarDataPromise;
61
+ var setGrammarData = function setGrammarData(data) {
62
+ var _data$grammarTransiti;
63
+ posTags = new Map(Object.entries(data.posTags));
64
+ ghostPosTags = data.ghostPosTags;
65
+ precomputedAllowedByPos = new Map(Object.entries((_data$grammarTransiti = data.grammarTransitions.transitions) !== null && _data$grammarTransiti !== void 0 ? _data$grammarTransiti : {}).map(function (_ref) {
66
+ var _ref2 = _slicedToArray(_ref, 2),
67
+ pos = _ref2[0],
68
+ rule = _ref2[1];
69
+ return [pos, new Set(rule.allowed)];
70
+ }));
71
+ };
72
+ export var isGrammarDataLoaded = function isGrammarDataLoaded() {
73
+ return precomputedAllowedByPos.size > 0;
74
+ };
39
75
 
40
76
  /**
41
- * Precomputed map from each POS tag to the set of allowed next POS tags.
42
- * Built once at module load from grammarTransitions so applyGrammarFilter
43
- * never re-iterates the transition rules per call.
77
+ * Fetch the POS tag and grammar transition payloads from the CDN.
78
+ *
79
+ * Safe to call repeatedly: the in-flight promise is shared, and a failure is not
80
+ * cached so a later call can retry.
44
81
  */
45
- var precomputedAllowedByPos = new Map(Object.entries(grammarTransitions.transitions).map(function (_ref) {
46
- var _ref2 = _slicedToArray(_ref, 2),
47
- pos = _ref2[0],
48
- rule = _ref2[1];
49
- return [pos, new Set(rule.allowed)];
50
- }));
82
+ export var loadGrammarDataAsync = function loadGrammarDataAsync(options) {
83
+ var _options$isLocalLLM;
84
+ if (grammarDataPromise) {
85
+ return grammarDataPromise;
86
+ }
87
+ var isLocalLLM = (_options$isLocalLLM = options === null || options === void 0 ? void 0 : options.isLocalLLM) !== null && _options$isLocalLLM !== void 0 ? _options$isLocalLLM : false;
88
+ var surface = options === null || options === void 0 ? void 0 : options.surface;
89
+ grammarDataPromise = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
90
+ var _yield$Promise$all, _yield$Promise$all2, posTagsData, ghostPosTagsData, grammarTransitionsData, _t;
91
+ return _regeneratorRuntime.wrap(function (_context) {
92
+ while (1) switch (_context.prev = _context.next) {
93
+ case 0:
94
+ startExp(EXPERIENCE_NAME.LOAD_GRAMMAR, 'singleton', _objectSpread({
95
+ isLocalLLM: isLocalLLM
96
+ }, surface ? {
97
+ surface: surface
98
+ } : {}));
99
+ _context.prev = 1;
100
+ _context.next = 2;
101
+ return Promise.all([fetchArtifactJson(ARTIFACT_NAME.POS_TAGS), fetchArtifactJson(ARTIFACT_NAME.GHOST_POS_TAGS), fetchArtifactJson(ARTIFACT_NAME.GRAMMAR_TRANSITIONS)]);
102
+ case 2:
103
+ _yield$Promise$all = _context.sent;
104
+ _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 3);
105
+ posTagsData = _yield$Promise$all2[0];
106
+ ghostPosTagsData = _yield$Promise$all2[1];
107
+ grammarTransitionsData = _yield$Promise$all2[2];
108
+ if (!((grammarTransitionsData === null || grammarTransitionsData === void 0 ? void 0 : grammarTransitionsData.transitions) == null)) {
109
+ _context.next = 3;
110
+ break;
111
+ }
112
+ throw new Error("[scoring-pipeline] ".concat(ARTIFACT_NAME.GRAMMAR_TRANSITIONS, " is missing its `transitions` wrapper"));
113
+ case 3:
114
+ setGrammarData({
115
+ posTags: posTagsData !== null && posTagsData !== void 0 ? posTagsData : {},
116
+ ghostPosTags: ghostPosTagsData !== null && ghostPosTagsData !== void 0 ? ghostPosTagsData : {},
117
+ grammarTransitions: grammarTransitionsData
118
+ });
119
+ succeedExp(EXPERIENCE_NAME.LOAD_GRAMMAR, 'singleton', _objectSpread({
120
+ isLocalLLM: isLocalLLM,
121
+ posTagCount: posTags.size,
122
+ transitionCount: precomputedAllowedByPos.size
123
+ }, surface ? {
124
+ surface: surface
125
+ } : {}));
126
+ if (isAutocompleteDebugEnabled()) {
127
+ // eslint-disable-next-line no-console
128
+ console.log('[scoring-pipeline] Grammar data loaded:', {
129
+ posTagCount: posTags.size,
130
+ ghostPosTagCount: Object.keys(ghostPosTags).length,
131
+ transitionCount: precomputedAllowedByPos.size
132
+ });
133
+ }
134
+ _context.next = 5;
135
+ break;
136
+ case 4:
137
+ _context.prev = 4;
138
+ _t = _context["catch"](1);
139
+ failExp(EXPERIENCE_NAME.LOAD_GRAMMAR, 'singleton', _objectSpread({
140
+ isLocalLLM: isLocalLLM,
141
+ errorType: 'network'
142
+ }, surface ? {
143
+ surface: surface
144
+ } : {}));
145
+ // Allow a later call to retry the load rather than caching the failure.
146
+ grammarDataPromise = undefined;
147
+ throw _t;
148
+ case 5:
149
+ case "end":
150
+ return _context.stop();
151
+ }
152
+ }, _callee, null, [[1, 4]]);
153
+ }))();
154
+ return grammarDataPromise;
155
+ };
51
156
 
52
157
  // ─── Math ───────────────────────────────────────────────────
53
158
 
@@ -96,18 +201,15 @@ function scoreStage1(candidate, contextVector, getWordVector, maxTenantFreq) {
96
201
 
97
202
  // ─── Grammar Filter ─────────────────────────────────────────
98
203
 
99
- /**
100
- * GHOST POS DICTIONARY
101
- * A hardcoded mapping of common structural English words that were stripped
102
- * from the main domain vocabulary. This allows the grammar filter to understand
103
- * context without suggesting these words to the user.
104
- */
105
- var ghostPosTags = ghostPosTagsData;
106
204
  function applyGrammarFilter(candidates, previousWord) {
107
- if (!previousWord) return {
108
- filtered: candidates,
109
- grammarMeta: null
110
- };
205
+ // Pass everything through until loadGrammarDataAsync resolves — filtering on a
206
+ // partially loaded ruleset would drop valid candidates.
207
+ if (!previousWord || !isGrammarDataLoaded()) {
208
+ return {
209
+ filtered: candidates,
210
+ grammarMeta: null
211
+ };
212
+ }
111
213
  var lowerPrev = previousWord.toLowerCase();
112
214
  var prevTags = ghostPosTags[lowerPrev] || posTags.get(lowerPrev);
113
215
  if (!prevTags || prevTags.length === 0) {