@promptbook/cli 0.81.0-21 → 0.81.0-23

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 -20
  2. package/esm/index.es.js +688 -616
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/core.index.d.ts +2 -0
  5. package/esm/typings/src/_packages/types.index.d.ts +2 -0
  6. package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
  7. package/esm/typings/src/cli/cli-commands/run.d.ts +2 -2
  8. package/esm/typings/src/collection/constructors/createCollectionFromDirectory.d.ts +11 -0
  9. package/esm/typings/src/collection/constructors/createCollectionFromUrl.d.ts +1 -1
  10. package/esm/typings/src/commands/index.d.ts +1 -1
  11. package/esm/typings/src/config.d.ts +2 -2
  12. package/esm/typings/src/conversion/parsePipeline.d.ts +1 -1
  13. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -3
  14. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +7 -7
  15. package/esm/typings/src/errors/utils/getErrorReportUrl.d.ts +1 -1
  16. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  17. package/esm/typings/src/llm-providers/anthropic-claude/createAnthropicClaudeExecutionTools.d.ts +2 -2
  18. package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +2 -2
  19. package/esm/typings/src/llm-providers/openai/playground/playground.d.ts +1 -1
  20. package/esm/typings/src/llm-providers/vercel/playground/playground.d.ts +1 -1
  21. package/esm/typings/src/other/templates/getBookTemplates.d.ts +1 -1
  22. package/esm/typings/src/personas/preparePersona.d.ts +4 -4
  23. package/esm/typings/src/pipeline/PipelineString.d.ts +0 -3
  24. package/esm/typings/src/pipeline/book-notation.d.ts +0 -1
  25. package/esm/typings/src/pipeline/isValidPipelineString.d.ts +3 -1
  26. package/esm/typings/src/pipeline/validatePipelineString.d.ts +14 -0
  27. package/esm/typings/src/prepare/isPipelinePrepared.d.ts +1 -1
  28. package/esm/typings/src/prepare/prepareTasks.d.ts +1 -1
  29. package/esm/typings/src/scripting/javascript/JavascriptEvalExecutionTools.test.d.ts +1 -1
  30. package/esm/typings/src/scripting/javascript/utils/preserve.d.ts +1 -1
  31. package/esm/typings/src/types/typeAliases.d.ts +8 -2
  32. package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +1 -1
  33. package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/umd/index.umd.js +688 -616
  36. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -39,7 +39,7 @@ var BOOK_LANGUAGE_VERSION = '1.0.0';
39
39
  * @generated
40
40
  * @see https://github.com/webgptorg/promptbook
41
41
  */
42
- var PROMPTBOOK_ENGINE_VERSION = '0.81.0-20';
42
+ var PROMPTBOOK_ENGINE_VERSION = '0.81.0-22';
43
43
  /**
44
44
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
45
45
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -520,7 +520,7 @@ function $provideFilesystemForNode(options) {
520
520
  /**
521
521
  * Make error report URL for the given error
522
522
  *
523
- * @private !!!!!!
523
+ * @private private within the repository
524
524
  */
525
525
  function getErrorReportUrl(error) {
526
526
  var report = {
@@ -721,7 +721,7 @@ function checkSerializableAsJson(options) {
721
721
  }
722
722
  /**
723
723
  * TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
724
- * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
724
+ * TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
725
725
  * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
726
726
  */
727
727
 
@@ -874,7 +874,7 @@ function isSerializableAsJson(value) {
874
874
  }
875
875
  }
876
876
  /**
877
- * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
877
+ * TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
878
878
  * TODO: [🧠][💺] Can be done this on type-level?
879
879
  */
880
880
 
@@ -1639,7 +1639,7 @@ function cacheLlmTools(llmTools, options) {
1639
1639
  return [3 /*break*/, 11];
1640
1640
  case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
1641
1641
  case 11:
1642
- // TODO: [🧠] !!!!! How to do timing in mixed cache / non-cache situation
1642
+ // TODO: [🧠] !!5 How to do timing in mixed cache / non-cache situation
1643
1643
  // promptResult.timing: FromtoItems
1644
1644
  return [4 /*yield*/, storage.setItem(key, {
1645
1645
  date: $getCurrentDate(),
@@ -1648,7 +1648,7 @@ function cacheLlmTools(llmTools, options) {
1648
1648
  promptResult: promptResult,
1649
1649
  })];
1650
1650
  case 12:
1651
- // TODO: [🧠] !!!!! How to do timing in mixed cache / non-cache situation
1651
+ // TODO: [🧠] !!5 How to do timing in mixed cache / non-cache situation
1652
1652
  // promptResult.timing: FromtoItems
1653
1653
  _c.sent();
1654
1654
  return [2 /*return*/, promptResult];
@@ -2785,139 +2785,25 @@ function collectionToJson(collection) {
2785
2785
  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:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou 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}\n```\n\n`-> {knowledgePieces}`\n"}],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:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou 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}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book.md"},{title:"Prepare Knowledge-piece 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 - Write maximum ideally 2 words, maximum 5 words\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:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book.md`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou 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 - Write maximum ideally 2 words, maximum 5 words\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book.md"},{title:"Prepare Persona",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:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book.md`\n- INPUT PARAMETER `{availableModelNames}` List of available model names separated by comma (,)\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou 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}\n```\n\n`-> {modelRequirements}`\n"}],sourceFile:"./books/prepare-persona.book.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book.md",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the task:\n\n> {book}\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Title starts with emoticon",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book.md`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the task:\n\n> {book}\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Title starts with emoticon\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book.md"}];
2786
2786
 
2787
2787
  /**
2788
- * This error indicates problems parsing the format value
2789
- *
2790
- * For example, when the format value is not a valid JSON or CSV
2791
- * This is not thrown directly but in extended classes
2792
- *
2793
- * @public exported from `@promptbook/core`
2794
- */
2795
- var AbstractFormatError = /** @class */ (function (_super) {
2796
- __extends(AbstractFormatError, _super);
2797
- // Note: To allow instanceof do not put here error `name`
2798
- // public readonly name = 'AbstractFormatError';
2799
- function AbstractFormatError(message) {
2800
- var _this = _super.call(this, message) || this;
2801
- Object.setPrototypeOf(_this, AbstractFormatError.prototype);
2802
- return _this;
2803
- }
2804
- return AbstractFormatError;
2805
- }(Error));
2806
-
2807
- /**
2808
- * This error indicates problem with parsing of CSV
2809
- *
2810
- * @public exported from `@promptbook/core`
2811
- */
2812
- var CsvFormatError = /** @class */ (function (_super) {
2813
- __extends(CsvFormatError, _super);
2814
- function CsvFormatError(message) {
2815
- var _this = _super.call(this, message) || this;
2816
- _this.name = 'CsvFormatError';
2817
- Object.setPrototypeOf(_this, CsvFormatError.prototype);
2818
- return _this;
2819
- }
2820
- return CsvFormatError;
2821
- }(AbstractFormatError));
2822
-
2823
- /**
2824
- * This error indicates that the pipeline collection cannot be propperly loaded
2825
- *
2826
- * @public exported from `@promptbook/core`
2827
- */
2828
- var CollectionError = /** @class */ (function (_super) {
2829
- __extends(CollectionError, _super);
2830
- function CollectionError(message) {
2831
- var _this = _super.call(this, message) || this;
2832
- _this.name = 'CollectionError';
2833
- Object.setPrototypeOf(_this, CollectionError.prototype);
2834
- return _this;
2835
- }
2836
- return CollectionError;
2837
- }(Error));
2838
-
2839
- /**
2840
- * This error occurs when some expectation is not met in the execution of the pipeline
2841
- *
2842
- * @public exported from `@promptbook/core`
2843
- * Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
2844
- * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
2845
- * Note: This is a kindof subtype of PipelineExecutionError
2846
- */
2847
- var ExpectError = /** @class */ (function (_super) {
2848
- __extends(ExpectError, _super);
2849
- function ExpectError(message) {
2850
- var _this = _super.call(this, message) || this;
2851
- _this.name = 'ExpectError';
2852
- Object.setPrototypeOf(_this, ExpectError.prototype);
2853
- return _this;
2854
- }
2855
- return ExpectError;
2856
- }(Error));
2857
-
2858
- /**
2859
- * This error indicates that the promptbook can not retrieve knowledge from external sources
2860
- *
2861
- * @public exported from `@promptbook/core`
2862
- */
2863
- var KnowledgeScrapeError = /** @class */ (function (_super) {
2864
- __extends(KnowledgeScrapeError, _super);
2865
- function KnowledgeScrapeError(message) {
2866
- var _this = _super.call(this, message) || this;
2867
- _this.name = 'KnowledgeScrapeError';
2868
- Object.setPrototypeOf(_this, KnowledgeScrapeError.prototype);
2869
- return _this;
2870
- }
2871
- return KnowledgeScrapeError;
2872
- }(Error));
2873
-
2874
- /**
2875
- * This error type indicates that some limit was reached
2876
- *
2877
- * @public exported from `@promptbook/core`
2878
- */
2879
- var LimitReachedError = /** @class */ (function (_super) {
2880
- __extends(LimitReachedError, _super);
2881
- function LimitReachedError(message) {
2882
- var _this = _super.call(this, message) || this;
2883
- _this.name = 'LimitReachedError';
2884
- Object.setPrototypeOf(_this, LimitReachedError.prototype);
2885
- return _this;
2886
- }
2887
- return LimitReachedError;
2888
- }(Error));
2889
-
2890
- /**
2891
- * This error type indicates that some tools are missing for pipeline execution or preparation
2788
+ * Function isValidJsonString will tell you if the string is valid JSON or not
2892
2789
  *
2893
- * @public exported from `@promptbook/core`
2790
+ * @public exported from `@promptbook/utils`
2894
2791
  */
2895
- var MissingToolsError = /** @class */ (function (_super) {
2896
- __extends(MissingToolsError, _super);
2897
- function MissingToolsError(message) {
2898
- var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: You have probbably forgot to provide some tools for pipeline execution or preparation\n\n "); })) || this;
2899
- _this.name = 'MissingToolsError';
2900
- Object.setPrototypeOf(_this, MissingToolsError.prototype);
2901
- return _this;
2792
+ function isValidJsonString(value /* <- [👨‍⚖️] */) {
2793
+ try {
2794
+ JSON.parse(value);
2795
+ return true;
2902
2796
  }
2903
- return MissingToolsError;
2904
- }(Error));
2905
-
2906
- /**
2907
- * This error indicates that promptbook not found in the collection
2908
- *
2909
- * @public exported from `@promptbook/core`
2910
- */
2911
- var NotFoundError = /** @class */ (function (_super) {
2912
- __extends(NotFoundError, _super);
2913
- function NotFoundError(message) {
2914
- var _this = _super.call(this, message) || this;
2915
- _this.name = 'NotFoundError';
2916
- Object.setPrototypeOf(_this, NotFoundError.prototype);
2917
- return _this;
2797
+ catch (error) {
2798
+ if (!(error instanceof Error)) {
2799
+ throw error;
2800
+ }
2801
+ if (error.message.includes('Unexpected token')) {
2802
+ return false;
2803
+ }
2804
+ return false;
2918
2805
  }
2919
- return NotFoundError;
2920
- }(Error));
2806
+ }
2921
2807
 
2922
2808
  /**
2923
2809
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -2939,188 +2825,75 @@ var ParseError = /** @class */ (function (_super) {
2939
2825
  */
2940
2826
 
2941
2827
  /**
2942
- * This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
2828
+ * Function `validatePipelineString` will validate the if the string is a valid pipeline string
2829
+ * It does not check if the string is fully logically correct, but if it is a string that can be a pipeline string or the string looks completely different.
2943
2830
  *
2831
+ * @param {string} pipelineString the candidate for a pipeline string
2832
+ * @returns {PipelineString} the same string as input, but validated as valid
2833
+ * @throws {ParseError} if the string is not a valid pipeline string
2944
2834
  * @public exported from `@promptbook/core`
2945
2835
  */
2946
- var PipelineLogicError = /** @class */ (function (_super) {
2947
- __extends(PipelineLogicError, _super);
2948
- function PipelineLogicError(message) {
2949
- var _this = _super.call(this, message) || this;
2950
- _this.name = 'PipelineLogicError';
2951
- Object.setPrototypeOf(_this, PipelineLogicError.prototype);
2952
- return _this;
2836
+ function validatePipelineString(pipelineString) {
2837
+ if (isValidJsonString(pipelineString)) {
2838
+ throw new ParseError('Expected a book, but got a JSON string');
2953
2839
  }
2954
- return PipelineLogicError;
2955
- }(Error));
2956
-
2840
+ // <- TODO: Implement the validation + add tests when the pipeline logic considered as invalid
2841
+ return pipelineString;
2842
+ }
2957
2843
  /**
2958
- * This error indicates errors in referencing promptbooks between each other
2959
- *
2960
- * @public exported from `@promptbook/core`
2844
+ * TODO: [🧠][🈴] Where is the best location for this file
2961
2845
  */
2962
- var PipelineUrlError = /** @class */ (function (_super) {
2963
- __extends(PipelineUrlError, _super);
2964
- function PipelineUrlError(message) {
2965
- var _this = _super.call(this, message) || this;
2966
- _this.name = 'PipelineUrlError';
2967
- Object.setPrototypeOf(_this, PipelineUrlError.prototype);
2968
- return _this;
2969
- }
2970
- return PipelineUrlError;
2971
- }(Error));
2972
2846
 
2973
2847
  /**
2974
- * Index of all custom errors
2848
+ * Prettify the html code
2975
2849
  *
2976
- * @public exported from `@promptbook/core`
2850
+ * @param content raw html code
2851
+ * @returns formatted html code
2852
+ * @private withing the package because of HUGE size of prettier dependency
2977
2853
  */
2978
- var PROMPTBOOK_ERRORS = {
2979
- AbstractFormatError: AbstractFormatError,
2980
- CsvFormatError: CsvFormatError,
2981
- CollectionError: CollectionError,
2982
- EnvironmentMismatchError: EnvironmentMismatchError,
2983
- ExpectError: ExpectError,
2984
- KnowledgeScrapeError: KnowledgeScrapeError,
2985
- LimitReachedError: LimitReachedError,
2986
- MissingToolsError: MissingToolsError,
2987
- NotFoundError: NotFoundError,
2988
- NotYetImplementedError: NotYetImplementedError,
2989
- ParseError: ParseError,
2990
- PipelineExecutionError: PipelineExecutionError,
2991
- PipelineLogicError: PipelineLogicError,
2992
- PipelineUrlError: PipelineUrlError,
2993
- UnexpectedError: UnexpectedError,
2994
- // TODO: [🪑]> VersionMismatchError,
2995
- };
2854
+ function prettifyMarkdown(content) {
2855
+ try {
2856
+ return format(content, {
2857
+ parser: 'markdown',
2858
+ plugins: [parserHtml],
2859
+ // TODO: DRY - make some import or auto-copy of .prettierrc
2860
+ endOfLine: 'lf',
2861
+ tabWidth: 4,
2862
+ singleQuote: true,
2863
+ trailingComma: 'all',
2864
+ arrowParens: 'always',
2865
+ printWidth: 120,
2866
+ htmlWhitespaceSensitivity: 'ignore',
2867
+ jsxBracketSameLine: false,
2868
+ bracketSpacing: true,
2869
+ });
2870
+ }
2871
+ catch (error) {
2872
+ // TODO: [🟥] Detect browser / node and make it colorfull
2873
+ console.error('There was an error with prettifying the markdown, using the original as the fallback', {
2874
+ error: error,
2875
+ html: content,
2876
+ });
2877
+ return content;
2878
+ }
2879
+ }
2880
+
2996
2881
  /**
2997
- * Index of all javascript errors
2882
+ * Makes first letter of a string uppercase
2998
2883
  *
2999
- * @private for internal usage
2884
+ * @public exported from `@promptbook/utils`
3000
2885
  */
3001
- var COMMON_JAVASCRIPT_ERRORS = {
3002
- Error: Error,
3003
- EvalError: EvalError,
3004
- RangeError: RangeError,
3005
- ReferenceError: ReferenceError,
3006
- SyntaxError: SyntaxError,
3007
- TypeError: TypeError,
3008
- URIError: URIError,
3009
- AggregateError: AggregateError,
3010
- /*
3011
- Note: Not widely supported
3012
- > InternalError,
3013
- > ModuleError,
3014
- > HeapError,
3015
- > WebAssemblyCompileError,
3016
- > WebAssemblyRuntimeError,
3017
- */
3018
- };
2886
+ function capitalize(word) {
2887
+ return word.substring(0, 1).toUpperCase() + word.substring(1);
2888
+ }
2889
+
3019
2890
  /**
3020
- * Index of all errors
2891
+ * Converts promptbook in JSON format to string format
3021
2892
  *
3022
- * @private for internal usage
3023
- */
3024
- var ALL_ERRORS = __assign(__assign({}, PROMPTBOOK_ERRORS), COMMON_JAVASCRIPT_ERRORS);
3025
- /**
3026
- * Note: [💞] Ignore a discrepancy between file name and entity name
3027
- */
3028
-
3029
- /**
3030
- * Deserializes the error object
3031
- *
3032
- * @public exported from `@promptbook/utils`
3033
- */
3034
- function deserializeError(error) {
3035
- var ErrorClass = ALL_ERRORS[error.name];
3036
- if (ErrorClass === undefined) {
3037
- return new Error("".concat(error.name, ": ").concat(error.message));
3038
- }
3039
- return new ErrorClass(error.message);
3040
- }
3041
-
3042
- /**
3043
- * Asserts that the execution of a Promptbook is successful
3044
- *
3045
- * @param executionResult - The partial result of the Promptbook execution
3046
- * @throws {PipelineExecutionError} If the execution is not successful or if multiple errors occurred
3047
- * @public exported from `@promptbook/core`
3048
- */
3049
- function assertsExecutionSuccessful(executionResult) {
3050
- var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors;
3051
- if (isSuccessful === true) {
3052
- return;
3053
- }
3054
- if (errors.length === 0) {
3055
- throw new PipelineExecutionError("Promptbook Execution failed because of unknown reason");
3056
- }
3057
- else if (errors.length === 1) {
3058
- throw deserializeError(errors[0]);
3059
- }
3060
- else {
3061
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Multiple errors occurred during Promptbook execution\n\n ".concat(block(errors
3062
- .map(function (_a, index) {
3063
- var name = _a.name, stack = _a.stack, message = _a.message;
3064
- return spaceTrim$1(function (block) { return "\n ".concat(name, " ").concat(index + 1, ":\n ").concat(block(stack || message), "\n "); });
3065
- })
3066
- .join('\n')), "\n "); }));
3067
- }
3068
- }
3069
- /**
3070
- * TODO: [🐚] This function should be removed OR changed OR be completely rewritten
3071
- * TODO: [🧠] Can this return type be better typed than void
3072
- */
3073
-
3074
- /**
3075
- * Prettify the html code
3076
- *
3077
- * @param content raw html code
3078
- * @returns formatted html code
3079
- * @private withing the package because of HUGE size of prettier dependency
3080
- */
3081
- function prettifyMarkdown(content) {
3082
- try {
3083
- return format(content, {
3084
- parser: 'markdown',
3085
- plugins: [parserHtml],
3086
- // TODO: DRY - make some import or auto-copy of .prettierrc
3087
- endOfLine: 'lf',
3088
- tabWidth: 4,
3089
- singleQuote: true,
3090
- trailingComma: 'all',
3091
- arrowParens: 'always',
3092
- printWidth: 120,
3093
- htmlWhitespaceSensitivity: 'ignore',
3094
- jsxBracketSameLine: false,
3095
- bracketSpacing: true,
3096
- });
3097
- }
3098
- catch (error) {
3099
- // TODO: [🟥] Detect browser / node and make it colorfull
3100
- console.error('There was an error with prettifying the markdown, using the original as the fallback', {
3101
- error: error,
3102
- html: content,
3103
- });
3104
- return content;
3105
- }
3106
- }
3107
-
3108
- /**
3109
- * Makes first letter of a string uppercase
3110
- *
3111
- * @public exported from `@promptbook/utils`
3112
- */
3113
- function capitalize(word) {
3114
- return word.substring(0, 1).toUpperCase() + word.substring(1);
3115
- }
3116
-
3117
- /**
3118
- * Converts promptbook in JSON format to string format
3119
- *
3120
- * @deprecated TODO: [🥍][🧠] Backup original files in `PipelineJson` same as in Promptbook.studio
3121
- * @param pipelineJson Promptbook in JSON format (.book.json)
3122
- * @returns Promptbook in string format (.book.md)
3123
- * @public exported from `@promptbook/core`
2893
+ * @deprecated TODO: [🥍][🧠] Backup original files in `PipelineJson` same as in Promptbook.studio
2894
+ * @param pipelineJson Promptbook in JSON format (.book.json)
2895
+ * @returns Promptbook in string format (.book.md)
2896
+ * @public exported from `@promptbook/core`
3124
2897
  */
3125
2898
  function pipelineJsonToString(pipelineJson) {
3126
2899
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
@@ -3137,7 +2910,7 @@ function pipelineJsonToString(pipelineJson) {
3137
2910
  if (bookVersion !== "undefined") {
3138
2911
  commands.push("BOOK VERSION ".concat(bookVersion));
3139
2912
  }
3140
- // TODO: [main] !!!!! This increases size of the bundle and is probbably not necessary
2913
+ // TODO: [main] !!5 This increases size of the bundle and is probbably not necessary
3141
2914
  pipelineString = prettifyMarkdown(pipelineString);
3142
2915
  try {
3143
2916
  for (var _g = __values(parameters.filter(function (_a) {
@@ -3285,12 +3058,12 @@ function pipelineJsonToString(pipelineJson) {
3285
3058
  pipelineString += '```' + contentLanguage;
3286
3059
  pipelineString += '\n';
3287
3060
  pipelineString += spaceTrim(content);
3288
- // <- TODO: [main] !!! Escape
3061
+ // <- TODO: [main] !!3 Escape
3289
3062
  // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
3290
3063
  pipelineString += '\n';
3291
3064
  pipelineString += '```';
3292
3065
  pipelineString += '\n\n';
3293
- pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use taskParameterJsonToString
3066
+ pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!3 If the parameter here has description, add it and use taskParameterJsonToString
3294
3067
  }
3295
3068
  }
3296
3069
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -3300,7 +3073,7 @@ function pipelineJsonToString(pipelineJson) {
3300
3073
  }
3301
3074
  finally { if (e_3) throw e_3.error; }
3302
3075
  }
3303
- return pipelineString;
3076
+ return validatePipelineString(pipelineString);
3304
3077
  }
3305
3078
  /**
3306
3079
  * @private internal utility of `pipelineJsonToString`
@@ -3321,6 +3094,22 @@ function taskParameterJsonToString(taskParameterJson) {
3321
3094
  * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
3322
3095
  */
3323
3096
 
3097
+ /**
3098
+ * This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
3099
+ *
3100
+ * @public exported from `@promptbook/core`
3101
+ */
3102
+ var PipelineLogicError = /** @class */ (function (_super) {
3103
+ __extends(PipelineLogicError, _super);
3104
+ function PipelineLogicError(message) {
3105
+ var _this = _super.call(this, message) || this;
3106
+ _this.name = 'PipelineLogicError';
3107
+ Object.setPrototypeOf(_this, PipelineLogicError.prototype);
3108
+ return _this;
3109
+ }
3110
+ return PipelineLogicError;
3111
+ }(Error));
3112
+
3324
3113
  /**
3325
3114
  * Tests if given string is valid semantic version
3326
3115
  *
@@ -3359,7 +3148,7 @@ function isValidPromptbookVersion(version) {
3359
3148
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
3360
3149
  return false;
3361
3150
  }
3362
- // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
3151
+ // <- TODO: [main] !!3 Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
3363
3152
  return true;
3364
3153
  }
3365
3154
 
@@ -3460,11 +3249,11 @@ function isValidPipelineUrl(url) {
3460
3249
  */
3461
3250
  function validatePipeline(pipeline) {
3462
3251
  if (IS_PIPELINE_LOGIC_VALIDATED) {
3463
- validatePipelineCore(pipeline);
3252
+ validatePipeline_InnerFunction(pipeline);
3464
3253
  }
3465
3254
  else {
3466
3255
  try {
3467
- validatePipelineCore(pipeline);
3256
+ validatePipeline_InnerFunction(pipeline);
3468
3257
  }
3469
3258
  catch (error) {
3470
3259
  if (!(error instanceof PipelineLogicError)) {
@@ -3478,7 +3267,7 @@ function validatePipeline(pipeline) {
3478
3267
  /**
3479
3268
  * @private internal function for `validatePipeline`
3480
3269
  */
3481
- function validatePipelineCore(pipeline) {
3270
+ function validatePipeline_InnerFunction(pipeline) {
3482
3271
  // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
3483
3272
  var e_1, _a, e_2, _b, e_3, _c;
3484
3273
  var pipelineIdentification = (function () {
@@ -3702,11 +3491,11 @@ function validatePipelineCore(pipeline) {
3702
3491
  _loop_3();
3703
3492
  }
3704
3493
  // Note: Check that formfactor is corresponding to the pipeline interface
3705
- // TODO: !!!!!! Implement this
3494
+ // TODO: !!6 Implement this
3706
3495
  // pipeline.formfactorName
3707
3496
  }
3708
3497
  /**
3709
- * TODO: !! [🧞‍♀️] Do not allow joker + foreach
3498
+ * TODO: [🧞‍♀️] Do not allow joker + foreach
3710
3499
  * TODO: [🧠] Work with promptbookVersion
3711
3500
  * TODO: Use here some json-schema, Zod or something similar and change it to:
3712
3501
  * > /**
@@ -3718,178 +3507,430 @@ function validatePipelineCore(pipeline) {
3718
3507
  * > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
3719
3508
  */
3720
3509
  /**
3721
- * TODO: [🧳][main] !!!! Validate that all examples match expectations
3722
- * TODO: [🧳][🐝][main] !!!! Validate that knowledge is valid (non-void)
3723
- * TODO: [🧳][main] !!!! Validate that persona can be used only with CHAT variant
3724
- * TODO: [🧳][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
3725
- * TODO: [🧳][main] !!!! Validate that reserved parameter is not used as joker
3726
- * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
3727
- * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
3510
+ * TODO: [🧳][main] !!4 Validate that all examples match expectations
3511
+ * TODO: [🧳][🐝][main] !!4 Validate that knowledge is valid (non-void)
3512
+ * TODO: [🧳][main] !!4 Validate that persona can be used only with CHAT variant
3513
+ * TODO: [🧳][main] !!4 Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
3514
+ * TODO: [🧳][main] !!4 Validate that reserved parameter is not used as joker
3515
+ * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
3516
+ * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
3517
+ */
3518
+
3519
+ /**
3520
+ * This error indicates that promptbook not found in the collection
3521
+ *
3522
+ * @public exported from `@promptbook/core`
3523
+ */
3524
+ var NotFoundError = /** @class */ (function (_super) {
3525
+ __extends(NotFoundError, _super);
3526
+ function NotFoundError(message) {
3527
+ var _this = _super.call(this, message) || this;
3528
+ _this.name = 'NotFoundError';
3529
+ Object.setPrototypeOf(_this, NotFoundError.prototype);
3530
+ return _this;
3531
+ }
3532
+ return NotFoundError;
3533
+ }(Error));
3534
+
3535
+ /**
3536
+ * This error indicates errors in referencing promptbooks between each other
3537
+ *
3538
+ * @public exported from `@promptbook/core`
3539
+ */
3540
+ var PipelineUrlError = /** @class */ (function (_super) {
3541
+ __extends(PipelineUrlError, _super);
3542
+ function PipelineUrlError(message) {
3543
+ var _this = _super.call(this, message) || this;
3544
+ _this.name = 'PipelineUrlError';
3545
+ Object.setPrototypeOf(_this, PipelineUrlError.prototype);
3546
+ return _this;
3547
+ }
3548
+ return PipelineUrlError;
3549
+ }(Error));
3550
+
3551
+ /**
3552
+ * Parses the task and returns the list of all parameter names
3553
+ *
3554
+ * @param template the string template with parameters in {curly} braces
3555
+ * @returns the list of parameter names
3556
+ * @public exported from `@promptbook/utils`
3557
+ */
3558
+ function extractParameterNames(template) {
3559
+ var e_1, _a;
3560
+ var matches = template.matchAll(/{\w+}/g);
3561
+ var parameterNames = new Set();
3562
+ try {
3563
+ for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
3564
+ var match = matches_1_1.value;
3565
+ var parameterName = match[0].slice(1, -1);
3566
+ parameterNames.add(parameterName);
3567
+ }
3568
+ }
3569
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3570
+ finally {
3571
+ try {
3572
+ if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
3573
+ }
3574
+ finally { if (e_1) throw e_1.error; }
3575
+ }
3576
+ return parameterNames;
3577
+ }
3578
+
3579
+ /**
3580
+ * Unprepare just strips the preparation data of the pipeline
3581
+ *
3582
+ * @deprecated In future version this function will be removed or deprecated
3583
+ * @public exported from `@promptbook/core`
3584
+ */
3585
+ function unpreparePipeline(pipeline) {
3586
+ var personas = pipeline.personas, knowledgeSources = pipeline.knowledgeSources, tasks = pipeline.tasks;
3587
+ personas = personas.map(function (persona) { return (__assign(__assign({}, persona), { modelRequirements: undefined, preparationIds: undefined })); });
3588
+ knowledgeSources = knowledgeSources.map(function (knowledgeSource) { return (__assign(__assign({}, knowledgeSource), { preparationIds: undefined })); });
3589
+ tasks = tasks.map(function (task) {
3590
+ var dependentParameterNames = task.dependentParameterNames;
3591
+ var parameterNames = extractParameterNames(task.preparedContent || '');
3592
+ dependentParameterNames = dependentParameterNames.filter(function (dependentParameterName) { return !parameterNames.has(dependentParameterName); });
3593
+ var taskUnprepared = __assign(__assign({}, task), { dependentParameterNames: dependentParameterNames });
3594
+ delete taskUnprepared.preparedContent;
3595
+ return taskUnprepared;
3596
+ });
3597
+ return exportJson({
3598
+ name: 'pipelineJson',
3599
+ message: "Result of `unpreparePipeline`",
3600
+ order: ORDER_OF_PIPELINE_JSON,
3601
+ value: __assign(__assign({}, pipeline), { tasks: tasks, knowledgeSources: knowledgeSources, knowledgePieces: [], personas: personas, preparations: [] }),
3602
+ });
3603
+ }
3604
+ /**
3605
+ * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
3606
+ * TODO: Write tests for `preparePipeline`
3607
+ * TODO: [🍙] Make some standard order of json properties
3608
+ */
3609
+
3610
+ /**
3611
+ * Library of pipelines that groups together pipelines for an application.
3612
+ * This implementation is a very thin wrapper around the Array / Map of pipelines.
3613
+ *
3614
+ * @private internal function of `createCollectionFromJson`, use `createCollectionFromJson` instead
3615
+ * @see https://github.com/webgptorg/pipeline#pipeline-collection
3616
+ */
3617
+ var SimplePipelineCollection = /** @class */ (function () {
3618
+ /**
3619
+ * Constructs a pipeline collection from pipelines
3620
+ *
3621
+ * @param pipelines @@@
3622
+ *
3623
+ * Note: During the construction logic of all pipelines are validated
3624
+ * Note: It is not recommended to use this constructor directly, use `createCollectionFromJson` *(or other variant)* instead
3625
+ */
3626
+ function SimplePipelineCollection() {
3627
+ var e_1, _a;
3628
+ var pipelines = [];
3629
+ for (var _i = 0; _i < arguments.length; _i++) {
3630
+ pipelines[_i] = arguments[_i];
3631
+ }
3632
+ this.collection = new Map();
3633
+ try {
3634
+ for (var pipelines_1 = __values(pipelines), pipelines_1_1 = pipelines_1.next(); !pipelines_1_1.done; pipelines_1_1 = pipelines_1.next()) {
3635
+ var pipeline = pipelines_1_1.value;
3636
+ // TODO: [👠] DRY
3637
+ if (pipeline.pipelineUrl === undefined) {
3638
+ throw new PipelineUrlError(spaceTrim$1("\n Pipeline with name \"".concat(pipeline.title, "\" does not have defined URL\n\n File:\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: Pipelines without URLs are called anonymous pipelines\n They can be used as standalone pipelines, but they cannot be referenced by other pipelines\n And also they cannot be used in the pipeline collection\n\n ")));
3639
+ }
3640
+ // Note: [🐨]
3641
+ validatePipeline(pipeline);
3642
+ // TODO: [🦄] DRY
3643
+ // Note: [🦄]
3644
+ if (
3645
+ // TODO: [🐽]
3646
+ this.collection.has(pipeline.pipelineUrl) &&
3647
+ pipelineJsonToString(unpreparePipeline(pipeline)) !==
3648
+ pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
3649
+ var existing = this.collection.get(pipeline.pipelineUrl);
3650
+ throw new PipelineUrlError(spaceTrim$1("\n Pipeline with URL ".concat(pipeline.pipelineUrl, " is already in the collection \uD83C\uDF4E\n\n Conflicting files:\n ").concat(existing.sourceFile || 'Unknown', "\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: You have probably forgotten to run \"ptbk make\" to update the collection\n Note: Pipelines with the same URL are not allowed\n Only exepction is when the pipelines are identical\n\n ")));
3651
+ }
3652
+ // Note: [🧠] Overwrite existing pipeline with the same URL
3653
+ this.collection.set(pipeline.pipelineUrl, pipeline);
3654
+ }
3655
+ }
3656
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3657
+ finally {
3658
+ try {
3659
+ if (pipelines_1_1 && !pipelines_1_1.done && (_a = pipelines_1.return)) _a.call(pipelines_1);
3660
+ }
3661
+ finally { if (e_1) throw e_1.error; }
3662
+ }
3663
+ }
3664
+ /**
3665
+ * Gets all pipelines in the collection
3666
+ */
3667
+ SimplePipelineCollection.prototype.listPipelines = function () {
3668
+ return Array.from(this.collection.keys());
3669
+ };
3670
+ /**
3671
+ * Gets pipeline by its URL
3672
+ *
3673
+ * Note: This is not a direct fetching from the URL, but a lookup in the collection
3674
+ */
3675
+ SimplePipelineCollection.prototype.getPipelineByUrl = function (url) {
3676
+ var _this = this;
3677
+ var pipeline = this.collection.get(url);
3678
+ if (!pipeline) {
3679
+ if (this.listPipelines().length === 0) {
3680
+ throw new NotFoundError(spaceTrim$1("\n Pipeline with url \"".concat(url, "\" not found\n\n No pipelines available\n ")));
3681
+ }
3682
+ throw new NotFoundError(spaceTrim$1(function (block) { return "\n Pipeline with url \"".concat(url, "\" not found\n\n Available pipelines:\n ").concat(block(_this.listPipelines()
3683
+ .map(function (pipelineUrl) { return "- ".concat(pipelineUrl); })
3684
+ .join('\n')), "\n\n "); }));
3685
+ }
3686
+ return pipeline;
3687
+ };
3688
+ /**
3689
+ * Checks whether given prompt was defined in any pipeline in the collection
3690
+ */
3691
+ SimplePipelineCollection.prototype.isResponsibleForPrompt = function (prompt) {
3692
+ return true;
3693
+ };
3694
+ return SimplePipelineCollection;
3695
+ }());
3696
+
3697
+ /**
3698
+ * Creates PipelineCollection from array of PipelineJson or PipelineString
3699
+ *
3700
+ * Note: Functions `collectionToJson` and `createCollectionFromJson` are complementary
3701
+ * Note: Syntax, parsing, and logic consistency checks are performed on all sources during build
3702
+ *
3703
+ * @param promptbookSources
3704
+ * @returns PipelineCollection
3705
+ * @public exported from `@promptbook/core`
3706
+ */
3707
+ function createCollectionFromJson() {
3708
+ var promptbooks = [];
3709
+ for (var _i = 0; _i < arguments.length; _i++) {
3710
+ promptbooks[_i] = arguments[_i];
3711
+ }
3712
+ return new (SimplePipelineCollection.bind.apply(SimplePipelineCollection, __spreadArray([void 0], __read(promptbooks), false)))();
3713
+ }
3714
+
3715
+ /**
3716
+ * This error type indicates that some tools are missing for pipeline execution or preparation
3717
+ *
3718
+ * @public exported from `@promptbook/core`
3719
+ */
3720
+ var MissingToolsError = /** @class */ (function (_super) {
3721
+ __extends(MissingToolsError, _super);
3722
+ function MissingToolsError(message) {
3723
+ var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: You have probbably forgot to provide some tools for pipeline execution or preparation\n\n "); })) || this;
3724
+ _this.name = 'MissingToolsError';
3725
+ Object.setPrototypeOf(_this, MissingToolsError.prototype);
3726
+ return _this;
3727
+ }
3728
+ return MissingToolsError;
3729
+ }(Error));
3730
+
3731
+ /**
3732
+ * This error indicates problems parsing the format value
3733
+ *
3734
+ * For example, when the format value is not a valid JSON or CSV
3735
+ * This is not thrown directly but in extended classes
3736
+ *
3737
+ * @public exported from `@promptbook/core`
3738
+ */
3739
+ var AbstractFormatError = /** @class */ (function (_super) {
3740
+ __extends(AbstractFormatError, _super);
3741
+ // Note: To allow instanceof do not put here error `name`
3742
+ // public readonly name = 'AbstractFormatError';
3743
+ function AbstractFormatError(message) {
3744
+ var _this = _super.call(this, message) || this;
3745
+ Object.setPrototypeOf(_this, AbstractFormatError.prototype);
3746
+ return _this;
3747
+ }
3748
+ return AbstractFormatError;
3749
+ }(Error));
3750
+
3751
+ /**
3752
+ * This error indicates problem with parsing of CSV
3753
+ *
3754
+ * @public exported from `@promptbook/core`
3755
+ */
3756
+ var CsvFormatError = /** @class */ (function (_super) {
3757
+ __extends(CsvFormatError, _super);
3758
+ function CsvFormatError(message) {
3759
+ var _this = _super.call(this, message) || this;
3760
+ _this.name = 'CsvFormatError';
3761
+ Object.setPrototypeOf(_this, CsvFormatError.prototype);
3762
+ return _this;
3763
+ }
3764
+ return CsvFormatError;
3765
+ }(AbstractFormatError));
3766
+
3767
+ /**
3768
+ * This error indicates that the pipeline collection cannot be propperly loaded
3769
+ *
3770
+ * @public exported from `@promptbook/core`
3771
+ */
3772
+ var CollectionError = /** @class */ (function (_super) {
3773
+ __extends(CollectionError, _super);
3774
+ function CollectionError(message) {
3775
+ var _this = _super.call(this, message) || this;
3776
+ _this.name = 'CollectionError';
3777
+ Object.setPrototypeOf(_this, CollectionError.prototype);
3778
+ return _this;
3779
+ }
3780
+ return CollectionError;
3781
+ }(Error));
3782
+
3783
+ /**
3784
+ * This error occurs when some expectation is not met in the execution of the pipeline
3785
+ *
3786
+ * @public exported from `@promptbook/core`
3787
+ * Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
3788
+ * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
3789
+ * Note: This is a kindof subtype of PipelineExecutionError
3790
+ */
3791
+ var ExpectError = /** @class */ (function (_super) {
3792
+ __extends(ExpectError, _super);
3793
+ function ExpectError(message) {
3794
+ var _this = _super.call(this, message) || this;
3795
+ _this.name = 'ExpectError';
3796
+ Object.setPrototypeOf(_this, ExpectError.prototype);
3797
+ return _this;
3798
+ }
3799
+ return ExpectError;
3800
+ }(Error));
3801
+
3802
+ /**
3803
+ * This error indicates that the promptbook can not retrieve knowledge from external sources
3804
+ *
3805
+ * @public exported from `@promptbook/core`
3806
+ */
3807
+ var KnowledgeScrapeError = /** @class */ (function (_super) {
3808
+ __extends(KnowledgeScrapeError, _super);
3809
+ function KnowledgeScrapeError(message) {
3810
+ var _this = _super.call(this, message) || this;
3811
+ _this.name = 'KnowledgeScrapeError';
3812
+ Object.setPrototypeOf(_this, KnowledgeScrapeError.prototype);
3813
+ return _this;
3814
+ }
3815
+ return KnowledgeScrapeError;
3816
+ }(Error));
3817
+
3818
+ /**
3819
+ * This error type indicates that some limit was reached
3820
+ *
3821
+ * @public exported from `@promptbook/core`
3822
+ */
3823
+ var LimitReachedError = /** @class */ (function (_super) {
3824
+ __extends(LimitReachedError, _super);
3825
+ function LimitReachedError(message) {
3826
+ var _this = _super.call(this, message) || this;
3827
+ _this.name = 'LimitReachedError';
3828
+ Object.setPrototypeOf(_this, LimitReachedError.prototype);
3829
+ return _this;
3830
+ }
3831
+ return LimitReachedError;
3832
+ }(Error));
3833
+
3834
+ /**
3835
+ * Index of all custom errors
3836
+ *
3837
+ * @public exported from `@promptbook/core`
3838
+ */
3839
+ var PROMPTBOOK_ERRORS = {
3840
+ AbstractFormatError: AbstractFormatError,
3841
+ CsvFormatError: CsvFormatError,
3842
+ CollectionError: CollectionError,
3843
+ EnvironmentMismatchError: EnvironmentMismatchError,
3844
+ ExpectError: ExpectError,
3845
+ KnowledgeScrapeError: KnowledgeScrapeError,
3846
+ LimitReachedError: LimitReachedError,
3847
+ MissingToolsError: MissingToolsError,
3848
+ NotFoundError: NotFoundError,
3849
+ NotYetImplementedError: NotYetImplementedError,
3850
+ ParseError: ParseError,
3851
+ PipelineExecutionError: PipelineExecutionError,
3852
+ PipelineLogicError: PipelineLogicError,
3853
+ PipelineUrlError: PipelineUrlError,
3854
+ UnexpectedError: UnexpectedError,
3855
+ // TODO: [🪑]> VersionMismatchError,
3856
+ };
3857
+ /**
3858
+ * Index of all javascript errors
3859
+ *
3860
+ * @private for internal usage
3861
+ */
3862
+ var COMMON_JAVASCRIPT_ERRORS = {
3863
+ Error: Error,
3864
+ EvalError: EvalError,
3865
+ RangeError: RangeError,
3866
+ ReferenceError: ReferenceError,
3867
+ SyntaxError: SyntaxError,
3868
+ TypeError: TypeError,
3869
+ URIError: URIError,
3870
+ AggregateError: AggregateError,
3871
+ /*
3872
+ Note: Not widely supported
3873
+ > InternalError,
3874
+ > ModuleError,
3875
+ > HeapError,
3876
+ > WebAssemblyCompileError,
3877
+ > WebAssemblyRuntimeError,
3878
+ */
3879
+ };
3880
+ /**
3881
+ * Index of all errors
3882
+ *
3883
+ * @private for internal usage
3884
+ */
3885
+ var ALL_ERRORS = __assign(__assign({}, PROMPTBOOK_ERRORS), COMMON_JAVASCRIPT_ERRORS);
3886
+ /**
3887
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3728
3888
  */
3729
3889
 
3730
3890
  /**
3731
- * Parses the task and returns the list of all parameter names
3891
+ * Deserializes the error object
3732
3892
  *
3733
- * @param template the string template with parameters in {curly} braces
3734
- * @returns the list of parameter names
3735
3893
  * @public exported from `@promptbook/utils`
3736
3894
  */
3737
- function extractParameterNames(template) {
3738
- var e_1, _a;
3739
- var matches = template.matchAll(/{\w+}/g);
3740
- var parameterNames = new Set();
3741
- try {
3742
- for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
3743
- var match = matches_1_1.value;
3744
- var parameterName = match[0].slice(1, -1);
3745
- parameterNames.add(parameterName);
3746
- }
3747
- }
3748
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3749
- finally {
3750
- try {
3751
- if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
3752
- }
3753
- finally { if (e_1) throw e_1.error; }
3895
+ function deserializeError(error) {
3896
+ var ErrorClass = ALL_ERRORS[error.name];
3897
+ if (ErrorClass === undefined) {
3898
+ return new Error("".concat(error.name, ": ").concat(error.message));
3754
3899
  }
3755
- return parameterNames;
3900
+ return new ErrorClass(error.message);
3756
3901
  }
3757
3902
 
3758
3903
  /**
3759
- * Unprepare just strips the preparation data of the pipeline
3904
+ * Asserts that the execution of a Promptbook is successful
3760
3905
  *
3761
- * @deprecated In future version this function will be removed or deprecated
3906
+ * @param executionResult - The partial result of the Promptbook execution
3907
+ * @throws {PipelineExecutionError} If the execution is not successful or if multiple errors occurred
3762
3908
  * @public exported from `@promptbook/core`
3763
3909
  */
3764
- function unpreparePipeline(pipeline) {
3765
- var personas = pipeline.personas, knowledgeSources = pipeline.knowledgeSources, tasks = pipeline.tasks;
3766
- personas = personas.map(function (persona) { return (__assign(__assign({}, persona), { modelRequirements: undefined, preparationIds: undefined })); });
3767
- knowledgeSources = knowledgeSources.map(function (knowledgeSource) { return (__assign(__assign({}, knowledgeSource), { preparationIds: undefined })); });
3768
- tasks = tasks.map(function (task) {
3769
- var dependentParameterNames = task.dependentParameterNames;
3770
- var parameterNames = extractParameterNames(task.preparedContent || '');
3771
- dependentParameterNames = dependentParameterNames.filter(function (dependentParameterName) { return !parameterNames.has(dependentParameterName); });
3772
- var taskUnprepared = __assign(__assign({}, task), { dependentParameterNames: dependentParameterNames });
3773
- delete taskUnprepared.preparedContent;
3774
- return taskUnprepared;
3775
- });
3776
- return exportJson({
3777
- name: 'pipelineJson',
3778
- message: "Result of `unpreparePipeline`",
3779
- order: ORDER_OF_PIPELINE_JSON,
3780
- value: __assign(__assign({}, pipeline), { tasks: tasks, knowledgeSources: knowledgeSources, knowledgePieces: [], personas: personas, preparations: [] }),
3781
- });
3782
- }
3783
- /**
3784
- * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
3785
- * TODO: Write tests for `preparePipeline`
3786
- * TODO: [🍙] Make some standard order of json properties
3787
- */
3788
-
3789
- /**
3790
- * Library of pipelines that groups together pipelines for an application.
3791
- * This implementation is a very thin wrapper around the Array / Map of pipelines.
3792
- *
3793
- * @private internal function of `createCollectionFromJson`, use `createCollectionFromJson` instead
3794
- * @see https://github.com/webgptorg/pipeline#pipeline-collection
3795
- */
3796
- var SimplePipelineCollection = /** @class */ (function () {
3797
- /**
3798
- * Constructs a pipeline collection from pipelines
3799
- *
3800
- * @param pipelines @@@
3801
- *
3802
- * Note: During the construction logic of all pipelines are validated
3803
- * Note: It is not recommended to use this constructor directly, use `createCollectionFromJson` *(or other variant)* instead
3804
- */
3805
- function SimplePipelineCollection() {
3806
- var e_1, _a;
3807
- var pipelines = [];
3808
- for (var _i = 0; _i < arguments.length; _i++) {
3809
- pipelines[_i] = arguments[_i];
3810
- }
3811
- this.collection = new Map();
3812
- try {
3813
- for (var pipelines_1 = __values(pipelines), pipelines_1_1 = pipelines_1.next(); !pipelines_1_1.done; pipelines_1_1 = pipelines_1.next()) {
3814
- var pipeline = pipelines_1_1.value;
3815
- // TODO: [👠] DRY
3816
- if (pipeline.pipelineUrl === undefined) {
3817
- throw new PipelineUrlError(spaceTrim$1("\n Pipeline with name \"".concat(pipeline.title, "\" does not have defined URL\n\n File:\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: Pipelines without URLs are called anonymous pipelines\n They can be used as standalone pipelines, but they cannot be referenced by other pipelines\n And also they cannot be used in the pipeline collection\n\n ")));
3818
- }
3819
- // Note: [🐨]
3820
- validatePipeline(pipeline);
3821
- // TODO: [🦄] DRY
3822
- // Note: [🦄]
3823
- if (
3824
- // TODO: [🐽]
3825
- this.collection.has(pipeline.pipelineUrl) &&
3826
- pipelineJsonToString(unpreparePipeline(pipeline)) !==
3827
- pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
3828
- var existing = this.collection.get(pipeline.pipelineUrl);
3829
- throw new PipelineUrlError(spaceTrim$1("\n Pipeline with URL \"".concat(pipeline.pipelineUrl, "\" is already in the collection \uD83C\uDF4E\n\n Conflicting files:\n ").concat(existing.sourceFile || 'Unknown', "\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: You have probably forgotten to run \"ptbk make\" to update the collection\n Note: Pipelines with the same URL are not allowed\n Only exepction is when the pipelines are identical\n\n ")));
3830
- }
3831
- // Note: [🧠] Overwrite existing pipeline with the same URL
3832
- this.collection.set(pipeline.pipelineUrl, pipeline);
3833
- }
3834
- }
3835
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3836
- finally {
3837
- try {
3838
- if (pipelines_1_1 && !pipelines_1_1.done && (_a = pipelines_1.return)) _a.call(pipelines_1);
3839
- }
3840
- finally { if (e_1) throw e_1.error; }
3841
- }
3910
+ function assertsExecutionSuccessful(executionResult) {
3911
+ var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors;
3912
+ if (isSuccessful === true) {
3913
+ return;
3842
3914
  }
3843
- /**
3844
- * Gets all pipelines in the collection
3845
- */
3846
- SimplePipelineCollection.prototype.listPipelines = function () {
3847
- return Array.from(this.collection.keys());
3848
- };
3849
- /**
3850
- * Gets pipeline by its URL
3851
- *
3852
- * Note: This is not a direct fetching from the URL, but a lookup in the collection
3853
- */
3854
- SimplePipelineCollection.prototype.getPipelineByUrl = function (url) {
3855
- var _this = this;
3856
- var pipeline = this.collection.get(url);
3857
- if (!pipeline) {
3858
- if (this.listPipelines().length === 0) {
3859
- throw new NotFoundError(spaceTrim$1("\n Pipeline with url \"".concat(url, "\" not found\n\n No pipelines available\n ")));
3860
- }
3861
- throw new NotFoundError(spaceTrim$1(function (block) { return "\n Pipeline with url \"".concat(url, "\" not found\n\n Available pipelines:\n ").concat(block(_this.listPipelines()
3862
- .map(function (pipelineUrl) { return "- ".concat(pipelineUrl); })
3863
- .join('\n')), "\n\n "); }));
3864
- }
3865
- return pipeline;
3866
- };
3867
- /**
3868
- * Checks whether given prompt was defined in any pipeline in the collection
3869
- */
3870
- SimplePipelineCollection.prototype.isResponsibleForPrompt = function (prompt) {
3871
- return true;
3872
- };
3873
- return SimplePipelineCollection;
3874
- }());
3875
-
3876
- /**
3877
- * Creates PipelineCollection from array of PipelineJson or PipelineString
3878
- *
3879
- * Note: Functions `collectionToJson` and `createCollectionFromJson` are complementary
3880
- * Note: Syntax, parsing, and logic consistency checks are performed on all sources during build
3881
- *
3882
- * @param promptbookSources
3883
- * @returns PipelineCollection
3884
- * @public exported from `@promptbook/core`
3885
- */
3886
- function createCollectionFromJson() {
3887
- var promptbooks = [];
3888
- for (var _i = 0; _i < arguments.length; _i++) {
3889
- promptbooks[_i] = arguments[_i];
3915
+ if (errors.length === 0) {
3916
+ throw new PipelineExecutionError("Promptbook Execution failed because of unknown reason");
3917
+ }
3918
+ else if (errors.length === 1) {
3919
+ throw deserializeError(errors[0]);
3920
+ }
3921
+ else {
3922
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Multiple errors occurred during Promptbook execution\n\n ".concat(block(errors
3923
+ .map(function (_a, index) {
3924
+ var name = _a.name, stack = _a.stack, message = _a.message;
3925
+ return spaceTrim$1(function (block) { return "\n ".concat(name, " ").concat(index + 1, ":\n ").concat(block(stack || message), "\n "); });
3926
+ })
3927
+ .join('\n')), "\n "); }));
3890
3928
  }
3891
- return new (SimplePipelineCollection.bind.apply(SimplePipelineCollection, __spreadArray([void 0], __read(promptbooks), false)))();
3892
3929
  }
3930
+ /**
3931
+ * TODO: [🐚] This function should be removed OR changed OR be completely rewritten
3932
+ * TODO: [🧠] Can this return type be better typed than void
3933
+ */
3893
3934
 
3894
3935
  /**
3895
3936
  * Determine if the pipeline is fully prepared
@@ -3919,7 +3960,7 @@ function isPipelinePrepared(pipeline) {
3919
3960
  return true;
3920
3961
  }
3921
3962
  /**
3922
- * TODO: [🔃][main] !! If the pipeline was prepared with different version or different set of models, prepare it once again
3963
+ * TODO: [🔃][main] If the pipeline was prepared with different version or different set of models, prepare it once again
3923
3964
  * TODO: [🐠] Maybe base this on `makeValidator`
3924
3965
  * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
3925
3966
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
@@ -4354,27 +4395,6 @@ var CsvFormatDefinition = {
4354
4395
  * TODO: [🏢] Allow to expect something inside CSV objects and other formats
4355
4396
  */
4356
4397
 
4357
- /**
4358
- * Function isValidJsonString will tell you if the string is valid JSON or not
4359
- *
4360
- * @public exported from `@promptbook/utils`
4361
- */
4362
- function isValidJsonString(value /* <- [👨‍⚖️] */) {
4363
- try {
4364
- JSON.parse(value);
4365
- return true;
4366
- }
4367
- catch (error) {
4368
- if (!(error instanceof Error)) {
4369
- throw error;
4370
- }
4371
- if (error.message.includes('Unexpected token')) {
4372
- return false;
4373
- }
4374
- return false;
4375
- }
4376
- }
4377
-
4378
4398
  /**
4379
4399
  * Definition for JSON format
4380
4400
  *
@@ -4768,6 +4788,8 @@ function templateParameters(template, parameters) {
4768
4788
  throw new PipelineExecutionError("Parameter `{".concat(parameterName, "}` is not defined"));
4769
4789
  }
4770
4790
  parameterValue = valueToString(parameterValue);
4791
+ // Escape curly braces in parameter values to prevent prompt-injection
4792
+ parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
4771
4793
  if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
4772
4794
  parameterValue = parameterValue
4773
4795
  .split('\n')
@@ -5127,7 +5149,7 @@ function executeAttempts(options) {
5127
5149
  promptTitle: task.title,
5128
5150
  promptMessage: templateParameters(task.description || '', parameters),
5129
5151
  defaultValue: templateParameters(preparedContent, parameters),
5130
- // TODO: [🧠] !! Figure out how to define placeholder in .book.md file
5152
+ // TODO: [🧠] Figure out how to define placeholder in .book.md file
5131
5153
  placeholder: undefined,
5132
5154
  priority: priority,
5133
5155
  }))];
@@ -6203,10 +6225,10 @@ function preparePersona(personaDescription, tools, options) {
6203
6225
  });
6204
6226
  }
6205
6227
  /**
6206
- * TODO: [🔃][main] !! If the persona was prepared with different version or different set of models, prepare it once again
6207
- * TODO: [🏢] !! Check validity of `modelName` in pipeline
6208
- * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
6209
- * TODO: [🏢] !! Check validity of `temperature` in pipeline
6228
+ * TODO: [🔃][main] If the persona was prepared with different version or different set of models, prepare it once again
6229
+ * TODO: [🏢] Check validity of `modelName` in pipeline
6230
+ * TODO: [🏢] Check validity of `systemMessage` in pipeline
6231
+ * TODO: [🏢] Check validity of `temperature` in pipeline
6210
6232
  */
6211
6233
 
6212
6234
  /**
@@ -6743,7 +6765,7 @@ function prepareTasks(pipeline, tools, options) {
6743
6765
  * TODO: [😂] Adding knowledge should be convert to async high-level abstractions, simmilar thing with expectations to sync high-level abstractions
6744
6766
  * TODO: [🧠] Add context to each task (if missing)
6745
6767
  * TODO: [🧠] What is better name `prepareTask` or `prepareTaskAndParameters`
6746
- * TODO: [♨][main] !!! Prepare index the examples and maybe tasks
6768
+ * TODO: [♨][main] !!3 Prepare index the examples and maybe tasks
6747
6769
  * TODO: Write tests for `preparePipeline`
6748
6770
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
6749
6771
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
@@ -6806,17 +6828,10 @@ function preparePipeline(pipeline, tools, options) {
6806
6828
  _d.tools = tools,
6807
6829
  _d)]);
6808
6830
  return [4 /*yield*/, prepareTitleExecutor({
6809
- book: sources
6810
- .map(function (_a) {
6831
+ book: sources.map(function (_a) {
6811
6832
  var content = _a.content;
6812
6833
  return content;
6813
- })
6814
- .join('\n\n')
6815
- // TODO: !!!!!!! Parameters in parameters - DO NOT ALLOW, ESCAPE:
6816
- .split('{')
6817
- .join('[')
6818
- .split('}')
6819
- .join(']'),
6834
+ }).join('\n\n'),
6820
6835
  })];
6821
6836
  case 2:
6822
6837
  result = _e.sent();
@@ -6970,7 +6985,7 @@ var knowledgeCommandParser = {
6970
6985
  if (sourceContent === '') {
6971
6986
  throw new ParseError("Source is not defined");
6972
6987
  }
6973
- // TODO: [main] !!!! Following checks should be applied every link in the `sourceContent`
6988
+ // TODO: [main] !!4 Following checks should be applied every link in the `sourceContent`
6974
6989
  if (sourceContent.startsWith('http://')) {
6975
6990
  throw new ParseError("Source is not secure");
6976
6991
  }
@@ -7142,7 +7157,7 @@ var sectionCommandParser = {
7142
7157
  expectResultingParameterName();
7143
7158
  var parameter = $pipelineJson.parameters.find(function (param) { return param.name === $taskJson.resultingParameterName; });
7144
7159
  if (parameter === undefined) {
7145
- // TODO: !!!!!! Change to logic error for higher level abstraction of chatbot to work
7160
+ // TODO: !!6 Change to logic error for higher level abstraction of chatbot to work
7146
7161
  throw new ParseError("Parameter `{".concat($taskJson.resultingParameterName, "}` is not defined so can not define example value of it"));
7147
7162
  }
7148
7163
  parameter.exampleValues = parameter.exampleValues || [];
@@ -7153,7 +7168,7 @@ var sectionCommandParser = {
7153
7168
  if (command.taskType === 'KNOWLEDGE') {
7154
7169
  knowledgeCommandParser.$applyToPipelineJson({
7155
7170
  type: 'KNOWLEDGE',
7156
- sourceContent: $taskJson.content, // <- TODO: [🐝][main] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
7171
+ sourceContent: $taskJson.content, // <- TODO: [🐝][main] !!3 Work with KNOWLEDGE which not referring to the source file or website, but its content itself
7157
7172
  }, $pipelineJson);
7158
7173
  $taskJson.isTask = false;
7159
7174
  return;
@@ -9098,7 +9113,7 @@ var COMMANDS = [
9098
9113
  instrumentCommandParser,
9099
9114
  personaCommandParser,
9100
9115
  foreachCommandParser,
9101
- boilerplateCommandParser, // <- TODO: !! Only in development, remove in production
9116
+ boilerplateCommandParser, // <- TODO: Only in development, remove in production
9102
9117
  // <- Note: [♓️][💩] This is the order of the commands in the pipeline, BUT its not used in parsing and before usage maybe it should be done better
9103
9118
  ];
9104
9119
  /**
@@ -9844,7 +9859,7 @@ function parsePipeline(pipelineString) {
9844
9859
  {
9845
9860
  type: 'BOOK',
9846
9861
  path: null,
9847
- // <- TODO: !!!!!! Pass here path of the file
9862
+ // <- TODO: !!6 Pass here path of the file
9848
9863
  content: pipelineString,
9849
9864
  },
9850
9865
  ],
@@ -9869,10 +9884,11 @@ function parsePipeline(pipelineString) {
9869
9884
  if (!(shebangLine_1 || '').includes('ptbk')) {
9870
9885
  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 "); }));
9871
9886
  }
9872
- pipelineString = restLines.join('\n');
9887
+ pipelineString = validatePipelineString(restLines.join('\n'));
9873
9888
  }
9874
9889
  pipelineString = removeMarkdownComments(pipelineString);
9875
9890
  pipelineString = spaceTrim$1(pipelineString);
9891
+ // <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
9876
9892
  // ==============
9877
9893
  // Note: 1️⃣◽2️⃣ Process flat pipeline
9878
9894
  var isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
@@ -9887,8 +9903,8 @@ function parsePipeline(pipelineString) {
9887
9903
  var pipelineStringLines = pipelineString.split('\n');
9888
9904
  var returnStatement_1 = pipelineStringLines.pop();
9889
9905
  var prompt_1 = spaceTrim$1(pipelineStringLines.join('\n'));
9890
- pipelineString = spaceTrim$1(function (block) { return "\n # ".concat(DEFAULT_BOOK_TITLE, "\n\n ## Prompt\n\n ```\n ").concat(block(prompt_1), "\n ```\n\n ").concat(returnStatement_1, "\n "); });
9891
- // <- TODO: !!!!!! Use book` notation
9906
+ pipelineString = validatePipelineString(spaceTrim$1(function (block) { return "\n # ".concat(DEFAULT_BOOK_TITLE, "\n\n ## Prompt\n\n ```\n ").concat(block(prompt_1), "\n ```\n\n ").concat(returnStatement_1, "\n "); }));
9907
+ // <- TODO: Maybe use book` notation
9892
9908
  // console.log(pipelineString);
9893
9909
  }
9894
9910
  // ==============
@@ -10289,7 +10305,7 @@ function parsePipeline(pipelineString) {
10289
10305
  }
10290
10306
  /**
10291
10307
  * TODO: [🧠] Maybe more things here can be refactored as high-level abstractions
10292
- * TODO: [main] !!!! Warn if used only sync version
10308
+ * TODO: [main] !!4 Warn if used only sync version
10293
10309
  * TODO: [🚞] Report here line/column of error
10294
10310
  * TODO: Use spaceTrim more effectively
10295
10311
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
@@ -10705,7 +10721,7 @@ function renderPromptbookMermaid(pipelineJson, options) {
10705
10721
  var parameter = pipelineJson.parameters.find(function (parameter) { return parameter.name === parameterName; });
10706
10722
  if (!parameter) {
10707
10723
  throw new UnexpectedError("Could not find {".concat(parameterName, "}"));
10708
- // <- TODO: !!!!!! This causes problems when {knowledge} and other reserved parameters are used
10724
+ // <- TODO: !!6 This causes problems when {knowledge} and other reserved parameters are used
10709
10725
  }
10710
10726
  if (parameter.isInput) {
10711
10727
  return 'input';
@@ -10749,9 +10765,9 @@ function renderPromptbookMermaid(pipelineJson, options) {
10749
10765
  return promptbookMermaid;
10750
10766
  }
10751
10767
  /**
10752
- * TODO: [🧠] !! FOREACH in mermaid graph
10753
- * TODO: [🧠] !! Knowledge in mermaid graph
10754
- * TODO: [🧠] !! Personas in mermaid graph
10768
+ * TODO: [🧠] FOREACH in mermaid graph
10769
+ * TODO: [🧠] Knowledge in mermaid graph
10770
+ * TODO: [🧠] Personas in mermaid graph
10755
10771
  * TODO: Maybe use some Mermaid package instead of string templating
10756
10772
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
10757
10773
  */
@@ -11020,7 +11036,7 @@ function preserve(func) {
11020
11036
  }
11021
11037
  /**
11022
11038
  * TODO: Probbably remove in favour of `keepImported`
11023
- * TODO: !! [1] This maybe does memory leak
11039
+ * TODO: [1] This maybe does memory leak
11024
11040
  */
11025
11041
 
11026
11042
  /**
@@ -11454,7 +11470,7 @@ function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
11454
11470
  */
11455
11471
  function createCollectionFromDirectory(path, tools, options) {
11456
11472
  return __awaiter(this, void 0, void 0, function () {
11457
- var madeLibraryFilePath, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashedOnError, collection;
11473
+ var madeLibraryFilePath, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashedOnError, rootUrl, collection;
11458
11474
  var _this = this;
11459
11475
  return __generator(this, function (_f) {
11460
11476
  switch (_f.label) {
@@ -11477,10 +11493,10 @@ function createCollectionFromDirectory(path, tools, options) {
11477
11493
  if (!(_f.sent())) ;
11478
11494
  else {
11479
11495
  colors.green("(In future, not implemented yet) Using your compiled pipeline collection ".concat(madeLibraryFilePath));
11480
- // TODO: !! Implement;
11496
+ // TODO: Implement;
11481
11497
  // TODO: [🌗]
11482
11498
  }
11483
- _a = options || {}, _b = _a.isRecursive, isRecursive = _b === void 0 ? true : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c, _d = _a.isLazyLoaded, isLazyLoaded = _d === void 0 ? false : _d, _e = _a.isCrashedOnError, isCrashedOnError = _e === void 0 ? true : _e;
11499
+ _a = options || {}, _b = _a.isRecursive, isRecursive = _b === void 0 ? true : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c, _d = _a.isLazyLoaded, isLazyLoaded = _d === void 0 ? false : _d, _e = _a.isCrashedOnError, isCrashedOnError = _e === void 0 ? true : _e, rootUrl = _a.rootUrl;
11484
11500
  collection = createCollectionFromPromise(function () { return __awaiter(_this, void 0, void 0, function () {
11485
11501
  var fileNames, collection, _loop_1, fileNames_1, fileNames_1_1, fileName, e_1_1;
11486
11502
  var e_1, _a;
@@ -11506,34 +11522,35 @@ function createCollectionFromDirectory(path, tools, options) {
11506
11522
  });
11507
11523
  collection = new Map();
11508
11524
  _loop_1 = function (fileName) {
11509
- var sourceFile, rootDirname, pipeline, pipelineString, _c, _d, existing, error_1, wrappedErrorMessage;
11510
- return __generator(this, function (_e) {
11511
- switch (_e.label) {
11525
+ var sourceFile, rootDirname, pipeline, pipelineString, _c, _d, _e, pipelineUrl, existing, error_1, wrappedErrorMessage;
11526
+ return __generator(this, function (_f) {
11527
+ switch (_f.label) {
11512
11528
  case 0:
11513
11529
  sourceFile = './' + fileName.split('\\').join('/');
11514
11530
  rootDirname = dirname(sourceFile).split('\\').join('/');
11515
- _e.label = 1;
11531
+ _f.label = 1;
11516
11532
  case 1:
11517
- _e.trys.push([1, 8, , 9]);
11533
+ _f.trys.push([1, 8, , 9]);
11518
11534
  pipeline = null;
11519
11535
  if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
11536
+ _c = validatePipelineString;
11520
11537
  return [4 /*yield*/, readFile(fileName, 'utf-8')];
11521
11538
  case 2:
11522
- pipelineString = (_e.sent());
11539
+ pipelineString = _c.apply(void 0, [_f.sent()]);
11523
11540
  return [4 /*yield*/, compilePipeline(pipelineString, tools, {
11524
11541
  rootDirname: rootDirname,
11525
11542
  })];
11526
11543
  case 3:
11527
- pipeline = _e.sent();
11544
+ pipeline = _f.sent();
11528
11545
  pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
11529
11546
  return [3 /*break*/, 7];
11530
11547
  case 4:
11531
11548
  if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
11532
- _d = (_c = JSON).parse;
11549
+ _e = (_d = JSON).parse;
11533
11550
  return [4 /*yield*/, readFile(fileName, 'utf-8')];
11534
11551
  case 5:
11535
11552
  // TODO: Handle non-valid JSON files
11536
- pipeline = _d.apply(_c, [_e.sent()]);
11553
+ pipeline = _e.apply(_d, [_f.sent()]);
11537
11554
  // TODO: [🌗]
11538
11555
  pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
11539
11556
  return [3 /*break*/, 7];
@@ -11541,10 +11558,24 @@ function createCollectionFromDirectory(path, tools, options) {
11541
11558
  if (isVerbose) {
11542
11559
  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")));
11543
11560
  }
11544
- _e.label = 7;
11561
+ _f.label = 7;
11545
11562
  case 7:
11546
11563
  // ---
11547
11564
  if (pipeline !== null) {
11565
+ if (rootUrl !== undefined) {
11566
+ if (pipeline.pipelineUrl === undefined) {
11567
+ pipelineUrl = rootUrl + '/' + fileName.split('\\').join('/');
11568
+ if (isVerbose) {
11569
+ console.info(colors.yellow("Implicitly set pipeline URL to ".concat(pipelineUrl, " from ").concat(fileName
11570
+ .split('\\')
11571
+ .join('/'))));
11572
+ }
11573
+ pipeline = __assign(__assign({}, pipeline), { pipelineUrl: pipelineUrl });
11574
+ }
11575
+ else if (!pipeline.pipelineUrl.startsWith(rootUrl)) {
11576
+ throw new PipelineUrlError(spaceTrim("\n Pipeline with URL ".concat(pipeline.pipelineUrl, " is not a child of the root URL ").concat(rootUrl, " \uD83C\uDF4F\n\n File:\n ").concat(sourceFile || 'Unknown', "\n\n ")));
11577
+ }
11578
+ }
11548
11579
  // TODO: [👠] DRY
11549
11580
  if (pipeline.pipelineUrl === undefined) {
11550
11581
  if (isVerbose) {
@@ -11576,17 +11607,17 @@ function createCollectionFromDirectory(path, tools, options) {
11576
11607
  }
11577
11608
  else {
11578
11609
  existing = collection.get(pipeline.pipelineUrl);
11579
- throw new PipelineUrlError(spaceTrim("\n Pipeline with URL \"".concat(pipeline.pipelineUrl, "\" is already in the collection \uD83C\uDF4F\n\n Conflicting files:\n ").concat(existing.sourceFile || 'Unknown', "\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: You have probably forgotten to run \"ptbk make\" to update the collection\n Note: Pipelines with the same URL are not allowed\n Only exepction is when the pipelines are identical\n\n ")));
11610
+ throw new PipelineUrlError(spaceTrim("\n Pipeline with URL ".concat(pipeline.pipelineUrl, " is already in the collection \uD83C\uDF4F\n\n Conflicting files:\n ").concat(existing.sourceFile || 'Unknown', "\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: You have probably forgotten to run \"ptbk make\" to update the collection\n Note: Pipelines with the same URL are not allowed\n Only exepction is when the pipelines are identical\n\n ")));
11580
11611
  }
11581
11612
  }
11582
11613
  }
11583
11614
  return [3 /*break*/, 9];
11584
11615
  case 8:
11585
- error_1 = _e.sent();
11616
+ error_1 = _f.sent();
11586
11617
  if (!(error_1 instanceof Error)) {
11587
11618
  throw error_1;
11588
11619
  }
11589
- 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';
11620
+ 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';
11590
11621
  if (isCrashedOnError) {
11591
11622
  throw new CollectionError(wrappedErrorMessage);
11592
11623
  }
@@ -11721,6 +11752,7 @@ function initializeMakeCommand(program) {
11721
11752
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
11722
11753
  'Path to promptbook collection directory', DEFAULT_BOOKS_DIRNAME);
11723
11754
  makeCommand.option('--project-name', "Name of the project for whom collection is", 'Untitled Promptbook project');
11755
+ makeCommand.option('--root-url <url>', "Root URL of all pipelines to make", undefined);
11724
11756
  makeCommand.option('-f, --format <format>', spaceTrim("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
11725
11757
  makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
11726
11758
  makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
@@ -11729,7 +11761,7 @@ function initializeMakeCommand(program) {
11729
11761
  makeCommand.option('-o, --output <path>', spaceTrim("\n Where to save the builded collection\n\n Note: If you keep it \"".concat(DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME, "\" it will be saved in the root of the promptbook directory\n If you set it to a path, it will be saved in that path\n BUT you can use only one format and set correct extension\n ")), DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME);
11730
11762
  makeCommand.option('-fn, --function-name <functionName>', spaceTrim("\n Name of the function to get pipeline collection\n\n Note: This can be used only with \"javascript\" or \"typescript\" format\n\n "), DEFAULT_GET_PIPELINE_COLLECTION_FUNCTION_NAME);
11731
11763
  makeCommand.action(function (path, _a) {
11732
- var projectName = _a.projectName, format = _a.format, functionName = _a.functionName, validation = _a.validation, isCacheReloaded = _a.reload, isVerbose = _a.verbose, output = _a.output;
11764
+ var projectName = _a.projectName, rootUrl = _a.rootUrl, format = _a.format, functionName = _a.functionName, validation = _a.validation, isCacheReloaded = _a.reload, isVerbose = _a.verbose, output = _a.output;
11733
11765
  return __awaiter(_this, void 0, void 0, function () {
11734
11766
  var formats, validations, prepareAndScrapeOptions, fs, llm, executables, tools, collection, pipelinesUrls, validations_1, validations_1_1, validation_1, pipelinesUrls_1, pipelinesUrls_1_1, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, collectionJsonItems, saveFile;
11735
11767
  var _b, e_2, _c, e_1, _d;
@@ -11741,6 +11773,10 @@ function initializeMakeCommand(program) {
11741
11773
  console.error(colors.red("Function name \"".concat(functionName, "\" is not valid javascript name")));
11742
11774
  return [2 /*return*/, process.exit(1)];
11743
11775
  }
11776
+ if (!isValidUrl(rootUrl) /* <- Note: Not using `isValidPipelineUrl` because this is root url not book url */) {
11777
+ console.error(colors.red("Root URL ".concat(rootUrl, " is not valid URL")));
11778
+ return [2 /*return*/, process.exit(1)];
11779
+ }
11744
11780
  formats = (format || '')
11745
11781
  .split(',')
11746
11782
  .map(function (_) { return _.trim(); })
@@ -11777,7 +11813,10 @@ function initializeMakeCommand(program) {
11777
11813
  _b);
11778
11814
  return [4 /*yield*/, createCollectionFromDirectory(path, tools, {
11779
11815
  isVerbose: isVerbose,
11816
+ rootUrl: rootUrl,
11780
11817
  isRecursive: true,
11818
+ isLazyLoaded: false,
11819
+ isCrashedOnError: true,
11781
11820
  // <- TODO: [🍖] Add `intermediateFilesStrategy`
11782
11821
  })];
11783
11822
  case 4:
@@ -11897,7 +11936,7 @@ function initializeMakeCommand(program) {
11897
11936
  case 24:
11898
11937
  if (!(formats.includes('typescript') || formats.includes('ts'))) return [3 /*break*/, 26];
11899
11938
  formats = formats.filter(function (format) { return format !== 'typescript' && format !== 'ts'; });
11900
- return [4 /*yield*/, saveFile('ts', spaceTrim(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 `").concat(functionName, "`\n * @generated\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 * @generated\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n */\n export function ").concat(functionName, "(): PipelineCollection{\n if(pipelineCollection===null){\n\n // TODO: !!!!!! Use book string literal notation\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pipelineCollection = (createCollectionFromJson as (..._: any) => PipelineCollection)(\n ").concat(block(collectionJsonItems), "\n );\n }\n\n return pipelineCollection;\n }\n "); }) + '\n')];
11939
+ return [4 /*yield*/, saveFile('ts', spaceTrim(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 `").concat(functionName, "`\n * @generated\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 * @generated\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n */\n export function ").concat(functionName, "(): PipelineCollection{\n if(pipelineCollection===null){\n\n // TODO: !!6 Use book string literal notation\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pipelineCollection = (createCollectionFromJson as (..._: any) => PipelineCollection)(\n ").concat(block(collectionJsonItems), "\n );\n }\n\n return pipelineCollection;\n }\n "); }) + '\n')];
11901
11940
  case 25:
11902
11941
  _e.sent();
11903
11942
  _e.label = 26;
@@ -11916,7 +11955,7 @@ function initializeMakeCommand(program) {
11916
11955
  });
11917
11956
  }
11918
11957
  /**
11919
- * TODO: [🥃][main] !!! Allow `ptbk make` without configuring any llm tools
11958
+ * TODO: [🥃][main] !!3 Allow `ptbk make` without configuring any llm tools
11920
11959
  * TODO: [0] DRY Javascript and typescript - Maybe make ONLY typescript and for javascript just remove types
11921
11960
  * Note: [💞] Ignore a discrepancy between file name and entity name
11922
11961
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
@@ -11981,6 +12020,7 @@ function prettifyPipelineString(pipelineString, options) {
11981
12020
  case 2:
11982
12021
  if (isPrettifyed) {
11983
12022
  pipelineString = prettifyMarkdown(pipelineString);
12023
+ // <- TODO: [😧] `prettifyMarkdown` should preserve discriminated type *(or at lease `PipelineString`)*
11984
12024
  }
11985
12025
  return [2 /*return*/, pipelineString];
11986
12026
  }
@@ -12009,18 +12049,18 @@ function initializePrettifyCommand(program) {
12009
12049
  prettifyCommand.action(function (filesGlob, _a) {
12010
12050
  var ignore = _a.ignore, isVerbose = _a.verbose;
12011
12051
  return __awaiter(_this, void 0, void 0, function () {
12012
- var filenames, filenames_1, filenames_1_1, filename, pipelineMarkdown, error_1, e_1_1;
12013
- var e_1, _b;
12014
- return __generator(this, function (_c) {
12015
- switch (_c.label) {
12052
+ var filenames, filenames_1, filenames_1_1, filename, pipelineMarkdown, _b, error_1, e_1_1;
12053
+ var e_1, _c;
12054
+ return __generator(this, function (_d) {
12055
+ switch (_d.label) {
12016
12056
  case 0: return [4 /*yield*/, glob(filesGlob, { ignore: ignore })];
12017
12057
  case 1:
12018
- filenames = _c.sent();
12019
- _c.label = 2;
12058
+ filenames = _d.sent();
12059
+ _d.label = 2;
12020
12060
  case 2:
12021
- _c.trys.push([2, 11, 12, 13]);
12061
+ _d.trys.push([2, 11, 12, 13]);
12022
12062
  filenames_1 = __values(filenames), filenames_1_1 = filenames_1.next();
12023
- _c.label = 3;
12063
+ _d.label = 3;
12024
12064
  case 3:
12025
12065
  if (!!filenames_1_1.done) return [3 /*break*/, 10];
12026
12066
  filename = filenames_1_1.value;
@@ -12028,28 +12068,29 @@ function initializePrettifyCommand(program) {
12028
12068
  console.info(colors.gray("Skipping ".concat(filename)));
12029
12069
  return [3 /*break*/, 9];
12030
12070
  }
12071
+ _b = validatePipelineString;
12031
12072
  return [4 /*yield*/, readFile(filename, 'utf-8')];
12032
12073
  case 4:
12033
- pipelineMarkdown = (_c.sent());
12034
- _c.label = 5;
12074
+ pipelineMarkdown = _b.apply(void 0, [_d.sent()]);
12075
+ _d.label = 5;
12035
12076
  case 5:
12036
- _c.trys.push([5, 8, , 9]);
12077
+ _d.trys.push([5, 8, , 9]);
12037
12078
  return [4 /*yield*/, prettifyPipelineString(pipelineMarkdown, {
12038
12079
  isGraphAdded: true,
12039
12080
  isPrettifyed: true,
12040
12081
  // <- [🕌]
12041
12082
  })];
12042
12083
  case 6:
12043
- pipelineMarkdown = _c.sent();
12084
+ pipelineMarkdown = _d.sent();
12044
12085
  return [4 /*yield*/, writeFile(filename, pipelineMarkdown)];
12045
12086
  case 7:
12046
- _c.sent();
12087
+ _d.sent();
12047
12088
  if (isVerbose) {
12048
12089
  console.info(colors.green("Prettify ".concat(filename)));
12049
12090
  }
12050
12091
  return [3 /*break*/, 9];
12051
12092
  case 8:
12052
- error_1 = _c.sent();
12093
+ error_1 = _d.sent();
12053
12094
  if (!(error_1 instanceof Error)) {
12054
12095
  throw error_1;
12055
12096
  }
@@ -12062,12 +12103,12 @@ function initializePrettifyCommand(program) {
12062
12103
  return [3 /*break*/, 3];
12063
12104
  case 10: return [3 /*break*/, 13];
12064
12105
  case 11:
12065
- e_1_1 = _c.sent();
12106
+ e_1_1 = _d.sent();
12066
12107
  e_1 = { error: e_1_1 };
12067
12108
  return [3 /*break*/, 13];
12068
12109
  case 12:
12069
12110
  try {
12070
- if (filenames_1_1 && !filenames_1_1.done && (_b = filenames_1.return)) _b.call(filenames_1);
12111
+ if (filenames_1_1 && !filenames_1_1.done && (_c = filenames_1.return)) _c.call(filenames_1);
12071
12112
  }
12072
12113
  finally { if (e_1) throw e_1.error; }
12073
12114
  return [7 /*endfinally*/];
@@ -12393,6 +12434,30 @@ function executionReportJsonToString(executionReportJson, options) {
12393
12434
  * TODO: [🧠] Should be in generated file GENERATOR_WARNING
12394
12435
  */
12395
12436
 
12437
+ /**
12438
+ * Function `isValidPipelineString` will validate the if the string is a valid pipeline string
12439
+ * It does not check if the string is fully logically correct, but if it is a string that can be a pipeline string or the string looks completely different.
12440
+ *
12441
+ * @param {string} pipelineString the candidate for a pipeline string
12442
+ * @returns {boolean} if the string is a valid pipeline string
12443
+ * @public exported from `@promptbook/core`
12444
+ */
12445
+ function isValidPipelineString(pipelineString) {
12446
+ try {
12447
+ validatePipelineString(pipelineString);
12448
+ return true;
12449
+ }
12450
+ catch (error) {
12451
+ if (!(error instanceof Error)) {
12452
+ throw error;
12453
+ }
12454
+ return false;
12455
+ }
12456
+ }
12457
+ /**
12458
+ * TODO: [🧠][🈴] Where is the best location for this file
12459
+ */
12460
+
12396
12461
  /**
12397
12462
  * @see ./wizzard.ts `getPipeline` method
12398
12463
  *
@@ -12400,11 +12465,11 @@ function executionReportJsonToString(executionReportJson, options) {
12400
12465
  */
12401
12466
  function $getCompiledBook(tools, pipelineSource, options) {
12402
12467
  return __awaiter(this, void 0, void 0, function () {
12403
- var fs, fetch, filePathRaw, filePath, filePathCandidates, filePathCandidates_1, filePathCandidates_1_1, filePathCandidate, pipelineString, pipelineJson, e_1_1, rootDirname, _loop_1, i, state_1, response_1, pipelineString, pipelineJson, pipelineJson;
12404
- var e_1, _a;
12468
+ var fs, fetch, filePathRaw, filePath, filePathCandidates, filePathCandidates_1, filePathCandidates_1_1, filePathCandidate, pipelineString, _a, pipelineJson, e_1_1, rootDirname, _loop_1, i, state_1, response_1, pipelineString, pipelineJson, pipelineJson;
12469
+ var e_1, _b;
12405
12470
  var _this = this;
12406
- return __generator(this, function (_b) {
12407
- switch (_b.label) {
12471
+ return __generator(this, function (_c) {
12472
+ switch (_c.label) {
12408
12473
  case 0:
12409
12474
  fs = tools.fs, fetch = tools.fetch;
12410
12475
  if (!isValidFilePath(pipelineSource)) return [3 /*break*/, 10];
@@ -12412,11 +12477,11 @@ function $getCompiledBook(tools, pipelineSource, options) {
12412
12477
  filePath = null;
12413
12478
  filePathCandidates = [filePathRaw, "".concat(filePathRaw, ".md"), "".concat(filePathRaw, ".book.md"), "".concat(filePathRaw, ".book.md")];
12414
12479
  filePathCandidates = __spreadArray(__spreadArray([], __read(filePathCandidates), false), __read(filePathCandidates.map(function (path) { return path.split('\\').join('/'); })), false);
12415
- _b.label = 1;
12480
+ _c.label = 1;
12416
12481
  case 1:
12417
- _b.trys.push([1, 8, 9, 10]);
12482
+ _c.trys.push([1, 8, 9, 10]);
12418
12483
  filePathCandidates_1 = __values(filePathCandidates), filePathCandidates_1_1 = filePathCandidates_1.next();
12419
- _b.label = 2;
12484
+ _c.label = 2;
12420
12485
  case 2:
12421
12486
  if (!!filePathCandidates_1_1.done) return [3 /*break*/, 7];
12422
12487
  filePathCandidate = filePathCandidates_1_1.value;
@@ -12424,26 +12489,27 @@ function $getCompiledBook(tools, pipelineSource, options) {
12424
12489
  // <- TODO: Also test that among the candidates the file is book not just any file
12425
12490
  ];
12426
12491
  case 3:
12427
- if (!_b.sent()) return [3 /*break*/, 6];
12492
+ if (!_c.sent()) return [3 /*break*/, 6];
12428
12493
  filePath = filePathCandidate;
12494
+ _a = validatePipelineString;
12429
12495
  return [4 /*yield*/, fs.readFile(filePath, 'utf-8')];
12430
12496
  case 4:
12431
- pipelineString = (_b.sent());
12497
+ pipelineString = _a.apply(void 0, [_c.sent()]);
12432
12498
  return [4 /*yield*/, compilePipeline(pipelineString, tools, __assign({ rootDirname: process.cwd() }, options))];
12433
12499
  case 5:
12434
- pipelineJson = _b.sent();
12500
+ pipelineJson = _c.sent();
12435
12501
  return [2 /*return*/, pipelineJson];
12436
12502
  case 6:
12437
12503
  filePathCandidates_1_1 = filePathCandidates_1.next();
12438
12504
  return [3 /*break*/, 2];
12439
12505
  case 7: return [3 /*break*/, 10];
12440
12506
  case 8:
12441
- e_1_1 = _b.sent();
12507
+ e_1_1 = _c.sent();
12442
12508
  e_1 = { error: e_1_1 };
12443
12509
  return [3 /*break*/, 10];
12444
12510
  case 9:
12445
12511
  try {
12446
- if (filePathCandidates_1_1 && !filePathCandidates_1_1.done && (_a = filePathCandidates_1.return)) _a.call(filePathCandidates_1);
12512
+ if (filePathCandidates_1_1 && !filePathCandidates_1_1.done && (_b = filePathCandidates_1.return)) _b.call(filePathCandidates_1);
12447
12513
  }
12448
12514
  finally { if (e_1) throw e_1.error; }
12449
12515
  return [7 /*endfinally*/];
@@ -12452,16 +12518,16 @@ function $getCompiledBook(tools, pipelineSource, options) {
12452
12518
  rootDirname = process.cwd();
12453
12519
  _loop_1 = function (i) {
12454
12520
  var booksDirname, collection_1, pipeline;
12455
- return __generator(this, function (_c) {
12456
- switch (_c.label) {
12521
+ return __generator(this, function (_d) {
12522
+ switch (_d.label) {
12457
12523
  case 0:
12458
12524
  booksDirname = join(rootDirname, DEFAULT_BOOKS_DIRNAME /* <- TODO: [🕝] Make here more candidates */);
12459
12525
  return [4 /*yield*/, isDirectoryExisting(booksDirname, fs)];
12460
12526
  case 1:
12461
- if (!_c.sent()) return [3 /*break*/, 4];
12527
+ if (!_d.sent()) return [3 /*break*/, 4];
12462
12528
  return [4 /*yield*/, createCollectionFromDirectory(booksDirname, tools, __assign({ isRecursive: true, rootDirname: booksDirname }, options))];
12463
12529
  case 2:
12464
- collection_1 = _c.sent();
12530
+ collection_1 = _d.sent();
12465
12531
  return [4 /*yield*/, (function () { return __awaiter(_this, void 0, void 0, function () {
12466
12532
  var error_1;
12467
12533
  return __generator(this, function (_a) {
@@ -12482,12 +12548,12 @@ function $getCompiledBook(tools, pipelineSource, options) {
12482
12548
  });
12483
12549
  }); })()];
12484
12550
  case 3:
12485
- pipeline = _c.sent();
12551
+ pipeline = _d.sent();
12486
12552
  // console.log({ pipeline });
12487
12553
  if (pipeline !== null) {
12488
12554
  return [2 /*return*/, { value: pipeline }];
12489
12555
  }
12490
- _c.label = 4;
12556
+ _d.label = 4;
12491
12557
  case 4:
12492
12558
  if (isRootPath(rootDirname)) {
12493
12559
  return [2 /*return*/, "break-up_to_root"];
@@ -12499,18 +12565,18 @@ function $getCompiledBook(tools, pipelineSource, options) {
12499
12565
  });
12500
12566
  };
12501
12567
  i = 0;
12502
- _b.label = 11;
12568
+ _c.label = 11;
12503
12569
  case 11:
12504
12570
  if (!(i < LOOP_LIMIT)) return [3 /*break*/, 14];
12505
12571
  return [5 /*yield**/, _loop_1(i)];
12506
12572
  case 12:
12507
- state_1 = _b.sent();
12573
+ state_1 = _c.sent();
12508
12574
  if (typeof state_1 === "object")
12509
12575
  return [2 /*return*/, state_1.value];
12510
12576
  switch (state_1) {
12511
12577
  case "break-up_to_root": return [3 /*break*/, 14];
12512
12578
  }
12513
- _b.label = 13;
12579
+ _c.label = 13;
12514
12580
  case 13:
12515
12581
  i++;
12516
12582
  return [3 /*break*/, 11];
@@ -12518,21 +12584,26 @@ function $getCompiledBook(tools, pipelineSource, options) {
12518
12584
  if (!isValidPipelineUrl(pipelineSource)) return [3 /*break*/, 18];
12519
12585
  return [4 /*yield*/, fetch(pipelineSource)];
12520
12586
  case 15:
12521
- response_1 = _b.sent();
12587
+ response_1 = _c.sent();
12522
12588
  if (response_1.status >= 300) {
12523
12589
  throw new NotFoundError(spaceTrim(function (block) { return "\n Book not found on URL:\n ".concat(block(pipelineSource), "\n\n Request failed with status ").concat(block(response_1.status.toString()), " ").concat(block(response_1.statusText), "\n "); }));
12524
12590
  }
12525
12591
  return [4 /*yield*/, response_1.text()];
12526
12592
  case 16:
12527
- pipelineString = _b.sent();
12593
+ pipelineString = _c.sent();
12594
+ // console.log({ pipelineString });
12595
+ if (!isValidPipelineString(pipelineString)) {
12596
+ throw new NotFoundError(spaceTrim(function (block) { return "\n Book not found on URL:\n ".concat(block(pipelineSource), "\n\n Requested URL does not seem to contain a valid book\n "); }));
12597
+ }
12528
12598
  return [4 /*yield*/, compilePipeline(pipelineString, tools, __assign({ rootDirname: null }, options))];
12529
12599
  case 17:
12530
- pipelineJson = _b.sent();
12600
+ pipelineJson = _c.sent();
12531
12601
  return [2 /*return*/, pipelineJson];
12532
12602
  case 18:
12603
+ if (!isValidPipelineString(pipelineSource)) return [3 /*break*/, 20];
12533
12604
  return [4 /*yield*/, compilePipeline(pipelineSource, tools, __assign({ rootDirname: null }, options))];
12534
12605
  case 19:
12535
- pipelineJson = _b.sent();
12606
+ pipelineJson = _c.sent();
12536
12607
  return [2 /*return*/, pipelineJson];
12537
12608
  case 20: /* not else */ throw new NotFoundError(spaceTrim(function (block) { return "\n Book not found:\n ".concat(block(pipelineSource), "\n\n Pipelines can be loaded from:\n 1) As a file ./books/write-cv.book.md\n 2) As a URL https://promptbook.studio/hejny/write-cv.book.md found in ./books folder recursively\n 2) As a URL https://promptbook.studio/hejny/write-cv.book.md fetched from the internet\n 3) As a string\n\n\n "); }));
12538
12609
  }
@@ -12944,9 +13015,9 @@ function initializeRunCommand(program) {
12944
13015
  }); });
12945
13016
  }
12946
13017
  /**
12947
- * TODO: !!!!! Catch and wrap all errors from CLI
13018
+ * TODO: !!5 Catch and wrap all errors from CLI
12948
13019
  * TODO: [🧠] Pass `maxExecutionAttempts`, `csvSettings`
12949
- * TODO: [🥃][main] !!! Allow `ptbk run` without configuring any llm tools
13020
+ * TODO: [🥃][main] !!3 Allow `ptbk run` without configuring any llm tools
12950
13021
  * Note: [💞] Ignore a discrepancy between file name and entity name
12951
13022
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
12952
13023
  * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
@@ -12970,10 +13041,10 @@ function initializeTestCommand(program) {
12970
13041
  testCommand.action(function (filesGlob, _a) {
12971
13042
  var ignore = _a.ignore, isCacheReloaded = _a.reload, isVerbose = _a.verbose;
12972
13043
  return __awaiter(_this, void 0, void 0, function () {
12973
- var prepareAndScrapeOptions, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, error_1, e_1_1;
12974
- var _d, e_1, _e;
12975
- return __generator(this, function (_f) {
12976
- switch (_f.label) {
13044
+ var prepareAndScrapeOptions, fs, llm, executables, tools, filenames, filenames_1, filenames_1_1, filename, pipeline, pipelineMarkdown, _b, _c, _d, error_1, e_1_1;
13045
+ var _e, e_1, _f;
13046
+ return __generator(this, function (_g) {
13047
+ switch (_g.label) {
12977
13048
  case 0:
12978
13049
  prepareAndScrapeOptions = {
12979
13050
  isVerbose: isVerbose,
@@ -12982,53 +13053,54 @@ function initializeTestCommand(program) {
12982
13053
  fs = $provideFilesystemForNode(prepareAndScrapeOptions);
12983
13054
  return [4 /*yield*/, $provideLlmToolsForWizzardOrCli(prepareAndScrapeOptions)];
12984
13055
  case 1:
12985
- llm = _f.sent();
13056
+ llm = _g.sent();
12986
13057
  return [4 /*yield*/, $provideExecutablesForNode(prepareAndScrapeOptions)];
12987
13058
  case 2:
12988
- executables = _f.sent();
12989
- _d = {
13059
+ executables = _g.sent();
13060
+ _e = {
12990
13061
  llm: llm,
12991
13062
  fs: fs
12992
13063
  };
12993
13064
  return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, prepareAndScrapeOptions)];
12994
13065
  case 3:
12995
- tools = (_d.scrapers = _f.sent(),
12996
- _d.script = [
13066
+ tools = (_e.scrapers = _g.sent(),
13067
+ _e.script = [
12997
13068
  /*new JavascriptExecutionTools(options)*/
12998
13069
  ],
12999
- _d);
13070
+ _e);
13000
13071
  return [4 /*yield*/, glob(filesGlob, { ignore: ignore })];
13001
13072
  case 4:
13002
- filenames = _f.sent();
13003
- _f.label = 5;
13073
+ filenames = _g.sent();
13074
+ _g.label = 5;
13004
13075
  case 5:
13005
- _f.trys.push([5, 17, 18, 19]);
13076
+ _g.trys.push([5, 17, 18, 19]);
13006
13077
  filenames_1 = __values(filenames), filenames_1_1 = filenames_1.next();
13007
- _f.label = 6;
13078
+ _g.label = 6;
13008
13079
  case 6:
13009
13080
  if (!!filenames_1_1.done) return [3 /*break*/, 16];
13010
13081
  filename = filenames_1_1.value;
13011
- _f.label = 7;
13082
+ _g.label = 7;
13012
13083
  case 7:
13013
- _f.trys.push([7, 14, , 15]);
13084
+ _g.trys.push([7, 14, , 15]);
13014
13085
  pipeline = void 0;
13015
13086
  if (!filename.endsWith('.book.md')) return [3 /*break*/, 10];
13087
+ _b = validatePipelineString;
13016
13088
  return [4 /*yield*/, readFile(filename, 'utf-8')];
13017
13089
  case 8:
13018
- pipelineMarkdown = (_f.sent());
13090
+ pipelineMarkdown = _b.apply(void 0, [_g.sent()]);
13019
13091
  return [4 /*yield*/, compilePipeline(pipelineMarkdown, tools)];
13020
13092
  case 9:
13021
- pipeline = _f.sent();
13093
+ pipeline = _g.sent();
13022
13094
  if (isVerbose) {
13023
13095
  console.info(colors.green("Parsed ".concat(filename)));
13024
13096
  }
13025
- _f.label = 10;
13097
+ _g.label = 10;
13026
13098
  case 10:
13027
13099
  if (!filename.endsWith('.book.json')) return [3 /*break*/, 12];
13028
- _c = (_b = JSON).parse;
13100
+ _d = (_c = JSON).parse;
13029
13101
  return [4 /*yield*/, readFile(filename, 'utf-8')];
13030
13102
  case 11:
13031
- pipeline = _c.apply(_b, [_f.sent()]);
13103
+ pipeline = _d.apply(_c, [_g.sent()]);
13032
13104
  return [3 /*break*/, 13];
13033
13105
  case 12:
13034
13106
  if (isVerbose) {
@@ -13040,7 +13112,7 @@ function initializeTestCommand(program) {
13040
13112
  console.info(colors.green("Validated ".concat(filename)));
13041
13113
  return [3 /*break*/, 15];
13042
13114
  case 14:
13043
- error_1 = _f.sent();
13115
+ error_1 = _g.sent();
13044
13116
  if (!(error_1 instanceof Error)) {
13045
13117
  throw error_1;
13046
13118
  }
@@ -13053,12 +13125,12 @@ function initializeTestCommand(program) {
13053
13125
  return [3 /*break*/, 6];
13054
13126
  case 16: return [3 /*break*/, 19];
13055
13127
  case 17:
13056
- e_1_1 = _f.sent();
13128
+ e_1_1 = _g.sent();
13057
13129
  e_1 = { error: e_1_1 };
13058
13130
  return [3 /*break*/, 19];
13059
13131
  case 18:
13060
13132
  try {
13061
- if (filenames_1_1 && !filenames_1_1.done && (_e = filenames_1.return)) _e.call(filenames_1);
13133
+ if (filenames_1_1 && !filenames_1_1.done && (_f = filenames_1.return)) _f.call(filenames_1);
13062
13134
  }
13063
13135
  finally { if (e_1) throw e_1.error; }
13064
13136
  return [7 /*endfinally*/];
@@ -13465,12 +13537,12 @@ var ANTHROPIC_CLAUDE_MODELS = exportJson({
13465
13537
  output: computeUsage("$2.40 / 1M tokens"),
13466
13538
  },
13467
13539
  },
13468
- // TODO: [main] !!! Claude 1 and 2 has also completion versions - ask Hoagy
13540
+ // TODO: [main] !!3 Claude 1 and 2 has also completion versions - ask Hoagy
13469
13541
  ],
13470
13542
  });
13471
13543
  /**
13472
13544
  * Note: [🤖] Add models of new variant
13473
- * TODO: [🧠][main] !!! Add embedding models OR Anthropic has only chat+completion models?
13545
+ * TODO: [🧠][main] !!3 Add embedding models OR Anthropic has only chat+completion models?
13474
13546
  * TODO: [🧠] Some mechanism to propagate unsureness
13475
13547
  * TODO: [🧠][👮‍♀️] Put here more info like description, isVision, trainingDateCutoff, languages, strengths ( Top-level performance, intelligence, fluency, and understanding), contextWindow,...
13476
13548
  * TODO: [🎰] Some mechanism to auto-update available models
@@ -13845,8 +13917,8 @@ var createAnthropicClaudeExecutionTools = Object.assign(function (options) {
13845
13917
  className: 'AnthropicClaudeExecutionTools',
13846
13918
  });
13847
13919
  /**
13848
- * TODO: [🧠][main] !!!! Make anonymous this with all LLM providers
13849
- * TODO: [🧠][🧱][main] !!!! Maybe change all `new AnthropicClaudeExecutionTools` -> `createAnthropicClaudeExecutionTools` in manual
13920
+ * TODO: [🧠][main] !!4 Make anonymous this with all LLM providers
13921
+ * TODO: [🧠][🧱][main] !!4 Maybe change all `new AnthropicClaudeExecutionTools` -> `createAnthropicClaudeExecutionTools` in manual
13850
13922
  * TODO: [🧠] Maybe auto-detect usage in browser and determine default value of `isProxied`
13851
13923
  * TODO: [🦺] Is there some way how to put `packageName` and `className` on top and function definition on bottom?
13852
13924
  * TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
@@ -14251,7 +14323,7 @@ var OPENAI_MODELS = exportJson({
14251
14323
  prompt: computeUsage("$5.00 / 1M tokens"),
14252
14324
  output: computeUsage("$15.00 / 1M tokens"),
14253
14325
  },
14254
- //TODO: [main] !!! Add gpt-4o-mini-2024-07-18 and all others to be up to date
14326
+ //TODO: [main] !!3 Add gpt-4o-mini-2024-07-18 and all others to be up to date
14255
14327
  },
14256
14328
  /**/
14257
14329
  /**/
@@ -14401,7 +14473,7 @@ var AzureOpenAiExecutionTools = /** @class */ (function () {
14401
14473
  AzureOpenAiExecutionTools.prototype.listModels = function () {
14402
14474
  return __awaiter(this, void 0, void 0, function () {
14403
14475
  return __generator(this, function (_a) {
14404
- // TODO: [main] !!! Do here some filtering which models are really available as deployment
14476
+ // TODO: [main] !!3 Do here some filtering which models are really available as deployment
14405
14477
  // @see https://management.azure.com/subscriptions/subscriptionId/resourceGroups/resourceGroupName/providers/Microsoft.CognitiveServices/accounts/accountName/deployments?api-version=2023-05-01
14406
14478
  return [2 /*return*/, OPENAI_MODELS.map(function (_a) {
14407
14479
  var modelTitle = _a.modelTitle, modelName = _a.modelName, modelVariant = _a.modelVariant;
@@ -15555,7 +15627,7 @@ var OpenAiAssistantExecutionTools = /** @class */ (function (_super) {
15555
15627
  assistant_id: this.assistantId,
15556
15628
  thread: {
15557
15629
  messages: [
15558
- // TODO: [🗯] !! Allow threads to be passed
15630
+ // TODO: [🗯] Allow threads to be passed
15559
15631
  { role: 'user', content: rawPromptContent },
15560
15632
  ],
15561
15633
  },
@@ -15658,7 +15730,7 @@ var OpenAiAssistantExecutionTools = /** @class */ (function (_super) {
15658
15730
  * @public exported from `@promptbook/openai`
15659
15731
  */
15660
15732
  var createOpenAiAssistantExecutionTools = Object.assign(function (options) {
15661
- // TODO: [🧠][main] !!!! If browser, auto add `dangerouslyAllowBrowser`
15733
+ // TODO: [🧠][main] !!4 If browser, auto add `dangerouslyAllowBrowser`
15662
15734
  if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
15663
15735
  options = __assign(__assign({}, options), { dangerouslyAllowBrowser: true });
15664
15736
  }
@@ -15678,7 +15750,7 @@ var createOpenAiAssistantExecutionTools = Object.assign(function (options) {
15678
15750
  * @public exported from `@promptbook/openai`
15679
15751
  */
15680
15752
  var createOpenAiExecutionTools = Object.assign(function (options) {
15681
- // TODO: [🧠][main] !!!! If browser, auto add `dangerouslyAllowBrowser`
15753
+ // TODO: [🧠][main] !!4 If browser, auto add `dangerouslyAllowBrowser`
15682
15754
  if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
15683
15755
  options = __assign(__assign({}, options), { dangerouslyAllowBrowser: true });
15684
15756
  }
@@ -16057,12 +16129,12 @@ var MarkdownScraper = /** @class */ (function () {
16057
16129
  outputParameters = result.outputParameters;
16058
16130
  knowledgePiecesRaw = outputParameters.knowledgePieces;
16059
16131
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
16060
- // <- TODO: [main] !! Smarter split and filter out empty pieces
16132
+ // <- TODO: [main] Smarter split and filter out empty pieces
16061
16133
  if (isVerbose) {
16062
16134
  console.info('knowledgeTextPieces:', knowledgeTextPieces);
16063
16135
  }
16064
16136
  return [4 /*yield*/, Promise.all(
16065
- // TODO: [🪂] !! Do not send all at once but in chunks
16137
+ // TODO: [🪂] Do not send all at once but in chunks
16066
16138
  knowledgeTextPieces.map(function (knowledgeTextPiece, i) { return __awaiter(_this, void 0, void 0, function () {
16067
16139
  var name, title, knowledgePieceContent, keywords, index, titleResult, _a, titleRaw, keywordsResult, _b, keywordsRaw, embeddingResult, error_1;
16068
16140
  return __generator(this, function (_c) {