@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.
- package/README.md +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +9 -26
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +3 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts +2 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.js +1 -1
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +3 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +26 -8
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +2 -3
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js +3 -2
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +17 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.js +122 -45
- package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +1 -9
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +13 -43
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +24 -0
- package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -0
- package/dist/lib/services/browser-realtime-media-host.js +95 -0
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -0
- package/dist/lib/services/conversation-attachment.service.d.ts +24 -2
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js +43 -4
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/graphql-attachment-blob-store.d.ts +44 -0
- package/dist/lib/services/graphql-attachment-blob-store.d.ts.map +1 -0
- package/dist/lib/services/graphql-attachment-blob-store.js +113 -0
- package/dist/lib/services/graphql-attachment-blob-store.js.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts +17 -141
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +15 -460
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +1 -1
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +16 -1150
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +28 -2430
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/utils/realtime-session-timeline.d.ts +8 -79
- package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -1
- package/dist/lib/utils/realtime-session-timeline.js +8 -89
- package/dist/lib/utils/realtime-session-timeline.js.map +1 -1
- package/dist/public-api.d.ts +2 -2
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -2
- package/dist/public-api.js.map +1 -1
- package/package.json +33 -32
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +0 -384
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +0 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +0 -231
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +0 -1
- package/dist/lib/services/delegation-result-parser.d.ts +0 -50
- package/dist/lib/services/delegation-result-parser.d.ts.map +0 -1
- package/dist/lib/services/delegation-result-parser.js +0 -60
- package/dist/lib/services/delegation-result-parser.js.map +0 -1
- package/dist/lib/services/narration-template.d.ts +0 -42
- package/dist/lib/services/narration-template.d.ts.map +0 -1
- package/dist/lib/services/narration-template.js +0 -73
- package/dist/lib/services/narration-template.js.map +0 -1
- package/dist/lib/services/skill-picker-narrowing.d.ts +0 -13
- package/dist/lib/services/skill-picker-narrowing.d.ts.map +0 -1
- package/dist/lib/services/skill-picker-narrowing.js +0 -13
- 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 {
|
|
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
|
-
*
|
|
7
|
-
*
|
|
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
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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
|
|
18
|
-
|
|
19
|
-
|
|
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,
|
|
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"}
|