@memberjunction/server 6.1.0-edge.1 → 6.1.0-edge.2
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/auth/exampleNewUserSubClass.js +1 -1
- package/dist/auth/exampleNewUserSubClass.js.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +9 -5
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +1 -1
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/newUsers.js +1 -1
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/context.js +2 -2
- package/dist/context.js.map +1 -1
- package/dist/generated/generated.d.ts +45 -4
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +229 -21
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +19 -3
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +51 -17
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +85 -41
- package/dist/index.js.map +1 -1
- package/dist/logging/secretRedactor.d.ts +9 -0
- package/dist/logging/secretRedactor.d.ts.map +1 -1
- package/dist/logging/secretRedactor.js +39 -0
- package/dist/logging/secretRedactor.js.map +1 -1
- package/dist/middleware/BaseServerMiddleware.d.ts +5 -0
- package/dist/middleware/BaseServerMiddleware.d.ts.map +1 -1
- package/dist/middleware/BaseServerMiddleware.js +5 -0
- package/dist/middleware/BaseServerMiddleware.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +12 -0
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.js +1 -1
- package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
- package/dist/resolvers/EntityPermissionResolver.js +1 -1
- package/dist/resolvers/EntityPermissionResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +9 -0
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +3 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +10 -0
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +5 -0
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/SearchEntitiesResolver.js +1 -1
- package/dist/resolvers/SearchEntitiesResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +2 -2
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +1 -1
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +1 -1
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/SignatureWebhookHandler.js +1 -1
- package/dist/rest/SignatureWebhookHandler.js.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.d.ts +26 -0
- package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -0
- package/dist/services/DurableEntityActionTaskSubmitter.js +55 -0
- package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -0
- package/dist/services/ScheduledJobsService.js +1 -1
- package/dist/services/ScheduledJobsService.js.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.d.ts.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.js +16 -1
- package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +34 -0
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -0
- package/dist/services/TaskGraphActionRunner.js +95 -0
- package/dist/services/TaskGraphActionRunner.js.map +1 -0
- package/dist/services/TaskGraphAgentRunner.d.ts +13 -0
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +30 -0
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphPromptRunner.d.ts +31 -0
- package/dist/services/TaskGraphPromptRunner.d.ts.map +1 -0
- package/dist/services/TaskGraphPromptRunner.js +134 -0
- package/dist/services/TaskGraphPromptRunner.js.map +1 -0
- package/dist/telephony/RingCentralTelephonyService.js +1 -1
- package/dist/telephony/RingCentralTelephonyService.js.map +1 -1
- package/dist/telephony/TwilioTelephonyRouter.js +1 -1
- package/dist/telephony/TwilioTelephonyRouter.js.map +1 -1
- package/dist/telephony/VonageTelephonyRouter.js +1 -1
- package/dist/telephony/VonageTelephonyRouter.js.map +1 -1
- package/package.json +90 -90
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +1 -1
- package/src/__tests__/ResolverBase.frozenRecordMapping.test.ts +133 -0
- package/src/__tests__/ResolverBase.transportMapping.test.ts +289 -0
- package/src/__tests__/SessionManager.test.ts +1 -1
- package/src/__tests__/WidgetSessionService.test.ts +1 -1
- package/src/__tests__/databaseAbstraction.test.ts +1 -1
- package/src/__tests__/magicLinkService.provisionLog.test.ts +1 -1
- package/src/__tests__/resolverBase.rls.test.ts +3 -0
- package/src/__tests__/secretRedactor.failOpen.test.ts +135 -0
- package/src/__tests__/widgetGuestElevation.test.ts +1 -1
- package/src/auth/exampleNewUserSubClass.ts +1 -1
- package/src/auth/index.ts +10 -6
- package/src/auth/magicLink/MagicLinkService.ts +1 -1
- package/src/auth/newUsers.ts +1 -1
- package/src/context.ts +2 -2
- package/src/generated/generated.ts +166 -17
- package/src/generic/ResolverBase.ts +52 -17
- package/src/index.ts +92 -42
- package/src/logging/secretRedactor.ts +43 -0
- package/src/middleware/BaseServerMiddleware.ts +5 -0
- package/src/realtimeWidget/WidgetSessionService.ts +1 -1
- package/src/realtimeWidget/widgetGuestElevation.ts +1 -1
- package/src/resolvers/ActionResolver.ts +13 -0
- package/src/resolvers/ComponentRegistryResolver.ts +1 -1
- package/src/resolvers/EntityPermissionResolver.ts +1 -1
- package/src/resolvers/IntegrationDiscoveryResolver.ts +12 -2
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +1 -1
- package/src/resolvers/RealtimeClientSessionResolver.ts +13 -0
- package/src/resolvers/SearchEntitiesResolver.ts +1 -1
- package/src/resolvers/SqlLoggingConfigResolver.ts +1 -2
- package/src/resolvers/SyncRolesUsersResolver.ts +2 -2
- package/src/resolvers/UserFavoriteResolver.ts +1 -1
- package/src/rest/OAuthCallbackHandler.ts +1 -1
- package/src/rest/SignatureWebhookHandler.ts +1 -1
- package/src/services/DurableEntityActionTaskSubmitter.ts +78 -0
- package/src/services/ScheduledJobsService.ts +1 -1
- package/src/services/StartTaskGraphDispatcher.ts +17 -0
- package/src/services/TaskGraphActionRunner.ts +99 -0
- package/src/services/TaskGraphAgentRunner.ts +35 -1
- package/src/services/TaskGraphPromptRunner.ts +144 -0
- package/src/telephony/RingCentralTelephonyService.ts +1 -1
- package/src/telephony/TwilioTelephonyRouter.ts +1 -1
- package/src/telephony/VonageTelephonyRouter.ts +1 -1
|
@@ -1050,10 +1050,6 @@ export class MJActionExecutionLog_ {
|
|
|
1050
1050
|
@MaxLength(100)
|
|
1051
1051
|
User: string;
|
|
1052
1052
|
|
|
1053
|
-
@Field({nullable: true})
|
|
1054
|
-
@MaxLength(425)
|
|
1055
|
-
EntityAction?: string;
|
|
1056
|
-
|
|
1057
1053
|
@Field({nullable: true})
|
|
1058
1054
|
@MaxLength(255)
|
|
1059
1055
|
EntityActionInvocationType?: string;
|
|
@@ -2207,6 +2203,9 @@ export class MJAction_ {
|
|
|
2207
2203
|
@Field(() => [MJAISkillAction_])
|
|
2208
2204
|
MJAISkillActions_ActionIDArray: MJAISkillAction_[]; // Link to MJAISkillActions
|
|
2209
2205
|
|
|
2206
|
+
@Field(() => [MJTask_])
|
|
2207
|
+
MJTasks_ActionIDArray: MJTask_[]; // Link to MJTasks
|
|
2208
|
+
|
|
2210
2209
|
}
|
|
2211
2210
|
|
|
2212
2211
|
//****************************************************************************
|
|
@@ -2568,6 +2567,16 @@ export class MJActionResolver extends ResolverBase {
|
|
|
2568
2567
|
return result;
|
|
2569
2568
|
}
|
|
2570
2569
|
|
|
2570
|
+
@FieldResolver(() => [MJTask_])
|
|
2571
|
+
async MJTasks_ActionIDArray(@Root() mjaction_: MJAction_, @Ctx() { userPayload, providers }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
2572
|
+
this.CheckUserReadPermissions('MJ: Tasks', userPayload);
|
|
2573
|
+
const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
|
|
2574
|
+
const sSQL = `SELECT * FROM ${provider.QuoteSchemaAndView(Metadata.Provider.ConfigData.MJCoreSchemaName, 'vwTasks')} WHERE ${provider.QuoteIdentifier('ActionID')}=${provider.BuildParameterPlaceholder(0)} ` + this.getRowLevelSecurityWhereClause(provider, 'MJ: Tasks', userPayload, EntityPermissionType.Read, 'AND');
|
|
2575
|
+
const rows = await provider.ExecuteSQL(sSQL, [mjaction_.ID], undefined, this.GetUserFromPayload(userPayload));
|
|
2576
|
+
const result = await this.ArrayMapFieldNamesToCodeNames('MJ: Tasks', rows, this.GetUserFromPayload(userPayload));
|
|
2577
|
+
return result;
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2571
2580
|
@Mutation(() => MJAction_)
|
|
2572
2581
|
async CreateMJAction(
|
|
2573
2582
|
@Arg('input', () => CreateMJActionInput) input: CreateMJActionInput,
|
|
@@ -7525,6 +7534,10 @@ export class MJAIAgentRequest_ {
|
|
|
7525
7534
|
@MaxLength(20)
|
|
7526
7535
|
ResponseSource?: string;
|
|
7527
7536
|
|
|
7537
|
+
@Field({nullable: true, description: `The workflow step (MJ: Tasks row) waiting on this request, when it came from a task graph rather than from a running agent. Distinct from OriginatingAgentRunStepID: a task graph outlives the agent run that submitted it, so the task — not the run — is what resumes when a person answers. NULL for requests raised by a run directly.`})
|
|
7538
|
+
@MaxLength(36)
|
|
7539
|
+
OriginatingTaskID?: string;
|
|
7540
|
+
|
|
7528
7541
|
@Field({nullable: true})
|
|
7529
7542
|
@MaxLength(255)
|
|
7530
7543
|
Agent?: string;
|
|
@@ -7553,6 +7566,10 @@ export class MJAIAgentRequest_ {
|
|
|
7553
7566
|
@MaxLength(255)
|
|
7554
7567
|
ResumingAgentRun?: string;
|
|
7555
7568
|
|
|
7569
|
+
@Field({nullable: true})
|
|
7570
|
+
@MaxLength(255)
|
|
7571
|
+
OriginatingTask?: string;
|
|
7572
|
+
|
|
7556
7573
|
}
|
|
7557
7574
|
|
|
7558
7575
|
//****************************************************************************
|
|
@@ -7617,6 +7634,9 @@ export class CreateMJAIAgentRequestInput {
|
|
|
7617
7634
|
@Field({ nullable: true })
|
|
7618
7635
|
ResponseSource: string | null;
|
|
7619
7636
|
|
|
7637
|
+
@Field({ nullable: true })
|
|
7638
|
+
OriginatingTaskID: string | null;
|
|
7639
|
+
|
|
7620
7640
|
@Field(() => RestoreContextInput, { nullable: true })
|
|
7621
7641
|
RestoreContext___?: RestoreContextInput;
|
|
7622
7642
|
}
|
|
@@ -7684,6 +7704,9 @@ export class UpdateMJAIAgentRequestInput {
|
|
|
7684
7704
|
@Field({ nullable: true })
|
|
7685
7705
|
ResponseSource?: string | null;
|
|
7686
7706
|
|
|
7707
|
+
@Field({ nullable: true })
|
|
7708
|
+
OriginatingTaskID?: string | null;
|
|
7709
|
+
|
|
7687
7710
|
@Field(() => [KeyValuePairInput], { nullable: true })
|
|
7688
7711
|
OldValues___?: KeyValuePairInput[];
|
|
7689
7712
|
|
|
@@ -16507,6 +16530,9 @@ export class MJAIModelType_ {
|
|
|
16507
16530
|
@Field({nullable: true, description: `Default fallback instruction text used when PrefillFallbackMode is SystemInstruction and the provider does not support native prefill. Use {{prefill}} as a placeholder for the actual prefill text. Example: "IMPORTANT: You must begin your response with exactly: {{prefill}}". Individual AI Model Vendor records can override this. If null, a generic fallback is used.`})
|
|
16508
16531
|
PrefillFallbackText?: string;
|
|
16509
16532
|
|
|
16533
|
+
@Field({nullable: true, description: `Type-wide default of the per-modality model-configuration bag (JSON, IAIModelConfiguration shape: LLM / Realtime / Vision / Audio sections). Base layer of the ModelConfiguration cascade — AIModel and AIModelVendor rows inherit from it per key and may override. NULL = contributes nothing.`})
|
|
16534
|
+
ModelConfiguration?: string;
|
|
16535
|
+
|
|
16510
16536
|
@Field()
|
|
16511
16537
|
@MaxLength(50)
|
|
16512
16538
|
DefaultInputModality: string;
|
|
@@ -16549,6 +16575,9 @@ export class CreateMJAIModelTypeInput {
|
|
|
16549
16575
|
@Field({ nullable: true })
|
|
16550
16576
|
PrefillFallbackText: string | null;
|
|
16551
16577
|
|
|
16578
|
+
@Field({ nullable: true })
|
|
16579
|
+
ModelConfiguration: string | null;
|
|
16580
|
+
|
|
16552
16581
|
@Field(() => RestoreContextInput, { nullable: true })
|
|
16553
16582
|
RestoreContext___?: RestoreContextInput;
|
|
16554
16583
|
}
|
|
@@ -16580,6 +16609,9 @@ export class UpdateMJAIModelTypeInput {
|
|
|
16580
16609
|
@Field({ nullable: true })
|
|
16581
16610
|
PrefillFallbackText?: string | null;
|
|
16582
16611
|
|
|
16612
|
+
@Field({ nullable: true })
|
|
16613
|
+
ModelConfiguration?: string | null;
|
|
16614
|
+
|
|
16583
16615
|
@Field(() => [KeyValuePairInput], { nullable: true })
|
|
16584
16616
|
OldValues___?: KeyValuePairInput[];
|
|
16585
16617
|
|
|
@@ -16771,6 +16803,9 @@ export class MJAIModelVendor_ {
|
|
|
16771
16803
|
@Field({nullable: true, description: `Model-specific fallback instruction text used when PrefillFallbackMode is SystemInstruction and the provider does not support native prefill. Overrides the AI Model Type default. Use {{prefill}} as a placeholder. Allows tuning the fallback instruction per model since different models respond better to different phrasing.`})
|
|
16772
16804
|
PrefillFallbackText?: string;
|
|
16773
16805
|
|
|
16806
|
+
@Field({nullable: true, description: `Most-specific layer of the per-modality model-configuration bag (JSON, IAIModelConfiguration shape) — configuration for THIS model on THIS provider. Deep-merges per key over the model and type layers. NULL = inherit the merged model/type configuration unchanged.`})
|
|
16807
|
+
ModelConfiguration?: string;
|
|
16808
|
+
|
|
16774
16809
|
@Field()
|
|
16775
16810
|
@MaxLength(50)
|
|
16776
16811
|
Model: string;
|
|
@@ -16841,6 +16876,9 @@ export class CreateMJAIModelVendorInput {
|
|
|
16841
16876
|
@Field({ nullable: true })
|
|
16842
16877
|
PrefillFallbackText: string | null;
|
|
16843
16878
|
|
|
16879
|
+
@Field({ nullable: true })
|
|
16880
|
+
ModelConfiguration: string | null;
|
|
16881
|
+
|
|
16844
16882
|
@Field(() => RestoreContextInput, { nullable: true })
|
|
16845
16883
|
RestoreContext___?: RestoreContextInput;
|
|
16846
16884
|
}
|
|
@@ -16899,6 +16937,9 @@ export class UpdateMJAIModelVendorInput {
|
|
|
16899
16937
|
@Field({ nullable: true })
|
|
16900
16938
|
PrefillFallbackText?: string | null;
|
|
16901
16939
|
|
|
16940
|
+
@Field({ nullable: true })
|
|
16941
|
+
ModelConfiguration?: string | null;
|
|
16942
|
+
|
|
16902
16943
|
@Field(() => [KeyValuePairInput], { nullable: true })
|
|
16903
16944
|
OldValues___?: KeyValuePairInput[];
|
|
16904
16945
|
|
|
@@ -17056,6 +17097,9 @@ export class MJAIModel_ {
|
|
|
17056
17097
|
@Field({nullable: true, description: `Model-level fallback instruction text used when PrefillFallbackMode is SystemInstruction and the provider does not support native prefill. Overrides the AI Model Type default, can be further overridden per-vendor in AI Model Vendor. Use {{prefill}} as a placeholder.`})
|
|
17057
17098
|
PrefillFallbackText?: string;
|
|
17058
17099
|
|
|
17100
|
+
@Field({nullable: true, description: `Per-model layer of the per-modality model-configuration bag (JSON, IAIModelConfiguration shape). Deep-merges per key over the AIModelType default; AIModelVendor rows may override per key on top. NULL = inherit the type default unchanged.`})
|
|
17101
|
+
ModelConfiguration?: string;
|
|
17102
|
+
|
|
17059
17103
|
@Field()
|
|
17060
17104
|
@MaxLength(50)
|
|
17061
17105
|
AIModelType: string;
|
|
@@ -17213,6 +17257,9 @@ export class CreateMJAIModelInput {
|
|
|
17213
17257
|
@Field({ nullable: true })
|
|
17214
17258
|
PrefillFallbackText: string | null;
|
|
17215
17259
|
|
|
17260
|
+
@Field({ nullable: true })
|
|
17261
|
+
ModelConfiguration: string | null;
|
|
17262
|
+
|
|
17216
17263
|
@Field({ nullable: true })
|
|
17217
17264
|
Vendor: string | null;
|
|
17218
17265
|
|
|
@@ -17283,6 +17330,9 @@ export class UpdateMJAIModelInput {
|
|
|
17283
17330
|
@Field({ nullable: true })
|
|
17284
17331
|
PrefillFallbackText?: string | null;
|
|
17285
17332
|
|
|
17333
|
+
@Field({ nullable: true })
|
|
17334
|
+
ModelConfiguration?: string | null;
|
|
17335
|
+
|
|
17286
17336
|
@Field({ nullable: true })
|
|
17287
17337
|
Vendor?: string | null;
|
|
17288
17338
|
|
|
@@ -19961,6 +20011,9 @@ export class MJAIPrompt_ {
|
|
|
19961
20011
|
@Field(() => [MJAIAgentType_])
|
|
19962
20012
|
MJAIAgentTypes_ConversationSummaryPromptIDArray: MJAIAgentType_[]; // Link to MJAIAgentTypes
|
|
19963
20013
|
|
|
20014
|
+
@Field(() => [MJTask_])
|
|
20015
|
+
MJTasks_PromptIDArray: MJTask_[]; // Link to MJTasks
|
|
20016
|
+
|
|
19964
20017
|
}
|
|
19965
20018
|
|
|
19966
20019
|
//****************************************************************************
|
|
@@ -20564,6 +20617,16 @@ export class MJAIPromptResolver extends ResolverBase {
|
|
|
20564
20617
|
return result;
|
|
20565
20618
|
}
|
|
20566
20619
|
|
|
20620
|
+
@FieldResolver(() => [MJTask_])
|
|
20621
|
+
async MJTasks_PromptIDArray(@Root() mjaiprompt_: MJAIPrompt_, @Ctx() { userPayload, providers }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
20622
|
+
this.CheckUserReadPermissions('MJ: Tasks', userPayload);
|
|
20623
|
+
const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
|
|
20624
|
+
const sSQL = `SELECT * FROM ${provider.QuoteSchemaAndView(Metadata.Provider.ConfigData.MJCoreSchemaName, 'vwTasks')} WHERE ${provider.QuoteIdentifier('PromptID')}=${provider.BuildParameterPlaceholder(0)} ` + this.getRowLevelSecurityWhereClause(provider, 'MJ: Tasks', userPayload, EntityPermissionType.Read, 'AND');
|
|
20625
|
+
const rows = await provider.ExecuteSQL(sSQL, [mjaiprompt_.ID], undefined, this.GetUserFromPayload(userPayload));
|
|
20626
|
+
const result = await this.ArrayMapFieldNamesToCodeNames('MJ: Tasks', rows, this.GetUserFromPayload(userPayload));
|
|
20627
|
+
return result;
|
|
20628
|
+
}
|
|
20629
|
+
|
|
20567
20630
|
@Mutation(() => MJAIPrompt_)
|
|
20568
20631
|
async CreateMJAIPrompt(
|
|
20569
20632
|
@Arg('input', () => CreateMJAIPromptInput) input: CreateMJAIPromptInput,
|
|
@@ -48584,10 +48647,6 @@ export class MJEntityActionFilter_ {
|
|
|
48584
48647
|
@Field()
|
|
48585
48648
|
_mj__UpdatedAt: Date;
|
|
48586
48649
|
|
|
48587
|
-
@Field()
|
|
48588
|
-
@MaxLength(425)
|
|
48589
|
-
EntityAction: string;
|
|
48590
|
-
|
|
48591
48650
|
@Field()
|
|
48592
48651
|
ActionFilter: string;
|
|
48593
48652
|
|
|
@@ -48947,10 +49006,6 @@ export class MJEntityActionInvocation_ {
|
|
|
48947
49006
|
@MaxLength(255)
|
|
48948
49007
|
RuntimeUXDriverClass?: string;
|
|
48949
49008
|
|
|
48950
|
-
@Field()
|
|
48951
|
-
@MaxLength(425)
|
|
48952
|
-
EntityAction: string;
|
|
48953
|
-
|
|
48954
49009
|
@Field()
|
|
48955
49010
|
@MaxLength(255)
|
|
48956
49011
|
InvocationType: string;
|
|
@@ -49131,10 +49186,6 @@ export class MJEntityActionParam_ {
|
|
|
49131
49186
|
@Field(() => Boolean, {nullable: true, description: `Optional per-binding override of ActionParam.LogValue. NULL (the default) inherits the parameter definition. Set to 0 when this particular binding passes something sensitive through a parameter that is ordinarily safe to log - a message body through a generic Text parameter, for instance. Cannot re-enable logging for a value type the hard rule suppresses.`})
|
|
49132
49187
|
LogValue?: boolean;
|
|
49133
49188
|
|
|
49134
|
-
@Field()
|
|
49135
|
-
@MaxLength(425)
|
|
49136
|
-
EntityAction: string;
|
|
49137
|
-
|
|
49138
49189
|
@Field()
|
|
49139
49190
|
@MaxLength(255)
|
|
49140
49191
|
ActionParam: string;
|
|
@@ -49333,6 +49384,10 @@ export class MJEntityAction_ {
|
|
|
49333
49384
|
@MaxLength(20)
|
|
49334
49385
|
LoggingMode: string;
|
|
49335
49386
|
|
|
49387
|
+
@Field({description: `How an After* dispatch of this binding executes. Inline (the default) runs it fire-and-forget in the saving process, which is fast but lost if that process dies. Durable submits a single-node task graph instead, so the work survives a restart and is reclaimed by the dispatcher — at the cost of a Task row, a dispatcher hop of latency, and the action's parameters being persisted (redacted) at rest. Ignored for Validate and Before* invocations, which run inside the save and cannot be deferred without changing whether the save succeeds.`})
|
|
49388
|
+
@MaxLength(20)
|
|
49389
|
+
RunMode: string;
|
|
49390
|
+
|
|
49336
49391
|
@Field()
|
|
49337
49392
|
@MaxLength(255)
|
|
49338
49393
|
Entity: string;
|
|
@@ -49388,6 +49443,9 @@ export class CreateMJEntityActionInput {
|
|
|
49388
49443
|
@Field({ nullable: true })
|
|
49389
49444
|
LoggingMode?: string;
|
|
49390
49445
|
|
|
49446
|
+
@Field({ nullable: true })
|
|
49447
|
+
RunMode?: string;
|
|
49448
|
+
|
|
49391
49449
|
@Field(() => RestoreContextInput, { nullable: true })
|
|
49392
49450
|
RestoreContext___?: RestoreContextInput;
|
|
49393
49451
|
}
|
|
@@ -49422,6 +49480,9 @@ export class UpdateMJEntityActionInput {
|
|
|
49422
49480
|
@Field({ nullable: true })
|
|
49423
49481
|
LoggingMode?: string;
|
|
49424
49482
|
|
|
49483
|
+
@Field({ nullable: true })
|
|
49484
|
+
RunMode?: string;
|
|
49485
|
+
|
|
49425
49486
|
@Field(() => [KeyValuePairInput], { nullable: true })
|
|
49426
49487
|
OldValues___?: KeyValuePairInput[];
|
|
49427
49488
|
|
|
@@ -84425,6 +84486,16 @@ export class MJTaskDependency_ {
|
|
|
84425
84486
|
@Field({nullable: true, description: `Optional boolean expression gating this dependency edge. NULL (the default, and the value every pre-existing row carries) means the edge is unconditional, so adding this column changes the meaning of no existing graph. When present it is evaluated by the shared GraphTraversalEngine against the same context a design-time AIAgentStepPath.Condition sees, which is what lets a runtime task graph and a flow-editor graph be the same graph. A condition that evaluates false skips the edge; one that fails to evaluate ALSO skips it, but is reported distinctly so a graph stalled by a malformed expression cannot be mistaken for one that finished normally.`})
|
|
84426
84487
|
Condition?: string;
|
|
84427
84488
|
|
|
84489
|
+
@Field(() => Int, {description: `Ordering within an exclusive group — higher wins. Mirrors AIAgentStepPath.Priority so a compiled workflow chooses the same branch the flow editor shows. Ignored for edges that are not part of an ExclusiveGroup.`})
|
|
84490
|
+
Priority: number;
|
|
84491
|
+
|
|
84492
|
+
@Field(() => Int, {description: `Deterministic tiebreak when two edges in an ExclusiveGroup share a Priority, applied ascending. Load-bearing rather than cosmetic: compiled dependencies get fresh UUIDs and Priority defaults to 0, so without a stored ordinal a tie would resolve by row order and the same workflow could take a different branch on a different machine.`})
|
|
84493
|
+
Sequence: number;
|
|
84494
|
+
|
|
84495
|
+
@Field({nullable: true, description: `XOR group key: sibling edges leaving the same origin that share a non-null ExclusiveGroup are an exclusive fan-out. The highest-Priority satisfied edge wins, ties broken by ascending Sequence; the rest are Skipped. NULL (the default) means an ordinary dependency, so existing graphs are unaffected. An unevaluable condition anywhere in the group holds the whole group rather than firing every branch.`})
|
|
84496
|
+
@MaxLength(255)
|
|
84497
|
+
ExclusiveGroup?: string;
|
|
84498
|
+
|
|
84428
84499
|
@Field()
|
|
84429
84500
|
@MaxLength(255)
|
|
84430
84501
|
Task: string;
|
|
@@ -84455,6 +84526,15 @@ export class CreateMJTaskDependencyInput {
|
|
|
84455
84526
|
@Field({ nullable: true })
|
|
84456
84527
|
Condition: string | null;
|
|
84457
84528
|
|
|
84529
|
+
@Field(() => Int, { nullable: true })
|
|
84530
|
+
Priority?: number;
|
|
84531
|
+
|
|
84532
|
+
@Field(() => Int, { nullable: true })
|
|
84533
|
+
Sequence?: number;
|
|
84534
|
+
|
|
84535
|
+
@Field({ nullable: true })
|
|
84536
|
+
ExclusiveGroup: string | null;
|
|
84537
|
+
|
|
84458
84538
|
@Field(() => RestoreContextInput, { nullable: true })
|
|
84459
84539
|
RestoreContext___?: RestoreContextInput;
|
|
84460
84540
|
}
|
|
@@ -84480,6 +84560,15 @@ export class UpdateMJTaskDependencyInput {
|
|
|
84480
84560
|
@Field({ nullable: true })
|
|
84481
84561
|
Condition?: string | null;
|
|
84482
84562
|
|
|
84563
|
+
@Field(() => Int, { nullable: true })
|
|
84564
|
+
Priority?: number;
|
|
84565
|
+
|
|
84566
|
+
@Field(() => Int, { nullable: true })
|
|
84567
|
+
Sequence?: number;
|
|
84568
|
+
|
|
84569
|
+
@Field({ nullable: true })
|
|
84570
|
+
ExclusiveGroup?: string | null;
|
|
84571
|
+
|
|
84483
84572
|
@Field(() => [KeyValuePairInput], { nullable: true })
|
|
84484
84573
|
OldValues___?: KeyValuePairInput[];
|
|
84485
84574
|
|
|
@@ -84780,7 +84869,7 @@ export class MJTask_ {
|
|
|
84780
84869
|
@MaxLength(36)
|
|
84781
84870
|
AgentID?: string;
|
|
84782
84871
|
|
|
84783
|
-
@Field({description: `
|
|
84872
|
+
@Field({description: `Lifecycle state. Pending awaits prerequisites; In Progress is claimed and running; Complete succeeded; Failed did not; Blocked can never run because a prerequisite is unsatisfiable; Cancelled was stopped deliberately; Deferred is waiting on a schedule. Skipped is a branch that was NOT TAKEN at an exclusive fan-out — a normal outcome, not a failure: it satisfies dependents (so a join downstream of a fork still runs) and is invisible to failure precedence when the parent rolls up.`})
|
|
84784
84873
|
@MaxLength(50)
|
|
84785
84874
|
Status: string;
|
|
84786
84875
|
|
|
@@ -84822,6 +84911,21 @@ export class MJTask_ {
|
|
|
84822
84911
|
@Field({nullable: true, description: `When the current dispatcher claim lapses. Long-running tasks extend it by heartbeat; reconciliation treats an expired claim as an orphaned task and returns it to Pending.`})
|
|
84823
84912
|
ClaimExpiresAt?: Date;
|
|
84824
84913
|
|
|
84914
|
+
@Field({nullable: true, description: `The Action this task executes, when the node is action-assigned rather than agent-assigned or awaiting a person. Mutually exclusive with UserID and AgentID (CK_Task_Assignment). Set by durable entity-action dispatch, where a single-node graph carries one action to run with restart recovery.`})
|
|
84915
|
+
@MaxLength(36)
|
|
84916
|
+
ActionID?: string;
|
|
84917
|
+
|
|
84918
|
+
@Field({nullable: true, description: `Which kind of workflow step this task represents. NULL for a task that is not part of a workflow, such as a hand-authored to-do. Determines which of AgentID/ActionID/PromptID/UserID is meaningful and how Configuration is read. This is the executable vocabulary and is deliberately not the same value list as AIAgentStep.StepType, which describes a step at design time.`})
|
|
84919
|
+
@MaxLength(20)
|
|
84920
|
+
StepType?: string;
|
|
84921
|
+
|
|
84922
|
+
@Field({nullable: true})
|
|
84923
|
+
@MaxLength(36)
|
|
84924
|
+
PromptID?: string;
|
|
84925
|
+
|
|
84926
|
+
@Field({nullable: true, description: `Everything about this step that has no column of its own, as JSON: the loop definition for a ForEach or While step, an agent step's message and template parameters, the mappings that move data between this step and the workflow payload, and the execution policy (timeout, retries, what to do on failure). Typed by ITaskStepConfiguration.`})
|
|
84927
|
+
Configuration?: string;
|
|
84928
|
+
|
|
84825
84929
|
@Field({nullable: true})
|
|
84826
84930
|
@MaxLength(255)
|
|
84827
84931
|
Parent?: string;
|
|
@@ -84854,6 +84958,14 @@ export class MJTask_ {
|
|
|
84854
84958
|
@MaxLength(255)
|
|
84855
84959
|
AgentRun?: string;
|
|
84856
84960
|
|
|
84961
|
+
@Field({nullable: true})
|
|
84962
|
+
@MaxLength(425)
|
|
84963
|
+
Action?: string;
|
|
84964
|
+
|
|
84965
|
+
@Field({nullable: true})
|
|
84966
|
+
@MaxLength(255)
|
|
84967
|
+
Prompt?: string;
|
|
84968
|
+
|
|
84857
84969
|
@Field({nullable: true})
|
|
84858
84970
|
@MaxLength(36)
|
|
84859
84971
|
RootParentID?: string;
|
|
@@ -84864,6 +84976,9 @@ export class MJTask_ {
|
|
|
84864
84976
|
@Field(() => [MJTaskDependency_])
|
|
84865
84977
|
MJTaskDependencies_DependsOnTaskIDArray: MJTaskDependency_[]; // Link to MJTaskDependencies
|
|
84866
84978
|
|
|
84979
|
+
@Field(() => [MJAIAgentRequest_])
|
|
84980
|
+
MJAIAgentRequests_OriginatingTaskIDArray: MJAIAgentRequest_[]; // Link to MJAIAgentRequests
|
|
84981
|
+
|
|
84867
84982
|
@Field(() => [MJTask_])
|
|
84868
84983
|
MJTasks_ParentIDArray: MJTask_[]; // Link to MJTasks
|
|
84869
84984
|
|
|
@@ -84937,6 +85052,18 @@ export class CreateMJTaskInput {
|
|
|
84937
85052
|
@Field({ nullable: true })
|
|
84938
85053
|
ClaimExpiresAt: Date | null;
|
|
84939
85054
|
|
|
85055
|
+
@Field({ nullable: true })
|
|
85056
|
+
ActionID: string | null;
|
|
85057
|
+
|
|
85058
|
+
@Field({ nullable: true })
|
|
85059
|
+
StepType: string | null;
|
|
85060
|
+
|
|
85061
|
+
@Field({ nullable: true })
|
|
85062
|
+
PromptID: string | null;
|
|
85063
|
+
|
|
85064
|
+
@Field({ nullable: true })
|
|
85065
|
+
Configuration: string | null;
|
|
85066
|
+
|
|
84940
85067
|
@Field(() => RestoreContextInput, { nullable: true })
|
|
84941
85068
|
RestoreContext___?: RestoreContextInput;
|
|
84942
85069
|
}
|
|
@@ -85010,6 +85137,18 @@ export class UpdateMJTaskInput {
|
|
|
85010
85137
|
@Field({ nullable: true })
|
|
85011
85138
|
ClaimExpiresAt?: Date | null;
|
|
85012
85139
|
|
|
85140
|
+
@Field({ nullable: true })
|
|
85141
|
+
ActionID?: string | null;
|
|
85142
|
+
|
|
85143
|
+
@Field({ nullable: true })
|
|
85144
|
+
StepType?: string | null;
|
|
85145
|
+
|
|
85146
|
+
@Field({ nullable: true })
|
|
85147
|
+
PromptID?: string | null;
|
|
85148
|
+
|
|
85149
|
+
@Field({ nullable: true })
|
|
85150
|
+
Configuration?: string | null;
|
|
85151
|
+
|
|
85013
85152
|
@Field(() => [KeyValuePairInput], { nullable: true })
|
|
85014
85153
|
OldValues___?: KeyValuePairInput[];
|
|
85015
85154
|
|
|
@@ -85094,6 +85233,16 @@ export class MJTaskResolver extends ResolverBase {
|
|
|
85094
85233
|
return result;
|
|
85095
85234
|
}
|
|
85096
85235
|
|
|
85236
|
+
@FieldResolver(() => [MJAIAgentRequest_])
|
|
85237
|
+
async MJAIAgentRequests_OriginatingTaskIDArray(@Root() mjtask_: MJTask_, @Ctx() { userPayload, providers }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
85238
|
+
this.CheckUserReadPermissions('MJ: AI Agent Requests', userPayload);
|
|
85239
|
+
const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
|
|
85240
|
+
const sSQL = `SELECT * FROM ${provider.QuoteSchemaAndView(Metadata.Provider.ConfigData.MJCoreSchemaName, 'vwAIAgentRequests')} WHERE ${provider.QuoteIdentifier('OriginatingTaskID')}=${provider.BuildParameterPlaceholder(0)} ` + this.getRowLevelSecurityWhereClause(provider, 'MJ: AI Agent Requests', userPayload, EntityPermissionType.Read, 'AND');
|
|
85241
|
+
const rows = await provider.ExecuteSQL(sSQL, [mjtask_.ID], undefined, this.GetUserFromPayload(userPayload));
|
|
85242
|
+
const result = await this.ArrayMapFieldNamesToCodeNames('MJ: AI Agent Requests', rows, this.GetUserFromPayload(userPayload));
|
|
85243
|
+
return result;
|
|
85244
|
+
}
|
|
85245
|
+
|
|
85097
85246
|
@FieldResolver(() => [MJTask_])
|
|
85098
85247
|
async MJTasks_ParentIDArray(@Root() mjtask_: MJTask_, @Ctx() { userPayload, providers }: AppContext, @PubSub() pubSub: PubSubEngine) {
|
|
85099
85248
|
this.CheckUserReadPermissions('MJ: Tasks', userPayload);
|
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
UserInfo,
|
|
21
21
|
} from '@memberjunction/core';
|
|
22
22
|
import { MJAuditLogEntity, MJErrorLogEntity, MJUserViewEntityExtended } from '@memberjunction/core-entities';
|
|
23
|
-
import { SQLServerDataProvider
|
|
23
|
+
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
24
|
+
import { UserCache } from '@memberjunction/generic-database-provider';
|
|
24
25
|
import { PubSubEngine, AuthorizationError } from 'type-graphql';
|
|
25
26
|
import { GraphQLError } from 'graphql';
|
|
26
27
|
import { GetAPIKeyEngine } from '@memberjunction/api-keys';
|
|
@@ -62,16 +63,28 @@ export class ResolverBase {
|
|
|
62
63
|
* - AllowDecryptInAPI=false + SendEncryptedValue=true: Keep encrypted ciphertext
|
|
63
64
|
* - AllowDecryptInAPI=false + SendEncryptedValue=false: Replace with sentinel
|
|
64
65
|
*
|
|
66
|
+
* Returns a COPY — `dataObject` is never written to. Callers routinely pass rows straight
|
|
67
|
+
* from `findBy`/`RunView`, which are the server cache's own objects held by reference, and
|
|
68
|
+
* `LocalCacheManager` deep-freezes them. Renaming in place therefore threw
|
|
69
|
+
* `Cannot add property _mj__CreatedAt, object is not extensible` on every `UserByEmail` /
|
|
70
|
+
* `UserByID` / `UserByEmployeeID` call and on every generated single-record resolver whose
|
|
71
|
+
* entity has caching enabled. (Before the freeze it did something worse but quieter: it
|
|
72
|
+
* rewrote the cached row's keys, so later readers were served transport-shaped rows that
|
|
73
|
+
* `BaseEntity.SetMany` rejects.) Copying here fixes every call site at once and makes the
|
|
74
|
+
* hazard unreachable for future ones.
|
|
75
|
+
*
|
|
65
76
|
* @param entityName - The entity name
|
|
66
|
-
* @param dataObject - The data object with field values
|
|
77
|
+
* @param dataObject - The data object with field values. Not modified.
|
|
67
78
|
* @param contextUser - Optional user context for decryption (required for encrypted fields)
|
|
68
|
-
* @returns
|
|
79
|
+
* @returns A new object in transport shape, or null when there is nothing to map
|
|
69
80
|
*/
|
|
70
81
|
protected async MapFieldNamesToCodeNames(entityName: string, dataObject: any, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<any> {
|
|
71
82
|
// Return null for empty objects (e.g. when no rows found due to RLS filtering)
|
|
72
83
|
if (!dataObject || Object.keys(dataObject).length === 0) {
|
|
73
84
|
return null;
|
|
74
85
|
}
|
|
86
|
+
// Shallow copy up front so every write below lands on our object, never the caller's.
|
|
87
|
+
dataObject = { ...dataObject };
|
|
75
88
|
|
|
76
89
|
// for the given entity name provided, check to see if there are any fields
|
|
77
90
|
// where the code name is different from the field name, and for just those
|
|
@@ -184,14 +197,21 @@ export class ResolverBase {
|
|
|
184
197
|
return true;
|
|
185
198
|
}
|
|
186
199
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Array form of {@link MapFieldNamesToCodeNames}. Returns a NEW array of NEW objects; neither
|
|
202
|
+
* the input array nor its rows are modified. Both matter: the cache freezes the array as well
|
|
203
|
+
* as the rows it contains, so collecting the mapped copies (rather than mapping in place and
|
|
204
|
+
* returning the original) is what makes this safe on cache-served input.
|
|
205
|
+
*/
|
|
206
|
+
protected async ArrayMapFieldNamesToCodeNames(entityName: string, dataObjectArray: any[], contextUser?: UserInfo, provider?: IMetadataProvider): Promise<any[]> {
|
|
207
|
+
if (!dataObjectArray || dataObjectArray.length === 0) {
|
|
208
|
+
return dataObjectArray;
|
|
193
209
|
}
|
|
194
|
-
|
|
210
|
+
const mapped: any[] = [];
|
|
211
|
+
for (const element of dataObjectArray) {
|
|
212
|
+
mapped.push(await this.MapFieldNamesToCodeNames(entityName, element, contextUser, provider));
|
|
213
|
+
}
|
|
214
|
+
return mapped;
|
|
195
215
|
}
|
|
196
216
|
|
|
197
217
|
/**
|
|
@@ -826,12 +846,27 @@ export class ResolverBase {
|
|
|
826
846
|
LogStatus(`[ResolverBase] RunView result aggregate info: entityName=${viewInfo.Entity}, hasAggregateResults=${!!result?.AggregateResults}, aggregateResultCount=${result?.AggregateResults?.length || 0}, aggregateExecutionTime=${result?.AggregateExecutionTime}, aggregateResults=${JSON.stringify(result?.AggregateResults)}`);
|
|
827
847
|
}
|
|
828
848
|
|
|
829
|
-
// Process results for GraphQL transport
|
|
849
|
+
// Process results for GraphQL transport.
|
|
850
|
+
//
|
|
851
|
+
// Map onto COPIES, never in place. `FieldMapper.MapFields` renames keys by
|
|
852
|
+
// mutating (`obj[mapped] = obj[k]; delete obj[k]`), and these rows are the
|
|
853
|
+
// provider's own result objects — which the server cache holds BY REFERENCE
|
|
854
|
+
// under a reference-sharing storage provider. Mapping them in place rewrote
|
|
855
|
+
// `__mj_CreatedAt` to the transport alias `_mj__CreatedAt` inside the live
|
|
856
|
+
// cache, and because that cache is process-wide, one GraphQL response made
|
|
857
|
+
// every later read hand back transport-shaped rows that `BaseEntity.SetMany`
|
|
858
|
+
// rejects. `ArrayFilterEncryptedFieldsForAPI` mutates too, so it must also
|
|
859
|
+
// see the copies. (FileResolver already maps a spread copy.)
|
|
860
|
+
//
|
|
861
|
+
// These copies are LOAD-BEARING, not merely defensive: LocalCacheManager now
|
|
862
|
+
// deep-freezes cached rows (see ILocalStorageProvider.SharesReferences), so
|
|
863
|
+
// mapping in place would throw rather than silently corrupt. `{ ...r }` is a
|
|
864
|
+
// SHALLOW copy, which is sufficient here because the only post-map mutators
|
|
865
|
+
// rename top-level keys and redact scalar fields — and the cache's freeze is
|
|
866
|
+
// deep, so a nested value can no longer be reached through the copy either.
|
|
830
867
|
const mapper = new FieldMapper();
|
|
831
868
|
if (result?.Success && result.Results?.length) {
|
|
832
|
-
|
|
833
|
-
mapper.MapFields(r);
|
|
834
|
-
}
|
|
869
|
+
result.Results = result.Results.map(r => mapper.MapFields({ ...r }));
|
|
835
870
|
// Filter encrypted fields before sending to API client
|
|
836
871
|
await this.ArrayFilterEncryptedFieldsForAPI(
|
|
837
872
|
viewInfo.Entity,
|
|
@@ -948,9 +983,9 @@ export class ResolverBase {
|
|
|
948
983
|
for (let i = 0; i < runViewResults.length; i++) {
|
|
949
984
|
const runViewResult = runViewResults[i];
|
|
950
985
|
if (runViewResult?.Success && runViewResult.Results?.length) {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}
|
|
986
|
+
// Copy-then-map, same reason as the single-view path above: these rows
|
|
987
|
+
// are cache-held references and MapFields renames keys in place.
|
|
988
|
+
runViewResult.Results = runViewResult.Results.map(r => mapper.MapFields({ ...r }));
|
|
954
989
|
// Filter encrypted fields before sending to API client
|
|
955
990
|
// Use the corresponding param's entity name
|
|
956
991
|
const entityName = params[i]?.viewInfo?.Entity;
|