@promptbook/cli 0.74.0-0 → 0.74.0-12

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 (57) hide show
  1. package/README.md +137 -32
  2. package/bin/promptbook-cli.js +6 -1
  3. package/esm/index.es.js +1078 -500
  4. package/esm/index.es.js.map +1 -1
  5. package/esm/typings/src/_packages/anthropic-claude.index.d.ts +2 -2
  6. package/esm/typings/src/_packages/azure-openai.index.d.ts +2 -2
  7. package/esm/typings/src/_packages/browser.index.d.ts +2 -2
  8. package/esm/typings/src/_packages/cli.index.d.ts +2 -2
  9. package/esm/typings/src/_packages/core.index.d.ts +7 -3
  10. package/esm/typings/src/_packages/documents.index.d.ts +2 -2
  11. package/esm/typings/src/_packages/execute-javascript.index.d.ts +2 -2
  12. package/esm/typings/src/_packages/fake-llm.index.d.ts +2 -2
  13. package/esm/typings/src/_packages/langtail.index.d.ts +2 -2
  14. package/esm/typings/src/_packages/legacy-documents.index.d.ts +2 -2
  15. package/esm/typings/src/_packages/markdown-utils.index.d.ts +2 -2
  16. package/esm/typings/src/_packages/node.index.d.ts +2 -2
  17. package/esm/typings/src/_packages/openai.index.d.ts +2 -2
  18. package/esm/typings/src/_packages/pdf.index.d.ts +2 -2
  19. package/esm/typings/src/_packages/remote-client.index.d.ts +2 -2
  20. package/esm/typings/src/_packages/remote-server.index.d.ts +2 -2
  21. package/esm/typings/src/_packages/utils.index.d.ts +2 -2
  22. package/esm/typings/src/_packages/website-crawler.index.d.ts +2 -2
  23. package/esm/typings/src/cli/cli-commands/make.d.ts +0 -1
  24. package/esm/typings/src/cli/cli-commands/run.d.ts +14 -0
  25. package/esm/typings/src/cli/promptbookCli.d.ts +1 -0
  26. package/esm/typings/src/cli/test/ptbk.d.ts +5 -2
  27. package/esm/typings/src/collection/collectionToJson.test.d.ts +1 -1
  28. package/esm/typings/src/collection/constructors/createCollectionFromDirectory.d.ts +1 -1
  29. package/esm/typings/src/commands/BOOK_VERSION/BookVersionCommand.d.ts +11 -0
  30. package/esm/typings/src/commands/BOOK_VERSION/bookVersionCommandParser.d.ts +9 -0
  31. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +2 -2
  32. package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
  33. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  34. package/esm/typings/src/commands/index.d.ts +1 -1
  35. package/esm/typings/src/config.d.ts +6 -0
  36. package/esm/typings/src/conversion/pipelineJsonToString.d.ts +3 -3
  37. package/esm/typings/src/conversion/pipelineStringToJson.d.ts +2 -2
  38. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +2 -2
  39. package/esm/typings/src/conversion/utils/stringifyPipelineJson.d.ts +1 -1
  40. package/esm/typings/src/conversion/validation/_importPipeline.d.ts +7 -7
  41. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +1 -1
  42. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +1 -1
  43. package/esm/typings/src/storage/blackhole/BlackholeStorage.d.ts +33 -0
  44. package/esm/typings/src/storage/memory/MemoryStorage.d.ts +1 -1
  45. package/esm/typings/src/storage/{memory/utils → utils}/PrefixStorage.d.ts +1 -1
  46. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +6 -4
  47. package/esm/typings/src/types/PipelineJson/PreparationJson.d.ts +1 -1
  48. package/esm/typings/src/types/Prompt.d.ts +1 -1
  49. package/esm/typings/src/types/typeAliases.d.ts +2 -2
  50. package/esm/typings/src/version.d.ts +13 -2
  51. package/package.json +8 -4
  52. package/umd/index.umd.js +1083 -504
  53. package/umd/index.umd.js.map +1 -1
  54. package/esm/typings/src/commands/PROMPTBOOK_VERSION/PromptbookVersionCommand.d.ts +0 -11
  55. package/esm/typings/src/commands/PROMPTBOOK_VERSION/promptbookVersionCommandParser.d.ts +0 -9
  56. /package/esm/typings/src/commands/{PROMPTBOOK_VERSION/promptbookVersionCommand.test.d.ts → BOOK_VERSION/bookVersionCommand.test.d.ts} +0 -0
  57. /package/esm/typings/src/storage/{memory → local-storage}/utils/makePromptbookStorageFromWebStorage.d.ts +0 -0
package/umd/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('commander'), require('spacetrim'), require('colors'), require('waitasecond'), require('fs/promises'), require('path'), require('prettier'), require('prettier/parser-html'), require('papaparse'), require('crypto-js'), require('crypto-js/enc-hex'), require('mime-types'), require('child_process'), require('util'), require('dotenv'), require('crypto-js/sha256'), require('glob-promise'), require('socket.io-client'), require('@anthropic-ai/sdk'), require('@azure/openai'), require('openai'), require('@mozilla/readability'), require('jsdom'), require('showdown')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'commander', 'spacetrim', 'colors', 'waitasecond', 'fs/promises', 'path', 'prettier', 'prettier/parser-html', 'papaparse', 'crypto-js', 'crypto-js/enc-hex', 'mime-types', 'child_process', 'util', 'dotenv', 'crypto-js/sha256', 'glob-promise', 'socket.io-client', '@anthropic-ai/sdk', '@azure/openai', 'openai', '@mozilla/readability', 'jsdom', 'showdown'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.commander, global.spaceTrim, global.colors, global.waitasecond, global.promises, global.path, global.prettier, global.parserHtml, global.papaparse, global.cryptoJs, global.hexEncoder, global.mimeTypes, global.child_process, global.util, global.dotenv, global.sha256, global.glob, global.socket_ioClient, global.Anthropic, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
5
- })(this, (function (exports, commander, spaceTrim, colors, waitasecond, promises, path, prettier, parserHtml, papaparse, cryptoJs, hexEncoder, mimeTypes, child_process, util, dotenv, sha256, glob, socket_ioClient, Anthropic, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('waitasecond'), require('fs/promises'), require('path'), require('prettier'), require('prettier/parser-html'), require('papaparse'), require('crypto-js'), require('crypto-js/enc-hex'), require('mime-types'), require('child_process'), require('util'), require('dotenv'), require('crypto-js/sha256'), require('glob-promise'), require('prompts'), require('moment'), require('socket.io-client'), require('@anthropic-ai/sdk'), require('@azure/openai'), require('openai'), require('@mozilla/readability'), require('jsdom'), require('showdown')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'waitasecond', 'fs/promises', 'path', 'prettier', 'prettier/parser-html', 'papaparse', 'crypto-js', 'crypto-js/enc-hex', 'mime-types', 'child_process', 'util', 'dotenv', 'crypto-js/sha256', 'glob-promise', 'prompts', 'moment', 'socket.io-client', '@anthropic-ai/sdk', '@azure/openai', 'openai', '@mozilla/readability', 'jsdom', 'showdown'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim, global.waitasecond, global.promises, global.path, global.prettier, global.parserHtml, global.papaparse, global.cryptoJs, global.hexEncoder, global.mimeTypes, global.child_process, global.util, global.dotenv, global.sha256, global.glob, global.prompts, global.moment, global.socket_ioClient, global.Anthropic, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
5
+ })(this, (function (exports, colors, commander, spaceTrim, waitasecond, promises, path, prettier, parserHtml, papaparse, cryptoJs, hexEncoder, mimeTypes, child_process, util, dotenv, sha256, glob, prompts, moment, socket_ioClient, Anthropic, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -24,23 +24,35 @@
24
24
  return Object.freeze(n);
25
25
  }
26
26
 
27
+ var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
27
28
  var commander__default = /*#__PURE__*/_interopDefaultLegacy(commander);
28
29
  var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
29
- var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
30
30
  var parserHtml__default = /*#__PURE__*/_interopDefaultLegacy(parserHtml);
31
31
  var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
32
32
  var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
33
33
  var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
34
34
  var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
35
+ var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
36
+ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
35
37
  var Anthropic__default = /*#__PURE__*/_interopDefaultLegacy(Anthropic);
36
38
  var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
37
39
 
38
40
  // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
39
41
  /**
40
- * The version of the Promptbook library
42
+ * The version of the Book language
43
+ *
44
+ * @see https://github.com/webgptorg/book
45
+ */
46
+ var BOOK_LANGUAGE_VERSION = '1.0.0';
47
+ /**
48
+ * The version of the Promptbook engine
49
+ *
50
+ * @see https://github.com/webgptorg/promptbook
51
+ */
52
+ var PROMPTBOOK_ENGINE_VERSION = '0.74.0-11';
53
+ /**
54
+ * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
41
55
  */
42
- var PROMPTBOOK_VERSION = '0.73.0';
43
- // TODO: [main] !!!! List here all the versions and annotate + put into script
44
56
 
45
57
  /*! *****************************************************************************
46
58
  Copyright (c) Microsoft Corporation.
@@ -161,31 +173,6 @@
161
173
  return to.concat(ar || Array.prototype.slice.call(from));
162
174
  }
163
175
 
164
- /**
165
- * This error type indicates that you try to use a feature that is not available in the current environment
166
- *
167
- * @public exported from `@promptbook/core`
168
- */
169
- var EnvironmentMismatchError = /** @class */ (function (_super) {
170
- __extends(EnvironmentMismatchError, _super);
171
- function EnvironmentMismatchError(message) {
172
- var _this = _super.call(this, message) || this;
173
- _this.name = 'EnvironmentMismatchError';
174
- Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
175
- return _this;
176
- }
177
- return EnvironmentMismatchError;
178
- }(Error));
179
-
180
- /**
181
- * Detects if the code is running in a Node.js environment
182
- *
183
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
184
- *
185
- * @public exported from `@promptbook/utils`
186
- */
187
- var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
188
-
189
176
  /**
190
177
  * Returns the same value that is passed as argument.
191
178
  * No side effects.
@@ -414,6 +401,12 @@
414
401
  */
415
402
  var CLAIM = "Build responsible, controlled and transparent applications on top of LLM models!";
416
403
  // <- TODO: [🐊] Pick the best claim
404
+ /**
405
+ * When the title is not provided, the default title is used
406
+ *
407
+ * @public exported from `@promptbook/core`
408
+ */
409
+ var DEFAULT_TITLE = "Untitled";
417
410
  /**
418
411
  * Warning message for the generated sections and files files
419
412
  *
@@ -527,6 +520,15 @@
527
520
  * @private within the repository
528
521
  */
529
522
  var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
523
+ /**
524
+ * The thresholds for the relative time in the `moment` NPM package.
525
+ *
526
+ * @see https://momentjscom.readthedocs.io/en/latest/moment/07-customization/13-relative-time-threshold/
527
+ * @private within the repository - too low-level in comparison with other constants
528
+ */
529
+ var MOMENT_ARG_THRESHOLDS = {
530
+ 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.
531
+ };
530
532
  /**
531
533
  * @@@
532
534
  *
@@ -557,12 +559,6 @@
557
559
  * @public exported from `@promptbook/core`
558
560
  */
559
561
  var DEFAULT_IS_VERBOSE = false;
560
- /**
561
- * @@@
562
- *
563
- * @public exported from `@promptbook/core`
564
- */
565
- var DEFAULT_IS_AUTO_INSTALLED = false;
566
562
  /**
567
563
  * @@@
568
564
  *
@@ -576,6 +572,31 @@
576
572
  * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
577
573
  */
578
574
 
575
+ /**
576
+ * This error type indicates that you try to use a feature that is not available in the current environment
577
+ *
578
+ * @public exported from `@promptbook/core`
579
+ */
580
+ var EnvironmentMismatchError = /** @class */ (function (_super) {
581
+ __extends(EnvironmentMismatchError, _super);
582
+ function EnvironmentMismatchError(message) {
583
+ var _this = _super.call(this, message) || this;
584
+ _this.name = 'EnvironmentMismatchError';
585
+ Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
586
+ return _this;
587
+ }
588
+ return EnvironmentMismatchError;
589
+ }(Error));
590
+
591
+ /**
592
+ * Detects if the code is running in a Node.js environment
593
+ *
594
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
595
+ *
596
+ * @public exported from `@promptbook/utils`
597
+ */
598
+ var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
599
+
579
600
  /**
580
601
  * Initializes `about` command for Promptbook CLI utilities
581
602
  *
@@ -587,12 +608,12 @@
587
608
  makeCommand.description(spaceTrim__default["default"]("\n Tells about Promptbook CLI and its abilities\n "));
588
609
  makeCommand.action(function () { return __awaiter(_this, void 0, void 0, function () {
589
610
  return __generator(this, function (_a) {
590
- console.info(colors__default["default"].cyan("Promptbook"));
591
- console.info(colors__default["default"].cyan(CLAIM));
592
- console.info(colors__default["default"].cyan("Version: ".concat(PROMPTBOOK_VERSION)));
611
+ console.info(colors__default["default"].bold(colors__default["default"].cyan("Promptbook: ".concat(CLAIM))));
612
+ console.info(colors__default["default"].cyan("Book language version: ".concat(BOOK_LANGUAGE_VERSION)));
613
+ console.info(colors__default["default"].cyan("Promptbook engine version: ".concat(PROMPTBOOK_ENGINE_VERSION)));
614
+ console.info(colors__default["default"].cyan("https://github.com/webgptorg/promptbook"));
593
615
  console.info(colors__default["default"].cyan("https://ptbk.io"));
594
- process.exit(0);
595
- return [2 /*return*/];
616
+ return [2 /*return*/, process.exit(0)];
596
617
  });
597
618
  }); });
598
619
  }
@@ -623,8 +644,7 @@
623
644
  case 1:
624
645
  _b.sent();
625
646
  console.info(colors__default["default"].rainbow("Nice to meet you!"));
626
- process.exit(0);
627
- return [2 /*return*/];
647
+ return [2 /*return*/, process.exit(0)];
628
648
  }
629
649
  });
630
650
  });
@@ -708,13 +728,13 @@
708
728
  /**
709
729
  * Converts promptbook in JSON format to string format
710
730
  *
711
- * @param pipelineJson Promptbook in JSON format (.ptbk.json)
712
- * @returns Promptbook in string format (.ptbk.md)
731
+ * @param pipelineJson Promptbook in JSON format (.book.json)
732
+ * @returns Promptbook in string format (.book.md)
713
733
  * @public exported from `@promptbook/core`
714
734
  */
715
735
  function pipelineJsonToString(pipelineJson) {
716
736
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
717
- var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, promptbookVersion = pipelineJson.promptbookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
737
+ var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, bookVersion = pipelineJson.bookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
718
738
  var pipelineString = "# ".concat(title);
719
739
  if (description) {
720
740
  pipelineString += '\n\n';
@@ -724,8 +744,10 @@
724
744
  if (pipelineUrl) {
725
745
  commands.push("PIPELINE URL ".concat(pipelineUrl));
726
746
  }
727
- commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
728
- // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
747
+ if (bookVersion !== "undefined") {
748
+ commands.push("BOOK VERSION ".concat(bookVersion));
749
+ }
750
+ // TODO: [main] !!!!!! This increase size of the bundle and is probbably not necessary
729
751
  pipelineString = prettifyMarkdown(pipelineString);
730
752
  try {
731
753
  for (var _g = __values(parameters.filter(function (_a) {
@@ -905,7 +927,7 @@
905
927
  * TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
906
928
  * TODO: [🏛] Maybe make some markdown builder
907
929
  * TODO: [🏛] Escape all
908
- * TODO: [🧠] Should be in generated .ptbk.md file GENERATOR_WARNING
930
+ * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
909
931
  */
910
932
 
911
933
  /**
@@ -1053,6 +1075,188 @@
1053
1075
  },
1054
1076
  });
1055
1077
 
1078
+ /**
1079
+ * @@@
1080
+ *
1081
+ * @public exported from `@promptbook/utils`
1082
+ */
1083
+ function deepClone(objectValue) {
1084
+ return JSON.parse(JSON.stringify(objectValue));
1085
+ /*
1086
+ TODO: [🧠] Is there a better implementation?
1087
+ > const propertyNames = Object.getOwnPropertyNames(objectValue);
1088
+ > for (const propertyName of propertyNames) {
1089
+ > const value = (objectValue as really_any)[propertyName];
1090
+ > if (value && typeof value === 'object') {
1091
+ > deepClone(value);
1092
+ > }
1093
+ > }
1094
+ > return Object.assign({}, objectValue);
1095
+ */
1096
+ }
1097
+ /**
1098
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
1099
+ */
1100
+
1101
+ /**
1102
+ * Function `addUsage` will add multiple usages into one
1103
+ *
1104
+ * Note: If you provide 0 values, it returns ZERO_USAGE
1105
+ *
1106
+ * @public exported from `@promptbook/core`
1107
+ */
1108
+ function addUsage() {
1109
+ var usageItems = [];
1110
+ for (var _i = 0; _i < arguments.length; _i++) {
1111
+ usageItems[_i] = arguments[_i];
1112
+ }
1113
+ return usageItems.reduce(function (acc, item) {
1114
+ var e_1, _a, e_2, _b;
1115
+ var _c;
1116
+ acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
1117
+ try {
1118
+ for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
1119
+ var key = _e.value;
1120
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1121
+ //@ts-ignore
1122
+ if (item.input[key]) {
1123
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1124
+ //@ts-ignore
1125
+ acc.input[key].value += item.input[key].value || 0;
1126
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1127
+ //@ts-ignore
1128
+ if (item.input[key].isUncertain) {
1129
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1130
+ //@ts-ignore
1131
+ acc.input[key].isUncertain = true;
1132
+ }
1133
+ }
1134
+ }
1135
+ }
1136
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1137
+ finally {
1138
+ try {
1139
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
1140
+ }
1141
+ finally { if (e_1) throw e_1.error; }
1142
+ }
1143
+ try {
1144
+ for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
1145
+ var key = _g.value;
1146
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1147
+ //@ts-ignore
1148
+ if (item.output[key]) {
1149
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1150
+ //@ts-ignore
1151
+ acc.output[key].value += item.output[key].value || 0;
1152
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1153
+ //@ts-ignore
1154
+ if (item.output[key].isUncertain) {
1155
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1156
+ //@ts-ignore
1157
+ acc.output[key].isUncertain = true;
1158
+ }
1159
+ }
1160
+ }
1161
+ }
1162
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1163
+ finally {
1164
+ try {
1165
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
1166
+ }
1167
+ finally { if (e_2) throw e_2.error; }
1168
+ }
1169
+ return acc;
1170
+ }, deepClone(ZERO_USAGE));
1171
+ }
1172
+
1173
+ /**
1174
+ * Intercepts LLM tools and counts total usage of the tools
1175
+ *
1176
+ * @param llmTools LLM tools to be intercepted with usage counting
1177
+ * @returns LLM tools with same functionality with added total cost counting
1178
+ * @public exported from `@promptbook/core`
1179
+ */
1180
+ function countTotalUsage(llmTools) {
1181
+ var _this = this;
1182
+ var totalUsage = ZERO_USAGE;
1183
+ var proxyTools = {
1184
+ get title() {
1185
+ // TODO: [🧠] Maybe put here some suffix
1186
+ return llmTools.title;
1187
+ },
1188
+ get description() {
1189
+ // TODO: [🧠] Maybe put here some suffix
1190
+ return llmTools.description;
1191
+ },
1192
+ checkConfiguration: function () {
1193
+ return __awaiter(this, void 0, void 0, function () {
1194
+ return __generator(this, function (_a) {
1195
+ return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
1196
+ });
1197
+ });
1198
+ },
1199
+ listModels: function () {
1200
+ return /* not await */ llmTools.listModels();
1201
+ },
1202
+ getTotalUsage: function () {
1203
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
1204
+ return totalUsage;
1205
+ },
1206
+ };
1207
+ if (llmTools.callChatModel !== undefined) {
1208
+ proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1209
+ var promptResult;
1210
+ return __generator(this, function (_a) {
1211
+ switch (_a.label) {
1212
+ case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
1213
+ case 1:
1214
+ promptResult = _a.sent();
1215
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1216
+ return [2 /*return*/, promptResult];
1217
+ }
1218
+ });
1219
+ }); };
1220
+ }
1221
+ if (llmTools.callCompletionModel !== undefined) {
1222
+ proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1223
+ var promptResult;
1224
+ return __generator(this, function (_a) {
1225
+ switch (_a.label) {
1226
+ case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
1227
+ case 1:
1228
+ promptResult = _a.sent();
1229
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1230
+ return [2 /*return*/, promptResult];
1231
+ }
1232
+ });
1233
+ }); };
1234
+ }
1235
+ if (llmTools.callEmbeddingModel !== undefined) {
1236
+ proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1237
+ var promptResult;
1238
+ return __generator(this, function (_a) {
1239
+ switch (_a.label) {
1240
+ case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
1241
+ case 1:
1242
+ promptResult = _a.sent();
1243
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1244
+ return [2 /*return*/, promptResult];
1245
+ }
1246
+ });
1247
+ }); };
1248
+ }
1249
+ // <- Note: [🤖]
1250
+ return proxyTools;
1251
+ }
1252
+ /**
1253
+ * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
1254
+ * TODO: [🧠] Is there some meaningfull way how to test this util
1255
+ * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
1256
+ * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
1257
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1258
+ */
1259
+
1056
1260
  /**
1057
1261
  * This error indicates errors during the execution of the pipeline
1058
1262
  *
@@ -1361,189 +1565,7 @@
1361
1565
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1362
1566
  */
1363
1567
 
1364
- /**
1365
- * @@@
1366
- *
1367
- * @public exported from `@promptbook/utils`
1368
- */
1369
- function deepClone(objectValue) {
1370
- return JSON.parse(JSON.stringify(objectValue));
1371
- /*
1372
- TODO: [🧠] Is there a better implementation?
1373
- > const propertyNames = Object.getOwnPropertyNames(objectValue);
1374
- > for (const propertyName of propertyNames) {
1375
- > const value = (objectValue as really_any)[propertyName];
1376
- > if (value && typeof value === 'object') {
1377
- > deepClone(value);
1378
- > }
1379
- > }
1380
- > return Object.assign({}, objectValue);
1381
- */
1382
- }
1383
- /**
1384
- * TODO: [🧠] Is there a way how to meaningfully test this utility
1385
- */
1386
-
1387
- /**
1388
- * Function `addUsage` will add multiple usages into one
1389
- *
1390
- * Note: If you provide 0 values, it returns ZERO_USAGE
1391
- *
1392
- * @public exported from `@promptbook/core`
1393
- */
1394
- function addUsage() {
1395
- var usageItems = [];
1396
- for (var _i = 0; _i < arguments.length; _i++) {
1397
- usageItems[_i] = arguments[_i];
1398
- }
1399
- return usageItems.reduce(function (acc, item) {
1400
- var e_1, _a, e_2, _b;
1401
- var _c;
1402
- acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
1403
- try {
1404
- for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
1405
- var key = _e.value;
1406
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1407
- //@ts-ignore
1408
- if (item.input[key]) {
1409
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1410
- //@ts-ignore
1411
- acc.input[key].value += item.input[key].value || 0;
1412
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1413
- //@ts-ignore
1414
- if (item.input[key].isUncertain) {
1415
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1416
- //@ts-ignore
1417
- acc.input[key].isUncertain = true;
1418
- }
1419
- }
1420
- }
1421
- }
1422
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1423
- finally {
1424
- try {
1425
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
1426
- }
1427
- finally { if (e_1) throw e_1.error; }
1428
- }
1429
- try {
1430
- for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
1431
- var key = _g.value;
1432
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1433
- //@ts-ignore
1434
- if (item.output[key]) {
1435
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1436
- //@ts-ignore
1437
- acc.output[key].value += item.output[key].value || 0;
1438
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1439
- //@ts-ignore
1440
- if (item.output[key].isUncertain) {
1441
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1442
- //@ts-ignore
1443
- acc.output[key].isUncertain = true;
1444
- }
1445
- }
1446
- }
1447
- }
1448
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
1449
- finally {
1450
- try {
1451
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
1452
- }
1453
- finally { if (e_2) throw e_2.error; }
1454
- }
1455
- return acc;
1456
- }, deepClone(ZERO_USAGE));
1457
- }
1458
-
1459
- /**
1460
- * Intercepts LLM tools and counts total usage of the tools
1461
- *
1462
- * @param llmTools LLM tools to be intercepted with usage counting
1463
- * @returns LLM tools with same functionality with added total cost counting
1464
- * @public exported from `@promptbook/core`
1465
- */
1466
- function countTotalUsage(llmTools) {
1467
- var _this = this;
1468
- var totalUsage = ZERO_USAGE;
1469
- var proxyTools = {
1470
- get title() {
1471
- // TODO: [🧠] Maybe put here some suffix
1472
- return llmTools.title;
1473
- },
1474
- get description() {
1475
- // TODO: [🧠] Maybe put here some suffix
1476
- return llmTools.description;
1477
- },
1478
- checkConfiguration: function () {
1479
- return __awaiter(this, void 0, void 0, function () {
1480
- return __generator(this, function (_a) {
1481
- return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
1482
- });
1483
- });
1484
- },
1485
- listModels: function () {
1486
- return /* not await */ llmTools.listModels();
1487
- },
1488
- getTotalUsage: function () {
1489
- // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
1490
- return totalUsage;
1491
- },
1492
- };
1493
- if (llmTools.callChatModel !== undefined) {
1494
- proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1495
- var promptResult;
1496
- return __generator(this, function (_a) {
1497
- switch (_a.label) {
1498
- case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
1499
- case 1:
1500
- promptResult = _a.sent();
1501
- totalUsage = addUsage(totalUsage, promptResult.usage);
1502
- return [2 /*return*/, promptResult];
1503
- }
1504
- });
1505
- }); };
1506
- }
1507
- if (llmTools.callCompletionModel !== undefined) {
1508
- proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1509
- var promptResult;
1510
- return __generator(this, function (_a) {
1511
- switch (_a.label) {
1512
- case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
1513
- case 1:
1514
- promptResult = _a.sent();
1515
- totalUsage = addUsage(totalUsage, promptResult.usage);
1516
- return [2 /*return*/, promptResult];
1517
- }
1518
- });
1519
- }); };
1520
- }
1521
- if (llmTools.callEmbeddingModel !== undefined) {
1522
- proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1523
- var promptResult;
1524
- return __generator(this, function (_a) {
1525
- switch (_a.label) {
1526
- case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
1527
- case 1:
1528
- promptResult = _a.sent();
1529
- totalUsage = addUsage(totalUsage, promptResult.usage);
1530
- return [2 /*return*/, promptResult];
1531
- }
1532
- });
1533
- }); };
1534
- }
1535
- // <- Note: [🤖]
1536
- return proxyTools;
1537
- }
1538
- /**
1539
- * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
1540
- * TODO: [🧠] Is there some meaningfull way how to test this util
1541
- * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
1542
- * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
1543
- * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1544
- */
1545
-
1546
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
1568
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.book.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.book.md"}];
1547
1569
 
1548
1570
  /**
1549
1571
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -1618,7 +1640,7 @@
1618
1640
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
1619
1641
  return false;
1620
1642
  }
1621
- // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
1643
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
1622
1644
  return true;
1623
1645
  }
1624
1646
 
@@ -1718,7 +1740,7 @@
1718
1740
  if (!url.startsWith('https://')) {
1719
1741
  return false;
1720
1742
  }
1721
- if (!url.endsWith('.ptbk.md')) {
1743
+ if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.book.md') || url.endsWith('.ptbk'))) {
1722
1744
  return false;
1723
1745
  }
1724
1746
  if (url.includes('#')) {
@@ -1787,9 +1809,9 @@
1787
1809
  // <- Note: [🚲]
1788
1810
  throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1789
1811
  }
1790
- if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1812
+ if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
1791
1813
  // <- Note: [🚲]
1792
- throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1814
+ throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.bookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1793
1815
  }
1794
1816
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
1795
1817
  if (!Array.isArray(pipeline.parameters)) {
@@ -2578,10 +2600,6 @@
2578
2600
  * @private within the repository
2579
2601
  */
2580
2602
  function TODO_USE() {
2581
- var value = [];
2582
- for (var _i = 0; _i < arguments.length; _i++) {
2583
- value[_i] = arguments[_i];
2584
- }
2585
2603
  }
2586
2604
 
2587
2605
  /**
@@ -2640,22 +2658,12 @@
2640
2658
  formatName: 'CSV',
2641
2659
  aliases: ['SPREADSHEET', 'TABLE'],
2642
2660
  isValid: function (value, settings, schema) {
2643
- // TODO: Implement CSV validation
2644
- TODO_USE(value /* <- TODO: Use value here */);
2645
- TODO_USE(settings /* <- TODO: Use settings here */);
2646
- TODO_USE(schema /* <- TODO: Use schema here */);
2647
2661
  return true;
2648
2662
  },
2649
2663
  canBeValid: function (partialValue, settings, schema) {
2650
- TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2651
- TODO_USE(settings /* <- TODO: Use settings here */);
2652
- TODO_USE(schema /* <- TODO: Use schema here */);
2653
2664
  return true;
2654
2665
  },
2655
2666
  heal: function (value, settings, schema) {
2656
- TODO_USE(value /* <- TODO: Use partialValue here */);
2657
- TODO_USE(settings /* <- TODO: Use settings here */);
2658
- TODO_USE(schema /* <- TODO: Use schema here */);
2659
2667
  throw new Error('Not implemented');
2660
2668
  },
2661
2669
  subvalueDefinitions: [
@@ -2774,20 +2782,12 @@
2774
2782
  formatName: 'JSON',
2775
2783
  mimeType: 'application/json',
2776
2784
  isValid: function (value, settings, schema) {
2777
- TODO_USE(schema /* <- TODO: Use schema here */);
2778
- TODO_USE(settings /* <- TODO: Use settings here */);
2779
2785
  return isValidJsonString(value);
2780
2786
  },
2781
2787
  canBeValid: function (partialValue, settings, schema) {
2782
- TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2783
- TODO_USE(settings /* <- TODO: Use settings here */);
2784
- TODO_USE(schema /* <- TODO: Use schema here */);
2785
2788
  return true;
2786
2789
  },
2787
2790
  heal: function (value, settings, schema) {
2788
- TODO_USE(value /* <- TODO: Use partialValue here */);
2789
- TODO_USE(settings /* <- TODO: Use settings here */);
2790
- TODO_USE(schema /* <- TODO: Use schema here */);
2791
2791
  throw new Error('Not implemented');
2792
2792
  },
2793
2793
  subvalueDefinitions: [],
@@ -2869,21 +2869,12 @@
2869
2869
  formatName: 'XML',
2870
2870
  mimeType: 'application/xml',
2871
2871
  isValid: function (value, settings, schema) {
2872
- TODO_USE(value /* <- TODO: Use value here */);
2873
- TODO_USE(settings /* <- TODO: Use settings here */);
2874
- TODO_USE(schema /* <- TODO: Use schema here */);
2875
2872
  return true;
2876
2873
  },
2877
2874
  canBeValid: function (partialValue, settings, schema) {
2878
- TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2879
- TODO_USE(settings /* <- TODO: Use settings here */);
2880
- TODO_USE(schema /* <- TODO: Use schema here */);
2881
2875
  return true;
2882
2876
  },
2883
2877
  heal: function (value, settings, schema) {
2884
- TODO_USE(value /* <- TODO: Use partialValue here */);
2885
- TODO_USE(settings /* <- TODO: Use settings here */);
2886
- TODO_USE(schema /* <- TODO: Use schema here */);
2887
2878
  throw new Error('Not implemented');
2888
2879
  },
2889
2880
  subvalueDefinitions: [],
@@ -3116,27 +3107,6 @@
3116
3107
  return [input];
3117
3108
  }
3118
3109
 
3119
- /**
3120
- * Just says that the variable is not used but should be kept
3121
- * No side effects.
3122
- *
3123
- * Note: It can be usefull for:
3124
- *
3125
- * 1) Suppressing eager optimization of unused imports
3126
- * 2) Suppressing eslint errors of unused variables in the tests
3127
- * 3) Keeping the type of the variable for type testing
3128
- *
3129
- * @param value any values
3130
- * @returns void
3131
- * @private within the repository
3132
- */
3133
- function keepUnused() {
3134
- var valuesToKeep = [];
3135
- for (var _i = 0; _i < arguments.length; _i++) {
3136
- valuesToKeep[_i] = arguments[_i];
3137
- }
3138
- }
3139
-
3140
3110
  /**
3141
3111
  * Replaces parameters in template with values from parameters object
3142
3112
  *
@@ -3249,10 +3219,12 @@
3249
3219
  * @public exported from `@promptbook/utils`
3250
3220
  */
3251
3221
  function countPages(text) {
3252
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
3253
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3254
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3255
- return pageCount;
3222
+ if (text === '') {
3223
+ return 0;
3224
+ }
3225
+ var pagesByLinesCount = Math.ceil(countLines(text) / 44);
3226
+ var pagesByCharactersCount = Math.ceil(countCharacters(text) / 2772);
3227
+ return Math.max(pagesByLinesCount, pagesByCharactersCount);
3256
3228
  }
3257
3229
 
3258
3230
  /**
@@ -3793,7 +3765,7 @@
3793
3765
  promptTitle: template.title,
3794
3766
  promptMessage: replaceParameters(template.description || '', parameters),
3795
3767
  defaultValue: replaceParameters(preparedContent, parameters),
3796
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3768
+ // TODO: [🧠] !! Figure out how to define placeholder in .book.md file
3797
3769
  placeholder: undefined,
3798
3770
  priority: priority,
3799
3771
  }))];
@@ -3891,7 +3863,6 @@
3891
3863
  $ongoingTemplateResult.$resultString = extractJsonBlock($ongoingTemplateResult.$resultString || '');
3892
3864
  }
3893
3865
  catch (error) {
3894
- keepUnused(error);
3895
3866
  throw new ExpectError(spaceTrim.spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3896
3867
  /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3897
3868
  }
@@ -4069,7 +4040,6 @@
4069
4040
  function getContextForTemplate(template) {
4070
4041
  return __awaiter(this, void 0, void 0, function () {
4071
4042
  return __generator(this, function (_a) {
4072
- TODO_USE(template);
4073
4043
  return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
4074
4044
  });
4075
4045
  });
@@ -4082,11 +4052,9 @@
4082
4052
  */
4083
4053
  function getKnowledgeForTemplate(options) {
4084
4054
  return __awaiter(this, void 0, void 0, function () {
4085
- var preparedPipeline, template;
4055
+ var preparedPipeline;
4086
4056
  return __generator(this, function (_a) {
4087
- preparedPipeline = options.preparedPipeline, template = options.template;
4088
- // TODO: [♨] Implement Better - use real index and keyword search from `template` and {examples}
4089
- TODO_USE(template);
4057
+ preparedPipeline = options.preparedPipeline, options.template;
4090
4058
  return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
4091
4059
  var content = _a.content;
4092
4060
  return "- ".concat(content);
@@ -4103,8 +4071,6 @@
4103
4071
  function getExamplesForTemplate(template) {
4104
4072
  return __awaiter(this, void 0, void 0, function () {
4105
4073
  return __generator(this, function (_a) {
4106
- // TODO: [♨] Implement Better - use real index and keyword search
4107
- TODO_USE(template);
4108
4074
  return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
4109
4075
  });
4110
4076
  });
@@ -4123,13 +4089,13 @@
4123
4089
  switch (_b.label) {
4124
4090
  case 0:
4125
4091
  preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
4126
- return [4 /*yield*/, getContextForTemplate(template)];
4092
+ return [4 /*yield*/, getContextForTemplate()];
4127
4093
  case 1:
4128
4094
  context = _b.sent();
4129
4095
  return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
4130
4096
  case 2:
4131
4097
  knowledge = _b.sent();
4132
- return [4 /*yield*/, getExamplesForTemplate(template)];
4098
+ return [4 /*yield*/, getExamplesForTemplate()];
4133
4099
  case 3:
4134
4100
  examples = _b.sent();
4135
4101
  currentDate = new Date().toISOString();
@@ -4364,8 +4330,8 @@
4364
4330
  executionReport = {
4365
4331
  pipelineUrl: preparedPipeline.pipelineUrl,
4366
4332
  title: preparedPipeline.title,
4367
- promptbookUsedVersion: PROMPTBOOK_VERSION,
4368
- promptbookRequestedVersion: preparedPipeline.promptbookVersion,
4333
+ promptbookUsedVersion: PROMPTBOOK_ENGINE_VERSION,
4334
+ promptbookRequestedVersion: preparedPipeline.bookVersion,
4369
4335
  description: preparedPipeline.description,
4370
4336
  promptExecutions: [],
4371
4337
  };
@@ -4714,7 +4680,7 @@
4714
4680
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
4715
4681
  _b = createPipelineExecutor;
4716
4682
  _c = {};
4717
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.ptbk.md')];
4683
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book.md')];
4718
4684
  case 1:
4719
4685
  preparePersonaExecutor = _b.apply(void 0, [(_c.pipeline = _d.sent(),
4720
4686
  _c.tools = tools,
@@ -5211,16 +5177,13 @@
5211
5177
  function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5212
5178
  var _a;
5213
5179
  return __awaiter(this, void 0, void 0, function () {
5214
- var sourceContent, name, _b, _c, rootDirname, _d,
5215
- // <- TODO: process.cwd() if running in Node.js
5216
- isVerbose, url, response_1, mimeType, filename_1, fileExtension, mimeType;
5180
+ var sourceContent, name, _b, _c, rootDirname, url, response_1, mimeType, filename_1, fileExtension, mimeType;
5217
5181
  return __generator(this, function (_e) {
5218
5182
  switch (_e.label) {
5219
5183
  case 0:
5220
5184
  sourceContent = knowledgeSource.sourceContent;
5221
5185
  name = knowledgeSource.name;
5222
- _b = options || {}, _c = _b.rootDirname, rootDirname = _c === void 0 ? null : _c, _d = _b.isVerbose, isVerbose = _d === void 0 ? DEFAULT_IS_VERBOSE : _d;
5223
- TODO_USE(isVerbose);
5186
+ _b = options || {}, _c = _b.rootDirname, rootDirname = _c === void 0 ? null : _c, _b.isVerbose;
5224
5187
  if (!name) {
5225
5188
  name = sourceContentToName(sourceContent);
5226
5189
  }
@@ -5474,12 +5437,12 @@
5474
5437
  */
5475
5438
  function clonePipeline(pipeline) {
5476
5439
  // Note: Not using spread operator (...) because @@@
5477
- var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, promptbookVersion = pipeline.promptbookVersion, description = pipeline.description, parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
5440
+ var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, bookVersion = pipeline.bookVersion, description = pipeline.description, parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
5478
5441
  return {
5479
5442
  pipelineUrl: pipelineUrl,
5480
5443
  sourceFile: sourceFile,
5481
5444
  title: title,
5482
- promptbookVersion: promptbookVersion,
5445
+ bookVersion: bookVersion,
5483
5446
  description: description,
5484
5447
  parameters: parameters,
5485
5448
  templates: templates,
@@ -5500,15 +5463,13 @@
5500
5463
  */
5501
5464
  function prepareTemplates(pipeline, tools, options) {
5502
5465
  return __awaiter(this, void 0, void 0, function () {
5503
- var _a, maxParallelCount, templates, parameters, knowledgePiecesCount, templatesPrepared;
5466
+ var _a, maxParallelCount, templates, knowledgePiecesCount, templatesPrepared;
5504
5467
  var _this = this;
5505
5468
  return __generator(this, function (_b) {
5506
5469
  switch (_b.label) {
5507
5470
  case 0:
5508
5471
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? DEFAULT_MAX_PARALLEL_COUNT : _a;
5509
- templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
5510
- // TODO: [main] !! Apply examples to each template (if missing and is for the template defined)
5511
- TODO_USE(parameters);
5472
+ templates = pipeline.templates, pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
5512
5473
  templatesPrepared = new Array(templates.length);
5513
5474
  return [4 /*yield*/, forEachAsync(templates, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (template, index) { return __awaiter(_this, void 0, void 0, function () {
5514
5475
  var dependentParameterNames, preparedContent, preparedTemplate;
@@ -5578,7 +5539,7 @@
5578
5539
  currentPreparation = {
5579
5540
  id: 1,
5580
5541
  // TODO: [🍥]> date: $currentDate(),
5581
- promptbookVersion: PROMPTBOOK_VERSION,
5542
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
5582
5543
  usage: ZERO_USAGE,
5583
5544
  };
5584
5545
  preparations = [
@@ -5693,7 +5654,7 @@
5693
5654
  throw new ParseError("Source not valid");
5694
5655
  }
5695
5656
  if (sourceContent.startsWith('../') || sourceContent.startsWith('/') || /^[A-Z]:[\\/]+/i.test(sourceContent)) {
5696
- throw new ParseError("Source cannot be outside of the .ptbk.md folder");
5657
+ throw new ParseError("Source cannot be outside of the .book.md folder");
5697
5658
  }
5698
5659
  return {
5699
5660
  type: 'KNOWLEDGE',
@@ -5718,7 +5679,6 @@
5718
5679
  * Note: This is used in `pipelineJsonToString` utility
5719
5680
  */
5720
5681
  stringify: function (command) {
5721
- keepUnused(command);
5722
5682
  return "---"; // <- TODO: [🛋] Implement
5723
5683
  },
5724
5684
  /**
@@ -5727,7 +5687,6 @@
5727
5687
  * Note: This is used in `pipelineJsonToString` utility
5728
5688
  */
5729
5689
  takeFromPipelineJson: function (pipelineJson) {
5730
- keepUnused(pipelineJson);
5731
5690
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5732
5691
  },
5733
5692
  };
@@ -5910,7 +5869,6 @@
5910
5869
  * Note: This is used in `pipelineJsonToString` utility
5911
5870
  */
5912
5871
  stringify: function (command) {
5913
- keepUnused(command);
5914
5872
  return "---"; // <- TODO: [🛋] Implement
5915
5873
  },
5916
5874
  /**
@@ -5919,7 +5877,6 @@
5919
5877
  * Note: This is used in `pipelineJsonToString` utility
5920
5878
  */
5921
5879
  takeFromTemplateJson: function ($templateJson) {
5922
- keepUnused($templateJson);
5923
5880
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5924
5881
  },
5925
5882
  };
@@ -6151,7 +6108,6 @@
6151
6108
  * Note: This is used in `pipelineJsonToString` utility
6152
6109
  */
6153
6110
  stringify: function (command) {
6154
- keepUnused(command);
6155
6111
  return "---"; // <- TODO: [🛋] Implement
6156
6112
  },
6157
6113
  /**
@@ -6160,7 +6116,6 @@
6160
6116
  * Note: This is used in `pipelineJsonToString` utility
6161
6117
  */
6162
6118
  takeFromTemplateJson: function ($templateJson) {
6163
- keepUnused($templateJson);
6164
6119
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6165
6120
  },
6166
6121
  };
@@ -6349,7 +6304,7 @@
6349
6304
  /**
6350
6305
  * Parses the foreach command
6351
6306
  *
6352
- * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.ptbk.md` file
6307
+ * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.book.md` file
6353
6308
  *
6354
6309
  * @see `documentationUrl` for more details
6355
6310
  * @private within the commands folder
@@ -6479,7 +6434,6 @@
6479
6434
  inputSubparameterNames: inputSubparameterNames,
6480
6435
  outputSubparameterName: outputSubparameterName,
6481
6436
  };
6482
- keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
6483
6437
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
6484
6438
  },
6485
6439
  /**
@@ -6488,7 +6442,6 @@
6488
6442
  * Note: This is used in `pipelineJsonToString` utility
6489
6443
  */
6490
6444
  stringify: function (command) {
6491
- keepUnused(command);
6492
6445
  return "---"; // <- TODO: [🛋] Implement
6493
6446
  },
6494
6447
  /**
@@ -6497,12 +6450,11 @@
6497
6450
  * Note: This is used in `pipelineJsonToString` utility
6498
6451
  */
6499
6452
  takeFromTemplateJson: function ($templateJson) {
6500
- keepUnused($templateJson);
6501
6453
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6502
6454
  },
6503
6455
  };
6504
6456
  /**
6505
- * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
6457
+ * TODO: [🍭] Make .book.md file with examples of the FOREACH with wrong parsing and logic
6506
6458
  */
6507
6459
 
6508
6460
  /**
@@ -6565,7 +6517,6 @@
6565
6517
  * Note: This is used in `pipelineJsonToString` utility
6566
6518
  */
6567
6519
  stringify: function (command) {
6568
- keepUnused(command);
6569
6520
  return "---"; // <- TODO: [🛋] Implement
6570
6521
  },
6571
6522
  /**
@@ -6574,7 +6525,6 @@
6574
6525
  * Note: This is used in `pipelineJsonToString` utility
6575
6526
  */
6576
6527
  takeFromTemplateJson: function ($templateJson) {
6577
- keepUnused($templateJson);
6578
6528
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6579
6529
  },
6580
6530
  };
@@ -6637,7 +6587,6 @@
6637
6587
  * Note: This is used in `pipelineJsonToString` utility
6638
6588
  */
6639
6589
  stringify: function (command) {
6640
- keepUnused(command);
6641
6590
  return "---"; // <- TODO: [🛋] Implement
6642
6591
  },
6643
6592
  /**
@@ -6646,7 +6595,6 @@
6646
6595
  * Note: This is used in `pipelineJsonToString` utility
6647
6596
  */
6648
6597
  takeFromTemplateJson: function ($templateJson) {
6649
- keepUnused($templateJson);
6650
6598
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6651
6599
  },
6652
6600
  };
@@ -6782,7 +6730,6 @@
6782
6730
  * Note: This is used in `pipelineJsonToString` utility
6783
6731
  */
6784
6732
  stringify: function (command) {
6785
- keepUnused(command);
6786
6733
  return "---"; // <- TODO: [🛋] Implement
6787
6734
  },
6788
6735
  /**
@@ -6791,7 +6738,6 @@
6791
6738
  * Note: This is used in `pipelineJsonToString` utility
6792
6739
  */
6793
6740
  takeFromPipelineJson: function (pipelineJson) {
6794
- keepUnused(pipelineJson);
6795
6741
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6796
6742
  },
6797
6743
  /**
@@ -6800,7 +6746,6 @@
6800
6746
  * Note: This is used in `pipelineJsonToString` utility
6801
6747
  */
6802
6748
  takeFromTemplateJson: function ($templateJson) {
6803
- keepUnused($templateJson);
6804
6749
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6805
6750
  },
6806
6751
  };
@@ -6874,7 +6819,6 @@
6874
6819
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6875
6820
  */
6876
6821
  $applyToPipelineJson: function (command, $pipelineJson) {
6877
- keepUnused(command, $pipelineJson);
6878
6822
  // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
6879
6823
  },
6880
6824
  /**
@@ -6883,7 +6827,6 @@
6883
6827
  * Note: `$` is used to indicate that this function mutates given `templateJson`
6884
6828
  */
6885
6829
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
6886
- keepUnused(command, $templateJson, $pipelineJson);
6887
6830
  // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
6888
6831
  },
6889
6832
  /**
@@ -6892,7 +6835,6 @@
6892
6835
  * Note: This is used in `pipelineJsonToString` utility
6893
6836
  */
6894
6837
  stringify: function (command) {
6895
- keepUnused(command);
6896
6838
  return "---"; // <- TODO: [🛋] Implement
6897
6839
  },
6898
6840
  /**
@@ -6901,7 +6843,6 @@
6901
6843
  * Note: This is used in `pipelineJsonToString` utility
6902
6844
  */
6903
6845
  takeFromPipelineJson: function (pipelineJson) {
6904
- keepUnused(pipelineJson);
6905
6846
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6906
6847
  },
6907
6848
  /**
@@ -6910,7 +6851,6 @@
6910
6851
  * Note: This is used in `pipelineJsonToString` utility
6911
6852
  */
6912
6853
  takeFromTemplateJson: function ($templateJson) {
6913
- keepUnused($templateJson);
6914
6854
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6915
6855
  },
6916
6856
  };
@@ -6982,7 +6922,6 @@
6982
6922
  * Note: This is used in `pipelineJsonToString` utility
6983
6923
  */
6984
6924
  stringify: function (command) {
6985
- keepUnused(command);
6986
6925
  return "---"; // <- TODO: [🛋] Implement
6987
6926
  },
6988
6927
  /**
@@ -6991,7 +6930,6 @@
6991
6930
  * Note: This is used in `pipelineJsonToString` utility
6992
6931
  */
6993
6932
  takeFromPipelineJson: function (pipelineJson) {
6994
- keepUnused(pipelineJson);
6995
6933
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6996
6934
  },
6997
6935
  /**
@@ -7000,7 +6938,6 @@
7000
6938
  * Note: This is used in `pipelineJsonToString` utility
7001
6939
  */
7002
6940
  takeFromTemplateJson: function ($templateJson) {
7003
- keepUnused($templateJson);
7004
6941
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7005
6942
  },
7006
6943
  };
@@ -7119,7 +7056,6 @@
7119
7056
  * Note: This is used in `pipelineJsonToString` utility
7120
7057
  */
7121
7058
  stringify: function (command) {
7122
- keepUnused(command);
7123
7059
  return "---"; // <- TODO: [🛋] Implement
7124
7060
  },
7125
7061
  /**
@@ -7128,85 +7064,82 @@
7128
7064
  * Note: This is used in `pipelineJsonToString` utility
7129
7065
  */
7130
7066
  takeFromTemplateJson: function ($templateJson) {
7131
- keepUnused($templateJson);
7132
7067
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7133
7068
  },
7134
7069
  };
7135
7070
 
7136
7071
  /**
7137
- * Parses the PROMPTBOOK_VERSION command
7072
+ * Parses the BOOK_VERSION command
7138
7073
  *
7139
7074
  * @see `documentationUrl` for more details
7140
7075
  * @private within the commands folder
7141
7076
  */
7142
- var promptbookVersionCommandParser = {
7077
+ var bookVersionCommandParser = {
7143
7078
  /**
7144
7079
  * Name of the command
7145
7080
  */
7146
- name: 'PROMPTBOOK_VERSION',
7147
- aliasNames: ['PTBK_VERSION', 'PTBK_V', 'PTBKV'],
7081
+ name: 'BOOK_VERSION',
7082
+ aliasNames: ['PTBK_VERSION', 'PROMPTBOOK_VERSION', 'BOOK'],
7148
7083
  /**
7149
7084
  * BOILERPLATE command can be used in:
7150
7085
  */
7151
7086
  isUsedInPipelineHead: true,
7152
7087
  isUsedInPipelineTemplate: false,
7153
7088
  /**
7154
- * Description of the PROMPTBOOK_VERSION command
7089
+ * Description of the BOOK_VERSION command
7155
7090
  */
7156
- description: "Which version of the promptbook is the .ptbk.md using",
7091
+ description: "Which version of the Book language is the .book.md using",
7157
7092
  /**
7158
7093
  * Link to documentation
7159
7094
  */
7160
7095
  documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/69',
7161
7096
  /**
7162
- * Example usages of the PROMPTBOOK_VERSION command
7097
+ * Example usages of the BOOK_VERSION command
7163
7098
  */
7164
- examples: ["PROMPTBOOK VERSION ".concat(PROMPTBOOK_VERSION), "PTBKV ".concat(PROMPTBOOK_VERSION)],
7099
+ examples: ["BOOK VERSION ".concat(BOOK_LANGUAGE_VERSION), "BOOK ".concat(BOOK_LANGUAGE_VERSION)],
7165
7100
  /**
7166
- * Parses the PROMPTBOOK_VERSION command
7101
+ * Parses the BOOK_VERSION command
7167
7102
  */
7168
7103
  parse: function (input) {
7169
7104
  var args = input.args;
7170
- var promptbookVersion = args.pop();
7171
- if (promptbookVersion === undefined) {
7105
+ var bookVersion = args.pop();
7106
+ if (bookVersion === undefined) {
7172
7107
  throw new ParseError("Version is required");
7173
7108
  }
7174
- if (!isValidPromptbookVersion(promptbookVersion)) {
7175
- throw new ParseError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
7109
+ if (!isValidPromptbookVersion(bookVersion)) {
7110
+ throw new ParseError("Invalid Promptbook version \"".concat(bookVersion, "\""));
7176
7111
  }
7177
- if (args.length > 0) {
7112
+ if (args.length > 0 && !(((args.length === 1 && args[0]) || '').toUpperCase() === 'VERSION')) {
7178
7113
  throw new ParseError("Can not have more than one Promptbook version");
7179
7114
  }
7180
7115
  return {
7181
- type: 'PROMPTBOOK_VERSION',
7182
- promptbookVersion: promptbookVersion,
7116
+ type: 'BOOK_VERSION',
7117
+ bookVersion: bookVersion,
7183
7118
  };
7184
7119
  },
7185
7120
  /**
7186
- * Apply the PROMPTBOOK_VERSION command to the `pipelineJson`
7121
+ * Apply the BOOK_VERSION command to the `pipelineJson`
7187
7122
  *
7188
7123
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7189
7124
  */
7190
7125
  $applyToPipelineJson: function (command, $pipelineJson) {
7191
7126
  // TODO: Warn if the version is overridden
7192
- $pipelineJson.promptbookVersion = command.promptbookVersion;
7127
+ $pipelineJson.bookVersion = command.bookVersion;
7193
7128
  },
7194
7129
  /**
7195
- * Converts the PROMPTBOOK_VERSION command back to string
7130
+ * Converts the BOOK_VERSION command back to string
7196
7131
  *
7197
7132
  * Note: This is used in `pipelineJsonToString` utility
7198
7133
  */
7199
7134
  stringify: function (command) {
7200
- keepUnused(command);
7201
7135
  return "---"; // <- TODO: [🛋] Implement
7202
7136
  },
7203
7137
  /**
7204
- * Reads the PROMPTBOOK_VERSION command from the `PipelineJson`
7138
+ * Reads the BOOK_VERSION command from the `PipelineJson`
7205
7139
  *
7206
7140
  * Note: This is used in `pipelineJsonToString` utility
7207
7141
  */
7208
7142
  takeFromPipelineJson: function (pipelineJson) {
7209
- keepUnused(pipelineJson);
7210
7143
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7211
7144
  },
7212
7145
  };
@@ -7244,9 +7177,9 @@
7244
7177
  * Example usages of the URL command
7245
7178
  */
7246
7179
  examples: [
7247
- 'PIPELINE URL https://promptbook.studio/library/write-cv.ptbk.md',
7248
- 'URL https://promptbook.studio/library/write-cv.ptbk.md',
7249
- 'https://promptbook.studio/library/write-cv.ptbk.md',
7180
+ 'PIPELINE URL https://promptbook.studio/library/write-cv.book.md',
7181
+ 'URL https://promptbook.studio/library/write-cv.book.md',
7182
+ 'https://promptbook.studio/library/write-cv.book.md',
7250
7183
  ],
7251
7184
  /**
7252
7185
  * Parses the URL command
@@ -7300,7 +7233,6 @@
7300
7233
  * Note: This is used in `pipelineJsonToString` utility
7301
7234
  */
7302
7235
  stringify: function (command) {
7303
- keepUnused(command);
7304
7236
  return "---"; // <- TODO: [🛋] Implement
7305
7237
  },
7306
7238
  /**
@@ -7309,7 +7241,6 @@
7309
7241
  * Note: This is used in `pipelineJsonToString` utility
7310
7242
  */
7311
7243
  takeFromPipelineJson: function (pipelineJson) {
7312
- keepUnused(pipelineJson);
7313
7244
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7314
7245
  },
7315
7246
  };
@@ -7346,8 +7277,7 @@
7346
7277
  * Parses the ACTION command
7347
7278
  */
7348
7279
  parse: function (input) {
7349
- var args = input.args;
7350
- TODO_USE(args);
7280
+ input.args;
7351
7281
  return {
7352
7282
  type: 'ACTION',
7353
7283
  };
@@ -7358,7 +7288,6 @@
7358
7288
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7359
7289
  */
7360
7290
  $applyToPipelineJson: function (command, $pipelineJson) {
7361
- keepUnused(command, $pipelineJson);
7362
7291
  console.error(new NotYetImplementedError('[🛠] Actions are not implemented yet'));
7363
7292
  },
7364
7293
  /**
@@ -7367,7 +7296,6 @@
7367
7296
  * Note: This is used in `pipelineJsonToString` utility
7368
7297
  */
7369
7298
  stringify: function (command) {
7370
- keepUnused(command);
7371
7299
  throw new NotYetImplementedError('[🛠] Actions are not implemented yet');
7372
7300
  },
7373
7301
  /**
@@ -7376,7 +7304,6 @@
7376
7304
  * Note: This is used in `pipelineJsonToString` utility
7377
7305
  */
7378
7306
  takeFromPipelineJson: function (pipelineJson) {
7379
- keepUnused(pipelineJson);
7380
7307
  throw new NotYetImplementedError('[🛠] Actions are not implemented yet');
7381
7308
  },
7382
7309
  };
@@ -7416,9 +7343,7 @@
7416
7343
  * Parses the INSTRUMENT command
7417
7344
  */
7418
7345
  parse: function (input) {
7419
- var args = input.args;
7420
- // TODO: [🛠] Implement
7421
- TODO_USE(args);
7346
+ input.args;
7422
7347
  return {
7423
7348
  type: 'INSTRUMENT',
7424
7349
  };
@@ -7429,7 +7354,6 @@
7429
7354
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7430
7355
  */
7431
7356
  $applyToPipelineJson: function (command, $pipelineJson) {
7432
- keepUnused(command, $pipelineJson);
7433
7357
  console.error(new NotYetImplementedError('[🛠] Instruments are not implemented yet'));
7434
7358
  },
7435
7359
  /**
@@ -7438,7 +7362,6 @@
7438
7362
  * Note: This is used in `pipelineJsonToString` utility
7439
7363
  */
7440
7364
  stringify: function (command) {
7441
- keepUnused(command);
7442
7365
  throw new NotYetImplementedError('[🛠] Instruments are not implemented yet');
7443
7366
  },
7444
7367
  /**
@@ -7447,7 +7370,6 @@
7447
7370
  * Note: This is used in `pipelineJsonToString` utility
7448
7371
  */
7449
7372
  takeFromPipelineJson: function (pipelineJson) {
7450
- keepUnused(pipelineJson);
7451
7373
  throw new NotYetImplementedError('[🛠] Instruments are not implemented yet');
7452
7374
  },
7453
7375
  };
@@ -7458,7 +7380,7 @@
7458
7380
  /**
7459
7381
  * Parses the boilerplate command
7460
7382
  *
7461
- * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.ptbk.md` file
7383
+ * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.book.md` file
7462
7384
  *
7463
7385
  * @see `documentationUrl` for more details
7464
7386
  * @private within the commands folder
@@ -7512,8 +7434,7 @@
7512
7434
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7513
7435
  */
7514
7436
  $applyToPipelineJson: function (command, $pipelineJson) {
7515
- keepUnused(command, $pipelineJson);
7516
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7437
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7517
7438
  },
7518
7439
  /**
7519
7440
  * Apply the BOILERPLATE command to the `pipelineJson`
@@ -7521,8 +7442,7 @@
7521
7442
  * Note: `$` is used to indicate that this function mutates given `templateJson`
7522
7443
  */
7523
7444
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
7524
- keepUnused(command, $templateJson, $pipelineJson);
7525
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7445
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7526
7446
  },
7527
7447
  /**
7528
7448
  * Converts the BOILERPLATE command back to string
@@ -7530,7 +7450,6 @@
7530
7450
  * Note: This is used in `pipelineJsonToString` utility
7531
7451
  */
7532
7452
  stringify: function (command) {
7533
- keepUnused(command);
7534
7453
  return "---"; // <- TODO: [🛋] Implement
7535
7454
  },
7536
7455
  /**
@@ -7539,8 +7458,7 @@
7539
7458
  * Note: This is used in `pipelineJsonToString` utility
7540
7459
  */
7541
7460
  takeFromPipelineJson: function (pipelineJson) {
7542
- keepUnused(pipelineJson);
7543
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7461
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7544
7462
  },
7545
7463
  /**
7546
7464
  * Reads the BOILERPLATE command from the `TemplateJson`
@@ -7548,8 +7466,7 @@
7548
7466
  * Note: This is used in `pipelineJsonToString` utility
7549
7467
  */
7550
7468
  takeFromTemplateJson: function ($templateJson) {
7551
- keepUnused($templateJson);
7552
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7469
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7553
7470
  },
7554
7471
  };
7555
7472
 
@@ -7566,7 +7483,7 @@
7566
7483
  modelCommandParser,
7567
7484
  parameterCommandParser,
7568
7485
  postprocessCommandParser,
7569
- promptbookVersionCommandParser,
7486
+ bookVersionCommandParser,
7570
7487
  urlCommandParser,
7571
7488
  knowledgeCommandParser,
7572
7489
  actionCommandParser,
@@ -7718,9 +7635,7 @@
7718
7635
  var _loop_1 = function (commandParser) {
7719
7636
  // <- Note: [🦦] Its strange that this type assertion is needed
7720
7637
  var name_1 = commandParser.name, isUsedInPipelineHead = commandParser.isUsedInPipelineHead, isUsedInPipelineTemplate = commandParser.isUsedInPipelineTemplate, aliasNames = commandParser.aliasNames, deprecatedNames = commandParser.deprecatedNames, parse = commandParser.parse;
7721
- if (just(false)) {
7722
- keepUnused( /* for better indentation */);
7723
- }
7638
+ if (just(false)) ;
7724
7639
  else if (usagePlace === 'PIPELINE_HEAD' && !isUsedInPipelineHead) {
7725
7640
  return "continue";
7726
7641
  }
@@ -7880,7 +7795,7 @@
7880
7795
  return;
7881
7796
  }
7882
7797
  if (!section.startsWith('#')) {
7883
- section = "# Untitled\n\n".concat(section);
7798
+ section = "# ".concat(DEFAULT_TITLE, "\n\n").concat(section);
7884
7799
  }
7885
7800
  sections.push(section);
7886
7801
  buffer = [];
@@ -7944,7 +7859,7 @@
7944
7859
  var e_1, _a;
7945
7860
  var sections = splitMarkdownIntoSections(markdown);
7946
7861
  if (sections.length === 0) {
7947
- return '# Untitled';
7862
+ return "# ".concat(DEFAULT_TITLE);
7948
7863
  }
7949
7864
  var flattenedMarkdown = '';
7950
7865
  var parsedSections = sections.map(parseMarkdownSection);
@@ -7955,7 +7870,7 @@
7955
7870
  }
7956
7871
  else {
7957
7872
  parsedSections.unshift(firstSection);
7958
- flattenedMarkdown += "# Untitled" + "\n\n"; // <- [🧠] Maybe 3 new lines?
7873
+ flattenedMarkdown += "# ".concat(DEFAULT_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
7959
7874
  }
7960
7875
  try {
7961
7876
  for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
@@ -8027,17 +7942,17 @@
8027
7942
  * Note: This function does not validate logic of the pipeline only the parsing
8028
7943
  * Note: This function acts as compilation process
8029
7944
  *
8030
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8031
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
7945
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
7946
+ * @returns {Promptbook} compiled in JSON format (.book.json)
8032
7947
  * @throws {ParseError} if the promptbook string is not valid
8033
7948
  * @public exported from `@promptbook/core`
8034
7949
  */
8035
7950
  function pipelineStringToJsonSync(pipelineString) {
8036
- var e_1, _a, e_2, _b;
7951
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
8037
7952
  var $pipelineJson = {
8038
7953
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
8039
7954
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
8040
- promptbookVersion: undefined /* <- Note: By default no explicit version */,
7955
+ bookVersion: undefined /* <- Note: By default no explicit version */,
8041
7956
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
8042
7957
  parameters: [],
8043
7958
  templates: [],
@@ -8060,11 +7975,18 @@
8060
7975
  }
8061
7976
  // =============================================================
8062
7977
  // Note: 1️⃣ Parsing of the markdown into object
7978
+ if (pipelineString.startsWith('#!')) {
7979
+ var _e = __read(pipelineString.split('\n')), shebangLine_1 = _e[0], restLines = _e.slice(1);
7980
+ if (!(shebangLine_1 || '').includes('ptbk')) {
7981
+ throw new ParseError(spaceTrim.spaceTrim(function (block) { return "\n It seems that you try to parse a book file which has non-standard shebang line for book files:\n Shebang line must contain 'ptbk'\n\n You have:\n ".concat(block(shebangLine_1 || '(empty line)'), "\n\n It should look like this:\n #!/usr/bin/env ptbk\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
7982
+ }
7983
+ pipelineString = restLines.join('\n');
7984
+ }
8063
7985
  pipelineString = removeContentComments(pipelineString);
8064
7986
  pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
8065
7987
  pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
8066
7988
  pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
8067
- var _c = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _c[0], pipelineSections = _c.slice(1); /* <- Note: [🥞] */
7989
+ var _f = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _f[0], pipelineSections = _f.slice(1); /* <- Note: [🥞] */
8068
7990
  if (pipelineHead === undefined) {
8069
7991
  throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Pipeline head is not defined\n\n ".concat(block(getPipelineIdentification()), "\n\n This should never happen, because the pipeline already flattened\n "); }));
8070
7992
  }
@@ -8092,6 +8014,8 @@
8092
8014
  if (parameterDescription) {
8093
8015
  existingParameter.description = parameterDescription;
8094
8016
  }
8017
+ existingParameter.isInput = existingParameter.isInput || isInput;
8018
+ existingParameter.isOutput = existingParameter.isOutput || isOutput;
8095
8019
  }
8096
8020
  else {
8097
8021
  $pipelineJson.parameters.push({
@@ -8154,10 +8078,10 @@
8154
8078
  finally { if (e_1) throw e_1.error; }
8155
8079
  }
8156
8080
  var _loop_2 = function (section) {
8157
- var e_3, _d;
8081
+ var e_5, _l, e_6, _m;
8158
8082
  // TODO: Parse template description (the content out of the codeblock and lists)
8159
8083
  var listItems_2 = extractAllListItemsFromMarkdown(section.content);
8160
- var _e = extractOneBlockFromMarkdown(section.content), language = _e.language, content = _e.content;
8084
+ var _o = extractOneBlockFromMarkdown(section.content), language = _o.language, content = _o.content;
8161
8085
  // TODO: [🎾][1] DRY description
8162
8086
  var description_1 = section.content;
8163
8087
  // Note: Remove codeblocks - TODO: [🎾]
@@ -8198,7 +8122,7 @@
8198
8122
  }) === false) {
8199
8123
  templateCommandParser.$applyToTemplateJson({ type: 'TEMPLATE', templateType: 'PROMPT_TEMPLATE' }, $templateJson, $pipelineJson);
8200
8124
  }
8201
- var _loop_3 = function (listItem, command) {
8125
+ var _loop_4 = function (listItem, command) {
8202
8126
  var commandParser = getParserForCommand(command);
8203
8127
  if (commandParser.isUsedInPipelineTemplate !== true /* <- Note: [🦦][4] */) {
8204
8128
  throw new ParseError(spaceTrim.spaceTrim(function (block) { return "\n Command ".concat(command.type, " is not allowed in the template of the promptbook ONLY at the pipeline head\n\n ").concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
@@ -8221,17 +8145,17 @@
8221
8145
  };
8222
8146
  try {
8223
8147
  // TODO [♓️] List commands and before apply order them to achieve order-agnostic commands
8224
- for (var commands_1 = (e_3 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
8225
- var _f = commands_1_1.value, listItem = _f.listItem, command = _f.command;
8226
- _loop_3(listItem, command);
8148
+ for (var commands_1 = (e_5 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
8149
+ var _p = commands_1_1.value, listItem = _p.listItem, command = _p.command;
8150
+ _loop_4(listItem, command);
8227
8151
  }
8228
8152
  }
8229
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
8153
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
8230
8154
  finally {
8231
8155
  try {
8232
- if (commands_1_1 && !commands_1_1.done && (_d = commands_1.return)) _d.call(commands_1);
8156
+ if (commands_1_1 && !commands_1_1.done && (_l = commands_1.return)) _l.call(commands_1);
8233
8157
  }
8234
- finally { if (e_3) throw e_3.error; }
8158
+ finally { if (e_5) throw e_5.error; }
8235
8159
  }
8236
8160
  // TODO: [🍧] Should be done in TEMPLATE command
8237
8161
  if ($templateJson.templateType === 'SCRIPT_TEMPLATE') {
@@ -8245,6 +8169,26 @@
8245
8169
  language;
8246
8170
  }
8247
8171
  $templateJson.dependentParameterNames = Array.from(extractParameterNamesFromTemplate($templateJson));
8172
+ try {
8173
+ for (var _q = (e_6 = void 0, __values($templateJson.dependentParameterNames)), _r = _q.next(); !_r.done; _r = _q.next()) {
8174
+ var parameterName = _r.value;
8175
+ // TODO: [🧠] This definition should be made first in the template
8176
+ defineParam({
8177
+ parameterName: parameterName,
8178
+ parameterDescription: null,
8179
+ isInput: false,
8180
+ isOutput: false,
8181
+ // <- Note: In this case null+false+false means that we do not know yet if it is input or output and we will set it later
8182
+ });
8183
+ }
8184
+ }
8185
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
8186
+ finally {
8187
+ try {
8188
+ if (_r && !_r.done && (_m = _q.return)) _m.call(_q);
8189
+ }
8190
+ finally { if (e_6) throw e_6.error; }
8191
+ }
8248
8192
  /*
8249
8193
  // TODO: [🍧] This should be checked in `MODEL` command + better error message
8250
8194
  if ($templateJson.templateType !== 'PROMPT_TEMPLATE' && $templateJson.modelRequirements !== undefined) {
@@ -8283,12 +8227,54 @@
8283
8227
  try {
8284
8228
  if (pipelineSections_1_1 && !pipelineSections_1_1.done && (_b = pipelineSections_1.return)) _b.call(pipelineSections_1);
8285
8229
  }
8286
- finally { if (e_2) throw e_2.error; }
8230
+ finally { if (e_2) throw e_2.error; }
8231
+ }
8232
+ // =============================================================
8233
+ // Note: 5️⃣ Mark parameters as INPUT if not explicitly set
8234
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isInput; })) {
8235
+ var _loop_3 = function (parameter) {
8236
+ var isThisParameterResulting = $pipelineJson.templates.some(function (template) { return template.resultingParameterName === parameter.name; });
8237
+ if (!isThisParameterResulting) {
8238
+ parameter.isInput = true;
8239
+ }
8240
+ };
8241
+ try {
8242
+ for (var _g = __values($pipelineJson.parameters), _h = _g.next(); !_h.done; _h = _g.next()) {
8243
+ var parameter = _h.value;
8244
+ _loop_3(parameter);
8245
+ }
8246
+ }
8247
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
8248
+ finally {
8249
+ try {
8250
+ if (_h && !_h.done && (_c = _g.return)) _c.call(_g);
8251
+ }
8252
+ finally { if (e_3) throw e_3.error; }
8253
+ }
8254
+ }
8255
+ // =============================================================
8256
+ // Note: 6️⃣ Mark all non-INPUT parameters as OUTPUT if any OUTPUT is not set
8257
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isOutput; })) {
8258
+ try {
8259
+ for (var _j = __values($pipelineJson.parameters), _k = _j.next(); !_k.done; _k = _j.next()) {
8260
+ var parameter = _k.value;
8261
+ if (!parameter.isInput) {
8262
+ parameter.isOutput = true;
8263
+ }
8264
+ }
8265
+ }
8266
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
8267
+ finally {
8268
+ try {
8269
+ if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
8270
+ }
8271
+ finally { if (e_4) throw e_4.error; }
8272
+ }
8287
8273
  }
8288
8274
  // =============================================================
8289
- // Note: 5️⃣ Cleanup of undefined values
8275
+ // Note: 7️⃣ Cleanup of undefined values
8290
8276
  $pipelineJson.templates.forEach(function (templates) {
8291
- var e_4, _a;
8277
+ var e_7, _a;
8292
8278
  try {
8293
8279
  for (var _b = __values(Object.entries(templates)), _c = _b.next(); !_c.done; _c = _b.next()) {
8294
8280
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8297,16 +8283,16 @@
8297
8283
  }
8298
8284
  }
8299
8285
  }
8300
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
8286
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
8301
8287
  finally {
8302
8288
  try {
8303
8289
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8304
8290
  }
8305
- finally { if (e_4) throw e_4.error; }
8291
+ finally { if (e_7) throw e_7.error; }
8306
8292
  }
8307
8293
  });
8308
8294
  $pipelineJson.parameters.forEach(function (parameter) {
8309
- var e_5, _a;
8295
+ var e_8, _a;
8310
8296
  try {
8311
8297
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
8312
8298
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8315,12 +8301,12 @@
8315
8301
  }
8316
8302
  }
8317
8303
  }
8318
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
8304
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
8319
8305
  finally {
8320
8306
  try {
8321
8307
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8322
8308
  }
8323
- finally { if (e_5) throw e_5.error; }
8309
+ finally { if (e_8) throw e_8.error; }
8324
8310
  }
8325
8311
  });
8326
8312
  // =============================================================
@@ -8349,10 +8335,10 @@
8349
8335
  * Note: This function does not validate logic of the pipeline only the parsing
8350
8336
  * Note: This function acts as compilation process
8351
8337
  *
8352
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8338
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
8353
8339
  * @param tools - Tools for the preparation and scraping - if not provided together with `llm`, the preparation will be skipped
8354
8340
  * @param options - Options and tools for the compilation
8355
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
8341
+ * @returns {Promptbook} compiled in JSON format (.book.json)
8356
8342
  * @throws {ParseError} if the promptbook string is not valid
8357
8343
  * @public exported from `@promptbook/core`
8358
8344
  */
@@ -8430,8 +8416,7 @@
8430
8416
  if (!$isRunningInNode()) {
8431
8417
  throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
8432
8418
  }
8433
- var _a = (options || {}).isVerbose, isVerbose = _a === void 0 ? DEFAULT_IS_VERBOSE : _a;
8434
- TODO_USE(isVerbose);
8419
+ (options || {}).isVerbose;
8435
8420
  return {
8436
8421
  stat: promises.stat,
8437
8422
  access: promises.access,
@@ -8677,7 +8662,7 @@
8677
8662
  */
8678
8663
  function $provideExecutablesForNode(options) {
8679
8664
  return __awaiter(this, void 0, void 0, function () {
8680
- var _a, _b, isAutoInstalled, _c, isVerbose;
8665
+ var _a;
8681
8666
  var _d;
8682
8667
  return __generator(this, function (_e) {
8683
8668
  switch (_e.label) {
@@ -8685,9 +8670,7 @@
8685
8670
  if (!$isRunningInNode()) {
8686
8671
  throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8687
8672
  }
8688
- _a = options || {}, _b = _a.isAutoInstalled, isAutoInstalled = _b === void 0 ? DEFAULT_IS_AUTO_INSTALLED : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c;
8689
- TODO_USE(isAutoInstalled); // <- TODO: [🔱][🧠] Auto-install the executables
8690
- TODO_USE(isVerbose);
8673
+ _a = options || {}, _a.isAutoInstalled, _a.isVerbose;
8691
8674
  _d = {};
8692
8675
  return [4 /*yield*/, locatePandoc()];
8693
8676
  case 1:
@@ -8944,7 +8927,7 @@
8944
8927
  */
8945
8928
  function $provideScrapersForNode(tools, options) {
8946
8929
  return __awaiter(this, void 0, void 0, function () {
8947
- var _a, _b, isAutoInstalled, _c, isVerbose, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8930
+ var _a, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8948
8931
  var e_1, _f;
8949
8932
  return __generator(this, function (_g) {
8950
8933
  switch (_g.label) {
@@ -8952,9 +8935,7 @@
8952
8935
  if (!$isRunningInNode()) {
8953
8936
  throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8954
8937
  }
8955
- _a = options || {}, _b = _a.isAutoInstalled, isAutoInstalled = _b === void 0 ? DEFAULT_IS_AUTO_INSTALLED : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c;
8956
- TODO_USE(isAutoInstalled);
8957
- TODO_USE(isVerbose);
8938
+ _a = options || {}, _a.isAutoInstalled, _a.isVerbose;
8958
8939
  scrapers = [];
8959
8940
  _g.label = 1;
8960
8941
  case 1:
@@ -9729,13 +9710,13 @@
9729
9710
  return [4 /*yield*/, listAllFiles(path$1, isRecursive, tools.fs)];
9730
9711
  case 1:
9731
9712
  fileNames = _b.sent();
9732
- // Note: First load all .ptbk.json and then .ptbk.md files
9733
- // .ptbk.json can be prepared so it is faster to load
9713
+ // Note: First load all .book.json and then .book.md files
9714
+ // .book.json can be prepared so it is faster to load
9734
9715
  fileNames.sort(function (a, b) {
9735
- if (a.endsWith('.ptbk.json') && b.endsWith('.ptbk.md')) {
9716
+ if (a.endsWith('.book.json') && b.endsWith('.book.md')) {
9736
9717
  return -1;
9737
9718
  }
9738
- if (a.endsWith('.ptbk.md') && b.endsWith('.ptbk.json')) {
9719
+ if (a.endsWith('.book.md') && b.endsWith('.book.json')) {
9739
9720
  return 1;
9740
9721
  }
9741
9722
  return 0;
@@ -9752,7 +9733,7 @@
9752
9733
  case 1:
9753
9734
  _e.trys.push([1, 8, , 9]);
9754
9735
  pipeline = null;
9755
- if (!fileName.endsWith('.ptbk.md')) return [3 /*break*/, 4];
9736
+ if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
9756
9737
  return [4 /*yield*/, promises.readFile(fileName, 'utf-8')];
9757
9738
  case 2:
9758
9739
  pipelineString = (_e.sent());
@@ -9764,7 +9745,7 @@
9764
9745
  pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
9765
9746
  return [3 /*break*/, 7];
9766
9747
  case 4:
9767
- if (!fileName.endsWith('.ptbk.json')) return [3 /*break*/, 6];
9748
+ if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
9768
9749
  _d = (_c = JSON).parse;
9769
9750
  return [4 /*yield*/, promises.readFile(fileName, 'utf-8')];
9770
9751
  case 5:
@@ -9932,7 +9913,7 @@
9932
9913
  return pipelineJsonStringified;
9933
9914
  }
9934
9915
  /**
9935
- * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.ptbk.md
9916
+ * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.book.md
9936
9917
  * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
9937
9918
  * TODO: [🧠] Maybe more elegant solution than replacing via regex
9938
9919
  * TODO: [🍙] Make some standard order of json properties
@@ -10113,7 +10094,7 @@
10113
10094
  */
10114
10095
 
10115
10096
  /**
10116
- * Stores
10097
+ * Stores data in memory (HEAP)
10117
10098
  *
10118
10099
  * @public exported from `@promptbook/core`
10119
10100
  */
@@ -10243,13 +10224,18 @@
10243
10224
  promptResult = _c.sent();
10244
10225
  return [3 /*break*/, 11];
10245
10226
  case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
10246
- case 11: return [4 /*yield*/, storage.setItem(key, {
10227
+ case 11:
10228
+ // TODO: [🧠] !!!!!! How to do timing in mixed cache / non-cache situation
10229
+ // promptResult.timing: FromtoItems
10230
+ return [4 /*yield*/, storage.setItem(key, {
10247
10231
  date: $currentDate(),
10248
- promptbookVersion: PROMPTBOOK_VERSION,
10232
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
10249
10233
  prompt: prompt,
10250
10234
  promptResult: promptResult,
10251
10235
  })];
10252
10236
  case 12:
10237
+ // TODO: [🧠] !!!!!! How to do timing in mixed cache / non-cache situation
10238
+ // promptResult.timing: FromtoItems
10253
10239
  _c.sent();
10254
10240
  return [2 /*return*/, promptResult];
10255
10241
  }
@@ -10323,6 +10309,7 @@
10323
10309
  var _this = this;
10324
10310
  var makeCommand = program.command('make');
10325
10311
  makeCommand.description(spaceTrim__default["default"]("\n Makes a new pipeline collection in given folder\n "));
10312
+ // TODO: [🧅] DRY command arguments
10326
10313
  makeCommand.argument('[path]',
10327
10314
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10328
10315
  'Path to promptbook collection directory', './promptbook-collection');
@@ -10330,13 +10317,13 @@
10330
10317
  makeCommand.option('-f, --format <format>', spaceTrim__default["default"]("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
10331
10318
  makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
10332
10319
  makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
10333
- makeCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache", false);
10334
- makeCommand.option('--verbose', "Is output verbose", false);
10320
+ makeCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
10321
+ makeCommand.option('-v, --verbose', "Is output verbose", false);
10335
10322
  makeCommand.option('-o, --out-file <path>', spaceTrim__default["default"]("\n Where to save the builded collection\n\n Note: If you keep it \"".concat(DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME, "\" it will be saved in the root of the promptbook directory\n If you set it to a path, it will be saved in that path\n BUT you can use only one format and set correct extension\n ")), DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME);
10336
10323
  makeCommand.action(function (path$1, _a) {
10337
- var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reloadCache, isVerbose = _a.verbose, outFile = _a.outFile;
10324
+ var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reload, isVerbose = _a.verbose, outFile = _a.outFile;
10338
10325
  return __awaiter(_this, void 0, void 0, function () {
10339
- var formats, validations, options, fs, llm, executables, tools, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, collectionJsonItems, saveFile;
10326
+ var formats, validations, prepareAndScrapeOptions, fs, llm, executables, tools, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, collectionJsonItems, saveFile;
10340
10327
  var _d, e_2, _e, e_1, _f;
10341
10328
  var _this = this;
10342
10329
  return __generator(this, function (_g) {
@@ -10352,22 +10339,22 @@
10352
10339
  .filter(function (_) { return _ !== ''; });
10353
10340
  if (outFile !== DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME && formats.length !== 1) {
10354
10341
  console.error(colors__default["default"].red("You can only use one format if you specify --out-file"));
10355
- process.exit(1);
10342
+ return [2 /*return*/, process.exit(1)];
10356
10343
  }
10357
- options = {
10344
+ prepareAndScrapeOptions = {
10358
10345
  isVerbose: isVerbose,
10359
10346
  isCacheReloaded: isCacheReloaded,
10360
10347
  };
10361
- fs = $provideFilesystemForNode(options);
10362
- llm = $provideLlmToolsForCli(options);
10363
- return [4 /*yield*/, $provideExecutablesForNode(options)];
10348
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
10349
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
10350
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
10364
10351
  case 1:
10365
10352
  executables = _g.sent();
10366
10353
  _d = {
10367
10354
  llm: llm,
10368
10355
  fs: fs
10369
10356
  };
10370
- return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
10357
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
10371
10358
  case 2:
10372
10359
  tools = (_d.scrapers = _g.sent(),
10373
10360
  _d.script = [
@@ -10504,8 +10491,7 @@
10504
10491
  if (isVerbose) {
10505
10492
  console.info(colors__default["default"].cyan(usageToHuman(llm.getTotalUsage())));
10506
10493
  }
10507
- process.exit(0);
10508
- return [2 /*return*/];
10494
+ return [2 /*return*/, process.exit(0)];
10509
10495
  }
10510
10496
  });
10511
10497
  });
@@ -10513,7 +10499,6 @@
10513
10499
  }
10514
10500
  /**
10515
10501
  * TODO: [🥃][main] !!! Allow `ptbk make` without configuring any llm tools
10516
- * TODO: Maybe remove this command - "about" command should be enough?
10517
10502
  * TODO: [0] DRY Javascript and typescript - Maybe make ONLY typescript and for javascript just remove types
10518
10503
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
10519
10504
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
@@ -10658,7 +10643,7 @@
10658
10643
  function initializePrettifyCommand(program) {
10659
10644
  var _this = this;
10660
10645
  var prettifyCommand = program.command('prettify');
10661
- prettifyCommand.description(spaceTrim__default["default"]("\n Iterates over `.ptbk.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
10646
+ prettifyCommand.description(spaceTrim__default["default"]("\n Iterates over `.book.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
10662
10647
  prettifyCommand.argument('<filesGlob>',
10663
10648
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10664
10649
  'Pipelines to prettify as glob pattern');
@@ -10682,7 +10667,7 @@
10682
10667
  case 3:
10683
10668
  if (!!filenames_1_1.done) return [3 /*break*/, 10];
10684
10669
  filename = filenames_1_1.value;
10685
- if (!filename.endsWith('.ptbk.md') && isVerbose) {
10670
+ if (!filename.endsWith('.book.md') && isVerbose) {
10686
10671
  console.info(colors__default["default"].gray("Skipping ".concat(filename)));
10687
10672
  return [3 /*break*/, 9];
10688
10673
  }
@@ -10714,8 +10699,7 @@
10714
10699
  console.info(colors__default["default"].red("Prettify ".concat(error_1.name, " ").concat(filename)));
10715
10700
  console.error(colors__default["default"].bgRed(error_1.name /* <- 11:11 */));
10716
10701
  console.error(colors__default["default"].red(error_1.stack || error_1.message));
10717
- process.exit(1);
10718
- return [3 /*break*/, 9];
10702
+ return [2 /*return*/, process.exit(1)];
10719
10703
  case 9:
10720
10704
  filenames_1_1 = filenames_1.next();
10721
10705
  return [3 /*break*/, 3];
@@ -10732,8 +10716,7 @@
10732
10716
  return [7 /*endfinally*/];
10733
10717
  case 13:
10734
10718
  console.info(colors__default["default"].green("All pipelines are prettified"));
10735
- process.exit(0);
10736
- return [2 /*return*/];
10719
+ return [2 /*return*/, process.exit(0)];
10737
10720
  }
10738
10721
  });
10739
10722
  });
@@ -10745,6 +10728,606 @@
10745
10728
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
10746
10729
  */
10747
10730
 
10731
+ /**
10732
+ * Pretty print an embedding vector for logging
10733
+ *
10734
+ * @public exported from `@promptbook/core`
10735
+ */
10736
+ function embeddingVectorToString(embeddingVector) {
10737
+ var vectorLength = Math.pow(embeddingVector.reduce(function (acc, val) { return acc + Math.pow(val, 2); }, 0), 0.5);
10738
+ return "[EmbeddingVector; ".concat(embeddingVector.length, " dimensions; length: ").concat(vectorLength.toFixed(2), "; ").concat(embeddingVector.slice(0, 3).join(', '), "...]");
10739
+ }
10740
+
10741
+ /**
10742
+ * Format either small or big number
10743
+ *
10744
+ * @private within the repository
10745
+ */
10746
+ function formatNumber(value) {
10747
+ if (value === 0) {
10748
+ return '0';
10749
+ }
10750
+ for (var exponent = 0; exponent < 15; exponent++) {
10751
+ var factor = Math.pow(10, exponent);
10752
+ var valueRounded = Math.round(value * factor) / factor;
10753
+ if (Math.abs(value - valueRounded) / value <
10754
+ 0.001 /* <- TODO: Pass as option, pass to executionReportJsonToString as option */) {
10755
+ return valueRounded.toFixed(exponent);
10756
+ }
10757
+ }
10758
+ return value.toString();
10759
+ }
10760
+
10761
+ /**
10762
+ * Create a markdown table from a 2D array of strings
10763
+ *
10764
+ * @public exported from `@promptbook/markdown-utils`
10765
+ */
10766
+ function createMarkdownTable(table) {
10767
+ var columnWidths = table.reduce(function (widths, row) {
10768
+ row.forEach(function (subformat, columnIndex) {
10769
+ var cellLength = subformat.length;
10770
+ if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
10771
+ widths[columnIndex] = cellLength;
10772
+ }
10773
+ });
10774
+ return widths;
10775
+ }, []);
10776
+ var header = "| ".concat(table[0]
10777
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
10778
+ .join(' | '), " |");
10779
+ var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
10780
+ var rows = table.slice(1).map(function (row) {
10781
+ var paddedRow = row.map(function (subformat, columnIndex) {
10782
+ return subformat.padEnd(columnWidths[columnIndex]);
10783
+ });
10784
+ return "| ".concat(paddedRow.join(' | '), " |");
10785
+ });
10786
+ return __spreadArray([header, separator], __read(rows), false).join('\n');
10787
+ }
10788
+ /**
10789
+ * TODO: [🏛] This can be part of markdown builder
10790
+ */
10791
+
10792
+ /**
10793
+ * Function createMarkdownChart will draw a chart in markdown from ⬛+🟦 tiles
10794
+ *
10795
+ * @public exported from `@promptbook/markdown-utils`
10796
+ */
10797
+ function createMarkdownChart(options) {
10798
+ var e_1, _a;
10799
+ var nameHeader = options.nameHeader, valueHeader = options.valueHeader, items = options.items, width = options.width, unitName = options.unitName;
10800
+ var from = Math.min.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.from; })), false));
10801
+ var to = Math.max.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.to; })), false));
10802
+ var scale = width / (to - from);
10803
+ var table = [[nameHeader, valueHeader]];
10804
+ try {
10805
+ for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
10806
+ var item = items_1_1.value;
10807
+ var before = Math.round((item.from - from) * scale);
10808
+ var during = Math.round((item.to - item.from) * scale);
10809
+ var after = width - before - during;
10810
+ table.push([removeEmojis(item.title).trim(), '░'.repeat(before) + '█'.repeat(during) + '░'.repeat(after)]);
10811
+ }
10812
+ }
10813
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
10814
+ finally {
10815
+ try {
10816
+ if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
10817
+ }
10818
+ finally { if (e_1) throw e_1.error; }
10819
+ }
10820
+ 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_");
10821
+ return createMarkdownTable(table) + '\n\n' + legend;
10822
+ }
10823
+ /**
10824
+ * TODO: Maybe use Mermain Gant Diagrams
10825
+ * @see https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/
10826
+ */
10827
+
10828
+ /**
10829
+ * Function escapeMarkdownBlock will escape markdown block if needed
10830
+ * It is useful when you want have block in block
10831
+ *
10832
+ * @public exported from `@promptbook/markdown-utils`
10833
+ */
10834
+ function escapeMarkdownBlock(value) {
10835
+ return value.replace(/```/g, '\\`\\`\\`');
10836
+ }
10837
+ /**
10838
+ * TODO: [🏛] This can be part of markdown builder
10839
+ */
10840
+
10841
+ /**
10842
+ * Default options for generating an execution report string
10843
+ *
10844
+ * @public exported from `@promptbook/core`
10845
+ */
10846
+ var ExecutionReportStringOptionsDefaults = {
10847
+ taxRate: 0,
10848
+ chartsWidth: 36,
10849
+ };
10850
+
10851
+ /**
10852
+ * Count the duration of working time
10853
+ *
10854
+ * @private within the repository
10855
+ */
10856
+ function countWorkingDuration(items) {
10857
+ var e_1, _a;
10858
+ var steps = Array.from(new Set(items.flatMap(function (item) { return [item.from, item.to]; })));
10859
+ steps.sort(function (a, b) { return a - b; });
10860
+ var intervals = steps.map(function (step, index) { return [step, steps[index + 1] || 0]; }).slice(0, -1);
10861
+ var duration = 0;
10862
+ var _loop_1 = function (interval) {
10863
+ var _b = __read(interval, 2), from = _b[0], to = _b[1];
10864
+ if (items.some(function (item) { return item.from < to && item.to > from; })) {
10865
+ duration += to - from;
10866
+ }
10867
+ };
10868
+ try {
10869
+ for (var intervals_1 = __values(intervals), intervals_1_1 = intervals_1.next(); !intervals_1_1.done; intervals_1_1 = intervals_1.next()) {
10870
+ var interval = intervals_1_1.value;
10871
+ _loop_1(interval);
10872
+ }
10873
+ }
10874
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
10875
+ finally {
10876
+ try {
10877
+ if (intervals_1_1 && !intervals_1_1.done && (_a = intervals_1.return)) _a.call(intervals_1);
10878
+ }
10879
+ finally { if (e_1) throw e_1.error; }
10880
+ }
10881
+ return duration;
10882
+ }
10883
+
10884
+ /**
10885
+ * Converts execution report from JSON to string format
10886
+ *
10887
+ * @public exported from `@promptbook/core`
10888
+ */
10889
+ function executionReportJsonToString(executionReportJson, options) {
10890
+ var e_1, _a;
10891
+ var _b, _c, _d, _e, _f, _g;
10892
+ var _h = __assign(__assign({}, ExecutionReportStringOptionsDefaults), (options || {})), taxRate = _h.taxRate, chartsWidth = _h.chartsWidth;
10893
+ var executionReportString = spaceTrim.spaceTrim(function (block) { return "\n # ".concat(executionReportJson.title || 'Execution report', "\n\n ").concat(block(executionReportJson.description || ''), "\n "); });
10894
+ var headerList = [];
10895
+ if (executionReportJson.pipelineUrl) {
10896
+ headerList.push("PIPELINE URL ".concat(executionReportJson.pipelineUrl));
10897
+ }
10898
+ headerList.push("PROMPTBOOK VERSION ".concat(executionReportJson.promptbookUsedVersion) +
10899
+ (!executionReportJson.promptbookRequestedVersion
10900
+ ? ''
10901
+ : " *(requested ".concat(executionReportJson.promptbookRequestedVersion, ")*")));
10902
+ if (executionReportJson.promptExecutions.length !== 0) {
10903
+ // TODO: What if startedAt OR/AND completedAt is not defined?
10904
+ var startedAt = moment__default["default"](Math.min.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
10905
+ .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; })
10906
+ .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.start).valueOf(); })), false)));
10907
+ var completedAt = moment__default["default"](Math.max.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
10908
+ .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; })
10909
+ .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.complete).valueOf(); })), false)));
10910
+ var timingItems = executionReportJson.promptExecutions.map(function (promptExecution) {
10911
+ var _a, _b, _c, _d;
10912
+ return ({
10913
+ title: promptExecution.prompt.title,
10914
+ 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,
10915
+ 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,
10916
+ });
10917
+ });
10918
+ var costItems = executionReportJson.promptExecutions
10919
+ .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'; })
10920
+ .map(function (promptExecution) {
10921
+ var _a, _b;
10922
+ return ({
10923
+ title: promptExecution.prompt.title,
10924
+ from: 0,
10925
+ to: (((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.usage) === null || _b === void 0 ? void 0 : _b.price.value) || 0) /* <- TODO: look at uncertain numbers */ *
10926
+ (1 + taxRate),
10927
+ });
10928
+ });
10929
+ var duration = moment__default["default"].duration(completedAt.diff(startedAt));
10930
+ var llmDuration = moment__default["default"].duration(countWorkingDuration(timingItems) * 1000);
10931
+ 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'; });
10932
+ var cost = executionsWithKnownCost.reduce(function (cost, promptExecution) {
10933
+ return cost + (promptExecution.result.usage.price.value /* <- Look at uncertain number */ || 0);
10934
+ }, 0);
10935
+ headerList.push("STARTED AT ".concat(moment__default["default"](startedAt).format("YYYY-MM-DD HH:mm:ss")));
10936
+ headerList.push("COMPLETED AT ".concat(moment__default["default"](completedAt).format("YYYY-MM-DD HH:mm:ss")));
10937
+ headerList.push("TOTAL DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
10938
+ headerList.push("TOTAL LLM DURATION ".concat(llmDuration.humanize(MOMENT_ARG_THRESHOLDS)));
10939
+ headerList.push("TOTAL COST $".concat(formatNumber(cost * (1 + taxRate))) +
10940
+ (executionsWithKnownCost.length === executionReportJson.promptExecutions.length
10941
+ ? ''
10942
+ : " *(Some cost is unknown)*") +
10943
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
10944
+ executionReportString += '\n\n' + headerList.map(function (header) { return "- ".concat(header); }).join('\n');
10945
+ executionReportString +=
10946
+ '\n\n' +
10947
+ '## 🗃 Index' +
10948
+ '\n\n' +
10949
+ executionReportJson.promptExecutions
10950
+ .map(function (promptExecution) {
10951
+ // TODO: Make some better system to convert hedings to links
10952
+ var hash = normalizeToKebabCase(promptExecution.prompt.title);
10953
+ if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
10954
+ hash = '-' + hash;
10955
+ }
10956
+ // TODO: Make working hash link for the template in md + pdf
10957
+ return "- [".concat(promptExecution.prompt.title, "](#").concat(hash, ")");
10958
+ })
10959
+ .join('\n');
10960
+ executionReportString +=
10961
+ '\n\n' +
10962
+ '## ⌚ Time chart' +
10963
+ '\n\n' +
10964
+ createMarkdownChart({
10965
+ nameHeader: 'Template',
10966
+ valueHeader: 'Timeline',
10967
+ items: timingItems,
10968
+ width: chartsWidth,
10969
+ unitName: 'seconds',
10970
+ });
10971
+ executionReportString +=
10972
+ '\n\n' +
10973
+ '## 💸 Cost chart' +
10974
+ '\n\n' +
10975
+ createMarkdownChart({
10976
+ nameHeader: 'Template',
10977
+ valueHeader: 'Cost',
10978
+ items: costItems,
10979
+ width: chartsWidth,
10980
+ unitName: 'USD',
10981
+ });
10982
+ }
10983
+ else {
10984
+ headerList.push("TOTAL COST $0 *(Nothing executed)*");
10985
+ }
10986
+ var _loop_1 = function (promptExecution) {
10987
+ executionReportString += '\n\n\n\n' + "## ".concat(promptExecution.prompt.title);
10988
+ var templateList = [];
10989
+ // TODO: What if startedAt OR/AND completedAt is not defined?
10990
+ 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);
10991
+ 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);
10992
+ var duration = moment__default["default"].duration(completedAt.diff(startedAt));
10993
+ // Not need here:
10994
+ // > templateList.push(`STARTED AT ${moment(startedAt).calendar()}`);
10995
+ templateList.push("DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
10996
+ if (typeof ((_g = (_f = promptExecution.result) === null || _f === void 0 ? void 0 : _f.usage) === null || _g === void 0 ? void 0 : _g.price) === 'number') {
10997
+ templateList.push("COST $".concat(formatNumber(promptExecution.result.usage.price * (1 + taxRate))) +
10998
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
10999
+ }
11000
+ else {
11001
+ templateList.push("COST UNKNOWN");
11002
+ }
11003
+ executionReportString += '\n\n' + templateList.map(function (header) { return "- ".concat(header); }).join('\n');
11004
+ /*
11005
+ - MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
11006
+ - MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
11007
+ promptExecution.prompt.modelRequirements.modelName
11008
+
11009
+ */
11010
+ if (just(true)) {
11011
+ executionReportString +=
11012
+ '\n\n\n\n' +
11013
+ spaceTrim.spaceTrim(function (block) {
11014
+ var _a;
11015
+ return "\n\n ### Prompt\n\n ```\n ".concat(block(escapeMarkdownBlock(((_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.rawPromptContent) || promptExecution.prompt.content)), "\n ```\n\n ");
11016
+ });
11017
+ }
11018
+ if (promptExecution.result && promptExecution.result.content) {
11019
+ executionReportString += '\n\n\n\n' + '### Result' + '\n\n';
11020
+ if (promptExecution.result === undefined) {
11021
+ executionReportString += '*No result*';
11022
+ }
11023
+ else if (typeof promptExecution.result.content === 'string') {
11024
+ executionReportString += spaceTrim.spaceTrim(function (block) { return "\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.result.content)), "\n ```\n "); });
11025
+ }
11026
+ else {
11027
+ executionReportString += embeddingVectorToString(promptExecution.result.content);
11028
+ }
11029
+ }
11030
+ if (promptExecution.error && promptExecution.error.message) {
11031
+ executionReportString +=
11032
+ '\n\n\n\n' +
11033
+ spaceTrim.spaceTrim(function (block) { return "\n\n ### Error\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.error.message)), "\n ```\n\n "); });
11034
+ }
11035
+ };
11036
+ try {
11037
+ for (var _j = __values(executionReportJson.promptExecutions), _k = _j.next(); !_k.done; _k = _j.next()) {
11038
+ var promptExecution = _k.value;
11039
+ _loop_1(promptExecution);
11040
+ }
11041
+ }
11042
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
11043
+ finally {
11044
+ try {
11045
+ if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
11046
+ }
11047
+ finally { if (e_1) throw e_1.error; }
11048
+ }
11049
+ executionReportString = prettifyMarkdown(executionReportString);
11050
+ return executionReportString;
11051
+ }
11052
+ /**
11053
+ * TODO: Add mermaid chart for every report
11054
+ * TODO: [🧠] Allow to filter out some parts of the report by options
11055
+ * TODO: [🧠] Should be in generated file GENERATOR_WARNING
11056
+ */
11057
+
11058
+ /**
11059
+ * Initializes `run` command for Promptbook CLI utilities
11060
+ *
11061
+ * @private internal function of `promptbookCli`
11062
+ */
11063
+ function initializeRunCommand(program) {
11064
+ var _this = this;
11065
+ var runCommand = program.command('run', { isDefault: true });
11066
+ runCommand.description(spaceTrim__default["default"]("\n Runs a pipeline\n "));
11067
+ // TODO: [🧅] DRY command arguments
11068
+ runCommand.argument('<path>',
11069
+ // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .book.md file
11070
+ 'Path to book file');
11071
+ runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
11072
+ runCommand.option('-v, --verbose', "Is output verbose", false);
11073
+ runCommand.option('--no-interactive', "Input is not interactive", false);
11074
+ runCommand.option('-s, --save-report <path>', "Save report to file");
11075
+ // TODO: !!!!!! Implement non-interactive mode - allow to pass input parameters as JSON
11076
+ // TODO: !!!!!! JSON output
11077
+ runCommand.action(function (filePathRaw, options) { return __awaiter(_this, void 0, void 0, function () {
11078
+ var isCacheReloaded, isVerbose, saveReport, prepareAndScrapeOptions, fs, filePath, filePathCandidates, filePathCandidates_1, filePathCandidates_1_1, filePathCandidate, e_1_1, llm, executables, tools, pipelineString, pipeline, error_1, pipelineExecutor, questions, response, inputParameters, result, isSuccessful, errors, warnings, outputParameters, executionReport, executionReportString, _a, _b, error, _c, _d, warning, _e, _f, key, value, separator;
11079
+ var e_1, _g, _h, e_2, _j, e_3, _k, e_4, _l;
11080
+ return __generator(this, function (_m) {
11081
+ switch (_m.label) {
11082
+ case 0:
11083
+ isCacheReloaded = options.reload, options.interactive, isVerbose = options.verbose, saveReport = options.saveReport;
11084
+ if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
11085
+ console.error(colors__default["default"].red("Report file must be .json or .md"));
11086
+ return [2 /*return*/, process.exit(1)];
11087
+ }
11088
+ prepareAndScrapeOptions = {
11089
+ isVerbose: isVerbose,
11090
+ isCacheReloaded: isCacheReloaded,
11091
+ };
11092
+ if (isVerbose) {
11093
+ console.info(colors__default["default"].gray('--- Preparing tools ---'));
11094
+ }
11095
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11096
+ filePath = null;
11097
+ filePathCandidates = [
11098
+ filePathRaw,
11099
+ "".concat(filePathRaw, ".md"),
11100
+ "".concat(filePathRaw, ".book.md"),
11101
+ "".concat(filePathRaw, ".book.md"),
11102
+ ];
11103
+ _m.label = 1;
11104
+ case 1:
11105
+ _m.trys.push([1, 6, 7, 8]);
11106
+ filePathCandidates_1 = __values(filePathCandidates), filePathCandidates_1_1 = filePathCandidates_1.next();
11107
+ _m.label = 2;
11108
+ case 2:
11109
+ if (!!filePathCandidates_1_1.done) return [3 /*break*/, 5];
11110
+ filePathCandidate = filePathCandidates_1_1.value;
11111
+ return [4 /*yield*/, isFileExisting(filePathCandidate, fs)
11112
+ // <- TODO: Also test that among the candidates the file is book not just any file
11113
+ ];
11114
+ case 3:
11115
+ if (_m.sent()
11116
+ // <- TODO: Also test that among the candidates the file is book not just any file
11117
+ ) {
11118
+ filePath = filePathCandidate;
11119
+ return [3 /*break*/, 5];
11120
+ }
11121
+ _m.label = 4;
11122
+ case 4:
11123
+ filePathCandidates_1_1 = filePathCandidates_1.next();
11124
+ return [3 /*break*/, 2];
11125
+ case 5: return [3 /*break*/, 8];
11126
+ case 6:
11127
+ e_1_1 = _m.sent();
11128
+ e_1 = { error: e_1_1 };
11129
+ return [3 /*break*/, 8];
11130
+ case 7:
11131
+ try {
11132
+ if (filePathCandidates_1_1 && !filePathCandidates_1_1.done && (_g = filePathCandidates_1.return)) _g.call(filePathCandidates_1);
11133
+ }
11134
+ finally { if (e_1) throw e_1.error; }
11135
+ return [7 /*endfinally*/];
11136
+ case 8:
11137
+ if (filePath === null) {
11138
+ console.error(colors__default["default"].red("File \"".concat(filePathRaw, "\" does not exist")));
11139
+ return [2 /*return*/, process.exit(1)];
11140
+ }
11141
+ try {
11142
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
11143
+ }
11144
+ catch (error) {
11145
+ if (!(error instanceof Error)) {
11146
+ throw error;
11147
+ }
11148
+ if (!error.message.includes('No LLM tools')) {
11149
+ throw error;
11150
+ }
11151
+ console.error(colors__default["default"].red(spaceTrim__default["default"]("\n You need to configure LLM tools first\n\n 1) Create .env file\n 2) Add OPENAI_API_KEY=...\n 3) *(and/or)* Add ANTHROPIC_CLAUDE_API_KEY=...\n ")));
11152
+ return [2 /*return*/, process.exit(1)];
11153
+ }
11154
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
11155
+ case 9:
11156
+ executables = _m.sent();
11157
+ _h = {
11158
+ llm: llm,
11159
+ fs: fs
11160
+ };
11161
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
11162
+ case 10:
11163
+ tools = (_h.scrapers = _m.sent(),
11164
+ _h.script = [
11165
+ /*new JavascriptExecutionTools(options)*/
11166
+ ],
11167
+ _h);
11168
+ if (isVerbose) {
11169
+ console.info(colors__default["default"].gray('--- Reading file ---'));
11170
+ }
11171
+ return [4 /*yield*/, promises.readFile(filePath, 'utf-8')];
11172
+ case 11:
11173
+ pipelineString = (_m.sent());
11174
+ if (isVerbose) {
11175
+ console.info(colors__default["default"].gray('--- Preparing pipeline ---'));
11176
+ }
11177
+ _m.label = 12;
11178
+ case 12:
11179
+ _m.trys.push([12, 14, , 15]);
11180
+ return [4 /*yield*/, pipelineStringToJson(pipelineString, tools)];
11181
+ case 13:
11182
+ pipeline = _m.sent();
11183
+ return [3 /*break*/, 15];
11184
+ case 14:
11185
+ error_1 = _m.sent();
11186
+ if (!(error_1 instanceof ParseError)) {
11187
+ throw error_1;
11188
+ }
11189
+ console.error(colors__default["default"].red(spaceTrim__default["default"](function (block) { return "\n ".concat(block(error_1.message), "\n\n in ").concat(filePath, "\n "); })));
11190
+ return [2 /*return*/, process.exit(1)];
11191
+ case 15:
11192
+ if (isVerbose) {
11193
+ console.info(colors__default["default"].gray('--- Validating pipeline ---'));
11194
+ }
11195
+ // TODO: !!!!!! Same try-catch for LogicError
11196
+ validatePipeline(pipeline);
11197
+ if (isVerbose) {
11198
+ console.info(colors__default["default"].gray('--- Creating executor ---'));
11199
+ }
11200
+ pipelineExecutor = createPipelineExecutor({
11201
+ pipeline: pipeline,
11202
+ tools: tools,
11203
+ isNotPreparedWarningSupressed: true,
11204
+ maxExecutionAttempts: 3,
11205
+ // <- TODO: !!!!!! Why "LLM execution failed undefinedx"
11206
+ maxParallelCount: 1, // <- TODO: !!!!!! Pass
11207
+ });
11208
+ if (isVerbose) {
11209
+ console.info(colors__default["default"].gray('--- Getting input parameters ---'));
11210
+ }
11211
+ questions = pipeline.parameters
11212
+ .filter(function (_a) {
11213
+ var isInput = _a.isInput;
11214
+ return isInput;
11215
+ })
11216
+ .map(function (_a) {
11217
+ var name = _a.name, exampleValues = _a.exampleValues;
11218
+ var message = name;
11219
+ var initial = '';
11220
+ if (exampleValues && exampleValues.length > 0) {
11221
+ var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1 && countCharacters(exampleValue) <= 30; });
11222
+ if (exampleValuesFiltered.length !== 0) {
11223
+ message += " (e.g. ".concat(exampleValuesFiltered.join(', '), ")");
11224
+ }
11225
+ initial = exampleValues[0] || '';
11226
+ }
11227
+ return {
11228
+ type: 'text',
11229
+ name: name,
11230
+ message: message,
11231
+ initial: initial,
11232
+ // TODO: Maybe use> validate: value => value < 18 ? `Forbidden` : true
11233
+ };
11234
+ });
11235
+ return [4 /*yield*/, prompts__default["default"](questions)];
11236
+ case 16:
11237
+ response = _m.sent();
11238
+ inputParameters = response;
11239
+ if (isVerbose) {
11240
+ console.info(colors__default["default"].gray('--- Executing ---'));
11241
+ }
11242
+ return [4 /*yield*/, pipelineExecutor(inputParameters, function (taskProgress) {
11243
+ if (isVerbose) {
11244
+ console.info(colors__default["default"].gray('--- Progress ---'));
11245
+ console.info(taskProgress);
11246
+ }
11247
+ })];
11248
+ case 17:
11249
+ result = _m.sent();
11250
+ isSuccessful = result.isSuccessful, errors = result.errors, warnings = result.warnings, outputParameters = result.outputParameters, executionReport = result.executionReport;
11251
+ if (isVerbose) {
11252
+ console.info(colors__default["default"].gray('--- Detailed Result ---'));
11253
+ console.info({ isSuccessful: isSuccessful, errors: errors, warnings: warnings, outputParameters: outputParameters, executionReport: executionReport });
11254
+ }
11255
+ if (!(saveReport && saveReport.endsWith('.json'))) return [3 /*break*/, 19];
11256
+ return [4 /*yield*/, promises.writeFile(saveReport, JSON.stringify(executionReport, null, 4) + '\n', 'utf-8')];
11257
+ case 18:
11258
+ _m.sent();
11259
+ return [3 /*break*/, 21];
11260
+ case 19:
11261
+ if (!(saveReport && saveReport.endsWith('.md'))) return [3 /*break*/, 21];
11262
+ executionReportString = executionReportJsonToString(executionReport);
11263
+ return [4 /*yield*/, promises.writeFile(saveReport, executionReportString, 'utf-8')];
11264
+ case 20:
11265
+ _m.sent();
11266
+ _m.label = 21;
11267
+ case 21:
11268
+ if (saveReport && isVerbose) {
11269
+ console.info(colors__default["default"].green("Report saved to ".concat(saveReport)));
11270
+ }
11271
+ if (isVerbose) {
11272
+ console.info(colors__default["default"].gray('--- Usage ---'));
11273
+ console.info(colors__default["default"].cyan(usageToHuman(result.usage)));
11274
+ }
11275
+ console.info(colors__default["default"].gray('--- Result ---'));
11276
+ try {
11277
+ // TODO: [🧠] Should be errors or warnings shown first
11278
+ for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
11279
+ error = _b.value;
11280
+ console.error(colors__default["default"].red(colors__default["default"].bold(error.name) + ': ' + error.message));
11281
+ }
11282
+ }
11283
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
11284
+ finally {
11285
+ try {
11286
+ if (_b && !_b.done && (_j = _a.return)) _j.call(_a);
11287
+ }
11288
+ finally { if (e_2) throw e_2.error; }
11289
+ }
11290
+ try {
11291
+ for (_c = __values(warnings || []), _d = _c.next(); !_d.done; _d = _c.next()) {
11292
+ warning = _d.value;
11293
+ console.error(colors__default["default"].red(colors__default["default"].bold(warning.name) + ': ' + warning.message));
11294
+ }
11295
+ }
11296
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
11297
+ finally {
11298
+ try {
11299
+ if (_d && !_d.done && (_k = _c.return)) _k.call(_c);
11300
+ }
11301
+ finally { if (e_3) throw e_3.error; }
11302
+ }
11303
+ try {
11304
+ for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11305
+ key = _f.value;
11306
+ value = outputParameters[key] || colors__default["default"].grey(colors__default["default"].italic('(nothing)'));
11307
+ separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11308
+ console.info(colors__default["default"].green(colors__default["default"].bold(key) + separator + value));
11309
+ }
11310
+ }
11311
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
11312
+ finally {
11313
+ try {
11314
+ if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11315
+ }
11316
+ finally { if (e_4) throw e_4.error; }
11317
+ }
11318
+ return [2 /*return*/, process.exit(0)];
11319
+ }
11320
+ });
11321
+ }); });
11322
+ }
11323
+ /**
11324
+ * TODO: !!!!!! Catch and wrap all errors from CLI
11325
+ * TODO: [🧠] Pass `maxExecutionAttempts`, `csvSettings`
11326
+ * TODO: [🥃][main] !!! Allow `ptbk run` without configuring any llm tools
11327
+ * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
11328
+ * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
11329
+ */
11330
+
10748
11331
  /**
10749
11332
  * Initializes `test` command for Promptbook CLI utilities
10750
11333
  *
@@ -10753,35 +11336,35 @@
10753
11336
  function initializeTestCommand(program) {
10754
11337
  var _this = this;
10755
11338
  var testCommand = program.command('test');
10756
- testCommand.description(spaceTrim__default["default"]("\n Iterates over `.ptbk.md` and `.ptbk.json` and checks if they are parsable and logically valid\n "));
11339
+ testCommand.description(spaceTrim__default["default"]("\n Iterates over `.book.md` and `.book.json` and checks if they are parsable and logically valid\n "));
10757
11340
  testCommand.argument('<filesGlob>',
10758
11341
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10759
11342
  'Pipelines to test as glob pattern');
10760
11343
  testCommand.option('-i, --ignore <glob>', "Ignore as glob pattern");
10761
- testCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache ", false);
11344
+ testCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache ", false);
10762
11345
  testCommand.option('-v, --verbose', "Is output verbose", false);
10763
11346
  testCommand.action(function (filesGlob, _a) {
10764
- var ignore = _a.ignore, isCacheReloaded = _a.reloadCache, isVerbose = _a.verbose;
11347
+ var ignore = _a.ignore, isCacheReloaded = _a.reload, isVerbose = _a.verbose;
10765
11348
  return __awaiter(_this, void 0, void 0, function () {
10766
- var options, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
11349
+ var prepareAndScrapeOptions, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
10767
11350
  var _d, e_1, _e;
10768
11351
  return __generator(this, function (_f) {
10769
11352
  switch (_f.label) {
10770
11353
  case 0:
10771
- options = {
11354
+ prepareAndScrapeOptions = {
10772
11355
  isVerbose: isVerbose,
10773
11356
  isCacheReloaded: isCacheReloaded,
10774
11357
  };
10775
- fs = $provideFilesystemForNode(options);
10776
- llm = $provideLlmToolsForCli(options);
10777
- return [4 /*yield*/, $provideExecutablesForNode(options)];
11358
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11359
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
11360
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
10778
11361
  case 1:
10779
11362
  executables = _f.sent();
10780
11363
  _d = {
10781
11364
  llm: llm,
10782
11365
  fs: fs
10783
11366
  };
10784
- return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
11367
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
10785
11368
  case 2:
10786
11369
  tools = (_d.scrapers = _f.sent(),
10787
11370
  _d.script = [
@@ -10803,7 +11386,7 @@
10803
11386
  case 6:
10804
11387
  _f.trys.push([6, 13, , 14]);
10805
11388
  pipeline = void 0;
10806
- if (!filename.endsWith('.ptbk.md')) return [3 /*break*/, 9];
11389
+ if (!filename.endsWith('.book.md')) return [3 /*break*/, 9];
10807
11390
  return [4 /*yield*/, promises.readFile(filename, 'utf-8')];
10808
11391
  case 7:
10809
11392
  pipelineMarkdown = (_f.sent());
@@ -10815,7 +11398,7 @@
10815
11398
  }
10816
11399
  _f.label = 9;
10817
11400
  case 9:
10818
- if (!filename.endsWith('.ptbk.json')) return [3 /*break*/, 11];
11401
+ if (!filename.endsWith('.book.json')) return [3 /*break*/, 11];
10819
11402
  _c = (_b = JSON).parse;
10820
11403
  return [4 /*yield*/, promises.readFile(filename, 'utf-8')];
10821
11404
  case 10:
@@ -10838,8 +11421,7 @@
10838
11421
  console.info(colors__default["default"].red("Pipeline is not valid ".concat(filename)));
10839
11422
  console.error(colors__default["default"].bgRed(error_1.name /* <- 11:11 */));
10840
11423
  console.error(colors__default["default"].red(error_1.stack || error_1.message));
10841
- process.exit(1);
10842
- return [3 /*break*/, 14];
11424
+ return [2 /*return*/, process.exit(1)];
10843
11425
  case 14:
10844
11426
  filenames_1_1 = filenames_1.next();
10845
11427
  return [3 /*break*/, 5];
@@ -10856,8 +11438,7 @@
10856
11438
  return [7 /*endfinally*/];
10857
11439
  case 18:
10858
11440
  console.info(colors__default["default"].green("All pipelines are valid"));
10859
- process.exit(0);
10860
- return [2 /*return*/];
11441
+ return [2 /*return*/, process.exit(0)];
10861
11442
  }
10862
11443
  });
10863
11444
  });
@@ -10877,17 +11458,23 @@
10877
11458
  */
10878
11459
  function promptbookCli() {
10879
11460
  return __awaiter(this, void 0, void 0, function () {
10880
- var program;
11461
+ var isVerbose, program;
10881
11462
  return __generator(this, function (_a) {
10882
11463
  if (!$isRunningInNode()) {
10883
11464
  throw new EnvironmentMismatchError(spaceTrim.spaceTrim("\n Function promptbookCli is initiator of CLI script and should be run in Node.js environment.\n\n - In browser use function exported from `@promptbook/utils` or `@promptbook/core` directly, for example `prettifyPipelineString`.\n\n "));
10884
11465
  }
11466
+ isVerbose = process.argv.some(function (arg) { return arg === '--verbose' || arg === '-v'; });
11467
+ // <- TODO: Can be this be done with commander before the commander commands are initialized?
11468
+ if (isVerbose) {
11469
+ console.info(colors__default["default"].gray("Promptbook CLI version ".concat(PROMPTBOOK_ENGINE_VERSION, " in ").concat(__filename.split('\\').join('/'))));
11470
+ }
10885
11471
  program = new commander__default["default"].Command();
10886
11472
  program.name('promptbook');
10887
11473
  program.alias('ptbk');
10888
- program.version(PROMPTBOOK_VERSION);
10889
- program.description(spaceTrim.spaceTrim("\n Promptbook utilities for enhancing workflow with promptbooks\n "));
11474
+ program.version(PROMPTBOOK_ENGINE_VERSION);
11475
+ program.description(CLAIM);
10890
11476
  initializeAboutCommand(program);
11477
+ initializeRunCommand(program);
10891
11478
  initializeHelloCommand(program);
10892
11479
  initializeMakeCommand(program);
10893
11480
  initializePrettifyCommand(program);
@@ -10898,6 +11485,7 @@
10898
11485
  });
10899
11486
  }
10900
11487
  /**
11488
+ * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.book.md` -> `ptbk ./foo.book.md`
10901
11489
  * TODO: [🥠] Do not export, its just for CLI script
10902
11490
  * TODO: [🕌] When more functionalities, rename
10903
11491
  * Note: 11:11
@@ -12487,8 +13075,6 @@
12487
13075
  };
12488
13076
  },
12489
13077
  createConfigurationFromEnv: function (env) {
12490
- // TODO: Maybe auto-configure (multiple) assistants from env variables
12491
- keepUnused(env);
12492
13078
  return null;
12493
13079
  /*
12494
13080
  if (typeof env.OPENAI_API_KEY === 'string' || typeof env.OPENAI_XXX === 'string') {
@@ -13215,12 +13801,9 @@
13215
13801
  })
13216
13802
  .filter(function (arg) { return arg !== ''; });
13217
13803
  if (_.length > 1) {
13218
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13219
13804
  _a = __read(_), command = _a[0], args = _a.slice(1);
13220
13805
  }
13221
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13222
13806
  if (options.args) {
13223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13224
13807
  args = __spreadArray(__spreadArray([], __read(args), false), __read(options.args), false);
13225
13808
  }
13226
13809
  var humanReadableCommand = !['npx', 'npm'].includes(command) ? command : args[0];
@@ -13341,12 +13924,12 @@
13341
13924
  */
13342
13925
  function getScraperIntermediateSource(source, options) {
13343
13926
  return __awaiter(this, void 0, void 0, function () {
13344
- var sourceFilename, url, rootDirname, cacheDirname, intermediateFilesStrategy, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
13927
+ var sourceFilename, url, cacheDirname, intermediateFilesStrategy, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
13345
13928
  return __generator(this, function (_a) {
13346
13929
  switch (_a.label) {
13347
13930
  case 0:
13348
13931
  sourceFilename = source.filename, url = source.url;
13349
- rootDirname = options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, extension = options.extension, isVerbose = options.isVerbose;
13932
+ options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, extension = options.extension, isVerbose = options.isVerbose;
13350
13933
  hash = cryptoJs.SHA256(
13351
13934
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
13352
13935
  hexEncoder__default["default"].parse(sourceFilename || url || 'untitled'))
@@ -13355,8 +13938,6 @@
13355
13938
  semanticName = normalizeToKebabCase(titleToName((sourceFilename || url || '').split('intermediate').join(''))).substring(0, 20);
13356
13939
  pieces = ['intermediate', semanticName, hash].filter(function (piece) { return piece !== ''; });
13357
13940
  name = pieces.join('-').split('--').join('-');
13358
- // <- TODO: Use MAX_FILENAME_LENGTH
13359
- TODO_USE(rootDirname); // <- TODO: [😡]
13360
13941
  cacheFilename = path.join.apply(void 0, __spreadArray(__spreadArray([process.cwd(),
13361
13942
  cacheDirname], __read(nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */)), false), [name], false)).split('\\')
13362
13943
  .join('/') +
@@ -13455,13 +14036,13 @@
13455
14036
  */
13456
14037
  MarkdownScraper.prototype.scrape = function (source) {
13457
14038
  return __awaiter(this, void 0, void 0, function () {
13458
- var _a, _b, maxParallelCount, _c, isVerbose, llm, _llms, llmTools, collection, prepareKnowledgeFromMarkdownExecutor, _d, prepareTitleExecutor, _e, prepareKeywordsExecutor, _f, knowledgeContent, result, outputParameters, knowledgePiecesRaw, knowledgeTextPieces, knowledge;
14039
+ var _a, _c, isVerbose, llm, _llms, llmTools, collection, prepareKnowledgeFromMarkdownExecutor, _d, prepareTitleExecutor, _e, prepareKeywordsExecutor, _f, knowledgeContent, result, outputParameters, knowledgePiecesRaw, knowledgeTextPieces, knowledge;
13459
14040
  var _g, _h, _j;
13460
14041
  var _this = this;
13461
14042
  return __generator(this, function (_k) {
13462
14043
  switch (_k.label) {
13463
14044
  case 0:
13464
- _a = this.options, _b = _a.maxParallelCount, maxParallelCount = _b === void 0 ? DEFAULT_MAX_PARALLEL_COUNT : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c;
14045
+ _a = this.options, _a.maxParallelCount, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c;
13465
14046
  llm = this.tools.llm;
13466
14047
  if (llm === undefined) {
13467
14048
  throw new MissingToolsError('LLM tools are required for scraping external files');
@@ -13469,11 +14050,10 @@
13469
14050
  }
13470
14051
  _llms = arrayableToArray(llm);
13471
14052
  llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(_llms), false));
13472
- TODO_USE(maxParallelCount); // <- [🪂]
13473
14053
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
13474
14054
  _d = createPipelineExecutor;
13475
14055
  _g = {};
13476
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md')];
14056
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md')];
13477
14057
  case 1:
13478
14058
  prepareKnowledgeFromMarkdownExecutor = _d.apply(void 0, [(_g.pipeline = _k.sent(),
13479
14059
  _g.tools = {
@@ -13482,7 +14062,7 @@
13482
14062
  _g)]);
13483
14063
  _e = createPipelineExecutor;
13484
14064
  _h = {};
13485
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md')];
14065
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.book.md')];
13486
14066
  case 2:
13487
14067
  prepareTitleExecutor = _e.apply(void 0, [(_h.pipeline = _k.sent(),
13488
14068
  _h.tools = {
@@ -13491,7 +14071,7 @@
13491
14071
  _h)]);
13492
14072
  _f = createPipelineExecutor;
13493
14073
  _j = {};
13494
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md')];
14074
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md')];
13495
14075
  case 3:
13496
14076
  prepareKeywordsExecutor = _f.apply(void 0, [(_j.pipeline = _k.sent(),
13497
14077
  _j.tools = {
@@ -14060,7 +14640,6 @@
14060
14640
  PdfScraper.prototype.$convert = function (source) {
14061
14641
  return __awaiter(this, void 0, void 0, function () {
14062
14642
  return __generator(this, function (_a) {
14063
- TODO_USE(source);
14064
14643
  TODO_USE(this.options);
14065
14644
  throw new NotYetImplementedError('PDF conversion not yet implemented');
14066
14645
  });
@@ -14072,7 +14651,6 @@
14072
14651
  PdfScraper.prototype.scrape = function (source) {
14073
14652
  return __awaiter(this, void 0, void 0, function () {
14074
14653
  return __generator(this, function (_a) {
14075
- TODO_USE(source);
14076
14654
  TODO_USE(this.options);
14077
14655
  /*
14078
14656
  const {
@@ -14315,7 +14893,8 @@
14315
14893
  * TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
14316
14894
  */
14317
14895
 
14318
- exports.PROMPTBOOK_VERSION = PROMPTBOOK_VERSION;
14896
+ exports.BOOK_LANGUAGE_VERSION = BOOK_LANGUAGE_VERSION;
14897
+ exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;
14319
14898
  exports._AnthropicClaudeMetadataRegistration = _AnthropicClaudeMetadataRegistration;
14320
14899
  exports._AnthropicClaudeRegistration = _AnthropicClaudeRegistration;
14321
14900
  exports._AzureOpenAiMetadataRegistration = _AzureOpenAiMetadataRegistration;