@futdevpro/nts-dynamo 1.10.23 → 1.10.25
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/build/_modules/oauth2/_routes/oauth2.controller.d.ts +17 -0
- package/build/_modules/oauth2/_routes/oauth2.controller.d.ts.map +1 -0
- package/build/_modules/oauth2/_routes/oauth2.controller.js +97 -0
- package/build/_modules/oauth2/_routes/oauth2.controller.js.map +1 -0
- package/build/_modules/oauth2/_services/oauth2.auth-service.d.ts +31 -0
- package/build/_modules/oauth2/_services/oauth2.auth-service.d.ts.map +1 -0
- package/build/_modules/oauth2/_services/oauth2.auth-service.js +216 -0
- package/build/_modules/oauth2/_services/oauth2.auth-service.js.map +1 -0
- package/build/_modules/oauth2/_services/oauth2.control-service.d.ts +133 -0
- package/build/_modules/oauth2/_services/oauth2.control-service.d.ts.map +1 -0
- package/build/_modules/oauth2/_services/oauth2.control-service.js +574 -0
- package/build/_modules/oauth2/_services/oauth2.control-service.js.map +1 -0
- package/build/_modules/oauth2/index.d.ts +4 -0
- package/build/_modules/oauth2/index.d.ts.map +1 -0
- package/build/_modules/oauth2/index.js +7 -0
- package/build/_modules/oauth2/index.js.map +1 -0
- package/build/_modules/open-ai/_enums/open-ai-model.enum.d.ts +11 -0
- package/build/_modules/open-ai/_enums/open-ai-model.enum.d.ts.map +1 -0
- package/build/_modules/open-ai/_enums/open-ai-model.enum.js +110 -0
- package/build/_modules/open-ai/_enums/open-ai-model.enum.js.map +1 -0
- package/build/_modules/open-ai/_models/gpt-call-settings.interface.d.ts +54 -0
- package/build/_modules/open-ai/_models/gpt-call-settings.interface.d.ts.map +1 -0
- package/build/_modules/open-ai/_models/gpt-call-settings.interface.js +65 -0
- package/build/_modules/open-ai/_models/gpt-call-settings.interface.js.map +1 -0
- package/build/_modules/open-ai/_models/open-ai-api-env-settings.interface.d.ts +7 -0
- package/build/_modules/open-ai/_models/open-ai-api-env-settings.interface.d.ts.map +1 -0
- package/build/_modules/open-ai/_models/open-ai-api-env-settings.interface.js +3 -0
- package/build/_modules/open-ai/_models/open-ai-api-env-settings.interface.js.map +1 -0
- package/build/_modules/open-ai/_models/open-ai-settings.interface.d.ts +17 -0
- package/build/_modules/open-ai/_models/open-ai-settings.interface.d.ts.map +1 -0
- package/build/_modules/open-ai/_models/open-ai-settings.interface.js +25 -0
- package/build/_modules/open-ai/_models/open-ai-settings.interface.js.map +1 -0
- package/build/_modules/open-ai/_services/embedding.control-service.d.ts +26 -0
- package/build/_modules/open-ai/_services/embedding.control-service.d.ts.map +1 -0
- package/build/_modules/open-ai/_services/embedding.control-service.js +54 -0
- package/build/_modules/open-ai/_services/embedding.control-service.js.map +1 -0
- package/build/_modules/open-ai/_services/gpt.service-base.d.ts +98 -0
- package/build/_modules/open-ai/_services/gpt.service-base.d.ts.map +1 -0
- package/build/_modules/open-ai/_services/gpt.service-base.js +284 -0
- package/build/_modules/open-ai/_services/gpt.service-base.js.map +1 -0
- package/build/_modules/open-ai/_services/open-ai.service-base.d.ts +23 -0
- package/build/_modules/open-ai/_services/open-ai.service-base.d.ts.map +1 -0
- package/build/_modules/open-ai/_services/open-ai.service-base.js +50 -0
- package/build/_modules/open-ai/_services/open-ai.service-base.js.map +1 -0
- package/build/_modules/open-ai/index.d.ts +8 -0
- package/build/_modules/open-ai/index.d.ts.map +1 -0
- package/build/_modules/open-ai/index.js +11 -0
- package/build/_modules/open-ai/index.js.map +1 -0
- package/build/_services/base/db.service.d.ts +38 -0
- package/build/_services/base/db.service.d.ts.map +1 -1
- package/build/_services/base/db.service.js +40 -0
- package/build/_services/base/db.service.js.map +1 -1
- package/build/_services/server/app.server.d.ts +17 -0
- package/build/_services/server/app.server.d.ts.map +1 -1
- package/build/_services/server/app.server.js +17 -0
- package/build/_services/server/app.server.js.map +1 -1
- package/package.json +47 -17
- package/src/_modules/oauth2/_routes/oauth2.controller.ts +99 -0
- package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -0
- package/src/_modules/oauth2/_services/oauth2.control-service.ts +651 -0
- package/src/_modules/oauth2/index.ts +9 -0
- package/src/_modules/open-ai/_enums/open-ai-model.enum.ts +137 -0
- package/src/_modules/open-ai/_models/gpt-call-settings.interface.ts +69 -0
- package/src/_modules/open-ai/_models/open-ai-api-env-settings.interface.ts +12 -0
- package/src/_modules/open-ai/_models/open-ai-settings.interface.ts +31 -0
- package/src/_modules/open-ai/_services/embedding.control-service.ts +61 -0
- package/src/_modules/open-ai/_services/gpt.service-base.ts +440 -0
- package/src/_modules/open-ai/_services/open-ai.service-base.ts +73 -0
- package/src/_modules/open-ai/index.ts +13 -0
- package/src/_services/base/db.service.ts +41 -0
- package/src/_services/server/app.server.ts +18 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
|
|
2
|
+
import { OpenAI, ClientOptions } from 'openai';
|
|
3
|
+
import { ChatCompletion, ChatCompletionMessageParam } from 'openai/resources';
|
|
4
|
+
|
|
5
|
+
import { DyFM_AnyError, DyFM_Error, DyFM_Error_Settings, DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
6
|
+
|
|
7
|
+
import { DyNTS_OpenAIModel } from '../_enums/open-ai-model.enum';
|
|
8
|
+
import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
|
|
9
|
+
import { DyNTS_OpenAI_ServiceBase } from './open-ai.service-base';
|
|
10
|
+
import { DyNTS_GPTCall_Settings } from '../_models/gpt-call-settings.interface';
|
|
11
|
+
import { RequestOptions } from 'openai/core';
|
|
12
|
+
import { ChatCompletionCreateParamsBase } from 'openai/resources/chat/completions';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* {
|
|
16
|
+
organization: 'org-XY',
|
|
17
|
+
apiKey: 'sk-XY',
|
|
18
|
+
project: 'proj_XY',
|
|
19
|
+
}
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// Di Dictionary DiModel DiEz DiAz
|
|
23
|
+
|
|
24
|
+
export class DyNTS_GPT_ServiceBase extends DyNTS_OpenAI_ServiceBase {
|
|
25
|
+
|
|
26
|
+
defaultLogReplacer: string = '...';
|
|
27
|
+
|
|
28
|
+
async askYesNoQuestion(
|
|
29
|
+
question: string,
|
|
30
|
+
issuer: string,
|
|
31
|
+
replaceThisInLog?: string
|
|
32
|
+
): Promise<boolean> {
|
|
33
|
+
question += ' (Only answer with "Yes" or "No")';
|
|
34
|
+
|
|
35
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
36
|
+
|
|
37
|
+
const answer = await this.getQuestionAnswer(question, issuer);
|
|
38
|
+
|
|
39
|
+
return answer.toUpperCase().includes('YES');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async askSimpleQuestion(
|
|
43
|
+
question: string,
|
|
44
|
+
issuer: string,
|
|
45
|
+
replaceThisInLog?: string
|
|
46
|
+
): Promise<string> {
|
|
47
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
48
|
+
|
|
49
|
+
return await this.getQuestionAnswer(question, issuer);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async askPercentageQuestion(
|
|
53
|
+
question: string,
|
|
54
|
+
issuer: string,
|
|
55
|
+
replaceThisInLog?: string
|
|
56
|
+
): Promise<number> {
|
|
57
|
+
question += ' (Only answer with a number between 0 and 1, e.g.: 0.65)';
|
|
58
|
+
|
|
59
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
60
|
+
|
|
61
|
+
const answer = await this.getQuestionAnswer(question, issuer);
|
|
62
|
+
|
|
63
|
+
if (isNaN(+answer)) {
|
|
64
|
+
DyFM_Log.error('GPT_ServiceBase', 'asykPercentageQuestion', 'Invalid answer', {
|
|
65
|
+
question,
|
|
66
|
+
answer,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return +answer;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async askSelectQuestion(
|
|
76
|
+
question: string,
|
|
77
|
+
selectFrom: string[],
|
|
78
|
+
issuer: string,
|
|
79
|
+
replaceThisInLog?: string
|
|
80
|
+
): Promise<string> {
|
|
81
|
+
question += ` (Only answer with one of the following: ${this.getListAsText(selectFrom)})`;
|
|
82
|
+
|
|
83
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
84
|
+
|
|
85
|
+
let answer = await this.getQuestionAnswer(question, issuer);
|
|
86
|
+
|
|
87
|
+
answer = answer.toLocaleUpperCase();
|
|
88
|
+
|
|
89
|
+
for (const item of selectFrom) {
|
|
90
|
+
if (answer.includes(item.toLocaleUpperCase())) return item;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async askMultipleSelectQuestionWithOptions(
|
|
97
|
+
question: string,
|
|
98
|
+
options: string[],
|
|
99
|
+
issuer: string,
|
|
100
|
+
replaceThisInLog?: string
|
|
101
|
+
): Promise<string[]> {
|
|
102
|
+
question += (` (You can choose one or more of the following: ${this.getListAsText(options)})`);
|
|
103
|
+
|
|
104
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
105
|
+
|
|
106
|
+
let answer = await this.getQuestionAnswer(question, issuer);
|
|
107
|
+
|
|
108
|
+
answer = answer.toLocaleUpperCase();
|
|
109
|
+
|
|
110
|
+
const result: string[] = [];
|
|
111
|
+
|
|
112
|
+
for (const item of options) {
|
|
113
|
+
if (answer.includes(item.toLocaleUpperCase())) {
|
|
114
|
+
result.push(item);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Azt kérjük tőle, hogy adjon egy JSON formában választ.
|
|
123
|
+
* Amit aztán megpróbálunk JSON.parse-olni.
|
|
124
|
+
* Ha nem sikerül, akkor { unparsable: answer }-t adunk vissza.
|
|
125
|
+
*/
|
|
126
|
+
async askJSONQuestion(
|
|
127
|
+
question: string,
|
|
128
|
+
issuer: string,
|
|
129
|
+
replaceThisInLog?: string
|
|
130
|
+
): Promise<any> {
|
|
131
|
+
question += ' (The answer must be in JSON format)';
|
|
132
|
+
|
|
133
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
134
|
+
|
|
135
|
+
const answer = await this.getQuestionAnswer(question, issuer);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
// replace all ```json, ```, \n
|
|
139
|
+
return JSON.parse(
|
|
140
|
+
answer.replaceAll('```json', '').replaceAll('```', '').replaceAll('\n', '')
|
|
141
|
+
);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
return {
|
|
144
|
+
unparsable: answer,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Azt kérjük tőle, hogy adjon egy JSON formában választ.
|
|
151
|
+
* Amit aztán megpróbálunk JSON.parse-olni.
|
|
152
|
+
* Ha nem sikerül, akkor { unparsable: answer }-t adunk vissza.
|
|
153
|
+
*
|
|
154
|
+
* A keysDescription-be leírjuk, milyen kulcsokat várunk. (nem konkrét kulcsneveket)
|
|
155
|
+
*/
|
|
156
|
+
async askJSONQuestionWithKeysDescription(
|
|
157
|
+
question: string,
|
|
158
|
+
keysDescription: string,
|
|
159
|
+
issuer: string,
|
|
160
|
+
replaceThisInLog?: string
|
|
161
|
+
): Promise<any> {
|
|
162
|
+
question += ` (The answer must be in JSON format, ${keysDescription})`;
|
|
163
|
+
|
|
164
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
165
|
+
|
|
166
|
+
const answer = await this.getQuestionAnswer(question, issuer);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
// replace all ```json, ```, \n
|
|
170
|
+
return JSON.parse(
|
|
171
|
+
answer.replaceAll('```json', '').replaceAll('```', '').replaceAll('\n', '')
|
|
172
|
+
);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return {
|
|
175
|
+
unparsable: answer,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Azt kérjük tőle, hogy adjon egy JSON formában választ.
|
|
182
|
+
* Amit aztán megpróbálunk JSON.parse-olni.
|
|
183
|
+
* Ha nem sikerül, akkor { unparsable: answer }-t adunk vissza.
|
|
184
|
+
*
|
|
185
|
+
* A keys-be leírjuk a konkrét kulcsneveket.
|
|
186
|
+
*/
|
|
187
|
+
async askJSONQuestionWithExactKeys(
|
|
188
|
+
question: string,
|
|
189
|
+
keys: string[],
|
|
190
|
+
issuer: string,
|
|
191
|
+
replaceThisInLog?: string
|
|
192
|
+
): Promise<any> {
|
|
193
|
+
question += ` (The answer must be in JSON format, ` +
|
|
194
|
+
`where the keys are: ${this.getListAsText(keys)})`;
|
|
195
|
+
|
|
196
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
197
|
+
|
|
198
|
+
const answer = await this.getQuestionAnswer(question, issuer);
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
// replace all ```json, ```, \n
|
|
202
|
+
return JSON.parse(
|
|
203
|
+
answer.replaceAll('```json', '').replaceAll('```', '').replaceAll('\n', '')
|
|
204
|
+
);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
return {
|
|
207
|
+
unparsable: answer,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async askListQuestion(
|
|
213
|
+
question: string,
|
|
214
|
+
issuer: string,
|
|
215
|
+
replaceThisInLog?: string
|
|
216
|
+
): Promise<string[]> {
|
|
217
|
+
question += ' (The answer must be in JSON format, a list of strings)';
|
|
218
|
+
|
|
219
|
+
this.logQuestion(question, issuer, replaceThisInLog);
|
|
220
|
+
|
|
221
|
+
const answer = await this.getQuestionAnswer(question, issuer);
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const parsed = JSON.parse(
|
|
225
|
+
answer.replaceAll('```json', '').replaceAll('```', '').replaceAll('\n', '')
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
if (Array.isArray(parsed)) {
|
|
229
|
+
return parsed;
|
|
230
|
+
} else if (typeof parsed === 'object') {
|
|
231
|
+
return Object.values(parsed);
|
|
232
|
+
} else {
|
|
233
|
+
DyFM_Log.error('GPT_ServiceBase', 'askListQuestion', 'Invalid answer', {
|
|
234
|
+
question,
|
|
235
|
+
answer,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
return [ parsed ];
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
return answer.split('\n').filter(item => item);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private logQuestion(question: string, issuer: string, replaceThisInLog?: string): void {
|
|
246
|
+
if (this.debugLog) {
|
|
247
|
+
if (replaceThisInLog) {
|
|
248
|
+
question = question.replace(replaceThisInLog, this.defaultLogReplacer);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
console.log('\n - ', question);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* This function will log the answer if the debugLog is true
|
|
257
|
+
*/
|
|
258
|
+
async getQuestionAnswer(
|
|
259
|
+
question: string,
|
|
260
|
+
issuer: string,
|
|
261
|
+
messageSettings: DyNTS_GPTCall_Settings = this.defaultSettings
|
|
262
|
+
): Promise<string> {
|
|
263
|
+
const answer = await this.resolveSimpleUserMessage(question, issuer, messageSettings);
|
|
264
|
+
|
|
265
|
+
console.log(' - ', answer);
|
|
266
|
+
|
|
267
|
+
return answer;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* olvasható mondatszerű-listaszerű formába teszi a listaelemeket
|
|
272
|
+
* pl.: ['a', 'b', 'c'] -> '"a", "b" or "c"'
|
|
273
|
+
*/
|
|
274
|
+
getListAsText(list: string[]): string {
|
|
275
|
+
list = list.filter(item => item?.trim()).map(item => `"${item}"`);
|
|
276
|
+
|
|
277
|
+
/* list = list.map(item => item.toLocaleLowerCase()); */
|
|
278
|
+
|
|
279
|
+
list.push(list.pop() + ' or ' + list.pop());
|
|
280
|
+
|
|
281
|
+
return list.join(', ');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* This function will log the question and the answer if the debugLog is true
|
|
286
|
+
*/
|
|
287
|
+
async getAnswer(
|
|
288
|
+
question: string,
|
|
289
|
+
issuer: string,
|
|
290
|
+
settings?: DyNTS_GPTCall_Settings
|
|
291
|
+
): Promise<string> {
|
|
292
|
+
if (this.debugLog) {
|
|
293
|
+
console.log('\n - ', question);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const answer = await this.resolveSimpleUserMessage(question, issuer, settings);
|
|
297
|
+
|
|
298
|
+
if (this.debugLog) {
|
|
299
|
+
console.log(' - ', answer);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return answer;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async resolveSimpleUserMessage(
|
|
306
|
+
message: string,
|
|
307
|
+
issuer: string,
|
|
308
|
+
settings?: DyNTS_GPTCall_Settings
|
|
309
|
+
): Promise<string> {
|
|
310
|
+
return this.resolveConversation(
|
|
311
|
+
[{ role: 'user', content: message }],
|
|
312
|
+
issuer,
|
|
313
|
+
settings,
|
|
314
|
+
false
|
|
315
|
+
) as Promise<string>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async resolveConversation(
|
|
319
|
+
conversation: DyNTS_GPT_Message[],
|
|
320
|
+
issuer: string,
|
|
321
|
+
settings?: DyNTS_GPTCall_Settings,
|
|
322
|
+
getFullResponse?: boolean
|
|
323
|
+
): Promise<string | ChatCompletion> {
|
|
324
|
+
try {
|
|
325
|
+
const result: ChatCompletion = await this.openai.chat.completions.create(
|
|
326
|
+
this.getMessageCreateInput(conversation, issuer, settings)
|
|
327
|
+
) as ChatCompletion;
|
|
328
|
+
|
|
329
|
+
if (getFullResponse) {
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return result.choices[0].message.content;
|
|
334
|
+
} catch (error) {
|
|
335
|
+
throw new DyFM_Error({
|
|
336
|
+
...this.getDefaultErrorSettings('resolveConversation', error, issuer),
|
|
337
|
+
|
|
338
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-OAB-RC0`,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* TODO: Overview this: maybe it should use each setting from default if not provided here
|
|
345
|
+
*/
|
|
346
|
+
private getMessageCreateInput(
|
|
347
|
+
messages: DyNTS_GPT_Message[],
|
|
348
|
+
issuer: string,
|
|
349
|
+
settings: DyNTS_GPTCall_Settings = this.defaultSettings
|
|
350
|
+
): ChatCompletionCreateParamsBase {
|
|
351
|
+
try {
|
|
352
|
+
messages.unshift(this.getDefaultSystemMessage(settings));
|
|
353
|
+
|
|
354
|
+
const result: ChatCompletionCreateParamsBase = {
|
|
355
|
+
model: settings.useModel ?? this.defaultModel,
|
|
356
|
+
messages: messages as ChatCompletionMessageParam[],
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
if (DyFM_notNull(settings.temperature)) {
|
|
360
|
+
result.temperature = settings.temperature;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (DyFM_notNull(settings.maxTokens)) {
|
|
364
|
+
result.max_tokens = settings.maxTokens;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (DyFM_notNull(settings.topP)) {
|
|
368
|
+
result.top_p = settings.topP;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (DyFM_notNull(settings.frequencyPenalty)) {
|
|
372
|
+
result.frequency_penalty = settings.frequencyPenalty;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (DyFM_notNull(settings.presencePenalty)) {
|
|
376
|
+
result.presence_penalty = settings.presencePenalty;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return result;
|
|
380
|
+
} catch (error) {
|
|
381
|
+
throw new DyFM_Error({
|
|
382
|
+
...this.getDefaultErrorSettings('getMessageCreateSettings', error, issuer),
|
|
383
|
+
|
|
384
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-OAB-RC0`,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
private getDefaultSystemMessage(settings: DyNTS_GPTCall_Settings): DyNTS_GPT_Message {
|
|
390
|
+
return {
|
|
391
|
+
role: DyNTS_GPT_Message_Role.system,
|
|
392
|
+
content: settings.systemPrompt || this.defaultSystemPrompt,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export interface DyNTS_GPT_Message {
|
|
398
|
+
role: DyNTS_GPT_Message_Role | string;
|
|
399
|
+
content: string;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export enum DyNTS_GPT_Message_Role {
|
|
403
|
+
/**
|
|
404
|
+
* Developer-provided instructions that the model should follow, regardless of
|
|
405
|
+
* messages sent by the user. With o1 models and newer, `developer` messages
|
|
406
|
+
* replace the previous `system` messages.
|
|
407
|
+
*/
|
|
408
|
+
developer = 'developer',
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Developer-provided instructions that the model should follow, regardless of
|
|
412
|
+
* messages sent by the user. With o1 models and newer, use `developer` messages
|
|
413
|
+
* for this purpose instead.
|
|
414
|
+
*/
|
|
415
|
+
system = 'system',
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Messages sent by an end user, containing prompts or additional context
|
|
419
|
+
* information.
|
|
420
|
+
*/
|
|
421
|
+
user = 'user',
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Messages sent by the model in response to user messages.
|
|
425
|
+
*/
|
|
426
|
+
assistant = 'assistant',
|
|
427
|
+
|
|
428
|
+
/** ??? */
|
|
429
|
+
tool = 'tool',
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* ???
|
|
433
|
+
* @deprecated
|
|
434
|
+
*/
|
|
435
|
+
function = 'function',
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export function DyFM_notNull(value: any): boolean {
|
|
439
|
+
return value !== null && value !== undefined;
|
|
440
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
import { OpenAI, ClientOptions } from 'openai';
|
|
3
|
+
import { ChatCompletion, ChatCompletionMessageParam } from 'openai/resources';
|
|
4
|
+
|
|
5
|
+
import { DyFM_AnyError, DyFM_Error, DyFM_Error_Settings, DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
6
|
+
|
|
7
|
+
import { DyNTS_OpenAIModel } from '../_enums/open-ai-model.enum';
|
|
8
|
+
import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
|
|
9
|
+
import { DyNTS_OpenAI_Settings } from '../_models/open-ai-settings.interface';
|
|
10
|
+
import { DyNTS_GPTCall_Settings } from '../_models/gpt-call-settings.interface';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* {
|
|
15
|
+
* organization: 'org-XY',
|
|
16
|
+
* apiKey: 'sk-XY',
|
|
17
|
+
* project: 'proj_XY',
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// Di Dictionary DiModel DiEz DiAz
|
|
22
|
+
|
|
23
|
+
export class DyNTS_OpenAI_ServiceBase {
|
|
24
|
+
|
|
25
|
+
readonly defaultErrorUserMsg: string =
|
|
26
|
+
`We encountered an unhandled Control Service Error, ` +
|
|
27
|
+
`\nplease contact the responsible development team.`;
|
|
28
|
+
|
|
29
|
+
readonly openai: OpenAI;
|
|
30
|
+
|
|
31
|
+
/* readonly defaultSystemPrompt: string;
|
|
32
|
+
readonly defaultModel: DyNTS_OpenAIModel | string; */
|
|
33
|
+
readonly defaultSettings: DyNTS_GPTCall_Settings;
|
|
34
|
+
|
|
35
|
+
get debugLog(): boolean {
|
|
36
|
+
return this.defaultSettings.debugLog;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get defaultSystemPrompt(): string {
|
|
40
|
+
return this.defaultSettings.systemPrompt;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get defaultModel(): DyNTS_OpenAIModel | string {
|
|
44
|
+
return this.defaultSettings.useModel;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
constructor(
|
|
48
|
+
set: DyNTS_OpenAI_Settings
|
|
49
|
+
) {
|
|
50
|
+
this.openai = new OpenAI(set.openAIConfig);
|
|
51
|
+
this.defaultSettings = set.defaultSettings ?? new DyNTS_GPTCall_Settings();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
protected getDefaultErrorSettings(
|
|
55
|
+
fnName: string,
|
|
56
|
+
error: DyFM_AnyError,
|
|
57
|
+
issuer: string
|
|
58
|
+
): DyFM_Error_Settings {
|
|
59
|
+
return {
|
|
60
|
+
status: (error as DyFM_Error)?.___status ?? 500,
|
|
61
|
+
message: (error as Error)?.message ??
|
|
62
|
+
(error as DyFM_Error)?._message ??
|
|
63
|
+
`${fnName} was UNSUCCESSFUL (${DyNTS_global_settings.systemShortCodeName})`,
|
|
64
|
+
addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
|
|
65
|
+
userMessage: (error as DyFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
|
|
66
|
+
issuer: issuer,
|
|
67
|
+
issuerService: this.constructor?.name,
|
|
68
|
+
error: error,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export * from './_enums/open-ai-model.enum';
|
|
4
|
+
|
|
5
|
+
export * from './_models/gpt-call-settings.interface';
|
|
6
|
+
export * from './_models/open-ai-api-env-settings.interface';
|
|
7
|
+
export * from './_models/open-ai-settings.interface';
|
|
8
|
+
|
|
9
|
+
export * from './_services/embedding.control-service';
|
|
10
|
+
export * from './_services/gpt.service-base';
|
|
11
|
+
export * from './_services/open-ai.service-base';
|
|
12
|
+
|
|
13
|
+
|
|
@@ -1028,6 +1028,47 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
|
|
|
1028
1028
|
});
|
|
1029
1029
|
}
|
|
1030
1030
|
|
|
1031
|
+
/**
|
|
1032
|
+
* {
|
|
1033
|
+
"mappings": {
|
|
1034
|
+
"dynamic": true,
|
|
1035
|
+
"fields": {
|
|
1036
|
+
"embedding": {
|
|
1037
|
+
"type": "knnVector",
|
|
1038
|
+
"dimensions": 768
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
*/
|
|
1044
|
+
/**
|
|
1045
|
+
*
|
|
1046
|
+
* @param set db.collection.aggregate([
|
|
1047
|
+
{
|
|
1048
|
+
$vectorSearch: {
|
|
1049
|
+
index: "index_neve",
|
|
1050
|
+
queryVector: [a keresett embedding],
|
|
1051
|
+
path: "title.embedding",
|
|
1052
|
+
numCandidates: 100,
|
|
1053
|
+
limit: 5
|
|
1054
|
+
}
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
$vectorSearch: {
|
|
1058
|
+
index: "index_neve",
|
|
1059
|
+
queryVector: [a keresett embedding],
|
|
1060
|
+
path: "description.embedding",
|
|
1061
|
+
numCandidates: 100,
|
|
1062
|
+
limit: 5
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
]);
|
|
1066
|
+
* @returns
|
|
1067
|
+
*/
|
|
1068
|
+
async aggregate(set: any) {
|
|
1069
|
+
return this.dataModel.aggregate(set);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1031
1072
|
// ----------------------------------------------------------------------------------
|
|
1032
1073
|
// ----------------------------------------------------------------------------------
|
|
1033
1074
|
// ----------------------------------------------------------------------------------
|
|
@@ -42,6 +42,24 @@ import { DyNTS_SingletonService } from '../base/singleton.service';
|
|
|
42
42
|
import { DyNTS_GlobalService } from '../core/global.service';
|
|
43
43
|
import { DyNTS_RoutingModule } from '../route/routing-module.service';
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* function MyDecorator(config: any) {
|
|
48
|
+
return function (target: Function) {
|
|
49
|
+
// attach metadata or modify target
|
|
50
|
+
target.prototype.myMeta = config;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@MyDecorator({ role: 'admin' })
|
|
55
|
+
class User {
|
|
56
|
+
printRole() {
|
|
57
|
+
console.log((this as any).myMeta.role); // → "admin"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
*/
|
|
62
|
+
|
|
45
63
|
/**
|
|
46
64
|
* This will be the MAIN service of our server project,
|
|
47
65
|
* follow the types and type instructions while setting up your project
|