@promptbook/core 0.23.2 → 0.24.0-1.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.
Files changed (75) hide show
  1. package/esm/index.es.js +418 -97
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/_packages/types.index.d.ts +2 -2
  4. package/esm/typings/_packages/utils.index.d.ts +11 -1
  5. package/esm/typings/classes/PromptTemplatePipeline.d.ts +4 -1
  6. package/esm/typings/classes/PromptTemplatePipelineLibrary.d.ts +8 -2
  7. package/esm/typings/conversion/parseCommand.d.ts +2 -2
  8. package/esm/typings/execution/PromptResult.d.ts +1 -1
  9. package/esm/typings/execution/PtpExecutor.d.ts +24 -4
  10. package/esm/typings/execution/createPtpExecutor.d.ts +9 -0
  11. package/esm/typings/types/Command.d.ts +17 -4
  12. package/esm/typings/types/Prompt.d.ts +8 -2
  13. package/esm/typings/types/PromptTemplatePipelineJson/PromptTemplateJson.d.ts +21 -2
  14. package/esm/typings/types/execution-report/ExecutionReportJson.d.ts +56 -0
  15. package/esm/typings/types/execution-report/ExecutionReportString.d.ts +16 -0
  16. package/esm/typings/types/execution-report/executionReportJsonToString.d.ts +6 -0
  17. package/esm/typings/types/typeAliases.d.ts +3 -1
  18. package/esm/typings/utils/expectation-counters/countCharacters.d.ts +5 -0
  19. package/esm/typings/utils/expectation-counters/countCharacters.test.d.ts +1 -0
  20. package/esm/typings/utils/expectation-counters/countLines.d.ts +5 -0
  21. package/esm/typings/utils/expectation-counters/countLines.test.d.ts +1 -0
  22. package/esm/typings/utils/expectation-counters/countPages.d.ts +5 -0
  23. package/esm/typings/utils/expectation-counters/countPages.test.d.ts +1 -0
  24. package/esm/typings/utils/expectation-counters/countParagraphs.d.ts +5 -0
  25. package/esm/typings/utils/expectation-counters/countParagraphs.test.d.ts +1 -0
  26. package/esm/typings/utils/expectation-counters/countSentences.d.ts +5 -0
  27. package/esm/typings/utils/expectation-counters/countSentences.test.d.ts +1 -0
  28. package/esm/typings/utils/expectation-counters/countWords.d.ts +5 -0
  29. package/esm/typings/utils/expectation-counters/countWords.test.d.ts +1 -0
  30. package/esm/typings/utils/expectation-counters/index.d.ts +5 -0
  31. package/esm/typings/utils/markdown/prettifyMarkdown.d.ts +8 -0
  32. package/esm/typings/utils/markdown/prettifyMarkdown.test.d.ts +1 -0
  33. package/esm/typings/utils/parseNumber.d.ts +10 -0
  34. package/esm/typings/utils/parseNumber.test.d.ts +1 -0
  35. package/esm/typings/utils/trimCodeBlock.d.ts +8 -0
  36. package/esm/typings/utils/trimCodeBlock.test.d.ts +1 -0
  37. package/esm/typings/utils/trimEndOfCodeBlock.d.ts +2 -1
  38. package/package.json +1 -1
  39. package/umd/index.umd.js +417 -96
  40. package/umd/index.umd.js.map +1 -1
  41. package/umd/typings/_packages/types.index.d.ts +2 -2
  42. package/umd/typings/_packages/utils.index.d.ts +11 -1
  43. package/umd/typings/classes/PromptTemplatePipeline.d.ts +4 -1
  44. package/umd/typings/classes/PromptTemplatePipelineLibrary.d.ts +8 -2
  45. package/umd/typings/conversion/parseCommand.d.ts +2 -2
  46. package/umd/typings/execution/PromptResult.d.ts +1 -1
  47. package/umd/typings/execution/PtpExecutor.d.ts +24 -4
  48. package/umd/typings/execution/createPtpExecutor.d.ts +9 -0
  49. package/umd/typings/types/Command.d.ts +17 -4
  50. package/umd/typings/types/Prompt.d.ts +8 -2
  51. package/umd/typings/types/PromptTemplatePipelineJson/PromptTemplateJson.d.ts +21 -2
  52. package/umd/typings/types/execution-report/ExecutionReportJson.d.ts +56 -0
  53. package/umd/typings/types/execution-report/ExecutionReportString.d.ts +16 -0
  54. package/umd/typings/types/execution-report/executionReportJsonToString.d.ts +6 -0
  55. package/umd/typings/types/typeAliases.d.ts +3 -1
  56. package/umd/typings/utils/expectation-counters/countCharacters.d.ts +5 -0
  57. package/umd/typings/utils/expectation-counters/countCharacters.test.d.ts +1 -0
  58. package/umd/typings/utils/expectation-counters/countLines.d.ts +5 -0
  59. package/umd/typings/utils/expectation-counters/countLines.test.d.ts +1 -0
  60. package/umd/typings/utils/expectation-counters/countPages.d.ts +5 -0
  61. package/umd/typings/utils/expectation-counters/countPages.test.d.ts +1 -0
  62. package/umd/typings/utils/expectation-counters/countParagraphs.d.ts +5 -0
  63. package/umd/typings/utils/expectation-counters/countParagraphs.test.d.ts +1 -0
  64. package/umd/typings/utils/expectation-counters/countSentences.d.ts +5 -0
  65. package/umd/typings/utils/expectation-counters/countSentences.test.d.ts +1 -0
  66. package/umd/typings/utils/expectation-counters/countWords.d.ts +5 -0
  67. package/umd/typings/utils/expectation-counters/countWords.test.d.ts +1 -0
  68. package/umd/typings/utils/expectation-counters/index.d.ts +5 -0
  69. package/umd/typings/utils/markdown/prettifyMarkdown.d.ts +8 -0
  70. package/umd/typings/utils/markdown/prettifyMarkdown.test.d.ts +1 -0
  71. package/umd/typings/utils/parseNumber.d.ts +10 -0
  72. package/umd/typings/utils/parseNumber.test.d.ts +1 -0
  73. package/umd/typings/utils/trimCodeBlock.d.ts +8 -0
  74. package/umd/typings/utils/trimCodeBlock.test.d.ts +1 -0
  75. package/umd/typings/utils/trimEndOfCodeBlock.d.ts +2 -1
package/umd/index.umd.js CHANGED
@@ -349,6 +349,14 @@
349
349
  */
350
350
  var ExecutionTypes = ['PROMPT_TEMPLATE', 'SIMPLE_TEMPLATE', 'SCRIPT', 'PROMPT_DIALOG'];
351
351
 
352
+ /**
353
+ * Units of text measurement
354
+ */
355
+ var EXPECTATION_UNITS = ['CHARACTERS', 'WORDS', 'SENTENCES', 'PARAGRAPHS', 'LINES', 'PAGES'];
356
+ /**
357
+ * TODO: use one helper type> (string_prompt | string_javascript | string_markdown) & string_template
358
+ */
359
+
352
360
  /**
353
361
  * Removes Markdown formatting tags from a string.
354
362
  *
@@ -365,10 +373,73 @@
365
373
  return str;
366
374
  }
367
375
 
376
+ /**
377
+ * Function parseNumber will parse number from string
378
+ *
379
+ * Unlike Number.parseInt, Number.parseFloat it will never ever result in NaN
380
+ * Note: it also works only with decimal numbers
381
+ */
382
+ function parseNumber(value) {
383
+ var originalValue = value;
384
+ if (typeof value === 'number') {
385
+ value = value.toString(); // <- TODO: Maybe more efficient way to do this
386
+ }
387
+ if (typeof value !== 'string') {
388
+ return 0;
389
+ }
390
+ value = value.trim();
391
+ if (value.startsWith('+')) {
392
+ return parseNumber(value.substring(1));
393
+ }
394
+ if (value.startsWith('-')) {
395
+ var number = parseNumber(value.substring(1));
396
+ if (number === 0) {
397
+ return 0; // <- Note: To prevent -0
398
+ }
399
+ return -number;
400
+ }
401
+ value = value.replace(/,/g, '.');
402
+ value = value.toUpperCase();
403
+ if (value === '') {
404
+ return 0;
405
+ }
406
+ if (value === '♾' || value.startsWith('INF')) {
407
+ return Infinity;
408
+ }
409
+ if (value.includes('/')) {
410
+ var _a = __read(value.split('/'), 2), numerator_ = _a[0], denominator_ = _a[1];
411
+ var numerator = parseNumber(numerator_);
412
+ var denominator = parseNumber(denominator_);
413
+ if (denominator === 0) {
414
+ throw new Error("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
415
+ }
416
+ return numerator / denominator;
417
+ }
418
+ if (/^(NAN|NULL|NONE|UNDEFINED|ZERO|NO.*)$/.test(value)) {
419
+ return 0;
420
+ }
421
+ if (value.includes('E')) {
422
+ var _b = __read(value.split('E'), 2), significand = _b[0], exponent = _b[1];
423
+ return parseNumber(significand) * Math.pow(10, parseNumber(exponent));
424
+ }
425
+ if (!/^[0-9.]+$/.test(value) || value.split('.').length > 2) {
426
+ throw new Error("Unable to parse number from \"".concat(originalValue, "\""));
427
+ }
428
+ var num = parseFloat(value);
429
+ if (isNaN(num)) {
430
+ throw new Error("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
431
+ }
432
+ return num;
433
+ }
434
+ /**
435
+ * TODO: Maybe use sth. like safe-eval in fraction/calculation case @see https://www.npmjs.com/package/safe-eval
436
+ */
437
+
368
438
  /**
369
439
  * Parses one line of ul/ol to command
370
440
  */
371
441
  function parseCommand(listItem) {
442
+ var e_1, _a;
372
443
  if (listItem.includes('\n') || listItem.includes('\r')) {
373
444
  throw new Error('Command can not contain new line characters:');
374
445
  }
@@ -475,7 +546,7 @@
475
546
  throw new Error(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
476
547
  }
477
548
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
478
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
549
+ var _b = parametersMatch.groups, parameterName = _b.parameterName, parameterDescription = _b.parameterDescription;
479
550
  if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
480
551
  throw new Error(spaceTrim__default["default"]("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
481
552
  }
@@ -497,6 +568,74 @@
497
568
  functionName: functionName,
498
569
  };
499
570
  }
571
+ else if (type.startsWith('EXPECT')) {
572
+ try {
573
+ listItemParts.shift();
574
+ var sign = void 0;
575
+ var signRaw = listItemParts.shift();
576
+ if (/^exact/i.test(signRaw)) {
577
+ sign = 'EXACTLY';
578
+ }
579
+ else if (/^min/i.test(signRaw)) {
580
+ sign = 'MINIMUM';
581
+ }
582
+ else if (/^max/i.test(signRaw)) {
583
+ sign = 'MAXIMUM';
584
+ }
585
+ else {
586
+ throw new Error("Invalid sign \"".concat(signRaw, "\""));
587
+ }
588
+ var amountRaw = listItemParts.shift();
589
+ var amount = parseNumber(amountRaw);
590
+ if (amount < 0) {
591
+ throw new Error('Amount must be positive number or zero');
592
+ }
593
+ if (amount !== Math.floor(amount)) {
594
+ throw new Error('Amount must be whole number');
595
+ }
596
+ var unitRaw = listItemParts.shift();
597
+ var unit = undefined;
598
+ try {
599
+ for (var EXPECTATION_UNITS_1 = __values(EXPECTATION_UNITS), EXPECTATION_UNITS_1_1 = EXPECTATION_UNITS_1.next(); !EXPECTATION_UNITS_1_1.done; EXPECTATION_UNITS_1_1 = EXPECTATION_UNITS_1.next()) {
600
+ var existingUnit = EXPECTATION_UNITS_1_1.value;
601
+ var existingUnitText = existingUnit;
602
+ existingUnitText = existingUnitText.substring(0, existingUnitText.length - 1);
603
+ if (existingUnitText === 'CHARACTER') {
604
+ existingUnitText = 'CHAR';
605
+ }
606
+ if (new RegExp("^".concat(existingUnitText.toLowerCase())).test(unitRaw.toLowerCase()) ||
607
+ new RegExp("^".concat(unitRaw.toLowerCase())).test(existingUnitText.toLowerCase())) {
608
+ if (unit !== undefined) {
609
+ throw new Error("Ambiguous unit \"".concat(unitRaw, "\""));
610
+ }
611
+ unit = existingUnit;
612
+ }
613
+ }
614
+ }
615
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
616
+ finally {
617
+ try {
618
+ if (EXPECTATION_UNITS_1_1 && !EXPECTATION_UNITS_1_1.done && (_a = EXPECTATION_UNITS_1.return)) _a.call(EXPECTATION_UNITS_1);
619
+ }
620
+ finally { if (e_1) throw e_1.error; }
621
+ }
622
+ if (unit === undefined) {
623
+ throw new Error("Invalid unit \"".concat(unitRaw, "\""));
624
+ }
625
+ return {
626
+ type: 'EXPECT',
627
+ sign: sign,
628
+ unit: unit,
629
+ amount: amount,
630
+ };
631
+ }
632
+ catch (error) {
633
+ if (!(error instanceof Error)) {
634
+ throw error;
635
+ }
636
+ throw new Error(spaceTrim__default["default"]("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
637
+ }
638
+ }
500
639
  else {
501
640
  throw new Error(spaceTrim__default["default"]("\n Unknown command:\n\n - ".concat(listItem, "\n\n Supported commands are:\n - Execute\n - Model\n - Parameter\n - Input parameter\n - Output parameter\n - PTBK Version\n ")));
502
641
  }
@@ -605,6 +744,7 @@
605
744
  var postprocessingCommands = [];
606
745
  var listItems_3 = extractAllListItemsFromMarkdown(section.content);
607
746
  var executionType = 'PROMPT_TEMPLATE';
747
+ var expectations = {};
608
748
  var isExecutionTypeChanged = false;
609
749
  try {
610
750
  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()) {
@@ -628,6 +768,23 @@
628
768
  case 'POSTPROCESS':
629
769
  postprocessingCommands.push(command);
630
770
  break;
771
+ case 'EXPECT':
772
+ // eslint-disable-next-line no-case-declarations
773
+ var unit = command.unit.toLowerCase();
774
+ expectations[unit] = expectations[unit] || {};
775
+ if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
776
+ if (expectations[unit].min !== undefined) {
777
+ throw new Error("Already defined minumum ".concat(expectations[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
778
+ }
779
+ expectations[unit].min = command.amount;
780
+ } /* not else */
781
+ if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
782
+ if (expectations[unit].max !== undefined) {
783
+ throw new Error("Already defined maximum ".concat(expectations[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
784
+ }
785
+ expectations[unit].max = command.amount;
786
+ }
787
+ break;
631
788
  default:
632
789
  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"));
633
790
  }
@@ -691,6 +848,7 @@
691
848
  title: section.title,
692
849
  description: description_1,
693
850
  executionType: executionType,
851
+ expectations: expectations,
694
852
  modelRequirements: templateModelRequirements,
695
853
  contentLanguage: executionType === 'SCRIPT' ? language : undefined,
696
854
  content: content,
@@ -824,8 +982,11 @@
824
982
  * @see https://github.com/webgptorg/promptbook#prompt-template-pipeline
825
983
  */
826
984
  var PromptTemplatePipeline = /** @class */ (function () {
827
- function PromptTemplatePipeline(ptbkUrl, parameters, promptTemplates) {
985
+ function PromptTemplatePipeline(ptbkUrl, title, ptbkVersion, description, parameters, promptTemplates) {
828
986
  this.ptbkUrl = ptbkUrl;
987
+ this.title = title;
988
+ this.ptbkVersion = ptbkVersion;
989
+ this.description = description;
829
990
  this.parameters = parameters;
830
991
  this.promptTemplates = promptTemplates;
831
992
  if (promptTemplates.length === 0) {
@@ -870,7 +1031,7 @@
870
1031
  */
871
1032
  PromptTemplatePipeline.fromJson = function (ptbkjson) {
872
1033
  validatePromptTemplatePipelineJson(ptbkjson);
873
- return new PromptTemplatePipeline(ptbkjson.ptbkUrl ? new URL(ptbkjson.ptbkUrl) : null, Object.fromEntries(ptbkjson.parameters.map(function (parameter) { return [parameter.name, parameter]; })), ptbkjson.promptTemplates);
1034
+ 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);
874
1035
  };
875
1036
  Object.defineProperty(PromptTemplatePipeline.prototype, "entryPromptTemplate", {
876
1037
  /**
@@ -927,6 +1088,74 @@
927
1088
  * TODO: [🧠] Each PromptTemplatePipeline should have its unique hash to be able to compare them and execute on server ONLY the desired ones
928
1089
  */
929
1090
 
1091
+ /**
1092
+ * Counts number of characters in the text
1093
+ */
1094
+ function countCharacters(text) {
1095
+ // Remove null characters
1096
+ text = text.replace(/\0/g, '');
1097
+ // Replace emojis (and also ZWJ sequence) with hyphens
1098
+ text = text.replace(/(\p{Emoji})\p{Modifier_Symbol}/gu, '$1');
1099
+ text = text.replace(/(\p{Emoji})[\u{FE00}-\u{FE0F}]/gu, '$1');
1100
+ text = text.replace(/\p{Emoji}(\u{200D}\p{Emoji})*/gu, '-');
1101
+ return text.length;
1102
+ }
1103
+
1104
+ /**
1105
+ * Counts number of lines in the text
1106
+ */
1107
+ function countLines(text) {
1108
+ if (text === '') {
1109
+ return 0;
1110
+ }
1111
+ return text.split('\n').length;
1112
+ }
1113
+
1114
+ /**
1115
+ * Counts number of pages in the text
1116
+ */
1117
+ function countPages(text) {
1118
+ var sentencesPerPage = 5; // Assuming each page has 5 sentences
1119
+ var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1120
+ var pageCount = Math.ceil(sentences.length / sentencesPerPage);
1121
+ return pageCount;
1122
+ }
1123
+
1124
+ /**
1125
+ * Counts number of paragraphs in the text
1126
+ */
1127
+ function countParagraphs(text) {
1128
+ return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
1129
+ }
1130
+
1131
+ /**
1132
+ * Counts number of sentences in the text
1133
+ */
1134
+ function countSentences(text) {
1135
+ return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; }).length;
1136
+ }
1137
+
1138
+ /**
1139
+ * Counts number of words in the text
1140
+ */
1141
+ function countWords(text) {
1142
+ text = text.replace(/[\p{Emoji}]/gu, 'a');
1143
+ text = n12.removeDiacritics(text);
1144
+ return text.split(/[^a-zа-я0-9]+/i).filter(function (word) { return word.length > 0; }).length;
1145
+ }
1146
+
1147
+ /**
1148
+ * Index of all counter functions
1149
+ */
1150
+ var CountUtils = {
1151
+ CHARACTERS: countCharacters,
1152
+ WORDS: countWords,
1153
+ SENTENCES: countSentences,
1154
+ PARAGRAPHS: countParagraphs,
1155
+ LINES: countLines,
1156
+ PAGES: countPages,
1157
+ };
1158
+
930
1159
  /**
931
1160
  * All possible emoji chars like "🍆", "🍡", "🍤"...
932
1161
  * Note: this will be needed to update annually - now updated at 2022-01-19
@@ -1050,19 +1279,31 @@
1050
1279
  */
1051
1280
  function createPtpExecutor(options) {
1052
1281
  var _this = this;
1053
- var ptp = options.ptp, tools = options.tools;
1282
+ var ptp = options.ptp, tools = options.tools, settings = options.settings;
1054
1283
  var ptpExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
1055
- var parametersToPass, currentTemplate, _loop_1;
1056
- return __generator(this, function (_a) {
1057
- switch (_a.label) {
1284
+ var parametersToPass, currentTemplate, executionReport, _loop_1, error_1;
1285
+ var _a;
1286
+ return __generator(this, function (_b) {
1287
+ switch (_b.label) {
1058
1288
  case 0:
1059
1289
  parametersToPass = inputParameters;
1060
1290
  currentTemplate = ptp.entryPromptTemplate;
1291
+ executionReport = {
1292
+ ptbkUrl: ((_a = ptp.ptbkUrl) === null || _a === void 0 ? void 0 : _a.href) || undefined,
1293
+ title: ptp.title || undefined,
1294
+ ptbkUsedVersion: PTBK_VERSION,
1295
+ ptbkRequestedVersion: ptp.ptbkVersion || undefined,
1296
+ description: ptp.description || undefined,
1297
+ promptExecutions: [],
1298
+ };
1299
+ _b.label = 1;
1300
+ case 1:
1301
+ _b.trys.push([1, 5, , 6]);
1061
1302
  _loop_1 = function () {
1062
- var resultingParameter, name_1, title, prompt_1, chatThread, completionResult, promptResult, scriptExecutionErrors, isScriptExecutionSuccessful, _b, _c, _d, _e, scriptTools, error_1, e_1_1;
1063
- var e_1, _f, _g;
1064
- return __generator(this, function (_h) {
1065
- switch (_h.label) {
1303
+ 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;
1304
+ var e_2, _l, e_1, _m, _o;
1305
+ return __generator(this, function (_p) {
1306
+ switch (_p.label) {
1066
1307
  case 0:
1067
1308
  resultingParameter = ptp.getResultingParameter(currentTemplate.name);
1068
1309
  name_1 = "ptp-executor-frame-".concat(currentTemplate.name);
@@ -1078,27 +1319,30 @@
1078
1319
  parameterValue: null,
1079
1320
  })];
1080
1321
  case 1:
1081
- _h.sent();
1082
- _h.label = 2;
1322
+ _p.sent();
1323
+ _p.label = 2;
1083
1324
  case 2:
1084
1325
  prompt_1 = void 0;
1085
1326
  chatThread = void 0;
1086
1327
  completionResult = void 0;
1087
- promptResult = null;
1328
+ result = null;
1329
+ resultString = null;
1330
+ naturalExecutionError = null;
1088
1331
  isScriptExecutionSuccessful = void 0;
1089
- _b = currentTemplate.executionType;
1090
- switch (_b) {
1332
+ _c = currentTemplate.executionType;
1333
+ switch (_c) {
1091
1334
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 3];
1092
1335
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 4];
1093
- case 'SCRIPT': return [3 /*break*/, 11];
1094
- case 'PROMPT_DIALOG': return [3 /*break*/, 22];
1336
+ case 'SCRIPT': return [3 /*break*/, 18];
1337
+ case 'PROMPT_DIALOG': return [3 /*break*/, 29];
1095
1338
  }
1096
- return [3 /*break*/, 24];
1339
+ return [3 /*break*/, 31];
1097
1340
  case 3:
1098
- promptResult = replaceParameters(currentTemplate.content, parametersToPass);
1099
- return [3 /*break*/, 25];
1341
+ resultString = replaceParameters(currentTemplate.content, parametersToPass);
1342
+ return [3 /*break*/, 32];
1100
1343
  case 4:
1101
1344
  prompt_1 = {
1345
+ title: currentTemplate.title,
1102
1346
  ptbkUrl: "".concat(ptp.ptbkUrl
1103
1347
  ? ptp.ptbkUrl.href
1104
1348
  : 'anonymous' /* <- [🧠] !!!! How to deal with anonymous PTPs, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
@@ -1106,28 +1350,88 @@
1106
1350
  content: replaceParameters(currentTemplate.content, parametersToPass),
1107
1351
  modelRequirements: currentTemplate.modelRequirements,
1108
1352
  };
1109
- _c = currentTemplate.modelRequirements.modelVariant;
1110
- switch (_c) {
1111
- case 'CHAT': return [3 /*break*/, 5];
1112
- case 'COMPLETION': return [3 /*break*/, 7];
1113
- }
1114
- return [3 /*break*/, 9];
1115
- case 5: return [4 /*yield*/, tools.natural.gptChat(prompt_1)];
1353
+ attempt = 0;
1354
+ _p.label = 5;
1355
+ case 5:
1356
+ if (!(attempt < settings.maxNaturalExecutionAttempts)) return [3 /*break*/, 17];
1357
+ result = null;
1358
+ resultString = null;
1359
+ naturalExecutionError = null;
1360
+ _p.label = 6;
1116
1361
  case 6:
1117
- chatThread = _h.sent();
1118
- // TODO: Use all information from chatThread like "model"
1119
- // TODO: [🍬] Destroy chatThread
1120
- promptResult = chatThread.content;
1121
- return [3 /*break*/, 10];
1122
- case 7: return [4 /*yield*/, tools.natural.gptComplete(prompt_1)];
1362
+ _p.trys.push([6, 13, 14, 15]);
1363
+ _d = currentTemplate.modelRequirements.modelVariant;
1364
+ switch (_d) {
1365
+ case 'CHAT': return [3 /*break*/, 7];
1366
+ case 'COMPLETION': return [3 /*break*/, 9];
1367
+ }
1368
+ return [3 /*break*/, 11];
1369
+ case 7: return [4 /*yield*/, tools.natural.gptChat(prompt_1)];
1123
1370
  case 8:
1124
- completionResult = _h.sent();
1125
- // TODO: Use all information from chatThread like "model"
1126
- promptResult = completionResult.content;
1127
- return [3 /*break*/, 10];
1128
- case 9: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1129
- case 10: return [3 /*break*/, 25];
1130
- case 11:
1371
+ chatThread = _p.sent();
1372
+ // TODO: [🍬] Destroy chatThread
1373
+ result = chatThread;
1374
+ resultString = chatThread.content;
1375
+ return [3 /*break*/, 12];
1376
+ case 9: return [4 /*yield*/, tools.natural.gptComplete(prompt_1)];
1377
+ case 10:
1378
+ completionResult = _p.sent();
1379
+ result = completionResult;
1380
+ resultString = completionResult.content;
1381
+ return [3 /*break*/, 12];
1382
+ case 11: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1383
+ case 12:
1384
+ try {
1385
+ // TODO: !!!!!! Here should postprocessing happen
1386
+ for (_e = (e_2 = void 0, __values(Object.entries(currentTemplate.expectations))), _f = _e.next(); !_f.done; _f = _e.next()) {
1387
+ _g = __read(_f.value, 2), unit = _g[0], _h = _g[1], max = _h.max, min = _h.min;
1388
+ amount = CountUtils[unit.toUpperCase()](resultString);
1389
+ if (min && amount < min) {
1390
+ throw new Error("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1391
+ } /* not else */
1392
+ if (max && amount > max) {
1393
+ throw new Error("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
1394
+ }
1395
+ }
1396
+ }
1397
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1398
+ finally {
1399
+ try {
1400
+ if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
1401
+ }
1402
+ finally { if (e_2) throw e_2.error; }
1403
+ }
1404
+ return [3 /*break*/, 15];
1405
+ case 13:
1406
+ error_2 = _p.sent();
1407
+ if (!(error_2 instanceof Error)) {
1408
+ throw error_2;
1409
+ }
1410
+ naturalExecutionError = error_2;
1411
+ return [3 /*break*/, 15];
1412
+ case 14:
1413
+ executionReport.promptExecutions.push({
1414
+ prompt: {
1415
+ title: prompt_1.title,
1416
+ content: prompt_1.content,
1417
+ modelRequirements: prompt_1.modelRequirements,
1418
+ // <- Note: Do want to pass ONLY wanted information to the report
1419
+ },
1420
+ result: result /* <- !!!!! Look what is exposed here and probbably also filter out */ ||
1421
+ undefined,
1422
+ error: naturalExecutionError || undefined,
1423
+ });
1424
+ return [7 /*endfinally*/];
1425
+ case 15:
1426
+ if (result !== null && naturalExecutionError === null) {
1427
+ return [3 /*break*/, 32];
1428
+ }
1429
+ _p.label = 16;
1430
+ case 16:
1431
+ attempt++;
1432
+ return [3 /*break*/, 5];
1433
+ case 17: throw new Error(spaceTrim__default["default"](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 "); }));
1434
+ case 18:
1131
1435
  if (tools.script.length === 0) {
1132
1436
  throw new Error('No script execution tools are available');
1133
1437
  }
@@ -1136,50 +1440,50 @@
1136
1440
  }
1137
1441
  scriptExecutionErrors = [];
1138
1442
  isScriptExecutionSuccessful = false;
1139
- _h.label = 12;
1140
- case 12:
1141
- _h.trys.push([12, 19, 20, 21]);
1142
- _d = (e_1 = void 0, __values(tools.script)), _e = _d.next();
1143
- _h.label = 13;
1144
- case 13:
1145
- if (!!_e.done) return [3 /*break*/, 18];
1146
- scriptTools = _e.value;
1147
- _h.label = 14;
1148
- case 14:
1149
- _h.trys.push([14, 16, , 17]);
1443
+ _p.label = 19;
1444
+ case 19:
1445
+ _p.trys.push([19, 26, 27, 28]);
1446
+ _j = (e_1 = void 0, __values(tools.script)), _k = _j.next();
1447
+ _p.label = 20;
1448
+ case 20:
1449
+ if (!!_k.done) return [3 /*break*/, 25];
1450
+ scriptTools = _k.value;
1451
+ _p.label = 21;
1452
+ case 21:
1453
+ _p.trys.push([21, 23, , 24]);
1150
1454
  return [4 /*yield*/, scriptTools.execute({
1151
1455
  scriptLanguage: currentTemplate.contentLanguage,
1152
1456
  script: currentTemplate.content,
1153
1457
  parameters: parametersToPass,
1154
1458
  })];
1155
- case 15:
1156
- promptResult = _h.sent();
1459
+ case 22:
1460
+ resultString = _p.sent();
1157
1461
  isScriptExecutionSuccessful = true;
1158
- return [3 /*break*/, 18];
1159
- case 16:
1160
- error_1 = _h.sent();
1161
- if (!(error_1 instanceof Error)) {
1162
- throw error_1;
1462
+ return [3 /*break*/, 25];
1463
+ case 23:
1464
+ error_3 = _p.sent();
1465
+ if (!(error_3 instanceof Error)) {
1466
+ throw error_3;
1163
1467
  }
1164
- scriptExecutionErrors.push(error_1);
1165
- return [3 /*break*/, 17];
1166
- case 17:
1167
- _e = _d.next();
1168
- return [3 /*break*/, 13];
1169
- case 18: return [3 /*break*/, 21];
1170
- case 19:
1171
- e_1_1 = _h.sent();
1468
+ scriptExecutionErrors.push(error_3);
1469
+ return [3 /*break*/, 24];
1470
+ case 24:
1471
+ _k = _j.next();
1472
+ return [3 /*break*/, 20];
1473
+ case 25: return [3 /*break*/, 28];
1474
+ case 26:
1475
+ e_1_1 = _p.sent();
1172
1476
  e_1 = { error: e_1_1 };
1173
- return [3 /*break*/, 21];
1174
- case 20:
1477
+ return [3 /*break*/, 28];
1478
+ case 27:
1175
1479
  try {
1176
- if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
1480
+ if (_k && !_k.done && (_m = _j.return)) _m.call(_j);
1177
1481
  }
1178
1482
  finally { if (e_1) throw e_1.error; }
1179
1483
  return [7 /*endfinally*/];
1180
- case 21:
1484
+ case 28:
1181
1485
  if (isScriptExecutionSuccessful) {
1182
- return [3 /*break*/, 25];
1486
+ return [3 /*break*/, 32];
1183
1487
  }
1184
1488
  if (scriptExecutionErrors.length === 1) {
1185
1489
  throw scriptExecutionErrors[0];
@@ -1187,20 +1491,20 @@
1187
1491
  else {
1188
1492
  throw new Error(spaceTrim__default["default"](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 "); }));
1189
1493
  }
1190
- case 22: return [4 /*yield*/, tools.userInterface.promptDialog({
1494
+ case 29: return [4 /*yield*/, tools.userInterface.promptDialog({
1191
1495
  prompt: replaceParameters(currentTemplate.description || '', parametersToPass),
1192
1496
  defaultValue: replaceParameters(currentTemplate.content, parametersToPass),
1193
1497
  // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
1194
1498
  placeholder: undefined,
1195
1499
  })];
1196
- case 23:
1197
- promptResult = _h.sent();
1198
- return [3 /*break*/, 25];
1199
- case 24:
1500
+ case 30:
1501
+ resultString = _p.sent();
1502
+ return [3 /*break*/, 32];
1503
+ case 31:
1200
1504
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1201
1505
  throw new Error("Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1202
- case 25:
1203
- if (promptResult === null) {
1506
+ case 32:
1507
+ if (resultString === null) {
1204
1508
  // <- TODO: [🥨] Make some NeverShouldHappenError
1205
1509
  throw new Error('Something went wrong and prompt result is null');
1206
1510
  }
@@ -1212,23 +1516,40 @@
1212
1516
  isDone: true,
1213
1517
  executionType: currentTemplate.executionType,
1214
1518
  parameterName: resultingParameter.name,
1215
- parameterValue: promptResult,
1519
+ parameterValue: resultString,
1216
1520
  });
1217
1521
  }
1218
- parametersToPass = __assign(__assign({}, parametersToPass), (_g = {}, _g[resultingParameter.name] = promptResult /* <- Note: Not need to detect parameter collision here because PromptTemplatePipeline checks logic consistency during construction */, _g));
1522
+ 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));
1219
1523
  currentTemplate = ptp.getFollowingPromptTemplate(currentTemplate.name);
1220
1524
  return [2 /*return*/];
1221
1525
  }
1222
1526
  });
1223
1527
  };
1224
- _a.label = 1;
1225
- case 1:
1226
- if (!(currentTemplate !== null)) return [3 /*break*/, 3];
1227
- return [5 /*yield**/, _loop_1()];
1528
+ _b.label = 2;
1228
1529
  case 2:
1229
- _a.sent();
1230
- return [3 /*break*/, 1];
1231
- case 3: return [2 /*return*/, parametersToPass];
1530
+ if (!(currentTemplate !== null)) return [3 /*break*/, 4];
1531
+ return [5 /*yield**/, _loop_1()];
1532
+ case 3:
1533
+ _b.sent();
1534
+ return [3 /*break*/, 2];
1535
+ case 4: return [3 /*break*/, 6];
1536
+ case 5:
1537
+ error_1 = _b.sent();
1538
+ if (!(error_1 instanceof Error)) {
1539
+ throw error_1;
1540
+ }
1541
+ return [2 /*return*/, {
1542
+ isSuccessful: false,
1543
+ errors: [error_1],
1544
+ executionReport: executionReport,
1545
+ outputParameters: parametersToPass,
1546
+ }];
1547
+ case 6: return [2 /*return*/, {
1548
+ isSuccessful: true,
1549
+ errors: [],
1550
+ executionReport: executionReport,
1551
+ outputParameters: parametersToPass,
1552
+ }];
1232
1553
  }
1233
1554
  });
1234
1555
  }); };
@@ -1249,8 +1570,8 @@
1249
1570
  * @see https://github.com/webgptorg/promptbook#prompt-template-pipeline-library
1250
1571
  */
1251
1572
  var PromptTemplatePipelineLibrary = /** @class */ (function () {
1252
- function PromptTemplatePipelineLibrary(promptTemplatePipelines) {
1253
- this.promptTemplatePipelines = promptTemplatePipelines;
1573
+ function PromptTemplatePipelineLibrary(options) {
1574
+ this.options = options;
1254
1575
  }
1255
1576
  /**
1256
1577
  * Constructs PromptTemplatePipeline from any sources
@@ -1261,13 +1582,13 @@
1261
1582
  * @param ptbkSources contents of .ptbk.md or .ptbk.json files
1262
1583
  * @returns PromptTemplatePipelineLibrary
1263
1584
  */
1264
- PromptTemplatePipelineLibrary.fromSources = function (ptbkSources) {
1585
+ PromptTemplatePipelineLibrary.fromSources = function (ptbkSources, settings) {
1265
1586
  var e_1, _a;
1266
- var promptTemplatePipelines = {};
1587
+ var library = {};
1267
1588
  try {
1268
1589
  for (var _b = __values(Object.entries(ptbkSources)), _c = _b.next(); !_c.done; _c = _b.next()) {
1269
1590
  var _d = __read(_c.value, 2), name_1 = _d[0], source = _d[1];
1270
- promptTemplatePipelines[name_1] = PromptTemplatePipeline.fromSource(source);
1591
+ library[name_1] = PromptTemplatePipeline.fromSource(source);
1271
1592
  }
1272
1593
  }
1273
1594
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -1277,13 +1598,13 @@
1277
1598
  }
1278
1599
  finally { if (e_1) throw e_1.error; }
1279
1600
  }
1280
- return new PromptTemplatePipelineLibrary(promptTemplatePipelines);
1601
+ return new PromptTemplatePipelineLibrary({ library: library, settings: settings });
1281
1602
  };
1282
1603
  /**
1283
1604
  * Gets prompt template pipeline by name
1284
1605
  */
1285
1606
  PromptTemplatePipelineLibrary.prototype.getPtp = function (name) {
1286
- var promptTemplatePipeline = this.promptTemplatePipelines[name];
1607
+ var promptTemplatePipeline = this.options.library[name];
1287
1608
  if (!promptTemplatePipeline) {
1288
1609
  throw new Error("Prompt template pipeline with name \"".concat(name, "\" not found"));
1289
1610
  }
@@ -1300,7 +1621,7 @@
1300
1621
  */
1301
1622
  PromptTemplatePipelineLibrary.prototype.createExecutor = function (name, tools) {
1302
1623
  var ptp = this.getPtp(name);
1303
- return createPtpExecutor({ ptp: ptp, tools: tools });
1624
+ return createPtpExecutor({ ptp: ptp, tools: tools, settings: this.options.settings });
1304
1625
  };
1305
1626
  return PromptTemplatePipelineLibrary;
1306
1627
  }());