@promptbook/core 0.69.0-8 → 0.69.1

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 (74) hide show
  1. package/README.md +4 -1
  2. package/esm/index.es.js +1025 -394
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/promptbook-collection/index.d.ts +0 -3
  5. package/esm/typings/src/_packages/core.index.d.ts +12 -0
  6. package/esm/typings/src/_packages/types.index.d.ts +6 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +4 -4
  8. package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
  9. package/esm/typings/src/collection/constructors/createCollectionFromUrl.d.ts +1 -1
  10. package/esm/typings/src/commands/FOREACH/ForeachCommand.d.ts +1 -1
  11. package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -5
  12. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +1 -2
  13. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  14. package/esm/typings/src/config.d.ts +11 -4
  15. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +1 -1
  16. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -3
  17. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +6 -5
  18. package/esm/typings/src/errors/AbstractFormatError.d.ts +11 -0
  19. package/esm/typings/src/execution/PipelineExecutor.d.ts +1 -0
  20. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +5 -6
  21. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTemplateResult.d.ts +24 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorSettings.d.ts +7 -0
  23. package/esm/typings/src/execution/createPipelineExecutor/00-createPipelineExecutor.d.ts +3 -0
  24. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +4 -1
  25. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +3 -0
  26. package/esm/typings/src/execution/createPipelineExecutor/{30-executeFormatCells.d.ts → 30-executeFormatSubvalues.d.ts} +2 -2
  27. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +2 -8
  28. package/esm/typings/src/execution/embeddingVectorToString.d.ts +1 -1
  29. package/esm/typings/src/execution/utils/checkExpectations.d.ts +2 -0
  30. package/esm/typings/src/execution/utils/usageToHuman.d.ts +3 -4
  31. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +14 -15
  32. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +31 -0
  33. package/esm/typings/src/formats/csv/{ListFormatDefinition.d.ts → CsvFormatDefinition.d.ts} +6 -3
  34. package/esm/typings/src/formats/csv/CsvFormatError.d.ts +10 -0
  35. package/esm/typings/src/formats/csv/CsvSettings.d.ts +13 -0
  36. package/esm/typings/src/formats/index.d.ts +1 -1
  37. package/esm/typings/src/formats/json/JsonFormatDefinition.d.ts +4 -3
  38. package/esm/typings/src/formats/text/TextFormatDefinition.d.ts +19 -0
  39. package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +4 -3
  40. package/esm/typings/src/knowledge/prepare-knowledge/markdown/prepareKnowledgeFromMarkdown.d.ts +1 -1
  41. package/esm/typings/src/knowledge/prepare-knowledge/pdf/prepareKnowledgeFromPdf.d.ts +1 -1
  42. package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +1 -1
  43. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +2 -1
  44. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  45. package/esm/typings/src/llm-providers/anthropic-claude/createAnthropicClaudeExecutionTools.d.ts +2 -2
  46. package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +2 -2
  47. package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +8 -1
  48. package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +2 -1
  49. package/esm/typings/src/llm-providers/openai/playground/playground.d.ts +1 -1
  50. package/esm/typings/src/personas/preparePersona.d.ts +1 -1
  51. package/esm/typings/src/prepare/isPipelinePrepared.d.ts +1 -1
  52. package/esm/typings/src/prepare/prepareTemplates.d.ts +1 -1
  53. package/esm/typings/src/types/PipelineJson/ParameterJson.d.ts +1 -1
  54. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +1 -1
  55. package/esm/typings/src/types/execution-report/ExecutionReportJson.d.ts +0 -3
  56. package/esm/typings/src/types/execution-report/executionReportJsonToString.d.ts +2 -1
  57. package/esm/typings/src/types/typeAliases.d.ts +1 -1
  58. package/esm/typings/src/utils/expectation-counters/index.d.ts +3 -0
  59. package/esm/typings/src/utils/organization/{f.d.ts → empty_object.d.ts} +5 -1
  60. package/esm/typings/src/utils/organization/just_empty_object.d.ts +12 -0
  61. package/esm/typings/src/utils/{extractParameterNames.d.ts → parameters/extractParameterNames.d.ts} +2 -2
  62. package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +27 -0
  63. package/esm/typings/src/utils/{replaceParameters.d.ts → parameters/replaceParameters.d.ts} +2 -2
  64. package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +1 -1
  65. package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +1 -1
  66. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +10 -0
  67. package/package.json +17 -12
  68. package/umd/index.umd.js +1033 -397
  69. package/umd/index.umd.js.map +1 -1
  70. package/esm/typings/src/formats/list/ListFormatDefinition.d.ts +0 -16
  71. /package/esm/typings/src/utils/{extractParameterNames.test.d.ts → parameters/extractParameterNames.test.d.ts} +0 -0
  72. /package/esm/typings/src/{execution/utils/usageToHuman.test.d.ts → utils/parameters/mapAvailableToExpectedParameters.test.d.ts} +0 -0
  73. /package/esm/typings/src/utils/{replaceParameters.test.d.ts → parameters/replaceParameters.test.d.ts} +0 -0
  74. /package/esm/typings/src/{personas/preparePersona.test.d.ts → utils/validators/parameterName/validateParameterName.test.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -2,6 +2,7 @@ import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
2
2
  import { format } from 'prettier';
3
3
  import parserHtml from 'prettier/parser-html';
4
4
  import { forTime } from 'waitasecond';
5
+ import { unparse, parse } from 'papaparse';
5
6
  import hexEncoder from 'crypto-js/enc-hex';
6
7
  import sha256 from 'crypto-js/sha256';
7
8
  import moment from 'moment';
@@ -10,8 +11,8 @@ import moment from 'moment';
10
11
  /**
11
12
  * The version of the Promptbook library
12
13
  */
13
- var PROMPTBOOK_VERSION = '0.69.0-7';
14
- // TODO: !!!! List here all the versions and annotate + put into script
14
+ var PROMPTBOOK_VERSION = '0.69.0';
15
+ // TODO: [main] !!!! List here all the versions and annotate + put into script
15
16
 
16
17
  /*! *****************************************************************************
17
18
  Copyright (c) Microsoft Corporation.
@@ -223,7 +224,7 @@ function pipelineJsonToString(pipelineJson) {
223
224
  commands.push("PIPELINE URL ".concat(pipelineUrl));
224
225
  }
225
226
  commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
226
- // TODO: !!! This increase size of the bundle and is probbably not necessary
227
+ // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
227
228
  pipelineString = prettifyMarkdown(pipelineString);
228
229
  try {
229
230
  for (var _g = __values(parameters.filter(function (_a) {
@@ -371,12 +372,12 @@ function pipelineJsonToString(pipelineJson) {
371
372
  pipelineString += '```' + contentLanguage;
372
373
  pipelineString += '\n';
373
374
  pipelineString += spaceTrim(content);
374
- // <- TODO: !!! Escape
375
+ // <- TODO: [main] !!! Escape
375
376
  // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
376
377
  pipelineString += '\n';
377
378
  pipelineString += '```';
378
379
  pipelineString += '\n\n';
379
- pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: !!! If the parameter here has description, add it and use templateParameterJsonToString
380
+ pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use templateParameterJsonToString
380
381
  }
381
382
  }
382
383
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -596,7 +597,7 @@ function checkSerializableAsJson(name, value) {
596
597
  }
597
598
  /**
598
599
  * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
599
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
600
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
600
601
  * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
601
602
  */
602
603
 
@@ -667,14 +668,14 @@ var MAX_EXECUTION_ATTEMPTS = 3; // <- TODO: [🤹‍♂️]
667
668
  var MAX_FILENAME_LENGTH = 30;
668
669
  /**
669
670
  * @@@
670
- * TODO: [🐝] !!! Use
671
+ * TODO: [🐝][main] !!! Use
671
672
  *
672
673
  * @public exported from `@promptbook/core`
673
674
  */
674
675
  var MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH = 3;
675
676
  /**
676
677
  * @@@
677
- * TODO: [🐝] !!! Use
678
+ * TODO: [🐝][main] !!! Use
678
679
  *
679
680
  * @public exported from `@promptbook/core`
680
681
  */
@@ -747,6 +748,17 @@ var DEFAULT_REMOTE_URL = 'https://api.pavolhejny.com/';
747
748
  */
748
749
  var DEFAULT_REMOTE_URL_PATH = '/promptbook/socket.io';
749
750
  // <- TODO: [🧜‍♂️]
751
+ /**
752
+ * @@@
753
+ *
754
+ * @public exported from `@promptbook/core`
755
+ */
756
+ var DEFAULT_CSV_SETTINGS = Object.freeze({
757
+ delimiter: ',',
758
+ quoteChar: '"',
759
+ newline: '\n',
760
+ skipEmptyLines: true,
761
+ });
750
762
  /**
751
763
  * @@@
752
764
  *
@@ -839,7 +851,7 @@ function isValidPromptbookVersion(version) {
839
851
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
840
852
  return false;
841
853
  }
842
- // <- TODO: !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
854
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
843
855
  return true;
844
856
  }
845
857
 
@@ -1008,7 +1020,7 @@ function validatePipelineCore(pipeline) {
1008
1020
  // <- Note: [🚲]
1009
1021
  throw new PipelineLogicError(spaceTrim$1(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1010
1022
  }
1011
- if (!isValidPromptbookVersion(pipeline.promptbookVersion)) {
1023
+ if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1012
1024
  // <- Note: [🚲]
1013
1025
  throw new PipelineLogicError(spaceTrim$1(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1014
1026
  }
@@ -1191,6 +1203,7 @@ function validatePipelineCore(pipeline) {
1191
1203
  }
1192
1204
  }
1193
1205
  /**
1206
+ * TODO: !!!!! [🧞‍♀️] Do not allow joker + foreach
1194
1207
  * TODO: [🧠] Work with promptbookVersion
1195
1208
  * TODO: Use here some json-schema, Zod or something similar and change it to:
1196
1209
  * > /**
@@ -1202,11 +1215,11 @@ function validatePipelineCore(pipeline) {
1202
1215
  * > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
1203
1216
  */
1204
1217
  /**
1205
- * TODO: [🐣] !!!! Validate that all samples match expectations
1206
- * TODO: [🐣][🐝] !!!! Validate that knowledge is valid (non-void)
1207
- * TODO: [🐣] !!!! Validate that persona can be used only with CHAT variant
1208
- * TODO: [🐣] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1209
- * TODO: [🐣] !!!! Validate that reserved parameter is not used as joker
1218
+ * TODO: [🐣][main] !!!! Validate that all samples match expectations
1219
+ * TODO: [🐣][🐝][main] !!!! Validate that knowledge is valid (non-void)
1220
+ * TODO: [🐣][main] !!!! Validate that persona can be used only with CHAT variant
1221
+ * TODO: [🐣][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1222
+ * TODO: [🐣][main] !!!! Validate that reserved parameter is not used as joker
1210
1223
  * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
1211
1224
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
1212
1225
  */
@@ -1520,7 +1533,7 @@ function createCollectionFromUrl(url, options) {
1520
1533
  });
1521
1534
  }
1522
1535
  /**
1523
- * TODO: !!!! [🧠] Library precompilation and do not mix markdown and json promptbooks
1536
+ * TODO: [main] !!!! [🧠] Library precompilation and do not mix markdown and json promptbooks
1524
1537
  */
1525
1538
 
1526
1539
  /**
@@ -1817,7 +1830,7 @@ function forEachAsync(array, options, callbackfunction) {
1817
1830
  });
1818
1831
  }
1819
1832
 
1820
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
1833
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
1821
1834
 
1822
1835
  var defaultDiacriticsRemovalMap = [
1823
1836
  {
@@ -2368,7 +2381,7 @@ function isPipelinePrepared(pipeline) {
2368
2381
  return true;
2369
2382
  }
2370
2383
  /**
2371
- * TODO: [🔃] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2384
+ * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2372
2385
  * TODO: [🐠] Maybe base this on `makeValidator`
2373
2386
  * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2374
2387
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
@@ -2420,9 +2433,10 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2420
2433
  });
2421
2434
  Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2422
2435
  get: function () {
2423
- return this.llmExecutionTools
2424
- .map(function (tools, index) { return "".concat(index + 1, ") ").concat(tools.title, " ").concat(tools.description || ''); })
2425
- .join('\n');
2436
+ return this.llmExecutionTools.map(function (_a, index) {
2437
+ var title = _a.title;
2438
+ return "".concat(index + 1, ") `").concat(title, "`");
2439
+ }).join('\n');
2426
2440
  },
2427
2441
  enumerable: false,
2428
2442
  configurable: true
@@ -2620,9 +2634,7 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2620
2634
  throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
2621
2635
  }
2622
2636
  else {
2623
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n You have not provided any `LlmExecutionTools` that support model variant \"".concat(prompt.modelRequirements.modelVariant, "\n\n Available `LlmExecutionTools`:\n ").concat(block(_this.llmExecutionTools
2624
- .map(function (tools) { return "- ".concat(tools.title, " ").concat(tools.description || ''); })
2625
- .join('\n')), "\n\n "); }));
2637
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n You have not provided any `LlmExecutionTools` that support model variant \"".concat(prompt.modelRequirements.modelVariant, "\"\n\n Available `LlmExecutionTools`:\n ").concat(block(_this.description), "\n\n "); }));
2626
2638
  }
2627
2639
  }
2628
2640
  });
@@ -2764,47 +2776,47 @@ function extractVariables(script) {
2764
2776
  * @public exported from `@promptbook/utils`
2765
2777
  */
2766
2778
  function extractParameterNamesFromTemplate(template) {
2767
- var e_1, _a, e_2, _b, e_3, _c;
2779
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
2768
2780
  var title = template.title, description = template.description, templateType = template.templateType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames, foreach = template.foreach;
2769
2781
  var parameterNames = new Set();
2770
2782
  try {
2771
- for (var _d = __values(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(extractParameterNames(title)), false), __read(extractParameterNames(description || '')), false), __read(extractParameterNames(content)), false), __read(extractParameterNames(preparedContent || '')), false)), _e = _d.next(); !_e.done; _e = _d.next()) {
2772
- var parameterName = _e.value;
2783
+ for (var _e = __values(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(extractParameterNames(title)), false), __read(extractParameterNames(description || '')), false), __read(extractParameterNames(content)), false), __read(extractParameterNames(preparedContent || '')), false)), _f = _e.next(); !_f.done; _f = _e.next()) {
2784
+ var parameterName = _f.value;
2773
2785
  parameterNames.add(parameterName);
2774
2786
  }
2775
2787
  }
2776
2788
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2777
2789
  finally {
2778
2790
  try {
2779
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2791
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
2780
2792
  }
2781
2793
  finally { if (e_1) throw e_1.error; }
2782
2794
  }
2783
2795
  if (templateType === 'SCRIPT_TEMPLATE') {
2784
2796
  try {
2785
- for (var _f = __values(extractVariables(content)), _g = _f.next(); !_g.done; _g = _f.next()) {
2786
- var parameterName = _g.value;
2797
+ for (var _g = __values(extractVariables(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
2798
+ var parameterName = _h.value;
2787
2799
  parameterNames.add(parameterName);
2788
2800
  }
2789
2801
  }
2790
2802
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
2791
2803
  finally {
2792
2804
  try {
2793
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2805
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
2794
2806
  }
2795
2807
  finally { if (e_2) throw e_2.error; }
2796
2808
  }
2797
2809
  }
2798
2810
  try {
2799
- for (var _h = __values(jokerParameterNames || []), _j = _h.next(); !_j.done; _j = _h.next()) {
2800
- var jokerName = _j.value;
2811
+ for (var _j = __values(jokerParameterNames || []), _k = _j.next(); !_k.done; _k = _j.next()) {
2812
+ var jokerName = _k.value;
2801
2813
  parameterNames.add(jokerName);
2802
2814
  }
2803
2815
  }
2804
2816
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
2805
2817
  finally {
2806
2818
  try {
2807
- if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
2819
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
2808
2820
  }
2809
2821
  finally { if (e_3) throw e_3.error; }
2810
2822
  }
@@ -2812,10 +2824,22 @@ function extractParameterNamesFromTemplate(template) {
2812
2824
  // <- Note {websiteContent} is used in `preparedContent`
2813
2825
  // Note: [🍭] Fixing dependent subparameterName from FOREACH command
2814
2826
  if (foreach !== undefined) {
2815
- if (parameterNames.has(foreach.subparameterName)) {
2816
- parameterNames.delete(foreach.subparameterName);
2817
- parameterNames.add(foreach.parameterName);
2818
- // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2827
+ try {
2828
+ for (var _l = __values(foreach.inputSubparameterNames), _m = _l.next(); !_m.done; _m = _l.next()) {
2829
+ var subparameterName = _m.value;
2830
+ if (parameterNames.has(subparameterName)) {
2831
+ parameterNames.delete(subparameterName);
2832
+ parameterNames.add(foreach.parameterName);
2833
+ // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2834
+ }
2835
+ }
2836
+ }
2837
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2838
+ finally {
2839
+ try {
2840
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
2841
+ }
2842
+ finally { if (e_4) throw e_4.error; }
2819
2843
  }
2820
2844
  }
2821
2845
  return parameterNames;
@@ -2899,6 +2923,183 @@ function union() {
2899
2923
  return union;
2900
2924
  }
2901
2925
 
2926
+ /**
2927
+ * Just marks a place of place where should be something implemented
2928
+ * No side effects.
2929
+ *
2930
+ * Note: It can be usefull suppressing eslint errors of unused variables
2931
+ *
2932
+ * @param value any values
2933
+ * @returns void
2934
+ * @private within the repository
2935
+ */
2936
+ function TODO_USE() {
2937
+ var value = [];
2938
+ for (var _i = 0; _i < arguments.length; _i++) {
2939
+ value[_i] = arguments[_i];
2940
+ }
2941
+ }
2942
+
2943
+ /**
2944
+ * This error indicates problems parsing the format value
2945
+ *
2946
+ * For example, when the format value is not a valid JSON or CSV
2947
+ * This is not thrown directly but in extended classes
2948
+ *
2949
+ * @public exported from `@promptbook/core`
2950
+ */
2951
+ var AbstractFormatError = /** @class */ (function (_super) {
2952
+ __extends(AbstractFormatError, _super);
2953
+ // Note: To allow instanceof do not put here error `name`
2954
+ // public readonly name = 'AbstractFormatError';
2955
+ function AbstractFormatError(message) {
2956
+ var _this = _super.call(this, message) || this;
2957
+ Object.setPrototypeOf(_this, AbstractFormatError.prototype);
2958
+ return _this;
2959
+ }
2960
+ return AbstractFormatError;
2961
+ }(Error));
2962
+
2963
+ /**
2964
+ * This error indicates problem with parsing of CSV
2965
+ *
2966
+ * @public exported from `@promptbook/core`
2967
+ */
2968
+ var CsvFormatError = /** @class */ (function (_super) {
2969
+ __extends(CsvFormatError, _super);
2970
+ function CsvFormatError(message) {
2971
+ var _this = _super.call(this, message) || this;
2972
+ _this.name = 'CsvFormatError';
2973
+ Object.setPrototypeOf(_this, CsvFormatError.prototype);
2974
+ return _this;
2975
+ }
2976
+ return CsvFormatError;
2977
+ }(AbstractFormatError));
2978
+
2979
+ /**
2980
+ * @@@
2981
+ *
2982
+ * @public exported from `@promptbook/core`
2983
+ */
2984
+ var MANDATORY_CSV_SETTINGS = Object.freeze({
2985
+ header: true,
2986
+ // encoding: 'utf8',
2987
+ });
2988
+
2989
+ /**
2990
+ * Definition for CSV spreadsheet
2991
+ *
2992
+ * @public exported from `@promptbook/core`
2993
+ * <- TODO: [🏢] Export from package `@promptbook/csv`
2994
+ */
2995
+ var CsvFormatDefinition = {
2996
+ formatName: 'CSV',
2997
+ aliases: ['SPREADSHEET', 'TABLE'],
2998
+ isValid: function (value, settings, schema) {
2999
+ // TODO: Implement CSV validation
3000
+ TODO_USE(value /* <- TODO: Use value here */);
3001
+ TODO_USE(settings /* <- TODO: Use settings here */);
3002
+ TODO_USE(schema /* <- TODO: Use schema here */);
3003
+ return true;
3004
+ },
3005
+ canBeValid: function (partialValue, settings, schema) {
3006
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3007
+ TODO_USE(settings /* <- TODO: Use settings here */);
3008
+ TODO_USE(schema /* <- TODO: Use schema here */);
3009
+ return true;
3010
+ },
3011
+ heal: function (value, settings, schema) {
3012
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3013
+ TODO_USE(settings /* <- TODO: Use settings here */);
3014
+ TODO_USE(schema /* <- TODO: Use schema here */);
3015
+ throw new Error('Not implemented');
3016
+ },
3017
+ subvalueDefinitions: [
3018
+ {
3019
+ subvalueName: 'ROW',
3020
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3021
+ return __awaiter(this, void 0, void 0, function () {
3022
+ var csv, mappedData;
3023
+ var _this = this;
3024
+ return __generator(this, function (_a) {
3025
+ switch (_a.label) {
3026
+ case 0:
3027
+ csv = parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
3028
+ if (csv.errors.length !== 0) {
3029
+ throw new CsvFormatError(spaceTrim(function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
3030
+ }
3031
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, index) { return __awaiter(_this, void 0, void 0, function () {
3032
+ var _a, _b;
3033
+ var _c;
3034
+ return __generator(this, function (_d) {
3035
+ switch (_d.label) {
3036
+ case 0:
3037
+ if (row[outputParameterName]) {
3038
+ throw new CsvFormatError("Can not overwrite existing column \"".concat(outputParameterName, "\" in CSV row"));
3039
+ }
3040
+ _a = [__assign({}, row)];
3041
+ _c = {};
3042
+ _b = outputParameterName;
3043
+ return [4 /*yield*/, mapCallback(row, index)];
3044
+ case 1: return [2 /*return*/, __assign.apply(void 0, _a.concat([(_c[_b] = _d.sent(), _c)]))];
3045
+ }
3046
+ });
3047
+ }); }))];
3048
+ case 1:
3049
+ mappedData = _a.sent();
3050
+ return [2 /*return*/, unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
3051
+ }
3052
+ });
3053
+ });
3054
+ },
3055
+ },
3056
+ {
3057
+ subvalueName: 'CELL',
3058
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3059
+ return __awaiter(this, void 0, void 0, function () {
3060
+ var csv, mappedData;
3061
+ var _this = this;
3062
+ return __generator(this, function (_a) {
3063
+ switch (_a.label) {
3064
+ case 0:
3065
+ csv = parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
3066
+ if (csv.errors.length !== 0) {
3067
+ throw new CsvFormatError(spaceTrim(function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
3068
+ }
3069
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, rowIndex) { return __awaiter(_this, void 0, void 0, function () {
3070
+ var _this = this;
3071
+ return __generator(this, function (_a) {
3072
+ return [2 /*return*/, /* not await */ Promise.all(Object.entries(row).map(function (_a, columnIndex) {
3073
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
3074
+ return __awaiter(_this, void 0, void 0, function () {
3075
+ var index;
3076
+ var _c;
3077
+ return __generator(this, function (_d) {
3078
+ index = rowIndex * Object.keys(row).length + columnIndex;
3079
+ return [2 /*return*/, /* not await */ mapCallback((_c = {}, _c[key] = value, _c), index)];
3080
+ });
3081
+ });
3082
+ }))];
3083
+ });
3084
+ }); }))];
3085
+ case 1:
3086
+ mappedData = _a.sent();
3087
+ return [2 /*return*/, unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
3088
+ }
3089
+ });
3090
+ });
3091
+ },
3092
+ },
3093
+ ],
3094
+ };
3095
+ /**
3096
+ * TODO: [🍓] In `CsvFormatDefinition` implement simple `isValid`
3097
+ * TODO: [🍓] In `CsvFormatDefinition` implement partial `canBeValid`
3098
+ * TODO: [🍓] In `CsvFormatDefinition` implement `heal
3099
+ * TODO: [🍓] In `CsvFormatDefinition` implement `subvalueDefinitions`
3100
+ * TODO: [🏢] Allow to expect something inside CSV objects and other formats
3101
+ */
3102
+
2902
3103
  /**
2903
3104
  * Function isValidJsonString will tell you if the string is valid JSON or not
2904
3105
  *
@@ -2920,6 +3121,222 @@ function isValidJsonString(value /* <- [👨‍⚖️] */) {
2920
3121
  }
2921
3122
  }
2922
3123
 
3124
+ /**
3125
+ * Definition for JSON format
3126
+ *
3127
+ * @private still in development [🏢]
3128
+ */
3129
+ var JsonFormatDefinition = {
3130
+ formatName: 'JSON',
3131
+ mimeType: 'application/json',
3132
+ isValid: function (value, settings, schema) {
3133
+ TODO_USE(schema /* <- TODO: Use schema here */);
3134
+ TODO_USE(settings /* <- TODO: Use settings here */);
3135
+ return isValidJsonString(value);
3136
+ },
3137
+ canBeValid: function (partialValue, settings, schema) {
3138
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3139
+ TODO_USE(settings /* <- TODO: Use settings here */);
3140
+ TODO_USE(schema /* <- TODO: Use schema here */);
3141
+ return true;
3142
+ },
3143
+ heal: function (value, settings, schema) {
3144
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3145
+ TODO_USE(settings /* <- TODO: Use settings here */);
3146
+ TODO_USE(schema /* <- TODO: Use schema here */);
3147
+ throw new Error('Not implemented');
3148
+ },
3149
+ subvalueDefinitions: [],
3150
+ };
3151
+ /**
3152
+ * TODO: [🧠] Maybe propper instance of object
3153
+ * TODO: [0] Make string_serialized_json
3154
+ * TODO: [1] Make type for JSON Settings and Schema
3155
+ * TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
3156
+ * TODO: [🍓] In `JsonFormatDefinition` implement simple `isValid`
3157
+ * TODO: [🍓] In `JsonFormatDefinition` implement partial `canBeValid`
3158
+ * TODO: [🍓] In `JsonFormatDefinition` implement `heal
3159
+ * TODO: [🍓] In `JsonFormatDefinition` implement `subvalueDefinitions`
3160
+ * TODO: [🏢] Allow to expect something inside JSON objects and other formats
3161
+ */
3162
+
3163
+ /**
3164
+ * Definition for any text - this will be always valid
3165
+ *
3166
+ * Note: This is not useful for validation, but for splitting and mapping with `subvalueDefinitions`
3167
+ *
3168
+ * @public exported from `@promptbook/core`
3169
+ */
3170
+ var TextFormatDefinition = {
3171
+ formatName: 'TEXT',
3172
+ isValid: function (value) {
3173
+ return typeof value === 'string';
3174
+ },
3175
+ canBeValid: function (partialValue) {
3176
+ return typeof partialValue === 'string';
3177
+ },
3178
+ heal: function () {
3179
+ throw new UnexpectedError('It does not make sense to call `TextFormatDefinition.heal`');
3180
+ },
3181
+ subvalueDefinitions: [
3182
+ {
3183
+ subvalueName: 'LINE',
3184
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3185
+ return __awaiter(this, void 0, void 0, function () {
3186
+ var lines, mappedLines;
3187
+ return __generator(this, function (_a) {
3188
+ switch (_a.label) {
3189
+ case 0:
3190
+ lines = value.split('\n');
3191
+ return [4 /*yield*/, Promise.all(lines.map(function (lineContent, lineNumber) {
3192
+ // TODO: [🧠] Maybe option to skip empty line
3193
+ /* not await */ return mapCallback({
3194
+ lineContent: lineContent,
3195
+ // TODO: [🧠] Maybe also put here `lineNumber`
3196
+ }, lineNumber);
3197
+ }))];
3198
+ case 1:
3199
+ mappedLines = _a.sent();
3200
+ return [2 /*return*/, mappedLines.join('\n')];
3201
+ }
3202
+ });
3203
+ });
3204
+ },
3205
+ },
3206
+ // <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3207
+ ],
3208
+ };
3209
+ /**
3210
+ * TODO: [1] Make type for XML Text and Schema
3211
+ * TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3212
+ * TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
3213
+ * TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
3214
+ * TODO: [🍓] In `TextFormatDefinition` implement `heal
3215
+ * TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
3216
+ * TODO: [🏢] Allow to expect something inside each item of list and other formats
3217
+ */
3218
+
3219
+ /**
3220
+ * Definition for XML format
3221
+ *
3222
+ * @private still in development [🏢]
3223
+ */
3224
+ var XmlFormatDefinition = {
3225
+ formatName: 'XML',
3226
+ mimeType: 'application/xml',
3227
+ isValid: function (value, settings, schema) {
3228
+ TODO_USE(value /* <- TODO: Use value here */);
3229
+ TODO_USE(settings /* <- TODO: Use settings here */);
3230
+ TODO_USE(schema /* <- TODO: Use schema here */);
3231
+ return true;
3232
+ },
3233
+ canBeValid: function (partialValue, settings, schema) {
3234
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3235
+ TODO_USE(settings /* <- TODO: Use settings here */);
3236
+ TODO_USE(schema /* <- TODO: Use schema here */);
3237
+ return true;
3238
+ },
3239
+ heal: function (value, settings, schema) {
3240
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3241
+ TODO_USE(settings /* <- TODO: Use settings here */);
3242
+ TODO_USE(schema /* <- TODO: Use schema here */);
3243
+ throw new Error('Not implemented');
3244
+ },
3245
+ subvalueDefinitions: [],
3246
+ };
3247
+ /**
3248
+ * TODO: [🧠] Maybe propper instance of object
3249
+ * TODO: [0] Make string_serialized_xml
3250
+ * TODO: [1] Make type for XML Settings and Schema
3251
+ * TODO: [🧠] What to use for validating XMLs - XSD,...
3252
+ * TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
3253
+ * TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
3254
+ * TODO: [🍓] In `XmlFormatDefinition` implement `heal
3255
+ * TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
3256
+ * TODO: [🏢] Allow to expect something inside XML and other formats
3257
+ */
3258
+
3259
+ /**
3260
+ * Definitions for all formats supported by Promptbook
3261
+ *
3262
+ * @private internal index of `...` <- TODO [🏢]
3263
+ */
3264
+ var FORMAT_DEFINITIONS = [
3265
+ JsonFormatDefinition,
3266
+ XmlFormatDefinition,
3267
+ TextFormatDefinition,
3268
+ CsvFormatDefinition,
3269
+ ];
3270
+
3271
+ /**
3272
+ * Maps available parameters to expected parameters
3273
+ *
3274
+ * The strategy is:
3275
+ * 1) @@@
3276
+ * 2) @@@
3277
+ *
3278
+ * @throws {PipelineExecutionError} @@@
3279
+ * @private within the repository used in `createPipelineExecutor`
3280
+ */
3281
+ function mapAvailableToExpectedParameters(options) {
3282
+ var e_1, _a;
3283
+ var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
3284
+ var availableParametersNames = new Set(Object.keys(availableParameters));
3285
+ var expectedParameterNames = new Set(Object.keys(expectedParameters));
3286
+ var mappedParameters = {};
3287
+ try {
3288
+ // Phase 1️⃣: Matching mapping
3289
+ for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
3290
+ var parameterName = _c.value;
3291
+ // Situation: Parameter is available and expected
3292
+ if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3293
+ mappedParameters[parameterName] = availableParameters[parameterName];
3294
+ // <- Note: [👩‍👩‍👧] Maybe detect parameter collision here?
3295
+ availableParametersNames.delete(parameterName);
3296
+ expectedParameterNames.delete(parameterName);
3297
+ }
3298
+ // Situation: Parameter is available but NOT expected
3299
+ else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
3300
+ // [🐱‍👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
3301
+ }
3302
+ // Situation: Parameter is NOT available BUT expected
3303
+ else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3304
+ // Do nothing here - this will be maybe fixed in the non-matching mapping
3305
+ }
3306
+ }
3307
+ }
3308
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3309
+ finally {
3310
+ try {
3311
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3312
+ }
3313
+ finally { if (e_1) throw e_1.error; }
3314
+ }
3315
+ if (expectedParameterNames.size === 0) {
3316
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3317
+ Object.freeze(mappedParameters);
3318
+ return mappedParameters;
3319
+ }
3320
+ // Phase 2️⃣: Non-matching mapping
3321
+ if (expectedParameterNames.size !== availableParametersNames.size) {
3322
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
3323
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3324
+ .join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
3325
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3326
+ .join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
3327
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3328
+ .join('\n')), "\n\n "); }));
3329
+ }
3330
+ var expectedParameterNamesArray = Array.from(expectedParameterNames);
3331
+ var availableParametersNamesArray = Array.from(availableParametersNames);
3332
+ for (var i = 0; i < expectedParameterNames.size; i++) {
3333
+ mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
3334
+ }
3335
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3336
+ Object.freeze(mappedParameters);
3337
+ return mappedParameters;
3338
+ }
3339
+
2923
3340
  /**
2924
3341
  * Extracts all code blocks from markdown.
2925
3342
  *
@@ -3225,6 +3642,9 @@ var CountUtils = {
3225
3642
  LINES: countLines,
3226
3643
  PAGES: countPages,
3227
3644
  };
3645
+ /**
3646
+ * TODO: [🧠][🤠] This should be probbably as part of `TextFormatDefinition`
3647
+ */
3228
3648
 
3229
3649
  /**
3230
3650
  * Function checkExpectations will check if the expectations on given value are met
@@ -3283,6 +3703,8 @@ function isPassingExpectations(expectations, value) {
3283
3703
  }
3284
3704
  /**
3285
3705
  * TODO: [💝] Unite object for expecting amount and format
3706
+ * TODO: [🧠][🤠] This should be part of `TextFormatDefinition`
3707
+ * Note: [💝] and [🤠] are interconnected together
3286
3708
  */
3287
3709
 
3288
3710
  /**
@@ -3292,58 +3714,66 @@ function isPassingExpectations(expectations, value) {
3292
3714
  */
3293
3715
  function executeAttempts(options) {
3294
3716
  return __awaiter(this, void 0, void 0, function () {
3295
- var $ongoingTemplateResult, jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, _loop_1, attempt, state_1;
3717
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3296
3718
  return __generator(this, function (_a) {
3297
3719
  switch (_a.label) {
3298
3720
  case 0:
3299
- $ongoingTemplateResult = options.$ongoingTemplateResult, jokerParameterNames = options.jokerParameterNames, priority = options.priority, maxAttempts = options.maxAttempts, preparedContent = options.preparedContent, parameters = options.parameters, template = options.template, preparedPipeline = options.preparedPipeline, tools = options.tools, llmTools = options.llmTools, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3721
+ jokerParameterNames = options.jokerParameterNames, priority = options.priority, maxAttempts = options.maxAttempts, preparedContent = options.preparedContent, parameters = options.parameters, template = options.template, preparedPipeline = options.preparedPipeline, tools = options.tools, llmTools = options.llmTools, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3300
3722
  maxExecutionAttempts = settings.maxExecutionAttempts;
3723
+ $ongoingTemplateResult = {
3724
+ $result: null,
3725
+ $resultString: null,
3726
+ $expectError: null,
3727
+ $scriptPipelineExecutionErrors: [],
3728
+ };
3301
3729
  _loop_1 = function (attempt) {
3302
- var isJokerAttempt, jokerParameterName, _b, modelRequirements, _c, _d, _e, _f, _g, _h, scriptTools, _j, error_1, e_1_1, _k, _l, _m, functionName, postprocessingError, _o, _p, scriptTools, _q, error_2, e_2_1, e_3_1, error_3;
3303
- var e_1, _r, e_3, _s, e_2, _t;
3304
- return __generator(this, function (_u) {
3305
- switch (_u.label) {
3730
+ var isJokerAttempt, jokerParameterName, _b, modelRequirements, _c, _d, _e, _f, _g, scriptTools, _h, error_1, e_1_1, _j, _k, _l, functionName, postprocessingError, _m, _o, scriptTools, _p, error_2, e_2_1, e_3_1, error_3;
3731
+ var e_1, _q, e_3, _r, e_2, _s;
3732
+ return __generator(this, function (_t) {
3733
+ switch (_t.label) {
3306
3734
  case 0:
3307
3735
  isJokerAttempt = attempt < 0;
3308
3736
  jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3309
- // TODO: [🧠] !!!!!! JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3737
+ // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3310
3738
  if (isJokerAttempt && !jokerParameterName) {
3311
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3739
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3312
3740
  }
3313
3741
  $ongoingTemplateResult.$result = null;
3314
3742
  $ongoingTemplateResult.$resultString = null;
3315
3743
  $ongoingTemplateResult.$expectError = null;
3316
3744
  if (isJokerAttempt) {
3317
3745
  if (parameters[jokerParameterName] === undefined) {
3318
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3746
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3319
3747
  // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3320
3748
  }
3321
3749
  else {
3322
3750
  $ongoingTemplateResult.$resultString = parameters[jokerParameterName];
3323
3751
  }
3324
3752
  }
3325
- _u.label = 1;
3753
+ _t.label = 1;
3326
3754
  case 1:
3327
- _u.trys.push([1, 44, 45, 46]);
3328
- if (!!isJokerAttempt) return [3 /*break*/, 26];
3755
+ _t.trys.push([1, 43, 44, 45]);
3756
+ if (!!isJokerAttempt) return [3 /*break*/, 25];
3329
3757
  _b = template.templateType;
3330
3758
  switch (_b) {
3331
3759
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3332
3760
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3333
- case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3334
- case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3761
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 11];
3762
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 22];
3335
3763
  }
3336
- return [3 /*break*/, 25];
3764
+ return [3 /*break*/, 24];
3337
3765
  case 2:
3338
3766
  $ongoingTemplateResult.$resultString = replaceParameters(preparedContent, parameters);
3339
- return [3 /*break*/, 26];
3767
+ return [3 /*break*/, 25];
3340
3768
  case 3:
3341
3769
  modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (template.modelRequirements || {}));
3342
3770
  $ongoingTemplateResult.$prompt = {
3343
3771
  title: template.title,
3344
3772
  pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3345
3773
  ? preparedPipeline.pipelineUrl
3346
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name),
3774
+ : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name
3775
+ // <- TODO: Here should be maybe also subformat index to distinguish between same template with different subformat values
3776
+ ),
3347
3777
  parameters: parameters,
3348
3778
  content: preparedContent,
3349
3779
  modelRequirements: modelRequirements,
@@ -3361,67 +3791,57 @@ function executeAttempts(options) {
3361
3791
  case 'COMPLETION': return [3 /*break*/, 6];
3362
3792
  case 'EMBEDDING': return [3 /*break*/, 8];
3363
3793
  }
3364
- return [3 /*break*/, 10];
3794
+ return [3 /*break*/, 9];
3365
3795
  case 4:
3366
3796
  _d = $ongoingTemplateResult;
3367
3797
  return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3368
3798
  case 5:
3369
- _d.$chatResult = _u.sent();
3799
+ _d.$chatResult = _t.sent();
3370
3800
  // TODO: [🍬] Destroy chatThread
3371
3801
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$chatResult;
3372
3802
  $ongoingTemplateResult.$resultString = $ongoingTemplateResult.$chatResult.content;
3373
- return [3 /*break*/, 11];
3803
+ return [3 /*break*/, 10];
3374
3804
  case 6:
3375
3805
  _e = $ongoingTemplateResult;
3376
3806
  return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3377
3807
  case 7:
3378
- _e.$completionResult = _u.sent();
3808
+ _e.$completionResult = _t.sent();
3379
3809
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
3380
3810
  $ongoingTemplateResult.$resultString =
3381
3811
  $ongoingTemplateResult.$completionResult.content;
3382
- return [3 /*break*/, 11];
3383
- case 8:
3384
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3385
- _f = $ongoingTemplateResult;
3386
- return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze($ongoingTemplateResult.$prompt))];
3387
- case 9:
3388
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3389
- _f.$embeddingResult = _u.sent();
3390
- $ongoingTemplateResult.$result = $ongoingTemplateResult.$embeddingResult;
3391
- $ongoingTemplateResult.$resultString =
3392
- $ongoingTemplateResult.$embeddingResult.content.join(',');
3393
- return [3 /*break*/, 11];
3394
- case 10: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3395
- case 11: return [3 /*break*/, 26];
3396
- case 12:
3812
+ return [3 /*break*/, 10];
3813
+ case 8: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Embedding model can not be used in pipeline\n\n This should be catched during parsing\n\n ".concat(block(pipelineIdentification), "\n\n "); }));
3814
+ case 9: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3815
+ case 10: return [3 /*break*/, 25];
3816
+ case 11:
3397
3817
  if (arrayableToArray(tools.script).length === 0) {
3398
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3818
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3399
3819
  }
3400
3820
  if (!template.contentLanguage) {
3401
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3821
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3402
3822
  }
3403
- _u.label = 13;
3823
+ _t.label = 12;
3824
+ case 12:
3825
+ _t.trys.push([12, 19, 20, 21]);
3826
+ _f = (e_1 = void 0, __values(arrayableToArray(tools.script))), _g = _f.next();
3827
+ _t.label = 13;
3404
3828
  case 13:
3405
- _u.trys.push([13, 20, 21, 22]);
3406
- _g = (e_1 = void 0, __values(arrayableToArray(tools.script))), _h = _g.next();
3407
- _u.label = 14;
3829
+ if (!!_g.done) return [3 /*break*/, 18];
3830
+ scriptTools = _g.value;
3831
+ _t.label = 14;
3408
3832
  case 14:
3409
- if (!!_h.done) return [3 /*break*/, 19];
3410
- scriptTools = _h.value;
3411
- _u.label = 15;
3412
- case 15:
3413
- _u.trys.push([15, 17, , 18]);
3414
- _j = $ongoingTemplateResult;
3833
+ _t.trys.push([14, 16, , 17]);
3834
+ _h = $ongoingTemplateResult;
3415
3835
  return [4 /*yield*/, scriptTools.execute($deepFreeze({
3416
3836
  scriptLanguage: template.contentLanguage,
3417
3837
  script: preparedContent,
3418
3838
  parameters: parameters,
3419
3839
  }))];
3840
+ case 15:
3841
+ _h.$resultString = _t.sent();
3842
+ return [3 /*break*/, 18];
3420
3843
  case 16:
3421
- _j.$resultString = _u.sent();
3422
- return [3 /*break*/, 19];
3423
- case 17:
3424
- error_1 = _u.sent();
3844
+ error_1 = _t.sent();
3425
3845
  if (!(error_1 instanceof Error)) {
3426
3846
  throw error_1;
3427
3847
  }
@@ -3429,39 +3849,39 @@ function executeAttempts(options) {
3429
3849
  throw error_1;
3430
3850
  }
3431
3851
  $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_1);
3432
- return [3 /*break*/, 18];
3433
- case 18:
3434
- _h = _g.next();
3435
- return [3 /*break*/, 14];
3436
- case 19: return [3 /*break*/, 22];
3437
- case 20:
3438
- e_1_1 = _u.sent();
3852
+ return [3 /*break*/, 17];
3853
+ case 17:
3854
+ _g = _f.next();
3855
+ return [3 /*break*/, 13];
3856
+ case 18: return [3 /*break*/, 21];
3857
+ case 19:
3858
+ e_1_1 = _t.sent();
3439
3859
  e_1 = { error: e_1_1 };
3440
- return [3 /*break*/, 22];
3441
- case 21:
3860
+ return [3 /*break*/, 21];
3861
+ case 20:
3442
3862
  try {
3443
- if (_h && !_h.done && (_r = _g.return)) _r.call(_g);
3863
+ if (_g && !_g.done && (_q = _f.return)) _q.call(_f);
3444
3864
  }
3445
3865
  finally { if (e_1) throw e_1.error; }
3446
3866
  return [7 /*endfinally*/];
3447
- case 22:
3867
+ case 21:
3448
3868
  if ($ongoingTemplateResult.$resultString !== null) {
3449
- return [3 /*break*/, 26];
3869
+ return [3 /*break*/, 25];
3450
3870
  }
3451
3871
  if ($ongoingTemplateResult.$scriptPipelineExecutionErrors.length === 1) {
3452
3872
  throw $ongoingTemplateResult.$scriptPipelineExecutionErrors[0];
3453
3873
  }
3454
3874
  else {
3455
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3875
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3456
3876
  .map(function (error) { return '- ' + error.message; })
3457
- .join('\n\n')), "\n "); }));
3877
+ .join('\n\n')), "\n "); }));
3458
3878
  }
3459
- case 23:
3879
+ case 22:
3460
3880
  if (tools.userInterface === undefined) {
3461
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3881
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3462
3882
  }
3463
3883
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3464
- _k = $ongoingTemplateResult;
3884
+ _j = $ongoingTemplateResult;
3465
3885
  return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3466
3886
  promptTitle: template.title,
3467
3887
  promptMessage: replaceParameters(template.description || '', parameters),
@@ -3470,34 +3890,34 @@ function executeAttempts(options) {
3470
3890
  placeholder: undefined,
3471
3891
  priority: priority,
3472
3892
  }))];
3473
- case 24:
3893
+ case 23:
3474
3894
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3475
- _k.$resultString = _u.sent();
3476
- return [3 /*break*/, 26];
3477
- case 25: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3895
+ _j.$resultString = _t.sent();
3896
+ return [3 /*break*/, 25];
3897
+ case 24: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3898
+ case 25:
3899
+ if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 42];
3900
+ _t.label = 26;
3478
3901
  case 26:
3479
- if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 43];
3480
- _u.label = 27;
3902
+ _t.trys.push([26, 40, 41, 42]);
3903
+ _k = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _l = _k.next();
3904
+ _t.label = 27;
3481
3905
  case 27:
3482
- _u.trys.push([27, 41, 42, 43]);
3483
- _l = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _m = _l.next();
3484
- _u.label = 28;
3485
- case 28:
3486
- if (!!_m.done) return [3 /*break*/, 40];
3487
- functionName = _m.value;
3906
+ if (!!_l.done) return [3 /*break*/, 39];
3907
+ functionName = _l.value;
3488
3908
  postprocessingError = null;
3489
- _u.label = 29;
3909
+ _t.label = 28;
3910
+ case 28:
3911
+ _t.trys.push([28, 35, 36, 37]);
3912
+ _m = (e_2 = void 0, __values(arrayableToArray(tools.script))), _o = _m.next();
3913
+ _t.label = 29;
3490
3914
  case 29:
3491
- _u.trys.push([29, 36, 37, 38]);
3492
- _o = (e_2 = void 0, __values(arrayableToArray(tools.script))), _p = _o.next();
3493
- _u.label = 30;
3915
+ if (!!_o.done) return [3 /*break*/, 34];
3916
+ scriptTools = _o.value;
3917
+ _t.label = 30;
3494
3918
  case 30:
3495
- if (!!_p.done) return [3 /*break*/, 35];
3496
- scriptTools = _p.value;
3497
- _u.label = 31;
3498
- case 31:
3499
- _u.trys.push([31, 33, , 34]);
3500
- _q = $ongoingTemplateResult;
3919
+ _t.trys.push([30, 32, , 33]);
3920
+ _p = $ongoingTemplateResult;
3501
3921
  return [4 /*yield*/, scriptTools.execute({
3502
3922
  scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3503
3923
  script: "".concat(functionName, "(resultString)"),
@@ -3506,12 +3926,12 @@ function executeAttempts(options) {
3506
3926
  // Note: No ...parametersForTemplate, because working with result only
3507
3927
  },
3508
3928
  })];
3509
- case 32:
3510
- _q.$resultString = _u.sent();
3929
+ case 31:
3930
+ _p.$resultString = _t.sent();
3511
3931
  postprocessingError = null;
3512
- return [3 /*break*/, 35];
3513
- case 33:
3514
- error_2 = _u.sent();
3932
+ return [3 /*break*/, 34];
3933
+ case 32:
3934
+ error_2 = _t.sent();
3515
3935
  if (!(error_2 instanceof Error)) {
3516
3936
  throw error_2;
3517
3937
  }
@@ -3520,41 +3940,41 @@ function executeAttempts(options) {
3520
3940
  }
3521
3941
  postprocessingError = error_2;
3522
3942
  $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_2);
3523
- return [3 /*break*/, 34];
3524
- case 34:
3525
- _p = _o.next();
3526
- return [3 /*break*/, 30];
3527
- case 35: return [3 /*break*/, 38];
3528
- case 36:
3529
- e_2_1 = _u.sent();
3943
+ return [3 /*break*/, 33];
3944
+ case 33:
3945
+ _o = _m.next();
3946
+ return [3 /*break*/, 29];
3947
+ case 34: return [3 /*break*/, 37];
3948
+ case 35:
3949
+ e_2_1 = _t.sent();
3530
3950
  e_2 = { error: e_2_1 };
3531
- return [3 /*break*/, 38];
3532
- case 37:
3951
+ return [3 /*break*/, 37];
3952
+ case 36:
3533
3953
  try {
3534
- if (_p && !_p.done && (_t = _o.return)) _t.call(_o);
3954
+ if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3535
3955
  }
3536
3956
  finally { if (e_2) throw e_2.error; }
3537
3957
  return [7 /*endfinally*/];
3538
- case 38:
3958
+ case 37:
3539
3959
  if (postprocessingError) {
3540
3960
  throw postprocessingError;
3541
3961
  }
3542
- _u.label = 39;
3543
- case 39:
3544
- _m = _l.next();
3545
- return [3 /*break*/, 28];
3546
- case 40: return [3 /*break*/, 43];
3547
- case 41:
3548
- e_3_1 = _u.sent();
3962
+ _t.label = 38;
3963
+ case 38:
3964
+ _l = _k.next();
3965
+ return [3 /*break*/, 27];
3966
+ case 39: return [3 /*break*/, 42];
3967
+ case 40:
3968
+ e_3_1 = _t.sent();
3549
3969
  e_3 = { error: e_3_1 };
3550
- return [3 /*break*/, 43];
3551
- case 42:
3970
+ return [3 /*break*/, 42];
3971
+ case 41:
3552
3972
  try {
3553
- if (_m && !_m.done && (_s = _l.return)) _s.call(_l);
3973
+ if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3554
3974
  }
3555
3975
  finally { if (e_3) throw e_3.error; }
3556
3976
  return [7 /*endfinally*/];
3557
- case 43:
3977
+ case 42:
3558
3978
  // TODO: [💝] Unite object for expecting amount and format
3559
3979
  if (template.format) {
3560
3980
  if (template.format === 'JSON') {
@@ -3565,13 +3985,13 @@ function executeAttempts(options) {
3565
3985
  }
3566
3986
  catch (error) {
3567
3987
  keepUnused(error);
3568
- throw new ExpectError(spaceTrim$1(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3569
- /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3988
+ throw new ExpectError(spaceTrim$1(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3989
+ /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3570
3990
  }
3571
3991
  }
3572
3992
  }
3573
3993
  else {
3574
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3994
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3575
3995
  }
3576
3996
  }
3577
3997
  // TODO: [💝] Unite object for expecting amount and format
@@ -3579,14 +3999,14 @@ function executeAttempts(options) {
3579
3999
  checkExpectations(template.expectations, $ongoingTemplateResult.$resultString || '');
3580
4000
  }
3581
4001
  return [2 /*return*/, "break-attempts"];
3582
- case 44:
3583
- error_3 = _u.sent();
4002
+ case 43:
4003
+ error_3 = _t.sent();
3584
4004
  if (!(error_3 instanceof ExpectError)) {
3585
4005
  throw error_3;
3586
4006
  }
3587
4007
  $ongoingTemplateResult.$expectError = error_3;
3588
- return [3 /*break*/, 46];
3589
- case 45:
4008
+ return [3 /*break*/, 45];
4009
+ case 44:
3590
4010
  if (!isJokerAttempt &&
3591
4011
  template.templateType === 'PROMPT_TEMPLATE' &&
3592
4012
  $ongoingTemplateResult.$prompt
@@ -3603,22 +4023,22 @@ function executeAttempts(options) {
3603
4023
  });
3604
4024
  }
3605
4025
  return [7 /*endfinally*/];
3606
- case 46:
4026
+ case 45:
3607
4027
  if ($ongoingTemplateResult.$expectError !== null && attempt === maxAttempts - 1) {
3608
4028
  throw new PipelineExecutionError(spaceTrim$1(function (block) {
3609
4029
  var _a, _b, _c;
3610
- return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block(pipelineIdentification), "\n\n ---\n The Prompt:\n ").concat(block((((_a = $ongoingTemplateResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
4030
+ return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block(pipelineIdentification), "\n\n ---\n The Prompt:\n ").concat(block((((_a = $ongoingTemplateResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
3611
4031
  .split('\n')
3612
4032
  .map(function (line) { return "> ".concat(line); })
3613
- .join('\n')), "\n\n Last error ").concat(((_b = $ongoingTemplateResult.$expectError) === null || _b === void 0 ? void 0 : _b.name) || '', ":\n ").concat(block((((_c = $ongoingTemplateResult.$expectError) === null || _c === void 0 ? void 0 : _c.message) || '')
4033
+ .join('\n')), "\n\n Last error ").concat(((_b = $ongoingTemplateResult.$expectError) === null || _b === void 0 ? void 0 : _b.name) || '', ":\n ").concat(block((((_c = $ongoingTemplateResult.$expectError) === null || _c === void 0 ? void 0 : _c.message) || '')
3614
4034
  .split('\n')
3615
4035
  .map(function (line) { return "> ".concat(line); })
3616
- .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
4036
+ .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
3617
4037
  ? 'null'
3618
4038
  : $ongoingTemplateResult.$resultString
3619
4039
  .split('\n')
3620
4040
  .map(function (line) { return "> ".concat(line); })
3621
- .join('\n')), "\n ---\n ");
4041
+ .join('\n')), "\n ---\n ");
3622
4042
  }));
3623
4043
  }
3624
4044
  return [2 /*return*/];
@@ -3639,7 +4059,11 @@ function executeAttempts(options) {
3639
4059
  case 3:
3640
4060
  attempt++;
3641
4061
  return [3 /*break*/, 1];
3642
- case 4: return [2 /*return*/];
4062
+ case 4:
4063
+ if ($ongoingTemplateResult.$resultString === null) {
4064
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
4065
+ }
4066
+ return [2 /*return*/, $ongoingTemplateResult.$resultString];
3643
4067
  }
3644
4068
  });
3645
4069
  });
@@ -3653,36 +4077,83 @@ function executeAttempts(options) {
3653
4077
  *
3654
4078
  * @private internal utility of `createPipelineExecutor`
3655
4079
  */
3656
- function executeFormatCells(options) {
4080
+ function executeFormatSubvalues(options) {
3657
4081
  return __awaiter(this, void 0, void 0, function () {
3658
- var template;
4082
+ var template, jokerParameterNames, parameters, priority, pipelineIdentification, settings, parameterValue, formatDefinition, subvalueDefinition, formatSettings, resultString;
4083
+ var _this = this;
3659
4084
  return __generator(this, function (_a) {
3660
- template = options.template;
3661
- if (template.foreach === undefined) {
3662
- return [2 /*return*/, /* not await */ executeAttempts(options)];
4085
+ switch (_a.label) {
4086
+ case 0:
4087
+ template = options.template, jokerParameterNames = options.jokerParameterNames, parameters = options.parameters, priority = options.priority, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
4088
+ if (template.foreach === undefined) {
4089
+ return [2 /*return*/, /* not await */ executeAttempts(options)];
4090
+ }
4091
+ if (jokerParameterNames.length !== 0) {
4092
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n JOKER parameters are not supported together with FOREACH command\n\n [\uD83E\uDDDE\u200D\u2640\uFE0F] This should be prevented in `validatePipeline`\n\n ".concat(block(pipelineIdentification), "\n "); }));
4093
+ }
4094
+ parameterValue = parameters[template.foreach.parameterName] || '';
4095
+ formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
4096
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(template.foreach.formatName);
4097
+ });
4098
+ if (formatDefinition === undefined) {
4099
+ throw new UnexpectedError(
4100
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4101
+ spaceTrim(function (block) { return "\n Unsupported format \"".concat(template.foreach.formatName, "\"\n\n Available formats:\n ").concat(block(FORMAT_DEFINITIONS.map(function (formatDefinition) { return formatDefinition.formatName; })
4102
+ .map(function (formatName) { return "- ".concat(formatName); })
4103
+ .join('\n')), "\n\n [\u26F7] This should never happen because format name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
4104
+ }
4105
+ subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
4106
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(template.foreach.subformatName);
4107
+ });
4108
+ if (subvalueDefinition === undefined) {
4109
+ throw new UnexpectedError(
4110
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4111
+ spaceTrim(function (block) { return "\n Unsupported subformat name \"".concat(template.foreach.subformatName, "\" for format \"").concat(template.foreach.formatName, "\"\n\n Available subformat names for format \"").concat(formatDefinition.formatName, "\":\n ").concat(block(formatDefinition.subvalueDefinitions
4112
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
4113
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
4114
+ .join('\n')), "\n\n [\u26F7] This should never happen because subformat name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
4115
+ }
4116
+ if (formatDefinition.formatName === 'CSV') {
4117
+ formatSettings = settings.csvSettings;
4118
+ // <- TODO: [🤹‍♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
4119
+ }
4120
+ return [4 /*yield*/, subvalueDefinition.mapValues(parameterValue, template.foreach.outputSubparameterName, formatSettings, function (subparameters, index) { return __awaiter(_this, void 0, void 0, function () {
4121
+ var mappedParameters, allSubparameters, subresultString;
4122
+ return __generator(this, function (_a) {
4123
+ switch (_a.label) {
4124
+ case 0:
4125
+ // TODO: [🤹‍♂️][🪂] Limit to N concurrent executions
4126
+ // TODO: When done [🐚] Report progress also for each subvalue here
4127
+ try {
4128
+ mappedParameters = mapAvailableToExpectedParameters({
4129
+ expectedParameters: Object.fromEntries(template.foreach.inputSubparameterNames.map(function (subparameterName) { return [subparameterName, null]; })),
4130
+ availableParameters: subparameters,
4131
+ });
4132
+ }
4133
+ catch (error) {
4134
+ if (!(error instanceof PipelineExecutionError)) {
4135
+ throw error;
4136
+ }
4137
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n ".concat(error.message, "\n\n This is error in FOREACH command\n You have probbably passed wrong data to pipeline or wrong data was generated which are processed by FOREACH command\n\n ").concat(block(pipelineIdentification), "\n Subparameter index: ").concat(index, "\n "); }));
4138
+ }
4139
+ allSubparameters = __assign(__assign({}, parameters), mappedParameters);
4140
+ // Note: [👨‍👨‍👧] Now we can freeze `subparameters` because we are sure that all and only used parameters are defined and are not going to be changed
4141
+ Object.freeze(allSubparameters);
4142
+ return [4 /*yield*/, executeAttempts(__assign(__assign({}, options), { priority: priority + index, parameters: allSubparameters, pipelineIdentification: spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Subparameter index: ").concat(index, "\n "); }) }))];
4143
+ case 1:
4144
+ subresultString = _a.sent();
4145
+ return [2 /*return*/, subresultString];
4146
+ }
4147
+ });
4148
+ }); })];
4149
+ case 1:
4150
+ resultString = _a.sent();
4151
+ return [2 /*return*/, resultString];
3663
4152
  }
3664
- throw new NotYetImplementedError('FOREACH execution not implemented yet');
3665
4153
  });
3666
4154
  });
3667
4155
  }
3668
4156
 
3669
- /**
3670
- * Just marks a place of place where should be something implemented
3671
- * No side effects.
3672
- *
3673
- * Note: It can be usefull suppressing eslint errors of unused variables
3674
- *
3675
- * @param value any values
3676
- * @returns void
3677
- * @private within the repository
3678
- */
3679
- function TODO_USE() {
3680
- var value = [];
3681
- for (var _i = 0; _i < arguments.length; _i++) {
3682
- value[_i] = arguments[_i];
3683
- }
3684
- }
3685
-
3686
4157
  /**
3687
4158
  * @@@
3688
4159
  *
@@ -3796,7 +4267,7 @@ function getReservedParametersForTemplate(options) {
3796
4267
  */
3797
4268
  function executeTemplate(options) {
3798
4269
  return __awaiter(this, void 0, void 0, function () {
3799
- var currentTemplate, preparedPipeline, parametersToPass, tools, llmTools, onProgress, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, $ongoingTemplateResult, maxAttempts, jokerParameterNames, preparedContent;
4270
+ var currentTemplate, preparedPipeline, parametersToPass, tools, llmTools, onProgress, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, maxAttempts, jokerParameterNames, preparedContent, resultString;
3800
4271
  var e_1, _f, _g;
3801
4272
  return __generator(this, function (_h) {
3802
4273
  switch (_h.label) {
@@ -3820,12 +4291,13 @@ function executeTemplate(options) {
3820
4291
  _h.sent();
3821
4292
  usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3822
4293
  dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
4294
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3823
4295
  if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3824
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Dependent parameters:\n ").concat(Array.from(dependentParameterNames)
4296
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n Dependent parameters:\n ".concat(Array.from(dependentParameterNames)
3825
4297
  .map(function (name) { return "{".concat(name, "}"); })
3826
4298
  .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3827
4299
  .map(function (name) { return "{".concat(name, "}"); })
3828
- .join(', '), "\n\n "); }));
4300
+ .join(', '), "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3829
4301
  }
3830
4302
  _b = (_a = Object).freeze;
3831
4303
  _c = [{}];
@@ -3854,6 +4326,7 @@ function executeTemplate(options) {
3854
4326
  };
3855
4327
  try {
3856
4328
  // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
4329
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3857
4330
  for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3858
4331
  parameterName = _e.value;
3859
4332
  _loop_1(parameterName);
@@ -3866,22 +4339,14 @@ function executeTemplate(options) {
3866
4339
  }
3867
4340
  finally { if (e_1) throw e_1.error; }
3868
4341
  }
3869
- // Note: Now we can freeze `parameters` because we are sure that all and only used parameters are defined and are not going to be changed
4342
+ // Note: [👨‍👨‍👧] Now we can freeze `parameters` because we are sure that all and only used parameters are defined and are not going to be changed
3870
4343
  Object.freeze(parameters);
3871
- $ongoingTemplateResult = {
3872
- $result: null,
3873
- $resultString: null,
3874
- $expectError: null,
3875
- $scriptPipelineExecutionErrors: [],
3876
- };
3877
4344
  maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3878
4345
  jokerParameterNames = currentTemplate.jokerParameterNames || [];
3879
4346
  preparedContent = (currentTemplate.preparedContent || '{content}')
3880
4347
  .split('{content}')
3881
4348
  .join(currentTemplate.content);
3882
- // <- TODO: [🍵] Use here `replaceParameters` to replace {websiteContent} with option to ignore missing parameters
3883
- return [4 /*yield*/, executeFormatCells({
3884
- $ongoingTemplateResult: $ongoingTemplateResult,
4349
+ return [4 /*yield*/, executeFormatSubvalues({
3885
4350
  jokerParameterNames: jokerParameterNames,
3886
4351
  priority: priority,
3887
4352
  maxAttempts: maxAttempts,
@@ -3896,11 +4361,7 @@ function executeTemplate(options) {
3896
4361
  pipelineIdentification: pipelineIdentification,
3897
4362
  })];
3898
4363
  case 3:
3899
- // <- TODO: [🍵] Use here `replaceParameters` to replace {websiteContent} with option to ignore missing parameters
3900
- _h.sent();
3901
- if ($ongoingTemplateResult.$resultString === null) {
3902
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3903
- }
4364
+ resultString = _h.sent();
3904
4365
  return [4 /*yield*/, onProgress({
3905
4366
  name: name,
3906
4367
  title: title,
@@ -3908,13 +4369,15 @@ function executeTemplate(options) {
3908
4369
  isDone: true,
3909
4370
  templateType: currentTemplate.templateType,
3910
4371
  parameterName: currentTemplate.resultingParameterName,
3911
- parameterValue: $ongoingTemplateResult.$resultString,
4372
+ parameterValue: resultString,
3912
4373
  // <- [🍸]
3913
4374
  })];
3914
4375
  case 4:
3915
4376
  _h.sent();
3916
4377
  return [2 /*return*/, Object.freeze((_g = {},
3917
- _g[currentTemplate.resultingParameterName] = $ongoingTemplateResult.$resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */,
4378
+ _g[currentTemplate.resultingParameterName] =
4379
+ // <- Note: [👩‍👩‍👧] No need to detect parameter collision here because pipeline checks logic consistency during construction
4380
+ resultString,
3918
4381
  _g))];
3919
4382
  }
3920
4383
  });
@@ -3923,6 +4386,9 @@ function executeTemplate(options) {
3923
4386
  /**
3924
4387
  * TODO: [🤹‍♂️]
3925
4388
  */
4389
+ /**
4390
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4391
+ */
3926
4392
 
3927
4393
  /**
3928
4394
  * @@@
@@ -3943,6 +4409,7 @@ function filterJustOutputParameters(options) {
3943
4409
  };
3944
4410
  try {
3945
4411
  // Note: Filter ONLY output parameters
4412
+ // TODO: [👩🏾‍🤝‍👩🏻] Maybe use here `mapAvailableToExpectedParameters`
3946
4413
  for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
3947
4414
  var isOutput = _a.isOutput;
3948
4415
  return isOutput;
@@ -4057,7 +4524,7 @@ function executePipeline(options) {
4057
4524
  return name === parameterName;
4058
4525
  });
4059
4526
  if (!(parameter === undefined)) return [3 /*break*/, 1];
4060
- warnings.push(new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
4527
+ warnings.push(new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
4061
4528
  return [3 /*break*/, 4];
4062
4529
  case 1:
4063
4530
  if (!(parameter.isInput === false)) return [3 /*break*/, 4];
@@ -4069,10 +4536,10 @@ function executePipeline(options) {
4069
4536
  // Note: Wait a short time to prevent race conditions
4070
4537
  _h.sent();
4071
4538
  _h.label = 3;
4072
- case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim$1(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4539
+ case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim$1(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4073
4540
  isSuccessful: false,
4074
4541
  errors: __spreadArray([
4075
- new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
4542
+ new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
4076
4543
  ], __read(errors), false).map(serializeError),
4077
4544
  warnings: warnings.map(serializeError),
4078
4545
  executionReport: executionReport,
@@ -4136,7 +4603,7 @@ function executePipeline(options) {
4136
4603
  case 0:
4137
4604
  if (loopLimit-- < 0) {
4138
4605
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
4139
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4606
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4140
4607
  }
4141
4608
  currentTemplate = unresovedTemplates_1.find(function (template) {
4142
4609
  return template.dependentParameterNames.every(function (name) {
@@ -4146,14 +4613,14 @@ function executePipeline(options) {
4146
4613
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
4147
4614
  throw new UnexpectedError(
4148
4615
  // TODO: [🐎] DRY
4149
- spaceTrim$1(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
4616
+ spaceTrim$1(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
4150
4617
  .map(function (_a) {
4151
4618
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
4152
4619
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
4153
4620
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
4154
4621
  .join(' and '));
4155
4622
  })
4156
- .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameterNames_1.map(function (name) { return "- Parameter {".concat(name, "}"); }).join('\n')), "\n\n Note: This should be catched in `validatePipeline`\n "); }));
4623
+ .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameterNames_1.map(function (name) { return "- Parameter {".concat(name, "}"); }).join('\n')), "\n\n Note: This should be catched in `validatePipeline`\n "); }));
4157
4624
  case 1:
4158
4625
  if (!!currentTemplate) return [3 /*break*/, 3];
4159
4626
  /* [🤹‍♂️] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -4170,10 +4637,10 @@ function executePipeline(options) {
4170
4637
  llmTools: llmTools,
4171
4638
  onProgress: function (progress) {
4172
4639
  if (isReturned) {
4173
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(progress, null, 4)
4640
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(progress, null, 4)
4174
4641
  .split('\n')
4175
4642
  .map(function (line) { return "> ".concat(line); })
4176
- .join('\n')), "\n "); }));
4643
+ .join('\n')), "\n "); }));
4177
4644
  }
4178
4645
  if (onProgress) {
4179
4646
  onProgress(progress);
@@ -4181,7 +4648,7 @@ function executePipeline(options) {
4181
4648
  },
4182
4649
  settings: settings,
4183
4650
  $executionReport: executionReport,
4184
- pipelineIdentification: pipelineIdentification,
4651
+ pipelineIdentification: spaceTrim$1(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Template name: ").concat(currentTemplate.name, "\n Template title: ").concat(currentTemplate.title, "\n "); }),
4185
4652
  })
4186
4653
  .then(function (newParametersToPass) {
4187
4654
  parametersToPass = __assign(__assign({}, newParametersToPass), parametersToPass);
@@ -4273,6 +4740,9 @@ function executePipeline(options) {
4273
4740
  });
4274
4741
  });
4275
4742
  }
4743
+ /**
4744
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4745
+ */
4276
4746
 
4277
4747
  /**
4278
4748
  * Creates executor function from pipeline and execution tools.
@@ -4284,7 +4754,7 @@ function executePipeline(options) {
4284
4754
  function createPipelineExecutor(options) {
4285
4755
  var _this = this;
4286
4756
  var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
4287
- var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? MAX_EXECUTION_ATTEMPTS : _b, _c = settings.maxParallelCount, maxParallelCount = _c === void 0 ? MAX_PARALLEL_COUNT : _c, _d = settings.isVerbose, isVerbose = _d === void 0 ? IS_VERBOSE : _d, _e = settings.isNotPreparedWarningSupressed, isNotPreparedWarningSupressed = _e === void 0 ? false : _e;
4757
+ var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? MAX_EXECUTION_ATTEMPTS : _b, _c = settings.maxParallelCount, maxParallelCount = _c === void 0 ? MAX_PARALLEL_COUNT : _c, _d = settings.csvSettings, csvSettings = _d === void 0 ? DEFAULT_CSV_SETTINGS : _d, _e = settings.isVerbose, isVerbose = _e === void 0 ? IS_VERBOSE : _e, _f = settings.isNotPreparedWarningSupressed, isNotPreparedWarningSupressed = _f === void 0 ? false : _f;
4288
4758
  validatePipeline(pipeline);
4289
4759
  var pipelineIdentification = (function () {
4290
4760
  // Note: This is a 😐 implementation of [🚞]
@@ -4304,9 +4774,11 @@ function createPipelineExecutor(options) {
4304
4774
  else if (isNotPreparedWarningSupressed !== true) {
4305
4775
  console.warn(spaceTrim$1(function (block) { return "\n Pipeline is not prepared\n\n ".concat(block(pipelineIdentification), "\n\n It will be prepared ad-hoc before the first execution and **returned as `preparedPipeline` in `PipelineExecutorResult`**\n But it is recommended to prepare the pipeline during collection preparation\n\n @see more at https://ptbk.io/prepare-pipeline\n "); }));
4306
4776
  }
4777
+ var runCount = 0;
4307
4778
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
4308
4779
  return __generator(this, function (_a) {
4309
- return [2 /*return*/, executePipeline({
4780
+ runCount++;
4781
+ return [2 /*return*/, /* not await */ executePipeline({
4310
4782
  pipeline: pipeline,
4311
4783
  preparedPipeline: preparedPipeline,
4312
4784
  setPreparedPipeline: function (newPreparedPipeline) {
@@ -4315,10 +4787,11 @@ function createPipelineExecutor(options) {
4315
4787
  inputParameters: inputParameters,
4316
4788
  tools: tools,
4317
4789
  onProgress: onProgress,
4318
- pipelineIdentification: pipelineIdentification,
4790
+ pipelineIdentification: spaceTrim$1(function (block) { return "\n ".concat(block(pipelineIdentification), "\n ").concat(runCount === 1 ? '' : "Run #".concat(runCount), "\n "); }),
4319
4791
  settings: {
4320
4792
  maxExecutionAttempts: maxExecutionAttempts,
4321
4793
  maxParallelCount: maxParallelCount,
4794
+ csvSettings: csvSettings,
4322
4795
  isVerbose: isVerbose,
4323
4796
  isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
4324
4797
  },
@@ -4327,6 +4800,9 @@ function createPipelineExecutor(options) {
4327
4800
  }); };
4328
4801
  return pipelineExecutor;
4329
4802
  }
4803
+ /**
4804
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4805
+ */
4330
4806
 
4331
4807
  /**
4332
4808
  * @@@
@@ -4378,7 +4854,7 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4378
4854
  outputParameters = result.outputParameters;
4379
4855
  knowledgePiecesRaw = outputParameters.knowledgePieces;
4380
4856
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
4381
- // <- TODO: !!!!! Smarter split and filter out empty pieces
4857
+ // <- TODO: [main] !!!!! Smarter split and filter out empty pieces
4382
4858
  if (isVerbose) {
4383
4859
  console.info('knowledgeTextPieces:', knowledgeTextPieces);
4384
4860
  }
@@ -4436,8 +4912,13 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4436
4912
  case 6: return [3 /*break*/, 8];
4437
4913
  case 7:
4438
4914
  error_1 = _c.sent();
4915
+ // Note: Here is expected error:
4916
+ // > PipelineExecutionError: You have not provided any `LlmExecutionTools` that support model variant "EMBEDDING
4917
+ if (!(error_1 instanceof PipelineExecutionError)) {
4918
+ throw error_1;
4919
+ }
4439
4920
  // TODO: [🟥] Detect browser / node and make it colorfull
4440
- console.error(error_1);
4921
+ console.error(error_1, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
4441
4922
  return [3 /*break*/, 8];
4442
4923
  case 8: return [2 /*return*/, {
4443
4924
  name: name,
@@ -4458,7 +4939,7 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4458
4939
  });
4459
4940
  }
4460
4941
  /**
4461
- * TODO: [🐝][🔼] !!! Export via `@promptbook/markdown`
4942
+ * TODO: [🐝][🔼][main] !!! Export via `@promptbook/markdown`
4462
4943
  * TODO: [🪂] Do it in parallel 11:11
4463
4944
  * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4464
4945
  */
@@ -4482,7 +4963,7 @@ function prepareKnowledgePieces(knowledgeSources, options) {
4482
4963
  var partialPieces, pieces;
4483
4964
  return __generator(this, function (_a) {
4484
4965
  switch (_a.label) {
4485
- case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4966
+ case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝][main] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4486
4967
  options)];
4487
4968
  case 1:
4488
4969
  partialPieces = _a.sent();
@@ -4674,7 +5155,7 @@ function preparePersona(personaDescription, options) {
4674
5155
  });
4675
5156
  }
4676
5157
  /**
4677
- * TODO: [🔃] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
5158
+ * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4678
5159
  * TODO: [🏢] !! Check validity of `modelName` in pipeline
4679
5160
  * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4680
5161
  * TODO: [🏢] !! Check validity of `temperature` in pipeline
@@ -4723,7 +5204,7 @@ function prepareTemplates(pipeline, options) {
4723
5204
  case 0:
4724
5205
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
4725
5206
  templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4726
- // TODO: !!!!! Apply samples to each template (if missing and is for the template defined)
5207
+ // TODO: [main] !!!!! Apply samples to each template (if missing and is for the template defined)
4727
5208
  TODO_USE(parameters);
4728
5209
  templatesPrepared = new Array(
4729
5210
  // <- TODO: [🧱] Implement in a functional (not new Class) way
@@ -4755,7 +5236,7 @@ function prepareTemplates(pipeline, options) {
4755
5236
  /**
4756
5237
  * TODO: [🧠] Add context to each template (if missing)
4757
5238
  * TODO: [🧠] What is better name `prepareTemplate` or `prepareTemplateAndParameters`
4758
- * TODO: [♨] !!! Prepare index the samples and maybe templates
5239
+ * TODO: [♨][main] !!! Prepare index the samples and maybe templates
4759
5240
  * TODO: Write tests for `preparePipeline`
4760
5241
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4761
5242
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
@@ -4927,7 +5408,7 @@ var knowledgeCommandParser = {
4927
5408
  if (sourceContent === '') {
4928
5409
  throw new ParseError("Source is not defined");
4929
5410
  }
4930
- // TODO: !!!! Following checks should be applied every link in the `sourceContent`
5411
+ // TODO: [main] !!!! Following checks should be applied every link in the `sourceContent`
4931
5412
  if (sourceContent.startsWith('http://')) {
4932
5413
  throw new ParseError("Source is not secure");
4933
5414
  }
@@ -5112,7 +5593,7 @@ var templateCommandParser = {
5112
5593
  if (command.templateType === 'KNOWLEDGE') {
5113
5594
  knowledgeCommandParser.$applyToPipelineJson({
5114
5595
  type: 'KNOWLEDGE',
5115
- sourceContent: $templateJson.content, // <- TODO: [🐝] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
5596
+ sourceContent: $templateJson.content, // <- TODO: [🐝][main] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
5116
5597
  }, $pipelineJson);
5117
5598
  $templateJson.isTemplate = false;
5118
5599
  return;
@@ -5462,6 +5943,171 @@ function normalizeTo_SCREAMING_CASE(text) {
5462
5943
  * TODO: [🌺] Use some intermediate util splitWords
5463
5944
  */
5464
5945
 
5946
+ /**
5947
+ * @@@
5948
+ *
5949
+ * @param text @@@
5950
+ * @param _isFirstLetterCapital @@@
5951
+ * @returns @@@
5952
+ * @example 'helloWorld'
5953
+ * @example 'iLovePromptbook'
5954
+ * @public exported from `@promptbook/utils`
5955
+ */
5956
+ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
5957
+ var e_1, _a;
5958
+ if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
5959
+ var charType;
5960
+ var lastCharType = null;
5961
+ var normalizedName = '';
5962
+ try {
5963
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5964
+ var char = text_1_1.value;
5965
+ var normalizedChar = void 0;
5966
+ if (/^[a-z]$/.test(char)) {
5967
+ charType = 'LOWERCASE';
5968
+ normalizedChar = char;
5969
+ }
5970
+ else if (/^[A-Z]$/.test(char)) {
5971
+ charType = 'UPPERCASE';
5972
+ normalizedChar = char.toLowerCase();
5973
+ }
5974
+ else if (/^[0-9]$/.test(char)) {
5975
+ charType = 'NUMBER';
5976
+ normalizedChar = char;
5977
+ }
5978
+ else {
5979
+ charType = 'OTHER';
5980
+ normalizedChar = '';
5981
+ }
5982
+ if (!lastCharType) {
5983
+ if (_isFirstLetterCapital) {
5984
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
5985
+ }
5986
+ }
5987
+ else if (charType !== lastCharType &&
5988
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
5989
+ !(lastCharType === 'NUMBER') &&
5990
+ !(charType === 'NUMBER')) {
5991
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
5992
+ }
5993
+ normalizedName += normalizedChar;
5994
+ lastCharType = charType;
5995
+ }
5996
+ }
5997
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5998
+ finally {
5999
+ try {
6000
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
6001
+ }
6002
+ finally { if (e_1) throw e_1.error; }
6003
+ }
6004
+ return normalizedName;
6005
+ }
6006
+ /**
6007
+ * TODO: [🌺] Use some intermediate util splitWords
6008
+ */
6009
+
6010
+ /**
6011
+ * Removes quotes from a string
6012
+ *
6013
+ * Tip: This is very usefull for post-processing of the result of the LLM model
6014
+ * Note: This function removes only the same quotes from the beginning and the end of the string
6015
+ * Note: There are two simmilar functions:
6016
+ * - `removeQuotes` which removes only bounding quotes
6017
+ * - `unwrapResult` which removes whole introduce sentence
6018
+ *
6019
+ * @param text optionally quoted text
6020
+ * @returns text without quotes
6021
+ * @public exported from `@promptbook/utils`
6022
+ */
6023
+ function removeQuotes(text) {
6024
+ if (text.startsWith('"') && text.endsWith('"')) {
6025
+ return text.slice(1, -1);
6026
+ }
6027
+ if (text.startsWith('\'') && text.endsWith('\'')) {
6028
+ return text.slice(1, -1);
6029
+ }
6030
+ return text;
6031
+ }
6032
+
6033
+ /**
6034
+ * Function `validateParameterName` will @@@
6035
+ *
6036
+ * @param parameterName @@@
6037
+ * @returns @@@
6038
+ * @throws {ParseError} @@@
6039
+ * @private within the repository
6040
+ */
6041
+ function validateParameterName(parameterName) {
6042
+ var e_1, _a;
6043
+ var rawParameterName = parameterName;
6044
+ try {
6045
+ for (var _b = __values([
6046
+ ['`', '`'],
6047
+ ['{', '}'],
6048
+ ['[', ']'],
6049
+ ['(', ')'],
6050
+ ['<', '>'],
6051
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
6052
+ var _d = __read(_c.value, 2), start = _d[0], end = _d[1];
6053
+ if (parameterName.substring(0, 1) === start &&
6054
+ parameterName.substring(parameterName.length - 1, parameterName.length) === end
6055
+ // <- TODO: More universal that 1 character
6056
+ ) {
6057
+ parameterName = parameterName.substring(1, parameterName.length - 1);
6058
+ // <- TODO: More universal that 1 character
6059
+ }
6060
+ }
6061
+ }
6062
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6063
+ finally {
6064
+ try {
6065
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
6066
+ }
6067
+ finally { if (e_1) throw e_1.error; }
6068
+ }
6069
+ // TODO: [🐠] Following try-catch block should be part of common validators logic
6070
+ try {
6071
+ /*
6072
+ Note: We don't need to check for spaces because we are going to normalize the parameter name to camelCase
6073
+ if (parameterName.includes(' ')) {
6074
+ throw new ParseError(`Parameter name cannot contain spaces`);
6075
+ }
6076
+ */
6077
+ if (parameterName.includes('.')) {
6078
+ throw new ParseError("Parameter name cannot contain dots");
6079
+ }
6080
+ if (parameterName.includes('/') || parameterName.includes('\\')) {
6081
+ throw new ParseError("Parameter name cannot contain slashes");
6082
+ }
6083
+ if (parameterName.includes('(') ||
6084
+ parameterName.includes(')') ||
6085
+ parameterName.includes('{') ||
6086
+ parameterName.includes('}') ||
6087
+ parameterName.includes('[') ||
6088
+ parameterName.includes(']')) {
6089
+ throw new ParseError("Parameter name cannot contain braces");
6090
+ }
6091
+ parameterName = removeDiacritics(parameterName);
6092
+ parameterName = removeEmojis(parameterName);
6093
+ parameterName = removeQuotes(parameterName);
6094
+ parameterName = normalizeTo_camelCase(parameterName);
6095
+ if (parameterName === '') {
6096
+ throw new ParseError("Parameter name cannot be empty");
6097
+ }
6098
+ if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
6099
+ throw new ParseError("{".concat(parameterName, "} is a reserved parameter name"));
6100
+ }
6101
+ }
6102
+ catch (error) {
6103
+ if (!(error instanceof ParseError)) {
6104
+ throw error;
6105
+ }
6106
+ throw new ParseError(spaceTrim(function (block) { return "\n ".concat(block(error.message), "\n\n Tried to validate parameter name:\n ").concat(block(rawParameterName), "\n "); }));
6107
+ }
6108
+ return parameterName;
6109
+ }
6110
+
5465
6111
  /**
5466
6112
  * Parses the foreach command
5467
6113
  *
@@ -5491,15 +6137,16 @@ var foreachCommandParser = {
5491
6137
  /**
5492
6138
  * Link to discussion
5493
6139
  */
5494
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
6140
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/148',
5495
6141
  /**
5496
6142
  * Example usages of the FOREACH command
5497
6143
  */
5498
6144
  examples: [
5499
- 'FOREACH List Line `{customers}` -> `{customer}`',
5500
- 'FOR List Line `{customers}` -> `{customer}`',
5501
- 'EACH List Line `{customers}` -> `{customer}`',
5502
- // <- TODO: [🍭] !!!!!! More
6145
+ 'FOREACH Text Line `{customers}` -> `{customer}`',
6146
+ 'FOREACH Csv Cell `{customers}` -> `{cell}`',
6147
+ 'FOREACH Csv Row `{customers}` -> `{firstName}`, `{lastName}`, `+{email}`',
6148
+ 'FOR Text Line `{customers}` -> `{customer}`',
6149
+ 'EACH Text Line `{customers}` -> `{customer}`',
5503
6150
  ],
5504
6151
  /**
5505
6152
  * Parses the FOREACH command
@@ -5507,55 +6154,75 @@ var foreachCommandParser = {
5507
6154
  parse: function (input) {
5508
6155
  var args = input.args;
5509
6156
  var formatName = normalizeTo_SCREAMING_CASE(args[0] || '');
5510
- var cellName = normalizeTo_SCREAMING_CASE(args[1] || '');
5511
- var parameterNameWrapped = args[2];
6157
+ var subformatName = normalizeTo_SCREAMING_CASE(args[1] || '');
6158
+ var parameterNameArg = args[2] || '';
5512
6159
  var assignSign = args[3];
5513
- var subparameterNameWrapped = args[4];
5514
- if (![
5515
- 'LIST',
5516
- 'CSV',
5517
- // <- TODO: [🏢] Unhardcode formats
5518
- ].includes(formatName)) {
5519
- console.info({ args: args, formatName: formatName });
5520
- throw new Error("Unsupported format \"".concat(formatName, "\""));
6160
+ var formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
6161
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(formatName);
6162
+ });
6163
+ if (formatDefinition === undefined) {
6164
+ throw new ParseError(spaceTrim(function (block) { return "\n Unsupported format \"".concat(formatName, "\"\n\n Available formats:\n ").concat(block(FORMAT_DEFINITIONS.map(function (formatDefinition) { return formatDefinition.formatName; })
6165
+ .map(function (formatName) { return "- ".concat(formatName); })
6166
+ .join('\n')), "\n "); }));
5521
6167
  // <- TODO: [🏢] List all supported format names
5522
6168
  }
5523
- if (![
5524
- 'LINE',
5525
- 'ROW',
5526
- 'COLUMN',
5527
- 'CELL',
5528
- // <- TODO: [🏢] Unhardcode format cells
5529
- ].includes(cellName)) {
5530
- console.info({ args: args, cellName: cellName });
5531
- throw new Error("Format ".concat(formatName, " does not support cell \"").concat(cellName, "\""));
5532
- // <- TODO: [🏢] List all supported cell names for the format
6169
+ var subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
6170
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(subformatName);
6171
+ });
6172
+ if (subvalueDefinition === undefined) {
6173
+ throw new ParseError(spaceTrim(function (block) { return "\n Unsupported subformat name \"".concat(subformatName, "\" for format \"").concat(formatName, "\"\n\n Available subformat names for format \"").concat(formatDefinition.formatName, "\":\n ").concat(block(formatDefinition.subvalueDefinitions
6174
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
6175
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
6176
+ .join('\n')), "\n "); }));
6177
+ // <- TODO: [🏢] List all supported subformat names for the format
5533
6178
  }
5534
6179
  if (assignSign !== '->') {
5535
- console.info({ args: args, assignSign: assignSign });
5536
- throw new Error("FOREACH command must have '->' to assign the value to the parameter");
5537
- }
5538
- // TODO: !!!!!! Replace with propper parameter name validation
5539
- if ((parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(0, 1)) !== '{' ||
5540
- (parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(parameterNameWrapped.length - 1, parameterNameWrapped.length)) !== '}') {
5541
- console.info({ args: args, parameterNameWrapped: parameterNameWrapped }, parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(0, 1), parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(parameterNameWrapped.length - 1, parameterNameWrapped.length));
5542
- throw new Error("!!!!!! 1 Here will be error (with rules and precise error) from validateParameterName");
5543
- }
5544
- var parameterName = parameterNameWrapped.substring(1, parameterNameWrapped.length - 1);
5545
- // TODO: !!!!!! Replace with propper parameter name validation
5546
- if ((subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(0, 1)) !== '{' ||
5547
- (subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(subparameterNameWrapped.length - 1, subparameterNameWrapped.length)) !==
5548
- '}') {
5549
- console.info({ args: args, subparameterNameWrapped: subparameterNameWrapped });
5550
- throw new Error("!!!!!! 2 Here will be error (with rules and precise error) from validateParameterName");
5551
- }
5552
- var subparameterName = subparameterNameWrapped.substring(1, subparameterNameWrapped.length - 1);
6180
+ throw new ParseError("FOREACH command must have '->' to assign the value to the parameter");
6181
+ }
6182
+ var parameterName = validateParameterName(parameterNameArg);
6183
+ var outputSubparameterName = null;
6184
+ // TODO: [4] DRY
6185
+ var inputSubparameterNames = args
6186
+ .slice(4)
6187
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6188
+ .filter(function (parameterName) { return !parameterName.includes('+'); })
6189
+ .filter(function (parameterName) { return parameterName !== ''; })
6190
+ .map(validateParameterName);
6191
+ // TODO: [4] DRY
6192
+ var outputSubparameterNames = args
6193
+ .slice(4)
6194
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6195
+ .filter(function (parameterName) { return parameterName.includes('+'); })
6196
+ .map(function (parameterName) { return parameterName.split('+').join(''); })
6197
+ .map(validateParameterName);
6198
+ if (outputSubparameterNames.length === 1) {
6199
+ outputSubparameterName = outputSubparameterNames[0];
6200
+ }
6201
+ else if (outputSubparameterNames.length > 1) {
6202
+ throw new ParseError("FOREACH command can not have more than one output subparameter");
6203
+ }
6204
+ if (inputSubparameterNames.length === 0) {
6205
+ throw new ParseError("FOREACH command must have at least one input subparameter");
6206
+ }
6207
+ if (outputSubparameterName === null) {
6208
+ // TODO: Following code should be unhardcoded from here and moved to the format definition
6209
+ if (formatName === 'CSV' && subformatName === 'CELL') {
6210
+ outputSubparameterName = 'newCell';
6211
+ }
6212
+ else if (formatName === 'TEXT' && subformatName === 'LINE') {
6213
+ outputSubparameterName = 'newLine';
6214
+ }
6215
+ else {
6216
+ throw new ParseError(spaceTrim("\n FOREACH ".concat(formatName, " ").concat(subformatName, " must specify output subparameter\n\n Correct example:\n - FOREACH ").concat(formatName, " ").concat(subformatName, " {").concat(parameterName, "} -> {inputSubparameterName1}, {inputSubparameterName2}, +{outputSubparameterName}\n\n ")));
6217
+ }
6218
+ }
5553
6219
  return {
5554
6220
  type: 'FOREACH',
5555
6221
  formatName: formatName,
5556
- cellName: cellName,
6222
+ subformatName: subformatName,
5557
6223
  parameterName: parameterName,
5558
- subparameterName: subparameterName,
6224
+ inputSubparameterNames: inputSubparameterNames,
6225
+ outputSubparameterName: outputSubparameterName,
5559
6226
  };
5560
6227
  },
5561
6228
  /**
@@ -5564,11 +6231,17 @@ var foreachCommandParser = {
5564
6231
  * Note: `$` is used to indicate that this function mutates given `templateJson`
5565
6232
  */
5566
6233
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5567
- var formatName = command.formatName, cellName = command.cellName, parameterName = command.parameterName, subparameterName = command.subparameterName;
5568
- // TODO: !!!!!! Detect double use
5569
- // TODO: !!!!!! Detect usage with JOKER and don't allow it
5570
- $templateJson.foreach = { formatName: formatName, cellName: cellName, parameterName: parameterName, subparameterName: subparameterName };
5571
- keepUnused($pipelineJson); // <- TODO: !!!!!! BUT Maybe register subparameter from foreach into parameters of the pipeline
6234
+ var formatName = command.formatName, subformatName = command.subformatName, parameterName = command.parameterName, inputSubparameterNames = command.inputSubparameterNames, outputSubparameterName = command.outputSubparameterName;
6235
+ // TODO: [🍭] Detect double use
6236
+ // TODO: [🍭] Detect usage with JOKER and don't allow it
6237
+ $templateJson.foreach = {
6238
+ formatName: formatName,
6239
+ subformatName: subformatName,
6240
+ parameterName: parameterName,
6241
+ inputSubparameterNames: inputSubparameterNames,
6242
+ outputSubparameterName: outputSubparameterName,
6243
+ };
6244
+ keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
5572
6245
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
5573
6246
  },
5574
6247
  /**
@@ -5591,8 +6264,7 @@ var foreachCommandParser = {
5591
6264
  },
5592
6265
  };
5593
6266
  /**
5594
- * TODO: !!!!!! Comment console logs
5595
- * TODO: [🍭] !!!!!! Make .ptbk.md file with examples of the FOREACH command and also with wrong parsing and logic
6267
+ * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
5596
6268
  */
5597
6269
 
5598
6270
  /**
@@ -5702,12 +6374,11 @@ var jokerCommandParser = {
5702
6374
  */
5703
6375
  parse: function (input) {
5704
6376
  var args = input.args;
5705
- // TODO: !!!!!! Replace with propper parameter name validation
5706
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5707
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5708
- throw new ParseError("Invalid joker");
6377
+ if (args.length !== 1) {
6378
+ throw new ParseError("JOKE command expects exactly one parameter name");
5709
6379
  }
5710
- var parameterName = parametersMatch.groups.parameterName;
6380
+ var parameterNameArg = args[0] || '';
6381
+ var parameterName = validateParameterName(parameterNameArg);
5711
6382
  return {
5712
6383
  type: 'JOKER',
5713
6384
  parameterName: parameterName,
@@ -5782,6 +6453,9 @@ var modelCommandParser = {
5782
6453
  */
5783
6454
  parse: function (input) {
5784
6455
  var args = input.args, normalized = input.normalized;
6456
+ var availableVariantsMessage = spaceTrim(function (block) { return "\n Available variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) {
6457
+ return "- ".concat(variantName).concat(variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)');
6458
+ }).join('\n')), "\n "); });
5785
6459
  // TODO: Make this more elegant and dynamically
5786
6460
  if (normalized.startsWith('MODEL_VARIANT')) {
5787
6461
  if (normalized === 'MODEL_VARIANT_CHAT') {
@@ -5797,17 +6471,13 @@ var modelCommandParser = {
5797
6471
  key: 'modelVariant',
5798
6472
  value: 'COMPLETION',
5799
6473
  };
6474
+ // <- Note: [🤖]
5800
6475
  }
5801
6476
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
5802
- return {
5803
- type: 'MODEL',
5804
- key: 'modelVariant',
5805
- value: 'EMBEDDING',
5806
- };
5807
- // <- Note: [🤖]
6477
+ spaceTrim(function (block) { return "\n Embedding model can not be used in pipeline\n\n ".concat(block(availableVariantsMessage), "\n "); });
5808
6478
  }
5809
6479
  else {
5810
- throw new ParseError(spaceTrim(function (block) { return "\n Unknown model variant in command:\n\n Supported variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) { return "- ".concat(variantName); }).join('\n')), "\n "); }));
6480
+ throw new ParseError(spaceTrim(function (block) { return "\n Unknown model variant in command:\n\n ".concat(block(availableVariantsMessage), "\n "); }));
5811
6481
  }
5812
6482
  }
5813
6483
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5932,14 +6602,13 @@ var parameterCommandParser = {
5932
6602
  * Parses the PARAMETER command
5933
6603
  */
5934
6604
  parse: function (input) {
5935
- var normalized = input.normalized, raw = input.raw;
5936
- var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5937
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5938
- throw new ParseError("Invalid parameter");
5939
- }
5940
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5941
- if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5942
- throw new ParseError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
6605
+ var normalized = input.normalized, args = input.args, raw = input.raw;
6606
+ var parameterNameRaw = args.shift() || '';
6607
+ var parameterDescriptionRaw = args.join(' ');
6608
+ // <- TODO: When [🥶] fixed, change to:
6609
+ // > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
6610
+ if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
6611
+ throw new ParseError(spaceTrim(function (block) { return "\n Parameter {".concat(parameterNameRaw, "} can not contain another parameter in description\n\n The description:\n ").concat(block(parameterDescriptionRaw), "\n "); }));
5943
6612
  }
5944
6613
  var isInput = normalized.startsWith('INPUT');
5945
6614
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5947,11 +6616,12 @@ var parameterCommandParser = {
5947
6616
  isInput = false;
5948
6617
  isOutput = false;
5949
6618
  }
5950
- // TODO: !!!!!! Add parameter name validation
6619
+ var parameterName = validateParameterName(parameterNameRaw);
6620
+ var parameterDescription = parameterDescriptionRaw.trim() || null;
5951
6621
  return {
5952
6622
  type: 'PARAMETER',
5953
6623
  parameterName: parameterName,
5954
- parameterDescription: parameterDescription.trim() || null,
6624
+ parameterDescription: parameterDescription,
5955
6625
  isInput: isInput,
5956
6626
  isOutput: isOutput,
5957
6627
  };
@@ -6276,6 +6946,7 @@ var promptbookVersionCommandParser = {
6276
6946
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6277
6947
  */
6278
6948
  $applyToPipelineJson: function (command, $pipelineJson) {
6949
+ // TODO: Warn if the version is overridden
6279
6950
  $pipelineJson.promptbookVersion = command.promptbookVersion;
6280
6951
  },
6281
6952
  /**
@@ -6758,7 +7429,9 @@ function parseCommand(raw, usagePlace) {
6758
7429
  for (var commandNameSegmentsCount = 0; commandNameSegmentsCount < Math.min(items.length, 3); commandNameSegmentsCount++) {
6759
7430
  var commandNameRaw = items.slice(0, commandNameSegmentsCount + 1).join('_');
6760
7431
  var args = items.slice(commandNameSegmentsCount + 1);
6761
- var rawArgs = raw.substring(commandNameRaw.length).trim();
7432
+ var rawArgs = raw
7433
+ .substring(commandNameRaw.length)
7434
+ .trim();
6762
7435
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6763
7436
  if (command !== null) {
6764
7437
  return command;
@@ -6769,7 +7442,9 @@ function parseCommand(raw, usagePlace) {
6769
7442
  {
6770
7443
  var commandNameRaw = items.slice(-1).join('_');
6771
7444
  var args = items.slice(0, -1); // <- Note: This is probbably not correct
6772
- var rawArgs = raw.substring(0, raw.length - commandNameRaw.length).trim();
7445
+ var rawArgs = raw
7446
+ .substring(0, raw.length - commandNameRaw.length)
7447
+ .trim();
6773
7448
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6774
7449
  if (command !== null) {
6775
7450
  return command;
@@ -6909,7 +7584,7 @@ function extractAllListItemsFromMarkdown(markdown) {
6909
7584
  function extractOneBlockFromMarkdown(markdown) {
6910
7585
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
6911
7586
  if (codeBlocks.length !== 1) {
6912
- throw new ParseError(spaceTrim(function (block) { return "\n There should be exactly 1 code block, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
7587
+ throw new ParseError(spaceTrim(function (block) { return "\n There should be exactly 1 code block in template, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
6913
7588
  }
6914
7589
  return codeBlocks[0];
6915
7590
  }
@@ -7096,7 +7771,7 @@ function pipelineStringToJsonSync(pipelineString) {
7096
7771
  var $pipelineJson = {
7097
7772
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
7098
7773
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
7099
- promptbookVersion: PROMPTBOOK_VERSION,
7774
+ promptbookVersion: undefined /* <- Note: By default no explicit version */,
7100
7775
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
7101
7776
  parameters: [],
7102
7777
  templates: [],
@@ -7387,7 +8062,7 @@ function pipelineStringToJsonSync(pipelineString) {
7387
8062
  return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
7388
8063
  }
7389
8064
  /**
7390
- * TODO: !!!! Warn if used only sync version
8065
+ * TODO: [main] !!!! Warn if used only sync version
7391
8066
  * TODO: [🚞] Report here line/column of error
7392
8067
  * TODO: Use spaceTrim more effectively
7393
8068
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
@@ -7468,70 +8143,6 @@ function addAutoGeneratedSection(content, options) {
7468
8143
  * TODO: [🏛] This can be part of markdown builder
7469
8144
  */
7470
8145
 
7471
- /**
7472
- * @@@
7473
- *
7474
- * @param text @@@
7475
- * @param _isFirstLetterCapital @@@
7476
- * @returns @@@
7477
- * @example 'helloWorld'
7478
- * @example 'iLovePromptbook'
7479
- * @public exported from `@promptbook/utils`
7480
- */
7481
- function normalizeTo_camelCase(text, _isFirstLetterCapital) {
7482
- var e_1, _a;
7483
- if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
7484
- var charType;
7485
- var lastCharType = null;
7486
- var normalizedName = '';
7487
- try {
7488
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
7489
- var char = text_1_1.value;
7490
- var normalizedChar = void 0;
7491
- if (/^[a-z]$/.test(char)) {
7492
- charType = 'LOWERCASE';
7493
- normalizedChar = char;
7494
- }
7495
- else if (/^[A-Z]$/.test(char)) {
7496
- charType = 'UPPERCASE';
7497
- normalizedChar = char.toLowerCase();
7498
- }
7499
- else if (/^[0-9]$/.test(char)) {
7500
- charType = 'NUMBER';
7501
- normalizedChar = char;
7502
- }
7503
- else {
7504
- charType = 'OTHER';
7505
- normalizedChar = '';
7506
- }
7507
- if (!lastCharType) {
7508
- if (_isFirstLetterCapital) {
7509
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
7510
- }
7511
- }
7512
- else if (charType !== lastCharType &&
7513
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
7514
- !(lastCharType === 'NUMBER') &&
7515
- !(charType === 'NUMBER')) {
7516
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
7517
- }
7518
- normalizedName += normalizedChar;
7519
- lastCharType = charType;
7520
- }
7521
- }
7522
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
7523
- finally {
7524
- try {
7525
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
7526
- }
7527
- finally { if (e_1) throw e_1.error; }
7528
- }
7529
- return normalizedName;
7530
- }
7531
- /**
7532
- * TODO: [🌺] Use some intermediate util splitWords
7533
- */
7534
-
7535
8146
  /**
7536
8147
  * Creates a Mermaid graph based on the promptbook
7537
8148
  *
@@ -7588,9 +8199,9 @@ function renderPromptbookMermaid(pipelineJson, options) {
7588
8199
  return promptbookMermaid;
7589
8200
  }
7590
8201
  /**
7591
- * TODO: !!!!!! FOREACH in mermaid graph
7592
- * TODO: !!!!!! Knowledge in mermaid graph
7593
- * TODO: !!!!!! Personas in mermaid graph
8202
+ * TODO: !!!!! FOREACH in mermaid graph
8203
+ * TODO: !!!!! Knowledge in mermaid graph
8204
+ * TODO: !!!!! Personas in mermaid graph
7594
8205
  * TODO: Maybe use some Mermaid package instead of string templating
7595
8206
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
7596
8207
  */
@@ -7665,7 +8276,7 @@ function isSerializableAsJson(value) {
7665
8276
  }
7666
8277
  }
7667
8278
  /**
7668
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
8279
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
7669
8280
  * TODO: [🧠][💺] Can be done this on type-level?
7670
8281
  */
7671
8282
 
@@ -7732,21 +8343,41 @@ function usageToWorktime(usage) {
7732
8343
  * @public exported from `@promptbook/core`
7733
8344
  */
7734
8345
  function usageToHuman(usage) {
7735
- var report = 'Usage:';
8346
+ var reportItems = [];
7736
8347
  var uncertainNumberToHuman = function (_a) {
7737
8348
  var value = _a.value, isUncertain = _a.isUncertain;
7738
8349
  return "".concat(isUncertain ? 'approximately ' : '').concat(Math.round(value * 100) / 100);
7739
8350
  };
7740
- report += '\n' + "- Cost ".concat(uncertainNumberToHuman(usage.price), " USD");
7741
- report += '\n' + "- Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time");
7742
- return spaceTrim(report);
8351
+ if (usage.price.value > 0.01
8352
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻] Configure negligible value - default value to config + value to `UsageToHumanSettings`
8353
+ ) {
8354
+ reportItems.push("Cost ".concat(uncertainNumberToHuman(usage.price), " USD"));
8355
+ }
8356
+ else {
8357
+ reportItems.push("Negligible cost");
8358
+ }
8359
+ var worktime = usageToWorktime(usage);
8360
+ if (worktime.value >
8361
+ 1 / 60
8362
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻]
8363
+ ) {
8364
+ reportItems.push("Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time"));
8365
+ // TODO: [🍓][🧞‍♂️] Show minutes, seconds, days NOT 0.1 hours
8366
+ }
8367
+ if (usage.output.charactersCount.value > 0) {
8368
+ reportItems.push("Written ".concat(uncertainNumberToHuman(usage.output.charactersCount), " characters"));
8369
+ }
8370
+ if (reportItems.length === 0) {
8371
+ // Note: For negligible usage, we report at least something
8372
+ reportItems.push('Negligible');
8373
+ }
8374
+ return spaceTrim(function (block) { return "\n Usage:\n ".concat(block(reportItems.map(function (item) { return "- ".concat(item); }).join('\n')), "\n "); });
7743
8375
  }
7744
8376
  /**
7745
- * TODO: Use "$1" not "1 USD"
7746
- * TODO: Use markdown formatting like "Cost approximately **$1**"
7747
- * TODO: Report in minutes, seconds, days NOT 0.1 hours
8377
+ * TODO: [🍓][🧞‍♂️] Use "$1" not "1 USD"
8378
+ * TODO: [🍓][🧞‍♂️] Use markdown formatting like "Cost approximately **$1**"
8379
+ * TODO: [🍓][🧞‍♂️] Report in minutes, seconds, days NOT 0.1 hours
7748
8380
  * TODO: [🧠] Maybe make from `uncertainNumberToHuman` separate exported utility
7749
- * TODO: When negligible usage, report "Negligible" or just don't report it
7750
8381
  * TODO: [🧠] Maybe use "~" instead of "approximately"
7751
8382
  * TODO: [🏛] Maybe make some markdown builder
7752
8383
  */
@@ -8395,8 +9026,8 @@ function formatNumber(value) {
8395
9026
  */
8396
9027
  function createMarkdownTable(table) {
8397
9028
  var columnWidths = table.reduce(function (widths, row) {
8398
- row.forEach(function (cell, columnIndex) {
8399
- var cellLength = cell.length;
9029
+ row.forEach(function (subformat, columnIndex) {
9030
+ var cellLength = subformat.length;
8400
9031
  if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
8401
9032
  widths[columnIndex] = cellLength;
8402
9033
  }
@@ -8404,12 +9035,12 @@ function createMarkdownTable(table) {
8404
9035
  return widths;
8405
9036
  }, []);
8406
9037
  var header = "| ".concat(table[0]
8407
- .map(function (cell, columnIndex) { return cell.padEnd(columnWidths[columnIndex]); })
9038
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
8408
9039
  .join(' | '), " |");
8409
9040
  var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
8410
9041
  var rows = table.slice(1).map(function (row) {
8411
- var paddedRow = row.map(function (cell, columnIndex) {
8412
- return cell.padEnd(columnWidths[columnIndex]);
9042
+ var paddedRow = row.map(function (subformat, columnIndex) {
9043
+ return subformat.padEnd(columnWidths[columnIndex]);
8413
9044
  });
8414
9045
  return "| ".concat(paddedRow.join(' | '), " |");
8415
9046
  });
@@ -8685,5 +9316,5 @@ function executionReportJsonToString(executionReportJson, options) {
8685
9316
  * TODO: [🧠] Should be in generated file GENERATOR_WARNING
8686
9317
  */
8687
9318
 
8688
- export { $llmToolsMetadataRegister, $llmToolsRegister, CLAIM, CallbackInterfaceTools, CollectionError, DEFAULT_REMOTE_URL, DEFAULT_REMOTE_URL_PATH, ERRORS, EXECUTIONS_CACHE_DIRNAME, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, IS_VERBOSE, LimitReachedError, MAX_EXECUTION_ATTEMPTS, MAX_FILENAME_LENGTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, MAX_PARALLEL_COUNT, MODEL_VARIANTS, MemoryStorage, NotFoundError, NotYetImplementedError, PIPELINE_COLLECTION_BASE_FILENAME, PROMPTBOOK_VERSION, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, RESERVED_PARAMETER_NAMES, TemplateTypes, UnexpectedError, ZERO_USAGE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _OpenAiMetadataRegistration, addUsage, assertsExecutionSuccessful, cacheLlmTools, collectionToJson, countTotalUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, isPassingExpectations, isPipelinePrepared, joinLlmExecutionTools, limitTotalUsage, pipelineJsonToString, pipelineStringToJson, pipelineStringToJsonSync, prepareKnowledgeFromMarkdown, prepareKnowledgePieces, preparePersona, preparePipeline, prepareTemplates, prettifyPipelineString, stringifyPipelineJson, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline };
9319
+ export { $llmToolsMetadataRegister, $llmToolsRegister, AbstractFormatError, CLAIM, CallbackInterfaceTools, CollectionError, CsvFormatDefinition, CsvFormatError, DEFAULT_CSV_SETTINGS, DEFAULT_REMOTE_URL, DEFAULT_REMOTE_URL_PATH, ERRORS, EXECUTIONS_CACHE_DIRNAME, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, IS_VERBOSE, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_EXECUTION_ATTEMPTS, MAX_FILENAME_LENGTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, MAX_PARALLEL_COUNT, MODEL_VARIANTS, MemoryStorage, NotFoundError, NotYetImplementedError, PIPELINE_COLLECTION_BASE_FILENAME, PROMPTBOOK_VERSION, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, RESERVED_PARAMETER_NAMES, TemplateTypes, TextFormatDefinition, UnexpectedError, ZERO_USAGE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _OpenAiMetadataRegistration, addUsage, assertsExecutionSuccessful, cacheLlmTools, collectionToJson, countTotalUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, isPassingExpectations, isPipelinePrepared, joinLlmExecutionTools, limitTotalUsage, pipelineJsonToString, pipelineStringToJson, pipelineStringToJsonSync, prepareKnowledgeFromMarkdown, prepareKnowledgePieces, preparePersona, preparePipeline, prepareTemplates, prettifyPipelineString, stringifyPipelineJson, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline };
8689
9320
  //# sourceMappingURL=index.es.js.map