@atlaskit/editor-plugin-autocomplete 3.5.0 → 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 +14 -0
- package/dist/cjs/pm-plugins/autocomplete-plugin.js +44 -5
- package/dist/cjs/pm-plugins/local-slow-lane-client.js +239 -63
- package/dist/es2019/pm-plugins/autocomplete-plugin.js +46 -5
- package/dist/es2019/pm-plugins/local-slow-lane-client.js +139 -11
- package/dist/esm/pm-plugins/autocomplete-plugin.js +44 -5
- package/dist/esm/pm-plugins/local-slow-lane-client.js +238 -62
- package/dist/types/pm-plugins/local-slow-lane-client.d.ts +52 -0
- package/dist/types-ts4.5/pm-plugins/local-slow-lane-client.d.ts +52 -0
- package/package.json +2 -2
- package/src/pm-plugins/autocomplete-plugin.ts +45 -1
- package/src/pm-plugins/local-slow-lane-client.ts +223 -12
|
@@ -55,6 +55,19 @@ import { isWordBoundary } from './slow-lane-client';
|
|
|
55
55
|
|
|
56
56
|
// Same return type as createSlowLaneClient for drop-in compatibility
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Why the local engine failed to load/start.
|
|
60
|
+
*
|
|
61
|
+
* The first three are user-machine limitations (WebGPU missing, no compatible
|
|
62
|
+
* GPU adapter, GPU lacks the `shader-f16` feature the model needs);
|
|
63
|
+
* `insufficient_memory` is hit when weights don't fit in VRAM. The rest cover
|
|
64
|
+
* delivery/runtime failures unrelated to hardware.
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/** Snapshot of the machine's WebGPU support, used to explain hardware limits. */
|
|
68
|
+
|
|
69
|
+
// Minimal WebGPU shape: lib.dom types aren't guaranteed in this build target.
|
|
70
|
+
|
|
58
71
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
59
72
|
|
|
60
73
|
var DEFAULT_DEBOUNCE_MS = 300;
|
|
@@ -601,6 +614,8 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
601
614
|
debounceMs = _config$debounceMs === void 0 ? DEFAULT_DEBOUNCE_MS : _config$debounceMs,
|
|
602
615
|
onUpdate = config.onUpdate,
|
|
603
616
|
onStatus = config.onStatus,
|
|
617
|
+
onLoadError = config.onLoadError,
|
|
618
|
+
onLoadSuccess = config.onLoadSuccess,
|
|
604
619
|
_config$modelId = config.modelId,
|
|
605
620
|
modelId = _config$modelId === void 0 ? LOCAL_MLC_CAUSAL_MODEL_ID : _config$modelId,
|
|
606
621
|
customModelConfig = config.customModelConfig;
|
|
@@ -647,28 +662,189 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
647
662
|
}
|
|
648
663
|
onStatus === null || onStatus === void 0 || onStatus(message);
|
|
649
664
|
};
|
|
650
|
-
var
|
|
665
|
+
var bytesToMB = function bytesToMB(bytes) {
|
|
666
|
+
return typeof bytes === 'number' ? Math.round(bytes / (1024 * 1024)) : undefined;
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Inspect the machine's WebGPU support so a load failure can be attributed
|
|
671
|
+
* to a concrete hardware/browser limitation rather than a generic error.
|
|
672
|
+
*/
|
|
673
|
+
var probeWebGpuCapabilities = /*#__PURE__*/function () {
|
|
651
674
|
var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
652
|
-
var
|
|
675
|
+
var gpu, _adapter$limits, _adapter$limits2, adapter, vendor, architecture, _adapter$info, _adapter$requestAdapt, info, _t, _t2, _t3;
|
|
653
676
|
return _regeneratorRuntime.wrap(function (_context2) {
|
|
654
677
|
while (1) switch (_context2.prev = _context2.next) {
|
|
655
678
|
case 0:
|
|
656
|
-
|
|
657
|
-
if (
|
|
658
|
-
// eslint-disable-next-line no-console
|
|
659
|
-
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;');
|
|
660
|
-
}
|
|
661
|
-
onStatus === null || onStatus === void 0 || onStatus("Initialising models: ".concat(modelId, " + ").concat(LOCAL_MLC_EMBEDDING_MODEL_ID, "\u2026"));
|
|
662
|
-
if ('gpu' in navigator) {
|
|
679
|
+
gpu = navigator.gpu;
|
|
680
|
+
if (gpu) {
|
|
663
681
|
_context2.next = 1;
|
|
664
682
|
break;
|
|
665
683
|
}
|
|
666
|
-
|
|
684
|
+
return _context2.abrupt("return", {
|
|
685
|
+
available: false
|
|
686
|
+
});
|
|
667
687
|
case 1:
|
|
688
|
+
_context2.prev = 1;
|
|
668
689
|
_context2.next = 2;
|
|
669
|
-
return
|
|
690
|
+
return gpu.requestAdapter();
|
|
691
|
+
case 2:
|
|
692
|
+
adapter = _context2.sent;
|
|
693
|
+
if (adapter) {
|
|
694
|
+
_context2.next = 3;
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
return _context2.abrupt("return", {
|
|
698
|
+
available: true,
|
|
699
|
+
adapterAvailable: false
|
|
700
|
+
});
|
|
701
|
+
case 3:
|
|
702
|
+
_context2.prev = 3;
|
|
703
|
+
if (!((_adapter$info = adapter.info) !== null && _adapter$info !== void 0)) {
|
|
704
|
+
_context2.next = 4;
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
_t = _adapter$info;
|
|
708
|
+
_context2.next = 6;
|
|
709
|
+
break;
|
|
710
|
+
case 4:
|
|
711
|
+
_context2.next = 5;
|
|
712
|
+
return (_adapter$requestAdapt = adapter.requestAdapterInfo) === null || _adapter$requestAdapt === void 0 ? void 0 : _adapter$requestAdapt.call(adapter);
|
|
713
|
+
case 5:
|
|
714
|
+
_t = _context2.sent;
|
|
715
|
+
case 6:
|
|
716
|
+
info = _t;
|
|
717
|
+
vendor = (info === null || info === void 0 ? void 0 : info.vendor) || undefined;
|
|
718
|
+
architecture = (info === null || info === void 0 ? void 0 : info.architecture) || undefined;
|
|
719
|
+
_context2.next = 8;
|
|
720
|
+
break;
|
|
721
|
+
case 7:
|
|
722
|
+
_context2.prev = 7;
|
|
723
|
+
_t2 = _context2["catch"](3);
|
|
724
|
+
case 8:
|
|
725
|
+
return _context2.abrupt("return", {
|
|
726
|
+
available: true,
|
|
727
|
+
adapterAvailable: true,
|
|
728
|
+
shaderF16Supported: adapter.features.has('shader-f16'),
|
|
729
|
+
maxBufferSizeMB: bytesToMB((_adapter$limits = adapter.limits) === null || _adapter$limits === void 0 ? void 0 : _adapter$limits.maxBufferSize),
|
|
730
|
+
maxStorageBufferBindingSizeMB: bytesToMB((_adapter$limits2 = adapter.limits) === null || _adapter$limits2 === void 0 ? void 0 : _adapter$limits2.maxStorageBufferBindingSize),
|
|
731
|
+
vendor: vendor,
|
|
732
|
+
architecture: architecture
|
|
733
|
+
});
|
|
734
|
+
case 9:
|
|
735
|
+
_context2.prev = 9;
|
|
736
|
+
_t3 = _context2["catch"](1);
|
|
737
|
+
return _context2.abrupt("return", {
|
|
738
|
+
available: true,
|
|
739
|
+
adapterAvailable: false
|
|
740
|
+
});
|
|
741
|
+
case 10:
|
|
742
|
+
case "end":
|
|
743
|
+
return _context2.stop();
|
|
744
|
+
}
|
|
745
|
+
}, _callee2, null, [[1, 9], [3, 7]]);
|
|
746
|
+
}));
|
|
747
|
+
return function probeWebGpuCapabilities() {
|
|
748
|
+
return _ref8.apply(this, arguments);
|
|
749
|
+
};
|
|
750
|
+
}();
|
|
751
|
+
|
|
752
|
+
/** Map an MLC/WebLLM engine-creation error message to a coarse reason. */
|
|
753
|
+
var classifyEngineError = function classifyEngineError(message) {
|
|
754
|
+
var lower = message.toLowerCase();
|
|
755
|
+
if (lower.includes('loading chunk') || lower.includes('dynamically imported module') || lower.includes('dynamic import')) {
|
|
756
|
+
return 'module_load_failed';
|
|
757
|
+
}
|
|
758
|
+
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')) {
|
|
759
|
+
return 'insufficient_memory';
|
|
760
|
+
}
|
|
761
|
+
// Pre-flight already returns missing_shader_f16 when the feature is absent,
|
|
762
|
+
// so only match the exact feature token here — not bare 'shader' (compile
|
|
763
|
+
// errors) or bare 'f16' (present in model ids like q0f16-MLC).
|
|
764
|
+
if (lower.includes('shader-f16') || lower.includes('shader_f16')) {
|
|
765
|
+
return 'missing_shader_f16';
|
|
766
|
+
}
|
|
767
|
+
if (lower.includes('fetch') || lower.includes('network') || lower.includes('download') || lower.includes('http') || lower.includes('cache')) {
|
|
768
|
+
return 'model_download_failed';
|
|
769
|
+
}
|
|
770
|
+
return 'init_failed';
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
// Canonical, controlled failure descriptions. We never emit the raw engine
|
|
774
|
+
// error into analytics — it can embed customer-context URLs/paths (HOT-120175)
|
|
775
|
+
// — so the analytics `message` is always one of these fixed strings.
|
|
776
|
+
var LOAD_FAILURE_MESSAGE = {
|
|
777
|
+
webgpu_unavailable: 'WebGPU is not available in this browser',
|
|
778
|
+
webgpu_no_adapter: 'No compatible WebGPU adapter found',
|
|
779
|
+
missing_shader_f16: 'GPU does not support the shader-f16 feature',
|
|
780
|
+
insufficient_memory: 'Insufficient GPU memory to load the model',
|
|
781
|
+
model_download_failed: 'Failed to download model assets',
|
|
782
|
+
module_load_failed: 'Failed to load the web-llm runtime module',
|
|
783
|
+
init_failed: 'Model engine failed to initialise'
|
|
784
|
+
};
|
|
785
|
+
var handleLoadFailure = function handleLoadFailure(reason, capabilities, debugDetail) {
|
|
786
|
+
ready = false;
|
|
787
|
+
var message = LOAD_FAILURE_MESSAGE[reason];
|
|
788
|
+
if (isAutocompleteDebugEnabled()) {
|
|
789
|
+
// eslint-disable-next-line no-console
|
|
790
|
+
console.log("[LocalSlowLane] Engine initialisation failed (".concat(reason, "): ").concat(debugDetail !== null && debugDetail !== void 0 ? debugDetail : message));
|
|
791
|
+
}
|
|
792
|
+
onStatus === null || onStatus === void 0 || onStatus("Engine initialisation failed: ".concat(message));
|
|
793
|
+
onLoadError === null || onLoadError === void 0 || onLoadError({
|
|
794
|
+
reason: reason,
|
|
795
|
+
message: message,
|
|
796
|
+
modelId: modelId,
|
|
797
|
+
embeddingModelId: LOCAL_MLC_EMBEDDING_MODEL_ID,
|
|
798
|
+
capabilities: capabilities
|
|
799
|
+
});
|
|
800
|
+
engineInitPromise = null;
|
|
801
|
+
initFailed = true;
|
|
802
|
+
};
|
|
803
|
+
var initEngine = /*#__PURE__*/function () {
|
|
804
|
+
var _ref9 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
805
|
+
var capabilities, startTime, _yield$Promise$all3, _yield$Promise$all4, _yield$Promise$all4$, MLCEngineCtor, prebuiltAppConfig, customModelRecord, appConfig, newEngine, loadDurationMs, errorMsg, _t4;
|
|
806
|
+
return _regeneratorRuntime.wrap(function (_context3) {
|
|
807
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
808
|
+
case 0:
|
|
809
|
+
_context3.next = 1;
|
|
810
|
+
return probeWebGpuCapabilities();
|
|
811
|
+
case 1:
|
|
812
|
+
capabilities = _context3.sent;
|
|
813
|
+
if (capabilities.available) {
|
|
814
|
+
_context3.next = 2;
|
|
815
|
+
break;
|
|
816
|
+
}
|
|
817
|
+
handleLoadFailure('webgpu_unavailable', capabilities);
|
|
818
|
+
return _context3.abrupt("return");
|
|
670
819
|
case 2:
|
|
671
|
-
|
|
820
|
+
if (!(capabilities.adapterAvailable === false)) {
|
|
821
|
+
_context3.next = 3;
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
824
|
+
handleLoadFailure('webgpu_no_adapter', capabilities);
|
|
825
|
+
return _context3.abrupt("return");
|
|
826
|
+
case 3:
|
|
827
|
+
if (!(capabilities.shaderF16Supported === false)) {
|
|
828
|
+
_context3.next = 4;
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
handleLoadFailure('missing_shader_f16', capabilities);
|
|
832
|
+
return _context3.abrupt("return");
|
|
833
|
+
case 4:
|
|
834
|
+
startTime = performance.now();
|
|
835
|
+
_context3.prev = 5;
|
|
836
|
+
if (isAutocompleteDebugEnabled()) {
|
|
837
|
+
// eslint-disable-next-line no-console
|
|
838
|
+
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;');
|
|
839
|
+
}
|
|
840
|
+
onStatus === null || onStatus === void 0 || onStatus("Initialising models: ".concat(modelId, " + ").concat(LOCAL_MLC_EMBEDDING_MODEL_ID, "\u2026"));
|
|
841
|
+
|
|
842
|
+
// Fetch the web-llm runtime and the BE-parity lookup tables in parallel;
|
|
843
|
+
// both are dynamically imported so they stay out of the main editor chunk.
|
|
844
|
+
_context3.next = 6;
|
|
845
|
+
return Promise.all([import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-mlc-web-llm" */'@mlc-ai/web-llm'), loadBePayloadData()]);
|
|
846
|
+
case 6:
|
|
847
|
+
_yield$Promise$all3 = _context3.sent;
|
|
672
848
|
_yield$Promise$all4 = _slicedToArray(_yield$Promise$all3, 1);
|
|
673
849
|
_yield$Promise$all4$ = _yield$Promise$all4[0];
|
|
674
850
|
MLCEngineCtor = _yield$Promise$all4$.MLCEngine;
|
|
@@ -696,19 +872,20 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
696
872
|
initProgressCallback: initProgressCallback,
|
|
697
873
|
logitProcessorRegistry: new Map([[modelId, lmLogitsCapture]])
|
|
698
874
|
});
|
|
699
|
-
|
|
875
|
+
_context3.next = 7;
|
|
700
876
|
return newEngine.reload([modelId, LOCAL_MLC_EMBEDDING_MODEL_ID]);
|
|
701
|
-
case
|
|
877
|
+
case 7:
|
|
702
878
|
if (!destroyed) {
|
|
703
|
-
|
|
879
|
+
_context3.next = 8;
|
|
704
880
|
break;
|
|
705
881
|
}
|
|
706
882
|
// destroy() was called while we were loading — clean up
|
|
707
883
|
unloadEngine(newEngine);
|
|
708
|
-
return
|
|
709
|
-
case
|
|
884
|
+
return _context3.abrupt("return");
|
|
885
|
+
case 8:
|
|
710
886
|
engine = newEngine;
|
|
711
887
|
ready = true;
|
|
888
|
+
loadDurationMs = Math.round(performance.now() - startTime);
|
|
712
889
|
if (isAutocompleteDebugEnabled()) {
|
|
713
890
|
// eslint-disable-next-line no-console
|
|
714
891
|
console.log('%c[LocalSlowLane] %c✅ Both models loaded and ready', 'color: #9c27b0; font-weight: bold;', 'color: #4caf50;');
|
|
@@ -720,28 +897,27 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
720
897
|
console.log('%c[LocalSlowLane] %c🔢 Embedder →', 'color: #9c27b0; font-weight: bold;', 'color: #009688; font-weight: bold;', LOCAL_MLC_EMBEDDING_MODEL_ID);
|
|
721
898
|
}
|
|
722
899
|
onStatus === null || onStatus === void 0 || onStatus('Model loaded and ready.');
|
|
723
|
-
|
|
900
|
+
onLoadSuccess === null || onLoadSuccess === void 0 || onLoadSuccess({
|
|
901
|
+
modelId: modelId,
|
|
902
|
+
embeddingModelId: LOCAL_MLC_EMBEDDING_MODEL_ID,
|
|
903
|
+
loadDurationMs: loadDurationMs,
|
|
904
|
+
capabilities: capabilities
|
|
905
|
+
});
|
|
906
|
+
_context3.next = 10;
|
|
724
907
|
break;
|
|
725
|
-
case
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
errorMsg =
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
// eslint-disable-next-line no-console
|
|
732
|
-
console.log("[LocalSlowLane] Engine initialisation failed: ".concat(errorMsg));
|
|
733
|
-
}
|
|
734
|
-
onStatus === null || onStatus === void 0 || onStatus("Engine initialisation failed: ".concat(errorMsg));
|
|
735
|
-
engineInitPromise = null;
|
|
736
|
-
initFailed = true;
|
|
737
|
-
case 6:
|
|
908
|
+
case 9:
|
|
909
|
+
_context3.prev = 9;
|
|
910
|
+
_t4 = _context3["catch"](5);
|
|
911
|
+
errorMsg = _t4 instanceof Error ? _t4.message : String(_t4);
|
|
912
|
+
handleLoadFailure(classifyEngineError(errorMsg), capabilities, errorMsg);
|
|
913
|
+
case 10:
|
|
738
914
|
case "end":
|
|
739
|
-
return
|
|
915
|
+
return _context3.stop();
|
|
740
916
|
}
|
|
741
|
-
},
|
|
917
|
+
}, _callee3, null, [[5, 9]]);
|
|
742
918
|
}));
|
|
743
919
|
return function initEngine() {
|
|
744
|
-
return
|
|
920
|
+
return _ref9.apply(this, arguments);
|
|
745
921
|
};
|
|
746
922
|
}();
|
|
747
923
|
var ensureEngineInitialized = function ensureEngineInitialized() {
|
|
@@ -768,16 +944,16 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
768
944
|
* 384-d semantic vector (passage-encoded; see `wrapForArctic`).
|
|
769
945
|
*/
|
|
770
946
|
var runInference = /*#__PURE__*/function () {
|
|
771
|
-
var
|
|
772
|
-
var lmText, semanticText, arcticInput, captureCompletionTime, _data, tStart, tLmDone, tEmbDone, _yield$Promise$all5, _yield$Promise$all6, embeddingResponse, rawLogits, payload, embedding, sumSq, i, topTokens, errorMsg,
|
|
773
|
-
return _regeneratorRuntime.wrap(function (
|
|
774
|
-
while (1) switch (
|
|
947
|
+
var _ref0 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(text, requestId) {
|
|
948
|
+
var lmText, semanticText, arcticInput, captureCompletionTime, _data, tStart, tLmDone, tEmbDone, _yield$Promise$all5, _yield$Promise$all6, embeddingResponse, rawLogits, payload, embedding, sumSq, i, topTokens, errorMsg, _t5;
|
|
949
|
+
return _regeneratorRuntime.wrap(function (_context4) {
|
|
950
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
775
951
|
case 0:
|
|
776
952
|
if (!(!engine || destroyed)) {
|
|
777
|
-
|
|
953
|
+
_context4.next = 1;
|
|
778
954
|
break;
|
|
779
955
|
}
|
|
780
|
-
return
|
|
956
|
+
return _context4.abrupt("return");
|
|
781
957
|
case 1:
|
|
782
958
|
// Clear the capture buffer so we read only this pass's logits. The engine
|
|
783
959
|
// serialises per-model requests and updateContext is debounced, so the
|
|
@@ -804,11 +980,11 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
804
980
|
// eslint-disable-next-line no-console
|
|
805
981
|
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;');
|
|
806
982
|
}
|
|
807
|
-
|
|
983
|
+
_context4.prev = 2;
|
|
808
984
|
tStart = performance.now();
|
|
809
985
|
tLmDone = 0;
|
|
810
986
|
tEmbDone = 0;
|
|
811
|
-
|
|
987
|
+
_context4.next = 3;
|
|
812
988
|
return Promise.all([captureCompletionTime(engine.completions.create({
|
|
813
989
|
model: modelId,
|
|
814
990
|
prompt: lmText,
|
|
@@ -824,7 +1000,7 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
824
1000
|
tEmbDone = resolvedAt;
|
|
825
1001
|
})]);
|
|
826
1002
|
case 3:
|
|
827
|
-
_yield$Promise$all5 =
|
|
1003
|
+
_yield$Promise$all5 = _context4.sent;
|
|
828
1004
|
_yield$Promise$all6 = _slicedToArray(_yield$Promise$all5, 2);
|
|
829
1005
|
embeddingResponse = _yield$Promise$all6[1];
|
|
830
1006
|
if (isAutocompleteDebugEnabled()) {
|
|
@@ -834,10 +1010,10 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
834
1010
|
|
|
835
1011
|
// Discard stale results
|
|
836
1012
|
if (!(requestId < latestRequestId || destroyed)) {
|
|
837
|
-
|
|
1013
|
+
_context4.next = 4;
|
|
838
1014
|
break;
|
|
839
1015
|
}
|
|
840
|
-
return
|
|
1016
|
+
return _context4.abrupt("return");
|
|
841
1017
|
case 4:
|
|
842
1018
|
// ── LM logits: whole-word BE-parity payload ──────────────────
|
|
843
1019
|
rawLogits = lmLogitsCapture.captured;
|
|
@@ -871,17 +1047,17 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
871
1047
|
// eslint-disable-next-line no-console
|
|
872
1048
|
console.log(storedLmLogits ? "\u2705 lm_logits: ".concat(Object.keys(storedLmLogits).length, " words") : '❌ No lm_logits');
|
|
873
1049
|
if (storedLmLogits) {
|
|
874
|
-
topTokens = Object.entries(storedLmLogits).sort(function (
|
|
875
|
-
var _ref10 = _slicedToArray(_ref0, 2),
|
|
876
|
-
a = _ref10[1];
|
|
1050
|
+
topTokens = Object.entries(storedLmLogits).sort(function (_ref1, _ref10) {
|
|
877
1051
|
var _ref11 = _slicedToArray(_ref1, 2),
|
|
878
|
-
|
|
1052
|
+
a = _ref11[1];
|
|
1053
|
+
var _ref12 = _slicedToArray(_ref10, 2),
|
|
1054
|
+
b = _ref12[1];
|
|
879
1055
|
return b - a;
|
|
880
1056
|
}).slice(0, 10); // eslint-disable-next-line no-console
|
|
881
|
-
console.log('Top 10 predictions:', topTokens.map(function (
|
|
882
|
-
var
|
|
883
|
-
t =
|
|
884
|
-
p =
|
|
1057
|
+
console.log('Top 10 predictions:', topTokens.map(function (_ref13) {
|
|
1058
|
+
var _ref14 = _slicedToArray(_ref13, 2),
|
|
1059
|
+
t = _ref14[0],
|
|
1060
|
+
p = _ref14[1];
|
|
885
1061
|
return "".concat(t, ": ").concat((p * 100).toFixed(1), "%");
|
|
886
1062
|
}).join(', '));
|
|
887
1063
|
}
|
|
@@ -893,16 +1069,16 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
893
1069
|
hasVector: storedContextVector !== null,
|
|
894
1070
|
hasLmLogits: storedLmLogits !== null
|
|
895
1071
|
});
|
|
896
|
-
|
|
1072
|
+
_context4.next = 7;
|
|
897
1073
|
break;
|
|
898
1074
|
case 5:
|
|
899
|
-
|
|
900
|
-
|
|
1075
|
+
_context4.prev = 5;
|
|
1076
|
+
_t5 = _context4["catch"](2);
|
|
901
1077
|
if (!(requestId < latestRequestId || destroyed)) {
|
|
902
|
-
|
|
1078
|
+
_context4.next = 6;
|
|
903
1079
|
break;
|
|
904
1080
|
}
|
|
905
|
-
return
|
|
1081
|
+
return _context4.abrupt("return");
|
|
906
1082
|
case 6:
|
|
907
1083
|
storedContextVector = null;
|
|
908
1084
|
storedLmLogits = null;
|
|
@@ -911,19 +1087,19 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
911
1087
|
hasVector: false,
|
|
912
1088
|
hasLmLogits: false
|
|
913
1089
|
});
|
|
914
|
-
errorMsg =
|
|
1090
|
+
errorMsg = _t5 instanceof Error ? _t5.message : String(_t5);
|
|
915
1091
|
if (isAutocompleteDebugEnabled()) {
|
|
916
1092
|
// eslint-disable-next-line no-console
|
|
917
1093
|
console.log("%c[LocalSlowLane] %c\u274C Inference error (request #".concat(requestId, "): ").concat(errorMsg), 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
|
|
918
1094
|
}
|
|
919
1095
|
case 7:
|
|
920
1096
|
case "end":
|
|
921
|
-
return
|
|
1097
|
+
return _context4.stop();
|
|
922
1098
|
}
|
|
923
|
-
},
|
|
1099
|
+
}, _callee4, null, [[2, 5]]);
|
|
924
1100
|
}));
|
|
925
1101
|
return function runInference(_x, _x2) {
|
|
926
|
-
return
|
|
1102
|
+
return _ref0.apply(this, arguments);
|
|
927
1103
|
};
|
|
928
1104
|
}();
|
|
929
1105
|
|
|
@@ -60,6 +60,10 @@ export interface LocalSlowLaneClientConfig {
|
|
|
60
60
|
* `customModelConfig` with the model URL and WASM library URL.
|
|
61
61
|
*/
|
|
62
62
|
modelId?: string;
|
|
63
|
+
/** Callback fired when the engine fails to load/start. */
|
|
64
|
+
onLoadError?: (error: LocalSlowLaneLoadError) => void;
|
|
65
|
+
/** Callback fired when the engine successfully loads and is ready. */
|
|
66
|
+
onLoadSuccess?: (info: LocalSlowLaneLoadSuccess) => void;
|
|
63
67
|
/** Callback fired with status messages (model loading progress, etc.). */
|
|
64
68
|
onStatus?: (message: string) => void;
|
|
65
69
|
/** Callback fired when inference returns new results. */
|
|
@@ -81,6 +85,54 @@ export interface LocalSlowLaneClient {
|
|
|
81
85
|
setLmLogits: (logits: Record<string, number> | null) => void;
|
|
82
86
|
updateContext: (text: string) => void;
|
|
83
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Why the local engine failed to load/start.
|
|
90
|
+
*
|
|
91
|
+
* The first three are user-machine limitations (WebGPU missing, no compatible
|
|
92
|
+
* GPU adapter, GPU lacks the `shader-f16` feature the model needs);
|
|
93
|
+
* `insufficient_memory` is hit when weights don't fit in VRAM. The rest cover
|
|
94
|
+
* delivery/runtime failures unrelated to hardware.
|
|
95
|
+
*/
|
|
96
|
+
export type LocalSlowLaneLoadErrorReason = 'webgpu_unavailable' | 'webgpu_no_adapter' | 'missing_shader_f16' | 'insufficient_memory' | 'model_download_failed' | 'module_load_failed' | 'init_failed';
|
|
97
|
+
/** Snapshot of the machine's WebGPU support, used to explain hardware limits. */
|
|
98
|
+
export interface WebGpuCapabilities {
|
|
99
|
+
/** GPU architecture reported by the adapter (e.g. "metal-3", "rdna2"). */
|
|
100
|
+
architecture?: string;
|
|
101
|
+
/** Whether `navigator.gpu.requestAdapter()` returned a usable adapter. */
|
|
102
|
+
adapterAvailable?: boolean;
|
|
103
|
+
/** Whether `navigator.gpu` exists at all. */
|
|
104
|
+
available: boolean;
|
|
105
|
+
/** Largest single GPU buffer the adapter allows, in MB. */
|
|
106
|
+
maxBufferSizeMB?: number;
|
|
107
|
+
/** Largest storage-buffer binding the adapter allows, in MB. */
|
|
108
|
+
maxStorageBufferBindingSizeMB?: number;
|
|
109
|
+
/** Whether the adapter exposes the `shader-f16` feature the model requires. */
|
|
110
|
+
shaderF16Supported?: boolean;
|
|
111
|
+
/** GPU vendor reported by the adapter (e.g. "apple", "intel"). */
|
|
112
|
+
vendor?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface LocalSlowLaneLoadError {
|
|
115
|
+
/** WebGPU support snapshot — explains hardware limitations behind the failure. */
|
|
116
|
+
capabilities: WebGpuCapabilities;
|
|
117
|
+
/** Semantic embedder loaded alongside the causal LM (loads atomically). */
|
|
118
|
+
embeddingModelId: string;
|
|
119
|
+
/** Canonical, controlled failure description (never raw error text). */
|
|
120
|
+
message: string;
|
|
121
|
+
/** Causal LM identifier that failed to load. */
|
|
122
|
+
modelId: string;
|
|
123
|
+
/** Coarse, privacy-safe failure category. */
|
|
124
|
+
reason: LocalSlowLaneLoadErrorReason;
|
|
125
|
+
}
|
|
126
|
+
export interface LocalSlowLaneLoadSuccess {
|
|
127
|
+
/** WebGPU support snapshot for the machine that loaded the model. */
|
|
128
|
+
capabilities: WebGpuCapabilities;
|
|
129
|
+
/** Semantic embedder loaded alongside the causal LM (loads atomically). */
|
|
130
|
+
embeddingModelId: string;
|
|
131
|
+
/** Model engine load time in ms (excludes the WebGPU capability probe). */
|
|
132
|
+
loadDurationMs: number;
|
|
133
|
+
/** Causal LM identifier that loaded. */
|
|
134
|
+
modelId: string;
|
|
135
|
+
}
|
|
84
136
|
export declare const LOCAL_MLC_CAUSAL_MODEL_ID = "SmolLM2-135M-Instruct-q0f16-MLC";
|
|
85
137
|
/**
|
|
86
138
|
* MLC ID for the semantic embedder (Snowflake Arctic Embed S, batch=4 variant).
|
|
@@ -60,6 +60,10 @@ export interface LocalSlowLaneClientConfig {
|
|
|
60
60
|
* `customModelConfig` with the model URL and WASM library URL.
|
|
61
61
|
*/
|
|
62
62
|
modelId?: string;
|
|
63
|
+
/** Callback fired when the engine fails to load/start. */
|
|
64
|
+
onLoadError?: (error: LocalSlowLaneLoadError) => void;
|
|
65
|
+
/** Callback fired when the engine successfully loads and is ready. */
|
|
66
|
+
onLoadSuccess?: (info: LocalSlowLaneLoadSuccess) => void;
|
|
63
67
|
/** Callback fired with status messages (model loading progress, etc.). */
|
|
64
68
|
onStatus?: (message: string) => void;
|
|
65
69
|
/** Callback fired when inference returns new results. */
|
|
@@ -81,6 +85,54 @@ export interface LocalSlowLaneClient {
|
|
|
81
85
|
setLmLogits: (logits: Record<string, number> | null) => void;
|
|
82
86
|
updateContext: (text: string) => void;
|
|
83
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Why the local engine failed to load/start.
|
|
90
|
+
*
|
|
91
|
+
* The first three are user-machine limitations (WebGPU missing, no compatible
|
|
92
|
+
* GPU adapter, GPU lacks the `shader-f16` feature the model needs);
|
|
93
|
+
* `insufficient_memory` is hit when weights don't fit in VRAM. The rest cover
|
|
94
|
+
* delivery/runtime failures unrelated to hardware.
|
|
95
|
+
*/
|
|
96
|
+
export type LocalSlowLaneLoadErrorReason = 'webgpu_unavailable' | 'webgpu_no_adapter' | 'missing_shader_f16' | 'insufficient_memory' | 'model_download_failed' | 'module_load_failed' | 'init_failed';
|
|
97
|
+
/** Snapshot of the machine's WebGPU support, used to explain hardware limits. */
|
|
98
|
+
export interface WebGpuCapabilities {
|
|
99
|
+
/** GPU architecture reported by the adapter (e.g. "metal-3", "rdna2"). */
|
|
100
|
+
architecture?: string;
|
|
101
|
+
/** Whether `navigator.gpu.requestAdapter()` returned a usable adapter. */
|
|
102
|
+
adapterAvailable?: boolean;
|
|
103
|
+
/** Whether `navigator.gpu` exists at all. */
|
|
104
|
+
available: boolean;
|
|
105
|
+
/** Largest single GPU buffer the adapter allows, in MB. */
|
|
106
|
+
maxBufferSizeMB?: number;
|
|
107
|
+
/** Largest storage-buffer binding the adapter allows, in MB. */
|
|
108
|
+
maxStorageBufferBindingSizeMB?: number;
|
|
109
|
+
/** Whether the adapter exposes the `shader-f16` feature the model requires. */
|
|
110
|
+
shaderF16Supported?: boolean;
|
|
111
|
+
/** GPU vendor reported by the adapter (e.g. "apple", "intel"). */
|
|
112
|
+
vendor?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface LocalSlowLaneLoadError {
|
|
115
|
+
/** WebGPU support snapshot — explains hardware limitations behind the failure. */
|
|
116
|
+
capabilities: WebGpuCapabilities;
|
|
117
|
+
/** Semantic embedder loaded alongside the causal LM (loads atomically). */
|
|
118
|
+
embeddingModelId: string;
|
|
119
|
+
/** Canonical, controlled failure description (never raw error text). */
|
|
120
|
+
message: string;
|
|
121
|
+
/** Causal LM identifier that failed to load. */
|
|
122
|
+
modelId: string;
|
|
123
|
+
/** Coarse, privacy-safe failure category. */
|
|
124
|
+
reason: LocalSlowLaneLoadErrorReason;
|
|
125
|
+
}
|
|
126
|
+
export interface LocalSlowLaneLoadSuccess {
|
|
127
|
+
/** WebGPU support snapshot for the machine that loaded the model. */
|
|
128
|
+
capabilities: WebGpuCapabilities;
|
|
129
|
+
/** Semantic embedder loaded alongside the causal LM (loads atomically). */
|
|
130
|
+
embeddingModelId: string;
|
|
131
|
+
/** Model engine load time in ms (excludes the WebGPU capability probe). */
|
|
132
|
+
loadDurationMs: number;
|
|
133
|
+
/** Causal LM identifier that loaded. */
|
|
134
|
+
modelId: string;
|
|
135
|
+
}
|
|
84
136
|
export declare const LOCAL_MLC_CAUSAL_MODEL_ID = "SmolLM2-135M-Instruct-q0f16-MLC";
|
|
85
137
|
/**
|
|
86
138
|
* MLC ID for the semantic embedder (Snowflake Arctic Embed S, batch=4 variant).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-autocomplete",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Client-side text autocomplete plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"wink-nlp": "^2.4.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@atlaskit/editor-common": "^115.
|
|
38
|
+
"@atlaskit/editor-common": "^115.15.0",
|
|
39
39
|
"@atlaskit/editor-plugin-analytics": "^11.0.0",
|
|
40
40
|
"react": "^18.2.0"
|
|
41
41
|
},
|
|
@@ -16,7 +16,12 @@ import type { AutocompletePlugin } from '../autocompletePluginType';
|
|
|
16
16
|
|
|
17
17
|
import { isAutocompleteDebugEnabled } from './debug-mode';
|
|
18
18
|
import { createGhostTextDecorationSet } from './ghost-text-decoration';
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
createLocalSlowLaneClient,
|
|
21
|
+
type LocalSlowLaneClient,
|
|
22
|
+
type LocalSlowLaneLoadError,
|
|
23
|
+
type LocalSlowLaneLoadSuccess,
|
|
24
|
+
} from './local-slow-lane-client';
|
|
20
25
|
import { createSlowLaneClient, setDefaultSlowLaneClient, isWordBoundary } from './slow-lane-client';
|
|
21
26
|
import {
|
|
22
27
|
predict,
|
|
@@ -298,6 +303,43 @@ export const createAutocompletePlugin = (
|
|
|
298
303
|
});
|
|
299
304
|
};
|
|
300
305
|
|
|
306
|
+
const fireLocalModelLoadedAnalytics = (info: LocalSlowLaneLoadSuccess): void => {
|
|
307
|
+
api?.analytics?.actions.fireAnalyticsEvent({
|
|
308
|
+
action: ACTION.LOCAL_MODEL_LOADED,
|
|
309
|
+
actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
|
|
310
|
+
eventType: EVENT_TYPE.TRACK,
|
|
311
|
+
attributes: {
|
|
312
|
+
modelId: info.modelId,
|
|
313
|
+
embeddingModelId: info.embeddingModelId,
|
|
314
|
+
loadDurationMs: info.loadDurationMs,
|
|
315
|
+
gpuVendor: info.capabilities.vendor,
|
|
316
|
+
gpuArchitecture: info.capabilities.architecture,
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const fireLocalModelLoadFailedAnalytics = (error: LocalSlowLaneLoadError): void => {
|
|
322
|
+
const { capabilities } = error;
|
|
323
|
+
api?.analytics?.actions.fireAnalyticsEvent({
|
|
324
|
+
action: ACTION.LOCAL_MODEL_LOAD_FAILED,
|
|
325
|
+
actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
|
|
326
|
+
eventType: EVENT_TYPE.TRACK,
|
|
327
|
+
attributes: {
|
|
328
|
+
reason: error.reason,
|
|
329
|
+
message: error.message,
|
|
330
|
+
modelId: error.modelId,
|
|
331
|
+
embeddingModelId: error.embeddingModelId,
|
|
332
|
+
webgpuAvailable: capabilities.available,
|
|
333
|
+
adapterAvailable: capabilities.adapterAvailable,
|
|
334
|
+
shaderF16Supported: capabilities.shaderF16Supported,
|
|
335
|
+
maxBufferSizeMB: capabilities.maxBufferSizeMB,
|
|
336
|
+
maxStorageBufferBindingSizeMB: capabilities.maxStorageBufferBindingSizeMB,
|
|
337
|
+
gpuVendor: capabilities.vendor,
|
|
338
|
+
gpuArchitecture: capabilities.architecture,
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
|
|
301
343
|
const fireSuggestionInsertedAnalytics = (ghostText: string): void => {
|
|
302
344
|
const typedLength = lastSuggestionTypedLength;
|
|
303
345
|
const suggestionLength = lastSuggestionLength || typedLength + ghostText.length;
|
|
@@ -319,6 +361,8 @@ export const createAutocompletePlugin = (
|
|
|
319
361
|
const slowLaneClient = options?.useLocalModel
|
|
320
362
|
? createLocalSlowLaneClient({
|
|
321
363
|
debounceMs: LOCAL_SLOW_LANE_DEBOUNCE_MS,
|
|
364
|
+
onLoadSuccess: fireLocalModelLoadedAnalytics,
|
|
365
|
+
onLoadError: fireLocalModelLoadFailedAnalytics,
|
|
322
366
|
})
|
|
323
367
|
: createSlowLaneClient({
|
|
324
368
|
baseUrl: '',
|