@memberjunction/core-entities 6.1.0-edge.2 → 6.1.0-edge.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +180 -4
- package/dist/custom/MJDashboardEntityExtended.d.ts.map +1 -1
- package/dist/custom/MJDashboardEntityExtended.js +140 -17
- package/dist/custom/MJDashboardEntityExtended.js.map +1 -1
- package/dist/engines/FileStorageEngine.d.ts.map +1 -1
- package/dist/engines/FileStorageEngine.js +1 -3
- package/dist/engines/FileStorageEngine.js.map +1 -1
- package/dist/engines/conversations.d.ts +169 -0
- package/dist/engines/conversations.d.ts.map +1 -1
- package/dist/engines/conversations.js +406 -3
- package/dist/engines/conversations.js.map +1 -1
- package/dist/generated/entity_subclasses.d.ts +3065 -381
- package/dist/generated/entity_subclasses.d.ts.map +1 -1
- package/dist/generated/entity_subclasses.js +4495 -1075
- package/dist/generated/entity_subclasses.js.map +1 -1
- package/dist/generated/remote_operations.d.ts +153 -2
- package/dist/generated/remote_operations.d.ts.map +1 -1
- package/dist/generated/remote_operations.js +144 -0
- package/dist/generated/remote_operations.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../src/engines/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,eAAe,EAAE,iBAAiB,EAA0D,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAClL,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AACnD,OAAO,EACH,oBAAoB,EACpB,0BAA0B,EAC1B,8BAA8B,EAC9B,kBAAkB,EAClB,sBAAsB,EACtB,oCAAoC,EACpC,sCAAsC,
|
|
1
|
+
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../src/engines/conversations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseEngine, RunQuery, RunView, TransformSimpleObjectToEntityObject } from "@memberjunction/core";
|
|
2
|
-
import { NormalizeUUID, UUIDsEqual } from "@memberjunction/global";
|
|
2
|
+
import { NormalizeUUID, ToEpochMs, UUIDsEqual } from "@memberjunction/global";
|
|
3
3
|
import { BehaviorSubject } from "rxjs";
|
|
4
4
|
import { ArtifactMetadataEngine } from "./artifacts.js";
|
|
5
5
|
import { ResourcePermissionEngine } from "../custom/ResourcePermissions/ResourcePermissionEngine.js";
|
|
@@ -32,6 +32,134 @@ export function parseConversationDetailComplete(queryResult) {
|
|
|
32
32
|
: []
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Timeline items the UI asks for per page. Mirrors `DEFAULT_TRANSCRIPT_PAGE_SIZE` in
|
|
37
|
+
* `@memberjunction/ng-conversations` — duplicated rather than imported because the
|
|
38
|
+
* dependency runs Angular → core-entities and must never run the other way.
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_WINDOW_PAGE_SIZE = 10;
|
|
41
|
+
/**
|
|
42
|
+
* Raw rows read per window fetch, as a multiple of the page size. A page of exactly
|
|
43
|
+
* `PageSize` rows can collapse to a single session card, so the fetch over-reads.
|
|
44
|
+
*/
|
|
45
|
+
const DETAIL_WINDOW_OVERREAD_FACTOR = 3;
|
|
46
|
+
/**
|
|
47
|
+
* Ceiling on the session-completion read. A pathological realtime session must not be
|
|
48
|
+
* able to drag the whole conversation into a single window.
|
|
49
|
+
*/
|
|
50
|
+
const MAX_SESSION_EXPANSION_ROWS = 200;
|
|
51
|
+
/** Empty peripherals — the "no rows" and "peripheral load failed" shape. */
|
|
52
|
+
function emptyWindowPeripherals() {
|
|
53
|
+
return {
|
|
54
|
+
AgentRunsByDetailId: new Map(),
|
|
55
|
+
UserAvatars: new Map(),
|
|
56
|
+
RatingsByDetailId: new Map(),
|
|
57
|
+
ArtifactsByDetailId: new Map()
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A window with no rows. Used for BOTH "this conversation has nothing here" and "the read
|
|
62
|
+
* failed" — `failed` is what tells them apart downstream, and getting it wrong silently
|
|
63
|
+
* disables the caller's paging. See {@link DetailWindowLoadResult.Failed}.
|
|
64
|
+
*/
|
|
65
|
+
function emptyDetailWindowResult(failed) {
|
|
66
|
+
return {
|
|
67
|
+
Details: [],
|
|
68
|
+
...emptyWindowPeripherals(),
|
|
69
|
+
HasMoreAbove: false,
|
|
70
|
+
OldestSequence: null,
|
|
71
|
+
NewestSequence: null,
|
|
72
|
+
Failed: failed
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Quotes a UUID list for an `IN (...)` predicate. */
|
|
76
|
+
function quoteIdList(ids) {
|
|
77
|
+
return ids.map(id => `'${id}'`).join(',');
|
|
78
|
+
}
|
|
79
|
+
/** `ConversationDetailID IN (...)` over the window's rows. */
|
|
80
|
+
function detailIdInFilter(detailIds) {
|
|
81
|
+
return `ConversationDetailID IN (${quoteIdList(detailIds)})`;
|
|
82
|
+
}
|
|
83
|
+
/** `ID IN (...)` for a follow-up lookup keyed by primary key. */
|
|
84
|
+
function idInFilter(ids) {
|
|
85
|
+
return `ID IN (${quoteIdList(ids)})`;
|
|
86
|
+
}
|
|
87
|
+
/** Keys agent runs by the detail they belong to. */
|
|
88
|
+
function groupAgentRunsByDetailId(runs) {
|
|
89
|
+
const byDetailId = new Map();
|
|
90
|
+
for (const run of runs) {
|
|
91
|
+
if (run.ConversationDetailID) {
|
|
92
|
+
byDetailId.set(run.ConversationDetailID, run);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return byDetailId;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Keys ratings by detail, denormalizing the rater's name onto each row the way
|
|
99
|
+
* GetConversationComplete's `UserName` join does.
|
|
100
|
+
*/
|
|
101
|
+
function groupRatingsByDetailId(ratings, usersById) {
|
|
102
|
+
const byDetailId = new Map();
|
|
103
|
+
for (const rating of ratings) {
|
|
104
|
+
const withUserName = {
|
|
105
|
+
...rating,
|
|
106
|
+
UserName: usersById.get(rating.UserID)?.Name ?? ''
|
|
107
|
+
};
|
|
108
|
+
const list = byDetailId.get(rating.ConversationDetailID) ?? [];
|
|
109
|
+
list.push(withUserName);
|
|
110
|
+
byDetailId.set(rating.ConversationDetailID, list);
|
|
111
|
+
}
|
|
112
|
+
return byDetailId;
|
|
113
|
+
}
|
|
114
|
+
/** Distinct UserIDs referenced by a window — message authors plus raters. */
|
|
115
|
+
function collectWindowUserIds(details, ratings) {
|
|
116
|
+
const ids = new Set();
|
|
117
|
+
for (const detail of details) {
|
|
118
|
+
if (detail.Role?.toLowerCase() === 'user' && detail.UserID) {
|
|
119
|
+
ids.add(detail.UserID);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const rating of ratings) {
|
|
123
|
+
if (rating.UserID) {
|
|
124
|
+
ids.add(rating.UserID);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return [...ids];
|
|
128
|
+
}
|
|
129
|
+
/** Avatar lookup for the window's message authors. */
|
|
130
|
+
function buildUserAvatarMap(details, usersById) {
|
|
131
|
+
const avatars = new Map();
|
|
132
|
+
for (const detail of details) {
|
|
133
|
+
if (detail.Role?.toLowerCase() !== 'user' || !detail.UserID || avatars.has(detail.UserID)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const user = usersById.get(detail.UserID);
|
|
137
|
+
avatars.set(detail.UserID, {
|
|
138
|
+
ImageURL: user?.UserImageURL ?? null,
|
|
139
|
+
IconClass: user?.UserImageIconClass ?? null
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return avatars;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Rebuilds one {@link ArtifactJSON} from the three rows GetConversationComplete joins:
|
|
146
|
+
* the detail↔version junction, the version, and the artifact.
|
|
147
|
+
*/
|
|
148
|
+
function mergeArtifactJSON(junction, version, artifact) {
|
|
149
|
+
return {
|
|
150
|
+
...junction,
|
|
151
|
+
ArtifactVersionID: version.ID,
|
|
152
|
+
VersionNumber: version.VersionNumber,
|
|
153
|
+
VersionName: version.Name,
|
|
154
|
+
VersionDescription: version.Description,
|
|
155
|
+
VersionCreatedAt: version.__mj_CreatedAt,
|
|
156
|
+
ArtifactID: artifact.ID,
|
|
157
|
+
ArtifactName: artifact.Name,
|
|
158
|
+
ArtifactType: artifact.Type,
|
|
159
|
+
ArtifactDescription: artifact.Description,
|
|
160
|
+
Visibility: artifact.Visibility
|
|
161
|
+
};
|
|
162
|
+
}
|
|
35
163
|
/**
|
|
36
164
|
* ConversationEngine provides centralized, reactive caching for conversations,
|
|
37
165
|
* conversation details (messages), and peripheral data (agent runs, artifacts).
|
|
@@ -805,6 +933,175 @@ export class ConversationEngine extends BaseEngine {
|
|
|
805
933
|
this._detailCache.set(key, cacheEntry);
|
|
806
934
|
return cacheEntry;
|
|
807
935
|
}
|
|
936
|
+
/**
|
|
937
|
+
* Loads ONE page of a conversation's transcript — the chat area's windowed history read.
|
|
938
|
+
*
|
|
939
|
+
* Additive counterpart to {@link LoadConversationDetails}, which stays the FULL-history
|
|
940
|
+
* API. Opening a long conversation must not transfer and hydrate every row, so this
|
|
941
|
+
* reads the newest `RawOverread` rows below an optional `Sequence` bound, completes any
|
|
942
|
+
* realtime session the page landed inside, probes whether older rows remain, and loads
|
|
943
|
+
* peripherals for just those rows.
|
|
944
|
+
*
|
|
945
|
+
* The result is deliberately NOT written to `_detailCache`. That cache is keyed by
|
|
946
|
+
* conversation id alone, and {@link GetAgentContextWindow} reads it as complete history —
|
|
947
|
+
* a partial entry there would silently starve the agent of everything before the summary
|
|
948
|
+
* boundary, with no error. Use a separate partial cache if incremental caching is needed.
|
|
949
|
+
*
|
|
950
|
+
* Does not throw for a read that FAILS — a failed load returns an empty window flagged
|
|
951
|
+
* {@link DetailWindowLoadResult.Failed} so the caller can leave its paging state intact
|
|
952
|
+
* rather than mistaking the failure for the start of the conversation.
|
|
953
|
+
*
|
|
954
|
+
* It is not, however, exception-proof: there is no `try/catch` here, so a provider that
|
|
955
|
+
* REJECTS rather than returning `Success: false` propagates out to the caller. That path
|
|
956
|
+
* is left deliberately — it degrades better than the handled one, because an exception
|
|
957
|
+
* skips the cursor write entirely and the caller's paging state survives untouched.
|
|
958
|
+
*
|
|
959
|
+
* ### Round-trip profile — the counterweight to the payload win
|
|
960
|
+
*
|
|
961
|
+
* This trades ONE fat query for several thin ones. Per page:
|
|
962
|
+
*
|
|
963
|
+
* 1. {@link fetchDetailRowsBySequence} — always
|
|
964
|
+
* 2. {@link expandOldestSession} — only when the oldest row is session-stamped
|
|
965
|
+
* 3. {@link hasOlderDetails} — always, in parallel with (4)
|
|
966
|
+
* 4. {@link buildWindowPeripherals} — one batched `RunViews` of 3
|
|
967
|
+
* 5. {@link loadWindowUsers} — whenever the window references any user
|
|
968
|
+
* 6-7. {@link buildWindowArtifactMap} — up to two SEQUENTIAL reads, and it cannot batch
|
|
969
|
+
* them: the version ids come from the junction rows and the artifact ids from the
|
|
970
|
+
* versions.
|
|
971
|
+
*
|
|
972
|
+
* That is 3-6 round trips / 5-9 queries per page, against the single
|
|
973
|
+
* `GetConversationComplete` call that previously covered the ENTIRE conversation.
|
|
974
|
+
*
|
|
975
|
+
* For first paint this is unambiguously the right trade — the old call scaled with total
|
|
976
|
+
* conversation length, this one does not. For a reader paging back it inverts: past
|
|
977
|
+
* roughly ten pages the cumulative round trips exceed the old single load.
|
|
978
|
+
*
|
|
979
|
+
* The lever for that is `PageSize`, NOT this method. The per-page cost above is fixed
|
|
980
|
+
* regardless of how many rows come back, so a larger page for OLDER pages amortizes it
|
|
981
|
+
* over more content — and unlike first paint, a reader who has scrolled up has already
|
|
982
|
+
* committed to reading back. If paging up ever feels slow, that is the number to raise.
|
|
983
|
+
*
|
|
984
|
+
* @param params - Conversation, optional `Sequence` bound, and page sizing
|
|
985
|
+
* @param contextUser - The requesting user (entity RLS applies)
|
|
986
|
+
*/
|
|
987
|
+
async LoadDetailWindow(params, contextUser) {
|
|
988
|
+
const pageSize = params.PageSize ?? DEFAULT_WINDOW_PAGE_SIZE;
|
|
989
|
+
const overread = params.RawOverread ?? pageSize * DETAIL_WINDOW_OVERREAD_FACTOR;
|
|
990
|
+
const page = await this.fetchDetailRowsBySequence(params.ConversationID, params.BeforeSequence, overread, contextUser);
|
|
991
|
+
// Deliberately two branches, not one. `null` is a FAILED read; an empty array is a
|
|
992
|
+
// range that genuinely holds no rows. Collapsing them is what lets a transport blip
|
|
993
|
+
// read downstream as "you have reached the start of the conversation".
|
|
994
|
+
if (page === null) {
|
|
995
|
+
return emptyDetailWindowResult(true);
|
|
996
|
+
}
|
|
997
|
+
if (page.length === 0) {
|
|
998
|
+
return emptyDetailWindowResult(false);
|
|
999
|
+
}
|
|
1000
|
+
const details = await this.expandOldestSession(params.ConversationID, page, contextUser);
|
|
1001
|
+
const oldestSequence = details[0].Sequence;
|
|
1002
|
+
const newestSequence = details[details.length - 1].Sequence;
|
|
1003
|
+
// Concurrent, not sequential: the probe needs only `oldestSequence` and the peripherals
|
|
1004
|
+
// need only `details`, both of which are settled above. Neither rejects — each degrades
|
|
1005
|
+
// to an empty/false result on a failed read — so `Promise.all` cannot introduce a
|
|
1006
|
+
// rejection path this method did not already have.
|
|
1007
|
+
const [olderProbe, peripherals] = await Promise.all([
|
|
1008
|
+
this.hasOlderDetails(params.ConversationID, oldestSequence, contextUser),
|
|
1009
|
+
this.buildWindowPeripherals(details, contextUser)
|
|
1010
|
+
]);
|
|
1011
|
+
return {
|
|
1012
|
+
Details: details,
|
|
1013
|
+
...peripherals,
|
|
1014
|
+
// A failed probe answers `false`, which is indistinguishable from a real "nothing
|
|
1015
|
+
// older" — so the rows are still returned, but the window is marked Failed and the
|
|
1016
|
+
// caller keeps whatever it already believed about what lies above.
|
|
1017
|
+
HasMoreAbove: olderProbe.HasOlder,
|
|
1018
|
+
OldestSequence: oldestSequence,
|
|
1019
|
+
NewestSequence: newestSequence,
|
|
1020
|
+
Failed: olderProbe.Failed
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Reads the newest `maxRows` detail rows below an optional `Sequence` bound and returns
|
|
1025
|
+
* them in CHRONOLOGICAL order.
|
|
1026
|
+
*
|
|
1027
|
+
* The query is `Sequence DESC` because the interesting end of a transcript is the tail;
|
|
1028
|
+
* the reversal happens here so every caller downstream sees oldest-to-newest.
|
|
1029
|
+
*
|
|
1030
|
+
* @returns The page in ascending `Sequence` order, or null when the read failed.
|
|
1031
|
+
*/
|
|
1032
|
+
async fetchDetailRowsBySequence(conversationId, beforeSequence, maxRows, contextUser) {
|
|
1033
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1034
|
+
const filter = beforeSequence == null
|
|
1035
|
+
? `ConversationID='${conversationId}'`
|
|
1036
|
+
: `ConversationID='${conversationId}' AND Sequence < ${beforeSequence}`;
|
|
1037
|
+
const result = await rv.RunView({
|
|
1038
|
+
EntityName: 'MJ: Conversation Details',
|
|
1039
|
+
ExtraFilter: filter,
|
|
1040
|
+
OrderBy: 'Sequence DESC',
|
|
1041
|
+
MaxRows: maxRows,
|
|
1042
|
+
ResultType: 'entity_object'
|
|
1043
|
+
}, contextUser);
|
|
1044
|
+
if (!result.Success) {
|
|
1045
|
+
console.error('[ConversationEngine] Failed to load detail window:', result.ErrorMessage);
|
|
1046
|
+
return null;
|
|
1047
|
+
}
|
|
1048
|
+
return [...(result.Results || [])].reverse();
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Completes a realtime session the page landed part-way through.
|
|
1052
|
+
*
|
|
1053
|
+
* Rows stamped with an `AgentSessionID` collapse into ONE session card in the UI. When
|
|
1054
|
+
* the oldest row of a page is stamped, the rest of that session sits below the page
|
|
1055
|
+
* boundary — without this read the card renders from a partial row set AND the same
|
|
1056
|
+
* session reappears on the next older page.
|
|
1057
|
+
*
|
|
1058
|
+
* @returns The page with any missing session rows prepended, still chronological.
|
|
1059
|
+
*/
|
|
1060
|
+
async expandOldestSession(conversationId, details, contextUser) {
|
|
1061
|
+
const sessionId = details[0].AgentSessionID?.trim();
|
|
1062
|
+
if (!sessionId) {
|
|
1063
|
+
return details;
|
|
1064
|
+
}
|
|
1065
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1066
|
+
const result = await rv.RunView({
|
|
1067
|
+
EntityName: 'MJ: Conversation Details',
|
|
1068
|
+
ExtraFilter: `ConversationID='${conversationId}' AND AgentSessionID='${sessionId}' `
|
|
1069
|
+
+ `AND Sequence < ${details[0].Sequence}`,
|
|
1070
|
+
OrderBy: 'Sequence DESC',
|
|
1071
|
+
MaxRows: MAX_SESSION_EXPANSION_ROWS,
|
|
1072
|
+
ResultType: 'entity_object'
|
|
1073
|
+
}, contextUser);
|
|
1074
|
+
if (!result.Success || !result.Results?.length) {
|
|
1075
|
+
return details;
|
|
1076
|
+
}
|
|
1077
|
+
return [...[...result.Results].reverse(), ...details];
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Probes whether any row exists below the window's oldest `Sequence` — i.e. whether the
|
|
1081
|
+
* UI should show its "earlier messages" sentinel.
|
|
1082
|
+
*
|
|
1083
|
+
* A one-row probe rather than `page.length === MaxRows`: session expansion changes the
|
|
1084
|
+
* row count, so a full page can look short and a short page can look full.
|
|
1085
|
+
*
|
|
1086
|
+
* Returns a TRI-STATE rather than a boolean. "No older rows" and "could not find out"
|
|
1087
|
+
* are both `HasOlder: false`, and only the second must leave the caller's cursor alone.
|
|
1088
|
+
*/
|
|
1089
|
+
async hasOlderDetails(conversationId, oldestSequence, contextUser) {
|
|
1090
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1091
|
+
const probe = await rv.RunView({
|
|
1092
|
+
EntityName: 'MJ: Conversation Details',
|
|
1093
|
+
ExtraFilter: `ConversationID='${conversationId}' AND Sequence < ${oldestSequence}`,
|
|
1094
|
+
OrderBy: 'Sequence DESC',
|
|
1095
|
+
MaxRows: 1,
|
|
1096
|
+
Fields: ['ID'],
|
|
1097
|
+
ResultType: 'simple'
|
|
1098
|
+
}, contextUser);
|
|
1099
|
+
if (!probe.Success) {
|
|
1100
|
+
console.error('[ConversationEngine] Failed to probe for older details:', probe.ErrorMessage);
|
|
1101
|
+
return { HasOlder: false, Failed: true };
|
|
1102
|
+
}
|
|
1103
|
+
return { HasOlder: (probe.Results?.length ?? 0) > 0, Failed: false };
|
|
1104
|
+
}
|
|
808
1105
|
/**
|
|
809
1106
|
* Builds a full ConversationDetailCache from raw GetConversationComplete query results.
|
|
810
1107
|
* Hydrates entity objects and parses peripheral JSON data in one pass.
|
|
@@ -868,6 +1165,112 @@ export class ConversationEngine extends BaseEngine {
|
|
|
868
1165
|
PeripheralDataStale: false
|
|
869
1166
|
};
|
|
870
1167
|
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Loads peripheral data for ONE window's rows.
|
|
1170
|
+
*
|
|
1171
|
+
* Sibling of {@link buildDetailCacheFromRawData}, which cannot be reused here: that
|
|
1172
|
+
* method parses the `AgentRunsJSON` / `ArtifactsJSON` / `RatingsJSON` columns that only
|
|
1173
|
+
* the GetConversationComplete stored query produces. A windowed RunView returns none of
|
|
1174
|
+
* them, so each peripheral is a real query.
|
|
1175
|
+
*
|
|
1176
|
+
* A failing peripheral degrades to an empty map — the transcript still renders.
|
|
1177
|
+
*/
|
|
1178
|
+
async buildWindowPeripherals(details, contextUser) {
|
|
1179
|
+
const detailIds = details.map(d => d.ID).filter(id => !!id);
|
|
1180
|
+
if (detailIds.length === 0) {
|
|
1181
|
+
return emptyWindowPeripherals();
|
|
1182
|
+
}
|
|
1183
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1184
|
+
const byDetail = detailIdInFilter(detailIds);
|
|
1185
|
+
const [runsResult, ratingsResult, junctionsResult] = await rv.RunViews([
|
|
1186
|
+
{ EntityName: 'MJ: AI Agent Runs', ExtraFilter: byDetail, ResultType: 'entity_object' },
|
|
1187
|
+
{ EntityName: 'MJ: Conversation Detail Ratings', ExtraFilter: byDetail, ResultType: 'simple' },
|
|
1188
|
+
// Direction='Output' mirrors GetConversationComplete — input artifacts aren't shown.
|
|
1189
|
+
{
|
|
1190
|
+
EntityName: 'MJ: Conversation Detail Artifacts',
|
|
1191
|
+
ExtraFilter: `${byDetail} AND Direction='Output'`,
|
|
1192
|
+
ResultType: 'simple'
|
|
1193
|
+
}
|
|
1194
|
+
], contextUser);
|
|
1195
|
+
const runs = (runsResult?.Success ? runsResult.Results : []);
|
|
1196
|
+
const ratings = (ratingsResult?.Success ? ratingsResult.Results : []);
|
|
1197
|
+
const junctions = (junctionsResult?.Success ? junctionsResult.Results : []);
|
|
1198
|
+
const usersById = await this.loadWindowUsers(collectWindowUserIds(details, ratings), contextUser);
|
|
1199
|
+
return {
|
|
1200
|
+
AgentRunsByDetailId: groupAgentRunsByDetailId(runs),
|
|
1201
|
+
UserAvatars: buildUserAvatarMap(details, usersById),
|
|
1202
|
+
RatingsByDetailId: groupRatingsByDetailId(ratings, usersById),
|
|
1203
|
+
ArtifactsByDetailId: await this.buildWindowArtifactMap(junctions, contextUser)
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
/**
|
|
1207
|
+
* Loads the users a window references — message authors (for avatars) and raters (for
|
|
1208
|
+
* the denormalized `UserName` on each rating).
|
|
1209
|
+
*/
|
|
1210
|
+
async loadWindowUsers(userIds, contextUser) {
|
|
1211
|
+
if (userIds.length === 0) {
|
|
1212
|
+
return new Map();
|
|
1213
|
+
}
|
|
1214
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1215
|
+
const result = await rv.RunView({
|
|
1216
|
+
EntityName: 'MJ: Users',
|
|
1217
|
+
ExtraFilter: idInFilter(userIds),
|
|
1218
|
+
Fields: ['ID', 'Name', 'UserImageURL', 'UserImageIconClass'],
|
|
1219
|
+
ResultType: 'simple'
|
|
1220
|
+
}, contextUser);
|
|
1221
|
+
if (!result.Success) {
|
|
1222
|
+
console.error('[ConversationEngine] Failed to load window users:', result.ErrorMessage);
|
|
1223
|
+
return new Map();
|
|
1224
|
+
}
|
|
1225
|
+
return new Map((result.Results || []).map(user => [user.ID, user]));
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Rebuilds the window's artifact cards from the three tables GetConversationComplete
|
|
1229
|
+
* joins: the detail↔version junction, the version, then the artifact.
|
|
1230
|
+
*
|
|
1231
|
+
* This cannot be one batched call — the version ids come from the junction rows, and
|
|
1232
|
+
* the artifact ids from the versions — so it is two sequential follow-up reads. Rows
|
|
1233
|
+
* whose version or artifact is missing are dropped, matching the stored query's INNER
|
|
1234
|
+
* JOIN semantics.
|
|
1235
|
+
*/
|
|
1236
|
+
async buildWindowArtifactMap(junctions, contextUser) {
|
|
1237
|
+
const byDetailId = new Map();
|
|
1238
|
+
if (junctions.length === 0) {
|
|
1239
|
+
return byDetailId;
|
|
1240
|
+
}
|
|
1241
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1242
|
+
const versionResult = await rv.RunView({
|
|
1243
|
+
EntityName: 'MJ: Artifact Versions',
|
|
1244
|
+
ExtraFilter: idInFilter([...new Set(junctions.map(j => j.ArtifactVersionID))]),
|
|
1245
|
+
ResultType: 'simple'
|
|
1246
|
+
}, contextUser);
|
|
1247
|
+
const versions = versionResult.Success ? (versionResult.Results || []) : [];
|
|
1248
|
+
const versionById = new Map(versions.map(v => [v.ID, v]));
|
|
1249
|
+
const artifactIds = [...new Set(versions.map(v => v.ArtifactID))];
|
|
1250
|
+
const artifacts = artifactIds.length === 0 ? [] : await this.loadArtifactsByIds(artifactIds, contextUser);
|
|
1251
|
+
const artifactById = new Map(artifacts.map(a => [a.ID, a]));
|
|
1252
|
+
for (const junction of junctions) {
|
|
1253
|
+
const version = versionById.get(junction.ArtifactVersionID);
|
|
1254
|
+
const artifact = version ? artifactById.get(version.ArtifactID) : undefined;
|
|
1255
|
+
if (!version || !artifact) {
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
const list = byDetailId.get(junction.ConversationDetailID) ?? [];
|
|
1259
|
+
list.push(mergeArtifactJSON(junction, version, artifact));
|
|
1260
|
+
byDetailId.set(junction.ConversationDetailID, list);
|
|
1261
|
+
}
|
|
1262
|
+
return byDetailId;
|
|
1263
|
+
}
|
|
1264
|
+
/** Reads the artifact rows behind a window's artifact versions. */
|
|
1265
|
+
async loadArtifactsByIds(artifactIds, contextUser) {
|
|
1266
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1267
|
+
const result = await rv.RunView({
|
|
1268
|
+
EntityName: 'MJ: Artifacts',
|
|
1269
|
+
ExtraFilter: idInFilter(artifactIds),
|
|
1270
|
+
ResultType: 'simple'
|
|
1271
|
+
}, contextUser);
|
|
1272
|
+
return result.Success ? (result.Results || []) : [];
|
|
1273
|
+
}
|
|
871
1274
|
/**
|
|
872
1275
|
* Refreshes conversation details by re-running the GetConversationComplete query
|
|
873
1276
|
* and surgically merging results into the existing cache. Existing objects that
|
|
@@ -1672,8 +2075,8 @@ export class ConversationEngine extends BaseEngine {
|
|
|
1672
2075
|
if (!a.IsPinned && b.IsPinned)
|
|
1673
2076
|
return 1;
|
|
1674
2077
|
// Then by updated date descending
|
|
1675
|
-
const aTime = a.__mj_UpdatedAt
|
|
1676
|
-
const bTime = b.__mj_UpdatedAt
|
|
2078
|
+
const aTime = ToEpochMs(a.__mj_UpdatedAt);
|
|
2079
|
+
const bTime = ToEpochMs(b.__mj_UpdatedAt);
|
|
1677
2080
|
return bTime - aTime;
|
|
1678
2081
|
});
|
|
1679
2082
|
}
|