@promptbook/cli 0.71.0-15 → 0.71.0-16

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.
package/esm/index.es.js CHANGED
@@ -2,7 +2,7 @@ import commander from 'commander';
2
2
  import spaceTrim$1, { spaceTrim } from 'spacetrim';
3
3
  import colors from 'colors';
4
4
  import { forTime } from 'waitasecond';
5
- import { readFile, stat, access, constants, readdir, writeFile, mkdir, unlink, rm, rmdir, rename } from 'fs/promises';
5
+ import { stat, access, constants, readFile, readdir, writeFile, mkdir, unlink, rm, rmdir, rename } from 'fs/promises';
6
6
  import { join, basename, dirname } from 'path';
7
7
  import { format } from 'prettier';
8
8
  import parserHtml from 'prettier/parser-html';
@@ -26,7 +26,7 @@ import { Converter } from 'showdown';
26
26
  /**
27
27
  * The version of the Promptbook library
28
28
  */
29
- var PROMPTBOOK_VERSION = '0.71.0-14';
29
+ var PROMPTBOOK_VERSION = '0.71.0-15';
30
30
  // TODO: [main] !!!! List here all the versions and annotate + put into script
31
31
 
32
32
  /*! *****************************************************************************
@@ -613,6 +613,271 @@ function initializeHelloCommand(program) {
613
613
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
614
614
  */
615
615
 
616
+ /**
617
+ * Just marks a place of place where should be something implemented
618
+ * No side effects.
619
+ *
620
+ * Note: It can be usefull suppressing eslint errors of unused variables
621
+ *
622
+ * @param value any values
623
+ * @returns void
624
+ * @private within the repository
625
+ */
626
+ function TODO_USE() {
627
+ var value = [];
628
+ for (var _i = 0; _i < arguments.length; _i++) {
629
+ value[_i] = arguments[_i];
630
+ }
631
+ }
632
+
633
+ /**
634
+ * @@@
635
+ *
636
+ * @public exported from `@promptbook/node`
637
+ */
638
+ function $provideFilesystemForNode(options) {
639
+ if (!$isRunningInNode()) {
640
+ throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
641
+ }
642
+ var _a = (options || {}).isVerbose, isVerbose = _a === void 0 ? IS_VERBOSE : _a;
643
+ TODO_USE(isVerbose);
644
+ return {
645
+ stat: stat,
646
+ access: access,
647
+ constants: constants,
648
+ readFile: readFile,
649
+ readdir: readdir,
650
+ };
651
+ }
652
+ /**
653
+ * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
654
+ */
655
+
656
+ /**
657
+ * This error type indicates that some part of the code is not implemented yet
658
+ *
659
+ * @public exported from `@promptbook/core`
660
+ */
661
+ var NotYetImplementedError = /** @class */ (function (_super) {
662
+ __extends(NotYetImplementedError, _super);
663
+ function NotYetImplementedError(message) {
664
+ var _this = _super.call(this, spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note: This feature is not implemented yet but it will be soon.\n\n If you want speed up the implementation or just read more, look here:\n https://github.com/webgptorg/promptbook\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
665
+ _this.name = 'NotYetImplementedError';
666
+ Object.setPrototypeOf(_this, NotYetImplementedError.prototype);
667
+ return _this;
668
+ }
669
+ return NotYetImplementedError;
670
+ }(Error));
671
+
672
+ /**
673
+ * @@@
674
+ *
675
+ * Note: `$` is used to indicate that this function is not a pure function - it access global scope
676
+ *
677
+ * @private internal function of `$Register`
678
+ */
679
+ function $getGlobalScope() {
680
+ return Function('return this')();
681
+ }
682
+
683
+ /**
684
+ * @@@
685
+ *
686
+ * @param text @@@
687
+ * @returns @@@
688
+ * @example 'HELLO_WORLD'
689
+ * @example 'I_LOVE_PROMPTBOOK'
690
+ * @public exported from `@promptbook/utils`
691
+ */
692
+ function normalizeTo_SCREAMING_CASE(text) {
693
+ var e_1, _a;
694
+ var charType;
695
+ var lastCharType = 'OTHER';
696
+ var normalizedName = '';
697
+ try {
698
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
699
+ var char = text_1_1.value;
700
+ var normalizedChar = void 0;
701
+ if (/^[a-z]$/.test(char)) {
702
+ charType = 'LOWERCASE';
703
+ normalizedChar = char.toUpperCase();
704
+ }
705
+ else if (/^[A-Z]$/.test(char)) {
706
+ charType = 'UPPERCASE';
707
+ normalizedChar = char;
708
+ }
709
+ else if (/^[0-9]$/.test(char)) {
710
+ charType = 'NUMBER';
711
+ normalizedChar = char;
712
+ }
713
+ else {
714
+ charType = 'OTHER';
715
+ normalizedChar = '_';
716
+ }
717
+ if (charType !== lastCharType &&
718
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
719
+ !(lastCharType === 'NUMBER') &&
720
+ !(charType === 'NUMBER')) {
721
+ normalizedName += '_';
722
+ }
723
+ normalizedName += normalizedChar;
724
+ lastCharType = charType;
725
+ }
726
+ }
727
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
728
+ finally {
729
+ try {
730
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
731
+ }
732
+ finally { if (e_1) throw e_1.error; }
733
+ }
734
+ normalizedName = normalizedName.replace(/_+/g, '_');
735
+ normalizedName = normalizedName.replace(/_?\/_?/g, '/');
736
+ normalizedName = normalizedName.replace(/^_/, '');
737
+ normalizedName = normalizedName.replace(/_$/, '');
738
+ return normalizedName;
739
+ }
740
+ /**
741
+ * TODO: Tests
742
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
743
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
744
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
745
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
746
+ * TODO: [🌺] Use some intermediate util splitWords
747
+ */
748
+
749
+ /**
750
+ * @@@
751
+ *
752
+ * @param text @@@
753
+ * @returns @@@
754
+ * @example 'hello_world'
755
+ * @example 'i_love_promptbook'
756
+ * @public exported from `@promptbook/utils`
757
+ */
758
+ function normalizeTo_snake_case(text) {
759
+ return normalizeTo_SCREAMING_CASE(text).toLowerCase();
760
+ }
761
+
762
+ /**
763
+ * Register is @@@
764
+ *
765
+ * Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
766
+ *
767
+ * @private internal utility, exported are only signleton instances of this class
768
+ */
769
+ var $Register = /** @class */ (function () {
770
+ function $Register(registerName) {
771
+ this.registerName = registerName;
772
+ var storageName = "_promptbook_".concat(normalizeTo_snake_case(registerName));
773
+ var globalScope = $getGlobalScope();
774
+ if (globalScope[storageName] === undefined) {
775
+ globalScope[storageName] = [];
776
+ }
777
+ else if (!Array.isArray(globalScope[storageName])) {
778
+ throw new UnexpectedError("Expected (global) ".concat(storageName, " to be an array, but got ").concat(typeof globalScope[storageName]));
779
+ }
780
+ this.storage = globalScope[storageName];
781
+ }
782
+ $Register.prototype.list = function () {
783
+ // <- TODO: ReadonlyDeep<Array<TRegistered>>
784
+ return this.storage;
785
+ };
786
+ $Register.prototype.register = function (registered) {
787
+ var packageName = registered.packageName, className = registered.className;
788
+ var existingRegistrationIndex = this.storage.findIndex(function (item) { return item.packageName === packageName && item.className === className; });
789
+ var existingRegistration = this.storage[existingRegistrationIndex];
790
+ if (!existingRegistration) {
791
+ this.storage.push(registered);
792
+ }
793
+ else {
794
+ this.storage[existingRegistrationIndex] = registered;
795
+ }
796
+ return {
797
+ registerName: this.registerName,
798
+ packageName: packageName,
799
+ className: className,
800
+ get isDestroyed() {
801
+ return false;
802
+ },
803
+ destroy: function () {
804
+ throw new NotYetImplementedError("Registration to ".concat(this.registerName, " is permanent in this version of Promptbook"));
805
+ },
806
+ };
807
+ };
808
+ return $Register;
809
+ }());
810
+
811
+ /**
812
+ * @@@
813
+ *
814
+ * Note: `$` is used to indicate that this interacts with the global scope
815
+ * @singleton Only one instance of each register is created per build, but thare can be more @@@
816
+ * @public exported from `@promptbook/core`
817
+ */
818
+ var $scrapersRegister = new $Register('scraper_constructors');
819
+ /**
820
+ * TODO: [®] DRY Register logic
821
+ */
822
+
823
+ /**
824
+ * !!!!!!
825
+ *
826
+ * 1) @@@
827
+ * 2) @@@
828
+ *
829
+ * @public exported from `@promptbook/node`
830
+ */
831
+ function $provideScrapersForNode(tools, options) {
832
+ return __awaiter(this, void 0, void 0, function () {
833
+ var _a, _b, isAutoInstalled, _c, isVerbose, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
834
+ var e_1, _f;
835
+ return __generator(this, function (_g) {
836
+ switch (_g.label) {
837
+ case 0:
838
+ if (!$isRunningInNode()) {
839
+ throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
840
+ }
841
+ _a = options || {}, _b = _a.isAutoInstalled, isAutoInstalled = _b === void 0 ? IS_AUTO_INSTALLED : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? IS_VERBOSE : _c;
842
+ TODO_USE(isAutoInstalled);
843
+ TODO_USE(isVerbose);
844
+ scrapers = [];
845
+ _g.label = 1;
846
+ case 1:
847
+ _g.trys.push([1, 6, 7, 8]);
848
+ _d = __values($scrapersRegister.list()), _e = _d.next();
849
+ _g.label = 2;
850
+ case 2:
851
+ if (!!_e.done) return [3 /*break*/, 5];
852
+ scraperFactory = _e.value;
853
+ return [4 /*yield*/, scraperFactory(tools, options || {})];
854
+ case 3:
855
+ scraper = _g.sent();
856
+ scrapers.push(scraper);
857
+ _g.label = 4;
858
+ case 4:
859
+ _e = _d.next();
860
+ return [3 /*break*/, 2];
861
+ case 5: return [3 /*break*/, 8];
862
+ case 6:
863
+ e_1_1 = _g.sent();
864
+ e_1 = { error: e_1_1 };
865
+ return [3 /*break*/, 8];
866
+ case 7:
867
+ try {
868
+ if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
869
+ }
870
+ finally { if (e_1) throw e_1.error; }
871
+ return [7 /*endfinally*/];
872
+ case 8: return [2 /*return*/, scrapers];
873
+ }
874
+ });
875
+ });
876
+ }
877
+ /**
878
+ * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
879
+ */
880
+
616
881
  /**
617
882
  * Converts PipelineCollection to serialized JSON
618
883
  *
@@ -2186,22 +2451,6 @@ var LimitReachedError = /** @class */ (function (_super) {
2186
2451
  return LimitReachedError;
2187
2452
  }(Error));
2188
2453
 
2189
- /**
2190
- * This error type indicates that some part of the code is not implemented yet
2191
- *
2192
- * @public exported from `@promptbook/core`
2193
- */
2194
- var NotYetImplementedError = /** @class */ (function (_super) {
2195
- __extends(NotYetImplementedError, _super);
2196
- function NotYetImplementedError(message) {
2197
- var _this = _super.call(this, spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note: This feature is not implemented yet but it will be soon.\n\n If you want speed up the implementation or just read more, look here:\n https://github.com/webgptorg/promptbook\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
2198
- _this.name = 'NotYetImplementedError';
2199
- Object.setPrototypeOf(_this, NotYetImplementedError.prototype);
2200
- return _this;
2201
- }
2202
- return NotYetImplementedError;
2203
- }(Error));
2204
-
2205
2454
  /**
2206
2455
  * Index of all custom errors
2207
2456
  *
@@ -2520,23 +2769,6 @@ function union() {
2520
2769
  return union;
2521
2770
  }
2522
2771
 
2523
- /**
2524
- * Just marks a place of place where should be something implemented
2525
- * No side effects.
2526
- *
2527
- * Note: It can be usefull suppressing eslint errors of unused variables
2528
- *
2529
- * @param value any values
2530
- * @returns void
2531
- * @private within the repository
2532
- */
2533
- function TODO_USE() {
2534
- var value = [];
2535
- for (var _i = 0; _i < arguments.length; _i++) {
2536
- value[_i] = arguments[_i];
2537
- }
2538
- }
2539
-
2540
2772
  /**
2541
2773
  * This error indicates problems parsing the format value
2542
2774
  *
@@ -4706,197 +4938,46 @@ function preparePersona(personaDescription, tools, options) {
4706
4938
  return [4 /*yield*/, preparePersonaExecutor({ availableModelNames: availableModelNames, personaDescription: personaDescription })];
4707
4939
  case 3:
4708
4940
  result = _d.sent();
4709
- assertsExecutionSuccessful(result);
4710
- outputParameters = result.outputParameters;
4711
- modelRequirementsRaw = outputParameters.modelRequirements;
4712
- modelRequirements = JSON.parse(modelRequirementsRaw);
4713
- if (isVerbose) {
4714
- console.info("PERSONA ".concat(personaDescription), modelRequirements);
4715
- }
4716
- modelName = modelRequirements.modelName, systemMessage = modelRequirements.systemMessage, temperature = modelRequirements.temperature;
4717
- return [2 /*return*/, {
4718
- modelVariant: 'CHAT',
4719
- modelName: modelName,
4720
- systemMessage: systemMessage,
4721
- temperature: temperature,
4722
- }];
4723
- }
4724
- });
4725
- });
4726
- }
4727
- /**
4728
- * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4729
- * TODO: [🏢] !! Check validity of `modelName` in pipeline
4730
- * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4731
- * TODO: [🏢] !! Check validity of `temperature` in pipeline
4732
- */
4733
-
4734
- /**
4735
- * This error indicates that the promptbook can not retrieve knowledge from external sources
4736
- *
4737
- * @public exported from `@promptbook/core`
4738
- */
4739
- var KnowledgeScrapeError = /** @class */ (function (_super) {
4740
- __extends(KnowledgeScrapeError, _super);
4741
- function KnowledgeScrapeError(message) {
4742
- var _this = _super.call(this, message) || this;
4743
- _this.name = 'KnowledgeScrapeError';
4744
- Object.setPrototypeOf(_this, KnowledgeScrapeError.prototype);
4745
- return _this;
4746
- }
4747
- return KnowledgeScrapeError;
4748
- }(Error));
4749
-
4750
- /**
4751
- * @@@
4752
- *
4753
- * Note: `$` is used to indicate that this function is not a pure function - it access global scope
4754
- *
4755
- * @private internal function of `$Register`
4756
- */
4757
- function $getGlobalScope() {
4758
- return Function('return this')();
4759
- }
4760
-
4761
- /**
4762
- * @@@
4763
- *
4764
- * @param text @@@
4765
- * @returns @@@
4766
- * @example 'HELLO_WORLD'
4767
- * @example 'I_LOVE_PROMPTBOOK'
4768
- * @public exported from `@promptbook/utils`
4769
- */
4770
- function normalizeTo_SCREAMING_CASE(text) {
4771
- var e_1, _a;
4772
- var charType;
4773
- var lastCharType = 'OTHER';
4774
- var normalizedName = '';
4775
- try {
4776
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
4777
- var char = text_1_1.value;
4778
- var normalizedChar = void 0;
4779
- if (/^[a-z]$/.test(char)) {
4780
- charType = 'LOWERCASE';
4781
- normalizedChar = char.toUpperCase();
4782
- }
4783
- else if (/^[A-Z]$/.test(char)) {
4784
- charType = 'UPPERCASE';
4785
- normalizedChar = char;
4786
- }
4787
- else if (/^[0-9]$/.test(char)) {
4788
- charType = 'NUMBER';
4789
- normalizedChar = char;
4790
- }
4791
- else {
4792
- charType = 'OTHER';
4793
- normalizedChar = '_';
4794
- }
4795
- if (charType !== lastCharType &&
4796
- !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
4797
- !(lastCharType === 'NUMBER') &&
4798
- !(charType === 'NUMBER')) {
4799
- normalizedName += '_';
4800
- }
4801
- normalizedName += normalizedChar;
4802
- lastCharType = charType;
4803
- }
4804
- }
4805
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
4806
- finally {
4807
- try {
4808
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
4809
- }
4810
- finally { if (e_1) throw e_1.error; }
4811
- }
4812
- normalizedName = normalizedName.replace(/_+/g, '_');
4813
- normalizedName = normalizedName.replace(/_?\/_?/g, '/');
4814
- normalizedName = normalizedName.replace(/^_/, '');
4815
- normalizedName = normalizedName.replace(/_$/, '');
4816
- return normalizedName;
4817
- }
4818
- /**
4819
- * TODO: Tests
4820
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
4821
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
4822
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
4823
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
4824
- * TODO: [🌺] Use some intermediate util splitWords
4825
- */
4826
-
4827
- /**
4828
- * @@@
4829
- *
4830
- * @param text @@@
4831
- * @returns @@@
4832
- * @example 'hello_world'
4833
- * @example 'i_love_promptbook'
4834
- * @public exported from `@promptbook/utils`
4835
- */
4836
- function normalizeTo_snake_case(text) {
4837
- return normalizeTo_SCREAMING_CASE(text).toLowerCase();
4941
+ assertsExecutionSuccessful(result);
4942
+ outputParameters = result.outputParameters;
4943
+ modelRequirementsRaw = outputParameters.modelRequirements;
4944
+ modelRequirements = JSON.parse(modelRequirementsRaw);
4945
+ if (isVerbose) {
4946
+ console.info("PERSONA ".concat(personaDescription), modelRequirements);
4947
+ }
4948
+ modelName = modelRequirements.modelName, systemMessage = modelRequirements.systemMessage, temperature = modelRequirements.temperature;
4949
+ return [2 /*return*/, {
4950
+ modelVariant: 'CHAT',
4951
+ modelName: modelName,
4952
+ systemMessage: systemMessage,
4953
+ temperature: temperature,
4954
+ }];
4955
+ }
4956
+ });
4957
+ });
4838
4958
  }
4839
-
4840
4959
  /**
4841
- * Register is @@@
4842
- *
4843
- * Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
4844
- *
4845
- * @private internal utility, exported are only signleton instances of this class
4960
+ * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4961
+ * TODO: [🏢] !! Check validity of `modelName` in pipeline
4962
+ * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4963
+ * TODO: [🏢] !! Check validity of `temperature` in pipeline
4846
4964
  */
4847
- var $Register = /** @class */ (function () {
4848
- function $Register(registerName) {
4849
- this.registerName = registerName;
4850
- var storageName = "_promptbook_".concat(normalizeTo_snake_case(registerName));
4851
- var globalScope = $getGlobalScope();
4852
- if (globalScope[storageName] === undefined) {
4853
- globalScope[storageName] = [];
4854
- }
4855
- else if (!Array.isArray(globalScope[storageName])) {
4856
- throw new UnexpectedError("Expected (global) ".concat(storageName, " to be an array, but got ").concat(typeof globalScope[storageName]));
4857
- }
4858
- this.storage = globalScope[storageName];
4859
- }
4860
- $Register.prototype.list = function () {
4861
- // <- TODO: ReadonlyDeep<Array<TRegistered>>
4862
- return this.storage;
4863
- };
4864
- $Register.prototype.register = function (registered) {
4865
- var packageName = registered.packageName, className = registered.className;
4866
- var existingRegistrationIndex = this.storage.findIndex(function (item) { return item.packageName === packageName && item.className === className; });
4867
- var existingRegistration = this.storage[existingRegistrationIndex];
4868
- if (!existingRegistration) {
4869
- this.storage.push(registered);
4870
- }
4871
- else {
4872
- this.storage[existingRegistrationIndex] = registered;
4873
- }
4874
- return {
4875
- registerName: this.registerName,
4876
- packageName: packageName,
4877
- className: className,
4878
- get isDestroyed() {
4879
- return false;
4880
- },
4881
- destroy: function () {
4882
- throw new NotYetImplementedError("Registration to ".concat(this.registerName, " is permanent in this version of Promptbook"));
4883
- },
4884
- };
4885
- };
4886
- return $Register;
4887
- }());
4888
4965
 
4889
4966
  /**
4890
- * @@@
4967
+ * This error indicates that the promptbook can not retrieve knowledge from external sources
4891
4968
  *
4892
- * Note: `$` is used to indicate that this interacts with the global scope
4893
- * @singleton Only one instance of each register is created per build, but thare can be more @@@
4894
4969
  * @public exported from `@promptbook/core`
4895
4970
  */
4896
- var $scrapersMetadataRegister = new $Register('scrapers_metadata');
4897
- /**
4898
- * TODO: [®] DRY Register logic
4899
- */
4971
+ var KnowledgeScrapeError = /** @class */ (function (_super) {
4972
+ __extends(KnowledgeScrapeError, _super);
4973
+ function KnowledgeScrapeError(message) {
4974
+ var _this = _super.call(this, message) || this;
4975
+ _this.name = 'KnowledgeScrapeError';
4976
+ Object.setPrototypeOf(_this, KnowledgeScrapeError.prototype);
4977
+ return _this;
4978
+ }
4979
+ return KnowledgeScrapeError;
4980
+ }(Error));
4900
4981
 
4901
4982
  /**
4902
4983
  * @@@
@@ -4905,7 +4986,7 @@ var $scrapersMetadataRegister = new $Register('scrapers_metadata');
4905
4986
  * @singleton Only one instance of each register is created per build, but thare can be more @@@
4906
4987
  * @public exported from `@promptbook/core`
4907
4988
  */
4908
- var $scrapersRegister = new $Register('scraper_constructors');
4989
+ var $scrapersMetadataRegister = new $Register('scrapers_metadata');
4909
4990
  /**
4910
4991
  * TODO: [®] DRY Register logic
4911
4992
  */
@@ -8583,87 +8664,6 @@ function $provideLlmToolsFromEnv(options) {
8583
8664
  * TODO: [®] DRY Register logic
8584
8665
  */
8585
8666
 
8586
- /**
8587
- * @@@
8588
- *
8589
- * @public exported from `@promptbook/node`
8590
- */
8591
- function $provideFilesystemForNode(options) {
8592
- if (!$isRunningInNode()) {
8593
- throw new EnvironmentMismatchError('Function `$provideFilesystemForNode` works only in Node.js environment');
8594
- }
8595
- var _a = (options || {}).isVerbose, isVerbose = _a === void 0 ? IS_VERBOSE : _a;
8596
- TODO_USE(isVerbose);
8597
- return {
8598
- stat: stat,
8599
- access: access,
8600
- constants: constants,
8601
- readFile: readFile,
8602
- readdir: readdir,
8603
- };
8604
- }
8605
- /**
8606
- * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
8607
- */
8608
-
8609
- /**
8610
- * !!!!!!
8611
- *
8612
- * 1) @@@
8613
- * 2) @@@
8614
- *
8615
- * @public exported from `@promptbook/node`
8616
- */
8617
- function $provideScrapersForNode(tools, options) {
8618
- return __awaiter(this, void 0, void 0, function () {
8619
- var _a, _b, isAutoInstalled, _c, isVerbose, scrapers, _d, _e, scraperFactory, scraper, e_1_1;
8620
- var e_1, _f;
8621
- return __generator(this, function (_g) {
8622
- switch (_g.label) {
8623
- case 0:
8624
- if (!$isRunningInNode()) {
8625
- throw new EnvironmentMismatchError('Function `$getScrapersForNode` works only in Node.js environment');
8626
- }
8627
- _a = options || {}, _b = _a.isAutoInstalled, isAutoInstalled = _b === void 0 ? IS_AUTO_INSTALLED : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? IS_VERBOSE : _c;
8628
- TODO_USE(isAutoInstalled);
8629
- TODO_USE(isVerbose);
8630
- scrapers = [];
8631
- _g.label = 1;
8632
- case 1:
8633
- _g.trys.push([1, 6, 7, 8]);
8634
- _d = __values($scrapersRegister.list()), _e = _d.next();
8635
- _g.label = 2;
8636
- case 2:
8637
- if (!!_e.done) return [3 /*break*/, 5];
8638
- scraperFactory = _e.value;
8639
- return [4 /*yield*/, scraperFactory(tools, options || {})];
8640
- case 3:
8641
- scraper = _g.sent();
8642
- scrapers.push(scraper);
8643
- _g.label = 4;
8644
- case 4:
8645
- _e = _d.next();
8646
- return [3 /*break*/, 2];
8647
- case 5: return [3 /*break*/, 8];
8648
- case 6:
8649
- e_1_1 = _g.sent();
8650
- e_1 = { error: e_1_1 };
8651
- return [3 /*break*/, 8];
8652
- case 7:
8653
- try {
8654
- if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
8655
- }
8656
- finally { if (e_1) throw e_1.error; }
8657
- return [7 /*endfinally*/];
8658
- case 8: return [2 /*return*/, scrapers];
8659
- }
8660
- });
8661
- });
8662
- }
8663
- /**
8664
- * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
8665
- */
8666
-
8667
8667
  /**
8668
8668
  * Extracts code block from markdown.
8669
8669
  *
@@ -9962,12 +9962,12 @@ function $provideLlmToolsForCli(options) {
9962
9962
  if (!$isRunningInNode()) {
9963
9963
  throw new EnvironmentMismatchError('Function `$provideLlmToolsForTestingAndScriptsAndPlayground` works only in Node.js environment');
9964
9964
  }
9965
- var _a = (options !== null && options !== void 0 ? options : {}).isCacheReloaded, isCacheReloaded = _a === void 0 ? false : _a;
9965
+ var _a = (options !== null && options !== void 0 ? options : {}).isCacheCleaned, isCacheCleaned = _a === void 0 ? false : _a;
9966
9966
  return cacheLlmTools(countTotalUsage(
9967
9967
  // <- Note: for example here we don`t want the [🌯]
9968
9968
  $provideLlmToolsFromEnv()), {
9969
9969
  storage: new FileCacheStorage({ fs: $provideFilesystemForNode() }, { rootFolderPath: join(process.cwd(), EXECUTIONS_CACHE_DIRNAME) }),
9970
- isReloaded: isCacheReloaded,
9970
+ isReloaded: isCacheCleaned,
9971
9971
  });
9972
9972
  }
9973
9973
  /**
@@ -9994,17 +9994,17 @@ function initializeMakeCommand(program) {
9994
9994
  makeCommand.option('-f, --format <format>', spaceTrim$1("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
9995
9995
  makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
9996
9996
  makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
9997
- makeCommand.option('--reload-cache', "Use LLM models even if cached ", false);
9997
+ makeCommand.option('--reload-cache', "Call LLM models even if same prompt with result is in the cache", false);
9998
9998
  makeCommand.option('--verbose', "Is output verbose", false);
9999
9999
  makeCommand.option('-o, --out-file <path>', spaceTrim$1("\n Where to save the builded collection\n\n Note: If you keep it \"".concat(PIPELINE_COLLECTION_BASE_FILENAME, "\" it will be saved in the root of the promptbook directory\n If you set it to a path, it will be saved in that path\n BUT you can use only one format and set correct extension\n ")), PIPELINE_COLLECTION_BASE_FILENAME);
10000
10000
  makeCommand.action(function (path, _a) {
10001
- var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheReloaded = _a.reloadCache, isVerbose = _a.verbose, outFile = _a.outFile;
10001
+ var projectName = _a.projectName, format = _a.format, validation = _a.validation, isCacheCleaned = _a.reloadCache, isVerbose = _a.verbose, outFile = _a.outFile;
10002
10002
  return __awaiter(_this, void 0, void 0, function () {
10003
- var formats, validations, llm, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, collectionJsonItems, saveFile;
10004
- var e_2, _d, e_1, _e;
10003
+ var formats, validations, options, fs, llm, tools, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, collectionJsonItems, saveFile;
10004
+ var _d, e_2, _e, e_1, _f;
10005
10005
  var _this = this;
10006
- return __generator(this, function (_f) {
10007
- switch (_f.label) {
10006
+ return __generator(this, function (_g) {
10007
+ switch (_g.label) {
10008
10008
  case 0:
10009
10009
  formats = (format || '')
10010
10010
  .split(',')
@@ -10018,79 +10018,90 @@ function initializeMakeCommand(program) {
10018
10018
  console.error(colors.red("You can only use one format if you specify --out-file"));
10019
10019
  process.exit(1);
10020
10020
  }
10021
- llm = $provideLlmToolsForCli({
10022
- isCacheReloaded: isCacheReloaded,
10023
- });
10024
- return [4 /*yield*/, createCollectionFromDirectory(path, {
10025
- llm: llm,
10026
- // !!!!!! Provide scrapers
10027
- }, {
10021
+ options = {
10022
+ isVerbose: isVerbose,
10023
+ isCacheCleaned: isCacheCleaned,
10024
+ };
10025
+ fs = $provideFilesystemForNode(options);
10026
+ llm = $provideLlmToolsForCli(options);
10027
+ _d = {
10028
+ llm: llm,
10029
+ fs: fs
10030
+ };
10031
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm }, options)];
10032
+ case 1:
10033
+ tools = (_d.scrapers = _g.sent(),
10034
+ _d.script = [
10035
+ /*new JavascriptExecutionTools(options)*/
10036
+ ],
10037
+ _d);
10038
+ return [4 /*yield*/, createCollectionFromDirectory(path, tools, {
10028
10039
  isVerbose: isVerbose,
10029
10040
  isRecursive: true,
10030
10041
  // <- TODO: [🍖] isCacheReloaded
10031
10042
  })];
10032
- case 1:
10033
- collection = _f.sent();
10034
- _f.label = 2;
10035
10043
  case 2:
10036
- _f.trys.push([2, 14, 15, 16]);
10037
- validations_1 = __values(validations), validations_1_1 = validations_1.next();
10038
- _f.label = 3;
10044
+ collection = _g.sent();
10045
+ _g.label = 3;
10039
10046
  case 3:
10040
- if (!!validations_1_1.done) return [3 /*break*/, 13];
10041
- validation_1 = validations_1_1.value;
10042
- _f.label = 4;
10047
+ _g.trys.push([3, 15, 16, 17]);
10048
+ validations_1 = __values(validations), validations_1_1 = validations_1.next();
10049
+ _g.label = 4;
10043
10050
  case 4:
10044
- _f.trys.push([4, 10, 11, 12]);
10051
+ if (!!validations_1_1.done) return [3 /*break*/, 14];
10052
+ validation_1 = validations_1_1.value;
10053
+ _g.label = 5;
10054
+ case 5:
10055
+ _g.trys.push([5, 11, 12, 13]);
10045
10056
  e_1 = void 0;
10046
10057
  return [4 /*yield*/, collection.listPipelines()];
10047
- case 5:
10048
- _b = (__values.apply(void 0, [_f.sent()])), _c = _b.next();
10049
- _f.label = 6;
10050
10058
  case 6:
10051
- if (!!_c.done) return [3 /*break*/, 9];
10059
+ _b = (__values.apply(void 0, [_g.sent()])), _c = _b.next();
10060
+ _g.label = 7;
10061
+ case 7:
10062
+ if (!!_c.done) return [3 /*break*/, 10];
10052
10063
  pipelineUrl = _c.value;
10053
10064
  return [4 /*yield*/, collection.getPipelineByUrl(pipelineUrl)];
10054
- case 7:
10055
- pipeline = _f.sent();
10065
+ case 8:
10066
+ pipeline = _g.sent();
10056
10067
  if (validation_1 === 'logic') {
10057
10068
  validatePipeline(pipeline);
10058
10069
  if (isVerbose) {
10059
10070
  console.info(colors.cyan("Validated logic of ".concat(pipeline.pipelineUrl)));
10060
10071
  }
10061
10072
  }
10062
- _f.label = 8;
10063
- case 8:
10073
+ _g.label = 9;
10074
+ case 9:
10064
10075
  _c = _b.next();
10065
- return [3 /*break*/, 6];
10066
- case 9: return [3 /*break*/, 12];
10067
- case 10:
10068
- e_1_1 = _f.sent();
10069
- e_1 = { error: e_1_1 };
10070
- return [3 /*break*/, 12];
10076
+ return [3 /*break*/, 7];
10077
+ case 10: return [3 /*break*/, 13];
10071
10078
  case 11:
10079
+ e_1_1 = _g.sent();
10080
+ e_1 = { error: e_1_1 };
10081
+ return [3 /*break*/, 13];
10082
+ case 12:
10072
10083
  try {
10073
- if (_c && !_c.done && (_e = _b.return)) _e.call(_b);
10084
+ if (_c && !_c.done && (_f = _b.return)) _f.call(_b);
10074
10085
  }
10075
10086
  finally { if (e_1) throw e_1.error; }
10076
10087
  return [7 /*endfinally*/];
10077
- case 12:
10088
+ case 13:
10078
10089
  validations_1_1 = validations_1.next();
10079
- return [3 /*break*/, 3];
10080
- case 13: return [3 /*break*/, 16];
10081
- case 14:
10082
- e_2_1 = _f.sent();
10083
- e_2 = { error: e_2_1 };
10084
- return [3 /*break*/, 16];
10090
+ return [3 /*break*/, 4];
10091
+ case 14: return [3 /*break*/, 17];
10085
10092
  case 15:
10093
+ e_2_1 = _g.sent();
10094
+ e_2 = { error: e_2_1 };
10095
+ return [3 /*break*/, 17];
10096
+ case 16:
10086
10097
  try {
10087
- if (validations_1_1 && !validations_1_1.done && (_d = validations_1.return)) _d.call(validations_1);
10098
+ if (validations_1_1 && !validations_1_1.done && (_e = validations_1.return)) _e.call(validations_1);
10088
10099
  }
10089
10100
  finally { if (e_2) throw e_2.error; }
10090
10101
  return [7 /*endfinally*/];
10091
- case 16: return [4 /*yield*/, collectionToJson(collection)];
10092
- case 17:
10093
- collectionJson = _f.sent();
10102
+ case 17: return [4 /*yield*/, collectionToJson(collection)];
10103
+ case 18:
10104
+ collectionJson = _g.sent();
10094
10105
  collectionJsonString = stringifyPipelineJson(collectionJson).trim();
10095
10106
  collectionJsonItems = (function () {
10096
10107
  var firstChar = collectionJsonString.charAt(0);
@@ -10126,27 +10137,27 @@ function initializeMakeCommand(program) {
10126
10137
  }
10127
10138
  });
10128
10139
  }); };
10129
- if (!formats.includes('json')) return [3 /*break*/, 19];
10140
+ if (!formats.includes('json')) return [3 /*break*/, 20];
10130
10141
  formats = formats.filter(function (format) { return format !== 'json'; });
10131
10142
  return [4 /*yield*/, saveFile('json', collectionJsonString)];
10132
- case 18:
10133
- _f.sent();
10134
- _f.label = 19;
10135
10143
  case 19:
10136
- if (!(formats.includes('javascript') || formats.includes('js'))) return [3 /*break*/, 21];
10144
+ _g.sent();
10145
+ _g.label = 20;
10146
+ case 20:
10147
+ if (!(formats.includes('javascript') || formats.includes('js'))) return [3 /*break*/, 22];
10137
10148
  formats = formats.filter(function (format) { return format !== 'javascript' && format !== 'js'; });
10138
10149
  return [4 /*yield*/, saveFile('js', spaceTrim$1(function (block) { return "\n // ".concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n\n import { createCollectionFromJson } from '@promptbook/core';\n\n /**\n * Pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @private internal cache for `getPipelineCollection`\n */\n let pipelineCollection = null;\n\n\n /**\n * Get pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n */\n export function getPipelineCollection(){\n if(pipelineCollection===null){\n pipelineCollection = createCollectionFromJson(\n ").concat(block(collectionJsonItems), "\n );\n }\n\n return pipelineCollection;\n }\n "); }))];
10139
- case 20:
10140
- (_f.sent()) + '\n';
10141
- _f.label = 21;
10142
10150
  case 21:
10143
- if (!(formats.includes('typescript') || formats.includes('ts'))) return [3 /*break*/, 23];
10151
+ (_g.sent()) + '\n';
10152
+ _g.label = 22;
10153
+ case 22:
10154
+ if (!(formats.includes('typescript') || formats.includes('ts'))) return [3 /*break*/, 24];
10144
10155
  formats = formats.filter(function (format) { return format !== 'typescript' && format !== 'ts'; });
10145
10156
  return [4 /*yield*/, saveFile('ts', spaceTrim$1(function (block) { return "\n // ".concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n\n import { createCollectionFromJson } from '@promptbook/core';\n import type { PipelineCollection } from '@promptbook/types';\n\n /**\n * Pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @private internal cache for `getPipelineCollection`\n */\n let pipelineCollection: null | PipelineCollection = null;\n\n\n /**\n * Get pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n */\n export function getPipelineCollection(): PipelineCollection{\n if(pipelineCollection===null){\n pipelineCollection = createCollectionFromJson(\n ").concat(block(collectionJsonItems), "\n );\n }\n\n return pipelineCollection;\n }\n "); }) + '\n')];
10146
- case 22:
10147
- _f.sent();
10148
- _f.label = 23;
10149
10157
  case 23:
10158
+ _g.sent();
10159
+ _g.label = 24;
10160
+ case 24:
10150
10161
  if (formats.length > 0) {
10151
10162
  console.warn(colors.yellow("Format ".concat(formats.join(' and '), " is not supported")));
10152
10163
  }
@@ -10408,49 +10419,65 @@ function initializeTestCommand(program) {
10408
10419
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10409
10420
  'Pipelines to test as glob pattern');
10410
10421
  testCommand.option('-i, --ignore <glob>', "Ignore as glob pattern");
10422
+ testCommand.option('--reload-cache', "Call LLM models even if same prompt with result is in the cache ", false);
10411
10423
  testCommand.option('-v, --verbose', "Is output verbose", false);
10412
10424
  testCommand.action(function (filesGlob, _a) {
10413
- var ignore = _a.ignore, isVerbose = _a.verbose;
10425
+ var ignore = _a.ignore, isCacheCleaned = _a.reloadCache, isVerbose = _a.verbose;
10414
10426
  return __awaiter(_this, void 0, void 0, function () {
10415
- var filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, _d, _e, error_1, e_1_1;
10416
- var e_1, _f;
10417
- return __generator(this, function (_g) {
10418
- switch (_g.label) {
10419
- case 0: return [4 /*yield*/, glob(filesGlob, { ignore: ignore })];
10427
+ var options, fs, llm, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
10428
+ var _d, e_1, _e;
10429
+ return __generator(this, function (_f) {
10430
+ switch (_f.label) {
10431
+ case 0:
10432
+ options = {
10433
+ isVerbose: isVerbose,
10434
+ isCacheCleaned: isCacheCleaned,
10435
+ };
10436
+ fs = $provideFilesystemForNode(options);
10437
+ llm = $provideLlmToolsForCli(options);
10438
+ _d = {
10439
+ llm: llm,
10440
+ fs: fs
10441
+ };
10442
+ return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm }, options)];
10420
10443
  case 1:
10421
- filenames = _g.sent();
10422
- _g.label = 2;
10444
+ tools = (_d.scrapers = _f.sent(),
10445
+ _d.script = [
10446
+ /*new JavascriptExecutionTools(options)*/
10447
+ ],
10448
+ _d);
10449
+ return [4 /*yield*/, glob(filesGlob, { ignore: ignore })];
10423
10450
  case 2:
10424
- _g.trys.push([2, 15, 16, 17]);
10425
- filenames_1 = __values(filenames), filenames_1_1 = filenames_1.next();
10426
- _g.label = 3;
10451
+ filenames = _f.sent();
10452
+ _f.label = 3;
10427
10453
  case 3:
10454
+ _f.trys.push([3, 15, 16, 17]);
10455
+ filenames_1 = __values(filenames), filenames_1_1 = filenames_1.next();
10456
+ _f.label = 4;
10457
+ case 4:
10428
10458
  if (!!filenames_1_1.done) return [3 /*break*/, 14];
10429
10459
  filename = filenames_1_1.value;
10430
- _g.label = 4;
10431
- case 4:
10432
- _g.trys.push([4, 12, , 13]);
10460
+ _f.label = 5;
10461
+ case 5:
10462
+ _f.trys.push([5, 12, , 13]);
10433
10463
  pipeline = void 0;
10434
10464
  if (!filename.endsWith('.ptbk.md')) return [3 /*break*/, 8];
10435
10465
  return [4 /*yield*/, readFile(filename, 'utf-8')];
10436
- case 5:
10437
- pipelineMarkdown = (_g.sent());
10438
- _b = pipelineStringToJson;
10439
- _c = [pipelineMarkdown];
10440
- return [4 /*yield*/, $provideExecutionToolsForNode()];
10441
- case 6: return [4 /*yield*/, _b.apply(void 0, _c.concat([_g.sent()]))];
10466
+ case 6:
10467
+ pipelineMarkdown = (_f.sent());
10468
+ return [4 /*yield*/, pipelineStringToJson(pipelineMarkdown, tools)];
10442
10469
  case 7:
10443
- pipeline = _g.sent();
10470
+ pipeline = _f.sent();
10444
10471
  if (isVerbose) {
10445
10472
  console.info(colors.green("Parsed ".concat(filename)));
10446
10473
  }
10447
- _g.label = 8;
10474
+ _f.label = 8;
10448
10475
  case 8:
10449
10476
  if (!filename.endsWith('.ptbk.json')) return [3 /*break*/, 10];
10450
- _e = (_d = JSON).parse;
10477
+ _c = (_b = JSON).parse;
10451
10478
  return [4 /*yield*/, readFile(filename, 'utf-8')];
10452
10479
  case 9:
10453
- pipeline = _e.apply(_d, [_g.sent()]);
10480
+ pipeline = _c.apply(_b, [_f.sent()]);
10454
10481
  return [3 /*break*/, 11];
10455
10482
  case 10:
10456
10483
  if (isVerbose) {
@@ -10462,7 +10489,7 @@ function initializeTestCommand(program) {
10462
10489
  console.info(colors.green("Validated ".concat(filename)));
10463
10490
  return [3 /*break*/, 13];
10464
10491
  case 12:
10465
- error_1 = _g.sent();
10492
+ error_1 = _f.sent();
10466
10493
  if (!(error_1 instanceof Error)) {
10467
10494
  throw error_1;
10468
10495
  }
@@ -10473,15 +10500,15 @@ function initializeTestCommand(program) {
10473
10500
  return [3 /*break*/, 13];
10474
10501
  case 13:
10475
10502
  filenames_1_1 = filenames_1.next();
10476
- return [3 /*break*/, 3];
10503
+ return [3 /*break*/, 4];
10477
10504
  case 14: return [3 /*break*/, 17];
10478
10505
  case 15:
10479
- e_1_1 = _g.sent();
10506
+ e_1_1 = _f.sent();
10480
10507
  e_1 = { error: e_1_1 };
10481
10508
  return [3 /*break*/, 17];
10482
10509
  case 16:
10483
10510
  try {
10484
- if (filenames_1_1 && !filenames_1_1.done && (_f = filenames_1.return)) _f.call(filenames_1);
10511
+ if (filenames_1_1 && !filenames_1_1.done && (_e = filenames_1.return)) _e.call(filenames_1);
10485
10512
  }
10486
10513
  finally { if (e_1) throw e_1.error; }
10487
10514
  return [7 /*endfinally*/];