@promptbook/node 0.78.4 → 0.80.0-0

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 (36) hide show
  1. package/README.md +4 -0
  2. package/esm/index.es.js +866 -451
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/books/index.d.ts +6 -6
  5. package/esm/typings/src/_packages/core.index.d.ts +4 -2
  6. package/esm/typings/src/_packages/types.index.d.ts +10 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +4 -0
  8. package/esm/typings/src/cli/cli-commands/runInteractiveChatbot.d.ts +32 -0
  9. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +5 -2
  10. package/esm/typings/src/config.d.ts +0 -25
  11. package/esm/typings/src/constants.d.ts +35 -0
  12. package/esm/typings/src/conversion/pipelineJsonToString.d.ts +1 -0
  13. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +1 -0
  14. package/esm/typings/src/formfactors/generator/GeneratorFormfactorDefinition.d.ts +6 -1
  15. package/esm/typings/src/formfactors/index.d.ts +12 -2
  16. package/esm/typings/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +6 -1
  17. package/esm/typings/src/high-level-abstractions/_common/HighLevelAbstraction.d.ts +20 -0
  18. package/esm/typings/src/high-level-abstractions/implicit-formfactor/ImplicitFormfactorHla.d.ts +10 -0
  19. package/esm/typings/src/high-level-abstractions/index.d.ts +44 -0
  20. package/esm/typings/src/high-level-abstractions/quick-chatbot/QuickChatbotHla.d.ts +10 -0
  21. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -1
  22. package/esm/typings/src/llm-providers/remote/startRemoteServer.d.ts +1 -1
  23. package/esm/typings/src/prepare/prepareTasks.d.ts +1 -0
  24. package/esm/typings/src/types/typeAliases.d.ts +1 -1
  25. package/esm/typings/src/utils/normalization/orderJson.d.ts +21 -0
  26. package/esm/typings/src/utils/normalization/orderJson.test.d.ts +4 -0
  27. package/esm/typings/src/utils/organization/keepTypeImported.d.ts +9 -0
  28. package/esm/typings/src/utils/serialization/$deepFreeze.d.ts +1 -1
  29. package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +20 -2
  30. package/esm/typings/src/utils/serialization/deepClone.test.d.ts +1 -0
  31. package/esm/typings/src/utils/serialization/exportJson.d.ts +29 -0
  32. package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +2 -1
  33. package/package.json +3 -2
  34. package/umd/index.umd.js +866 -451
  35. package/umd/index.umd.js.map +1 -1
  36. package/esm/typings/src/utils/serialization/$asDeeplyFrozenSerializableJson.d.ts +0 -17
package/esm/index.es.js CHANGED
@@ -26,7 +26,7 @@ var BOOK_LANGUAGE_VERSION = '1.0.0';
26
26
  *
27
27
  * @see https://github.com/webgptorg/promptbook
28
28
  */
29
- var PROMPTBOOK_ENGINE_VERSION = '0.78.3';
29
+ var PROMPTBOOK_ENGINE_VERSION = '0.79.0';
30
30
  /**
31
31
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
32
32
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -249,41 +249,6 @@ var DEFAULT_SCRAPE_CACHE_DIRNAME = './.promptbook/scrape-cache';
249
249
  * @public exported from `@promptbook/core`
250
250
  */
251
251
  var DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME = "index";
252
- /**
253
- * Nonce which is used for replacing things in strings
254
- *
255
- * @private within the repository
256
- */
257
- var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
258
- /**
259
- * The names of the parameters that are reserved for special purposes
260
- *
261
- * @public exported from `@promptbook/core`
262
- */
263
- var RESERVED_PARAMETER_NAMES =
264
- /* !!!!!! $asDeeplyFrozenSerializableJson('RESERVED_PARAMETER_NAMES', _____ as const); */ [
265
- 'content',
266
- 'context',
267
- 'knowledge',
268
- 'examples',
269
- 'modelName',
270
- 'currentDate',
271
- // <- TODO: list here all command names
272
- // <- TODO: Add more like 'date', 'modelName',...
273
- // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
274
- ];
275
- /**
276
- * @@@
277
- *
278
- * @private within the repository
279
- */
280
- var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
281
- /**
282
- * @@@
283
- *
284
- * @private within the repository
285
- */
286
- var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
287
252
  // <- TODO: [🧜‍♂️]
288
253
  /**
289
254
  * @@@
@@ -318,7 +283,6 @@ var IS_PIPELINE_LOGIC_VALIDATED = just(
318
283
  // Note: In normal situations, we check the pipeline logic:
319
284
  true);
320
285
  /**
321
- * TODO: Extract `constants.ts` from `config.ts`
322
286
  * Note: [💞] Ignore a discrepancy between file name and entity name
323
287
  * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
324
288
  */
@@ -369,6 +333,7 @@ function capitalize(word) {
369
333
  /**
370
334
  * Converts promptbook in JSON format to string format
371
335
  *
336
+ * @deprecated TODO: [🥍][🧠] Backup original files in `PipelineJson` same as in Promptbook.studio
372
337
  * @param pipelineJson Promptbook in JSON format (.book.json)
373
338
  * @returns Promptbook in string format (.book.md)
374
339
  * @public exported from `@promptbook/core`
@@ -572,6 +537,332 @@ function taskParameterJsonToString(taskParameterJson) {
572
537
  * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
573
538
  */
574
539
 
540
+ /**
541
+ * Orders JSON object by keys
542
+ *
543
+ * @returns The same type of object as the input re-ordered
544
+ * @public exported from `@promptbook/utils`
545
+ */
546
+ function orderJson(options) {
547
+ var value = options.value, order = options.order;
548
+ var orderedValue = __assign(__assign({}, (order === undefined ? {} : Object.fromEntries(order.map(function (key) { return [key, undefined]; })))), value);
549
+ return orderedValue;
550
+ }
551
+
552
+ /**
553
+ * Freezes the given object and all its nested objects recursively
554
+ *
555
+ * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
556
+ * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
557
+ *
558
+ * @returns The same object as the input, but deeply frozen
559
+ * @public exported from `@promptbook/utils`
560
+ */
561
+ function $deepFreeze(objectValue) {
562
+ var e_1, _a;
563
+ if (Array.isArray(objectValue)) {
564
+ return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
565
+ }
566
+ var propertyNames = Object.getOwnPropertyNames(objectValue);
567
+ try {
568
+ for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
569
+ var propertyName = propertyNames_1_1.value;
570
+ var value = objectValue[propertyName];
571
+ if (value && typeof value === 'object') {
572
+ $deepFreeze(value);
573
+ }
574
+ }
575
+ }
576
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
577
+ finally {
578
+ try {
579
+ if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
580
+ }
581
+ finally { if (e_1) throw e_1.error; }
582
+ }
583
+ Object.freeze(objectValue);
584
+ return objectValue;
585
+ }
586
+ /**
587
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
588
+ */
589
+
590
+ /**
591
+ * Make error report URL for the given error
592
+ *
593
+ * @private !!!!!!
594
+ */
595
+ function getErrorReportUrl(error) {
596
+ var report = {
597
+ title: "\uD83D\uDC1C Error report from ".concat(NAME),
598
+ body: spaceTrim(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 "); }),
599
+ };
600
+ var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
601
+ reportUrl.searchParams.set('labels', 'bug');
602
+ reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
603
+ reportUrl.searchParams.set('title', report.title);
604
+ reportUrl.searchParams.set('body', report.body);
605
+ return reportUrl;
606
+ }
607
+
608
+ /**
609
+ * This error type indicates that the error should not happen and its last check before crashing with some other error
610
+ *
611
+ * @public exported from `@promptbook/core`
612
+ */
613
+ var UnexpectedError = /** @class */ (function (_super) {
614
+ __extends(UnexpectedError, _super);
615
+ function UnexpectedError(message) {
616
+ var _this = _super.call(this, spaceTrim$1(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;
617
+ _this.name = 'UnexpectedError';
618
+ Object.setPrototypeOf(_this, UnexpectedError.prototype);
619
+ return _this;
620
+ }
621
+ return UnexpectedError;
622
+ }(Error));
623
+
624
+ /**
625
+ * Checks if the value is [🚉] serializable as JSON
626
+ * If not, throws an UnexpectedError with a rich error message and tracking
627
+ *
628
+ * - Almost all primitives are serializable BUT:
629
+ * - `undefined` is not serializable
630
+ * - `NaN` is not serializable
631
+ * - Objects and arrays are serializable if all their properties are serializable
632
+ * - Functions are not serializable
633
+ * - Circular references are not serializable
634
+ * - `Date` objects are not serializable
635
+ * - `Map` and `Set` objects are not serializable
636
+ * - `RegExp` objects are not serializable
637
+ * - `Error` objects are not serializable
638
+ * - `Symbol` objects are not serializable
639
+ * - And much more...
640
+ *
641
+ * @throws UnexpectedError if the value is not serializable as JSON
642
+ * @public exported from `@promptbook/utils`
643
+ */
644
+ function checkSerializableAsJson(options) {
645
+ var e_1, _a;
646
+ var value = options.value, name = options.name, message = options.message;
647
+ if (value === undefined) {
648
+ throw new UnexpectedError("".concat(name, " is undefined"));
649
+ }
650
+ else if (value === null) {
651
+ return;
652
+ }
653
+ else if (typeof value === 'boolean') {
654
+ return;
655
+ }
656
+ else if (typeof value === 'number' && !isNaN(value)) {
657
+ return;
658
+ }
659
+ else if (typeof value === 'string') {
660
+ return;
661
+ }
662
+ else if (typeof value === 'symbol') {
663
+ throw new UnexpectedError("".concat(name, " is symbol"));
664
+ }
665
+ else if (typeof value === 'function') {
666
+ throw new UnexpectedError("".concat(name, " is function"));
667
+ }
668
+ else if (typeof value === 'object' && Array.isArray(value)) {
669
+ for (var i = 0; i < value.length; i++) {
670
+ checkSerializableAsJson({ name: "".concat(name, "[").concat(i, "]"), value: value[i], message: message });
671
+ }
672
+ }
673
+ else if (typeof value === 'object') {
674
+ if (value instanceof Date) {
675
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is Date\n\n Use `string_date_iso8601` instead\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
676
+ }
677
+ else if (value instanceof Map) {
678
+ throw new UnexpectedError("".concat(name, " is Map"));
679
+ }
680
+ else if (value instanceof Set) {
681
+ throw new UnexpectedError("".concat(name, " is Set"));
682
+ }
683
+ else if (value instanceof RegExp) {
684
+ throw new UnexpectedError("".concat(name, " is RegExp"));
685
+ }
686
+ else if (value instanceof Error) {
687
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is unserialized Error\n\n Use function `serializeError`\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n\n "); }));
688
+ }
689
+ else {
690
+ try {
691
+ for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
692
+ var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
693
+ if (subValue === undefined) {
694
+ // Note: undefined in object is serializable - it is just omited
695
+ continue;
696
+ }
697
+ checkSerializableAsJson({ name: "".concat(name, ".").concat(subName), value: subValue, message: message });
698
+ }
699
+ }
700
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
701
+ finally {
702
+ try {
703
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
704
+ }
705
+ finally { if (e_1) throw e_1.error; }
706
+ }
707
+ try {
708
+ JSON.stringify(value); // <- TODO: [0]
709
+ }
710
+ catch (error) {
711
+ if (!(error instanceof Error)) {
712
+ throw error;
713
+ }
714
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is not serializable\n\n ").concat(block(error.toString()), "\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
715
+ }
716
+ /*
717
+ TODO: [0] Is there some more elegant way to check circular references?
718
+ const seen = new Set();
719
+ const stack = [{ value }];
720
+ while (stack.length > 0) {
721
+ const { value } = stack.pop()!;
722
+ if (typeof value === 'object' && value !== null) {
723
+ if (seen.has(value)) {
724
+ throw new UnexpectedError(`${name} has circular reference`);
725
+ }
726
+ seen.add(value);
727
+ if (Array.isArray(value)) {
728
+ stack.push(...value.map((value) => ({ value })));
729
+ } else {
730
+ stack.push(...Object.values(value).map((value) => ({ value })));
731
+ }
732
+ }
733
+ }
734
+ */
735
+ return;
736
+ }
737
+ }
738
+ else {
739
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is unknown type\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
740
+ }
741
+ }
742
+ /**
743
+ * TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
744
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
745
+ * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
746
+ */
747
+
748
+ /**
749
+ * @@@
750
+ *
751
+ * @public exported from `@promptbook/utils`
752
+ */
753
+ function deepClone(objectValue) {
754
+ return JSON.parse(JSON.stringify(objectValue));
755
+ /*
756
+ !!!!!!!!
757
+ TODO: [🧠] Is there a better implementation?
758
+ > const propertyNames = Object.getOwnPropertyNames(objectValue);
759
+ > for (const propertyName of propertyNames) {
760
+ > const value = (objectValue as really_any)[propertyName];
761
+ > if (value && typeof value === 'object') {
762
+ > deepClone(value);
763
+ > }
764
+ > }
765
+ > return Object.assign({}, objectValue);
766
+ */
767
+ }
768
+ /**
769
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
770
+ */
771
+
772
+ /**
773
+ * Utility to export a JSON object from a function
774
+ *
775
+ * 1) Checks if the value is serializable as JSON
776
+ * 2) Makes a deep clone of the object
777
+ * 2) Orders the object properties
778
+ * 2) Deeply freezes the cloned object
779
+ *
780
+ * Note: This function does not mutates the given object
781
+ *
782
+ * @returns The same type of object as the input but read-only and re-ordered
783
+ * @public exported from `@promptbook/utils`
784
+ */
785
+ function exportJson(options) {
786
+ var name = options.name, value = options.value, order = options.order, message = options.message;
787
+ checkSerializableAsJson({ name: name, value: value, message: message });
788
+ var orderedValue =
789
+ // TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
790
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
791
+ // @ts-ignore
792
+ order === undefined
793
+ ? deepClone(value)
794
+ : orderJson({
795
+ value: value,
796
+ // <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
797
+ order: order,
798
+ });
799
+ $deepFreeze(orderedValue);
800
+ return orderedValue;
801
+ }
802
+ /**
803
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
804
+ */
805
+
806
+ /**
807
+ * Order of keys in the pipeline JSON
808
+ *
809
+ * @public exported from `@promptbook/core`
810
+ */
811
+ var ORDER_OF_PIPELINE_JSON = [
812
+ 'title',
813
+ 'pipelineUrl',
814
+ 'bookVersion',
815
+ 'description',
816
+ 'formfactorName',
817
+ 'parameters',
818
+ 'tasks',
819
+ 'personas',
820
+ 'preparations',
821
+ 'knowledgeSources',
822
+ 'knowledgePieces',
823
+ ];
824
+ /**
825
+ * Nonce which is used for replacing things in strings
826
+ *
827
+ * @private within the repository
828
+ */
829
+ var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
830
+ /**
831
+ * @@@
832
+ *
833
+ * @private within the repository
834
+ */
835
+ var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
836
+ /**
837
+ * @@@
838
+ *
839
+ * @private within the repository
840
+ */
841
+ var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
842
+ /**
843
+ * The names of the parameters that are reserved for special purposes
844
+ *
845
+ * @public exported from `@promptbook/core`
846
+ */
847
+ var RESERVED_PARAMETER_NAMES = exportJson({
848
+ name: 'RESERVED_PARAMETER_NAMES',
849
+ message: "The names of the parameters that are reserved for special purposes",
850
+ value: [
851
+ 'content',
852
+ 'context',
853
+ 'knowledge',
854
+ 'examples',
855
+ 'modelName',
856
+ 'currentDate',
857
+ // <- TODO: list here all command names
858
+ // <- TODO: Add more like 'date', 'modelName',...
859
+ // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
860
+ ],
861
+ });
862
+ /**
863
+ * Note: [💞] Ignore a discrepancy between file name and entity name
864
+ */
865
+
575
866
  /**
576
867
  * This error type indicates that some tools are missing for pipeline execution or preparation
577
868
  *
@@ -655,48 +946,14 @@ function forEachAsync(array, options, callbackfunction) {
655
946
  }
656
947
  finally { if (e_1) throw e_1.error; }
657
948
  return [7 /*endfinally*/];
658
- case 8: return [4 /*yield*/, Promise.all(tasks)];
659
- case 9:
660
- _e.sent();
661
- return [2 /*return*/];
662
- }
663
- });
664
- });
665
- }
666
-
667
- /**
668
- * @@@
669
- *
670
- * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
671
- * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
672
- *
673
- * @returns The same object as the input, but deeply frozen
674
- * @public exported from `@promptbook/utils`
675
- */
676
- function $deepFreeze(objectValue) {
677
- var e_1, _a;
678
- var propertyNames = Object.getOwnPropertyNames(objectValue);
679
- try {
680
- for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
681
- var propertyName = propertyNames_1_1.value;
682
- var value = objectValue[propertyName];
683
- if (value && typeof value === 'object') {
684
- $deepFreeze(value);
685
- }
686
- }
687
- }
688
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
689
- finally {
690
- try {
691
- if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
692
- }
693
- finally { if (e_1) throw e_1.error; }
694
- }
695
- return Object.freeze(objectValue);
949
+ case 8: return [4 /*yield*/, Promise.all(tasks)];
950
+ case 9:
951
+ _e.sent();
952
+ return [2 /*return*/];
953
+ }
954
+ });
955
+ });
696
956
  }
697
- /**
698
- * TODO: [🧠] Is there a way how to meaningfully test this utility
699
- */
700
957
 
701
958
  /**
702
959
  * Represents the usage with no resources consumed
@@ -754,29 +1011,6 @@ $deepFreeze({
754
1011
  * Note: [💞] Ignore a discrepancy between file name and entity name
755
1012
  */
756
1013
 
757
- /**
758
- * @@@
759
- *
760
- * @public exported from `@promptbook/utils`
761
- */
762
- function deepClone(objectValue) {
763
- return JSON.parse(JSON.stringify(objectValue));
764
- /*
765
- TODO: [🧠] Is there a better implementation?
766
- > const propertyNames = Object.getOwnPropertyNames(objectValue);
767
- > for (const propertyName of propertyNames) {
768
- > const value = (objectValue as really_any)[propertyName];
769
- > if (value && typeof value === 'object') {
770
- > deepClone(value);
771
- > }
772
- > }
773
- > return Object.assign({}, objectValue);
774
- */
775
- }
776
- /**
777
- * TODO: [🧠] Is there a way how to meaningfully test this utility
778
- */
779
-
780
1014
  /**
781
1015
  * Function `addUsage` will add multiple usages into one
782
1016
  *
@@ -952,40 +1186,6 @@ var PipelineExecutionError = /** @class */ (function (_super) {
952
1186
  return PipelineExecutionError;
953
1187
  }(Error));
954
1188
 
955
- /**
956
- * Make error report URL for the given error
957
- *
958
- * @private !!!!!!
959
- */
960
- function getErrorReportUrl(error) {
961
- var report = {
962
- title: "\uD83D\uDC1C Error report from ".concat(NAME),
963
- body: spaceTrim(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 "); }),
964
- };
965
- var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
966
- reportUrl.searchParams.set('labels', 'bug');
967
- reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
968
- reportUrl.searchParams.set('title', report.title);
969
- reportUrl.searchParams.set('body', report.body);
970
- return reportUrl;
971
- }
972
-
973
- /**
974
- * This error type indicates that the error should not happen and its last check before crashing with some other error
975
- *
976
- * @public exported from `@promptbook/core`
977
- */
978
- var UnexpectedError = /** @class */ (function (_super) {
979
- __extends(UnexpectedError, _super);
980
- function UnexpectedError(message) {
981
- var _this = _super.call(this, spaceTrim$1(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;
982
- _this.name = 'UnexpectedError';
983
- Object.setPrototypeOf(_this, UnexpectedError.prototype);
984
- return _this;
985
- }
986
- return UnexpectedError;
987
- }(Error));
988
-
989
1189
  /**
990
1190
  * Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
991
1191
  *
@@ -1278,7 +1478,7 @@ function joinLlmExecutionTools() {
1278
1478
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1279
1479
  */
1280
1480
 
1281
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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:"./books/prepare-knowledge-from-markdown.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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:"./books/prepare-knowledge-keywords.book.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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:"./books/prepare-knowledge-title.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",formfactorName:"GENERIC",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}],tasks:[{taskType:"PROMPT_TASK",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:"./books/prepare-persona.book.md"}];
1481
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sourceFile:"./books/prepare-knowledge-from-markdown.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sourceFile:"./books/prepare-knowledge-keywords.book.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sourceFile:"./books/prepare-knowledge-title.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",formfactorName:"GENERIC",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}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sourceFile:"./books/prepare-persona.book.md"}];
1282
1482
 
1283
1483
  /**
1284
1484
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -1552,6 +1752,21 @@ function validatePipelineCore(pipeline) {
1552
1752
  }
1553
1753
  };
1554
1754
  try {
1755
+ /*
1756
+ TODO: [🧠][🅾] Should be empty pipeline valid or not
1757
+ // Note: Check that pipeline has some tasks
1758
+ if (pipeline.tasks.length === 0) {
1759
+ throw new PipelineLogicError(
1760
+ spaceTrim(
1761
+ (block) => `
1762
+ Pipeline must have at least one task
1763
+
1764
+ ${block(pipelineIdentification)}
1765
+ `,
1766
+ ),
1767
+ );
1768
+ }
1769
+ */
1555
1770
  // Note: Check each parameter individually
1556
1771
  for (var _d = __values(pipeline.parameters), _e = _d.next(); !_e.done; _e = _d.next()) {
1557
1772
  var parameter = _e.value;
@@ -1712,6 +1927,9 @@ function validatePipelineCore(pipeline) {
1712
1927
  while (unresovedTasks.length > 0) {
1713
1928
  _loop_3();
1714
1929
  }
1930
+ // Note: Check that formfactor is corresponding to the pipeline interface
1931
+ // TODO: !!!!!! Implement this
1932
+ // pipeline.formfactorName
1715
1933
  }
1716
1934
  /**
1717
1935
  * TODO: !! [🧞‍♀️] Do not allow joker + foreach
@@ -1728,215 +1946,72 @@ function validatePipelineCore(pipeline) {
1728
1946
  /**
1729
1947
  * TODO: [🧳][main] !!!! Validate that all examples match expectations
1730
1948
  * TODO: [🧳][🐝][main] !!!! Validate that knowledge is valid (non-void)
1731
- * TODO: [🧳][main] !!!! Validate that persona can be used only with CHAT variant
1732
- * TODO: [🧳][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1733
- * TODO: [🧳][main] !!!! Validate that reserved parameter is not used as joker
1734
- * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
1735
- * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
1736
- */
1737
-
1738
- /**
1739
- * This error indicates that promptbook not found in the collection
1740
- *
1741
- * @public exported from `@promptbook/core`
1742
- */
1743
- var NotFoundError = /** @class */ (function (_super) {
1744
- __extends(NotFoundError, _super);
1745
- function NotFoundError(message) {
1746
- var _this = _super.call(this, message) || this;
1747
- _this.name = 'NotFoundError';
1748
- Object.setPrototypeOf(_this, NotFoundError.prototype);
1749
- return _this;
1750
- }
1751
- return NotFoundError;
1752
- }(Error));
1753
-
1754
- /**
1755
- * This error indicates errors in referencing promptbooks between each other
1756
- *
1757
- * @public exported from `@promptbook/core`
1758
- */
1759
- var PipelineUrlError = /** @class */ (function (_super) {
1760
- __extends(PipelineUrlError, _super);
1761
- function PipelineUrlError(message) {
1762
- var _this = _super.call(this, message) || this;
1763
- _this.name = 'PipelineUrlError';
1764
- Object.setPrototypeOf(_this, PipelineUrlError.prototype);
1765
- return _this;
1766
- }
1767
- return PipelineUrlError;
1768
- }(Error));
1769
-
1770
- /**
1771
- * Parses the task and returns the list of all parameter names
1772
- *
1773
- * @param template the string template with parameters in {curly} braces
1774
- * @returns the list of parameter names
1775
- * @public exported from `@promptbook/utils`
1776
- */
1777
- function extractParameterNames(template) {
1778
- var e_1, _a;
1779
- var matches = template.matchAll(/{\w+}/g);
1780
- var parameterNames = new Set();
1781
- try {
1782
- for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
1783
- var match = matches_1_1.value;
1784
- var parameterName = match[0].slice(1, -1);
1785
- parameterNames.add(parameterName);
1786
- }
1787
- }
1788
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1789
- finally {
1790
- try {
1791
- if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
1792
- }
1793
- finally { if (e_1) throw e_1.error; }
1794
- }
1795
- return parameterNames;
1796
- }
1797
-
1798
- /**
1799
- * Checks if the value is [🚉] serializable as JSON
1800
- * If not, throws an UnexpectedError with a rich error message and tracking
1801
- *
1802
- * - Almost all primitives are serializable BUT:
1803
- * - `undefined` is not serializable
1804
- * - `NaN` is not serializable
1805
- * - Objects and arrays are serializable if all their properties are serializable
1806
- * - Functions are not serializable
1807
- * - Circular references are not serializable
1808
- * - `Date` objects are not serializable
1809
- * - `Map` and `Set` objects are not serializable
1810
- * - `RegExp` objects are not serializable
1811
- * - `Error` objects are not serializable
1812
- * - `Symbol` objects are not serializable
1813
- * - And much more...
1814
- *
1815
- * @throws UnexpectedError if the value is not serializable as JSON
1816
- * @public exported from `@promptbook/utils`
1817
- */
1818
- function checkSerializableAsJson(name, value) {
1819
- var e_1, _a;
1820
- if (value === undefined) {
1821
- throw new UnexpectedError("".concat(name, " is undefined"));
1822
- }
1823
- else if (value === null) {
1824
- return;
1825
- }
1826
- else if (typeof value === 'boolean') {
1827
- return;
1828
- }
1829
- else if (typeof value === 'number' && !isNaN(value)) {
1830
- return;
1831
- }
1832
- else if (typeof value === 'string') {
1833
- return;
1834
- }
1835
- else if (typeof value === 'symbol') {
1836
- throw new UnexpectedError("".concat(name, " is symbol"));
1837
- }
1838
- else if (typeof value === 'function') {
1839
- throw new UnexpectedError("".concat(name, " is function"));
1840
- }
1841
- else if (typeof value === 'object' && Array.isArray(value)) {
1842
- for (var i = 0; i < value.length; i++) {
1843
- checkSerializableAsJson("".concat(name, "[").concat(i, "]"), value[i]);
1844
- }
1845
- }
1846
- else if (typeof value === 'object') {
1847
- if (value instanceof Date) {
1848
- throw new UnexpectedError(spaceTrim("\n ".concat(name, " is Date\n\n Use `string_date_iso8601` instead\n ")));
1849
- }
1850
- else if (value instanceof Map) {
1851
- throw new UnexpectedError("".concat(name, " is Map"));
1852
- }
1853
- else if (value instanceof Set) {
1854
- throw new UnexpectedError("".concat(name, " is Set"));
1855
- }
1856
- else if (value instanceof RegExp) {
1857
- throw new UnexpectedError("".concat(name, " is RegExp"));
1858
- }
1859
- else if (value instanceof Error) {
1860
- throw new UnexpectedError(spaceTrim("\n ".concat(name, " is unserialized Error\n\n Use function `serializeError`\n ")));
1861
- }
1862
- else {
1863
- try {
1864
- for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
1865
- var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
1866
- if (subValue === undefined) {
1867
- // Note: undefined in object is serializable - it is just omited
1868
- continue;
1869
- }
1870
- checkSerializableAsJson("".concat(name, ".").concat(subName), subValue);
1871
- }
1872
- }
1873
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1874
- finally {
1875
- try {
1876
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1877
- }
1878
- finally { if (e_1) throw e_1.error; }
1879
- }
1880
- try {
1881
- JSON.stringify(value); // <- TODO: [0]
1882
- }
1883
- catch (error) {
1884
- if (!(error instanceof Error)) {
1885
- throw error;
1886
- }
1887
- throw new UnexpectedError(spaceTrim(function (block) { return "\n ".concat(name, " is not serializable\n\n ").concat(block(error.toString()), "\n "); }));
1888
- }
1889
- /*
1890
- TODO: [0] Is there some more elegant way to check circular references?
1891
- const seen = new Set();
1892
- const stack = [{ value }];
1893
- while (stack.length > 0) {
1894
- const { value } = stack.pop()!;
1895
- if (typeof value === 'object' && value !== null) {
1896
- if (seen.has(value)) {
1897
- throw new UnexpectedError(`${name} has circular reference`);
1898
- }
1899
- seen.add(value);
1900
- if (Array.isArray(value)) {
1901
- stack.push(...value.map((value) => ({ value })));
1902
- } else {
1903
- stack.push(...Object.values(value).map((value) => ({ value })));
1904
- }
1905
- }
1906
- }
1907
- */
1908
- return;
1909
- }
1910
- }
1911
- else {
1912
- throw new UnexpectedError("".concat(name, " is unknown"));
1913
- }
1914
- }
1915
- /**
1916
- * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
1917
- * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
1918
- * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
1949
+ * TODO: [🧳][main] !!!! Validate that persona can be used only with CHAT variant
1950
+ * TODO: [🧳][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1951
+ * TODO: [🧳][main] !!!! Validate that reserved parameter is not used as joker
1952
+ * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
1953
+ * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
1919
1954
  */
1920
1955
 
1921
1956
  /**
1922
- * @@@
1923
- * @@@
1957
+ * This error indicates that promptbook not found in the collection
1924
1958
  *
1925
- * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
1959
+ * @public exported from `@promptbook/core`
1960
+ */
1961
+ var NotFoundError = /** @class */ (function (_super) {
1962
+ __extends(NotFoundError, _super);
1963
+ function NotFoundError(message) {
1964
+ var _this = _super.call(this, message) || this;
1965
+ _this.name = 'NotFoundError';
1966
+ Object.setPrototypeOf(_this, NotFoundError.prototype);
1967
+ return _this;
1968
+ }
1969
+ return NotFoundError;
1970
+ }(Error));
1971
+
1972
+ /**
1973
+ * This error indicates errors in referencing promptbooks between each other
1926
1974
  *
1927
- * @param name - Name of the object for debugging purposes
1928
- * @param objectValue - Object to be deeply frozen
1929
- * @returns The same object as the input, but deeply frozen
1930
- * @private this is in comparison to `deepFreeze` a more specific utility and maybe not very good practice to use without specific reason and considerations
1975
+ * @public exported from `@promptbook/core`
1931
1976
  */
1932
- function $asDeeplyFrozenSerializableJson(name, objectValue) {
1933
- checkSerializableAsJson(name, objectValue);
1934
- return $deepFreeze(objectValue);
1935
- }
1977
+ var PipelineUrlError = /** @class */ (function (_super) {
1978
+ __extends(PipelineUrlError, _super);
1979
+ function PipelineUrlError(message) {
1980
+ var _this = _super.call(this, message) || this;
1981
+ _this.name = 'PipelineUrlError';
1982
+ Object.setPrototypeOf(_this, PipelineUrlError.prototype);
1983
+ return _this;
1984
+ }
1985
+ return PipelineUrlError;
1986
+ }(Error));
1987
+
1936
1988
  /**
1937
- * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
1938
- * TODO: [🧠] Is there a way how to meaningfully test this utility
1989
+ * Parses the task and returns the list of all parameter names
1990
+ *
1991
+ * @param template the string template with parameters in {curly} braces
1992
+ * @returns the list of parameter names
1993
+ * @public exported from `@promptbook/utils`
1939
1994
  */
1995
+ function extractParameterNames(template) {
1996
+ var e_1, _a;
1997
+ var matches = template.matchAll(/{\w+}/g);
1998
+ var parameterNames = new Set();
1999
+ try {
2000
+ for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
2001
+ var match = matches_1_1.value;
2002
+ var parameterName = match[0].slice(1, -1);
2003
+ parameterNames.add(parameterName);
2004
+ }
2005
+ }
2006
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2007
+ finally {
2008
+ try {
2009
+ if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
2010
+ }
2011
+ finally { if (e_1) throw e_1.error; }
2012
+ }
2013
+ return parameterNames;
2014
+ }
1940
2015
 
1941
2016
  /**
1942
2017
  * Unprepare just strips the preparation data of the pipeline
@@ -1955,7 +2030,12 @@ function unpreparePipeline(pipeline) {
1955
2030
  delete taskUnprepared.preparedContent;
1956
2031
  return taskUnprepared;
1957
2032
  });
1958
- return $asDeeplyFrozenSerializableJson('Unprepared PipelineJson', __assign(__assign({}, pipeline), { tasks: tasks, knowledgeSources: knowledgeSources, knowledgePieces: [], personas: personas, preparations: [] }));
2033
+ return exportJson({
2034
+ name: 'pipelineJson',
2035
+ message: "Result of `unpreparePipeline`",
2036
+ order: ORDER_OF_PIPELINE_JSON,
2037
+ value: __assign(__assign({}, pipeline), { tasks: tasks, knowledgeSources: knowledgeSources, knowledgePieces: [], personas: personas, preparations: [] }),
2038
+ });
1959
2039
  }
1960
2040
  /**
1961
2041
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
@@ -4316,16 +4396,21 @@ function executePipeline(options) {
4316
4396
  // Note: Wait a short time to prevent race conditions
4317
4397
  _g.sent();
4318
4398
  _g.label = 6;
4319
- case 6: return [2 /*return*/, $asDeeplyFrozenSerializableJson("Unuccessful PipelineExecutorResult (with missing parameter {".concat(parameter.name, "}) PipelineExecutorResult"), {
4320
- isSuccessful: false,
4321
- errors: __spreadArray([
4322
- new PipelineExecutionError("Parameter `{".concat(parameter.name, "}` is required as an input parameter"))
4323
- ], __read(errors), false).map(serializeError),
4324
- warnings: [],
4325
- executionReport: executionReport,
4326
- outputParameters: {},
4327
- usage: ZERO_USAGE,
4328
- preparedPipeline: preparedPipeline,
4399
+ case 6: return [2 /*return*/, exportJson({
4400
+ name: "executionReport",
4401
+ message: "Unuccessful PipelineExecutorResult (with missing parameter {".concat(parameter.name, "}) PipelineExecutorResult"),
4402
+ order: [],
4403
+ value: {
4404
+ isSuccessful: false,
4405
+ errors: __spreadArray([
4406
+ new PipelineExecutionError("Parameter `{".concat(parameter.name, "}` is required as an input parameter"))
4407
+ ], __read(errors), false).map(serializeError),
4408
+ warnings: [],
4409
+ executionReport: executionReport,
4410
+ outputParameters: {},
4411
+ usage: ZERO_USAGE,
4412
+ preparedPipeline: preparedPipeline,
4413
+ },
4329
4414
  })];
4330
4415
  case 7:
4331
4416
  _b = _a.next();
@@ -4364,16 +4449,21 @@ function executePipeline(options) {
4364
4449
  // Note: Wait a short time to prevent race conditions
4365
4450
  _h.sent();
4366
4451
  _h.label = 3;
4367
- case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim$1(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4368
- isSuccessful: false,
4369
- errors: __spreadArray([
4370
- new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter `{".concat(parameter.name, "}` is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
4371
- ], __read(errors), false).map(serializeError),
4372
- warnings: warnings.map(serializeError),
4373
- executionReport: executionReport,
4374
- outputParameters: {},
4375
- usage: ZERO_USAGE,
4376
- preparedPipeline: preparedPipeline,
4452
+ case 3: return [2 /*return*/, { value: exportJson({
4453
+ name: 'pipelineExecutorResult',
4454
+ message: spaceTrim$1(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }),
4455
+ order: [],
4456
+ value: {
4457
+ isSuccessful: false,
4458
+ errors: __spreadArray([
4459
+ new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter `{".concat(parameter.name, "}` is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
4460
+ ], __read(errors), false).map(serializeError),
4461
+ warnings: warnings.map(serializeError),
4462
+ executionReport: executionReport,
4463
+ outputParameters: {},
4464
+ usage: ZERO_USAGE,
4465
+ preparedPipeline: preparedPipeline,
4466
+ },
4377
4467
  }) }];
4378
4468
  case 4: return [2 /*return*/];
4379
4469
  }
@@ -4527,14 +4617,19 @@ function executePipeline(options) {
4527
4617
  // Note: Wait a short time to prevent race conditions
4528
4618
  _g.sent();
4529
4619
  _g.label = 27;
4530
- case 27: return [2 /*return*/, $asDeeplyFrozenSerializableJson('Unuccessful PipelineExecutorResult (with misc errors) PipelineExecutorResult', {
4531
- isSuccessful: false,
4532
- errors: __spreadArray([error_1], __read(errors), false).map(serializeError),
4533
- warnings: warnings.map(serializeError),
4534
- usage: usage_1,
4535
- executionReport: executionReport,
4536
- outputParameters: outputParameters_1,
4537
- preparedPipeline: preparedPipeline,
4620
+ case 27: return [2 /*return*/, exportJson({
4621
+ name: 'pipelineExecutorResult',
4622
+ message: "Unuccessful PipelineExecutorResult (with misc errors) PipelineExecutorResult",
4623
+ order: [],
4624
+ value: {
4625
+ isSuccessful: false,
4626
+ errors: __spreadArray([error_1], __read(errors), false).map(serializeError),
4627
+ warnings: warnings.map(serializeError),
4628
+ usage: usage_1,
4629
+ executionReport: executionReport,
4630
+ outputParameters: outputParameters_1,
4631
+ preparedPipeline: preparedPipeline,
4632
+ },
4538
4633
  })];
4539
4634
  case 28:
4540
4635
  usage = addUsage.apply(void 0, __spreadArray([], __read(executionReport.promptExecutions.map(function (_a) {
@@ -4555,14 +4650,19 @@ function executePipeline(options) {
4555
4650
  // Note: Wait a short time to prevent race conditions
4556
4651
  _g.sent();
4557
4652
  _g.label = 30;
4558
- case 30: return [2 /*return*/, $asDeeplyFrozenSerializableJson('Successful PipelineExecutorResult', {
4559
- isSuccessful: true,
4560
- errors: errors.map(serializeError),
4561
- warnings: warnings.map(serializeError),
4562
- usage: usage,
4563
- executionReport: executionReport,
4564
- outputParameters: outputParameters,
4565
- preparedPipeline: preparedPipeline,
4653
+ case 30: return [2 /*return*/, exportJson({
4654
+ name: 'pipelineExecutorResult',
4655
+ message: "Successful PipelineExecutorResult",
4656
+ order: [],
4657
+ value: {
4658
+ isSuccessful: true,
4659
+ errors: errors.map(serializeError),
4660
+ warnings: warnings.map(serializeError),
4661
+ usage: usage,
4662
+ executionReport: executionReport,
4663
+ outputParameters: outputParameters,
4664
+ preparedPipeline: preparedPipeline,
4665
+ },
4566
4666
  })];
4567
4667
  }
4568
4668
  });
@@ -5427,36 +5527,6 @@ TODO: [🧊] This is how it can look in future
5427
5527
  * [ ] One piece can have multiple sources
5428
5528
  */
5429
5529
 
5430
- /**
5431
- * @@@
5432
- *
5433
- * Note: It is usefull @@@
5434
- *
5435
- * @param pipeline
5436
- * @public exported from `@promptbook/utils`
5437
- */
5438
- function clonePipeline(pipeline) {
5439
- // Note: Not using spread operator (...) because @@@
5440
- var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, bookVersion = pipeline.bookVersion, description = pipeline.description, formfactorName = pipeline.formfactorName, parameters = pipeline.parameters, tasks = pipeline.tasks, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
5441
- return {
5442
- pipelineUrl: pipelineUrl,
5443
- sourceFile: sourceFile,
5444
- title: title,
5445
- bookVersion: bookVersion,
5446
- description: description,
5447
- formfactorName: formfactorName,
5448
- parameters: parameters,
5449
- tasks: tasks,
5450
- knowledgeSources: knowledgeSources,
5451
- knowledgePieces: knowledgePieces,
5452
- personas: personas,
5453
- preparations: preparations,
5454
- };
5455
- }
5456
- /**
5457
- * TODO: [🍙] Make some standard order of json properties
5458
- */
5459
-
5460
5530
  /**
5461
5531
  * @@@
5462
5532
  *
@@ -5497,6 +5567,7 @@ function prepareTasks(pipeline, tools, options) {
5497
5567
  });
5498
5568
  }
5499
5569
  /**
5570
+ * TODO: [😂] Adding knowledge should be convert to async high-level abstractions, simmilar thing with expectations to sync high-level abstractions
5500
5571
  * TODO: [🧠] Add context to each task (if missing)
5501
5572
  * TODO: [🧠] What is better name `prepareTask` or `prepareTaskAndParameters`
5502
5573
  * TODO: [♨][main] !!! Prepare index the examples and maybe tasks
@@ -5585,11 +5656,19 @@ function preparePipeline(pipeline, tools, options) {
5585
5656
  case 3:
5586
5657
  tasksPrepared = (_c.sent()).tasksPrepared;
5587
5658
  // ----- /Tasks preparation -----
5659
+ // TODO: [😂] Use here all `AsyncHighLevelAbstraction`
5588
5660
  // Note: Count total usage
5589
5661
  currentPreparation.usage = llmToolsWithUsage.getTotalUsage();
5590
- return [2 /*return*/, $asDeeplyFrozenSerializableJson('Prepared PipelineJson', __assign(__assign({}, clonePipeline(pipeline)), { tasks: __spreadArray([], __read(tasksPrepared), false),
5591
- // <- TODO: [🪓] Here should be no need for spreading new array, just ` tasks: tasksPrepared`
5592
- knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, personas: preparedPersonas, preparations: __spreadArray([], __read(preparations), false) }))];
5662
+ return [2 /*return*/, exportJson({
5663
+ name: 'pipelineJson',
5664
+ message: "Result of `preparePipeline`",
5665
+ order: ORDER_OF_PIPELINE_JSON,
5666
+ value: __assign(__assign({}, pipeline), {
5667
+ // <- TODO: Probbably deeply clone the pipeline because `$exportJson` freezes the subobjects
5668
+ knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, tasks: __spreadArray([], __read(tasksPrepared), false),
5669
+ // <- TODO: [🪓] Here should be no need for spreading new array, just ` tasks: tasksPrepared`
5670
+ personas: preparedPersonas, preparations: __spreadArray([], __read(preparations), false) }),
5671
+ })];
5593
5672
  }
5594
5673
  });
5595
5674
  });
@@ -5853,7 +5932,8 @@ var sectionCommandParser = {
5853
5932
  expectResultingParameterName();
5854
5933
  var parameter = $pipelineJson.parameters.find(function (param) { return param.name === $taskJson.resultingParameterName; });
5855
5934
  if (parameter === undefined) {
5856
- throw new ParseError("Can not find parameter {".concat($taskJson.resultingParameterName, "} to assign example value on it"));
5935
+ // TODO: !!!!!! Change to logic error for higher level abstractions to work
5936
+ throw new ParseError("Parameter `{".concat($taskJson.resultingParameterName, "}` is not defined so can not define example value of it"));
5857
5937
  }
5858
5938
  parameter.exampleValues = parameter.exampleValues || [];
5859
5939
  parameter.exampleValues.push($taskJson.content);
@@ -6762,7 +6842,13 @@ var GeneratorFormfactorDefinition = {
6762
6842
  documentationUrl: "https://github.com/webgptorg/promptbook/discussions/184",
6763
6843
  pipelineInterface: {
6764
6844
  inputParameters: [
6765
- /* @@@ */
6845
+ /* @@@ */
6846
+ {
6847
+ name: 'nonce',
6848
+ description: 'Just to prevent GENERATOR to be set as implicit formfactor',
6849
+ isInput: true,
6850
+ isOutput: false,
6851
+ },
6766
6852
  ],
6767
6853
  outputParameters: [
6768
6854
  /* @@@ */
@@ -6808,7 +6894,13 @@ var MatcherFormfactorDefinition = {
6808
6894
  documentationUrl: "https://github.com/webgptorg/promptbook/discussions/177",
6809
6895
  pipelineInterface: {
6810
6896
  inputParameters: [
6811
- /* @@@ */
6897
+ /* @@@ */
6898
+ {
6899
+ name: 'nonce',
6900
+ description: 'Just to prevent EXPERIMENTAL_MATCHER to be set as implicit formfactor',
6901
+ isInput: true,
6902
+ isOutput: false,
6903
+ },
6812
6904
  ],
6813
6905
  outputParameters: [
6814
6906
  /* @@@ */
@@ -6957,6 +7049,9 @@ var formfactorCommandParser = {
6957
7049
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6958
7050
  */
6959
7051
  $applyToPipelineJson: function (command, $pipelineJson) {
7052
+ if ($pipelineJson.formfactorName !== undefined && $pipelineJson.formfactorName !== command.formfactorName) {
7053
+ throw new ParseError(spaceTrim("\n Redefinition of `FORMFACTOR` in the pipeline head\n\n You have used:\n 1) FORMFACTOR `".concat($pipelineJson.formfactorName, "`\n 2) FORMFACTOR `").concat(command.formfactorName, "`\n ")));
7054
+ }
6960
7055
  $pipelineJson.formfactorName = command.formfactorName;
6961
7056
  },
6962
7057
  /**
@@ -7144,7 +7239,7 @@ var modelCommandParser = {
7144
7239
  // <- TODO: [🚎][💩] Some better way how to get warnings from pipeline parsing / logic
7145
7240
  }
7146
7241
  else {
7147
- throw new ParseError(spaceTrim("\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 ")));
7242
+ throw new ParseError(spaceTrim("\n Redefinition of `MODEL ".concat(command.key, "` in the pipeline head\n\n You have used:\n 1) `MODEL ").concat(command.key, " ").concat($pipelineJson.defaultModelRequirements[command.key], "`\n 2) `MODEL ").concat(command.key, " ").concat(command.value, "`\n ")));
7148
7243
  }
7149
7244
  }
7150
7245
  $pipelineJson.defaultModelRequirements[command.key] = command.value;
@@ -7962,6 +8057,295 @@ function parseCommandVariant(input) {
7962
8057
  return null;
7963
8058
  }
7964
8059
 
8060
+ /**
8061
+ * @@@
8062
+ *
8063
+ * @deprecated https://github.com/webgptorg/promptbook/pull/186
8064
+ * @see https://github.com/webgptorg/promptbook/discussions/171
8065
+ *
8066
+ * @public exported from `@promptbook/core`
8067
+ */
8068
+ function getPipelineInterface(pipeline) {
8069
+ var e_1, _a, e_2, _b;
8070
+ var pipelineInterface = {
8071
+ inputParameters: [],
8072
+ outputParameters: [],
8073
+ };
8074
+ try {
8075
+ for (var _c = __values(pipeline.parameters), _d = _c.next(); !_d.done; _d = _c.next()) {
8076
+ var parameter = _d.value;
8077
+ var isInput = parameter.isInput, isOutput = parameter.isOutput;
8078
+ if (isInput) {
8079
+ pipelineInterface.inputParameters.push(deepClone(parameter));
8080
+ }
8081
+ if (isOutput) {
8082
+ pipelineInterface.outputParameters.push(deepClone(parameter));
8083
+ }
8084
+ }
8085
+ }
8086
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
8087
+ finally {
8088
+ try {
8089
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
8090
+ }
8091
+ finally { if (e_1) throw e_1.error; }
8092
+ }
8093
+ try {
8094
+ for (var _e = __values(['inputParameters', 'outputParameters']), _f = _e.next(); !_f.done; _f = _e.next()) {
8095
+ var key = _f.value;
8096
+ pipelineInterface[key].sort(function (_a, _b) {
8097
+ var name1 = _a.name;
8098
+ var name2 = _b.name;
8099
+ return name1.localeCompare(name2);
8100
+ });
8101
+ }
8102
+ }
8103
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
8104
+ finally {
8105
+ try {
8106
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
8107
+ }
8108
+ finally { if (e_2) throw e_2.error; }
8109
+ }
8110
+ return exportJson({
8111
+ name: "pipelineInterface",
8112
+ message: "Result of `getPipelineInterface`",
8113
+ order: ['inputParameters', 'outputParameters'],
8114
+ value: pipelineInterface,
8115
+ });
8116
+ }
8117
+
8118
+ /**
8119
+ * @@@
8120
+ *
8121
+ * @deprecated https://github.com/webgptorg/promptbook/pull/186
8122
+ * @see https://github.com/webgptorg/promptbook/discussions/171
8123
+ *
8124
+ * @public exported from `@promptbook/core`
8125
+ */
8126
+ function isPipelineInterfacesEqual(pipelineInterface1, pipelineInterface2) {
8127
+ var e_1, _a, e_2, _b;
8128
+ try {
8129
+ for (var _c = __values(['inputParameters', 'outputParameters']), _d = _c.next(); !_d.done; _d = _c.next()) {
8130
+ var whichParameters = _d.value;
8131
+ var parameters1 = pipelineInterface1[whichParameters]; // <- Note: `isPipelineInterfacesEqual` is just temporary solution, no need to fix this
8132
+ var parameters2 = pipelineInterface2[whichParameters];
8133
+ if (parameters1.length !== parameters2.length) {
8134
+ return false;
8135
+ }
8136
+ var _loop_1 = function (parameter) {
8137
+ var matchingParameter = parameters2.find(function (_a) {
8138
+ var name = _a.name;
8139
+ return name === parameter.name;
8140
+ });
8141
+ if (!matchingParameter) {
8142
+ return { value: false };
8143
+ }
8144
+ // Note: Do not compare description, it is not relevant for compatibility
8145
+ if (matchingParameter.isInput !== parameter.isInput) {
8146
+ return { value: false };
8147
+ }
8148
+ if (matchingParameter.isOutput !== parameter.isOutput) {
8149
+ return { value: false };
8150
+ }
8151
+ };
8152
+ try {
8153
+ for (var parameters1_1 = (e_2 = void 0, __values(parameters1)), parameters1_1_1 = parameters1_1.next(); !parameters1_1_1.done; parameters1_1_1 = parameters1_1.next()) {
8154
+ var parameter = parameters1_1_1.value;
8155
+ var state_1 = _loop_1(parameter);
8156
+ if (typeof state_1 === "object")
8157
+ return state_1.value;
8158
+ }
8159
+ }
8160
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
8161
+ finally {
8162
+ try {
8163
+ if (parameters1_1_1 && !parameters1_1_1.done && (_b = parameters1_1.return)) _b.call(parameters1_1);
8164
+ }
8165
+ finally { if (e_2) throw e_2.error; }
8166
+ }
8167
+ }
8168
+ }
8169
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
8170
+ finally {
8171
+ try {
8172
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
8173
+ }
8174
+ finally { if (e_1) throw e_1.error; }
8175
+ }
8176
+ return true;
8177
+ }
8178
+
8179
+ /**
8180
+ * @@@
8181
+ *
8182
+ * @deprecated https://github.com/webgptorg/promptbook/pull/186
8183
+ * @see https://github.com/webgptorg/promptbook/discussions/171
8184
+ *
8185
+ * @public exported from `@promptbook/core`
8186
+ */
8187
+ function isPipelineImplementingInterface(options) {
8188
+ var pipeline = options.pipeline, pipelineInterface = options.pipelineInterface;
8189
+ return isPipelineInterfacesEqual(getPipelineInterface(pipeline), pipelineInterface);
8190
+ }
8191
+
8192
+ /**
8193
+ * Set formfactor based on the pipeline interface e
8194
+ *
8195
+ * @private
8196
+ */
8197
+ var ImplicitFormfactorHla = {
8198
+ type: 'SYNC',
8199
+ $applyToPipelineJson: function ($pipelineJson) {
8200
+ var e_1, _a;
8201
+ if ($pipelineJson.formfactorName !== undefined) {
8202
+ // Note: When formfactor is already set, do nothing
8203
+ return;
8204
+ }
8205
+ try {
8206
+ for (var _b = __values(FORMFACTOR_DEFINITIONS.filter(function (_a) {
8207
+ var name = _a.name;
8208
+ return name !== 'GENERIC';
8209
+ })), _c = _b.next(); !_c.done; _c = _b.next()) {
8210
+ var formfactorDefinition = _c.value;
8211
+ // <- Note: [♓️][💩] This is the order of the formfactors, make some explicit priority
8212
+ var name_1 = formfactorDefinition.name, pipelineInterface = formfactorDefinition.pipelineInterface;
8213
+ var isCompatible = isPipelineImplementingInterface({
8214
+ pipeline: __assign({ formfactorName: name_1 }, $pipelineJson),
8215
+ pipelineInterface: pipelineInterface,
8216
+ });
8217
+ /*/
8218
+ console.log({
8219
+ subject: `${$pipelineJson.title} implements ${name}`,
8220
+ pipelineTitle: $pipelineJson.title,
8221
+ formfactorName: name,
8222
+ isCompatible,
8223
+ formfactorInterface: pipelineInterface,
8224
+ pipelineInterface: getPipelineInterface($pipelineJson as PipelineJson),
8225
+ });
8226
+ /**/
8227
+ if (isCompatible) {
8228
+ $pipelineJson.formfactorName = name_1;
8229
+ return;
8230
+ }
8231
+ }
8232
+ }
8233
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
8234
+ finally {
8235
+ try {
8236
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8237
+ }
8238
+ finally { if (e_1) throw e_1.error; }
8239
+ }
8240
+ },
8241
+ };
8242
+
8243
+ /**
8244
+ * Allow to define chatbot with no need to write full interface
8245
+ *
8246
+ * @private
8247
+ */
8248
+ var QuickChatbotHla = {
8249
+ type: 'SYNC',
8250
+ $applyToPipelineJson: function ($pipelineJson) {
8251
+ if ($pipelineJson.tasks.length !== 0) {
8252
+ // Note: When there are already tasks, do nothing
8253
+ return;
8254
+ }
8255
+ if ($pipelineJson.parameters.length !== 0) {
8256
+ // Note: When there are already parameters, do nothing
8257
+ return;
8258
+ }
8259
+ if ($pipelineJson.personas.length === 0) {
8260
+ // Note: When no personas defined, do nothing
8261
+ return;
8262
+ }
8263
+ var personaName = $pipelineJson.personas[0].name;
8264
+ $pipelineJson.formfactorName = 'CHATBOT';
8265
+ $pipelineJson.parameters.push({
8266
+ name: 'previousTitle',
8267
+ description: 'Previous title of the conversation',
8268
+ isInput: true,
8269
+ isOutput: false,
8270
+ }, {
8271
+ name: 'previousConversationSummary',
8272
+ description: 'Previous conversation summary',
8273
+ isInput: true,
8274
+ isOutput: false,
8275
+ }, {
8276
+ name: 'userMessage',
8277
+ description: 'User message',
8278
+ isInput: true,
8279
+ isOutput: false,
8280
+ }, {
8281
+ name: 'title',
8282
+ description: 'Title of the conversation',
8283
+ isInput: false,
8284
+ isOutput: true,
8285
+ }, {
8286
+ name: 'conversationSummary',
8287
+ description: 'Summary of the conversation',
8288
+ isInput: false,
8289
+ isOutput: true,
8290
+ }, {
8291
+ name: 'chatbotResponse',
8292
+ description: 'Chatbot response',
8293
+ isInput: false,
8294
+ isOutput: true,
8295
+ exampleValues: ['Hello, I am a Pavol`s virtual avatar. How can I help you?'],
8296
+ });
8297
+ // TODO: !!!!!! spaceTrim
8298
+ $pipelineJson.tasks.push({
8299
+ taskType: 'PROMPT_TASK',
8300
+ name: 'create-an-answer',
8301
+ title: 'Create an answer',
8302
+ content: 'Write a response to the user message:\n\n**Question from user**\n\n> {userMessage}\n\n**Previous conversation**\n\n> {previousConversationSummary}',
8303
+ resultingParameterName: 'chatbotResponse',
8304
+ personaName: personaName,
8305
+ dependentParameterNames: ['userMessage', 'previousConversationSummary' /* !!!!!!, 'knowledge'*/],
8306
+ // !!!!!! preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
8307
+ }, {
8308
+ taskType: 'PROMPT_TASK',
8309
+ name: 'summarize-the-conversation',
8310
+ title: 'Summarize the conversation',
8311
+ content: 'Summarize the conversation in a few words:\n\n## Rules\n\n- Summarise the text of the conversation in a few words\n- Convert the text to its basic idea\n- Imagine you are writing the headline or subject line of an email\n- Respond with a few words of summary only\n\n## Conversation\n\n**User:**\n\n> {userMessage}\n\n**You:**\n\n> {chatbotResponse}',
8312
+ resultingParameterName: 'conversationSummary',
8313
+ personaName: personaName,
8314
+ expectations: {
8315
+ words: {
8316
+ min: 1,
8317
+ max: 10,
8318
+ },
8319
+ },
8320
+ dependentParameterNames: ['userMessage', 'chatbotResponse' /* !!!!!!, 'knowledge'*/],
8321
+ // !!!!!! preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
8322
+ }, {
8323
+ taskType: 'SIMPLE_TASK',
8324
+ name: 'title',
8325
+ title: 'Title',
8326
+ content: '{conversationSummary}',
8327
+ resultingParameterName: 'title',
8328
+ dependentParameterNames: ['conversationSummary' /* !!!!!!, 'knowledge'*/],
8329
+ // !!!!!! preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
8330
+ });
8331
+ },
8332
+ };
8333
+
8334
+ /**
8335
+ * All high-level abstractions
8336
+ *
8337
+ * @private internal index of `pipelineStringToJsonSync` (= used for sync) and `preparePipeline` (= used for async)
8338
+ */
8339
+ var HIGH_LEVEL_ABSTRACTIONS = [
8340
+ ImplicitFormfactorHla,
8341
+ QuickChatbotHla,
8342
+ // <- Note: [♓️][💩] This is the order of the application of high-level abstractions application on pipeline JSON
8343
+ ];
8344
+ /**
8345
+ * TODO: Test that all sync high-level abstractions are before async high-level abstractions
8346
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8347
+ */
8348
+
7965
8349
  /**
7966
8350
  * Supported script languages
7967
8351
  *
@@ -8237,20 +8621,15 @@ function titleToName(value) {
8237
8621
  * @public exported from `@promptbook/core`
8238
8622
  */
8239
8623
  function pipelineStringToJsonSync(pipelineString) {
8240
- var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e;
8624
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
8241
8625
  var $pipelineJson = {
8242
- title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
8243
- pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
8244
- bookVersion: undefined /* <- Note: By default no explicit version */,
8245
- description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
8246
- formfactorName: 'GENERIC',
8626
+ title: DEFAULT_TITLE,
8247
8627
  parameters: [],
8248
8628
  tasks: [],
8249
8629
  knowledgeSources: [],
8250
8630
  knowledgePieces: [],
8251
8631
  personas: [],
8252
8632
  preparations: [],
8253
- // <- TODO: [🍙] Some standard order of properties
8254
8633
  };
8255
8634
  function getPipelineIdentification() {
8256
8635
  // Note: This is a 😐 implementation of [🚞]
@@ -8266,7 +8645,7 @@ function pipelineStringToJsonSync(pipelineString) {
8266
8645
  // =============================================================
8267
8646
  // Note: 1️⃣ Parsing of the markdown into object
8268
8647
  if (pipelineString.startsWith('#!')) {
8269
- var _f = __read(pipelineString.split('\n')), shebangLine_1 = _f[0], restLines = _f.slice(1);
8648
+ var _g = __read(pipelineString.split('\n')), shebangLine_1 = _g[0], restLines = _g.slice(1);
8270
8649
  if (!(shebangLine_1 || '').includes('ptbk')) {
8271
8650
  throw new ParseError(spaceTrim$1(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 "); }));
8272
8651
  }
@@ -8276,7 +8655,7 @@ function pipelineStringToJsonSync(pipelineString) {
8276
8655
  pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
8277
8656
  pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
8278
8657
  pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
8279
- var _g = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _g[0], pipelineSections = _g.slice(1); /* <- Note: [🥞] */
8658
+ var _h = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _h[0], pipelineSections = _h.slice(1); /* <- Note: [🥞] */
8280
8659
  if (pipelineHead === undefined) {
8281
8660
  throw new UnexpectedError(spaceTrim$1(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 "); }));
8282
8661
  }
@@ -8341,7 +8720,7 @@ function pipelineStringToJsonSync(pipelineString) {
8341
8720
  }
8342
8721
  try {
8343
8722
  commandParser.$applyToPipelineJson(command, $pipelineJson);
8344
- // <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitelly
8723
+ // <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitly
8345
8724
  }
8346
8725
  catch (error) {
8347
8726
  if (!(error instanceof ParseError)) {
@@ -8398,10 +8777,10 @@ function pipelineStringToJsonSync(pipelineString) {
8398
8777
  return nameWithSuffix;
8399
8778
  };
8400
8779
  var _loop_2 = function (section) {
8401
- var e_6, _m, e_7, _o;
8780
+ var e_7, _q, e_8, _r;
8402
8781
  // TODO: Parse section's description (the content out of the codeblock and lists)
8403
8782
  var listItems_2 = extractAllListItemsFromMarkdown(section.content);
8404
- var _p = extractOneBlockFromMarkdown(section.content), language = _p.language, content = _p.content;
8783
+ var _s = extractOneBlockFromMarkdown(section.content), language = _s.language, content = _s.content;
8405
8784
  // TODO: [🎾][1] DRY description
8406
8785
  var description_1 = section.content;
8407
8786
  // Note: Remove codeblocks - TODO: [🎾]
@@ -8449,7 +8828,7 @@ function pipelineStringToJsonSync(pipelineString) {
8449
8828
  }
8450
8829
  try {
8451
8830
  commandParser.$applyToTaskJson(
8452
- // <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitelly
8831
+ // <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitly
8453
8832
  command, $taskJson, $pipelineJson);
8454
8833
  }
8455
8834
  catch (error) {
@@ -8465,17 +8844,17 @@ function pipelineStringToJsonSync(pipelineString) {
8465
8844
  };
8466
8845
  try {
8467
8846
  // TODO [♓️] List commands and before apply order them to achieve order-agnostic commands
8468
- for (var commands_1 = (e_6 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
8469
- var _q = commands_1_1.value, listItem = _q.listItem, command = _q.command;
8847
+ for (var commands_1 = (e_7 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
8848
+ var _t = commands_1_1.value, listItem = _t.listItem, command = _t.command;
8470
8849
  _loop_4(listItem, command);
8471
8850
  }
8472
8851
  }
8473
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
8852
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
8474
8853
  finally {
8475
8854
  try {
8476
- if (commands_1_1 && !commands_1_1.done && (_m = commands_1.return)) _m.call(commands_1);
8855
+ if (commands_1_1 && !commands_1_1.done && (_q = commands_1.return)) _q.call(commands_1);
8477
8856
  }
8478
- finally { if (e_6) throw e_6.error; }
8857
+ finally { if (e_7) throw e_7.error; }
8479
8858
  }
8480
8859
  // TODO: [🍧] Should be done in SECTION command
8481
8860
  if ($taskJson.taskType === 'SCRIPT_TASK') {
@@ -8489,8 +8868,8 @@ function pipelineStringToJsonSync(pipelineString) {
8489
8868
  }
8490
8869
  $taskJson.dependentParameterNames = Array.from(extractParameterNamesFromTask($taskJson));
8491
8870
  try {
8492
- for (var _r = (e_7 = void 0, __values($taskJson.dependentParameterNames)), _s = _r.next(); !_s.done; _s = _r.next()) {
8493
- var parameterName = _s.value;
8871
+ for (var _u = (e_8 = void 0, __values($taskJson.dependentParameterNames)), _v = _u.next(); !_v.done; _v = _u.next()) {
8872
+ var parameterName = _v.value;
8494
8873
  // TODO: [🧠] This definition should be made first in the task
8495
8874
  defineParam({
8496
8875
  parameterName: parameterName,
@@ -8501,12 +8880,12 @@ function pipelineStringToJsonSync(pipelineString) {
8501
8880
  });
8502
8881
  }
8503
8882
  }
8504
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
8883
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
8505
8884
  finally {
8506
8885
  try {
8507
- if (_s && !_s.done && (_o = _r.return)) _o.call(_r);
8886
+ if (_v && !_v.done && (_r = _u.return)) _r.call(_u);
8508
8887
  }
8509
- finally { if (e_7) throw e_7.error; }
8888
+ finally { if (e_8) throw e_8.error; }
8510
8889
  }
8511
8890
  /*
8512
8891
  // TODO: [🍧] This should be checked in `MODEL` command + better error message
@@ -8555,18 +8934,22 @@ function pipelineStringToJsonSync(pipelineString) {
8555
8934
  var isThisParameterResulting = $pipelineJson.tasks.some(function (task) { return task.resultingParameterName === parameter.name; });
8556
8935
  if (!isThisParameterResulting) {
8557
8936
  parameter.isInput = true;
8937
+ // <- TODO: [💔] Why this is making typescript error in vscode but not in cli
8938
+ // > Type 'true' is not assignable to type 'false'.ts(2322)
8939
+ // > (property) isInput: false
8940
+ // > The parameter is input of the pipeline The parameter is NOT input of the pipeline
8558
8941
  }
8559
8942
  };
8560
8943
  try {
8561
- for (var _h = __values($pipelineJson.parameters), _j = _h.next(); !_j.done; _j = _h.next()) {
8562
- var parameter = _j.value;
8944
+ for (var _j = __values($pipelineJson.parameters), _k = _j.next(); !_k.done; _k = _j.next()) {
8945
+ var parameter = _k.value;
8563
8946
  _loop_3(parameter);
8564
8947
  }
8565
8948
  }
8566
8949
  catch (e_4_1) { e_4 = { error: e_4_1 }; }
8567
8950
  finally {
8568
8951
  try {
8569
- if (_j && !_j.done && (_d = _h.return)) _d.call(_h);
8952
+ if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
8570
8953
  }
8571
8954
  finally { if (e_4) throw e_4.error; }
8572
8955
  }
@@ -8575,17 +8958,18 @@ function pipelineStringToJsonSync(pipelineString) {
8575
8958
  // Note: 7️⃣ Mark all non-INPUT parameters as OUTPUT if any OUTPUT is not set
8576
8959
  if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isOutput; })) {
8577
8960
  try {
8578
- for (var _k = __values($pipelineJson.parameters), _l = _k.next(); !_l.done; _l = _k.next()) {
8579
- var parameter = _l.value;
8961
+ for (var _l = __values($pipelineJson.parameters), _m = _l.next(); !_m.done; _m = _l.next()) {
8962
+ var parameter = _m.value;
8580
8963
  if (!parameter.isInput) {
8581
8964
  parameter.isOutput = true;
8965
+ // <- TODO: [💔]
8582
8966
  }
8583
8967
  }
8584
8968
  }
8585
8969
  catch (e_5_1) { e_5 = { error: e_5_1 }; }
8586
8970
  finally {
8587
8971
  try {
8588
- if (_l && !_l.done && (_e = _k.return)) _e.call(_k);
8972
+ if (_m && !_m.done && (_e = _l.return)) _e.call(_l);
8589
8973
  }
8590
8974
  finally { if (e_5) throw e_5.error; }
8591
8975
  }
@@ -8593,7 +8977,7 @@ function pipelineStringToJsonSync(pipelineString) {
8593
8977
  // =============================================================
8594
8978
  // Note: 8️⃣ Cleanup of undefined values
8595
8979
  $pipelineJson.tasks.forEach(function (tasks) {
8596
- var e_8, _a;
8980
+ var e_9, _a;
8597
8981
  try {
8598
8982
  for (var _b = __values(Object.entries(tasks)), _c = _b.next(); !_c.done; _c = _b.next()) {
8599
8983
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8602,16 +8986,16 @@ function pipelineStringToJsonSync(pipelineString) {
8602
8986
  }
8603
8987
  }
8604
8988
  }
8605
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
8989
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
8606
8990
  finally {
8607
8991
  try {
8608
8992
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8609
8993
  }
8610
- finally { if (e_8) throw e_8.error; }
8994
+ finally { if (e_9) throw e_9.error; }
8611
8995
  }
8612
8996
  });
8613
8997
  $pipelineJson.parameters.forEach(function (parameter) {
8614
- var e_9, _a;
8998
+ var e_10, _a;
8615
8999
  try {
8616
9000
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
8617
9001
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8620,19 +9004,49 @@ function pipelineStringToJsonSync(pipelineString) {
8620
9004
  }
8621
9005
  }
8622
9006
  }
8623
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
9007
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
8624
9008
  finally {
8625
9009
  try {
8626
9010
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8627
9011
  }
8628
- finally { if (e_9) throw e_9.error; }
9012
+ finally { if (e_10) throw e_10.error; }
8629
9013
  }
8630
9014
  });
9015
+ try {
9016
+ // =============================================================
9017
+ // Note: 9️⃣ Apply sync high-level abstractions
9018
+ for (var _o = __values(HIGH_LEVEL_ABSTRACTIONS.filter(function (_a) {
9019
+ var type = _a.type;
9020
+ return type === 'SYNC';
9021
+ })), _p = _o.next(); !_p.done; _p = _o.next()) {
9022
+ var highLevelAbstraction = _p.value;
9023
+ highLevelAbstraction.$applyToPipelineJson($pipelineJson);
9024
+ }
9025
+ }
9026
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
9027
+ finally {
9028
+ try {
9029
+ if (_p && !_p.done && (_f = _o.return)) _f.call(_o);
9030
+ }
9031
+ finally { if (e_6) throw e_6.error; }
9032
+ }
9033
+ // =============================================================
9034
+ // Note: 🔟 Default formfactor
9035
+ // Note: [🔆] If formfactor is still not set, set it to 'GENERIC'
9036
+ if ($pipelineJson.formfactorName === undefined) {
9037
+ $pipelineJson.formfactorName = 'GENERIC';
9038
+ }
8631
9039
  // =============================================================
8632
9040
  // TODO: [🍙] Maybe do reorder of `$pipelineJson` here
8633
- return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
9041
+ return exportJson({
9042
+ name: 'pipelineJson',
9043
+ message: "Result of `pipelineStringToJsonSync`",
9044
+ order: ORDER_OF_PIPELINE_JSON,
9045
+ value: __assign({ formfactorName: 'GENERIC' }, $pipelineJson),
9046
+ });
8634
9047
  }
8635
9048
  /**
9049
+ * TODO: [🧠] Maybe more things here can be refactored as high-level abstractions
8636
9050
  * TODO: [main] !!!! Warn if used only sync version
8637
9051
  * TODO: [🚞] Report here line/column of error
8638
9052
  * TODO: Use spaceTrim more effectively
@@ -8676,7 +9090,7 @@ function pipelineStringToJson(pipelineString, tools, options) {
8676
9090
  pipelineJson = _a.sent();
8677
9091
  _a.label = 2;
8678
9092
  case 2:
8679
- // Note: No need to use `$asDeeplyFrozenSerializableJson` because `pipelineStringToJsonSync` and `preparePipeline` already do that
9093
+ // Note: No need to use `$exportJson` because `pipelineStringToJsonSync` and `preparePipeline` already do that
8680
9094
  return [2 /*return*/, pipelineJson];
8681
9095
  }
8682
9096
  });
@@ -10133,7 +10547,7 @@ function createCollectionFromDirectory(path, tools, options) {
10133
10547
  return [3 /*break*/, 7];
10134
10548
  case 6:
10135
10549
  if (isVerbose) {
10136
- console.info(colors.gray("Skipped file ".concat(fileName.split('\\').join('/'), " \u2013\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060 Not a pipeline")));
10550
+ console.info(colors.gray("Skipped file ".concat(fileName.split('\\').join('/'), " \u2013\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060 Not a book")));
10137
10551
  }
10138
10552
  _e.label = 7;
10139
10553
  case 7:
@@ -10180,7 +10594,7 @@ function createCollectionFromDirectory(path, tools, options) {
10180
10594
  if (!(error_1 instanceof Error)) {
10181
10595
  throw error_1;
10182
10596
  }
10183
- wrappedErrorMessage = spaceTrim(function (block) { return "\n ".concat(error_1.name, " in pipeline ").concat(fileName.split('\\').join('/'), "\u2060:\n\n ").concat(block(error_1.message), "\n\n "); });
10597
+ wrappedErrorMessage = spaceTrim(function (block) { return "\n ".concat(error_1.name, " in pipeline ").concat(fileName.split('\\').join('/'), "\u2060:\n\n Original error message:\n ").concat(block(error_1.message), "\n\n Original stack trace:\n ").concat(block(error_1.stack || ''), "\n\n ---\n\n "); }) + '\n';
10184
10598
  if (isCrashedOnError) {
10185
10599
  throw new CollectionError(wrappedErrorMessage);
10186
10600
  }
@@ -10236,6 +10650,7 @@ function createCollectionFromDirectory(path, tools, options) {
10236
10650
  * TODO: Maybe move from `@promptbook/node` to `@promptbook/core` as we removes direct dependency on `fs`
10237
10651
  */
10238
10652
 
10653
+ // <- TODO: !!!!!!! Auto convert to type `import { ... } from 'type-fest';`
10239
10654
  /**
10240
10655
  * Tests if the value is [🚉] serializable as JSON
10241
10656
  *
@@ -10257,7 +10672,7 @@ function createCollectionFromDirectory(path, tools, options) {
10257
10672
  */
10258
10673
  function isSerializableAsJson(value) {
10259
10674
  try {
10260
- checkSerializableAsJson('', value);
10675
+ checkSerializableAsJson({ value: value });
10261
10676
  return true;
10262
10677
  }
10263
10678
  catch (error) {