@promptbook/core 0.40.0-0 → 0.40.0-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/esm/index.es.js +250 -159
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/_packages/core.index.d.ts +1 -1
  4. package/esm/typings/_packages/types.index.d.ts +1 -4
  5. package/esm/typings/_packages/utils.index.d.ts +5 -2
  6. package/esm/typings/config.d.ts +4 -0
  7. package/esm/typings/conversion/{_importPromptbook.d.ts → test/_importPromptbook.d.ts} +2 -2
  8. package/{umd/typings/conversion → esm/typings/conversion/test}/validatePromptbookJson.d.ts +1 -1
  9. package/{umd/typings → esm/typings/conversion}/utils/extractVariables.d.ts +2 -2
  10. package/esm/typings/conversion/utils/parseCommand.d.ts +8 -0
  11. package/{umd/typings → esm/typings/conversion}/utils/parseNumber.d.ts +2 -0
  12. package/esm/typings/errors/ExpectError.d.ts +2 -0
  13. package/esm/typings/errors/NotFoundError.d.ts +1 -1
  14. package/esm/typings/errors/PromptbookExecutionError.d.ts +7 -0
  15. package/esm/typings/errors/PromptbookLogicError.d.ts +7 -0
  16. package/esm/typings/errors/PromptbookSyntaxError.d.ts +7 -0
  17. package/esm/typings/errors/UnexpectedError.d.ts +7 -0
  18. package/esm/typings/execution/UserInterfaceTools.d.ts +1 -1
  19. package/{umd/typings → esm/typings/execution}/utils/replaceParameters.d.ts +3 -3
  20. package/esm/typings/library/SimplePromptbookLibrary.d.ts +1 -1
  21. package/esm/typings/utils/markdown/extractOneBlockFromMarkdown.d.ts +3 -0
  22. package/package.json +2 -2
  23. package/umd/index.umd.js +250 -159
  24. package/umd/index.umd.js.map +1 -1
  25. package/umd/typings/_packages/core.index.d.ts +1 -1
  26. package/umd/typings/_packages/types.index.d.ts +1 -4
  27. package/umd/typings/_packages/utils.index.d.ts +5 -2
  28. package/umd/typings/config.d.ts +4 -0
  29. package/umd/typings/conversion/{_importPromptbook.d.ts → test/_importPromptbook.d.ts} +2 -2
  30. package/{esm/typings/conversion → umd/typings/conversion/test}/validatePromptbookJson.d.ts +1 -1
  31. package/{esm/typings → umd/typings/conversion}/utils/extractVariables.d.ts +2 -2
  32. package/umd/typings/conversion/utils/parseCommand.d.ts +8 -0
  33. package/{esm/typings → umd/typings/conversion}/utils/parseNumber.d.ts +2 -0
  34. package/umd/typings/errors/ExpectError.d.ts +2 -0
  35. package/umd/typings/errors/NotFoundError.d.ts +1 -1
  36. package/umd/typings/errors/PromptbookExecutionError.d.ts +7 -0
  37. package/umd/typings/errors/PromptbookLogicError.d.ts +7 -0
  38. package/umd/typings/errors/PromptbookSyntaxError.d.ts +7 -0
  39. package/umd/typings/errors/UnexpectedError.d.ts +7 -0
  40. package/umd/typings/execution/UserInterfaceTools.d.ts +1 -1
  41. package/{esm/typings → umd/typings/execution}/utils/replaceParameters.d.ts +3 -3
  42. package/umd/typings/library/SimplePromptbookLibrary.d.ts +1 -1
  43. package/umd/typings/utils/markdown/extractOneBlockFromMarkdown.d.ts +3 -0
  44. package/esm/typings/conversion/parseCommand.d.ts +0 -6
  45. package/umd/typings/conversion/parseCommand.d.ts +0 -6
  46. /package/esm/typings/conversion/{promptbookStringToJson-syntaxErrors.test.d.ts → test/promptbookStringToJson-syntaxErrors.test.d.ts} +0 -0
  47. /package/esm/typings/conversion/{promptbookStringToJson.test.d.ts → test/promptbookStringToJson.test.d.ts} +0 -0
  48. /package/esm/typings/conversion/{validatePromptbookJson-logicErrors.test.d.ts → test/validatePromptbookJson-logicErrors.test.d.ts} +0 -0
  49. /package/esm/typings/conversion/{validatePromptbookJson.test.d.ts → test/validatePromptbookJson.test.d.ts} +0 -0
  50. /package/esm/typings/{utils → conversion/utils}/extractVariables.test.d.ts +0 -0
  51. /package/esm/typings/conversion/{parseCommand.test.d.ts → utils/parseCommand.test.d.ts} +0 -0
  52. /package/esm/typings/{utils → conversion/utils}/parseNumber.test.d.ts +0 -0
  53. /package/esm/typings/{utils → execution/utils}/replaceParameters.test.d.ts +0 -0
  54. /package/umd/typings/conversion/{promptbookStringToJson-syntaxErrors.test.d.ts → test/promptbookStringToJson-syntaxErrors.test.d.ts} +0 -0
  55. /package/umd/typings/conversion/{promptbookStringToJson.test.d.ts → test/promptbookStringToJson.test.d.ts} +0 -0
  56. /package/umd/typings/conversion/{validatePromptbookJson-logicErrors.test.d.ts → test/validatePromptbookJson-logicErrors.test.d.ts} +0 -0
  57. /package/umd/typings/conversion/{validatePromptbookJson.test.d.ts → test/validatePromptbookJson.test.d.ts} +0 -0
  58. /package/umd/typings/{utils → conversion/utils}/extractVariables.test.d.ts +0 -0
  59. /package/umd/typings/conversion/{parseCommand.test.d.ts → utils/parseCommand.test.d.ts} +0 -0
  60. /package/umd/typings/{utils → conversion/utils}/parseNumber.test.d.ts +0 -0
  61. /package/umd/typings/{utils → execution/utils}/replaceParameters.test.d.ts +0 -0
package/umd/index.umd.js CHANGED
@@ -127,6 +127,20 @@
127
127
  return to.concat(ar || Array.prototype.slice.call(from));
128
128
  }
129
129
 
130
+ /**
131
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
132
+ */
133
+ var PromptbookSyntaxError = /** @class */ (function (_super) {
134
+ __extends(PromptbookSyntaxError, _super);
135
+ function PromptbookSyntaxError(message) {
136
+ var _this = _super.call(this, message) || this;
137
+ _this.name = 'PromptbookSyntaxError';
138
+ Object.setPrototypeOf(_this, PromptbookSyntaxError.prototype);
139
+ return _this;
140
+ }
141
+ return PromptbookSyntaxError;
142
+ }(Error));
143
+
130
144
  /**
131
145
  * Supported script languages
132
146
  */
@@ -163,53 +177,6 @@
163
177
  return parameterNames;
164
178
  }
165
179
 
166
- /**
167
- * Parses the given script and returns the list of all used variables that are not defined in the script
168
- *
169
- * @param script from which to extract the variables
170
- * @returns the list of variable names
171
- *
172
- * @private within the library
173
- */
174
- function extractVariables(script) {
175
- var variables = [];
176
- script = "(()=>{".concat(script, "})()");
177
- try {
178
- for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
179
- try {
180
- eval(script);
181
- }
182
- catch (error) {
183
- if (!(error instanceof ReferenceError)) {
184
- throw error;
185
- }
186
- var undefinedName = error.message.split(' ')[0];
187
- /*
188
- Note: Remapping error
189
- From: [ReferenceError: thing is not defined],
190
- To: [Error: Parameter {thing} is not defined],
191
- */
192
- if (!undefinedName) {
193
- throw error;
194
- }
195
- if (script.includes(undefinedName + '(')) {
196
- script = "const ".concat(undefinedName, " = ()=>'';") + script;
197
- }
198
- else {
199
- variables.push(undefinedName);
200
- script = "const ".concat(undefinedName, " = '';") + script;
201
- }
202
- }
203
- }
204
- catch (error) {
205
- if (!(error instanceof Error)) {
206
- throw error;
207
- }
208
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
209
- }
210
- return variables;
211
- }
212
-
213
180
  /**
214
181
  * Computes the deepness of the markdown structure.
215
182
  *
@@ -234,6 +201,25 @@
234
201
  return maxDeepness + 1;
235
202
  }
236
203
 
204
+ /**
205
+ * The maximum number of iterations for a loops
206
+ */
207
+ var LOOP_LIMIT = 1000;
208
+
209
+ /**
210
+ * This error type indicates that the error should not happen and its last check before crashing with some other error
211
+ */
212
+ var UnexpectedError = /** @class */ (function (_super) {
213
+ __extends(UnexpectedError, _super);
214
+ function UnexpectedError(message) {
215
+ var _this = _super.call(this, spaceTrim__default["default"](function (block) { return "\n ".concat(block(message), "\n\n Note: This error should not happen.\n It's probbably a bug in the promptbook library\n\n Please report issue:\n https://github.com/webgptorg/promptbook/issues\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
216
+ _this.name = 'UnexpectedError';
217
+ Object.setPrototypeOf(_this, UnexpectedError.prototype);
218
+ return _this;
219
+ }
220
+ return UnexpectedError;
221
+ }(Error));
222
+
237
223
  /**
238
224
  * Parse a markdown string into a MarkdownStructure object.
239
225
  *
@@ -272,8 +258,13 @@
272
258
  else {
273
259
  // Note: Going up or staying at the same level (next section is sibling or parent or grandparent,... of current)
274
260
  parent_1 = current;
261
+ var loopLimit = LOOP_LIMIT;
275
262
  while (parent_1.level !== level - 1) {
263
+ if (loopLimit-- < 0) {
264
+ throw new UnexpectedError('Loop limit reached during parsing of markdown structure in `markdownToMarkdownStructure`');
265
+ }
276
266
  if (parent_1.parent === null /* <- Note: We are in root */) {
267
+ // [🌻]
277
268
  throw new Error(spaceTrim__default["default"]("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
278
269
  }
279
270
  parent_1 = parent_1.parent;
@@ -296,6 +287,7 @@
296
287
  var markdownStructure = parsingMarkdownStructureToMarkdownStructure(root.sections[0]);
297
288
  return markdownStructure;
298
289
  }
290
+ // [🌻]
299
291
  throw new Error('The markdown file must have exactly one top-level section.');
300
292
  // return root;
301
293
  }
@@ -372,6 +364,7 @@
372
364
  }
373
365
  else {
374
366
  if (language !== null) {
367
+ // [🌻]
375
368
  throw new Error("".concat(n12.capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
376
369
  }
377
370
  codeBlocks.push(currentCodeBlock);
@@ -394,6 +387,7 @@
394
387
  finally { if (e_1) throw e_1.error; }
395
388
  }
396
389
  if (currentCodeBlock !== null) {
390
+ // [🌻]
397
391
  throw new Error("".concat(n12.capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
398
392
  }
399
393
  return codeBlocks;
@@ -412,10 +406,13 @@
412
406
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
413
407
  if (codeBlocks.length !== 1) {
414
408
  // TODO: Report more specific place where the error happened
415
- throw new Error('There should be exactly one code block in the markdown');
409
+ throw new Error(/* <- [🌻] */ 'There should be exactly one code block in the markdown');
416
410
  }
417
411
  return codeBlocks[0];
418
412
  }
413
+ /***
414
+ * TODO: [🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
415
+ */
419
416
 
420
417
  /**
421
418
  * Removes HTML or Markdown comments from a string.
@@ -430,7 +427,54 @@
430
427
  /**
431
428
  * The version of the Promptbook library
432
429
  */
433
- var PROMPTBOOK_VERSION = '0.39.4';
430
+ var PROMPTBOOK_VERSION = '0.40.0-1';
431
+
432
+ /**
433
+ * Parses the given script and returns the list of all used variables that are not defined in the script
434
+ *
435
+ * @param script from which to extract the variables
436
+ * @returns the list of variable names
437
+ *
438
+ * @private within the promptbookStringToJson
439
+ */
440
+ function extractVariables(script) {
441
+ var variables = [];
442
+ script = "(()=>{".concat(script, "})()");
443
+ try {
444
+ for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
445
+ try {
446
+ eval(script);
447
+ }
448
+ catch (error) {
449
+ if (!(error instanceof ReferenceError)) {
450
+ throw error;
451
+ }
452
+ var undefinedName = error.message.split(' ')[0];
453
+ /*
454
+ Note: Remapping error
455
+ From: [ReferenceError: thing is not defined],
456
+ To: [Error: Parameter {thing} is not defined],
457
+ */
458
+ if (!undefinedName) {
459
+ throw error;
460
+ }
461
+ if (script.includes(undefinedName + '(')) {
462
+ script = "const ".concat(undefinedName, " = ()=>'';") + script;
463
+ }
464
+ else {
465
+ variables.push(undefinedName);
466
+ script = "const ".concat(undefinedName, " = '';") + script;
467
+ }
468
+ }
469
+ }
470
+ catch (error) {
471
+ if (!(error instanceof Error)) {
472
+ throw error;
473
+ }
474
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
475
+ }
476
+ return variables;
477
+ }
434
478
 
435
479
  /**
436
480
  * Execution type describes the way how the block is executed
@@ -468,6 +512,8 @@
468
512
  *
469
513
  * Unlike Number.parseInt, Number.parseFloat it will never ever result in NaN
470
514
  * Note: it also works only with decimal numbers
515
+ *
516
+ * @private within the parseCommand
471
517
  */
472
518
  function parseNumber(value) {
473
519
  var originalValue = value;
@@ -501,7 +547,7 @@
501
547
  var numerator = parseNumber(numerator_);
502
548
  var denominator = parseNumber(denominator_);
503
549
  if (denominator === 0) {
504
- throw new Error("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
550
+ throw new PromptbookSyntaxError("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
505
551
  }
506
552
  return numerator / denominator;
507
553
  }
@@ -513,11 +559,11 @@
513
559
  return parseNumber(significand) * Math.pow(10, parseNumber(exponent));
514
560
  }
515
561
  if (!/^[0-9.]+$/.test(value) || value.split('.').length > 2) {
516
- throw new Error("Unable to parse number from \"".concat(originalValue, "\""));
562
+ throw new PromptbookSyntaxError("Unable to parse number from \"".concat(originalValue, "\""));
517
563
  }
518
564
  var num = parseFloat(value);
519
565
  if (isNaN(num)) {
520
- throw new Error("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
566
+ throw new PromptbookSyntaxError("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
521
567
  }
522
568
  return num;
523
569
  }
@@ -527,11 +573,13 @@
527
573
 
528
574
  /**
529
575
  * Parses one line of ul/ol to command
576
+ *
577
+ * @private within the promptbookStringToJson
530
578
  */
531
579
  function parseCommand(listItem) {
532
580
  var e_1, _a;
533
581
  if (listItem.includes('\n') || listItem.includes('\r')) {
534
- throw new Error('Command can not contain new line characters:');
582
+ throw new PromptbookSyntaxError('Command can not contain new line characters:');
535
583
  }
536
584
  var type = listItem.trim();
537
585
  type = type.split('`').join('');
@@ -558,15 +606,15 @@
558
606
  type.startsWith('PROMPTBOOKURL') ||
559
607
  type.startsWith('HTTPS')) {
560
608
  if (!(listItemParts.length === 2 || (listItemParts.length === 1 && type.startsWith('HTTPS')))) {
561
- throw new Error(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n ")));
609
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n ")));
562
610
  }
563
611
  var promptbookUrlString = listItemParts.pop();
564
612
  var promptbookUrl = new URL(promptbookUrlString);
565
613
  if (promptbookUrl.protocol !== 'https:') {
566
- throw new Error(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n Protocol must be HTTPS\n ")));
614
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n Protocol must be HTTPS\n ")));
567
615
  }
568
616
  if (promptbookUrl.hash !== '') {
569
- throw new Error(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n URL must not contain hash\n Hash is used for identification of the prompt template in the pipeline\n ")));
617
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n URL must not contain hash\n Hash is used for identification of the prompt template in the pipeline\n ")));
570
618
  }
571
619
  return {
572
620
  type: 'PROMPTBOOK_URL',
@@ -575,7 +623,7 @@
575
623
  }
576
624
  else if (type.startsWith('PROMPTBOOK_VERSION') || type.startsWith('PTBK_VERSION')) {
577
625
  if (listItemParts.length !== 2) {
578
- throw new Error(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_VERSION command:\n\n - ".concat(listItem, "\n ")));
626
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_VERSION command:\n\n - ".concat(listItem, "\n ")));
579
627
  }
580
628
  var promptbookVersion = listItemParts.pop();
581
629
  // TODO: Validate version
@@ -590,7 +638,7 @@
590
638
  type.startsWith('SIMPLE_TEMPLATE')) {
591
639
  var executionTypes = ExecutionTypes.filter(function (executionType) { return type.includes(executionType); });
592
640
  if (executionTypes.length !== 1) {
593
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Unknown execution type in command:\n\n - ".concat(listItem, "\n\n Supported execution types are:\n ").concat(block(ExecutionTypes.join(', ')), "\n "); }));
641
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Unknown execution type in command:\n\n - ".concat(listItem, "\n\n Supported execution types are:\n ").concat(block(ExecutionTypes.join(', ')), "\n "); }));
594
642
  }
595
643
  return {
596
644
  type: 'EXECUTE',
@@ -615,7 +663,7 @@
615
663
  };
616
664
  }
617
665
  else {
618
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Unknown model variant in command:\n\n - ".concat(listItem, "\n\n Supported variants are:\n ").concat(block(['CHAT', 'COMPLETION'].join(', ')), "\n "); }));
666
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Unknown model variant in command:\n\n - ".concat(listItem, "\n\n Supported variants are:\n ").concat(block(['CHAT', 'COMPLETION'].join(', ')), "\n "); }));
619
667
  }
620
668
  }
621
669
  if (type.startsWith('MODEL_NAME')) {
@@ -626,7 +674,7 @@
626
674
  };
627
675
  }
628
676
  else {
629
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Unknown model key in command:\n\n - ".concat(listItem, "\n\n Supported model keys are:\n ").concat(block(['variant', 'name'].join(', ')), "\n\n Example:\n\n - MODEL VARIANT Chat\n - MODEL NAME gpt-4\n "); }));
677
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Unknown model key in command:\n\n - ".concat(listItem, "\n\n Supported model keys are:\n ").concat(block(['variant', 'name'].join(', ')), "\n\n Example:\n\n - MODEL VARIANT Chat\n - MODEL NAME gpt-4\n "); }));
630
678
  }
631
679
  }
632
680
  else if (type.startsWith('PARAM') ||
@@ -636,12 +684,12 @@
636
684
  listItem.startsWith('> {') /* <- Note: This is a bit hack to parse return parameters defined at the end of each section */) {
637
685
  var parametersMatch = listItem.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
638
686
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
639
- throw new Error(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
687
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
640
688
  }
641
689
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
642
690
  var _b = parametersMatch.groups, parameterName = _b.parameterName, parameterDescription = _b.parameterDescription;
643
691
  if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
644
- throw new Error(spaceTrim__default["default"]("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
692
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
645
693
  }
646
694
  var isInput = type.startsWith('INPUT');
647
695
  var isOutput = type.startsWith('OUTPUT');
@@ -655,11 +703,11 @@
655
703
  }
656
704
  else if (type.startsWith('JOKER')) {
657
705
  if (listItemParts.length !== 2) {
658
- throw new Error(spaceTrim__default["default"]("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
706
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
659
707
  }
660
708
  var parametersMatch = (listItemParts.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
661
709
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
662
- throw new Error(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
710
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
663
711
  }
664
712
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
665
713
  var parameterName = parametersMatch.groups.parameterName;
@@ -670,7 +718,7 @@
670
718
  }
671
719
  else if (type.startsWith('POSTPROCESS') || type.startsWith('POST_PROCESS')) {
672
720
  if (listItemParts.length !== 2) {
673
- throw new Error(spaceTrim__default["default"]("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
721
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
674
722
  }
675
723
  var functionName = listItemParts.pop();
676
724
  return {
@@ -700,15 +748,15 @@
700
748
  sign = 'MAXIMUM';
701
749
  }
702
750
  else {
703
- throw new Error("Invalid sign \"".concat(signRaw, "\""));
751
+ throw new PromptbookSyntaxError("Invalid sign \"".concat(signRaw, "\""));
704
752
  }
705
753
  var amountRaw = listItemParts.shift();
706
754
  var amount = parseNumber(amountRaw);
707
755
  if (amount < 0) {
708
- throw new Error('Amount must be positive number or zero');
756
+ throw new PromptbookSyntaxError('Amount must be positive number or zero');
709
757
  }
710
758
  if (amount !== Math.floor(amount)) {
711
- throw new Error('Amount must be whole number');
759
+ throw new PromptbookSyntaxError('Amount must be whole number');
712
760
  }
713
761
  var unitRaw = listItemParts.shift();
714
762
  var unit = undefined;
@@ -723,7 +771,7 @@
723
771
  if (new RegExp("^".concat(existingUnitText.toLowerCase())).test(unitRaw.toLowerCase()) ||
724
772
  new RegExp("^".concat(unitRaw.toLowerCase())).test(existingUnitText.toLowerCase())) {
725
773
  if (unit !== undefined) {
726
- throw new Error("Ambiguous unit \"".concat(unitRaw, "\""));
774
+ throw new PromptbookSyntaxError("Ambiguous unit \"".concat(unitRaw, "\""));
727
775
  }
728
776
  unit = existingUnit;
729
777
  }
@@ -737,7 +785,7 @@
737
785
  finally { if (e_1) throw e_1.error; }
738
786
  }
739
787
  if (unit === undefined) {
740
- throw new Error("Invalid unit \"".concat(unitRaw, "\""));
788
+ throw new PromptbookSyntaxError("Invalid unit \"".concat(unitRaw, "\""));
741
789
  }
742
790
  return {
743
791
  type: 'EXPECT_AMOUNT',
@@ -750,11 +798,11 @@
750
798
  if (!(error instanceof Error)) {
751
799
  throw error;
752
800
  }
753
- throw new Error(spaceTrim__default["default"]("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
801
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
754
802
  }
755
803
  }
756
804
  else {
757
- 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 - PROMPTBOOK VERSION\n ")));
805
+ throw new PromptbookSyntaxError(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 - PROMPTBOOK VERSION\n ")));
758
806
  }
759
807
  }
760
808
 
@@ -777,8 +825,8 @@
777
825
  // =============================================================
778
826
  // Note: 1️⃣ Normalization of the PROMPTBOOK string
779
827
  promptbookString = removeContentComments(promptbookString);
780
- promptbookString = promptbookString.replaceAll(/`\{(?<paramName>[a-z0-9_]+)\}`/gi, '{$<paramName>}');
781
- promptbookString = promptbookString.replaceAll(/`->\s+\{(?<paramName>[a-z0-9_]+)\}`/gi, '-> {$<paramName>}');
828
+ promptbookString = promptbookString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
829
+ promptbookString = promptbookString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
782
830
  // =============================================================
783
831
  ///Note: 2️⃣ Function for adding parameters
784
832
  var addParam = function (parameterCommand) {
@@ -788,7 +836,7 @@
788
836
  existingParameter.description &&
789
837
  existingParameter.description !== parameterDescription &&
790
838
  parameterDescription) {
791
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Parameter {".concat(parameterName, "} is defined multiple times with different description.\n\n First definition:\n ").concat(block(existingParameter.description || '[undefined]'), "\n\n Second definition:\n ").concat(block(parameterDescription || '[undefined]'), "\n "); }));
839
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Parameter {".concat(parameterName, "} is defined multiple times with different description.\n\n First definition:\n ").concat(block(existingParameter.description || '[undefined]'), "\n\n Second definition:\n ").concat(block(parameterDescription || '[undefined]'), "\n "); }));
792
840
  }
793
841
  if (existingParameter) {
794
842
  if (parameterDescription) {
@@ -809,7 +857,7 @@
809
857
  var markdownStructure = markdownToMarkdownStructure(promptbookString);
810
858
  var markdownStructureDeepness = countMarkdownStructureDeepness(markdownStructure);
811
859
  if (markdownStructureDeepness !== 2) {
812
- throw new Error(spaceTrim__default["default"]("\n Invalid markdown structure.\n The markdown must have exactly 2 levels of headings (one top-level section and one section for each template).\n Now it has ".concat(markdownStructureDeepness, " levels of headings.\n ")));
860
+ throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid markdown structure.\n The markdown must have exactly 2 levels of headings (one top-level section and one section for each template).\n Now it has ".concat(markdownStructureDeepness, " levels of headings.\n ")));
813
861
  }
814
862
  promptbookJson.title = markdownStructure.title;
815
863
  // TODO: [1] DRY description
@@ -843,7 +891,7 @@
843
891
  addParam(command);
844
892
  break;
845
893
  default:
846
- throw new Error("Command ".concat(command.type, " is not allowed in the head of the promptbook ONLY at the prompt template block"));
894
+ throw new PromptbookSyntaxError("Command ".concat(command.type, " is not allowed in the head of the promptbook ONLY at the prompt template block"));
847
895
  }
848
896
  }
849
897
  }
@@ -877,7 +925,7 @@
877
925
  break;
878
926
  case 'EXECUTE':
879
927
  if (isExecutionTypeChanged) {
880
- throw new Error('Execution type is already defined in the prompt template. It can be defined only once.');
928
+ throw new PromptbookSyntaxError('Execution type is already defined in the prompt template. It can be defined only once.');
881
929
  }
882
930
  executionType = command.executionType;
883
931
  isExecutionTypeChanged = true;
@@ -898,25 +946,25 @@
898
946
  expectAmount[unit] = expectAmount[unit] || {};
899
947
  if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
900
948
  if (expectAmount[unit].min !== undefined) {
901
- throw new Error("Already defined minumum ".concat(expectAmount[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
949
+ throw new PromptbookSyntaxError("Already defined minumum ".concat(expectAmount[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
902
950
  }
903
951
  expectAmount[unit].min = command.amount;
904
952
  } /* not else */
905
953
  if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
906
954
  if (expectAmount[unit].max !== undefined) {
907
- throw new Error("Already defined maximum ".concat(expectAmount[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
955
+ throw new PromptbookSyntaxError("Already defined maximum ".concat(expectAmount[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
908
956
  }
909
957
  expectAmount[unit].max = command.amount;
910
958
  }
911
959
  break;
912
960
  case 'EXPECT_FORMAT':
913
961
  if (expectFormat !== undefined && command.format !== expectFormat) {
914
- throw new Error("Expect format is already defined to \"".concat(expectFormat, "\". Now you try to redefine it by \"").concat(command.format, "\"."));
962
+ throw new PromptbookSyntaxError("Expect format is already defined to \"".concat(expectFormat, "\". Now you try to redefine it by \"").concat(command.format, "\"."));
915
963
  }
916
964
  expectFormat = command.format;
917
965
  break;
918
966
  default:
919
- throw new Error("Command ".concat(command.type, " is not allowed in the block of the prompt template ONLY at the head of the promptbook"));
967
+ throw new PromptbookSyntaxError("Command ".concat(command.type, " is not allowed in the block of the prompt template ONLY at the head of the promptbook"));
920
968
  }
921
969
  }
922
970
  }
@@ -930,16 +978,16 @@
930
978
  var _h = extractOneBlockFromMarkdown(section.content), language = _h.language, content = _h.content;
931
979
  if (executionType === 'SCRIPT') {
932
980
  if (!language) {
933
- throw new Error('You must specify the language of the script in the prompt template');
981
+ throw new PromptbookSyntaxError('You must specify the language of the script in the prompt template');
934
982
  }
935
983
  else if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
936
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Script language ".concat(language, " is not supported.\n\n Supported languages are:\n ").concat(block(SUPPORTED_SCRIPT_LANGUAGES.join(', ')), "\n\n "); }));
984
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Script language ".concat(language, " is not supported.\n\n Supported languages are:\n ").concat(block(SUPPORTED_SCRIPT_LANGUAGES.join(', ')), "\n\n "); }));
937
985
  }
938
986
  }
939
987
  var lastLine = section.content.split('\n').pop();
940
988
  var match = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im.exec(lastLine);
941
989
  if (!match || match.groups === undefined || match.groups.resultingParamName === undefined) {
942
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Invalid template - each section must end with \"-> {...}\"\n\n Invalid section:\n ".concat(block(
990
+ throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Invalid template - each section must end with \"-> {...}\"\n\n Invalid section:\n ".concat(block(
943
991
  // TODO: Show code of invalid sections each time + DRY
944
992
  section.content
945
993
  .split('\n')
@@ -1033,6 +1081,20 @@
1033
1081
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
1034
1082
  */
1035
1083
 
1084
+ /**
1085
+ * This error indicates that the promptbook object has valid syntax but contains logical errors (like circular dependencies)
1086
+ */
1087
+ var PromptbookLogicError = /** @class */ (function (_super) {
1088
+ __extends(PromptbookLogicError, _super);
1089
+ function PromptbookLogicError(message) {
1090
+ var _this = _super.call(this, message) || this;
1091
+ _this.name = 'PromptbookLogicError';
1092
+ Object.setPrototypeOf(_this, PromptbookLogicError.prototype);
1093
+ return _this;
1094
+ }
1095
+ return PromptbookLogicError;
1096
+ }(Error));
1097
+
1036
1098
  /**
1037
1099
  * Tests if given string is valid URL.
1038
1100
  *
@@ -1075,7 +1137,8 @@
1075
1137
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
1076
1138
  if (promptbook.promptbookUrl !== undefined) {
1077
1139
  if (!isValidUrl(promptbook.promptbookUrl)) {
1078
- throw new Error("Invalid promptbook URL \"".concat(promptbook.promptbookUrl, "\""));
1140
+ // TODO: This should be maybe the syntax error detected during parsing
1141
+ throw new PromptbookLogicError("Invalid promptbook URL \"".concat(promptbook.promptbookUrl, "\""));
1079
1142
  }
1080
1143
  }
1081
1144
  var definedParameters = new Set(promptbook.parameters.filter(function (_a) {
@@ -1087,18 +1150,18 @@
1087
1150
  }));
1088
1151
  var _loop_1 = function (parameter) {
1089
1152
  if (parameter.isInput && parameter.isOutput) {
1090
- throw new Error("Parameter {".concat(parameter.name, "} can not be both input and output"));
1153
+ throw new PromptbookLogicError("Parameter {".concat(parameter.name, "} can not be both input and output"));
1091
1154
  }
1092
1155
  // Note: Testing that parameter is either intermediate or output BUT not created and unused
1093
1156
  if (!parameter.isInput &&
1094
1157
  !parameter.isOutput &&
1095
1158
  !promptbook.promptTemplates.some(function (template) { return template.dependentParameterNames.includes(parameter.name); })) {
1096
- throw new Error(spaceTrim__default["default"]("\n Parameter {".concat(parameter.name, "} is created but not used\n\n You can declare {").concat(parameter.name, "} as output parameter by adding in the header:\n - OUTPUT PARAMETER `{").concat(parameter.name, "}` ").concat(parameter.description || '', "\n\n ")));
1159
+ throw new PromptbookLogicError(spaceTrim__default["default"]("\n Parameter {".concat(parameter.name, "} is created but not used\n\n You can declare {").concat(parameter.name, "} as output parameter by adding in the header:\n - OUTPUT PARAMETER `{").concat(parameter.name, "}` ").concat(parameter.description || '', "\n\n ")));
1097
1160
  }
1098
1161
  // Note: Testing that parameter is either input or result of some template
1099
1162
  if (!parameter.isInput &&
1100
1163
  !promptbook.promptTemplates.some(function (template) { return template.resultingParameterName === parameter.name; })) {
1101
- throw new Error(spaceTrim__default["default"]("\n Parameter {".concat(parameter.name, "} is declared but not defined\n\n You can do one of these:\n - Remove declaration of {").concat(parameter.name, "}\n - Add prompt template that results in -> {").concat(parameter.name, "}\n\n ")));
1164
+ throw new PromptbookLogicError(spaceTrim__default["default"]("\n Parameter {".concat(parameter.name, "} is declared but not defined\n\n You can do one of these:\n - Remove declaration of {").concat(parameter.name, "}\n - Add prompt template that results in -> {").concat(parameter.name, "}\n\n ")));
1102
1165
  }
1103
1166
  };
1104
1167
  try {
@@ -1120,23 +1183,23 @@
1120
1183
  for (var _g = __values(promptbook.promptTemplates), _h = _g.next(); !_h.done; _h = _g.next()) {
1121
1184
  var template = _h.value;
1122
1185
  if (definedParameters.has(template.resultingParameterName)) {
1123
- throw new Error("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
1186
+ throw new PromptbookLogicError("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
1124
1187
  }
1125
1188
  if (template.executionType === 'PROMPT_TEMPLATE' &&
1126
1189
  (template.modelRequirements.modelVariant === undefined ||
1127
1190
  template.modelRequirements.modelName === undefined)) {
1128
- throw new Error(spaceTrim__default["default"]("\n\n You must specify MODEL VARIANT and MODEL NAME in the prompt template \"".concat(template.title, "\"\n\n For example:\n - MODEL VARIANT Chat\n - MODEL NAME `gpt-4-1106-preview`\n\n ")));
1191
+ throw new PromptbookLogicError(spaceTrim__default["default"]("\n\n You must specify MODEL VARIANT and MODEL NAME in the prompt template \"".concat(template.title, "\"\n\n For example:\n - MODEL VARIANT Chat\n - MODEL NAME `gpt-4-1106-preview`\n\n ")));
1129
1192
  }
1130
1193
  if (template.jokers && template.jokers.length > 0) {
1131
1194
  if (!template.expectFormat &&
1132
1195
  !template.expectAmount /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
1133
- throw new Error("Joker parameters are used but no expectations are defined");
1196
+ throw new PromptbookLogicError("Joker parameters are used but no expectations are defined");
1134
1197
  }
1135
1198
  try {
1136
1199
  for (var _j = (e_3 = void 0, __values(template.jokers)), _k = _j.next(); !_k.done; _k = _j.next()) {
1137
1200
  var joker = _k.value;
1138
1201
  if (!template.dependentParameterNames.includes(joker)) {
1139
- throw new Error("Parameter {".concat(joker, "} is used as joker but not in dependentParameterNames"));
1202
+ throw new PromptbookLogicError("Parameter {".concat(joker, "} is used as joker but not in dependentParameterNames"));
1140
1203
  }
1141
1204
  }
1142
1205
  }
@@ -1153,13 +1216,13 @@
1153
1216
  for (var _l = (e_4 = void 0, __values(Object.entries(template.expectAmount))), _m = _l.next(); !_m.done; _m = _l.next()) {
1154
1217
  var _o = __read(_m.value, 2), unit = _o[0], _p = _o[1], min = _p.min, max = _p.max;
1155
1218
  if (min !== undefined && max !== undefined && min > max) {
1156
- throw new Error("Min expectation (=".concat(min, ") of ").concat(unit, " is higher than max expectation (=").concat(max, ")"));
1219
+ throw new PromptbookLogicError("Min expectation (=".concat(min, ") of ").concat(unit, " is higher than max expectation (=").concat(max, ")"));
1157
1220
  }
1158
1221
  if (min !== undefined && min < 0) {
1159
- throw new Error("Min expectation of ".concat(unit, " must be zero or positive"));
1222
+ throw new PromptbookLogicError("Min expectation of ".concat(unit, " must be zero or positive"));
1160
1223
  }
1161
1224
  if (max !== undefined && max <= 0) {
1162
- throw new Error("Max expectation of ".concat(unit, " must be positive"));
1225
+ throw new PromptbookLogicError("Max expectation of ".concat(unit, " must be positive"));
1163
1226
  }
1164
1227
  }
1165
1228
  }
@@ -1192,12 +1255,16 @@
1192
1255
  return name;
1193
1256
  });
1194
1257
  var unresovedTemplates = __spreadArray([], __read(promptbook.promptTemplates), false);
1258
+ var loopLimit = LOOP_LIMIT;
1195
1259
  var _loop_2 = function () {
1260
+ if (loopLimit-- < 0) {
1261
+ throw new UnexpectedError('Loop limit reached during detection of circular dependencies in `validatePromptbookJson`');
1262
+ }
1196
1263
  var currentlyResovedTemplates = unresovedTemplates.filter(function (template) {
1197
1264
  return template.dependentParameterNames.every(function (name) { return resovedParameters.includes(name); });
1198
1265
  });
1199
1266
  if (currentlyResovedTemplates.length === 0) {
1200
- throw new Error(spaceTrim__default["default"](function (block) { return "\n\n Can not resolve some parameters\n It may be circular dependencies\n\n Can not resolve:\n ".concat(block(unresovedTemplates
1267
+ throw new PromptbookLogicError(spaceTrim__default["default"](function (block) { return "\n\n Can not resolve some parameters\n It may be circular dependencies\n\n Can not resolve:\n ".concat(block(unresovedTemplates
1201
1268
  .map(function (_a) {
1202
1269
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
1203
1270
  return "- {".concat(resultingParameterName, "} depends on ").concat(dependentParameterNames
@@ -1228,6 +1295,36 @@
1228
1295
  * > ex port function validatePromptbookJson(promptbook: unknown): asserts promptbook is PromptbookJson {
1229
1296
  */
1230
1297
 
1298
+ /**
1299
+ * This error occurs when some expectation is not met in the execution of the pipeline
1300
+ *
1301
+ * Note: This is a kindof subtype of PromptbookExecutionError
1302
+ */
1303
+ var ExpectError = /** @class */ (function (_super) {
1304
+ __extends(ExpectError, _super);
1305
+ function ExpectError(message) {
1306
+ var _this = _super.call(this, message) || this;
1307
+ _this.name = 'ExpectError';
1308
+ Object.setPrototypeOf(_this, ExpectError.prototype);
1309
+ return _this;
1310
+ }
1311
+ return ExpectError;
1312
+ }(Error));
1313
+
1314
+ /**
1315
+ * This error indicates errors during the execution of the promptbook
1316
+ */
1317
+ var PromptbookExecutionError = /** @class */ (function (_super) {
1318
+ __extends(PromptbookExecutionError, _super);
1319
+ function PromptbookExecutionError(message) {
1320
+ var _this = _super.call(this, message) || this;
1321
+ _this.name = 'PromptbookExecutionError';
1322
+ Object.setPrototypeOf(_this, PromptbookExecutionError.prototype);
1323
+ return _this;
1324
+ }
1325
+ return PromptbookExecutionError;
1326
+ }(Error));
1327
+
1231
1328
  /**
1232
1329
  * Counts number of characters in the text
1233
1330
  */
@@ -1322,62 +1419,54 @@
1322
1419
  * @param parameters the object with parameters
1323
1420
  * @returns the template with replaced parameters
1324
1421
  *
1325
- * @private within the library
1422
+ * @private within the createPromptbookExecutor
1326
1423
  */
1327
1424
  function replaceParameters(template, parameters) {
1328
- var e_1, _a;
1329
- var placeholders = template.match(/{\w+}/g);
1330
1425
  var replacedTemplate = template;
1331
- if (placeholders) {
1332
- try {
1333
- for (var placeholders_1 = __values(placeholders), placeholders_1_1 = placeholders_1.next(); !placeholders_1_1.done; placeholders_1_1 = placeholders_1.next()) {
1334
- var placeholder = placeholders_1_1.value;
1335
- var paramName = placeholder.slice(1, -1); // Remove the curly braces to get the parameter name
1336
- if (paramName === '') {
1337
- continue; // Skip empty placeholders. It's used to avoid confusion with JSON-like strings
1338
- }
1339
- if (paramName.indexOf('{') !== -1 || paramName.indexOf('}') !== -1) {
1340
- throw new Error('Parameter is already opened or not closed');
1341
- }
1342
- if (parameters[paramName] === undefined) {
1343
- throw new Error("Parameter {".concat(paramName, "} is not defined"));
1344
- }
1345
- replacedTemplate = replacedTemplate.replace(new RegExp(placeholder, 'g'), parameters[paramName]);
1346
- }
1347
- }
1348
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1349
- finally {
1350
- try {
1351
- if (placeholders_1_1 && !placeholders_1_1.done && (_a = placeholders_1.return)) _a.call(placeholders_1);
1352
- }
1353
- finally { if (e_1) throw e_1.error; }
1426
+ var match;
1427
+ var loopLimit = LOOP_LIMIT;
1428
+ var _loop_1 = function () {
1429
+ if (loopLimit-- < 0) {
1430
+ throw new UnexpectedError('Loop limit reached during parameters replacement in `replaceParameters`');
1431
+ }
1432
+ var precol = match.groups.precol;
1433
+ var parameterName = match.groups.parameterName;
1434
+ if (parameterName === '') {
1435
+ return "continue";
1436
+ }
1437
+ if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
1438
+ throw new PromptbookExecutionError('Parameter is already opened or not closed');
1439
+ }
1440
+ if (parameters[parameterName] === undefined) {
1441
+ throw new PromptbookExecutionError("Parameter {".concat(parameterName, "} is not defined"));
1442
+ }
1443
+ var parameterValue = parameters[parameterName];
1444
+ if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
1445
+ parameterValue = parameterValue
1446
+ .split('\n')
1447
+ .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
1448
+ .join('\n');
1354
1449
  }
1450
+ replacedTemplate =
1451
+ replacedTemplate.substring(0, match.index + precol.length) +
1452
+ parameterValue +
1453
+ replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
1454
+ };
1455
+ while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
1456
+ .exec(replacedTemplate))) {
1457
+ _loop_1();
1355
1458
  }
1356
1459
  // [💫] Check if there are parameters that are not closed properly
1357
1460
  if (/{\w+$/.test(replacedTemplate)) {
1358
- throw new Error('Parameter is not closed');
1461
+ throw new PromptbookExecutionError('Parameter is not closed');
1359
1462
  }
1360
1463
  // [💫] Check if there are parameters that are not opened properly
1361
1464
  if (/^\w+}/.test(replacedTemplate)) {
1362
- throw new Error('Parameter is not opened');
1465
+ throw new PromptbookExecutionError('Parameter is not opened');
1363
1466
  }
1364
1467
  return replacedTemplate;
1365
1468
  }
1366
1469
 
1367
- /**
1368
- * This error occurs when some expectation is not met in the execution of the pipeline
1369
- */
1370
- var ExpectError = /** @class */ (function (_super) {
1371
- __extends(ExpectError, _super);
1372
- function ExpectError(message) {
1373
- var _this = _super.call(this, message) || this;
1374
- _this.name = 'ExpectError';
1375
- Object.setPrototypeOf(_this, ExpectError.prototype);
1376
- return _this;
1377
- }
1378
- return ExpectError;
1379
- }(Error));
1380
-
1381
1470
  /**
1382
1471
  * Creates executor function from promptbook and execution tools.
1383
1472
  *
@@ -1426,15 +1515,14 @@
1426
1515
  isJokerAttempt = attempt < 0;
1427
1516
  joker = jokers[jokers.length + attempt];
1428
1517
  if (isJokerAttempt && !joker) {
1429
- throw new Error("Joker not found in attempt ".concat(attempt));
1430
- // <- TODO: [🥨] Make some NeverShouldHappenError
1518
+ throw new UnexpectedError("Joker not found in attempt ".concat(attempt));
1431
1519
  }
1432
1520
  result = null;
1433
1521
  resultString = null;
1434
1522
  expectError = null;
1435
1523
  if (isJokerAttempt) {
1436
1524
  if (typeof parametersToPass[joker] === 'undefined') {
1437
- throw new Error("Joker parameter {".concat(joker, "} not defined"));
1525
+ throw new PromptbookExecutionError("Joker parameter {".concat(joker, "} not defined"));
1438
1526
  }
1439
1527
  resultString = parametersToPass[joker];
1440
1528
  }
@@ -1482,14 +1570,14 @@
1482
1570
  result = completionResult;
1483
1571
  resultString = completionResult.content;
1484
1572
  return [3 /*break*/, 12];
1485
- case 11: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1573
+ case 11: throw new PromptbookExecutionError("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1486
1574
  case 12: return [3 /*break*/, 27];
1487
1575
  case 13:
1488
1576
  if (tools.script.length === 0) {
1489
- throw new Error('No script execution tools are available');
1577
+ throw new PromptbookExecutionError('No script execution tools are available');
1490
1578
  }
1491
1579
  if (!currentTemplate.contentLanguage) {
1492
- throw new Error("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1580
+ throw new PromptbookExecutionError("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1493
1581
  }
1494
1582
  // TODO: DRY [1]
1495
1583
  scriptExecutionErrors = [];
@@ -1541,7 +1629,7 @@
1541
1629
  throw scriptExecutionErrors[0];
1542
1630
  }
1543
1631
  else {
1544
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors
1632
+ throw new PromptbookExecutionError(spaceTrim__default["default"](function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors
1545
1633
  .map(function (error) { return '- ' + error.message; })
1546
1634
  .join('\n\n')), "\n "); }));
1547
1635
  }
@@ -1557,7 +1645,7 @@
1557
1645
  // TODO: [🌹] When making next attempt for `PROMPT DIALOG`, preserve the previous user input
1558
1646
  resultString = _t.sent();
1559
1647
  return [3 /*break*/, 27];
1560
- case 26: throw new Error(
1648
+ case 26: throw new PromptbookExecutionError(
1561
1649
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1562
1650
  "Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1563
1651
  case 27:
@@ -1693,7 +1781,7 @@
1693
1781
  return [7 /*endfinally*/];
1694
1782
  case 47:
1695
1783
  if (expectError !== null && attempt === maxAttempts - 1) {
1696
- throw new Error(spaceTrim__default["default"](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 "); }));
1784
+ throw new PromptbookExecutionError(spaceTrim__default["default"](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 "); }));
1697
1785
  }
1698
1786
  _t.label = 48;
1699
1787
  case 48:
@@ -1701,8 +1789,7 @@
1701
1789
  return [3 /*break*/, 3];
1702
1790
  case 49:
1703
1791
  if (resultString === null) {
1704
- // <- TODO: [🥨] Make some NeverShouldHappenError
1705
- throw new Error('Something went wrong and prompt result is null');
1792
+ throw new UnexpectedError('Something went wrong and prompt result is null');
1706
1793
  }
1707
1794
  if (onProgress /* <- [3] */) {
1708
1795
  onProgress({
@@ -1722,7 +1809,7 @@
1722
1809
  });
1723
1810
  });
1724
1811
  }
1725
- var parametersToPass, executionReport, resovedParameters_1, unresovedTemplates, resolving_1, _loop_1, error_1, _a, _b, parameter;
1812
+ var parametersToPass, executionReport, resovedParameters_1, unresovedTemplates, resolving_1, loopLimit, _loop_1, error_1, _a, _b, parameter;
1726
1813
  var e_1, _c;
1727
1814
  return __generator(this, function (_d) {
1728
1815
  switch (_d.label) {
@@ -1750,16 +1837,20 @@
1750
1837
  });
1751
1838
  unresovedTemplates = __spreadArray([], __read(promptbook.promptTemplates), false);
1752
1839
  resolving_1 = [];
1840
+ loopLimit = LOOP_LIMIT;
1753
1841
  _loop_1 = function () {
1754
1842
  var currentTemplate, work_1;
1755
1843
  return __generator(this, function (_e) {
1756
1844
  switch (_e.label) {
1757
1845
  case 0:
1846
+ if (loopLimit-- < 0) {
1847
+ throw new UnexpectedError('Loop limit reached during resolving parameters promptbook execution');
1848
+ }
1758
1849
  currentTemplate = unresovedTemplates.find(function (template) {
1759
1850
  return template.dependentParameterNames.every(function (name) { return resovedParameters_1.includes(name); });
1760
1851
  });
1761
1852
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
1762
- throw new Error("Can not resolve some parameters");
1853
+ throw new UnexpectedError(spaceTrim__default["default"]("\n Can not resolve some parameters\n\n Note: This should be catched during validatePromptbookJson\n "));
1763
1854
  case 1:
1764
1855
  if (!!currentTemplate) return [3 /*break*/, 3];
1765
1856
  /* [5] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -1966,12 +2057,12 @@
1966
2057
  return __awaiter(this, void 0, void 0, function () {
1967
2058
  var answer;
1968
2059
  return __generator(this, function (_a) {
1969
- answer = window.prompt(spaceTrim__default["default"](function (block) { return "\n ".concat(block(options.promptTitle), "\n \n ").concat(block(options.promptMessage), "\n "); }));
2060
+ answer = window.prompt(spaceTrim__default["default"](function (block) { return "\n ".concat(block(options.promptTitle), "\n\n ").concat(block(options.promptMessage), "\n "); }));
1970
2061
  if (this.options.isVerbose) {
1971
2062
  console.info(spaceTrim__default["default"](function (block) { return "\n \uD83D\uDCD6 ".concat(block(options.promptTitle), "\n \uD83D\uDC64 ").concat(block(answer || '🚫 User cancelled prompt'), "\n "); }));
1972
2063
  }
1973
2064
  if (answer === null) {
1974
- throw new Error('User cancelled prompt');
2065
+ throw new PromptbookExecutionError('User cancelled prompt');
1975
2066
  }
1976
2067
  return [2 /*return*/, answer];
1977
2068
  });
@@ -1981,7 +2072,7 @@
1981
2072
  }());
1982
2073
 
1983
2074
  /**
1984
- * This error !!!
2075
+ * This error indicates that the requested resource (for example promptbook in the library ) was not found
1985
2076
  */
1986
2077
  var NotFoundError = /** @class */ (function (_super) {
1987
2078
  __extends(NotFoundError, _super);
@@ -2018,8 +2109,8 @@
2018
2109
  var e_1, _a;
2019
2110
  var library = {};
2020
2111
  try {
2021
- for (var _b = __values(Object.entries(promptbookSources)), _c = _b.next(); !_c.done; _c = _b.next()) {
2022
- var _d = __read(_c.value, 2), name_1 = _d[0], source = _d[1];
2112
+ for (var promptbookSources_1 = __values(promptbookSources), promptbookSources_1_1 = promptbookSources_1.next(); !promptbookSources_1_1.done; promptbookSources_1_1 = promptbookSources_1.next()) {
2113
+ var source = promptbookSources_1_1.value;
2023
2114
  var promptbook = void 0;
2024
2115
  if (typeof source === 'string') {
2025
2116
  // Note: When directly creating from string, no need to validate the source
@@ -2031,7 +2122,7 @@
2031
2122
  }
2032
2123
  validatePromptbookJson(promptbook);
2033
2124
  if (promptbook.promptbookUrl === undefined) {
2034
- throw new Error(spaceTrim__default["default"]("\n Promptbook with name \"".concat(name_1, "\" does not have defined URL\n\n Note: Promptbooks without URLs are called anonymous promptbooks\n They can be used as standalone promptbooks, but they cannot be referenced by other promptbooks\n And also they cannot be used in the promptbook library\n\n ")));
2125
+ throw new Error(spaceTrim__default["default"]("\n Promptbook with name \"".concat(promptbook.title, "\" does not have defined URL\n\n Note: Promptbooks without URLs are called anonymous promptbooks\n They can be used as standalone promptbooks, but they cannot be referenced by other promptbooks\n And also they cannot be used in the promptbook library\n\n ")));
2035
2126
  }
2036
2127
  library[promptbook.promptbookUrl] = promptbook;
2037
2128
  }
@@ -2039,7 +2130,7 @@
2039
2130
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2040
2131
  finally {
2041
2132
  try {
2042
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2133
+ if (promptbookSources_1_1 && !promptbookSources_1_1.done && (_a = promptbookSources_1.return)) _a.call(promptbookSources_1);
2043
2134
  }
2044
2135
  finally { if (e_1) throw e_1.error; }
2045
2136
  }