@promptbook/utils 0.44.0-2 → 0.44.0-20

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 (28) hide show
  1. package/README.md +676 -2
  2. package/esm/index.es.js +510 -432
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/_packages/utils.index.d.ts +5 -3
  5. package/esm/typings/config.d.ts +4 -0
  6. package/esm/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.d.ts +9 -1
  7. package/esm/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.test.d.ts +1 -0
  8. package/esm/typings/execution/plugins/natural-execution-tools/mocked/faked-completion.test.d.ts +1 -0
  9. package/esm/typings/execution/plugins/script-execution-tools/javascript/JavascriptExecutionToolsOptions.d.ts +5 -1
  10. package/esm/typings/execution/plugins/script-execution-tools/javascript/utils/unknownToString.d.ts +7 -0
  11. package/esm/typings/execution/utils/checkExpectations.d.ts +25 -0
  12. package/esm/typings/execution/utils/checkExpectations.test.d.ts +1 -0
  13. package/esm/typings/types/Prompt.d.ts +5 -0
  14. package/esm/typings/types/PromptbookJson/PromptTemplateJson.d.ts +2 -0
  15. package/package.json +2 -2
  16. package/umd/index.umd.js +547 -468
  17. package/umd/index.umd.js.map +1 -1
  18. package/umd/typings/_packages/utils.index.d.ts +5 -3
  19. package/umd/typings/config.d.ts +4 -0
  20. package/umd/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.d.ts +9 -1
  21. package/umd/typings/execution/plugins/natural-execution-tools/mocked/fakeTextToExpectations.test.d.ts +1 -0
  22. package/umd/typings/execution/plugins/natural-execution-tools/mocked/faked-completion.test.d.ts +1 -0
  23. package/umd/typings/execution/plugins/script-execution-tools/javascript/JavascriptExecutionToolsOptions.d.ts +5 -1
  24. package/umd/typings/execution/plugins/script-execution-tools/javascript/utils/unknownToString.d.ts +7 -0
  25. package/umd/typings/execution/utils/checkExpectations.d.ts +25 -0
  26. package/umd/typings/execution/utils/checkExpectations.test.d.ts +1 -0
  27. package/umd/typings/types/Prompt.d.ts +5 -0
  28. package/umd/typings/types/PromptbookJson/PromptTemplateJson.d.ts +2 -0
package/umd/index.umd.js CHANGED
@@ -1,12 +1,11 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('prettier'), require('prettier/parser-html'), require('moment')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'prettier', 'prettier/parser-html', 'moment'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-utils"] = {}, global.spaceTrim, global.prettier, global.parserHtml, global.moment));
5
- })(this, (function (exports, spaceTrim, prettier, parserHtml, moment) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-utils"] = {}, global.spacetrim, global.prettier, global.parserHtml, global.moment));
5
+ })(this, (function (exports, spacetrim, prettier, parserHtml, moment) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
- var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
10
9
  var parserHtml__default = /*#__PURE__*/_interopDefaultLegacy(parserHtml);
11
10
  var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
12
11
 
@@ -176,7 +175,7 @@
176
175
  var UnexpectedError = /** @class */ (function (_super) {
177
176
  __extends(UnexpectedError, _super);
178
177
  function UnexpectedError(message) {
179
- 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;
178
+ var _this = _super.call(this, spacetrim.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;
180
179
  _this.name = 'UnexpectedError';
181
180
  Object.setPrototypeOf(_this, UnexpectedError.prototype);
182
181
  return _this;
@@ -229,7 +228,7 @@
229
228
  }
230
229
  if (parent_1.parent === null /* <- Note: We are in root */) {
231
230
  // [🌻]
232
- 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 "));
231
+ throw new Error(spacetrim.spaceTrim("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
233
232
  }
234
233
  parent_1 = parent_1.parent;
235
234
  }
@@ -263,7 +262,7 @@
263
262
  return {
264
263
  level: level,
265
264
  title: title,
266
- content: spaceTrim__default["default"](contentLines.join('\n')),
265
+ content: spacetrim.spaceTrim(contentLines.join('\n')),
267
266
  sections: sections.map(parsingMarkdownStructureToMarkdownStructure),
268
267
  };
269
268
  }
@@ -403,13 +402,13 @@
403
402
  * @returns {string} The input string with all comments removed.
404
403
  */
405
404
  function removeContentComments(content) {
406
- return spaceTrim__default["default"](content.replace(/<!--(.*?)-->/gs, ''));
405
+ return spacetrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
407
406
  }
408
407
 
409
408
  /**
410
409
  * The version of the Promptbook library
411
410
  */
412
- var PROMPTBOOK_VERSION = '0.44.0-1';
411
+ var PROMPTBOOK_VERSION = '0.44.0-19';
413
412
 
414
413
  /**
415
414
  * Parses the given script and returns the list of all used variables that are not defined in the script
@@ -454,7 +453,7 @@
454
453
  if (!(error instanceof Error)) {
455
454
  throw error;
456
455
  }
457
- 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 "); }));
456
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
458
457
  }
459
458
  return variables;
460
459
  }
@@ -477,6 +476,7 @@
477
476
  */
478
477
  var EXPECTATION_UNITS = ['CHARACTERS', 'WORDS', 'SENTENCES', 'PARAGRAPHS', 'LINES', 'PAGES'];
479
478
  /**
479
+ * TODO: [💝] Unite object for expecting amount and format - remove expectFormat
480
480
  * TODO: use one helper type> (string_prompt | string_javascript | string_markdown) & string_template
481
481
  */
482
482
 
@@ -601,15 +601,15 @@
601
601
  type.startsWith('PROMPTBOOKURL') ||
602
602
  type.startsWith('HTTPS')) {
603
603
  if (!(listItemParts.length === 2 || (listItemParts.length === 1 && type.startsWith('HTTPS')))) {
604
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n ")));
604
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n ")));
605
605
  }
606
606
  var promptbookUrlString = listItemParts.pop();
607
607
  var promptbookUrl = new URL(promptbookUrlString);
608
608
  if (promptbookUrl.protocol !== 'https:') {
609
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n Protocol must be HTTPS\n ")));
609
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid PROMPTBOOK_URL command:\n\n - ".concat(listItem, "\n\n Protocol must be HTTPS\n ")));
610
610
  }
611
611
  if (promptbookUrl.hash !== '') {
612
- 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 ")));
612
+ throw new PromptbookSyntaxError(spacetrim.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 ")));
613
613
  }
614
614
  return {
615
615
  type: 'PROMPTBOOK_URL',
@@ -618,7 +618,7 @@
618
618
  }
619
619
  else if (type.startsWith('PROMPTBOOK_VERSION') || type.startsWith('PTBK_VERSION')) {
620
620
  if (listItemParts.length !== 2) {
621
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid PROMPTBOOK_VERSION command:\n\n - ".concat(listItem, "\n ")));
621
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid PROMPTBOOK_VERSION command:\n\n - ".concat(listItem, "\n ")));
622
622
  }
623
623
  var promptbookVersion = listItemParts.pop();
624
624
  // TODO: Validate version
@@ -633,7 +633,7 @@
633
633
  type.startsWith('SIMPLE_TEMPLATE')) {
634
634
  var executionTypes = ExecutionTypes.filter(function (executionType) { return type.includes(executionType); });
635
635
  if (executionTypes.length !== 1) {
636
- 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 "); }));
636
+ throw new PromptbookSyntaxError(spacetrim.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 "); }));
637
637
  }
638
638
  return {
639
639
  type: 'EXECUTE',
@@ -658,7 +658,7 @@
658
658
  };
659
659
  }
660
660
  else {
661
- 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 "); }));
661
+ throw new PromptbookSyntaxError(spacetrim.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 "); }));
662
662
  }
663
663
  }
664
664
  if (type.startsWith('MODEL_NAME')) {
@@ -669,7 +669,7 @@
669
669
  };
670
670
  }
671
671
  else {
672
- 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 "); }));
672
+ throw new PromptbookSyntaxError(spacetrim.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 "); }));
673
673
  }
674
674
  }
675
675
  else if (type.startsWith('PARAM') ||
@@ -679,12 +679,12 @@
679
679
  listItem.startsWith('> {') /* <- Note: This is a bit hack to parse return parameters defined at the end of each section */) {
680
680
  var parametersMatch = listItem.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
681
681
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
682
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
682
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
683
683
  }
684
684
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
685
685
  var _b = parametersMatch.groups, parameterName = _b.parameterName, parameterDescription = _b.parameterDescription;
686
686
  if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
687
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
687
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Parameter {".concat(parameterName, "} can not contain another parameter in description:\n\n - ").concat(listItem, "\n ")));
688
688
  }
689
689
  var isInput = type.startsWith('INPUT');
690
690
  var isOutput = type.startsWith('OUTPUT');
@@ -702,11 +702,11 @@
702
702
  }
703
703
  else if (type.startsWith('JOKER')) {
704
704
  if (listItemParts.length !== 2) {
705
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
705
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
706
706
  }
707
707
  var parametersMatch = (listItemParts.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
708
708
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
709
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
709
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
710
710
  }
711
711
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
712
712
  var parameterName = parametersMatch.groups.parameterName;
@@ -717,7 +717,7 @@
717
717
  }
718
718
  else if (type.startsWith('POSTPROCESS') || type.startsWith('POST_PROCESS')) {
719
719
  if (listItemParts.length !== 2) {
720
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
720
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
721
721
  }
722
722
  var functionName = listItemParts.pop();
723
723
  return {
@@ -797,7 +797,7 @@
797
797
  if (!(error instanceof Error)) {
798
798
  throw error;
799
799
  }
800
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
800
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Invalid EXPECT command; ".concat(error.message, ":\n\n - ").concat(listItem, "\n ")));
801
801
  }
802
802
  /*
803
803
  } else if (type.startsWith('__________________')) {
@@ -805,7 +805,7 @@
805
805
  */
806
806
  }
807
807
  else {
808
- throw new PromptbookSyntaxError(spaceTrim__default["default"]("\n Unknown command:\n\n - ".concat(listItem, "\n\n Supported commands are:\n - PROMPTBOOK_URL <url>\n - PROMPTBOOK_VERSION <version>\n - EXECUTE PROMPT TEMPLATE\n - EXECUTE SIMPLE TEMPLATE\n - SIMPLE TEMPLATE\n - EXECUTE SCRIPT\n - EXECUTE PROMPT_DIALOG'\n - PROMPT_DIALOG'\n - MODEL NAME <name>\n - MODEL VARIANT <\"Chat\"|\"Completion\">\n - INPUT PARAM {<name>} <description>\n - OUTPUT PARAM {<name>} <description>\n - POSTPROCESS `{functionName}`\n - JOKER {<name>}\n - EXPECT JSON\n - EXPECT <\"Exactly\"|\"Min\"|\"Max\"> <number> <\"Chars\"|\"Words\"|\"Sentences\"|\"Paragraphs\"|\"Pages\">\n\n ")));
808
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim("\n Unknown command:\n\n - ".concat(listItem, "\n\n Supported commands are:\n - PROMPTBOOK_URL <url>\n - PROMPTBOOK_VERSION <version>\n - EXECUTE PROMPT TEMPLATE\n - EXECUTE SIMPLE TEMPLATE\n - SIMPLE TEMPLATE\n - EXECUTE SCRIPT\n - EXECUTE PROMPT_DIALOG'\n - PROMPT_DIALOG'\n - MODEL NAME <name>\n - MODEL VARIANT <\"Chat\"|\"Completion\">\n - INPUT PARAM {<name>} <description>\n - OUTPUT PARAM {<name>} <description>\n - POSTPROCESS `{functionName}`\n - JOKER {<name>}\n - EXPECT JSON\n - EXPECT <\"Exactly\"|\"Min\"|\"Max\"> <number> <\"Chars\"|\"Words\"|\"Sentences\"|\"Paragraphs\"|\"Pages\">\n\n ")));
809
809
  }
810
810
  }
811
811
 
@@ -841,7 +841,7 @@
841
841
  existingParameter.description &&
842
842
  existingParameter.description !== parameterDescription &&
843
843
  parameterDescription) {
844
- 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 "); }));
844
+ throw new PromptbookSyntaxError(spacetrim.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 "); }));
845
845
  }
846
846
  if (existingParameter) {
847
847
  if (parameterDescription) {
@@ -862,7 +862,7 @@
862
862
  var markdownStructure = markdownToMarkdownStructure(promptbookString);
863
863
  var markdownStructureDeepness = countMarkdownStructureDeepness(markdownStructure);
864
864
  if (markdownStructureDeepness !== 2) {
865
- 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 ")));
865
+ throw new PromptbookSyntaxError(spacetrim.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 ")));
866
866
  }
867
867
  promptbookJson.title = markdownStructure.title;
868
868
  // TODO: [1] DRY description
@@ -871,7 +871,7 @@
871
871
  description = description.split(/^```.*^```/gms).join('');
872
872
  //Note: Remove lists and return statement
873
873
  description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
874
- description = spaceTrim__default["default"](description);
874
+ description = spacetrim.spaceTrim(description);
875
875
  if (description === '') {
876
876
  description = undefined;
877
877
  }
@@ -986,13 +986,13 @@
986
986
  throw new PromptbookSyntaxError('You must specify the language of the script in the prompt template');
987
987
  }
988
988
  else if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
989
- 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 "); }));
989
+ throw new PromptbookSyntaxError(spacetrim.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 "); }));
990
990
  }
991
991
  }
992
992
  var lastLine = section.content.split('\n').pop();
993
993
  var match = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im.exec(lastLine);
994
994
  if (!match || match.groups === undefined || match.groups.resultingParamName === undefined) {
995
- throw new PromptbookSyntaxError(spaceTrim__default["default"](function (block) { return "\n Invalid template - each section must end with \"-> {...}\"\n\n Invalid section:\n ".concat(block(
995
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim(function (block) { return "\n Invalid template - each section must end with \"-> {...}\"\n\n Invalid section:\n ".concat(block(
996
996
  // TODO: Show code of invalid sections each time + DRY
997
997
  section.content
998
998
  .split('\n')
@@ -1006,7 +1006,7 @@
1006
1006
  description_1 = description_1.split(/^```.*^```/gms).join('');
1007
1007
  //Note: Remove lists and return statement
1008
1008
  description_1 = description_1.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
1009
- description_1 = spaceTrim__default["default"](description_1);
1009
+ description_1 = spacetrim.spaceTrim(description_1);
1010
1010
  if (description_1 === '') {
1011
1011
  description_1 = undefined;
1012
1012
  }
@@ -1097,7 +1097,7 @@
1097
1097
  var sectionRegex = new RegExp("<!--".concat(sectionName, "-->([\\s\\S]*?)<!--/").concat(sectionName, "-->"), 'g');
1098
1098
  var sectionMatch = content.match(sectionRegex);
1099
1099
  if (sectionMatch) {
1100
- return content.replace(sectionRegex, spaceTrim__default["default"](function (block) { return "\n <!--".concat(sectionName, "-->\n ").concat(block(warningLine), "\n ").concat(block(sectionContent), "\n <!--/").concat(sectionName, "-->\n "); }));
1100
+ return content.replace(sectionRegex, spacetrim.spaceTrim(function (block) { return "\n <!--".concat(sectionName, "-->\n ").concat(block(warningLine), "\n ").concat(block(sectionContent), "\n <!--/").concat(sectionName, "-->\n "); }));
1101
1101
  }
1102
1102
  var placeForSection = removeContentComments(content).match(/^##.*$/im);
1103
1103
  if (!placeForSection) {
@@ -1160,7 +1160,7 @@
1160
1160
  }
1161
1161
  return 'template' + normalizeTo_PascalCase(template.title);
1162
1162
  };
1163
- var promptbookMermaid_1 = spaceTrim__default["default"](function (block) { return "\n\n %% \uD83D\uDD2E Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually\n\n flowchart LR\n subgraph \"".concat(promptbookJson_1.title, "\"\n\n direction TB\n\n input((Input)):::input\n ").concat(block(promptbookJson_1.promptTemplates
1163
+ var promptbookMermaid_1 = spacetrim.spaceTrim(function (block) { return "\n\n %% \uD83D\uDD2E Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually\n\n flowchart LR\n subgraph \"".concat(promptbookJson_1.title, "\"\n\n direction TB\n\n input((Input)):::input\n ").concat(block(promptbookJson_1.promptTemplates
1164
1164
  .flatMap(function (_a) {
1165
1165
  var title = _a.title, dependentParameterNames = _a.dependentParameterNames, resultingParameterName = _a.resultingParameterName;
1166
1166
  return __spreadArray([
@@ -1179,7 +1179,7 @@
1179
1179
  return "".concat(parameterNameToTemplateName_1(name), "--\"{").concat(name, "}\"-->output");
1180
1180
  })
1181
1181
  .join('\n')), "\n output((Output)):::output\n\n classDef input color: grey;\n classDef output color: grey;\n\n end;\n\n\n\n "); });
1182
- var promptbookMermaidBlock = spaceTrim__default["default"](function (block) { return "\n ```mermaid\n ".concat(block(promptbookMermaid_1), "\n ```\n "); });
1182
+ var promptbookMermaidBlock = spacetrim.spaceTrim(function (block) { return "\n ```mermaid\n ".concat(block(promptbookMermaid_1), "\n ```\n "); });
1183
1183
  promptbookString = addAutoGeneratedSection(promptbookString, {
1184
1184
  sectionName: 'Graph',
1185
1185
  sectionContent: promptbookMermaidBlock,
@@ -1227,7 +1227,7 @@
1227
1227
  throw errors[0];
1228
1228
  }
1229
1229
  else {
1230
- throw new PromptbookExecutionError(spaceTrim__default["default"](function (block) { return "\n Multiple errors occurred during promptnook execution\n\n ".concat(block(errors.map(function (error) { return '- ' + error.message; }).join('\n')), "\n "); }));
1230
+ throw new PromptbookExecutionError(spacetrim.spaceTrim(function (block) { return "\n Multiple errors occurred during promptnook execution\n\n ".concat(block(errors.map(function (error) { return '- ' + error.message; }).join('\n')), "\n "); }));
1231
1231
  }
1232
1232
  }
1233
1233
  /**
@@ -1235,464 +1235,73 @@
1235
1235
  */
1236
1236
 
1237
1237
  /**
1238
- * This error occurs during the parameter replacement in the template
1238
+ * This error occurs when some expectation is not met in the execution of the pipeline
1239
1239
  *
1240
- * Note: This is a kindof subtype of PromptbookExecutionError because it occurs during the execution of the pipeline
1240
+ * @private Always catched and rethrown as `PromptbookExecutionError`
1241
+ * Note: This is a kindof subtype of PromptbookExecutionError
1241
1242
  */
1242
- var TemplateError = /** @class */ (function (_super) {
1243
- __extends(TemplateError, _super);
1244
- function TemplateError(message) {
1243
+ var ExpectError = /** @class */ (function (_super) {
1244
+ __extends(ExpectError, _super);
1245
+ function ExpectError(message) {
1245
1246
  var _this = _super.call(this, message) || this;
1246
- _this.name = 'TemplateError';
1247
- Object.setPrototypeOf(_this, TemplateError.prototype);
1247
+ _this.name = 'ExpectError';
1248
+ Object.setPrototypeOf(_this, ExpectError.prototype);
1248
1249
  return _this;
1249
1250
  }
1250
- return TemplateError;
1251
+ return ExpectError;
1251
1252
  }(Error));
1252
1253
 
1253
1254
  /**
1254
- * Replaces parameters in template with values from parameters object
1255
- *
1256
- * @param template the template with parameters in {curly} braces
1257
- * @param parameters the object with parameters
1258
- * @returns the template with replaced parameters
1259
- * @throws {TemplateError} if parameter is not defined, not closed, or not opened
1260
- *
1261
- * @private within the createPromptbookExecutor
1262
- */
1263
- function replaceParameters(template, parameters) {
1264
- var replacedTemplate = template;
1265
- var match;
1266
- var loopLimit = LOOP_LIMIT;
1267
- var _loop_1 = function () {
1268
- if (loopLimit-- < 0) {
1269
- throw new UnexpectedError('Loop limit reached during parameters replacement in `replaceParameters`');
1270
- }
1271
- var precol = match.groups.precol;
1272
- var parameterName = match.groups.parameterName;
1273
- if (parameterName === '') {
1274
- return "continue";
1275
- }
1276
- if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
1277
- throw new TemplateError('Parameter is already opened or not closed');
1278
- }
1279
- if (parameters[parameterName] === undefined) {
1280
- throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
1281
- }
1282
- var parameterValue = parameters[parameterName];
1283
- if (parameterValue === undefined) {
1284
- throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
1285
- }
1286
- parameterValue = parameterValue.toString();
1287
- if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
1288
- parameterValue = parameterValue
1289
- .split('\n')
1290
- .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
1291
- .join('\n');
1292
- }
1293
- replacedTemplate =
1294
- replacedTemplate.substring(0, match.index + precol.length) +
1295
- parameterValue +
1296
- replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
1297
- };
1298
- while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
1299
- .exec(replacedTemplate))) {
1300
- _loop_1();
1301
- }
1302
- // [💫] Check if there are parameters that are not closed properly
1303
- if (/{\w+$/.test(replacedTemplate)) {
1304
- throw new TemplateError('Parameter is not closed');
1305
- }
1306
- // [💫] Check if there are parameters that are not opened properly
1307
- if (/^\w+}/.test(replacedTemplate)) {
1308
- throw new TemplateError('Parameter is not opened');
1309
- }
1310
- return replacedTemplate;
1311
- }
1312
-
1313
- /**
1314
- * Format either small or big number
1315
- *
1316
- * @private within the library
1317
- */
1318
- function formatNumber(value) {
1319
- if (value === 0) {
1320
- return '0';
1321
- }
1322
- for (var exponent = 0; exponent < 15; exponent++) {
1323
- var factor = Math.pow(10, exponent);
1324
- var valueRounded = Math.round(value * factor) / factor;
1325
- if (Math.abs(value - valueRounded) / value <
1326
- 0.001 /* <- TODO: Pass as option, pass to executionReportJsonToString as option */) {
1327
- return valueRounded.toFixed(exponent);
1328
- }
1329
- }
1330
- return value.toString();
1331
- }
1332
-
1333
- /**
1334
- * Returns the same value that is passed as argument.
1335
- * No side effects.
1336
- *
1337
- * Note: It can be usefull for leveling indentation
1338
- *
1339
- * @param value any values
1340
- * @returns the same values
1341
- */
1342
- function just(value) {
1343
- if (value === undefined) {
1344
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1345
- return undefined;
1346
- }
1347
- return value;
1348
- }
1349
-
1350
- /**
1351
- * Removes emojis from a string and fix whitespaces
1352
- *
1353
- * @param text with emojis
1354
- * @returns text without emojis
1255
+ * Counts number of characters in the text
1355
1256
  */
1356
- function removeEmojis(text) {
1257
+ function countCharacters(text) {
1258
+ // Remove null characters
1259
+ text = text.replace(/\0/g, '');
1357
1260
  // Replace emojis (and also ZWJ sequence) with hyphens
1358
1261
  text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
1359
1262
  text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
1360
- text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
1361
- text = text.replace(/\p{Extended_Pictographic}/gu, '');
1362
- return text;
1363
- }
1364
-
1365
- /**
1366
- * Create a markdown table from a 2D array of strings
1367
- *
1368
- * @private within the library
1369
- */
1370
- function createMarkdownTable(table) {
1371
- var columnWidths = table.reduce(function (widths, row) {
1372
- row.forEach(function (cell, columnIndex) {
1373
- var cellLength = cell.length;
1374
- if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
1375
- widths[columnIndex] = cellLength;
1376
- }
1377
- });
1378
- return widths;
1379
- }, []);
1380
- var header = "| ".concat(table[0]
1381
- .map(function (cell, columnIndex) { return cell.padEnd(columnWidths[columnIndex]); })
1382
- .join(' | '), " |");
1383
- var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
1384
- var rows = table.slice(1).map(function (row) {
1385
- var paddedRow = row.map(function (cell, columnIndex) {
1386
- return cell.padEnd(columnWidths[columnIndex]);
1387
- });
1388
- return "| ".concat(paddedRow.join(' | '), " |");
1389
- });
1390
- return __spreadArray([header, separator], __read(rows), false).join('\n');
1263
+ text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
1264
+ return text.length;
1391
1265
  }
1392
1266
 
1393
1267
  /**
1394
- * Function createMarkdownChart will draw a chart in markdown from ⬛+🟦 tiles
1395
- *
1396
- * @private within the library
1268
+ * Counts number of lines in the text
1397
1269
  */
1398
- function createMarkdownChart(options) {
1399
- var e_1, _a;
1400
- var nameHeader = options.nameHeader, valueHeader = options.valueHeader, items = options.items, width = options.width, unitName = options.unitName;
1401
- var from = Math.min.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.from; })), false));
1402
- var to = Math.max.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.to; })), false));
1403
- var scale = width / (to - from);
1404
- var table = [[nameHeader, valueHeader]];
1405
- try {
1406
- for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
1407
- var item = items_1_1.value;
1408
- var before = Math.round((item.from - from) * scale);
1409
- var during = Math.round((item.to - item.from) * scale);
1410
- var after = width - before - during;
1411
- table.push([removeEmojis(item.title).trim(), '░'.repeat(before) + '█'.repeat(during) + '░'.repeat(after)]);
1412
- }
1413
- }
1414
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1415
- finally {
1416
- try {
1417
- if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
1418
- }
1419
- finally { if (e_1) throw e_1.error; }
1270
+ function countLines(text) {
1271
+ if (text === '') {
1272
+ return 0;
1420
1273
  }
1421
- var legend = "_Note: Each \u2588 represents ".concat(formatNumber(1 / scale), " ").concat(unitName, ", width of ").concat(valueHeader.toLowerCase(), " is ").concat(formatNumber(to - from), " ").concat(unitName, " = ").concat(width, " squares_");
1422
- return createMarkdownTable(table) + '\n\n' + legend;
1274
+ return text.split('\n').length;
1423
1275
  }
1424
- /**
1425
- * TODO: Maybe use Mermain Gant Diagrams
1426
- * @see https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/
1427
- */
1428
1276
 
1429
1277
  /**
1430
- * Function escapeMarkdownBlock will escape markdown block if needed
1431
- * It is useful when you want have block in block
1278
+ * Counts number of pages in the text
1432
1279
  */
1433
- function escapeMarkdownBlock(value) {
1434
- return value.replace(/```/g, '\\`\\`\\`');
1280
+ function countPages(text) {
1281
+ var sentencesPerPage = 5; // Assuming each page has 5 sentences
1282
+ var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1283
+ var pageCount = Math.ceil(sentences.length / sentencesPerPage);
1284
+ return pageCount;
1435
1285
  }
1436
1286
 
1437
1287
  /**
1438
- * Default options for generating an execution report string
1288
+ * Counts number of paragraphs in the text
1439
1289
  */
1440
- var ExecutionReportStringOptionsDefaults = {
1441
- taxRate: 0,
1442
- chartsWidth: 36,
1443
- };
1290
+ function countParagraphs(text) {
1291
+ return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
1292
+ }
1444
1293
 
1445
1294
  /**
1446
- * The thresholds for the relative time in the `moment` library.
1447
- *
1448
- * @see https://momentjscom.readthedocs.io/en/latest/moment/07-customization/13-relative-time-threshold/
1295
+ * Split text into sentences
1449
1296
  */
1450
- var MOMENT_ARG_THRESHOLDS = {
1451
- ss: 3, // <- least number of seconds to be counted in seconds, minus 1. Must be set after setting the `s` unit or without setting the `s` unit.
1452
- };
1453
-
1297
+ function splitIntoSentences(text) {
1298
+ return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1299
+ }
1454
1300
  /**
1455
- * Count the duration of working time
1456
- *
1457
- * @private within the library
1301
+ * Counts number of sentences in the text
1458
1302
  */
1459
- function countWorkingDuration(items) {
1460
- var e_1, _a;
1461
- var steps = Array.from(new Set(items.flatMap(function (item) { return [item.from, item.to]; })));
1462
- steps.sort(function (a, b) { return a - b; });
1463
- var intervals = steps.map(function (step, index) { return [step, steps[index + 1] || 0]; }).slice(0, -1);
1464
- var duration = 0;
1465
- var _loop_1 = function (interval) {
1466
- var _b = __read(interval, 2), from = _b[0], to = _b[1];
1467
- if (items.some(function (item) { return item.from < to && item.to > from; })) {
1468
- duration += to - from;
1469
- }
1470
- };
1471
- try {
1472
- for (var intervals_1 = __values(intervals), intervals_1_1 = intervals_1.next(); !intervals_1_1.done; intervals_1_1 = intervals_1.next()) {
1473
- var interval = intervals_1_1.value;
1474
- _loop_1(interval);
1475
- }
1476
- }
1477
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1478
- finally {
1479
- try {
1480
- if (intervals_1_1 && !intervals_1_1.done && (_a = intervals_1.return)) _a.call(intervals_1);
1481
- }
1482
- finally { if (e_1) throw e_1.error; }
1483
- }
1484
- return duration;
1485
- }
1486
-
1487
- /**
1488
- * Converts execution report from JSON to string format
1489
- */
1490
- function executionReportJsonToString(executionReportJson, options) {
1491
- var e_1, _a;
1492
- var _b, _c, _d, _e, _f, _g;
1493
- var _h = __assign(__assign({}, ExecutionReportStringOptionsDefaults), (options || {})), taxRate = _h.taxRate, chartsWidth = _h.chartsWidth;
1494
- var executionReportString = spaceTrim__default["default"](function (block) { return "\n # ".concat(executionReportJson.title || 'Execution report', "\n\n ").concat(block(executionReportJson.description || ''), "\n "); });
1495
- var headerList = [];
1496
- if (executionReportJson.promptbookUrl) {
1497
- headerList.push("PROMPTBOOK URL ".concat(executionReportJson.promptbookUrl));
1498
- }
1499
- headerList.push("PROMPTBOOK VERSION ".concat(executionReportJson.promptbookUsedVersion) +
1500
- (!executionReportJson.promptbookRequestedVersion
1501
- ? ''
1502
- : " *(requested ".concat(executionReportJson.promptbookRequestedVersion, ")*")));
1503
- if (executionReportJson.promptExecutions.length !== 0) {
1504
- // TODO: What if startedAt OR/AND completedAt is not defined?
1505
- var startedAt = moment__default["default"](Math.min.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
1506
- .filter(function (promptExecution) { var _a, _b; return (_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start; })
1507
- .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.start).valueOf(); })), false)));
1508
- var completedAt = moment__default["default"](Math.max.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
1509
- .filter(function (promptExecution) { var _a, _b; return (_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.complete; })
1510
- .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.complete).valueOf(); })), false)));
1511
- var timingItems = executionReportJson.promptExecutions.map(function (promptExecution) {
1512
- var _a, _b, _c, _d;
1513
- return ({
1514
- title: promptExecution.prompt.title,
1515
- from: moment__default["default"]((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start).valueOf() / 1000,
1516
- to: moment__default["default"]((_d = (_c = promptExecution.result) === null || _c === void 0 ? void 0 : _c.timing) === null || _d === void 0 ? void 0 : _d.complete).valueOf() / 1000,
1517
- });
1518
- });
1519
- var costItems = executionReportJson.promptExecutions
1520
- .filter(function (promptExecution) { var _a, _b; return typeof ((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) === 'number'; })
1521
- .map(function (promptExecution) {
1522
- var _a, _b;
1523
- return ({
1524
- title: promptExecution.prompt.title,
1525
- from: 0,
1526
- to: ((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) * (1 + taxRate),
1527
- });
1528
- });
1529
- var duration = moment__default["default"].duration(completedAt.diff(startedAt));
1530
- var naturalDuration = moment__default["default"].duration(countWorkingDuration(timingItems) * 1000);
1531
- var executionsWithKnownCost = executionReportJson.promptExecutions.filter(function (promptExecution) { var _a, _b; return (((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) || 'UNKNOWN') !== 'UNKNOWN'; });
1532
- var cost = executionsWithKnownCost.reduce(function (cost, promptExecution) { return cost + (promptExecution.result.usage.price || 0); }, 0);
1533
- headerList.push("STARTED AT ".concat(moment__default["default"](startedAt).format("YYYY-MM-DD HH:mm:ss")));
1534
- headerList.push("COMPLETED AT ".concat(moment__default["default"](completedAt).format("YYYY-MM-DD HH:mm:ss")));
1535
- headerList.push("TOTAL DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
1536
- headerList.push("TOTAL NATURAL DURATION ".concat(naturalDuration.humanize(MOMENT_ARG_THRESHOLDS)));
1537
- headerList.push("TOTAL COST $".concat(formatNumber(cost * (1 + taxRate))) +
1538
- (executionsWithKnownCost.length === executionReportJson.promptExecutions.length
1539
- ? ''
1540
- : " *(Some cost is unknown)*") +
1541
- (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
1542
- executionReportString += '\n\n' + headerList.map(function (header) { return "- ".concat(header); }).join('\n');
1543
- executionReportString +=
1544
- '\n\n' +
1545
- '## 🗃 Index' +
1546
- '\n\n' +
1547
- executionReportJson.promptExecutions
1548
- .map(function (promptExecution) {
1549
- // TODO: Make some better system to convert hedings to links
1550
- var hash = normalizeToKebabCase(promptExecution.prompt.title);
1551
- if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
1552
- hash = '-' + hash;
1553
- }
1554
- // TODO: Make working hash link for the template in md + pdf
1555
- return "- [".concat(promptExecution.prompt.title, "](#").concat(hash, ")");
1556
- })
1557
- .join('\n');
1558
- executionReportString +=
1559
- '\n\n' +
1560
- '## ⌚ Time chart' +
1561
- '\n\n' +
1562
- createMarkdownChart({
1563
- nameHeader: 'Template',
1564
- valueHeader: 'Timeline',
1565
- items: timingItems,
1566
- width: chartsWidth,
1567
- unitName: 'seconds',
1568
- });
1569
- executionReportString +=
1570
- '\n\n' +
1571
- '## 💸 Cost chart' +
1572
- '\n\n' +
1573
- createMarkdownChart({
1574
- nameHeader: 'Template',
1575
- valueHeader: 'Cost',
1576
- items: costItems,
1577
- width: chartsWidth,
1578
- unitName: 'USD',
1579
- });
1580
- }
1581
- else {
1582
- headerList.push("TOTAL COST $0 *(Nothing executed)*");
1583
- }
1584
- var _loop_1 = function (promptExecution) {
1585
- executionReportString += '\n\n\n\n' + "## ".concat(promptExecution.prompt.title);
1586
- var templateList = [];
1587
- // TODO: What if startedAt OR/AND completedAt is not defined?
1588
- var startedAt = moment__default["default"]((_c = (_b = promptExecution.result) === null || _b === void 0 ? void 0 : _b.timing) === null || _c === void 0 ? void 0 : _c.start);
1589
- var completedAt = moment__default["default"]((_e = (_d = promptExecution.result) === null || _d === void 0 ? void 0 : _d.timing) === null || _e === void 0 ? void 0 : _e.complete);
1590
- var duration = moment__default["default"].duration(completedAt.diff(startedAt));
1591
- // Not need here:
1592
- // > templateList.push(`STARTED AT ${moment(startedAt).calendar()}`);
1593
- templateList.push("DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
1594
- if (typeof ((_g = (_f = promptExecution.result) === null || _f === void 0 ? void 0 : _f.usage) === null || _g === void 0 ? void 0 : _g.price) === 'number') {
1595
- templateList.push("COST $".concat(formatNumber(promptExecution.result.usage.price * (1 + taxRate))) +
1596
- (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
1597
- }
1598
- else {
1599
- templateList.push("COST UNKNOWN");
1600
- }
1601
- executionReportString += '\n\n' + templateList.map(function (header) { return "- ".concat(header); }).join('\n');
1602
- /*
1603
- - MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
1604
- - MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
1605
- promptExecution.prompt.modelRequirements.modelName
1606
-
1607
- */
1608
- if (just(true)) {
1609
- executionReportString +=
1610
- '\n\n\n\n' +
1611
- spaceTrim__default["default"](function (block) { return "\n\n ### Prompt\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.prompt.content)), "\n ```\n\n "); });
1612
- }
1613
- if (promptExecution.result && promptExecution.result.content) {
1614
- executionReportString +=
1615
- '\n\n\n\n' +
1616
- spaceTrim__default["default"](function (block) { return "\n\n ### Result\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.result.content)), "\n ```\n "); });
1617
- }
1618
- if (promptExecution.error && promptExecution.error.message) {
1619
- executionReportString +=
1620
- '\n\n\n\n' +
1621
- spaceTrim__default["default"](function (block) { return "\n\n ### Error\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.error.message)), "\n ```\n\n "); });
1622
- }
1623
- };
1624
- try {
1625
- for (var _j = __values(executionReportJson.promptExecutions), _k = _j.next(); !_k.done; _k = _j.next()) {
1626
- var promptExecution = _k.value;
1627
- _loop_1(promptExecution);
1628
- }
1629
- }
1630
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1631
- finally {
1632
- try {
1633
- if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
1634
- }
1635
- finally { if (e_1) throw e_1.error; }
1636
- }
1637
- executionReportString = prettifyMarkdown(executionReportString);
1638
- return executionReportString;
1639
- }
1640
- /**
1641
- * TODO: Add mermaid chart for every report
1642
- * TODO: [🧠] Allow to filter out some parts of the report by options
1643
- */
1644
-
1645
- /**
1646
- * Counts number of characters in the text
1647
- */
1648
- function countCharacters(text) {
1649
- // Remove null characters
1650
- text = text.replace(/\0/g, '');
1651
- // Replace emojis (and also ZWJ sequence) with hyphens
1652
- text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
1653
- text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
1654
- text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
1655
- return text.length;
1656
- }
1657
-
1658
- /**
1659
- * Counts number of lines in the text
1660
- */
1661
- function countLines(text) {
1662
- if (text === '') {
1663
- return 0;
1664
- }
1665
- return text.split('\n').length;
1666
- }
1667
-
1668
- /**
1669
- * Counts number of pages in the text
1670
- */
1671
- function countPages(text) {
1672
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
1673
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1674
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
1675
- return pageCount;
1676
- }
1677
-
1678
- /**
1679
- * Counts number of paragraphs in the text
1680
- */
1681
- function countParagraphs(text) {
1682
- return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
1683
- }
1684
-
1685
- /**
1686
- * Split text into sentences
1687
- */
1688
- function splitIntoSentences(text) {
1689
- return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1690
- }
1691
- /**
1692
- * Counts number of sentences in the text
1693
- */
1694
- function countSentences(text) {
1695
- return splitIntoSentences(text).length;
1303
+ function countSentences(text) {
1304
+ return splitIntoSentences(text).length;
1696
1305
  }
1697
1306
 
1698
1307
  var defaultDiacriticsRemovalMap = [
@@ -1969,6 +1578,471 @@
1969
1578
  PAGES: countPages,
1970
1579
  };
1971
1580
 
1581
+ /**
1582
+ * Function checkExpectations will check if the expectations on given value are met
1583
+ *
1584
+ * Note: There are two simmilar functions:
1585
+ * - `checkExpectations` which throws an error if the expectations are not met
1586
+ * - `isPassingExpectations` which returns a boolean
1587
+ *
1588
+ * @throws {ExpectError} if the expectations are not met
1589
+ * @returns {void} Nothing
1590
+ */
1591
+ function checkExpectations(expectations, value) {
1592
+ var e_1, _a;
1593
+ try {
1594
+ for (var _b = __values(Object.entries(expectations)), _c = _b.next(); !_c.done; _c = _b.next()) {
1595
+ var _d = __read(_c.value, 2), unit = _d[0], _e = _d[1], max = _e.max, min = _e.min;
1596
+ var amount = CountUtils[unit.toUpperCase()](value);
1597
+ if (min && amount < min) {
1598
+ throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1599
+ } /* not else */
1600
+ if (max && amount > max) {
1601
+ throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
1602
+ }
1603
+ }
1604
+ }
1605
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1606
+ finally {
1607
+ try {
1608
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1609
+ }
1610
+ finally { if (e_1) throw e_1.error; }
1611
+ }
1612
+ }
1613
+ /**
1614
+ * Function checkExpectations will check if the expectations on given value are met
1615
+ *
1616
+ * Note: There are two simmilar functions:
1617
+ * - `checkExpectations` which throws an error if the expectations are not met
1618
+ * - `isPassingExpectations` which returns a boolean
1619
+ *
1620
+ * @returns {boolean} True if the expectations are met
1621
+ */
1622
+ function isPassingExpectations(expectations, value) {
1623
+ try {
1624
+ checkExpectations(expectations, value);
1625
+ return true;
1626
+ }
1627
+ catch (error) {
1628
+ if (!(error instanceof ExpectError)) {
1629
+ throw error;
1630
+ }
1631
+ return false;
1632
+ }
1633
+ }
1634
+ /**
1635
+ * TODO: [💝] Unite object for expecting amount and format
1636
+ */
1637
+
1638
+ /**
1639
+ * This error occurs during the parameter replacement in the template
1640
+ *
1641
+ * Note: This is a kindof subtype of PromptbookExecutionError because it occurs during the execution of the pipeline
1642
+ */
1643
+ var TemplateError = /** @class */ (function (_super) {
1644
+ __extends(TemplateError, _super);
1645
+ function TemplateError(message) {
1646
+ var _this = _super.call(this, message) || this;
1647
+ _this.name = 'TemplateError';
1648
+ Object.setPrototypeOf(_this, TemplateError.prototype);
1649
+ return _this;
1650
+ }
1651
+ return TemplateError;
1652
+ }(Error));
1653
+
1654
+ /**
1655
+ * Replaces parameters in template with values from parameters object
1656
+ *
1657
+ * @param template the template with parameters in {curly} braces
1658
+ * @param parameters the object with parameters
1659
+ * @returns the template with replaced parameters
1660
+ * @throws {TemplateError} if parameter is not defined, not closed, or not opened
1661
+ *
1662
+ * @private within the createPromptbookExecutor
1663
+ */
1664
+ function replaceParameters(template, parameters) {
1665
+ var replacedTemplate = template;
1666
+ var match;
1667
+ var loopLimit = LOOP_LIMIT;
1668
+ var _loop_1 = function () {
1669
+ if (loopLimit-- < 0) {
1670
+ throw new UnexpectedError('Loop limit reached during parameters replacement in `replaceParameters`');
1671
+ }
1672
+ var precol = match.groups.precol;
1673
+ var parameterName = match.groups.parameterName;
1674
+ if (parameterName === '') {
1675
+ return "continue";
1676
+ }
1677
+ if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
1678
+ throw new TemplateError('Parameter is already opened or not closed');
1679
+ }
1680
+ if (parameters[parameterName] === undefined) {
1681
+ throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
1682
+ }
1683
+ var parameterValue = parameters[parameterName];
1684
+ if (parameterValue === undefined) {
1685
+ throw new TemplateError("Parameter {".concat(parameterName, "} is not defined"));
1686
+ }
1687
+ parameterValue = parameterValue.toString();
1688
+ if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
1689
+ parameterValue = parameterValue
1690
+ .split('\n')
1691
+ .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
1692
+ .join('\n');
1693
+ }
1694
+ replacedTemplate =
1695
+ replacedTemplate.substring(0, match.index + precol.length) +
1696
+ parameterValue +
1697
+ replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
1698
+ };
1699
+ while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
1700
+ .exec(replacedTemplate))) {
1701
+ _loop_1();
1702
+ }
1703
+ // [💫] Check if there are parameters that are not closed properly
1704
+ if (/{\w+$/.test(replacedTemplate)) {
1705
+ throw new TemplateError('Parameter is not closed');
1706
+ }
1707
+ // [💫] Check if there are parameters that are not opened properly
1708
+ if (/^\w+}/.test(replacedTemplate)) {
1709
+ throw new TemplateError('Parameter is not opened');
1710
+ }
1711
+ return replacedTemplate;
1712
+ }
1713
+
1714
+ /**
1715
+ * Format either small or big number
1716
+ *
1717
+ * @private within the library
1718
+ */
1719
+ function formatNumber(value) {
1720
+ if (value === 0) {
1721
+ return '0';
1722
+ }
1723
+ for (var exponent = 0; exponent < 15; exponent++) {
1724
+ var factor = Math.pow(10, exponent);
1725
+ var valueRounded = Math.round(value * factor) / factor;
1726
+ if (Math.abs(value - valueRounded) / value <
1727
+ 0.001 /* <- TODO: Pass as option, pass to executionReportJsonToString as option */) {
1728
+ return valueRounded.toFixed(exponent);
1729
+ }
1730
+ }
1731
+ return value.toString();
1732
+ }
1733
+
1734
+ /**
1735
+ * Returns the same value that is passed as argument.
1736
+ * No side effects.
1737
+ *
1738
+ * Note: It can be usefull for leveling indentation
1739
+ *
1740
+ * @param value any values
1741
+ * @returns the same values
1742
+ */
1743
+ function just(value) {
1744
+ if (value === undefined) {
1745
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1746
+ return undefined;
1747
+ }
1748
+ return value;
1749
+ }
1750
+
1751
+ /**
1752
+ * Removes emojis from a string and fix whitespaces
1753
+ *
1754
+ * @param text with emojis
1755
+ * @returns text without emojis
1756
+ */
1757
+ function removeEmojis(text) {
1758
+ // Replace emojis (and also ZWJ sequence) with hyphens
1759
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
1760
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
1761
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
1762
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
1763
+ return text;
1764
+ }
1765
+
1766
+ /**
1767
+ * Create a markdown table from a 2D array of strings
1768
+ *
1769
+ * @private within the library
1770
+ */
1771
+ function createMarkdownTable(table) {
1772
+ var columnWidths = table.reduce(function (widths, row) {
1773
+ row.forEach(function (cell, columnIndex) {
1774
+ var cellLength = cell.length;
1775
+ if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
1776
+ widths[columnIndex] = cellLength;
1777
+ }
1778
+ });
1779
+ return widths;
1780
+ }, []);
1781
+ var header = "| ".concat(table[0]
1782
+ .map(function (cell, columnIndex) { return cell.padEnd(columnWidths[columnIndex]); })
1783
+ .join(' | '), " |");
1784
+ var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
1785
+ var rows = table.slice(1).map(function (row) {
1786
+ var paddedRow = row.map(function (cell, columnIndex) {
1787
+ return cell.padEnd(columnWidths[columnIndex]);
1788
+ });
1789
+ return "| ".concat(paddedRow.join(' | '), " |");
1790
+ });
1791
+ return __spreadArray([header, separator], __read(rows), false).join('\n');
1792
+ }
1793
+
1794
+ /**
1795
+ * Function createMarkdownChart will draw a chart in markdown from ⬛+🟦 tiles
1796
+ *
1797
+ * @private within the library
1798
+ */
1799
+ function createMarkdownChart(options) {
1800
+ var e_1, _a;
1801
+ var nameHeader = options.nameHeader, valueHeader = options.valueHeader, items = options.items, width = options.width, unitName = options.unitName;
1802
+ var from = Math.min.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.from; })), false));
1803
+ var to = Math.max.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.to; })), false));
1804
+ var scale = width / (to - from);
1805
+ var table = [[nameHeader, valueHeader]];
1806
+ try {
1807
+ for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
1808
+ var item = items_1_1.value;
1809
+ var before = Math.round((item.from - from) * scale);
1810
+ var during = Math.round((item.to - item.from) * scale);
1811
+ var after = width - before - during;
1812
+ table.push([removeEmojis(item.title).trim(), '░'.repeat(before) + '█'.repeat(during) + '░'.repeat(after)]);
1813
+ }
1814
+ }
1815
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1816
+ finally {
1817
+ try {
1818
+ if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
1819
+ }
1820
+ finally { if (e_1) throw e_1.error; }
1821
+ }
1822
+ var legend = "_Note: Each \u2588 represents ".concat(formatNumber(1 / scale), " ").concat(unitName, ", width of ").concat(valueHeader.toLowerCase(), " is ").concat(formatNumber(to - from), " ").concat(unitName, " = ").concat(width, " squares_");
1823
+ return createMarkdownTable(table) + '\n\n' + legend;
1824
+ }
1825
+ /**
1826
+ * TODO: Maybe use Mermain Gant Diagrams
1827
+ * @see https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/
1828
+ */
1829
+
1830
+ /**
1831
+ * Function escapeMarkdownBlock will escape markdown block if needed
1832
+ * It is useful when you want have block in block
1833
+ */
1834
+ function escapeMarkdownBlock(value) {
1835
+ return value.replace(/```/g, '\\`\\`\\`');
1836
+ }
1837
+
1838
+ /**
1839
+ * Default options for generating an execution report string
1840
+ */
1841
+ var ExecutionReportStringOptionsDefaults = {
1842
+ taxRate: 0,
1843
+ chartsWidth: 36,
1844
+ };
1845
+
1846
+ /**
1847
+ * The thresholds for the relative time in the `moment` library.
1848
+ *
1849
+ * @see https://momentjscom.readthedocs.io/en/latest/moment/07-customization/13-relative-time-threshold/
1850
+ */
1851
+ var MOMENT_ARG_THRESHOLDS = {
1852
+ ss: 3, // <- least number of seconds to be counted in seconds, minus 1. Must be set after setting the `s` unit or without setting the `s` unit.
1853
+ };
1854
+
1855
+ /**
1856
+ * Count the duration of working time
1857
+ *
1858
+ * @private within the library
1859
+ */
1860
+ function countWorkingDuration(items) {
1861
+ var e_1, _a;
1862
+ var steps = Array.from(new Set(items.flatMap(function (item) { return [item.from, item.to]; })));
1863
+ steps.sort(function (a, b) { return a - b; });
1864
+ var intervals = steps.map(function (step, index) { return [step, steps[index + 1] || 0]; }).slice(0, -1);
1865
+ var duration = 0;
1866
+ var _loop_1 = function (interval) {
1867
+ var _b = __read(interval, 2), from = _b[0], to = _b[1];
1868
+ if (items.some(function (item) { return item.from < to && item.to > from; })) {
1869
+ duration += to - from;
1870
+ }
1871
+ };
1872
+ try {
1873
+ for (var intervals_1 = __values(intervals), intervals_1_1 = intervals_1.next(); !intervals_1_1.done; intervals_1_1 = intervals_1.next()) {
1874
+ var interval = intervals_1_1.value;
1875
+ _loop_1(interval);
1876
+ }
1877
+ }
1878
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1879
+ finally {
1880
+ try {
1881
+ if (intervals_1_1 && !intervals_1_1.done && (_a = intervals_1.return)) _a.call(intervals_1);
1882
+ }
1883
+ finally { if (e_1) throw e_1.error; }
1884
+ }
1885
+ return duration;
1886
+ }
1887
+
1888
+ /**
1889
+ * Converts execution report from JSON to string format
1890
+ */
1891
+ function executionReportJsonToString(executionReportJson, options) {
1892
+ var e_1, _a;
1893
+ var _b, _c, _d, _e, _f, _g;
1894
+ var _h = __assign(__assign({}, ExecutionReportStringOptionsDefaults), (options || {})), taxRate = _h.taxRate, chartsWidth = _h.chartsWidth;
1895
+ var executionReportString = spacetrim.spaceTrim(function (block) { return "\n # ".concat(executionReportJson.title || 'Execution report', "\n\n ").concat(block(executionReportJson.description || ''), "\n "); });
1896
+ var headerList = [];
1897
+ if (executionReportJson.promptbookUrl) {
1898
+ headerList.push("PROMPTBOOK URL ".concat(executionReportJson.promptbookUrl));
1899
+ }
1900
+ headerList.push("PROMPTBOOK VERSION ".concat(executionReportJson.promptbookUsedVersion) +
1901
+ (!executionReportJson.promptbookRequestedVersion
1902
+ ? ''
1903
+ : " *(requested ".concat(executionReportJson.promptbookRequestedVersion, ")*")));
1904
+ if (executionReportJson.promptExecutions.length !== 0) {
1905
+ // TODO: What if startedAt OR/AND completedAt is not defined?
1906
+ var startedAt = moment__default["default"](Math.min.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
1907
+ .filter(function (promptExecution) { var _a, _b; return (_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start; })
1908
+ .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.start).valueOf(); })), false)));
1909
+ var completedAt = moment__default["default"](Math.max.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
1910
+ .filter(function (promptExecution) { var _a, _b; return (_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.complete; })
1911
+ .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.complete).valueOf(); })), false)));
1912
+ var timingItems = executionReportJson.promptExecutions.map(function (promptExecution) {
1913
+ var _a, _b, _c, _d;
1914
+ return ({
1915
+ title: promptExecution.prompt.title,
1916
+ from: moment__default["default"]((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start).valueOf() / 1000,
1917
+ to: moment__default["default"]((_d = (_c = promptExecution.result) === null || _c === void 0 ? void 0 : _c.timing) === null || _d === void 0 ? void 0 : _d.complete).valueOf() / 1000,
1918
+ });
1919
+ });
1920
+ var costItems = executionReportJson.promptExecutions
1921
+ .filter(function (promptExecution) { var _a, _b; return typeof ((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) === 'number'; })
1922
+ .map(function (promptExecution) {
1923
+ var _a, _b;
1924
+ return ({
1925
+ title: promptExecution.prompt.title,
1926
+ from: 0,
1927
+ to: ((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) * (1 + taxRate),
1928
+ });
1929
+ });
1930
+ var duration = moment__default["default"].duration(completedAt.diff(startedAt));
1931
+ var naturalDuration = moment__default["default"].duration(countWorkingDuration(timingItems) * 1000);
1932
+ var executionsWithKnownCost = executionReportJson.promptExecutions.filter(function (promptExecution) { var _a, _b; return (((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price) || 'UNKNOWN') !== 'UNKNOWN'; });
1933
+ var cost = executionsWithKnownCost.reduce(function (cost, promptExecution) { return cost + (promptExecution.result.usage.price || 0); }, 0);
1934
+ headerList.push("STARTED AT ".concat(moment__default["default"](startedAt).format("YYYY-MM-DD HH:mm:ss")));
1935
+ headerList.push("COMPLETED AT ".concat(moment__default["default"](completedAt).format("YYYY-MM-DD HH:mm:ss")));
1936
+ headerList.push("TOTAL DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
1937
+ headerList.push("TOTAL NATURAL DURATION ".concat(naturalDuration.humanize(MOMENT_ARG_THRESHOLDS)));
1938
+ headerList.push("TOTAL COST $".concat(formatNumber(cost * (1 + taxRate))) +
1939
+ (executionsWithKnownCost.length === executionReportJson.promptExecutions.length
1940
+ ? ''
1941
+ : " *(Some cost is unknown)*") +
1942
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
1943
+ executionReportString += '\n\n' + headerList.map(function (header) { return "- ".concat(header); }).join('\n');
1944
+ executionReportString +=
1945
+ '\n\n' +
1946
+ '## 🗃 Index' +
1947
+ '\n\n' +
1948
+ executionReportJson.promptExecutions
1949
+ .map(function (promptExecution) {
1950
+ // TODO: Make some better system to convert hedings to links
1951
+ var hash = normalizeToKebabCase(promptExecution.prompt.title);
1952
+ if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
1953
+ hash = '-' + hash;
1954
+ }
1955
+ // TODO: Make working hash link for the template in md + pdf
1956
+ return "- [".concat(promptExecution.prompt.title, "](#").concat(hash, ")");
1957
+ })
1958
+ .join('\n');
1959
+ executionReportString +=
1960
+ '\n\n' +
1961
+ '## ⌚ Time chart' +
1962
+ '\n\n' +
1963
+ createMarkdownChart({
1964
+ nameHeader: 'Template',
1965
+ valueHeader: 'Timeline',
1966
+ items: timingItems,
1967
+ width: chartsWidth,
1968
+ unitName: 'seconds',
1969
+ });
1970
+ executionReportString +=
1971
+ '\n\n' +
1972
+ '## 💸 Cost chart' +
1973
+ '\n\n' +
1974
+ createMarkdownChart({
1975
+ nameHeader: 'Template',
1976
+ valueHeader: 'Cost',
1977
+ items: costItems,
1978
+ width: chartsWidth,
1979
+ unitName: 'USD',
1980
+ });
1981
+ }
1982
+ else {
1983
+ headerList.push("TOTAL COST $0 *(Nothing executed)*");
1984
+ }
1985
+ var _loop_1 = function (promptExecution) {
1986
+ executionReportString += '\n\n\n\n' + "## ".concat(promptExecution.prompt.title);
1987
+ var templateList = [];
1988
+ // TODO: What if startedAt OR/AND completedAt is not defined?
1989
+ var startedAt = moment__default["default"]((_c = (_b = promptExecution.result) === null || _b === void 0 ? void 0 : _b.timing) === null || _c === void 0 ? void 0 : _c.start);
1990
+ var completedAt = moment__default["default"]((_e = (_d = promptExecution.result) === null || _d === void 0 ? void 0 : _d.timing) === null || _e === void 0 ? void 0 : _e.complete);
1991
+ var duration = moment__default["default"].duration(completedAt.diff(startedAt));
1992
+ // Not need here:
1993
+ // > templateList.push(`STARTED AT ${moment(startedAt).calendar()}`);
1994
+ templateList.push("DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
1995
+ if (typeof ((_g = (_f = promptExecution.result) === null || _f === void 0 ? void 0 : _f.usage) === null || _g === void 0 ? void 0 : _g.price) === 'number') {
1996
+ templateList.push("COST $".concat(formatNumber(promptExecution.result.usage.price * (1 + taxRate))) +
1997
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
1998
+ }
1999
+ else {
2000
+ templateList.push("COST UNKNOWN");
2001
+ }
2002
+ executionReportString += '\n\n' + templateList.map(function (header) { return "- ".concat(header); }).join('\n');
2003
+ /*
2004
+ - MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
2005
+ - MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
2006
+ promptExecution.prompt.modelRequirements.modelName
2007
+
2008
+ */
2009
+ if (just(true)) {
2010
+ executionReportString +=
2011
+ '\n\n\n\n' +
2012
+ spacetrim.spaceTrim(function (block) { return "\n\n ### Prompt\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.prompt.content)), "\n ```\n\n "); });
2013
+ }
2014
+ if (promptExecution.result && promptExecution.result.content) {
2015
+ executionReportString +=
2016
+ '\n\n\n\n' +
2017
+ spacetrim.spaceTrim(function (block) { return "\n\n ### Result\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.result.content)), "\n ```\n "); });
2018
+ }
2019
+ if (promptExecution.error && promptExecution.error.message) {
2020
+ executionReportString +=
2021
+ '\n\n\n\n' +
2022
+ spacetrim.spaceTrim(function (block) { return "\n\n ### Error\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.error.message)), "\n ```\n\n "); });
2023
+ }
2024
+ };
2025
+ try {
2026
+ for (var _j = __values(executionReportJson.promptExecutions), _k = _j.next(); !_k.done; _k = _j.next()) {
2027
+ var promptExecution = _k.value;
2028
+ _loop_1(promptExecution);
2029
+ }
2030
+ }
2031
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2032
+ finally {
2033
+ try {
2034
+ if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
2035
+ }
2036
+ finally { if (e_1) throw e_1.error; }
2037
+ }
2038
+ executionReportString = prettifyMarkdown(executionReportString);
2039
+ return executionReportString;
2040
+ }
2041
+ /**
2042
+ * TODO: Add mermaid chart for every report
2043
+ * TODO: [🧠] Allow to filter out some parts of the report by options
2044
+ */
2045
+
1972
2046
  /**
1973
2047
  * Function isValidJsonString will tell you if the string is valid JSON or not
1974
2048
  */
@@ -2340,13 +2414,13 @@
2340
2414
  *
2341
2415
  */
2342
2416
  function trimCodeBlock(value) {
2343
- value = spaceTrim__default["default"](value);
2417
+ value = spacetrim.spaceTrim(value);
2344
2418
  if (!/^```[a-z]*(.*)```$/is.test(value)) {
2345
2419
  return value;
2346
2420
  }
2347
2421
  value = value.replace(/^```[a-z]*/i, '');
2348
2422
  value = value.replace(/```$/i, '');
2349
- value = spaceTrim__default["default"](value);
2423
+ value = spacetrim.spaceTrim(value);
2350
2424
  return value;
2351
2425
  }
2352
2426
 
@@ -2357,9 +2431,9 @@
2357
2431
  * if you want to start code block in the prompt but you don't want to end it in the result.
2358
2432
  */
2359
2433
  function trimEndOfCodeBlock(value) {
2360
- value = spaceTrim__default["default"](value);
2434
+ value = spacetrim.spaceTrim(value);
2361
2435
  value = value.replace(/```$/g, '');
2362
- value = spaceTrim__default["default"](value);
2436
+ value = spacetrim.spaceTrim(value);
2363
2437
  return value;
2364
2438
  }
2365
2439
 
@@ -2380,7 +2454,7 @@
2380
2454
  var trimmedText = text;
2381
2455
  // Remove leading and trailing spaces and newlines
2382
2456
  if (isTrimmed) {
2383
- trimmedText = spaceTrim__default["default"](trimmedText);
2457
+ trimmedText = spacetrim.spaceTrim(trimmedText);
2384
2458
  }
2385
2459
  var processedText = trimmedText;
2386
2460
  if (isIntroduceSentenceRemoved) {
@@ -2389,7 +2463,7 @@
2389
2463
  // Remove the introduce sentence and quotes by replacing it with an empty string
2390
2464
  processedText = processedText.replace(introduceSentenceRegex, '');
2391
2465
  }
2392
- processedText = spaceTrim__default["default"](processedText);
2466
+ processedText = spacetrim.spaceTrim(processedText);
2393
2467
  }
2394
2468
  if (processedText.length < 3) {
2395
2469
  return trimmedText;
@@ -2436,14 +2510,17 @@
2436
2510
 
2437
2511
  // And the normalization (originally n12 library) utilities:
2438
2512
  var normalizeTo = {
2513
+ // [🕙] lowercase: normalizeTo_lowercase,
2514
+ // [🕙] UPPERCASE: normalizeTo_UPPERCASE,
2439
2515
  camelCase: normalizeTo_camelCase,
2440
2516
  PascalCase: normalizeTo_PascalCase,
2441
- 'SCREAMING-CASE': normalizeTo_SCREAMING_CASE,
2517
+ SCREAMING_CASE: normalizeTo_SCREAMING_CASE,
2442
2518
  snake_case: normalizeTo_snake_case,
2443
2519
  'kebab-case': normalizeToKebabCase,
2444
2520
  };
2445
2521
  /**
2446
2522
  * TODO: [🧠] Maybe create some indipendent package like `markdown-tools` from both here exported and @private utilities
2523
+ * Note: [🕙] It does not make sence to have simple lower / UPPER case normalization
2447
2524
  */
2448
2525
 
2449
2526
  exports.CountUtils = CountUtils;
@@ -2451,6 +2528,7 @@
2451
2528
  exports.ExecutionReportStringOptionsDefaults = ExecutionReportStringOptionsDefaults;
2452
2529
  exports.assertsExecutionSuccessful = assertsExecutionSuccessful;
2453
2530
  exports.capitalize = capitalize;
2531
+ exports.checkExpectations = checkExpectations;
2454
2532
  exports.countCharacters = countCharacters;
2455
2533
  exports.countLines = countLines;
2456
2534
  exports.countPages = countPages;
@@ -2463,6 +2541,7 @@
2463
2541
  exports.extractAllListItemsFromMarkdown = extractAllListItemsFromMarkdown;
2464
2542
  exports.extractBlock = extractBlock;
2465
2543
  exports.extractOneBlockFromMarkdown = extractOneBlockFromMarkdown;
2544
+ exports.isPassingExpectations = isPassingExpectations;
2466
2545
  exports.isValidJsonString = isValidJsonString;
2467
2546
  exports.isValidKeyword = isValidKeyword;
2468
2547
  exports.nameToUriPart = nameToUriPart;