@memberjunction/ng-conversations 6.1.3 → 6.2.0-edge.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.
Files changed (113) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  3. package/dist/lib/components/conversation/conversation-chat-area.component.js +9 -26
  4. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  5. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +1 -1
  6. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -1
  7. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -1
  8. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +1 -1
  9. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
  10. package/dist/lib/components/realtime/channels/client-context-channel.js +1 -1
  11. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
  12. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +1 -1
  13. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
  14. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +3 -0
  15. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
  16. package/dist/lib/components/realtime/media/media-channel.d.ts +2 -1
  17. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  18. package/dist/lib/components/realtime/media/media-channel.js +1 -1
  19. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  20. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +1 -1
  21. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
  22. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
  23. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +1 -1
  24. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  25. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  26. package/dist/lib/components/realtime/realtime-composer.component.d.ts +3 -1
  27. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  28. package/dist/lib/components/realtime/realtime-composer.component.js +26 -8
  29. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  30. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +1 -1
  31. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
  32. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
  33. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +2 -2
  34. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  35. package/dist/lib/components/realtime/realtime-session-overlay.component.js +1 -1
  36. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  37. package/dist/lib/components/realtime/realtime-session-state.d.ts +2 -3
  38. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
  39. package/dist/lib/components/realtime/realtime-session-state.js +3 -2
  40. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
  41. package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +17 -1
  42. package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -1
  43. package/dist/lib/components/realtime/realtime-session-thread.component.js +122 -45
  44. package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -1
  45. package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +1 -9
  46. package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -1
  47. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +13 -43
  48. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -1
  49. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +2 -2
  50. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  51. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  52. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +1 -1
  53. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  54. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  55. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +1 -1
  56. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  57. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +1 -1
  58. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  59. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +1 -1
  60. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  61. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +1 -1
  62. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  63. package/dist/lib/conversations.module.d.ts.map +1 -1
  64. package/dist/lib/conversations.module.js.map +1 -1
  65. package/dist/lib/services/browser-realtime-media-host.d.ts +24 -0
  66. package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -0
  67. package/dist/lib/services/browser-realtime-media-host.js +95 -0
  68. package/dist/lib/services/browser-realtime-media-host.js.map +1 -0
  69. package/dist/lib/services/conversation-attachment.service.d.ts +24 -2
  70. package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
  71. package/dist/lib/services/conversation-attachment.service.js +43 -4
  72. package/dist/lib/services/conversation-attachment.service.js.map +1 -1
  73. package/dist/lib/services/graphql-attachment-blob-store.d.ts +44 -0
  74. package/dist/lib/services/graphql-attachment-blob-store.d.ts.map +1 -0
  75. package/dist/lib/services/graphql-attachment-blob-store.js +113 -0
  76. package/dist/lib/services/graphql-attachment-blob-store.js.map +1 -0
  77. package/dist/lib/services/mention-autocomplete.service.d.ts +17 -141
  78. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  79. package/dist/lib/services/mention-autocomplete.service.js +15 -460
  80. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  81. package/dist/lib/services/realtime-session-review.service.d.ts +1 -1
  82. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
  83. package/dist/lib/services/realtime-session-review.service.js +1 -1
  84. package/dist/lib/services/realtime-session-review.service.js.map +1 -1
  85. package/dist/lib/services/realtime-session.service.d.ts +16 -1150
  86. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  87. package/dist/lib/services/realtime-session.service.js +28 -2430
  88. package/dist/lib/services/realtime-session.service.js.map +1 -1
  89. package/dist/lib/utils/realtime-session-timeline.d.ts +8 -79
  90. package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -1
  91. package/dist/lib/utils/realtime-session-timeline.js +8 -89
  92. package/dist/lib/utils/realtime-session-timeline.js.map +1 -1
  93. package/dist/public-api.d.ts +2 -2
  94. package/dist/public-api.d.ts.map +1 -1
  95. package/dist/public-api.js +6 -2
  96. package/dist/public-api.js.map +1 -1
  97. package/package.json +33 -32
  98. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +0 -384
  99. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +0 -1
  100. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +0 -231
  101. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +0 -1
  102. package/dist/lib/services/delegation-result-parser.d.ts +0 -50
  103. package/dist/lib/services/delegation-result-parser.d.ts.map +0 -1
  104. package/dist/lib/services/delegation-result-parser.js +0 -60
  105. package/dist/lib/services/delegation-result-parser.js.map +0 -1
  106. package/dist/lib/services/narration-template.d.ts +0 -42
  107. package/dist/lib/services/narration-template.d.ts.map +0 -1
  108. package/dist/lib/services/narration-template.js +0 -73
  109. package/dist/lib/services/narration-template.js.map +0 -1
  110. package/dist/lib/services/skill-picker-narrowing.d.ts +0 -13
  111. package/dist/lib/services/skill-picker-narrowing.d.ts.map +0 -1
  112. package/dist/lib/services/skill-picker-narrowing.js +0 -13
  113. package/dist/lib/services/skill-picker-narrowing.js.map +0 -1
@@ -1,464 +1,19 @@
1
- import { Metadata } from '@memberjunction/core';
2
- import { AIEngineBase, AIAgentPermissionHelper, AISkillPermissionHelper } from '@memberjunction/ai-engine-base';
3
- import { BaseSingleton, UUIDsEqual } from '@memberjunction/global';
4
- import { IntersectAcceptedSkills } from './skill-picker-narrowing';
1
+ import { MentionAutocomplete } from '@memberjunction/conversations-runtime';
5
2
  /**
6
- * Shared engine behind the conversations composer plugins (the agent-mentions /
7
- * record-mentions / skill-commands `ComposerTriggerProvider`s) and the mention-parsing
8
- * consumers (message routing, saved-message badge rendering). Loads the
9
- * permission-filtered agent / user / entity / query / skill caches once per session and
10
- * serves ranked `MentionSuggestion` lists per trigger char.
3
+ * @fileoverview Angular alias for the framework-agnostic `MentionAutocomplete` engine in
4
+ * `@memberjunction/conversations-runtime`.
11
5
  *
12
- * NOT an Angular DI service — it's a `BaseSingleton` engine so the
13
- * ClassFactory-instantiated trigger providers (which live outside Angular DI) and the
14
- * Angular components share ONE instance (one cache warm-up) via
15
- * `MentionAutocompleteService.Instance`.
6
+ * The engine — permission-filtered agent / user / entity / query / skill caches, the `/` picker's
7
+ * target-agent narrowing, and the per-trigger ranking — moved into the runtime. It had never
8
+ * imported anything from `@angular/*` and carried no decorator; it was Angular-coupled only by
9
+ * which package it happened to sit in, which meant a React Native host could not reach it without
10
+ * a second implementation of the same permission rules.
11
+ *
12
+ * This alias keeps every existing `MentionAutocompleteService.Instance` call site working
13
+ * unchanged. It is a `const`, not a subclass, so there is exactly one instance and one cache
14
+ * warm-up shared with the ClassFactory-instantiated trigger providers and any non-Angular host.
15
+ *
16
+ * **For new code:** import `MentionAutocomplete` from `@memberjunction/conversations-runtime`.
16
17
  */
17
- export class MentionAutocompleteService extends BaseSingleton {
18
- constructor() {
19
- super();
20
- }
21
- /** The process-wide shared instance (Global Object Store backed). */
22
- static get Instance() {
23
- return super.getInstance();
24
- }
25
- agentsCache = [];
26
- usersCache = [];
27
- entitiesCache = [];
28
- queriesCache = [];
29
- /** Active skills the current user can Run — surfaced under the '/' trigger. */
30
- skillsCache = [];
31
- /** The provider this instance was initialised against (multi-provider hosts); undefined = global. */
32
- provider;
33
- /** Default icon for a skill with no IconClass of its own. */
34
- defaultSkillIcon = 'fa-solid fa-wand-magic-sparkles';
35
- /** Generic icon for all query mentions, sourced from the 'MJ: Queries' entity. */
36
- queriesEntityIcon = 'fa-solid fa-database';
37
- isInitialized = false;
38
- initializationPromise = null;
39
- /** True once the caches have loaded (agents/users/entities/queries/skills). */
40
- get IsInitialized() {
41
- return this.isInitialized;
42
- }
43
- /**
44
- * Initialize the service by loading agents and users
45
- * Prevents concurrent initialization with promise lock
46
- */
47
- async initialize(currentUser, provider) {
48
- // If already initialized, return immediately
49
- if (this.isInitialized) {
50
- return;
51
- }
52
- // If initialization is in progress, wait for it
53
- if (this.initializationPromise) {
54
- return this.initializationPromise;
55
- }
56
- // Create initialization promise and store it
57
- this.initializationPromise = this._initializeInternal(currentUser, provider);
58
- try {
59
- await this.initializationPromise;
60
- }
61
- finally {
62
- this.initializationPromise = null;
63
- }
64
- }
65
- /**
66
- * Internal initialization logic
67
- */
68
- async _initializeInternal(currentUser, provider) {
69
- try {
70
- // Load agents from AIEngineBase
71
- await AIEngineBase.Instance.Config(false);
72
- const allAgents = AIEngineBase.Instance.Agents || [];
73
- // Filter by status, hierarchy, and invocation mode first
74
- const candidateAgents = allAgents.filter(a => !a.ParentID && a.Status === 'Active' && a.InvocationMode !== 'Sub-Agent' && !a.IsRestricted);
75
- // Filter by user's 'run' permission — respects open-by-default + explicit permissions
76
- this.agentsCache = await this.filterAgentsByRunPermission(candidateAgents, currentUser);
77
- // Load users from the system (optional - can be expanded later)
78
- // For now, we'll just use the current user
79
- this.usersCache = [currentUser];
80
- // Load entities the current user can read (candidates for #entity mentions)
81
- this.entitiesCache = this.loadReadableEntities(currentUser, provider);
82
- // Load queries the current user can run (also surfaced under the '#' trigger)
83
- this.queriesCache = this.loadRunnableQueries(currentUser, provider);
84
- this.queriesEntityIcon = this.resolveQueriesEntityIcon(provider);
85
- // Load Active skills the current user can Run (surfaced under the '/' trigger). Mirrors the
86
- // agent filter: open-by-default unless a skill has explicit permission rows. This is the user's
87
- // full run-permitted set; when the host names the target agent (getSuggestions' targetAgentId)
88
- // the picker narrows it to what that agent accepts, and the server's RequestedSkills guard is
89
- // the backstop either way.
90
- this.skillsCache = await this.filterSkillsByRunPermission(currentUser);
91
- this.provider = provider;
92
- this.isInitialized = true;
93
- }
94
- catch (error) {
95
- console.error('Failed to initialize MentionAutocompleteService:', error);
96
- throw error;
97
- }
98
- }
99
- /**
100
- * Filter agents to only those the current user has 'run' permission for.
101
- * Agents with no permission records are open to everyone (canRun = true).
102
- * Agents with explicit permission records are checked against the user.
103
- */
104
- async filterAgentsByRunPermission(agents, user) {
105
- const permitted = [];
106
- for (const agent of agents) {
107
- try {
108
- const canRun = await AIAgentPermissionHelper.HasPermission(agent.ID, user, 'run');
109
- if (canRun) {
110
- permitted.push(agent);
111
- }
112
- }
113
- catch {
114
- // Fail closed — exclude agent on error
115
- }
116
- }
117
- return permitted;
118
- }
119
- /**
120
- * Filter Active skills to those the current user has 'run' permission for.
121
- * Skills with no permission records are open to everyone (canRun = true);
122
- * skills with explicit records are checked against the user (open-by-default).
123
- */
124
- async filterSkillsByRunPermission(user) {
125
- try {
126
- const runnable = await AISkillPermissionHelper.GetAccessibleSkills(user, 'run');
127
- return runnable.filter(s => s.Status === 'Active');
128
- }
129
- catch {
130
- // Fail closed — no skills on error.
131
- return [];
132
- }
133
- }
134
- /**
135
- * Load entities the current user has read permission for.
136
- * These are the candidates surfaced for #entity mentions.
137
- */
138
- loadReadableEntities(user, provider) {
139
- try {
140
- const md = provider ?? Metadata.Provider;
141
- return (md.Entities || []).filter(entity => {
142
- try {
143
- return entity.GetUserPermisions(user).CanRead;
144
- }
145
- catch {
146
- // Fail closed — exclude entity on permission-check error
147
- return false;
148
- }
149
- });
150
- }
151
- catch (error) {
152
- console.error('Failed to load entities for mention autocomplete:', error);
153
- return [];
154
- }
155
- }
156
- /**
157
- * Load queries the current user has run permission for.
158
- * These are the candidates surfaced for #query mentions.
159
- */
160
- loadRunnableQueries(user, provider) {
161
- try {
162
- const md = provider ?? Metadata.Provider;
163
- return (md.Queries || []).filter(query => {
164
- try {
165
- return query.UserCanRun(user);
166
- }
167
- catch {
168
- // Fail closed — exclude query on permission-check error
169
- return false;
170
- }
171
- });
172
- }
173
- catch (error) {
174
- console.error('Failed to load queries for mention autocomplete:', error);
175
- return [];
176
- }
177
- }
178
- /**
179
- * Resolve the generic icon used for all query mentions from the 'MJ: Queries' entity.
180
- */
181
- resolveQueriesEntityIcon(provider) {
182
- try {
183
- const md = provider ?? Metadata.Provider;
184
- return md.EntityByName('MJ: Queries')?.Icon || 'fa-solid fa-database';
185
- }
186
- catch {
187
- return 'fa-solid fa-database';
188
- }
189
- }
190
- /**
191
- * Get suggestions based on search query
192
- * @param query The search text after the trigger character
193
- * @param includeUsers Whether to include users in suggestions
194
- * @param trigger '@' (agents + users), '#' (entities + queries) or '/' (skills)
195
- * @param targetAgentId When the host knows which agent the message will go to (the '/' trigger
196
- * only), skill suggestions are narrowed to what THAT agent accepts — `AcceptsSkills` + its
197
- * `MJ: AI Agent Skills` grants — via {@link AIEngineBase.GetSkillsForAgent}. Without it (or for an
198
- * agent not in the user's runnable set) the user's full runnable catalog is shown, as before, and
199
- * the server's `RequestedSkills` guard is the backstop.
200
- * @returns Filtered and ranked suggestions
201
- */
202
- getSuggestions(query, includeUsers = true, trigger = '@', targetAgentId = null) {
203
- // The '#' trigger searches entities + queries; '/' searches skills; '@' searches agents + users
204
- if (trigger === '#') {
205
- return this.getEntityAndQuerySuggestions(query);
206
- }
207
- if (trigger === '/') {
208
- return this.getSkillSuggestions(query, targetAgentId);
209
- }
210
- const lowerQuery = query.toLowerCase().trim();
211
- const suggestions = [];
212
- // Add agent suggestions
213
- for (const agent of this.agentsCache) {
214
- const score = this.calculateMatchScore(agent.Name || '', lowerQuery);
215
- if (score > 0 || !lowerQuery) {
216
- suggestions.push({
217
- type: 'agent',
218
- id: agent.ID,
219
- name: agent.Name || 'Unknown',
220
- displayName: agent.Name || 'Unknown',
221
- description: agent.Description || undefined,
222
- imageUrl: agent.LogoURL || undefined, // Agent logo/avatar image
223
- icon: this.getAgentIcon(agent),
224
- // Configuration presets ride on the suggestion — the (AI-blind) composer
225
- // renders a preset picker on the inserted chip when there are 2+.
226
- presets: this.getAgentPresets(agent.ID)
227
- });
228
- }
229
- }
230
- // Add user suggestions (if enabled)
231
- if (includeUsers) {
232
- for (const user of this.usersCache) {
233
- const score = this.calculateMatchScore(user.Name, lowerQuery);
234
- if (score > 0 || !lowerQuery) {
235
- suggestions.push({
236
- type: 'user',
237
- id: user.ID,
238
- name: user.Name,
239
- displayName: user.Name,
240
- description: user.Email || undefined
241
- });
242
- }
243
- }
244
- }
245
- // Sort by relevance: exact match > starts with > contains
246
- return suggestions.sort((a, b) => {
247
- const scoreA = this.calculateMatchScore(a.name, lowerQuery);
248
- const scoreB = this.calculateMatchScore(b.name, lowerQuery);
249
- if (scoreB !== scoreA)
250
- return scoreB - scoreA;
251
- // If scores are equal, sort agents before users
252
- if (a.type !== b.type)
253
- return a.type === 'agent' ? -1 : 1;
254
- // Otherwise alphabetically
255
- return a.name.localeCompare(b.name);
256
- });
257
- }
258
- /**
259
- * Get entity + query suggestions for #mentions, ranked by query match.
260
- * Capped to keep the dropdown light (entity/query sets can be large).
261
- */
262
- getEntityAndQuerySuggestions(query) {
263
- const lowerQuery = query.toLowerCase().trim();
264
- const MAX_SUGGESTIONS = 50;
265
- const entityItems = this.entitiesCache.map(entity => ({
266
- label: entity.DisplayNameOrName,
267
- score: Math.max(this.calculateMatchScore(entity.Name || '', lowerQuery), this.calculateMatchScore(entity.DisplayName || '', lowerQuery)),
268
- suggestion: {
269
- type: 'entity',
270
- id: entity.ID,
271
- name: entity.Name,
272
- displayName: entity.DisplayNameOrName,
273
- description: entity.Description || undefined,
274
- icon: entity.Icon || 'fa-solid fa-table'
275
- }
276
- }));
277
- const queryItems = this.queriesCache.map(q => ({
278
- label: q.Name || '',
279
- score: this.calculateMatchScore(q.Name || '', lowerQuery),
280
- suggestion: {
281
- type: 'query',
282
- id: q.ID,
283
- name: q.Name || '',
284
- displayName: q.Name || '',
285
- description: q.Description || undefined,
286
- icon: this.queriesEntityIcon
287
- }
288
- }));
289
- return [...entityItems, ...queryItems]
290
- .filter(x => x.score > 0 || !lowerQuery)
291
- .sort((a, b) => {
292
- if (b.score !== a.score)
293
- return b.score - a.score;
294
- // When scores tie, prioritize entities over queries
295
- if (a.suggestion.type !== b.suggestion.type) {
296
- return a.suggestion.type === 'entity' ? -1 : 1;
297
- }
298
- return a.label.localeCompare(b.label);
299
- })
300
- .slice(0, MAX_SUGGESTIONS)
301
- .map(x => x.suggestion);
302
- }
303
- /**
304
- * The skills to offer under '/': the user's runnable catalog, narrowed to the target agent's
305
- * accepted set when the agent is known. Intersection only — the agent filter never adds a skill
306
- * the user could not run. Unknown agent id (not in the user's runnable agents) → no narrowing.
307
- */
308
- skillsForTarget(targetAgentId) {
309
- if (!targetAgentId) {
310
- return this.skillsCache;
311
- }
312
- const agent = this.agentsCache.find(a => UUIDsEqual(a.ID, targetAgentId));
313
- if (!agent) {
314
- return this.skillsCache;
315
- }
316
- const engine = this.provider
317
- ? AIEngineBase.GetProviderInstance(this.provider, AIEngineBase)
318
- : AIEngineBase.Instance;
319
- return IntersectAcceptedSkills(this.skillsCache, engine.GetSkillsForAgent(agent));
320
- }
321
- /**
322
- * Get skill suggestions for '/'-mentions, ranked by query match. Each carries the skill's own
323
- * IconClass/Color (UX metadata) so the dropdown + inserted chip render distinctly per skill.
324
- */
325
- getSkillSuggestions(query, targetAgentId = null) {
326
- const lowerQuery = query.toLowerCase().trim();
327
- const MAX_SUGGESTIONS = 12;
328
- return this.skillsForTarget(targetAgentId)
329
- .map(skill => ({
330
- score: this.calculateMatchScore(skill.Name || '', lowerQuery),
331
- suggestion: {
332
- type: 'skill',
333
- id: skill.ID,
334
- name: skill.Name || 'Unknown Skill',
335
- displayName: skill.Name || 'Unknown Skill',
336
- description: skill.Description || undefined,
337
- icon: skill.IconClass || this.defaultSkillIcon,
338
- color: skill.Color || undefined
339
- }
340
- }))
341
- .filter(x => x.score > 0 || !lowerQuery)
342
- .sort((a, b) => {
343
- if (b.score !== a.score)
344
- return b.score - a.score;
345
- return a.suggestion.name.localeCompare(b.suggestion.name);
346
- })
347
- .slice(0, MAX_SUGGESTIONS)
348
- .map(x => x.suggestion);
349
- }
350
- /**
351
- * Calculate match score for ranking
352
- * Higher score = better match
353
- */
354
- calculateMatchScore(name, query) {
355
- if (!query)
356
- return 1; // Show all if no query
357
- const lowerName = name.toLowerCase();
358
- const lowerQuery = query.toLowerCase();
359
- // Exact match
360
- if (lowerName === lowerQuery)
361
- return 100;
362
- // Starts with
363
- if (lowerName.startsWith(lowerQuery))
364
- return 50;
365
- // Contains
366
- if (lowerName.includes(lowerQuery))
367
- return 25;
368
- // Word boundary match (e.g., "MA" matches "Marketing Agent")
369
- const words = lowerName.split(/\s+/);
370
- for (const word of words) {
371
- if (word.startsWith(lowerQuery))
372
- return 40;
373
- }
374
- return 0; // No match
375
- }
376
- /**
377
- * Map an agent's AI Agent Configuration presets into the composer's generic
378
- * `MentionSuggestionPreset` shape so the chip's preset picker works without the
379
- * composer knowing anything about agents.
380
- *
381
- * IMPORTANT: preset.ID is the AIAgentConfiguration.ID (preset ID), not
382
- * AIConfigurationID — the backend mapping converts preset ID -> AIConfigurationID.
383
- */
384
- getAgentPresets(agentId) {
385
- try {
386
- const presets = AIEngineBase.Instance.GetAgentConfigurationPresets(agentId, true);
387
- if (!presets || presets.length === 0) {
388
- return undefined;
389
- }
390
- return presets.map(p => ({
391
- ID: p.ID,
392
- Name: p.Name,
393
- DisplayName: p.DisplayName || undefined,
394
- Description: p.Description || undefined,
395
- IsDefault: p.IsDefault
396
- }));
397
- }
398
- catch {
399
- // Presets are a chip nicety — never let them break suggestion building
400
- return undefined;
401
- }
402
- }
403
- /**
404
- * Get icon for agent based on type/name
405
- */
406
- getAgentIcon(agent) {
407
- // Use agent's icon if available, otherwise default based on type
408
- if (agent.IconClass)
409
- return agent.IconClass;
410
- // Default icons based on agent name patterns
411
- const name = agent.Name?.toLowerCase() || '';
412
- if (name.includes('marketing'))
413
- return 'fa-megaphone';
414
- if (name.includes('data') || name.includes('analysis'))
415
- return 'fa-chart-line';
416
- if (name.includes('code') || name.includes('developer'))
417
- return 'fa-code';
418
- if (name.includes('design'))
419
- return 'fa-palette';
420
- if (name.includes('conversation') || name.includes('manager'))
421
- return 'fa-comments';
422
- return 'fa-robot'; // Default
423
- }
424
- /**
425
- * Get available agents for parsing
426
- */
427
- getAvailableAgents() {
428
- return this.agentsCache;
429
- }
430
- /**
431
- * Get available users for parsing
432
- */
433
- getAvailableUsers() {
434
- return this.usersCache;
435
- }
436
- /**
437
- * Get available entities for parsing
438
- */
439
- getAvailableEntities() {
440
- return this.entitiesCache;
441
- }
442
- /**
443
- * Get available queries for parsing
444
- */
445
- getAvailableQueries() {
446
- return this.queriesCache;
447
- }
448
- /**
449
- * Get the generic icon used for all query mentions.
450
- */
451
- getQueriesEntityIcon() {
452
- return this.queriesEntityIcon;
453
- }
454
- /**
455
- * Refresh the caches
456
- * Resets initialization state and reloads agents
457
- */
458
- async refresh(currentUser) {
459
- this.isInitialized = false;
460
- this.initializationPromise = null;
461
- await this.initialize(currentUser);
462
- }
463
- }
18
+ export const MentionAutocompleteService = MentionAutocomplete;
464
19
  //# sourceMappingURL=mention-autocomplete.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mention-autocomplete.service.js","sourceRoot":"","sources":["../../../src/lib/services/mention-autocomplete.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';\nimport { MJAISkillEntity } from '@memberjunction/core-entities';\nimport { UserInfo, Metadata, EntityInfo, QueryInfo, IMetadataProvider } from '@memberjunction/core';\nimport { AIEngineBase, AIAgentPermissionHelper, AISkillPermissionHelper } from '@memberjunction/ai-engine-base';\nimport { BaseSingleton, UUIDsEqual } from '@memberjunction/global';\nimport { IntersectAcceptedSkills } from './skill-picker-narrowing';\nimport { MentionSuggestion, MentionSuggestionPreset } from '@memberjunction/ng-composer';\n\n/**\n * Shared engine behind the conversations composer plugins (the agent-mentions /\n * record-mentions / skill-commands `ComposerTriggerProvider`s) and the mention-parsing\n * consumers (message routing, saved-message badge rendering). Loads the\n * permission-filtered agent / user / entity / query / skill caches once per session and\n * serves ranked `MentionSuggestion` lists per trigger char.\n *\n * NOT an Angular DI service — it's a `BaseSingleton` engine so the\n * ClassFactory-instantiated trigger providers (which live outside Angular DI) and the\n * Angular components share ONE instance (one cache warm-up) via\n * `MentionAutocompleteService.Instance`.\n */\nexport class MentionAutocompleteService extends BaseSingleton<MentionAutocompleteService> {\n protected constructor() {\n super();\n }\n\n /** The process-wide shared instance (Global Object Store backed). */\n public static get Instance(): MentionAutocompleteService {\n return super.getInstance<MentionAutocompleteService>();\n }\n\n private agentsCache: MJAIAgentEntityExtended[] = [];\n private usersCache: UserInfo[] = [];\n private entitiesCache: EntityInfo[] = [];\n private queriesCache: QueryInfo[] = [];\n /** Active skills the current user can Run — surfaced under the '/' trigger. */\n private skillsCache: MJAISkillEntity[] = [];\n /** The provider this instance was initialised against (multi-provider hosts); undefined = global. */\n private provider: IMetadataProvider | undefined;\n /** Default icon for a skill with no IconClass of its own. */\n private defaultSkillIcon = 'fa-solid fa-wand-magic-sparkles';\n /** Generic icon for all query mentions, sourced from the 'MJ: Queries' entity. */\n private queriesEntityIcon = 'fa-solid fa-database';\n private isInitialized = false;\n private initializationPromise: Promise<void> | null = null;\n\n /** True once the caches have loaded (agents/users/entities/queries/skills). */\n public get IsInitialized(): boolean {\n return this.isInitialized;\n }\n\n /**\n * Initialize the service by loading agents and users\n * Prevents concurrent initialization with promise lock\n */\n async initialize(currentUser: UserInfo, provider?: IMetadataProvider): Promise<void> {\n // If already initialized, return immediately\n if (this.isInitialized) {\n return;\n }\n\n // If initialization is in progress, wait for it\n if (this.initializationPromise) {\n return this.initializationPromise;\n }\n\n // Create initialization promise and store it\n this.initializationPromise = this._initializeInternal(currentUser, provider);\n\n try {\n await this.initializationPromise;\n } finally {\n this.initializationPromise = null;\n }\n }\n\n /**\n * Internal initialization logic\n */\n private async _initializeInternal(currentUser: UserInfo, provider?: IMetadataProvider): Promise<void> {\n try {\n // Load agents from AIEngineBase\n await AIEngineBase.Instance.Config(false);\n\n const allAgents = AIEngineBase.Instance.Agents || [];\n\n // Filter by status, hierarchy, and invocation mode first\n const candidateAgents = allAgents.filter(\n a => !a.ParentID && a.Status === 'Active' && a.InvocationMode !== 'Sub-Agent' && !a.IsRestricted\n );\n\n // Filter by user's 'run' permission — respects open-by-default + explicit permissions\n this.agentsCache = await this.filterAgentsByRunPermission(candidateAgents, currentUser);\n\n // Load users from the system (optional - can be expanded later)\n // For now, we'll just use the current user\n this.usersCache = [currentUser];\n\n // Load entities the current user can read (candidates for #entity mentions)\n this.entitiesCache = this.loadReadableEntities(currentUser, provider);\n\n // Load queries the current user can run (also surfaced under the '#' trigger)\n this.queriesCache = this.loadRunnableQueries(currentUser, provider);\n this.queriesEntityIcon = this.resolveQueriesEntityIcon(provider);\n\n // Load Active skills the current user can Run (surfaced under the '/' trigger). Mirrors the\n // agent filter: open-by-default unless a skill has explicit permission rows. This is the user's\n // full run-permitted set; when the host names the target agent (getSuggestions' targetAgentId)\n // the picker narrows it to what that agent accepts, and the server's RequestedSkills guard is\n // the backstop either way.\n this.skillsCache = await this.filterSkillsByRunPermission(currentUser);\n this.provider = provider;\n\n this.isInitialized = true;\n } catch (error) {\n console.error('Failed to initialize MentionAutocompleteService:', error);\n throw error;\n }\n }\n\n /**\n * Filter agents to only those the current user has 'run' permission for.\n * Agents with no permission records are open to everyone (canRun = true).\n * Agents with explicit permission records are checked against the user.\n */\n private async filterAgentsByRunPermission(\n agents: MJAIAgentEntityExtended[],\n user: UserInfo\n ): Promise<MJAIAgentEntityExtended[]> {\n const permitted: MJAIAgentEntityExtended[] = [];\n for (const agent of agents) {\n try {\n const canRun = await AIAgentPermissionHelper.HasPermission(agent.ID, user, 'run');\n if (canRun) {\n permitted.push(agent);\n }\n } catch {\n // Fail closed — exclude agent on error\n }\n }\n return permitted;\n }\n\n /**\n * Filter Active skills to those the current user has 'run' permission for.\n * Skills with no permission records are open to everyone (canRun = true);\n * skills with explicit records are checked against the user (open-by-default).\n */\n private async filterSkillsByRunPermission(user: UserInfo): Promise<MJAISkillEntity[]> {\n try {\n const runnable = await AISkillPermissionHelper.GetAccessibleSkills(user, 'run');\n return runnable.filter(s => s.Status === 'Active');\n } catch {\n // Fail closed — no skills on error.\n return [];\n }\n }\n\n /**\n * Load entities the current user has read permission for.\n * These are the candidates surfaced for #entity mentions.\n */\n private loadReadableEntities(user: UserInfo, provider?: IMetadataProvider): EntityInfo[] {\n try {\n const md = provider ?? Metadata.Provider;\n return (md.Entities || []).filter(entity => {\n try {\n return entity.GetUserPermisions(user).CanRead;\n } catch {\n // Fail closed — exclude entity on permission-check error\n return false;\n }\n });\n } catch (error) {\n console.error('Failed to load entities for mention autocomplete:', error);\n return [];\n }\n }\n\n /**\n * Load queries the current user has run permission for.\n * These are the candidates surfaced for #query mentions.\n */\n private loadRunnableQueries(user: UserInfo, provider?: IMetadataProvider): QueryInfo[] {\n try {\n const md = provider ?? Metadata.Provider;\n return (md.Queries || []).filter(query => {\n try {\n return query.UserCanRun(user);\n } catch {\n // Fail closed — exclude query on permission-check error\n return false;\n }\n });\n } catch (error) {\n console.error('Failed to load queries for mention autocomplete:', error);\n return [];\n }\n }\n\n /**\n * Resolve the generic icon used for all query mentions from the 'MJ: Queries' entity.\n */\n private resolveQueriesEntityIcon(provider?: IMetadataProvider): string {\n try {\n const md = provider ?? Metadata.Provider;\n return md.EntityByName('MJ: Queries')?.Icon || 'fa-solid fa-database';\n } catch {\n return 'fa-solid fa-database';\n }\n }\n\n /**\n * Get suggestions based on search query\n * @param query The search text after the trigger character\n * @param includeUsers Whether to include users in suggestions\n * @param trigger '@' (agents + users), '#' (entities + queries) or '/' (skills)\n * @param targetAgentId When the host knows which agent the message will go to (the '/' trigger\n * only), skill suggestions are narrowed to what THAT agent accepts — `AcceptsSkills` + its\n * `MJ: AI Agent Skills` grants — via {@link AIEngineBase.GetSkillsForAgent}. Without it (or for an\n * agent not in the user's runnable set) the user's full runnable catalog is shown, as before, and\n * the server's `RequestedSkills` guard is the backstop.\n * @returns Filtered and ranked suggestions\n */\n getSuggestions(query: string, includeUsers: boolean = true, trigger: string = '@', targetAgentId: string | null = null): MentionSuggestion[] {\n // The '#' trigger searches entities + queries; '/' searches skills; '@' searches agents + users\n if (trigger === '#') {\n return this.getEntityAndQuerySuggestions(query);\n }\n if (trigger === '/') {\n return this.getSkillSuggestions(query, targetAgentId);\n }\n\n const lowerQuery = query.toLowerCase().trim();\n const suggestions: MentionSuggestion[] = [];\n\n // Add agent suggestions\n for (const agent of this.agentsCache) {\n const score = this.calculateMatchScore(agent.Name || '', lowerQuery);\n if (score > 0 || !lowerQuery) {\n suggestions.push({\n type: 'agent',\n id: agent.ID,\n name: agent.Name || 'Unknown',\n displayName: agent.Name || 'Unknown',\n description: agent.Description || undefined,\n imageUrl: agent.LogoURL || undefined, // Agent logo/avatar image\n icon: this.getAgentIcon(agent),\n // Configuration presets ride on the suggestion — the (AI-blind) composer\n // renders a preset picker on the inserted chip when there are 2+.\n presets: this.getAgentPresets(agent.ID)\n });\n }\n }\n\n // Add user suggestions (if enabled)\n if (includeUsers) {\n for (const user of this.usersCache) {\n const score = this.calculateMatchScore(user.Name, lowerQuery);\n if (score > 0 || !lowerQuery) {\n suggestions.push({\n type: 'user',\n id: user.ID,\n name: user.Name,\n displayName: user.Name,\n description: user.Email || undefined\n });\n }\n }\n }\n\n // Sort by relevance: exact match > starts with > contains\n return suggestions.sort((a, b) => {\n const scoreA = this.calculateMatchScore(a.name, lowerQuery);\n const scoreB = this.calculateMatchScore(b.name, lowerQuery);\n if (scoreB !== scoreA) return scoreB - scoreA;\n\n // If scores are equal, sort agents before users\n if (a.type !== b.type) return a.type === 'agent' ? -1 : 1;\n\n // Otherwise alphabetically\n return a.name.localeCompare(b.name);\n });\n }\n\n /**\n * Get entity + query suggestions for #mentions, ranked by query match.\n * Capped to keep the dropdown light (entity/query sets can be large).\n */\n private getEntityAndQuerySuggestions(query: string): MentionSuggestion[] {\n const lowerQuery = query.toLowerCase().trim();\n const MAX_SUGGESTIONS = 50;\n\n const entityItems = this.entitiesCache.map(entity => ({\n label: entity.DisplayNameOrName,\n score: Math.max(\n this.calculateMatchScore(entity.Name || '', lowerQuery),\n this.calculateMatchScore(entity.DisplayName || '', lowerQuery)\n ),\n suggestion: {\n type: 'entity' as const,\n id: entity.ID,\n name: entity.Name,\n displayName: entity.DisplayNameOrName,\n description: entity.Description || undefined,\n icon: entity.Icon || 'fa-solid fa-table'\n }\n }));\n\n const queryItems = this.queriesCache.map(q => ({\n label: q.Name || '',\n score: this.calculateMatchScore(q.Name || '', lowerQuery),\n suggestion: {\n type: 'query' as const,\n id: q.ID,\n name: q.Name || '',\n displayName: q.Name || '',\n description: q.Description || undefined,\n icon: this.queriesEntityIcon\n }\n }));\n\n return [...entityItems, ...queryItems]\n .filter(x => x.score > 0 || !lowerQuery)\n .sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n // When scores tie, prioritize entities over queries\n if (a.suggestion.type !== b.suggestion.type) {\n return a.suggestion.type === 'entity' ? -1 : 1;\n }\n return a.label.localeCompare(b.label);\n })\n .slice(0, MAX_SUGGESTIONS)\n .map(x => x.suggestion);\n }\n\n /**\n * The skills to offer under '/': the user's runnable catalog, narrowed to the target agent's\n * accepted set when the agent is known. Intersection only — the agent filter never adds a skill\n * the user could not run. Unknown agent id (not in the user's runnable agents) → no narrowing.\n */\n private skillsForTarget(targetAgentId: string | null): MJAISkillEntity[] {\n if (!targetAgentId) {\n return this.skillsCache;\n }\n const agent = this.agentsCache.find(a => UUIDsEqual(a.ID, targetAgentId));\n if (!agent) {\n return this.skillsCache;\n }\n const engine = this.provider\n ? (AIEngineBase.GetProviderInstance<AIEngineBase>(this.provider, AIEngineBase) as AIEngineBase)\n : AIEngineBase.Instance;\n return IntersectAcceptedSkills(this.skillsCache, engine.GetSkillsForAgent(agent));\n }\n\n\n /**\n * Get skill suggestions for '/'-mentions, ranked by query match. Each carries the skill's own\n * IconClass/Color (UX metadata) so the dropdown + inserted chip render distinctly per skill.\n */\n private getSkillSuggestions(query: string, targetAgentId: string | null = null): MentionSuggestion[] {\n const lowerQuery = query.toLowerCase().trim();\n const MAX_SUGGESTIONS = 12;\n\n return this.skillsForTarget(targetAgentId)\n .map(skill => ({\n score: this.calculateMatchScore(skill.Name || '', lowerQuery),\n suggestion: {\n type: 'skill' as const,\n id: skill.ID,\n name: skill.Name || 'Unknown Skill',\n displayName: skill.Name || 'Unknown Skill',\n description: skill.Description || undefined,\n icon: skill.IconClass || this.defaultSkillIcon,\n color: skill.Color || undefined\n }\n }))\n .filter(x => x.score > 0 || !lowerQuery)\n .sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n return a.suggestion.name.localeCompare(b.suggestion.name);\n })\n .slice(0, MAX_SUGGESTIONS)\n .map(x => x.suggestion);\n }\n\n /**\n * Calculate match score for ranking\n * Higher score = better match\n */\n private calculateMatchScore(name: string, query: string): number {\n if (!query) return 1; // Show all if no query\n\n const lowerName = name.toLowerCase();\n const lowerQuery = query.toLowerCase();\n\n // Exact match\n if (lowerName === lowerQuery) return 100;\n\n // Starts with\n if (lowerName.startsWith(lowerQuery)) return 50;\n\n // Contains\n if (lowerName.includes(lowerQuery)) return 25;\n\n // Word boundary match (e.g., \"MA\" matches \"Marketing Agent\")\n const words = lowerName.split(/\\s+/);\n for (const word of words) {\n if (word.startsWith(lowerQuery)) return 40;\n }\n\n return 0; // No match\n }\n\n /**\n * Map an agent's AI Agent Configuration presets into the composer's generic\n * `MentionSuggestionPreset` shape so the chip's preset picker works without the\n * composer knowing anything about agents.\n *\n * IMPORTANT: preset.ID is the AIAgentConfiguration.ID (preset ID), not\n * AIConfigurationID — the backend mapping converts preset ID -> AIConfigurationID.\n */\n private getAgentPresets(agentId: string): MentionSuggestionPreset[] | undefined {\n try {\n const presets = AIEngineBase.Instance.GetAgentConfigurationPresets(agentId, true);\n if (!presets || presets.length === 0) {\n return undefined;\n }\n return presets.map(p => ({\n ID: p.ID,\n Name: p.Name,\n DisplayName: p.DisplayName || undefined,\n Description: p.Description || undefined,\n IsDefault: p.IsDefault\n }));\n } catch {\n // Presets are a chip nicety — never let them break suggestion building\n return undefined;\n }\n }\n\n /**\n * Get icon for agent based on type/name\n */\n private getAgentIcon(agent: MJAIAgentEntityExtended): string {\n // Use agent's icon if available, otherwise default based on type\n if (agent.IconClass) return agent.IconClass;\n\n // Default icons based on agent name patterns\n const name = agent.Name?.toLowerCase() || '';\n if (name.includes('marketing')) return 'fa-megaphone';\n if (name.includes('data') || name.includes('analysis')) return 'fa-chart-line';\n if (name.includes('code') || name.includes('developer')) return 'fa-code';\n if (name.includes('design')) return 'fa-palette';\n if (name.includes('conversation') || name.includes('manager')) return 'fa-comments';\n\n return 'fa-robot'; // Default\n }\n\n /**\n * Get available agents for parsing\n */\n getAvailableAgents(): MJAIAgentEntityExtended[] {\n return this.agentsCache;\n }\n\n /**\n * Get available users for parsing\n */\n getAvailableUsers(): UserInfo[] {\n return this.usersCache;\n }\n\n /**\n * Get available entities for parsing\n */\n getAvailableEntities(): EntityInfo[] {\n return this.entitiesCache;\n }\n\n /**\n * Get available queries for parsing\n */\n getAvailableQueries(): QueryInfo[] {\n return this.queriesCache;\n }\n\n /**\n * Get the generic icon used for all query mentions.\n */\n getQueriesEntityIcon(): string {\n return this.queriesEntityIcon;\n }\n\n /**\n * Refresh the caches\n * Resets initialization state and reloads agents\n */\n async refresh(currentUser: UserInfo): Promise<void> {\n this.isInitialized = false;\n this.initializationPromise = null;\n await this.initialize(currentUser);\n }\n}\n"]}
1
+ {"version":3,"file":"mention-autocomplete.service.js","sourceRoot":"","sources":["../../../src/lib/services/mention-autocomplete.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,mBAAmB,CAAC","sourcesContent":["import { MentionAutocomplete } from '@memberjunction/conversations-runtime';\n\n/**\n * @fileoverview Angular alias for the framework-agnostic `MentionAutocomplete` engine in\n * `@memberjunction/conversations-runtime`.\n *\n * The engine — permission-filtered agent / user / entity / query / skill caches, the `/` picker's\n * target-agent narrowing, and the per-trigger ranking — moved into the runtime. It had never\n * imported anything from `@angular/*` and carried no decorator; it was Angular-coupled only by\n * which package it happened to sit in, which meant a React Native host could not reach it without\n * a second implementation of the same permission rules.\n *\n * This alias keeps every existing `MentionAutocompleteService.Instance` call site working\n * unchanged. It is a `const`, not a subclass, so there is exactly one instance and one cache\n * warm-up shared with the ClassFactory-instantiated trigger providers and any non-Angular host.\n *\n * **For new code:** import `MentionAutocomplete` from `@memberjunction/conversations-runtime`.\n */\nexport const MentionAutocompleteService = MentionAutocomplete;\n\n/** The engine's type, for call sites that annotate it. */\nexport type MentionAutocompleteService = MentionAutocomplete;\n"]}
@@ -1,6 +1,6 @@
1
1
  import { IMetadataProvider } from '@memberjunction/core';
2
2
  import { RealtimeDelegationCardVM, RealtimeThreadItem } from '../components/realtime/realtime-session-state';
3
- import { ParsedDelegationArtifact } from './delegation-result-parser';
3
+ import { ParsedDelegationArtifact } from '@memberjunction/realtime-runtime';
4
4
  import * as i0 from "@angular/core";
5
5
  /**
6
6
  * Why a reviewed session was closed, as stamped server-side by `SessionManager.CloseSession`
@@ -1 +1 @@
1
- {"version":3,"file":"realtime-session-review.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/realtime-session-review.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"realtime-session-review.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/realtime-session-review.service.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { Injectable } from '@angular/core';
2
2
  import { Metadata, RunView } from '@memberjunction/core';
3
3
  import { UUIDsEqual } from '@memberjunction/global';
4
- import { FormatToolName } from './delegation-result-parser';
4
+ import { FormatToolName } from '@memberjunction/realtime-runtime';
5
5
  import * as i0 from "@angular/core";
6
6
  /**
7
7
  * MULTI-LEG channel-state merge: folds every leg's channel rows into one state set,