@atlaskit/editor-plugin-autocomplete 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -208,6 +208,11 @@ export interface AutocompleteContext {
208
208
  }
209
209
 
210
210
  export interface AutocompletePluginOptions {
211
+ /**
212
+ * Product/editor surface where autocomplete runs (e.g. "comment", "chat").
213
+ * Added to analytics and UFO metadata for cross-surface reporting.
214
+ */
215
+ surface?: string;
211
216
  /**
212
217
  * Async function called once on first editor focus to retrieve context for
213
218
  * word-frequency boosting. Called lazily so the preset can remain synchronous.
@@ -328,6 +333,7 @@ export const createAutocompletePlugin = (
328
333
  options?: AutocompletePluginOptions,
329
334
  api?: ExtractInjectionAPI<AutocompletePlugin>,
330
335
  ): SafePlugin<AutocompletePluginState> => {
336
+ const surface = options?.surface ?? 'editor';
331
337
  const locale =
332
338
  options?.locale ?? (typeof navigator !== 'undefined' ? navigator.language : undefined);
333
339
  const isAutocompleteEnabled = isEnglishLocale(locale);
@@ -375,7 +381,7 @@ export const createAutocompletePlugin = (
375
381
  action: ACTION.SUGGESTION_DISMISSED,
376
382
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
377
383
  eventType: EVENT_TYPE.TRACK,
378
- attributes: { completionSource: getCompletionSource(), reason },
384
+ attributes: { completionSource: getCompletionSource(), reason, surface },
379
385
  });
380
386
  };
381
387
 
@@ -390,6 +396,7 @@ export const createAutocompletePlugin = (
390
396
  loadDurationMs: info.loadDurationMs,
391
397
  gpuVendor: info.capabilities.vendor,
392
398
  gpuArchitecture: info.capabilities.architecture,
399
+ surface,
393
400
  },
394
401
  });
395
402
  };
@@ -412,6 +419,7 @@ export const createAutocompletePlugin = (
412
419
  maxStorageBufferBindingSizeMB: capabilities.maxStorageBufferBindingSizeMB,
413
420
  gpuVendor: capabilities.vendor,
414
421
  gpuArchitecture: capabilities.architecture,
422
+ surface,
415
423
  },
416
424
  });
417
425
  };
@@ -430,6 +438,7 @@ export const createAutocompletePlugin = (
430
438
  suggestionLength,
431
439
  typedLength,
432
440
  kssDelta,
441
+ surface,
433
442
  },
434
443
  });
435
444
  };
@@ -439,10 +448,12 @@ export const createAutocompletePlugin = (
439
448
  debounceMs: LOCAL_SLOW_LANE_DEBOUNCE_MS,
440
449
  onLoadSuccess: fireLocalModelLoadedAnalytics,
441
450
  onLoadError: fireLocalModelLoadFailedAnalytics,
451
+ surface,
442
452
  })
443
453
  : createSlowLaneClient({
444
454
  baseUrl: '',
445
455
  debounceMs: NETWORK_SLOW_LANE_DEBOUNCE_MS,
456
+ surface,
446
457
  });
447
458
  setDefaultSlowLaneClient(slowLaneClient);
448
459
 
@@ -632,7 +643,7 @@ export const createAutocompletePlugin = (
632
643
  action: ACTION.SUGGESTION_VIEWED,
633
644
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
634
645
  eventType: EVENT_TYPE.TRACK,
635
- attributes: { completionSource: getCompletionSource() },
646
+ attributes: { completionSource: getCompletionSource(), surface },
636
647
  });
637
648
  }
638
649
  }
@@ -778,7 +789,10 @@ export const createAutocompletePlugin = (
778
789
  return false;
779
790
  }
780
791
 
781
- loadDefaultVocabulary({ isLocalLLM: options?.useLocalModel ?? false }).catch((error) => {
792
+ loadDefaultVocabulary({
793
+ isLocalLLM: options?.useLocalModel ?? false,
794
+ surface,
795
+ }).catch((error) => {
782
796
  logException(error as Error, {
783
797
  location: 'editor-plugin-autocomplete/loadDefaultVocabulary',
784
798
  });
@@ -786,6 +800,7 @@ export const createAutocompletePlugin = (
786
800
  loadVectorsAsync({
787
801
  getBinaryUrl: options?.getVectorsBinaryUrl,
788
802
  isLocalLLM: options?.useLocalModel ?? false,
803
+ surface,
789
804
  }).catch((error) => {
790
805
  logException(error as Error, {
791
806
  location: 'editor-plugin-autocomplete/loadVectorsAsync',
@@ -81,6 +81,8 @@ export interface LocalSlowLaneClientConfig {
81
81
  onStatus?: (message: string) => void;
82
82
  /** Callback fired when inference returns new results. */
83
83
  onUpdate?: (opts: { hasLmLogits: boolean; hasVector: boolean; textLength: number }) => void;
84
+ /** Product/editor surface where autocomplete runs. */
85
+ surface?: string;
84
86
  }
85
87
 
86
88
  // Same return type as createSlowLaneClient for drop-in compatibility
@@ -664,6 +666,7 @@ export const createLocalSlowLaneClient = (
664
666
  onLoadSuccess,
665
667
  modelId = LOCAL_MLC_CAUSAL_MODEL_ID,
666
668
  customModelConfig,
669
+ surface,
667
670
  } = config;
668
671
 
669
672
  // ── State ──────────────────────────────────────────────────────────────
@@ -1040,6 +1043,7 @@ export const createLocalSlowLaneClient = (
1040
1043
  startExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, experienceId, {
1041
1044
  textLength: text.length,
1042
1045
  isLocalLLM: true,
1046
+ ...(surface ? { surface } : {}),
1043
1047
  });
1044
1048
 
1045
1049
  const tStart = performance.now();
@@ -1085,7 +1089,7 @@ export const createLocalSlowLaneClient = (
1085
1089
  EXPERIENCE_NAME.SLOW_LANE_FETCH,
1086
1090
  experienceId,
1087
1091
  destroyed ? 'destroyed' : 'superseded',
1088
- { isLocalLLM: true },
1092
+ { isLocalLLM: true, ...(surface ? { surface } : {}) },
1089
1093
  );
1090
1094
  return;
1091
1095
  }
@@ -1154,6 +1158,7 @@ export const createLocalSlowLaneClient = (
1154
1158
  hasVector: storedContextVector !== null,
1155
1159
  hasLmLogits: storedLmLogits !== null,
1156
1160
  isLocalLLM: true,
1161
+ ...(surface ? { surface } : {}),
1157
1162
  });
1158
1163
 
1159
1164
  onUpdate?.({
@@ -1168,7 +1173,7 @@ export const createLocalSlowLaneClient = (
1168
1173
  EXPERIENCE_NAME.SLOW_LANE_FETCH,
1169
1174
  experienceId,
1170
1175
  destroyed ? 'destroyed' : 'superseded',
1171
- { isLocalLLM: true },
1176
+ { isLocalLLM: true, ...(surface ? { surface } : {}) },
1172
1177
  );
1173
1178
  return;
1174
1179
  }
@@ -1178,6 +1183,7 @@ export const createLocalSlowLaneClient = (
1178
1183
  failExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, experienceId, {
1179
1184
  errorType: 'inference',
1180
1185
  isLocalLLM: true,
1186
+ ...(surface ? { surface } : {}),
1181
1187
  });
1182
1188
  onUpdate?.({ textLength: text.length, hasVector: false, hasLmLogits: false });
1183
1189
 
@@ -54,6 +54,7 @@ export interface SlowLaneClientConfig {
54
54
  onUpdate?: (opts: { hasLmLogits: boolean; hasVector: boolean; textLength: number }) => void;
55
55
  productKey?: string;
56
56
  sessionId?: string;
57
+ surface?: string;
57
58
  }
58
59
 
59
60
  export const createSlowLaneClient = (
@@ -70,6 +71,7 @@ export const createSlowLaneClient = (
70
71
  baseUrl,
71
72
  sessionId: configSessionId,
72
73
  productKey = 'confluence',
74
+ surface,
73
75
  endpoint = '/gateway/api/v1/autocomplete/typeahead-encodings',
74
76
  debounceMs = DEFAULT_DEBOUNCE_MS,
75
77
  fetchFn = fetch,
@@ -105,6 +107,7 @@ export const createSlowLaneClient = (
105
107
  startExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, {
106
108
  textLength: text.length,
107
109
  isLocalLLM: false,
110
+ ...(surface ? { surface } : {}),
108
111
  });
109
112
 
110
113
  if (isAutocompleteDebugEnabled()) {
@@ -136,6 +139,7 @@ export const createSlowLaneClient = (
136
139
  status: res.status,
137
140
  errorType: 'http_error',
138
141
  isLocalLLM: false,
142
+ ...(surface ? { surface } : {}),
139
143
  });
140
144
  if (isAutocompleteDebugEnabled()) {
141
145
  // eslint-disable-next-line no-console
@@ -190,6 +194,7 @@ export const createSlowLaneClient = (
190
194
  hasVector: storedContextVector !== null,
191
195
  hasLmLogits: storedLmLogits !== null,
192
196
  isLocalLLM: false,
197
+ ...(surface ? { surface } : {}),
193
198
  });
194
199
 
195
200
  onUpdate?.({
@@ -204,6 +209,7 @@ export const createSlowLaneClient = (
204
209
  failExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, requestId, {
205
210
  errorType: 'network',
206
211
  isLocalLLM: false,
212
+ ...(surface ? { surface } : {}),
207
213
  });
208
214
  if (isAutocompleteDebugEnabled()) {
209
215
  // eslint-disable-next-line no-console
@@ -230,6 +236,7 @@ export const createSlowLaneClient = (
230
236
  if (inflightRequestId !== null) {
231
237
  abortExp(EXPERIENCE_NAME.SLOW_LANE_FETCH, inflightRequestId, 'superseded', {
232
238
  isLocalLLM: false,
239
+ ...(surface ? { surface } : {}),
233
240
  });
234
241
  }
235
242
  const requestId = String(++requestSeq);
@@ -751,6 +751,7 @@ function unwrapJsonModule<T>(mod: unknown, shape: 'object' | 'array'): T | null
751
751
  export const loadVectorsAsync = async (options?: {
752
752
  getBinaryUrl?: () => Promise<string>;
753
753
  isLocalLLM?: boolean;
754
+ surface?: string;
754
755
  }): Promise<void> => {
755
756
  if (vectorStore || vectorsLoadStarted) {
756
757
  return;
@@ -763,15 +764,23 @@ export const loadVectorsAsync = async (options?: {
763
764
  return;
764
765
  }
765
766
  const isLocalLLM = options?.isLocalLLM ?? false;
767
+ const surface = options?.surface;
766
768
  vectorsLoadStarted = true;
767
- startExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', { isLocalLLM });
769
+ startExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', {
770
+ isLocalLLM,
771
+ ...(surface ? { surface } : {}),
772
+ });
768
773
 
769
774
  let url: string;
770
775
  try {
771
776
  url = await options.getBinaryUrl();
772
777
  } catch (e) {
773
778
  vectorsLoadStarted = false;
774
- failExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', { isLocalLLM, errorType: 'resolve_url' });
779
+ failExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', {
780
+ isLocalLLM,
781
+ errorType: 'resolve_url',
782
+ ...(surface ? { surface } : {}),
783
+ });
775
784
  // eslint-disable-next-line no-console
776
785
  console.warn('[text-predictor] Failed to resolve vectors URL:', e);
777
786
  return;
@@ -785,6 +794,7 @@ export const loadVectorsAsync = async (options?: {
785
794
  isLocalLLM,
786
795
  status: res.status,
787
796
  errorType: 'http_error',
797
+ ...(surface ? { surface } : {}),
788
798
  });
789
799
  // eslint-disable-next-line no-console
790
800
  console.warn(`[text-predictor] Failed to load vectors: ${res.status}`);
@@ -819,6 +829,7 @@ export const loadVectorsAsync = async (options?: {
819
829
  wordCount: nWords,
820
830
  dim,
821
831
  sizeBytes: float32.byteLength,
832
+ ...(surface ? { surface } : {}),
822
833
  });
823
834
  if (isAutocompleteDebugEnabled()) {
824
835
  // eslint-disable-next-line no-console
@@ -830,7 +841,11 @@ export const loadVectorsAsync = async (options?: {
830
841
  }
831
842
  } catch (e) {
832
843
  vectorsLoadStarted = false;
833
- failExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', { isLocalLLM, errorType: 'network' });
844
+ failExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', {
845
+ isLocalLLM,
846
+ errorType: 'network',
847
+ ...(surface ? { surface } : {}),
848
+ });
834
849
  // eslint-disable-next-line no-console
835
850
  console.warn('[text-predictor] Failed to load vectors:', e);
836
851
  }
@@ -842,7 +857,10 @@ export const initVectors = (store: VectorStore): void => {
842
857
 
843
858
  let vocabularyLoadPromise: Promise<void> | undefined;
844
859
 
845
- export const loadDefaultVocabulary = (options?: { isLocalLLM?: boolean }): Promise<void> => {
860
+ export const loadDefaultVocabulary = (options?: {
861
+ isLocalLLM?: boolean;
862
+ surface?: string;
863
+ }): Promise<void> => {
846
864
  if (isInitialized) {
847
865
  return Promise.resolve();
848
866
  }
@@ -851,8 +869,12 @@ export const loadDefaultVocabulary = (options?: { isLocalLLM?: boolean }): Promi
851
869
  }
852
870
 
853
871
  const isLocalLLM = options?.isLocalLLM ?? false;
872
+ const surface = options?.surface;
854
873
  vocabularyLoadPromise = (async () => {
855
- startExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', { isLocalLLM });
874
+ startExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', {
875
+ isLocalLLM,
876
+ ...(surface ? { surface } : {}),
877
+ });
856
878
 
857
879
  try {
858
880
  // The L2 vocabulary and L3 word list are code-split into their own async
@@ -890,11 +912,13 @@ export const loadDefaultVocabulary = (options?: { isLocalLLM?: boolean }): Promi
890
912
  isLocalLLM,
891
913
  l2WordCount: terms.length,
892
914
  l3WordCount: l3VocabularyData.length,
915
+ ...(surface ? { surface } : {}),
893
916
  });
894
917
  } catch (e) {
895
918
  failExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', {
896
919
  isLocalLLM,
897
920
  errorType: 'parse_error',
921
+ ...(surface ? { surface } : {}),
898
922
  });
899
923
  // Allow a later call to retry the load rather than caching the failure.
900
924
  vocabularyLoadPromise = undefined;