@promptbook/cli 0.73.0 → 0.74.0-11

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 (41) hide show
  1. package/README.md +176 -3
  2. package/bin/promptbook-cli.js +6 -1
  3. package/esm/index.es.js +1025 -449
  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/commands/{PROMPTBOOK_VERSION/PromptbookVersionCommand.d.ts → BOOK_VERSION/BookVersionCommand.d.ts} +4 -4
  28. package/esm/typings/src/commands/BOOK_VERSION/bookVersionCommandParser.d.ts +9 -0
  29. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  30. package/esm/typings/src/commands/index.d.ts +1 -1
  31. package/esm/typings/src/config.d.ts +6 -0
  32. package/esm/typings/src/storage/blackhole/BlackholeStorage.d.ts +33 -0
  33. package/esm/typings/src/storage/memory/MemoryStorage.d.ts +1 -1
  34. package/esm/typings/src/storage/{memory/utils → utils}/PrefixStorage.d.ts +1 -1
  35. package/esm/typings/src/version.d.ts +13 -2
  36. package/package.json +8 -4
  37. package/umd/index.umd.js +1030 -453
  38. package/umd/index.umd.js.map +1 -1
  39. package/esm/typings/src/commands/PROMPTBOOK_VERSION/promptbookVersionCommandParser.d.ts +0 -9
  40. /package/esm/typings/src/commands/{PROMPTBOOK_VERSION/promptbookVersionCommand.test.d.ts → BOOK_VERSION/bookVersionCommand.test.d.ts} +0 -0
  41. /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-10';
53
+ /**
54
+ * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
41
55
  */
42
- var PROMPTBOOK_VERSION = '0.72.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
  });
@@ -1053,6 +1073,188 @@
1053
1073
  },
1054
1074
  });
1055
1075
 
1076
+ /**
1077
+ * @@@
1078
+ *
1079
+ * @public exported from `@promptbook/utils`
1080
+ */
1081
+ function deepClone(objectValue) {
1082
+ return JSON.parse(JSON.stringify(objectValue));
1083
+ /*
1084
+ TODO: [🧠] Is there a better implementation?
1085
+ > const propertyNames = Object.getOwnPropertyNames(objectValue);
1086
+ > for (const propertyName of propertyNames) {
1087
+ > const value = (objectValue as really_any)[propertyName];
1088
+ > if (value && typeof value === 'object') {
1089
+ > deepClone(value);
1090
+ > }
1091
+ > }
1092
+ > return Object.assign({}, objectValue);
1093
+ */
1094
+ }
1095
+ /**
1096
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
1097
+ */
1098
+
1099
+ /**
1100
+ * Function `addUsage` will add multiple usages into one
1101
+ *
1102
+ * Note: If you provide 0 values, it returns ZERO_USAGE
1103
+ *
1104
+ * @public exported from `@promptbook/core`
1105
+ */
1106
+ function addUsage() {
1107
+ var usageItems = [];
1108
+ for (var _i = 0; _i < arguments.length; _i++) {
1109
+ usageItems[_i] = arguments[_i];
1110
+ }
1111
+ return usageItems.reduce(function (acc, item) {
1112
+ var e_1, _a, e_2, _b;
1113
+ var _c;
1114
+ acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
1115
+ try {
1116
+ for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
1117
+ var key = _e.value;
1118
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1119
+ //@ts-ignore
1120
+ if (item.input[key]) {
1121
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1122
+ //@ts-ignore
1123
+ acc.input[key].value += item.input[key].value || 0;
1124
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1125
+ //@ts-ignore
1126
+ if (item.input[key].isUncertain) {
1127
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1128
+ //@ts-ignore
1129
+ acc.input[key].isUncertain = true;
1130
+ }
1131
+ }
1132
+ }
1133
+ }
1134
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1135
+ finally {
1136
+ try {
1137
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
1138
+ }
1139
+ finally { if (e_1) throw e_1.error; }
1140
+ }
1141
+ try {
1142
+ for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
1143
+ var key = _g.value;
1144
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1145
+ //@ts-ignore
1146
+ if (item.output[key]) {
1147
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1148
+ //@ts-ignore
1149
+ acc.output[key].value += item.output[key].value || 0;
1150
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1151
+ //@ts-ignore
1152
+ if (item.output[key].isUncertain) {
1153
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1154
+ //@ts-ignore
1155
+ acc.output[key].isUncertain = true;
1156
+ }
1157
+ }
1158
+ }
1159
+ }
1160
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1161
+ finally {
1162
+ try {
1163
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
1164
+ }
1165
+ finally { if (e_2) throw e_2.error; }
1166
+ }
1167
+ return acc;
1168
+ }, deepClone(ZERO_USAGE));
1169
+ }
1170
+
1171
+ /**
1172
+ * Intercepts LLM tools and counts total usage of the tools
1173
+ *
1174
+ * @param llmTools LLM tools to be intercepted with usage counting
1175
+ * @returns LLM tools with same functionality with added total cost counting
1176
+ * @public exported from `@promptbook/core`
1177
+ */
1178
+ function countTotalUsage(llmTools) {
1179
+ var _this = this;
1180
+ var totalUsage = ZERO_USAGE;
1181
+ var proxyTools = {
1182
+ get title() {
1183
+ // TODO: [🧠] Maybe put here some suffix
1184
+ return llmTools.title;
1185
+ },
1186
+ get description() {
1187
+ // TODO: [🧠] Maybe put here some suffix
1188
+ return llmTools.description;
1189
+ },
1190
+ checkConfiguration: function () {
1191
+ return __awaiter(this, void 0, void 0, function () {
1192
+ return __generator(this, function (_a) {
1193
+ return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
1194
+ });
1195
+ });
1196
+ },
1197
+ listModels: function () {
1198
+ return /* not await */ llmTools.listModels();
1199
+ },
1200
+ getTotalUsage: function () {
1201
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
1202
+ return totalUsage;
1203
+ },
1204
+ };
1205
+ if (llmTools.callChatModel !== undefined) {
1206
+ proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1207
+ var promptResult;
1208
+ return __generator(this, function (_a) {
1209
+ switch (_a.label) {
1210
+ case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
1211
+ case 1:
1212
+ promptResult = _a.sent();
1213
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1214
+ return [2 /*return*/, promptResult];
1215
+ }
1216
+ });
1217
+ }); };
1218
+ }
1219
+ if (llmTools.callCompletionModel !== undefined) {
1220
+ proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1221
+ var promptResult;
1222
+ return __generator(this, function (_a) {
1223
+ switch (_a.label) {
1224
+ case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
1225
+ case 1:
1226
+ promptResult = _a.sent();
1227
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1228
+ return [2 /*return*/, promptResult];
1229
+ }
1230
+ });
1231
+ }); };
1232
+ }
1233
+ if (llmTools.callEmbeddingModel !== undefined) {
1234
+ proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1235
+ var promptResult;
1236
+ return __generator(this, function (_a) {
1237
+ switch (_a.label) {
1238
+ case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
1239
+ case 1:
1240
+ promptResult = _a.sent();
1241
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1242
+ return [2 /*return*/, promptResult];
1243
+ }
1244
+ });
1245
+ }); };
1246
+ }
1247
+ // <- Note: [🤖]
1248
+ return proxyTools;
1249
+ }
1250
+ /**
1251
+ * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
1252
+ * TODO: [🧠] Is there some meaningfull way how to test this util
1253
+ * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
1254
+ * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
1255
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1256
+ */
1257
+
1056
1258
  /**
1057
1259
  * This error indicates errors during the execution of the pipeline
1058
1260
  *
@@ -1361,188 +1563,6 @@
1361
1563
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1362
1564
  */
1363
1565
 
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
1566
  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"}];
1547
1567
 
1548
1568
  /**
@@ -1618,7 +1638,7 @@
1618
1638
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
1619
1639
  return false;
1620
1640
  }
1621
- // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
1641
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
1622
1642
  return true;
1623
1643
  }
1624
1644
 
@@ -1718,7 +1738,7 @@
1718
1738
  if (!url.startsWith('https://')) {
1719
1739
  return false;
1720
1740
  }
1721
- if (!url.endsWith('.ptbk.md')) {
1741
+ if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.ptbk.md') || url.endsWith('.ptbk'))) {
1722
1742
  return false;
1723
1743
  }
1724
1744
  if (url.includes('#')) {
@@ -2578,10 +2598,6 @@
2578
2598
  * @private within the repository
2579
2599
  */
2580
2600
  function TODO_USE() {
2581
- var value = [];
2582
- for (var _i = 0; _i < arguments.length; _i++) {
2583
- value[_i] = arguments[_i];
2584
- }
2585
2601
  }
2586
2602
 
2587
2603
  /**
@@ -2640,22 +2656,12 @@
2640
2656
  formatName: 'CSV',
2641
2657
  aliases: ['SPREADSHEET', 'TABLE'],
2642
2658
  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
2659
  return true;
2648
2660
  },
2649
2661
  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
2662
  return true;
2654
2663
  },
2655
2664
  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
2665
  throw new Error('Not implemented');
2660
2666
  },
2661
2667
  subvalueDefinitions: [
@@ -2774,20 +2780,12 @@
2774
2780
  formatName: 'JSON',
2775
2781
  mimeType: 'application/json',
2776
2782
  isValid: function (value, settings, schema) {
2777
- TODO_USE(schema /* <- TODO: Use schema here */);
2778
- TODO_USE(settings /* <- TODO: Use settings here */);
2779
2783
  return isValidJsonString(value);
2780
2784
  },
2781
2785
  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
2786
  return true;
2786
2787
  },
2787
2788
  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
2789
  throw new Error('Not implemented');
2792
2790
  },
2793
2791
  subvalueDefinitions: [],
@@ -2869,21 +2867,12 @@
2869
2867
  formatName: 'XML',
2870
2868
  mimeType: 'application/xml',
2871
2869
  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
2870
  return true;
2876
2871
  },
2877
2872
  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
2873
  return true;
2882
2874
  },
2883
2875
  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
2876
  throw new Error('Not implemented');
2888
2877
  },
2889
2878
  subvalueDefinitions: [],
@@ -3116,27 +3105,6 @@
3116
3105
  return [input];
3117
3106
  }
3118
3107
 
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
3108
  /**
3141
3109
  * Replaces parameters in template with values from parameters object
3142
3110
  *
@@ -3249,10 +3217,12 @@
3249
3217
  * @public exported from `@promptbook/utils`
3250
3218
  */
3251
3219
  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;
3220
+ if (text === '') {
3221
+ return 0;
3222
+ }
3223
+ var pagesByLinesCount = Math.ceil(countLines(text) / 44);
3224
+ var pagesByCharactersCount = Math.ceil(countCharacters(text) / 2772);
3225
+ return Math.max(pagesByLinesCount, pagesByCharactersCount);
3256
3226
  }
3257
3227
 
3258
3228
  /**
@@ -3891,7 +3861,6 @@
3891
3861
  $ongoingTemplateResult.$resultString = extractJsonBlock($ongoingTemplateResult.$resultString || '');
3892
3862
  }
3893
3863
  catch (error) {
3894
- keepUnused(error);
3895
3864
  throw new ExpectError(spaceTrim.spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3896
3865
  /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3897
3866
  }
@@ -4069,7 +4038,6 @@
4069
4038
  function getContextForTemplate(template) {
4070
4039
  return __awaiter(this, void 0, void 0, function () {
4071
4040
  return __generator(this, function (_a) {
4072
- TODO_USE(template);
4073
4041
  return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
4074
4042
  });
4075
4043
  });
@@ -4082,11 +4050,9 @@
4082
4050
  */
4083
4051
  function getKnowledgeForTemplate(options) {
4084
4052
  return __awaiter(this, void 0, void 0, function () {
4085
- var preparedPipeline, template;
4053
+ var preparedPipeline;
4086
4054
  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);
4055
+ preparedPipeline = options.preparedPipeline, options.template;
4090
4056
  return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
4091
4057
  var content = _a.content;
4092
4058
  return "- ".concat(content);
@@ -4103,8 +4069,6 @@
4103
4069
  function getExamplesForTemplate(template) {
4104
4070
  return __awaiter(this, void 0, void 0, function () {
4105
4071
  return __generator(this, function (_a) {
4106
- // TODO: [♨] Implement Better - use real index and keyword search
4107
- TODO_USE(template);
4108
4072
  return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
4109
4073
  });
4110
4074
  });
@@ -4123,13 +4087,13 @@
4123
4087
  switch (_b.label) {
4124
4088
  case 0:
4125
4089
  preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
4126
- return [4 /*yield*/, getContextForTemplate(template)];
4090
+ return [4 /*yield*/, getContextForTemplate()];
4127
4091
  case 1:
4128
4092
  context = _b.sent();
4129
4093
  return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
4130
4094
  case 2:
4131
4095
  knowledge = _b.sent();
4132
- return [4 /*yield*/, getExamplesForTemplate(template)];
4096
+ return [4 /*yield*/, getExamplesForTemplate()];
4133
4097
  case 3:
4134
4098
  examples = _b.sent();
4135
4099
  currentDate = new Date().toISOString();
@@ -4364,7 +4328,7 @@
4364
4328
  executionReport = {
4365
4329
  pipelineUrl: preparedPipeline.pipelineUrl,
4366
4330
  title: preparedPipeline.title,
4367
- promptbookUsedVersion: PROMPTBOOK_VERSION,
4331
+ promptbookUsedVersion: PROMPTBOOK_ENGINE_VERSION,
4368
4332
  promptbookRequestedVersion: preparedPipeline.promptbookVersion,
4369
4333
  description: preparedPipeline.description,
4370
4334
  promptExecutions: [],
@@ -5211,16 +5175,13 @@
5211
5175
  function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5212
5176
  var _a;
5213
5177
  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;
5178
+ var sourceContent, name, _b, _c, rootDirname, url, response_1, mimeType, filename_1, fileExtension, mimeType;
5217
5179
  return __generator(this, function (_e) {
5218
5180
  switch (_e.label) {
5219
5181
  case 0:
5220
5182
  sourceContent = knowledgeSource.sourceContent;
5221
5183
  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);
5184
+ _b = options || {}, _c = _b.rootDirname, rootDirname = _c === void 0 ? null : _c, _b.isVerbose;
5224
5185
  if (!name) {
5225
5186
  name = sourceContentToName(sourceContent);
5226
5187
  }
@@ -5500,15 +5461,13 @@
5500
5461
  */
5501
5462
  function prepareTemplates(pipeline, tools, options) {
5502
5463
  return __awaiter(this, void 0, void 0, function () {
5503
- var _a, maxParallelCount, templates, parameters, knowledgePiecesCount, templatesPrepared;
5464
+ var _a, maxParallelCount, templates, knowledgePiecesCount, templatesPrepared;
5504
5465
  var _this = this;
5505
5466
  return __generator(this, function (_b) {
5506
5467
  switch (_b.label) {
5507
5468
  case 0:
5508
5469
  _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);
5470
+ templates = pipeline.templates, pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
5512
5471
  templatesPrepared = new Array(templates.length);
5513
5472
  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
5473
  var dependentParameterNames, preparedContent, preparedTemplate;
@@ -5578,7 +5537,7 @@
5578
5537
  currentPreparation = {
5579
5538
  id: 1,
5580
5539
  // TODO: [🍥]> date: $currentDate(),
5581
- promptbookVersion: PROMPTBOOK_VERSION,
5540
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
5582
5541
  usage: ZERO_USAGE,
5583
5542
  };
5584
5543
  preparations = [
@@ -5718,7 +5677,6 @@
5718
5677
  * Note: This is used in `pipelineJsonToString` utility
5719
5678
  */
5720
5679
  stringify: function (command) {
5721
- keepUnused(command);
5722
5680
  return "---"; // <- TODO: [🛋] Implement
5723
5681
  },
5724
5682
  /**
@@ -5727,7 +5685,6 @@
5727
5685
  * Note: This is used in `pipelineJsonToString` utility
5728
5686
  */
5729
5687
  takeFromPipelineJson: function (pipelineJson) {
5730
- keepUnused(pipelineJson);
5731
5688
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5732
5689
  },
5733
5690
  };
@@ -5910,7 +5867,6 @@
5910
5867
  * Note: This is used in `pipelineJsonToString` utility
5911
5868
  */
5912
5869
  stringify: function (command) {
5913
- keepUnused(command);
5914
5870
  return "---"; // <- TODO: [🛋] Implement
5915
5871
  },
5916
5872
  /**
@@ -5919,7 +5875,6 @@
5919
5875
  * Note: This is used in `pipelineJsonToString` utility
5920
5876
  */
5921
5877
  takeFromTemplateJson: function ($templateJson) {
5922
- keepUnused($templateJson);
5923
5878
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5924
5879
  },
5925
5880
  };
@@ -6151,7 +6106,6 @@
6151
6106
  * Note: This is used in `pipelineJsonToString` utility
6152
6107
  */
6153
6108
  stringify: function (command) {
6154
- keepUnused(command);
6155
6109
  return "---"; // <- TODO: [🛋] Implement
6156
6110
  },
6157
6111
  /**
@@ -6160,7 +6114,6 @@
6160
6114
  * Note: This is used in `pipelineJsonToString` utility
6161
6115
  */
6162
6116
  takeFromTemplateJson: function ($templateJson) {
6163
- keepUnused($templateJson);
6164
6117
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6165
6118
  },
6166
6119
  };
@@ -6479,7 +6432,6 @@
6479
6432
  inputSubparameterNames: inputSubparameterNames,
6480
6433
  outputSubparameterName: outputSubparameterName,
6481
6434
  };
6482
- keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
6483
6435
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
6484
6436
  },
6485
6437
  /**
@@ -6488,7 +6440,6 @@
6488
6440
  * Note: This is used in `pipelineJsonToString` utility
6489
6441
  */
6490
6442
  stringify: function (command) {
6491
- keepUnused(command);
6492
6443
  return "---"; // <- TODO: [🛋] Implement
6493
6444
  },
6494
6445
  /**
@@ -6497,7 +6448,6 @@
6497
6448
  * Note: This is used in `pipelineJsonToString` utility
6498
6449
  */
6499
6450
  takeFromTemplateJson: function ($templateJson) {
6500
- keepUnused($templateJson);
6501
6451
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6502
6452
  },
6503
6453
  };
@@ -6565,7 +6515,6 @@
6565
6515
  * Note: This is used in `pipelineJsonToString` utility
6566
6516
  */
6567
6517
  stringify: function (command) {
6568
- keepUnused(command);
6569
6518
  return "---"; // <- TODO: [🛋] Implement
6570
6519
  },
6571
6520
  /**
@@ -6574,7 +6523,6 @@
6574
6523
  * Note: This is used in `pipelineJsonToString` utility
6575
6524
  */
6576
6525
  takeFromTemplateJson: function ($templateJson) {
6577
- keepUnused($templateJson);
6578
6526
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6579
6527
  },
6580
6528
  };
@@ -6637,7 +6585,6 @@
6637
6585
  * Note: This is used in `pipelineJsonToString` utility
6638
6586
  */
6639
6587
  stringify: function (command) {
6640
- keepUnused(command);
6641
6588
  return "---"; // <- TODO: [🛋] Implement
6642
6589
  },
6643
6590
  /**
@@ -6646,7 +6593,6 @@
6646
6593
  * Note: This is used in `pipelineJsonToString` utility
6647
6594
  */
6648
6595
  takeFromTemplateJson: function ($templateJson) {
6649
- keepUnused($templateJson);
6650
6596
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6651
6597
  },
6652
6598
  };
@@ -6782,7 +6728,6 @@
6782
6728
  * Note: This is used in `pipelineJsonToString` utility
6783
6729
  */
6784
6730
  stringify: function (command) {
6785
- keepUnused(command);
6786
6731
  return "---"; // <- TODO: [🛋] Implement
6787
6732
  },
6788
6733
  /**
@@ -6791,7 +6736,6 @@
6791
6736
  * Note: This is used in `pipelineJsonToString` utility
6792
6737
  */
6793
6738
  takeFromPipelineJson: function (pipelineJson) {
6794
- keepUnused(pipelineJson);
6795
6739
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6796
6740
  },
6797
6741
  /**
@@ -6800,7 +6744,6 @@
6800
6744
  * Note: This is used in `pipelineJsonToString` utility
6801
6745
  */
6802
6746
  takeFromTemplateJson: function ($templateJson) {
6803
- keepUnused($templateJson);
6804
6747
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6805
6748
  },
6806
6749
  };
@@ -6874,7 +6817,6 @@
6874
6817
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6875
6818
  */
6876
6819
  $applyToPipelineJson: function (command, $pipelineJson) {
6877
- keepUnused(command, $pipelineJson);
6878
6820
  // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
6879
6821
  },
6880
6822
  /**
@@ -6883,7 +6825,6 @@
6883
6825
  * Note: `$` is used to indicate that this function mutates given `templateJson`
6884
6826
  */
6885
6827
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
6886
- keepUnused(command, $templateJson, $pipelineJson);
6887
6828
  // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
6888
6829
  },
6889
6830
  /**
@@ -6892,7 +6833,6 @@
6892
6833
  * Note: This is used in `pipelineJsonToString` utility
6893
6834
  */
6894
6835
  stringify: function (command) {
6895
- keepUnused(command);
6896
6836
  return "---"; // <- TODO: [🛋] Implement
6897
6837
  },
6898
6838
  /**
@@ -6901,7 +6841,6 @@
6901
6841
  * Note: This is used in `pipelineJsonToString` utility
6902
6842
  */
6903
6843
  takeFromPipelineJson: function (pipelineJson) {
6904
- keepUnused(pipelineJson);
6905
6844
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6906
6845
  },
6907
6846
  /**
@@ -6910,7 +6849,6 @@
6910
6849
  * Note: This is used in `pipelineJsonToString` utility
6911
6850
  */
6912
6851
  takeFromTemplateJson: function ($templateJson) {
6913
- keepUnused($templateJson);
6914
6852
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6915
6853
  },
6916
6854
  };
@@ -6982,7 +6920,6 @@
6982
6920
  * Note: This is used in `pipelineJsonToString` utility
6983
6921
  */
6984
6922
  stringify: function (command) {
6985
- keepUnused(command);
6986
6923
  return "---"; // <- TODO: [🛋] Implement
6987
6924
  },
6988
6925
  /**
@@ -6991,7 +6928,6 @@
6991
6928
  * Note: This is used in `pipelineJsonToString` utility
6992
6929
  */
6993
6930
  takeFromPipelineJson: function (pipelineJson) {
6994
- keepUnused(pipelineJson);
6995
6931
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6996
6932
  },
6997
6933
  /**
@@ -7000,7 +6936,6 @@
7000
6936
  * Note: This is used in `pipelineJsonToString` utility
7001
6937
  */
7002
6938
  takeFromTemplateJson: function ($templateJson) {
7003
- keepUnused($templateJson);
7004
6939
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7005
6940
  },
7006
6941
  };
@@ -7119,7 +7054,6 @@
7119
7054
  * Note: This is used in `pipelineJsonToString` utility
7120
7055
  */
7121
7056
  stringify: function (command) {
7122
- keepUnused(command);
7123
7057
  return "---"; // <- TODO: [🛋] Implement
7124
7058
  },
7125
7059
  /**
@@ -7128,42 +7062,41 @@
7128
7062
  * Note: This is used in `pipelineJsonToString` utility
7129
7063
  */
7130
7064
  takeFromTemplateJson: function ($templateJson) {
7131
- keepUnused($templateJson);
7132
7065
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7133
7066
  },
7134
7067
  };
7135
7068
 
7136
7069
  /**
7137
- * Parses the PROMPTBOOK_VERSION command
7070
+ * Parses the BOOK_VERSION command
7138
7071
  *
7139
7072
  * @see `documentationUrl` for more details
7140
7073
  * @private within the commands folder
7141
7074
  */
7142
- var promptbookVersionCommandParser = {
7075
+ var bookVersionCommandParser = {
7143
7076
  /**
7144
7077
  * Name of the command
7145
7078
  */
7146
- name: 'PROMPTBOOK_VERSION',
7147
- aliasNames: ['PTBK_VERSION', 'PTBK_V', 'PTBKV'],
7079
+ name: 'BOOK_VERSION',
7080
+ aliasNames: ['PTBK_VERSION', 'PROMPTBOOK_VERSION', 'BOOK'],
7148
7081
  /**
7149
7082
  * BOILERPLATE command can be used in:
7150
7083
  */
7151
7084
  isUsedInPipelineHead: true,
7152
7085
  isUsedInPipelineTemplate: false,
7153
7086
  /**
7154
- * Description of the PROMPTBOOK_VERSION command
7087
+ * Description of the BOOK_VERSION command
7155
7088
  */
7156
- description: "Which version of the promptbook is the .ptbk.md using",
7089
+ description: "Which version of the Book language is the .ptbk.md using",
7157
7090
  /**
7158
7091
  * Link to documentation
7159
7092
  */
7160
7093
  documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/69',
7161
7094
  /**
7162
- * Example usages of the PROMPTBOOK_VERSION command
7095
+ * Example usages of the BOOK_VERSION command
7163
7096
  */
7164
- examples: ["PROMPTBOOK VERSION ".concat(PROMPTBOOK_VERSION), "PTBKV ".concat(PROMPTBOOK_VERSION)],
7097
+ examples: ["BOOK VERSION ".concat(BOOK_LANGUAGE_VERSION), "BOOK ".concat(BOOK_LANGUAGE_VERSION)],
7165
7098
  /**
7166
- * Parses the PROMPTBOOK_VERSION command
7099
+ * Parses the BOOK_VERSION command
7167
7100
  */
7168
7101
  parse: function (input) {
7169
7102
  var args = input.args;
@@ -7174,16 +7107,16 @@
7174
7107
  if (!isValidPromptbookVersion(promptbookVersion)) {
7175
7108
  throw new ParseError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
7176
7109
  }
7177
- if (args.length > 0) {
7110
+ if (args.length > 0 && !(((args.length === 1 && args[0]) || '').toUpperCase() === 'VERSION')) {
7178
7111
  throw new ParseError("Can not have more than one Promptbook version");
7179
7112
  }
7180
7113
  return {
7181
- type: 'PROMPTBOOK_VERSION',
7114
+ type: 'BOOK_VERSION',
7182
7115
  promptbookVersion: promptbookVersion,
7183
7116
  };
7184
7117
  },
7185
7118
  /**
7186
- * Apply the PROMPTBOOK_VERSION command to the `pipelineJson`
7119
+ * Apply the BOOK_VERSION command to the `pipelineJson`
7187
7120
  *
7188
7121
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7189
7122
  */
@@ -7192,21 +7125,19 @@
7192
7125
  $pipelineJson.promptbookVersion = command.promptbookVersion;
7193
7126
  },
7194
7127
  /**
7195
- * Converts the PROMPTBOOK_VERSION command back to string
7128
+ * Converts the BOOK_VERSION command back to string
7196
7129
  *
7197
7130
  * Note: This is used in `pipelineJsonToString` utility
7198
7131
  */
7199
7132
  stringify: function (command) {
7200
- keepUnused(command);
7201
7133
  return "---"; // <- TODO: [🛋] Implement
7202
7134
  },
7203
7135
  /**
7204
- * Reads the PROMPTBOOK_VERSION command from the `PipelineJson`
7136
+ * Reads the BOOK_VERSION command from the `PipelineJson`
7205
7137
  *
7206
7138
  * Note: This is used in `pipelineJsonToString` utility
7207
7139
  */
7208
7140
  takeFromPipelineJson: function (pipelineJson) {
7209
- keepUnused(pipelineJson);
7210
7141
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7211
7142
  },
7212
7143
  };
@@ -7300,7 +7231,6 @@
7300
7231
  * Note: This is used in `pipelineJsonToString` utility
7301
7232
  */
7302
7233
  stringify: function (command) {
7303
- keepUnused(command);
7304
7234
  return "---"; // <- TODO: [🛋] Implement
7305
7235
  },
7306
7236
  /**
@@ -7309,7 +7239,6 @@
7309
7239
  * Note: This is used in `pipelineJsonToString` utility
7310
7240
  */
7311
7241
  takeFromPipelineJson: function (pipelineJson) {
7312
- keepUnused(pipelineJson);
7313
7242
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7314
7243
  },
7315
7244
  };
@@ -7346,8 +7275,7 @@
7346
7275
  * Parses the ACTION command
7347
7276
  */
7348
7277
  parse: function (input) {
7349
- var args = input.args;
7350
- TODO_USE(args);
7278
+ input.args;
7351
7279
  return {
7352
7280
  type: 'ACTION',
7353
7281
  };
@@ -7358,7 +7286,6 @@
7358
7286
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7359
7287
  */
7360
7288
  $applyToPipelineJson: function (command, $pipelineJson) {
7361
- keepUnused(command, $pipelineJson);
7362
7289
  console.error(new NotYetImplementedError('[🛠] Actions are not implemented yet'));
7363
7290
  },
7364
7291
  /**
@@ -7367,7 +7294,6 @@
7367
7294
  * Note: This is used in `pipelineJsonToString` utility
7368
7295
  */
7369
7296
  stringify: function (command) {
7370
- keepUnused(command);
7371
7297
  throw new NotYetImplementedError('[🛠] Actions are not implemented yet');
7372
7298
  },
7373
7299
  /**
@@ -7376,7 +7302,6 @@
7376
7302
  * Note: This is used in `pipelineJsonToString` utility
7377
7303
  */
7378
7304
  takeFromPipelineJson: function (pipelineJson) {
7379
- keepUnused(pipelineJson);
7380
7305
  throw new NotYetImplementedError('[🛠] Actions are not implemented yet');
7381
7306
  },
7382
7307
  };
@@ -7416,9 +7341,7 @@
7416
7341
  * Parses the INSTRUMENT command
7417
7342
  */
7418
7343
  parse: function (input) {
7419
- var args = input.args;
7420
- // TODO: [🛠] Implement
7421
- TODO_USE(args);
7344
+ input.args;
7422
7345
  return {
7423
7346
  type: 'INSTRUMENT',
7424
7347
  };
@@ -7429,7 +7352,6 @@
7429
7352
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7430
7353
  */
7431
7354
  $applyToPipelineJson: function (command, $pipelineJson) {
7432
- keepUnused(command, $pipelineJson);
7433
7355
  console.error(new NotYetImplementedError('[🛠] Instruments are not implemented yet'));
7434
7356
  },
7435
7357
  /**
@@ -7438,7 +7360,6 @@
7438
7360
  * Note: This is used in `pipelineJsonToString` utility
7439
7361
  */
7440
7362
  stringify: function (command) {
7441
- keepUnused(command);
7442
7363
  throw new NotYetImplementedError('[🛠] Instruments are not implemented yet');
7443
7364
  },
7444
7365
  /**
@@ -7447,7 +7368,6 @@
7447
7368
  * Note: This is used in `pipelineJsonToString` utility
7448
7369
  */
7449
7370
  takeFromPipelineJson: function (pipelineJson) {
7450
- keepUnused(pipelineJson);
7451
7371
  throw new NotYetImplementedError('[🛠] Instruments are not implemented yet');
7452
7372
  },
7453
7373
  };
@@ -7512,7 +7432,6 @@
7512
7432
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7513
7433
  */
7514
7434
  $applyToPipelineJson: function (command, $pipelineJson) {
7515
- keepUnused(command, $pipelineJson);
7516
7435
  throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7517
7436
  },
7518
7437
  /**
@@ -7521,7 +7440,6 @@
7521
7440
  * Note: `$` is used to indicate that this function mutates given `templateJson`
7522
7441
  */
7523
7442
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
7524
- keepUnused(command, $templateJson, $pipelineJson);
7525
7443
  throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7526
7444
  },
7527
7445
  /**
@@ -7530,7 +7448,6 @@
7530
7448
  * Note: This is used in `pipelineJsonToString` utility
7531
7449
  */
7532
7450
  stringify: function (command) {
7533
- keepUnused(command);
7534
7451
  return "---"; // <- TODO: [🛋] Implement
7535
7452
  },
7536
7453
  /**
@@ -7539,7 +7456,6 @@
7539
7456
  * Note: This is used in `pipelineJsonToString` utility
7540
7457
  */
7541
7458
  takeFromPipelineJson: function (pipelineJson) {
7542
- keepUnused(pipelineJson);
7543
7459
  throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7544
7460
  },
7545
7461
  /**
@@ -7548,7 +7464,6 @@
7548
7464
  * Note: This is used in `pipelineJsonToString` utility
7549
7465
  */
7550
7466
  takeFromTemplateJson: function ($templateJson) {
7551
- keepUnused($templateJson);
7552
7467
  throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7553
7468
  },
7554
7469
  };
@@ -7566,7 +7481,7 @@
7566
7481
  modelCommandParser,
7567
7482
  parameterCommandParser,
7568
7483
  postprocessCommandParser,
7569
- promptbookVersionCommandParser,
7484
+ bookVersionCommandParser,
7570
7485
  urlCommandParser,
7571
7486
  knowledgeCommandParser,
7572
7487
  actionCommandParser,
@@ -7718,9 +7633,7 @@
7718
7633
  var _loop_1 = function (commandParser) {
7719
7634
  // <- Note: [🦦] Its strange that this type assertion is needed
7720
7635
  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
- }
7636
+ if (just(false)) ;
7724
7637
  else if (usagePlace === 'PIPELINE_HEAD' && !isUsedInPipelineHead) {
7725
7638
  return "continue";
7726
7639
  }
@@ -7880,7 +7793,7 @@
7880
7793
  return;
7881
7794
  }
7882
7795
  if (!section.startsWith('#')) {
7883
- section = "# Untitled\n\n".concat(section);
7796
+ section = "# ".concat(DEFAULT_TITLE, "\n\n").concat(section);
7884
7797
  }
7885
7798
  sections.push(section);
7886
7799
  buffer = [];
@@ -7944,7 +7857,7 @@
7944
7857
  var e_1, _a;
7945
7858
  var sections = splitMarkdownIntoSections(markdown);
7946
7859
  if (sections.length === 0) {
7947
- return '# Untitled';
7860
+ return "# ".concat(DEFAULT_TITLE);
7948
7861
  }
7949
7862
  var flattenedMarkdown = '';
7950
7863
  var parsedSections = sections.map(parseMarkdownSection);
@@ -7955,7 +7868,7 @@
7955
7868
  }
7956
7869
  else {
7957
7870
  parsedSections.unshift(firstSection);
7958
- flattenedMarkdown += "# Untitled" + "\n\n"; // <- [🧠] Maybe 3 new lines?
7871
+ flattenedMarkdown += "# ".concat(DEFAULT_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
7959
7872
  }
7960
7873
  try {
7961
7874
  for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
@@ -8033,7 +7946,7 @@
8033
7946
  * @public exported from `@promptbook/core`
8034
7947
  */
8035
7948
  function pipelineStringToJsonSync(pipelineString) {
8036
- var e_1, _a, e_2, _b;
7949
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
8037
7950
  var $pipelineJson = {
8038
7951
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
8039
7952
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
@@ -8060,11 +7973,18 @@
8060
7973
  }
8061
7974
  // =============================================================
8062
7975
  // Note: 1️⃣ Parsing of the markdown into object
7976
+ if (pipelineString.startsWith('#!')) {
7977
+ var _e = __read(pipelineString.split('\n')), shebangLine_1 = _e[0], restLines = _e.slice(1);
7978
+ if (!(shebangLine_1 || '').includes('ptbk')) {
7979
+ 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 "); }));
7980
+ }
7981
+ pipelineString = restLines.join('\n');
7982
+ }
8063
7983
  pipelineString = removeContentComments(pipelineString);
8064
7984
  pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
8065
7985
  pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
8066
7986
  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: [🥞] */
7987
+ var _f = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _f[0], pipelineSections = _f.slice(1); /* <- Note: [🥞] */
8068
7988
  if (pipelineHead === undefined) {
8069
7989
  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
7990
  }
@@ -8092,6 +8012,8 @@
8092
8012
  if (parameterDescription) {
8093
8013
  existingParameter.description = parameterDescription;
8094
8014
  }
8015
+ existingParameter.isInput = existingParameter.isInput || isInput;
8016
+ existingParameter.isOutput = existingParameter.isOutput || isOutput;
8095
8017
  }
8096
8018
  else {
8097
8019
  $pipelineJson.parameters.push({
@@ -8154,10 +8076,10 @@
8154
8076
  finally { if (e_1) throw e_1.error; }
8155
8077
  }
8156
8078
  var _loop_2 = function (section) {
8157
- var e_3, _d;
8079
+ var e_5, _l, e_6, _m;
8158
8080
  // TODO: Parse template description (the content out of the codeblock and lists)
8159
8081
  var listItems_2 = extractAllListItemsFromMarkdown(section.content);
8160
- var _e = extractOneBlockFromMarkdown(section.content), language = _e.language, content = _e.content;
8082
+ var _o = extractOneBlockFromMarkdown(section.content), language = _o.language, content = _o.content;
8161
8083
  // TODO: [🎾][1] DRY description
8162
8084
  var description_1 = section.content;
8163
8085
  // Note: Remove codeblocks - TODO: [🎾]
@@ -8198,7 +8120,7 @@
8198
8120
  }) === false) {
8199
8121
  templateCommandParser.$applyToTemplateJson({ type: 'TEMPLATE', templateType: 'PROMPT_TEMPLATE' }, $templateJson, $pipelineJson);
8200
8122
  }
8201
- var _loop_3 = function (listItem, command) {
8123
+ var _loop_4 = function (listItem, command) {
8202
8124
  var commandParser = getParserForCommand(command);
8203
8125
  if (commandParser.isUsedInPipelineTemplate !== true /* <- Note: [🦦][4] */) {
8204
8126
  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 +8143,17 @@
8221
8143
  };
8222
8144
  try {
8223
8145
  // 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);
8146
+ 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()) {
8147
+ var _p = commands_1_1.value, listItem = _p.listItem, command = _p.command;
8148
+ _loop_4(listItem, command);
8227
8149
  }
8228
8150
  }
8229
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
8151
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
8230
8152
  finally {
8231
8153
  try {
8232
- if (commands_1_1 && !commands_1_1.done && (_d = commands_1.return)) _d.call(commands_1);
8154
+ if (commands_1_1 && !commands_1_1.done && (_l = commands_1.return)) _l.call(commands_1);
8233
8155
  }
8234
- finally { if (e_3) throw e_3.error; }
8156
+ finally { if (e_5) throw e_5.error; }
8235
8157
  }
8236
8158
  // TODO: [🍧] Should be done in TEMPLATE command
8237
8159
  if ($templateJson.templateType === 'SCRIPT_TEMPLATE') {
@@ -8245,6 +8167,26 @@
8245
8167
  language;
8246
8168
  }
8247
8169
  $templateJson.dependentParameterNames = Array.from(extractParameterNamesFromTemplate($templateJson));
8170
+ try {
8171
+ for (var _q = (e_6 = void 0, __values($templateJson.dependentParameterNames)), _r = _q.next(); !_r.done; _r = _q.next()) {
8172
+ var parameterName = _r.value;
8173
+ // TODO: [🧠] This definition should be made first in the template
8174
+ defineParam({
8175
+ parameterName: parameterName,
8176
+ parameterDescription: null,
8177
+ isInput: false,
8178
+ isOutput: false,
8179
+ // <- 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
8180
+ });
8181
+ }
8182
+ }
8183
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
8184
+ finally {
8185
+ try {
8186
+ if (_r && !_r.done && (_m = _q.return)) _m.call(_q);
8187
+ }
8188
+ finally { if (e_6) throw e_6.error; }
8189
+ }
8248
8190
  /*
8249
8191
  // TODO: [🍧] This should be checked in `MODEL` command + better error message
8250
8192
  if ($templateJson.templateType !== 'PROMPT_TEMPLATE' && $templateJson.modelRequirements !== undefined) {
@@ -8283,12 +8225,54 @@
8283
8225
  try {
8284
8226
  if (pipelineSections_1_1 && !pipelineSections_1_1.done && (_b = pipelineSections_1.return)) _b.call(pipelineSections_1);
8285
8227
  }
8286
- finally { if (e_2) throw e_2.error; }
8228
+ finally { if (e_2) throw e_2.error; }
8229
+ }
8230
+ // =============================================================
8231
+ // Note: 5️⃣ Mark parameters as INPUT if not explicitly set
8232
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isInput; })) {
8233
+ var _loop_3 = function (parameter) {
8234
+ var isThisParameterResulting = $pipelineJson.templates.some(function (template) { return template.resultingParameterName === parameter.name; });
8235
+ if (!isThisParameterResulting) {
8236
+ parameter.isInput = true;
8237
+ }
8238
+ };
8239
+ try {
8240
+ for (var _g = __values($pipelineJson.parameters), _h = _g.next(); !_h.done; _h = _g.next()) {
8241
+ var parameter = _h.value;
8242
+ _loop_3(parameter);
8243
+ }
8244
+ }
8245
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
8246
+ finally {
8247
+ try {
8248
+ if (_h && !_h.done && (_c = _g.return)) _c.call(_g);
8249
+ }
8250
+ finally { if (e_3) throw e_3.error; }
8251
+ }
8252
+ }
8253
+ // =============================================================
8254
+ // Note: 6️⃣ Mark all non-INPUT parameters as OUTPUT if any OUTPUT is not set
8255
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isOutput; })) {
8256
+ try {
8257
+ for (var _j = __values($pipelineJson.parameters), _k = _j.next(); !_k.done; _k = _j.next()) {
8258
+ var parameter = _k.value;
8259
+ if (!parameter.isInput) {
8260
+ parameter.isOutput = true;
8261
+ }
8262
+ }
8263
+ }
8264
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
8265
+ finally {
8266
+ try {
8267
+ if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
8268
+ }
8269
+ finally { if (e_4) throw e_4.error; }
8270
+ }
8287
8271
  }
8288
8272
  // =============================================================
8289
- // Note: 5️⃣ Cleanup of undefined values
8273
+ // Note: 7️⃣ Cleanup of undefined values
8290
8274
  $pipelineJson.templates.forEach(function (templates) {
8291
- var e_4, _a;
8275
+ var e_7, _a;
8292
8276
  try {
8293
8277
  for (var _b = __values(Object.entries(templates)), _c = _b.next(); !_c.done; _c = _b.next()) {
8294
8278
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8297,16 +8281,16 @@
8297
8281
  }
8298
8282
  }
8299
8283
  }
8300
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
8284
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
8301
8285
  finally {
8302
8286
  try {
8303
8287
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8304
8288
  }
8305
- finally { if (e_4) throw e_4.error; }
8289
+ finally { if (e_7) throw e_7.error; }
8306
8290
  }
8307
8291
  });
8308
8292
  $pipelineJson.parameters.forEach(function (parameter) {
8309
- var e_5, _a;
8293
+ var e_8, _a;
8310
8294
  try {
8311
8295
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
8312
8296
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8315,12 +8299,12 @@
8315
8299
  }
8316
8300
  }
8317
8301
  }
8318
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
8302
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
8319
8303
  finally {
8320
8304
  try {
8321
8305
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8322
8306
  }
8323
- finally { if (e_5) throw e_5.error; }
8307
+ finally { if (e_8) throw e_8.error; }
8324
8308
  }
8325
8309
  });
8326
8310
  // =============================================================
@@ -8430,8 +8414,7 @@
8430
8414
  if (!$isRunningInNode()) {
8431
8415
  throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
8432
8416
  }
8433
- var _a = (options || {}).isVerbose, isVerbose = _a === void 0 ? DEFAULT_IS_VERBOSE : _a;
8434
- TODO_USE(isVerbose);
8417
+ (options || {}).isVerbose;
8435
8418
  return {
8436
8419
  stat: promises.stat,
8437
8420
  access: promises.access,
@@ -8677,7 +8660,7 @@
8677
8660
  */
8678
8661
  function $provideExecutablesForNode(options) {
8679
8662
  return __awaiter(this, void 0, void 0, function () {
8680
- var _a, _b, isAutoInstalled, _c, isVerbose;
8663
+ var _a;
8681
8664
  var _d;
8682
8665
  return __generator(this, function (_e) {
8683
8666
  switch (_e.label) {
@@ -8685,9 +8668,7 @@
8685
8668
  if (!$isRunningInNode()) {
8686
8669
  throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8687
8670
  }
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);
8671
+ _a = options || {}, _a.isAutoInstalled, _a.isVerbose;
8691
8672
  _d = {};
8692
8673
  return [4 /*yield*/, locatePandoc()];
8693
8674
  case 1:
@@ -8944,7 +8925,7 @@
8944
8925
  */
8945
8926
  function $provideScrapersForNode(tools, options) {
8946
8927
  return __awaiter(this, void 0, void 0, function () {
8947
- var _a, _b, isAutoInstalled, _c, isVerbose, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8928
+ var _a, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8948
8929
  var e_1, _f;
8949
8930
  return __generator(this, function (_g) {
8950
8931
  switch (_g.label) {
@@ -8952,9 +8933,7 @@
8952
8933
  if (!$isRunningInNode()) {
8953
8934
  throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8954
8935
  }
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);
8936
+ _a = options || {}, _a.isAutoInstalled, _a.isVerbose;
8958
8937
  scrapers = [];
8959
8938
  _g.label = 1;
8960
8939
  case 1:
@@ -10113,7 +10092,7 @@
10113
10092
  */
10114
10093
 
10115
10094
  /**
10116
- * Stores
10095
+ * Stores data in memory (HEAP)
10117
10096
  *
10118
10097
  * @public exported from `@promptbook/core`
10119
10098
  */
@@ -10243,13 +10222,18 @@
10243
10222
  promptResult = _c.sent();
10244
10223
  return [3 /*break*/, 11];
10245
10224
  case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
10246
- case 11: return [4 /*yield*/, storage.setItem(key, {
10225
+ case 11:
10226
+ // TODO: [🧠] !!!!!! How to do timing in mixed cache / non-cache situation
10227
+ // promptResult.timing: FromtoItems
10228
+ return [4 /*yield*/, storage.setItem(key, {
10247
10229
  date: $currentDate(),
10248
- promptbookVersion: PROMPTBOOK_VERSION,
10230
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
10249
10231
  prompt: prompt,
10250
10232
  promptResult: promptResult,
10251
10233
  })];
10252
10234
  case 12:
10235
+ // TODO: [🧠] !!!!!! How to do timing in mixed cache / non-cache situation
10236
+ // promptResult.timing: FromtoItems
10253
10237
  _c.sent();
10254
10238
  return [2 /*return*/, promptResult];
10255
10239
  }
@@ -10323,6 +10307,7 @@
10323
10307
  var _this = this;
10324
10308
  var makeCommand = program.command('make');
10325
10309
  makeCommand.description(spaceTrim__default["default"]("\n Makes a new pipeline collection in given folder\n "));
10310
+ // TODO: [🧅] DRY command arguments
10326
10311
  makeCommand.argument('[path]',
10327
10312
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10328
10313
  'Path to promptbook collection directory', './promptbook-collection');
@@ -10330,13 +10315,13 @@
10330
10315
  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
10316
  makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
10332
10317
  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);
10318
+ makeCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
10319
+ makeCommand.option('-v, --verbose', "Is output verbose", false);
10335
10320
  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
10321
  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;
10322
+ var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reload, isVerbose = _a.verbose, outFile = _a.outFile;
10338
10323
  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;
10324
+ 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
10325
  var _d, e_2, _e, e_1, _f;
10341
10326
  var _this = this;
10342
10327
  return __generator(this, function (_g) {
@@ -10352,22 +10337,22 @@
10352
10337
  .filter(function (_) { return _ !== ''; });
10353
10338
  if (outFile !== DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME && formats.length !== 1) {
10354
10339
  console.error(colors__default["default"].red("You can only use one format if you specify --out-file"));
10355
- process.exit(1);
10340
+ return [2 /*return*/, process.exit(1)];
10356
10341
  }
10357
- options = {
10342
+ prepareAndScrapeOptions = {
10358
10343
  isVerbose: isVerbose,
10359
10344
  isCacheReloaded: isCacheReloaded,
10360
10345
  };
10361
- fs = $provideFilesystemForNode(options);
10362
- llm = $provideLlmToolsForCli(options);
10363
- return [4 /*yield*/, $provideExecutablesForNode(options)];
10346
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
10347
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
10348
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
10364
10349
  case 1:
10365
10350
  executables = _g.sent();
10366
10351
  _d = {
10367
10352
  llm: llm,
10368
10353
  fs: fs
10369
10354
  };
10370
- return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
10355
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
10371
10356
  case 2:
10372
10357
  tools = (_d.scrapers = _g.sent(),
10373
10358
  _d.script = [
@@ -10504,8 +10489,7 @@
10504
10489
  if (isVerbose) {
10505
10490
  console.info(colors__default["default"].cyan(usageToHuman(llm.getTotalUsage())));
10506
10491
  }
10507
- process.exit(0);
10508
- return [2 /*return*/];
10492
+ return [2 /*return*/, process.exit(0)];
10509
10493
  }
10510
10494
  });
10511
10495
  });
@@ -10513,7 +10497,6 @@
10513
10497
  }
10514
10498
  /**
10515
10499
  * TODO: [🥃][main] !!! Allow `ptbk make` without configuring any llm tools
10516
- * TODO: Maybe remove this command - "about" command should be enough?
10517
10500
  * TODO: [0] DRY Javascript and typescript - Maybe make ONLY typescript and for javascript just remove types
10518
10501
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
10519
10502
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
@@ -10714,8 +10697,7 @@
10714
10697
  console.info(colors__default["default"].red("Prettify ".concat(error_1.name, " ").concat(filename)));
10715
10698
  console.error(colors__default["default"].bgRed(error_1.name /* <- 11:11 */));
10716
10699
  console.error(colors__default["default"].red(error_1.stack || error_1.message));
10717
- process.exit(1);
10718
- return [3 /*break*/, 9];
10700
+ return [2 /*return*/, process.exit(1)];
10719
10701
  case 9:
10720
10702
  filenames_1_1 = filenames_1.next();
10721
10703
  return [3 /*break*/, 3];
@@ -10732,8 +10714,7 @@
10732
10714
  return [7 /*endfinally*/];
10733
10715
  case 13:
10734
10716
  console.info(colors__default["default"].green("All pipelines are prettified"));
10735
- process.exit(0);
10736
- return [2 /*return*/];
10717
+ return [2 /*return*/, process.exit(0)];
10737
10718
  }
10738
10719
  });
10739
10720
  });
@@ -10745,6 +10726,606 @@
10745
10726
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
10746
10727
  */
10747
10728
 
10729
+ /**
10730
+ * Pretty print an embedding vector for logging
10731
+ *
10732
+ * @public exported from `@promptbook/core`
10733
+ */
10734
+ function embeddingVectorToString(embeddingVector) {
10735
+ var vectorLength = Math.pow(embeddingVector.reduce(function (acc, val) { return acc + Math.pow(val, 2); }, 0), 0.5);
10736
+ return "[EmbeddingVector; ".concat(embeddingVector.length, " dimensions; length: ").concat(vectorLength.toFixed(2), "; ").concat(embeddingVector.slice(0, 3).join(', '), "...]");
10737
+ }
10738
+
10739
+ /**
10740
+ * Format either small or big number
10741
+ *
10742
+ * @private within the repository
10743
+ */
10744
+ function formatNumber(value) {
10745
+ if (value === 0) {
10746
+ return '0';
10747
+ }
10748
+ for (var exponent = 0; exponent < 15; exponent++) {
10749
+ var factor = Math.pow(10, exponent);
10750
+ var valueRounded = Math.round(value * factor) / factor;
10751
+ if (Math.abs(value - valueRounded) / value <
10752
+ 0.001 /* <- TODO: Pass as option, pass to executionReportJsonToString as option */) {
10753
+ return valueRounded.toFixed(exponent);
10754
+ }
10755
+ }
10756
+ return value.toString();
10757
+ }
10758
+
10759
+ /**
10760
+ * Create a markdown table from a 2D array of strings
10761
+ *
10762
+ * @public exported from `@promptbook/markdown-utils`
10763
+ */
10764
+ function createMarkdownTable(table) {
10765
+ var columnWidths = table.reduce(function (widths, row) {
10766
+ row.forEach(function (subformat, columnIndex) {
10767
+ var cellLength = subformat.length;
10768
+ if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
10769
+ widths[columnIndex] = cellLength;
10770
+ }
10771
+ });
10772
+ return widths;
10773
+ }, []);
10774
+ var header = "| ".concat(table[0]
10775
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
10776
+ .join(' | '), " |");
10777
+ var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
10778
+ var rows = table.slice(1).map(function (row) {
10779
+ var paddedRow = row.map(function (subformat, columnIndex) {
10780
+ return subformat.padEnd(columnWidths[columnIndex]);
10781
+ });
10782
+ return "| ".concat(paddedRow.join(' | '), " |");
10783
+ });
10784
+ return __spreadArray([header, separator], __read(rows), false).join('\n');
10785
+ }
10786
+ /**
10787
+ * TODO: [🏛] This can be part of markdown builder
10788
+ */
10789
+
10790
+ /**
10791
+ * Function createMarkdownChart will draw a chart in markdown from ⬛+🟦 tiles
10792
+ *
10793
+ * @public exported from `@promptbook/markdown-utils`
10794
+ */
10795
+ function createMarkdownChart(options) {
10796
+ var e_1, _a;
10797
+ var nameHeader = options.nameHeader, valueHeader = options.valueHeader, items = options.items, width = options.width, unitName = options.unitName;
10798
+ var from = Math.min.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.from; })), false));
10799
+ var to = Math.max.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.to; })), false));
10800
+ var scale = width / (to - from);
10801
+ var table = [[nameHeader, valueHeader]];
10802
+ try {
10803
+ for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
10804
+ var item = items_1_1.value;
10805
+ var before = Math.round((item.from - from) * scale);
10806
+ var during = Math.round((item.to - item.from) * scale);
10807
+ var after = width - before - during;
10808
+ table.push([removeEmojis(item.title).trim(), '░'.repeat(before) + '█'.repeat(during) + '░'.repeat(after)]);
10809
+ }
10810
+ }
10811
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
10812
+ finally {
10813
+ try {
10814
+ if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
10815
+ }
10816
+ finally { if (e_1) throw e_1.error; }
10817
+ }
10818
+ 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_");
10819
+ return createMarkdownTable(table) + '\n\n' + legend;
10820
+ }
10821
+ /**
10822
+ * TODO: Maybe use Mermain Gant Diagrams
10823
+ * @see https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/
10824
+ */
10825
+
10826
+ /**
10827
+ * Function escapeMarkdownBlock will escape markdown block if needed
10828
+ * It is useful when you want have block in block
10829
+ *
10830
+ * @public exported from `@promptbook/markdown-utils`
10831
+ */
10832
+ function escapeMarkdownBlock(value) {
10833
+ return value.replace(/```/g, '\\`\\`\\`');
10834
+ }
10835
+ /**
10836
+ * TODO: [🏛] This can be part of markdown builder
10837
+ */
10838
+
10839
+ /**
10840
+ * Default options for generating an execution report string
10841
+ *
10842
+ * @public exported from `@promptbook/core`
10843
+ */
10844
+ var ExecutionReportStringOptionsDefaults = {
10845
+ taxRate: 0,
10846
+ chartsWidth: 36,
10847
+ };
10848
+
10849
+ /**
10850
+ * Count the duration of working time
10851
+ *
10852
+ * @private within the repository
10853
+ */
10854
+ function countWorkingDuration(items) {
10855
+ var e_1, _a;
10856
+ var steps = Array.from(new Set(items.flatMap(function (item) { return [item.from, item.to]; })));
10857
+ steps.sort(function (a, b) { return a - b; });
10858
+ var intervals = steps.map(function (step, index) { return [step, steps[index + 1] || 0]; }).slice(0, -1);
10859
+ var duration = 0;
10860
+ var _loop_1 = function (interval) {
10861
+ var _b = __read(interval, 2), from = _b[0], to = _b[1];
10862
+ if (items.some(function (item) { return item.from < to && item.to > from; })) {
10863
+ duration += to - from;
10864
+ }
10865
+ };
10866
+ try {
10867
+ for (var intervals_1 = __values(intervals), intervals_1_1 = intervals_1.next(); !intervals_1_1.done; intervals_1_1 = intervals_1.next()) {
10868
+ var interval = intervals_1_1.value;
10869
+ _loop_1(interval);
10870
+ }
10871
+ }
10872
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
10873
+ finally {
10874
+ try {
10875
+ if (intervals_1_1 && !intervals_1_1.done && (_a = intervals_1.return)) _a.call(intervals_1);
10876
+ }
10877
+ finally { if (e_1) throw e_1.error; }
10878
+ }
10879
+ return duration;
10880
+ }
10881
+
10882
+ /**
10883
+ * Converts execution report from JSON to string format
10884
+ *
10885
+ * @public exported from `@promptbook/core`
10886
+ */
10887
+ function executionReportJsonToString(executionReportJson, options) {
10888
+ var e_1, _a;
10889
+ var _b, _c, _d, _e, _f, _g;
10890
+ var _h = __assign(__assign({}, ExecutionReportStringOptionsDefaults), (options || {})), taxRate = _h.taxRate, chartsWidth = _h.chartsWidth;
10891
+ var executionReportString = spaceTrim.spaceTrim(function (block) { return "\n # ".concat(executionReportJson.title || 'Execution report', "\n\n ").concat(block(executionReportJson.description || ''), "\n "); });
10892
+ var headerList = [];
10893
+ if (executionReportJson.pipelineUrl) {
10894
+ headerList.push("PIPELINE URL ".concat(executionReportJson.pipelineUrl));
10895
+ }
10896
+ headerList.push("PROMPTBOOK VERSION ".concat(executionReportJson.promptbookUsedVersion) +
10897
+ (!executionReportJson.promptbookRequestedVersion
10898
+ ? ''
10899
+ : " *(requested ".concat(executionReportJson.promptbookRequestedVersion, ")*")));
10900
+ if (executionReportJson.promptExecutions.length !== 0) {
10901
+ // TODO: What if startedAt OR/AND completedAt is not defined?
10902
+ var startedAt = moment__default["default"](Math.min.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
10903
+ .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; })
10904
+ .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.start).valueOf(); })), false)));
10905
+ var completedAt = moment__default["default"](Math.max.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
10906
+ .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; })
10907
+ .map(function (promptExecution) { return moment__default["default"](promptExecution.result.timing.complete).valueOf(); })), false)));
10908
+ var timingItems = executionReportJson.promptExecutions.map(function (promptExecution) {
10909
+ var _a, _b, _c, _d;
10910
+ return ({
10911
+ title: promptExecution.prompt.title,
10912
+ 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,
10913
+ 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,
10914
+ });
10915
+ });
10916
+ var costItems = executionReportJson.promptExecutions
10917
+ .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'; })
10918
+ .map(function (promptExecution) {
10919
+ var _a, _b;
10920
+ return ({
10921
+ title: promptExecution.prompt.title,
10922
+ from: 0,
10923
+ 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 */ *
10924
+ (1 + taxRate),
10925
+ });
10926
+ });
10927
+ var duration = moment__default["default"].duration(completedAt.diff(startedAt));
10928
+ var llmDuration = moment__default["default"].duration(countWorkingDuration(timingItems) * 1000);
10929
+ 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'; });
10930
+ var cost = executionsWithKnownCost.reduce(function (cost, promptExecution) {
10931
+ return cost + (promptExecution.result.usage.price.value /* <- Look at uncertain number */ || 0);
10932
+ }, 0);
10933
+ headerList.push("STARTED AT ".concat(moment__default["default"](startedAt).format("YYYY-MM-DD HH:mm:ss")));
10934
+ headerList.push("COMPLETED AT ".concat(moment__default["default"](completedAt).format("YYYY-MM-DD HH:mm:ss")));
10935
+ headerList.push("TOTAL DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
10936
+ headerList.push("TOTAL LLM DURATION ".concat(llmDuration.humanize(MOMENT_ARG_THRESHOLDS)));
10937
+ headerList.push("TOTAL COST $".concat(formatNumber(cost * (1 + taxRate))) +
10938
+ (executionsWithKnownCost.length === executionReportJson.promptExecutions.length
10939
+ ? ''
10940
+ : " *(Some cost is unknown)*") +
10941
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
10942
+ executionReportString += '\n\n' + headerList.map(function (header) { return "- ".concat(header); }).join('\n');
10943
+ executionReportString +=
10944
+ '\n\n' +
10945
+ '## 🗃 Index' +
10946
+ '\n\n' +
10947
+ executionReportJson.promptExecutions
10948
+ .map(function (promptExecution) {
10949
+ // TODO: Make some better system to convert hedings to links
10950
+ var hash = normalizeToKebabCase(promptExecution.prompt.title);
10951
+ if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
10952
+ hash = '-' + hash;
10953
+ }
10954
+ // TODO: Make working hash link for the template in md + pdf
10955
+ return "- [".concat(promptExecution.prompt.title, "](#").concat(hash, ")");
10956
+ })
10957
+ .join('\n');
10958
+ executionReportString +=
10959
+ '\n\n' +
10960
+ '## ⌚ Time chart' +
10961
+ '\n\n' +
10962
+ createMarkdownChart({
10963
+ nameHeader: 'Template',
10964
+ valueHeader: 'Timeline',
10965
+ items: timingItems,
10966
+ width: chartsWidth,
10967
+ unitName: 'seconds',
10968
+ });
10969
+ executionReportString +=
10970
+ '\n\n' +
10971
+ '## 💸 Cost chart' +
10972
+ '\n\n' +
10973
+ createMarkdownChart({
10974
+ nameHeader: 'Template',
10975
+ valueHeader: 'Cost',
10976
+ items: costItems,
10977
+ width: chartsWidth,
10978
+ unitName: 'USD',
10979
+ });
10980
+ }
10981
+ else {
10982
+ headerList.push("TOTAL COST $0 *(Nothing executed)*");
10983
+ }
10984
+ var _loop_1 = function (promptExecution) {
10985
+ executionReportString += '\n\n\n\n' + "## ".concat(promptExecution.prompt.title);
10986
+ var templateList = [];
10987
+ // TODO: What if startedAt OR/AND completedAt is not defined?
10988
+ 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);
10989
+ 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);
10990
+ var duration = moment__default["default"].duration(completedAt.diff(startedAt));
10991
+ // Not need here:
10992
+ // > templateList.push(`STARTED AT ${moment(startedAt).calendar()}`);
10993
+ templateList.push("DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
10994
+ if (typeof ((_g = (_f = promptExecution.result) === null || _f === void 0 ? void 0 : _f.usage) === null || _g === void 0 ? void 0 : _g.price) === 'number') {
10995
+ templateList.push("COST $".concat(formatNumber(promptExecution.result.usage.price * (1 + taxRate))) +
10996
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
10997
+ }
10998
+ else {
10999
+ templateList.push("COST UNKNOWN");
11000
+ }
11001
+ executionReportString += '\n\n' + templateList.map(function (header) { return "- ".concat(header); }).join('\n');
11002
+ /*
11003
+ - MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
11004
+ - MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
11005
+ promptExecution.prompt.modelRequirements.modelName
11006
+
11007
+ */
11008
+ if (just(true)) {
11009
+ executionReportString +=
11010
+ '\n\n\n\n' +
11011
+ spaceTrim.spaceTrim(function (block) {
11012
+ var _a;
11013
+ 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 ");
11014
+ });
11015
+ }
11016
+ if (promptExecution.result && promptExecution.result.content) {
11017
+ executionReportString += '\n\n\n\n' + '### Result' + '\n\n';
11018
+ if (promptExecution.result === undefined) {
11019
+ executionReportString += '*No result*';
11020
+ }
11021
+ else if (typeof promptExecution.result.content === 'string') {
11022
+ executionReportString += spaceTrim.spaceTrim(function (block) { return "\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.result.content)), "\n ```\n "); });
11023
+ }
11024
+ else {
11025
+ executionReportString += embeddingVectorToString(promptExecution.result.content);
11026
+ }
11027
+ }
11028
+ if (promptExecution.error && promptExecution.error.message) {
11029
+ executionReportString +=
11030
+ '\n\n\n\n' +
11031
+ spaceTrim.spaceTrim(function (block) { return "\n\n ### Error\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.error.message)), "\n ```\n\n "); });
11032
+ }
11033
+ };
11034
+ try {
11035
+ for (var _j = __values(executionReportJson.promptExecutions), _k = _j.next(); !_k.done; _k = _j.next()) {
11036
+ var promptExecution = _k.value;
11037
+ _loop_1(promptExecution);
11038
+ }
11039
+ }
11040
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
11041
+ finally {
11042
+ try {
11043
+ if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
11044
+ }
11045
+ finally { if (e_1) throw e_1.error; }
11046
+ }
11047
+ executionReportString = prettifyMarkdown(executionReportString);
11048
+ return executionReportString;
11049
+ }
11050
+ /**
11051
+ * TODO: Add mermaid chart for every report
11052
+ * TODO: [🧠] Allow to filter out some parts of the report by options
11053
+ * TODO: [🧠] Should be in generated file GENERATOR_WARNING
11054
+ */
11055
+
11056
+ /**
11057
+ * Initializes `run` command for Promptbook CLI utilities
11058
+ *
11059
+ * @private internal function of `promptbookCli`
11060
+ */
11061
+ function initializeRunCommand(program) {
11062
+ var _this = this;
11063
+ var runCommand = program.command('run', { isDefault: true });
11064
+ runCommand.description(spaceTrim__default["default"]("\n Runs a pipeline\n "));
11065
+ // TODO: [🧅] DRY command arguments
11066
+ runCommand.argument('<path>',
11067
+ // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .ptbk.md file
11068
+ 'Path to book file');
11069
+ runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
11070
+ runCommand.option('-v, --verbose', "Is output verbose", false);
11071
+ runCommand.option('--no-interactive', "Input is not interactive", false);
11072
+ runCommand.option('-s, --save-report <path>', "Save report to file");
11073
+ // TODO: !!!!!! Implement non-interactive mode - allow to pass input parameters as JSON
11074
+ // TODO: !!!!!! JSON output
11075
+ runCommand.action(function (filePathRaw, options) { return __awaiter(_this, void 0, void 0, function () {
11076
+ 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;
11077
+ var e_1, _g, _h, e_2, _j, e_3, _k, e_4, _l;
11078
+ return __generator(this, function (_m) {
11079
+ switch (_m.label) {
11080
+ case 0:
11081
+ isCacheReloaded = options.reload, options.interactive, isVerbose = options.verbose, saveReport = options.saveReport;
11082
+ if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
11083
+ console.error(colors__default["default"].red("Report file must be .json or .md"));
11084
+ return [2 /*return*/, process.exit(1)];
11085
+ }
11086
+ prepareAndScrapeOptions = {
11087
+ isVerbose: isVerbose,
11088
+ isCacheReloaded: isCacheReloaded,
11089
+ };
11090
+ if (isVerbose) {
11091
+ console.info(colors__default["default"].gray('--- Preparing tools ---'));
11092
+ }
11093
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11094
+ filePath = null;
11095
+ filePathCandidates = [
11096
+ filePathRaw,
11097
+ "".concat(filePathRaw, ".md"),
11098
+ "".concat(filePathRaw, ".book.md"),
11099
+ "".concat(filePathRaw, ".ptbk.md"),
11100
+ ];
11101
+ _m.label = 1;
11102
+ case 1:
11103
+ _m.trys.push([1, 6, 7, 8]);
11104
+ filePathCandidates_1 = __values(filePathCandidates), filePathCandidates_1_1 = filePathCandidates_1.next();
11105
+ _m.label = 2;
11106
+ case 2:
11107
+ if (!!filePathCandidates_1_1.done) return [3 /*break*/, 5];
11108
+ filePathCandidate = filePathCandidates_1_1.value;
11109
+ return [4 /*yield*/, isFileExisting(filePathCandidate, fs)
11110
+ // <- TODO: Also test that among the candidates the file is book not just any file
11111
+ ];
11112
+ case 3:
11113
+ if (_m.sent()
11114
+ // <- TODO: Also test that among the candidates the file is book not just any file
11115
+ ) {
11116
+ filePath = filePathCandidate;
11117
+ return [3 /*break*/, 5];
11118
+ }
11119
+ _m.label = 4;
11120
+ case 4:
11121
+ filePathCandidates_1_1 = filePathCandidates_1.next();
11122
+ return [3 /*break*/, 2];
11123
+ case 5: return [3 /*break*/, 8];
11124
+ case 6:
11125
+ e_1_1 = _m.sent();
11126
+ e_1 = { error: e_1_1 };
11127
+ return [3 /*break*/, 8];
11128
+ case 7:
11129
+ try {
11130
+ if (filePathCandidates_1_1 && !filePathCandidates_1_1.done && (_g = filePathCandidates_1.return)) _g.call(filePathCandidates_1);
11131
+ }
11132
+ finally { if (e_1) throw e_1.error; }
11133
+ return [7 /*endfinally*/];
11134
+ case 8:
11135
+ if (filePath === null) {
11136
+ console.error(colors__default["default"].red("File \"".concat(filePathRaw, "\" does not exist")));
11137
+ return [2 /*return*/, process.exit(1)];
11138
+ }
11139
+ try {
11140
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
11141
+ }
11142
+ catch (error) {
11143
+ if (!(error instanceof Error)) {
11144
+ throw error;
11145
+ }
11146
+ if (!error.message.includes('No LLM tools')) {
11147
+ throw error;
11148
+ }
11149
+ 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 ")));
11150
+ return [2 /*return*/, process.exit(1)];
11151
+ }
11152
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
11153
+ case 9:
11154
+ executables = _m.sent();
11155
+ _h = {
11156
+ llm: llm,
11157
+ fs: fs
11158
+ };
11159
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
11160
+ case 10:
11161
+ tools = (_h.scrapers = _m.sent(),
11162
+ _h.script = [
11163
+ /*new JavascriptExecutionTools(options)*/
11164
+ ],
11165
+ _h);
11166
+ if (isVerbose) {
11167
+ console.info(colors__default["default"].gray('--- Reading file ---'));
11168
+ }
11169
+ return [4 /*yield*/, promises.readFile(filePath, 'utf-8')];
11170
+ case 11:
11171
+ pipelineString = (_m.sent());
11172
+ if (isVerbose) {
11173
+ console.info(colors__default["default"].gray('--- Preparing pipeline ---'));
11174
+ }
11175
+ _m.label = 12;
11176
+ case 12:
11177
+ _m.trys.push([12, 14, , 15]);
11178
+ return [4 /*yield*/, pipelineStringToJson(pipelineString, tools)];
11179
+ case 13:
11180
+ pipeline = _m.sent();
11181
+ return [3 /*break*/, 15];
11182
+ case 14:
11183
+ error_1 = _m.sent();
11184
+ if (!(error_1 instanceof ParseError)) {
11185
+ throw error_1;
11186
+ }
11187
+ console.error(colors__default["default"].red(spaceTrim__default["default"](function (block) { return "\n ".concat(block(error_1.message), "\n\n in ").concat(filePath, "\n "); })));
11188
+ return [2 /*return*/, process.exit(1)];
11189
+ case 15:
11190
+ if (isVerbose) {
11191
+ console.info(colors__default["default"].gray('--- Validating pipeline ---'));
11192
+ }
11193
+ // TODO: !!!!!! Same try-catch for LogicError
11194
+ validatePipeline(pipeline);
11195
+ if (isVerbose) {
11196
+ console.info(colors__default["default"].gray('--- Creating executor ---'));
11197
+ }
11198
+ pipelineExecutor = createPipelineExecutor({
11199
+ pipeline: pipeline,
11200
+ tools: tools,
11201
+ isNotPreparedWarningSupressed: true,
11202
+ maxExecutionAttempts: 3,
11203
+ // <- TODO: !!!!!! Why "LLM execution failed undefinedx"
11204
+ maxParallelCount: 1, // <- TODO: !!!!!! Pass
11205
+ });
11206
+ if (isVerbose) {
11207
+ console.info(colors__default["default"].gray('--- Getting input parameters ---'));
11208
+ }
11209
+ questions = pipeline.parameters
11210
+ .filter(function (_a) {
11211
+ var isInput = _a.isInput;
11212
+ return isInput;
11213
+ })
11214
+ .map(function (_a) {
11215
+ var name = _a.name, exampleValues = _a.exampleValues;
11216
+ var message = name;
11217
+ var initial = '';
11218
+ if (exampleValues && exampleValues.length > 0) {
11219
+ var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1 && countCharacters(exampleValue) <= 30; });
11220
+ if (exampleValuesFiltered.length !== 0) {
11221
+ message += " (e.g. ".concat(exampleValuesFiltered.join(', '), ")");
11222
+ }
11223
+ initial = exampleValues[0] || '';
11224
+ }
11225
+ return {
11226
+ type: 'text',
11227
+ name: name,
11228
+ message: message,
11229
+ initial: initial,
11230
+ // TODO: Maybe use> validate: value => value < 18 ? `Forbidden` : true
11231
+ };
11232
+ });
11233
+ return [4 /*yield*/, prompts__default["default"](questions)];
11234
+ case 16:
11235
+ response = _m.sent();
11236
+ inputParameters = response;
11237
+ if (isVerbose) {
11238
+ console.info(colors__default["default"].gray('--- Executing ---'));
11239
+ }
11240
+ return [4 /*yield*/, pipelineExecutor(inputParameters, function (taskProgress) {
11241
+ if (isVerbose) {
11242
+ console.info(colors__default["default"].gray('--- Progress ---'));
11243
+ console.info(taskProgress);
11244
+ }
11245
+ })];
11246
+ case 17:
11247
+ result = _m.sent();
11248
+ isSuccessful = result.isSuccessful, errors = result.errors, warnings = result.warnings, outputParameters = result.outputParameters, executionReport = result.executionReport;
11249
+ if (isVerbose) {
11250
+ console.info(colors__default["default"].gray('--- Detailed Result ---'));
11251
+ console.info({ isSuccessful: isSuccessful, errors: errors, warnings: warnings, outputParameters: outputParameters, executionReport: executionReport });
11252
+ }
11253
+ if (!(saveReport && saveReport.endsWith('.json'))) return [3 /*break*/, 19];
11254
+ return [4 /*yield*/, promises.writeFile(saveReport, JSON.stringify(executionReport, null, 4) + '\n', 'utf-8')];
11255
+ case 18:
11256
+ _m.sent();
11257
+ return [3 /*break*/, 21];
11258
+ case 19:
11259
+ if (!(saveReport && saveReport.endsWith('.md'))) return [3 /*break*/, 21];
11260
+ executionReportString = executionReportJsonToString(executionReport);
11261
+ return [4 /*yield*/, promises.writeFile(saveReport, executionReportString, 'utf-8')];
11262
+ case 20:
11263
+ _m.sent();
11264
+ _m.label = 21;
11265
+ case 21:
11266
+ if (saveReport && isVerbose) {
11267
+ console.info(colors__default["default"].green("Report saved to ".concat(saveReport)));
11268
+ }
11269
+ if (isVerbose) {
11270
+ console.info(colors__default["default"].gray('--- Usage ---'));
11271
+ console.info(colors__default["default"].cyan(usageToHuman(result.usage)));
11272
+ }
11273
+ console.info(colors__default["default"].gray('--- Result ---'));
11274
+ try {
11275
+ // TODO: [🧠] Should be errors or warnings shown first
11276
+ for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
11277
+ error = _b.value;
11278
+ console.error(colors__default["default"].red(colors__default["default"].bold(error.name) + ': ' + error.message));
11279
+ }
11280
+ }
11281
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
11282
+ finally {
11283
+ try {
11284
+ if (_b && !_b.done && (_j = _a.return)) _j.call(_a);
11285
+ }
11286
+ finally { if (e_2) throw e_2.error; }
11287
+ }
11288
+ try {
11289
+ for (_c = __values(warnings || []), _d = _c.next(); !_d.done; _d = _c.next()) {
11290
+ warning = _d.value;
11291
+ console.error(colors__default["default"].red(colors__default["default"].bold(warning.name) + ': ' + warning.message));
11292
+ }
11293
+ }
11294
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
11295
+ finally {
11296
+ try {
11297
+ if (_d && !_d.done && (_k = _c.return)) _k.call(_c);
11298
+ }
11299
+ finally { if (e_3) throw e_3.error; }
11300
+ }
11301
+ try {
11302
+ for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11303
+ key = _f.value;
11304
+ value = outputParameters[key] || colors__default["default"].grey(colors__default["default"].italic('(nothing)'));
11305
+ separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11306
+ console.info(colors__default["default"].green(colors__default["default"].bold(key) + separator + value));
11307
+ }
11308
+ }
11309
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
11310
+ finally {
11311
+ try {
11312
+ if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11313
+ }
11314
+ finally { if (e_4) throw e_4.error; }
11315
+ }
11316
+ return [2 /*return*/, process.exit(0)];
11317
+ }
11318
+ });
11319
+ }); });
11320
+ }
11321
+ /**
11322
+ * TODO: !!!!!! Catch and wrap all errors from CLI
11323
+ * TODO: [🧠] Pass `maxExecutionAttempts`, `csvSettings`
11324
+ * TODO: [🥃][main] !!! Allow `ptbk run` without configuring any llm tools
11325
+ * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
11326
+ * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
11327
+ */
11328
+
10748
11329
  /**
10749
11330
  * Initializes `test` command for Promptbook CLI utilities
10750
11331
  *
@@ -10758,30 +11339,30 @@
10758
11339
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10759
11340
  'Pipelines to test as glob pattern');
10760
11341
  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);
11342
+ testCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache ", false);
10762
11343
  testCommand.option('-v, --verbose', "Is output verbose", false);
10763
11344
  testCommand.action(function (filesGlob, _a) {
10764
- var ignore = _a.ignore, isCacheReloaded = _a.reloadCache, isVerbose = _a.verbose;
11345
+ var ignore = _a.ignore, isCacheReloaded = _a.reload, isVerbose = _a.verbose;
10765
11346
  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;
11347
+ var prepareAndScrapeOptions, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
10767
11348
  var _d, e_1, _e;
10768
11349
  return __generator(this, function (_f) {
10769
11350
  switch (_f.label) {
10770
11351
  case 0:
10771
- options = {
11352
+ prepareAndScrapeOptions = {
10772
11353
  isVerbose: isVerbose,
10773
11354
  isCacheReloaded: isCacheReloaded,
10774
11355
  };
10775
- fs = $provideFilesystemForNode(options);
10776
- llm = $provideLlmToolsForCli(options);
10777
- return [4 /*yield*/, $provideExecutablesForNode(options)];
11356
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11357
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
11358
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
10778
11359
  case 1:
10779
11360
  executables = _f.sent();
10780
11361
  _d = {
10781
11362
  llm: llm,
10782
11363
  fs: fs
10783
11364
  };
10784
- return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
11365
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
10785
11366
  case 2:
10786
11367
  tools = (_d.scrapers = _f.sent(),
10787
11368
  _d.script = [
@@ -10838,8 +11419,7 @@
10838
11419
  console.info(colors__default["default"].red("Pipeline is not valid ".concat(filename)));
10839
11420
  console.error(colors__default["default"].bgRed(error_1.name /* <- 11:11 */));
10840
11421
  console.error(colors__default["default"].red(error_1.stack || error_1.message));
10841
- process.exit(1);
10842
- return [3 /*break*/, 14];
11422
+ return [2 /*return*/, process.exit(1)];
10843
11423
  case 14:
10844
11424
  filenames_1_1 = filenames_1.next();
10845
11425
  return [3 /*break*/, 5];
@@ -10856,8 +11436,7 @@
10856
11436
  return [7 /*endfinally*/];
10857
11437
  case 18:
10858
11438
  console.info(colors__default["default"].green("All pipelines are valid"));
10859
- process.exit(0);
10860
- return [2 /*return*/];
11439
+ return [2 /*return*/, process.exit(0)];
10861
11440
  }
10862
11441
  });
10863
11442
  });
@@ -10877,17 +11456,23 @@
10877
11456
  */
10878
11457
  function promptbookCli() {
10879
11458
  return __awaiter(this, void 0, void 0, function () {
10880
- var program;
11459
+ var isVerbose, program;
10881
11460
  return __generator(this, function (_a) {
10882
11461
  if (!$isRunningInNode()) {
10883
11462
  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
11463
  }
11464
+ isVerbose = process.argv.some(function (arg) { return arg === '--verbose' || arg === '-v'; });
11465
+ // <- TODO: Can be this be done with commander before the commander commands are initialized?
11466
+ if (isVerbose) {
11467
+ console.info(colors__default["default"].gray("Promptbook CLI version ".concat(PROMPTBOOK_ENGINE_VERSION, " in ").concat(__filename.split('\\').join('/'))));
11468
+ }
10885
11469
  program = new commander__default["default"].Command();
10886
11470
  program.name('promptbook');
10887
11471
  program.alias('ptbk');
10888
- program.version(PROMPTBOOK_VERSION);
10889
- program.description(spaceTrim.spaceTrim("\n Promptbook utilities for enhancing workflow with promptbooks\n "));
11472
+ program.version(PROMPTBOOK_ENGINE_VERSION);
11473
+ program.description(CLAIM);
10890
11474
  initializeAboutCommand(program);
11475
+ initializeRunCommand(program);
10891
11476
  initializeHelloCommand(program);
10892
11477
  initializeMakeCommand(program);
10893
11478
  initializePrettifyCommand(program);
@@ -10898,6 +11483,7 @@
10898
11483
  });
10899
11484
  }
10900
11485
  /**
11486
+ * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.ptbk.md` -> `ptbk ./foo.ptbk.md`
10901
11487
  * TODO: [🥠] Do not export, its just for CLI script
10902
11488
  * TODO: [🕌] When more functionalities, rename
10903
11489
  * Note: 11:11
@@ -12487,8 +13073,6 @@
12487
13073
  };
12488
13074
  },
12489
13075
  createConfigurationFromEnv: function (env) {
12490
- // TODO: Maybe auto-configure (multiple) assistants from env variables
12491
- keepUnused(env);
12492
13076
  return null;
12493
13077
  /*
12494
13078
  if (typeof env.OPENAI_API_KEY === 'string' || typeof env.OPENAI_XXX === 'string') {
@@ -13215,12 +13799,9 @@
13215
13799
  })
13216
13800
  .filter(function (arg) { return arg !== ''; });
13217
13801
  if (_.length > 1) {
13218
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13219
13802
  _a = __read(_), command = _a[0], args = _a.slice(1);
13220
13803
  }
13221
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13222
13804
  if (options.args) {
13223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13224
13805
  args = __spreadArray(__spreadArray([], __read(args), false), __read(options.args), false);
13225
13806
  }
13226
13807
  var humanReadableCommand = !['npx', 'npm'].includes(command) ? command : args[0];
@@ -13341,12 +13922,12 @@
13341
13922
  */
13342
13923
  function getScraperIntermediateSource(source, options) {
13343
13924
  return __awaiter(this, void 0, void 0, function () {
13344
- var sourceFilename, url, rootDirname, cacheDirname, intermediateFilesStrategy, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
13925
+ var sourceFilename, url, cacheDirname, intermediateFilesStrategy, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
13345
13926
  return __generator(this, function (_a) {
13346
13927
  switch (_a.label) {
13347
13928
  case 0:
13348
13929
  sourceFilename = source.filename, url = source.url;
13349
- rootDirname = options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, extension = options.extension, isVerbose = options.isVerbose;
13930
+ options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, extension = options.extension, isVerbose = options.isVerbose;
13350
13931
  hash = cryptoJs.SHA256(
13351
13932
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
13352
13933
  hexEncoder__default["default"].parse(sourceFilename || url || 'untitled'))
@@ -13355,8 +13936,6 @@
13355
13936
  semanticName = normalizeToKebabCase(titleToName((sourceFilename || url || '').split('intermediate').join(''))).substring(0, 20);
13356
13937
  pieces = ['intermediate', semanticName, hash].filter(function (piece) { return piece !== ''; });
13357
13938
  name = pieces.join('-').split('--').join('-');
13358
- // <- TODO: Use MAX_FILENAME_LENGTH
13359
- TODO_USE(rootDirname); // <- TODO: [😡]
13360
13939
  cacheFilename = path.join.apply(void 0, __spreadArray(__spreadArray([process.cwd(),
13361
13940
  cacheDirname], __read(nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */)), false), [name], false)).split('\\')
13362
13941
  .join('/') +
@@ -13455,13 +14034,13 @@
13455
14034
  */
13456
14035
  MarkdownScraper.prototype.scrape = function (source) {
13457
14036
  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;
14037
+ var _a, _c, isVerbose, llm, _llms, llmTools, collection, prepareKnowledgeFromMarkdownExecutor, _d, prepareTitleExecutor, _e, prepareKeywordsExecutor, _f, knowledgeContent, result, outputParameters, knowledgePiecesRaw, knowledgeTextPieces, knowledge;
13459
14038
  var _g, _h, _j;
13460
14039
  var _this = this;
13461
14040
  return __generator(this, function (_k) {
13462
14041
  switch (_k.label) {
13463
14042
  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;
14043
+ _a = this.options, _a.maxParallelCount, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c;
13465
14044
  llm = this.tools.llm;
13466
14045
  if (llm === undefined) {
13467
14046
  throw new MissingToolsError('LLM tools are required for scraping external files');
@@ -13469,7 +14048,6 @@
13469
14048
  }
13470
14049
  _llms = arrayableToArray(llm);
13471
14050
  llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(_llms), false));
13472
- TODO_USE(maxParallelCount); // <- [🪂]
13473
14051
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
13474
14052
  _d = createPipelineExecutor;
13475
14053
  _g = {};
@@ -14060,7 +14638,6 @@
14060
14638
  PdfScraper.prototype.$convert = function (source) {
14061
14639
  return __awaiter(this, void 0, void 0, function () {
14062
14640
  return __generator(this, function (_a) {
14063
- TODO_USE(source);
14064
14641
  TODO_USE(this.options);
14065
14642
  throw new NotYetImplementedError('PDF conversion not yet implemented');
14066
14643
  });
@@ -14072,7 +14649,6 @@
14072
14649
  PdfScraper.prototype.scrape = function (source) {
14073
14650
  return __awaiter(this, void 0, void 0, function () {
14074
14651
  return __generator(this, function (_a) {
14075
- TODO_USE(source);
14076
14652
  TODO_USE(this.options);
14077
14653
  /*
14078
14654
  const {
@@ -14315,7 +14891,8 @@
14315
14891
  * TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
14316
14892
  */
14317
14893
 
14318
- exports.PROMPTBOOK_VERSION = PROMPTBOOK_VERSION;
14894
+ exports.BOOK_LANGUAGE_VERSION = BOOK_LANGUAGE_VERSION;
14895
+ exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;
14319
14896
  exports._AnthropicClaudeMetadataRegistration = _AnthropicClaudeMetadataRegistration;
14320
14897
  exports._AnthropicClaudeRegistration = _AnthropicClaudeRegistration;
14321
14898
  exports._AzureOpenAiMetadataRegistration = _AzureOpenAiMetadataRegistration;