@memberjunction/server 2.45.0 → 2.47.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/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
- package/dist/generated/generated.d.ts +7 -2
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +56 -24
- package/dist/generated/generated.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
- package/dist/resolvers/AskSkipResolver.js +5 -2
- package/dist/resolvers/AskSkipResolver.js.map +1 -1
- package/package.json +24 -23
- package/src/entitySubclasses/entityPermissions.server.ts +3 -0
- package/src/generated/generated.ts +40 -18
- package/src/index.ts +3 -3
- package/src/resolvers/AskSkipResolver.ts +5 -2
- package/dist/entitySubclasses/DuplicateRunEntity.server.d.ts +0 -6
- package/dist/entitySubclasses/DuplicateRunEntity.server.d.ts.map +0 -1
- package/dist/entitySubclasses/DuplicateRunEntity.server.js +0 -32
- package/dist/entitySubclasses/DuplicateRunEntity.server.js.map +0 -1
- package/dist/entitySubclasses/reportEntity.server.d.ts +0 -6
- package/dist/entitySubclasses/reportEntity.server.d.ts.map +0 -1
- package/dist/entitySubclasses/reportEntity.server.js +0 -103
- package/dist/entitySubclasses/reportEntity.server.js.map +0 -1
- package/dist/entitySubclasses/userViewEntity.server.d.ts +0 -13
- package/dist/entitySubclasses/userViewEntity.server.d.ts.map +0 -1
- package/dist/entitySubclasses/userViewEntity.server.js +0 -205
- package/dist/entitySubclasses/userViewEntity.server.js.map +0 -1
- package/src/entitySubclasses/DuplicateRunEntity.server.ts +0 -27
- package/src/entitySubclasses/reportEntity.server.ts +0 -130
- package/src/entitySubclasses/userViewEntity.server.ts +0 -231
|
@@ -1244,6 +1244,18 @@ export class AIAgentRun_ {
|
|
|
1244
1244
|
@MaxLength(10)
|
|
1245
1245
|
_mj__UpdatedAt: Date;
|
|
1246
1246
|
|
|
1247
|
+
@Field({nullable: true})
|
|
1248
|
+
@MaxLength(510)
|
|
1249
|
+
Agent?: string;
|
|
1250
|
+
|
|
1251
|
+
@Field({nullable: true})
|
|
1252
|
+
@MaxLength(510)
|
|
1253
|
+
Conversation?: string;
|
|
1254
|
+
|
|
1255
|
+
@Field({nullable: true})
|
|
1256
|
+
@MaxLength(200)
|
|
1257
|
+
User?: string;
|
|
1258
|
+
|
|
1247
1259
|
@Field(() => [AIAgentRunStep_])
|
|
1248
1260
|
MJ_AIAgentRunSteps_AgentRunIDArray: AIAgentRunStep_[]; // Link to MJ_AIAgentRunSteps
|
|
1249
1261
|
|
|
@@ -1982,6 +1994,10 @@ export class AIAgent_ {
|
|
|
1982
1994
|
@MaxLength(510)
|
|
1983
1995
|
ContextCompressionPrompt?: string;
|
|
1984
1996
|
|
|
1997
|
+
@Field()
|
|
1998
|
+
@MaxLength(200)
|
|
1999
|
+
Type: string;
|
|
2000
|
+
|
|
1985
2001
|
@Field(() => [AIAgentRequest_])
|
|
1986
2002
|
AIAgentRequests_AgentIDArray: AIAgentRequest_[]; // Link to AIAgentRequests
|
|
1987
2003
|
|
|
@@ -2556,6 +2572,10 @@ export class AIAgentType_ {
|
|
|
2556
2572
|
@MaxLength(10)
|
|
2557
2573
|
_mj__UpdatedAt: Date;
|
|
2558
2574
|
|
|
2575
|
+
@Field({nullable: true})
|
|
2576
|
+
@MaxLength(510)
|
|
2577
|
+
SystemPrompt?: string;
|
|
2578
|
+
|
|
2559
2579
|
@Field(() => [AIAgent_])
|
|
2560
2580
|
AIAgents_TypeIDArray: AIAgent_[]; // Link to AIAgents
|
|
2561
2581
|
|
|
@@ -7999,15 +8019,15 @@ export class User_ {
|
|
|
7999
8019
|
@Field(() => [UserFavorite_])
|
|
8000
8020
|
UserFavorites_UserIDArray: UserFavorite_[]; // Link to UserFavorites
|
|
8001
8021
|
|
|
8022
|
+
@Field(() => [ResourceLink_])
|
|
8023
|
+
ResourceLinks_UserIDArray: ResourceLink_[]; // Link to ResourceLinks
|
|
8024
|
+
|
|
8002
8025
|
@Field(() => [ListCategory_])
|
|
8003
8026
|
ListCategories_UserIDArray: ListCategory_[]; // Link to ListCategories
|
|
8004
8027
|
|
|
8005
8028
|
@Field(() => [ScheduledAction_])
|
|
8006
8029
|
ScheduledActions_CreatedByUserIDArray: ScheduledAction_[]; // Link to ScheduledActions
|
|
8007
8030
|
|
|
8008
|
-
@Field(() => [ResourceLink_])
|
|
8009
|
-
ResourceLinks_UserIDArray: ResourceLink_[]; // Link to ResourceLinks
|
|
8010
|
-
|
|
8011
8031
|
@Field(() => [AIAgentRequest_])
|
|
8012
8032
|
AIAgentRequests_ResponseByUserIDArray: AIAgentRequest_[]; // Link to AIAgentRequests
|
|
8013
8033
|
|
|
@@ -8457,6 +8477,15 @@ export class UserResolverBase extends ResolverBase {
|
|
|
8457
8477
|
return result;
|
|
8458
8478
|
}
|
|
8459
8479
|
|
|
8480
|
+
@FieldResolver(() => [ResourceLink_])
|
|
8481
|
+
async ResourceLinks_UserIDArray(@Root() user_: User_, @Ctx() { dataSources, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
8482
|
+
this.CheckUserReadPermissions('Resource Links', userPayload);
|
|
8483
|
+
const dataSource = GetReadOnlyDataSource(dataSources, { allowFallbackToReadWrite: true });
|
|
8484
|
+
const sSQL = `SELECT * FROM [${Metadata.Provider.ConfigData.MJCoreSchemaName}].[vwResourceLinks] WHERE [UserID]='${user_.ID}' ` + this.getRowLevelSecurityWhereClause('Resource Links', userPayload, EntityPermissionType.Read, 'AND');
|
|
8485
|
+
const result = this.ArrayMapFieldNamesToCodeNames('Resource Links', await dataSource.query(sSQL));
|
|
8486
|
+
return result;
|
|
8487
|
+
}
|
|
8488
|
+
|
|
8460
8489
|
@FieldResolver(() => [ListCategory_])
|
|
8461
8490
|
async ListCategories_UserIDArray(@Root() user_: User_, @Ctx() { dataSources, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
8462
8491
|
this.CheckUserReadPermissions('List Categories', userPayload);
|
|
@@ -8475,15 +8504,6 @@ export class UserResolverBase extends ResolverBase {
|
|
|
8475
8504
|
return result;
|
|
8476
8505
|
}
|
|
8477
8506
|
|
|
8478
|
-
@FieldResolver(() => [ResourceLink_])
|
|
8479
|
-
async ResourceLinks_UserIDArray(@Root() user_: User_, @Ctx() { dataSources, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
8480
|
-
this.CheckUserReadPermissions('Resource Links', userPayload);
|
|
8481
|
-
const dataSource = GetReadOnlyDataSource(dataSources, { allowFallbackToReadWrite: true });
|
|
8482
|
-
const sSQL = `SELECT * FROM [${Metadata.Provider.ConfigData.MJCoreSchemaName}].[vwResourceLinks] WHERE [UserID]='${user_.ID}' ` + this.getRowLevelSecurityWhereClause('Resource Links', userPayload, EntityPermissionType.Read, 'AND');
|
|
8483
|
-
const result = this.ArrayMapFieldNamesToCodeNames('Resource Links', await dataSource.query(sSQL));
|
|
8484
|
-
return result;
|
|
8485
|
-
}
|
|
8486
|
-
|
|
8487
8507
|
@FieldResolver(() => [AIAgentRequest_])
|
|
8488
8508
|
async AIAgentRequests_ResponseByUserIDArray(@Root() user_: User_, @Ctx() { dataSources, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
8489
8509
|
this.CheckUserReadPermissions('AI Agent Requests', userPayload);
|
|
@@ -35843,10 +35863,12 @@ export class AIPromptRun_ {
|
|
|
35843
35863
|
@MaxLength(16)
|
|
35844
35864
|
ConfigurationID?: string;
|
|
35845
35865
|
|
|
35846
|
-
@Field(
|
|
35866
|
+
@Field({description: `When the prompt run started, with timezone offset information.`})
|
|
35867
|
+
@MaxLength(10)
|
|
35847
35868
|
RunAt: Date;
|
|
35848
35869
|
|
|
35849
|
-
@Field(
|
|
35870
|
+
@Field({nullable: true, description: `When the prompt run completed, with timezone offset information.`})
|
|
35871
|
+
@MaxLength(10)
|
|
35850
35872
|
CompletedAt?: Date;
|
|
35851
35873
|
|
|
35852
35874
|
@Field(() => Int, {nullable: true, description: `Total execution time in milliseconds.`})
|
|
@@ -35947,10 +35969,10 @@ export class CreateAIPromptRunInput {
|
|
|
35947
35969
|
@Field({ nullable: true })
|
|
35948
35970
|
ConfigurationID: string | null;
|
|
35949
35971
|
|
|
35950
|
-
@Field(
|
|
35972
|
+
@Field({ nullable: true })
|
|
35951
35973
|
RunAt?: Date;
|
|
35952
35974
|
|
|
35953
|
-
@Field(
|
|
35975
|
+
@Field({ nullable: true })
|
|
35954
35976
|
CompletedAt: Date | null;
|
|
35955
35977
|
|
|
35956
35978
|
@Field(() => Int, { nullable: true })
|
|
@@ -36017,10 +36039,10 @@ export class UpdateAIPromptRunInput {
|
|
|
36017
36039
|
@Field({ nullable: true })
|
|
36018
36040
|
ConfigurationID?: string | null;
|
|
36019
36041
|
|
|
36020
|
-
@Field(
|
|
36042
|
+
@Field({ nullable: true })
|
|
36021
36043
|
RunAt?: Date;
|
|
36022
36044
|
|
|
36023
|
-
@Field(
|
|
36045
|
+
@Field({ nullable: true })
|
|
36024
36046
|
CompletedAt?: Date | null;
|
|
36025
36047
|
|
|
36026
36048
|
@Field(() => Int, { nullable: true })
|
package/src/index.ts
CHANGED
|
@@ -33,6 +33,9 @@ LoadActionEntityServer(); // prevent tree shaking for this dynamic module
|
|
|
33
33
|
import { LoadGeneratedActions } from '@memberjunction/core-actions';
|
|
34
34
|
LoadGeneratedActions(); // prevent tree shaking for this dynamic module
|
|
35
35
|
|
|
36
|
+
import { LoadCoreEntitiesServerSubClasses } from '@memberjunction/core-entities-server';
|
|
37
|
+
LoadCoreEntitiesServerSubClasses(); // prevent tree shaking for this dynamic module
|
|
38
|
+
|
|
36
39
|
import { ExternalChangeDetectorEngine } from '@memberjunction/external-change-detection';
|
|
37
40
|
|
|
38
41
|
const cacheRefreshInterval = configInfo.databaseSettings.metadataCacheRefreshInterval;
|
|
@@ -42,10 +45,7 @@ export * from 'type-graphql';
|
|
|
42
45
|
export { NewUserBase } from './auth/newUsers.js';
|
|
43
46
|
export { configInfo } from './config.js';
|
|
44
47
|
export * from './directives/index.js';
|
|
45
|
-
export * from './entitySubclasses/userViewEntity.server.js';
|
|
46
48
|
export * from './entitySubclasses/entityPermissions.server.js';
|
|
47
|
-
export * from './entitySubclasses/DuplicateRunEntity.server.js';
|
|
48
|
-
export * from './entitySubclasses/reportEntity.server.js';
|
|
49
49
|
export * from './types.js';
|
|
50
50
|
export { TokenExpiredError, getSystemUser } from './auth/index.js';
|
|
51
51
|
|
|
@@ -2044,8 +2044,10 @@ cycle.`);
|
|
|
2044
2044
|
responsePhase: SkipResponsePhase.AnalysisComplete,
|
|
2045
2045
|
techExplanation: analysisDetail.techExplanation,
|
|
2046
2046
|
userExplanation: analysisDetail.userExplanation,
|
|
2047
|
-
|
|
2047
|
+
executionResults: analysisDetail.executionResults,
|
|
2048
2048
|
tableDataColumns: analysisDetail.tableDataColumns,
|
|
2049
|
+
componentOptions: analysisDetail.componentOptions,
|
|
2050
|
+
artifactRequest: analysisDetail.artifactRequest
|
|
2049
2051
|
});
|
|
2050
2052
|
} else if (detail?.responsePhase === SkipResponsePhase.ClarifyingQuestion) {
|
|
2051
2053
|
const clarifyingQuestionDetail = <SkipAPIClarifyingQuestionResponse>detail;
|
|
@@ -2567,6 +2569,7 @@ cycle.`);
|
|
|
2567
2569
|
item.Type = 'sql';
|
|
2568
2570
|
item.SQL = dr.text;
|
|
2569
2571
|
item.AdditionalDescription = dr.description;
|
|
2572
|
+
item.CodeName = dr.codeName;
|
|
2570
2573
|
if (!(await item.LoadData(dataSource, false, false, 0, user)))
|
|
2571
2574
|
throw new Error(`SQL data request failed: ${item.DataLoadingError}`);
|
|
2572
2575
|
break;
|
|
@@ -2681,7 +2684,7 @@ cycle.`);
|
|
|
2681
2684
|
dataSource: DataSource,
|
|
2682
2685
|
startTime: Date
|
|
2683
2686
|
): Promise<{ AIMessageConversationDetailID: string }> {
|
|
2684
|
-
const sTitle = apiResponse.title;
|
|
2687
|
+
const sTitle = apiResponse.title || apiResponse.reportTitle;
|
|
2685
2688
|
const sResult = JSON.stringify(apiResponse);
|
|
2686
2689
|
|
|
2687
2690
|
// first up, let's see if Skip asked us to create an artifact or add a new version to an existing artifact, or NOT
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { DuplicateRunEntity } from "@memberjunction/core-entities";
|
|
2
|
-
export declare class DuplicateRunEntity_Server extends DuplicateRunEntity {
|
|
3
|
-
Save(): Promise<boolean>;
|
|
4
|
-
}
|
|
5
|
-
export declare function LoadDuplicateRunEntityServerSubClass(): void;
|
|
6
|
-
//# sourceMappingURL=DuplicateRunEntity.server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DuplicateRunEntity.server.d.ts","sourceRoot":"","sources":["../../src/entitySubclasses/DuplicateRunEntity.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,qBACa,yBAA0B,SAAQ,kBAAkB;IAChD,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CAiBxC;AAED,wBAAgB,oCAAoC,SAAK"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { BaseEntity, PotentialDuplicateRequest } from "@memberjunction/core";
|
|
8
|
-
import { RegisterClass } from "@memberjunction/global";
|
|
9
|
-
import { DuplicateRunEntity } from "@memberjunction/core-entities";
|
|
10
|
-
import { DuplicateRecordDetector } from "@memberjunction/ai-vector-dupe";
|
|
11
|
-
let DuplicateRunEntity_Server = class DuplicateRunEntity_Server extends DuplicateRunEntity {
|
|
12
|
-
async Save() {
|
|
13
|
-
const saveResult = await super.Save();
|
|
14
|
-
if (saveResult && this.EndedAt === null) {
|
|
15
|
-
const duplicateRecordDetector = new DuplicateRecordDetector();
|
|
16
|
-
let request = new PotentialDuplicateRequest();
|
|
17
|
-
request.EntityID = this.EntityID;
|
|
18
|
-
request.ListID = this.SourceListID;
|
|
19
|
-
request.Options = {
|
|
20
|
-
DuplicateRunID: this.ID,
|
|
21
|
-
};
|
|
22
|
-
const response = await duplicateRecordDetector.getDuplicateRecords(request, this.ContextCurrentUser);
|
|
23
|
-
}
|
|
24
|
-
return saveResult;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
DuplicateRunEntity_Server = __decorate([
|
|
28
|
-
RegisterClass(BaseEntity, 'Duplicate Runs')
|
|
29
|
-
], DuplicateRunEntity_Server);
|
|
30
|
-
export { DuplicateRunEntity_Server };
|
|
31
|
-
export function LoadDuplicateRunEntityServerSubClass() { }
|
|
32
|
-
//# sourceMappingURL=DuplicateRunEntity.server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DuplicateRunEntity.server.js","sourceRoot":"","sources":["../../src/entitySubclasses/DuplicateRunEntity.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,kBAAkB;IACtD,KAAK,CAAC,IAAI;QACb,MAAM,UAAU,GAAY,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,UAAU,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAEtC,MAAM,uBAAuB,GAA4B,IAAI,uBAAuB,EAAE,CAAC;YACvF,IAAI,OAAO,GAA8B,IAAI,yBAAyB,EAAE,CAAC;YACzE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;YACnC,OAAO,CAAC,OAAO,GAAG;gBACd,cAAc,EAAE,IAAI,CAAC,EAAE;aAC1B,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACzG,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAA;AAlBY,yBAAyB;IADrC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC;GAC/B,yBAAyB,CAkBrC;;AAED,MAAM,UAAU,oCAAoC,KAAI,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { ReportEntity } from "@memberjunction/core-entities";
|
|
2
|
-
export declare class ReportEntity_Server extends ReportEntity {
|
|
3
|
-
Save(): Promise<boolean>;
|
|
4
|
-
}
|
|
5
|
-
export declare function LoadReportEntityServerSubClass(): void;
|
|
6
|
-
//# sourceMappingURL=reportEntity.server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reportEntity.server.d.ts","sourceRoot":"","sources":["../../src/entitySubclasses/reportEntity.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAA6C,MAAM,+BAA+B,CAAC;AAGxG,qBACa,mBAAoB,SAAQ,YAAY;IAMpC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CAmHxC;AAED,wBAAgB,8BAA8B,SAAK"}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { BaseEntity, Metadata, RunView } from "@memberjunction/core";
|
|
8
|
-
import { RegisterClass, SafeJSONParse } from "@memberjunction/global";
|
|
9
|
-
import { ReportEntity } from "@memberjunction/core-entities";
|
|
10
|
-
let ReportEntity_Server = class ReportEntity_Server extends ReportEntity {
|
|
11
|
-
async Save() {
|
|
12
|
-
try {
|
|
13
|
-
const config = this.Configuration && this.Configuration.length > 0 ? SafeJSONParse(this.Configuration) : null;
|
|
14
|
-
const oldTextConfig = this.GetFieldByName('Configuration')?.OldValue;
|
|
15
|
-
const oldConfig = oldTextConfig && oldTextConfig.length > 0 ? SafeJSONParse(oldTextConfig) : null;
|
|
16
|
-
if ((config && oldConfig) || (config && !this.IsSaved)) {
|
|
17
|
-
let createSnapshot = false;
|
|
18
|
-
let createReportVersion = false;
|
|
19
|
-
if (this.IsSaved) {
|
|
20
|
-
const castedConfig = config;
|
|
21
|
-
const castedOldConfig = oldConfig;
|
|
22
|
-
const dataContextChanged = Object.keys(castedConfig.dataContext || {})?.length !== Object.keys(castedOldConfig.dataContext || {})?.length;
|
|
23
|
-
const executionResultsChanged = JSON.stringify(castedConfig.executionResults) !== JSON.stringify(castedOldConfig.executionResults);
|
|
24
|
-
const analysisChanged = castedConfig.analysis !== castedOldConfig.analysis;
|
|
25
|
-
delete castedConfig.dataContext;
|
|
26
|
-
delete castedConfig.analysis;
|
|
27
|
-
delete castedConfig.executionResults;
|
|
28
|
-
delete castedOldConfig.dataContext;
|
|
29
|
-
delete castedOldConfig.executionResults;
|
|
30
|
-
delete castedOldConfig.analysis;
|
|
31
|
-
const configChanged = JSON.stringify(castedConfig) !== JSON.stringify(castedOldConfig);
|
|
32
|
-
createSnapshot = dataContextChanged || executionResultsChanged || analysisChanged;
|
|
33
|
-
createReportVersion = configChanged;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
createSnapshot = true;
|
|
37
|
-
createReportVersion = true;
|
|
38
|
-
}
|
|
39
|
-
const wasNewRecord = !this.IsSaved;
|
|
40
|
-
const saveResult = await super.Save();
|
|
41
|
-
if (saveResult && (createSnapshot || createReportVersion)) {
|
|
42
|
-
let success = true;
|
|
43
|
-
const md = new Metadata();
|
|
44
|
-
if (createReportVersion) {
|
|
45
|
-
const reportVersion = await md.GetEntityObject('MJ: Report Versions', this.ContextCurrentUser);
|
|
46
|
-
reportVersion.ReportID = this.ID;
|
|
47
|
-
let newVersionNumber = 1;
|
|
48
|
-
if (!wasNewRecord) {
|
|
49
|
-
const rv = new RunView();
|
|
50
|
-
const rvResult = await rv.RunView({
|
|
51
|
-
Fields: ['VersionNumber'],
|
|
52
|
-
EntityName: 'MJ: Report Versions',
|
|
53
|
-
ExtraFilter: `ReportID = '${this.ID}'`,
|
|
54
|
-
MaxRows: 1,
|
|
55
|
-
OrderBy: 'VersionNumber DESC',
|
|
56
|
-
}, this.ContextCurrentUser);
|
|
57
|
-
if (rvResult.Success && rvResult.Results.length > 0) {
|
|
58
|
-
newVersionNumber = parseInt(rvResult.Results[0].VersionNumber) + 1;
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
newVersionNumber = 1;
|
|
62
|
-
console.warn('ReportEntity_Server.Save(): No report versions found for report ID:', this.ID);
|
|
63
|
-
console.warn('ReportEntity_Server.Save(): Using version number 1 for new report version');
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
reportVersion.Name = this.Name;
|
|
67
|
-
reportVersion.Description = this.Description;
|
|
68
|
-
reportVersion.VersionNumber = newVersionNumber;
|
|
69
|
-
reportVersion.Configuration = JSON.stringify(this.Configuration);
|
|
70
|
-
success = success && await reportVersion.Save();
|
|
71
|
-
if (!success) {
|
|
72
|
-
console.error('ReportEntity_Server.Save(): Error saving report version\n' + reportVersion.LatestResult.Message);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (createSnapshot) {
|
|
76
|
-
const snapshot = await md.GetEntityObject('Report Snapshots', this.ContextCurrentUser);
|
|
77
|
-
snapshot.ReportID = this.ID;
|
|
78
|
-
snapshot.UserID = this.ContextCurrentUser.ID;
|
|
79
|
-
snapshot.ResultSet = JSON.stringify(this.Configuration);
|
|
80
|
-
success = success && await snapshot.Save();
|
|
81
|
-
}
|
|
82
|
-
return success;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
return saveResult;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
return super.Save();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
console.error('Error in ReportEntity_Server.Save():', e);
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
ReportEntity_Server = __decorate([
|
|
99
|
-
RegisterClass(BaseEntity, 'Reports')
|
|
100
|
-
], ReportEntity_Server);
|
|
101
|
-
export { ReportEntity_Server };
|
|
102
|
-
export function LoadReportEntityServerSubClass() { }
|
|
103
|
-
//# sourceMappingURL=reportEntity.server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reportEntity.server.js","sourceRoot":"","sources":["../../src/entitySubclasses/reportEntity.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { EntityInfo } from "@memberjunction/core";
|
|
2
|
-
import { AIModelEntityExtended, UserViewEntityExtended } from '@memberjunction/core-entities';
|
|
3
|
-
export declare class UserViewEntity_Server extends UserViewEntityExtended {
|
|
4
|
-
protected get SmartFilterImplemented(): boolean;
|
|
5
|
-
protected get AIVendorName(): string;
|
|
6
|
-
protected GetAIModel(): Promise<AIModelEntityExtended>;
|
|
7
|
-
GenerateSmartFilterWhereClause(prompt: string, entityInfo: EntityInfo): Promise<{
|
|
8
|
-
whereClause: string;
|
|
9
|
-
userExplanation: string;
|
|
10
|
-
}>;
|
|
11
|
-
GenerateSysPrompt(entityInfo: EntityInfo): string;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=userViewEntity.server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"userViewEntity.server.d.ts","sourceRoot":"","sources":["../../src/entitySubclasses/userViewEntity.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,UAAU,EAAsB,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAiB,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AAM5G,qBACa,qBAAsB,SAAQ,sBAAsB;IAI7D,cAAuB,sBAAsB,IAAI,OAAO,CAEvD;IAMD,SAAS,KAAK,YAAY,IAAI,MAAM,CAEnC;cAMe,UAAU,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAc/C,8BAA8B,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAC,CAAC;IAuErI,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;CAoH3D"}
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { CleanJSON, MJGlobal, RegisterClass } from "@memberjunction/global";
|
|
8
|
-
import { BaseEntity, LogError, Metadata } from "@memberjunction/core";
|
|
9
|
-
import { UserViewEntityExtended } from '@memberjunction/core-entities';
|
|
10
|
-
import { BaseLLM, GetAIAPIKey } from "@memberjunction/ai";
|
|
11
|
-
import { AIEngine } from "@memberjunction/aiengine";
|
|
12
|
-
import { LoadOpenAILLM } from "@memberjunction/ai-openai";
|
|
13
|
-
LoadOpenAILLM();
|
|
14
|
-
let UserViewEntity_Server = class UserViewEntity_Server extends UserViewEntityExtended {
|
|
15
|
-
get SmartFilterImplemented() {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
get AIVendorName() {
|
|
19
|
-
return 'OpenAI';
|
|
20
|
-
}
|
|
21
|
-
async GetAIModel() {
|
|
22
|
-
await AIEngine.Instance.Config(false, this.ContextCurrentUser);
|
|
23
|
-
const models = AIEngine.Instance.Models.filter(m => m.AIModelType.trim().toLowerCase() === 'llm' &&
|
|
24
|
-
m.Vendor.trim().toLowerCase() === this.AIVendorName.trim().toLowerCase());
|
|
25
|
-
models.sort((a, b) => b.PowerRank - a.PowerRank);
|
|
26
|
-
return models[0];
|
|
27
|
-
}
|
|
28
|
-
async GenerateSmartFilterWhereClause(prompt, entityInfo) {
|
|
29
|
-
try {
|
|
30
|
-
const model = await this.GetAIModel();
|
|
31
|
-
const llm = MJGlobal.Instance.ClassFactory.CreateInstance(BaseLLM, model.DriverClass, GetAIAPIKey(model.DriverClass));
|
|
32
|
-
const chatParams = {
|
|
33
|
-
model: model.APINameOrName,
|
|
34
|
-
messages: [
|
|
35
|
-
{
|
|
36
|
-
role: 'system',
|
|
37
|
-
content: this.GenerateSysPrompt(entityInfo)
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
role: 'user',
|
|
41
|
-
content: `${prompt}`,
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
const result = await llm.ChatCompletion(chatParams);
|
|
46
|
-
if (result && result.data) {
|
|
47
|
-
const llmResponse = result.data.choices[0].message.content;
|
|
48
|
-
if (llmResponse) {
|
|
49
|
-
try {
|
|
50
|
-
const cleansed = CleanJSON(llmResponse);
|
|
51
|
-
if (!cleansed)
|
|
52
|
-
throw new Error('Invalid JSON response from AI: ' + llmResponse);
|
|
53
|
-
const parsed = JSON.parse(cleansed);
|
|
54
|
-
if (parsed.whereClause && parsed.whereClause.length > 0) {
|
|
55
|
-
const trimmed = parsed.whereClause.trim();
|
|
56
|
-
let ret = '';
|
|
57
|
-
if (trimmed.toLowerCase().startsWith('where '))
|
|
58
|
-
ret = trimmed.substring(6);
|
|
59
|
-
else
|
|
60
|
-
ret = parsed.whereClause;
|
|
61
|
-
return {
|
|
62
|
-
whereClause: ret,
|
|
63
|
-
userExplanation: parsed.userExplanationMessage
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
else if (parsed.whereClause !== undefined && parsed.whereClause !== null) {
|
|
67
|
-
return {
|
|
68
|
-
whereClause: '',
|
|
69
|
-
userExplanation: parsed.userExplanationMessage
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
throw new Error('Invalid response from AI, no whereClause property found in response: ' + llmResponse);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch (e) {
|
|
77
|
-
LogError(e);
|
|
78
|
-
throw new Error('Error parsing JSON response from AI: ' + llmResponse);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
else
|
|
82
|
-
throw new Error('Null response from AI');
|
|
83
|
-
}
|
|
84
|
-
else
|
|
85
|
-
throw new Error('No result returned from AI');
|
|
86
|
-
}
|
|
87
|
-
catch (e) {
|
|
88
|
-
LogError(e);
|
|
89
|
-
throw e;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
GenerateSysPrompt(entityInfo) {
|
|
93
|
-
const processedViews = [entityInfo.BaseView];
|
|
94
|
-
const md = new Metadata();
|
|
95
|
-
const listsEntity = md.EntityByName("Lists");
|
|
96
|
-
const listDetailsEntity = md.EntityByName("List Details");
|
|
97
|
-
const gptSysPrompt = `You are an expert in SQL and Microsoft SQL Server.
|
|
98
|
-
You will be provided a user prompt representing how they want to filter the data.
|
|
99
|
-
You may *NOT* use JOINS, only sub-queries for related tables.
|
|
100
|
-
|
|
101
|
-
I am a bot and can only understand JSON. Your response must be parsable into this type:
|
|
102
|
-
const returnType = {
|
|
103
|
-
whereClause: string,
|
|
104
|
-
orderByClause: string
|
|
105
|
-
userExplanationMessage: string
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
In MemberJunction, we have a concept called "Entities" and these are metadata constructs that wrap SQL tables and views. The entity that we are currently
|
|
109
|
-
building a filter for is called "${entityInfo.Name}" and has an ID of "${entityInfo.ID}"
|
|
110
|
-
|
|
111
|
-
You won't be using this Entity name or ID in your SQL, unless you need to use it for List filtering (more on that below).
|
|
112
|
-
|
|
113
|
-
The view that the user is querying is called ${entityInfo.BaseView} and has these fields:
|
|
114
|
-
${entityInfo.Fields.map(f => {
|
|
115
|
-
let ret = `${f.Name} (${f.Type})`;
|
|
116
|
-
if (f.RelatedEntity) {
|
|
117
|
-
ret += ` (fkey to ${f.RelatedEntityBaseView})`;
|
|
118
|
-
}
|
|
119
|
-
return ret;
|
|
120
|
-
}).join(',')}`;
|
|
121
|
-
const fkeyFields = entityInfo.Fields.filter(f => f.RelatedEntity && f.RelatedEntity.length > 0);
|
|
122
|
-
const fkeyBaseViewsDistinct = fkeyFields.map(f => f.RelatedEntityBaseView).filter((v, i, a) => a.indexOf(v) === i);
|
|
123
|
-
const relationships = `
|
|
124
|
-
In addition, ${entityInfo.BaseView} has links to other views, as shown here, you can use these views in sub-queries to achieve the request from the user.
|
|
125
|
-
If there are multiple filters related to a single related view, attempt to combine them into a single sub-query for efficiency.
|
|
126
|
-
${fkeyBaseViewsDistinct.map(v => {
|
|
127
|
-
if (processedViews.indexOf(v) === -1) {
|
|
128
|
-
const e = md.Entities.find(e => e.BaseView === v);
|
|
129
|
-
if (e) {
|
|
130
|
-
processedViews.push(v);
|
|
131
|
-
return `* ${e.SchemaName}.${e.BaseView}: ${e.Fields.map(ef => {
|
|
132
|
-
return ef.Name + ' (' + ef.Type + ')';
|
|
133
|
-
}).join(',')}`;
|
|
134
|
-
}
|
|
135
|
-
else
|
|
136
|
-
return '';
|
|
137
|
-
}
|
|
138
|
-
else
|
|
139
|
-
return '';
|
|
140
|
-
}).join('\n')}
|
|
141
|
-
${entityInfo.RelatedEntities.map(r => {
|
|
142
|
-
const e = md.Entities.find(e => e.Name === r.RelatedEntity);
|
|
143
|
-
if (e) {
|
|
144
|
-
if (processedViews.indexOf(e.BaseView) === -1) {
|
|
145
|
-
processedViews.push(e.BaseView);
|
|
146
|
-
return `* ${e.SchemaName}.${e.BaseView}: ${e.Fields.map(ef => {
|
|
147
|
-
let ret = `${ef.Name} (${ef.Type})`;
|
|
148
|
-
if (ef.RelatedEntity) {
|
|
149
|
-
ret += ` (fkey to ${ef.RelatedEntityBaseView})`;
|
|
150
|
-
}
|
|
151
|
-
return ret;
|
|
152
|
-
}).join(',')}`;
|
|
153
|
-
}
|
|
154
|
-
else
|
|
155
|
-
return '';
|
|
156
|
-
}
|
|
157
|
-
else
|
|
158
|
-
return '';
|
|
159
|
-
}).join('\n')}
|
|
160
|
-
|
|
161
|
-
<IMPORTANT - LISTS FEATURE>
|
|
162
|
-
In addition to the above related views, a user may talk about "Lists" in their request. A List is a static set of records modeled in our database with the ${listsEntity.SchemaName}.vwLists view and
|
|
163
|
-
the ${listsEntity.SchemaName}.vwListDetails view. ${listsEntity.SchemaName}.vwLists contains the list "header" information with these columns:
|
|
164
|
-
${listsEntity.Fields.map(f => {
|
|
165
|
-
return f.Name + ' (' + f.SQLFullType + ')';
|
|
166
|
-
}).join(', ')}
|
|
167
|
-
The vwListDetails view contains the list "detail" information with these columns which is basically the records that are part of the list. ${listsEntity.SchemaName}.vwListDetails contains these columns:
|
|
168
|
-
${listDetailsEntity.Fields.map(f => {
|
|
169
|
-
return f.Name + ' (' + f.SQLFullType + ')';
|
|
170
|
-
}).join(', ')}.
|
|
171
|
-
|
|
172
|
-
If a user is asking to use a list in creating a view, you need to use a sub-query along these lines:
|
|
173
|
-
|
|
174
|
-
ID IN (SELECT RecordID FROM ${listsEntity.SchemaName}.vwListDetails WHERE ListID='My List ID')
|
|
175
|
-
|
|
176
|
-
In this example we're assuming the user has asked us to filter to include only records that are part of the list with the ID of 'My List ID'. In reality the prompt you will have will have a UUID/GUID type ID not a text string like this.
|
|
177
|
-
You can use any fields at the detail level filter the records and of course combine this type of list-oriented sub-query with other filters as appropriate to satisfy the user's request.
|
|
178
|
-
|
|
179
|
-
It is also possible that a user will provide ONLY the name of the list they want to filter on. If they provide the List ID, use it with a query like the above. However, if ONLY a List name is provided, you can do as follows: use this style of query with a join to the vwLists view (the list "header") to filter on the name
|
|
180
|
-
of the view or other header information if they want to filter on other list header attributes you can do this. Here is an example:
|
|
181
|
-
|
|
182
|
-
ID IN (SELECT ld.RecordID FROM ${listsEntity.SchemaName}.vwListDetails ld INNER JOIN ${listsEntity.SchemaName}.vwLists l ON ld.ListID=l.ID WHERE l.Name='My List Name')
|
|
183
|
-
|
|
184
|
-
No need to use table aliasing if you're just using the vwListDetails view, in that simple subquery it is automatic and unnecessary. If you need to join to the vwLists view, you can use the aliases "l" and "ld", as shown in the example above.
|
|
185
|
-
|
|
186
|
-
</IMPORTANT - LISTS FEATURE>
|
|
187
|
-
<IMPORTANT - OTHER VIEWS>
|
|
188
|
-
The user might reference other "views" in their request. In the user's terminology a view is what we call a "User View" in MemberJunction system-speak. The idea is a user might ask for a filter that includes or excludes
|
|
189
|
-
records from another view. Unlike Lists, which are STATIC sets of records, User Views are dynamic and can change based on the underlying data. So, what we need to do is use a sub-query that pulls in the SQL for the other view
|
|
190
|
-
The user will be referring to the other view by name, so what you need to do when generating SQL for this scenario is to simply embed a sub-query along the lines of this example, updated of course in the context of the user's request and the rest of any filters you are building:
|
|
191
|
-
ID IN ({%UserView "ViewID"%}) -- this is for filtering the primary key using other User Views for this entity: "${entityInfo.Name}"
|
|
192
|
-
AccountID IN ({%UserView "ViewID"%}) -- this is an example where the foreign key relationship for the AccountID field in this entity (${entityInfo.Name}) links to another entity hypothetically called "Accounts" and we want to use an Accounts view for filtering in some way
|
|
193
|
-
By including this sub-query in your generated WHERE clause, it will give me what I need to dynamically replace the {%UserView "View Name"%} with the actual SQL for the view that the user is referring to. Since that actual SQL
|
|
194
|
-
can change over time, I don't want to embed it directly here but rather have it templatized and each time it is run, I will pre-process the SQL to replace the template with the actual SQL for the view.
|
|
195
|
-
</IMPORTANT - OTHER VIEWS>
|
|
196
|
-
`;
|
|
197
|
-
return gptSysPrompt + (processedViews.length > 1 ? relationships : '') + `
|
|
198
|
-
**** REMEMBER **** I am a BOT, do not return anything other than JSON to me or I will choke on your response!`;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
UserViewEntity_Server = __decorate([
|
|
202
|
-
RegisterClass(BaseEntity, 'User Views')
|
|
203
|
-
], UserViewEntity_Server);
|
|
204
|
-
export { UserViewEntity_Server };
|
|
205
|
-
//# sourceMappingURL=userViewEntity.server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"userViewEntity.server.js","sourceRoot":"","sources":["../../src/entitySubclasses/userViewEntity.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { BaseEntity, PotentialDuplicateRequest } from "@memberjunction/core";
|
|
2
|
-
import { RegisterClass } from "@memberjunction/global";
|
|
3
|
-
import { DuplicateRunEntity } from "@memberjunction/core-entities";
|
|
4
|
-
import { DuplicateRecordDetector } from "@memberjunction/ai-vector-dupe";
|
|
5
|
-
|
|
6
|
-
@RegisterClass(BaseEntity, 'Duplicate Runs')
|
|
7
|
-
export class DuplicateRunEntity_Server extends DuplicateRunEntity {
|
|
8
|
-
public async Save(): Promise<boolean> {
|
|
9
|
-
const saveResult: boolean = await super.Save();
|
|
10
|
-
if (saveResult && this.EndedAt === null) {
|
|
11
|
-
// do something
|
|
12
|
-
const duplicateRecordDetector: DuplicateRecordDetector = new DuplicateRecordDetector();
|
|
13
|
-
let request: PotentialDuplicateRequest = new PotentialDuplicateRequest();
|
|
14
|
-
request.EntityID = this.EntityID;
|
|
15
|
-
request.ListID = this.SourceListID;
|
|
16
|
-
request.Options = {
|
|
17
|
-
DuplicateRunID: this.ID,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const response = await duplicateRecordDetector.getDuplicateRecords(request, this.ContextCurrentUser);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return saveResult;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function LoadDuplicateRunEntityServerSubClass() {}
|