@atlaskit/editor-plugin-autocomplete 3.4.1 → 3.6.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @atlaskit/editor-plugin-autocomplete
2
2
 
3
+ ## 3.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`9f6b6c9fffc50`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9f6b6c9fffc50) -
8
+ Add analytics for the on-device (local LLM) autocomplete slow lane: fire a `localModelLoaded`
9
+ track event when the engine initialises successfully (with load duration and GPU info) and a
10
+ `localModelLoadFailed` track event when it fails, categorising the reason and capturing WebGPU
11
+ capability diagnostics to surface user-machine limitations.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
17
+ ## 3.5.0
18
+
19
+ ### Minor Changes
20
+
21
+ - [`52c7f5f973025`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/52c7f5f973025) -
22
+ Switch the CTC autocomplete debug toggle off `localStorage` and onto a storage-free mechanism.
23
+ Debug logging is now enabled via the `__atlCtcDebug__.enable()` / `.disable()` console API for the
24
+ current session, or by appending `?atlCtcDebug=1` to the URL to have it active from initial load
25
+ (and survive reloads). This avoids browser-storage consent controls (BSC) that can block
26
+ uncategorized `localStorage` writes in some products. The `isAutocompleteDebugEnabled()` API is
27
+ unchanged for callers.
28
+
3
29
  ## 3.4.1
4
30
 
5
31
  ### Patch Changes
@@ -247,12 +247,49 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
247
247
  }
248
248
  });
249
249
  };
250
- var fireSuggestionInsertedAnalytics = function fireSuggestionInsertedAnalytics(ghostText) {
250
+ var fireLocalModelLoadedAnalytics = function fireLocalModelLoadedAnalytics(info) {
251
251
  var _api$analytics2;
252
+ api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
253
+ action: _analytics.ACTION.LOCAL_MODEL_LOADED,
254
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
255
+ eventType: _analytics.EVENT_TYPE.TRACK,
256
+ attributes: {
257
+ modelId: info.modelId,
258
+ embeddingModelId: info.embeddingModelId,
259
+ loadDurationMs: info.loadDurationMs,
260
+ gpuVendor: info.capabilities.vendor,
261
+ gpuArchitecture: info.capabilities.architecture
262
+ }
263
+ });
264
+ };
265
+ var fireLocalModelLoadFailedAnalytics = function fireLocalModelLoadFailedAnalytics(error) {
266
+ var _api$analytics3;
267
+ var capabilities = error.capabilities;
268
+ api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
269
+ action: _analytics.ACTION.LOCAL_MODEL_LOAD_FAILED,
270
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
271
+ eventType: _analytics.EVENT_TYPE.TRACK,
272
+ attributes: {
273
+ reason: error.reason,
274
+ message: error.message,
275
+ modelId: error.modelId,
276
+ embeddingModelId: error.embeddingModelId,
277
+ webgpuAvailable: capabilities.available,
278
+ adapterAvailable: capabilities.adapterAvailable,
279
+ shaderF16Supported: capabilities.shaderF16Supported,
280
+ maxBufferSizeMB: capabilities.maxBufferSizeMB,
281
+ maxStorageBufferBindingSizeMB: capabilities.maxStorageBufferBindingSizeMB,
282
+ gpuVendor: capabilities.vendor,
283
+ gpuArchitecture: capabilities.architecture
284
+ }
285
+ });
286
+ };
287
+ var fireSuggestionInsertedAnalytics = function fireSuggestionInsertedAnalytics(ghostText) {
288
+ var _api$analytics4;
252
289
  var typedLength = lastSuggestionTypedLength;
253
290
  var suggestionLength = lastSuggestionLength || typedLength + ghostText.length;
254
291
  var kssDelta = suggestionLength - typedLength;
255
- api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
292
+ api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 || _api$analytics4.actions.fireAnalyticsEvent({
256
293
  action: _analytics.ACTION.SUGGESTION_INSERTED,
257
294
  actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
258
295
  eventType: _analytics.EVENT_TYPE.TRACK,
@@ -265,7 +302,9 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
265
302
  });
266
303
  };
267
304
  var slowLaneClient = options !== null && options !== void 0 && options.useLocalModel ? (0, _localSlowLaneClient.createLocalSlowLaneClient)({
268
- debounceMs: LOCAL_SLOW_LANE_DEBOUNCE_MS
305
+ debounceMs: LOCAL_SLOW_LANE_DEBOUNCE_MS,
306
+ onLoadSuccess: fireLocalModelLoadedAnalytics,
307
+ onLoadError: fireLocalModelLoadFailedAnalytics
269
308
  }) : (0, _slowLaneClient.createSlowLaneClient)({
270
309
  baseUrl: '',
271
310
  debounceMs: NETWORK_SLOW_LANE_DEBOUNCE_MS
@@ -419,9 +458,9 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
419
458
  lastSuggestionLength = typedLength + prediction.length;
420
459
  showGhostText(view, prediction, selection.from);
421
460
  if (prediction !== lastShownGhostText) {
422
- var _api$analytics3;
461
+ var _api$analytics5;
423
462
  lastShownGhostText = prediction;
424
- api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
463
+ api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 || _api$analytics5.actions.fireAnalyticsEvent({
425
464
  action: _analytics.ACTION.SUGGESTION_VIEWED,
426
465
  actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
427
466
  eventType: _analytics.EVENT_TYPE.TRACK,
@@ -7,18 +7,59 @@ exports.isAutocompleteDebugEnabled = void 0;
7
7
  /**
8
8
  * Contextual Typeahead Completions (CTC) debug logging utility.
9
9
  *
10
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
10
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
11
11
  *
12
- * localStorage.setItem('atl-ctc-dbg', '1')
12
+ * // Live, for the current session (no reload required):
13
+ * __atlCtcDebug__.enable()
13
14
  *
14
- * Then reload the page. To disable:
15
+ * // To disable:
16
+ * __atlCtcDebug__.disable()
15
17
  *
16
- * localStorage.removeItem('atl-ctc-dbg')
18
+ * // From initial page load (survives reload) — append to the URL:
19
+ * ?atlCtcDebug=1
20
+ *
21
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
22
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
17
23
  */
18
- var isAutocompleteDebugEnabled = exports.isAutocompleteDebugEnabled = function isAutocompleteDebugEnabled() {
24
+
25
+ var hasUrlDebugFlag = function hasUrlDebugFlag() {
26
+ if (typeof window === 'undefined') {
27
+ return false;
28
+ }
19
29
  try {
20
- return typeof localStorage !== 'undefined' && localStorage.getItem('atl-ctc-dbg') === '1';
30
+ return new URLSearchParams(window.location.search).get('atlCtcDebug') === '1';
21
31
  } catch (_unused) {
22
32
  return false;
23
33
  }
24
- };
34
+ };
35
+
36
+ // State lives on the window object (not a module closure) so duplicate copies of this
37
+ // module across separate bundles/realms share one source of truth and the console API
38
+ // controls them all. In-memory only; persisted across reload via the URL flag.
39
+ var getDebugApi = function getDebugApi() {
40
+ if (typeof window === 'undefined') {
41
+ return undefined;
42
+ }
43
+ if (!window.__atlCtcDebug__) {
44
+ var debugEnabled = hasUrlDebugFlag();
45
+ window.__atlCtcDebug__ = {
46
+ enable: function enable() {
47
+ debugEnabled = true;
48
+ },
49
+ disable: function disable() {
50
+ debugEnabled = false;
51
+ },
52
+ isEnabled: function isEnabled() {
53
+ return debugEnabled;
54
+ }
55
+ };
56
+ }
57
+ return window.__atlCtcDebug__;
58
+ };
59
+ var isAutocompleteDebugEnabled = exports.isAutocompleteDebugEnabled = function isAutocompleteDebugEnabled() {
60
+ var _getDebugApi$isEnable, _getDebugApi;
61
+ return (_getDebugApi$isEnable = (_getDebugApi = getDebugApi()) === null || _getDebugApi === void 0 ? void 0 : _getDebugApi.isEnabled()) !== null && _getDebugApi$isEnable !== void 0 ? _getDebugApi$isEnable : false;
62
+ };
63
+
64
+ // Eagerly install so the console API is available on load, regardless of call order.
65
+ getDebugApi();
@@ -18,7 +18,7 @@ var _debugMode = require("./debug-mode");
18
18
  var _slowLaneClient = require("./slow-lane-client");
19
19
  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; }
20
20
  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) { (0, _defineProperty2.default)(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; }
21
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
21
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t6 in e) "default" !== _t6 && {}.hasOwnProperty.call(e, _t6) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t6)) && (i.get || i.set) ? o(f, _t6, i) : f[_t6] = e[_t6]); return f; })(e, t); }
22
22
  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; } } }; }
23
23
  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; } }
24
24
  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; } /**
@@ -61,6 +61,19 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
61
61
 
62
62
  // Same return type as createSlowLaneClient for drop-in compatibility
63
63
 
64
+ /**
65
+ * Why the local engine failed to load/start.
66
+ *
67
+ * The first three are user-machine limitations (WebGPU missing, no compatible
68
+ * GPU adapter, GPU lacks the `shader-f16` feature the model needs);
69
+ * `insufficient_memory` is hit when weights don't fit in VRAM. The rest cover
70
+ * delivery/runtime failures unrelated to hardware.
71
+ */
72
+
73
+ /** Snapshot of the machine's WebGPU support, used to explain hardware limits. */
74
+
75
+ // Minimal WebGPU shape: lib.dom types aren't guaranteed in this build target.
76
+
64
77
  // ─── Constants ───────────────────────────────────────────────────────────────
65
78
 
66
79
  var DEFAULT_DEBOUNCE_MS = 300;
@@ -611,6 +624,8 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
611
624
  debounceMs = _config$debounceMs === void 0 ? DEFAULT_DEBOUNCE_MS : _config$debounceMs,
612
625
  onUpdate = config.onUpdate,
613
626
  onStatus = config.onStatus,
627
+ onLoadError = config.onLoadError,
628
+ onLoadSuccess = config.onLoadSuccess,
614
629
  _config$modelId = config.modelId,
615
630
  modelId = _config$modelId === void 0 ? LOCAL_MLC_CAUSAL_MODEL_ID : _config$modelId,
616
631
  customModelConfig = config.customModelConfig;
@@ -657,30 +672,191 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
657
672
  }
658
673
  onStatus === null || onStatus === void 0 || onStatus(message);
659
674
  };
660
- var initEngine = /*#__PURE__*/function () {
675
+ var bytesToMB = function bytesToMB(bytes) {
676
+ return typeof bytes === 'number' ? Math.round(bytes / (1024 * 1024)) : undefined;
677
+ };
678
+
679
+ /**
680
+ * Inspect the machine's WebGPU support so a load failure can be attributed
681
+ * to a concrete hardware/browser limitation rather than a generic error.
682
+ */
683
+ var probeWebGpuCapabilities = /*#__PURE__*/function () {
661
684
  var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
662
- var _yield$Promise$all3, _yield$Promise$all4, _yield$Promise$all4$, MLCEngineCtor, prebuiltAppConfig, customModelRecord, appConfig, newEngine, errorMsg, _t;
685
+ var gpu, _adapter$limits, _adapter$limits2, adapter, vendor, architecture, _adapter$info, _adapter$requestAdapt, info, _t, _t2, _t3;
663
686
  return _regenerator.default.wrap(function (_context2) {
664
687
  while (1) switch (_context2.prev = _context2.next) {
665
688
  case 0:
666
- _context2.prev = 0;
667
- if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
668
- // eslint-disable-next-line no-console
669
- console.log("%c[LocalSlowLane] %c\uD83D\uDE80 Initialising MLC engine with models: ".concat(modelId, " (LM) + ").concat(LOCAL_MLC_EMBEDDING_MODEL_ID, " (embedder)"), 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
670
- }
671
- onStatus === null || onStatus === void 0 || onStatus("Initialising models: ".concat(modelId, " + ").concat(LOCAL_MLC_EMBEDDING_MODEL_ID, "\u2026"));
672
- if ('gpu' in navigator) {
689
+ gpu = navigator.gpu;
690
+ if (gpu) {
673
691
  _context2.next = 1;
674
692
  break;
675
693
  }
676
- throw new Error('WebGPU not supported');
694
+ return _context2.abrupt("return", {
695
+ available: false
696
+ });
677
697
  case 1:
698
+ _context2.prev = 1;
678
699
  _context2.next = 2;
700
+ return gpu.requestAdapter();
701
+ case 2:
702
+ adapter = _context2.sent;
703
+ if (adapter) {
704
+ _context2.next = 3;
705
+ break;
706
+ }
707
+ return _context2.abrupt("return", {
708
+ available: true,
709
+ adapterAvailable: false
710
+ });
711
+ case 3:
712
+ _context2.prev = 3;
713
+ if (!((_adapter$info = adapter.info) !== null && _adapter$info !== void 0)) {
714
+ _context2.next = 4;
715
+ break;
716
+ }
717
+ _t = _adapter$info;
718
+ _context2.next = 6;
719
+ break;
720
+ case 4:
721
+ _context2.next = 5;
722
+ return (_adapter$requestAdapt = adapter.requestAdapterInfo) === null || _adapter$requestAdapt === void 0 ? void 0 : _adapter$requestAdapt.call(adapter);
723
+ case 5:
724
+ _t = _context2.sent;
725
+ case 6:
726
+ info = _t;
727
+ vendor = (info === null || info === void 0 ? void 0 : info.vendor) || undefined;
728
+ architecture = (info === null || info === void 0 ? void 0 : info.architecture) || undefined;
729
+ _context2.next = 8;
730
+ break;
731
+ case 7:
732
+ _context2.prev = 7;
733
+ _t2 = _context2["catch"](3);
734
+ case 8:
735
+ return _context2.abrupt("return", {
736
+ available: true,
737
+ adapterAvailable: true,
738
+ shaderF16Supported: adapter.features.has('shader-f16'),
739
+ maxBufferSizeMB: bytesToMB((_adapter$limits = adapter.limits) === null || _adapter$limits === void 0 ? void 0 : _adapter$limits.maxBufferSize),
740
+ maxStorageBufferBindingSizeMB: bytesToMB((_adapter$limits2 = adapter.limits) === null || _adapter$limits2 === void 0 ? void 0 : _adapter$limits2.maxStorageBufferBindingSize),
741
+ vendor: vendor,
742
+ architecture: architecture
743
+ });
744
+ case 9:
745
+ _context2.prev = 9;
746
+ _t3 = _context2["catch"](1);
747
+ return _context2.abrupt("return", {
748
+ available: true,
749
+ adapterAvailable: false
750
+ });
751
+ case 10:
752
+ case "end":
753
+ return _context2.stop();
754
+ }
755
+ }, _callee2, null, [[1, 9], [3, 7]]);
756
+ }));
757
+ return function probeWebGpuCapabilities() {
758
+ return _ref8.apply(this, arguments);
759
+ };
760
+ }();
761
+
762
+ /** Map an MLC/WebLLM engine-creation error message to a coarse reason. */
763
+ var classifyEngineError = function classifyEngineError(message) {
764
+ var lower = message.toLowerCase();
765
+ if (lower.includes('loading chunk') || lower.includes('dynamically imported module') || lower.includes('dynamic import')) {
766
+ return 'module_load_failed';
767
+ }
768
+ if (lower.includes('out of memory') || /\boom\b/.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
769
+ return 'insufficient_memory';
770
+ }
771
+ // Pre-flight already returns missing_shader_f16 when the feature is absent,
772
+ // so only match the exact feature token here — not bare 'shader' (compile
773
+ // errors) or bare 'f16' (present in model ids like q0f16-MLC).
774
+ if (lower.includes('shader-f16') || lower.includes('shader_f16')) {
775
+ return 'missing_shader_f16';
776
+ }
777
+ if (lower.includes('fetch') || lower.includes('network') || lower.includes('download') || lower.includes('http') || lower.includes('cache')) {
778
+ return 'model_download_failed';
779
+ }
780
+ return 'init_failed';
781
+ };
782
+
783
+ // Canonical, controlled failure descriptions. We never emit the raw engine
784
+ // error into analytics — it can embed customer-context URLs/paths (HOT-120175)
785
+ // — so the analytics `message` is always one of these fixed strings.
786
+ var LOAD_FAILURE_MESSAGE = {
787
+ webgpu_unavailable: 'WebGPU is not available in this browser',
788
+ webgpu_no_adapter: 'No compatible WebGPU adapter found',
789
+ missing_shader_f16: 'GPU does not support the shader-f16 feature',
790
+ insufficient_memory: 'Insufficient GPU memory to load the model',
791
+ model_download_failed: 'Failed to download model assets',
792
+ module_load_failed: 'Failed to load the web-llm runtime module',
793
+ init_failed: 'Model engine failed to initialise'
794
+ };
795
+ var handleLoadFailure = function handleLoadFailure(reason, capabilities, debugDetail) {
796
+ ready = false;
797
+ var message = LOAD_FAILURE_MESSAGE[reason];
798
+ if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
799
+ // eslint-disable-next-line no-console
800
+ console.log("[LocalSlowLane] Engine initialisation failed (".concat(reason, "): ").concat(debugDetail !== null && debugDetail !== void 0 ? debugDetail : message));
801
+ }
802
+ onStatus === null || onStatus === void 0 || onStatus("Engine initialisation failed: ".concat(message));
803
+ onLoadError === null || onLoadError === void 0 || onLoadError({
804
+ reason: reason,
805
+ message: message,
806
+ modelId: modelId,
807
+ embeddingModelId: LOCAL_MLC_EMBEDDING_MODEL_ID,
808
+ capabilities: capabilities
809
+ });
810
+ engineInitPromise = null;
811
+ initFailed = true;
812
+ };
813
+ var initEngine = /*#__PURE__*/function () {
814
+ var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
815
+ var capabilities, startTime, _yield$Promise$all3, _yield$Promise$all4, _yield$Promise$all4$, MLCEngineCtor, prebuiltAppConfig, customModelRecord, appConfig, newEngine, loadDurationMs, errorMsg, _t4;
816
+ return _regenerator.default.wrap(function (_context3) {
817
+ while (1) switch (_context3.prev = _context3.next) {
818
+ case 0:
819
+ _context3.next = 1;
820
+ return probeWebGpuCapabilities();
821
+ case 1:
822
+ capabilities = _context3.sent;
823
+ if (capabilities.available) {
824
+ _context3.next = 2;
825
+ break;
826
+ }
827
+ handleLoadFailure('webgpu_unavailable', capabilities);
828
+ return _context3.abrupt("return");
829
+ case 2:
830
+ if (!(capabilities.adapterAvailable === false)) {
831
+ _context3.next = 3;
832
+ break;
833
+ }
834
+ handleLoadFailure('webgpu_no_adapter', capabilities);
835
+ return _context3.abrupt("return");
836
+ case 3:
837
+ if (!(capabilities.shaderF16Supported === false)) {
838
+ _context3.next = 4;
839
+ break;
840
+ }
841
+ handleLoadFailure('missing_shader_f16', capabilities);
842
+ return _context3.abrupt("return");
843
+ case 4:
844
+ startTime = performance.now();
845
+ _context3.prev = 5;
846
+ if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
847
+ // eslint-disable-next-line no-console
848
+ console.log("%c[LocalSlowLane] %c\uD83D\uDE80 Initialising MLC engine with models: ".concat(modelId, " (LM) + ").concat(LOCAL_MLC_EMBEDDING_MODEL_ID, " (embedder)"), 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
849
+ }
850
+ onStatus === null || onStatus === void 0 || onStatus("Initialising models: ".concat(modelId, " + ").concat(LOCAL_MLC_EMBEDDING_MODEL_ID, "\u2026"));
851
+
852
+ // Fetch the web-llm runtime and the BE-parity lookup tables in parallel;
853
+ // both are dynamically imported so they stay out of the main editor chunk.
854
+ _context3.next = 6;
679
855
  return Promise.all([Promise.resolve().then(function () {
680
856
  return _interopRequireWildcard(require( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-mlc-web-llm" */'@mlc-ai/web-llm'));
681
857
  }), loadBePayloadData()]);
682
- case 2:
683
- _yield$Promise$all3 = _context2.sent;
858
+ case 6:
859
+ _yield$Promise$all3 = _context3.sent;
684
860
  _yield$Promise$all4 = (0, _slicedToArray2.default)(_yield$Promise$all3, 1);
685
861
  _yield$Promise$all4$ = _yield$Promise$all4[0];
686
862
  MLCEngineCtor = _yield$Promise$all4$.MLCEngine;
@@ -708,19 +884,20 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
708
884
  initProgressCallback: initProgressCallback,
709
885
  logitProcessorRegistry: new Map([[modelId, lmLogitsCapture]])
710
886
  });
711
- _context2.next = 3;
887
+ _context3.next = 7;
712
888
  return newEngine.reload([modelId, LOCAL_MLC_EMBEDDING_MODEL_ID]);
713
- case 3:
889
+ case 7:
714
890
  if (!destroyed) {
715
- _context2.next = 4;
891
+ _context3.next = 8;
716
892
  break;
717
893
  }
718
894
  // destroy() was called while we were loading — clean up
719
895
  unloadEngine(newEngine);
720
- return _context2.abrupt("return");
721
- case 4:
896
+ return _context3.abrupt("return");
897
+ case 8:
722
898
  engine = newEngine;
723
899
  ready = true;
900
+ loadDurationMs = Math.round(performance.now() - startTime);
724
901
  if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
725
902
  // eslint-disable-next-line no-console
726
903
  console.log('%c[LocalSlowLane] %c✅ Both models loaded and ready', 'color: #9c27b0; font-weight: bold;', 'color: #4caf50;');
@@ -732,28 +909,27 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
732
909
  console.log('%c[LocalSlowLane] %c🔢 Embedder →', 'color: #9c27b0; font-weight: bold;', 'color: #009688; font-weight: bold;', LOCAL_MLC_EMBEDDING_MODEL_ID);
733
910
  }
734
911
  onStatus === null || onStatus === void 0 || onStatus('Model loaded and ready.');
735
- _context2.next = 6;
912
+ onLoadSuccess === null || onLoadSuccess === void 0 || onLoadSuccess({
913
+ modelId: modelId,
914
+ embeddingModelId: LOCAL_MLC_EMBEDDING_MODEL_ID,
915
+ loadDurationMs: loadDurationMs,
916
+ capabilities: capabilities
917
+ });
918
+ _context3.next = 10;
736
919
  break;
737
- case 5:
738
- _context2.prev = 5;
739
- _t = _context2["catch"](0);
740
- errorMsg = _t instanceof Error ? _t.message : String(_t);
741
- ready = false;
742
- if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
743
- // eslint-disable-next-line no-console
744
- console.log("[LocalSlowLane] Engine initialisation failed: ".concat(errorMsg));
745
- }
746
- onStatus === null || onStatus === void 0 || onStatus("Engine initialisation failed: ".concat(errorMsg));
747
- engineInitPromise = null;
748
- initFailed = true;
749
- case 6:
920
+ case 9:
921
+ _context3.prev = 9;
922
+ _t4 = _context3["catch"](5);
923
+ errorMsg = _t4 instanceof Error ? _t4.message : String(_t4);
924
+ handleLoadFailure(classifyEngineError(errorMsg), capabilities, errorMsg);
925
+ case 10:
750
926
  case "end":
751
- return _context2.stop();
927
+ return _context3.stop();
752
928
  }
753
- }, _callee2, null, [[0, 5]]);
929
+ }, _callee3, null, [[5, 9]]);
754
930
  }));
755
931
  return function initEngine() {
756
- return _ref8.apply(this, arguments);
932
+ return _ref9.apply(this, arguments);
757
933
  };
758
934
  }();
759
935
  var ensureEngineInitialized = function ensureEngineInitialized() {
@@ -780,16 +956,16 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
780
956
  * 384-d semantic vector (passage-encoded; see `wrapForArctic`).
781
957
  */
782
958
  var runInference = /*#__PURE__*/function () {
783
- var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(text, requestId) {
784
- var lmText, semanticText, arcticInput, captureCompletionTime, _data, tStart, tLmDone, tEmbDone, _yield$Promise$all5, _yield$Promise$all6, embeddingResponse, rawLogits, payload, embedding, sumSq, i, topTokens, errorMsg, _t2;
785
- return _regenerator.default.wrap(function (_context3) {
786
- while (1) switch (_context3.prev = _context3.next) {
959
+ var _ref0 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(text, requestId) {
960
+ var lmText, semanticText, arcticInput, captureCompletionTime, _data, tStart, tLmDone, tEmbDone, _yield$Promise$all5, _yield$Promise$all6, embeddingResponse, rawLogits, payload, embedding, sumSq, i, topTokens, errorMsg, _t5;
961
+ return _regenerator.default.wrap(function (_context4) {
962
+ while (1) switch (_context4.prev = _context4.next) {
787
963
  case 0:
788
964
  if (!(!engine || destroyed)) {
789
- _context3.next = 1;
965
+ _context4.next = 1;
790
966
  break;
791
967
  }
792
- return _context3.abrupt("return");
968
+ return _context4.abrupt("return");
793
969
  case 1:
794
970
  // Clear the capture buffer so we read only this pass's logits. The engine
795
971
  // serialises per-model requests and updateContext is debounced, so the
@@ -816,11 +992,11 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
816
992
  // eslint-disable-next-line no-console
817
993
  console.log("%c[LocalSlowLane] %c\uD83E\uDDE0 LM input (".concat(lmText.length, " chars, ").concat(splitOnWhitespace(lmText).length, " words): \"").concat(lmText.length > 100 ? "".concat(lmText.slice(0, 100), "\u2026") : lmText, "\""), 'color: #9c27b0; font-weight: bold;', 'color: #2196f3;');
818
994
  }
819
- _context3.prev = 2;
995
+ _context4.prev = 2;
820
996
  tStart = performance.now();
821
997
  tLmDone = 0;
822
998
  tEmbDone = 0;
823
- _context3.next = 3;
999
+ _context4.next = 3;
824
1000
  return Promise.all([captureCompletionTime(engine.completions.create({
825
1001
  model: modelId,
826
1002
  prompt: lmText,
@@ -836,7 +1012,7 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
836
1012
  tEmbDone = resolvedAt;
837
1013
  })]);
838
1014
  case 3:
839
- _yield$Promise$all5 = _context3.sent;
1015
+ _yield$Promise$all5 = _context4.sent;
840
1016
  _yield$Promise$all6 = (0, _slicedToArray2.default)(_yield$Promise$all5, 2);
841
1017
  embeddingResponse = _yield$Promise$all6[1];
842
1018
  if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
@@ -846,10 +1022,10 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
846
1022
 
847
1023
  // Discard stale results
848
1024
  if (!(requestId < latestRequestId || destroyed)) {
849
- _context3.next = 4;
1025
+ _context4.next = 4;
850
1026
  break;
851
1027
  }
852
- return _context3.abrupt("return");
1028
+ return _context4.abrupt("return");
853
1029
  case 4:
854
1030
  // ── LM logits: whole-word BE-parity payload ──────────────────
855
1031
  rawLogits = lmLogitsCapture.captured;
@@ -883,17 +1059,17 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
883
1059
  // eslint-disable-next-line no-console
884
1060
  console.log(storedLmLogits ? "\u2705 lm_logits: ".concat(Object.keys(storedLmLogits).length, " words") : '❌ No lm_logits');
885
1061
  if (storedLmLogits) {
886
- topTokens = Object.entries(storedLmLogits).sort(function (_ref0, _ref1) {
887
- var _ref10 = (0, _slicedToArray2.default)(_ref0, 2),
888
- a = _ref10[1];
1062
+ topTokens = Object.entries(storedLmLogits).sort(function (_ref1, _ref10) {
889
1063
  var _ref11 = (0, _slicedToArray2.default)(_ref1, 2),
890
- b = _ref11[1];
1064
+ a = _ref11[1];
1065
+ var _ref12 = (0, _slicedToArray2.default)(_ref10, 2),
1066
+ b = _ref12[1];
891
1067
  return b - a;
892
1068
  }).slice(0, 10); // eslint-disable-next-line no-console
893
- console.log('Top 10 predictions:', topTokens.map(function (_ref12) {
894
- var _ref13 = (0, _slicedToArray2.default)(_ref12, 2),
895
- t = _ref13[0],
896
- p = _ref13[1];
1069
+ console.log('Top 10 predictions:', topTokens.map(function (_ref13) {
1070
+ var _ref14 = (0, _slicedToArray2.default)(_ref13, 2),
1071
+ t = _ref14[0],
1072
+ p = _ref14[1];
897
1073
  return "".concat(t, ": ").concat((p * 100).toFixed(1), "%");
898
1074
  }).join(', '));
899
1075
  }
@@ -905,16 +1081,16 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
905
1081
  hasVector: storedContextVector !== null,
906
1082
  hasLmLogits: storedLmLogits !== null
907
1083
  });
908
- _context3.next = 7;
1084
+ _context4.next = 7;
909
1085
  break;
910
1086
  case 5:
911
- _context3.prev = 5;
912
- _t2 = _context3["catch"](2);
1087
+ _context4.prev = 5;
1088
+ _t5 = _context4["catch"](2);
913
1089
  if (!(requestId < latestRequestId || destroyed)) {
914
- _context3.next = 6;
1090
+ _context4.next = 6;
915
1091
  break;
916
1092
  }
917
- return _context3.abrupt("return");
1093
+ return _context4.abrupt("return");
918
1094
  case 6:
919
1095
  storedContextVector = null;
920
1096
  storedLmLogits = null;
@@ -923,19 +1099,19 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
923
1099
  hasVector: false,
924
1100
  hasLmLogits: false
925
1101
  });
926
- errorMsg = _t2 instanceof Error ? _t2.message : String(_t2);
1102
+ errorMsg = _t5 instanceof Error ? _t5.message : String(_t5);
927
1103
  if ((0, _debugMode.isAutocompleteDebugEnabled)()) {
928
1104
  // eslint-disable-next-line no-console
929
1105
  console.log("%c[LocalSlowLane] %c\u274C Inference error (request #".concat(requestId, "): ").concat(errorMsg), 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
930
1106
  }
931
1107
  case 7:
932
1108
  case "end":
933
- return _context3.stop();
1109
+ return _context4.stop();
934
1110
  }
935
- }, _callee3, null, [[2, 5]]);
1111
+ }, _callee4, null, [[2, 5]]);
936
1112
  }));
937
1113
  return function runInference(_x, _x2) {
938
- return _ref9.apply(this, arguments);
1114
+ return _ref0.apply(this, arguments);
939
1115
  };
940
1116
  }();
941
1117