wingbot 3.73.15 → 3.74.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/.github/workflows/deploy.yml +74 -49
- package/index.js +7 -1
- package/package.json +6 -1
- package/src/BuildRouter.js +24 -3
- package/src/ChatGpt.js +112 -35
- package/src/LLM.js +140 -48
- package/src/LLMConsts.js +42 -0
- package/src/LLMMockProvider.js +62 -1
- package/src/LLMSession.js +733 -90
- package/src/LLMTool.js +56 -0
- package/src/LLMType.js +331 -0
- package/src/Processor.js +6 -6
- package/src/Responder.js +56 -34
- package/src/Router.js +7 -2
- package/src/graphApi/validateBotApi.js +6 -1
- package/src/resolvers/expectedInput.js +11 -2
- package/src/resolvers/message.js +2 -3
- package/.claude/settings.local.json +0 -9
package/src/LLMTool.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author David Menger
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
/** @typedef {import('./LLMSession').Tool} Tool */
|
|
7
|
+
/** @typedef {import('./LLMSession').ToolInput} ToolInput */
|
|
8
|
+
/** @typedef {import('./LLMSession').ObjectTool} ObjectTool */
|
|
9
|
+
/** @typedef {import('./LLMSession').ToolFunctionInput} ToolFunctionInput */
|
|
10
|
+
/** @typedef {import('./LLMSession').ToolFnCallback} ToolFnCallback */
|
|
11
|
+
/** @typedef {import('./LLMSession').ToolFunction} ToolFunction */
|
|
12
|
+
/** @typedef {import('./LLMSession').FnParamsObject} FnParamsObject */
|
|
13
|
+
/** @typedef {import('./LLMSession').SimpleJsonSchema} SimpleJsonSchema */
|
|
14
|
+
|
|
15
|
+
/** @typedef {string[]} Enum */
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {{}} SchemaDefinition
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @class LLMTool
|
|
23
|
+
*/
|
|
24
|
+
class LLMTool {
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param {ToolFnCallback} fn
|
|
29
|
+
* @param {ToolFunctionInput} options
|
|
30
|
+
* @returns {ObjectTool}
|
|
31
|
+
*/
|
|
32
|
+
static create (fn, {
|
|
33
|
+
name = fn.name,
|
|
34
|
+
...rest
|
|
35
|
+
}) {
|
|
36
|
+
let {
|
|
37
|
+
parameters = {
|
|
38
|
+
properties: {}
|
|
39
|
+
}
|
|
40
|
+
} = rest;
|
|
41
|
+
|
|
42
|
+
if ('toJSON' in parameters && typeof parameters.toJSON === 'function') {
|
|
43
|
+
parameters = parameters.toJSON();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
fn,
|
|
48
|
+
name,
|
|
49
|
+
...rest,
|
|
50
|
+
parameters
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = LLMTool;
|
package/src/LLMType.js
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Lightweight fluent builder for JSON Schema definitions used by LLM tools.
|
|
5
|
+
*
|
|
6
|
+
* @class LLMType
|
|
7
|
+
*/
|
|
8
|
+
class LLMType {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {'string'|'number'|'enum'|'boolean'|'array'|'object'} type
|
|
12
|
+
* @param {object} [config]
|
|
13
|
+
* @param {string[]} [config.values]
|
|
14
|
+
* @param {LLMType} [config.items]
|
|
15
|
+
* @param {{ [key: string]: LLMType }} [config.properties]
|
|
16
|
+
* @param {string} [config.name]
|
|
17
|
+
*/
|
|
18
|
+
constructor (type, {
|
|
19
|
+
values = null,
|
|
20
|
+
items = null,
|
|
21
|
+
properties = null,
|
|
22
|
+
name = null
|
|
23
|
+
} = {}) {
|
|
24
|
+
this._type = type;
|
|
25
|
+
this._name = name;
|
|
26
|
+
|
|
27
|
+
this._description = null;
|
|
28
|
+
this._min = null;
|
|
29
|
+
this._max = null;
|
|
30
|
+
|
|
31
|
+
this._required = true;
|
|
32
|
+
|
|
33
|
+
this._values = values;
|
|
34
|
+
this._items = items;
|
|
35
|
+
this._properties = properties;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates a string schema.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* const title = LLMType.string()
|
|
43
|
+
* .description('Short title')
|
|
44
|
+
* .min(1)
|
|
45
|
+
* .max(64);
|
|
46
|
+
*
|
|
47
|
+
* @returns {LLMType}
|
|
48
|
+
*/
|
|
49
|
+
static string () {
|
|
50
|
+
return new LLMType('string');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a number schema.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* const temperature = LLMType.number()
|
|
58
|
+
* .description('Temperature in Celsius')
|
|
59
|
+
* .min(-40)
|
|
60
|
+
* .max(100);
|
|
61
|
+
*
|
|
62
|
+
* @returns {LLMType}
|
|
63
|
+
*/
|
|
64
|
+
static number () {
|
|
65
|
+
return new LLMType('number');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates an enum schema.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* const tone = LLMType.enum(['formal', 'casual'])
|
|
73
|
+
* .description('Response tone');
|
|
74
|
+
*
|
|
75
|
+
* @param {string[]} values
|
|
76
|
+
* @returns {LLMType}
|
|
77
|
+
*/
|
|
78
|
+
static enum (values) {
|
|
79
|
+
if (!Array.isArray(values) || values.length === 0 || !values.every((v) => typeof v === 'string')) {
|
|
80
|
+
throw new Error('LLMType.enum(values) expects a non-empty array of strings');
|
|
81
|
+
}
|
|
82
|
+
return new LLMType('enum', { values: [...values] });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Creates a boolean schema.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* const includeSummary = LLMType.boolean()
|
|
90
|
+
* .description('Whether summary should be included');
|
|
91
|
+
*
|
|
92
|
+
* @returns {LLMType}
|
|
93
|
+
*/
|
|
94
|
+
static boolean () {
|
|
95
|
+
return new LLMType('boolean');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Creates an array schema with one item type.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* const tags = LLMType.array(LLMType.string().min(1))
|
|
103
|
+
* .description('List of tags')
|
|
104
|
+
* .min(1)
|
|
105
|
+
* .max(20);
|
|
106
|
+
*
|
|
107
|
+
* @param {LLMType} itemType
|
|
108
|
+
* @returns {LLMType}
|
|
109
|
+
*/
|
|
110
|
+
static array (itemType) {
|
|
111
|
+
if (!(itemType instanceof LLMType)) {
|
|
112
|
+
throw new Error('LLMType.array(itemType) expects itemType to be LLMType');
|
|
113
|
+
}
|
|
114
|
+
return new LLMType('array', { items: itemType });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Creates an object schema from named `LLMType` properties.
|
|
119
|
+
* Properties are required by default unless `optional()` is called.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* const user = LLMType.object({
|
|
123
|
+
* name: LLMType.string().description('User name'),
|
|
124
|
+
* age: LLMType.number().optional()
|
|
125
|
+
* });
|
|
126
|
+
*
|
|
127
|
+
* @param {{ [key: string]: LLMType }} properties
|
|
128
|
+
* @param {string} [name=null]
|
|
129
|
+
* @returns {LLMType}
|
|
130
|
+
*/
|
|
131
|
+
static object (properties = {}, name = null) {
|
|
132
|
+
if (!properties || typeof properties !== 'object' || Array.isArray(properties)) {
|
|
133
|
+
throw new Error('LLMType.object(properties) expects an object');
|
|
134
|
+
}
|
|
135
|
+
const entries = Object.entries(properties);
|
|
136
|
+
for (const [key, value] of entries) {
|
|
137
|
+
if (!(value instanceof LLMType)) {
|
|
138
|
+
throw new Error(`LLMType.object(properties) expects property "${key}" to be LLMType`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return new LLMType('object', { properties: { ...properties }, name });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Sets human-readable field description.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* const schema = LLMType.string().description('Display name');
|
|
149
|
+
*
|
|
150
|
+
* @param {string} text
|
|
151
|
+
* @returns {this}
|
|
152
|
+
*/
|
|
153
|
+
description (text) {
|
|
154
|
+
this._description = text;
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Sets minimum boundary and maps it to a type-specific JSON Schema keyword.
|
|
160
|
+
*
|
|
161
|
+
* Mapping:
|
|
162
|
+
* - string/enum -> `minLength`
|
|
163
|
+
* - number -> `minimum`
|
|
164
|
+
* - array -> `minItems`
|
|
165
|
+
* - object -> `minProperties`
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* const schema = LLMType.array(LLMType.string()).min(2);
|
|
169
|
+
*
|
|
170
|
+
* @param {number} value
|
|
171
|
+
* @returns {this}
|
|
172
|
+
*/
|
|
173
|
+
min (value) {
|
|
174
|
+
this._min = value;
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Sets maximum boundary and maps it to a type-specific JSON Schema keyword.
|
|
180
|
+
*
|
|
181
|
+
* Mapping:
|
|
182
|
+
* - string/enum -> `maxLength`
|
|
183
|
+
* - number -> `maximum`
|
|
184
|
+
* - array -> `maxItems`
|
|
185
|
+
* - object -> `maxProperties`
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* const schema = LLMType.number().max(100);
|
|
189
|
+
*
|
|
190
|
+
* @param {number} value
|
|
191
|
+
* @returns {this}
|
|
192
|
+
*/
|
|
193
|
+
max (value) {
|
|
194
|
+
this._max = value;
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Marks field as optional when used as an object property.
|
|
200
|
+
*
|
|
201
|
+
* When used outside object-property context, it has no practical effect,
|
|
202
|
+
* because requiredness is evaluated by parent object schemas.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* const input = LLMType.object({
|
|
206
|
+
* query: LLMType.string(),
|
|
207
|
+
* locale: LLMType.string().optional()
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* @returns {this}
|
|
211
|
+
*/
|
|
212
|
+
optional () {
|
|
213
|
+
this._required = false;
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Returns JSON Schema representation.
|
|
219
|
+
*
|
|
220
|
+
* For object schemas, nested properties are resolved recursively by calling
|
|
221
|
+
* `toJSON()` on each nested `LLMType` instance.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* const schema = LLMType.object({
|
|
225
|
+
* query: LLMType.string().min(1),
|
|
226
|
+
* limit: LLMType.number().optional()
|
|
227
|
+
* }).toJSON();
|
|
228
|
+
*
|
|
229
|
+
* @returns {object}
|
|
230
|
+
*/
|
|
231
|
+
toJSON () {
|
|
232
|
+
const schema = this._baseSchema();
|
|
233
|
+
|
|
234
|
+
switch (this._type) {
|
|
235
|
+
case 'enum':
|
|
236
|
+
schema.type = 'string';
|
|
237
|
+
schema.enum = this._values;
|
|
238
|
+
break;
|
|
239
|
+
|
|
240
|
+
case 'array':
|
|
241
|
+
schema.type = 'array';
|
|
242
|
+
schema.items = this._items.toJSON();
|
|
243
|
+
break;
|
|
244
|
+
|
|
245
|
+
case 'object': {
|
|
246
|
+
const properties = {};
|
|
247
|
+
const required = [];
|
|
248
|
+
Object.entries(this._properties).forEach(([key, child]) => {
|
|
249
|
+
properties[key] = child.toJSON();
|
|
250
|
+
if (child._required) {
|
|
251
|
+
required.push(key);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
schema.type = 'object';
|
|
256
|
+
schema.properties = properties;
|
|
257
|
+
schema.additionalProperties = false;
|
|
258
|
+
if (required.length > 0) {
|
|
259
|
+
schema.required = required;
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
default:
|
|
265
|
+
schema.type = this._type;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
this._applyMinMax(schema);
|
|
269
|
+
return schema;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* @returns {object}
|
|
274
|
+
*/
|
|
275
|
+
_baseSchema () {
|
|
276
|
+
return /** @type {object} */ ({
|
|
277
|
+
...(this._description !== null && { description: this._description }),
|
|
278
|
+
...(this._name !== null && { name: this._name })
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* @param {object} schema
|
|
284
|
+
*/
|
|
285
|
+
_applyMinMax (schema) {
|
|
286
|
+
if (this._min === null && this._max === null) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const target = schema;
|
|
291
|
+
|
|
292
|
+
let minKey = null;
|
|
293
|
+
let maxKey = null;
|
|
294
|
+
|
|
295
|
+
switch (this._type) {
|
|
296
|
+
case 'string':
|
|
297
|
+
case 'enum':
|
|
298
|
+
minKey = 'minLength';
|
|
299
|
+
maxKey = 'maxLength';
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case 'number':
|
|
303
|
+
minKey = 'minimum';
|
|
304
|
+
maxKey = 'maximum';
|
|
305
|
+
break;
|
|
306
|
+
|
|
307
|
+
case 'array':
|
|
308
|
+
minKey = 'minItems';
|
|
309
|
+
maxKey = 'maxItems';
|
|
310
|
+
break;
|
|
311
|
+
|
|
312
|
+
case 'object':
|
|
313
|
+
minKey = 'minProperties';
|
|
314
|
+
maxKey = 'maxProperties';
|
|
315
|
+
break;
|
|
316
|
+
|
|
317
|
+
default:
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (this._min !== null) {
|
|
322
|
+
target[minKey] = this._min;
|
|
323
|
+
}
|
|
324
|
+
if (this._max !== null) {
|
|
325
|
+
target[maxKey] = this._max;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
module.exports = LLMType;
|
package/src/Processor.js
CHANGED
|
@@ -21,7 +21,7 @@ const LLMMockProvider = require('./LLMMockProvider');
|
|
|
21
21
|
/** @typedef {import('./analytics/consts').TrackingCategory} TrackingCategory */
|
|
22
22
|
/** @typedef {import('./analytics/consts').TrackingType} TrackingType */
|
|
23
23
|
/** @typedef {import('./analytics/consts').ResponseFlag} ResponseFlag */
|
|
24
|
-
/** @typedef {import('./LLM').
|
|
24
|
+
/** @typedef {import('./LLM').LLMGlobalConfig} LLMGlobalConfig */
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @typedef {object} AutoTypingConfig
|
|
@@ -113,7 +113,7 @@ const LLMMockProvider = require('./LLMMockProvider');
|
|
|
113
113
|
* @prop {string} [apiUrl] - Url for calling orchestrator API
|
|
114
114
|
* @prop {Function} [fetch] - Fetch function for calling orchestrator API
|
|
115
115
|
* @prop {number} [sessionDuration] - Session duration for analytic purposes
|
|
116
|
-
* @prop {
|
|
116
|
+
* @prop {LLMGlobalConfig} [llm] - LLM model configuration
|
|
117
117
|
* @prop {Preloader<R>} [preloader]
|
|
118
118
|
*/
|
|
119
119
|
|
|
@@ -405,19 +405,19 @@ class Processor extends EventEmitter {
|
|
|
405
405
|
return { status: 304 };
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
/** @type {
|
|
409
|
-
const
|
|
408
|
+
/** @type {LLMGlobalConfig} */
|
|
409
|
+
const llmConfiguration = {
|
|
410
410
|
provider: new LLMMockProvider(),
|
|
411
411
|
...this.options.llm
|
|
412
412
|
};
|
|
413
413
|
|
|
414
414
|
if (typeof messageSender.logPrompt === 'function') {
|
|
415
|
-
Object.assign(
|
|
415
|
+
Object.assign(llmConfiguration, {
|
|
416
416
|
logger: messageSender
|
|
417
417
|
});
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
-
const llm = new LLM(
|
|
420
|
+
const llm = new LLM(llmConfiguration, Ai.ai, this.options.log);
|
|
421
421
|
|
|
422
422
|
const result = await this
|
|
423
423
|
._dispatch(message, pageId, messageSender, responderData, preloadPromise, llm);
|
package/src/Responder.js
CHANGED
|
@@ -34,7 +34,7 @@ const EXCEPTION_HOPCOUNT_THRESHOLD = 5;
|
|
|
34
34
|
/** @typedef {import('./transcript/transcriptFromHistory').Transcript} Transcript */
|
|
35
35
|
/** @typedef {import('./analytics/consts').TrackingType} TrackingType */
|
|
36
36
|
|
|
37
|
-
/** @typedef {import('./LLM').
|
|
37
|
+
/** @typedef {import('./LLM').LLMCallPreset} LLMCallPreset */
|
|
38
38
|
/** @typedef {import('./LLM').PreprocessedRule} PreprocessedRule */
|
|
39
39
|
/** @typedef {import('./LLM').EvaluationRuleAction} EvaluationRuleAction */
|
|
40
40
|
/** @typedef {import('./LLM').EvaluationResult} EvaluationResult */
|
|
@@ -42,6 +42,8 @@ const EXCEPTION_HOPCOUNT_THRESHOLD = 5;
|
|
|
42
42
|
/** @typedef {import('./LLMSession').LLMFilterFn} LLMFilterFn */
|
|
43
43
|
/** @typedef {import('./LLMSession').LLMFilter} LLMFilter */
|
|
44
44
|
/** @typedef {import('./LLMSession').FilterScope} FilterScope */
|
|
45
|
+
/** @typedef {import('./LLMSession').LLMMessageSrc} LLMMessageSrc */
|
|
46
|
+
/** @typedef {import('./LLMSession').AsyncLLMMessage} AsyncLLMMessage */
|
|
45
47
|
/** @typedef {import('./utils/stateData').IStateRequest} IStateRequest */
|
|
46
48
|
|
|
47
49
|
/**
|
|
@@ -63,6 +65,7 @@ Object.freeze(ExpectedInput);
|
|
|
63
65
|
* @prop {string} [webview_height_ratio]
|
|
64
66
|
* @prop {string} [onCloseAction]
|
|
65
67
|
* @prop {string} [onCloseActionData]
|
|
68
|
+
* @prop {number} [max_length]
|
|
66
69
|
*/
|
|
67
70
|
|
|
68
71
|
/**
|
|
@@ -355,13 +358,34 @@ class Responder {
|
|
|
355
358
|
return this;
|
|
356
359
|
}
|
|
357
360
|
|
|
358
|
-
|
|
361
|
+
/**
|
|
362
|
+
*
|
|
363
|
+
* @param {string} contextType
|
|
364
|
+
* @returns {AsyncLLMMessage}
|
|
365
|
+
*/
|
|
366
|
+
async _getSystemMessagesForType (contextType) {
|
|
359
367
|
const system = await this._getSystemContentForType(contextType);
|
|
368
|
+
return system.map((content) => ({ role: LLM.ROLE_SYSTEM, content }));
|
|
369
|
+
}
|
|
360
370
|
|
|
361
|
-
|
|
371
|
+
/**
|
|
372
|
+
*
|
|
373
|
+
* @param {string} contextType
|
|
374
|
+
* @returns {Promise<LLMSession>}
|
|
375
|
+
*/
|
|
376
|
+
async llmSession (contextType = this.LLM_CTX_DEFAULT) {
|
|
377
|
+
const system = this._getSystemMessagesForType(contextType);
|
|
362
378
|
|
|
363
379
|
const filters = this._filtersForContext(contextType);
|
|
364
|
-
return new LLMSession(this.llm,
|
|
380
|
+
return new LLMSession(this.llm, [system], this._llmSend.bind(this), filters);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
*
|
|
385
|
+
* @returns {LLMSession}
|
|
386
|
+
*/
|
|
387
|
+
llmSessionEmpty () {
|
|
388
|
+
return new LLMSession(this.llm, [], this._llmSend.bind(this));
|
|
365
389
|
}
|
|
366
390
|
|
|
367
391
|
/**
|
|
@@ -372,7 +396,7 @@ class Responder {
|
|
|
372
396
|
*/
|
|
373
397
|
async llmEvaluate (session, contextType = this.LLM_CTX_DEFAULT) {
|
|
374
398
|
const rules = this._llmResultRules.get(contextType) || [];
|
|
375
|
-
const text = session.
|
|
399
|
+
const text = session.lastResponseSync();
|
|
376
400
|
|
|
377
401
|
if (rules.length === 0 || !text) {
|
|
378
402
|
return {
|
|
@@ -449,38 +473,35 @@ class Responder {
|
|
|
449
473
|
return resolved;
|
|
450
474
|
}
|
|
451
475
|
|
|
452
|
-
|
|
476
|
+
/**
|
|
477
|
+
*
|
|
478
|
+
* @param {'default'|string} contextType
|
|
479
|
+
* @param {LLMCallPreset} callPreset
|
|
480
|
+
* @returns {LLMSession}
|
|
481
|
+
*/
|
|
482
|
+
llmSessionWithHistory (
|
|
453
483
|
contextType = this.LLM_CTX_DEFAULT,
|
|
454
|
-
|
|
455
|
-
transcriptFlag = undefined
|
|
484
|
+
callPreset = undefined
|
|
456
485
|
) {
|
|
457
486
|
const {
|
|
458
487
|
transcriptAnonymize,
|
|
459
|
-
transcriptFlag
|
|
460
|
-
transcriptLength
|
|
461
|
-
} = this.llm.
|
|
462
|
-
|
|
463
|
-
const computedTranscriptLength = transcriptLength === undefined
|
|
464
|
-
? transcriptLengthCfg
|
|
465
|
-
: transcriptLength;
|
|
466
|
-
const computedTranscriptFlag = transcriptFlag === undefined
|
|
467
|
-
? transcriptFlagCfg : transcriptFlag;
|
|
468
|
-
|
|
469
|
-
const [systems, transcript] = await Promise.all([
|
|
470
|
-
this._getSystemContentForType(contextType),
|
|
471
|
-
this.getTranscript(
|
|
472
|
-
computedTranscriptLength,
|
|
473
|
-
computedTranscriptFlag
|
|
474
|
-
)
|
|
475
|
-
]);
|
|
476
|
-
|
|
477
|
-
const chat = [
|
|
478
|
-
...systems.map((content) => ({ role: LLM.ROLE_SYSTEM, content })),
|
|
479
|
-
...LLM.anonymizeTranscript(transcript, transcriptAnonymize)
|
|
480
|
-
];
|
|
488
|
+
transcriptFlag,
|
|
489
|
+
transcriptLength
|
|
490
|
+
} = this.llm.llmOptions(callPreset);
|
|
481
491
|
|
|
482
492
|
const filters = this._filtersForContext(contextType);
|
|
483
|
-
return new LLMSession(this.llm,
|
|
493
|
+
return new LLMSession(this.llm, [
|
|
494
|
+
this._getSystemMessagesForType(contextType),
|
|
495
|
+
this._getTranscriptMessages(transcriptLength, transcriptFlag, transcriptAnonymize)
|
|
496
|
+
], this._llmSend.bind(this), filters);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
async _getTranscriptMessages (transcriptLength, transcriptFlag, transcriptAnonymize) {
|
|
500
|
+
const transcript = await this.getTranscript(
|
|
501
|
+
transcriptLength,
|
|
502
|
+
transcriptFlag
|
|
503
|
+
);
|
|
504
|
+
return LLM.anonymizeTranscript(transcript, transcriptAnonymize);
|
|
484
505
|
}
|
|
485
506
|
|
|
486
507
|
/**
|
|
@@ -1188,6 +1209,7 @@ class Responder {
|
|
|
1188
1209
|
* After processing the user input, next requests will be processed as usual,
|
|
1189
1210
|
*
|
|
1190
1211
|
* @param {ExpectedInput} [expectedInput]
|
|
1212
|
+
* @param {ExpectedInputOptions} [options]
|
|
1191
1213
|
* @returns {this}
|
|
1192
1214
|
* @example
|
|
1193
1215
|
*
|
|
@@ -1213,9 +1235,9 @@ class Responder {
|
|
|
1213
1235
|
* .setState({ cardNumber });
|
|
1214
1236
|
* });
|
|
1215
1237
|
*/
|
|
1216
|
-
expectedConfidentInput (expectedInput = null) {
|
|
1217
|
-
if (expectedInput) {
|
|
1218
|
-
this.expectedInput(expectedInput);
|
|
1238
|
+
expectedConfidentInput (expectedInput = null, options = undefined) {
|
|
1239
|
+
if (expectedInput || options) {
|
|
1240
|
+
this.expectedInput(expectedInput, options);
|
|
1219
1241
|
}
|
|
1220
1242
|
return this.setState({
|
|
1221
1243
|
_expectedConfidentInput: true
|
package/src/Router.js
CHANGED
|
@@ -7,8 +7,13 @@ const { pathToRegexp } = require('path-to-regexp');
|
|
|
7
7
|
const ReducerWrapper = require('./ReducerWrapper');
|
|
8
8
|
const { makeAbsolute } = require('./utils');
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/** @typedef {import('./Responder')} Responder */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @template {object} [S=object]
|
|
14
|
+
* @template {BaseConfiguration} [C=object]
|
|
15
|
+
* @typedef {import('./Request')<S, C>} Request
|
|
16
|
+
*/
|
|
12
17
|
|
|
13
18
|
function defaultPathContext () {
|
|
14
19
|
return { globalIntentsMeta: {}, path: '/*' };
|
|
@@ -21,7 +21,12 @@ const apiAuthorizer = require('./apiAuthorizer');
|
|
|
21
21
|
*/
|
|
22
22
|
async function validate (bot, validationRequestBody, postBackTest = null, textTest = null) {
|
|
23
23
|
try {
|
|
24
|
-
bot.buildWithSnapshot(
|
|
24
|
+
bot.buildWithSnapshot(
|
|
25
|
+
validationRequestBody.blocks,
|
|
26
|
+
Number.MAX_SAFE_INTEGER,
|
|
27
|
+
undefined,
|
|
28
|
+
validationRequestBody.deployedConfiguration
|
|
29
|
+
);
|
|
25
30
|
} catch (e) {
|
|
26
31
|
const error = `Bot build failed: ${e.message}`;
|
|
27
32
|
// eslint-disable-next-line no-console
|
|
@@ -5,13 +5,22 @@
|
|
|
5
5
|
|
|
6
6
|
const Router = require('../Router');
|
|
7
7
|
|
|
8
|
-
function expectedInput ({ type = null, confident = false }, { isLastIndex }) {
|
|
8
|
+
function expectedInput ({ type = null, confident = false, maxLength = null }, { isLastIndex }) {
|
|
9
9
|
|
|
10
10
|
return (req, res) => {
|
|
11
|
+
const opts = {};
|
|
12
|
+
|
|
13
|
+
const useMaxLen = maxLength && parseInt(`${maxLength}`, 10);
|
|
14
|
+
if ((!type || type === 'password') && useMaxLen) {
|
|
15
|
+
Object.assign(opts, {
|
|
16
|
+
max_length: useMaxLen
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
if (confident) {
|
|
12
21
|
res.expectedConfidentInput(type);
|
|
13
22
|
} else if (type) {
|
|
14
|
-
res.expectedInput(type);
|
|
23
|
+
res.expectedInput(type, opts);
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
return isLastIndex ? Router.END : Router.CONTINUE;
|
package/src/resolvers/message.js
CHANGED
|
@@ -455,8 +455,7 @@ function message (params, context = {}) {
|
|
|
455
455
|
let discard;
|
|
456
456
|
|
|
457
457
|
try {
|
|
458
|
-
session =
|
|
459
|
-
|
|
458
|
+
session = res.llmSessionWithHistory(params.llmContextType);
|
|
460
459
|
await session.systemPrompt(text)
|
|
461
460
|
.generate();
|
|
462
461
|
|
|
@@ -483,7 +482,7 @@ function message (params, context = {}) {
|
|
|
483
482
|
// // no response?
|
|
484
483
|
// }
|
|
485
484
|
|
|
486
|
-
const messages = session.
|
|
485
|
+
const messages = session.messagesToSendSync();
|
|
487
486
|
|
|
488
487
|
res.setFlag(LLM.GPT_FLAG);
|
|
489
488
|
|