@memberjunction/server 0.9.24 → 0.9.26
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/userViewEntity.server.js +54 -16
- package/dist/entitySubclasses/userViewEntity.server.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/entitySubclasses/userViewEntity.server.ts +59 -18
- package/src/index.ts +1 -0
|
@@ -19,7 +19,7 @@ let UserViewEntity_Server = class UserViewEntity_Server extends core_entities_1.
|
|
|
19
19
|
try {
|
|
20
20
|
const llm = new ai_1.OpenAILLM();
|
|
21
21
|
const chatParams = {
|
|
22
|
-
model: 'gpt-
|
|
22
|
+
model: 'gpt-4',
|
|
23
23
|
systemPrompt: this.GenerateSysPrompt(entityInfo),
|
|
24
24
|
userMessage: '',
|
|
25
25
|
messages: [
|
|
@@ -30,8 +30,32 @@ let UserViewEntity_Server = class UserViewEntity_Server extends core_entities_1.
|
|
|
30
30
|
],
|
|
31
31
|
};
|
|
32
32
|
const result = await llm.ChatCompletion(chatParams);
|
|
33
|
-
if (result && result.data)
|
|
34
|
-
|
|
33
|
+
if (result && result.data) {
|
|
34
|
+
const llmResponse = result.data.choices[0].message.content;
|
|
35
|
+
if (llmResponse) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(llmResponse);
|
|
38
|
+
if (parsed.whereClause && parsed.whereClause.length > 0) {
|
|
39
|
+
const trimmed = parsed.whereClause.trim();
|
|
40
|
+
if (trimmed.toLowerCase().startsWith('where '))
|
|
41
|
+
return trimmed.substring(6);
|
|
42
|
+
else
|
|
43
|
+
return parsed.whereClause;
|
|
44
|
+
}
|
|
45
|
+
else if (parsed.whereClause !== undefined && parsed.whereClause !== null)
|
|
46
|
+
return '';
|
|
47
|
+
else {
|
|
48
|
+
throw new Error('Invalid response from AI, no whereClause property found in response: ' + llmResponse);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
(0, core_1.LogError)(e);
|
|
53
|
+
throw new Error('Error parsing JSON response from AI: ' + llmResponse);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
throw new Error('Null response from AI');
|
|
58
|
+
}
|
|
35
59
|
else
|
|
36
60
|
throw new Error('No result returned from AI');
|
|
37
61
|
}
|
|
@@ -41,6 +65,7 @@ let UserViewEntity_Server = class UserViewEntity_Server extends core_entities_1.
|
|
|
41
65
|
}
|
|
42
66
|
}
|
|
43
67
|
GenerateSysPrompt(entityInfo) {
|
|
68
|
+
const processedViews = [entityInfo.BaseView];
|
|
44
69
|
const md = new core_1.Metadata();
|
|
45
70
|
const gptSysPrompt = `You are an expert in SQL and Microsoft SQL Server.
|
|
46
71
|
You will be provided a user prompt representing how they want to filter the data.
|
|
@@ -66,26 +91,39 @@ ${entityInfo.Fields.map(f => {
|
|
|
66
91
|
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.
|
|
67
92
|
If there are multiple filters related to a single related view, attempt to combine them into a single sub-query for efficiency.
|
|
68
93
|
${fkeyBaseViewsDistinct.map(v => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
if (processedViews.indexOf(v) === -1) {
|
|
95
|
+
const e = md.Entities.find(e => e.BaseView === v);
|
|
96
|
+
if (e) {
|
|
97
|
+
processedViews.push(v);
|
|
98
|
+
return `* ${e.Name}: ${e.Fields.map(ef => ef.Name).join(',')}`;
|
|
99
|
+
}
|
|
100
|
+
else
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
72
103
|
else
|
|
73
104
|
return '';
|
|
74
105
|
}).join('\n')}
|
|
75
106
|
${entityInfo.RelatedEntities.map(r => {
|
|
76
|
-
const e = md.Entities.find(e => e.Name === r.
|
|
77
|
-
if (e)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
ret
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
107
|
+
const e = md.Entities.find(e => e.Name === r.RelatedEntity);
|
|
108
|
+
if (e) {
|
|
109
|
+
if (processedViews.indexOf(e.BaseView) === -1) {
|
|
110
|
+
processedViews.push(e.BaseView);
|
|
111
|
+
return `* ${e.BaseView}: ${e.Fields.map(ef => {
|
|
112
|
+
let ret = `${ef.Name} (${ef.Type})`;
|
|
113
|
+
if (ef.RelatedEntity) {
|
|
114
|
+
ret += ` (fkey to ${ef.RelatedEntityBaseView})`;
|
|
115
|
+
}
|
|
116
|
+
return ret;
|
|
117
|
+
}).join(',')}`;
|
|
118
|
+
}
|
|
119
|
+
else
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
85
122
|
else
|
|
86
123
|
return '';
|
|
87
124
|
}).join('\n')}`;
|
|
88
|
-
return gptSysPrompt + (
|
|
125
|
+
return gptSysPrompt + (processedViews.length > 1 ? relationships : '') + `
|
|
126
|
+
**** REMEMBER **** I am a BOT, do not return anything other than JSON to me or I will choke on your response!`;
|
|
89
127
|
}
|
|
90
128
|
};
|
|
91
129
|
UserViewEntity_Server = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userViewEntity.server.js","sourceRoot":"","sources":["../../src/entitySubclasses/userViewEntity.server.ts"],"names":[],"mappings":";;;;;;;;;AAAA,mDAAiE;AACjE,+CAAkF;AAClF,iEAAsE;AACtE,2CAAsF;AAG/E,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,sCAAsB;IAI7D,IAAuB,sBAAsB;QACzC,OAAO,IAAI,CAAC;IAChB,CAAC;IAOM,KAAK,CAAC,8BAA8B,CAAC,MAAc,EAAE,UAAsB;QAC9E,IAAI;YACA,MAAM,GAAG,GAAW,IAAI,cAAS,EAAE,CAAC;YAEpC,MAAM,UAAU,GAAe;gBAC3B,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"userViewEntity.server.js","sourceRoot":"","sources":["../../src/entitySubclasses/userViewEntity.server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,7 @@ var config_2 = require("./config");
|
|
|
62
62
|
Object.defineProperty(exports, "configInfo", { enumerable: true, get: function () { return config_2.configInfo; } });
|
|
63
63
|
__exportStar(require("./directives"), exports);
|
|
64
64
|
__exportStar(require("./types"), exports);
|
|
65
|
+
__exportStar(require("./entitySubclasses/userViewEntity.server"), exports);
|
|
65
66
|
const serve = async (resolverPaths) => {
|
|
66
67
|
const paths = resolverPaths.flatMap((path) => (0, fast_glob_1.globSync)((0, fast_glob_1.convertPathToPattern)(path)));
|
|
67
68
|
console.log({ resolverPaths, paths });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAA4B;AAE5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,sDAA4D;AAC5D,kDAAqD;AACrD,+CAAgD;AAChD,mFAA2G;AAC3G,6CAAmC;AACnC,gDAAwB;AACxB,sDAA8B;AAC9B,yCAA2D;AAC3D,8CAAkD;AAClD,yCAAyC;AACzC,4BAA0B;AAC1B,+BAAqC;AACrC,+CAAqF;AACrF,qCAAqC;AACrC,2BAAqC;AACrC,kEAA+C;AAC/C,qCAA2G;AAC3G,uCAA4D;AAC5D,6CAA+C;AAC/C,gDAAwB;AAExB,MAAM,oBAAoB,GAAG,mBAAU,CAAC,gBAAgB,CAAC,4BAA4B,CAAC;AAEtF,mDAA4C;AAAnC,4GAAA,SAAS,OAAA;AAClB,+CAA6B;AAC7B,4CAA8C;AAArC,uGAAA,WAAW,OAAA;AACpB,mCAAsC;AAA7B,oGAAA,UAAU,OAAA;AACnB,+CAA6B;AAC7B,0CAAwB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/server",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.26",
|
|
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",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@apollo/server": "^4.9.1",
|
|
23
23
|
"@graphql-tools/utils": "^10.0.1",
|
|
24
|
-
"@memberjunction/ai": "^0.9.
|
|
25
|
-
"@memberjunction/core": "^0.9.
|
|
26
|
-
"@memberjunction/core-entities": "^0.9.
|
|
27
|
-
"@memberjunction/global": "^0.9.
|
|
28
|
-
"@memberjunction/queue": "^0.9.
|
|
29
|
-
"@memberjunction/sqlserver-dataprovider": "^0.9.
|
|
24
|
+
"@memberjunction/ai": "^0.9.40",
|
|
25
|
+
"@memberjunction/core": "^0.9.43",
|
|
26
|
+
"@memberjunction/core-entities": "^0.9.16",
|
|
27
|
+
"@memberjunction/global": "^0.9.43",
|
|
28
|
+
"@memberjunction/queue": "^0.9.40",
|
|
29
|
+
"@memberjunction/sqlserver-dataprovider": "^0.9.39",
|
|
30
30
|
"@types/axios": "^0.14.0",
|
|
31
31
|
"@types/cors": "^2.8.13",
|
|
32
32
|
"@types/jsonwebtoken": "^8.5.9",
|
|
@@ -22,7 +22,7 @@ export class UserViewEntity_Server extends UserViewEntityExtended {
|
|
|
22
22
|
const llm = <IChat> new OpenAILLM(); // for now, hardcoded to use OpenAI
|
|
23
23
|
|
|
24
24
|
const chatParams: ChatParams = {
|
|
25
|
-
model: 'gpt-
|
|
25
|
+
model: 'gpt-4',
|
|
26
26
|
systemPrompt: this.GenerateSysPrompt(entityInfo),
|
|
27
27
|
userMessage: '',
|
|
28
28
|
messages: [
|
|
@@ -33,8 +33,35 @@ export class UserViewEntity_Server extends UserViewEntityExtended {
|
|
|
33
33
|
],
|
|
34
34
|
}
|
|
35
35
|
const result = await llm.ChatCompletion(chatParams);
|
|
36
|
-
if (result && result.data)
|
|
37
|
-
|
|
36
|
+
if (result && result.data) {
|
|
37
|
+
const llmResponse = result.data.choices[0].message.content;
|
|
38
|
+
if (llmResponse) {
|
|
39
|
+
// try to parse it as JSON
|
|
40
|
+
try {
|
|
41
|
+
const parsed = JSON.parse(llmResponse);
|
|
42
|
+
if (parsed.whereClause && parsed.whereClause.length > 0) {
|
|
43
|
+
// we have the where clause. Sometimes the LLM prefixes it with WHERE and somtimes not, we need to strip WHERE if it is there
|
|
44
|
+
const trimmed = parsed.whereClause.trim();
|
|
45
|
+
if (trimmed.toLowerCase().startsWith('where '))
|
|
46
|
+
return trimmed.substring(6);
|
|
47
|
+
else
|
|
48
|
+
return parsed.whereClause;
|
|
49
|
+
}
|
|
50
|
+
else if (parsed.whereClause !== undefined && parsed.whereClause !== null)
|
|
51
|
+
return ''; // empty string is valid, it means no where clause
|
|
52
|
+
else {
|
|
53
|
+
// if we get here, no whereClause property was provided by the LLM, that is an error
|
|
54
|
+
throw new Error('Invalid response from AI, no whereClause property found in response: ' + llmResponse);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
LogError(e);
|
|
59
|
+
throw new Error('Error parsing JSON response from AI: ' + llmResponse);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else
|
|
63
|
+
throw new Error('Null response from AI');
|
|
64
|
+
}
|
|
38
65
|
else
|
|
39
66
|
throw new Error('No result returned from AI');
|
|
40
67
|
}
|
|
@@ -45,6 +72,7 @@ export class UserViewEntity_Server extends UserViewEntityExtended {
|
|
|
45
72
|
}
|
|
46
73
|
|
|
47
74
|
public GenerateSysPrompt(entityInfo: EntityInfo): string {
|
|
75
|
+
const processedViews: string[] = [entityInfo.BaseView];
|
|
48
76
|
const md = new Metadata();
|
|
49
77
|
const gptSysPrompt: string = `You are an expert in SQL and Microsoft SQL Server.
|
|
50
78
|
You will be provided a user prompt representing how they want to filter the data.
|
|
@@ -73,30 +101,43 @@ If there are multiple filters related to a single related view, attempt to combi
|
|
|
73
101
|
${
|
|
74
102
|
// this part returns a list of all the related views and the fields that are related to the current view via fkeys in the current view
|
|
75
103
|
fkeyBaseViewsDistinct.map(v => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
104
|
+
if (processedViews.indexOf(v) === -1) {
|
|
105
|
+
const e = md.Entities.find(e => e.BaseView === v);
|
|
106
|
+
if (e) {
|
|
107
|
+
processedViews.push(v); // already processed this view now, so we won't repeat it
|
|
108
|
+
return `* ${e.Name}: ${e.Fields.map(ef => ef.Name).join(',') }`
|
|
109
|
+
}
|
|
110
|
+
else
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
else
|
|
114
|
+
return ''; // already did this at some point
|
|
81
115
|
}).join('\n')
|
|
82
116
|
}
|
|
83
117
|
${
|
|
84
118
|
// this part returns a list of all the related views and the fields that are related to the current view fkeys in THOSE views
|
|
85
119
|
entityInfo.RelatedEntities.map(r => {
|
|
86
|
-
const e = md.Entities.find(e => e.Name === r.
|
|
87
|
-
if (e)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
ret
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
120
|
+
const e = md.Entities.find(e => e.Name === r.RelatedEntity);
|
|
121
|
+
if (e) {
|
|
122
|
+
if (processedViews.indexOf(e.BaseView) === -1) {
|
|
123
|
+
processedViews.push(e.BaseView); // note that we are processing this view now, so we won't repeat it
|
|
124
|
+
return `* ${e.BaseView}: ${e.Fields.map(ef => {
|
|
125
|
+
let ret: string = `${ef.Name} (${ef.Type})`;
|
|
126
|
+
if (ef.RelatedEntity) {
|
|
127
|
+
ret += ` (fkey to ${ef.RelatedEntityBaseView})`;
|
|
128
|
+
}
|
|
129
|
+
return ret;
|
|
130
|
+
}).join(',') }`
|
|
131
|
+
}
|
|
132
|
+
else
|
|
133
|
+
return ''; // already did this at some point
|
|
134
|
+
}
|
|
95
135
|
else
|
|
96
136
|
return '';
|
|
97
137
|
}).join('\n')
|
|
98
138
|
}`
|
|
99
139
|
|
|
100
|
-
return gptSysPrompt + (
|
|
140
|
+
return gptSysPrompt + (processedViews.length > 1 /*we always have 1 from the entity base view*/ ? relationships : '') + `
|
|
141
|
+
**** REMEMBER **** I am a BOT, do not return anything other than JSON to me or I will choke on your response!`;
|
|
101
142
|
}
|
|
102
143
|
}
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ export { NewUserBase } from './auth/newUsers';
|
|
|
31
31
|
export { configInfo } from './config';
|
|
32
32
|
export * from './directives';
|
|
33
33
|
export * from './types';
|
|
34
|
+
export * from './entitySubclasses/userViewEntity.server'
|
|
34
35
|
|
|
35
36
|
export const serve = async (resolverPaths: Array<string>) => {
|
|
36
37
|
const paths = resolverPaths.flatMap((path) => globSync(convertPathToPattern(path)));
|