@memberjunction/server 2.110.1 → 2.111.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/server",
3
- "version": "2.110.1",
3
+ "version": "2.111.1",
4
4
  "description": "MemberJunction: This project provides API access via GraphQL to the common data store.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./src/index.ts",
@@ -22,42 +22,42 @@
22
22
  "dependencies": {
23
23
  "@apollo/server": "^4.9.1",
24
24
  "@graphql-tools/utils": "^10.0.1",
25
- "@memberjunction/actions": "2.110.1",
26
- "@memberjunction/ai": "2.110.1",
27
- "@memberjunction/ai-core-plus": "2.110.1",
28
- "@memberjunction/ai-agents": "2.110.1",
29
- "@memberjunction/ai-provider-bundle": "2.110.1",
30
- "@memberjunction/aiengine": "2.110.1",
31
- "@memberjunction/ai-prompts": "2.110.1",
32
- "@memberjunction/ai-agent-manager": "2.110.1",
33
- "@memberjunction/ai-agent-manager-actions": "2.110.1",
34
- "@memberjunction/ai-vectors-pinecone": "2.110.1",
35
- "@memberjunction/core": "2.100.3",
36
- "@memberjunction/core-actions": "2.110.1",
37
- "@memberjunction/actions-apollo": "2.110.1",
38
- "@memberjunction/actions-bizapps-accounting": "2.110.1",
39
- "@memberjunction/actions-bizapps-crm": "2.110.1",
40
- "@memberjunction/actions-bizapps-lms": "2.110.1",
41
- "@memberjunction/actions-bizapps-social": "2.110.1",
42
- "@memberjunction/component-registry-client-sdk": "2.110.1",
43
- "@memberjunction/core-entities": "2.110.1",
44
- "@memberjunction/core-entities-server": "2.110.1",
45
- "@memberjunction/data-context": "2.110.1",
46
- "@memberjunction/data-context-server": "2.110.1",
47
- "@memberjunction/doc-utils": "2.110.1",
48
- "@memberjunction/entity-communications-server": "2.110.1",
49
- "@memberjunction/external-change-detection": "2.110.1",
50
- "@memberjunction/global": "2.100.3",
51
- "@memberjunction/graphql-dataprovider": "2.110.1",
52
- "@memberjunction/queue": "2.110.1",
53
- "@memberjunction/scheduling-base-types": "2.110.1",
54
- "@memberjunction/scheduling-engine-base": "2.110.1",
55
- "@memberjunction/scheduling-engine": "2.110.1",
56
- "@memberjunction/scheduling-actions": "2.110.1",
57
- "@memberjunction/skip-types": "2.110.1",
58
- "@memberjunction/sqlserver-dataprovider": "2.110.1",
59
- "@memberjunction/storage": "2.110.1",
60
- "@memberjunction/templates": "2.110.1",
25
+ "@memberjunction/actions": "2.111.1",
26
+ "@memberjunction/actions-apollo": "2.111.1",
27
+ "@memberjunction/actions-bizapps-accounting": "2.111.1",
28
+ "@memberjunction/actions-bizapps-crm": "2.111.1",
29
+ "@memberjunction/actions-bizapps-lms": "2.111.1",
30
+ "@memberjunction/actions-bizapps-social": "2.111.1",
31
+ "@memberjunction/ai": "2.111.1",
32
+ "@memberjunction/ai-agent-manager": "2.111.1",
33
+ "@memberjunction/ai-agent-manager-actions": "2.111.1",
34
+ "@memberjunction/ai-agents": "2.111.1",
35
+ "@memberjunction/ai-core-plus": "2.111.1",
36
+ "@memberjunction/ai-prompts": "2.111.1",
37
+ "@memberjunction/ai-provider-bundle": "2.111.1",
38
+ "@memberjunction/ai-vectors-pinecone": "2.111.1",
39
+ "@memberjunction/aiengine": "2.111.1",
40
+ "@memberjunction/component-registry-client-sdk": "2.111.1",
41
+ "@memberjunction/core": "2.111.1",
42
+ "@memberjunction/core-actions": "2.111.1",
43
+ "@memberjunction/core-entities": "2.111.1",
44
+ "@memberjunction/core-entities-server": "2.111.1",
45
+ "@memberjunction/data-context": "2.111.1",
46
+ "@memberjunction/data-context-server": "2.111.1",
47
+ "@memberjunction/doc-utils": "2.111.1",
48
+ "@memberjunction/entity-communications-server": "2.111.1",
49
+ "@memberjunction/external-change-detection": "2.111.1",
50
+ "@memberjunction/global": "2.111.1",
51
+ "@memberjunction/graphql-dataprovider": "2.111.1",
52
+ "@memberjunction/queue": "2.111.1",
53
+ "@memberjunction/scheduling-actions": "2.111.1",
54
+ "@memberjunction/scheduling-base-types": "2.111.1",
55
+ "@memberjunction/scheduling-engine": "2.111.1",
56
+ "@memberjunction/scheduling-engine-base": "2.111.1",
57
+ "@memberjunction/skip-types": "2.111.1",
58
+ "@memberjunction/sqlserver-dataprovider": "2.111.1",
59
+ "@memberjunction/storage": "2.111.1",
60
+ "@memberjunction/templates": "2.111.1",
61
61
  "@types/compression": "^1.7.5",
62
62
  "@types/cors": "^2.8.13",
63
63
  "@types/jsonwebtoken": "9.0.6",
@@ -66,7 +66,7 @@
66
66
  "axios": "^1.6.7",
67
67
  "body-parser": "^1.20.2",
68
68
  "class-validator": "^0.14.0",
69
- "cloudevents": "^8.0.2",
69
+ "cloudevents": "^10",
70
70
  "compression": "^1.7.4",
71
71
  "cors": "^2.8.5",
72
72
  "cosmiconfig": "9.0.0",
@@ -91,7 +91,12 @@
91
91
  "zod": "^3.23.4"
92
92
  },
93
93
  "devDependencies": {
94
+ "@jest/globals": "^30.2.0",
94
95
  "pkgroll": "2.1.1",
95
96
  "typescript": "^5.4.5"
97
+ },
98
+ "repository": {
99
+ "type": "git",
100
+ "url": "https://github.com/MemberJunction/MJ"
96
101
  }
97
102
  }
@@ -21,17 +21,19 @@ import {
21
21
  SkipEntityRelationshipInfo,
22
22
  SkipAPIAgentNote,
23
23
  SkipAPIAgentNoteType,
24
- SkipAPIArtifact
24
+ SkipAPIArtifact,
25
+ SkipAPIArtifactVersion,
26
+ SkipAPIArtifactType
25
27
  } from '@memberjunction/skip-types';
26
28
  import { DataContext } from '@memberjunction/data-context';
27
- import { UserInfo, LogStatus, LogError, Metadata, RunView, EntityInfo, EntityFieldInfo, EntityRelationshipInfo } from '@memberjunction/core';
29
+ import { UserInfo, LogStatus, LogError, Metadata, RunQuery, EntityInfo, EntityFieldInfo, EntityRelationshipInfo } from '@memberjunction/core';
28
30
  import { sendPostRequest } from '../util.js';
29
31
  import { configInfo, baseUrl, publicUrl, graphqlPort, graphqlRootPath, apiKey as callbackAPIKey } from '../config.js';
30
32
  import { GetAIAPIKey } from '@memberjunction/ai';
33
+ import { AIEngine } from '@memberjunction/aiengine';
31
34
  import { CopyScalarsAndArrays } from '@memberjunction/global';
32
35
  import mssql from 'mssql';
33
36
  import { registerAccessToken, GetDataAccessToken } from '../resolvers/GetDataResolver.js';
34
- import { ArtifactTypeEntity } from '@memberjunction/core-entities';
35
37
  import { BehaviorSubject } from 'rxjs';
36
38
  import { take } from 'rxjs/operators';
37
39
 
@@ -451,104 +453,115 @@ export class SkipSDK {
451
453
  }
452
454
 
453
455
  /**
454
- * Build artifacts for a conversation
455
- * Uses ConversationDetailArtifact join table to get artifacts that were outputs from previous conversation details
456
- * Direction = 'Output' means the artifact was generated by Skip, Direction = 'Input' means it was passed in
457
- * Note: ConversationArtifact entity is deprecated - we now use the core Artifact entity
456
+ * Build artifacts for a conversation using optimized query
457
+ * Uses GetConversationArtifactsForAgent query which joins through ConversationDetailArtifact
458
+ * to get artifacts that were outputs from Skip agent's conversation details
458
459
  */
459
460
  private async buildArtifacts(contextUser: UserInfo, dataSource: mssql.ConnectionPool, conversationId: string): Promise<SkipAPIArtifact[]> {
460
- const rv = new RunView();
461
+ try {
462
+ const rq = new RunQuery();
461
463
 
462
- // Query ConversationDetailArtifact to find artifacts that were outputs (generated by Skip)
463
- // These are the artifacts we want to pass back as context for future requests
464
- const results = await rv.RunViews([
465
- {
466
- EntityName: "MJ: Conversation Detail Artifacts",
467
- ExtraFilter: `Direction='Output' AND ConversationDetailID IN (SELECT ID FROM [${Metadata.Provider.ConfigData.MJCoreSchemaName}].[vwConversationDetails] WHERE ConversationID='${conversationId}')`,
468
- OrderBy: "__mj_CreatedAt"
469
- },
470
- {
471
- EntityName: "MJ: Artifacts",
472
- OrderBy: "__mj_CreatedAt"
473
- },
474
- {
475
- EntityName: "MJ: Artifact Types",
476
- OrderBy: "Name"
477
- },
478
- {
479
- EntityName: "MJ: Artifact Versions",
480
- OrderBy: 'ArtifactID, __mj_CreatedAt'
464
+ // Ensure AIEngine is configured and get Skip agent ID
465
+ await AIEngine.Instance.Config(false, contextUser);
466
+ const skipAgent = AIEngine.Instance.GetAgentByName('Skip');
467
+ const skipAgentId = skipAgent?.ID;
468
+
469
+ if (!skipAgentId) {
470
+ LogError('[SkipSDK] Skip agent not found in AIEngine');
481
471
  }
482
- ], contextUser);
483
472
 
484
- if (!results || results.length === 0 || !results.every(r => r.Success)) {
485
- return [];
486
- }
473
+ // Use optimized query that replaces 4 RunView calls with 1 query
474
+ // This query includes Configuration field needed for component spec extraction
475
+ // Filter by Skip agent ID to only get artifacts created by Skip (not delegation agents)
476
+ const result = await rq.RunQuery({
477
+ QueryName: 'GetConversationArtifactsForAgent',
478
+ CategoryPath: 'MJ/Conversations',
479
+ Parameters: {
480
+ ConversationID: conversationId,
481
+ AgentID: skipAgentId // Filter to only artifacts created by Skip agent
482
+ }
483
+ }, contextUser);
487
484
 
488
- // Get the artifact VERSION IDs from ConversationDetailArtifact where Direction='Output'
489
- // ConversationDetailArtifact links to ArtifactVersionID, not ArtifactID directly
490
- const outputVersionIds = new Set(
491
- results[0].Results
492
- .map((cda: any) => cda.ArtifactVersionID)
493
- .filter(id => id) // Filter out null/undefined
494
- );
485
+ if (!result.Success || !result.Results || result.Results.length === 0) {
486
+ return [];
487
+ }
495
488
 
496
- const types = results[2].Results.map((a: ArtifactTypeEntity) => ({
497
- id: a.ID,
498
- name: a.Name,
499
- description: a.Description,
500
- contentType: a.ContentType,
501
- enabled: a.IsEnabled,
502
- createdAt: a.__mj_CreatedAt,
503
- updatedAt: a.__mj_UpdatedAt
504
- }));
489
+ // Query returns flat result set: one row per artifact version
490
+ // Group by ArtifactID to build SkipAPIArtifact objects with their versions
491
+ const artifactMap = new Map<string, {
492
+ artifact: any,
493
+ artifactType: SkipAPIArtifactType,
494
+ versions: SkipAPIArtifactVersion[]
495
+ }>();
496
+
497
+ // Process each row (represents one version)
498
+ for (const row of result.Results) {
499
+ const artifactId = row.ArtifactID;
500
+
501
+ // Initialize artifact entry if not exists
502
+ if (!artifactMap.has(artifactId)) {
503
+ // Map database sharingScope values to SkipAPIArtifact expected values
504
+ let sharingScope: 'None' | 'SpecificUsers' | 'Everyone' | 'Public' = 'None';
505
+ const dbSharingScope = (row.SharingScope || '').toLowerCase();
506
+ if (dbSharingScope === 'always' || dbSharingScope === 'everyone') {
507
+ sharingScope = 'Everyone';
508
+ } else if (dbSharingScope === 'public') {
509
+ sharingScope = 'Public';
510
+ } else if (dbSharingScope === 'specific users' || dbSharingScope === 'specificusers') {
511
+ sharingScope = 'SpecificUsers';
512
+ }
505
513
 
506
- // Get the versions that were outputs
507
- const allVersions: any[] = results[3].Results as any[];
508
- const outputVersions = allVersions.filter(v => outputVersionIds.has(v.ID));
514
+ artifactMap.set(artifactId, {
515
+ artifact: {
516
+ id: artifactId,
517
+ conversationId: conversationId,
518
+ name: row.ArtifactName,
519
+ description: row.ArtifactDescription || '',
520
+ sharingScope: sharingScope,
521
+ comments: row.ArtifactComments || '',
522
+ createdAt: new Date(row.ArtifactCreatedAt),
523
+ updatedAt: new Date(row.ArtifactUpdatedAt)
524
+ },
525
+ artifactType: {
526
+ id: row.ArtifactTypeID,
527
+ name: row.ArtifactTypeName,
528
+ description: row.ArtifactTypeDescription,
529
+ contentType: row.ArtifactTypeContentType,
530
+ enabled: true,
531
+ createdAt: new Date(row.ArtifactTypeCreatedAt),
532
+ updatedAt: new Date(row.ArtifactTypeUpdatedAt)
533
+ },
534
+ versions: []
535
+ });
536
+ }
509
537
 
510
- // Group versions by their parent ArtifactID to build SkipAPIArtifact objects
511
- const versionsByArtifactId = new Map<string, any[]>();
512
- outputVersions.forEach(v => {
513
- if (!versionsByArtifactId.has(v.ArtifactID)) {
514
- versionsByArtifactId.set(v.ArtifactID, []);
538
+ // Add this version to the artifact
539
+ const entry = artifactMap.get(artifactId)!;
540
+ entry.versions.push({
541
+ id: row.VersionID,
542
+ artifactId: artifactId,
543
+ conversationDetailID: row.ConversationDetailID, // Direct from join table!
544
+ version: row.Version,
545
+ configuration: row.Configuration || '',
546
+ content: row.Content || '',
547
+ comments: row.VersionComments || '',
548
+ createdAt: new Date(row.VersionCreatedAt),
549
+ updatedAt: new Date(row.VersionUpdatedAt)
550
+ });
515
551
  }
516
- versionsByArtifactId.get(v.ArtifactID)!.push(v);
517
- });
518
-
519
- const allArtifacts = results[1].Results as any[];
520
- const artifacts = allArtifacts
521
- .filter(a => versionsByArtifactId.has(a.ID)) // Only include artifacts that have output versions
522
- .map((a: any) => {
523
- const thisArtifactsVersions = versionsByArtifactId.get(a.ID) || [];
524
-
525
- const versions = thisArtifactsVersions.map((v: any) => ({
526
- id: v.ID,
527
- artifactId: v.ArtifactID,
528
- version: v.Version,
529
- configuration: v.Configuration,
530
- content: v.Content,
531
- comments: v.Comments,
532
- createdAt: v.__mj_CreatedAt,
533
- updatedAt: v.__mj_UpdatedAt
534
- }));
535
552
 
536
- return {
537
- id: a.ID,
538
- conversationId: conversationId, // Set from parameter since Artifact doesn't have ConversationID
539
- name: a.Name,
540
- description: a.Description,
541
- artifactType: types.find(t => t.id === a.ArtifactTypeID),
542
- sharingScope: a.SharingScope,
543
- currentVersion: versions.length > 0 ? Math.max(...versions.map(v => v.version)) : 1,
544
- versions,
545
- comments: a.Comments || '', // Use artifact comments if available
546
- createdAt: a.__mj_CreatedAt,
547
- updatedAt: a.__mj_UpdatedAt
548
- };
549
- });
553
+ // Convert map to SkipAPIArtifact array
554
+ const artifacts: SkipAPIArtifact[] = Array.from(artifactMap.values()).map(entry => ({
555
+ ...entry.artifact,
556
+ artifactType: entry.artifactType,
557
+ versions: entry.versions
558
+ }));
550
559
 
551
- return artifacts;
560
+ return artifacts;
561
+ } catch (error) {
562
+ LogError(`Failed to build artifacts for conversation ${conversationId}: ${error}`);
563
+ return [];
564
+ }
552
565
  }
553
566
 
554
567
  /**