@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/esm/index.es.js CHANGED
@@ -120,6 +120,20 @@ function __spreadArray(to, from, pack) {
120
120
  return to.concat(ar || Array.prototype.slice.call(from));
121
121
  }
122
122
 
123
+ /**
124
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
125
+ */
126
+ var PromptbookSyntaxError = /** @class */ (function (_super) {
127
+ __extends(PromptbookSyntaxError, _super);
128
+ function PromptbookSyntaxError(message) {
129
+ var _this = _super.call(this, message) || this;
130
+ _this.name = 'PromptbookSyntaxError';
131
+ Object.setPrototypeOf(_this, PromptbookSyntaxError.prototype);
132
+ return _this;
133
+ }
134
+ return PromptbookSyntaxError;
135
+ }(Error));
136
+
123
137
  /**
124
138
  * Supported script languages
125
139
  */
@@ -156,53 +170,6 @@ function extractParameters(template) {
156
170
  return parameterNames;
157
171
  }
158
172
 
159
- /**
160
- * Parses the given script and returns the list of all used variables that are not defined in the script
161
- *
162
- * @param script from which to extract the variables
163
- * @returns the list of variable names
164
- *
165
- * @private within the library
166
- */
167
- function extractVariables(script) {
168
- var variables = [];
169
- script = "(()=>{".concat(script, "})()");
170
- try {
171
- for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
172
- try {
173
- eval(script);
174
- }
175
- catch (error) {
176
- if (!(error instanceof ReferenceError)) {
177
- throw error;
178
- }
179
- var undefinedName = error.message.split(' ')[0];
180
- /*
181
- Note: Remapping error
182
- From: [ReferenceError: thing is not defined],
183
- To: [Error: Parameter {thing} is not defined],
184
- */
185
- if (!undefinedName) {
186
- throw error;
187
- }
188
- if (script.includes(undefinedName + '(')) {
189
- script = "const ".concat(undefinedName, " = ()=>'';") + script;
190
- }
191
- else {
192
- variables.push(undefinedName);
193
- script = "const ".concat(undefinedName, " = '';") + script;
194
- }
195
- }
196
- }
197
- catch (error) {
198
- if (!(error instanceof Error)) {
199
- throw error;
200
- }
201
- throw new Error(spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
202
- }
203
- return variables;
204
- }
205
-
206
173
  /**
207
174
  * Computes the deepness of the markdown structure.
208
175
  *
@@ -227,6 +194,25 @@ function countMarkdownStructureDeepness(markdownStructure) {
227
194
  return maxDeepness + 1;
228
195
  }
229
196
 
197
+ /**
198
+ * The maximum number of iterations for a loops
199
+ */
200
+ var LOOP_LIMIT = 1000;
201
+
202
+ /**
203
+ * This error type indicates that the error should not happen and its last check before crashing with some other error
204
+ */
205
+ var UnexpectedError = /** @class */ (function (_super) {
206
+ __extends(UnexpectedError, _super);
207
+ function UnexpectedError(message) {
208
+ var _this = _super.call(this, spaceTrim(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;
209
+ _this.name = 'UnexpectedError';
210
+ Object.setPrototypeOf(_this, UnexpectedError.prototype);
211
+ return _this;
212
+ }
213
+ return UnexpectedError;
214
+ }(Error));
215
+
230
216
  /**
231
217
  * Parse a markdown string into a MarkdownStructure object.
232
218
  *
@@ -265,8 +251,13 @@ function markdownToMarkdownStructure(markdown) {
265
251
  else {
266
252
  // Note: Going up or staying at the same level (next section is sibling or parent or grandparent,... of current)
267
253
  parent_1 = current;
254
+ var loopLimit = LOOP_LIMIT;
268
255
  while (parent_1.level !== level - 1) {
256
+ if (loopLimit-- < 0) {
257
+ throw new UnexpectedError('Loop limit reached during parsing of markdown structure in `markdownToMarkdownStructure`');
258
+ }
269
259
  if (parent_1.parent === null /* <- Note: We are in root */) {
260
+ // [🌻]
270
261
  throw new Error(spaceTrim("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
271
262
  }
272
263
  parent_1 = parent_1.parent;
@@ -289,6 +280,7 @@ function markdownToMarkdownStructure(markdown) {
289
280
  var markdownStructure = parsingMarkdownStructureToMarkdownStructure(root.sections[0]);
290
281
  return markdownStructure;
291
282
  }
283
+ // [🌻]
292
284
  throw new Error('The markdown file must have exactly one top-level section.');
293
285
  // return root;
294
286
  }
@@ -365,6 +357,7 @@ function extractAllBlocksFromMarkdown(markdown) {
365
357
  }
366
358
  else {
367
359
  if (language !== null) {
360
+ // [🌻]
368
361
  throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
369
362
  }
370
363
  codeBlocks.push(currentCodeBlock);
@@ -387,6 +380,7 @@ function extractAllBlocksFromMarkdown(markdown) {
387
380
  finally { if (e_1) throw e_1.error; }
388
381
  }
389
382
  if (currentCodeBlock !== null) {
383
+ // [🌻]
390
384
  throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
391
385
  }
392
386
  return codeBlocks;
@@ -405,10 +399,13 @@ function extractOneBlockFromMarkdown(markdown) {
405
399
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
406
400
  if (codeBlocks.length !== 1) {
407
401
  // TODO: Report more specific place where the error happened
408
- throw new Error('There should be exactly one code block in the markdown');
402
+ throw new Error(/* <- [🌻] */ 'There should be exactly one code block in the markdown');
409
403
  }
410
404
  return codeBlocks[0];
411
405
  }
406
+ /***
407
+ * TODO: [🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
408
+ */
412
409
 
413
410
  /**
414
411
  * Removes HTML or Markdown comments from a string.
@@ -423,7 +420,54 @@ function removeContentComments(content) {
423
420
  /**
424
421
  * The version of the Promptbook library
425
422
  */
426
- var PROMPTBOOK_VERSION = '0.39.4';
423
+ var PROMPTBOOK_VERSION = '0.40.0-1';
424
+
425
+ /**
426
+ * Parses the given script and returns the list of all used variables that are not defined in the script
427
+ *
428
+ * @param script from which to extract the variables
429
+ * @returns the list of variable names
430
+ *
431
+ * @private within the promptbookStringToJson
432
+ */
433
+ function extractVariables(script) {
434
+ var variables = [];
435
+ script = "(()=>{".concat(script, "})()");
436
+ try {
437
+ for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
438
+ try {
439
+ eval(script);
440
+ }
441
+ catch (error) {
442
+ if (!(error instanceof ReferenceError)) {
443
+ throw error;
444
+ }
445
+ var undefinedName = error.message.split(' ')[0];
446
+ /*
447
+ Note: Remapping error
448
+ From: [ReferenceError: thing is not defined],
449
+ To: [Error: Parameter {thing} is not defined],
450
+ */
451
+ if (!undefinedName) {
452
+ throw error;
453
+ }
454
+ if (script.includes(undefinedName + '(')) {
455
+ script = "const ".concat(undefinedName, " = ()=>'';") + script;
456
+ }
457
+ else {
458
+ variables.push(undefinedName);
459
+ script = "const ".concat(undefinedName, " = '';") + script;
460
+ }
461
+ }
462
+ }
463
+ catch (error) {
464
+ if (!(error instanceof Error)) {
465
+ throw error;
466
+ }
467
+ throw new PromptbookSyntaxError(spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
468
+ }
469
+ return variables;
470
+ }
427
471
 
428
472
  /**
429
473
  * Execution type describes the way how the block is executed
@@ -461,6 +505,8 @@ function removeMarkdownFormatting(str) {
461
505
  *
462
506
  * Unlike Number.parseInt, Number.parseFloat it will never ever result in NaN
463
507
  * Note: it also works only with decimal numbers
508
+ *
509
+ * @private within the parseCommand
464
510
  */
465
511
  function parseNumber(value) {
466
512
  var originalValue = value;
@@ -494,7 +540,7 @@ function parseNumber(value) {
494
540
  var numerator = parseNumber(numerator_);
495
541
  var denominator = parseNumber(denominator_);
496
542
  if (denominator === 0) {
497
- throw new Error("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
543
+ throw new PromptbookSyntaxError("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
498
544
  }
499
545
  return numerator / denominator;
500
546
  }
@@ -506,11 +552,11 @@ function parseNumber(value) {
506
552
  return parseNumber(significand) * Math.pow(10, parseNumber(exponent));
507
553
  }
508
554
  if (!/^[0-9.]+$/.test(value) || value.split('.').length > 2) {
509
- throw new Error("Unable to parse number from \"".concat(originalValue, "\""));
555
+ throw new PromptbookSyntaxError("Unable to parse number from \"".concat(originalValue, "\""));
510
556
  }
511
557
  var num = parseFloat(value);
512
558
  if (isNaN(num)) {
513
- throw new Error("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
559
+ throw new PromptbookSyntaxError("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
514
560
  }
515
561
  return num;
516
562
  }
@@ -520,11 +566,13 @@ function parseNumber(value) {
520
566
 
521
567
  /**
522
568
  * Parses one line of ul/ol to command
569
+ *
570
+ * @private within the promptbookStringToJson
523
571
  */
524
572
  function parseCommand(listItem) {
525
573
  var e_1, _a;
526
574
  if (listItem.includes('\n') || listItem.includes('\r')) {
527
- throw new Error('Command can not contain new line characters:');
575
+ throw new PromptbookSyntaxError('Command can not contain new line characters:');
528
576
  }
529
577
  var type = listItem.trim();
530
578
  type = type.split('`').join('');
@@ -551,15 +599,15 @@ function parseCommand(listItem) {
551
599
  type.startsWith('PROMPTBOOKURL') ||
552
600
  type.startsWith('HTTPS')) {
553
601
  if (!(listItemParts.length === 2 || (listItemParts.length === 1 && type.startsWith('HTTPS')))) {
554
- throw new Error(spaceTrim("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n ")));
602
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n ")));
555
603
  }
556
604
  var promptbookUrlString = listItemParts.pop();
557
605
  var promptbookUrl = new URL(promptbookUrlString);
558
606
  if (promptbookUrl.protocol !== 'https:') {
559
- throw new Error(spaceTrim("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n Protocol must be HTTPS\n ")));
607
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n Protocol must be HTTPS\n ")));
560
608
  }
561
609
  if (promptbookUrl.hash !== '') {
562
- throw new Error(spaceTrim("\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 ")));
610
+ throw new PromptbookSyntaxError(spaceTrim("\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 ")));
563
611
  }
564
612
  return {
565
613
  type: 'PROMPTBOOK_URL',
@@ -568,7 +616,7 @@ function parseCommand(listItem) {
568
616
  }
569
617
  else if (type.startsWith('PROMPTBOOK_VERSION') || type.startsWith('PTBK_VERSION')) {
570
618
  if (listItemParts.length !== 2) {
571
- throw new Error(spaceTrim("\n Invalid PROMPTBOOK_VERSION command:\n\n - ".concat(listItem, "\n ")));
619
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid PROMPTBOOK_VERSION command:\n\n - ".concat(listItem, "\n ")));
572
620
  }
573
621
  var promptbookVersion = listItemParts.pop();
574
622
  // TODO: Validate version
@@ -583,7 +631,7 @@ function parseCommand(listItem) {
583
631
  type.startsWith('SIMPLE_TEMPLATE')) {
584
632
  var executionTypes = ExecutionTypes.filter(function (executionType) { return type.includes(executionType); });
585
633
  if (executionTypes.length !== 1) {
586
- throw new Error(spaceTrim(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 "); }));
634
+ throw new PromptbookSyntaxError(spaceTrim(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 "); }));
587
635
  }
588
636
  return {
589
637
  type: 'EXECUTE',
@@ -608,7 +656,7 @@ function parseCommand(listItem) {
608
656
  };
609
657
  }
610
658
  else {
611
- throw new Error(spaceTrim(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 "); }));
659
+ throw new PromptbookSyntaxError(spaceTrim(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 "); }));
612
660
  }
613
661
  }
614
662
  if (type.startsWith('MODEL_NAME')) {
@@ -619,7 +667,7 @@ function parseCommand(listItem) {
619
667
  };
620
668
  }
621
669
  else {
622
- throw new Error(spaceTrim(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 "); }));
670
+ throw new PromptbookSyntaxError(spaceTrim(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 "); }));
623
671
  }
624
672
  }
625
673
  else if (type.startsWith('PARAM') ||
@@ -629,12 +677,12 @@ function parseCommand(listItem) {
629
677
  listItem.startsWith('> {') /* <- Note: This is a bit hack to parse return parameters defined at the end of each section */) {
630
678
  var parametersMatch = listItem.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
631
679
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
632
- throw new Error(spaceTrim("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
680
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
633
681
  }
634
682
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
635
683
  var _b = parametersMatch.groups, parameterName = _b.parameterName, parameterDescription = _b.parameterDescription;
636
684
  if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
637
- throw new Error(spaceTrim("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
685
+ throw new PromptbookSyntaxError(spaceTrim("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
638
686
  }
639
687
  var isInput = type.startsWith('INPUT');
640
688
  var isOutput = type.startsWith('OUTPUT');
@@ -648,11 +696,11 @@ function parseCommand(listItem) {
648
696
  }
649
697
  else if (type.startsWith('JOKER')) {
650
698
  if (listItemParts.length !== 2) {
651
- throw new Error(spaceTrim("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
699
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
652
700
  }
653
701
  var parametersMatch = (listItemParts.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
654
702
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
655
- throw new Error(spaceTrim("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
703
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
656
704
  }
657
705
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
658
706
  var parameterName = parametersMatch.groups.parameterName;
@@ -663,7 +711,7 @@ function parseCommand(listItem) {
663
711
  }
664
712
  else if (type.startsWith('POSTPROCESS') || type.startsWith('POST_PROCESS')) {
665
713
  if (listItemParts.length !== 2) {
666
- throw new Error(spaceTrim("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
714
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
667
715
  }
668
716
  var functionName = listItemParts.pop();
669
717
  return {
@@ -693,15 +741,15 @@ function parseCommand(listItem) {
693
741
  sign = 'MAXIMUM';
694
742
  }
695
743
  else {
696
- throw new Error("Invalid sign \"".concat(signRaw, "\""));
744
+ throw new PromptbookSyntaxError("Invalid sign \"".concat(signRaw, "\""));
697
745
  }
698
746
  var amountRaw = listItemParts.shift();
699
747
  var amount = parseNumber(amountRaw);
700
748
  if (amount < 0) {
701
- throw new Error('Amount must be positive number or zero');
749
+ throw new PromptbookSyntaxError('Amount must be positive number or zero');
702
750
  }
703
751
  if (amount !== Math.floor(amount)) {
704
- throw new Error('Amount must be whole number');
752
+ throw new PromptbookSyntaxError('Amount must be whole number');
705
753
  }
706
754
  var unitRaw = listItemParts.shift();
707
755
  var unit = undefined;
@@ -716,7 +764,7 @@ function parseCommand(listItem) {
716
764
  if (new RegExp("^".concat(existingUnitText.toLowerCase())).test(unitRaw.toLowerCase()) ||
717
765
  new RegExp("^".concat(unitRaw.toLowerCase())).test(existingUnitText.toLowerCase())) {
718
766
  if (unit !== undefined) {
719
- throw new Error("Ambiguous unit \"".concat(unitRaw, "\""));
767
+ throw new PromptbookSyntaxError("Ambiguous unit \"".concat(unitRaw, "\""));
720
768
  }
721
769
  unit = existingUnit;
722
770
  }
@@ -730,7 +778,7 @@ function parseCommand(listItem) {
730
778
  finally { if (e_1) throw e_1.error; }
731
779
  }
732
780
  if (unit === undefined) {
733
- throw new Error("Invalid unit \"".concat(unitRaw, "\""));
781
+ throw new PromptbookSyntaxError("Invalid unit \"".concat(unitRaw, "\""));
734
782
  }
735
783
  return {
736
784
  type: 'EXPECT_AMOUNT',
@@ -743,11 +791,11 @@ function parseCommand(listItem) {
743
791
  if (!(error instanceof Error)) {
744
792
  throw error;
745
793
  }
746
- throw new Error(spaceTrim("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
794
+ throw new PromptbookSyntaxError(spaceTrim("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
747
795
  }
748
796
  }
749
797
  else {
750
- throw new Error(spaceTrim("\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 ")));
798
+ throw new PromptbookSyntaxError(spaceTrim("\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 ")));
751
799
  }
752
800
  }
753
801
 
@@ -770,8 +818,8 @@ function promptbookStringToJson(promptbookString) {
770
818
  // =============================================================
771
819
  // Note: 1️⃣ Normalization of the PROMPTBOOK string
772
820
  promptbookString = removeContentComments(promptbookString);
773
- promptbookString = promptbookString.replaceAll(/`\{(?<paramName>[a-z0-9_]+)\}`/gi, '{$<paramName>}');
774
- promptbookString = promptbookString.replaceAll(/`->\s+\{(?<paramName>[a-z0-9_]+)\}`/gi, '-> {$<paramName>}');
821
+ promptbookString = promptbookString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
822
+ promptbookString = promptbookString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
775
823
  // =============================================================
776
824
  ///Note: 2️⃣ Function for adding parameters
777
825
  var addParam = function (parameterCommand) {
@@ -781,7 +829,7 @@ function promptbookStringToJson(promptbookString) {
781
829
  existingParameter.description &&
782
830
  existingParameter.description !== parameterDescription &&
783
831
  parameterDescription) {
784
- throw new Error(spaceTrim(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 "); }));
832
+ throw new PromptbookSyntaxError(spaceTrim(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 "); }));
785
833
  }
786
834
  if (existingParameter) {
787
835
  if (parameterDescription) {
@@ -802,7 +850,7 @@ function promptbookStringToJson(promptbookString) {
802
850
  var markdownStructure = markdownToMarkdownStructure(promptbookString);
803
851
  var markdownStructureDeepness = countMarkdownStructureDeepness(markdownStructure);
804
852
  if (markdownStructureDeepness !== 2) {
805
- throw new Error(spaceTrim("\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 ")));
853
+ throw new PromptbookSyntaxError(spaceTrim("\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 ")));
806
854
  }
807
855
  promptbookJson.title = markdownStructure.title;
808
856
  // TODO: [1] DRY description
@@ -836,7 +884,7 @@ function promptbookStringToJson(promptbookString) {
836
884
  addParam(command);
837
885
  break;
838
886
  default:
839
- throw new Error("Command ".concat(command.type, " is not allowed in the head of the promptbook ONLY at the prompt template block"));
887
+ throw new PromptbookSyntaxError("Command ".concat(command.type, " is not allowed in the head of the promptbook ONLY at the prompt template block"));
840
888
  }
841
889
  }
842
890
  }
@@ -870,7 +918,7 @@ function promptbookStringToJson(promptbookString) {
870
918
  break;
871
919
  case 'EXECUTE':
872
920
  if (isExecutionTypeChanged) {
873
- throw new Error('Execution type is already defined in the prompt template. It can be defined only once.');
921
+ throw new PromptbookSyntaxError('Execution type is already defined in the prompt template. It can be defined only once.');
874
922
  }
875
923
  executionType = command.executionType;
876
924
  isExecutionTypeChanged = true;
@@ -891,25 +939,25 @@ function promptbookStringToJson(promptbookString) {
891
939
  expectAmount[unit] = expectAmount[unit] || {};
892
940
  if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
893
941
  if (expectAmount[unit].min !== undefined) {
894
- throw new Error("Already defined minumum ".concat(expectAmount[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
942
+ throw new PromptbookSyntaxError("Already defined minumum ".concat(expectAmount[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
895
943
  }
896
944
  expectAmount[unit].min = command.amount;
897
945
  } /* not else */
898
946
  if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
899
947
  if (expectAmount[unit].max !== undefined) {
900
- throw new Error("Already defined maximum ".concat(expectAmount[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
948
+ throw new PromptbookSyntaxError("Already defined maximum ".concat(expectAmount[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
901
949
  }
902
950
  expectAmount[unit].max = command.amount;
903
951
  }
904
952
  break;
905
953
  case 'EXPECT_FORMAT':
906
954
  if (expectFormat !== undefined && command.format !== expectFormat) {
907
- throw new Error("Expect format is already defined to \"".concat(expectFormat, "\". Now you try to redefine it by \"").concat(command.format, "\"."));
955
+ throw new PromptbookSyntaxError("Expect format is already defined to \"".concat(expectFormat, "\". Now you try to redefine it by \"").concat(command.format, "\"."));
908
956
  }
909
957
  expectFormat = command.format;
910
958
  break;
911
959
  default:
912
- throw new Error("Command ".concat(command.type, " is not allowed in the block of the prompt template ONLY at the head of the promptbook"));
960
+ throw new PromptbookSyntaxError("Command ".concat(command.type, " is not allowed in the block of the prompt template ONLY at the head of the promptbook"));
913
961
  }
914
962
  }
915
963
  }
@@ -923,16 +971,16 @@ function promptbookStringToJson(promptbookString) {
923
971
  var _h = extractOneBlockFromMarkdown(section.content), language = _h.language, content = _h.content;
924
972
  if (executionType === 'SCRIPT') {
925
973
  if (!language) {
926
- throw new Error('You must specify the language of the script in the prompt template');
974
+ throw new PromptbookSyntaxError('You must specify the language of the script in the prompt template');
927
975
  }
928
976
  else if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
929
- throw new Error(spaceTrim(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 "); }));
977
+ throw new PromptbookSyntaxError(spaceTrim(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 "); }));
930
978
  }
931
979
  }
932
980
  var lastLine = section.content.split('\n').pop();
933
981
  var match = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im.exec(lastLine);
934
982
  if (!match || match.groups === undefined || match.groups.resultingParamName === undefined) {
935
- throw new Error(spaceTrim(function (block) { return "\n Invalid template - each section must end with \"-> {...}\"\n\n Invalid section:\n ".concat(block(
983
+ throw new PromptbookSyntaxError(spaceTrim(function (block) { return "\n Invalid template - each section must end with \"-> {...}\"\n\n Invalid section:\n ".concat(block(
936
984
  // TODO: Show code of invalid sections each time + DRY
937
985
  section.content
938
986
  .split('\n')
@@ -1026,6 +1074,20 @@ function promptbookStringToJson(promptbookString) {
1026
1074
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
1027
1075
  */
1028
1076
 
1077
+ /**
1078
+ * This error indicates that the promptbook object has valid syntax but contains logical errors (like circular dependencies)
1079
+ */
1080
+ var PromptbookLogicError = /** @class */ (function (_super) {
1081
+ __extends(PromptbookLogicError, _super);
1082
+ function PromptbookLogicError(message) {
1083
+ var _this = _super.call(this, message) || this;
1084
+ _this.name = 'PromptbookLogicError';
1085
+ Object.setPrototypeOf(_this, PromptbookLogicError.prototype);
1086
+ return _this;
1087
+ }
1088
+ return PromptbookLogicError;
1089
+ }(Error));
1090
+
1029
1091
  /**
1030
1092
  * Tests if given string is valid URL.
1031
1093
  *
@@ -1068,7 +1130,8 @@ function validatePromptbookJson(promptbook) {
1068
1130
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
1069
1131
  if (promptbook.promptbookUrl !== undefined) {
1070
1132
  if (!isValidUrl(promptbook.promptbookUrl)) {
1071
- throw new Error("Invalid promptbook URL \"".concat(promptbook.promptbookUrl, "\""));
1133
+ // TODO: This should be maybe the syntax error detected during parsing
1134
+ throw new PromptbookLogicError("Invalid promptbook URL \"".concat(promptbook.promptbookUrl, "\""));
1072
1135
  }
1073
1136
  }
1074
1137
  var definedParameters = new Set(promptbook.parameters.filter(function (_a) {
@@ -1080,18 +1143,18 @@ function validatePromptbookJson(promptbook) {
1080
1143
  }));
1081
1144
  var _loop_1 = function (parameter) {
1082
1145
  if (parameter.isInput && parameter.isOutput) {
1083
- throw new Error("Parameter {".concat(parameter.name, "} can not be both input and output"));
1146
+ throw new PromptbookLogicError("Parameter {".concat(parameter.name, "} can not be both input and output"));
1084
1147
  }
1085
1148
  // Note: Testing that parameter is either intermediate or output BUT not created and unused
1086
1149
  if (!parameter.isInput &&
1087
1150
  !parameter.isOutput &&
1088
1151
  !promptbook.promptTemplates.some(function (template) { return template.dependentParameterNames.includes(parameter.name); })) {
1089
- throw new Error(spaceTrim("\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 ")));
1152
+ throw new PromptbookLogicError(spaceTrim("\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 ")));
1090
1153
  }
1091
1154
  // Note: Testing that parameter is either input or result of some template
1092
1155
  if (!parameter.isInput &&
1093
1156
  !promptbook.promptTemplates.some(function (template) { return template.resultingParameterName === parameter.name; })) {
1094
- throw new Error(spaceTrim("\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 ")));
1157
+ throw new PromptbookLogicError(spaceTrim("\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 ")));
1095
1158
  }
1096
1159
  };
1097
1160
  try {
@@ -1113,23 +1176,23 @@ function validatePromptbookJson(promptbook) {
1113
1176
  for (var _g = __values(promptbook.promptTemplates), _h = _g.next(); !_h.done; _h = _g.next()) {
1114
1177
  var template = _h.value;
1115
1178
  if (definedParameters.has(template.resultingParameterName)) {
1116
- throw new Error("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
1179
+ throw new PromptbookLogicError("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
1117
1180
  }
1118
1181
  if (template.executionType === 'PROMPT_TEMPLATE' &&
1119
1182
  (template.modelRequirements.modelVariant === undefined ||
1120
1183
  template.modelRequirements.modelName === undefined)) {
1121
- throw new Error(spaceTrim("\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 ")));
1184
+ throw new PromptbookLogicError(spaceTrim("\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 ")));
1122
1185
  }
1123
1186
  if (template.jokers && template.jokers.length > 0) {
1124
1187
  if (!template.expectFormat &&
1125
1188
  !template.expectAmount /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
1126
- throw new Error("Joker parameters are used but no expectations are defined");
1189
+ throw new PromptbookLogicError("Joker parameters are used but no expectations are defined");
1127
1190
  }
1128
1191
  try {
1129
1192
  for (var _j = (e_3 = void 0, __values(template.jokers)), _k = _j.next(); !_k.done; _k = _j.next()) {
1130
1193
  var joker = _k.value;
1131
1194
  if (!template.dependentParameterNames.includes(joker)) {
1132
- throw new Error("Parameter {".concat(joker, "} is used as joker but not in dependentParameterNames"));
1195
+ throw new PromptbookLogicError("Parameter {".concat(joker, "} is used as joker but not in dependentParameterNames"));
1133
1196
  }
1134
1197
  }
1135
1198
  }
@@ -1146,13 +1209,13 @@ function validatePromptbookJson(promptbook) {
1146
1209
  for (var _l = (e_4 = void 0, __values(Object.entries(template.expectAmount))), _m = _l.next(); !_m.done; _m = _l.next()) {
1147
1210
  var _o = __read(_m.value, 2), unit = _o[0], _p = _o[1], min = _p.min, max = _p.max;
1148
1211
  if (min !== undefined && max !== undefined && min > max) {
1149
- throw new Error("Min expectation (=".concat(min, ") of ").concat(unit, " is higher than max expectation (=").concat(max, ")"));
1212
+ throw new PromptbookLogicError("Min expectation (=".concat(min, ") of ").concat(unit, " is higher than max expectation (=").concat(max, ")"));
1150
1213
  }
1151
1214
  if (min !== undefined && min < 0) {
1152
- throw new Error("Min expectation of ".concat(unit, " must be zero or positive"));
1215
+ throw new PromptbookLogicError("Min expectation of ".concat(unit, " must be zero or positive"));
1153
1216
  }
1154
1217
  if (max !== undefined && max <= 0) {
1155
- throw new Error("Max expectation of ".concat(unit, " must be positive"));
1218
+ throw new PromptbookLogicError("Max expectation of ".concat(unit, " must be positive"));
1156
1219
  }
1157
1220
  }
1158
1221
  }
@@ -1185,12 +1248,16 @@ function validatePromptbookJson(promptbook) {
1185
1248
  return name;
1186
1249
  });
1187
1250
  var unresovedTemplates = __spreadArray([], __read(promptbook.promptTemplates), false);
1251
+ var loopLimit = LOOP_LIMIT;
1188
1252
  var _loop_2 = function () {
1253
+ if (loopLimit-- < 0) {
1254
+ throw new UnexpectedError('Loop limit reached during detection of circular dependencies in `validatePromptbookJson`');
1255
+ }
1189
1256
  var currentlyResovedTemplates = unresovedTemplates.filter(function (template) {
1190
1257
  return template.dependentParameterNames.every(function (name) { return resovedParameters.includes(name); });
1191
1258
  });
1192
1259
  if (currentlyResovedTemplates.length === 0) {
1193
- throw new Error(spaceTrim(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
1260
+ throw new PromptbookLogicError(spaceTrim(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
1194
1261
  .map(function (_a) {
1195
1262
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
1196
1263
  return "- {".concat(resultingParameterName, "} depends on ").concat(dependentParameterNames
@@ -1221,6 +1288,36 @@ function validatePromptbookJson(promptbook) {
1221
1288
  * > ex port function validatePromptbookJson(promptbook: unknown): asserts promptbook is PromptbookJson {
1222
1289
  */
1223
1290
 
1291
+ /**
1292
+ * This error occurs when some expectation is not met in the execution of the pipeline
1293
+ *
1294
+ * Note: This is a kindof subtype of PromptbookExecutionError
1295
+ */
1296
+ var ExpectError = /** @class */ (function (_super) {
1297
+ __extends(ExpectError, _super);
1298
+ function ExpectError(message) {
1299
+ var _this = _super.call(this, message) || this;
1300
+ _this.name = 'ExpectError';
1301
+ Object.setPrototypeOf(_this, ExpectError.prototype);
1302
+ return _this;
1303
+ }
1304
+ return ExpectError;
1305
+ }(Error));
1306
+
1307
+ /**
1308
+ * This error indicates errors during the execution of the promptbook
1309
+ */
1310
+ var PromptbookExecutionError = /** @class */ (function (_super) {
1311
+ __extends(PromptbookExecutionError, _super);
1312
+ function PromptbookExecutionError(message) {
1313
+ var _this = _super.call(this, message) || this;
1314
+ _this.name = 'PromptbookExecutionError';
1315
+ Object.setPrototypeOf(_this, PromptbookExecutionError.prototype);
1316
+ return _this;
1317
+ }
1318
+ return PromptbookExecutionError;
1319
+ }(Error));
1320
+
1224
1321
  /**
1225
1322
  * Counts number of characters in the text
1226
1323
  */
@@ -1315,62 +1412,54 @@ function isValidJsonString(value) {
1315
1412
  * @param parameters the object with parameters
1316
1413
  * @returns the template with replaced parameters
1317
1414
  *
1318
- * @private within the library
1415
+ * @private within the createPromptbookExecutor
1319
1416
  */
1320
1417
  function replaceParameters(template, parameters) {
1321
- var e_1, _a;
1322
- var placeholders = template.match(/{\w+}/g);
1323
1418
  var replacedTemplate = template;
1324
- if (placeholders) {
1325
- try {
1326
- for (var placeholders_1 = __values(placeholders), placeholders_1_1 = placeholders_1.next(); !placeholders_1_1.done; placeholders_1_1 = placeholders_1.next()) {
1327
- var placeholder = placeholders_1_1.value;
1328
- var paramName = placeholder.slice(1, -1); // Remove the curly braces to get the parameter name
1329
- if (paramName === '') {
1330
- continue; // Skip empty placeholders. It's used to avoid confusion with JSON-like strings
1331
- }
1332
- if (paramName.indexOf('{') !== -1 || paramName.indexOf('}') !== -1) {
1333
- throw new Error('Parameter is already opened or not closed');
1334
- }
1335
- if (parameters[paramName] === undefined) {
1336
- throw new Error("Parameter {".concat(paramName, "} is not defined"));
1337
- }
1338
- replacedTemplate = replacedTemplate.replace(new RegExp(placeholder, 'g'), parameters[paramName]);
1339
- }
1340
- }
1341
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1342
- finally {
1343
- try {
1344
- if (placeholders_1_1 && !placeholders_1_1.done && (_a = placeholders_1.return)) _a.call(placeholders_1);
1345
- }
1346
- finally { if (e_1) throw e_1.error; }
1419
+ var match;
1420
+ var loopLimit = LOOP_LIMIT;
1421
+ var _loop_1 = function () {
1422
+ if (loopLimit-- < 0) {
1423
+ throw new UnexpectedError('Loop limit reached during parameters replacement in `replaceParameters`');
1424
+ }
1425
+ var precol = match.groups.precol;
1426
+ var parameterName = match.groups.parameterName;
1427
+ if (parameterName === '') {
1428
+ return "continue";
1429
+ }
1430
+ if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
1431
+ throw new PromptbookExecutionError('Parameter is already opened or not closed');
1432
+ }
1433
+ if (parameters[parameterName] === undefined) {
1434
+ throw new PromptbookExecutionError("Parameter {".concat(parameterName, "} is not defined"));
1435
+ }
1436
+ var parameterValue = parameters[parameterName];
1437
+ if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
1438
+ parameterValue = parameterValue
1439
+ .split('\n')
1440
+ .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
1441
+ .join('\n');
1347
1442
  }
1443
+ replacedTemplate =
1444
+ replacedTemplate.substring(0, match.index + precol.length) +
1445
+ parameterValue +
1446
+ replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
1447
+ };
1448
+ while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
1449
+ .exec(replacedTemplate))) {
1450
+ _loop_1();
1348
1451
  }
1349
1452
  // [💫] Check if there are parameters that are not closed properly
1350
1453
  if (/{\w+$/.test(replacedTemplate)) {
1351
- throw new Error('Parameter is not closed');
1454
+ throw new PromptbookExecutionError('Parameter is not closed');
1352
1455
  }
1353
1456
  // [💫] Check if there are parameters that are not opened properly
1354
1457
  if (/^\w+}/.test(replacedTemplate)) {
1355
- throw new Error('Parameter is not opened');
1458
+ throw new PromptbookExecutionError('Parameter is not opened');
1356
1459
  }
1357
1460
  return replacedTemplate;
1358
1461
  }
1359
1462
 
1360
- /**
1361
- * This error occurs when some expectation is not met in the execution of the pipeline
1362
- */
1363
- var ExpectError = /** @class */ (function (_super) {
1364
- __extends(ExpectError, _super);
1365
- function ExpectError(message) {
1366
- var _this = _super.call(this, message) || this;
1367
- _this.name = 'ExpectError';
1368
- Object.setPrototypeOf(_this, ExpectError.prototype);
1369
- return _this;
1370
- }
1371
- return ExpectError;
1372
- }(Error));
1373
-
1374
1463
  /**
1375
1464
  * Creates executor function from promptbook and execution tools.
1376
1465
  *
@@ -1419,15 +1508,14 @@ function createPromptbookExecutor(options) {
1419
1508
  isJokerAttempt = attempt < 0;
1420
1509
  joker = jokers[jokers.length + attempt];
1421
1510
  if (isJokerAttempt && !joker) {
1422
- throw new Error("Joker not found in attempt ".concat(attempt));
1423
- // <- TODO: [🥨] Make some NeverShouldHappenError
1511
+ throw new UnexpectedError("Joker not found in attempt ".concat(attempt));
1424
1512
  }
1425
1513
  result = null;
1426
1514
  resultString = null;
1427
1515
  expectError = null;
1428
1516
  if (isJokerAttempt) {
1429
1517
  if (typeof parametersToPass[joker] === 'undefined') {
1430
- throw new Error("Joker parameter {".concat(joker, "} not defined"));
1518
+ throw new PromptbookExecutionError("Joker parameter {".concat(joker, "} not defined"));
1431
1519
  }
1432
1520
  resultString = parametersToPass[joker];
1433
1521
  }
@@ -1475,14 +1563,14 @@ function createPromptbookExecutor(options) {
1475
1563
  result = completionResult;
1476
1564
  resultString = completionResult.content;
1477
1565
  return [3 /*break*/, 12];
1478
- case 11: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1566
+ case 11: throw new PromptbookExecutionError("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1479
1567
  case 12: return [3 /*break*/, 27];
1480
1568
  case 13:
1481
1569
  if (tools.script.length === 0) {
1482
- throw new Error('No script execution tools are available');
1570
+ throw new PromptbookExecutionError('No script execution tools are available');
1483
1571
  }
1484
1572
  if (!currentTemplate.contentLanguage) {
1485
- throw new Error("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1573
+ throw new PromptbookExecutionError("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1486
1574
  }
1487
1575
  // TODO: DRY [1]
1488
1576
  scriptExecutionErrors = [];
@@ -1534,7 +1622,7 @@ function createPromptbookExecutor(options) {
1534
1622
  throw scriptExecutionErrors[0];
1535
1623
  }
1536
1624
  else {
1537
- throw new Error(spaceTrim(function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors
1625
+ throw new PromptbookExecutionError(spaceTrim(function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors
1538
1626
  .map(function (error) { return '- ' + error.message; })
1539
1627
  .join('\n\n')), "\n "); }));
1540
1628
  }
@@ -1550,7 +1638,7 @@ function createPromptbookExecutor(options) {
1550
1638
  // TODO: [🌹] When making next attempt for `PROMPT DIALOG`, preserve the previous user input
1551
1639
  resultString = _t.sent();
1552
1640
  return [3 /*break*/, 27];
1553
- case 26: throw new Error(
1641
+ case 26: throw new PromptbookExecutionError(
1554
1642
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1555
1643
  "Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1556
1644
  case 27:
@@ -1686,7 +1774,7 @@ function createPromptbookExecutor(options) {
1686
1774
  return [7 /*endfinally*/];
1687
1775
  case 47:
1688
1776
  if (expectError !== null && attempt === maxAttempts - 1) {
1689
- 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 "); }));
1777
+ throw new PromptbookExecutionError(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 "); }));
1690
1778
  }
1691
1779
  _t.label = 48;
1692
1780
  case 48:
@@ -1694,8 +1782,7 @@ function createPromptbookExecutor(options) {
1694
1782
  return [3 /*break*/, 3];
1695
1783
  case 49:
1696
1784
  if (resultString === null) {
1697
- // <- TODO: [🥨] Make some NeverShouldHappenError
1698
- throw new Error('Something went wrong and prompt result is null');
1785
+ throw new UnexpectedError('Something went wrong and prompt result is null');
1699
1786
  }
1700
1787
  if (onProgress /* <- [3] */) {
1701
1788
  onProgress({
@@ -1715,7 +1802,7 @@ function createPromptbookExecutor(options) {
1715
1802
  });
1716
1803
  });
1717
1804
  }
1718
- var parametersToPass, executionReport, resovedParameters_1, unresovedTemplates, resolving_1, _loop_1, error_1, _a, _b, parameter;
1805
+ var parametersToPass, executionReport, resovedParameters_1, unresovedTemplates, resolving_1, loopLimit, _loop_1, error_1, _a, _b, parameter;
1719
1806
  var e_1, _c;
1720
1807
  return __generator(this, function (_d) {
1721
1808
  switch (_d.label) {
@@ -1743,16 +1830,20 @@ function createPromptbookExecutor(options) {
1743
1830
  });
1744
1831
  unresovedTemplates = __spreadArray([], __read(promptbook.promptTemplates), false);
1745
1832
  resolving_1 = [];
1833
+ loopLimit = LOOP_LIMIT;
1746
1834
  _loop_1 = function () {
1747
1835
  var currentTemplate, work_1;
1748
1836
  return __generator(this, function (_e) {
1749
1837
  switch (_e.label) {
1750
1838
  case 0:
1839
+ if (loopLimit-- < 0) {
1840
+ throw new UnexpectedError('Loop limit reached during resolving parameters promptbook execution');
1841
+ }
1751
1842
  currentTemplate = unresovedTemplates.find(function (template) {
1752
1843
  return template.dependentParameterNames.every(function (name) { return resovedParameters_1.includes(name); });
1753
1844
  });
1754
1845
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
1755
- throw new Error("Can not resolve some parameters");
1846
+ throw new UnexpectedError(spaceTrim("\n Can not resolve some parameters\n\n Note: This should be catched during validatePromptbookJson\n "));
1756
1847
  case 1:
1757
1848
  if (!!currentTemplate) return [3 /*break*/, 3];
1758
1849
  /* [5] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -1959,12 +2050,12 @@ var SimplePromptInterfaceTools = /** @class */ (function () {
1959
2050
  return __awaiter(this, void 0, void 0, function () {
1960
2051
  var answer;
1961
2052
  return __generator(this, function (_a) {
1962
- answer = window.prompt(spaceTrim(function (block) { return "\n ".concat(block(options.promptTitle), "\n \n ").concat(block(options.promptMessage), "\n "); }));
2053
+ answer = window.prompt(spaceTrim(function (block) { return "\n ".concat(block(options.promptTitle), "\n\n ").concat(block(options.promptMessage), "\n "); }));
1963
2054
  if (this.options.isVerbose) {
1964
2055
  console.info(spaceTrim(function (block) { return "\n \uD83D\uDCD6 ".concat(block(options.promptTitle), "\n \uD83D\uDC64 ").concat(block(answer || '🚫 User cancelled prompt'), "\n "); }));
1965
2056
  }
1966
2057
  if (answer === null) {
1967
- throw new Error('User cancelled prompt');
2058
+ throw new PromptbookExecutionError('User cancelled prompt');
1968
2059
  }
1969
2060
  return [2 /*return*/, answer];
1970
2061
  });
@@ -1974,7 +2065,7 @@ var SimplePromptInterfaceTools = /** @class */ (function () {
1974
2065
  }());
1975
2066
 
1976
2067
  /**
1977
- * This error !!!
2068
+ * This error indicates that the requested resource (for example promptbook in the library ) was not found
1978
2069
  */
1979
2070
  var NotFoundError = /** @class */ (function (_super) {
1980
2071
  __extends(NotFoundError, _super);
@@ -2011,8 +2102,8 @@ var SimplePromptbookLibrary = /** @class */ (function () {
2011
2102
  var e_1, _a;
2012
2103
  var library = {};
2013
2104
  try {
2014
- for (var _b = __values(Object.entries(promptbookSources)), _c = _b.next(); !_c.done; _c = _b.next()) {
2015
- var _d = __read(_c.value, 2), name_1 = _d[0], source = _d[1];
2105
+ for (var promptbookSources_1 = __values(promptbookSources), promptbookSources_1_1 = promptbookSources_1.next(); !promptbookSources_1_1.done; promptbookSources_1_1 = promptbookSources_1.next()) {
2106
+ var source = promptbookSources_1_1.value;
2016
2107
  var promptbook = void 0;
2017
2108
  if (typeof source === 'string') {
2018
2109
  // Note: When directly creating from string, no need to validate the source
@@ -2024,7 +2115,7 @@ var SimplePromptbookLibrary = /** @class */ (function () {
2024
2115
  }
2025
2116
  validatePromptbookJson(promptbook);
2026
2117
  if (promptbook.promptbookUrl === undefined) {
2027
- throw new Error(spaceTrim("\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 ")));
2118
+ throw new Error(spaceTrim("\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 ")));
2028
2119
  }
2029
2120
  library[promptbook.promptbookUrl] = promptbook;
2030
2121
  }
@@ -2032,7 +2123,7 @@ var SimplePromptbookLibrary = /** @class */ (function () {
2032
2123
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2033
2124
  finally {
2034
2125
  try {
2035
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2126
+ if (promptbookSources_1_1 && !promptbookSources_1_1.done && (_a = promptbookSources_1.return)) _a.call(promptbookSources_1);
2036
2127
  }
2037
2128
  finally { if (e_1) throw e_1.error; }
2038
2129
  }