@memberjunction/server 2.104.0 → 2.105.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/agents/skip-agent.d.ts +1 -1
- package/dist/agents/skip-agent.d.ts.map +1 -1
- package/dist/agents/skip-agent.js +1189 -24
- package/dist/agents/skip-agent.js.map +1 -1
- package/dist/agents/skip-sdk.d.ts.map +1 -1
- package/dist/agents/skip-sdk.js +3 -4
- package/dist/agents/skip-sdk.js.map +1 -1
- package/dist/generated/generated.d.ts +3621 -3407
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +21331 -19952
- package/dist/generated/generated.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -18
- package/dist/index.js.map +1 -1
- package/dist/resolvers/CreateQueryResolver.d.ts +2 -2
- package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/CreateQueryResolver.js +12 -12
- package/dist/resolvers/CreateQueryResolver.js.map +1 -1
- package/dist/resolvers/EntityResolver.d.ts +2 -2
- package/dist/resolvers/EntityResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityResolver.js +4 -4
- package/dist/resolvers/EntityResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +2 -2
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +6 -6
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +14 -14
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js +0 -2
- package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +2 -2
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +21 -17
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/TaskResolver.d.ts +18 -0
- package/dist/resolvers/TaskResolver.d.ts.map +1 -0
- package/dist/resolvers/TaskResolver.js +138 -0
- package/dist/resolvers/TaskResolver.js.map +1 -0
- package/dist/resolvers/UserFavoriteResolver.d.ts +2 -2
- package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +5 -5
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/resolvers/UserResolver.d.ts +2 -2
- package/dist/resolvers/UserResolver.d.ts.map +1 -1
- package/dist/resolvers/UserResolver.js +7 -7
- package/dist/resolvers/UserResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +2 -2
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +8 -8
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/services/TaskOrchestrator.d.ts +52 -0
- package/dist/services/TaskOrchestrator.d.ts.map +1 -0
- package/dist/services/TaskOrchestrator.js +486 -0
- package/dist/services/TaskOrchestrator.js.map +1 -0
- package/package.json +30 -38
- package/src/agents/skip-agent.ts +1176 -28
- package/src/agents/skip-sdk.ts +3 -5
- package/src/generated/generated.ts +7664 -6785
- package/src/index.ts +7 -21
- package/src/resolvers/CreateQueryResolver.ts +6 -6
- package/src/resolvers/EntityResolver.ts +4 -4
- package/src/resolvers/FileCategoryResolver.ts +2 -2
- package/src/resolvers/FileResolver.ts +12 -12
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +2 -3
- package/src/resolvers/RunAIAgentResolver.ts +7 -0
- package/src/resolvers/RunTemplateResolver.ts +1 -2
- package/src/resolvers/TaskResolver.ts +142 -0
- package/src/resolvers/UserFavoriteResolver.ts +5 -5
- package/src/resolvers/UserResolver.ts +7 -7
- package/src/resolvers/UserViewResolver.ts +8 -8
- package/src/services/TaskOrchestration-Integration.md +188 -0
- package/src/services/TaskOrchestrator.ts +756 -0
package/src/index.ts
CHANGED
|
@@ -44,28 +44,10 @@ LoadAgentManagementActions();
|
|
|
44
44
|
import { resolve } from 'node:path';
|
|
45
45
|
import { DataSourceInfo, raiseEvent } from './types.js';
|
|
46
46
|
import { LoadAIEngine } from '@memberjunction/aiengine';
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
import { LoadGroqLLM } from '@memberjunction/ai-groq';
|
|
50
|
-
import { LoadCerebrasLLM } from '@memberjunction/ai-cerebras';
|
|
51
|
-
import { LoadMistralLLM } from '@memberjunction/ai-mistral';
|
|
52
|
-
import { LoadLMStudioLLM } from '@memberjunction/ai-lmstudio';
|
|
53
|
-
import { LoadOpenRouterLLM } from '@memberjunction/ai-openrouter';
|
|
54
|
-
import { LoadOllamaLLM } from '@memberjunction/ai-ollama';
|
|
55
|
-
import { LoadLocalEmbedding } from '@memberjunction/ai-local-embeddings';
|
|
56
|
-
// Load AI LLMs and Base AI Engine
|
|
57
|
-
// These imports are necessary to ensure the LLMs are registered in the MemberJunction AI
|
|
58
|
-
// system. They are not tree-shaken because they are dynamically loaded at runtime.
|
|
47
|
+
import { LoadAIProviders } from '@memberjunction/ai-provider-bundle';
|
|
48
|
+
// Load AI Engine and all providers to prevent tree shaking
|
|
59
49
|
LoadAIEngine();
|
|
60
|
-
|
|
61
|
-
LoadAnthropicLLM();
|
|
62
|
-
LoadGroqLLM();
|
|
63
|
-
LoadCerebrasLLM();
|
|
64
|
-
LoadMistralLLM();
|
|
65
|
-
LoadLMStudioLLM();
|
|
66
|
-
LoadOpenRouterLLM();
|
|
67
|
-
LoadOllamaLLM();
|
|
68
|
-
LoadLocalEmbedding();
|
|
50
|
+
LoadAIProviders();
|
|
69
51
|
|
|
70
52
|
import { ExternalChangeDetectorEngine } from '@memberjunction/external-change-detection';
|
|
71
53
|
|
|
@@ -86,10 +68,14 @@ export * from './generic/RunViewResolver.js';
|
|
|
86
68
|
export * from './resolvers/RunTemplateResolver.js';
|
|
87
69
|
export * from './resolvers/RunAIPromptResolver.js';
|
|
88
70
|
export * from './resolvers/RunAIAgentResolver.js';
|
|
71
|
+
export * from './resolvers/TaskResolver.js';
|
|
89
72
|
export * from './generic/KeyValuePairInput.js';
|
|
90
73
|
export * from './generic/KeyInputOutputTypes.js';
|
|
91
74
|
export * from './generic/DeleteOptionsInput.js';
|
|
92
75
|
|
|
76
|
+
export * from './agents/skip-agent.js';
|
|
77
|
+
export * from './agents/skip-sdk.js';
|
|
78
|
+
|
|
93
79
|
export * from './resolvers/AskSkipResolver.js';
|
|
94
80
|
export * from './resolvers/ColorResolver.js';
|
|
95
81
|
export * from './resolvers/ComponentRegistryResolver.js';
|
|
@@ -3,7 +3,7 @@ import { AppContext } from '../types.js';
|
|
|
3
3
|
import { LogError, Metadata, RunView, UserInfo, CompositeKey, DatabaseProviderBase } from '@memberjunction/core';
|
|
4
4
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
5
5
|
import { QueryCategoryEntity, QueryPermissionEntity } from '@memberjunction/core-entities';
|
|
6
|
-
import {
|
|
6
|
+
import { MJQueryResolver } from '../generated/generated.js';
|
|
7
7
|
import { GetReadOnlyProvider, GetReadWriteProvider } from '../util.js';
|
|
8
8
|
import { DeleteOptionsInput } from '../generic/DeleteOptionsInput.js';
|
|
9
9
|
import { QueryEntityExtended } from '@memberjunction/core-entities-server';
|
|
@@ -294,7 +294,7 @@ export class DeleteQueryResultType {
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
@Resolver()
|
|
297
|
-
export class
|
|
297
|
+
export class MJQueryResolverExtended extends MJQueryResolver {
|
|
298
298
|
/**
|
|
299
299
|
* Creates a new query with the provided attributes. This mutation is restricted to system users only.
|
|
300
300
|
* @param input - CreateQuerySystemUserInput containing all the query attributes
|
|
@@ -373,7 +373,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
373
373
|
LogError(err);
|
|
374
374
|
return {
|
|
375
375
|
Success: false,
|
|
376
|
-
ErrorMessage: `
|
|
376
|
+
ErrorMessage: `MJQueryResolverExtended::CreateQuerySystemUser --- Error creating query: ${err instanceof Error ? err.message : String(err)}`
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
379
|
}
|
|
@@ -553,7 +553,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
553
553
|
LogError(err);
|
|
554
554
|
return {
|
|
555
555
|
Success: false,
|
|
556
|
-
ErrorMessage: `
|
|
556
|
+
ErrorMessage: `MJQueryResolverExtended::UpdateQuerySystemUser --- Error updating query: ${err instanceof Error ? err.message : String(err)}`
|
|
557
557
|
};
|
|
558
558
|
}
|
|
559
559
|
}
|
|
@@ -578,7 +578,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
578
578
|
if (!ID || ID.trim() === '') {
|
|
579
579
|
return {
|
|
580
580
|
Success: false,
|
|
581
|
-
ErrorMessage: '
|
|
581
|
+
ErrorMessage: 'MJQueryResolverExtended::DeleteQuerySystemResolver --- Invalid query ID: ID cannot be null or empty'
|
|
582
582
|
};
|
|
583
583
|
}
|
|
584
584
|
|
|
@@ -610,7 +610,7 @@ export class QueryResolverExtended extends QueryResolver {
|
|
|
610
610
|
LogError(err);
|
|
611
611
|
return {
|
|
612
612
|
Success: false,
|
|
613
|
-
ErrorMessage: `
|
|
613
|
+
ErrorMessage: `MJQueryResolverExtended::DeleteQuerySystemResolver --- Error deleting query: ${err instanceof Error ? err.message : String(err)}`
|
|
614
614
|
};
|
|
615
615
|
}
|
|
616
616
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { EntityPermissionType, IRunViewProvider } from '@memberjunction/core';
|
|
2
2
|
import { AppContext } from '../types.js';
|
|
3
3
|
import { Arg, Ctx, Query, Resolver, InputType, Field } from 'type-graphql';
|
|
4
|
-
import {
|
|
4
|
+
import { MJEntity_, MJEntityResolverBase } from '../generated/generated.js';
|
|
5
5
|
import sql from 'mssql';
|
|
6
6
|
import { GetReadOnlyProvider } from '../util.js';
|
|
7
7
|
|
|
8
|
-
@Resolver(
|
|
9
|
-
export class EntityResolver extends
|
|
10
|
-
@Query(() => [
|
|
8
|
+
@Resolver(MJEntity_)
|
|
9
|
+
export class EntityResolver extends MJEntityResolverBase {
|
|
10
|
+
@Query(() => [MJEntity_])
|
|
11
11
|
async EntitiesBySchemas(
|
|
12
12
|
@Ctx() { providers, userPayload }: AppContext,
|
|
13
13
|
@Arg('IncludeSchemas', () => [String], { nullable: true }) IncludeSchemas?: string[],
|
|
@@ -2,13 +2,13 @@ import { CompositeKey, EntityDeleteOptions, EntityPermissionType, EntitySaveOpti
|
|
|
2
2
|
import { FileCategoryEntity, FileEntity } from '@memberjunction/core-entities';
|
|
3
3
|
import { AppContext, Arg, Ctx, DeleteOptionsInput, Int, Mutation } from '@memberjunction/server';
|
|
4
4
|
import { mj_core_schema } from '../config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { MJFileCategoryResolver as FileCategoryResolverBase, MJFileCategory_ } from '../generated/generated.js';
|
|
6
6
|
import sql from 'mssql';
|
|
7
7
|
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
8
8
|
import { GetReadWriteProvider } from '../util.js';
|
|
9
9
|
|
|
10
10
|
export class FileResolver extends FileCategoryResolverBase {
|
|
11
|
-
@Mutation(() =>
|
|
11
|
+
@Mutation(() => MJFileCategory_)
|
|
12
12
|
async DeleteFileCategory(
|
|
13
13
|
@Arg('ID', () => String) ID: string,
|
|
14
14
|
@Arg('options___', () => DeleteOptionsInput) options: DeleteOptionsInput,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
Root,
|
|
18
18
|
} from '@memberjunction/server';
|
|
19
19
|
import { createDownloadUrl, createUploadUrl, deleteObject, moveObject } from '@memberjunction/storage';
|
|
20
|
-
import {
|
|
20
|
+
import { CreateMJFileInput, MJFileResolver as FileResolverBase, MJFile_, UpdateMJFileInput } from '../generated/generated.js';
|
|
21
21
|
import { FieldMapper } from '@memberjunction/graphql-dataprovider';
|
|
22
22
|
import { GetReadOnlyProvider } from '../util.js';
|
|
23
23
|
|
|
@@ -29,8 +29,8 @@ export class CreateUploadURLInput {
|
|
|
29
29
|
|
|
30
30
|
@ObjectType()
|
|
31
31
|
export class CreateFilePayload {
|
|
32
|
-
@Field(() =>
|
|
33
|
-
File:
|
|
32
|
+
@Field(() => MJFile_)
|
|
33
|
+
File: MJFile_;
|
|
34
34
|
@Field(() => String)
|
|
35
35
|
UploadUrl: string;
|
|
36
36
|
@Field(() => Boolean)
|
|
@@ -38,16 +38,16 @@ export class CreateFilePayload {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
@ObjectType()
|
|
41
|
-
export class FileExt extends
|
|
41
|
+
export class FileExt extends MJFile_ {
|
|
42
42
|
@Field(() => String)
|
|
43
43
|
DownloadUrl: string;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
@Resolver(
|
|
46
|
+
@Resolver(MJFile_)
|
|
47
47
|
export class FileResolver extends FileResolverBase {
|
|
48
48
|
@Mutation(() => CreateFilePayload)
|
|
49
49
|
async CreateFile(
|
|
50
|
-
@Arg('input', () =>
|
|
50
|
+
@Arg('input', () => CreateMJFileInput) input: CreateMJFileInput,
|
|
51
51
|
@Ctx() context: AppContext,
|
|
52
52
|
@PubSub() pubSub: PubSubEngine
|
|
53
53
|
) {
|
|
@@ -86,7 +86,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
@FieldResolver(() => String)
|
|
89
|
-
async DownloadUrl(@Root() file:
|
|
89
|
+
async DownloadUrl(@Root() file: MJFile_, @Ctx() { userPayload }: AppContext) {
|
|
90
90
|
const md = new Metadata();
|
|
91
91
|
const user = this.GetUserFromPayload(userPayload);
|
|
92
92
|
const fileEntity = await md.GetEntityObject<FileEntity>('Files', user);
|
|
@@ -100,9 +100,9 @@ export class FileResolver extends FileResolverBase {
|
|
|
100
100
|
return url;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
@Mutation(() =>
|
|
103
|
+
@Mutation(() => MJFile_)
|
|
104
104
|
async UpdateFile(
|
|
105
|
-
@Arg('input', () =>
|
|
105
|
+
@Arg('input', () => UpdateMJFileInput) input: UpdateMJFileInput,
|
|
106
106
|
@Ctx() context: AppContext,
|
|
107
107
|
@PubSub() pubSub: PubSubEngine
|
|
108
108
|
) {
|
|
@@ -124,11 +124,11 @@ export class FileResolver extends FileResolverBase {
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
const updatedFile = await super.
|
|
127
|
+
const updatedFile = await super.UpdateMJFile(input, context, pubSub);
|
|
128
128
|
return updatedFile;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
@Mutation(() =>
|
|
131
|
+
@Mutation(() => MJFile_)
|
|
132
132
|
async DeleteFile(
|
|
133
133
|
@Arg('ID', () => String) ID: string,
|
|
134
134
|
@Arg('options___', () => DeleteOptionsInput) options: DeleteOptionsInput,
|
|
@@ -152,6 +152,6 @@ export class FileResolver extends FileResolverBase {
|
|
|
152
152
|
await deleteObject(providerEntity, fileEntity.ProviderKey ?? fileEntity.Name);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
return super.
|
|
155
|
+
return super.DeleteMJFile(ID, options, context, pubSub);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -10,12 +10,11 @@ import {
|
|
|
10
10
|
import { AppContext } from '../types.js';
|
|
11
11
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
12
12
|
|
|
13
|
-
//load the default vectorDB
|
|
14
|
-
import { LoadMistralEmbedding } from '@memberjunction/ai-mistral';
|
|
13
|
+
//load the default vectorDB
|
|
15
14
|
import { LoadPineconeVectorDB } from '@memberjunction/ai-vectors-pinecone';
|
|
16
15
|
import { CompositeKeyInputType, CompositeKeyOutputType, KeyValuePairOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
17
16
|
import { GetReadOnlyProvider } from '../util.js';
|
|
18
|
-
|
|
17
|
+
// AI provider loading now handled by @memberjunction/aiengine
|
|
19
18
|
LoadPineconeVectorDB();
|
|
20
19
|
|
|
21
20
|
@InputType()
|
|
@@ -9,6 +9,7 @@ import { ResolverBase } from '../generic/ResolverBase.js';
|
|
|
9
9
|
import { PUSH_STATUS_UPDATES_TOPIC } from '../generic/PushStatusResolver.js';
|
|
10
10
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
11
11
|
import { GetReadWriteProvider } from '../util.js';
|
|
12
|
+
import { SafeJSONParse } from '@memberjunction/global';
|
|
12
13
|
|
|
13
14
|
@ObjectType()
|
|
14
15
|
export class AIAgentRunResult {
|
|
@@ -312,6 +313,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
312
313
|
sessionId: string,
|
|
313
314
|
pubSub: PubSubEngine,
|
|
314
315
|
data?: string,
|
|
316
|
+
payload?: string,
|
|
315
317
|
templateData?: string,
|
|
316
318
|
lastRunId?: string,
|
|
317
319
|
autoPopulateLastRunPayload?: boolean,
|
|
@@ -356,6 +358,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
356
358
|
const result = await agentRunner.RunAgent({
|
|
357
359
|
agent: agentEntity,
|
|
358
360
|
conversationMessages: parsedMessages,
|
|
361
|
+
payload: payload ? SafeJSONParse(payload) : undefined,
|
|
359
362
|
contextUser: currentUser,
|
|
360
363
|
onProgress: this.createProgressCallback(pubSub, sessionId, userPayload, agentRunRef),
|
|
361
364
|
onStreaming: this.createStreamingCallback(pubSub, sessionId, userPayload, agentRunRef),
|
|
@@ -464,6 +467,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
464
467
|
@Arg('sessionId') sessionId: string,
|
|
465
468
|
@PubSub() pubSub: PubSubEngine,
|
|
466
469
|
@Arg('data', { nullable: true }) data?: string,
|
|
470
|
+
@Arg('payload', { nullable: true }) payload?: string,
|
|
467
471
|
@Arg('templateData', { nullable: true }) templateData?: string,
|
|
468
472
|
@Arg('lastRunId', { nullable: true }) lastRunId?: string,
|
|
469
473
|
@Arg('autoPopulateLastRunPayload', { nullable: true }) autoPopulateLastRunPayload?: boolean,
|
|
@@ -479,6 +483,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
479
483
|
sessionId,
|
|
480
484
|
pubSub,
|
|
481
485
|
data,
|
|
486
|
+
payload,
|
|
482
487
|
templateData,
|
|
483
488
|
lastRunId,
|
|
484
489
|
autoPopulateLastRunPayload,
|
|
@@ -500,6 +505,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
500
505
|
@Arg('sessionId') sessionId: string,
|
|
501
506
|
@PubSub() pubSub: PubSubEngine,
|
|
502
507
|
@Arg('data', { nullable: true }) data?: string,
|
|
508
|
+
@Arg('payload', { nullable: true }) payload?: string,
|
|
503
509
|
@Arg('templateData', { nullable: true }) templateData?: string,
|
|
504
510
|
@Arg('lastRunId', { nullable: true }) lastRunId?: string,
|
|
505
511
|
@Arg('autoPopulateLastRunPayload', { nullable: true }) autoPopulateLastRunPayload?: boolean,
|
|
@@ -515,6 +521,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
515
521
|
sessionId,
|
|
516
522
|
pubSub,
|
|
517
523
|
data,
|
|
524
|
+
payload,
|
|
518
525
|
templateData,
|
|
519
526
|
lastRunId,
|
|
520
527
|
autoPopulateLastRunPayload,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Resolver, Mutation, Arg, Ctx, ObjectType, Field } from 'type-graphql';
|
|
2
2
|
import { AppContext, UserPayload } from '../types.js';
|
|
3
3
|
import { LogError, LogStatus, Metadata, RunView } from '@memberjunction/core';
|
|
4
|
-
import { TemplateContentEntity } from '@memberjunction/core-entities';
|
|
4
|
+
import { TemplateContentEntity, TemplateEntityExtended } from '@memberjunction/core-entities';
|
|
5
5
|
import { TemplateEngineServer } from '@memberjunction/templates';
|
|
6
|
-
import { TemplateEntityExtended } from '@memberjunction/templates-base-types';
|
|
7
6
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
8
7
|
import { GetReadWriteProvider } from '../util.js';
|
|
9
8
|
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Resolver, Mutation, Arg, Ctx, ObjectType, Field, PubSub, PubSubEngine } from 'type-graphql';
|
|
2
|
+
import { AppContext } from '../types.js';
|
|
3
|
+
import { LogError, LogStatus } from '@memberjunction/core';
|
|
4
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
5
|
+
import { TaskOrchestrator, TaskGraphResponse, TaskExecutionResult } from '../services/TaskOrchestrator.js';
|
|
6
|
+
|
|
7
|
+
@ObjectType()
|
|
8
|
+
export class TaskExecutionResultType {
|
|
9
|
+
@Field()
|
|
10
|
+
taskId: string;
|
|
11
|
+
|
|
12
|
+
@Field()
|
|
13
|
+
success: boolean;
|
|
14
|
+
|
|
15
|
+
@Field({ nullable: true })
|
|
16
|
+
output?: string;
|
|
17
|
+
|
|
18
|
+
@Field({ nullable: true })
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@ObjectType()
|
|
23
|
+
export class ExecuteTaskGraphResult {
|
|
24
|
+
@Field()
|
|
25
|
+
success: boolean;
|
|
26
|
+
|
|
27
|
+
@Field({ nullable: true })
|
|
28
|
+
errorMessage?: string;
|
|
29
|
+
|
|
30
|
+
@Field(() => [TaskExecutionResultType])
|
|
31
|
+
results: TaskExecutionResultType[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* TaskOrchestrationResolver handles multi-step task orchestration.
|
|
36
|
+
* This resolver is called when the Conversation Manager returns a task graph
|
|
37
|
+
* for complex workflows that require multiple agents working in sequence or parallel.
|
|
38
|
+
*/
|
|
39
|
+
@Resolver()
|
|
40
|
+
export class TaskOrchestrationResolver extends ResolverBase {
|
|
41
|
+
/**
|
|
42
|
+
* Execute a task graph from the Conversation Manager.
|
|
43
|
+
* This creates tasks in the database, manages dependencies, and executes them in proper order.
|
|
44
|
+
*
|
|
45
|
+
* @param taskGraphJson - JSON string containing the task graph from Conversation Manager
|
|
46
|
+
* @param conversationDetailId - ID of the conversation detail that triggered this workflow
|
|
47
|
+
* @param environmentId - Environment ID for the tasks
|
|
48
|
+
*/
|
|
49
|
+
@Mutation(() => ExecuteTaskGraphResult)
|
|
50
|
+
async ExecuteTaskGraph(
|
|
51
|
+
@Arg('taskGraphJson') taskGraphJson: string,
|
|
52
|
+
@Arg('conversationDetailId') conversationDetailId: string,
|
|
53
|
+
@Arg('environmentId') environmentId: string,
|
|
54
|
+
@Arg('sessionId') sessionId: string,
|
|
55
|
+
@PubSub() pubSub: PubSubEngine,
|
|
56
|
+
@Ctx() { userPayload }: AppContext
|
|
57
|
+
): Promise<ExecuteTaskGraphResult> {
|
|
58
|
+
try {
|
|
59
|
+
LogStatus(`=== EXECUTING TASK GRAPH FOR CONVERSATION: ${conversationDetailId} ===`);
|
|
60
|
+
|
|
61
|
+
// Parse task graph
|
|
62
|
+
const taskGraph: TaskGraphResponse = JSON.parse(taskGraphJson);
|
|
63
|
+
|
|
64
|
+
// Validate task graph
|
|
65
|
+
if (!taskGraph.workflowName || !taskGraph.tasks || taskGraph.tasks.length === 0) {
|
|
66
|
+
throw new Error('Invalid task graph: must have workflowName and at least one task');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Get current user
|
|
70
|
+
const currentUser = this.GetUserFromPayload(userPayload);
|
|
71
|
+
if (!currentUser) {
|
|
72
|
+
throw new Error('Unable to determine current user');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
LogStatus(`Workflow: ${taskGraph.workflowName} (${taskGraph.tasks.length} tasks)`);
|
|
76
|
+
if (taskGraph.reasoning) {
|
|
77
|
+
LogStatus(`Reasoning: ${taskGraph.reasoning}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Create task orchestrator with PubSub for progress updates
|
|
81
|
+
const orchestrator = new TaskOrchestrator(currentUser, pubSub, sessionId, userPayload);
|
|
82
|
+
|
|
83
|
+
// Create parent task and child tasks with dependencies
|
|
84
|
+
const { parentTaskId, taskIdMap } = await orchestrator.createTasksFromGraph(
|
|
85
|
+
taskGraph,
|
|
86
|
+
conversationDetailId,
|
|
87
|
+
environmentId
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
LogStatus(`Created parent task ${parentTaskId} with ${taskIdMap.size} child tasks`);
|
|
91
|
+
|
|
92
|
+
// Execute tasks in proper order
|
|
93
|
+
const results = await orchestrator.executeTasksForParent(
|
|
94
|
+
parentTaskId
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// Log results
|
|
98
|
+
const successCount = results.filter(r => r.success).length;
|
|
99
|
+
LogStatus(`Completed ${successCount} of ${results.length} tasks successfully`);
|
|
100
|
+
|
|
101
|
+
for (const result of results) {
|
|
102
|
+
if (result.success) {
|
|
103
|
+
LogStatus(`✅ Task ${result.taskId} completed successfully`);
|
|
104
|
+
} else {
|
|
105
|
+
LogError(`❌ Task ${result.taskId} failed: ${result.error}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Convert results to GraphQL types
|
|
110
|
+
const graphqlResults: TaskExecutionResultType[] = results.map(r => ({
|
|
111
|
+
taskId: r.taskId,
|
|
112
|
+
success: r.success,
|
|
113
|
+
output: r.output ? JSON.stringify(r.output) : undefined,
|
|
114
|
+
error: r.error
|
|
115
|
+
}));
|
|
116
|
+
|
|
117
|
+
LogStatus(`=== TASK GRAPH EXECUTION COMPLETE ===`);
|
|
118
|
+
|
|
119
|
+
const result = {
|
|
120
|
+
success: true,
|
|
121
|
+
results: graphqlResults
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
LogStatus(`Returning ExecuteTaskGraph result: ${JSON.stringify({
|
|
125
|
+
success: result.success,
|
|
126
|
+
resultsCount: result.results.length,
|
|
127
|
+
firstResult: result.results[0]
|
|
128
|
+
})}`);
|
|
129
|
+
|
|
130
|
+
return result;
|
|
131
|
+
|
|
132
|
+
} catch (error) {
|
|
133
|
+
LogError(`Task graph execution failed:`, undefined, error);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
success: false,
|
|
137
|
+
errorMessage: (error as Error).message || 'Unknown error occurred',
|
|
138
|
+
results: []
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from '@memberjunction/server';
|
|
16
16
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { MJUserFavorite_, MJUserFavoriteResolverBase } from '../generated/generated.js';
|
|
19
19
|
import { GetReadOnlyProvider } from '../util.js';
|
|
20
20
|
|
|
21
21
|
//****************************************************************************
|
|
@@ -66,15 +66,15 @@ export class UserFavoriteResult {
|
|
|
66
66
|
Success: boolean;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
@Resolver(
|
|
70
|
-
export class UserFavoriteResolver extends
|
|
71
|
-
@Query(() => [
|
|
69
|
+
@Resolver(MJUserFavorite_)
|
|
70
|
+
export class UserFavoriteResolver extends MJUserFavoriteResolverBase {
|
|
71
|
+
@Query(() => [MJUserFavorite_])
|
|
72
72
|
async UserFavoritesByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { providers, userPayload }: AppContext) {
|
|
73
73
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
74
74
|
return await this.findBy(provider, 'User Favorites', { UserID }, userPayload.userRecord);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
@Query(() => [
|
|
77
|
+
@Query(() => [MJUserFavorite_])
|
|
78
78
|
async UserFavoriteSearchByParams(@Arg('params', () => Int) params: UserFavoriteSearchParams, @Ctx() { providers, userPayload }: AppContext) {
|
|
79
79
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
80
80
|
return await this.findBy(provider, 'User Favorites', params, userPayload.userRecord);
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import { AppContext, Arg, Ctx, Int, Query, Resolver } from '@memberjunction/server';
|
|
2
|
-
import {
|
|
2
|
+
import { MJUser_, MJUserResolverBase } from '../generated/generated.js';
|
|
3
3
|
import { GetReadOnlyProvider } from '../util.js';
|
|
4
4
|
|
|
5
|
-
@Resolver(
|
|
6
|
-
export class UserResolver extends
|
|
7
|
-
@Query(() =>
|
|
5
|
+
@Resolver(MJUser_)
|
|
6
|
+
export class UserResolver extends MJUserResolverBase {
|
|
7
|
+
@Query(() => MJUser_)
|
|
8
8
|
async CurrentUser(@Ctx() context: AppContext) {
|
|
9
9
|
const result = await this.UserByEmail(context.userPayload.email, context);
|
|
10
10
|
console.log('CurrentUser', result);
|
|
11
11
|
return result;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
@Query(() =>
|
|
14
|
+
@Query(() => MJUser_)
|
|
15
15
|
async UserByID(@Arg('ID', () => Int) ID: number, @Ctx() { providers, userPayload }: AppContext) {
|
|
16
16
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
17
17
|
const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { ID }, userPayload.userRecord));
|
|
18
18
|
return this.MapFieldNamesToCodeNames('Users', retVal);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
@Query(() =>
|
|
21
|
+
@Query(() => MJUser_)
|
|
22
22
|
async UserByEmployeeID(@Arg('EmployeeID', () => Int) EmployeeID: number, @Ctx() { providers, userPayload }: AppContext) {
|
|
23
23
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
24
24
|
const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { EmployeeID }, userPayload.userRecord));
|
|
25
25
|
return this.MapFieldNamesToCodeNames('Users', retVal);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
@Query(() =>
|
|
28
|
+
@Query(() => MJUser_)
|
|
29
29
|
async UserByEmail(@Arg('Email', () => String) Email: string, @Ctx() { providers, userPayload }: AppContext) {
|
|
30
30
|
// const searchEmail = userEmailMap[Email] ?? Email;
|
|
31
31
|
const searchEmail = Email;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { EntitySaveOptions, Metadata } from '@memberjunction/core';
|
|
3
3
|
import { AppContext, Arg, Ctx, Int, Query, Resolver, UserPayload } from '@memberjunction/server';
|
|
4
|
-
import {
|
|
4
|
+
import { MJUserView_, MJUserViewResolverBase } from '../generated/generated.js';
|
|
5
5
|
import { UserResolver } from './UserResolver.js';
|
|
6
6
|
import { UserViewEntity, UserViewEntityExtended } from '@memberjunction/core-entities';
|
|
7
7
|
import { GetReadOnlyProvider } from '../util.js';
|
|
8
8
|
|
|
9
|
-
@Resolver(
|
|
10
|
-
export class UserViewResolver extends
|
|
11
|
-
@Query(() => [
|
|
9
|
+
@Resolver(MJUserView_)
|
|
10
|
+
export class UserViewResolver extends MJUserViewResolverBase {
|
|
11
|
+
@Query(() => [MJUserView_])
|
|
12
12
|
async UserViewsByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { providers, userPayload }: AppContext) {
|
|
13
13
|
const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
|
|
14
14
|
return await this.findBy(provider, 'User Views', { UserID }, userPayload.userRecord);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
@Query(() => [
|
|
17
|
+
@Query(() => [MJUserView_])
|
|
18
18
|
async DefaultViewByUserAndEntity(
|
|
19
19
|
@Arg('UserID', () => Int) UserID: number,
|
|
20
20
|
@Arg('EntityID', () => Int) EntityID: number,
|
|
@@ -24,7 +24,7 @@ export class UserViewResolver extends UserViewResolverBase {
|
|
|
24
24
|
return await this.findBy(provider, 'User Views', { UserID, EntityID, IsDefault: true }, userPayload.userRecord);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
@Query(() => [
|
|
27
|
+
@Query(() => [MJUserView_])
|
|
28
28
|
async CurrentUserDefaultViewByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() context: AppContext) {
|
|
29
29
|
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
30
30
|
return await this.findBy(provider, 'User Views', {
|
|
@@ -40,13 +40,13 @@ export class UserViewResolver extends UserViewResolverBase {
|
|
|
40
40
|
return user.ID;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
@Query(() => [
|
|
43
|
+
@Query(() => [MJUserView_])
|
|
44
44
|
async CurrentUserUserViewsByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() context: AppContext) {
|
|
45
45
|
const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
|
|
46
46
|
return this.findBy(provider, 'User Views', { UserID: await this.getCurrentUserID(context), EntityID}, context.userPayload.userRecord);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
@Query(() => [
|
|
49
|
+
@Query(() => [MJUserView_])
|
|
50
50
|
async UpdateWhereClause(@Arg('ID', () => String) ID: string, @Ctx() { userPayload, providers }: AppContext) {
|
|
51
51
|
// in this query we want to update the uesrView record in the DB with a new where clause
|
|
52
52
|
// this should normally not be a factor but we have this exposed in the GraphQL API so that
|