@atlaskit/editor-plugin-mentions 15.0.2 → 15.0.3
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/dist/cjs/mentionsPlugin.js +24 -1
- package/dist/cjs/pm-plugins/agent.js +763 -0
- package/dist/cjs/pm-plugins/main.js +107 -102
- package/dist/es2019/mentionsPlugin.js +22 -0
- package/dist/es2019/pm-plugins/agent.js +733 -0
- package/dist/es2019/pm-plugins/main.js +109 -104
- package/dist/esm/mentionsPlugin.js +24 -1
- package/dist/esm/pm-plugins/agent.js +757 -0
- package/dist/esm/pm-plugins/main.js +107 -102
- package/dist/types/pm-plugins/agent.d.ts +40 -0
- package/package.json +6 -6
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import { isResolvingMentionProvider, MentionNameStatus } from '@atlaskit/mention/resource';
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
6
|
+
import { getAgentMentionParentContext } from './agent-mention-context';
|
|
7
|
+
import { mentionPluginKey } from './key';
|
|
8
|
+
import { ACTIONS } from './main';
|
|
9
|
+
|
|
10
|
+
// 'AGENT' is not in the ADF schema UserType enum but is used at runtime.
|
|
11
|
+
|
|
12
|
+
const AGENT_USER_TYPES = new Set(['APP', 'AGENT']);
|
|
13
|
+
const isAgentUserType = userType => {
|
|
14
|
+
return typeof userType === 'string' && AGENT_USER_TYPES.has(userType);
|
|
15
|
+
};
|
|
16
|
+
const getAgentMentionName = (text, fallbackName) => {
|
|
17
|
+
const trimmedFallbackName = typeof fallbackName === 'string' ? fallbackName.trim() : '';
|
|
18
|
+
const normalizedFallbackName = (trimmedFallbackName.startsWith('@') ? trimmedFallbackName.slice(1).trim() : trimmedFallbackName) || null;
|
|
19
|
+
if (typeof text !== 'string') {
|
|
20
|
+
return normalizedFallbackName;
|
|
21
|
+
}
|
|
22
|
+
const trimmedText = text.trim();
|
|
23
|
+
const displayName = trimmedText.startsWith('@') ? trimmedText.slice(1).trim() : trimmedText;
|
|
24
|
+
const normalizedName = displayName || normalizedFallbackName;
|
|
25
|
+
return normalizedName;
|
|
26
|
+
};
|
|
27
|
+
const AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
|
|
28
|
+
const AGENT_MENTION_INACTIVITY_MS = 3000;
|
|
29
|
+
const MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
|
|
30
|
+
/**
|
|
31
|
+
* Returns true when a transaction represents a local user document edit that
|
|
32
|
+
* should restart pending agent-mention inactivity tracking.
|
|
33
|
+
*
|
|
34
|
+
* Remote/collab updates, replace-document transactions, AI streaming transforms,
|
|
35
|
+
* selection-only movements, and metadata-only transactions are intentionally ignored.
|
|
36
|
+
*/
|
|
37
|
+
const isQualifyingLocalUserDocChange = tr => {
|
|
38
|
+
const isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
|
|
39
|
+
return tr.docChanged && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
|
|
40
|
+
};
|
|
41
|
+
const isLocalSelectionChange = (tr, hasPositionChanged) => {
|
|
42
|
+
const isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
|
|
43
|
+
|
|
44
|
+
// Pressing Enter can move selection through a doc split without setting tr.selectionSet
|
|
45
|
+
// or changing from/to numerically, so local doc changes are checked against the
|
|
46
|
+
// pending mention's current parent before publishing.
|
|
47
|
+
return (hasPositionChanged || tr.docChanged) && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Reads agent-mention details from a known document position without traversing
|
|
52
|
+
* the document. Callers pass a matcher so mapped positions are only accepted
|
|
53
|
+
* when they still point at the same pending/tracked mention.
|
|
54
|
+
*/
|
|
55
|
+
const getAgentMentionDetailsAtPos = (state, pos, matchesMention, fallbackName) => {
|
|
56
|
+
var _parentNode$type$name;
|
|
57
|
+
if (pos < 0 || pos > state.doc.content.size) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const node = state.doc.nodeAt(pos);
|
|
61
|
+
const mentionSchema = state.schema.nodes.mention;
|
|
62
|
+
if ((node === null || node === void 0 ? void 0 : node.type) !== mentionSchema || !isAgentUserType(node.attrs.userType) || !matchesMention(node.attrs) || !node.attrs.id || !node.attrs.localId) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const $mentionPos = state.doc.resolve(Math.min(pos + node.nodeSize, state.doc.content.size));
|
|
66
|
+
const parentNode = $mentionPos.node($mentionPos.depth);
|
|
67
|
+
const id = node.attrs.id;
|
|
68
|
+
const name = getAgentMentionName(node.attrs.text, fallbackName);
|
|
69
|
+
return {
|
|
70
|
+
id,
|
|
71
|
+
localId: node.attrs.localId,
|
|
72
|
+
context: getAgentMentionParentContext(parentNode, node.attrs.localId),
|
|
73
|
+
name,
|
|
74
|
+
prompt: parentNode.textContent.trim() || null,
|
|
75
|
+
nodeSize: node.nodeSize,
|
|
76
|
+
parentEnd: $mentionPos.end($mentionPos.depth),
|
|
77
|
+
parentNodeType: (_parentNode$type$name = parentNode.type.name) !== null && _parentNode$type$name !== void 0 ? _parentNode$type$name : null,
|
|
78
|
+
parentStart: $mentionPos.start($mentionPos.depth),
|
|
79
|
+
pos
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Finds an agent mention that survived a document change when the changed-range
|
|
85
|
+
* scan did not find one. Uses the tracked localId as the mention instance identity
|
|
86
|
+
* so same-agent mentions elsewhere in the document cannot be selected as fallback.
|
|
87
|
+
*/
|
|
88
|
+
const getSurvivingAgentMentionDetails = (state, preferredLocalId, preferredName) => {
|
|
89
|
+
const mentionSchema = state.schema.nodes.mention;
|
|
90
|
+
let result = null;
|
|
91
|
+
state.doc.descendants((node, pos) => {
|
|
92
|
+
if (result) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType) || node.attrs.localId !== preferredLocalId) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
result = getAgentMentionDetailsAtPos(state, pos, attrs => attrs.localId === preferredLocalId, preferredName);
|
|
99
|
+
return !result;
|
|
100
|
+
});
|
|
101
|
+
return result;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Maps a pending typed agent mention through a document-changing transaction and
|
|
106
|
+
* returns the updated pending state. If the mapped position was deleted or no
|
|
107
|
+
* longer points at the same local mention, the pending mention is cleared.
|
|
108
|
+
*/
|
|
109
|
+
const getPendingTypedAgentMentionAfterDocChange = (state, tr, pendingTypedAgentMention, {
|
|
110
|
+
resetTimer
|
|
111
|
+
}) => {
|
|
112
|
+
const mappedPos = tr.mapping.mapResult(pendingTypedAgentMention.pos, 1);
|
|
113
|
+
const resetCount = resetTimer ? pendingTypedAgentMention.resetCount + 1 : pendingTypedAgentMention.resetCount;
|
|
114
|
+
if (mappedPos.deleted) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const pendingMentionDetails = getAgentMentionDetailsAtPos(state, mappedPos.pos, attrs => attrs.localId === pendingTypedAgentMention.localId, pendingTypedAgentMention.name);
|
|
118
|
+
return pendingMentionDetails ? {
|
|
119
|
+
id: pendingMentionDetails.id,
|
|
120
|
+
localId: pendingTypedAgentMention.localId,
|
|
121
|
+
name: pendingMentionDetails.name,
|
|
122
|
+
nodeSize: pendingMentionDetails.nodeSize,
|
|
123
|
+
parentNodeType: pendingMentionDetails.parentNodeType,
|
|
124
|
+
pos: pendingMentionDetails.pos,
|
|
125
|
+
resetCount
|
|
126
|
+
} : null;
|
|
127
|
+
};
|
|
128
|
+
const hasPendingMentionMovedToNewParent = (oldState, tr, previousPendingTypedAgentMention, pendingMentionDetails) => {
|
|
129
|
+
if (!previousPendingTypedAgentMention) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
const previousMentionDetails = getAgentMentionDetailsAtPos(oldState, previousPendingTypedAgentMention.pos, attrs => attrs.localId === previousPendingTypedAgentMention.localId);
|
|
133
|
+
|
|
134
|
+
// Keep the previous parent boundary associated with the left side of an
|
|
135
|
+
// insertion at that boundary, so typing at the start of the parent does not
|
|
136
|
+
// look like the pending mention moved into a new parent.
|
|
137
|
+
const mappedPreviousParentStart = previousMentionDetails && tr.mapping.map(previousMentionDetails.parentStart, -1);
|
|
138
|
+
return Boolean(previousMentionDetails && mappedPreviousParentStart !== pendingMentionDetails.parentStart);
|
|
139
|
+
};
|
|
140
|
+
const isSelectionOutsideDirectParent = (state, pendingMentionDetails) => {
|
|
141
|
+
return state.selection.from < pendingMentionDetails.parentStart || state.selection.to > pendingMentionDetails.parentEnd;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Finalises a pending typed agent mention by copying its details into the
|
|
146
|
+
* public lastInserted* plugin state after the caller has already resolved the
|
|
147
|
+
* pending mention from the current document.
|
|
148
|
+
*/
|
|
149
|
+
const commitResolvedPendingTypedAgentMention = (pluginState, pendingMentionDetails) => {
|
|
150
|
+
var _pluginState$lastAgen;
|
|
151
|
+
return {
|
|
152
|
+
hasPublicPluginStateChanged: true,
|
|
153
|
+
pluginState: {
|
|
154
|
+
...pluginState,
|
|
155
|
+
pendingTypedAgentMention: null,
|
|
156
|
+
lastInsertedAgentMentionId: pendingMentionDetails.id,
|
|
157
|
+
lastInsertedAgentMentionLocalId: pendingMentionDetails.localId,
|
|
158
|
+
lastInsertedAgentMentionContext: pendingMentionDetails.context,
|
|
159
|
+
lastInsertedAgentMentionName: pendingMentionDetails.name,
|
|
160
|
+
lastInsertedAgentMentionPrompt: pendingMentionDetails.prompt,
|
|
161
|
+
lastInsertedAgentMentionParentNodeType: pendingMentionDetails.parentNodeType,
|
|
162
|
+
lastAgentMentionInsertionCount: ((_pluginState$lastAgen = pluginState.lastAgentMentionInsertionCount) !== null && _pluginState$lastAgen !== void 0 ? _pluginState$lastAgen : 0) + 1
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Resolves and finalises a pending typed agent mention. If the tracked mention
|
|
169
|
+
* no longer resolves, the stale pending state is cleared without dispatching a
|
|
170
|
+
* public update.
|
|
171
|
+
*/
|
|
172
|
+
const commitPendingTypedAgentMention = (state, pluginState, pendingTypedAgentMention) => {
|
|
173
|
+
const pendingMentionDetails = getAgentMentionDetailsAtPos(state, pendingTypedAgentMention.pos, attrs => attrs.localId === pendingTypedAgentMention.localId, pendingTypedAgentMention.name);
|
|
174
|
+
if (!pendingMentionDetails) {
|
|
175
|
+
return {
|
|
176
|
+
hasPublicPluginStateChanged: false,
|
|
177
|
+
pluginState: {
|
|
178
|
+
...pluginState,
|
|
179
|
+
pendingTypedAgentMention: null
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return commitResolvedPendingTypedAgentMention(pluginState, pendingMentionDetails);
|
|
184
|
+
};
|
|
185
|
+
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;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Clears agent mention state that points at a specific document snapshot.
|
|
189
|
+
* replaceDocument swaps content wholesale, so pending typed mentions and
|
|
190
|
+
* lastInserted* details from the previous document must be cleared together.
|
|
191
|
+
*/
|
|
192
|
+
const clearTrackedAgentMentionState = pluginState => {
|
|
193
|
+
return {
|
|
194
|
+
...pluginState,
|
|
195
|
+
pendingTypedAgentMention: null,
|
|
196
|
+
...(fg('platform_editor_agent_mentions_drop_one_fixes') ? {
|
|
197
|
+
pendingPastedAgentMention: null
|
|
198
|
+
} : {}),
|
|
199
|
+
lastInsertedAgentMentionId: null,
|
|
200
|
+
lastInsertedAgentMentionLocalId: null,
|
|
201
|
+
lastInsertedAgentMentionContext: null,
|
|
202
|
+
lastInsertedAgentMentionName: null,
|
|
203
|
+
lastInsertedAgentMentionPrompt: null,
|
|
204
|
+
lastInsertedAgentMentionParentNodeType: null
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Attempts to synchronously resolve an agent mention name from the mention
|
|
210
|
+
* provider's cache. Falls back to undefined if the provider doesn't support
|
|
211
|
+
* name resolution, the result is a Promise (async/cache miss), or the status
|
|
212
|
+
* is not OK.
|
|
213
|
+
*/
|
|
214
|
+
const resolveCachedAgentMentionName = (mentionProvider, params, id) => {
|
|
215
|
+
if (params !== null && params !== void 0 && params.name || !isResolvingMentionProvider(mentionProvider)) {
|
|
216
|
+
var _params$name;
|
|
217
|
+
return (_params$name = params === null || params === void 0 ? void 0 : params.name) !== null && _params$name !== void 0 ? _params$name : undefined;
|
|
218
|
+
}
|
|
219
|
+
const result = mentionProvider.resolveMentionName(id);
|
|
220
|
+
if (!(result instanceof Promise) && result.status === MentionNameStatus.OK) {
|
|
221
|
+
return result.name || undefined;
|
|
222
|
+
}
|
|
223
|
+
return undefined;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Resolves the name of a pasted agent mention via the mention provider and
|
|
228
|
+
* dispatches the appropriate action to update plugin state.
|
|
229
|
+
*/
|
|
230
|
+
export const resolveAndDispatchPastedAgentMentionName = (agentId, mentionProvider, pendingResolveMentionIds, view) => {
|
|
231
|
+
if (pendingResolveMentionIds.has(agentId)) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
pendingResolveMentionIds.add(agentId);
|
|
235
|
+
const result = mentionProvider.resolveMentionName(agentId);
|
|
236
|
+
if (result instanceof Promise) {
|
|
237
|
+
result.then(nameDetails => {
|
|
238
|
+
pendingResolveMentionIds.delete(agentId);
|
|
239
|
+
if (nameDetails.status === MentionNameStatus.OK && nameDetails.name) {
|
|
240
|
+
view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
|
|
241
|
+
action: ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME,
|
|
242
|
+
params: {
|
|
243
|
+
id: agentId,
|
|
244
|
+
name: nameDetails.name
|
|
245
|
+
}
|
|
246
|
+
}));
|
|
247
|
+
} else {
|
|
248
|
+
view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
|
|
249
|
+
action: ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION,
|
|
250
|
+
params: {
|
|
251
|
+
id: agentId
|
|
252
|
+
}
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
255
|
+
}).catch(() => {
|
|
256
|
+
pendingResolveMentionIds.delete(agentId);
|
|
257
|
+
});
|
|
258
|
+
} else if (result.status === MentionNameStatus.OK && result.name) {
|
|
259
|
+
pendingResolveMentionIds.delete(agentId);
|
|
260
|
+
view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
|
|
261
|
+
action: ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME,
|
|
262
|
+
params: {
|
|
263
|
+
id: agentId,
|
|
264
|
+
name: result.name
|
|
265
|
+
}
|
|
266
|
+
}));
|
|
267
|
+
} else {
|
|
268
|
+
pendingResolveMentionIds.delete(agentId);
|
|
269
|
+
view.dispatch(view.state.tr.setMeta(mentionPluginKey, {
|
|
270
|
+
action: ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION,
|
|
271
|
+
params: {
|
|
272
|
+
id: agentId
|
|
273
|
+
}
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
export const applyAgentMentionState = ({
|
|
278
|
+
tr,
|
|
279
|
+
pluginState,
|
|
280
|
+
oldState,
|
|
281
|
+
newState,
|
|
282
|
+
getIsRovoPanelOpen
|
|
283
|
+
}) => {
|
|
284
|
+
// mentionPluginKey intentionally remains the shared transaction action channel while
|
|
285
|
+
// agentMentionPluginKey owns the extracted agent state.
|
|
286
|
+
const {
|
|
287
|
+
action,
|
|
288
|
+
params
|
|
289
|
+
} = tr.getMeta(mentionPluginKey) || {
|
|
290
|
+
action: null,
|
|
291
|
+
params: null
|
|
292
|
+
};
|
|
293
|
+
let hasPublicPluginStateChanged = false;
|
|
294
|
+
let newPluginState = pluginState;
|
|
295
|
+
const isAgentMentionsExperimentEnabled = editorExperiment('platform_editor_agent_mentions', true);
|
|
296
|
+
const hasPositionChanged = oldState.selection.from !== newState.selection.from || oldState.selection.to !== newState.selection.to;
|
|
297
|
+
switch (action) {
|
|
298
|
+
case ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION:
|
|
299
|
+
{
|
|
300
|
+
const pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
|
|
301
|
+
if (!isAgentMentionsExperimentEnabled || !pendingTypedAgentMention || pendingTypedAgentMention.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMention.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
const commitResult = commitPendingTypedAgentMention(newState, newPluginState, pendingTypedAgentMention);
|
|
305
|
+
newPluginState = commitResult.pluginState;
|
|
306
|
+
hasPublicPluginStateChanged = hasPublicPluginStateChanged || commitResult.hasPublicPluginStateChanged;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
case ACTIONS.DISCARD_PENDING_TYPED_AGENT_MENTION:
|
|
310
|
+
{
|
|
311
|
+
const pendingTypedAgentMentionToDiscard = newPluginState.pendingTypedAgentMention;
|
|
312
|
+
if (!isAgentMentionsExperimentEnabled || !pendingTypedAgentMentionToDiscard || pendingTypedAgentMentionToDiscard.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMentionToDiscard.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
newPluginState = {
|
|
316
|
+
...newPluginState,
|
|
317
|
+
pendingTypedAgentMention: null
|
|
318
|
+
};
|
|
319
|
+
hasPublicPluginStateChanged = true;
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case ACTIONS.SET_PROVIDER:
|
|
323
|
+
newPluginState = {
|
|
324
|
+
...newPluginState,
|
|
325
|
+
mentionProvider: params.provider
|
|
326
|
+
};
|
|
327
|
+
hasPublicPluginStateChanged = true;
|
|
328
|
+
break;
|
|
329
|
+
case ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME:
|
|
330
|
+
{
|
|
331
|
+
var _newPluginState$pendi, _newPluginState$pendi2, _newPluginState$pendi3, _newPluginState$pendi4, _newPluginState$pendi5, _newPluginState$pendi6;
|
|
332
|
+
if (!isAgentMentionsExperimentEnabled || !(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')) {
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
newPluginState = {
|
|
336
|
+
...newPluginState,
|
|
337
|
+
pendingPastedAgentMention: null,
|
|
338
|
+
lastInsertedAgentMentionId: (_newPluginState$pendi2 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi2 === void 0 ? void 0 : _newPluginState$pendi2.id,
|
|
339
|
+
lastInsertedAgentMentionLocalId: (_newPluginState$pendi3 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi3 === void 0 ? void 0 : _newPluginState$pendi3.localId,
|
|
340
|
+
lastInsertedAgentMentionContext: (_newPluginState$pendi4 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi4 === void 0 ? void 0 : _newPluginState$pendi4.context,
|
|
341
|
+
lastInsertedAgentMentionName: params.name,
|
|
342
|
+
lastInsertedAgentMentionPrompt: (_newPluginState$pendi5 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi5 === void 0 ? void 0 : _newPluginState$pendi5.prompt,
|
|
343
|
+
lastInsertedAgentMentionParentNodeType: (_newPluginState$pendi6 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi6 === void 0 ? void 0 : _newPluginState$pendi6.parentNodeType
|
|
344
|
+
};
|
|
345
|
+
hasPublicPluginStateChanged = true;
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
case ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION:
|
|
349
|
+
{
|
|
350
|
+
var _newPluginState$pendi7;
|
|
351
|
+
if (!isAgentMentionsExperimentEnabled || !(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')) {
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
newPluginState = {
|
|
355
|
+
...newPluginState,
|
|
356
|
+
pendingPastedAgentMention: null
|
|
357
|
+
};
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (isAgentMentionsExperimentEnabled && isQualifyingLocalUserDocChange(tr)) {
|
|
362
|
+
const mentionSchema = newState.schema.nodes.mention;
|
|
363
|
+
const newDocRanges = [];
|
|
364
|
+
const oldDocRanges = [];
|
|
365
|
+
let stepsTouchMentions = false;
|
|
366
|
+
tr.steps.forEach(step => {
|
|
367
|
+
let found = false;
|
|
368
|
+
const stepNewRanges = [];
|
|
369
|
+
const stepOldRanges = [];
|
|
370
|
+
step.getMap().forEach((oldFrom, oldTo, newFrom, newTo) => {
|
|
371
|
+
stepOldRanges.push([oldFrom, oldTo]);
|
|
372
|
+
stepNewRanges.push([newFrom, newTo]);
|
|
373
|
+
if (!found) {
|
|
374
|
+
const clampedNewFrom = Math.min(newFrom, newState.doc.content.size);
|
|
375
|
+
const clampedNewTo = Math.min(newTo, newState.doc.content.size);
|
|
376
|
+
if (clampedNewFrom < clampedNewTo) {
|
|
377
|
+
newState.doc.nodesBetween(clampedNewFrom, clampedNewTo, node => {
|
|
378
|
+
if (node.type === mentionSchema && isAgentUserType(node.attrs.userType)) {
|
|
379
|
+
found = true;
|
|
380
|
+
}
|
|
381
|
+
return !found;
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
if (!found) {
|
|
385
|
+
const clampedOldFrom = Math.min(oldFrom, oldState.doc.content.size);
|
|
386
|
+
const clampedOldTo = Math.min(oldTo, oldState.doc.content.size);
|
|
387
|
+
if (clampedOldFrom < clampedOldTo) {
|
|
388
|
+
oldState.doc.nodesBetween(clampedOldFrom, clampedOldTo, node => {
|
|
389
|
+
if (node.type === mentionSchema && AGENT_USER_TYPES.has(node.attrs.userType)) {
|
|
390
|
+
found = true;
|
|
391
|
+
}
|
|
392
|
+
return !found;
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
if (found) {
|
|
399
|
+
stepsTouchMentions = true;
|
|
400
|
+
newDocRanges.push(...stepNewRanges);
|
|
401
|
+
oldDocRanges.push(...stepOldRanges);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
const shouldResolveAgentMentionState = stepsTouchMentions || Boolean(newPluginState.lastInsertedAgentMentionLocalId);
|
|
405
|
+
if (shouldResolveAgentMentionState) {
|
|
406
|
+
var _newPluginState$lastI, _newPluginState$lastA, _newPluginState$lastI2, _newPluginState$lastI3, _newPluginState$lastI4, _newPluginState$lastI5, _newPluginState$lastI6;
|
|
407
|
+
let agentMentionId = null;
|
|
408
|
+
let agentMentionLocalId = null;
|
|
409
|
+
let agentMentionContext = null;
|
|
410
|
+
let agentMentionName = null;
|
|
411
|
+
let agentMentionPrompt = null;
|
|
412
|
+
let agentMentionParentNodeType = null;
|
|
413
|
+
const existingAgentMentionLocalIdsInChangedRanges = new Set();
|
|
414
|
+
let pendingTypedAgentMentionDetails = null;
|
|
415
|
+
if (stepsTouchMentions) {
|
|
416
|
+
for (const [from, to] of newDocRanges) {
|
|
417
|
+
const clampedTo = Math.min(to, newState.doc.content.size);
|
|
418
|
+
if (from >= clampedTo) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
newState.doc.nodesBetween(from, clampedTo, (node, pos) => {
|
|
422
|
+
if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType)) {
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
if (pendingTypedAgentMentionDetails === null && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && node.attrs.localId === (params === null || params === void 0 ? void 0 : params.localId)) {
|
|
426
|
+
pendingTypedAgentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, attrs => attrs.localId === params.localId, params.name);
|
|
427
|
+
}
|
|
428
|
+
if (agentMentionLocalId === null && node.attrs.localId) {
|
|
429
|
+
const cachedName = fg('platform_editor_agent_mentions_drop_one_fixes') ? resolveCachedAgentMentionName(newPluginState.mentionProvider, params, node.attrs.id) : params === null || params === void 0 ? void 0 : params.name;
|
|
430
|
+
const agentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, attrs => attrs.localId === node.attrs.localId, cachedName);
|
|
431
|
+
if (agentMentionDetails) {
|
|
432
|
+
agentMentionId = agentMentionDetails.id;
|
|
433
|
+
agentMentionLocalId = agentMentionDetails.localId;
|
|
434
|
+
agentMentionContext = agentMentionDetails.context;
|
|
435
|
+
agentMentionName = agentMentionDetails.name;
|
|
436
|
+
agentMentionPrompt = agentMentionDetails.prompt;
|
|
437
|
+
agentMentionParentNodeType = agentMentionDetails.parentNodeType;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return true;
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
for (const [from, to] of oldDocRanges) {
|
|
444
|
+
const clampedOldTo = Math.min(to, oldState.doc.content.size);
|
|
445
|
+
if (from >= clampedOldTo) {
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
oldState.doc.nodesBetween(from, clampedOldTo, node => {
|
|
449
|
+
if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType)) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
if (node.attrs.localId) {
|
|
453
|
+
existingAgentMentionLocalIdsInChangedRanges.add(node.attrs.localId);
|
|
454
|
+
}
|
|
455
|
+
return true;
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
let resolvedFromFullDocFallback = false;
|
|
460
|
+
if (agentMentionId === null && newPluginState.lastInsertedAgentMentionLocalId) {
|
|
461
|
+
const survivorDetails = getSurvivingAgentMentionDetails(newState, newPluginState.lastInsertedAgentMentionLocalId, newPluginState.lastInsertedAgentMentionName);
|
|
462
|
+
if (survivorDetails) {
|
|
463
|
+
agentMentionId = survivorDetails.id;
|
|
464
|
+
agentMentionLocalId = survivorDetails.localId;
|
|
465
|
+
agentMentionContext = survivorDetails.context;
|
|
466
|
+
agentMentionName = survivorDetails.name;
|
|
467
|
+
agentMentionPrompt = survivorDetails.prompt;
|
|
468
|
+
agentMentionParentNodeType = survivorDetails.parentNodeType;
|
|
469
|
+
resolvedFromFullDocFallback = true;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const trackedAgentMentionLocalId = (_newPluginState$lastI = newPluginState.lastInsertedAgentMentionLocalId) !== null && _newPluginState$lastI !== void 0 ? _newPluginState$lastI : null;
|
|
473
|
+
const changedRangeMentionIsNew = agentMentionLocalId !== null && !existingAgentMentionLocalIdsInChangedRanges.has(agentMentionLocalId);
|
|
474
|
+
if (agentMentionLocalId !== null && !changedRangeMentionIsNew && agentMentionLocalId !== trackedAgentMentionLocalId) {
|
|
475
|
+
const survivorDetails = trackedAgentMentionLocalId ? getSurvivingAgentMentionDetails(newState, trackedAgentMentionLocalId, newPluginState.lastInsertedAgentMentionName) : null;
|
|
476
|
+
if (survivorDetails) {
|
|
477
|
+
agentMentionId = survivorDetails.id;
|
|
478
|
+
agentMentionLocalId = survivorDetails.localId;
|
|
479
|
+
agentMentionContext = survivorDetails.context;
|
|
480
|
+
agentMentionName = survivorDetails.name;
|
|
481
|
+
agentMentionParentNodeType = survivorDetails.parentNodeType;
|
|
482
|
+
resolvedFromFullDocFallback = true;
|
|
483
|
+
} else {
|
|
484
|
+
agentMentionId = null;
|
|
485
|
+
agentMentionLocalId = null;
|
|
486
|
+
agentMentionContext = null;
|
|
487
|
+
agentMentionName = null;
|
|
488
|
+
agentMentionParentNodeType = null;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const isNewInsertion = agentMentionId !== null && !resolvedFromFullDocFallback && changedRangeMentionIsNew;
|
|
492
|
+
const isPendingTypedAgentMentionInsertion = isNewInsertion && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && typeof (params === null || params === void 0 ? void 0 : params.localId) === 'string';
|
|
493
|
+
const newInsertionCount = isNewInsertion ? ((_newPluginState$lastA = newPluginState.lastAgentMentionInsertionCount) !== null && _newPluginState$lastA !== void 0 ? _newPluginState$lastA : 0) + 1 : undefined;
|
|
494
|
+
const pendingTypedAgentMentionDetailsForState = pendingTypedAgentMentionDetails;
|
|
495
|
+
if (isPendingTypedAgentMentionInsertion && pendingTypedAgentMentionDetailsForState) {
|
|
496
|
+
const pendingTypedAgentMentionLocalId = params === null || params === void 0 ? void 0 : params.localId;
|
|
497
|
+
newPluginState = {
|
|
498
|
+
...newPluginState,
|
|
499
|
+
pendingTypedAgentMention: {
|
|
500
|
+
id: pendingTypedAgentMentionDetailsForState.id,
|
|
501
|
+
localId: pendingTypedAgentMentionLocalId,
|
|
502
|
+
name: pendingTypedAgentMentionDetailsForState.name,
|
|
503
|
+
nodeSize: pendingTypedAgentMentionDetailsForState.nodeSize,
|
|
504
|
+
parentNodeType: pendingTypedAgentMentionDetailsForState.parentNodeType,
|
|
505
|
+
pos: pendingTypedAgentMentionDetailsForState.pos,
|
|
506
|
+
resetCount: 1
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
} else if (isPendingTypedAgentMentionInsertion) {
|
|
510
|
+
newPluginState = {
|
|
511
|
+
...newPluginState,
|
|
512
|
+
pendingTypedAgentMention: null,
|
|
513
|
+
lastInsertedAgentMentionId: agentMentionId,
|
|
514
|
+
lastInsertedAgentMentionLocalId: agentMentionLocalId,
|
|
515
|
+
lastInsertedAgentMentionContext: agentMentionContext,
|
|
516
|
+
lastInsertedAgentMentionName: agentMentionName,
|
|
517
|
+
lastInsertedAgentMentionPrompt: agentMentionPrompt,
|
|
518
|
+
lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType,
|
|
519
|
+
...(newInsertionCount !== undefined ? {
|
|
520
|
+
lastAgentMentionInsertionCount: newInsertionCount
|
|
521
|
+
} : {})
|
|
522
|
+
};
|
|
523
|
+
hasPublicPluginStateChanged = true;
|
|
524
|
+
} 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) {
|
|
525
|
+
const isTaskItemMentionForPaste = agentMentionParentNodeType === 'taskItem';
|
|
526
|
+
if (!isTaskItemMentionForPaste && isNewInsertion && getIsRovoPanelOpen !== null && getIsRovoPanelOpen !== void 0 && getIsRovoPanelOpen()) {
|
|
527
|
+
// Rovo is already open, so do not publish a nudge-triggering state change.
|
|
528
|
+
} else if (agentMentionName === null && agentMentionId !== null && isResolvingMentionProvider(newPluginState.mentionProvider) && fg('platform_editor_agent_mentions_drop_one_fixes')) {
|
|
529
|
+
newPluginState = {
|
|
530
|
+
...newPluginState,
|
|
531
|
+
pendingPastedAgentMention: {
|
|
532
|
+
id: agentMentionId,
|
|
533
|
+
localId: agentMentionLocalId,
|
|
534
|
+
context: agentMentionContext,
|
|
535
|
+
prompt: agentMentionPrompt,
|
|
536
|
+
parentNodeType: agentMentionParentNodeType
|
|
537
|
+
},
|
|
538
|
+
...(newInsertionCount !== undefined ? {
|
|
539
|
+
lastAgentMentionInsertionCount: newInsertionCount
|
|
540
|
+
} : {})
|
|
541
|
+
};
|
|
542
|
+
} else {
|
|
543
|
+
newPluginState = {
|
|
544
|
+
...newPluginState,
|
|
545
|
+
lastInsertedAgentMentionId: agentMentionId,
|
|
546
|
+
lastInsertedAgentMentionLocalId: agentMentionLocalId,
|
|
547
|
+
lastInsertedAgentMentionContext: agentMentionContext,
|
|
548
|
+
lastInsertedAgentMentionName: agentMentionName,
|
|
549
|
+
lastInsertedAgentMentionPrompt: agentMentionPrompt,
|
|
550
|
+
lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType,
|
|
551
|
+
...(newInsertionCount !== undefined ? {
|
|
552
|
+
lastAgentMentionInsertionCount: newInsertionCount
|
|
553
|
+
} : {})
|
|
554
|
+
};
|
|
555
|
+
hasPublicPluginStateChanged = true;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (isAgentMentionsExperimentEnabled && tr.docChanged && tr.getMeta('replaceDocument') && hasTrackedAgentMentionState(newPluginState)) {
|
|
561
|
+
newPluginState = clearTrackedAgentMentionState(newPluginState);
|
|
562
|
+
hasPublicPluginStateChanged = true;
|
|
563
|
+
}
|
|
564
|
+
if (isAgentMentionsExperimentEnabled && newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && tr.docChanged) {
|
|
565
|
+
newPluginState = {
|
|
566
|
+
...newPluginState,
|
|
567
|
+
pendingTypedAgentMention: getPendingTypedAgentMentionAfterDocChange(newState, tr, newPluginState.pendingTypedAgentMention, {
|
|
568
|
+
resetTimer: isQualifyingLocalUserDocChange(tr)
|
|
569
|
+
})
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
const shouldCheckPendingTypedAgentMentionParent = isLocalSelectionChange(tr, hasPositionChanged);
|
|
573
|
+
if (isAgentMentionsExperimentEnabled && newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && shouldCheckPendingTypedAgentMentionParent) {
|
|
574
|
+
const pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
|
|
575
|
+
const pendingMentionDetails = getAgentMentionDetailsAtPos(newState, pendingTypedAgentMention.pos, attrs => attrs.localId === pendingTypedAgentMention.localId, pendingTypedAgentMention.name);
|
|
576
|
+
if (!pendingMentionDetails) {
|
|
577
|
+
newPluginState = {
|
|
578
|
+
...newPluginState,
|
|
579
|
+
pendingTypedAgentMention: null
|
|
580
|
+
};
|
|
581
|
+
} else if (hasPendingMentionMovedToNewParent(oldState, tr, pluginState.pendingTypedAgentMention, pendingMentionDetails) || isSelectionOutsideDirectParent(newState, pendingMentionDetails)) {
|
|
582
|
+
if (pendingMentionDetails.parentNodeType !== 'taskItem' && getIsRovoPanelOpen !== null && getIsRovoPanelOpen !== void 0 && getIsRovoPanelOpen()) {
|
|
583
|
+
newPluginState = {
|
|
584
|
+
...newPluginState,
|
|
585
|
+
pendingTypedAgentMention: null
|
|
586
|
+
};
|
|
587
|
+
hasPublicPluginStateChanged = true;
|
|
588
|
+
} else {
|
|
589
|
+
const commitResult = commitResolvedPendingTypedAgentMention(newPluginState, pendingMentionDetails);
|
|
590
|
+
newPluginState = commitResult.pluginState;
|
|
591
|
+
hasPublicPluginStateChanged = hasPublicPluginStateChanged || commitResult.hasPublicPluginStateChanged;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
hasPublicPluginStateChanged,
|
|
597
|
+
pluginState: newPluginState
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
export const createAgentMentionPluginView = ({
|
|
601
|
+
editorView,
|
|
602
|
+
getIsRovoPanelOpen,
|
|
603
|
+
stateKey
|
|
604
|
+
}) => {
|
|
605
|
+
const isAgentMentionsEnabled = editorExperiment('platform_editor_agent_mentions', true);
|
|
606
|
+
let pendingTypedAgentMentionTimer;
|
|
607
|
+
let pendingTypedAgentMentionTimerKey = null;
|
|
608
|
+
let pendingTypedAgentMentionFocusDeferCount = 0;
|
|
609
|
+
const pendingResolveMentionIds = new Set();
|
|
610
|
+
const clearPendingTypedAgentMentionTimer = ({
|
|
611
|
+
preserveFocusDeferCount = false
|
|
612
|
+
} = {}) => {
|
|
613
|
+
if (pendingTypedAgentMentionTimer) {
|
|
614
|
+
clearTimeout(pendingTypedAgentMentionTimer);
|
|
615
|
+
pendingTypedAgentMentionTimer = undefined;
|
|
616
|
+
}
|
|
617
|
+
pendingTypedAgentMentionTimerKey = null;
|
|
618
|
+
if (!preserveFocusDeferCount) {
|
|
619
|
+
pendingTypedAgentMentionFocusDeferCount = 0;
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
const shouldDeferPendingTypedAgentMention = () => typeof document !== 'undefined' && document.hasFocus() && !editorView.hasFocus();
|
|
623
|
+
const schedulePendingTypedAgentMentionTimer = (mentionPluginState, {
|
|
624
|
+
preserveFocusDeferCount = false
|
|
625
|
+
} = {}) => {
|
|
626
|
+
if (!isAgentMentionsEnabled) {
|
|
627
|
+
clearPendingTypedAgentMentionTimer();
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
const pendingTypedAgentMention = mentionPluginState === null || mentionPluginState === void 0 ? void 0 : mentionPluginState.pendingTypedAgentMention;
|
|
631
|
+
if (!pendingTypedAgentMention) {
|
|
632
|
+
clearPendingTypedAgentMentionTimer();
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
const timerKey = `${pendingTypedAgentMention.localId}:${pendingTypedAgentMention.resetCount}`;
|
|
636
|
+
if (timerKey === pendingTypedAgentMentionTimerKey) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
clearPendingTypedAgentMentionTimer({
|
|
640
|
+
preserveFocusDeferCount
|
|
641
|
+
});
|
|
642
|
+
pendingTypedAgentMentionTimerKey = timerKey;
|
|
643
|
+
pendingTypedAgentMentionTimer = setTimeout(() => {
|
|
644
|
+
var _stateKey$getState;
|
|
645
|
+
const isTaskItemMention = pendingTypedAgentMention.parentNodeType === 'taskItem';
|
|
646
|
+
if (!isTaskItemMention && getIsRovoPanelOpen !== null && getIsRovoPanelOpen !== void 0 && getIsRovoPanelOpen()) {
|
|
647
|
+
// Agent actions continue to use mentionPluginKey as the shared transaction meta channel.
|
|
648
|
+
editorView.dispatch(editorView.state.tr.setMeta(mentionPluginKey, {
|
|
649
|
+
action: ACTIONS.DISCARD_PENDING_TYPED_AGENT_MENTION,
|
|
650
|
+
params: {
|
|
651
|
+
localId: pendingTypedAgentMention.localId,
|
|
652
|
+
resetCount: pendingTypedAgentMention.resetCount
|
|
653
|
+
}
|
|
654
|
+
}));
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const latestPendingTypedAgentMention = (_stateKey$getState = stateKey.getState(editorView.state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.pendingTypedAgentMention;
|
|
658
|
+
if (!latestPendingTypedAgentMention || latestPendingTypedAgentMention.localId !== pendingTypedAgentMention.localId || latestPendingTypedAgentMention.resetCount !== pendingTypedAgentMention.resetCount) {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
if (shouldDeferPendingTypedAgentMention() && pendingTypedAgentMentionFocusDeferCount < MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS) {
|
|
662
|
+
pendingTypedAgentMentionFocusDeferCount++;
|
|
663
|
+
pendingTypedAgentMentionTimerKey = null;
|
|
664
|
+
schedulePendingTypedAgentMentionTimer(stateKey.getState(editorView.state), {
|
|
665
|
+
preserveFocusDeferCount: true
|
|
666
|
+
});
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
pendingTypedAgentMentionFocusDeferCount = 0;
|
|
670
|
+
editorView.dispatch(editorView.state.tr.setMeta(mentionPluginKey, {
|
|
671
|
+
action: ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION,
|
|
672
|
+
params: {
|
|
673
|
+
localId: pendingTypedAgentMention.localId,
|
|
674
|
+
resetCount: pendingTypedAgentMention.resetCount
|
|
675
|
+
}
|
|
676
|
+
}));
|
|
677
|
+
}, AGENT_MENTION_INACTIVITY_MS);
|
|
678
|
+
};
|
|
679
|
+
return {
|
|
680
|
+
update(view, prevState) {
|
|
681
|
+
var _mentionPluginState$p;
|
|
682
|
+
const mentionPluginState = stateKey.getState(view.state);
|
|
683
|
+
if (mentionPluginState === stateKey.getState(prevState)) {
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
schedulePendingTypedAgentMentionTimer(mentionPluginState);
|
|
687
|
+
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')) {
|
|
688
|
+
resolveAndDispatchPastedAgentMentionName(mentionPluginState.pendingPastedAgentMention.id, mentionPluginState.mentionProvider, pendingResolveMentionIds, view);
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
destroy() {
|
|
692
|
+
clearPendingTypedAgentMentionTimer();
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
};
|
|
696
|
+
export const agentMentionPluginKey = new PluginKey('agentMention');
|
|
697
|
+
export const createAgentMentionPlugin = ({
|
|
698
|
+
options,
|
|
699
|
+
pmPluginFactoryParams
|
|
700
|
+
}) => {
|
|
701
|
+
return new SafePlugin({
|
|
702
|
+
key: agentMentionPluginKey,
|
|
703
|
+
state: {
|
|
704
|
+
init() {
|
|
705
|
+
return {};
|
|
706
|
+
},
|
|
707
|
+
apply(tr, pluginState, oldState, newState) {
|
|
708
|
+
const result = applyAgentMentionState({
|
|
709
|
+
tr,
|
|
710
|
+
pluginState,
|
|
711
|
+
oldState,
|
|
712
|
+
newState,
|
|
713
|
+
getIsRovoPanelOpen: options === null || options === void 0 ? void 0 : options.getIsRovoPanelOpen
|
|
714
|
+
});
|
|
715
|
+
const mentionPluginState = mentionPluginKey.getState(newState);
|
|
716
|
+
if (result.hasPublicPluginStateChanged) {
|
|
717
|
+
pmPluginFactoryParams.dispatch(mentionPluginKey, {
|
|
718
|
+
...mentionPluginState,
|
|
719
|
+
...result.pluginState
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
return result.pluginState;
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
view(editorView) {
|
|
726
|
+
return createAgentMentionPluginView({
|
|
727
|
+
editorView,
|
|
728
|
+
getIsRovoPanelOpen: options === null || options === void 0 ? void 0 : options.getIsRovoPanelOpen,
|
|
729
|
+
stateKey: agentMentionPluginKey
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
};
|