@atlaskit/editor-plugin-autocomplete 0.1.0 → 0.2.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 +8 -0
- package/afm-cc/tsconfig.json +5 -1
- package/afm-jira/tsconfig.json +5 -1
- package/afm-products/tsconfig.json +5 -1
- package/build/tsconfig.json +24 -0
- package/dist/cjs/autocompletePlugin.js +18 -5
- package/dist/cjs/autocompletePluginType.js +5 -1
- package/dist/cjs/pm-plugins/autocomplete-plugin.js +361 -0
- package/dist/cjs/pm-plugins/ghost-text-decoration.js +39 -0
- package/dist/cjs/pm-plugins/scoring-pipeline.js +258 -0
- package/dist/cjs/pm-plugins/slow-lane-client.js +197 -0
- package/dist/cjs/pm-plugins/text-predictor.js +786 -0
- package/dist/es2019/autocompletePlugin.js +20 -6
- package/dist/es2019/autocompletePluginType.js +1 -0
- package/dist/es2019/pm-plugins/autocomplete-plugin.js +360 -0
- package/dist/es2019/pm-plugins/ghost-text-decoration.js +33 -0
- package/dist/es2019/pm-plugins/scoring-pipeline.js +224 -0
- package/dist/es2019/pm-plugins/slow-lane-client.js +154 -0
- package/dist/es2019/pm-plugins/text-predictor.js +624 -0
- package/dist/esm/autocompletePlugin.js +18 -5
- package/dist/esm/autocompletePluginType.js +1 -0
- package/dist/esm/pm-plugins/autocomplete-plugin.js +354 -0
- package/dist/esm/pm-plugins/ghost-text-decoration.js +33 -0
- package/dist/esm/pm-plugins/scoring-pipeline.js +255 -0
- package/dist/esm/pm-plugins/slow-lane-client.js +190 -0
- package/dist/esm/pm-plugins/text-predictor.js +783 -0
- package/dist/types/autocompletePluginType.d.ts +6 -3
- package/dist/types/pm-plugins/autocomplete-plugin.d.ts +36 -0
- package/dist/types/pm-plugins/ghost-text-decoration.d.ts +7 -0
- package/dist/types/pm-plugins/scoring-pipeline.d.ts +33 -0
- package/dist/types/pm-plugins/slow-lane-client.d.ts +46 -0
- package/dist/types/pm-plugins/text-predictor.d.ts +90 -0
- package/dist/types-ts4.5/autocompletePluginType.d.ts +6 -3
- package/dist/types-ts4.5/pm-plugins/autocomplete-plugin.d.ts +36 -0
- package/dist/types-ts4.5/pm-plugins/ghost-text-decoration.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/scoring-pipeline.d.ts +33 -0
- package/dist/types-ts4.5/pm-plugins/slow-lane-client.d.ts +46 -0
- package/dist/types-ts4.5/pm-plugins/text-predictor.d.ts +90 -0
- package/package.json +2 -2
- package/src/autocompletePlugin.tsx +25 -5
- package/src/autocompletePluginType.ts +14 -3
- package/src/pm-plugins/autocomplete-plugin/package.json +15 -0
- package/src/pm-plugins/autocomplete-plugin.ts +429 -0
- package/src/pm-plugins/ghost-text-decoration.ts +44 -0
- package/src/pm-plugins/scoring-pipeline.ts +297 -0
- package/src/pm-plugins/slow-lane-client/package.json +15 -0
- package/src/pm-plugins/slow-lane-client.ts +220 -0
- package/src/pm-plugins/text-predictor/package.json +15 -0
- package/src/pm-plugins/text-predictor.ts +771 -0
- package/src/pm-plugins/typings.d.ts +12 -0
- package/tsconfig.app.json +10 -2
- package/tsconfig.json +3 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.rankCandidates = rankCandidates;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _combined_l2_l3_pos_tags = _interopRequireDefault(require("./data/combined_l2_l3_pos_tags.json"));
|
|
10
|
+
var _ghost_pos_tags = _interopRequireDefault(require("./data/ghost_pos_tags.json"));
|
|
11
|
+
var _grammar_transitions_10k = _interopRequireDefault(require("./data/grammar_transitions_10k.json"));
|
|
12
|
+
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; } } }; }
|
|
13
|
+
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; } }
|
|
14
|
+
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; } /**
|
|
15
|
+
* Scoring Pipeline: Stage 1 (Semantic + Frequency), Grammar Filter, Stage 2 (LM Re-ranking).
|
|
16
|
+
*
|
|
17
|
+
* Operates synchronously on pre-loaded data. Each stage gracefully degrades
|
|
18
|
+
* when its required data isn't available (cold → warm → full warm).
|
|
19
|
+
*/ // resolveJsonModule is disabled for this package (see tsconfig.json) to prevent
|
|
20
|
+
// TypeScript from parsing LFS pointer files during CI typecheck. JSON imports
|
|
21
|
+
// are typed via the '*.json' declaration in typings.d.ts.
|
|
22
|
+
// ─── Types ──────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
/** Metadata returned by the grammar filter for debug logging in the caller. */
|
|
25
|
+
|
|
26
|
+
// ─── Scoring Constants ──────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
var ALPHA = 0.5;
|
|
29
|
+
var BETA = 0.5;
|
|
30
|
+
var NEUTRAL_SCORE = 0.5;
|
|
31
|
+
var STAGE1_WEIGHT = 0.6;
|
|
32
|
+
var STAGE2_WEIGHT = 0.4;
|
|
33
|
+
var MIN_STAGE1_SCORE = 0.35;
|
|
34
|
+
var L1_SESSION_CAP = 1.2;
|
|
35
|
+
|
|
36
|
+
// ─── Grammar Data (loaded once on import) ───────────────────
|
|
37
|
+
|
|
38
|
+
var posTags = new Map(Object.entries(_combined_l2_l3_pos_tags.default));
|
|
39
|
+
var grammarTransitions = _grammar_transitions_10k.default;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Precomputed map from each POS tag to the set of allowed next POS tags.
|
|
43
|
+
* Built once at module load from grammarTransitions so applyGrammarFilter
|
|
44
|
+
* never re-iterates the transition rules per call.
|
|
45
|
+
*/
|
|
46
|
+
var precomputedAllowedByPos = new Map(Object.entries(grammarTransitions.transitions).map(function (_ref) {
|
|
47
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
48
|
+
pos = _ref2[0],
|
|
49
|
+
rule = _ref2[1];
|
|
50
|
+
return [pos, new Set(rule.allowed)];
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
// ─── Math ───────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
function cosineSimilarity(a, b) {
|
|
56
|
+
var dot = 0;
|
|
57
|
+
var normA = 0;
|
|
58
|
+
var normB = 0;
|
|
59
|
+
for (var i = 0; i < a.length; i++) {
|
|
60
|
+
dot += a[i] * b[i];
|
|
61
|
+
normA += a[i] * a[i];
|
|
62
|
+
normB += b[i] * b[i];
|
|
63
|
+
}
|
|
64
|
+
var dNormA = Math.sqrt(normA);
|
|
65
|
+
var dNormB = Math.sqrt(normB);
|
|
66
|
+
if (dNormA === 0 || dNormB === 0) {
|
|
67
|
+
return NEUTRAL_SCORE;
|
|
68
|
+
}
|
|
69
|
+
return (1 + dot / (dNormA * dNormB)) / 2;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ─── Stage 1: Semantic + Frequency ──────────────────────────
|
|
73
|
+
|
|
74
|
+
function scoreStage1(candidate, contextVector, getWordVector, maxTenantFreq) {
|
|
75
|
+
// 1. Calculate Base Global Score (Normalized Log)
|
|
76
|
+
var maxPossibleLog = Math.log10(maxTenantFreq + 1);
|
|
77
|
+
|
|
78
|
+
// Diversity Adjustment
|
|
79
|
+
var diversityRaw = (Math.log10(candidate.tenantFreq + 1) * 0.50 + Math.log10(candidate.docFreq + 1) * 0.25 + Math.log10(candidate.authorFreq + 1) * 0.25) / maxPossibleLog;
|
|
80
|
+
var sessionMultiplier = candidate.sessionFreq > 0 ? 1 + Math.log10(candidate.sessionFreq + 1) * 2.5 : 1;
|
|
81
|
+
|
|
82
|
+
// Apply multiplier; capped at L1_SESSION_CAP (default 1.2) to prevent excessive over-indexing
|
|
83
|
+
var freqScore = Math.min(diversityRaw * sessionMultiplier, L1_SESSION_CAP);
|
|
84
|
+
|
|
85
|
+
// 3. Semantic Scoring
|
|
86
|
+
var semanticScore = NEUTRAL_SCORE;
|
|
87
|
+
if (contextVector) {
|
|
88
|
+
var wordVec = getWordVector(candidate.word);
|
|
89
|
+
semanticScore = wordVec ? cosineSimilarity(contextVector, wordVec) : NEUTRAL_SCORE;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
semanticScore: semanticScore,
|
|
93
|
+
freqScore: freqScore,
|
|
94
|
+
stage1Score: ALPHA * semanticScore + BETA * freqScore
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ─── Grammar Filter ─────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* GHOST POS DICTIONARY
|
|
102
|
+
* A hardcoded mapping of common structural English words that were stripped
|
|
103
|
+
* from the main domain vocabulary. This allows the grammar filter to understand
|
|
104
|
+
* context without suggesting these words to the user.
|
|
105
|
+
*/
|
|
106
|
+
var ghostPosTags = _ghost_pos_tags.default;
|
|
107
|
+
function applyGrammarFilter(candidates, previousWord) {
|
|
108
|
+
if (!previousWord) return {
|
|
109
|
+
filtered: candidates,
|
|
110
|
+
grammarMeta: null
|
|
111
|
+
};
|
|
112
|
+
var lowerPrev = previousWord.toLowerCase();
|
|
113
|
+
var prevTags = ghostPosTags[lowerPrev] || posTags.get(lowerPrev);
|
|
114
|
+
if (!prevTags || prevTags.length === 0) {
|
|
115
|
+
return {
|
|
116
|
+
filtered: candidates,
|
|
117
|
+
grammarMeta: null
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
var allowedNextTags;
|
|
121
|
+
if (prevTags.length === 1) {
|
|
122
|
+
var _precomputedAllowedBy;
|
|
123
|
+
// Common case: single POS tag — reuse the precomputed Set directly (no allocation)
|
|
124
|
+
allowedNextTags = (_precomputedAllowedBy = precomputedAllowedByPos.get(prevTags[0])) !== null && _precomputedAllowedBy !== void 0 ? _precomputedAllowedBy : new Set();
|
|
125
|
+
} else {
|
|
126
|
+
allowedNextTags = new Set();
|
|
127
|
+
var _iterator = _createForOfIteratorHelper(prevTags),
|
|
128
|
+
_step;
|
|
129
|
+
try {
|
|
130
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
131
|
+
var pt = _step.value;
|
|
132
|
+
var allowed = precomputedAllowedByPos.get(pt);
|
|
133
|
+
if (allowed) allowed.forEach(function (tag) {
|
|
134
|
+
return allowedNextTags.add(tag);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
_iterator.e(err);
|
|
139
|
+
} finally {
|
|
140
|
+
_iterator.f();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
var filtered = [];
|
|
144
|
+
var dropped = [];
|
|
145
|
+
var _iterator2 = _createForOfIteratorHelper(candidates),
|
|
146
|
+
_step2;
|
|
147
|
+
try {
|
|
148
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
149
|
+
var entry = _step2.value;
|
|
150
|
+
var candidateTags = posTags.get(entry.candidate.word.toLowerCase());
|
|
151
|
+
|
|
152
|
+
// If candidate has no tags (unknown word), let it pass to be safe
|
|
153
|
+
if (!candidateTags || candidateTags.length === 0) {
|
|
154
|
+
filtered.push(entry);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (candidateTags.some(function (ct) {
|
|
158
|
+
return allowedNextTags.has(ct);
|
|
159
|
+
})) {
|
|
160
|
+
filtered.push(entry);
|
|
161
|
+
} else {
|
|
162
|
+
dropped.push(entry.candidate.word);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} catch (err) {
|
|
166
|
+
_iterator2.e(err);
|
|
167
|
+
} finally {
|
|
168
|
+
_iterator2.f();
|
|
169
|
+
}
|
|
170
|
+
var finalFiltered = filtered.length > 0 ? filtered : candidates;
|
|
171
|
+
return {
|
|
172
|
+
filtered: finalFiltered,
|
|
173
|
+
grammarMeta: {
|
|
174
|
+
prevWord: lowerPrev,
|
|
175
|
+
prevTags: prevTags,
|
|
176
|
+
before: candidates.length,
|
|
177
|
+
after: finalFiltered.length,
|
|
178
|
+
dropped: filtered.length > 0 ? dropped : []
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ─── Stage 2: LM Re-ranking ────────────────────────────────
|
|
184
|
+
function getLmScore(word, lmLogits) {
|
|
185
|
+
if (!lmLogits) return 0;
|
|
186
|
+
|
|
187
|
+
// Look up the word directly! No more tokens.
|
|
188
|
+
var val = lmLogits[word.toLowerCase()];
|
|
189
|
+
if (typeof val === 'number') {
|
|
190
|
+
return val;
|
|
191
|
+
}
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
196
|
+
|
|
197
|
+
function rankCandidates(candidates, contextVector, getWordVector, lmLogits, maxTenantFreq, previousWord) {
|
|
198
|
+
// Stage 1
|
|
199
|
+
var stage1Results = candidates.map(function (candidate) {
|
|
200
|
+
var _scoreStage = scoreStage1(candidate, contextVector, getWordVector, maxTenantFreq),
|
|
201
|
+
semanticScore = _scoreStage.semanticScore,
|
|
202
|
+
freqScore = _scoreStage.freqScore,
|
|
203
|
+
stage1Score = _scoreStage.stage1Score;
|
|
204
|
+
return {
|
|
205
|
+
candidate: candidate,
|
|
206
|
+
semanticScore: semanticScore,
|
|
207
|
+
freqScore: freqScore,
|
|
208
|
+
stage1Score: stage1Score
|
|
209
|
+
};
|
|
210
|
+
});
|
|
211
|
+
var stage1Survivors = stage1Results.filter(function (entry) {
|
|
212
|
+
return entry.stage1Score >= MIN_STAGE1_SCORE;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Grammar Filter
|
|
216
|
+
var _applyGrammarFilter = applyGrammarFilter(stage1Survivors, previousWord),
|
|
217
|
+
filtered = _applyGrammarFilter.filtered,
|
|
218
|
+
grammarMeta = _applyGrammarFilter.grammarMeta;
|
|
219
|
+
|
|
220
|
+
// Stage 2 + final assembly
|
|
221
|
+
var lmMax = 0;
|
|
222
|
+
if (lmLogits && Object.keys(lmLogits).length > 0) {
|
|
223
|
+
var values = Object.values(lmLogits);
|
|
224
|
+
lmMax = Math.max.apply(Math, values);
|
|
225
|
+
}
|
|
226
|
+
var scored = filtered.map(function (entry) {
|
|
227
|
+
var lmScore = 0;
|
|
228
|
+
var finalScore = entry.stage1Score;
|
|
229
|
+
if (lmLogits && Object.keys(lmLogits).length > 0) {
|
|
230
|
+
var rawLm = getLmScore(entry.candidate.word, lmLogits);
|
|
231
|
+
if (rawLm !== 0) {
|
|
232
|
+
// The word was in the top_k! Score it normally.
|
|
233
|
+
var logitDiff = Math.log(rawLm) - Math.log(lmMax);
|
|
234
|
+
lmScore = Math.exp(logitDiff);
|
|
235
|
+
} else {
|
|
236
|
+
lmScore = 0.05;
|
|
237
|
+
}
|
|
238
|
+
finalScore = STAGE1_WEIGHT * entry.stage1Score + STAGE2_WEIGHT * lmScore;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
word: entry.candidate.word,
|
|
242
|
+
freqScore: entry.freqScore,
|
|
243
|
+
semanticScore: entry.semanticScore,
|
|
244
|
+
lmScore: lmScore,
|
|
245
|
+
finalScore: finalScore
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
scored.sort(function (a, b) {
|
|
249
|
+
if (b.finalScore !== a.finalScore) {
|
|
250
|
+
return b.finalScore - a.finalScore;
|
|
251
|
+
}
|
|
252
|
+
return a.word.length - b.word.length;
|
|
253
|
+
});
|
|
254
|
+
return {
|
|
255
|
+
candidates: scored,
|
|
256
|
+
grammarMeta: grammarMeta
|
|
257
|
+
};
|
|
258
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.setDefaultSlowLaneClient = exports.isWordBoundary = exports.getStoredLmLogits = exports.getStoredContextVector = exports.createSlowLaneClient = void 0;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
10
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
|
+
/**
|
|
12
|
+
* Slow Lane Client: Backend context encoding for autocomplete.
|
|
13
|
+
*
|
|
14
|
+
* Fires a BE request on word boundaries to encode document context.
|
|
15
|
+
* Expects the typeahead-encodings API format:
|
|
16
|
+
* Request: { text, session_id }
|
|
17
|
+
* Response: { semantic_vector: number[], lm_logits: Record<string, number> }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
/** Request payload for typeahead-encodings endpoint. */
|
|
23
|
+
|
|
24
|
+
/** Response from typeahead-encodings endpoint. */
|
|
25
|
+
|
|
26
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
var WORD_BOUNDARY_CHARS = /[\t-\r !,\.:;\?\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
29
|
+
var DEFAULT_DEBOUNCE_MS = 300;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if text ends with a word boundary character (space or punctuation).
|
|
33
|
+
*/
|
|
34
|
+
var isWordBoundary = exports.isWordBoundary = function isWordBoundary(text) {
|
|
35
|
+
if (!text || text.length === 0) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
var lastChar = text[text.length - 1];
|
|
39
|
+
return WORD_BOUNDARY_CHARS.test(lastChar);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// ─── Slow Lane Client ────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
var createSlowLaneClient = exports.createSlowLaneClient = function createSlowLaneClient(config) {
|
|
45
|
+
var baseUrl = config.baseUrl,
|
|
46
|
+
configSessionId = config.sessionId,
|
|
47
|
+
_config$productKey = config.productKey,
|
|
48
|
+
productKey = _config$productKey === void 0 ? 'confluence' : _config$productKey,
|
|
49
|
+
_config$endpoint = config.endpoint,
|
|
50
|
+
endpoint = _config$endpoint === void 0 ? '/gateway/api/v1/autocomplete/typeahead-encodings' : _config$endpoint,
|
|
51
|
+
_config$debounceMs = config.debounceMs,
|
|
52
|
+
debounceMs = _config$debounceMs === void 0 ? DEFAULT_DEBOUNCE_MS : _config$debounceMs,
|
|
53
|
+
_config$fetchFn = config.fetchFn,
|
|
54
|
+
fetchFn = _config$fetchFn === void 0 ? fetch : _config$fetchFn,
|
|
55
|
+
onUpdate = config.onUpdate;
|
|
56
|
+
var sessionId = configSessionId !== null && configSessionId !== void 0 ? configSessionId : crypto.randomUUID();
|
|
57
|
+
var headers = {
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
'x-experience-id': 'confluence-smart-typeahead-encodings',
|
|
60
|
+
'x-product': productKey
|
|
61
|
+
};
|
|
62
|
+
var debounceTimer = null;
|
|
63
|
+
var lastRequestedText = '';
|
|
64
|
+
var storedContextVector = null;
|
|
65
|
+
var storedLmLogits = null;
|
|
66
|
+
var doUpdateContext = /*#__PURE__*/function () {
|
|
67
|
+
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(text) {
|
|
68
|
+
var url, payload, res, data;
|
|
69
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
70
|
+
while (1) switch (_context.prev = _context.next) {
|
|
71
|
+
case 0:
|
|
72
|
+
if (!(!text || text.trim().length === 0)) {
|
|
73
|
+
_context.next = 2;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
return _context.abrupt("return");
|
|
77
|
+
case 2:
|
|
78
|
+
url = "".concat(baseUrl.replace(/\/$/, '')).concat(endpoint);
|
|
79
|
+
payload = {
|
|
80
|
+
text: text,
|
|
81
|
+
session_id: sessionId
|
|
82
|
+
}; // Log the exact payload being sent so the comment/reply structure is visible
|
|
83
|
+
// eslint-disable-next-line no-console
|
|
84
|
+
console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE4 Sending context | ".concat(text.length, " chars"), 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
|
|
85
|
+
text.split('\n').forEach(function (line, i, arr) {
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.log(" ".concat(i === arr.length - 1 ? '▶' : ' ', " ").concat(line));
|
|
88
|
+
});
|
|
89
|
+
// eslint-disable-next-line no-console
|
|
90
|
+
console.groupEnd();
|
|
91
|
+
_context.prev = 7;
|
|
92
|
+
_context.next = 10;
|
|
93
|
+
return fetchFn(url, {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: headers,
|
|
96
|
+
body: JSON.stringify(payload)
|
|
97
|
+
});
|
|
98
|
+
case 10:
|
|
99
|
+
res = _context.sent;
|
|
100
|
+
if (res.ok) {
|
|
101
|
+
_context.next = 16;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
storedContextVector = null;
|
|
105
|
+
storedLmLogits = null;
|
|
106
|
+
// eslint-disable-next-line no-console
|
|
107
|
+
console.log("%c[SlowLane] %c\u274C Request failed (".concat(res.status, ")"), 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
|
|
108
|
+
return _context.abrupt("return");
|
|
109
|
+
case 16:
|
|
110
|
+
_context.next = 18;
|
|
111
|
+
return res.json();
|
|
112
|
+
case 18:
|
|
113
|
+
data = _context.sent;
|
|
114
|
+
if (data.semantic_vector && Array.isArray(data.semantic_vector)) {
|
|
115
|
+
storedContextVector = new Float32Array(data.semantic_vector);
|
|
116
|
+
} else {
|
|
117
|
+
storedContextVector = null;
|
|
118
|
+
}
|
|
119
|
+
if (data.lm_logits && (0, _typeof2.default)(data.lm_logits) === 'object') {
|
|
120
|
+
storedLmLogits = data.lm_logits;
|
|
121
|
+
} else {
|
|
122
|
+
storedLmLogits = null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Log what came back so it can be correlated with the next prediction group
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE5 Response received", 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
console.log(storedContextVector ? "\u2705 semantic_vector: ".concat(storedContextVector.length, " dims") : '❌ No semantic_vector');
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.log(storedLmLogits ? "\u2705 lm_logits: ".concat(Object.keys(storedLmLogits).length, " tokens") : '❌ No lm_logits');
|
|
132
|
+
// eslint-disable-next-line no-console
|
|
133
|
+
console.groupEnd();
|
|
134
|
+
onUpdate === null || onUpdate === void 0 || onUpdate({
|
|
135
|
+
textLength: text.length,
|
|
136
|
+
hasVector: storedContextVector !== null,
|
|
137
|
+
hasLmLogits: storedLmLogits !== null
|
|
138
|
+
});
|
|
139
|
+
// eslint-disable-next-line no-unused-vars
|
|
140
|
+
_context.next = 33;
|
|
141
|
+
break;
|
|
142
|
+
case 28:
|
|
143
|
+
_context.prev = 28;
|
|
144
|
+
_context.t0 = _context["catch"](7);
|
|
145
|
+
storedContextVector = null;
|
|
146
|
+
storedLmLogits = null;
|
|
147
|
+
// eslint-disable-next-line no-console
|
|
148
|
+
console.log('%c[SlowLane] %c❌ Network error — context cleared', 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
|
|
149
|
+
case 33:
|
|
150
|
+
case "end":
|
|
151
|
+
return _context.stop();
|
|
152
|
+
}
|
|
153
|
+
}, _callee, null, [[7, 28]]);
|
|
154
|
+
}));
|
|
155
|
+
return function doUpdateContext(_x) {
|
|
156
|
+
return _ref.apply(this, arguments);
|
|
157
|
+
};
|
|
158
|
+
}();
|
|
159
|
+
var updateContextDebounced = function updateContextDebounced(text) {
|
|
160
|
+
if (debounceTimer) {
|
|
161
|
+
clearTimeout(debounceTimer);
|
|
162
|
+
}
|
|
163
|
+
lastRequestedText = text;
|
|
164
|
+
debounceTimer = setTimeout(function () {
|
|
165
|
+
debounceTimer = null;
|
|
166
|
+
doUpdateContext(lastRequestedText);
|
|
167
|
+
}, debounceMs);
|
|
168
|
+
};
|
|
169
|
+
return {
|
|
170
|
+
updateContext: updateContextDebounced,
|
|
171
|
+
getContextVector: function getContextVector() {
|
|
172
|
+
return storedContextVector;
|
|
173
|
+
},
|
|
174
|
+
getLmLogits: function getLmLogits() {
|
|
175
|
+
return storedLmLogits;
|
|
176
|
+
},
|
|
177
|
+
setContextVector: function setContextVector(vector) {
|
|
178
|
+
storedContextVector = vector;
|
|
179
|
+
},
|
|
180
|
+
setLmLogits: function setLmLogits(logits) {
|
|
181
|
+
storedLmLogits = logits;
|
|
182
|
+
},
|
|
183
|
+
isWordBoundary: isWordBoundary
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
var defaultSlowLaneClient = null;
|
|
187
|
+
var setDefaultSlowLaneClient = exports.setDefaultSlowLaneClient = function setDefaultSlowLaneClient(client) {
|
|
188
|
+
defaultSlowLaneClient = client;
|
|
189
|
+
};
|
|
190
|
+
var getStoredContextVector = exports.getStoredContextVector = function getStoredContextVector() {
|
|
191
|
+
var _defaultSlowLaneClien, _defaultSlowLaneClien2;
|
|
192
|
+
return (_defaultSlowLaneClien = (_defaultSlowLaneClien2 = defaultSlowLaneClient) === null || _defaultSlowLaneClien2 === void 0 ? void 0 : _defaultSlowLaneClien2.getContextVector()) !== null && _defaultSlowLaneClien !== void 0 ? _defaultSlowLaneClien : null;
|
|
193
|
+
};
|
|
194
|
+
var getStoredLmLogits = exports.getStoredLmLogits = function getStoredLmLogits() {
|
|
195
|
+
var _defaultSlowLaneClien3, _defaultSlowLaneClien4;
|
|
196
|
+
return (_defaultSlowLaneClien3 = (_defaultSlowLaneClien4 = defaultSlowLaneClient) === null || _defaultSlowLaneClien4 === void 0 ? void 0 : _defaultSlowLaneClien4.getLmLogits()) !== null && _defaultSlowLaneClien3 !== void 0 ? _defaultSlowLaneClien3 : null;
|
|
197
|
+
};
|