@promptbook/cli 0.74.0-0 → 0.74.0-12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +137 -32
  2. package/bin/promptbook-cli.js +6 -1
  3. package/esm/index.es.js +1078 -500
  4. package/esm/index.es.js.map +1 -1
  5. package/esm/typings/src/_packages/anthropic-claude.index.d.ts +2 -2
  6. package/esm/typings/src/_packages/azure-openai.index.d.ts +2 -2
  7. package/esm/typings/src/_packages/browser.index.d.ts +2 -2
  8. package/esm/typings/src/_packages/cli.index.d.ts +2 -2
  9. package/esm/typings/src/_packages/core.index.d.ts +7 -3
  10. package/esm/typings/src/_packages/documents.index.d.ts +2 -2
  11. package/esm/typings/src/_packages/execute-javascript.index.d.ts +2 -2
  12. package/esm/typings/src/_packages/fake-llm.index.d.ts +2 -2
  13. package/esm/typings/src/_packages/langtail.index.d.ts +2 -2
  14. package/esm/typings/src/_packages/legacy-documents.index.d.ts +2 -2
  15. package/esm/typings/src/_packages/markdown-utils.index.d.ts +2 -2
  16. package/esm/typings/src/_packages/node.index.d.ts +2 -2
  17. package/esm/typings/src/_packages/openai.index.d.ts +2 -2
  18. package/esm/typings/src/_packages/pdf.index.d.ts +2 -2
  19. package/esm/typings/src/_packages/remote-client.index.d.ts +2 -2
  20. package/esm/typings/src/_packages/remote-server.index.d.ts +2 -2
  21. package/esm/typings/src/_packages/utils.index.d.ts +2 -2
  22. package/esm/typings/src/_packages/website-crawler.index.d.ts +2 -2
  23. package/esm/typings/src/cli/cli-commands/make.d.ts +0 -1
  24. package/esm/typings/src/cli/cli-commands/run.d.ts +14 -0
  25. package/esm/typings/src/cli/promptbookCli.d.ts +1 -0
  26. package/esm/typings/src/cli/test/ptbk.d.ts +5 -2
  27. package/esm/typings/src/collection/collectionToJson.test.d.ts +1 -1
  28. package/esm/typings/src/collection/constructors/createCollectionFromDirectory.d.ts +1 -1
  29. package/esm/typings/src/commands/BOOK_VERSION/BookVersionCommand.d.ts +11 -0
  30. package/esm/typings/src/commands/BOOK_VERSION/bookVersionCommandParser.d.ts +9 -0
  31. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +2 -2
  32. package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
  33. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  34. package/esm/typings/src/commands/index.d.ts +1 -1
  35. package/esm/typings/src/config.d.ts +6 -0
  36. package/esm/typings/src/conversion/pipelineJsonToString.d.ts +3 -3
  37. package/esm/typings/src/conversion/pipelineStringToJson.d.ts +2 -2
  38. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +2 -2
  39. package/esm/typings/src/conversion/utils/stringifyPipelineJson.d.ts +1 -1
  40. package/esm/typings/src/conversion/validation/_importPipeline.d.ts +7 -7
  41. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +1 -1
  42. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +1 -1
  43. package/esm/typings/src/storage/blackhole/BlackholeStorage.d.ts +33 -0
  44. package/esm/typings/src/storage/memory/MemoryStorage.d.ts +1 -1
  45. package/esm/typings/src/storage/{memory/utils → utils}/PrefixStorage.d.ts +1 -1
  46. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +6 -4
  47. package/esm/typings/src/types/PipelineJson/PreparationJson.d.ts +1 -1
  48. package/esm/typings/src/types/Prompt.d.ts +1 -1
  49. package/esm/typings/src/types/typeAliases.d.ts +2 -2
  50. package/esm/typings/src/version.d.ts +13 -2
  51. package/package.json +8 -4
  52. package/umd/index.umd.js +1083 -504
  53. package/umd/index.umd.js.map +1 -1
  54. package/esm/typings/src/commands/PROMPTBOOK_VERSION/PromptbookVersionCommand.d.ts +0 -11
  55. package/esm/typings/src/commands/PROMPTBOOK_VERSION/promptbookVersionCommandParser.d.ts +0 -9
  56. /package/esm/typings/src/commands/{PROMPTBOOK_VERSION/promptbookVersionCommand.test.d.ts → BOOK_VERSION/bookVersionCommand.test.d.ts} +0 -0
  57. /package/esm/typings/src/storage/{memory → local-storage}/utils/makePromptbookStorageFromWebStorage.d.ts +0 -0
package/esm/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
+ import colors from 'colors';
1
2
  import commander from 'commander';
2
3
  import spaceTrim$1, { spaceTrim } from 'spacetrim';
3
- import colors from 'colors';
4
4
  import { forTime } from 'waitasecond';
5
5
  import { stat, access, constants, readFile, writeFile, readdir, mkdir, unlink, rm, rmdir, rename } from 'fs/promises';
6
6
  import { join, basename, dirname } from 'path';
@@ -15,6 +15,8 @@ import { promisify } from 'util';
15
15
  import * as dotenv from 'dotenv';
16
16
  import sha256 from 'crypto-js/sha256';
17
17
  import glob from 'glob-promise';
18
+ import prompts from 'prompts';
19
+ import moment from 'moment';
18
20
  import { io } from 'socket.io-client';
19
21
  import Anthropic from '@anthropic-ai/sdk';
20
22
  import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
@@ -25,10 +27,20 @@ import { Converter } from 'showdown';
25
27
 
26
28
  // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
27
29
  /**
28
- * The version of the Promptbook library
30
+ * The version of the Book language
31
+ *
32
+ * @see https://github.com/webgptorg/book
33
+ */
34
+ var BOOK_LANGUAGE_VERSION = '1.0.0';
35
+ /**
36
+ * The version of the Promptbook engine
37
+ *
38
+ * @see https://github.com/webgptorg/promptbook
39
+ */
40
+ var PROMPTBOOK_ENGINE_VERSION = '0.74.0-11';
41
+ /**
42
+ * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
29
43
  */
30
- var PROMPTBOOK_VERSION = '0.73.0';
31
- // TODO: [main] !!!! List here all the versions and annotate + put into script
32
44
 
33
45
  /*! *****************************************************************************
34
46
  Copyright (c) Microsoft Corporation.
@@ -149,31 +161,6 @@ function __spreadArray(to, from, pack) {
149
161
  return to.concat(ar || Array.prototype.slice.call(from));
150
162
  }
151
163
 
152
- /**
153
- * This error type indicates that you try to use a feature that is not available in the current environment
154
- *
155
- * @public exported from `@promptbook/core`
156
- */
157
- var EnvironmentMismatchError = /** @class */ (function (_super) {
158
- __extends(EnvironmentMismatchError, _super);
159
- function EnvironmentMismatchError(message) {
160
- var _this = _super.call(this, message) || this;
161
- _this.name = 'EnvironmentMismatchError';
162
- Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
163
- return _this;
164
- }
165
- return EnvironmentMismatchError;
166
- }(Error));
167
-
168
- /**
169
- * Detects if the code is running in a Node.js environment
170
- *
171
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
172
- *
173
- * @public exported from `@promptbook/utils`
174
- */
175
- var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
176
-
177
164
  /**
178
165
  * Returns the same value that is passed as argument.
179
166
  * No side effects.
@@ -402,6 +389,12 @@ var GENERATOR_WARNING = "\u26A0\uFE0F WARNING: This code has been generated so t
402
389
  */
403
390
  var CLAIM = "Build responsible, controlled and transparent applications on top of LLM models!";
404
391
  // <- TODO: [🐊] Pick the best claim
392
+ /**
393
+ * When the title is not provided, the default title is used
394
+ *
395
+ * @public exported from `@promptbook/core`
396
+ */
397
+ var DEFAULT_TITLE = "Untitled";
405
398
  /**
406
399
  * Warning message for the generated sections and files files
407
400
  *
@@ -515,6 +508,15 @@ var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
515
508
  * @private within the repository
516
509
  */
517
510
  var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
511
+ /**
512
+ * The thresholds for the relative time in the `moment` NPM package.
513
+ *
514
+ * @see https://momentjscom.readthedocs.io/en/latest/moment/07-customization/13-relative-time-threshold/
515
+ * @private within the repository - too low-level in comparison with other constants
516
+ */
517
+ var MOMENT_ARG_THRESHOLDS = {
518
+ 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.
519
+ };
518
520
  /**
519
521
  * @@@
520
522
  *
@@ -545,12 +547,6 @@ var DEFAULT_CSV_SETTINGS = Object.freeze({
545
547
  * @public exported from `@promptbook/core`
546
548
  */
547
549
  var DEFAULT_IS_VERBOSE = false;
548
- /**
549
- * @@@
550
- *
551
- * @public exported from `@promptbook/core`
552
- */
553
- var DEFAULT_IS_AUTO_INSTALLED = false;
554
550
  /**
555
551
  * @@@
556
552
  *
@@ -564,6 +560,31 @@ true);
564
560
  * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
565
561
  */
566
562
 
563
+ /**
564
+ * This error type indicates that you try to use a feature that is not available in the current environment
565
+ *
566
+ * @public exported from `@promptbook/core`
567
+ */
568
+ var EnvironmentMismatchError = /** @class */ (function (_super) {
569
+ __extends(EnvironmentMismatchError, _super);
570
+ function EnvironmentMismatchError(message) {
571
+ var _this = _super.call(this, message) || this;
572
+ _this.name = 'EnvironmentMismatchError';
573
+ Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
574
+ return _this;
575
+ }
576
+ return EnvironmentMismatchError;
577
+ }(Error));
578
+
579
+ /**
580
+ * Detects if the code is running in a Node.js environment
581
+ *
582
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
583
+ *
584
+ * @public exported from `@promptbook/utils`
585
+ */
586
+ var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
587
+
567
588
  /**
568
589
  * Initializes `about` command for Promptbook CLI utilities
569
590
  *
@@ -575,12 +596,12 @@ function initializeAboutCommand(program) {
575
596
  makeCommand.description(spaceTrim$1("\n Tells about Promptbook CLI and its abilities\n "));
576
597
  makeCommand.action(function () { return __awaiter(_this, void 0, void 0, function () {
577
598
  return __generator(this, function (_a) {
578
- console.info(colors.cyan("Promptbook"));
579
- console.info(colors.cyan(CLAIM));
580
- console.info(colors.cyan("Version: ".concat(PROMPTBOOK_VERSION)));
599
+ console.info(colors.bold(colors.cyan("Promptbook: ".concat(CLAIM))));
600
+ console.info(colors.cyan("Book language version: ".concat(BOOK_LANGUAGE_VERSION)));
601
+ console.info(colors.cyan("Promptbook engine version: ".concat(PROMPTBOOK_ENGINE_VERSION)));
602
+ console.info(colors.cyan("https://github.com/webgptorg/promptbook"));
581
603
  console.info(colors.cyan("https://ptbk.io"));
582
- process.exit(0);
583
- return [2 /*return*/];
604
+ return [2 /*return*/, process.exit(0)];
584
605
  });
585
606
  }); });
586
607
  }
@@ -611,8 +632,7 @@ function initializeHelloCommand(program) {
611
632
  case 1:
612
633
  _b.sent();
613
634
  console.info(colors.rainbow("Nice to meet you!"));
614
- process.exit(0);
615
- return [2 /*return*/];
635
+ return [2 /*return*/, process.exit(0)];
616
636
  }
617
637
  });
618
638
  });
@@ -696,13 +716,13 @@ function capitalize(word) {
696
716
  /**
697
717
  * Converts promptbook in JSON format to string format
698
718
  *
699
- * @param pipelineJson Promptbook in JSON format (.ptbk.json)
700
- * @returns Promptbook in string format (.ptbk.md)
719
+ * @param pipelineJson Promptbook in JSON format (.book.json)
720
+ * @returns Promptbook in string format (.book.md)
701
721
  * @public exported from `@promptbook/core`
702
722
  */
703
723
  function pipelineJsonToString(pipelineJson) {
704
724
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
705
- var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, promptbookVersion = pipelineJson.promptbookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
725
+ var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, bookVersion = pipelineJson.bookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
706
726
  var pipelineString = "# ".concat(title);
707
727
  if (description) {
708
728
  pipelineString += '\n\n';
@@ -712,8 +732,10 @@ function pipelineJsonToString(pipelineJson) {
712
732
  if (pipelineUrl) {
713
733
  commands.push("PIPELINE URL ".concat(pipelineUrl));
714
734
  }
715
- commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
716
- // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
735
+ if (bookVersion !== "undefined") {
736
+ commands.push("BOOK VERSION ".concat(bookVersion));
737
+ }
738
+ // TODO: [main] !!!!!! This increase size of the bundle and is probbably not necessary
717
739
  pipelineString = prettifyMarkdown(pipelineString);
718
740
  try {
719
741
  for (var _g = __values(parameters.filter(function (_a) {
@@ -893,7 +915,7 @@ function templateParameterJsonToString(templateParameterJson) {
893
915
  * TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
894
916
  * TODO: [🏛] Maybe make some markdown builder
895
917
  * TODO: [🏛] Escape all
896
- * TODO: [🧠] Should be in generated .ptbk.md file GENERATOR_WARNING
918
+ * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
897
919
  */
898
920
 
899
921
  /**
@@ -1041,6 +1063,188 @@ var UNCERTAIN_USAGE = $deepFreeze({
1041
1063
  },
1042
1064
  });
1043
1065
 
1066
+ /**
1067
+ * @@@
1068
+ *
1069
+ * @public exported from `@promptbook/utils`
1070
+ */
1071
+ function deepClone(objectValue) {
1072
+ return JSON.parse(JSON.stringify(objectValue));
1073
+ /*
1074
+ TODO: [🧠] Is there a better implementation?
1075
+ > const propertyNames = Object.getOwnPropertyNames(objectValue);
1076
+ > for (const propertyName of propertyNames) {
1077
+ > const value = (objectValue as really_any)[propertyName];
1078
+ > if (value && typeof value === 'object') {
1079
+ > deepClone(value);
1080
+ > }
1081
+ > }
1082
+ > return Object.assign({}, objectValue);
1083
+ */
1084
+ }
1085
+ /**
1086
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
1087
+ */
1088
+
1089
+ /**
1090
+ * Function `addUsage` will add multiple usages into one
1091
+ *
1092
+ * Note: If you provide 0 values, it returns ZERO_USAGE
1093
+ *
1094
+ * @public exported from `@promptbook/core`
1095
+ */
1096
+ function addUsage() {
1097
+ var usageItems = [];
1098
+ for (var _i = 0; _i < arguments.length; _i++) {
1099
+ usageItems[_i] = arguments[_i];
1100
+ }
1101
+ return usageItems.reduce(function (acc, item) {
1102
+ var e_1, _a, e_2, _b;
1103
+ var _c;
1104
+ acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
1105
+ try {
1106
+ for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
1107
+ var key = _e.value;
1108
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1109
+ //@ts-ignore
1110
+ if (item.input[key]) {
1111
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1112
+ //@ts-ignore
1113
+ acc.input[key].value += item.input[key].value || 0;
1114
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1115
+ //@ts-ignore
1116
+ if (item.input[key].isUncertain) {
1117
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1118
+ //@ts-ignore
1119
+ acc.input[key].isUncertain = true;
1120
+ }
1121
+ }
1122
+ }
1123
+ }
1124
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1125
+ finally {
1126
+ try {
1127
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
1128
+ }
1129
+ finally { if (e_1) throw e_1.error; }
1130
+ }
1131
+ try {
1132
+ for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
1133
+ var key = _g.value;
1134
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1135
+ //@ts-ignore
1136
+ if (item.output[key]) {
1137
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1138
+ //@ts-ignore
1139
+ acc.output[key].value += item.output[key].value || 0;
1140
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1141
+ //@ts-ignore
1142
+ if (item.output[key].isUncertain) {
1143
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1144
+ //@ts-ignore
1145
+ acc.output[key].isUncertain = true;
1146
+ }
1147
+ }
1148
+ }
1149
+ }
1150
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1151
+ finally {
1152
+ try {
1153
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
1154
+ }
1155
+ finally { if (e_2) throw e_2.error; }
1156
+ }
1157
+ return acc;
1158
+ }, deepClone(ZERO_USAGE));
1159
+ }
1160
+
1161
+ /**
1162
+ * Intercepts LLM tools and counts total usage of the tools
1163
+ *
1164
+ * @param llmTools LLM tools to be intercepted with usage counting
1165
+ * @returns LLM tools with same functionality with added total cost counting
1166
+ * @public exported from `@promptbook/core`
1167
+ */
1168
+ function countTotalUsage(llmTools) {
1169
+ var _this = this;
1170
+ var totalUsage = ZERO_USAGE;
1171
+ var proxyTools = {
1172
+ get title() {
1173
+ // TODO: [🧠] Maybe put here some suffix
1174
+ return llmTools.title;
1175
+ },
1176
+ get description() {
1177
+ // TODO: [🧠] Maybe put here some suffix
1178
+ return llmTools.description;
1179
+ },
1180
+ checkConfiguration: function () {
1181
+ return __awaiter(this, void 0, void 0, function () {
1182
+ return __generator(this, function (_a) {
1183
+ return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
1184
+ });
1185
+ });
1186
+ },
1187
+ listModels: function () {
1188
+ return /* not await */ llmTools.listModels();
1189
+ },
1190
+ getTotalUsage: function () {
1191
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
1192
+ return totalUsage;
1193
+ },
1194
+ };
1195
+ if (llmTools.callChatModel !== undefined) {
1196
+ proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1197
+ var promptResult;
1198
+ return __generator(this, function (_a) {
1199
+ switch (_a.label) {
1200
+ case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
1201
+ case 1:
1202
+ promptResult = _a.sent();
1203
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1204
+ return [2 /*return*/, promptResult];
1205
+ }
1206
+ });
1207
+ }); };
1208
+ }
1209
+ if (llmTools.callCompletionModel !== undefined) {
1210
+ proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1211
+ var promptResult;
1212
+ return __generator(this, function (_a) {
1213
+ switch (_a.label) {
1214
+ case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
1215
+ case 1:
1216
+ promptResult = _a.sent();
1217
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1218
+ return [2 /*return*/, promptResult];
1219
+ }
1220
+ });
1221
+ }); };
1222
+ }
1223
+ if (llmTools.callEmbeddingModel !== undefined) {
1224
+ proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1225
+ var promptResult;
1226
+ return __generator(this, function (_a) {
1227
+ switch (_a.label) {
1228
+ case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
1229
+ case 1:
1230
+ promptResult = _a.sent();
1231
+ totalUsage = addUsage(totalUsage, promptResult.usage);
1232
+ return [2 /*return*/, promptResult];
1233
+ }
1234
+ });
1235
+ }); };
1236
+ }
1237
+ // <- Note: [🤖]
1238
+ return proxyTools;
1239
+ }
1240
+ /**
1241
+ * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
1242
+ * TODO: [🧠] Is there some meaningfull way how to test this util
1243
+ * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
1244
+ * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
1245
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1246
+ */
1247
+
1044
1248
  /**
1045
1249
  * This error indicates errors during the execution of the pipeline
1046
1250
  *
@@ -1349,189 +1553,7 @@ function joinLlmExecutionTools() {
1349
1553
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1350
1554
  */
1351
1555
 
1352
- /**
1353
- * @@@
1354
- *
1355
- * @public exported from `@promptbook/utils`
1356
- */
1357
- function deepClone(objectValue) {
1358
- return JSON.parse(JSON.stringify(objectValue));
1359
- /*
1360
- TODO: [🧠] Is there a better implementation?
1361
- > const propertyNames = Object.getOwnPropertyNames(objectValue);
1362
- > for (const propertyName of propertyNames) {
1363
- > const value = (objectValue as really_any)[propertyName];
1364
- > if (value && typeof value === 'object') {
1365
- > deepClone(value);
1366
- > }
1367
- > }
1368
- > return Object.assign({}, objectValue);
1369
- */
1370
- }
1371
- /**
1372
- * TODO: [🧠] Is there a way how to meaningfully test this utility
1373
- */
1374
-
1375
- /**
1376
- * Function `addUsage` will add multiple usages into one
1377
- *
1378
- * Note: If you provide 0 values, it returns ZERO_USAGE
1379
- *
1380
- * @public exported from `@promptbook/core`
1381
- */
1382
- function addUsage() {
1383
- var usageItems = [];
1384
- for (var _i = 0; _i < arguments.length; _i++) {
1385
- usageItems[_i] = arguments[_i];
1386
- }
1387
- return usageItems.reduce(function (acc, item) {
1388
- var e_1, _a, e_2, _b;
1389
- var _c;
1390
- acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
1391
- try {
1392
- for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
1393
- var key = _e.value;
1394
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1395
- //@ts-ignore
1396
- if (item.input[key]) {
1397
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1398
- //@ts-ignore
1399
- acc.input[key].value += item.input[key].value || 0;
1400
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1401
- //@ts-ignore
1402
- if (item.input[key].isUncertain) {
1403
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1404
- //@ts-ignore
1405
- acc.input[key].isUncertain = true;
1406
- }
1407
- }
1408
- }
1409
- }
1410
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1411
- finally {
1412
- try {
1413
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
1414
- }
1415
- finally { if (e_1) throw e_1.error; }
1416
- }
1417
- try {
1418
- for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
1419
- var key = _g.value;
1420
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1421
- //@ts-ignore
1422
- if (item.output[key]) {
1423
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1424
- //@ts-ignore
1425
- acc.output[key].value += item.output[key].value || 0;
1426
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1427
- //@ts-ignore
1428
- if (item.output[key].isUncertain) {
1429
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1430
- //@ts-ignore
1431
- acc.output[key].isUncertain = true;
1432
- }
1433
- }
1434
- }
1435
- }
1436
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
1437
- finally {
1438
- try {
1439
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
1440
- }
1441
- finally { if (e_2) throw e_2.error; }
1442
- }
1443
- return acc;
1444
- }, deepClone(ZERO_USAGE));
1445
- }
1446
-
1447
- /**
1448
- * Intercepts LLM tools and counts total usage of the tools
1449
- *
1450
- * @param llmTools LLM tools to be intercepted with usage counting
1451
- * @returns LLM tools with same functionality with added total cost counting
1452
- * @public exported from `@promptbook/core`
1453
- */
1454
- function countTotalUsage(llmTools) {
1455
- var _this = this;
1456
- var totalUsage = ZERO_USAGE;
1457
- var proxyTools = {
1458
- get title() {
1459
- // TODO: [🧠] Maybe put here some suffix
1460
- return llmTools.title;
1461
- },
1462
- get description() {
1463
- // TODO: [🧠] Maybe put here some suffix
1464
- return llmTools.description;
1465
- },
1466
- checkConfiguration: function () {
1467
- return __awaiter(this, void 0, void 0, function () {
1468
- return __generator(this, function (_a) {
1469
- return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
1470
- });
1471
- });
1472
- },
1473
- listModels: function () {
1474
- return /* not await */ llmTools.listModels();
1475
- },
1476
- getTotalUsage: function () {
1477
- // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
1478
- return totalUsage;
1479
- },
1480
- };
1481
- if (llmTools.callChatModel !== undefined) {
1482
- proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1483
- var promptResult;
1484
- return __generator(this, function (_a) {
1485
- switch (_a.label) {
1486
- case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
1487
- case 1:
1488
- promptResult = _a.sent();
1489
- totalUsage = addUsage(totalUsage, promptResult.usage);
1490
- return [2 /*return*/, promptResult];
1491
- }
1492
- });
1493
- }); };
1494
- }
1495
- if (llmTools.callCompletionModel !== undefined) {
1496
- proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1497
- var promptResult;
1498
- return __generator(this, function (_a) {
1499
- switch (_a.label) {
1500
- case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
1501
- case 1:
1502
- promptResult = _a.sent();
1503
- totalUsage = addUsage(totalUsage, promptResult.usage);
1504
- return [2 /*return*/, promptResult];
1505
- }
1506
- });
1507
- }); };
1508
- }
1509
- if (llmTools.callEmbeddingModel !== undefined) {
1510
- proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
1511
- var promptResult;
1512
- return __generator(this, function (_a) {
1513
- switch (_a.label) {
1514
- case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
1515
- case 1:
1516
- promptResult = _a.sent();
1517
- totalUsage = addUsage(totalUsage, promptResult.usage);
1518
- return [2 /*return*/, promptResult];
1519
- }
1520
- });
1521
- }); };
1522
- }
1523
- // <- Note: [🤖]
1524
- return proxyTools;
1525
- }
1526
- /**
1527
- * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
1528
- * TODO: [🧠] Is there some meaningfull way how to test this util
1529
- * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
1530
- * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
1531
- * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1532
- */
1533
-
1534
- 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"}];
1556
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.book.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.book.md"}];
1535
1557
 
1536
1558
  /**
1537
1559
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -1606,7 +1628,7 @@ function isValidPromptbookVersion(version) {
1606
1628
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
1607
1629
  return false;
1608
1630
  }
1609
- // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
1631
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
1610
1632
  return true;
1611
1633
  }
1612
1634
 
@@ -1706,7 +1728,7 @@ function isValidPipelineUrl(url) {
1706
1728
  if (!url.startsWith('https://')) {
1707
1729
  return false;
1708
1730
  }
1709
- if (!url.endsWith('.ptbk.md')) {
1731
+ if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.book.md') || url.endsWith('.ptbk'))) {
1710
1732
  return false;
1711
1733
  }
1712
1734
  if (url.includes('#')) {
@@ -1775,9 +1797,9 @@ function validatePipelineCore(pipeline) {
1775
1797
  // <- Note: [🚲]
1776
1798
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1777
1799
  }
1778
- if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1800
+ if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
1779
1801
  // <- Note: [🚲]
1780
- throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1802
+ throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.bookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1781
1803
  }
1782
1804
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
1783
1805
  if (!Array.isArray(pipeline.parameters)) {
@@ -2566,10 +2588,6 @@ function union() {
2566
2588
  * @private within the repository
2567
2589
  */
2568
2590
  function TODO_USE() {
2569
- var value = [];
2570
- for (var _i = 0; _i < arguments.length; _i++) {
2571
- value[_i] = arguments[_i];
2572
- }
2573
2591
  }
2574
2592
 
2575
2593
  /**
@@ -2628,22 +2646,12 @@ var CsvFormatDefinition = {
2628
2646
  formatName: 'CSV',
2629
2647
  aliases: ['SPREADSHEET', 'TABLE'],
2630
2648
  isValid: function (value, settings, schema) {
2631
- // TODO: Implement CSV validation
2632
- TODO_USE(value /* <- TODO: Use value here */);
2633
- TODO_USE(settings /* <- TODO: Use settings here */);
2634
- TODO_USE(schema /* <- TODO: Use schema here */);
2635
2649
  return true;
2636
2650
  },
2637
2651
  canBeValid: function (partialValue, settings, schema) {
2638
- TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2639
- TODO_USE(settings /* <- TODO: Use settings here */);
2640
- TODO_USE(schema /* <- TODO: Use schema here */);
2641
2652
  return true;
2642
2653
  },
2643
2654
  heal: function (value, settings, schema) {
2644
- TODO_USE(value /* <- TODO: Use partialValue here */);
2645
- TODO_USE(settings /* <- TODO: Use settings here */);
2646
- TODO_USE(schema /* <- TODO: Use schema here */);
2647
2655
  throw new Error('Not implemented');
2648
2656
  },
2649
2657
  subvalueDefinitions: [
@@ -2762,20 +2770,12 @@ var JsonFormatDefinition = {
2762
2770
  formatName: 'JSON',
2763
2771
  mimeType: 'application/json',
2764
2772
  isValid: function (value, settings, schema) {
2765
- TODO_USE(schema /* <- TODO: Use schema here */);
2766
- TODO_USE(settings /* <- TODO: Use settings here */);
2767
2773
  return isValidJsonString(value);
2768
2774
  },
2769
2775
  canBeValid: function (partialValue, settings, schema) {
2770
- TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2771
- TODO_USE(settings /* <- TODO: Use settings here */);
2772
- TODO_USE(schema /* <- TODO: Use schema here */);
2773
2776
  return true;
2774
2777
  },
2775
2778
  heal: function (value, settings, schema) {
2776
- TODO_USE(value /* <- TODO: Use partialValue here */);
2777
- TODO_USE(settings /* <- TODO: Use settings here */);
2778
- TODO_USE(schema /* <- TODO: Use schema here */);
2779
2779
  throw new Error('Not implemented');
2780
2780
  },
2781
2781
  subvalueDefinitions: [],
@@ -2857,21 +2857,12 @@ var XmlFormatDefinition = {
2857
2857
  formatName: 'XML',
2858
2858
  mimeType: 'application/xml',
2859
2859
  isValid: function (value, settings, schema) {
2860
- TODO_USE(value /* <- TODO: Use value here */);
2861
- TODO_USE(settings /* <- TODO: Use settings here */);
2862
- TODO_USE(schema /* <- TODO: Use schema here */);
2863
2860
  return true;
2864
2861
  },
2865
2862
  canBeValid: function (partialValue, settings, schema) {
2866
- TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2867
- TODO_USE(settings /* <- TODO: Use settings here */);
2868
- TODO_USE(schema /* <- TODO: Use schema here */);
2869
2863
  return true;
2870
2864
  },
2871
2865
  heal: function (value, settings, schema) {
2872
- TODO_USE(value /* <- TODO: Use partialValue here */);
2873
- TODO_USE(settings /* <- TODO: Use settings here */);
2874
- TODO_USE(schema /* <- TODO: Use schema here */);
2875
2866
  throw new Error('Not implemented');
2876
2867
  },
2877
2868
  subvalueDefinitions: [],
@@ -3104,27 +3095,6 @@ function arrayableToArray(input) {
3104
3095
  return [input];
3105
3096
  }
3106
3097
 
3107
- /**
3108
- * Just says that the variable is not used but should be kept
3109
- * No side effects.
3110
- *
3111
- * Note: It can be usefull for:
3112
- *
3113
- * 1) Suppressing eager optimization of unused imports
3114
- * 2) Suppressing eslint errors of unused variables in the tests
3115
- * 3) Keeping the type of the variable for type testing
3116
- *
3117
- * @param value any values
3118
- * @returns void
3119
- * @private within the repository
3120
- */
3121
- function keepUnused() {
3122
- var valuesToKeep = [];
3123
- for (var _i = 0; _i < arguments.length; _i++) {
3124
- valuesToKeep[_i] = arguments[_i];
3125
- }
3126
- }
3127
-
3128
3098
  /**
3129
3099
  * Replaces parameters in template with values from parameters object
3130
3100
  *
@@ -3237,10 +3207,12 @@ function countLines(text) {
3237
3207
  * @public exported from `@promptbook/utils`
3238
3208
  */
3239
3209
  function countPages(text) {
3240
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
3241
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3242
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3243
- return pageCount;
3210
+ if (text === '') {
3211
+ return 0;
3212
+ }
3213
+ var pagesByLinesCount = Math.ceil(countLines(text) / 44);
3214
+ var pagesByCharactersCount = Math.ceil(countCharacters(text) / 2772);
3215
+ return Math.max(pagesByLinesCount, pagesByCharactersCount);
3244
3216
  }
3245
3217
 
3246
3218
  /**
@@ -3781,7 +3753,7 @@ function executeAttempts(options) {
3781
3753
  promptTitle: template.title,
3782
3754
  promptMessage: replaceParameters(template.description || '', parameters),
3783
3755
  defaultValue: replaceParameters(preparedContent, parameters),
3784
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3756
+ // TODO: [🧠] !! Figure out how to define placeholder in .book.md file
3785
3757
  placeholder: undefined,
3786
3758
  priority: priority,
3787
3759
  }))];
@@ -3879,7 +3851,6 @@ function executeAttempts(options) {
3879
3851
  $ongoingTemplateResult.$resultString = extractJsonBlock($ongoingTemplateResult.$resultString || '');
3880
3852
  }
3881
3853
  catch (error) {
3882
- keepUnused(error);
3883
3854
  throw new ExpectError(spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3884
3855
  /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3885
3856
  }
@@ -4057,7 +4028,6 @@ function executeFormatSubvalues(options) {
4057
4028
  function getContextForTemplate(template) {
4058
4029
  return __awaiter(this, void 0, void 0, function () {
4059
4030
  return __generator(this, function (_a) {
4060
- TODO_USE(template);
4061
4031
  return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
4062
4032
  });
4063
4033
  });
@@ -4070,11 +4040,9 @@ function getContextForTemplate(template) {
4070
4040
  */
4071
4041
  function getKnowledgeForTemplate(options) {
4072
4042
  return __awaiter(this, void 0, void 0, function () {
4073
- var preparedPipeline, template;
4043
+ var preparedPipeline;
4074
4044
  return __generator(this, function (_a) {
4075
- preparedPipeline = options.preparedPipeline, template = options.template;
4076
- // TODO: [♨] Implement Better - use real index and keyword search from `template` and {examples}
4077
- TODO_USE(template);
4045
+ preparedPipeline = options.preparedPipeline, options.template;
4078
4046
  return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
4079
4047
  var content = _a.content;
4080
4048
  return "- ".concat(content);
@@ -4091,8 +4059,6 @@ function getKnowledgeForTemplate(options) {
4091
4059
  function getExamplesForTemplate(template) {
4092
4060
  return __awaiter(this, void 0, void 0, function () {
4093
4061
  return __generator(this, function (_a) {
4094
- // TODO: [♨] Implement Better - use real index and keyword search
4095
- TODO_USE(template);
4096
4062
  return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
4097
4063
  });
4098
4064
  });
@@ -4111,13 +4077,13 @@ function getReservedParametersForTemplate(options) {
4111
4077
  switch (_b.label) {
4112
4078
  case 0:
4113
4079
  preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
4114
- return [4 /*yield*/, getContextForTemplate(template)];
4080
+ return [4 /*yield*/, getContextForTemplate()];
4115
4081
  case 1:
4116
4082
  context = _b.sent();
4117
4083
  return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
4118
4084
  case 2:
4119
4085
  knowledge = _b.sent();
4120
- return [4 /*yield*/, getExamplesForTemplate(template)];
4086
+ return [4 /*yield*/, getExamplesForTemplate()];
4121
4087
  case 3:
4122
4088
  examples = _b.sent();
4123
4089
  currentDate = new Date().toISOString();
@@ -4352,8 +4318,8 @@ function executePipeline(options) {
4352
4318
  executionReport = {
4353
4319
  pipelineUrl: preparedPipeline.pipelineUrl,
4354
4320
  title: preparedPipeline.title,
4355
- promptbookUsedVersion: PROMPTBOOK_VERSION,
4356
- promptbookRequestedVersion: preparedPipeline.promptbookVersion,
4321
+ promptbookUsedVersion: PROMPTBOOK_ENGINE_VERSION,
4322
+ promptbookRequestedVersion: preparedPipeline.bookVersion,
4357
4323
  description: preparedPipeline.description,
4358
4324
  promptExecutions: [],
4359
4325
  };
@@ -4702,7 +4668,7 @@ function preparePersona(personaDescription, tools, options) {
4702
4668
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
4703
4669
  _b = createPipelineExecutor;
4704
4670
  _c = {};
4705
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.ptbk.md')];
4671
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book.md')];
4706
4672
  case 1:
4707
4673
  preparePersonaExecutor = _b.apply(void 0, [(_c.pipeline = _d.sent(),
4708
4674
  _c.tools = tools,
@@ -5199,16 +5165,13 @@ function isValidFilePath(filename) {
5199
5165
  function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5200
5166
  var _a;
5201
5167
  return __awaiter(this, void 0, void 0, function () {
5202
- var sourceContent, name, _b, _c, rootDirname, _d,
5203
- // <- TODO: process.cwd() if running in Node.js
5204
- isVerbose, url, response_1, mimeType, filename_1, fileExtension, mimeType;
5168
+ var sourceContent, name, _b, _c, rootDirname, url, response_1, mimeType, filename_1, fileExtension, mimeType;
5205
5169
  return __generator(this, function (_e) {
5206
5170
  switch (_e.label) {
5207
5171
  case 0:
5208
5172
  sourceContent = knowledgeSource.sourceContent;
5209
5173
  name = knowledgeSource.name;
5210
- _b = options || {}, _c = _b.rootDirname, rootDirname = _c === void 0 ? null : _c, _d = _b.isVerbose, isVerbose = _d === void 0 ? DEFAULT_IS_VERBOSE : _d;
5211
- TODO_USE(isVerbose);
5174
+ _b = options || {}, _c = _b.rootDirname, rootDirname = _c === void 0 ? null : _c, _b.isVerbose;
5212
5175
  if (!name) {
5213
5176
  name = sourceContentToName(sourceContent);
5214
5177
  }
@@ -5462,12 +5425,12 @@ TODO: [🧊] This is how it can look in future
5462
5425
  */
5463
5426
  function clonePipeline(pipeline) {
5464
5427
  // Note: Not using spread operator (...) because @@@
5465
- var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, promptbookVersion = pipeline.promptbookVersion, description = pipeline.description, parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
5428
+ var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, bookVersion = pipeline.bookVersion, description = pipeline.description, parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
5466
5429
  return {
5467
5430
  pipelineUrl: pipelineUrl,
5468
5431
  sourceFile: sourceFile,
5469
5432
  title: title,
5470
- promptbookVersion: promptbookVersion,
5433
+ bookVersion: bookVersion,
5471
5434
  description: description,
5472
5435
  parameters: parameters,
5473
5436
  templates: templates,
@@ -5488,15 +5451,13 @@ function clonePipeline(pipeline) {
5488
5451
  */
5489
5452
  function prepareTemplates(pipeline, tools, options) {
5490
5453
  return __awaiter(this, void 0, void 0, function () {
5491
- var _a, maxParallelCount, templates, parameters, knowledgePiecesCount, templatesPrepared;
5454
+ var _a, maxParallelCount, templates, knowledgePiecesCount, templatesPrepared;
5492
5455
  var _this = this;
5493
5456
  return __generator(this, function (_b) {
5494
5457
  switch (_b.label) {
5495
5458
  case 0:
5496
5459
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? DEFAULT_MAX_PARALLEL_COUNT : _a;
5497
- templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
5498
- // TODO: [main] !! Apply examples to each template (if missing and is for the template defined)
5499
- TODO_USE(parameters);
5460
+ templates = pipeline.templates, pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
5500
5461
  templatesPrepared = new Array(templates.length);
5501
5462
  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 () {
5502
5463
  var dependentParameterNames, preparedContent, preparedTemplate;
@@ -5566,7 +5527,7 @@ function preparePipeline(pipeline, tools, options) {
5566
5527
  currentPreparation = {
5567
5528
  id: 1,
5568
5529
  // TODO: [🍥]> date: $currentDate(),
5569
- promptbookVersion: PROMPTBOOK_VERSION,
5530
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
5570
5531
  usage: ZERO_USAGE,
5571
5532
  };
5572
5533
  preparations = [
@@ -5681,7 +5642,7 @@ var knowledgeCommandParser = {
5681
5642
  throw new ParseError("Source not valid");
5682
5643
  }
5683
5644
  if (sourceContent.startsWith('../') || sourceContent.startsWith('/') || /^[A-Z]:[\\/]+/i.test(sourceContent)) {
5684
- throw new ParseError("Source cannot be outside of the .ptbk.md folder");
5645
+ throw new ParseError("Source cannot be outside of the .book.md folder");
5685
5646
  }
5686
5647
  return {
5687
5648
  type: 'KNOWLEDGE',
@@ -5706,7 +5667,6 @@ var knowledgeCommandParser = {
5706
5667
  * Note: This is used in `pipelineJsonToString` utility
5707
5668
  */
5708
5669
  stringify: function (command) {
5709
- keepUnused(command);
5710
5670
  return "---"; // <- TODO: [🛋] Implement
5711
5671
  },
5712
5672
  /**
@@ -5715,7 +5675,6 @@ var knowledgeCommandParser = {
5715
5675
  * Note: This is used in `pipelineJsonToString` utility
5716
5676
  */
5717
5677
  takeFromPipelineJson: function (pipelineJson) {
5718
- keepUnused(pipelineJson);
5719
5678
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5720
5679
  },
5721
5680
  };
@@ -5898,7 +5857,6 @@ var templateCommandParser = {
5898
5857
  * Note: This is used in `pipelineJsonToString` utility
5899
5858
  */
5900
5859
  stringify: function (command) {
5901
- keepUnused(command);
5902
5860
  return "---"; // <- TODO: [🛋] Implement
5903
5861
  },
5904
5862
  /**
@@ -5907,7 +5865,6 @@ var templateCommandParser = {
5907
5865
  * Note: This is used in `pipelineJsonToString` utility
5908
5866
  */
5909
5867
  takeFromTemplateJson: function ($templateJson) {
5910
- keepUnused($templateJson);
5911
5868
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5912
5869
  },
5913
5870
  };
@@ -6139,7 +6096,6 @@ var expectCommandParser = {
6139
6096
  * Note: This is used in `pipelineJsonToString` utility
6140
6097
  */
6141
6098
  stringify: function (command) {
6142
- keepUnused(command);
6143
6099
  return "---"; // <- TODO: [🛋] Implement
6144
6100
  },
6145
6101
  /**
@@ -6148,7 +6104,6 @@ var expectCommandParser = {
6148
6104
  * Note: This is used in `pipelineJsonToString` utility
6149
6105
  */
6150
6106
  takeFromTemplateJson: function ($templateJson) {
6151
- keepUnused($templateJson);
6152
6107
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6153
6108
  },
6154
6109
  };
@@ -6337,7 +6292,7 @@ function validateParameterName(parameterName) {
6337
6292
  /**
6338
6293
  * Parses the foreach command
6339
6294
  *
6340
- * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.ptbk.md` file
6295
+ * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.book.md` file
6341
6296
  *
6342
6297
  * @see `documentationUrl` for more details
6343
6298
  * @private within the commands folder
@@ -6467,7 +6422,6 @@ var foreachCommandParser = {
6467
6422
  inputSubparameterNames: inputSubparameterNames,
6468
6423
  outputSubparameterName: outputSubparameterName,
6469
6424
  };
6470
- keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
6471
6425
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
6472
6426
  },
6473
6427
  /**
@@ -6476,7 +6430,6 @@ var foreachCommandParser = {
6476
6430
  * Note: This is used in `pipelineJsonToString` utility
6477
6431
  */
6478
6432
  stringify: function (command) {
6479
- keepUnused(command);
6480
6433
  return "---"; // <- TODO: [🛋] Implement
6481
6434
  },
6482
6435
  /**
@@ -6485,12 +6438,11 @@ var foreachCommandParser = {
6485
6438
  * Note: This is used in `pipelineJsonToString` utility
6486
6439
  */
6487
6440
  takeFromTemplateJson: function ($templateJson) {
6488
- keepUnused($templateJson);
6489
6441
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6490
6442
  },
6491
6443
  };
6492
6444
  /**
6493
- * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
6445
+ * TODO: [🍭] Make .book.md file with examples of the FOREACH with wrong parsing and logic
6494
6446
  */
6495
6447
 
6496
6448
  /**
@@ -6553,7 +6505,6 @@ var formatCommandParser = {
6553
6505
  * Note: This is used in `pipelineJsonToString` utility
6554
6506
  */
6555
6507
  stringify: function (command) {
6556
- keepUnused(command);
6557
6508
  return "---"; // <- TODO: [🛋] Implement
6558
6509
  },
6559
6510
  /**
@@ -6562,7 +6513,6 @@ var formatCommandParser = {
6562
6513
  * Note: This is used in `pipelineJsonToString` utility
6563
6514
  */
6564
6515
  takeFromTemplateJson: function ($templateJson) {
6565
- keepUnused($templateJson);
6566
6516
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6567
6517
  },
6568
6518
  };
@@ -6625,7 +6575,6 @@ var jokerCommandParser = {
6625
6575
  * Note: This is used in `pipelineJsonToString` utility
6626
6576
  */
6627
6577
  stringify: function (command) {
6628
- keepUnused(command);
6629
6578
  return "---"; // <- TODO: [🛋] Implement
6630
6579
  },
6631
6580
  /**
@@ -6634,7 +6583,6 @@ var jokerCommandParser = {
6634
6583
  * Note: This is used in `pipelineJsonToString` utility
6635
6584
  */
6636
6585
  takeFromTemplateJson: function ($templateJson) {
6637
- keepUnused($templateJson);
6638
6586
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6639
6587
  },
6640
6588
  };
@@ -6770,7 +6718,6 @@ var modelCommandParser = {
6770
6718
  * Note: This is used in `pipelineJsonToString` utility
6771
6719
  */
6772
6720
  stringify: function (command) {
6773
- keepUnused(command);
6774
6721
  return "---"; // <- TODO: [🛋] Implement
6775
6722
  },
6776
6723
  /**
@@ -6779,7 +6726,6 @@ var modelCommandParser = {
6779
6726
  * Note: This is used in `pipelineJsonToString` utility
6780
6727
  */
6781
6728
  takeFromPipelineJson: function (pipelineJson) {
6782
- keepUnused(pipelineJson);
6783
6729
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6784
6730
  },
6785
6731
  /**
@@ -6788,7 +6734,6 @@ var modelCommandParser = {
6788
6734
  * Note: This is used in `pipelineJsonToString` utility
6789
6735
  */
6790
6736
  takeFromTemplateJson: function ($templateJson) {
6791
- keepUnused($templateJson);
6792
6737
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6793
6738
  },
6794
6739
  };
@@ -6862,7 +6807,6 @@ var parameterCommandParser = {
6862
6807
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6863
6808
  */
6864
6809
  $applyToPipelineJson: function (command, $pipelineJson) {
6865
- keepUnused(command, $pipelineJson);
6866
6810
  // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
6867
6811
  },
6868
6812
  /**
@@ -6871,7 +6815,6 @@ var parameterCommandParser = {
6871
6815
  * Note: `$` is used to indicate that this function mutates given `templateJson`
6872
6816
  */
6873
6817
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
6874
- keepUnused(command, $templateJson, $pipelineJson);
6875
6818
  // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
6876
6819
  },
6877
6820
  /**
@@ -6880,7 +6823,6 @@ var parameterCommandParser = {
6880
6823
  * Note: This is used in `pipelineJsonToString` utility
6881
6824
  */
6882
6825
  stringify: function (command) {
6883
- keepUnused(command);
6884
6826
  return "---"; // <- TODO: [🛋] Implement
6885
6827
  },
6886
6828
  /**
@@ -6889,7 +6831,6 @@ var parameterCommandParser = {
6889
6831
  * Note: This is used in `pipelineJsonToString` utility
6890
6832
  */
6891
6833
  takeFromPipelineJson: function (pipelineJson) {
6892
- keepUnused(pipelineJson);
6893
6834
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6894
6835
  },
6895
6836
  /**
@@ -6898,7 +6839,6 @@ var parameterCommandParser = {
6898
6839
  * Note: This is used in `pipelineJsonToString` utility
6899
6840
  */
6900
6841
  takeFromTemplateJson: function ($templateJson) {
6901
- keepUnused($templateJson);
6902
6842
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6903
6843
  },
6904
6844
  };
@@ -6970,7 +6910,6 @@ var personaCommandParser = {
6970
6910
  * Note: This is used in `pipelineJsonToString` utility
6971
6911
  */
6972
6912
  stringify: function (command) {
6973
- keepUnused(command);
6974
6913
  return "---"; // <- TODO: [🛋] Implement
6975
6914
  },
6976
6915
  /**
@@ -6979,7 +6918,6 @@ var personaCommandParser = {
6979
6918
  * Note: This is used in `pipelineJsonToString` utility
6980
6919
  */
6981
6920
  takeFromPipelineJson: function (pipelineJson) {
6982
- keepUnused(pipelineJson);
6983
6921
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6984
6922
  },
6985
6923
  /**
@@ -6988,7 +6926,6 @@ var personaCommandParser = {
6988
6926
  * Note: This is used in `pipelineJsonToString` utility
6989
6927
  */
6990
6928
  takeFromTemplateJson: function ($templateJson) {
6991
- keepUnused($templateJson);
6992
6929
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
6993
6930
  },
6994
6931
  };
@@ -7107,7 +7044,6 @@ var postprocessCommandParser = {
7107
7044
  * Note: This is used in `pipelineJsonToString` utility
7108
7045
  */
7109
7046
  stringify: function (command) {
7110
- keepUnused(command);
7111
7047
  return "---"; // <- TODO: [🛋] Implement
7112
7048
  },
7113
7049
  /**
@@ -7116,85 +7052,82 @@ var postprocessCommandParser = {
7116
7052
  * Note: This is used in `pipelineJsonToString` utility
7117
7053
  */
7118
7054
  takeFromTemplateJson: function ($templateJson) {
7119
- keepUnused($templateJson);
7120
7055
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7121
7056
  },
7122
7057
  };
7123
7058
 
7124
7059
  /**
7125
- * Parses the PROMPTBOOK_VERSION command
7060
+ * Parses the BOOK_VERSION command
7126
7061
  *
7127
7062
  * @see `documentationUrl` for more details
7128
7063
  * @private within the commands folder
7129
7064
  */
7130
- var promptbookVersionCommandParser = {
7065
+ var bookVersionCommandParser = {
7131
7066
  /**
7132
7067
  * Name of the command
7133
7068
  */
7134
- name: 'PROMPTBOOK_VERSION',
7135
- aliasNames: ['PTBK_VERSION', 'PTBK_V', 'PTBKV'],
7069
+ name: 'BOOK_VERSION',
7070
+ aliasNames: ['PTBK_VERSION', 'PROMPTBOOK_VERSION', 'BOOK'],
7136
7071
  /**
7137
7072
  * BOILERPLATE command can be used in:
7138
7073
  */
7139
7074
  isUsedInPipelineHead: true,
7140
7075
  isUsedInPipelineTemplate: false,
7141
7076
  /**
7142
- * Description of the PROMPTBOOK_VERSION command
7077
+ * Description of the BOOK_VERSION command
7143
7078
  */
7144
- description: "Which version of the promptbook is the .ptbk.md using",
7079
+ description: "Which version of the Book language is the .book.md using",
7145
7080
  /**
7146
7081
  * Link to documentation
7147
7082
  */
7148
7083
  documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/69',
7149
7084
  /**
7150
- * Example usages of the PROMPTBOOK_VERSION command
7085
+ * Example usages of the BOOK_VERSION command
7151
7086
  */
7152
- examples: ["PROMPTBOOK VERSION ".concat(PROMPTBOOK_VERSION), "PTBKV ".concat(PROMPTBOOK_VERSION)],
7087
+ examples: ["BOOK VERSION ".concat(BOOK_LANGUAGE_VERSION), "BOOK ".concat(BOOK_LANGUAGE_VERSION)],
7153
7088
  /**
7154
- * Parses the PROMPTBOOK_VERSION command
7089
+ * Parses the BOOK_VERSION command
7155
7090
  */
7156
7091
  parse: function (input) {
7157
7092
  var args = input.args;
7158
- var promptbookVersion = args.pop();
7159
- if (promptbookVersion === undefined) {
7093
+ var bookVersion = args.pop();
7094
+ if (bookVersion === undefined) {
7160
7095
  throw new ParseError("Version is required");
7161
7096
  }
7162
- if (!isValidPromptbookVersion(promptbookVersion)) {
7163
- throw new ParseError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
7097
+ if (!isValidPromptbookVersion(bookVersion)) {
7098
+ throw new ParseError("Invalid Promptbook version \"".concat(bookVersion, "\""));
7164
7099
  }
7165
- if (args.length > 0) {
7100
+ if (args.length > 0 && !(((args.length === 1 && args[0]) || '').toUpperCase() === 'VERSION')) {
7166
7101
  throw new ParseError("Can not have more than one Promptbook version");
7167
7102
  }
7168
7103
  return {
7169
- type: 'PROMPTBOOK_VERSION',
7170
- promptbookVersion: promptbookVersion,
7104
+ type: 'BOOK_VERSION',
7105
+ bookVersion: bookVersion,
7171
7106
  };
7172
7107
  },
7173
7108
  /**
7174
- * Apply the PROMPTBOOK_VERSION command to the `pipelineJson`
7109
+ * Apply the BOOK_VERSION command to the `pipelineJson`
7175
7110
  *
7176
7111
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7177
7112
  */
7178
7113
  $applyToPipelineJson: function (command, $pipelineJson) {
7179
7114
  // TODO: Warn if the version is overridden
7180
- $pipelineJson.promptbookVersion = command.promptbookVersion;
7115
+ $pipelineJson.bookVersion = command.bookVersion;
7181
7116
  },
7182
7117
  /**
7183
- * Converts the PROMPTBOOK_VERSION command back to string
7118
+ * Converts the BOOK_VERSION command back to string
7184
7119
  *
7185
7120
  * Note: This is used in `pipelineJsonToString` utility
7186
7121
  */
7187
7122
  stringify: function (command) {
7188
- keepUnused(command);
7189
7123
  return "---"; // <- TODO: [🛋] Implement
7190
7124
  },
7191
7125
  /**
7192
- * Reads the PROMPTBOOK_VERSION command from the `PipelineJson`
7126
+ * Reads the BOOK_VERSION command from the `PipelineJson`
7193
7127
  *
7194
7128
  * Note: This is used in `pipelineJsonToString` utility
7195
7129
  */
7196
7130
  takeFromPipelineJson: function (pipelineJson) {
7197
- keepUnused(pipelineJson);
7198
7131
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7199
7132
  },
7200
7133
  };
@@ -7232,9 +7165,9 @@ var urlCommandParser = {
7232
7165
  * Example usages of the URL command
7233
7166
  */
7234
7167
  examples: [
7235
- 'PIPELINE URL https://promptbook.studio/library/write-cv.ptbk.md',
7236
- 'URL https://promptbook.studio/library/write-cv.ptbk.md',
7237
- 'https://promptbook.studio/library/write-cv.ptbk.md',
7168
+ 'PIPELINE URL https://promptbook.studio/library/write-cv.book.md',
7169
+ 'URL https://promptbook.studio/library/write-cv.book.md',
7170
+ 'https://promptbook.studio/library/write-cv.book.md',
7238
7171
  ],
7239
7172
  /**
7240
7173
  * Parses the URL command
@@ -7288,7 +7221,6 @@ var urlCommandParser = {
7288
7221
  * Note: This is used in `pipelineJsonToString` utility
7289
7222
  */
7290
7223
  stringify: function (command) {
7291
- keepUnused(command);
7292
7224
  return "---"; // <- TODO: [🛋] Implement
7293
7225
  },
7294
7226
  /**
@@ -7297,7 +7229,6 @@ var urlCommandParser = {
7297
7229
  * Note: This is used in `pipelineJsonToString` utility
7298
7230
  */
7299
7231
  takeFromPipelineJson: function (pipelineJson) {
7300
- keepUnused(pipelineJson);
7301
7232
  throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
7302
7233
  },
7303
7234
  };
@@ -7334,8 +7265,7 @@ var actionCommandParser = {
7334
7265
  * Parses the ACTION command
7335
7266
  */
7336
7267
  parse: function (input) {
7337
- var args = input.args;
7338
- TODO_USE(args);
7268
+ input.args;
7339
7269
  return {
7340
7270
  type: 'ACTION',
7341
7271
  };
@@ -7346,7 +7276,6 @@ var actionCommandParser = {
7346
7276
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7347
7277
  */
7348
7278
  $applyToPipelineJson: function (command, $pipelineJson) {
7349
- keepUnused(command, $pipelineJson);
7350
7279
  console.error(new NotYetImplementedError('[🛠] Actions are not implemented yet'));
7351
7280
  },
7352
7281
  /**
@@ -7355,7 +7284,6 @@ var actionCommandParser = {
7355
7284
  * Note: This is used in `pipelineJsonToString` utility
7356
7285
  */
7357
7286
  stringify: function (command) {
7358
- keepUnused(command);
7359
7287
  throw new NotYetImplementedError('[🛠] Actions are not implemented yet');
7360
7288
  },
7361
7289
  /**
@@ -7364,7 +7292,6 @@ var actionCommandParser = {
7364
7292
  * Note: This is used in `pipelineJsonToString` utility
7365
7293
  */
7366
7294
  takeFromPipelineJson: function (pipelineJson) {
7367
- keepUnused(pipelineJson);
7368
7295
  throw new NotYetImplementedError('[🛠] Actions are not implemented yet');
7369
7296
  },
7370
7297
  };
@@ -7404,9 +7331,7 @@ var instrumentCommandParser = {
7404
7331
  * Parses the INSTRUMENT command
7405
7332
  */
7406
7333
  parse: function (input) {
7407
- var args = input.args;
7408
- // TODO: [🛠] Implement
7409
- TODO_USE(args);
7334
+ input.args;
7410
7335
  return {
7411
7336
  type: 'INSTRUMENT',
7412
7337
  };
@@ -7417,7 +7342,6 @@ var instrumentCommandParser = {
7417
7342
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7418
7343
  */
7419
7344
  $applyToPipelineJson: function (command, $pipelineJson) {
7420
- keepUnused(command, $pipelineJson);
7421
7345
  console.error(new NotYetImplementedError('[🛠] Instruments are not implemented yet'));
7422
7346
  },
7423
7347
  /**
@@ -7426,7 +7350,6 @@ var instrumentCommandParser = {
7426
7350
  * Note: This is used in `pipelineJsonToString` utility
7427
7351
  */
7428
7352
  stringify: function (command) {
7429
- keepUnused(command);
7430
7353
  throw new NotYetImplementedError('[🛠] Instruments are not implemented yet');
7431
7354
  },
7432
7355
  /**
@@ -7435,7 +7358,6 @@ var instrumentCommandParser = {
7435
7358
  * Note: This is used in `pipelineJsonToString` utility
7436
7359
  */
7437
7360
  takeFromPipelineJson: function (pipelineJson) {
7438
- keepUnused(pipelineJson);
7439
7361
  throw new NotYetImplementedError('[🛠] Instruments are not implemented yet');
7440
7362
  },
7441
7363
  };
@@ -7446,7 +7368,7 @@ var instrumentCommandParser = {
7446
7368
  /**
7447
7369
  * Parses the boilerplate command
7448
7370
  *
7449
- * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.ptbk.md` file
7371
+ * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.book.md` file
7450
7372
  *
7451
7373
  * @see `documentationUrl` for more details
7452
7374
  * @private within the commands folder
@@ -7500,8 +7422,7 @@ var boilerplateCommandParser = {
7500
7422
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7501
7423
  */
7502
7424
  $applyToPipelineJson: function (command, $pipelineJson) {
7503
- keepUnused(command, $pipelineJson);
7504
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7425
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7505
7426
  },
7506
7427
  /**
7507
7428
  * Apply the BOILERPLATE command to the `pipelineJson`
@@ -7509,8 +7430,7 @@ var boilerplateCommandParser = {
7509
7430
  * Note: `$` is used to indicate that this function mutates given `templateJson`
7510
7431
  */
7511
7432
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
7512
- keepUnused(command, $templateJson, $pipelineJson);
7513
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7433
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7514
7434
  },
7515
7435
  /**
7516
7436
  * Converts the BOILERPLATE command back to string
@@ -7518,7 +7438,6 @@ var boilerplateCommandParser = {
7518
7438
  * Note: This is used in `pipelineJsonToString` utility
7519
7439
  */
7520
7440
  stringify: function (command) {
7521
- keepUnused(command);
7522
7441
  return "---"; // <- TODO: [🛋] Implement
7523
7442
  },
7524
7443
  /**
@@ -7527,8 +7446,7 @@ var boilerplateCommandParser = {
7527
7446
  * Note: This is used in `pipelineJsonToString` utility
7528
7447
  */
7529
7448
  takeFromPipelineJson: function (pipelineJson) {
7530
- keepUnused(pipelineJson);
7531
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7449
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7532
7450
  },
7533
7451
  /**
7534
7452
  * Reads the BOILERPLATE command from the `TemplateJson`
@@ -7536,8 +7454,7 @@ var boilerplateCommandParser = {
7536
7454
  * Note: This is used in `pipelineJsonToString` utility
7537
7455
  */
7538
7456
  takeFromTemplateJson: function ($templateJson) {
7539
- keepUnused($templateJson);
7540
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7457
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7541
7458
  },
7542
7459
  };
7543
7460
 
@@ -7554,7 +7471,7 @@ var COMMANDS = [
7554
7471
  modelCommandParser,
7555
7472
  parameterCommandParser,
7556
7473
  postprocessCommandParser,
7557
- promptbookVersionCommandParser,
7474
+ bookVersionCommandParser,
7558
7475
  urlCommandParser,
7559
7476
  knowledgeCommandParser,
7560
7477
  actionCommandParser,
@@ -7706,9 +7623,7 @@ function parseCommandVariant(input) {
7706
7623
  var _loop_1 = function (commandParser) {
7707
7624
  // <- Note: [🦦] Its strange that this type assertion is needed
7708
7625
  var name_1 = commandParser.name, isUsedInPipelineHead = commandParser.isUsedInPipelineHead, isUsedInPipelineTemplate = commandParser.isUsedInPipelineTemplate, aliasNames = commandParser.aliasNames, deprecatedNames = commandParser.deprecatedNames, parse = commandParser.parse;
7709
- if (just(false)) {
7710
- keepUnused( /* for better indentation */);
7711
- }
7626
+ if (just(false)) ;
7712
7627
  else if (usagePlace === 'PIPELINE_HEAD' && !isUsedInPipelineHead) {
7713
7628
  return "continue";
7714
7629
  }
@@ -7868,7 +7783,7 @@ function splitMarkdownIntoSections(markdown) {
7868
7783
  return;
7869
7784
  }
7870
7785
  if (!section.startsWith('#')) {
7871
- section = "# Untitled\n\n".concat(section);
7786
+ section = "# ".concat(DEFAULT_TITLE, "\n\n").concat(section);
7872
7787
  }
7873
7788
  sections.push(section);
7874
7789
  buffer = [];
@@ -7932,7 +7847,7 @@ function flattenMarkdown(markdown) {
7932
7847
  var e_1, _a;
7933
7848
  var sections = splitMarkdownIntoSections(markdown);
7934
7849
  if (sections.length === 0) {
7935
- return '# Untitled';
7850
+ return "# ".concat(DEFAULT_TITLE);
7936
7851
  }
7937
7852
  var flattenedMarkdown = '';
7938
7853
  var parsedSections = sections.map(parseMarkdownSection);
@@ -7943,7 +7858,7 @@ function flattenMarkdown(markdown) {
7943
7858
  }
7944
7859
  else {
7945
7860
  parsedSections.unshift(firstSection);
7946
- flattenedMarkdown += "# Untitled" + "\n\n"; // <- [🧠] Maybe 3 new lines?
7861
+ flattenedMarkdown += "# ".concat(DEFAULT_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
7947
7862
  }
7948
7863
  try {
7949
7864
  for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
@@ -8015,17 +7930,17 @@ function titleToName(value) {
8015
7930
  * Note: This function does not validate logic of the pipeline only the parsing
8016
7931
  * Note: This function acts as compilation process
8017
7932
  *
8018
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8019
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
7933
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
7934
+ * @returns {Promptbook} compiled in JSON format (.book.json)
8020
7935
  * @throws {ParseError} if the promptbook string is not valid
8021
7936
  * @public exported from `@promptbook/core`
8022
7937
  */
8023
7938
  function pipelineStringToJsonSync(pipelineString) {
8024
- var e_1, _a, e_2, _b;
7939
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
8025
7940
  var $pipelineJson = {
8026
7941
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
8027
7942
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
8028
- promptbookVersion: undefined /* <- Note: By default no explicit version */,
7943
+ bookVersion: undefined /* <- Note: By default no explicit version */,
8029
7944
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
8030
7945
  parameters: [],
8031
7946
  templates: [],
@@ -8048,11 +7963,18 @@ function pipelineStringToJsonSync(pipelineString) {
8048
7963
  }
8049
7964
  // =============================================================
8050
7965
  // Note: 1️⃣ Parsing of the markdown into object
7966
+ if (pipelineString.startsWith('#!')) {
7967
+ var _e = __read(pipelineString.split('\n')), shebangLine_1 = _e[0], restLines = _e.slice(1);
7968
+ if (!(shebangLine_1 || '').includes('ptbk')) {
7969
+ throw new ParseError(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 "); }));
7970
+ }
7971
+ pipelineString = restLines.join('\n');
7972
+ }
8051
7973
  pipelineString = removeContentComments(pipelineString);
8052
7974
  pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
8053
7975
  pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
8054
7976
  pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
8055
- var _c = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _c[0], pipelineSections = _c.slice(1); /* <- Note: [🥞] */
7977
+ var _f = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _f[0], pipelineSections = _f.slice(1); /* <- Note: [🥞] */
8056
7978
  if (pipelineHead === undefined) {
8057
7979
  throw new UnexpectedError(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 "); }));
8058
7980
  }
@@ -8080,6 +8002,8 @@ function pipelineStringToJsonSync(pipelineString) {
8080
8002
  if (parameterDescription) {
8081
8003
  existingParameter.description = parameterDescription;
8082
8004
  }
8005
+ existingParameter.isInput = existingParameter.isInput || isInput;
8006
+ existingParameter.isOutput = existingParameter.isOutput || isOutput;
8083
8007
  }
8084
8008
  else {
8085
8009
  $pipelineJson.parameters.push({
@@ -8142,10 +8066,10 @@ function pipelineStringToJsonSync(pipelineString) {
8142
8066
  finally { if (e_1) throw e_1.error; }
8143
8067
  }
8144
8068
  var _loop_2 = function (section) {
8145
- var e_3, _d;
8069
+ var e_5, _l, e_6, _m;
8146
8070
  // TODO: Parse template description (the content out of the codeblock and lists)
8147
8071
  var listItems_2 = extractAllListItemsFromMarkdown(section.content);
8148
- var _e = extractOneBlockFromMarkdown(section.content), language = _e.language, content = _e.content;
8072
+ var _o = extractOneBlockFromMarkdown(section.content), language = _o.language, content = _o.content;
8149
8073
  // TODO: [🎾][1] DRY description
8150
8074
  var description_1 = section.content;
8151
8075
  // Note: Remove codeblocks - TODO: [🎾]
@@ -8186,7 +8110,7 @@ function pipelineStringToJsonSync(pipelineString) {
8186
8110
  }) === false) {
8187
8111
  templateCommandParser.$applyToTemplateJson({ type: 'TEMPLATE', templateType: 'PROMPT_TEMPLATE' }, $templateJson, $pipelineJson);
8188
8112
  }
8189
- var _loop_3 = function (listItem, command) {
8113
+ var _loop_4 = function (listItem, command) {
8190
8114
  var commandParser = getParserForCommand(command);
8191
8115
  if (commandParser.isUsedInPipelineTemplate !== true /* <- Note: [🦦][4] */) {
8192
8116
  throw new ParseError(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: [🚞]
@@ -8209,17 +8133,17 @@ function pipelineStringToJsonSync(pipelineString) {
8209
8133
  };
8210
8134
  try {
8211
8135
  // TODO [♓️] List commands and before apply order them to achieve order-agnostic commands
8212
- 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()) {
8213
- var _f = commands_1_1.value, listItem = _f.listItem, command = _f.command;
8214
- _loop_3(listItem, command);
8136
+ 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()) {
8137
+ var _p = commands_1_1.value, listItem = _p.listItem, command = _p.command;
8138
+ _loop_4(listItem, command);
8215
8139
  }
8216
8140
  }
8217
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
8141
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
8218
8142
  finally {
8219
8143
  try {
8220
- if (commands_1_1 && !commands_1_1.done && (_d = commands_1.return)) _d.call(commands_1);
8144
+ if (commands_1_1 && !commands_1_1.done && (_l = commands_1.return)) _l.call(commands_1);
8221
8145
  }
8222
- finally { if (e_3) throw e_3.error; }
8146
+ finally { if (e_5) throw e_5.error; }
8223
8147
  }
8224
8148
  // TODO: [🍧] Should be done in TEMPLATE command
8225
8149
  if ($templateJson.templateType === 'SCRIPT_TEMPLATE') {
@@ -8233,6 +8157,26 @@ function pipelineStringToJsonSync(pipelineString) {
8233
8157
  language;
8234
8158
  }
8235
8159
  $templateJson.dependentParameterNames = Array.from(extractParameterNamesFromTemplate($templateJson));
8160
+ try {
8161
+ for (var _q = (e_6 = void 0, __values($templateJson.dependentParameterNames)), _r = _q.next(); !_r.done; _r = _q.next()) {
8162
+ var parameterName = _r.value;
8163
+ // TODO: [🧠] This definition should be made first in the template
8164
+ defineParam({
8165
+ parameterName: parameterName,
8166
+ parameterDescription: null,
8167
+ isInput: false,
8168
+ isOutput: false,
8169
+ // <- 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
8170
+ });
8171
+ }
8172
+ }
8173
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
8174
+ finally {
8175
+ try {
8176
+ if (_r && !_r.done && (_m = _q.return)) _m.call(_q);
8177
+ }
8178
+ finally { if (e_6) throw e_6.error; }
8179
+ }
8236
8180
  /*
8237
8181
  // TODO: [🍧] This should be checked in `MODEL` command + better error message
8238
8182
  if ($templateJson.templateType !== 'PROMPT_TEMPLATE' && $templateJson.modelRequirements !== undefined) {
@@ -8271,12 +8215,54 @@ function pipelineStringToJsonSync(pipelineString) {
8271
8215
  try {
8272
8216
  if (pipelineSections_1_1 && !pipelineSections_1_1.done && (_b = pipelineSections_1.return)) _b.call(pipelineSections_1);
8273
8217
  }
8274
- finally { if (e_2) throw e_2.error; }
8218
+ finally { if (e_2) throw e_2.error; }
8219
+ }
8220
+ // =============================================================
8221
+ // Note: 5️⃣ Mark parameters as INPUT if not explicitly set
8222
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isInput; })) {
8223
+ var _loop_3 = function (parameter) {
8224
+ var isThisParameterResulting = $pipelineJson.templates.some(function (template) { return template.resultingParameterName === parameter.name; });
8225
+ if (!isThisParameterResulting) {
8226
+ parameter.isInput = true;
8227
+ }
8228
+ };
8229
+ try {
8230
+ for (var _g = __values($pipelineJson.parameters), _h = _g.next(); !_h.done; _h = _g.next()) {
8231
+ var parameter = _h.value;
8232
+ _loop_3(parameter);
8233
+ }
8234
+ }
8235
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
8236
+ finally {
8237
+ try {
8238
+ if (_h && !_h.done && (_c = _g.return)) _c.call(_g);
8239
+ }
8240
+ finally { if (e_3) throw e_3.error; }
8241
+ }
8242
+ }
8243
+ // =============================================================
8244
+ // Note: 6️⃣ Mark all non-INPUT parameters as OUTPUT if any OUTPUT is not set
8245
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isOutput; })) {
8246
+ try {
8247
+ for (var _j = __values($pipelineJson.parameters), _k = _j.next(); !_k.done; _k = _j.next()) {
8248
+ var parameter = _k.value;
8249
+ if (!parameter.isInput) {
8250
+ parameter.isOutput = true;
8251
+ }
8252
+ }
8253
+ }
8254
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
8255
+ finally {
8256
+ try {
8257
+ if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
8258
+ }
8259
+ finally { if (e_4) throw e_4.error; }
8260
+ }
8275
8261
  }
8276
8262
  // =============================================================
8277
- // Note: 5️⃣ Cleanup of undefined values
8263
+ // Note: 7️⃣ Cleanup of undefined values
8278
8264
  $pipelineJson.templates.forEach(function (templates) {
8279
- var e_4, _a;
8265
+ var e_7, _a;
8280
8266
  try {
8281
8267
  for (var _b = __values(Object.entries(templates)), _c = _b.next(); !_c.done; _c = _b.next()) {
8282
8268
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8285,16 +8271,16 @@ function pipelineStringToJsonSync(pipelineString) {
8285
8271
  }
8286
8272
  }
8287
8273
  }
8288
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
8274
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
8289
8275
  finally {
8290
8276
  try {
8291
8277
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8292
8278
  }
8293
- finally { if (e_4) throw e_4.error; }
8279
+ finally { if (e_7) throw e_7.error; }
8294
8280
  }
8295
8281
  });
8296
8282
  $pipelineJson.parameters.forEach(function (parameter) {
8297
- var e_5, _a;
8283
+ var e_8, _a;
8298
8284
  try {
8299
8285
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
8300
8286
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8303,12 +8289,12 @@ function pipelineStringToJsonSync(pipelineString) {
8303
8289
  }
8304
8290
  }
8305
8291
  }
8306
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
8292
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
8307
8293
  finally {
8308
8294
  try {
8309
8295
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8310
8296
  }
8311
- finally { if (e_5) throw e_5.error; }
8297
+ finally { if (e_8) throw e_8.error; }
8312
8298
  }
8313
8299
  });
8314
8300
  // =============================================================
@@ -8337,10 +8323,10 @@ function pipelineStringToJsonSync(pipelineString) {
8337
8323
  * Note: This function does not validate logic of the pipeline only the parsing
8338
8324
  * Note: This function acts as compilation process
8339
8325
  *
8340
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8326
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
8341
8327
  * @param tools - Tools for the preparation and scraping - if not provided together with `llm`, the preparation will be skipped
8342
8328
  * @param options - Options and tools for the compilation
8343
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
8329
+ * @returns {Promptbook} compiled in JSON format (.book.json)
8344
8330
  * @throws {ParseError} if the promptbook string is not valid
8345
8331
  * @public exported from `@promptbook/core`
8346
8332
  */
@@ -8418,8 +8404,7 @@ function $provideFilesystemForNode(options) {
8418
8404
  if (!$isRunningInNode()) {
8419
8405
  throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
8420
8406
  }
8421
- var _a = (options || {}).isVerbose, isVerbose = _a === void 0 ? DEFAULT_IS_VERBOSE : _a;
8422
- TODO_USE(isVerbose);
8407
+ (options || {}).isVerbose;
8423
8408
  return {
8424
8409
  stat: stat,
8425
8410
  access: access,
@@ -8665,7 +8650,7 @@ function locatePandoc() {
8665
8650
  */
8666
8651
  function $provideExecutablesForNode(options) {
8667
8652
  return __awaiter(this, void 0, void 0, function () {
8668
- var _a, _b, isAutoInstalled, _c, isVerbose;
8653
+ var _a;
8669
8654
  var _d;
8670
8655
  return __generator(this, function (_e) {
8671
8656
  switch (_e.label) {
@@ -8673,9 +8658,7 @@ function $provideExecutablesForNode(options) {
8673
8658
  if (!$isRunningInNode()) {
8674
8659
  throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8675
8660
  }
8676
- _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;
8677
- TODO_USE(isAutoInstalled); // <- TODO: [🔱][🧠] Auto-install the executables
8678
- TODO_USE(isVerbose);
8661
+ _a = options || {}, _a.isAutoInstalled, _a.isVerbose;
8679
8662
  _d = {};
8680
8663
  return [4 /*yield*/, locatePandoc()];
8681
8664
  case 1:
@@ -8932,7 +8915,7 @@ function $provideLlmToolsFromEnv(options) {
8932
8915
  */
8933
8916
  function $provideScrapersForNode(tools, options) {
8934
8917
  return __awaiter(this, void 0, void 0, function () {
8935
- var _a, _b, isAutoInstalled, _c, isVerbose, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8918
+ var _a, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8936
8919
  var e_1, _f;
8937
8920
  return __generator(this, function (_g) {
8938
8921
  switch (_g.label) {
@@ -8940,9 +8923,7 @@ function $provideScrapersForNode(tools, options) {
8940
8923
  if (!$isRunningInNode()) {
8941
8924
  throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8942
8925
  }
8943
- _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;
8944
- TODO_USE(isAutoInstalled);
8945
- TODO_USE(isVerbose);
8926
+ _a = options || {}, _a.isAutoInstalled, _a.isVerbose;
8946
8927
  scrapers = [];
8947
8928
  _g.label = 1;
8948
8929
  case 1:
@@ -9717,13 +9698,13 @@ function createCollectionFromDirectory(path, tools, options) {
9717
9698
  return [4 /*yield*/, listAllFiles(path, isRecursive, tools.fs)];
9718
9699
  case 1:
9719
9700
  fileNames = _b.sent();
9720
- // Note: First load all .ptbk.json and then .ptbk.md files
9721
- // .ptbk.json can be prepared so it is faster to load
9701
+ // Note: First load all .book.json and then .book.md files
9702
+ // .book.json can be prepared so it is faster to load
9722
9703
  fileNames.sort(function (a, b) {
9723
- if (a.endsWith('.ptbk.json') && b.endsWith('.ptbk.md')) {
9704
+ if (a.endsWith('.book.json') && b.endsWith('.book.md')) {
9724
9705
  return -1;
9725
9706
  }
9726
- if (a.endsWith('.ptbk.md') && b.endsWith('.ptbk.json')) {
9707
+ if (a.endsWith('.book.md') && b.endsWith('.book.json')) {
9727
9708
  return 1;
9728
9709
  }
9729
9710
  return 0;
@@ -9740,7 +9721,7 @@ function createCollectionFromDirectory(path, tools, options) {
9740
9721
  case 1:
9741
9722
  _e.trys.push([1, 8, , 9]);
9742
9723
  pipeline = null;
9743
- if (!fileName.endsWith('.ptbk.md')) return [3 /*break*/, 4];
9724
+ if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
9744
9725
  return [4 /*yield*/, readFile(fileName, 'utf-8')];
9745
9726
  case 2:
9746
9727
  pipelineString = (_e.sent());
@@ -9752,7 +9733,7 @@ function createCollectionFromDirectory(path, tools, options) {
9752
9733
  pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
9753
9734
  return [3 /*break*/, 7];
9754
9735
  case 4:
9755
- if (!fileName.endsWith('.ptbk.json')) return [3 /*break*/, 6];
9736
+ if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
9756
9737
  _d = (_c = JSON).parse;
9757
9738
  return [4 /*yield*/, readFile(fileName, 'utf-8')];
9758
9739
  case 5:
@@ -9920,7 +9901,7 @@ function stringifyPipelineJson(pipeline) {
9920
9901
  return pipelineJsonStringified;
9921
9902
  }
9922
9903
  /**
9923
- * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.ptbk.md
9904
+ * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.book.md
9924
9905
  * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
9925
9906
  * TODO: [🧠] Maybe more elegant solution than replacing via regex
9926
9907
  * TODO: [🍙] Make some standard order of json properties
@@ -10101,7 +10082,7 @@ var FileCacheStorage = /** @class */ (function () {
10101
10082
  */
10102
10083
 
10103
10084
  /**
10104
- * Stores
10085
+ * Stores data in memory (HEAP)
10105
10086
  *
10106
10087
  * @public exported from `@promptbook/core`
10107
10088
  */
@@ -10231,13 +10212,18 @@ function cacheLlmTools(llmTools, options) {
10231
10212
  promptResult = _c.sent();
10232
10213
  return [3 /*break*/, 11];
10233
10214
  case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
10234
- case 11: return [4 /*yield*/, storage.setItem(key, {
10215
+ case 11:
10216
+ // TODO: [🧠] !!!!!! How to do timing in mixed cache / non-cache situation
10217
+ // promptResult.timing: FromtoItems
10218
+ return [4 /*yield*/, storage.setItem(key, {
10235
10219
  date: $currentDate(),
10236
- promptbookVersion: PROMPTBOOK_VERSION,
10220
+ promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
10237
10221
  prompt: prompt,
10238
10222
  promptResult: promptResult,
10239
10223
  })];
10240
10224
  case 12:
10225
+ // TODO: [🧠] !!!!!! How to do timing in mixed cache / non-cache situation
10226
+ // promptResult.timing: FromtoItems
10241
10227
  _c.sent();
10242
10228
  return [2 /*return*/, promptResult];
10243
10229
  }
@@ -10311,6 +10297,7 @@ function initializeMakeCommand(program) {
10311
10297
  var _this = this;
10312
10298
  var makeCommand = program.command('make');
10313
10299
  makeCommand.description(spaceTrim$1("\n Makes a new pipeline collection in given folder\n "));
10300
+ // TODO: [🧅] DRY command arguments
10314
10301
  makeCommand.argument('[path]',
10315
10302
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10316
10303
  'Path to promptbook collection directory', './promptbook-collection');
@@ -10318,13 +10305,13 @@ function initializeMakeCommand(program) {
10318
10305
  makeCommand.option('-f, --format <format>', spaceTrim$1("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
10319
10306
  makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
10320
10307
  makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
10321
- makeCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache", false);
10322
- makeCommand.option('--verbose', "Is output verbose", false);
10308
+ makeCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
10309
+ makeCommand.option('-v, --verbose', "Is output verbose", false);
10323
10310
  makeCommand.option('-o, --out-file <path>', spaceTrim$1("\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);
10324
10311
  makeCommand.action(function (path, _a) {
10325
- var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reloadCache, isVerbose = _a.verbose, outFile = _a.outFile;
10312
+ var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reload, isVerbose = _a.verbose, outFile = _a.outFile;
10326
10313
  return __awaiter(_this, void 0, void 0, function () {
10327
- 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;
10314
+ 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;
10328
10315
  var _d, e_2, _e, e_1, _f;
10329
10316
  var _this = this;
10330
10317
  return __generator(this, function (_g) {
@@ -10340,22 +10327,22 @@ function initializeMakeCommand(program) {
10340
10327
  .filter(function (_) { return _ !== ''; });
10341
10328
  if (outFile !== DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME && formats.length !== 1) {
10342
10329
  console.error(colors.red("You can only use one format if you specify --out-file"));
10343
- process.exit(1);
10330
+ return [2 /*return*/, process.exit(1)];
10344
10331
  }
10345
- options = {
10332
+ prepareAndScrapeOptions = {
10346
10333
  isVerbose: isVerbose,
10347
10334
  isCacheReloaded: isCacheReloaded,
10348
10335
  };
10349
- fs = $provideFilesystemForNode(options);
10350
- llm = $provideLlmToolsForCli(options);
10351
- return [4 /*yield*/, $provideExecutablesForNode(options)];
10336
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
10337
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
10338
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
10352
10339
  case 1:
10353
10340
  executables = _g.sent();
10354
10341
  _d = {
10355
10342
  llm: llm,
10356
10343
  fs: fs
10357
10344
  };
10358
- return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
10345
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
10359
10346
  case 2:
10360
10347
  tools = (_d.scrapers = _g.sent(),
10361
10348
  _d.script = [
@@ -10492,8 +10479,7 @@ function initializeMakeCommand(program) {
10492
10479
  if (isVerbose) {
10493
10480
  console.info(colors.cyan(usageToHuman(llm.getTotalUsage())));
10494
10481
  }
10495
- process.exit(0);
10496
- return [2 /*return*/];
10482
+ return [2 /*return*/, process.exit(0)];
10497
10483
  }
10498
10484
  });
10499
10485
  });
@@ -10501,7 +10487,6 @@ function initializeMakeCommand(program) {
10501
10487
  }
10502
10488
  /**
10503
10489
  * TODO: [🥃][main] !!! Allow `ptbk make` without configuring any llm tools
10504
- * TODO: Maybe remove this command - "about" command should be enough?
10505
10490
  * TODO: [0] DRY Javascript and typescript - Maybe make ONLY typescript and for javascript just remove types
10506
10491
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
10507
10492
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
@@ -10646,7 +10631,7 @@ function prettifyPipelineString(pipelineString, options) {
10646
10631
  function initializePrettifyCommand(program) {
10647
10632
  var _this = this;
10648
10633
  var prettifyCommand = program.command('prettify');
10649
- prettifyCommand.description(spaceTrim$1("\n Iterates over `.ptbk.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
10634
+ prettifyCommand.description(spaceTrim$1("\n Iterates over `.book.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
10650
10635
  prettifyCommand.argument('<filesGlob>',
10651
10636
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10652
10637
  'Pipelines to prettify as glob pattern');
@@ -10670,7 +10655,7 @@ function initializePrettifyCommand(program) {
10670
10655
  case 3:
10671
10656
  if (!!filenames_1_1.done) return [3 /*break*/, 10];
10672
10657
  filename = filenames_1_1.value;
10673
- if (!filename.endsWith('.ptbk.md') && isVerbose) {
10658
+ if (!filename.endsWith('.book.md') && isVerbose) {
10674
10659
  console.info(colors.gray("Skipping ".concat(filename)));
10675
10660
  return [3 /*break*/, 9];
10676
10661
  }
@@ -10702,8 +10687,7 @@ function initializePrettifyCommand(program) {
10702
10687
  console.info(colors.red("Prettify ".concat(error_1.name, " ").concat(filename)));
10703
10688
  console.error(colors.bgRed(error_1.name /* <- 11:11 */));
10704
10689
  console.error(colors.red(error_1.stack || error_1.message));
10705
- process.exit(1);
10706
- return [3 /*break*/, 9];
10690
+ return [2 /*return*/, process.exit(1)];
10707
10691
  case 9:
10708
10692
  filenames_1_1 = filenames_1.next();
10709
10693
  return [3 /*break*/, 3];
@@ -10720,8 +10704,7 @@ function initializePrettifyCommand(program) {
10720
10704
  return [7 /*endfinally*/];
10721
10705
  case 13:
10722
10706
  console.info(colors.green("All pipelines are prettified"));
10723
- process.exit(0);
10724
- return [2 /*return*/];
10707
+ return [2 /*return*/, process.exit(0)];
10725
10708
  }
10726
10709
  });
10727
10710
  });
@@ -10733,6 +10716,606 @@ function initializePrettifyCommand(program) {
10733
10716
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
10734
10717
  */
10735
10718
 
10719
+ /**
10720
+ * Pretty print an embedding vector for logging
10721
+ *
10722
+ * @public exported from `@promptbook/core`
10723
+ */
10724
+ function embeddingVectorToString(embeddingVector) {
10725
+ var vectorLength = Math.pow(embeddingVector.reduce(function (acc, val) { return acc + Math.pow(val, 2); }, 0), 0.5);
10726
+ return "[EmbeddingVector; ".concat(embeddingVector.length, " dimensions; length: ").concat(vectorLength.toFixed(2), "; ").concat(embeddingVector.slice(0, 3).join(', '), "...]");
10727
+ }
10728
+
10729
+ /**
10730
+ * Format either small or big number
10731
+ *
10732
+ * @private within the repository
10733
+ */
10734
+ function formatNumber(value) {
10735
+ if (value === 0) {
10736
+ return '0';
10737
+ }
10738
+ for (var exponent = 0; exponent < 15; exponent++) {
10739
+ var factor = Math.pow(10, exponent);
10740
+ var valueRounded = Math.round(value * factor) / factor;
10741
+ if (Math.abs(value - valueRounded) / value <
10742
+ 0.001 /* <- TODO: Pass as option, pass to executionReportJsonToString as option */) {
10743
+ return valueRounded.toFixed(exponent);
10744
+ }
10745
+ }
10746
+ return value.toString();
10747
+ }
10748
+
10749
+ /**
10750
+ * Create a markdown table from a 2D array of strings
10751
+ *
10752
+ * @public exported from `@promptbook/markdown-utils`
10753
+ */
10754
+ function createMarkdownTable(table) {
10755
+ var columnWidths = table.reduce(function (widths, row) {
10756
+ row.forEach(function (subformat, columnIndex) {
10757
+ var cellLength = subformat.length;
10758
+ if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
10759
+ widths[columnIndex] = cellLength;
10760
+ }
10761
+ });
10762
+ return widths;
10763
+ }, []);
10764
+ var header = "| ".concat(table[0]
10765
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
10766
+ .join(' | '), " |");
10767
+ var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
10768
+ var rows = table.slice(1).map(function (row) {
10769
+ var paddedRow = row.map(function (subformat, columnIndex) {
10770
+ return subformat.padEnd(columnWidths[columnIndex]);
10771
+ });
10772
+ return "| ".concat(paddedRow.join(' | '), " |");
10773
+ });
10774
+ return __spreadArray([header, separator], __read(rows), false).join('\n');
10775
+ }
10776
+ /**
10777
+ * TODO: [🏛] This can be part of markdown builder
10778
+ */
10779
+
10780
+ /**
10781
+ * Function createMarkdownChart will draw a chart in markdown from ⬛+🟦 tiles
10782
+ *
10783
+ * @public exported from `@promptbook/markdown-utils`
10784
+ */
10785
+ function createMarkdownChart(options) {
10786
+ var e_1, _a;
10787
+ var nameHeader = options.nameHeader, valueHeader = options.valueHeader, items = options.items, width = options.width, unitName = options.unitName;
10788
+ var from = Math.min.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.from; })), false));
10789
+ var to = Math.max.apply(Math, __spreadArray([], __read(items.map(function (item) { return item.to; })), false));
10790
+ var scale = width / (to - from);
10791
+ var table = [[nameHeader, valueHeader]];
10792
+ try {
10793
+ for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
10794
+ var item = items_1_1.value;
10795
+ var before = Math.round((item.from - from) * scale);
10796
+ var during = Math.round((item.to - item.from) * scale);
10797
+ var after = width - before - during;
10798
+ table.push([removeEmojis(item.title).trim(), '░'.repeat(before) + '█'.repeat(during) + '░'.repeat(after)]);
10799
+ }
10800
+ }
10801
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
10802
+ finally {
10803
+ try {
10804
+ if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
10805
+ }
10806
+ finally { if (e_1) throw e_1.error; }
10807
+ }
10808
+ 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_");
10809
+ return createMarkdownTable(table) + '\n\n' + legend;
10810
+ }
10811
+ /**
10812
+ * TODO: Maybe use Mermain Gant Diagrams
10813
+ * @see https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/
10814
+ */
10815
+
10816
+ /**
10817
+ * Function escapeMarkdownBlock will escape markdown block if needed
10818
+ * It is useful when you want have block in block
10819
+ *
10820
+ * @public exported from `@promptbook/markdown-utils`
10821
+ */
10822
+ function escapeMarkdownBlock(value) {
10823
+ return value.replace(/```/g, '\\`\\`\\`');
10824
+ }
10825
+ /**
10826
+ * TODO: [🏛] This can be part of markdown builder
10827
+ */
10828
+
10829
+ /**
10830
+ * Default options for generating an execution report string
10831
+ *
10832
+ * @public exported from `@promptbook/core`
10833
+ */
10834
+ var ExecutionReportStringOptionsDefaults = {
10835
+ taxRate: 0,
10836
+ chartsWidth: 36,
10837
+ };
10838
+
10839
+ /**
10840
+ * Count the duration of working time
10841
+ *
10842
+ * @private within the repository
10843
+ */
10844
+ function countWorkingDuration(items) {
10845
+ var e_1, _a;
10846
+ var steps = Array.from(new Set(items.flatMap(function (item) { return [item.from, item.to]; })));
10847
+ steps.sort(function (a, b) { return a - b; });
10848
+ var intervals = steps.map(function (step, index) { return [step, steps[index + 1] || 0]; }).slice(0, -1);
10849
+ var duration = 0;
10850
+ var _loop_1 = function (interval) {
10851
+ var _b = __read(interval, 2), from = _b[0], to = _b[1];
10852
+ if (items.some(function (item) { return item.from < to && item.to > from; })) {
10853
+ duration += to - from;
10854
+ }
10855
+ };
10856
+ try {
10857
+ for (var intervals_1 = __values(intervals), intervals_1_1 = intervals_1.next(); !intervals_1_1.done; intervals_1_1 = intervals_1.next()) {
10858
+ var interval = intervals_1_1.value;
10859
+ _loop_1(interval);
10860
+ }
10861
+ }
10862
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
10863
+ finally {
10864
+ try {
10865
+ if (intervals_1_1 && !intervals_1_1.done && (_a = intervals_1.return)) _a.call(intervals_1);
10866
+ }
10867
+ finally { if (e_1) throw e_1.error; }
10868
+ }
10869
+ return duration;
10870
+ }
10871
+
10872
+ /**
10873
+ * Converts execution report from JSON to string format
10874
+ *
10875
+ * @public exported from `@promptbook/core`
10876
+ */
10877
+ function executionReportJsonToString(executionReportJson, options) {
10878
+ var e_1, _a;
10879
+ var _b, _c, _d, _e, _f, _g;
10880
+ var _h = __assign(__assign({}, ExecutionReportStringOptionsDefaults), (options || {})), taxRate = _h.taxRate, chartsWidth = _h.chartsWidth;
10881
+ var executionReportString = spaceTrim(function (block) { return "\n # ".concat(executionReportJson.title || 'Execution report', "\n\n ").concat(block(executionReportJson.description || ''), "\n "); });
10882
+ var headerList = [];
10883
+ if (executionReportJson.pipelineUrl) {
10884
+ headerList.push("PIPELINE URL ".concat(executionReportJson.pipelineUrl));
10885
+ }
10886
+ headerList.push("PROMPTBOOK VERSION ".concat(executionReportJson.promptbookUsedVersion) +
10887
+ (!executionReportJson.promptbookRequestedVersion
10888
+ ? ''
10889
+ : " *(requested ".concat(executionReportJson.promptbookRequestedVersion, ")*")));
10890
+ if (executionReportJson.promptExecutions.length !== 0) {
10891
+ // TODO: What if startedAt OR/AND completedAt is not defined?
10892
+ var startedAt = moment(Math.min.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
10893
+ .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; })
10894
+ .map(function (promptExecution) { return moment(promptExecution.result.timing.start).valueOf(); })), false)));
10895
+ var completedAt = moment(Math.max.apply(Math, __spreadArray([], __read(executionReportJson.promptExecutions
10896
+ .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; })
10897
+ .map(function (promptExecution) { return moment(promptExecution.result.timing.complete).valueOf(); })), false)));
10898
+ var timingItems = executionReportJson.promptExecutions.map(function (promptExecution) {
10899
+ var _a, _b, _c, _d;
10900
+ return ({
10901
+ title: promptExecution.prompt.title,
10902
+ from: moment((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start).valueOf() / 1000,
10903
+ to: moment((_d = (_c = promptExecution.result) === null || _c === void 0 ? void 0 : _c.timing) === null || _d === void 0 ? void 0 : _d.complete).valueOf() / 1000,
10904
+ });
10905
+ });
10906
+ var costItems = executionReportJson.promptExecutions
10907
+ .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'; })
10908
+ .map(function (promptExecution) {
10909
+ var _a, _b;
10910
+ return ({
10911
+ title: promptExecution.prompt.title,
10912
+ from: 0,
10913
+ 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 */ *
10914
+ (1 + taxRate),
10915
+ });
10916
+ });
10917
+ var duration = moment.duration(completedAt.diff(startedAt));
10918
+ var llmDuration = moment.duration(countWorkingDuration(timingItems) * 1000);
10919
+ 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'; });
10920
+ var cost = executionsWithKnownCost.reduce(function (cost, promptExecution) {
10921
+ return cost + (promptExecution.result.usage.price.value /* <- Look at uncertain number */ || 0);
10922
+ }, 0);
10923
+ headerList.push("STARTED AT ".concat(moment(startedAt).format("YYYY-MM-DD HH:mm:ss")));
10924
+ headerList.push("COMPLETED AT ".concat(moment(completedAt).format("YYYY-MM-DD HH:mm:ss")));
10925
+ headerList.push("TOTAL DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
10926
+ headerList.push("TOTAL LLM DURATION ".concat(llmDuration.humanize(MOMENT_ARG_THRESHOLDS)));
10927
+ headerList.push("TOTAL COST $".concat(formatNumber(cost * (1 + taxRate))) +
10928
+ (executionsWithKnownCost.length === executionReportJson.promptExecutions.length
10929
+ ? ''
10930
+ : " *(Some cost is unknown)*") +
10931
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
10932
+ executionReportString += '\n\n' + headerList.map(function (header) { return "- ".concat(header); }).join('\n');
10933
+ executionReportString +=
10934
+ '\n\n' +
10935
+ '## 🗃 Index' +
10936
+ '\n\n' +
10937
+ executionReportJson.promptExecutions
10938
+ .map(function (promptExecution) {
10939
+ // TODO: Make some better system to convert hedings to links
10940
+ var hash = normalizeToKebabCase(promptExecution.prompt.title);
10941
+ if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
10942
+ hash = '-' + hash;
10943
+ }
10944
+ // TODO: Make working hash link for the template in md + pdf
10945
+ return "- [".concat(promptExecution.prompt.title, "](#").concat(hash, ")");
10946
+ })
10947
+ .join('\n');
10948
+ executionReportString +=
10949
+ '\n\n' +
10950
+ '## ⌚ Time chart' +
10951
+ '\n\n' +
10952
+ createMarkdownChart({
10953
+ nameHeader: 'Template',
10954
+ valueHeader: 'Timeline',
10955
+ items: timingItems,
10956
+ width: chartsWidth,
10957
+ unitName: 'seconds',
10958
+ });
10959
+ executionReportString +=
10960
+ '\n\n' +
10961
+ '## 💸 Cost chart' +
10962
+ '\n\n' +
10963
+ createMarkdownChart({
10964
+ nameHeader: 'Template',
10965
+ valueHeader: 'Cost',
10966
+ items: costItems,
10967
+ width: chartsWidth,
10968
+ unitName: 'USD',
10969
+ });
10970
+ }
10971
+ else {
10972
+ headerList.push("TOTAL COST $0 *(Nothing executed)*");
10973
+ }
10974
+ var _loop_1 = function (promptExecution) {
10975
+ executionReportString += '\n\n\n\n' + "## ".concat(promptExecution.prompt.title);
10976
+ var templateList = [];
10977
+ // TODO: What if startedAt OR/AND completedAt is not defined?
10978
+ var startedAt = moment((_c = (_b = promptExecution.result) === null || _b === void 0 ? void 0 : _b.timing) === null || _c === void 0 ? void 0 : _c.start);
10979
+ var completedAt = moment((_e = (_d = promptExecution.result) === null || _d === void 0 ? void 0 : _d.timing) === null || _e === void 0 ? void 0 : _e.complete);
10980
+ var duration = moment.duration(completedAt.diff(startedAt));
10981
+ // Not need here:
10982
+ // > templateList.push(`STARTED AT ${moment(startedAt).calendar()}`);
10983
+ templateList.push("DURATION ".concat(duration.humanize(MOMENT_ARG_THRESHOLDS)));
10984
+ if (typeof ((_g = (_f = promptExecution.result) === null || _f === void 0 ? void 0 : _f.usage) === null || _g === void 0 ? void 0 : _g.price) === 'number') {
10985
+ templateList.push("COST $".concat(formatNumber(promptExecution.result.usage.price * (1 + taxRate))) +
10986
+ (taxRate !== 0 ? " *(with tax ".concat(taxRate * 100, "%)*") : ''));
10987
+ }
10988
+ else {
10989
+ templateList.push("COST UNKNOWN");
10990
+ }
10991
+ executionReportString += '\n\n' + templateList.map(function (header) { return "- ".concat(header); }).join('\n');
10992
+ /*
10993
+ - MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
10994
+ - MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
10995
+ promptExecution.prompt.modelRequirements.modelName
10996
+
10997
+ */
10998
+ if (just(true)) {
10999
+ executionReportString +=
11000
+ '\n\n\n\n' +
11001
+ spaceTrim(function (block) {
11002
+ var _a;
11003
+ 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 ");
11004
+ });
11005
+ }
11006
+ if (promptExecution.result && promptExecution.result.content) {
11007
+ executionReportString += '\n\n\n\n' + '### Result' + '\n\n';
11008
+ if (promptExecution.result === undefined) {
11009
+ executionReportString += '*No result*';
11010
+ }
11011
+ else if (typeof promptExecution.result.content === 'string') {
11012
+ executionReportString += spaceTrim(function (block) { return "\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.result.content)), "\n ```\n "); });
11013
+ }
11014
+ else {
11015
+ executionReportString += embeddingVectorToString(promptExecution.result.content);
11016
+ }
11017
+ }
11018
+ if (promptExecution.error && promptExecution.error.message) {
11019
+ executionReportString +=
11020
+ '\n\n\n\n' +
11021
+ spaceTrim(function (block) { return "\n\n ### Error\n\n ```\n ".concat(block(escapeMarkdownBlock(promptExecution.error.message)), "\n ```\n\n "); });
11022
+ }
11023
+ };
11024
+ try {
11025
+ for (var _j = __values(executionReportJson.promptExecutions), _k = _j.next(); !_k.done; _k = _j.next()) {
11026
+ var promptExecution = _k.value;
11027
+ _loop_1(promptExecution);
11028
+ }
11029
+ }
11030
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
11031
+ finally {
11032
+ try {
11033
+ if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
11034
+ }
11035
+ finally { if (e_1) throw e_1.error; }
11036
+ }
11037
+ executionReportString = prettifyMarkdown(executionReportString);
11038
+ return executionReportString;
11039
+ }
11040
+ /**
11041
+ * TODO: Add mermaid chart for every report
11042
+ * TODO: [🧠] Allow to filter out some parts of the report by options
11043
+ * TODO: [🧠] Should be in generated file GENERATOR_WARNING
11044
+ */
11045
+
11046
+ /**
11047
+ * Initializes `run` command for Promptbook CLI utilities
11048
+ *
11049
+ * @private internal function of `promptbookCli`
11050
+ */
11051
+ function initializeRunCommand(program) {
11052
+ var _this = this;
11053
+ var runCommand = program.command('run', { isDefault: true });
11054
+ runCommand.description(spaceTrim$1("\n Runs a pipeline\n "));
11055
+ // TODO: [🧅] DRY command arguments
11056
+ runCommand.argument('<path>',
11057
+ // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .book.md file
11058
+ 'Path to book file');
11059
+ runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
11060
+ runCommand.option('-v, --verbose', "Is output verbose", false);
11061
+ runCommand.option('--no-interactive', "Input is not interactive", false);
11062
+ runCommand.option('-s, --save-report <path>', "Save report to file");
11063
+ // TODO: !!!!!! Implement non-interactive mode - allow to pass input parameters as JSON
11064
+ // TODO: !!!!!! JSON output
11065
+ runCommand.action(function (filePathRaw, options) { return __awaiter(_this, void 0, void 0, function () {
11066
+ 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;
11067
+ var e_1, _g, _h, e_2, _j, e_3, _k, e_4, _l;
11068
+ return __generator(this, function (_m) {
11069
+ switch (_m.label) {
11070
+ case 0:
11071
+ isCacheReloaded = options.reload, options.interactive, isVerbose = options.verbose, saveReport = options.saveReport;
11072
+ if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
11073
+ console.error(colors.red("Report file must be .json or .md"));
11074
+ return [2 /*return*/, process.exit(1)];
11075
+ }
11076
+ prepareAndScrapeOptions = {
11077
+ isVerbose: isVerbose,
11078
+ isCacheReloaded: isCacheReloaded,
11079
+ };
11080
+ if (isVerbose) {
11081
+ console.info(colors.gray('--- Preparing tools ---'));
11082
+ }
11083
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11084
+ filePath = null;
11085
+ filePathCandidates = [
11086
+ filePathRaw,
11087
+ "".concat(filePathRaw, ".md"),
11088
+ "".concat(filePathRaw, ".book.md"),
11089
+ "".concat(filePathRaw, ".book.md"),
11090
+ ];
11091
+ _m.label = 1;
11092
+ case 1:
11093
+ _m.trys.push([1, 6, 7, 8]);
11094
+ filePathCandidates_1 = __values(filePathCandidates), filePathCandidates_1_1 = filePathCandidates_1.next();
11095
+ _m.label = 2;
11096
+ case 2:
11097
+ if (!!filePathCandidates_1_1.done) return [3 /*break*/, 5];
11098
+ filePathCandidate = filePathCandidates_1_1.value;
11099
+ return [4 /*yield*/, isFileExisting(filePathCandidate, fs)
11100
+ // <- TODO: Also test that among the candidates the file is book not just any file
11101
+ ];
11102
+ case 3:
11103
+ if (_m.sent()
11104
+ // <- TODO: Also test that among the candidates the file is book not just any file
11105
+ ) {
11106
+ filePath = filePathCandidate;
11107
+ return [3 /*break*/, 5];
11108
+ }
11109
+ _m.label = 4;
11110
+ case 4:
11111
+ filePathCandidates_1_1 = filePathCandidates_1.next();
11112
+ return [3 /*break*/, 2];
11113
+ case 5: return [3 /*break*/, 8];
11114
+ case 6:
11115
+ e_1_1 = _m.sent();
11116
+ e_1 = { error: e_1_1 };
11117
+ return [3 /*break*/, 8];
11118
+ case 7:
11119
+ try {
11120
+ if (filePathCandidates_1_1 && !filePathCandidates_1_1.done && (_g = filePathCandidates_1.return)) _g.call(filePathCandidates_1);
11121
+ }
11122
+ finally { if (e_1) throw e_1.error; }
11123
+ return [7 /*endfinally*/];
11124
+ case 8:
11125
+ if (filePath === null) {
11126
+ console.error(colors.red("File \"".concat(filePathRaw, "\" does not exist")));
11127
+ return [2 /*return*/, process.exit(1)];
11128
+ }
11129
+ try {
11130
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
11131
+ }
11132
+ catch (error) {
11133
+ if (!(error instanceof Error)) {
11134
+ throw error;
11135
+ }
11136
+ if (!error.message.includes('No LLM tools')) {
11137
+ throw error;
11138
+ }
11139
+ console.error(colors.red(spaceTrim$1("\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 ")));
11140
+ return [2 /*return*/, process.exit(1)];
11141
+ }
11142
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
11143
+ case 9:
11144
+ executables = _m.sent();
11145
+ _h = {
11146
+ llm: llm,
11147
+ fs: fs
11148
+ };
11149
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
11150
+ case 10:
11151
+ tools = (_h.scrapers = _m.sent(),
11152
+ _h.script = [
11153
+ /*new JavascriptExecutionTools(options)*/
11154
+ ],
11155
+ _h);
11156
+ if (isVerbose) {
11157
+ console.info(colors.gray('--- Reading file ---'));
11158
+ }
11159
+ return [4 /*yield*/, readFile(filePath, 'utf-8')];
11160
+ case 11:
11161
+ pipelineString = (_m.sent());
11162
+ if (isVerbose) {
11163
+ console.info(colors.gray('--- Preparing pipeline ---'));
11164
+ }
11165
+ _m.label = 12;
11166
+ case 12:
11167
+ _m.trys.push([12, 14, , 15]);
11168
+ return [4 /*yield*/, pipelineStringToJson(pipelineString, tools)];
11169
+ case 13:
11170
+ pipeline = _m.sent();
11171
+ return [3 /*break*/, 15];
11172
+ case 14:
11173
+ error_1 = _m.sent();
11174
+ if (!(error_1 instanceof ParseError)) {
11175
+ throw error_1;
11176
+ }
11177
+ console.error(colors.red(spaceTrim$1(function (block) { return "\n ".concat(block(error_1.message), "\n\n in ").concat(filePath, "\n "); })));
11178
+ return [2 /*return*/, process.exit(1)];
11179
+ case 15:
11180
+ if (isVerbose) {
11181
+ console.info(colors.gray('--- Validating pipeline ---'));
11182
+ }
11183
+ // TODO: !!!!!! Same try-catch for LogicError
11184
+ validatePipeline(pipeline);
11185
+ if (isVerbose) {
11186
+ console.info(colors.gray('--- Creating executor ---'));
11187
+ }
11188
+ pipelineExecutor = createPipelineExecutor({
11189
+ pipeline: pipeline,
11190
+ tools: tools,
11191
+ isNotPreparedWarningSupressed: true,
11192
+ maxExecutionAttempts: 3,
11193
+ // <- TODO: !!!!!! Why "LLM execution failed undefinedx"
11194
+ maxParallelCount: 1, // <- TODO: !!!!!! Pass
11195
+ });
11196
+ if (isVerbose) {
11197
+ console.info(colors.gray('--- Getting input parameters ---'));
11198
+ }
11199
+ questions = pipeline.parameters
11200
+ .filter(function (_a) {
11201
+ var isInput = _a.isInput;
11202
+ return isInput;
11203
+ })
11204
+ .map(function (_a) {
11205
+ var name = _a.name, exampleValues = _a.exampleValues;
11206
+ var message = name;
11207
+ var initial = '';
11208
+ if (exampleValues && exampleValues.length > 0) {
11209
+ var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1 && countCharacters(exampleValue) <= 30; });
11210
+ if (exampleValuesFiltered.length !== 0) {
11211
+ message += " (e.g. ".concat(exampleValuesFiltered.join(', '), ")");
11212
+ }
11213
+ initial = exampleValues[0] || '';
11214
+ }
11215
+ return {
11216
+ type: 'text',
11217
+ name: name,
11218
+ message: message,
11219
+ initial: initial,
11220
+ // TODO: Maybe use> validate: value => value < 18 ? `Forbidden` : true
11221
+ };
11222
+ });
11223
+ return [4 /*yield*/, prompts(questions)];
11224
+ case 16:
11225
+ response = _m.sent();
11226
+ inputParameters = response;
11227
+ if (isVerbose) {
11228
+ console.info(colors.gray('--- Executing ---'));
11229
+ }
11230
+ return [4 /*yield*/, pipelineExecutor(inputParameters, function (taskProgress) {
11231
+ if (isVerbose) {
11232
+ console.info(colors.gray('--- Progress ---'));
11233
+ console.info(taskProgress);
11234
+ }
11235
+ })];
11236
+ case 17:
11237
+ result = _m.sent();
11238
+ isSuccessful = result.isSuccessful, errors = result.errors, warnings = result.warnings, outputParameters = result.outputParameters, executionReport = result.executionReport;
11239
+ if (isVerbose) {
11240
+ console.info(colors.gray('--- Detailed Result ---'));
11241
+ console.info({ isSuccessful: isSuccessful, errors: errors, warnings: warnings, outputParameters: outputParameters, executionReport: executionReport });
11242
+ }
11243
+ if (!(saveReport && saveReport.endsWith('.json'))) return [3 /*break*/, 19];
11244
+ return [4 /*yield*/, writeFile(saveReport, JSON.stringify(executionReport, null, 4) + '\n', 'utf-8')];
11245
+ case 18:
11246
+ _m.sent();
11247
+ return [3 /*break*/, 21];
11248
+ case 19:
11249
+ if (!(saveReport && saveReport.endsWith('.md'))) return [3 /*break*/, 21];
11250
+ executionReportString = executionReportJsonToString(executionReport);
11251
+ return [4 /*yield*/, writeFile(saveReport, executionReportString, 'utf-8')];
11252
+ case 20:
11253
+ _m.sent();
11254
+ _m.label = 21;
11255
+ case 21:
11256
+ if (saveReport && isVerbose) {
11257
+ console.info(colors.green("Report saved to ".concat(saveReport)));
11258
+ }
11259
+ if (isVerbose) {
11260
+ console.info(colors.gray('--- Usage ---'));
11261
+ console.info(colors.cyan(usageToHuman(result.usage)));
11262
+ }
11263
+ console.info(colors.gray('--- Result ---'));
11264
+ try {
11265
+ // TODO: [🧠] Should be errors or warnings shown first
11266
+ for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
11267
+ error = _b.value;
11268
+ console.error(colors.red(colors.bold(error.name) + ': ' + error.message));
11269
+ }
11270
+ }
11271
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
11272
+ finally {
11273
+ try {
11274
+ if (_b && !_b.done && (_j = _a.return)) _j.call(_a);
11275
+ }
11276
+ finally { if (e_2) throw e_2.error; }
11277
+ }
11278
+ try {
11279
+ for (_c = __values(warnings || []), _d = _c.next(); !_d.done; _d = _c.next()) {
11280
+ warning = _d.value;
11281
+ console.error(colors.red(colors.bold(warning.name) + ': ' + warning.message));
11282
+ }
11283
+ }
11284
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
11285
+ finally {
11286
+ try {
11287
+ if (_d && !_d.done && (_k = _c.return)) _k.call(_c);
11288
+ }
11289
+ finally { if (e_3) throw e_3.error; }
11290
+ }
11291
+ try {
11292
+ for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11293
+ key = _f.value;
11294
+ value = outputParameters[key] || colors.grey(colors.italic('(nothing)'));
11295
+ separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11296
+ console.info(colors.green(colors.bold(key) + separator + value));
11297
+ }
11298
+ }
11299
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
11300
+ finally {
11301
+ try {
11302
+ if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11303
+ }
11304
+ finally { if (e_4) throw e_4.error; }
11305
+ }
11306
+ return [2 /*return*/, process.exit(0)];
11307
+ }
11308
+ });
11309
+ }); });
11310
+ }
11311
+ /**
11312
+ * TODO: !!!!!! Catch and wrap all errors from CLI
11313
+ * TODO: [🧠] Pass `maxExecutionAttempts`, `csvSettings`
11314
+ * TODO: [🥃][main] !!! Allow `ptbk run` without configuring any llm tools
11315
+ * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
11316
+ * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
11317
+ */
11318
+
10736
11319
  /**
10737
11320
  * Initializes `test` command for Promptbook CLI utilities
10738
11321
  *
@@ -10741,35 +11324,35 @@ function initializePrettifyCommand(program) {
10741
11324
  function initializeTestCommand(program) {
10742
11325
  var _this = this;
10743
11326
  var testCommand = program.command('test');
10744
- testCommand.description(spaceTrim$1("\n Iterates over `.ptbk.md` and `.ptbk.json` and checks if they are parsable and logically valid\n "));
11327
+ testCommand.description(spaceTrim$1("\n Iterates over `.book.md` and `.book.json` and checks if they are parsable and logically valid\n "));
10745
11328
  testCommand.argument('<filesGlob>',
10746
11329
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10747
11330
  'Pipelines to test as glob pattern');
10748
11331
  testCommand.option('-i, --ignore <glob>', "Ignore as glob pattern");
10749
- testCommand.option('--reload', "Call LLM models even if same prompt with result is in the cache ", false);
11332
+ testCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache ", false);
10750
11333
  testCommand.option('-v, --verbose', "Is output verbose", false);
10751
11334
  testCommand.action(function (filesGlob, _a) {
10752
- var ignore = _a.ignore, isCacheReloaded = _a.reloadCache, isVerbose = _a.verbose;
11335
+ var ignore = _a.ignore, isCacheReloaded = _a.reload, isVerbose = _a.verbose;
10753
11336
  return __awaiter(_this, void 0, void 0, function () {
10754
- var options, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
11337
+ var prepareAndScrapeOptions, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
10755
11338
  var _d, e_1, _e;
10756
11339
  return __generator(this, function (_f) {
10757
11340
  switch (_f.label) {
10758
11341
  case 0:
10759
- options = {
11342
+ prepareAndScrapeOptions = {
10760
11343
  isVerbose: isVerbose,
10761
11344
  isCacheReloaded: isCacheReloaded,
10762
11345
  };
10763
- fs = $provideFilesystemForNode(options);
10764
- llm = $provideLlmToolsForCli(options);
10765
- return [4 /*yield*/, $provideExecutablesForNode(options)];
11346
+ fs = $provideFilesystemForNode(prepareAndScrapeOptions);
11347
+ llm = $provideLlmToolsForCli(prepareAndScrapeOptions);
11348
+ return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
10766
11349
  case 1:
10767
11350
  executables = _f.sent();
10768
11351
  _d = {
10769
11352
  llm: llm,
10770
11353
  fs: fs
10771
11354
  };
10772
- return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
11355
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
10773
11356
  case 2:
10774
11357
  tools = (_d.scrapers = _f.sent(),
10775
11358
  _d.script = [
@@ -10791,7 +11374,7 @@ function initializeTestCommand(program) {
10791
11374
  case 6:
10792
11375
  _f.trys.push([6, 13, , 14]);
10793
11376
  pipeline = void 0;
10794
- if (!filename.endsWith('.ptbk.md')) return [3 /*break*/, 9];
11377
+ if (!filename.endsWith('.book.md')) return [3 /*break*/, 9];
10795
11378
  return [4 /*yield*/, readFile(filename, 'utf-8')];
10796
11379
  case 7:
10797
11380
  pipelineMarkdown = (_f.sent());
@@ -10803,7 +11386,7 @@ function initializeTestCommand(program) {
10803
11386
  }
10804
11387
  _f.label = 9;
10805
11388
  case 9:
10806
- if (!filename.endsWith('.ptbk.json')) return [3 /*break*/, 11];
11389
+ if (!filename.endsWith('.book.json')) return [3 /*break*/, 11];
10807
11390
  _c = (_b = JSON).parse;
10808
11391
  return [4 /*yield*/, readFile(filename, 'utf-8')];
10809
11392
  case 10:
@@ -10826,8 +11409,7 @@ function initializeTestCommand(program) {
10826
11409
  console.info(colors.red("Pipeline is not valid ".concat(filename)));
10827
11410
  console.error(colors.bgRed(error_1.name /* <- 11:11 */));
10828
11411
  console.error(colors.red(error_1.stack || error_1.message));
10829
- process.exit(1);
10830
- return [3 /*break*/, 14];
11412
+ return [2 /*return*/, process.exit(1)];
10831
11413
  case 14:
10832
11414
  filenames_1_1 = filenames_1.next();
10833
11415
  return [3 /*break*/, 5];
@@ -10844,8 +11426,7 @@ function initializeTestCommand(program) {
10844
11426
  return [7 /*endfinally*/];
10845
11427
  case 18:
10846
11428
  console.info(colors.green("All pipelines are valid"));
10847
- process.exit(0);
10848
- return [2 /*return*/];
11429
+ return [2 /*return*/, process.exit(0)];
10849
11430
  }
10850
11431
  });
10851
11432
  });
@@ -10865,17 +11446,23 @@ function initializeTestCommand(program) {
10865
11446
  */
10866
11447
  function promptbookCli() {
10867
11448
  return __awaiter(this, void 0, void 0, function () {
10868
- var program;
11449
+ var isVerbose, program;
10869
11450
  return __generator(this, function (_a) {
10870
11451
  if (!$isRunningInNode()) {
10871
11452
  throw new EnvironmentMismatchError(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 "));
10872
11453
  }
11454
+ isVerbose = process.argv.some(function (arg) { return arg === '--verbose' || arg === '-v'; });
11455
+ // <- TODO: Can be this be done with commander before the commander commands are initialized?
11456
+ if (isVerbose) {
11457
+ console.info(colors.gray("Promptbook CLI version ".concat(PROMPTBOOK_ENGINE_VERSION, " in ").concat(__filename.split('\\').join('/'))));
11458
+ }
10873
11459
  program = new commander.Command();
10874
11460
  program.name('promptbook');
10875
11461
  program.alias('ptbk');
10876
- program.version(PROMPTBOOK_VERSION);
10877
- program.description(spaceTrim("\n Promptbook utilities for enhancing workflow with promptbooks\n "));
11462
+ program.version(PROMPTBOOK_ENGINE_VERSION);
11463
+ program.description(CLAIM);
10878
11464
  initializeAboutCommand(program);
11465
+ initializeRunCommand(program);
10879
11466
  initializeHelloCommand(program);
10880
11467
  initializeMakeCommand(program);
10881
11468
  initializePrettifyCommand(program);
@@ -10886,6 +11473,7 @@ function promptbookCli() {
10886
11473
  });
10887
11474
  }
10888
11475
  /**
11476
+ * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.book.md` -> `ptbk ./foo.book.md`
10889
11477
  * TODO: [🥠] Do not export, its just for CLI script
10890
11478
  * TODO: [🕌] When more functionalities, rename
10891
11479
  * Note: 11:11
@@ -12475,8 +13063,6 @@ var _OpenAiAssistantMetadataRegistration = $llmToolsMetadataRegister.register({
12475
13063
  };
12476
13064
  },
12477
13065
  createConfigurationFromEnv: function (env) {
12478
- // TODO: Maybe auto-configure (multiple) assistants from env variables
12479
- keepUnused(env);
12480
13066
  return null;
12481
13067
  /*
12482
13068
  if (typeof env.OPENAI_API_KEY === 'string' || typeof env.OPENAI_XXX === 'string') {
@@ -13203,12 +13789,9 @@ function $execCommandNormalizeOptions(options) {
13203
13789
  })
13204
13790
  .filter(function (arg) { return arg !== ''; });
13205
13791
  if (_.length > 1) {
13206
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13207
13792
  _a = __read(_), command = _a[0], args = _a.slice(1);
13208
13793
  }
13209
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13210
13794
  if (options.args) {
13211
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13212
13795
  args = __spreadArray(__spreadArray([], __read(args), false), __read(options.args), false);
13213
13796
  }
13214
13797
  var humanReadableCommand = !['npx', 'npm'].includes(command) ? command : args[0];
@@ -13329,12 +13912,12 @@ function $execCommand(options) {
13329
13912
  */
13330
13913
  function getScraperIntermediateSource(source, options) {
13331
13914
  return __awaiter(this, void 0, void 0, function () {
13332
- var sourceFilename, url, rootDirname, cacheDirname, intermediateFilesStrategy, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
13915
+ var sourceFilename, url, cacheDirname, intermediateFilesStrategy, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
13333
13916
  return __generator(this, function (_a) {
13334
13917
  switch (_a.label) {
13335
13918
  case 0:
13336
13919
  sourceFilename = source.filename, url = source.url;
13337
- rootDirname = options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, extension = options.extension, isVerbose = options.isVerbose;
13920
+ options.rootDirname, cacheDirname = options.cacheDirname, intermediateFilesStrategy = options.intermediateFilesStrategy, extension = options.extension, isVerbose = options.isVerbose;
13338
13921
  hash = SHA256(
13339
13922
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
13340
13923
  hexEncoder.parse(sourceFilename || url || 'untitled'))
@@ -13343,8 +13926,6 @@ function getScraperIntermediateSource(source, options) {
13343
13926
  semanticName = normalizeToKebabCase(titleToName((sourceFilename || url || '').split('intermediate').join(''))).substring(0, 20);
13344
13927
  pieces = ['intermediate', semanticName, hash].filter(function (piece) { return piece !== ''; });
13345
13928
  name = pieces.join('-').split('--').join('-');
13346
- // <- TODO: Use MAX_FILENAME_LENGTH
13347
- TODO_USE(rootDirname); // <- TODO: [😡]
13348
13929
  cacheFilename = join.apply(void 0, __spreadArray(__spreadArray([process.cwd(),
13349
13930
  cacheDirname], __read(nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */)), false), [name], false)).split('\\')
13350
13931
  .join('/') +
@@ -13443,13 +14024,13 @@ var MarkdownScraper = /** @class */ (function () {
13443
14024
  */
13444
14025
  MarkdownScraper.prototype.scrape = function (source) {
13445
14026
  return __awaiter(this, void 0, void 0, function () {
13446
- var _a, _b, maxParallelCount, _c, isVerbose, llm, _llms, llmTools, collection, prepareKnowledgeFromMarkdownExecutor, _d, prepareTitleExecutor, _e, prepareKeywordsExecutor, _f, knowledgeContent, result, outputParameters, knowledgePiecesRaw, knowledgeTextPieces, knowledge;
14027
+ var _a, _c, isVerbose, llm, _llms, llmTools, collection, prepareKnowledgeFromMarkdownExecutor, _d, prepareTitleExecutor, _e, prepareKeywordsExecutor, _f, knowledgeContent, result, outputParameters, knowledgePiecesRaw, knowledgeTextPieces, knowledge;
13447
14028
  var _g, _h, _j;
13448
14029
  var _this = this;
13449
14030
  return __generator(this, function (_k) {
13450
14031
  switch (_k.label) {
13451
14032
  case 0:
13452
- _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;
14033
+ _a = this.options, _a.maxParallelCount, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c;
13453
14034
  llm = this.tools.llm;
13454
14035
  if (llm === undefined) {
13455
14036
  throw new MissingToolsError('LLM tools are required for scraping external files');
@@ -13457,11 +14038,10 @@ var MarkdownScraper = /** @class */ (function () {
13457
14038
  }
13458
14039
  _llms = arrayableToArray(llm);
13459
14040
  llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(_llms), false));
13460
- TODO_USE(maxParallelCount); // <- [🪂]
13461
14041
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
13462
14042
  _d = createPipelineExecutor;
13463
14043
  _g = {};
13464
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md')];
14044
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md')];
13465
14045
  case 1:
13466
14046
  prepareKnowledgeFromMarkdownExecutor = _d.apply(void 0, [(_g.pipeline = _k.sent(),
13467
14047
  _g.tools = {
@@ -13470,7 +14050,7 @@ var MarkdownScraper = /** @class */ (function () {
13470
14050
  _g)]);
13471
14051
  _e = createPipelineExecutor;
13472
14052
  _h = {};
13473
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md')];
14053
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.book.md')];
13474
14054
  case 2:
13475
14055
  prepareTitleExecutor = _e.apply(void 0, [(_h.pipeline = _k.sent(),
13476
14056
  _h.tools = {
@@ -13479,7 +14059,7 @@ var MarkdownScraper = /** @class */ (function () {
13479
14059
  _h)]);
13480
14060
  _f = createPipelineExecutor;
13481
14061
  _j = {};
13482
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md')];
14062
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md')];
13483
14063
  case 3:
13484
14064
  prepareKeywordsExecutor = _f.apply(void 0, [(_j.pipeline = _k.sent(),
13485
14065
  _j.tools = {
@@ -14048,7 +14628,6 @@ var PdfScraper = /** @class */ (function () {
14048
14628
  PdfScraper.prototype.$convert = function (source) {
14049
14629
  return __awaiter(this, void 0, void 0, function () {
14050
14630
  return __generator(this, function (_a) {
14051
- TODO_USE(source);
14052
14631
  TODO_USE(this.options);
14053
14632
  throw new NotYetImplementedError('PDF conversion not yet implemented');
14054
14633
  });
@@ -14060,7 +14639,6 @@ var PdfScraper = /** @class */ (function () {
14060
14639
  PdfScraper.prototype.scrape = function (source) {
14061
14640
  return __awaiter(this, void 0, void 0, function () {
14062
14641
  return __generator(this, function (_a) {
14063
- TODO_USE(source);
14064
14642
  TODO_USE(this.options);
14065
14643
  /*
14066
14644
  const {
@@ -14303,5 +14881,5 @@ var _WebsiteScraperRegistration = $scrapersRegister.register(createWebsiteScrape
14303
14881
  * TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
14304
14882
  */
14305
14883
 
14306
- export { PROMPTBOOK_VERSION, _AnthropicClaudeMetadataRegistration, _AnthropicClaudeRegistration, _AzureOpenAiMetadataRegistration, _AzureOpenAiRegistration, _CLI, _DocumentScraperMetadataRegistration, _DocumentScraperRegistration, _LegacyDocumentScraperMetadataRegistration, _LegacyDocumentScraperRegistration, _MarkdownScraperMetadataRegistration, _MarkdownScraperRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiAssistantRegistration, _OpenAiMetadataRegistration, _OpenAiRegistration, _PdfScraperMetadataRegistration, _PdfScraperRegistration, _WebsiteScraperMetadataRegistration, _WebsiteScraperRegistration };
14884
+ export { BOOK_LANGUAGE_VERSION, PROMPTBOOK_ENGINE_VERSION, _AnthropicClaudeMetadataRegistration, _AnthropicClaudeRegistration, _AzureOpenAiMetadataRegistration, _AzureOpenAiRegistration, _CLI, _DocumentScraperMetadataRegistration, _DocumentScraperRegistration, _LegacyDocumentScraperMetadataRegistration, _LegacyDocumentScraperRegistration, _MarkdownScraperMetadataRegistration, _MarkdownScraperRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiAssistantRegistration, _OpenAiMetadataRegistration, _OpenAiRegistration, _PdfScraperMetadataRegistration, _PdfScraperRegistration, _WebsiteScraperMetadataRegistration, _WebsiteScraperRegistration };
14307
14885
  //# sourceMappingURL=index.es.js.map