@promptbook/core 0.44.0-2 โ 0.44.0-21
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/README.md +713 -2
- package/esm/index.es.js +361 -186
- package/esm/index.es.js.map +1 -1
- package/esm/typings/_packages/utils.index.d.ts +5 -3
- package/esm/typings/config.d.ts +4 -0
- package/esm/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.d.ts +9 -1
- package/esm/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.test.d.ts +1 -0
- package/esm/typings/execution/plugins/natural-execution-tools/mocked/faked-completion.test.d.ts +1 -0
- package/esm/typings/execution/plugins/script-execution-tools/javascript/JavascriptExecutionToolsOptions.d.ts +5 -1
- package/esm/typings/execution/plugins/script-execution-tools/javascript/utils/unknownToString.d.ts +7 -0
- package/esm/typings/execution/utils/checkExpectations.d.ts +25 -0
- package/esm/typings/execution/utils/checkExpectations.test.d.ts +1 -0
- package/esm/typings/types/Prompt.d.ts +5 -0
- package/esm/typings/types/PromptbookJson/PromptTemplateJson.d.ts +2 -0
- package/package.json +2 -2
- package/umd/index.umd.js +401 -230
- package/umd/index.umd.js.map +1 -1
- package/umd/typings/_packages/utils.index.d.ts +5 -3
- package/umd/typings/config.d.ts +4 -0
- package/umd/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.d.ts +9 -1
- package/umd/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.test.d.ts +1 -0
- package/umd/typings/execution/plugins/natural-execution-tools/mocked/faked-completion.test.d.ts +1 -0
- package/umd/typings/execution/plugins/script-execution-tools/javascript/JavascriptExecutionToolsOptions.d.ts +5 -1
- package/umd/typings/execution/plugins/script-execution-tools/javascript/utils/unknownToString.d.ts +7 -0
- package/umd/typings/execution/utils/checkExpectations.d.ts +25 -0
- package/umd/typings/execution/utils/checkExpectations.test.d.ts +1 -0
- package/umd/typings/types/Prompt.d.ts +5 -0
- package/umd/typings/types/PromptbookJson/PromptTemplateJson.d.ts +2 -0
package/esm/index.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import spaceTrim from 'spacetrim';
|
|
1
|
+
import { spaceTrim } from 'spacetrim';
|
|
2
2
|
import 'prettier';
|
|
3
3
|
import 'prettier/parser-html';
|
|
4
4
|
import 'moment';
|
|
@@ -243,86 +243,22 @@ var PromptbookExecutionError = /** @class */ (function (_super) {
|
|
|
243
243
|
}(Error));
|
|
244
244
|
|
|
245
245
|
/**
|
|
246
|
-
*
|
|
247
|
-
*/
|
|
248
|
-
var LOOP_LIMIT = 1000;
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* This error occurs during the parameter replacement in the template
|
|
246
|
+
* This error occurs when some expectation is not met in the execution of the pipeline
|
|
252
247
|
*
|
|
253
|
-
*
|
|
248
|
+
* @private Always catched and rethrown as `PromptbookExecutionError`
|
|
249
|
+
* Note: This is a kindof subtype of PromptbookExecutionError
|
|
254
250
|
*/
|
|
255
|
-
var
|
|
256
|
-
__extends(
|
|
257
|
-
function
|
|
251
|
+
var ExpectError = /** @class */ (function (_super) {
|
|
252
|
+
__extends(ExpectError, _super);
|
|
253
|
+
function ExpectError(message) {
|
|
258
254
|
var _this = _super.call(this, message) || this;
|
|
259
|
-
_this.name = '
|
|
260
|
-
Object.setPrototypeOf(_this,
|
|
255
|
+
_this.name = 'ExpectError';
|
|
256
|
+
Object.setPrototypeOf(_this, ExpectError.prototype);
|
|
261
257
|
return _this;
|
|
262
258
|
}
|
|
263
|
-
return
|
|
259
|
+
return ExpectError;
|
|
264
260
|
}(Error));
|
|
265
261
|
|
|
266
|
-
/**
|
|
267
|
-
* Replaces parameters in template with values from parameters object
|
|
268
|
-
*
|
|
269
|
-
* @param template the template with parameters in {curly} braces
|
|
270
|
-
* @param parameters the object with parameters
|
|
271
|
-
* @returns the template with replaced parameters
|
|
272
|
-
* @throws {TemplateError} if parameter is not defined, not closed, or not opened
|
|
273
|
-
*
|
|
274
|
-
* @private within the createPromptbookExecutor
|
|
275
|
-
*/
|
|
276
|
-
function replaceParameters(template, parameters) {
|
|
277
|
-
var replacedTemplate = template;
|
|
278
|
-
var match;
|
|
279
|
-
var loopLimit = LOOP_LIMIT;
|
|
280
|
-
var _loop_1 = function () {
|
|
281
|
-
if (loopLimit-- < 0) {
|
|
282
|
-
throw new UnexpectedError('Loop limit reached during parameters replacement in `replaceParameters`');
|
|
283
|
-
}
|
|
284
|
-
var precol = match.groups.precol;
|
|
285
|
-
var parameterName = match.groups.parameterName;
|
|
286
|
-
if (parameterName === '') {
|
|
287
|
-
return "continue";
|
|
288
|
-
}
|
|
289
|
-
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
290
|
-
throw new TemplateError('Parameter is already opened or not closed');
|
|
291
|
-
}
|
|
292
|
-
if (parameters[parameterName] === undefined) {
|
|
293
|
-
throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
|
|
294
|
-
}
|
|
295
|
-
var parameterValue = parameters[parameterName];
|
|
296
|
-
if (parameterValue === undefined) {
|
|
297
|
-
throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
|
|
298
|
-
}
|
|
299
|
-
parameterValue = parameterValue.toString();
|
|
300
|
-
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
301
|
-
parameterValue = parameterValue
|
|
302
|
-
.split('\n')
|
|
303
|
-
.map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
|
|
304
|
-
.join('\n');
|
|
305
|
-
}
|
|
306
|
-
replacedTemplate =
|
|
307
|
-
replacedTemplate.substring(0, match.index + precol.length) +
|
|
308
|
-
parameterValue +
|
|
309
|
-
replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
|
|
310
|
-
};
|
|
311
|
-
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
312
|
-
.exec(replacedTemplate))) {
|
|
313
|
-
_loop_1();
|
|
314
|
-
}
|
|
315
|
-
// [๐ซ] Check if there are parameters that are not closed properly
|
|
316
|
-
if (/{\w+$/.test(replacedTemplate)) {
|
|
317
|
-
throw new TemplateError('Parameter is not closed');
|
|
318
|
-
}
|
|
319
|
-
// [๐ซ] Check if there are parameters that are not opened properly
|
|
320
|
-
if (/^\w+}/.test(replacedTemplate)) {
|
|
321
|
-
throw new TemplateError('Parameter is not opened');
|
|
322
|
-
}
|
|
323
|
-
return replacedTemplate;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
262
|
/**
|
|
327
263
|
* Counts number of characters in the text
|
|
328
264
|
*/
|
|
@@ -650,6 +586,148 @@ var CountUtils = {
|
|
|
650
586
|
PAGES: countPages,
|
|
651
587
|
};
|
|
652
588
|
|
|
589
|
+
/**
|
|
590
|
+
* Function checkExpectations will check if the expectations on given value are met
|
|
591
|
+
*
|
|
592
|
+
* Note: There are two simmilar functions:
|
|
593
|
+
* - `checkExpectations` which throws an error if the expectations are not met
|
|
594
|
+
* - `isPassingExpectations` which returns a boolean
|
|
595
|
+
*
|
|
596
|
+
* @throws {ExpectError} if the expectations are not met
|
|
597
|
+
* @returns {void} Nothing
|
|
598
|
+
*/
|
|
599
|
+
function checkExpectations(expectations, value) {
|
|
600
|
+
var e_1, _a;
|
|
601
|
+
try {
|
|
602
|
+
for (var _b = __values(Object.entries(expectations)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
603
|
+
var _d = __read(_c.value, 2), unit = _d[0], _e = _d[1], max = _e.max, min = _e.min;
|
|
604
|
+
var amount = CountUtils[unit.toUpperCase()](value);
|
|
605
|
+
if (min && amount < min) {
|
|
606
|
+
throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
|
|
607
|
+
} /* not else */
|
|
608
|
+
if (max && amount > max) {
|
|
609
|
+
throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
614
|
+
finally {
|
|
615
|
+
try {
|
|
616
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
617
|
+
}
|
|
618
|
+
finally { if (e_1) throw e_1.error; }
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Function checkExpectations will check if the expectations on given value are met
|
|
623
|
+
*
|
|
624
|
+
* Note: There are two simmilar functions:
|
|
625
|
+
* - `checkExpectations` which throws an error if the expectations are not met
|
|
626
|
+
* - `isPassingExpectations` which returns a boolean
|
|
627
|
+
*
|
|
628
|
+
* @returns {boolean} True if the expectations are met
|
|
629
|
+
*/
|
|
630
|
+
function isPassingExpectations(expectations, value) {
|
|
631
|
+
try {
|
|
632
|
+
checkExpectations(expectations, value);
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
if (!(error instanceof ExpectError)) {
|
|
637
|
+
throw error;
|
|
638
|
+
}
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* TODO: [๐] Unite object for expecting amount and format
|
|
644
|
+
*/
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* The maximum number of iterations for a loops
|
|
648
|
+
*/
|
|
649
|
+
var LOOP_LIMIT = 1000;
|
|
650
|
+
/**
|
|
651
|
+
* The maximum number of iterations for a loops which adds characters one by one
|
|
652
|
+
*/
|
|
653
|
+
var CHARACTER_LOOP_LIMIT = 100000;
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* This error occurs during the parameter replacement in the template
|
|
657
|
+
*
|
|
658
|
+
* Note: This is a kindof subtype of PromptbookExecutionError because it occurs during the execution of the pipeline
|
|
659
|
+
*/
|
|
660
|
+
var TemplateError = /** @class */ (function (_super) {
|
|
661
|
+
__extends(TemplateError, _super);
|
|
662
|
+
function TemplateError(message) {
|
|
663
|
+
var _this = _super.call(this, message) || this;
|
|
664
|
+
_this.name = 'TemplateError';
|
|
665
|
+
Object.setPrototypeOf(_this, TemplateError.prototype);
|
|
666
|
+
return _this;
|
|
667
|
+
}
|
|
668
|
+
return TemplateError;
|
|
669
|
+
}(Error));
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Replaces parameters in template with values from parameters object
|
|
673
|
+
*
|
|
674
|
+
* @param template the template with parameters in {curly} braces
|
|
675
|
+
* @param parameters the object with parameters
|
|
676
|
+
* @returns the template with replaced parameters
|
|
677
|
+
* @throws {TemplateError} if parameter is not defined, not closed, or not opened
|
|
678
|
+
*
|
|
679
|
+
* @private within the createPromptbookExecutor
|
|
680
|
+
*/
|
|
681
|
+
function replaceParameters(template, parameters) {
|
|
682
|
+
var replacedTemplate = template;
|
|
683
|
+
var match;
|
|
684
|
+
var loopLimit = LOOP_LIMIT;
|
|
685
|
+
var _loop_1 = function () {
|
|
686
|
+
if (loopLimit-- < 0) {
|
|
687
|
+
throw new UnexpectedError('Loop limit reached during parameters replacement in `replaceParameters`');
|
|
688
|
+
}
|
|
689
|
+
var precol = match.groups.precol;
|
|
690
|
+
var parameterName = match.groups.parameterName;
|
|
691
|
+
if (parameterName === '') {
|
|
692
|
+
return "continue";
|
|
693
|
+
}
|
|
694
|
+
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
695
|
+
throw new TemplateError('Parameter is already opened or not closed');
|
|
696
|
+
}
|
|
697
|
+
if (parameters[parameterName] === undefined) {
|
|
698
|
+
throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
|
|
699
|
+
}
|
|
700
|
+
var parameterValue = parameters[parameterName];
|
|
701
|
+
if (parameterValue === undefined) {
|
|
702
|
+
throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
|
|
703
|
+
}
|
|
704
|
+
parameterValue = parameterValue.toString();
|
|
705
|
+
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
706
|
+
parameterValue = parameterValue
|
|
707
|
+
.split('\n')
|
|
708
|
+
.map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
|
|
709
|
+
.join('\n');
|
|
710
|
+
}
|
|
711
|
+
replacedTemplate =
|
|
712
|
+
replacedTemplate.substring(0, match.index + precol.length) +
|
|
713
|
+
parameterValue +
|
|
714
|
+
replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
|
|
715
|
+
};
|
|
716
|
+
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
717
|
+
.exec(replacedTemplate))) {
|
|
718
|
+
_loop_1();
|
|
719
|
+
}
|
|
720
|
+
// [๐ซ] Check if there are parameters that are not closed properly
|
|
721
|
+
if (/{\w+$/.test(replacedTemplate)) {
|
|
722
|
+
throw new TemplateError('Parameter is not closed');
|
|
723
|
+
}
|
|
724
|
+
// [๐ซ] Check if there are parameters that are not opened properly
|
|
725
|
+
if (/^\w+}/.test(replacedTemplate)) {
|
|
726
|
+
throw new TemplateError('Parameter is not opened');
|
|
727
|
+
}
|
|
728
|
+
return replacedTemplate;
|
|
729
|
+
}
|
|
730
|
+
|
|
653
731
|
/**
|
|
654
732
|
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
655
733
|
*/
|
|
@@ -1083,7 +1161,7 @@ function parsingMarkdownStructureToMarkdownStructure(parsingMarkdownStructure) {
|
|
|
1083
1161
|
/**
|
|
1084
1162
|
* The version of the Promptbook library
|
|
1085
1163
|
*/
|
|
1086
|
-
var PROMPTBOOK_VERSION = '0.44.0-
|
|
1164
|
+
var PROMPTBOOK_VERSION = '0.44.0-20';
|
|
1087
1165
|
|
|
1088
1166
|
/**
|
|
1089
1167
|
* Parses the given script and returns the list of all used variables that are not defined in the script
|
|
@@ -1151,6 +1229,7 @@ var ExecutionTypes = [
|
|
|
1151
1229
|
*/
|
|
1152
1230
|
var EXPECTATION_UNITS = ['CHARACTERS', 'WORDS', 'SENTENCES', 'PARAGRAPHS', 'LINES', 'PAGES'];
|
|
1153
1231
|
/**
|
|
1232
|
+
* TODO: [๐] Unite object for expecting amount and format - remove expectFormat
|
|
1154
1233
|
* TODO: use one helper type> (string_prompt | string_javascript | string_markdown) & string_template
|
|
1155
1234
|
*/
|
|
1156
1235
|
|
|
@@ -1891,23 +1970,6 @@ function validatePromptbookJson(promptbook) {
|
|
|
1891
1970
|
* > ex port function validatePromptbookJson(promptbook: unknown): asserts promptbook is PromptbookJson {
|
|
1892
1971
|
*/
|
|
1893
1972
|
|
|
1894
|
-
/**
|
|
1895
|
-
* This error occurs when some expectation is not met in the execution of the pipeline
|
|
1896
|
-
*
|
|
1897
|
-
* @private Always catched and rethrown as `PromptbookExecutionError`
|
|
1898
|
-
* Note: This is a kindof subtype of PromptbookExecutionError
|
|
1899
|
-
*/
|
|
1900
|
-
var ExpectError = /** @class */ (function (_super) {
|
|
1901
|
-
__extends(ExpectError, _super);
|
|
1902
|
-
function ExpectError(message) {
|
|
1903
|
-
var _this = _super.call(this, message) || this;
|
|
1904
|
-
_this.name = 'ExpectError';
|
|
1905
|
-
Object.setPrototypeOf(_this, ExpectError.prototype);
|
|
1906
|
-
return _this;
|
|
1907
|
-
}
|
|
1908
|
-
return ExpectError;
|
|
1909
|
-
}(Error));
|
|
1910
|
-
|
|
1911
1973
|
/**
|
|
1912
1974
|
* Creates executor function from promptbook and execution tools.
|
|
1913
1975
|
*
|
|
@@ -1922,10 +1984,11 @@ function createPromptbookExecutor(options) {
|
|
|
1922
1984
|
var promptbookExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
|
|
1923
1985
|
function executeSingleTemplate(currentTemplate) {
|
|
1924
1986
|
return __awaiter(this, void 0, void 0, function () {
|
|
1925
|
-
var name, title, priority, prompt, chatThread, completionResult, result, resultString, expectError, scriptExecutionErrors, maxAttempts, jokers, attempt, isJokerAttempt, joker, _a, _b, _c, _d, scriptTools, error_2, e_2_1, _e, _f, functionName, postprocessingError, _g, _h, scriptTools, error_3, e_3_1, e_4_1,
|
|
1926
|
-
var e_2,
|
|
1927
|
-
|
|
1928
|
-
|
|
1987
|
+
var name, title, priority, prompt, chatThread, completionResult, result, resultString, expectError, scriptExecutionErrors, maxAttempts, jokers, attempt, isJokerAttempt, joker, _a, _b, _c, _d, scriptTools, error_2, e_2_1, _e, _f, functionName, postprocessingError, _g, _h, scriptTools, error_3, e_3_1, e_4_1, error_4;
|
|
1988
|
+
var e_2, _j, e_4, _k, e_3, _l, _m;
|
|
1989
|
+
var _this = this;
|
|
1990
|
+
return __generator(this, function (_o) {
|
|
1991
|
+
switch (_o.label) {
|
|
1929
1992
|
case 0:
|
|
1930
1993
|
name = "promptbook-executor-frame-".concat(currentTemplate.name);
|
|
1931
1994
|
title = currentTemplate.title;
|
|
@@ -1942,8 +2005,8 @@ function createPromptbookExecutor(options) {
|
|
|
1942
2005
|
// <- [3]
|
|
1943
2006
|
})];
|
|
1944
2007
|
case 1:
|
|
1945
|
-
|
|
1946
|
-
|
|
2008
|
+
_o.sent();
|
|
2009
|
+
_o.label = 2;
|
|
1947
2010
|
case 2:
|
|
1948
2011
|
result = null;
|
|
1949
2012
|
resultString = null;
|
|
@@ -1951,7 +2014,7 @@ function createPromptbookExecutor(options) {
|
|
|
1951
2014
|
maxAttempts = currentTemplate.executionType === 'PROMPT_DIALOG' ? Infinity : maxExecutionAttempts;
|
|
1952
2015
|
jokers = currentTemplate.jokers || [];
|
|
1953
2016
|
attempt = -jokers.length;
|
|
1954
|
-
|
|
2017
|
+
_o.label = 3;
|
|
1955
2018
|
case 3:
|
|
1956
2019
|
if (!(attempt < maxAttempts)) return [3 /*break*/, 49];
|
|
1957
2020
|
isJokerAttempt = attempt < 0;
|
|
@@ -1968,9 +2031,9 @@ function createPromptbookExecutor(options) {
|
|
|
1968
2031
|
}
|
|
1969
2032
|
resultString = parametersToPass[joker];
|
|
1970
2033
|
}
|
|
1971
|
-
|
|
2034
|
+
_o.label = 4;
|
|
1972
2035
|
case 4:
|
|
1973
|
-
|
|
2036
|
+
_o.trys.push([4, 45, 46, 47]);
|
|
1974
2037
|
if (!!isJokerAttempt) return [3 /*break*/, 27];
|
|
1975
2038
|
_a = currentTemplate.executionType;
|
|
1976
2039
|
switch (_a) {
|
|
@@ -1993,6 +2056,67 @@ function createPromptbookExecutor(options) {
|
|
|
1993
2056
|
content: replaceParameters(currentTemplate.content, parametersToPass) /* <- [2] */,
|
|
1994
2057
|
modelRequirements: currentTemplate.modelRequirements,
|
|
1995
2058
|
expectations: currentTemplate.expectations,
|
|
2059
|
+
postprocessing: (currentTemplate.postprocessing || []).map(function (functionName) { return function (result) { return __awaiter(_this, void 0, void 0, function () {
|
|
2060
|
+
var errors, _a, _b, scriptTools, error_5, e_5_1;
|
|
2061
|
+
var e_5, _c;
|
|
2062
|
+
return __generator(this, function (_d) {
|
|
2063
|
+
switch (_d.label) {
|
|
2064
|
+
case 0:
|
|
2065
|
+
errors = [];
|
|
2066
|
+
_d.label = 1;
|
|
2067
|
+
case 1:
|
|
2068
|
+
_d.trys.push([1, 8, 9, 10]);
|
|
2069
|
+
_a = __values(tools.script), _b = _a.next();
|
|
2070
|
+
_d.label = 2;
|
|
2071
|
+
case 2:
|
|
2072
|
+
if (!!_b.done) return [3 /*break*/, 7];
|
|
2073
|
+
scriptTools = _b.value;
|
|
2074
|
+
_d.label = 3;
|
|
2075
|
+
case 3:
|
|
2076
|
+
_d.trys.push([3, 5, , 6]);
|
|
2077
|
+
return [4 /*yield*/, scriptTools.execute({
|
|
2078
|
+
scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
|
|
2079
|
+
script: "".concat(functionName, "(result)"),
|
|
2080
|
+
parameters: {
|
|
2081
|
+
result: result || '',
|
|
2082
|
+
// Note: No ...parametersToPass, because working with result only
|
|
2083
|
+
},
|
|
2084
|
+
})];
|
|
2085
|
+
case 4: return [2 /*return*/, _d.sent()];
|
|
2086
|
+
case 5:
|
|
2087
|
+
error_5 = _d.sent();
|
|
2088
|
+
if (!(error_5 instanceof Error)) {
|
|
2089
|
+
throw error_5;
|
|
2090
|
+
}
|
|
2091
|
+
errors.push(error_5);
|
|
2092
|
+
return [3 /*break*/, 6];
|
|
2093
|
+
case 6:
|
|
2094
|
+
_b = _a.next();
|
|
2095
|
+
return [3 /*break*/, 2];
|
|
2096
|
+
case 7: return [3 /*break*/, 10];
|
|
2097
|
+
case 8:
|
|
2098
|
+
e_5_1 = _d.sent();
|
|
2099
|
+
e_5 = { error: e_5_1 };
|
|
2100
|
+
return [3 /*break*/, 10];
|
|
2101
|
+
case 9:
|
|
2102
|
+
try {
|
|
2103
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
2104
|
+
}
|
|
2105
|
+
finally { if (e_5) throw e_5.error; }
|
|
2106
|
+
return [7 /*endfinally*/];
|
|
2107
|
+
case 10:
|
|
2108
|
+
if (errors.length === 0) {
|
|
2109
|
+
throw new PromptbookExecutionError('Postprocessing in NaturalExecutionTools failed because no ScriptExecutionTools were provided');
|
|
2110
|
+
}
|
|
2111
|
+
else if (errors.length === 1) {
|
|
2112
|
+
throw errors[0];
|
|
2113
|
+
}
|
|
2114
|
+
else {
|
|
2115
|
+
throw new PromptbookExecutionError(spaceTrim(function (block) { return "\n Postprocessing in NaturalExecutionTools failed ".concat(errors.length, "x\n\n ").concat(block(errors.map(function (error) { return '- ' + error.message; }).join('\n\n')), "\n "); }));
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
});
|
|
2119
|
+
}); }; }),
|
|
1996
2120
|
};
|
|
1997
2121
|
_b = currentTemplate.modelRequirements.modelVariant;
|
|
1998
2122
|
switch (_b) {
|
|
@@ -2002,14 +2126,14 @@ function createPromptbookExecutor(options) {
|
|
|
2002
2126
|
return [3 /*break*/, 11];
|
|
2003
2127
|
case 7: return [4 /*yield*/, tools.natural.gptChat(prompt)];
|
|
2004
2128
|
case 8:
|
|
2005
|
-
chatThread =
|
|
2129
|
+
chatThread = _o.sent();
|
|
2006
2130
|
// TODO: [๐ฌ] Destroy chatThread
|
|
2007
2131
|
result = chatThread;
|
|
2008
2132
|
resultString = chatThread.content;
|
|
2009
2133
|
return [3 /*break*/, 12];
|
|
2010
2134
|
case 9: return [4 /*yield*/, tools.natural.gptComplete(prompt)];
|
|
2011
2135
|
case 10:
|
|
2012
|
-
completionResult =
|
|
2136
|
+
completionResult = _o.sent();
|
|
2013
2137
|
result = completionResult;
|
|
2014
2138
|
resultString = completionResult.content;
|
|
2015
2139
|
return [3 /*break*/, 12];
|
|
@@ -2024,27 +2148,27 @@ function createPromptbookExecutor(options) {
|
|
|
2024
2148
|
}
|
|
2025
2149
|
// TODO: DRY [1]
|
|
2026
2150
|
scriptExecutionErrors = [];
|
|
2027
|
-
|
|
2151
|
+
_o.label = 14;
|
|
2028
2152
|
case 14:
|
|
2029
|
-
|
|
2153
|
+
_o.trys.push([14, 21, 22, 23]);
|
|
2030
2154
|
_c = (e_2 = void 0, __values(tools.script)), _d = _c.next();
|
|
2031
|
-
|
|
2155
|
+
_o.label = 15;
|
|
2032
2156
|
case 15:
|
|
2033
2157
|
if (!!_d.done) return [3 /*break*/, 20];
|
|
2034
2158
|
scriptTools = _d.value;
|
|
2035
|
-
|
|
2159
|
+
_o.label = 16;
|
|
2036
2160
|
case 16:
|
|
2037
|
-
|
|
2161
|
+
_o.trys.push([16, 18, , 19]);
|
|
2038
2162
|
return [4 /*yield*/, scriptTools.execute({
|
|
2039
2163
|
scriptLanguage: currentTemplate.contentLanguage,
|
|
2040
2164
|
script: currentTemplate.content,
|
|
2041
2165
|
parameters: parametersToPass,
|
|
2042
2166
|
})];
|
|
2043
2167
|
case 17:
|
|
2044
|
-
resultString =
|
|
2168
|
+
resultString = _o.sent();
|
|
2045
2169
|
return [3 /*break*/, 20];
|
|
2046
2170
|
case 18:
|
|
2047
|
-
error_2 =
|
|
2171
|
+
error_2 = _o.sent();
|
|
2048
2172
|
if (!(error_2 instanceof Error)) {
|
|
2049
2173
|
throw error_2;
|
|
2050
2174
|
}
|
|
@@ -2055,17 +2179,17 @@ function createPromptbookExecutor(options) {
|
|
|
2055
2179
|
return [3 /*break*/, 15];
|
|
2056
2180
|
case 20: return [3 /*break*/, 23];
|
|
2057
2181
|
case 21:
|
|
2058
|
-
e_2_1 =
|
|
2182
|
+
e_2_1 = _o.sent();
|
|
2059
2183
|
e_2 = { error: e_2_1 };
|
|
2060
2184
|
return [3 /*break*/, 23];
|
|
2061
2185
|
case 22:
|
|
2062
2186
|
try {
|
|
2063
|
-
if (_d && !_d.done && (
|
|
2187
|
+
if (_d && !_d.done && (_j = _c.return)) _j.call(_c);
|
|
2064
2188
|
}
|
|
2065
2189
|
finally { if (e_2) throw e_2.error; }
|
|
2066
2190
|
return [7 /*endfinally*/];
|
|
2067
2191
|
case 23:
|
|
2068
|
-
if (resultString) {
|
|
2192
|
+
if (resultString !== null) {
|
|
2069
2193
|
return [3 /*break*/, 27];
|
|
2070
2194
|
}
|
|
2071
2195
|
if (scriptExecutionErrors.length === 1) {
|
|
@@ -2086,46 +2210,49 @@ function createPromptbookExecutor(options) {
|
|
|
2086
2210
|
})];
|
|
2087
2211
|
case 25:
|
|
2088
2212
|
// TODO: [๐น] When making next attempt for `PROMPT DIALOG`, preserve the previous user input
|
|
2089
|
-
resultString =
|
|
2213
|
+
resultString = _o.sent();
|
|
2090
2214
|
return [3 /*break*/, 27];
|
|
2091
2215
|
case 26: throw new PromptbookExecutionError(
|
|
2092
2216
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2093
2217
|
"Unknown execution type \"".concat(currentTemplate.executionType, "\""));
|
|
2094
2218
|
case 27:
|
|
2095
2219
|
if (!(!isJokerAttempt && currentTemplate.postprocessing)) return [3 /*break*/, 44];
|
|
2096
|
-
|
|
2220
|
+
_o.label = 28;
|
|
2097
2221
|
case 28:
|
|
2098
|
-
|
|
2222
|
+
_o.trys.push([28, 42, 43, 44]);
|
|
2099
2223
|
_e = (e_4 = void 0, __values(currentTemplate.postprocessing)), _f = _e.next();
|
|
2100
|
-
|
|
2224
|
+
_o.label = 29;
|
|
2101
2225
|
case 29:
|
|
2102
2226
|
if (!!_f.done) return [3 /*break*/, 41];
|
|
2103
2227
|
functionName = _f.value;
|
|
2104
2228
|
// TODO: DRY [1]
|
|
2105
2229
|
scriptExecutionErrors = [];
|
|
2106
2230
|
postprocessingError = null;
|
|
2107
|
-
|
|
2231
|
+
_o.label = 30;
|
|
2108
2232
|
case 30:
|
|
2109
|
-
|
|
2233
|
+
_o.trys.push([30, 37, 38, 39]);
|
|
2110
2234
|
_g = (e_3 = void 0, __values(tools.script)), _h = _g.next();
|
|
2111
|
-
|
|
2235
|
+
_o.label = 31;
|
|
2112
2236
|
case 31:
|
|
2113
2237
|
if (!!_h.done) return [3 /*break*/, 36];
|
|
2114
2238
|
scriptTools = _h.value;
|
|
2115
|
-
|
|
2239
|
+
_o.label = 32;
|
|
2116
2240
|
case 32:
|
|
2117
|
-
|
|
2241
|
+
_o.trys.push([32, 34, , 35]);
|
|
2118
2242
|
return [4 /*yield*/, scriptTools.execute({
|
|
2119
2243
|
scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
|
|
2120
2244
|
script: "".concat(functionName, "(resultString)"),
|
|
2121
|
-
parameters:
|
|
2245
|
+
parameters: {
|
|
2246
|
+
resultString: resultString || '',
|
|
2247
|
+
// Note: No ...parametersToPass, because working with result only
|
|
2248
|
+
},
|
|
2122
2249
|
})];
|
|
2123
2250
|
case 33:
|
|
2124
|
-
resultString =
|
|
2251
|
+
resultString = _o.sent();
|
|
2125
2252
|
postprocessingError = null;
|
|
2126
2253
|
return [3 /*break*/, 36];
|
|
2127
2254
|
case 34:
|
|
2128
|
-
error_3 =
|
|
2255
|
+
error_3 = _o.sent();
|
|
2129
2256
|
if (!(error_3 instanceof Error)) {
|
|
2130
2257
|
throw error_3;
|
|
2131
2258
|
}
|
|
@@ -2137,12 +2264,12 @@ function createPromptbookExecutor(options) {
|
|
|
2137
2264
|
return [3 /*break*/, 31];
|
|
2138
2265
|
case 36: return [3 /*break*/, 39];
|
|
2139
2266
|
case 37:
|
|
2140
|
-
e_3_1 =
|
|
2267
|
+
e_3_1 = _o.sent();
|
|
2141
2268
|
e_3 = { error: e_3_1 };
|
|
2142
2269
|
return [3 /*break*/, 39];
|
|
2143
2270
|
case 38:
|
|
2144
2271
|
try {
|
|
2145
|
-
if (_h && !_h.done && (
|
|
2272
|
+
if (_h && !_h.done && (_l = _g.return)) _l.call(_g);
|
|
2146
2273
|
}
|
|
2147
2274
|
finally { if (e_3) throw e_3.error; }
|
|
2148
2275
|
return [7 /*endfinally*/];
|
|
@@ -2150,22 +2277,23 @@ function createPromptbookExecutor(options) {
|
|
|
2150
2277
|
if (postprocessingError) {
|
|
2151
2278
|
throw postprocessingError;
|
|
2152
2279
|
}
|
|
2153
|
-
|
|
2280
|
+
_o.label = 40;
|
|
2154
2281
|
case 40:
|
|
2155
2282
|
_f = _e.next();
|
|
2156
2283
|
return [3 /*break*/, 29];
|
|
2157
2284
|
case 41: return [3 /*break*/, 44];
|
|
2158
2285
|
case 42:
|
|
2159
|
-
e_4_1 =
|
|
2286
|
+
e_4_1 = _o.sent();
|
|
2160
2287
|
e_4 = { error: e_4_1 };
|
|
2161
2288
|
return [3 /*break*/, 44];
|
|
2162
2289
|
case 43:
|
|
2163
2290
|
try {
|
|
2164
|
-
if (_f && !_f.done && (
|
|
2291
|
+
if (_f && !_f.done && (_k = _e.return)) _k.call(_e);
|
|
2165
2292
|
}
|
|
2166
2293
|
finally { if (e_4) throw e_4.error; }
|
|
2167
2294
|
return [7 /*endfinally*/];
|
|
2168
2295
|
case 44:
|
|
2296
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
2169
2297
|
if (currentTemplate.expectFormat) {
|
|
2170
2298
|
if (currentTemplate.expectFormat === 'JSON') {
|
|
2171
2299
|
if (!isValidJsonString(resultString || '')) {
|
|
@@ -2173,30 +2301,13 @@ function createPromptbookExecutor(options) {
|
|
|
2173
2301
|
}
|
|
2174
2302
|
}
|
|
2175
2303
|
}
|
|
2304
|
+
// TODO: [๐] Unite object for expecting amount and format
|
|
2176
2305
|
if (currentTemplate.expectations) {
|
|
2177
|
-
|
|
2178
|
-
for (_j = (e_5 = void 0, __values(Object.entries(currentTemplate.expectations))), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
2179
|
-
_l = __read(_k.value, 2), unit = _l[0], _m = _l[1], max = _m.max, min = _m.min;
|
|
2180
|
-
amount = CountUtils[unit.toUpperCase()](resultString || '');
|
|
2181
|
-
if (min && amount < min) {
|
|
2182
|
-
throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
|
|
2183
|
-
} /* not else */
|
|
2184
|
-
if (max && amount > max) {
|
|
2185
|
-
throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
2190
|
-
finally {
|
|
2191
|
-
try {
|
|
2192
|
-
if (_k && !_k.done && (_r = _j.return)) _r.call(_j);
|
|
2193
|
-
}
|
|
2194
|
-
finally { if (e_5) throw e_5.error; }
|
|
2195
|
-
}
|
|
2306
|
+
checkExpectations(currentTemplate.expectations, resultString || '');
|
|
2196
2307
|
}
|
|
2197
2308
|
return [3 /*break*/, 49];
|
|
2198
2309
|
case 45:
|
|
2199
|
-
error_4 =
|
|
2310
|
+
error_4 = _o.sent();
|
|
2200
2311
|
if (!(error_4 instanceof ExpectError)) {
|
|
2201
2312
|
throw error_4;
|
|
2202
2313
|
}
|
|
@@ -2225,9 +2336,9 @@ function createPromptbookExecutor(options) {
|
|
|
2225
2336
|
return [7 /*endfinally*/];
|
|
2226
2337
|
case 47:
|
|
2227
2338
|
if (expectError !== null && attempt === maxAttempts - 1) {
|
|
2228
|
-
throw new PromptbookExecutionError(spaceTrim(function (block) { return "\n Natural execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n "); }));
|
|
2339
|
+
throw new PromptbookExecutionError(spaceTrim(function (block) { return "\n Natural execution failed ".concat(maxExecutionAttempts, "x\n\n ---\n Last error ").concat((expectError === null || expectError === void 0 ? void 0 : expectError.name) || '', ":\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n\n Last result:\n ").concat(resultString, "\n ---\n "); }));
|
|
2229
2340
|
}
|
|
2230
|
-
|
|
2341
|
+
_o.label = 48;
|
|
2231
2342
|
case 48:
|
|
2232
2343
|
attempt++;
|
|
2233
2344
|
return [3 /*break*/, 3];
|
|
@@ -2247,7 +2358,7 @@ function createPromptbookExecutor(options) {
|
|
|
2247
2358
|
// <- [3]
|
|
2248
2359
|
});
|
|
2249
2360
|
}
|
|
2250
|
-
parametersToPass = __assign(__assign({}, parametersToPass), (
|
|
2361
|
+
parametersToPass = __assign(__assign({}, parametersToPass), (_m = {}, _m[currentTemplate.resultingParameterName] = resultString /* <- Note: Not need to detect parameter collision here because Promptbook checks logic consistency during construction */, _m));
|
|
2251
2362
|
return [2 /*return*/];
|
|
2252
2363
|
}
|
|
2253
2364
|
});
|
|
@@ -2457,22 +2568,75 @@ var MockedEchoNaturalExecutionTools = /** @class */ (function () {
|
|
|
2457
2568
|
/**
|
|
2458
2569
|
* Gets the expectations and creates a fake text that meets the expectations
|
|
2459
2570
|
*
|
|
2571
|
+
* Note: You can provide postprocessing functions to modify the text before checking the expectations
|
|
2572
|
+
* The result will be the text BEFORE the postprocessing
|
|
2573
|
+
*
|
|
2460
2574
|
* @private internal util for MockedFackedNaturalExecutionTools
|
|
2461
2575
|
*/
|
|
2462
|
-
function $fakeTextToExpectations(expectations) {
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2576
|
+
function $fakeTextToExpectations(expectations, postprocessing) {
|
|
2577
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2578
|
+
var lorem, loremText, text, loopLimit, textToCheck, _a, _b, func, e_1_1;
|
|
2579
|
+
var e_1, _c;
|
|
2580
|
+
return __generator(this, function (_d) {
|
|
2581
|
+
switch (_d.label) {
|
|
2582
|
+
case 0:
|
|
2583
|
+
lorem = new LoremIpsum({
|
|
2584
|
+
wordsPerSentence: { min: 5, max: 15 },
|
|
2585
|
+
sentencesPerParagraph: { min: 5, max: 15 },
|
|
2586
|
+
});
|
|
2587
|
+
loremText = '';
|
|
2588
|
+
text = '';
|
|
2589
|
+
loopLimit = CHARACTER_LOOP_LIMIT;
|
|
2590
|
+
_d.label = 1;
|
|
2591
|
+
case 1:
|
|
2592
|
+
if (!(loopLimit-- > 0)) return [3 /*break*/, 11];
|
|
2593
|
+
textToCheck = text;
|
|
2594
|
+
_d.label = 2;
|
|
2595
|
+
case 2:
|
|
2596
|
+
_d.trys.push([2, 7, 8, 9]);
|
|
2597
|
+
_a = (e_1 = void 0, __values(postprocessing || [])), _b = _a.next();
|
|
2598
|
+
_d.label = 3;
|
|
2599
|
+
case 3:
|
|
2600
|
+
if (!!_b.done) return [3 /*break*/, 6];
|
|
2601
|
+
func = _b.value;
|
|
2602
|
+
return [4 /*yield*/, func(textToCheck)];
|
|
2603
|
+
case 4:
|
|
2604
|
+
textToCheck = _d.sent();
|
|
2605
|
+
_d.label = 5;
|
|
2606
|
+
case 5:
|
|
2607
|
+
_b = _a.next();
|
|
2608
|
+
return [3 /*break*/, 3];
|
|
2609
|
+
case 6: return [3 /*break*/, 9];
|
|
2610
|
+
case 7:
|
|
2611
|
+
e_1_1 = _d.sent();
|
|
2612
|
+
e_1 = { error: e_1_1 };
|
|
2613
|
+
return [3 /*break*/, 9];
|
|
2614
|
+
case 8:
|
|
2615
|
+
try {
|
|
2616
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
2617
|
+
}
|
|
2618
|
+
finally { if (e_1) throw e_1.error; }
|
|
2619
|
+
return [7 /*endfinally*/];
|
|
2620
|
+
case 9:
|
|
2621
|
+
if (isPassingExpectations(expectations, textToCheck)) {
|
|
2622
|
+
return [2 /*return*/, text]; // <- Note: Returning the text because the postprocessing
|
|
2623
|
+
}
|
|
2624
|
+
if (loremText === '') {
|
|
2625
|
+
loremText = lorem.generateParagraphs(1) + '\n\n';
|
|
2626
|
+
}
|
|
2627
|
+
text += loremText.substring(0, 1);
|
|
2628
|
+
loremText = loremText.substring(1);
|
|
2629
|
+
_d.label = 10;
|
|
2630
|
+
case 10: return [3 /*break*/, 1];
|
|
2631
|
+
case 11: throw new Error(spaceTrim(function (block) { return "\n Can not generate fake text to met the expectations\n\n Loop limit reached\n The expectations:\n ".concat(block(JSON.stringify(expectations, null, 4)), "\n\n The draft text:\n ").concat(block(text), "\n\n "); }));
|
|
2632
|
+
}
|
|
2633
|
+
});
|
|
2472
2634
|
});
|
|
2473
|
-
// TODO: !!! Really use the expectations to generate the text
|
|
2474
|
-
return lorem.generateSentences(5);
|
|
2475
2635
|
}
|
|
2636
|
+
/**
|
|
2637
|
+
* TODO: Implement better - create FakeLLM from this
|
|
2638
|
+
* TODO: [๐] Unite object for expecting amount and format - use here also a format
|
|
2639
|
+
*/
|
|
2476
2640
|
|
|
2477
2641
|
/**
|
|
2478
2642
|
* Mocked execution Tools for just faking expected responses for testing purposes
|
|
@@ -2486,29 +2650,40 @@ var MockedFackedNaturalExecutionTools = /** @class */ (function () {
|
|
|
2486
2650
|
*/
|
|
2487
2651
|
MockedFackedNaturalExecutionTools.prototype.gptChat = function (prompt) {
|
|
2488
2652
|
return __awaiter(this, void 0, void 0, function () {
|
|
2653
|
+
var content, result;
|
|
2489
2654
|
return __generator(this, function (_a) {
|
|
2490
|
-
|
|
2491
|
-
|
|
2655
|
+
switch (_a.label) {
|
|
2656
|
+
case 0:
|
|
2657
|
+
if (this.options.isVerbose) {
|
|
2658
|
+
console.info('๐ฌ Mocked faked prompt', prompt);
|
|
2659
|
+
}
|
|
2660
|
+
return [4 /*yield*/, $fakeTextToExpectations(prompt.expectations || {
|
|
2661
|
+
sentences: { min: 1, max: 1 },
|
|
2662
|
+
}, prompt.postprocessing)];
|
|
2663
|
+
case 1:
|
|
2664
|
+
content = _a.sent();
|
|
2665
|
+
result = {
|
|
2666
|
+
content: content,
|
|
2667
|
+
model: 'mocked-facked',
|
|
2668
|
+
timing: {
|
|
2669
|
+
start: getCurrentIsoDate(),
|
|
2670
|
+
complete: getCurrentIsoDate(),
|
|
2671
|
+
},
|
|
2672
|
+
usage: {
|
|
2673
|
+
price: 0,
|
|
2674
|
+
inputTokens: 0,
|
|
2675
|
+
outputTokens: 0,
|
|
2676
|
+
},
|
|
2677
|
+
rawResponse: {
|
|
2678
|
+
note: 'This is mocked echo',
|
|
2679
|
+
},
|
|
2680
|
+
// <- [๐คนโโ๏ธ]
|
|
2681
|
+
};
|
|
2682
|
+
if (this.options.isVerbose) {
|
|
2683
|
+
console.info('๐ฌ Mocked faked result', result);
|
|
2684
|
+
}
|
|
2685
|
+
return [2 /*return*/, result];
|
|
2492
2686
|
}
|
|
2493
|
-
return [2 /*return*/, {
|
|
2494
|
-
content: $fakeTextToExpectations(prompt.expectations || {
|
|
2495
|
-
sentences: { min: 1, max: 1 },
|
|
2496
|
-
}),
|
|
2497
|
-
model: 'mocked-facked',
|
|
2498
|
-
timing: {
|
|
2499
|
-
start: getCurrentIsoDate(),
|
|
2500
|
-
complete: getCurrentIsoDate(),
|
|
2501
|
-
},
|
|
2502
|
-
usage: {
|
|
2503
|
-
price: 0,
|
|
2504
|
-
inputTokens: 0,
|
|
2505
|
-
outputTokens: 0,
|
|
2506
|
-
},
|
|
2507
|
-
rawResponse: {
|
|
2508
|
-
note: 'This is mocked echo',
|
|
2509
|
-
},
|
|
2510
|
-
// <- [๐คนโโ๏ธ]
|
|
2511
|
-
}];
|
|
2512
2687
|
});
|
|
2513
2688
|
});
|
|
2514
2689
|
};
|