@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
@@ -0,0 +1,113 @@
1
+ import { LogError } from '@memberjunction/core';
2
+ import { GraphQLDataProvider, GraphQLFileStorageClient } from '@memberjunction/graphql-dataprovider';
3
+ /**
4
+ * @fileoverview Browser-side implementation of the conversation-attachment blob seam.
5
+ *
6
+ * The server binds an MJStorage implementation that talks to S3/Azure/Dropbox directly. A browser
7
+ * obviously cannot — and should not — hold those credentials, so it goes through MJAPI instead:
8
+ * `GraphQLFileStorageClient` already exposes exactly the four operations the seam needs, backed by
9
+ * the server's own storage subsystem and the caller's permissions.
10
+ *
11
+ * Binding this is what gives Explorer real large-attachment support. Before the seam existed, the
12
+ * Angular attachment service stored **everything inline** — it never consulted
13
+ * `ConversationUtility.ShouldStoreInline`, so a 5 MB image went into a database column rather than
14
+ * MJStorage, silently contradicting the `MJ: Conversation Detail Attachments` contract that
15
+ * `InlineData` is for small attachments and `FileID` for large ones. That is the concrete cost of
16
+ * having had three implementations of one policy.
17
+ */
18
+ /**
19
+ * Mints a short-lived, permission-checked URL for one `MJ: Files` record.
20
+ *
21
+ * The server resolves the storage account and object name behind the token and serves the bytes
22
+ * through its Range-capable `/media` route, so the browser never learns either.
23
+ */
24
+ const CreateMediaAccessTokenMutation = `
25
+ mutation CreateMediaAccessToken($fileId: String!) {
26
+ CreateMediaAccessToken(fileId: $fileId) {
27
+ Success
28
+ Url
29
+ MimeType
30
+ ErrorMessage
31
+ }
32
+ }
33
+ `;
34
+ export class GraphQLAttachmentBlobStore {
35
+ /**
36
+ * Uploads bytes through MJAPI's storage subsystem, which creates the `MJ: Files` record.
37
+ *
38
+ * Storage account selection is the server's decision here: a browser has no business choosing
39
+ * a storage backend, and `UploadFile` resolves a default when none is named.
40
+ */
41
+ async Upload(input, _contextUser, _provider) {
42
+ try {
43
+ const client = new GraphQLFileStorageClient(GraphQLDataProvider.Instance);
44
+ const result = await client.UploadFile({
45
+ FileName: input.FileName,
46
+ Base64Data: input.Base64Data,
47
+ MimeType: input.MimeType,
48
+ AccountID: input.StorageAccountID ?? undefined,
49
+ });
50
+ if (!result?.Success || !result.FileID) {
51
+ return { Success: false, Error: result?.ErrorMessage ?? 'Upload failed.' };
52
+ }
53
+ return { Success: true, FileID: result.FileID };
54
+ }
55
+ catch (err) {
56
+ return { Success: false, Error: err instanceof Error ? err.message : String(err) };
57
+ }
58
+ }
59
+ /**
60
+ * Not supported from the browser, deliberately.
61
+ *
62
+ * Pulling file bytes through JavaScript only to re-encode them as base64 wastes memory and
63
+ * bandwidth for no benefit — {@link GetDownloadUrl} gives the browser something it can hand
64
+ * straight to an `<img>`, a download, or a fetch, and the service falls back to exactly that
65
+ * when this returns `null`. This is the one operation where "not supported" is the better
66
+ * answer rather than a gap.
67
+ */
68
+ async Download(_fileId, _contextUser, _provider) {
69
+ return null;
70
+ }
71
+ /**
72
+ * Mints a permission-gated, time-limited URL for a stored file.
73
+ *
74
+ * Goes through `CreateMediaAccessToken` rather than `CreatePreAuthDownloadUrl`: the latter is
75
+ * keyed by storage account + object name, so using it would mean the client resolving storage
76
+ * internals it has no business knowing. The media route is keyed by `MJ: Files` id, checks the
77
+ * caller's permissions server-side, and Range-streams — it is the same path
78
+ * `mj-storage-media-player` already uses, so this adds a caller rather than a second mechanism.
79
+ *
80
+ * This is what makes the write path readable. Explorer only started producing storage-backed
81
+ * attachments when this seam was bound; without a URL here, every attachment over the inline
82
+ * threshold would upload successfully and then be permanently undisplayable.
83
+ */
84
+ async GetDownloadUrl(fileId, _contextUser, _provider) {
85
+ try {
86
+ const result = (await GraphQLDataProvider.Instance.ExecuteGQL(CreateMediaAccessTokenMutation, {
87
+ fileId,
88
+ }));
89
+ const minted = result?.CreateMediaAccessToken;
90
+ if (!minted?.Success || !minted.Url) {
91
+ LogError(`[GraphQLAttachmentBlobStore] Could not mint a media URL for file ${fileId}: ` +
92
+ `${minted?.ErrorMessage ?? 'no URL returned'}`);
93
+ return null;
94
+ }
95
+ return minted.Url;
96
+ }
97
+ catch (err) {
98
+ LogError(`[GraphQLAttachmentBlobStore] Failed to mint a media URL for file ${fileId}: ${err}`);
99
+ return null;
100
+ }
101
+ }
102
+ /**
103
+ * Not supported from the browser.
104
+ *
105
+ * Deleting stored bytes is a server-side concern with its own permission and retention rules;
106
+ * a client requesting it directly would bypass them. Returning `false` leaves the attachment
107
+ * row intact rather than orphaning it against content the client could not remove.
108
+ */
109
+ async Delete(_fileId, _contextUser, _provider) {
110
+ return false;
111
+ }
112
+ }
113
+ //# sourceMappingURL=graphql-attachment-blob-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql-attachment-blob-store.js","sourceRoot":"","sources":["../../../src/lib/services/graphql-attachment-blob-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAOrG;;;;;;;;;;;;;;GAcG;AACH;;;;;GAKG;AACH,MAAM,8BAA8B,GAAG;;;;;;;;;CAStC,CAAC;AAYF,MAAM,OAAO,0BAA0B;IACnC;;;;;OAKG;IACI,KAAK,CAAC,MAAM,CACf,KAAgC,EAChC,YAAsB,EACtB,SAA6B;QAE7B,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,wBAAwB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC1E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;gBACnC,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,gBAAgB,IAAI,SAAS;aACjD,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACrC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,IAAI,gBAAgB,EAAE,CAAC;YAC/E,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACvF,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,QAAQ,CACjB,OAAe,EACf,YAAsB,EACtB,SAA6B;QAE7B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,KAAK,CAAC,cAAc,CACvB,MAAc,EACd,YAAsB,EACtB,SAA6B;QAE7B,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,CAAC,MAAM,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,8BAA8B,EAAE;gBAC1F,MAAM;aACT,CAAC,CAA6B,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,EAAE,sBAAsB,CAAC;YAC9C,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBAClC,QAAQ,CACJ,oEAAoE,MAAM,IAAI;oBAC1E,GAAG,MAAM,EAAE,YAAY,IAAI,iBAAiB,EAAE,CACrD,CAAC;gBACF,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,oEAAoE,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC;YAC/F,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,CACf,OAAe,EACf,YAAsB,EACtB,SAA6B;QAE7B,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ","sourcesContent":["import { UserInfo, IMetadataProvider, LogError } from '@memberjunction/core';\nimport { GraphQLDataProvider, GraphQLFileStorageClient } from '@memberjunction/graphql-dataprovider';\nimport type {\n AttachmentBlobUploadInput,\n AttachmentBlobUploadResult,\n IAttachmentBlobStore,\n} from '@memberjunction/ai-core-plus';\n\n/**\n * @fileoverview Browser-side implementation of the conversation-attachment blob seam.\n *\n * The server binds an MJStorage implementation that talks to S3/Azure/Dropbox directly. A browser\n * obviously cannot — and should not — hold those credentials, so it goes through MJAPI instead:\n * `GraphQLFileStorageClient` already exposes exactly the four operations the seam needs, backed by\n * the server's own storage subsystem and the caller's permissions.\n *\n * Binding this is what gives Explorer real large-attachment support. Before the seam existed, the\n * Angular attachment service stored **everything inline** — it never consulted\n * `ConversationUtility.ShouldStoreInline`, so a 5 MB image went into a database column rather than\n * MJStorage, silently contradicting the `MJ: Conversation Detail Attachments` contract that\n * `InlineData` is for small attachments and `FileID` for large ones. That is the concrete cost of\n * having had three implementations of one policy.\n */\n/**\n * Mints a short-lived, permission-checked URL for one `MJ: Files` record.\n *\n * The server resolves the storage account and object name behind the token and serves the bytes\n * through its Range-capable `/media` route, so the browser never learns either.\n */\nconst CreateMediaAccessTokenMutation = `\n mutation CreateMediaAccessToken($fileId: String!) {\n CreateMediaAccessToken(fileId: $fileId) {\n Success\n Url\n MimeType\n ErrorMessage\n }\n }\n`;\n\n/** The shape `CreateMediaAccessToken` returns, narrowed once at this boundary. */\ntype MediaAccessTokenResponse = {\n CreateMediaAccessToken?: {\n Success?: boolean;\n Url?: string | null;\n MimeType?: string | null;\n ErrorMessage?: string | null;\n } | null;\n};\n\nexport class GraphQLAttachmentBlobStore implements IAttachmentBlobStore {\n /**\n * Uploads bytes through MJAPI's storage subsystem, which creates the `MJ: Files` record.\n *\n * Storage account selection is the server's decision here: a browser has no business choosing\n * a storage backend, and `UploadFile` resolves a default when none is named.\n */\n public async Upload(\n input: AttachmentBlobUploadInput,\n _contextUser: UserInfo,\n _provider?: IMetadataProvider\n ): Promise<AttachmentBlobUploadResult> {\n try {\n const client = new GraphQLFileStorageClient(GraphQLDataProvider.Instance);\n const result = await client.UploadFile({\n FileName: input.FileName,\n Base64Data: input.Base64Data,\n MimeType: input.MimeType,\n AccountID: input.StorageAccountID ?? undefined,\n });\n if (!result?.Success || !result.FileID) {\n return { Success: false, Error: result?.ErrorMessage ?? 'Upload failed.' };\n }\n return { Success: true, FileID: result.FileID };\n } catch (err) {\n return { Success: false, Error: err instanceof Error ? err.message : String(err) };\n }\n }\n\n /**\n * Not supported from the browser, deliberately.\n *\n * Pulling file bytes through JavaScript only to re-encode them as base64 wastes memory and\n * bandwidth for no benefit — {@link GetDownloadUrl} gives the browser something it can hand\n * straight to an `<img>`, a download, or a fetch, and the service falls back to exactly that\n * when this returns `null`. This is the one operation where \"not supported\" is the better\n * answer rather than a gap.\n */\n public async Download(\n _fileId: string,\n _contextUser: UserInfo,\n _provider?: IMetadataProvider\n ): Promise<string | null> {\n return null;\n }\n\n /**\n * Mints a permission-gated, time-limited URL for a stored file.\n *\n * Goes through `CreateMediaAccessToken` rather than `CreatePreAuthDownloadUrl`: the latter is\n * keyed by storage account + object name, so using it would mean the client resolving storage\n * internals it has no business knowing. The media route is keyed by `MJ: Files` id, checks the\n * caller's permissions server-side, and Range-streams — it is the same path\n * `mj-storage-media-player` already uses, so this adds a caller rather than a second mechanism.\n *\n * This is what makes the write path readable. Explorer only started producing storage-backed\n * attachments when this seam was bound; without a URL here, every attachment over the inline\n * threshold would upload successfully and then be permanently undisplayable.\n */\n public async GetDownloadUrl(\n fileId: string,\n _contextUser: UserInfo,\n _provider?: IMetadataProvider\n ): Promise<string | null> {\n try {\n const result = (await GraphQLDataProvider.Instance.ExecuteGQL(CreateMediaAccessTokenMutation, {\n fileId,\n })) as MediaAccessTokenResponse;\n const minted = result?.CreateMediaAccessToken;\n if (!minted?.Success || !minted.Url) {\n LogError(\n `[GraphQLAttachmentBlobStore] Could not mint a media URL for file ${fileId}: ` +\n `${minted?.ErrorMessage ?? 'no URL returned'}`\n );\n return null;\n }\n return minted.Url;\n } catch (err) {\n LogError(`[GraphQLAttachmentBlobStore] Failed to mint a media URL for file ${fileId}: ${err}`);\n return null;\n }\n }\n\n /**\n * Not supported from the browser.\n *\n * Deleting stored bytes is a server-side concern with its own permission and retention rules;\n * a client requesting it directly would bypass them. Returning `false` leaves the attachment\n * row intact rather than orphaning it against content the client could not remove.\n */\n public async Delete(\n _fileId: string,\n _contextUser: UserInfo,\n _provider?: IMetadataProvider\n ): Promise<boolean> {\n return false;\n }\n}\n"]}
@@ -1,145 +1,21 @@
1
- import { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';
2
- import { UserInfo, EntityInfo, QueryInfo, IMetadataProvider } from '@memberjunction/core';
3
- import { BaseSingleton } from '@memberjunction/global';
4
- import { MentionSuggestion } from '@memberjunction/ng-composer';
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 declare class MentionAutocompleteService extends BaseSingleton<MentionAutocompleteService> {
18
- protected constructor();
19
- /** The process-wide shared instance (Global Object Store backed). */
20
- static get Instance(): MentionAutocompleteService;
21
- private agentsCache;
22
- private usersCache;
23
- private entitiesCache;
24
- private queriesCache;
25
- /** Active skills the current user can Run — surfaced under the '/' trigger. */
26
- private skillsCache;
27
- /** The provider this instance was initialised against (multi-provider hosts); undefined = global. */
28
- private provider;
29
- /** Default icon for a skill with no IconClass of its own. */
30
- private defaultSkillIcon;
31
- /** Generic icon for all query mentions, sourced from the 'MJ: Queries' entity. */
32
- private queriesEntityIcon;
33
- private isInitialized;
34
- private initializationPromise;
35
- /** True once the caches have loaded (agents/users/entities/queries/skills). */
36
- get IsInitialized(): boolean;
37
- /**
38
- * Initialize the service by loading agents and users
39
- * Prevents concurrent initialization with promise lock
40
- */
41
- initialize(currentUser: UserInfo, provider?: IMetadataProvider): Promise<void>;
42
- /**
43
- * Internal initialization logic
44
- */
45
- private _initializeInternal;
46
- /**
47
- * Filter agents to only those the current user has 'run' permission for.
48
- * Agents with no permission records are open to everyone (canRun = true).
49
- * Agents with explicit permission records are checked against the user.
50
- */
51
- private filterAgentsByRunPermission;
52
- /**
53
- * Filter Active skills to those the current user has 'run' permission for.
54
- * Skills with no permission records are open to everyone (canRun = true);
55
- * skills with explicit records are checked against the user (open-by-default).
56
- */
57
- private filterSkillsByRunPermission;
58
- /**
59
- * Load entities the current user has read permission for.
60
- * These are the candidates surfaced for #entity mentions.
61
- */
62
- private loadReadableEntities;
63
- /**
64
- * Load queries the current user has run permission for.
65
- * These are the candidates surfaced for #query mentions.
66
- */
67
- private loadRunnableQueries;
68
- /**
69
- * Resolve the generic icon used for all query mentions from the 'MJ: Queries' entity.
70
- */
71
- private resolveQueriesEntityIcon;
72
- /**
73
- * Get suggestions based on search query
74
- * @param query The search text after the trigger character
75
- * @param includeUsers Whether to include users in suggestions
76
- * @param trigger '@' (agents + users), '#' (entities + queries) or '/' (skills)
77
- * @param targetAgentId When the host knows which agent the message will go to (the '/' trigger
78
- * only), skill suggestions are narrowed to what THAT agent accepts — `AcceptsSkills` + its
79
- * `MJ: AI Agent Skills` grants — via {@link AIEngineBase.GetSkillsForAgent}. Without it (or for an
80
- * agent not in the user's runnable set) the user's full runnable catalog is shown, as before, and
81
- * the server's `RequestedSkills` guard is the backstop.
82
- * @returns Filtered and ranked suggestions
83
- */
84
- getSuggestions(query: string, includeUsers?: boolean, trigger?: string, targetAgentId?: string | null): MentionSuggestion[];
85
- /**
86
- * Get entity + query suggestions for #mentions, ranked by query match.
87
- * Capped to keep the dropdown light (entity/query sets can be large).
88
- */
89
- private getEntityAndQuerySuggestions;
90
- /**
91
- * The skills to offer under '/': the user's runnable catalog, narrowed to the target agent's
92
- * accepted set when the agent is known. Intersection only — the agent filter never adds a skill
93
- * the user could not run. Unknown agent id (not in the user's runnable agents) → no narrowing.
94
- */
95
- private skillsForTarget;
96
- /**
97
- * Get skill suggestions for '/'-mentions, ranked by query match. Each carries the skill's own
98
- * IconClass/Color (UX metadata) so the dropdown + inserted chip render distinctly per skill.
99
- */
100
- private getSkillSuggestions;
101
- /**
102
- * Calculate match score for ranking
103
- * Higher score = better match
104
- */
105
- private calculateMatchScore;
106
- /**
107
- * Map an agent's AI Agent Configuration presets into the composer's generic
108
- * `MentionSuggestionPreset` shape so the chip's preset picker works without the
109
- * composer knowing anything about agents.
110
- *
111
- * IMPORTANT: preset.ID is the AIAgentConfiguration.ID (preset ID), not
112
- * AIConfigurationID — the backend mapping converts preset ID -> AIConfigurationID.
113
- */
114
- private getAgentPresets;
115
- /**
116
- * Get icon for agent based on type/name
117
- */
118
- private getAgentIcon;
119
- /**
120
- * Get available agents for parsing
121
- */
122
- getAvailableAgents(): MJAIAgentEntityExtended[];
123
- /**
124
- * Get available users for parsing
125
- */
126
- getAvailableUsers(): UserInfo[];
127
- /**
128
- * Get available entities for parsing
129
- */
130
- getAvailableEntities(): EntityInfo[];
131
- /**
132
- * Get available queries for parsing
133
- */
134
- getAvailableQueries(): QueryInfo[];
135
- /**
136
- * Get the generic icon used for all query mentions.
137
- */
138
- getQueriesEntityIcon(): string;
139
- /**
140
- * Refresh the caches
141
- * Resets initialization state and reloads agents
142
- */
143
- refresh(currentUser: UserInfo): Promise<void>;
144
- }
18
+ export declare const MentionAutocompleteService: typeof MentionAutocomplete;
19
+ /** The engine's type, for call sites that annotate it. */
20
+ export type MentionAutocompleteService = MentionAutocomplete;
145
21
  //# sourceMappingURL=mention-autocomplete.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mention-autocomplete.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/mention-autocomplete.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,EAAE,QAAQ,EAAY,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEpG,OAAO,EAAE,aAAa,EAAc,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAA2B,MAAM,6BAA6B,CAAC;AAEzF;;;;;;;;;;;GAWG;AACH,qBAAa,0BAA2B,SAAQ,aAAa,CAAC,0BAA0B,CAAC;IACvF,SAAS;IAIT,qEAAqE;IACrE,WAAkB,QAAQ,IAAI,0BAA0B,CAEvD;IAED,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,YAAY,CAAmB;IACvC,+EAA+E;IAC/E,OAAO,CAAC,WAAW,CAAyB;IAC5C,qGAAqG;IACrG,OAAO,CAAC,QAAQ,CAAgC;IAChD,6DAA6D;IAC7D,OAAO,CAAC,gBAAgB,CAAqC;IAC7D,kFAAkF;IAClF,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,+EAA+E;IAC/E,IAAW,aAAa,IAAI,OAAO,CAElC;IAED;;;OAGG;IACG,UAAU,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBpF;;OAEG;YACW,mBAAmB;IAyCjC;;;;OAIG;YACW,2BAA2B;IAkBzC;;;;OAIG;YACW,2BAA2B;IAUzC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,GAAE,OAAc,EAAE,OAAO,GAAE,MAAY,EAAE,aAAa,GAAE,MAAM,GAAG,IAAW,GAAG,iBAAiB,EAAE;IA6D5I;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IA+CpC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAevB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA0B3B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAmBvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,kBAAkB,IAAI,uBAAuB,EAAE;IAI/C;;OAEG;IACH,iBAAiB,IAAI,QAAQ,EAAE;IAI/B;;OAEG;IACH,oBAAoB,IAAI,UAAU,EAAE;IAIpC;;OAEG;IACH,mBAAmB,IAAI,SAAS,EAAE;IAIlC;;OAEG;IACH,oBAAoB,IAAI,MAAM;IAI9B;;;OAGG;IACG,OAAO,CAAC,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAKpD"}
1
+ {"version":3,"file":"mention-autocomplete.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/mention-autocomplete.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,0BAA0B,4BAAsB,CAAC;AAE9D,0DAA0D;AAC1D,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,CAAC"}