wingbot 3.67.0 → 3.67.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/package.json +1 -1
- package/src/Ai.js +29 -10
- package/src/ChatGpt.js +63 -11
- package/src/wingbot/CustomEntityDetectionModel.js +4 -1
package/package.json
CHANGED
package/src/Ai.js
CHANGED
|
@@ -51,9 +51,15 @@ let uq = 1;
|
|
|
51
51
|
// eslint-disable-next-line max-len
|
|
52
52
|
/** @typedef {import('./wingbot/CustomEntityDetectionModel').WordEntityDetector} WordEntityDetector */
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {object} WordDetectorData
|
|
56
|
+
* @prop {WordEntityDetector} detector
|
|
57
|
+
* @prop {number} [maxWordCount]
|
|
58
|
+
*/
|
|
59
|
+
|
|
54
60
|
/**
|
|
55
61
|
* @callback WordEntityDetectorFactory
|
|
56
|
-
* @returns {Promise<WordEntityDetector>}
|
|
62
|
+
* @returns {Promise<WordEntityDetector|WordDetectorData>}
|
|
57
63
|
*/
|
|
58
64
|
|
|
59
65
|
/** @typedef {[string,EntityDetector|RegExp,DetectorOptions]} DetectorArgs */
|
|
@@ -90,6 +96,8 @@ class Ai {
|
|
|
90
96
|
*/
|
|
91
97
|
this._wordEntityDetector = null;
|
|
92
98
|
|
|
99
|
+
this._wordEntityDetectorMaxWordCount = 0;
|
|
100
|
+
|
|
93
101
|
/**
|
|
94
102
|
* Upper threshold - for match method and for navigate method
|
|
95
103
|
*
|
|
@@ -289,19 +297,33 @@ class Ai {
|
|
|
289
297
|
|
|
290
298
|
/**
|
|
291
299
|
*
|
|
292
|
-
* @param {WordEntityDetector|WordEntityDetectorFactory} wordEntityDetector
|
|
300
|
+
* @param {WordEntityDetector|WordEntityDetectorFactory|WordDetectorData} wordEntityDetector
|
|
293
301
|
*/
|
|
294
302
|
setWordEntityDetector (wordEntityDetector) {
|
|
295
|
-
if (wordEntityDetector.length === 0) {
|
|
303
|
+
if (typeof wordEntityDetector === 'function' && wordEntityDetector.length === 0) {
|
|
296
304
|
// @ts-ignore
|
|
297
305
|
this._wordEntityDetectorFactory = wordEntityDetector;
|
|
298
306
|
return this;
|
|
299
307
|
}
|
|
300
308
|
|
|
301
|
-
|
|
309
|
+
let detector;
|
|
310
|
+
if (typeof wordEntityDetector === 'object') {
|
|
311
|
+
({ detector } = wordEntityDetector);
|
|
312
|
+
this._wordEntityDetectorMaxWordCount = Math.max(
|
|
313
|
+
this._wordEntityDetectorMaxWordCount,
|
|
314
|
+
wordEntityDetector.maxWordCount || 0
|
|
315
|
+
);
|
|
316
|
+
} else {
|
|
317
|
+
detector = wordEntityDetector;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// @ts-ignore
|
|
321
|
+
this._wordEntityDetector = detector;
|
|
302
322
|
|
|
303
323
|
for (const model of this._keyworders.values()) {
|
|
304
|
-
|
|
324
|
+
// @ts-ignore
|
|
325
|
+
model.wordEntityDetector = detector;
|
|
326
|
+
model.maxWordCount = Math.max(model.maxWordCount, this._wordEntityDetectorMaxWordCount);
|
|
305
327
|
}
|
|
306
328
|
return this;
|
|
307
329
|
}
|
|
@@ -684,15 +706,12 @@ class Ai {
|
|
|
684
706
|
*/
|
|
685
707
|
preloadDetectors () {
|
|
686
708
|
if (this._wordEntityDetectorFactory === null || this._wordEntityDetector) {
|
|
687
|
-
return Promise.resolve();
|
|
709
|
+
return Promise.resolve(this._wordEntityDetector);
|
|
688
710
|
}
|
|
689
711
|
|
|
690
712
|
const promise = this._wordEntityDetectorFactory()
|
|
691
713
|
.then((detector) => {
|
|
692
|
-
this.
|
|
693
|
-
for (const model of this._keyworders.values()) {
|
|
694
|
-
model.wordEntityDetector = detector;
|
|
695
|
-
}
|
|
714
|
+
this.setWordEntityDetector(detector);
|
|
696
715
|
return detector;
|
|
697
716
|
})
|
|
698
717
|
.catch((e) => {
|
package/src/ChatGpt.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
6
|
const nodeFetch = require('node-fetch').default;
|
|
7
|
+
const util = require('util');
|
|
7
8
|
const { PHONE_REGEX, EMAIL_REGEX } = require('./systemEntities/regexps');
|
|
8
9
|
|
|
9
10
|
/** @typedef {import('node-fetch').default} Fetch */
|
|
@@ -30,7 +31,7 @@ const { PHONE_REGEX, EMAIL_REGEX } = require('./systemEntities/regexps');
|
|
|
30
31
|
/** @typedef {'gpt-3.5-turbo'|'gpt-4'|'gpt-4-32k'|'gpt-3.5-turbo-16k'|string} ChatGPTModel */
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
|
-
* @typedef {object}
|
|
34
|
+
* @typedef {object} DefaultRequestOptions
|
|
34
35
|
* @prop {ChatGPTModel} [model]
|
|
35
36
|
* @prop {number} [presencePenalty=0.0]
|
|
36
37
|
* @prop {number} [requestTokens=256]
|
|
@@ -40,7 +41,14 @@ const { PHONE_REGEX, EMAIL_REGEX } = require('./systemEntities/regexps');
|
|
|
40
41
|
*/
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
|
-
* @typedef {
|
|
44
|
+
* @typedef {object} OptionsExtension
|
|
45
|
+
* @prop {FNAnnotation[]} [functions]
|
|
46
|
+
*
|
|
47
|
+
* @typedef {OptionsExtension & DefaultRequestOptions} RequestOptions
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {GeneralOptions & DefaultRequestOptions} ChatGptOptions
|
|
44
52
|
*/
|
|
45
53
|
|
|
46
54
|
/**
|
|
@@ -106,6 +114,37 @@ const { PHONE_REGEX, EMAIL_REGEX } = require('./systemEntities/regexps');
|
|
|
106
114
|
* @prop {boolean} [anonymize=true]
|
|
107
115
|
*/
|
|
108
116
|
|
|
117
|
+
/**
|
|
118
|
+
* @typedef {object} FNScalarParam
|
|
119
|
+
* @prop {'string'|'number'|'boolean'} type
|
|
120
|
+
* @prop {string[]} [enum]
|
|
121
|
+
* @prop {string} [description]
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @typedef {object} FNArrayParam
|
|
126
|
+
* @prop {'array'} type
|
|
127
|
+
* @prop {string} [description]
|
|
128
|
+
* @prop {FNParam} items
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @typedef {object} FNObjectParam
|
|
133
|
+
* @prop {'object'} type
|
|
134
|
+
* @prop {{ [key: string]: FNParam }} properties
|
|
135
|
+
* @prop {string[]} [required]
|
|
136
|
+
* @prop {string} [description]
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
/** @typedef {FNScalarParam|FNObjectParam|FNArrayParam} FNParam */
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @typedef {object} FNAnnotation
|
|
143
|
+
* @prop {string} name
|
|
144
|
+
* @prop {string} description
|
|
145
|
+
* @prop {FNParam} parameters
|
|
146
|
+
*/
|
|
147
|
+
|
|
109
148
|
/**
|
|
110
149
|
* @class ChatGpt
|
|
111
150
|
*/
|
|
@@ -135,7 +174,7 @@ class ChatGpt {
|
|
|
135
174
|
|
|
136
175
|
this._defaultUser = defaultUser;
|
|
137
176
|
|
|
138
|
-
/** @type {Required<
|
|
177
|
+
/** @type {Required<DefaultRequestOptions>} */
|
|
139
178
|
this._options = {
|
|
140
179
|
requestTokens: 256,
|
|
141
180
|
tokensLimit: 4096,
|
|
@@ -146,7 +185,7 @@ class ChatGpt {
|
|
|
146
185
|
...rest
|
|
147
186
|
};
|
|
148
187
|
|
|
149
|
-
this.
|
|
188
|
+
this._logger = log;
|
|
150
189
|
|
|
151
190
|
this.MSG_REPLACE = '#MSG-REPLACE#';
|
|
152
191
|
|
|
@@ -158,6 +197,17 @@ class ChatGpt {
|
|
|
158
197
|
];
|
|
159
198
|
}
|
|
160
199
|
|
|
200
|
+
_log (msg, ...args) {
|
|
201
|
+
if (this._logger === console) {
|
|
202
|
+
|
|
203
|
+
this._logger.log(msg, ...args.map((arg) => util.inspect(arg, {
|
|
204
|
+
showHidden: false, depth: null, colors: true
|
|
205
|
+
})));
|
|
206
|
+
} else {
|
|
207
|
+
this._logger.log(msg, ...args);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
161
211
|
/**
|
|
162
212
|
*
|
|
163
213
|
* @param {Responder} res
|
|
@@ -202,7 +252,8 @@ class ChatGpt {
|
|
|
202
252
|
tokensLimit,
|
|
203
253
|
model,
|
|
204
254
|
presencePenalty,
|
|
205
|
-
temperature
|
|
255
|
+
temperature,
|
|
256
|
+
functions = []
|
|
206
257
|
} = {
|
|
207
258
|
...this._options,
|
|
208
259
|
...requestOptions
|
|
@@ -218,7 +269,8 @@ class ChatGpt {
|
|
|
218
269
|
frequency_penalty: 0,
|
|
219
270
|
presence_penalty: presencePenalty,
|
|
220
271
|
max_tokens: maxTokens,
|
|
221
|
-
temperature
|
|
272
|
+
temperature,
|
|
273
|
+
functions
|
|
222
274
|
};
|
|
223
275
|
|
|
224
276
|
if (typeof user === 'string') {
|
|
@@ -253,7 +305,7 @@ class ChatGpt {
|
|
|
253
305
|
|
|
254
306
|
const apiUrl = `${this._openAiEndpoint}/chat/completions${this._apiKey ? '?api-version=2023-03-15-preview' : ''}`;
|
|
255
307
|
|
|
256
|
-
this._log
|
|
308
|
+
this._log('#GPT request', body);
|
|
257
309
|
|
|
258
310
|
const response = await this._fetch(apiUrl, {
|
|
259
311
|
method: 'POST',
|
|
@@ -273,7 +325,7 @@ class ChatGpt {
|
|
|
273
325
|
|| !Array.isArray(data.choices)) {
|
|
274
326
|
const { status, statusText } = response;
|
|
275
327
|
|
|
276
|
-
this.
|
|
328
|
+
this._logger.error('#GPT failed', {
|
|
277
329
|
status, statusText, data, body
|
|
278
330
|
});
|
|
279
331
|
throw new Error(`Chat GPT ${status}`);
|
|
@@ -281,11 +333,11 @@ class ChatGpt {
|
|
|
281
333
|
|
|
282
334
|
const [choice] = data.choices;
|
|
283
335
|
|
|
284
|
-
this._log
|
|
336
|
+
this._log('#GPT response', { choice, data });
|
|
285
337
|
|
|
286
338
|
return choice;
|
|
287
339
|
} catch (e) {
|
|
288
|
-
this.
|
|
340
|
+
this._logger.error('#GPT failed', e, body);
|
|
289
341
|
throw e;
|
|
290
342
|
}
|
|
291
343
|
}
|
|
@@ -412,7 +464,7 @@ class ChatGpt {
|
|
|
412
464
|
|
|
413
465
|
if (messages.length === 0) {
|
|
414
466
|
const err = new Error('#GPT nothing to send');
|
|
415
|
-
this.
|
|
467
|
+
this._logger.error('#GPT nothing to send', err, { choice, content });
|
|
416
468
|
throw err;
|
|
417
469
|
}
|
|
418
470
|
|
|
@@ -68,6 +68,7 @@ const { iterateThroughWords } = require('../utils/ai');
|
|
|
68
68
|
* @param {DetectedEntity[]} entities
|
|
69
69
|
* @param {number} startIndex
|
|
70
70
|
* @param {string} prefix
|
|
71
|
+
* @returns {DetectedEntity[]}
|
|
71
72
|
*/
|
|
72
73
|
|
|
73
74
|
/**
|
|
@@ -403,7 +404,8 @@ class CustomEntityDetectionModel {
|
|
|
403
404
|
let entities = prevEnts.slice();
|
|
404
405
|
if (this.wordEntityDetector) {
|
|
405
406
|
for (const [s, startIndex] of iterateThroughWords(text, this.maxWordCount)) {
|
|
406
|
-
this.wordEntityDetector(s,
|
|
407
|
+
const ents = this.wordEntityDetector(s, prevEnts, startIndex, this.prefix);
|
|
408
|
+
entities.push(...ents);
|
|
407
409
|
}
|
|
408
410
|
}
|
|
409
411
|
|
|
@@ -496,6 +498,7 @@ class CustomEntityDetectionModel {
|
|
|
496
498
|
// filter the text
|
|
497
499
|
for (let i = entities.length - 1; i >= 0; i--) {
|
|
498
500
|
const entity = entities[i];
|
|
501
|
+
if (!this._entityDetectors.has(entity.entity)) continue;
|
|
499
502
|
const { anonymize } = this._entityDetectors.get(entity.entity);
|
|
500
503
|
|
|
501
504
|
if (anonymize) {
|