@promptbook/cli 0.77.1 → 0.78.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/esm/index.es.js +509 -466
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/core.index.d.ts +10 -0
  4. package/esm/typings/src/_packages/types.index.d.ts +4 -0
  5. package/esm/typings/src/_packages/utils.index.d.ts +4 -8
  6. package/esm/typings/src/commands/_common/types/CommandType.d.ts +17 -0
  7. package/esm/typings/src/config.d.ts +14 -0
  8. package/esm/typings/src/conversion/utils/extractParameterNamesFromTask.d.ts +1 -1
  9. package/esm/typings/src/conversion/utils/{extractVariables.d.ts → extractVariablesFromScript.d.ts} +2 -2
  10. package/esm/typings/src/conversion/utils/removePipelineCommand.d.ts +22 -0
  11. package/esm/typings/src/conversion/utils/{renameParameter.d.ts → renamePipelineParameter.d.ts} +3 -3
  12. package/esm/typings/src/errors/utils/getErrorReportUrl.d.ts +6 -0
  13. package/esm/typings/src/execution/execution-report/ExecutionReportString.d.ts +1 -1
  14. package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
  15. package/esm/typings/src/pipeline/PipelineString.d.ts +1 -1
  16. package/esm/typings/src/utils/normalization/titleToName.test.d.ts +1 -0
  17. package/package.json +1 -1
  18. package/umd/index.umd.js +337 -294
  19. package/umd/index.umd.js.map +1 -1
  20. /package/esm/typings/src/conversion/utils/{extractVariables.test.d.ts → extractVariablesFromScript.test.d.ts} +0 -0
  21. /package/esm/typings/src/conversion/utils/{renameParameter.test.d.ts → removePipelineCommand.test.d.ts} +0 -0
  22. /package/esm/typings/src/conversion/utils/{titleToName.test.d.ts → renamePipelineParameter.test.d.ts} +0 -0
  23. /package/esm/typings/src/{conversion/utils → utils/normalization}/titleToName.d.ts +0 -0
package/umd/index.umd.js CHANGED
@@ -49,7 +49,7 @@
49
49
  *
50
50
  * @see https://github.com/webgptorg/promptbook
51
51
  */
52
- var PROMPTBOOK_ENGINE_VERSION = '0.77.0';
52
+ var PROMPTBOOK_ENGINE_VERSION = '0.78.1';
53
53
  /**
54
54
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
55
55
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -195,204 +195,31 @@
195
195
  }
196
196
 
197
197
  /**
198
- * @@@
199
- *
200
- * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
201
- * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
202
- *
203
- * @returns The same object as the input, but deeply frozen
204
- * @public exported from `@promptbook/utils`
205
- */
206
- function $deepFreeze(objectValue) {
207
- var e_1, _a;
208
- var propertyNames = Object.getOwnPropertyNames(objectValue);
209
- try {
210
- for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
211
- var propertyName = propertyNames_1_1.value;
212
- var value = objectValue[propertyName];
213
- if (value && typeof value === 'object') {
214
- $deepFreeze(value);
215
- }
216
- }
217
- }
218
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
219
- finally {
220
- try {
221
- if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
222
- }
223
- finally { if (e_1) throw e_1.error; }
224
- }
225
- return Object.freeze(objectValue);
226
- }
227
- /**
228
- * TODO: [🧠] Is there a way how to meaningfully test this utility
229
- */
230
-
231
- /**
232
- * This error type indicates that the error should not happen and its last check before crashing with some other error
198
+ * Warning message for the generated sections and files files
233
199
  *
234
- * @public exported from `@promptbook/core`
200
+ * @private within the repository
235
201
  */
236
- var UnexpectedError = /** @class */ (function (_super) {
237
- __extends(UnexpectedError, _super);
238
- function UnexpectedError(message) {
239
- var _this = _super.call(this, spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note: This error should not happen.\n It's probbably a bug in the pipeline collection\n\n Please report issue:\n https://github.com/webgptorg/promptbook/issues\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
240
- _this.name = 'UnexpectedError';
241
- Object.setPrototypeOf(_this, UnexpectedError.prototype);
242
- return _this;
243
- }
244
- return UnexpectedError;
245
- }(Error));
246
-
202
+ var GENERATOR_WARNING = "\u26A0\uFE0F WARNING: This code has been generated so that any manual changes will be overwritten";
247
203
  /**
248
- * Checks if the value is [🚉] serializable as JSON
249
- * If not, throws an UnexpectedError with a rich error message and tracking
204
+ * Name for the Promptbook
250
205
  *
251
- * - Almost all primitives are serializable BUT:
252
- * - `undefined` is not serializable
253
- * - `NaN` is not serializable
254
- * - Objects and arrays are serializable if all their properties are serializable
255
- * - Functions are not serializable
256
- * - Circular references are not serializable
257
- * - `Date` objects are not serializable
258
- * - `Map` and `Set` objects are not serializable
259
- * - `RegExp` objects are not serializable
260
- * - `Error` objects are not serializable
261
- * - `Symbol` objects are not serializable
262
- * - And much more...
206
+ * TODO: [🗽] Unite branding and make single place for it
263
207
  *
264
- * @throws UnexpectedError if the value is not serializable as JSON
265
- * @public exported from `@promptbook/utils`
266
- */
267
- function checkSerializableAsJson(name, value) {
268
- var e_1, _a;
269
- if (value === undefined) {
270
- throw new UnexpectedError("".concat(name, " is undefined"));
271
- }
272
- else if (value === null) {
273
- return;
274
- }
275
- else if (typeof value === 'boolean') {
276
- return;
277
- }
278
- else if (typeof value === 'number' && !isNaN(value)) {
279
- return;
280
- }
281
- else if (typeof value === 'string') {
282
- return;
283
- }
284
- else if (typeof value === 'symbol') {
285
- throw new UnexpectedError("".concat(name, " is symbol"));
286
- }
287
- else if (typeof value === 'function') {
288
- throw new UnexpectedError("".concat(name, " is function"));
289
- }
290
- else if (typeof value === 'object' && Array.isArray(value)) {
291
- for (var i = 0; i < value.length; i++) {
292
- checkSerializableAsJson("".concat(name, "[").concat(i, "]"), value[i]);
293
- }
294
- }
295
- else if (typeof value === 'object') {
296
- if (value instanceof Date) {
297
- throw new UnexpectedError(spaceTrim__default["default"]("\n ".concat(name, " is Date\n\n Use `string_date_iso8601` instead\n ")));
298
- }
299
- else if (value instanceof Map) {
300
- throw new UnexpectedError("".concat(name, " is Map"));
301
- }
302
- else if (value instanceof Set) {
303
- throw new UnexpectedError("".concat(name, " is Set"));
304
- }
305
- else if (value instanceof RegExp) {
306
- throw new UnexpectedError("".concat(name, " is RegExp"));
307
- }
308
- else if (value instanceof Error) {
309
- throw new UnexpectedError(spaceTrim__default["default"]("\n ".concat(name, " is unserialized Error\n\n Use function `serializeError`\n ")));
310
- }
311
- else {
312
- try {
313
- for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
314
- var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
315
- if (subValue === undefined) {
316
- // Note: undefined in object is serializable - it is just omited
317
- continue;
318
- }
319
- checkSerializableAsJson("".concat(name, ".").concat(subName), subValue);
320
- }
321
- }
322
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
323
- finally {
324
- try {
325
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
326
- }
327
- finally { if (e_1) throw e_1.error; }
328
- }
329
- try {
330
- JSON.stringify(value); // <- TODO: [0]
331
- }
332
- catch (error) {
333
- if (!(error instanceof Error)) {
334
- throw error;
335
- }
336
- throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n ".concat(name, " is not serializable\n\n ").concat(block(error.toString()), "\n "); }));
337
- }
338
- /*
339
- TODO: [0] Is there some more elegant way to check circular references?
340
- const seen = new Set();
341
- const stack = [{ value }];
342
- while (stack.length > 0) {
343
- const { value } = stack.pop()!;
344
- if (typeof value === 'object' && value !== null) {
345
- if (seen.has(value)) {
346
- throw new UnexpectedError(`${name} has circular reference`);
347
- }
348
- seen.add(value);
349
- if (Array.isArray(value)) {
350
- stack.push(...value.map((value) => ({ value })));
351
- } else {
352
- stack.push(...Object.values(value).map((value) => ({ value })));
353
- }
354
- }
355
- }
356
- */
357
- return;
358
- }
359
- }
360
- else {
361
- throw new UnexpectedError("".concat(name, " is unknown"));
362
- }
363
- }
364
- /**
365
- * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
366
- * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
367
- * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
208
+ * @public exported from `@promptbook/core`
368
209
  */
369
-
210
+ var NAME = "Promptbook";
370
211
  /**
371
- * @@@
372
- * @@@
212
+ * Email of the responsible person
373
213
  *
374
- * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
375
- *
376
- * @param name - Name of the object for debugging purposes
377
- * @param objectValue - Object to be deeply frozen
378
- * @returns The same object as the input, but deeply frozen
379
- * @private this is in comparison to `deepFreeze` a more specific utility and maybe not very good practice to use without specific reason and considerations
380
- */
381
- function $asDeeplyFrozenSerializableJson(name, objectValue) {
382
- checkSerializableAsJson(name, objectValue);
383
- return $deepFreeze(objectValue);
384
- }
385
- /**
386
- * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
387
- * TODO: [🧠] Is there a way how to meaningfully test this utility
214
+ * @public exported from `@promptbook/core`
388
215
  */
389
-
216
+ var ADMIN_EMAIL = 'me@pavolhejny.com';
390
217
  /**
391
- * Warning message for the generated sections and files files
218
+ * Name of the responsible person for the Promptbook on GitHub
392
219
  *
393
- * @private within the repository
220
+ * @public exported from `@promptbook/core`
394
221
  */
395
- var GENERATOR_WARNING = "\u26A0\uFE0F WARNING: This code has been generated so that any manual changes will be overwritten";
222
+ var ADMIN_GITHUB_NAME = 'hejny';
396
223
  /**
397
224
  * Claim for the Promptbook
398
225
  *
@@ -504,7 +331,8 @@
504
331
  *
505
332
  * @public exported from `@promptbook/core`
506
333
  */
507
- var RESERVED_PARAMETER_NAMES = $asDeeplyFrozenSerializableJson('RESERVED_PARAMETER_NAMES', [
334
+ var RESERVED_PARAMETER_NAMES =
335
+ /* !!!!!! $asDeeplyFrozenSerializableJson('RESERVED_PARAMETER_NAMES', _____ as const); */ [
508
336
  'content',
509
337
  'context',
510
338
  'knowledge',
@@ -514,7 +342,7 @@
514
342
  // <- TODO: list here all command names
515
343
  // <- TODO: Add more like 'date', 'modelName',...
516
344
  // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
517
- ]);
345
+ ];
518
346
  /**
519
347
  * @@@
520
348
  *
@@ -694,18 +522,175 @@
694
522
  if (!$isRunningInNode()) {
695
523
  throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
696
524
  }
697
- (options || {}).isVerbose;
698
- return {
699
- stat: promises.stat,
700
- access: promises.access,
701
- constants: promises.constants,
702
- readFile: promises.readFile,
703
- writeFile: promises.writeFile,
704
- readdir: promises.readdir,
705
- };
525
+ (options || {}).isVerbose;
526
+ return {
527
+ stat: promises.stat,
528
+ access: promises.access,
529
+ constants: promises.constants,
530
+ readFile: promises.readFile,
531
+ writeFile: promises.writeFile,
532
+ readdir: promises.readdir,
533
+ };
534
+ }
535
+ /**
536
+ * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
537
+ */
538
+
539
+ /**
540
+ * Make error report URL for the given error
541
+ *
542
+ * @private !!!!!!
543
+ */
544
+ function getErrorReportUrl(error) {
545
+ var report = {
546
+ title: "\uD83D\uDC1C Error report from ".concat(NAME),
547
+ body: spaceTrim__default["default"](function (block) { return "\n\n\n `".concat(error.name || 'Error', "` has occurred in the [").concat(NAME, "], please look into it @").concat(ADMIN_GITHUB_NAME, ".\n\n ```\n ").concat(block(error.message || '(no error message)'), "\n ```\n\n\n ## More info:\n\n - **Promptbook engine version:** ").concat(PROMPTBOOK_ENGINE_VERSION, "\n - **Book language version:** ").concat(BOOK_LANGUAGE_VERSION, "\n - **Time:** ").concat(new Date().toISOString(), "\n\n <details>\n <summary>Stack trace:</summary>\n\n ## Stack trace:\n\n ```stacktrace\n ").concat(block(error.stack || '(empty)'), "\n ```\n </details>\n\n "); }),
548
+ };
549
+ var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
550
+ reportUrl.searchParams.set('labels', 'bug');
551
+ reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
552
+ reportUrl.searchParams.set('title', report.title);
553
+ reportUrl.searchParams.set('body', report.body);
554
+ return reportUrl;
555
+ }
556
+
557
+ /**
558
+ * This error type indicates that the error should not happen and its last check before crashing with some other error
559
+ *
560
+ * @public exported from `@promptbook/core`
561
+ */
562
+ var UnexpectedError = /** @class */ (function (_super) {
563
+ __extends(UnexpectedError, _super);
564
+ function UnexpectedError(message) {
565
+ var _this = _super.call(this, spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note: This error should not happen.\n It's probbably a bug in the pipeline collection\n\n Please report issue:\n ").concat(block(getErrorReportUrl(new Error(message)).href), "\n\n Or contact us on ").concat(ADMIN_EMAIL, "\n\n "); })) || this;
566
+ _this.name = 'UnexpectedError';
567
+ Object.setPrototypeOf(_this, UnexpectedError.prototype);
568
+ return _this;
569
+ }
570
+ return UnexpectedError;
571
+ }(Error));
572
+
573
+ /**
574
+ * Checks if the value is [🚉] serializable as JSON
575
+ * If not, throws an UnexpectedError with a rich error message and tracking
576
+ *
577
+ * - Almost all primitives are serializable BUT:
578
+ * - `undefined` is not serializable
579
+ * - `NaN` is not serializable
580
+ * - Objects and arrays are serializable if all their properties are serializable
581
+ * - Functions are not serializable
582
+ * - Circular references are not serializable
583
+ * - `Date` objects are not serializable
584
+ * - `Map` and `Set` objects are not serializable
585
+ * - `RegExp` objects are not serializable
586
+ * - `Error` objects are not serializable
587
+ * - `Symbol` objects are not serializable
588
+ * - And much more...
589
+ *
590
+ * @throws UnexpectedError if the value is not serializable as JSON
591
+ * @public exported from `@promptbook/utils`
592
+ */
593
+ function checkSerializableAsJson(name, value) {
594
+ var e_1, _a;
595
+ if (value === undefined) {
596
+ throw new UnexpectedError("".concat(name, " is undefined"));
597
+ }
598
+ else if (value === null) {
599
+ return;
600
+ }
601
+ else if (typeof value === 'boolean') {
602
+ return;
603
+ }
604
+ else if (typeof value === 'number' && !isNaN(value)) {
605
+ return;
606
+ }
607
+ else if (typeof value === 'string') {
608
+ return;
609
+ }
610
+ else if (typeof value === 'symbol') {
611
+ throw new UnexpectedError("".concat(name, " is symbol"));
612
+ }
613
+ else if (typeof value === 'function') {
614
+ throw new UnexpectedError("".concat(name, " is function"));
615
+ }
616
+ else if (typeof value === 'object' && Array.isArray(value)) {
617
+ for (var i = 0; i < value.length; i++) {
618
+ checkSerializableAsJson("".concat(name, "[").concat(i, "]"), value[i]);
619
+ }
620
+ }
621
+ else if (typeof value === 'object') {
622
+ if (value instanceof Date) {
623
+ throw new UnexpectedError(spaceTrim__default["default"]("\n ".concat(name, " is Date\n\n Use `string_date_iso8601` instead\n ")));
624
+ }
625
+ else if (value instanceof Map) {
626
+ throw new UnexpectedError("".concat(name, " is Map"));
627
+ }
628
+ else if (value instanceof Set) {
629
+ throw new UnexpectedError("".concat(name, " is Set"));
630
+ }
631
+ else if (value instanceof RegExp) {
632
+ throw new UnexpectedError("".concat(name, " is RegExp"));
633
+ }
634
+ else if (value instanceof Error) {
635
+ throw new UnexpectedError(spaceTrim__default["default"]("\n ".concat(name, " is unserialized Error\n\n Use function `serializeError`\n ")));
636
+ }
637
+ else {
638
+ try {
639
+ for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
640
+ var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
641
+ if (subValue === undefined) {
642
+ // Note: undefined in object is serializable - it is just omited
643
+ continue;
644
+ }
645
+ checkSerializableAsJson("".concat(name, ".").concat(subName), subValue);
646
+ }
647
+ }
648
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
649
+ finally {
650
+ try {
651
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
652
+ }
653
+ finally { if (e_1) throw e_1.error; }
654
+ }
655
+ try {
656
+ JSON.stringify(value); // <- TODO: [0]
657
+ }
658
+ catch (error) {
659
+ if (!(error instanceof Error)) {
660
+ throw error;
661
+ }
662
+ throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n ".concat(name, " is not serializable\n\n ").concat(block(error.toString()), "\n "); }));
663
+ }
664
+ /*
665
+ TODO: [0] Is there some more elegant way to check circular references?
666
+ const seen = new Set();
667
+ const stack = [{ value }];
668
+ while (stack.length > 0) {
669
+ const { value } = stack.pop()!;
670
+ if (typeof value === 'object' && value !== null) {
671
+ if (seen.has(value)) {
672
+ throw new UnexpectedError(`${name} has circular reference`);
673
+ }
674
+ seen.add(value);
675
+ if (Array.isArray(value)) {
676
+ stack.push(...value.map((value) => ({ value })));
677
+ } else {
678
+ stack.push(...Object.values(value).map((value) => ({ value })));
679
+ }
680
+ }
681
+ }
682
+ */
683
+ return;
684
+ }
685
+ }
686
+ else {
687
+ throw new UnexpectedError("".concat(name, " is unknown"));
688
+ }
706
689
  }
707
690
  /**
708
- * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
691
+ * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
692
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
693
+ * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
709
694
  */
710
695
 
711
696
  /**
@@ -768,6 +753,84 @@
768
753
  * TODO: [🍙] Make some standard order of json properties
769
754
  */
770
755
 
756
+ /**
757
+ * Checks if the file exists
758
+ *
759
+ * @private within the repository
760
+ */
761
+ function isFileExisting(filename, fs) {
762
+ return __awaiter(this, void 0, void 0, function () {
763
+ var isReadAccessAllowed, isFile;
764
+ return __generator(this, function (_a) {
765
+ switch (_a.label) {
766
+ case 0: return [4 /*yield*/, fs
767
+ .access(filename, fs.constants.R_OK)
768
+ .then(function () { return true; })
769
+ .catch(function () { return false; })];
770
+ case 1:
771
+ isReadAccessAllowed = _a.sent();
772
+ if (!isReadAccessAllowed) {
773
+ return [2 /*return*/, false];
774
+ }
775
+ return [4 /*yield*/, fs
776
+ .stat(filename)
777
+ .then(function (fileStat) { return fileStat.isFile(); })
778
+ .catch(function () { return false; })];
779
+ case 2:
780
+ isFile = _a.sent();
781
+ return [2 /*return*/, isFile];
782
+ }
783
+ });
784
+ });
785
+ }
786
+ /**
787
+ * Note: Not [~🟢~] because it is not directly dependent on `fs
788
+ * TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
789
+ * TODO: [🖇] What about symlinks?
790
+ */
791
+
792
+ /**
793
+ * Removes emojis from a string and fix whitespaces
794
+ *
795
+ * @param text with emojis
796
+ * @returns text without emojis
797
+ * @public exported from `@promptbook/utils`
798
+ */
799
+ function removeEmojis(text) {
800
+ // Replace emojis (and also ZWJ sequence) with hyphens
801
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
802
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
803
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
804
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
805
+ return text;
806
+ }
807
+
808
+ /**
809
+ * Tests if given string is valid URL.
810
+ *
811
+ * Note: This does not check if the file exists only if the path is valid
812
+ * @public exported from `@promptbook/utils`
813
+ */
814
+ function isValidFilePath(filename) {
815
+ if (typeof filename !== 'string') {
816
+ return false;
817
+ }
818
+ var filenameSlashes = filename.split('\\').join('/');
819
+ // Absolute Unix path: /hello.txt
820
+ if (/^(\/)/i.test(filenameSlashes)) {
821
+ return true;
822
+ }
823
+ // Absolute Windows path: /hello.txt
824
+ if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
825
+ return true;
826
+ }
827
+ // Relative path: ./hello.txt
828
+ if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
829
+ return true;
830
+ }
831
+ return false;
832
+ }
833
+
771
834
  /**
772
835
  * Tests if given string is valid URL.
773
836
  *
@@ -1120,48 +1183,6 @@
1120
1183
  * Note: [💞] Ignore a discrepancy between file name and entity name
1121
1184
  */
1122
1185
 
1123
- /**
1124
- * Removes emojis from a string and fix whitespaces
1125
- *
1126
- * @param text with emojis
1127
- * @returns text without emojis
1128
- * @public exported from `@promptbook/utils`
1129
- */
1130
- function removeEmojis(text) {
1131
- // Replace emojis (and also ZWJ sequence) with hyphens
1132
- text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
1133
- text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
1134
- text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
1135
- text = text.replace(/\p{Extended_Pictographic}/gu, '');
1136
- return text;
1137
- }
1138
-
1139
- /**
1140
- * Tests if given string is valid URL.
1141
- *
1142
- * Note: This does not check if the file exists only if the path is valid
1143
- * @public exported from `@promptbook/utils`
1144
- */
1145
- function isValidFilePath(filename) {
1146
- if (typeof filename !== 'string') {
1147
- return false;
1148
- }
1149
- var filenameSlashes = filename.split('\\').join('/');
1150
- // Absolute Unix path: /hello.txt
1151
- if (/^(\/)/i.test(filenameSlashes)) {
1152
- return true;
1153
- }
1154
- // Absolute Windows path: /hello.txt
1155
- if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
1156
- return true;
1157
- }
1158
- // Relative path: ./hello.txt
1159
- if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
1160
- return true;
1161
- }
1162
- return false;
1163
- }
1164
-
1165
1186
  /**
1166
1187
  * @@@
1167
1188
  *
@@ -1186,42 +1207,6 @@
1186
1207
  return value;
1187
1208
  }
1188
1209
 
1189
- /**
1190
- * Checks if the file exists
1191
- *
1192
- * @private within the repository
1193
- */
1194
- function isFileExisting(filename, fs) {
1195
- return __awaiter(this, void 0, void 0, function () {
1196
- var isReadAccessAllowed, isFile;
1197
- return __generator(this, function (_a) {
1198
- switch (_a.label) {
1199
- case 0: return [4 /*yield*/, fs
1200
- .access(filename, fs.constants.R_OK)
1201
- .then(function () { return true; })
1202
- .catch(function () { return false; })];
1203
- case 1:
1204
- isReadAccessAllowed = _a.sent();
1205
- if (!isReadAccessAllowed) {
1206
- return [2 /*return*/, false];
1207
- }
1208
- return [4 /*yield*/, fs
1209
- .stat(filename)
1210
- .then(function (fileStat) { return fileStat.isFile(); })
1211
- .catch(function () { return false; })];
1212
- case 2:
1213
- isFile = _a.sent();
1214
- return [2 /*return*/, isFile];
1215
- }
1216
- });
1217
- });
1218
- }
1219
- /**
1220
- * Note: Not [~🟢~] because it is not directly dependent on `fs
1221
- * TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
1222
- * TODO: [🖇] What about symlinks?
1223
- */
1224
-
1225
1210
  /**
1226
1211
  * @@@
1227
1212
  *
@@ -1550,6 +1535,40 @@
1550
1535
  * TODO: [🧠] Is there a way how to meaningfully test this utility
1551
1536
  */
1552
1537
 
1538
+ /**
1539
+ * @@@
1540
+ *
1541
+ * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
1542
+ * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
1543
+ *
1544
+ * @returns The same object as the input, but deeply frozen
1545
+ * @public exported from `@promptbook/utils`
1546
+ */
1547
+ function $deepFreeze(objectValue) {
1548
+ var e_1, _a;
1549
+ var propertyNames = Object.getOwnPropertyNames(objectValue);
1550
+ try {
1551
+ for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
1552
+ var propertyName = propertyNames_1_1.value;
1553
+ var value = objectValue[propertyName];
1554
+ if (value && typeof value === 'object') {
1555
+ $deepFreeze(value);
1556
+ }
1557
+ }
1558
+ }
1559
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1560
+ finally {
1561
+ try {
1562
+ if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
1563
+ }
1564
+ finally { if (e_1) throw e_1.error; }
1565
+ }
1566
+ return Object.freeze(objectValue);
1567
+ }
1568
+ /**
1569
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
1570
+ */
1571
+
1553
1572
  /**
1554
1573
  * Represents the usage with no resources consumed
1555
1574
  *
@@ -3397,6 +3416,26 @@
3397
3416
  return parameterNames;
3398
3417
  }
3399
3418
 
3419
+ /**
3420
+ * @@@
3421
+ * @@@
3422
+ *
3423
+ * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
3424
+ *
3425
+ * @param name - Name of the object for debugging purposes
3426
+ * @param objectValue - Object to be deeply frozen
3427
+ * @returns The same object as the input, but deeply frozen
3428
+ * @private this is in comparison to `deepFreeze` a more specific utility and maybe not very good practice to use without specific reason and considerations
3429
+ */
3430
+ function $asDeeplyFrozenSerializableJson(name, objectValue) {
3431
+ checkSerializableAsJson(name, objectValue);
3432
+ return $deepFreeze(objectValue);
3433
+ }
3434
+ /**
3435
+ * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
3436
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
3437
+ */
3438
+
3400
3439
  /**
3401
3440
  * Unprepare just strips the preparation data of the pipeline
3402
3441
  *
@@ -3786,10 +3825,11 @@
3786
3825
  * @param script from which to extract the variables
3787
3826
  * @returns the list of variable names
3788
3827
  * @throws {ParseError} if the script is invalid
3789
- * @public exported from `@promptbook/utils`
3828
+ * @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
3790
3829
  */
3791
- function extractVariables(script) {
3830
+ function extractVariablesFromScript(script) {
3792
3831
  var variables = new Set();
3832
+ var originalScript = script;
3793
3833
  script = "(()=>{".concat(script, "})()");
3794
3834
  try {
3795
3835
  for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
@@ -3821,7 +3861,9 @@
3821
3861
  if (!(error instanceof Error)) {
3822
3862
  throw error;
3823
3863
  }
3824
- throw new ParseError(spaceTrim.spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.toString()), "}\n "); }));
3864
+ throw new ParseError(spaceTrim.spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.toString()), "}\n\n\n Found variables:\n\n ").concat(Array.from(variables)
3865
+ .map(function (variableName, i) { return "".concat(i + 1, ") ").concat(variableName); })
3866
+ .join('\n'), "\n\n\n The script:\n\n ```javascript\n ").concat(block(originalScript), "\n ```\n "); }));
3825
3867
  }
3826
3868
  return variables;
3827
3869
  }
@@ -3835,7 +3877,7 @@
3835
3877
  * @param task the task with used parameters
3836
3878
  * @returns the set of parameter names
3837
3879
  * @throws {ParseError} if the script is invalid
3838
- * @public exported from `@promptbook/utils`
3880
+ * @public exported from `@promptbook/core` <- Note: [👖] This utility is so tightly interconnected with the Promptbook that it is not exported as util but in core
3839
3881
  */
3840
3882
  function extractParameterNamesFromTask(task) {
3841
3883
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
@@ -3856,7 +3898,7 @@
3856
3898
  }
3857
3899
  if (taskType === 'SCRIPT_TASK') {
3858
3900
  try {
3859
- for (var _g = __values(extractVariables(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
3901
+ for (var _g = __values(extractVariablesFromScript(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
3860
3902
  var parameterName = _h.value;
3861
3903
  parameterNames.add(parameterName);
3862
3904
  }
@@ -6727,7 +6769,7 @@
6727
6769
  throw new ParseError(spaceTrim__default["default"]("\n Section type is already defined in the section.\n It can be defined only once.\n "));
6728
6770
  }
6729
6771
  $taskJson.isSectionTypeSet = true;
6730
- // TODO: [🍧] Rearrange better - but at bottom and unwrap from function
6772
+ // TODO: [🍧][💩] Rearrange better - but at bottom and unwrap from function
6731
6773
  var expectResultingParameterName = function () {
6732
6774
  if ($taskJson.resultingParameterName) {
6733
6775
  return;
@@ -8013,7 +8055,7 @@
8013
8055
  if ($pipelineJson.defaultModelRequirements[command.key] !== undefined) {
8014
8056
  if ($pipelineJson.defaultModelRequirements[command.key] === command.value) {
8015
8057
  console.warn("Multiple commands `MODEL ".concat(command.key, " ").concat(command.value, "` in the pipeline head"));
8016
- // <- TODO: [🚎] Some better way how to get warnings from pipeline parsing / logic
8058
+ // <- TODO: [🚎][💩] Some better way how to get warnings from pipeline parsing / logic
8017
8059
  }
8018
8060
  else {
8019
8061
  throw new ParseError(spaceTrim__default["default"]("\n Redefinition of MODEL `".concat(command.key, "` in the pipeline head\n\n You have used:\n - MODEL ").concat(command.key, " ").concat($pipelineJson.defaultModelRequirements[command.key], "\n - MODEL ").concat(command.key, " ").concat(command.value, "\n ")));
@@ -8648,7 +8690,7 @@
8648
8690
  personaCommandParser,
8649
8691
  foreachCommandParser,
8650
8692
  boilerplateCommandParser, // <- TODO: !! Only in development, remove in production
8651
- // <- Note: [♓️] This is the order of the commands in the pipeline, BUT its not used in parsing and before usage maybe it should be done better
8693
+ // <- Note: [♓️][💩] This is the order of the commands in the pipeline, BUT its not used in parsing and before usage maybe it should be done better
8652
8694
  ];
8653
8695
  /**
8654
8696
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -8944,6 +8986,7 @@
8944
8986
  var e_1, _a;
8945
8987
  var lines = markdown.split('\n');
8946
8988
  var sections = [];
8989
+ // TODO: [🧽] DRY
8947
8990
  var currentType = 'MARKDOWN';
8948
8991
  var buffer = [];
8949
8992
  var finishSection = function () {
@@ -10103,10 +10146,10 @@
10103
10146
  return __generator(this, function (_a) {
10104
10147
  switch (_a.label) {
10105
10148
  case 0:
10106
- // TODO: Change to `await forEver` or something better
10149
+ // TODO: [💩] Change to `await forEver` or something better
10107
10150
  return [4 /*yield*/, waitasecond.forTime(100000000)];
10108
10151
  case 1:
10109
- // TODO: Change to `await forEver` or something better
10152
+ // TODO: [💩] Change to `await forEver` or something better
10110
10153
  _a.sent();
10111
10154
  _a.label = 2;
10112
10155
  case 2:
@@ -11060,11 +11103,11 @@
11060
11103
  var placeForSection = removeContentComments(content).match(/^##.*$/im);
11061
11104
  if (placeForSection !== null) {
11062
11105
  var _a = __read(placeForSection, 1), heading_1 = _a[0];
11063
- return content.replace(heading_1, spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(contentToInsert), "\n \n ").concat(block(heading_1), "\n "); }));
11106
+ return content.replace(heading_1, spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(contentToInsert), "\n\n ").concat(block(heading_1), "\n "); }));
11064
11107
  }
11065
11108
  console.warn("No place where to put the section <!--".concat(sectionName, "-->, using the end of the file"));
11066
- // <- TODO: [🚎] Some better way how to get warnings from pipeline parsing / logic
11067
- return spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(content), "\n \n ").concat(block(contentToInsert), "\n "); });
11109
+ // <- TODO: [🚎][💩] Some better way how to get warnings from pipeline parsing / logic
11110
+ return spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(content), "\n\n ").concat(block(contentToInsert), "\n "); });
11068
11111
  }
11069
11112
  /**
11070
11113
  * TODO: [🏛] This can be part of markdown builder
@@ -11489,7 +11532,7 @@
11489
11532
  '\n\n' +
11490
11533
  executionReportJson.promptExecutions
11491
11534
  .map(function (promptExecution) {
11492
- // TODO: Make some better system to convert hedings to links
11535
+ // TODO: [💩] Make some better system to convert headings to links
11493
11536
  var hash = normalizeToKebabCase(promptExecution.prompt.title);
11494
11537
  if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
11495
11538
  hash = '-' + hash;
@@ -12257,7 +12300,7 @@
12257
12300
  socket.on('connect', function () {
12258
12301
  resolve(socket);
12259
12302
  });
12260
- // TODO: [main] !!!! Better timeout handling
12303
+ // TODO: [💩] Better timeout handling
12261
12304
  setTimeout(function () {
12262
12305
  reject(new Error("Timeout while connecting to ".concat(_this.options.remoteUrl)));
12263
12306
  }, CONNECTION_TIMEOUT_MS);
@@ -13235,7 +13278,7 @@
13235
13278
  modelVariant: 'CHAT',
13236
13279
  modelTitle: 'o1-preview-2024-09-12',
13237
13280
  modelName: 'o1-preview-2024-09-12',
13238
- // <- TODO: [main] !!! Some better system to organize theese date suffixes and versions
13281
+ // <- TODO: [💩] Some better system to organize theese date suffixes and versions
13239
13282
  pricing: {
13240
13283
  prompt: computeUsage("$15.00 / 1M tokens"),
13241
13284
  output: computeUsage("$60.00 / 1M tokens"),
@@ -13285,7 +13328,7 @@
13285
13328
  * @see https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4
13286
13329
  * @see https://openai.com/api/pricing/
13287
13330
  * @see /other/playground/playground.ts
13288
- * TODO: [🍓] Make better
13331
+ * TODO: [🍓][💩] Make better
13289
13332
  * TODO: Change model titles to human eg: "gpt-4-turbo-2024-04-09" -> "GPT-4 Turbo (2024-04-09)"
13290
13333
  * TODO: [🚸] Not all models are compatible with JSON mode, add this information here and use it
13291
13334
  * Note: [💞] Ignore a discrepancy between file name and entity name