@promptbook/core 0.25.0 → 0.27.0-0

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/esm/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { capitalize, normalizeTo_SCREAMING_CASE, normalizeTo_PascalCase, normalizeTo_camelCase, removeDiacritics } from 'n12';
1
+ import { capitalize, normalizeTo_SCREAMING_CASE, normalizeTo_PascalCase, removeDiacritics } from 'n12';
2
2
  import spaceTrim from 'spacetrim';
3
3
 
4
4
  /*! *****************************************************************************
@@ -15,6 +15,22 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
15
15
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16
16
  PERFORMANCE OF THIS SOFTWARE.
17
17
  ***************************************************************************** */
18
+ /* global Reflect, Promise */
19
+
20
+ var extendStatics = function(d, b) {
21
+ extendStatics = Object.setPrototypeOf ||
22
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
23
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
24
+ return extendStatics(d, b);
25
+ };
26
+
27
+ function __extends(d, b) {
28
+ if (typeof b !== "function" && b !== null)
29
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
30
+ extendStatics(d, b);
31
+ function __() { this.constructor = d; }
32
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
33
+ }
18
34
 
19
35
  var __assign = function() {
20
36
  __assign = Object.assign || function __assign(t) {
@@ -561,6 +577,12 @@ function parseCommand(listItem) {
561
577
  functionName: functionName,
562
578
  };
563
579
  }
580
+ else if (type.startsWith('EXPECT_JSON')) {
581
+ return {
582
+ type: 'EXPECT_FORMAT',
583
+ format: 'JSON',
584
+ };
585
+ }
564
586
  else if (type.startsWith('EXPECT')) {
565
587
  try {
566
588
  listItemParts.shift();
@@ -616,7 +638,7 @@ function parseCommand(listItem) {
616
638
  throw new Error("Invalid unit \"".concat(unitRaw, "\""));
617
639
  }
618
640
  return {
619
- type: 'EXPECT',
641
+ type: 'EXPECT_AMOUNT',
620
642
  sign: sign,
621
643
  unit: unit,
622
644
  amount: amount,
@@ -731,13 +753,14 @@ function promptTemplatePipelineStringToJson(promptTemplatePipelineString) {
731
753
  finally { if (e_1) throw e_1.error; }
732
754
  }
733
755
  var _loop_1 = function (section) {
734
- var e_3, _e, e_4, _f;
756
+ var e_3, _e;
735
757
  // TODO: Parse prompt template description (the content out of the codeblock and lists)
736
758
  var templateModelRequirements = __assign({}, defaultModelRequirements);
737
- var postprocessingCommands = [];
738
759
  var listItems_3 = extractAllListItemsFromMarkdown(section.content);
739
760
  var executionType = 'PROMPT_TEMPLATE';
740
- var expectations = {};
761
+ var postprocessing = [];
762
+ var expectAmount = {};
763
+ var expectFormat = undefined;
741
764
  var isExecutionTypeChanged = false;
742
765
  try {
743
766
  for (var listItems_2 = (e_3 = void 0, __values(listItems_3)), listItems_2_1 = listItems_2.next(); !listItems_2_1.done; listItems_2_1 = listItems_2.next()) {
@@ -759,24 +782,30 @@ function promptTemplatePipelineStringToJson(promptTemplatePipelineString) {
759
782
  addParam(command);
760
783
  break;
761
784
  case 'POSTPROCESS':
762
- postprocessingCommands.push(command);
785
+ postprocessing.push(command.functionName);
763
786
  break;
764
- case 'EXPECT':
787
+ case 'EXPECT_AMOUNT':
765
788
  // eslint-disable-next-line no-case-declarations
766
789
  var unit = command.unit.toLowerCase();
767
- expectations[unit] = expectations[unit] || {};
790
+ expectAmount[unit] = expectAmount[unit] || {};
768
791
  if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
769
- if (expectations[unit].min !== undefined) {
770
- throw new Error("Already defined minumum ".concat(expectations[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
792
+ if (expectAmount[unit].min !== undefined) {
793
+ throw new Error("Already defined minumum ".concat(expectAmount[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
771
794
  }
772
- expectations[unit].min = command.amount;
795
+ expectAmount[unit].min = command.amount;
773
796
  } /* not else */
774
797
  if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
775
- if (expectations[unit].max !== undefined) {
776
- throw new Error("Already defined maximum ".concat(expectations[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
798
+ if (expectAmount[unit].max !== undefined) {
799
+ throw new Error("Already defined maximum ".concat(expectAmount[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
777
800
  }
778
- expectations[unit].max = command.amount;
801
+ expectAmount[unit].max = command.amount;
802
+ }
803
+ break;
804
+ case 'EXPECT_FORMAT':
805
+ if (expectFormat !== undefined && command.format !== expectFormat) {
806
+ throw new Error("Expect format is already defined to \"".concat(expectFormat, "\". Now you try to redefine it by \"").concat(command.format, "\"."));
779
807
  }
808
+ expectFormat = command.format;
780
809
  break;
781
810
  default:
782
811
  throw new Error("Command ".concat(command.type, " is not allowed in the block of the prompt template ONLY at the head of the prompt template pipeline"));
@@ -790,7 +819,7 @@ function promptTemplatePipelineStringToJson(promptTemplatePipelineString) {
790
819
  }
791
820
  finally { if (e_3) throw e_3.error; }
792
821
  }
793
- var _g = extractOneBlockFromMarkdown(section.content), language = _g.language, content = _g.content;
822
+ var _f = extractOneBlockFromMarkdown(section.content), language = _f.language, content = _f.content;
794
823
  if (executionType === 'SCRIPT') {
795
824
  if (!language) {
796
825
  throw new Error('You must specify the language of the script in the prompt template');
@@ -820,57 +849,25 @@ function promptTemplatePipelineStringToJson(promptTemplatePipelineString) {
820
849
  if (description_1 === '') {
821
850
  description_1 = undefined;
822
851
  }
823
- var getParameterName = function (i) {
824
- var parameterName = postprocessingCommands.length <= i
825
- ? resultingParameterName
826
- : normalizeTo_camelCase("".concat(resultingParameterName, " before ").concat(postprocessingCommands[i].functionName));
827
- var isParameterDefined = ptbJson.parameters.some(function (parameter) { return parameter.name === parameterName; });
828
- if (!isParameterDefined) {
829
- var parameterDescription = "*(".concat(capitalize(section.title), " postprocessing ").concat(i + 1, "/").concat(postprocessingCommands.length, ")* {").concat(resultingParameterName, "} before `").concat(postprocessingCommands[i].functionName, "`");
830
- addParam({
831
- parameterName: parameterName,
832
- parameterDescription: parameterDescription,
833
- isInputParameter: false,
834
- // TODO:> isPrivate: true,
835
- });
836
- }
837
- return parameterName;
838
- };
852
+ if (Object.keys(expectAmount).length === 0) {
853
+ expectAmount = undefined;
854
+ }
855
+ if (Object.keys(postprocessing).length === 0) {
856
+ postprocessing = undefined;
857
+ }
839
858
  ptbJson.promptTemplates.push({
840
859
  name: normalizeTo_PascalCase(section.title),
841
860
  title: section.title,
842
861
  description: description_1,
843
862
  executionType: executionType,
844
- expectations: expectations,
863
+ postprocessing: postprocessing,
864
+ expectAmount: expectAmount,
865
+ expectFormat: expectFormat,
845
866
  modelRequirements: templateModelRequirements,
846
867
  contentLanguage: executionType === 'SCRIPT' ? language : undefined,
847
868
  content: content,
848
- resultingParameterName: getParameterName(0),
869
+ resultingParameterName: resultingParameterName,
849
870
  });
850
- try {
851
- for (var _h = (e_4 = void 0, __values(postprocessingCommands.map(function (_a, i) {
852
- var functionName = _a.functionName;
853
- return [functionName, i];
854
- }))), _j = _h.next(); !_j.done; _j = _h.next()) {
855
- var _k = __read(_j.value, 2), functionName = _k[0], i = _k[1];
856
- ptbJson.promptTemplates.push({
857
- name: normalizeTo_PascalCase(section.title + ' Postprocessing ' + i),
858
- title: "(".concat(i + 1, "/").concat(postprocessingCommands.length, ") ").concat(section.title, " postprocessing"),
859
- description: "Postprocessing of section ".concat(section.title, " finally with resulting parameter {").concat(resultingParameterName, "}"),
860
- executionType: 'SCRIPT',
861
- contentLanguage: 'javascript',
862
- content: "".concat(functionName, "(").concat(getParameterName(i), ")"),
863
- resultingParameterName: getParameterName(i + 1),
864
- });
865
- }
866
- }
867
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
868
- finally {
869
- try {
870
- if (_j && !_j.done && (_f = _h.return)) _f.call(_h);
871
- }
872
- finally { if (e_4) throw e_4.error; }
873
- }
874
871
  };
875
872
  try {
876
873
  for (var _c = __values(markdownStructure.sections), _d = _c.next(); !_d.done; _d = _c.next()) {
@@ -891,9 +888,7 @@ function promptTemplatePipelineStringToJson(promptTemplatePipelineString) {
891
888
  /**
892
889
  * TODO: Report here line/column of error
893
890
  * TODO: Use spaceTrim more effectively
894
- * TODO: !!!! Parameter flags - isInput, isOutput, isInternal, isBeforePostprocessing, isBeforeFinal, canonicalName
895
- * TODO: !!!! Allow to have non-immutable parameters - suffix them with fooPrevious3 -> fooPrevious2 -> fooPrevious1 -> foo
896
- * This must work with other technial parameters
891
+ * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
897
892
  */
898
893
 
899
894
  /**
@@ -1024,7 +1019,7 @@ var PromptTemplatePipeline = /** @class */ (function () {
1024
1019
  */
1025
1020
  PromptTemplatePipeline.fromJson = function (ptbkjson) {
1026
1021
  validatePromptTemplatePipelineJson(ptbkjson);
1027
- return new PromptTemplatePipeline(ptbkjson.ptbkUrl ? new URL(ptbkjson.ptbkUrl) : null, ptbkjson.title, ptbkjson.ptbkVersion, ptbkjson.ptbkVersion, Object.fromEntries(ptbkjson.parameters.map(function (parameter) { return [parameter.name, parameter]; })), ptbkjson.promptTemplates);
1022
+ return new PromptTemplatePipeline(ptbkjson.ptbkUrl ? new URL(ptbkjson.ptbkUrl) : null, ptbkjson.title, ptbkjson.ptbkVersion, ptbkjson.description || null, Object.fromEntries(ptbkjson.parameters.map(function (parameter) { return [parameter.name, parameter]; })), ptbkjson.promptTemplates);
1028
1023
  };
1029
1024
  Object.defineProperty(PromptTemplatePipeline.prototype, "entryPromptTemplate", {
1030
1025
  /**
@@ -1149,6 +1144,25 @@ var CountUtils = {
1149
1144
  PAGES: countPages,
1150
1145
  };
1151
1146
 
1147
+ /**
1148
+ * Function isValidJsonString will tell you if the string is valid JSON or not
1149
+ */
1150
+ function isValidJsonString(value) {
1151
+ try {
1152
+ JSON.parse(value);
1153
+ return true;
1154
+ }
1155
+ catch (error) {
1156
+ if (!(error instanceof Error)) {
1157
+ throw error;
1158
+ }
1159
+ if (error.message.includes('Unexpected token')) {
1160
+ return false;
1161
+ }
1162
+ return false;
1163
+ }
1164
+ }
1165
+
1152
1166
  /**
1153
1167
  * All possible emoji chars like "🍆", "🍡", "🍤"...
1154
1168
  * Note: this will be needed to update annually - now updated at 2022-01-19
@@ -1265,6 +1279,23 @@ function replaceParameters(template, parameters) {
1265
1279
  return replacedTemplate;
1266
1280
  }
1267
1281
 
1282
+ /**
1283
+ * This error occurs when some expectation is not met in the execution of the pipeline
1284
+ */
1285
+ var ExpectError = /** @class */ (function (_super) {
1286
+ __extends(ExpectError, _super);
1287
+ function ExpectError(message) {
1288
+ var _this = _super.call(this, message) || this;
1289
+ _this.name = 'ExpectError';
1290
+ Object.setPrototypeOf(_this, ExpectError.prototype);
1291
+ return _this;
1292
+ }
1293
+ return ExpectError;
1294
+ }(Error));
1295
+ /**
1296
+ * TODO: [🧠] Should be this exported from the library
1297
+ */
1298
+
1268
1299
  /**
1269
1300
  * Creates executor function from prompt template pipeline and execution tools.
1270
1301
  *
@@ -1273,7 +1304,7 @@ function replaceParameters(template, parameters) {
1273
1304
  function createPtpExecutor(options) {
1274
1305
  var _this = this;
1275
1306
  var ptp = options.ptp, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
1276
- var _b = settings.maxNaturalExecutionAttempts, maxNaturalExecutionAttempts = _b === void 0 ? 3 : _b;
1307
+ var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? 3 : _b;
1277
1308
  var ptpExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
1278
1309
  var parametersToPass, currentTemplate, executionReport, _loop_1, error_1;
1279
1310
  var _a;
@@ -1294,10 +1325,10 @@ function createPtpExecutor(options) {
1294
1325
  case 1:
1295
1326
  _b.trys.push([1, 5, , 6]);
1296
1327
  _loop_1 = function () {
1297
- var resultingParameter, name_1, title, prompt_1, chatThread, completionResult, result, resultString, naturalExecutionError, scriptExecutionErrors, isScriptExecutionSuccessful, _c, attempt, _d, _e, _f, _g, unit, _h, max, min, amount, error_2, _j, _k, scriptTools, error_3, e_1_1;
1298
- var e_2, _l, e_1, _m, _o;
1299
- return __generator(this, function (_p) {
1300
- switch (_p.label) {
1328
+ var resultingParameter, name_1, title, prompt_1, chatThread, completionResult, result, resultString, expectError, scriptExecutionErrors, attempt, _c, _d, _e, _f, scriptTools, error_2, e_1_1, _g, _h, functionName, _j, _k, scriptTools, error_3, e_2_1, e_3_1, _l, _m, _o, unit, _p, max, min, amount, error_4;
1329
+ var e_1, _q, e_3, _r, e_2, _s, e_4, _t, _u;
1330
+ return __generator(this, function (_v) {
1331
+ switch (_v.label) {
1301
1332
  case 0:
1302
1333
  resultingParameter = ptp.getResultingParameter(currentTemplate.name);
1303
1334
  name_1 = "ptp-executor-frame-".concat(currentTemplate.name);
@@ -1313,47 +1344,46 @@ function createPtpExecutor(options) {
1313
1344
  parameterValue: null,
1314
1345
  })];
1315
1346
  case 1:
1316
- _p.sent();
1317
- _p.label = 2;
1347
+ _v.sent();
1348
+ _v.label = 2;
1318
1349
  case 2:
1319
1350
  prompt_1 = void 0;
1320
1351
  chatThread = void 0;
1321
1352
  completionResult = void 0;
1322
1353
  result = null;
1323
1354
  resultString = null;
1324
- naturalExecutionError = null;
1325
- isScriptExecutionSuccessful = void 0;
1355
+ expectError = null;
1356
+ attempt = 0;
1357
+ _v.label = 3;
1358
+ case 3:
1359
+ if (!(attempt < maxExecutionAttempts)) return [3 /*break*/, 48];
1360
+ result = null;
1361
+ resultString = null;
1362
+ expectError = null;
1363
+ _v.label = 4;
1364
+ case 4:
1365
+ _v.trys.push([4, 44, 45, 46]);
1326
1366
  _c = currentTemplate.executionType;
1327
1367
  switch (_c) {
1328
- case 'SIMPLE_TEMPLATE': return [3 /*break*/, 3];
1329
- case 'PROMPT_TEMPLATE': return [3 /*break*/, 4];
1330
- case 'SCRIPT': return [3 /*break*/, 18];
1331
- case 'PROMPT_DIALOG': return [3 /*break*/, 29];
1368
+ case 'SIMPLE_TEMPLATE': return [3 /*break*/, 5];
1369
+ case 'PROMPT_TEMPLATE': return [3 /*break*/, 6];
1370
+ case 'SCRIPT': return [3 /*break*/, 13];
1371
+ case 'PROMPT_DIALOG': return [3 /*break*/, 24];
1332
1372
  }
1333
- return [3 /*break*/, 31];
1334
- case 3:
1373
+ return [3 /*break*/, 26];
1374
+ case 5:
1335
1375
  resultString = replaceParameters(currentTemplate.content, parametersToPass);
1336
- return [3 /*break*/, 32];
1337
- case 4:
1376
+ return [3 /*break*/, 27];
1377
+ case 6:
1338
1378
  prompt_1 = {
1339
1379
  title: currentTemplate.title,
1340
1380
  ptbkUrl: "".concat(ptp.ptbkUrl
1341
1381
  ? ptp.ptbkUrl.href
1342
- : 'anonymous' /* <- [🧠] !!!! How to deal with anonymous PTPs, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
1382
+ : 'anonymous' /* <- [🧠] !!! How to deal with anonymous PTPs, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
1343
1383
  parameters: parametersToPass,
1344
- content: replaceParameters(currentTemplate.content, parametersToPass),
1384
+ content: replaceParameters(currentTemplate.content, parametersToPass) /* <- [2] */,
1345
1385
  modelRequirements: currentTemplate.modelRequirements,
1346
1386
  };
1347
- attempt = 0;
1348
- _p.label = 5;
1349
- case 5:
1350
- if (!(attempt < maxNaturalExecutionAttempts)) return [3 /*break*/, 17];
1351
- result = null;
1352
- resultString = null;
1353
- naturalExecutionError = null;
1354
- _p.label = 6;
1355
- case 6:
1356
- _p.trys.push([6, 13, 14, 15]);
1357
1387
  _d = currentTemplate.modelRequirements.modelVariant;
1358
1388
  switch (_d) {
1359
1389
  case 'CHAT': return [3 /*break*/, 7];
@@ -1362,122 +1392,71 @@ function createPtpExecutor(options) {
1362
1392
  return [3 /*break*/, 11];
1363
1393
  case 7: return [4 /*yield*/, tools.natural.gptChat(prompt_1)];
1364
1394
  case 8:
1365
- chatThread = _p.sent();
1395
+ chatThread = _v.sent();
1366
1396
  // TODO: [🍬] Destroy chatThread
1367
1397
  result = chatThread;
1368
1398
  resultString = chatThread.content;
1369
1399
  return [3 /*break*/, 12];
1370
1400
  case 9: return [4 /*yield*/, tools.natural.gptComplete(prompt_1)];
1371
1401
  case 10:
1372
- completionResult = _p.sent();
1402
+ completionResult = _v.sent();
1373
1403
  result = completionResult;
1374
1404
  resultString = completionResult.content;
1375
1405
  return [3 /*break*/, 12];
1376
1406
  case 11: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1377
- case 12:
1378
- try {
1379
- // TODO: !!!!!! Here should postprocessing happen
1380
- for (_e = (e_2 = void 0, __values(Object.entries(currentTemplate.expectations))), _f = _e.next(); !_f.done; _f = _e.next()) {
1381
- _g = __read(_f.value, 2), unit = _g[0], _h = _g[1], max = _h.max, min = _h.min;
1382
- amount = CountUtils[unit.toUpperCase()](resultString);
1383
- if (min && amount < min) {
1384
- throw new Error("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1385
- } /* not else */
1386
- if (max && amount > max) {
1387
- throw new Error("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
1388
- }
1389
- }
1390
- }
1391
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
1392
- finally {
1393
- try {
1394
- if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
1395
- }
1396
- finally { if (e_2) throw e_2.error; }
1397
- }
1398
- return [3 /*break*/, 15];
1407
+ case 12: return [3 /*break*/, 27];
1399
1408
  case 13:
1400
- error_2 = _p.sent();
1401
- if (!(error_2 instanceof Error)) {
1402
- throw error_2;
1403
- }
1404
- naturalExecutionError = error_2;
1405
- return [3 /*break*/, 15];
1406
- case 14:
1407
- executionReport.promptExecutions.push({
1408
- prompt: {
1409
- title: prompt_1.title,
1410
- content: prompt_1.content,
1411
- modelRequirements: prompt_1.modelRequirements,
1412
- // <- Note: Do want to pass ONLY wanted information to the report
1413
- },
1414
- result: result /* <- !!!!! Look what is exposed here and probbably also filter out */ ||
1415
- undefined,
1416
- error: naturalExecutionError || undefined,
1417
- });
1418
- return [7 /*endfinally*/];
1419
- case 15:
1420
- if (result !== null && naturalExecutionError === null) {
1421
- return [3 /*break*/, 32];
1422
- }
1423
- _p.label = 16;
1424
- case 16:
1425
- attempt++;
1426
- return [3 /*break*/, 5];
1427
- case 17: throw new Error(spaceTrim(function (block) { return "\n Natural execution failed ".concat(settings.maxNaturalExecutionAttempts, "x\n\n ").concat(block((naturalExecutionError === null || naturalExecutionError === void 0 ? void 0 : naturalExecutionError.message) || ''), "\n "); }));
1428
- case 18:
1429
1409
  if (tools.script.length === 0) {
1430
1410
  throw new Error('No script execution tools are available');
1431
1411
  }
1432
1412
  if (!currentTemplate.contentLanguage) {
1433
1413
  throw new Error("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1434
1414
  }
1415
+ // TODO: DRY [1]
1435
1416
  scriptExecutionErrors = [];
1436
- isScriptExecutionSuccessful = false;
1437
- _p.label = 19;
1438
- case 19:
1439
- _p.trys.push([19, 26, 27, 28]);
1440
- _j = (e_1 = void 0, __values(tools.script)), _k = _j.next();
1441
- _p.label = 20;
1442
- case 20:
1443
- if (!!_k.done) return [3 /*break*/, 25];
1444
- scriptTools = _k.value;
1445
- _p.label = 21;
1446
- case 21:
1447
- _p.trys.push([21, 23, , 24]);
1417
+ _v.label = 14;
1418
+ case 14:
1419
+ _v.trys.push([14, 21, 22, 23]);
1420
+ _e = (e_1 = void 0, __values(tools.script)), _f = _e.next();
1421
+ _v.label = 15;
1422
+ case 15:
1423
+ if (!!_f.done) return [3 /*break*/, 20];
1424
+ scriptTools = _f.value;
1425
+ _v.label = 16;
1426
+ case 16:
1427
+ _v.trys.push([16, 18, , 19]);
1448
1428
  return [4 /*yield*/, scriptTools.execute({
1449
1429
  scriptLanguage: currentTemplate.contentLanguage,
1450
1430
  script: currentTemplate.content,
1451
1431
  parameters: parametersToPass,
1452
1432
  })];
1453
- case 22:
1454
- resultString = _p.sent();
1455
- isScriptExecutionSuccessful = true;
1456
- return [3 /*break*/, 25];
1457
- case 23:
1458
- error_3 = _p.sent();
1459
- if (!(error_3 instanceof Error)) {
1460
- throw error_3;
1461
- }
1462
- scriptExecutionErrors.push(error_3);
1463
- return [3 /*break*/, 24];
1464
- case 24:
1465
- _k = _j.next();
1433
+ case 17:
1434
+ resultString = _v.sent();
1466
1435
  return [3 /*break*/, 20];
1467
- case 25: return [3 /*break*/, 28];
1468
- case 26:
1469
- e_1_1 = _p.sent();
1436
+ case 18:
1437
+ error_2 = _v.sent();
1438
+ if (!(error_2 instanceof Error)) {
1439
+ throw error_2;
1440
+ }
1441
+ scriptExecutionErrors.push(error_2);
1442
+ return [3 /*break*/, 19];
1443
+ case 19:
1444
+ _f = _e.next();
1445
+ return [3 /*break*/, 15];
1446
+ case 20: return [3 /*break*/, 23];
1447
+ case 21:
1448
+ e_1_1 = _v.sent();
1470
1449
  e_1 = { error: e_1_1 };
1471
- return [3 /*break*/, 28];
1472
- case 27:
1450
+ return [3 /*break*/, 23];
1451
+ case 22:
1473
1452
  try {
1474
- if (_k && !_k.done && (_m = _j.return)) _m.call(_j);
1453
+ if (_f && !_f.done && (_q = _e.return)) _q.call(_e);
1475
1454
  }
1476
1455
  finally { if (e_1) throw e_1.error; }
1477
1456
  return [7 /*endfinally*/];
1478
- case 28:
1479
- if (isScriptExecutionSuccessful) {
1480
- return [3 /*break*/, 32];
1457
+ case 23:
1458
+ if (resultString) {
1459
+ return [3 /*break*/, 27];
1481
1460
  }
1482
1461
  if (scriptExecutionErrors.length === 1) {
1483
1462
  throw scriptExecutionErrors[0];
@@ -1485,19 +1464,149 @@ function createPtpExecutor(options) {
1485
1464
  else {
1486
1465
  throw new Error(spaceTrim(function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors.map(function (error) { return '- ' + error.message; }).join('\n\n')), "\n "); }));
1487
1466
  }
1488
- case 29: return [4 /*yield*/, tools.userInterface.promptDialog({
1467
+ case 24: return [4 /*yield*/, tools.userInterface.promptDialog({
1489
1468
  prompt: replaceParameters(currentTemplate.description || '', parametersToPass),
1490
1469
  defaultValue: replaceParameters(currentTemplate.content, parametersToPass),
1491
1470
  // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
1492
1471
  placeholder: undefined,
1493
1472
  })];
1494
- case 30:
1495
- resultString = _p.sent();
1496
- return [3 /*break*/, 32];
1497
- case 31:
1473
+ case 25:
1474
+ resultString = _v.sent();
1475
+ return [3 /*break*/, 27];
1476
+ case 26:
1498
1477
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1499
1478
  throw new Error("Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1479
+ case 27:
1480
+ if (!currentTemplate.postprocessing) return [3 /*break*/, 43];
1481
+ _v.label = 28;
1482
+ case 28:
1483
+ _v.trys.push([28, 41, 42, 43]);
1484
+ _g = (e_3 = void 0, __values(currentTemplate.postprocessing)), _h = _g.next();
1485
+ _v.label = 29;
1486
+ case 29:
1487
+ if (!!_h.done) return [3 /*break*/, 40];
1488
+ functionName = _h.value;
1489
+ // TODO: DRY [1]
1490
+ scriptExecutionErrors = [];
1491
+ _v.label = 30;
1492
+ case 30:
1493
+ _v.trys.push([30, 37, 38, 39]);
1494
+ _j = (e_2 = void 0, __values(tools.script)), _k = _j.next();
1495
+ _v.label = 31;
1496
+ case 31:
1497
+ if (!!_k.done) return [3 /*break*/, 36];
1498
+ scriptTools = _k.value;
1499
+ _v.label = 32;
1500
1500
  case 32:
1501
+ _v.trys.push([32, 34, , 35]);
1502
+ return [4 /*yield*/, scriptTools.execute({
1503
+ scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
1504
+ script: "".concat(functionName, "(resultString)"),
1505
+ parameters: __assign(__assign({}, parametersToPass), { resultString: resultString }),
1506
+ })];
1507
+ case 33:
1508
+ resultString = _v.sent();
1509
+ return [3 /*break*/, 36];
1510
+ case 34:
1511
+ error_3 = _v.sent();
1512
+ if (!(error_3 instanceof Error)) {
1513
+ throw error_3;
1514
+ }
1515
+ scriptExecutionErrors.push(error_3);
1516
+ return [3 /*break*/, 35];
1517
+ case 35:
1518
+ _k = _j.next();
1519
+ return [3 /*break*/, 31];
1520
+ case 36: return [3 /*break*/, 39];
1521
+ case 37:
1522
+ e_2_1 = _v.sent();
1523
+ e_2 = { error: e_2_1 };
1524
+ return [3 /*break*/, 39];
1525
+ case 38:
1526
+ try {
1527
+ if (_k && !_k.done && (_s = _j.return)) _s.call(_j);
1528
+ }
1529
+ finally { if (e_2) throw e_2.error; }
1530
+ return [7 /*endfinally*/];
1531
+ case 39:
1532
+ _h = _g.next();
1533
+ return [3 /*break*/, 29];
1534
+ case 40: return [3 /*break*/, 43];
1535
+ case 41:
1536
+ e_3_1 = _v.sent();
1537
+ e_3 = { error: e_3_1 };
1538
+ return [3 /*break*/, 43];
1539
+ case 42:
1540
+ try {
1541
+ if (_h && !_h.done && (_r = _g.return)) _r.call(_g);
1542
+ }
1543
+ finally { if (e_3) throw e_3.error; }
1544
+ return [7 /*endfinally*/];
1545
+ case 43:
1546
+ if (currentTemplate.expectFormat) {
1547
+ if (currentTemplate.expectFormat === 'JSON') {
1548
+ if (!isValidJsonString(resultString)) {
1549
+ throw new ExpectError('Expected valid JSON string');
1550
+ }
1551
+ }
1552
+ }
1553
+ if (currentTemplate.expectAmount) {
1554
+ try {
1555
+ for (_l = (e_4 = void 0, __values(Object.entries(currentTemplate.expectAmount))), _m = _l.next(); !_m.done; _m = _l.next()) {
1556
+ _o = __read(_m.value, 2), unit = _o[0], _p = _o[1], max = _p.max, min = _p.min;
1557
+ amount = CountUtils[unit.toUpperCase()](resultString);
1558
+ if (min && amount < min) {
1559
+ throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1560
+ } /* not else */
1561
+ if (max && amount > max) {
1562
+ throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
1563
+ }
1564
+ }
1565
+ }
1566
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
1567
+ finally {
1568
+ try {
1569
+ if (_m && !_m.done && (_t = _l.return)) _t.call(_l);
1570
+ }
1571
+ finally { if (e_4) throw e_4.error; }
1572
+ }
1573
+ }
1574
+ return [3 /*break*/, 46];
1575
+ case 44:
1576
+ error_4 = _v.sent();
1577
+ if (!(error_4 instanceof ExpectError)) {
1578
+ throw error_4;
1579
+ }
1580
+ expectError = error_4;
1581
+ return [3 /*break*/, 46];
1582
+ case 45:
1583
+ if (currentTemplate.executionType === 'PROMPT_TEMPLATE' &&
1584
+ prompt_1
1585
+ // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
1586
+ // In that case we don’t want to make a report about it because it’s not a natural execution error
1587
+ ) {
1588
+ // TODO: [🧠] Maybe put other executionTypes into report
1589
+ executionReport.promptExecutions.push({
1590
+ prompt: {
1591
+ title: currentTemplate.title /* <- Note: If title in promptbook contains emojis, pass it innto report */,
1592
+ content: prompt_1.content,
1593
+ modelRequirements: prompt_1.modelRequirements,
1594
+ // <- Note: Do want to pass ONLY wanted information to the report
1595
+ },
1596
+ result: result || undefined,
1597
+ error: expectError || undefined,
1598
+ });
1599
+ }
1600
+ return [7 /*endfinally*/];
1601
+ case 46:
1602
+ if (result === null && attempt === maxExecutionAttempts) {
1603
+ throw new Error(spaceTrim(function (block) { return "\n Natural execution failed ".concat(settings.maxExecutionAttempts, "x\n\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n "); }));
1604
+ }
1605
+ _v.label = 47;
1606
+ case 47:
1607
+ attempt++;
1608
+ return [3 /*break*/, 3];
1609
+ case 48:
1501
1610
  if (resultString === null) {
1502
1611
  // <- TODO: [🥨] Make some NeverShouldHappenError
1503
1612
  throw new Error('Something went wrong and prompt result is null');
@@ -1513,7 +1622,7 @@ function createPtpExecutor(options) {
1513
1622
  parameterValue: resultString,
1514
1623
  });
1515
1624
  }
1516
- parametersToPass = __assign(__assign({}, parametersToPass), (_o = {}, _o[resultingParameter.name] = resultString /* <- Note: Not need to detect parameter collision here because PromptTemplatePipeline checks logic consistency during construction */, _o));
1625
+ parametersToPass = __assign(__assign({}, parametersToPass), (_u = {}, _u[resultingParameter.name] = resultString /* <- Note: Not need to detect parameter collision here because PromptTemplatePipeline checks logic consistency during construction */, _u));
1517
1626
  currentTemplate = ptp.getFollowingPromptTemplate(currentTemplate.name);
1518
1627
  return [2 /*return*/];
1519
1628
  }