@atlaskit/editor-plugin-mentions 18.2.7 → 18.2.9

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.
@@ -1,16 +1,11 @@
1
1
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
- import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
3
  import { insm } from '@atlaskit/insm';
5
- import { isResolvingMentionProvider, MentionNameStatus, SLI_EVENT_TYPE, SMART_EVENT_TYPE } from '@atlaskit/mention/resource';
4
+ import { SLI_EVENT_TYPE, SMART_EVENT_TYPE } from '@atlaskit/mention/resource';
6
5
  import { ComponentNames } from '@atlaskit/mention/types';
7
- import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
8
6
  import { fg } from '@atlaskit/platform-feature-flags/fg';
9
- import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
10
7
  import { MentionNodeView } from '../nodeviews/mentionNodeView';
11
8
  import { MENTION_PROVIDER_REJECTED, MENTION_PROVIDER_UNDEFINED } from '../types';
12
- import { getAgentMentionParentContext } from './agent-mention-context';
13
- import { nextRunStateDecorations } from './agent-run-state';
14
9
  import { mentionPluginKey } from './key';
15
10
  import { canMentionBeCreatedInRange } from './utils';
16
11
  export const ACTIONS = {
@@ -36,29 +31,8 @@ export const ACTIONS = {
36
31
  */
37
32
  CLEAR_PENDING_PASTED_AGENT_MENTION: 'CLEAR_PENDING_PASTED_AGENT_MENTION'
38
33
  };
39
-
40
- // 'AGENT' is not in the ADF schema UserType enum but is used at runtime.
41
-
42
- const AGENT_USER_TYPES = new Set(['APP', 'AGENT']);
43
- const isAgentUserType = userType => {
44
- return typeof userType === 'string' && AGENT_USER_TYPES.has(userType);
45
- };
46
- const getAgentMentionName = (text, fallbackName) => {
47
- const trimmedFallbackName = typeof fallbackName === 'string' ? fallbackName.trim() : '';
48
- const normalizedFallbackName = (trimmedFallbackName.startsWith('@') ? trimmedFallbackName.slice(1).trim() : trimmedFallbackName) || null;
49
- if (typeof text !== 'string') {
50
- return normalizedFallbackName;
51
- }
52
- const trimmedText = text.trim();
53
- const displayName = trimmedText.startsWith('@') ? trimmedText.slice(1).trim() : trimmedText;
54
- const normalizedName = displayName || normalizedFallbackName;
55
- return normalizedName;
56
- };
57
- const AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
58
- const AGENT_MENTION_INACTIVITY_MS = 3000;
59
- const MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
60
34
  const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
61
- const PACKAGE_VERSION = "18.2.6";
35
+ const PACKAGE_VERSION = "18.2.8";
62
36
  const setProvider = provider => (state, dispatch) => {
63
37
  if (dispatch) {
64
38
  dispatch(state.tr.setMeta(mentionPluginKey, {
@@ -70,266 +44,6 @@ const setProvider = provider => (state, dispatch) => {
70
44
  }
71
45
  return true;
72
46
  };
73
-
74
- /**
75
- * Returns true when a transaction represents a local user document edit that
76
- * should restart pending agent-mention inactivity tracking.
77
- *
78
- * Remote/collab updates, replace-document transactions, AI streaming transforms,
79
- * selection-only movements, and metadata-only transactions are intentionally ignored.
80
- */
81
- const isQualifyingLocalUserDocChange = tr => {
82
- const isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
83
- return tr.docChanged && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
84
- };
85
- const isLocalSelectionChange = (tr, hasPositionChanged) => {
86
- const isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
87
-
88
- // Pressing Enter can move selection through a doc split without setting tr.selectionSet
89
- // or changing from/to numerically, so local doc changes are checked against the
90
- // pending mention's current parent before publishing.
91
- return (hasPositionChanged || tr.docChanged) && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
92
- };
93
-
94
- /**
95
- * Reads agent-mention details from a known document position without traversing
96
- * the document. Callers pass a matcher so mapped positions are only accepted
97
- * when they still point at the same pending/tracked mention.
98
- */
99
- const getAgentMentionDetailsAtPos = (state, pos, matchesMention, fallbackName) => {
100
- var _parentNode$type$name;
101
- if (pos < 0 || pos > state.doc.content.size) {
102
- return null;
103
- }
104
- const node = state.doc.nodeAt(pos);
105
- const mentionSchema = state.schema.nodes.mention;
106
- if ((node === null || node === void 0 ? void 0 : node.type) !== mentionSchema || !isAgentUserType(node.attrs.userType) || !matchesMention(node.attrs) || !node.attrs.id || !node.attrs.localId) {
107
- return null;
108
- }
109
- const $mentionPos = state.doc.resolve(Math.min(pos + node.nodeSize, state.doc.content.size));
110
- const parentNode = $mentionPos.node($mentionPos.depth);
111
- const id = node.attrs.id;
112
- const name = getAgentMentionName(node.attrs.text, fallbackName);
113
- return {
114
- id,
115
- localId: node.attrs.localId,
116
- context: getAgentMentionParentContext(parentNode, node.attrs.localId),
117
- name,
118
- prompt: parentNode.textContent.trim() || null,
119
- nodeSize: node.nodeSize,
120
- parentEnd: $mentionPos.end($mentionPos.depth),
121
- parentNodeType: (_parentNode$type$name = parentNode.type.name) !== null && _parentNode$type$name !== void 0 ? _parentNode$type$name : null,
122
- parentStart: $mentionPos.start($mentionPos.depth),
123
- pos
124
- };
125
- };
126
-
127
- /**
128
- * Finds an agent mention that survived a document change when the changed-range
129
- * scan did not find one. Uses the tracked localId as the mention instance identity
130
- * so same-agent mentions elsewhere in the document cannot be selected as fallback.
131
- */
132
- const getSurvivingAgentMentionDetails = (state, preferredLocalId, preferredName) => {
133
- const mentionSchema = state.schema.nodes.mention;
134
- let result = null;
135
- state.doc.descendants((node, pos) => {
136
- if (result) {
137
- return false;
138
- }
139
- if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType) || node.attrs.localId !== preferredLocalId) {
140
- return true;
141
- }
142
- result = getAgentMentionDetailsAtPos(state, pos, attrs => attrs.localId === preferredLocalId, preferredName);
143
- return !result;
144
- });
145
- return result;
146
- };
147
-
148
- /**
149
- * Maps a pending typed agent mention through a document-changing transaction and
150
- * returns the updated pending state. If the mapped position was deleted or no
151
- * longer points at the same local mention, the pending mention is cleared.
152
- */
153
- const getPendingTypedAgentMentionAfterDocChange = (state, tr, pendingTypedAgentMention, {
154
- resetTimer
155
- }) => {
156
- const mappedPos = tr.mapping.mapResult(pendingTypedAgentMention.pos, 1);
157
- const resetCount = resetTimer ? pendingTypedAgentMention.resetCount + 1 : pendingTypedAgentMention.resetCount;
158
- if (mappedPos.deleted) {
159
- return null;
160
- }
161
- const pendingMentionDetails = getAgentMentionDetailsAtPos(state, mappedPos.pos, attrs => attrs.localId === pendingTypedAgentMention.localId, pendingTypedAgentMention.name);
162
- return pendingMentionDetails ? {
163
- id: pendingMentionDetails.id,
164
- localId: pendingTypedAgentMention.localId,
165
- name: pendingMentionDetails.name,
166
- nodeSize: pendingMentionDetails.nodeSize,
167
- parentNodeType: pendingMentionDetails.parentNodeType,
168
- pos: pendingMentionDetails.pos,
169
- resetCount
170
- } : null;
171
- };
172
- const hasPendingMentionMovedToNewParent = (oldState, tr, previousPendingTypedAgentMention, pendingMentionDetails) => {
173
- if (!previousPendingTypedAgentMention) {
174
- return false;
175
- }
176
- const previousMentionDetails = getAgentMentionDetailsAtPos(oldState, previousPendingTypedAgentMention.pos, attrs => attrs.localId === previousPendingTypedAgentMention.localId);
177
-
178
- // Keep the previous parent boundary associated with the left side of an
179
- // insertion at that boundary, so typing at the start of the parent does not
180
- // look like the pending mention moved into a new parent.
181
- const mappedPreviousParentStart = previousMentionDetails && tr.mapping.map(previousMentionDetails.parentStart, -1);
182
- return Boolean(previousMentionDetails && mappedPreviousParentStart !== pendingMentionDetails.parentStart);
183
- };
184
- const isSelectionOutsideDirectParent = (state, pendingMentionDetails) => {
185
- return state.selection.from < pendingMentionDetails.parentStart || state.selection.to > pendingMentionDetails.parentEnd;
186
- };
187
-
188
- /**
189
- * Finalises a pending typed agent mention by copying its details into the
190
- * public lastInserted* plugin state after the caller has already resolved the
191
- * pending mention from the current document.
192
- */
193
- const commitResolvedPendingTypedAgentMention = (pluginState, pendingMentionDetails) => {
194
- var _pluginState$lastAgen;
195
- return {
196
- hasPublicPluginStateChanged: true,
197
- pluginState: {
198
- ...pluginState,
199
- pendingTypedAgentMention: null,
200
- lastInsertedAgentMentionId: pendingMentionDetails.id,
201
- lastInsertedAgentMentionLocalId: pendingMentionDetails.localId,
202
- lastInsertedAgentMentionContext: pendingMentionDetails.context,
203
- lastInsertedAgentMentionName: pendingMentionDetails.name,
204
- lastInsertedAgentMentionPrompt: pendingMentionDetails.prompt,
205
- lastInsertedAgentMentionParentNodeType: pendingMentionDetails.parentNodeType,
206
- lastAgentMentionInsertionCount: ((_pluginState$lastAgen = pluginState.lastAgentMentionInsertionCount) !== null && _pluginState$lastAgen !== void 0 ? _pluginState$lastAgen : 0) + 1
207
- }
208
- };
209
- };
210
-
211
- /**
212
- * Resolves and finalises a pending typed agent mention. If the tracked mention
213
- * no longer resolves, the stale pending state is cleared without dispatching a
214
- * public update.
215
- */
216
- const commitPendingTypedAgentMention = (state, pluginState, pendingTypedAgentMention) => {
217
- const pendingMentionDetails = getAgentMentionDetailsAtPos(state, pendingTypedAgentMention.pos, attrs => attrs.localId === pendingTypedAgentMention.localId, pendingTypedAgentMention.name);
218
- if (!pendingMentionDetails) {
219
- return {
220
- hasPublicPluginStateChanged: false,
221
- pluginState: {
222
- ...pluginState,
223
- pendingTypedAgentMention: null
224
- }
225
- };
226
- }
227
- return commitResolvedPendingTypedAgentMention(pluginState, pendingMentionDetails);
228
- };
229
- const hasTrackedAgentMentionState = pluginState => Boolean(pluginState.pendingTypedAgentMention) || Boolean(pluginState.pendingPastedAgentMention) && fg('platform_editor_agent_mentions_drop_one_fixes') || pluginState.lastInsertedAgentMentionId != null || pluginState.lastInsertedAgentMentionLocalId != null || pluginState.lastInsertedAgentMentionContext != null || pluginState.lastInsertedAgentMentionName != null || pluginState.lastInsertedAgentMentionPrompt != null || pluginState.lastInsertedAgentMentionParentNodeType != null;
230
-
231
- /**
232
- * Clears agent mention state that points at a specific document snapshot.
233
- * replaceDocument swaps content wholesale, so pending typed mentions and
234
- * lastInserted* details from the previous document must be cleared together.
235
- */
236
- const clearTrackedAgentMentionState = pluginState => {
237
- return {
238
- ...pluginState,
239
- pendingTypedAgentMention: null,
240
- ...(fg('platform_editor_agent_mentions_drop_one_fixes') ? {
241
- pendingPastedAgentMention: null
242
- } : {}),
243
- lastInsertedAgentMentionId: null,
244
- lastInsertedAgentMentionLocalId: null,
245
- lastInsertedAgentMentionContext: null,
246
- lastInsertedAgentMentionName: null,
247
- lastInsertedAgentMentionPrompt: null,
248
- lastInsertedAgentMentionParentNodeType: null
249
- };
250
- };
251
-
252
- /**
253
- * Attempts to synchronously resolve an agent mention name from the mention
254
- * provider's cache. Falls back to undefined if the provider doesn't support
255
- * name resolution, the result is a Promise (async/cache miss), or the status
256
- * is not OK.
257
- */
258
- const resolveCachedAgentMentionName = (mentionProvider, params, id) => {
259
- if (params !== null && params !== void 0 && params.name || !isResolvingMentionProvider(mentionProvider)) {
260
- var _params$name;
261
- return (_params$name = params === null || params === void 0 ? void 0 : params.name) !== null && _params$name !== void 0 ? _params$name : undefined;
262
- }
263
- const result = mentionProvider.resolveMentionName(id);
264
- if (!(result instanceof Promise) && result.status === MentionNameStatus.OK) {
265
- return result.name || undefined;
266
- }
267
- return undefined;
268
- };
269
-
270
- /**
271
- * Resolves the name of a pasted agent mention via the mention provider and
272
- * dispatches the appropriate action to update plugin state.
273
- *
274
- * Handles both async (Promise) and synchronous cache-hit results:
275
- * - On OK resolution → dispatches RESOLVE_PASTED_AGENT_MENTION_NAME so the nudge
276
- * shows the correct agent name.
277
- * - On non-OK result → dispatches CLEAR_PENDING_PASTED_AGENT_MENTION to prevent
278
- * an infinite retry loop on subsequent update() calls.
279
- *
280
- * Guards against duplicate in-flight requests via pendingResolveMentionIds.
281
- */
282
- export const resolveAndDispatchPastedAgentMentionName = (agentId, mentionProvider, pendingResolveMentionIds, view) => {
283
- if (pendingResolveMentionIds.has(agentId)) {
284
- return;
285
- }
286
- pendingResolveMentionIds.add(agentId);
287
- const result = mentionProvider.resolveMentionName(agentId);
288
- if (result instanceof Promise) {
289
- result.then(nameDetails => {
290
- pendingResolveMentionIds.delete(agentId);
291
- if (nameDetails.status === MentionNameStatus.OK && nameDetails.name) {
292
- view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
293
- action: ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME,
294
- params: {
295
- id: agentId,
296
- name: nameDetails.name
297
- }
298
- }));
299
- } else {
300
- // Non-OK status — clear pendingPastedAgentMention to prevent
301
- // an infinite retry loop on subsequent update() calls.
302
- view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
303
- action: ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION,
304
- params: {
305
- id: agentId
306
- }
307
- }));
308
- }
309
- });
310
- } else if (result.status === MentionNameStatus.OK && result.name) {
311
- pendingResolveMentionIds.delete(agentId);
312
- // Synchronous hit on a second update cycle (e.g. provider warmed up
313
- // between the paste transaction and this view update).
314
- view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
315
- action: ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME,
316
- params: {
317
- id: agentId,
318
- name: result.name
319
- }
320
- }));
321
- } else {
322
- pendingResolveMentionIds.delete(agentId);
323
- // Non-OK synchronous status — clear pendingPastedAgentMention to prevent
324
- // an infinite retry loop on subsequent update() calls.
325
- view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
326
- action: ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION,
327
- params: {
328
- id: agentId
329
- }
330
- }));
331
- }
332
- };
333
47
  export function createMentionPlugin({
334
48
  pmPluginFactoryParams,
335
49
  fireEvent,
@@ -362,7 +76,6 @@ export function createMentionPlugin({
362
76
  };
363
77
  },
364
78
  apply(tr, pluginState, oldState, newState) {
365
- var _params$runStateByLoc;
366
79
  const {
367
80
  action,
368
81
  params
@@ -389,82 +102,7 @@ export function createMentionPlugin({
389
102
  hasPublicPluginStateChanged = true;
390
103
  break;
391
104
  }
392
- const nextDecorations = nextRunStateDecorations(newPluginState.runStateDecorations, tr, newState, action === ACTIONS.SET_AGENT_RUN_STATES ? (_params$runStateByLoc = params === null || params === void 0 ? void 0 : params.runStateByLocalId) !== null && _params$runStateByLoc !== void 0 ? _params$runStateByLoc : {} : undefined);
393
- if (nextDecorations !== newPluginState.runStateDecorations) {
394
- newPluginState = {
395
- ...newPluginState,
396
- runStateDecorations: nextDecorations
397
- };
398
- }
399
- if (!isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') && editorExperiment('platform_editor_agent_mentions', true)) {
400
- switch (action) {
401
- case ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION:
402
- {
403
- const pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
404
- // Ignore stale timer callbacks. The localId and resetCount must still match the
405
- // current pending mention so older timers cannot publish after later user edits.
406
- if (!pendingTypedAgentMention || pendingTypedAgentMention.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMention.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
407
- break;
408
- }
409
- const commitResult = commitPendingTypedAgentMention(newState, newPluginState, pendingTypedAgentMention);
410
- newPluginState = commitResult.pluginState;
411
- hasPublicPluginStateChanged = hasPublicPluginStateChanged || commitResult.hasPublicPluginStateChanged;
412
- break;
413
- }
414
- case ACTIONS.DISCARD_PENDING_TYPED_AGENT_MENTION:
415
- {
416
- // Silently discard the pending typed agent mention without committing it.
417
- const pendingTypedAgentMentionToDiscard = newPluginState.pendingTypedAgentMention;
418
- if (!pendingTypedAgentMentionToDiscard || pendingTypedAgentMentionToDiscard.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMentionToDiscard.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
419
- break;
420
- }
421
- newPluginState = {
422
- ...newPluginState,
423
- pendingTypedAgentMention: null
424
- };
425
- hasPublicPluginStateChanged = true;
426
- break;
427
- }
428
- case ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME:
429
- {
430
- var _newPluginState$pendi, _newPluginState$pendi2, _newPluginState$pendi3, _newPluginState$pendi4, _newPluginState$pendi5, _newPluginState$pendi6;
431
- // Guard: only apply if there is a matching pending pasted mention (staleness check).
432
- if (!(params !== null && params !== void 0 && params.id) || !(params !== null && params !== void 0 && params.name) || ((_newPluginState$pendi = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi === void 0 ? void 0 : _newPluginState$pendi.id) !== params.id || !fg('platform_editor_agent_mentions_drop_one_fixes')) {
433
- break;
434
- }
435
- newPluginState = {
436
- ...newPluginState,
437
- pendingPastedAgentMention: null,
438
- lastInsertedAgentMentionId: (_newPluginState$pendi2 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi2 === void 0 ? void 0 : _newPluginState$pendi2.id,
439
- lastInsertedAgentMentionLocalId: (_newPluginState$pendi3 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi3 === void 0 ? void 0 : _newPluginState$pendi3.localId,
440
- lastInsertedAgentMentionContext: (_newPluginState$pendi4 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi4 === void 0 ? void 0 : _newPluginState$pendi4.context,
441
- lastInsertedAgentMentionName: params.name,
442
- lastInsertedAgentMentionPrompt: (_newPluginState$pendi5 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi5 === void 0 ? void 0 : _newPluginState$pendi5.prompt,
443
- lastInsertedAgentMentionParentNodeType: (_newPluginState$pendi6 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi6 === void 0 ? void 0 : _newPluginState$pendi6.parentNodeType
444
- };
445
- hasPublicPluginStateChanged = true;
446
- break;
447
- }
448
- case ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION:
449
- {
450
- var _newPluginState$pendi7;
451
- if (!(params !== null && params !== void 0 && params.id) || ((_newPluginState$pendi7 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi7 === void 0 ? void 0 : _newPluginState$pendi7.id) !== params.id || !fg('platform_editor_agent_mentions_drop_one_fixes')) {
452
- break;
453
- }
454
- // resolveMentionName() returned a non-OK status — clear the pending state.
455
- newPluginState = {
456
- ...newPluginState,
457
- pendingPastedAgentMention: null
458
- };
459
- break;
460
- }
461
- }
462
- }
463
-
464
- // When the agent mentions experiment is off, dispatch immediately (original behaviour).
465
- // When it's on, defer dispatch to after the agent tracking block below so that
466
- // agent-mention state changes are included in the notification.
467
- if (hasPublicPluginStateChanged && (isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') || !editorExperiment('platform_editor_agent_mentions', true))) {
105
+ if (hasPublicPluginStateChanged) {
468
106
  pmPluginFactoryParams.dispatch(mentionPluginKey, newPluginState);
469
107
  }
470
108
  if (options !== null && options !== void 0 && options.handleMentionsChanged && tr.docChanged) {
@@ -524,279 +162,6 @@ export function createMentionPlugin({
524
162
  }
525
163
  (_insm$session2 = insm.session) === null || _insm$session2 === void 0 ? void 0 : _insm$session2.endFeature('mentionDeletionDetection');
526
164
  }
527
- if (!isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') && editorExperiment('platform_editor_agent_mentions', true) && isQualifyingLocalUserDocChange(tr)) {
528
- const mentionSchema = newState.schema.nodes.mention;
529
- const newDocRanges = [];
530
- const oldDocRanges = [];
531
- let stepsTouchMentions = false;
532
- tr.steps.forEach(step => {
533
- let found = false;
534
- // Only merge a step's ranges if it actually touched an agent mention,
535
- // so unrelated steps (e.g. mark-only changes) don't inflate the scan area.
536
- const stepNewRanges = [];
537
- const stepOldRanges = [];
538
- step.getMap().forEach((oldFrom, oldTo, newFrom, newTo) => {
539
- stepOldRanges.push([oldFrom, oldTo]);
540
- stepNewRanges.push([newFrom, newTo]);
541
- if (!found) {
542
- // Clamp positions: delete-only steps can produce newTo > doc.content.size.
543
- const clampedNewFrom = Math.min(newFrom, newState.doc.content.size);
544
- const clampedNewTo = Math.min(newTo, newState.doc.content.size);
545
- if (clampedNewFrom < clampedNewTo) {
546
- newState.doc.nodesBetween(clampedNewFrom, clampedNewTo, node => {
547
- if (node.type === mentionSchema && isAgentUserType(node.attrs.userType)) {
548
- found = true;
549
- }
550
- return !found;
551
- });
552
- }
553
- if (!found) {
554
- const clampedOldFrom = Math.min(oldFrom, oldState.doc.content.size);
555
- const clampedOldTo = Math.min(oldTo, oldState.doc.content.size);
556
- if (clampedOldFrom < clampedOldTo) {
557
- oldState.doc.nodesBetween(clampedOldFrom, clampedOldTo, node => {
558
- if (node.type === mentionSchema && AGENT_USER_TYPES.has(node.attrs.userType)) {
559
- found = true;
560
- }
561
- return !found;
562
- });
563
- }
564
- }
565
- }
566
- });
567
- if (found) {
568
- stepsTouchMentions = true;
569
- newDocRanges.push(...stepNewRanges);
570
- oldDocRanges.push(...stepOldRanges);
571
- }
572
- });
573
- const shouldResolveAgentMentionState = stepsTouchMentions || Boolean(newPluginState.lastInsertedAgentMentionLocalId);
574
- if (shouldResolveAgentMentionState) {
575
- var _newPluginState$lastI, _newPluginState$lastA, _newPluginState$lastI2, _newPluginState$lastI3, _newPluginState$lastI4, _newPluginState$lastI5, _newPluginState$lastI6;
576
- let agentMentionId = null;
577
- let agentMentionLocalId = null;
578
- let agentMentionContext = null;
579
- let agentMentionName = null;
580
- let agentMentionPrompt = null;
581
- let agentMentionParentNodeType = null;
582
- const existingAgentMentionLocalIdsInChangedRanges = new Set();
583
- let pendingTypedAgentMentionDetails = null;
584
- if (stepsTouchMentions) {
585
- for (const [from, to] of newDocRanges) {
586
- const clampedTo = Math.min(to, newState.doc.content.size);
587
- if (from >= clampedTo) {
588
- continue;
589
- }
590
- newState.doc.nodesBetween(from, clampedTo, (node, pos) => {
591
- if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType)) {
592
- return true;
593
- }
594
- if (pendingTypedAgentMentionDetails === null && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && node.attrs.localId === (params === null || params === void 0 ? void 0 : params.localId)) {
595
- pendingTypedAgentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, attrs => attrs.localId === params.localId, params.name);
596
- }
597
- if (agentMentionLocalId === null && node.attrs.localId) {
598
- // Try to recover the name synchronously from the mention provider's
599
- // name cache (populated by cacheMentionName on typed insert).
600
- const cachedName = fg('platform_editor_agent_mentions_drop_one_fixes') ? resolveCachedAgentMentionName(mentionProvider, params, node.attrs.id) : params === null || params === void 0 ? void 0 : params.name;
601
- const agentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, attrs => attrs.localId === node.attrs.localId, cachedName);
602
- if (agentMentionDetails) {
603
- agentMentionId = agentMentionDetails.id;
604
- agentMentionLocalId = agentMentionDetails.localId;
605
- agentMentionContext = agentMentionDetails.context;
606
- agentMentionName = agentMentionDetails.name;
607
- agentMentionPrompt = agentMentionDetails.prompt;
608
- agentMentionParentNodeType = agentMentionDetails.parentNodeType;
609
- }
610
- }
611
- return true;
612
- });
613
- }
614
- for (const [from, to] of oldDocRanges) {
615
- const clampedOldTo = Math.min(to, oldState.doc.content.size);
616
- if (from >= clampedOldTo) {
617
- continue;
618
- }
619
- oldState.doc.nodesBetween(from, clampedOldTo, node => {
620
- if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType)) {
621
- return true;
622
- }
623
- if (node.attrs.localId) {
624
- existingAgentMentionLocalIdsInChangedRanges.add(node.attrs.localId);
625
- }
626
- return true;
627
- });
628
- }
629
- }
630
-
631
- // When a deletion collapses the new-doc range to a zero-width point, or when
632
- // the doc changed but no step covered the tracked mention, the new-doc scan
633
- // above finds nothing. Check whether any agent mention survived in the document.
634
- let resolvedFromFullDocFallback = false;
635
- if (agentMentionId === null && newPluginState.lastInsertedAgentMentionLocalId) {
636
- const survivorDetails = getSurvivingAgentMentionDetails(newState, newPluginState.lastInsertedAgentMentionLocalId, newPluginState.lastInsertedAgentMentionName);
637
- if (survivorDetails) {
638
- agentMentionId = survivorDetails.id;
639
- agentMentionLocalId = survivorDetails.localId;
640
- agentMentionContext = survivorDetails.context;
641
- agentMentionName = survivorDetails.name;
642
- agentMentionPrompt = survivorDetails.prompt;
643
- agentMentionParentNodeType = survivorDetails.parentNodeType;
644
- resolvedFromFullDocFallback = true;
645
- }
646
- }
647
- const trackedAgentMentionLocalId = (_newPluginState$lastI = newPluginState.lastInsertedAgentMentionLocalId) !== null && _newPluginState$lastI !== void 0 ? _newPluginState$lastI : null;
648
- const changedRangeMentionIsNew = agentMentionLocalId !== null && !existingAgentMentionLocalIdsInChangedRanges.has(agentMentionLocalId);
649
- if (agentMentionLocalId !== null && !changedRangeMentionIsNew && agentMentionLocalId !== trackedAgentMentionLocalId) {
650
- const survivorDetails = trackedAgentMentionLocalId ? getSurvivingAgentMentionDetails(newState, trackedAgentMentionLocalId, newPluginState.lastInsertedAgentMentionName) : null;
651
- if (survivorDetails) {
652
- agentMentionId = survivorDetails.id;
653
- agentMentionLocalId = survivorDetails.localId;
654
- agentMentionContext = survivorDetails.context;
655
- agentMentionName = survivorDetails.name;
656
- agentMentionParentNodeType = survivorDetails.parentNodeType;
657
- resolvedFromFullDocFallback = true;
658
- } else {
659
- agentMentionId = null;
660
- agentMentionLocalId = null;
661
- agentMentionContext = null;
662
- agentMentionName = null;
663
- agentMentionParentNodeType = null;
664
- }
665
- }
666
- const isNewInsertion = agentMentionId !== null && !resolvedFromFullDocFallback && changedRangeMentionIsNew;
667
- const isPendingTypedAgentMentionInsertion = isNewInsertion && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && typeof (params === null || params === void 0 ? void 0 : params.localId) === 'string';
668
- const newInsertionCount = isNewInsertion ? ((_newPluginState$lastA = newPluginState.lastAgentMentionInsertionCount) !== null && _newPluginState$lastA !== void 0 ? _newPluginState$lastA : 0) + 1 : undefined;
669
- const pendingTypedAgentMentionDetailsForState = pendingTypedAgentMentionDetails;
670
- if (isPendingTypedAgentMentionInsertion && pendingTypedAgentMentionDetailsForState) {
671
- const pendingTypedAgentMentionLocalId = params === null || params === void 0 ? void 0 : params.localId;
672
- newPluginState = {
673
- ...newPluginState,
674
- pendingTypedAgentMention: {
675
- id: pendingTypedAgentMentionDetailsForState.id,
676
- localId: pendingTypedAgentMentionLocalId,
677
- name: pendingTypedAgentMentionDetailsForState.name,
678
- nodeSize: pendingTypedAgentMentionDetailsForState.nodeSize,
679
- parentNodeType: pendingTypedAgentMentionDetailsForState.parentNodeType,
680
- pos: pendingTypedAgentMentionDetailsForState.pos,
681
- resetCount: 1
682
- }
683
- };
684
- } else if (isPendingTypedAgentMentionInsertion) {
685
- // Fallback: if the localId-specific scan missed the typed mention,
686
- // publish immediately so the insertion is not dropped.
687
- newPluginState = {
688
- ...newPluginState,
689
- pendingTypedAgentMention: null,
690
- lastInsertedAgentMentionId: agentMentionId,
691
- lastInsertedAgentMentionLocalId: agentMentionLocalId,
692
- lastInsertedAgentMentionContext: agentMentionContext,
693
- lastInsertedAgentMentionName: agentMentionName,
694
- lastInsertedAgentMentionPrompt: agentMentionPrompt,
695
- lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType,
696
- ...(newInsertionCount !== undefined ? {
697
- lastAgentMentionInsertionCount: newInsertionCount
698
- } : {})
699
- };
700
- hasPublicPluginStateChanged = true;
701
- } else if (agentMentionId !== ((_newPluginState$lastI2 = newPluginState.lastInsertedAgentMentionId) !== null && _newPluginState$lastI2 !== void 0 ? _newPluginState$lastI2 : null) || agentMentionLocalId !== ((_newPluginState$lastI3 = newPluginState.lastInsertedAgentMentionLocalId) !== null && _newPluginState$lastI3 !== void 0 ? _newPluginState$lastI3 : null) || agentMentionName !== ((_newPluginState$lastI4 = newPluginState.lastInsertedAgentMentionName) !== null && _newPluginState$lastI4 !== void 0 ? _newPluginState$lastI4 : null) || agentMentionPrompt !== ((_newPluginState$lastI5 = newPluginState.lastInsertedAgentMentionPrompt) !== null && _newPluginState$lastI5 !== void 0 ? _newPluginState$lastI5 : null) || agentMentionParentNodeType !== ((_newPluginState$lastI6 = newPluginState.lastInsertedAgentMentionParentNodeType) !== null && _newPluginState$lastI6 !== void 0 ? _newPluginState$lastI6 : null) || newInsertionCount !== undefined) {
702
- var _options$getIsRovoPan;
703
- // Suppress the nudge for pasted/non-typed agent mentions when Rovo is already
704
- // open.
705
- // Task items are exempt only while
706
- // platform_editor_agent_mentions_no_task_autofire is off (they auto-fire
707
- // instead). With it on they are suppressed like every other block.
708
- const isTaskItemMentionForPaste = agentMentionParentNodeType === 'taskItem' && !fg('platform_editor_agent_mentions_no_task_autofire');
709
- if (!isTaskItemMentionForPaste && isNewInsertion && options !== null && options !== void 0 && (_options$getIsRovoPan = options.getIsRovoPanelOpen) !== null && _options$getIsRovoPan !== void 0 && _options$getIsRovoPan.call(options)) {
710
- // Rovo is already open — skip setting lastInsertedAgentMention* so the
711
- // downstream nudge listener never fires.
712
- } else if (agentMentionName === null && agentMentionId !== null && isResolvingMentionProvider(newPluginState.mentionProvider) && fg('platform_editor_agent_mentions_drop_one_fixes')) {
713
- // Store details in pendingPastedAgentMention (private, not broadcast), preventing a double-nudge.
714
- newPluginState = {
715
- ...newPluginState,
716
- pendingPastedAgentMention: {
717
- id: agentMentionId,
718
- localId: agentMentionLocalId,
719
- context: agentMentionContext,
720
- prompt: agentMentionPrompt,
721
- parentNodeType: agentMentionParentNodeType
722
- },
723
- ...(newInsertionCount !== undefined ? {
724
- lastAgentMentionInsertionCount: newInsertionCount
725
- } : {})
726
- };
727
- // the nudge does not fire until the name is resolved.
728
- } else {
729
- // Not suppressed — update state so the nudge fires normally.
730
- newPluginState = {
731
- ...newPluginState,
732
- lastInsertedAgentMentionId: agentMentionId,
733
- lastInsertedAgentMentionLocalId: agentMentionLocalId,
734
- lastInsertedAgentMentionContext: agentMentionContext,
735
- lastInsertedAgentMentionName: agentMentionName,
736
- lastInsertedAgentMentionPrompt: agentMentionPrompt,
737
- lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType,
738
- ...(newInsertionCount !== undefined ? {
739
- lastAgentMentionInsertionCount: newInsertionCount
740
- } : {})
741
- };
742
- hasPublicPluginStateChanged = true;
743
- }
744
- }
745
- }
746
- }
747
- if (!isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') && editorExperiment('platform_editor_agent_mentions', true) && tr.docChanged && tr.getMeta('replaceDocument') && hasTrackedAgentMentionState(newPluginState)) {
748
- newPluginState = clearTrackedAgentMentionState(newPluginState);
749
- hasPublicPluginStateChanged = true;
750
- }
751
- if (!isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') && editorExperiment('platform_editor_agent_mentions', true) && newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && tr.docChanged) {
752
- newPluginState = {
753
- ...newPluginState,
754
- pendingTypedAgentMention: getPendingTypedAgentMentionAfterDocChange(newState, tr, newPluginState.pendingTypedAgentMention, {
755
- resetTimer: isQualifyingLocalUserDocChange(tr)
756
- })
757
- };
758
- }
759
- if (!isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') && editorExperiment('platform_editor_agent_mentions', true)) {
760
- // Typed agent mentions stay pending while the user is still editing around them,
761
- // but leaving the mention's direct parent means they have moved on from that
762
- // paragraph/block. Publish immediately in that case instead of waiting for the
763
- // inactivity timer.
764
- const shouldCheckPendingTypedAgentMentionParent = isLocalSelectionChange(tr, hasPositionChanged);
765
- if (newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && shouldCheckPendingTypedAgentMentionParent) {
766
- const pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
767
- const pendingMentionDetails = getAgentMentionDetailsAtPos(newState, pendingTypedAgentMention.pos, attrs => attrs.localId === pendingTypedAgentMention.localId, pendingTypedAgentMention.name);
768
- if (!pendingMentionDetails) {
769
- newPluginState = {
770
- ...newPluginState,
771
- pendingTypedAgentMention: null
772
- };
773
- } else if (hasPendingMentionMovedToNewParent(oldState, tr, pluginState.pendingTypedAgentMention, pendingMentionDetails) || isSelectionOutsideDirectParent(newState, pendingMentionDetails)) {
774
- var _options$getIsRovoPan2;
775
- // Suppress the nudge when Rovo chat is already open, mirroring the same
776
- // guard used in the inactivity-timer path. Task-item mentions are
777
- // exempt only while platform_editor_agent_mentions_no_task_autofire is off
778
- // (they auto-fire the mini modal and never show a nudge). With it on they
779
- // are suppressed like any block.
780
- const isTaskItemMention = pendingMentionDetails.parentNodeType === 'taskItem' && !fg('platform_editor_agent_mentions_no_task_autofire');
781
- if (!isTaskItemMention && options !== null && options !== void 0 && (_options$getIsRovoPan2 = options.getIsRovoPanelOpen) !== null && _options$getIsRovoPan2 !== void 0 && _options$getIsRovoPan2.call(options)) {
782
- // Discard without committing so lastInsertedAgentMention* fields are
783
- // never set and the downstream nudge listener never fires.
784
- newPluginState = {
785
- ...newPluginState,
786
- pendingTypedAgentMention: null
787
- };
788
- hasPublicPluginStateChanged = true;
789
- } else {
790
- const commitResult = commitResolvedPendingTypedAgentMention(newPluginState, pendingMentionDetails);
791
- newPluginState = commitResult.pluginState;
792
- hasPublicPluginStateChanged = hasPublicPluginStateChanged || commitResult.hasPublicPluginStateChanged;
793
- }
794
- }
795
- }
796
- }
797
- if (hasPublicPluginStateChanged && !isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') && editorExperiment('platform_editor_agent_mentions', true)) {
798
- pmPluginFactoryParams.dispatch(mentionPluginKey, newPluginState);
799
- }
800
165
  return newPluginState;
801
166
  }
802
167
  },
@@ -810,125 +175,9 @@ export function createMentionPlugin({
810
175
  portalProviderAPI: pmPluginFactoryParams.portalProviderAPI
811
176
  });
812
177
  }
813
- },
814
- // Duplicated in platform/packages/editor/editor-plugin-mentions/src/pm-plugins/agent.ts
815
- // Can remove once platform_editor_agent_mentions_separate_pm_plugin has been cleaned up
816
- decorations(state) {
817
- var _mentionPluginKey$get;
818
- const runStateDecorations = (_mentionPluginKey$get = mentionPluginKey.getState(state)) === null || _mentionPluginKey$get === void 0 ? void 0 : _mentionPluginKey$get.runStateDecorations;
819
- if (!runStateDecorations || runStateDecorations === DecorationSet.empty) {
820
- return undefined;
821
- }
822
- if (isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') || !editorExperiment('platform_editor_agent_mentions', true) || !isExperimentEnabled('platform_editor_agent_mention_state_anim')) {
823
- return undefined;
824
- }
825
- return runStateDecorations;
826
178
  }
827
179
  },
828
180
  view(editorView) {
829
- let pendingTypedAgentMentionTimer;
830
- let pendingTypedAgentMentionTimerKey = null;
831
- let pendingTypedAgentMentionFocusDeferCount = 0;
832
- // Tracks agent IDs for which resolveMentionName() is already in-flight,
833
- // preventing duplicate concurrent Promises for the same ID across update() cycles.
834
- const pendingResolveMentionIds = new Set();
835
-
836
- /**
837
- * Clears the currently scheduled pending typed-agent-mention timer.
838
- *
839
- * By default this also resets the focus defer count because a new pending mention,
840
- * local edit reset, or cleanup should start a fresh escape-hatch window. Focus-based
841
- * retries pass `preserveFocusDeferCount` so repeated defers for the same pending
842
- * mention are counted toward the bounded retry cap.
843
- */
844
- const clearPendingTypedAgentMentionTimer = ({
845
- preserveFocusDeferCount = false
846
- } = {}) => {
847
- if (pendingTypedAgentMentionTimer) {
848
- clearTimeout(pendingTypedAgentMentionTimer);
849
- pendingTypedAgentMentionTimer = undefined;
850
- }
851
- pendingTypedAgentMentionTimerKey = null;
852
- if (!preserveFocusDeferCount) {
853
- pendingTypedAgentMentionFocusDeferCount = 0;
854
- }
855
- };
856
-
857
- /**
858
- * Typed agent mentions intentionally wait before invoking the agent so content the
859
- * user adds next can become context. That context can be authored through
860
- * editor-adjacent UI, such as mention typeahead, date picker, or status picker,
861
- * where focus leaves the ProseMirror editor but remains in the active document.
862
- * Treat that as continued authoring activity by restarting the inactivity window.
863
- * This only defers the inactivity timer path: existing selection-change handling can
864
- * still publish or clear the pending mention sooner. After 20 focus defers (~1 minute),
865
- * publish anyway so pathological focus states cannot keep the mention pending indefinitely.
866
- */
867
- const shouldDeferPendingTypedAgentMention = () => typeof document !== 'undefined' && document.hasFocus() && !editorView.hasFocus();
868
- const schedulePendingTypedAgentMentionTimer = (mentionPluginState, {
869
- preserveFocusDeferCount = false
870
- } = {}) => {
871
- if (isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin') || !editorExperiment('platform_editor_agent_mentions', true)) {
872
- clearPendingTypedAgentMentionTimer();
873
- return;
874
- }
875
- const pendingTypedAgentMention = mentionPluginState === null || mentionPluginState === void 0 ? void 0 : mentionPluginState.pendingTypedAgentMention;
876
- if (!pendingTypedAgentMention) {
877
- clearPendingTypedAgentMentionTimer();
878
- return;
879
- }
880
- const timerKey = `${pendingTypedAgentMention.localId}:${pendingTypedAgentMention.resetCount}`;
881
- if (timerKey === pendingTypedAgentMentionTimerKey) {
882
- return;
883
- }
884
- clearPendingTypedAgentMentionTimer({
885
- preserveFocusDeferCount
886
- });
887
- pendingTypedAgentMentionTimerKey = timerKey;
888
- pendingTypedAgentMentionTimer = setTimeout(() => {
889
- var _mentionPluginKey$get2;
890
- {
891
- var _options$getIsRovoPan3;
892
- // Suppress the agent-mention nudge when the Rovo panel is already open. Task
893
- // items are exempt only while platform_editor_agent_mentions_no_task_autofire
894
- // is off (they auto-fire instead). With it on they are suppressed like every
895
- // other block.
896
- const isTaskItemMention = pendingTypedAgentMention.parentNodeType === 'taskItem' && !fg('platform_editor_agent_mentions_no_task_autofire');
897
- if (!isTaskItemMention && options !== null && options !== void 0 && (_options$getIsRovoPan3 = options.getIsRovoPanelOpen) !== null && _options$getIsRovoPan3 !== void 0 && _options$getIsRovoPan3.call(options)) {
898
- // Dispatch a discard so pendingTypedAgentMention is nulled out of plugin
899
- // state.
900
- editorView.dispatch(editorView.state.tr.setMeta(mentionPluginKey, {
901
- action: ACTIONS.DISCARD_PENDING_TYPED_AGENT_MENTION,
902
- params: {
903
- localId: pendingTypedAgentMention.localId,
904
- resetCount: pendingTypedAgentMention.resetCount
905
- }
906
- }));
907
- return;
908
- }
909
- }
910
- const latestPendingTypedAgentMention = (_mentionPluginKey$get2 = mentionPluginKey.getState(editorView.state)) === null || _mentionPluginKey$get2 === void 0 ? void 0 : _mentionPluginKey$get2.pendingTypedAgentMention;
911
- if (!latestPendingTypedAgentMention || latestPendingTypedAgentMention.localId !== pendingTypedAgentMention.localId || latestPendingTypedAgentMention.resetCount !== pendingTypedAgentMention.resetCount) {
912
- return;
913
- }
914
- if (shouldDeferPendingTypedAgentMention() && pendingTypedAgentMentionFocusDeferCount < MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS) {
915
- pendingTypedAgentMentionFocusDeferCount++;
916
- pendingTypedAgentMentionTimerKey = null;
917
- schedulePendingTypedAgentMentionTimer(mentionPluginKey.getState(editorView.state), {
918
- preserveFocusDeferCount: true
919
- });
920
- return;
921
- }
922
- pendingTypedAgentMentionFocusDeferCount = 0;
923
- editorView.dispatch(editorView.state.tr.setMeta(mentionPluginKey, {
924
- action: ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION,
925
- params: {
926
- localId: pendingTypedAgentMention.localId,
927
- resetCount: pendingTypedAgentMention.resetCount
928
- }
929
- }));
930
- }, AGENT_MENTION_INACTIVITY_MS);
931
- };
932
181
  const providerHandler = (name, providerPromise) => {
933
182
  switch (name) {
934
183
  case 'mentionProvider':
@@ -974,25 +223,7 @@ export function createMentionPlugin({
974
223
  pmPluginFactoryParams.providerFactory.subscribe('mentionProvider', providerHandler);
975
224
  }
976
225
  return {
977
- update(view, prevState) {
978
- const mentionPluginState = mentionPluginKey.getState(view.state);
979
- if (mentionPluginState === mentionPluginKey.getState(prevState)) {
980
- return;
981
- }
982
- if (!isExperimentEnabled('platform_editor_agent_mentions_separate_pm_plugin')) {
983
- var _mentionPluginState$p;
984
- schedulePendingTypedAgentMentionTimer(mentionPluginState);
985
-
986
- // If a pasted agent mention has no name (cache miss), resolve it async
987
- // via the mention provider and dispatch RESOLVE_PASTED_AGENT_MENTION_NAME
988
- // so the nudge displays the correct name.
989
- if (editorExperiment('platform_editor_agent_mentions', true) && (mentionPluginState === null || mentionPluginState === void 0 ? void 0 : (_mentionPluginState$p = mentionPluginState.pendingPastedAgentMention) === null || _mentionPluginState$p === void 0 ? void 0 : _mentionPluginState$p.id) != null && mentionPluginState !== null && mentionPluginState !== void 0 && mentionPluginState.mentionProvider && isResolvingMentionProvider(mentionPluginState.mentionProvider) && fg('platform_editor_agent_mentions_drop_one_fixes')) {
990
- resolveAndDispatchPastedAgentMentionName(mentionPluginState.pendingPastedAgentMention.id, mentionPluginState.mentionProvider, pendingResolveMentionIds, view);
991
- }
992
- }
993
- },
994
226
  destroy() {
995
- clearPendingTypedAgentMentionTimer();
996
227
  if (pmPluginFactoryParams.providerFactory) {
997
228
  pmPluginFactoryParams.providerFactory.unsubscribe('mentionProvider', providerHandler);
998
229
  }