@promptbook/core 0.69.0-7 → 0.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +4 -1
  2. package/esm/index.es.js +1550 -867
  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 +45 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorSettings.d.ts +10 -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 +5 -2
  25. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +3 -0
  26. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +15 -0
  27. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +74 -0
  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/anthropic-claude-models.d.ts +1 -1
  44. package/esm/typings/src/llm-providers/anthropic-claude/createAnthropicClaudeExecutionTools.d.ts +2 -2
  45. package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +2 -2
  46. package/esm/typings/src/llm-providers/openai/playground/playground.d.ts +1 -1
  47. package/esm/typings/src/personas/preparePersona.d.ts +1 -1
  48. package/esm/typings/src/prepare/isPipelinePrepared.d.ts +1 -1
  49. package/esm/typings/src/prepare/prepareTemplates.d.ts +1 -1
  50. package/esm/typings/src/types/PipelineJson/ParameterJson.d.ts +1 -1
  51. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +1 -1
  52. package/esm/typings/src/types/execution-report/ExecutionReportJson.d.ts +0 -3
  53. package/esm/typings/src/types/execution-report/executionReportJsonToString.d.ts +2 -1
  54. package/esm/typings/src/types/typeAliases.d.ts +1 -1
  55. package/esm/typings/src/utils/expectation-counters/index.d.ts +3 -0
  56. package/esm/typings/src/utils/organization/{f.d.ts → empty_object.d.ts} +5 -1
  57. package/esm/typings/src/utils/organization/just_empty_object.d.ts +12 -0
  58. package/esm/typings/src/utils/{extractParameterNames.d.ts → parameters/extractParameterNames.d.ts} +2 -2
  59. package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +27 -0
  60. package/esm/typings/src/utils/{replaceParameters.d.ts → parameters/replaceParameters.d.ts} +2 -2
  61. package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +1 -1
  62. package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +1 -1
  63. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +10 -0
  64. package/package.json +17 -12
  65. package/umd/index.umd.js +1558 -870
  66. package/umd/index.umd.js.map +1 -1
  67. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatCell.d.ts +0 -30
  68. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempt.d.ts +0 -30
  69. package/esm/typings/src/formats/list/ListFormatDefinition.d.ts +0 -16
  70. /package/esm/typings/src/utils/{extractParameterNames.test.d.ts → parameters/extractParameterNames.test.d.ts} +0 -0
  71. /package/esm/typings/src/{execution/utils/usageToHuman.test.d.ts → utils/parameters/mapAvailableToExpectedParameters.test.d.ts} +0 -0
  72. /package/esm/typings/src/utils/{replaceParameters.test.d.ts → parameters/replaceParameters.test.d.ts} +0 -0
  73. /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-6';
14
- // TODO: !!!! List here all the versions and annotate + put into script
14
+ var PROMPTBOOK_VERSION = '0.69.0-21';
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
 
@@ -652,13 +653,13 @@ var IMMEDIATE_TIME = 10;
652
653
  *
653
654
  * @public exported from `@promptbook/core`
654
655
  */
655
- var MAX_PARALLEL_COUNT = 5;
656
+ var MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹‍♂️]
656
657
  /**
657
658
  * The maximum number of attempts to execute LLM task before giving up
658
659
  *
659
660
  * @public exported from `@promptbook/core`
660
661
  */
661
- var MAX_EXECUTION_ATTEMPTS = 3;
662
+ var MAX_EXECUTION_ATTEMPTS = 3; // <- TODO: [🤹‍♂️]
662
663
  /**
663
664
  * The maximum length of the (generated) filename
664
665
  *
@@ -667,14 +668,14 @@ var MAX_EXECUTION_ATTEMPTS = 3;
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-6",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-6",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-6",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-6",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`
@@ -2377,6 +2390,23 @@ function isPipelinePrepared(pipeline) {
2377
2390
  * - [♨] Are templates prepared
2378
2391
  */
2379
2392
 
2393
+ /**
2394
+ * Serializes an error into a [🚉] JSON-serializable object
2395
+ *
2396
+ * @public exported from `@promptbook/utils`
2397
+ */
2398
+ function serializeError(error) {
2399
+ var name = error.name, message = error.message, stack = error.stack;
2400
+ if (!__spreadArray(['Error'], __read(Object.keys(ERRORS)), false).includes(name)) {
2401
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
2402
+ }
2403
+ return {
2404
+ name: name,
2405
+ message: message,
2406
+ stack: stack,
2407
+ };
2408
+ }
2409
+
2380
2410
  /**
2381
2411
  * Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
2382
2412
  *
@@ -2403,9 +2433,10 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2403
2433
  });
2404
2434
  Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2405
2435
  get: function () {
2406
- return this.llmExecutionTools
2407
- .map(function (tools, index) { return "".concat(index + 1, ") ").concat(tools.title, " ").concat(tools.description || ''); })
2408
- .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');
2409
2440
  },
2410
2441
  enumerable: false,
2411
2442
  configurable: true
@@ -2603,9 +2634,7 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2603
2634
  throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
2604
2635
  }
2605
2636
  else {
2606
- 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
2607
- .map(function (tools) { return "- ".concat(tools.title, " ").concat(tools.description || ''); })
2608
- .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 "); }));
2609
2638
  }
2610
2639
  }
2611
2640
  });
@@ -2670,23 +2699,6 @@ function joinLlmExecutionTools() {
2670
2699
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
2671
2700
  */
2672
2701
 
2673
- /**
2674
- * Serializes an error into a [🚉] JSON-serializable object
2675
- *
2676
- * @public exported from `@promptbook/utils`
2677
- */
2678
- function serializeError(error) {
2679
- var name = error.name, message = error.message, stack = error.stack;
2680
- if (!__spreadArray(['Error'], __read(Object.keys(ERRORS)), false).includes(name)) {
2681
- throw new UnexpectedError(spaceTrim(function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
2682
- }
2683
- return {
2684
- name: name,
2685
- message: message,
2686
- stack: stack,
2687
- };
2688
- }
2689
-
2690
2702
  /**
2691
2703
  * Takes an item or an array of items and returns an array of items
2692
2704
  *
@@ -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;
@@ -2825,315 +2849,708 @@ function extractParameterNamesFromTemplate(template) {
2825
2849
  */
2826
2850
 
2827
2851
  /**
2828
- * Function isValidJsonString will tell you if the string is valid JSON or not
2852
+ * Create difference set of two sets.
2829
2853
  *
2854
+ * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
2830
2855
  * @public exported from `@promptbook/utils`
2831
2856
  */
2832
- function isValidJsonString(value /* <- [👨‍⚖️] */) {
2857
+ function difference(a, b, isEqual) {
2858
+ var e_1, _a;
2859
+ if (isEqual === void 0) { isEqual = function (a, b) { return a === b; }; }
2860
+ var diff = new Set();
2861
+ var _loop_1 = function (itemA) {
2862
+ if (!Array.from(b).some(function (itemB) { return isEqual(itemA, itemB); })) {
2863
+ diff.add(itemA);
2864
+ }
2865
+ };
2833
2866
  try {
2834
- JSON.parse(value);
2835
- return true;
2836
- }
2837
- catch (error) {
2838
- if (!(error instanceof Error)) {
2839
- throw error;
2867
+ for (var _b = __values(Array.from(a)), _c = _b.next(); !_c.done; _c = _b.next()) {
2868
+ var itemA = _c.value;
2869
+ _loop_1(itemA);
2840
2870
  }
2841
- if (error.message.includes('Unexpected token')) {
2842
- return false;
2871
+ }
2872
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2873
+ finally {
2874
+ try {
2875
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2843
2876
  }
2844
- return false;
2877
+ finally { if (e_1) throw e_1.error; }
2845
2878
  }
2879
+ return diff;
2846
2880
  }
2881
+ /**
2882
+ * TODO: [🧠][💯] Maybe also implement symmetricDifference
2883
+ */
2847
2884
 
2848
2885
  /**
2849
- * Extracts all code blocks from markdown.
2850
- *
2851
- * Note: There are multiple simmilar function:
2852
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2853
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2854
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2855
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2886
+ * Creates a new set with all elements that are present in either set
2856
2887
  *
2857
- * @param markdown any valid markdown
2858
- * @returns code blocks with language and content
2859
- * @throws {ParseError} if block is not closed properly
2860
- * @public exported from `@promptbook/markdown-utils`
2888
+ * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
2889
+ * @public exported from `@promptbook/utils`
2861
2890
  */
2862
- function extractAllBlocksFromMarkdown(markdown) {
2863
- var e_1, _a;
2864
- var codeBlocks = [];
2865
- var lines = markdown.split('\n');
2866
- // Note: [0] Ensure that the last block notated by gt > will be closed
2867
- lines.push('');
2868
- var currentCodeBlock = null;
2891
+ function union() {
2892
+ var e_1, _a, e_2, _b;
2893
+ var sets = [];
2894
+ for (var _i = 0; _i < arguments.length; _i++) {
2895
+ sets[_i] = arguments[_i];
2896
+ }
2897
+ var union = new Set();
2869
2898
  try {
2870
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
2871
- var line = lines_1_1.value;
2872
- if (line.startsWith('> ') || line === '>') {
2873
- if (currentCodeBlock === null) {
2874
- currentCodeBlock = { blockNotation: '>', language: null, content: '' };
2875
- } /* not else */
2876
- if (currentCodeBlock.blockNotation === '>') {
2877
- if (currentCodeBlock.content !== '') {
2878
- currentCodeBlock.content += '\n';
2879
- }
2880
- currentCodeBlock.content += line.slice(2);
2881
- }
2882
- }
2883
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
2884
- codeBlocks.push(currentCodeBlock);
2885
- currentCodeBlock = null;
2886
- }
2887
- /* not else */
2888
- if (line.startsWith('```')) {
2889
- var language = line.slice(3).trim() || null;
2890
- if (currentCodeBlock === null) {
2891
- currentCodeBlock = { blockNotation: '```', language: language, content: '' };
2892
- }
2893
- else {
2894
- if (language !== null) {
2895
- throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
2896
- }
2897
- codeBlocks.push(currentCodeBlock);
2898
- currentCodeBlock = null;
2899
+ for (var sets_1 = __values(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
2900
+ var set = sets_1_1.value;
2901
+ try {
2902
+ for (var _c = (e_2 = void 0, __values(Array.from(set))), _d = _c.next(); !_d.done; _d = _c.next()) {
2903
+ var item = _d.value;
2904
+ union.add(item);
2899
2905
  }
2900
2906
  }
2901
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
2902
- if (currentCodeBlock.content !== '') {
2903
- currentCodeBlock.content += '\n';
2907
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2908
+ finally {
2909
+ try {
2910
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
2904
2911
  }
2905
- currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
2912
+ finally { if (e_2) throw e_2.error; }
2906
2913
  }
2907
2914
  }
2908
2915
  }
2909
2916
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2910
2917
  finally {
2911
2918
  try {
2912
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
2919
+ if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
2913
2920
  }
2914
2921
  finally { if (e_1) throw e_1.error; }
2915
2922
  }
2916
- if (currentCodeBlock !== null) {
2917
- throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
2918
- }
2919
- return codeBlocks;
2923
+ return union;
2920
2924
  }
2921
- /**
2922
- * TODO: Maybe name for `blockNotation` instead of '```' and '>'
2923
- */
2924
2925
 
2925
2926
  /**
2926
- * Extracts extracts exactly one valid JSON code block
2927
- *
2928
- * - When given string is a valid JSON as it is, it just returns it
2929
- * - When there is no JSON code block the function throws a `ParseError`
2930
- * - When there are multiple JSON code blocks the function throws a `ParseError`
2927
+ * Just marks a place of place where should be something implemented
2928
+ * No side effects.
2931
2929
  *
2932
- * Note: It is not important if marked as ```json BUT if it is VALID JSON
2933
- * Note: There are multiple simmilar function:
2934
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2935
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2936
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2937
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2930
+ * Note: It can be usefull suppressing eslint errors of unused variables
2938
2931
  *
2939
- * @public exported from `@promptbook/markdown-utils`
2940
- * @throws {ParseError} if there is no valid JSON block in the markdown
2932
+ * @param value any values
2933
+ * @returns void
2934
+ * @private within the repository
2941
2935
  */
2942
- function extractJsonBlock(markdown) {
2943
- if (isValidJsonString(markdown)) {
2944
- return markdown;
2945
- }
2946
- var codeBlocks = extractAllBlocksFromMarkdown(markdown);
2947
- var jsonBlocks = codeBlocks.filter(function (_a) {
2948
- var content = _a.content;
2949
- return isValidJsonString(content);
2950
- });
2951
- if (jsonBlocks.length === 0) {
2952
- throw new Error('There is no valid JSON block in the markdown');
2953
- }
2954
- if (jsonBlocks.length > 1) {
2955
- throw new Error('There are multiple JSON code blocks in the markdown');
2936
+ function TODO_USE() {
2937
+ var value = [];
2938
+ for (var _i = 0; _i < arguments.length; _i++) {
2939
+ value[_i] = arguments[_i];
2956
2940
  }
2957
- return jsonBlocks[0].content;
2958
2941
  }
2959
- /**
2960
- * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
2961
- * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
2962
- */
2963
2942
 
2964
2943
  /**
2965
- * Just says that the variable is not used but should be kept
2966
- * No side effects.
2967
- *
2968
- * Note: It can be usefull for:
2944
+ * This error indicates problems parsing the format value
2969
2945
  *
2970
- * 1) Suppressing eager optimization of unused imports
2971
- * 2) Suppressing eslint errors of unused variables in the tests
2972
- * 3) Keeping the type of the variable for type testing
2946
+ * For example, when the format value is not a valid JSON or CSV
2947
+ * This is not thrown directly but in extended classes
2973
2948
  *
2974
- * @param value any values
2975
- * @returns void
2976
- * @private within the repository
2949
+ * @public exported from `@promptbook/core`
2977
2950
  */
2978
- function keepUnused() {
2979
- var valuesToKeep = [];
2980
- for (var _i = 0; _i < arguments.length; _i++) {
2981
- valuesToKeep[_i] = arguments[_i];
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;
2982
2959
  }
2983
- }
2960
+ return AbstractFormatError;
2961
+ }(Error));
2984
2962
 
2985
2963
  /**
2986
- * Replaces parameters in template with values from parameters object
2964
+ * This error indicates problem with parsing of CSV
2987
2965
  *
2988
- * @param template the template with parameters in {curly} braces
2989
- * @param parameters the object with parameters
2990
- * @returns the template with replaced parameters
2991
- * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
2992
- * @public exported from `@promptbook/utils`
2966
+ * @public exported from `@promptbook/core`
2993
2967
  */
2994
- function replaceParameters(template, parameters) {
2995
- var e_1, _a;
2996
- try {
2997
- for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
2998
- var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
2999
- if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
3000
- throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
3001
- }
3002
- else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
3003
- // TODO: [🍵]
3004
- throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
3005
- }
3006
- }
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;
3007
2975
  }
3008
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3009
- finally {
3010
- try {
3011
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3012
- }
3013
- finally { if (e_1) throw e_1.error; }
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
+
3103
+ /**
3104
+ * Function isValidJsonString will tell you if the string is valid JSON or not
3105
+ *
3106
+ * @public exported from `@promptbook/utils`
3107
+ */
3108
+ function isValidJsonString(value /* <- [👨‍⚖️] */) {
3109
+ try {
3110
+ JSON.parse(value);
3111
+ return true;
3014
3112
  }
3015
- var replacedTemplate = template;
3016
- var match;
3017
- var loopLimit = LOOP_LIMIT;
3018
- var _loop_1 = function () {
3019
- if (loopLimit-- < 0) {
3020
- throw new LimitReachedError('Loop limit reached during parameters replacement in `replaceParameters`');
3021
- }
3022
- var precol = match.groups.precol;
3023
- var parameterName = match.groups.parameterName;
3024
- if (parameterName === '') {
3025
- return "continue";
3026
- }
3027
- if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
3028
- throw new PipelineExecutionError('Parameter is already opened or not closed');
3029
- }
3030
- if (parameters[parameterName] === undefined) {
3031
- throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
3032
- }
3033
- var parameterValue = parameters[parameterName];
3034
- if (parameterValue === undefined) {
3035
- throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
3113
+ catch (error) {
3114
+ if (!(error instanceof Error)) {
3115
+ throw error;
3036
3116
  }
3037
- parameterValue = parameterValue.toString();
3038
- if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
3039
- parameterValue = parameterValue
3040
- .split('\n')
3041
- .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
3042
- .join('\n');
3117
+ if (error.message.includes('Unexpected token')) {
3118
+ return false;
3043
3119
  }
3044
- replacedTemplate =
3045
- replacedTemplate.substring(0, match.index + precol.length) +
3046
- parameterValue +
3047
- replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
3048
- };
3049
- while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
3050
- .exec(replacedTemplate))) {
3051
- _loop_1();
3120
+ return false;
3052
3121
  }
3053
- // [💫] Check if there are parameters that are not closed properly
3054
- if (/{\w+$/.test(replacedTemplate)) {
3055
- throw new PipelineExecutionError('Parameter is not closed');
3122
+ }
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
+ }
3056
3307
  }
3057
- // [💫] Check if there are parameters that are not opened properly
3058
- if (/^\w+}/.test(replacedTemplate)) {
3059
- throw new PipelineExecutionError('Parameter is not opened');
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; }
3060
3314
  }
3061
- return replacedTemplate;
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;
3062
3338
  }
3063
3339
 
3064
3340
  /**
3065
- * Create difference set of two sets.
3341
+ * Extracts all code blocks from markdown.
3066
3342
  *
3067
- * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
3068
- * @public exported from `@promptbook/utils`
3343
+ * Note: There are multiple simmilar function:
3344
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
3345
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
3346
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
3347
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
3348
+ *
3349
+ * @param markdown any valid markdown
3350
+ * @returns code blocks with language and content
3351
+ * @throws {ParseError} if block is not closed properly
3352
+ * @public exported from `@promptbook/markdown-utils`
3069
3353
  */
3070
- function difference(a, b, isEqual) {
3354
+ function extractAllBlocksFromMarkdown(markdown) {
3071
3355
  var e_1, _a;
3072
- if (isEqual === void 0) { isEqual = function (a, b) { return a === b; }; }
3073
- var diff = new Set();
3074
- var _loop_1 = function (itemA) {
3075
- if (!Array.from(b).some(function (itemB) { return isEqual(itemA, itemB); })) {
3076
- diff.add(itemA);
3077
- }
3078
- };
3356
+ var codeBlocks = [];
3357
+ var lines = markdown.split('\n');
3358
+ // Note: [0] Ensure that the last block notated by gt > will be closed
3359
+ lines.push('');
3360
+ var currentCodeBlock = null;
3079
3361
  try {
3080
- for (var _b = __values(Array.from(a)), _c = _b.next(); !_c.done; _c = _b.next()) {
3081
- var itemA = _c.value;
3082
- _loop_1(itemA);
3362
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
3363
+ var line = lines_1_1.value;
3364
+ if (line.startsWith('> ') || line === '>') {
3365
+ if (currentCodeBlock === null) {
3366
+ currentCodeBlock = { blockNotation: '>', language: null, content: '' };
3367
+ } /* not else */
3368
+ if (currentCodeBlock.blockNotation === '>') {
3369
+ if (currentCodeBlock.content !== '') {
3370
+ currentCodeBlock.content += '\n';
3371
+ }
3372
+ currentCodeBlock.content += line.slice(2);
3373
+ }
3374
+ }
3375
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
3376
+ codeBlocks.push(currentCodeBlock);
3377
+ currentCodeBlock = null;
3378
+ }
3379
+ /* not else */
3380
+ if (line.startsWith('```')) {
3381
+ var language = line.slice(3).trim() || null;
3382
+ if (currentCodeBlock === null) {
3383
+ currentCodeBlock = { blockNotation: '```', language: language, content: '' };
3384
+ }
3385
+ else {
3386
+ if (language !== null) {
3387
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
3388
+ }
3389
+ codeBlocks.push(currentCodeBlock);
3390
+ currentCodeBlock = null;
3391
+ }
3392
+ }
3393
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
3394
+ if (currentCodeBlock.content !== '') {
3395
+ currentCodeBlock.content += '\n';
3396
+ }
3397
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
3398
+ }
3083
3399
  }
3084
3400
  }
3085
3401
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
3086
3402
  finally {
3087
3403
  try {
3088
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3404
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
3089
3405
  }
3090
3406
  finally { if (e_1) throw e_1.error; }
3091
3407
  }
3092
- return diff;
3408
+ if (currentCodeBlock !== null) {
3409
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
3410
+ }
3411
+ return codeBlocks;
3093
3412
  }
3094
3413
  /**
3095
- * TODO: [🧠][💯] Maybe also implement symmetricDifference
3414
+ * TODO: Maybe name for `blockNotation` instead of '```' and '>'
3096
3415
  */
3097
3416
 
3098
3417
  /**
3099
- * Creates a new set with all elements that are present in either set
3418
+ * Extracts extracts exactly one valid JSON code block
3100
3419
  *
3101
- * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
3102
- * @public exported from `@promptbook/utils`
3420
+ * - When given string is a valid JSON as it is, it just returns it
3421
+ * - When there is no JSON code block the function throws a `ParseError`
3422
+ * - When there are multiple JSON code blocks the function throws a `ParseError`
3423
+ *
3424
+ * Note: It is not important if marked as ```json BUT if it is VALID JSON
3425
+ * Note: There are multiple simmilar function:
3426
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
3427
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
3428
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
3429
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
3430
+ *
3431
+ * @public exported from `@promptbook/markdown-utils`
3432
+ * @throws {ParseError} if there is no valid JSON block in the markdown
3103
3433
  */
3104
- function union() {
3105
- var e_1, _a, e_2, _b;
3106
- var sets = [];
3434
+ function extractJsonBlock(markdown) {
3435
+ if (isValidJsonString(markdown)) {
3436
+ return markdown;
3437
+ }
3438
+ var codeBlocks = extractAllBlocksFromMarkdown(markdown);
3439
+ var jsonBlocks = codeBlocks.filter(function (_a) {
3440
+ var content = _a.content;
3441
+ return isValidJsonString(content);
3442
+ });
3443
+ if (jsonBlocks.length === 0) {
3444
+ throw new Error('There is no valid JSON block in the markdown');
3445
+ }
3446
+ if (jsonBlocks.length > 1) {
3447
+ throw new Error('There are multiple JSON code blocks in the markdown');
3448
+ }
3449
+ return jsonBlocks[0].content;
3450
+ }
3451
+ /**
3452
+ * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
3453
+ * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
3454
+ */
3455
+
3456
+ /**
3457
+ * Just says that the variable is not used but should be kept
3458
+ * No side effects.
3459
+ *
3460
+ * Note: It can be usefull for:
3461
+ *
3462
+ * 1) Suppressing eager optimization of unused imports
3463
+ * 2) Suppressing eslint errors of unused variables in the tests
3464
+ * 3) Keeping the type of the variable for type testing
3465
+ *
3466
+ * @param value any values
3467
+ * @returns void
3468
+ * @private within the repository
3469
+ */
3470
+ function keepUnused() {
3471
+ var valuesToKeep = [];
3107
3472
  for (var _i = 0; _i < arguments.length; _i++) {
3108
- sets[_i] = arguments[_i];
3473
+ valuesToKeep[_i] = arguments[_i];
3109
3474
  }
3110
- var union = new Set();
3475
+ }
3476
+
3477
+ /**
3478
+ * Replaces parameters in template with values from parameters object
3479
+ *
3480
+ * @param template the template with parameters in {curly} braces
3481
+ * @param parameters the object with parameters
3482
+ * @returns the template with replaced parameters
3483
+ * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
3484
+ * @public exported from `@promptbook/utils`
3485
+ */
3486
+ function replaceParameters(template, parameters) {
3487
+ var e_1, _a;
3111
3488
  try {
3112
- for (var sets_1 = __values(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
3113
- var set = sets_1_1.value;
3114
- try {
3115
- for (var _c = (e_2 = void 0, __values(Array.from(set))), _d = _c.next(); !_d.done; _d = _c.next()) {
3116
- var item = _d.value;
3117
- union.add(item);
3118
- }
3489
+ for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
3490
+ var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
3491
+ if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
3492
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
3119
3493
  }
3120
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3121
- finally {
3122
- try {
3123
- if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
3124
- }
3125
- finally { if (e_2) throw e_2.error; }
3494
+ else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
3495
+ // TODO: [🍵]
3496
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
3126
3497
  }
3127
3498
  }
3128
3499
  }
3129
3500
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
3130
3501
  finally {
3131
3502
  try {
3132
- if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
3503
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3133
3504
  }
3134
3505
  finally { if (e_1) throw e_1.error; }
3135
3506
  }
3136
- return union;
3507
+ var replacedTemplate = template;
3508
+ var match;
3509
+ var loopLimit = LOOP_LIMIT;
3510
+ var _loop_1 = function () {
3511
+ if (loopLimit-- < 0) {
3512
+ throw new LimitReachedError('Loop limit reached during parameters replacement in `replaceParameters`');
3513
+ }
3514
+ var precol = match.groups.precol;
3515
+ var parameterName = match.groups.parameterName;
3516
+ if (parameterName === '') {
3517
+ return "continue";
3518
+ }
3519
+ if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
3520
+ throw new PipelineExecutionError('Parameter is already opened or not closed');
3521
+ }
3522
+ if (parameters[parameterName] === undefined) {
3523
+ throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
3524
+ }
3525
+ var parameterValue = parameters[parameterName];
3526
+ if (parameterValue === undefined) {
3527
+ throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
3528
+ }
3529
+ parameterValue = parameterValue.toString();
3530
+ if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
3531
+ parameterValue = parameterValue
3532
+ .split('\n')
3533
+ .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
3534
+ .join('\n');
3535
+ }
3536
+ replacedTemplate =
3537
+ replacedTemplate.substring(0, match.index + precol.length) +
3538
+ parameterValue +
3539
+ replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
3540
+ };
3541
+ while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
3542
+ .exec(replacedTemplate))) {
3543
+ _loop_1();
3544
+ }
3545
+ // [💫] Check if there are parameters that are not closed properly
3546
+ if (/{\w+$/.test(replacedTemplate)) {
3547
+ throw new PipelineExecutionError('Parameter is not closed');
3548
+ }
3549
+ // [💫] Check if there are parameters that are not opened properly
3550
+ if (/^\w+}/.test(replacedTemplate)) {
3551
+ throw new PipelineExecutionError('Parameter is not opened');
3552
+ }
3553
+ return replacedTemplate;
3137
3554
  }
3138
3555
 
3139
3556
  /**
@@ -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,432 +3703,235 @@ 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
- /**
3289
- * Just marks a place of place where should be something implemented
3290
- * No side effects.
3291
- *
3292
- * Note: It can be usefull suppressing eslint errors of unused variables
3293
- *
3294
- * @param value any values
3295
- * @returns void
3296
- * @private within the repository
3297
- */
3298
- function TODO_USE() {
3299
- var value = [];
3300
- for (var _i = 0; _i < arguments.length; _i++) {
3301
- value[_i] = arguments[_i];
3302
- }
3303
- }
3304
-
3305
- /**
3306
- * @@@
3307
- *
3308
- * @private internal utility of `createPipelineExecutor`
3309
- */
3310
- function getContextForTemplate(template) {
3311
- return __awaiter(this, void 0, void 0, function () {
3312
- return __generator(this, function (_a) {
3313
- TODO_USE(template);
3314
- return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
3315
- });
3316
- });
3317
- }
3318
-
3319
- /**
3320
- * @@@
3321
- *
3322
- * @private internal utility of `createPipelineExecutor`
3323
- */
3324
- function getKnowledgeForTemplate(options) {
3325
- return __awaiter(this, void 0, void 0, function () {
3326
- var preparedPipeline, template;
3327
- return __generator(this, function (_a) {
3328
- preparedPipeline = options.preparedPipeline, template = options.template;
3329
- // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
3330
- TODO_USE(template);
3331
- return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
3332
- var content = _a.content;
3333
- return "- ".concat(content);
3334
- }).join('\n')];
3335
- });
3336
- });
3337
- }
3338
-
3339
3710
  /**
3340
3711
  * @@@
3341
3712
  *
3342
3713
  * @private internal utility of `createPipelineExecutor`
3343
3714
  */
3344
- function getSamplesForTemplate(template) {
3715
+ function executeAttempts(options) {
3345
3716
  return __awaiter(this, void 0, void 0, function () {
3717
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3346
3718
  return __generator(this, function (_a) {
3347
- // TODO: [♨] Implement Better - use real index and keyword search
3348
- TODO_USE(template);
3349
- return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
3350
- });
3351
- });
3352
- }
3353
-
3354
- /**
3355
- * @@@
3356
- *
3357
- * @private internal utility of `createPipelineExecutor`
3358
- */
3359
- function getReservedParametersForTemplate(options) {
3360
- return __awaiter(this, void 0, void 0, function () {
3361
- var preparedPipeline, template, pipelineIdentification, context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_1, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
3362
- var e_1, _a;
3363
- return __generator(this, function (_b) {
3364
- switch (_b.label) {
3365
- case 0:
3366
- preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
3367
- return [4 /*yield*/, getContextForTemplate(template)];
3368
- case 1:
3369
- context = _b.sent();
3370
- return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
3371
- case 2:
3372
- knowledge = _b.sent();
3373
- return [4 /*yield*/, getSamplesForTemplate(template)];
3374
- case 3:
3375
- samples = _b.sent();
3376
- currentDate = new Date().toISOString();
3377
- modelName = RESERVED_PARAMETER_MISSING_VALUE;
3378
- reservedParameters = {
3379
- content: RESERVED_PARAMETER_RESTRICTED,
3380
- context: context,
3381
- knowledge: knowledge,
3382
- samples: samples,
3383
- currentDate: currentDate,
3384
- modelName: modelName,
3385
- };
3386
- _loop_1 = function (parameterName) {
3387
- if (reservedParameters[parameterName] === undefined) {
3388
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3389
- }
3390
- };
3391
- try {
3392
- // Note: Doublecheck that ALL reserved parameters are defined:
3393
- for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
3394
- parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
3395
- _loop_1(parameterName);
3396
- }
3397
- }
3398
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3399
- finally {
3400
- try {
3401
- if (RESERVED_PARAMETER_NAMES_1_1 && !RESERVED_PARAMETER_NAMES_1_1.done && (_a = RESERVED_PARAMETER_NAMES_1.return)) _a.call(RESERVED_PARAMETER_NAMES_1);
3402
- }
3403
- finally { if (e_1) throw e_1.error; }
3404
- }
3405
- return [2 /*return*/, reservedParameters];
3406
- }
3407
- });
3408
- });
3409
- }
3410
-
3411
- /**
3412
- * @@@
3413
- *
3414
- * @private internal utility of `createPipelineExecutor`
3415
- */
3416
- function executeTemplate(options) {
3417
- return __awaiter(this, void 0, void 0, function () {
3418
- 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, $ongoingResult, maxAttempts, jokerParameterNames, preparedContent, _loop_2, attempt, state_1;
3419
- var e_1, _f, _g;
3420
- return __generator(this, function (_h) {
3421
- switch (_h.label) {
3422
- case 0:
3423
- currentTemplate = options.currentTemplate, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, llmTools = options.llmTools, onProgress = options.onProgress, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3424
- maxExecutionAttempts = settings.maxExecutionAttempts;
3425
- name = "pipeline-executor-frame-".concat(currentTemplate.name);
3426
- title = currentTemplate.title;
3427
- priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
3428
- return [4 /*yield*/, onProgress({
3429
- name: name,
3430
- title: title,
3431
- isStarted: false,
3432
- isDone: false,
3433
- templateType: currentTemplate.templateType,
3434
- parameterName: currentTemplate.resultingParameterName,
3435
- parameterValue: null,
3436
- // <- [🍸]
3437
- })];
3438
- case 1:
3439
- _h.sent();
3440
- usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3441
- dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
3442
- if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3443
- 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)
3444
- .map(function (name) { return "{".concat(name, "}"); })
3445
- .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3446
- .map(function (name) { return "{".concat(name, "}"); })
3447
- .join(', '), "\n\n "); }));
3448
- }
3449
- _b = (_a = Object).freeze;
3450
- _c = [{}];
3451
- return [4 /*yield*/, getReservedParametersForTemplate({
3452
- preparedPipeline: preparedPipeline,
3453
- template: currentTemplate,
3454
- pipelineIdentification: pipelineIdentification,
3455
- })];
3456
- case 2:
3457
- definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
3458
- definedParameterNames = new Set(Object.keys(definedParameters));
3459
- parameters = {};
3460
- _loop_1 = function (parameterName) {
3461
- // Situation: Parameter is defined and used
3462
- if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3463
- parameters[parameterName] = definedParameters[parameterName];
3464
- }
3465
- // Situation: Parameter is defined but NOT used
3466
- else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
3467
- // Situation: Parameter is NOT defined BUT used
3468
- else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3469
- // Houston, we have a problem
3470
- // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
3471
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3472
- }
3473
- };
3474
- try {
3475
- // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
3476
- for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3477
- parameterName = _e.value;
3478
- _loop_1(parameterName);
3479
- }
3480
- }
3481
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3482
- finally {
3483
- try {
3484
- if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
3485
- }
3486
- finally { if (e_1) throw e_1.error; }
3487
- }
3488
- // 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
3489
- Object.freeze(parameters);
3490
- $ongoingResult = {
3719
+ switch (_a.label) {
3720
+ case 0:
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;
3722
+ maxExecutionAttempts = settings.maxExecutionAttempts;
3723
+ $ongoingTemplateResult = {
3491
3724
  $result: null,
3492
3725
  $resultString: null,
3493
3726
  $expectError: null,
3494
3727
  $scriptPipelineExecutionErrors: [],
3495
3728
  };
3496
- maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3497
- jokerParameterNames = currentTemplate.jokerParameterNames || [];
3498
- preparedContent = (currentTemplate.preparedContent || '{content}')
3499
- .split('{content}')
3500
- .join(currentTemplate.content);
3501
- _loop_2 = function (attempt) {
3502
- var isJokerAttempt, jokerParameterName, _j, modelRequirements, _k, _l, _m, _o, _p, _q, scriptTools, _r, error_1, e_2_1, _s, _t, _u, functionName, postprocessingError, _v, _w, scriptTools, _x, error_2, e_3_1, e_4_1, error_3;
3503
- var e_2, _y, e_4, _z, e_3, _0;
3504
- return __generator(this, function (_1) {
3505
- switch (_1.label) {
3729
+ _loop_1 = function (attempt) {
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) {
3506
3734
  case 0:
3507
3735
  isJokerAttempt = attempt < 0;
3508
3736
  jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3509
- // TODO: [🧠] !!!!!! JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3737
+ // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3510
3738
  if (isJokerAttempt && !jokerParameterName) {
3511
3739
  throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3512
3740
  }
3513
- $ongoingResult.$result = null;
3514
- $ongoingResult.$resultString = null;
3515
- $ongoingResult.$expectError = null;
3741
+ $ongoingTemplateResult.$result = null;
3742
+ $ongoingTemplateResult.$resultString = null;
3743
+ $ongoingTemplateResult.$expectError = null;
3516
3744
  if (isJokerAttempt) {
3517
3745
  if (parameters[jokerParameterName] === undefined) {
3518
3746
  throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3519
3747
  // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3520
3748
  }
3521
3749
  else {
3522
- $ongoingResult.$resultString = parameters[jokerParameterName];
3750
+ $ongoingTemplateResult.$resultString = parameters[jokerParameterName];
3523
3751
  }
3524
3752
  }
3525
- _1.label = 1;
3753
+ _t.label = 1;
3526
3754
  case 1:
3527
- _1.trys.push([1, 44, 45, 46]);
3528
- if (!!isJokerAttempt) return [3 /*break*/, 26];
3529
- _j = currentTemplate.templateType;
3530
- switch (_j) {
3755
+ _t.trys.push([1, 43, 44, 45]);
3756
+ if (!!isJokerAttempt) return [3 /*break*/, 25];
3757
+ _b = template.templateType;
3758
+ switch (_b) {
3531
3759
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3532
3760
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3533
- case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3534
- case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3761
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 11];
3762
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 22];
3535
3763
  }
3536
- return [3 /*break*/, 25];
3764
+ return [3 /*break*/, 24];
3537
3765
  case 2:
3538
- $ongoingResult.$resultString = replaceParameters(preparedContent, parameters);
3539
- return [3 /*break*/, 26];
3766
+ $ongoingTemplateResult.$resultString = replaceParameters(preparedContent, parameters);
3767
+ return [3 /*break*/, 25];
3540
3768
  case 3:
3541
- modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (currentTemplate.modelRequirements || {}));
3542
- $ongoingResult.$prompt = {
3543
- title: currentTemplate.title,
3769
+ modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (template.modelRequirements || {}));
3770
+ $ongoingTemplateResult.$prompt = {
3771
+ title: template.title,
3544
3772
  pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3545
3773
  ? preparedPipeline.pipelineUrl
3546
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.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
+ ),
3547
3777
  parameters: parameters,
3548
3778
  content: preparedContent,
3549
3779
  modelRequirements: modelRequirements,
3550
3780
  expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3551
3781
  var name = _a.name;
3552
- return name === currentTemplate.personaName;
3553
- }) || {})), currentTemplate.expectations),
3554
- format: currentTemplate.format,
3555
- postprocessingFunctionNames: currentTemplate.postprocessingFunctionNames,
3782
+ return name === template.personaName;
3783
+ }) ||
3784
+ {})), template.expectations),
3785
+ format: template.format,
3786
+ postprocessingFunctionNames: template.postprocessingFunctionNames,
3556
3787
  }; // <- TODO: Not very good type guard
3557
- _k = modelRequirements.modelVariant;
3558
- switch (_k) {
3788
+ _c = modelRequirements.modelVariant;
3789
+ switch (_c) {
3559
3790
  case 'CHAT': return [3 /*break*/, 4];
3560
3791
  case 'COMPLETION': return [3 /*break*/, 6];
3561
3792
  case 'EMBEDDING': return [3 /*break*/, 8];
3562
3793
  }
3563
- return [3 /*break*/, 10];
3794
+ return [3 /*break*/, 9];
3564
3795
  case 4:
3565
- _l = $ongoingResult;
3566
- return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingResult.$prompt))];
3796
+ _d = $ongoingTemplateResult;
3797
+ return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3567
3798
  case 5:
3568
- _l.$chatResult = _1.sent();
3799
+ _d.$chatResult = _t.sent();
3569
3800
  // TODO: [🍬] Destroy chatThread
3570
- $ongoingResult.$result = $ongoingResult.$chatResult;
3571
- $ongoingResult.$resultString = $ongoingResult.$chatResult.content;
3572
- return [3 /*break*/, 11];
3801
+ $ongoingTemplateResult.$result = $ongoingTemplateResult.$chatResult;
3802
+ $ongoingTemplateResult.$resultString = $ongoingTemplateResult.$chatResult.content;
3803
+ return [3 /*break*/, 10];
3573
3804
  case 6:
3574
- _m = $ongoingResult;
3575
- return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingResult.$prompt))];
3805
+ _e = $ongoingTemplateResult;
3806
+ return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3576
3807
  case 7:
3577
- _m.$completionResult = _1.sent();
3578
- $ongoingResult.$result = $ongoingResult.$completionResult;
3579
- $ongoingResult.$resultString = $ongoingResult.$completionResult.content;
3580
- return [3 /*break*/, 11];
3581
- case 8:
3582
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3583
- _o = $ongoingResult;
3584
- return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze($ongoingResult.$prompt))];
3585
- case 9:
3586
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3587
- _o.$embeddingResult = _1.sent();
3588
- $ongoingResult.$result = $ongoingResult.$embeddingResult;
3589
- $ongoingResult.$resultString = $ongoingResult.$embeddingResult.content.join(',');
3590
- return [3 /*break*/, 11];
3591
- case 10: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3592
- case 11: return [3 /*break*/, 26];
3593
- case 12:
3808
+ _e.$completionResult = _t.sent();
3809
+ $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
3810
+ $ongoingTemplateResult.$resultString =
3811
+ $ongoingTemplateResult.$completionResult.content;
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:
3594
3817
  if (arrayableToArray(tools.script).length === 0) {
3595
3818
  throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3596
3819
  }
3597
- if (!currentTemplate.contentLanguage) {
3598
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(currentTemplate.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3820
+ if (!template.contentLanguage) {
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 "); }));
3599
3822
  }
3600
- _1.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;
3601
3828
  case 13:
3602
- _1.trys.push([13, 20, 21, 22]);
3603
- _p = (e_2 = void 0, __values(arrayableToArray(tools.script))), _q = _p.next();
3604
- _1.label = 14;
3829
+ if (!!_g.done) return [3 /*break*/, 18];
3830
+ scriptTools = _g.value;
3831
+ _t.label = 14;
3605
3832
  case 14:
3606
- if (!!_q.done) return [3 /*break*/, 19];
3607
- scriptTools = _q.value;
3608
- _1.label = 15;
3609
- case 15:
3610
- _1.trys.push([15, 17, , 18]);
3611
- _r = $ongoingResult;
3833
+ _t.trys.push([14, 16, , 17]);
3834
+ _h = $ongoingTemplateResult;
3612
3835
  return [4 /*yield*/, scriptTools.execute($deepFreeze({
3613
- scriptLanguage: currentTemplate.contentLanguage,
3836
+ scriptLanguage: template.contentLanguage,
3614
3837
  script: preparedContent,
3615
3838
  parameters: parameters,
3616
3839
  }))];
3840
+ case 15:
3841
+ _h.$resultString = _t.sent();
3842
+ return [3 /*break*/, 18];
3617
3843
  case 16:
3618
- _r.$resultString = _1.sent();
3619
- return [3 /*break*/, 19];
3620
- case 17:
3621
- error_1 = _1.sent();
3844
+ error_1 = _t.sent();
3622
3845
  if (!(error_1 instanceof Error)) {
3623
3846
  throw error_1;
3624
3847
  }
3625
3848
  if (error_1 instanceof UnexpectedError) {
3626
3849
  throw error_1;
3627
3850
  }
3628
- $ongoingResult.$scriptPipelineExecutionErrors.push(error_1);
3629
- return [3 /*break*/, 18];
3630
- case 18:
3631
- _q = _p.next();
3632
- return [3 /*break*/, 14];
3633
- case 19: return [3 /*break*/, 22];
3851
+ $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_1);
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();
3859
+ e_1 = { error: e_1_1 };
3860
+ return [3 /*break*/, 21];
3634
3861
  case 20:
3635
- e_2_1 = _1.sent();
3636
- e_2 = { error: e_2_1 };
3637
- return [3 /*break*/, 22];
3638
- case 21:
3639
3862
  try {
3640
- if (_q && !_q.done && (_y = _p.return)) _y.call(_p);
3863
+ if (_g && !_g.done && (_q = _f.return)) _q.call(_f);
3641
3864
  }
3642
- finally { if (e_2) throw e_2.error; }
3865
+ finally { if (e_1) throw e_1.error; }
3643
3866
  return [7 /*endfinally*/];
3644
- case 22:
3645
- if ($ongoingResult.$resultString !== null) {
3646
- return [3 /*break*/, 26];
3867
+ case 21:
3868
+ if ($ongoingTemplateResult.$resultString !== null) {
3869
+ return [3 /*break*/, 25];
3647
3870
  }
3648
- if ($ongoingResult.$scriptPipelineExecutionErrors.length === 1) {
3649
- throw $ongoingResult.$scriptPipelineExecutionErrors[0];
3871
+ if ($ongoingTemplateResult.$scriptPipelineExecutionErrors.length === 1) {
3872
+ throw $ongoingTemplateResult.$scriptPipelineExecutionErrors[0];
3650
3873
  }
3651
3874
  else {
3652
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script execution failed ".concat($ongoingResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingResult.$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
3653
3876
  .map(function (error) { return '- ' + error.message; })
3654
3877
  .join('\n\n')), "\n "); }));
3655
3878
  }
3656
- case 23:
3879
+ case 22:
3657
3880
  if (tools.userInterface === undefined) {
3658
3881
  throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3659
3882
  }
3660
3883
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3661
- _s = $ongoingResult;
3884
+ _j = $ongoingTemplateResult;
3662
3885
  return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3663
- promptTitle: currentTemplate.title,
3664
- promptMessage: replaceParameters(currentTemplate.description || '', parameters),
3886
+ promptTitle: template.title,
3887
+ promptMessage: replaceParameters(template.description || '', parameters),
3665
3888
  defaultValue: replaceParameters(preparedContent, parameters),
3666
3889
  // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3667
3890
  placeholder: undefined,
3668
3891
  priority: priority,
3669
3892
  }))];
3670
- case 24:
3893
+ case 23:
3671
3894
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3672
- _s.$resultString = _1.sent();
3673
- return [3 /*break*/, 26];
3674
- case 25: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown execution type \"".concat(currentTemplate.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;
3675
3901
  case 26:
3676
- if (!(!isJokerAttempt && currentTemplate.postprocessingFunctionNames)) return [3 /*break*/, 43];
3677
- _1.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;
3678
3905
  case 27:
3679
- _1.trys.push([27, 41, 42, 43]);
3680
- _t = (e_4 = void 0, __values(currentTemplate.postprocessingFunctionNames)), _u = _t.next();
3681
- _1.label = 28;
3682
- case 28:
3683
- if (!!_u.done) return [3 /*break*/, 40];
3684
- functionName = _u.value;
3906
+ if (!!_l.done) return [3 /*break*/, 39];
3907
+ functionName = _l.value;
3685
3908
  postprocessingError = null;
3686
- _1.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;
3687
3914
  case 29:
3688
- _1.trys.push([29, 36, 37, 38]);
3689
- _v = (e_3 = void 0, __values(arrayableToArray(tools.script))), _w = _v.next();
3690
- _1.label = 30;
3915
+ if (!!_o.done) return [3 /*break*/, 34];
3916
+ scriptTools = _o.value;
3917
+ _t.label = 30;
3691
3918
  case 30:
3692
- if (!!_w.done) return [3 /*break*/, 35];
3693
- scriptTools = _w.value;
3694
- _1.label = 31;
3695
- case 31:
3696
- _1.trys.push([31, 33, , 34]);
3697
- _x = $ongoingResult;
3919
+ _t.trys.push([30, 32, , 33]);
3920
+ _p = $ongoingTemplateResult;
3698
3921
  return [4 /*yield*/, scriptTools.execute({
3699
3922
  scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3700
3923
  script: "".concat(functionName, "(resultString)"),
3701
3924
  parameters: {
3702
- resultString: $ongoingResult.$resultString || '',
3925
+ resultString: $ongoingTemplateResult.$resultString || '',
3703
3926
  // Note: No ...parametersForTemplate, because working with result only
3704
3927
  },
3705
3928
  })];
3706
- case 32:
3707
- _x.$resultString = _1.sent();
3929
+ case 31:
3930
+ _p.$resultString = _t.sent();
3708
3931
  postprocessingError = null;
3709
- return [3 /*break*/, 35];
3710
- case 33:
3711
- error_2 = _1.sent();
3932
+ return [3 /*break*/, 34];
3933
+ case 32:
3934
+ error_2 = _t.sent();
3712
3935
  if (!(error_2 instanceof Error)) {
3713
3936
  throw error_2;
3714
3937
  }
@@ -3716,49 +3939,49 @@ function executeTemplate(options) {
3716
3939
  throw error_2;
3717
3940
  }
3718
3941
  postprocessingError = error_2;
3719
- $ongoingResult.$scriptPipelineExecutionErrors.push(error_2);
3720
- return [3 /*break*/, 34];
3721
- case 34:
3722
- _w = _v.next();
3723
- return [3 /*break*/, 30];
3724
- case 35: return [3 /*break*/, 38];
3942
+ $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_2);
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();
3950
+ e_2 = { error: e_2_1 };
3951
+ return [3 /*break*/, 37];
3725
3952
  case 36:
3726
- e_3_1 = _1.sent();
3727
- e_3 = { error: e_3_1 };
3728
- return [3 /*break*/, 38];
3729
- case 37:
3730
3953
  try {
3731
- if (_w && !_w.done && (_0 = _v.return)) _0.call(_v);
3954
+ if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3732
3955
  }
3733
- finally { if (e_3) throw e_3.error; }
3956
+ finally { if (e_2) throw e_2.error; }
3734
3957
  return [7 /*endfinally*/];
3735
- case 38:
3958
+ case 37:
3736
3959
  if (postprocessingError) {
3737
3960
  throw postprocessingError;
3738
3961
  }
3739
- _1.label = 39;
3740
- case 39:
3741
- _u = _t.next();
3742
- return [3 /*break*/, 28];
3743
- case 40: return [3 /*break*/, 43];
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();
3969
+ e_3 = { error: e_3_1 };
3970
+ return [3 /*break*/, 42];
3744
3971
  case 41:
3745
- e_4_1 = _1.sent();
3746
- e_4 = { error: e_4_1 };
3747
- return [3 /*break*/, 43];
3748
- case 42:
3749
3972
  try {
3750
- if (_u && !_u.done && (_z = _t.return)) _z.call(_t);
3973
+ if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3751
3974
  }
3752
- finally { if (e_4) throw e_4.error; }
3975
+ finally { if (e_3) throw e_3.error; }
3753
3976
  return [7 /*endfinally*/];
3754
- case 43:
3977
+ case 42:
3755
3978
  // TODO: [💝] Unite object for expecting amount and format
3756
- if (currentTemplate.format) {
3757
- if (currentTemplate.format === 'JSON') {
3758
- if (!isValidJsonString($ongoingResult.$resultString || '')) {
3979
+ if (template.format) {
3980
+ if (template.format === 'JSON') {
3981
+ if (!isValidJsonString($ongoingTemplateResult.$resultString || '')) {
3759
3982
  // TODO: [🏢] Do more universally via `FormatDefinition`
3760
3983
  try {
3761
- $ongoingResult.$resultString = extractJsonBlock($ongoingResult.$resultString || '');
3984
+ $ongoingTemplateResult.$resultString = extractJsonBlock($ongoingTemplateResult.$resultString || '');
3762
3985
  }
3763
3986
  catch (error) {
3764
3987
  keepUnused(error);
@@ -3768,49 +3991,51 @@ function executeTemplate(options) {
3768
3991
  }
3769
3992
  }
3770
3993
  else {
3771
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Unknown format \"".concat(currentTemplate.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 "); }));
3772
3995
  }
3773
3996
  }
3774
3997
  // TODO: [💝] Unite object for expecting amount and format
3775
- if (currentTemplate.expectations) {
3776
- checkExpectations(currentTemplate.expectations, $ongoingResult.$resultString || '');
3998
+ if (template.expectations) {
3999
+ checkExpectations(template.expectations, $ongoingTemplateResult.$resultString || '');
3777
4000
  }
3778
4001
  return [2 /*return*/, "break-attempts"];
3779
- case 44:
3780
- error_3 = _1.sent();
4002
+ case 43:
4003
+ error_3 = _t.sent();
3781
4004
  if (!(error_3 instanceof ExpectError)) {
3782
4005
  throw error_3;
3783
4006
  }
3784
- $ongoingResult.$expectError = error_3;
3785
- return [3 /*break*/, 46];
3786
- case 45:
4007
+ $ongoingTemplateResult.$expectError = error_3;
4008
+ return [3 /*break*/, 45];
4009
+ case 44:
3787
4010
  if (!isJokerAttempt &&
3788
- currentTemplate.templateType === 'PROMPT_TEMPLATE' &&
3789
- $ongoingResult.$prompt
4011
+ template.templateType === 'PROMPT_TEMPLATE' &&
4012
+ $ongoingTemplateResult.$prompt
3790
4013
  // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
3791
4014
  // In that case we don’t want to make a report about it because it’s not a llm execution error
3792
4015
  ) {
3793
4016
  // TODO: [🧠] Maybe put other templateTypes into report
3794
4017
  $executionReport.promptExecutions.push({
3795
- prompt: __assign({}, $ongoingResult.$prompt),
3796
- result: $ongoingResult.$result || undefined,
3797
- error: $ongoingResult.$expectError === null ? undefined : serializeError($ongoingResult.$expectError),
4018
+ prompt: __assign({}, $ongoingTemplateResult.$prompt),
4019
+ result: $ongoingTemplateResult.$result || undefined,
4020
+ error: $ongoingTemplateResult.$expectError === null
4021
+ ? undefined
4022
+ : serializeError($ongoingTemplateResult.$expectError),
3798
4023
  });
3799
4024
  }
3800
4025
  return [7 /*endfinally*/];
3801
- case 46:
3802
- if ($ongoingResult.$expectError !== null && attempt === maxAttempts - 1) {
4026
+ case 45:
4027
+ if ($ongoingTemplateResult.$expectError !== null && attempt === maxAttempts - 1) {
3803
4028
  throw new PipelineExecutionError(spaceTrim$1(function (block) {
3804
4029
  var _a, _b, _c;
3805
- return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block(pipelineIdentification), "\n\n ---\n The Prompt:\n ").concat(block((((_a = $ongoingResult.$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) || '')
3806
4031
  .split('\n')
3807
4032
  .map(function (line) { return "> ".concat(line); })
3808
- .join('\n')), "\n\n Last error ").concat(((_b = $ongoingResult.$expectError) === null || _b === void 0 ? void 0 : _b.name) || '', ":\n ").concat(block((((_c = $ongoingResult.$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) || '')
3809
4034
  .split('\n')
3810
4035
  .map(function (line) { return "> ".concat(line); })
3811
- .join('\n')), "\n\n Last result:\n ").concat(block($ongoingResult.$resultString === null
4036
+ .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
3812
4037
  ? 'null'
3813
- : $ongoingResult.$resultString
4038
+ : $ongoingTemplateResult.$resultString
3814
4039
  .split('\n')
3815
4040
  .map(function (line) { return "> ".concat(line); })
3816
4041
  .join('\n')), "\n ---\n ");
@@ -3820,37 +4045,323 @@ function executeTemplate(options) {
3820
4045
  }
3821
4046
  });
3822
4047
  };
3823
- attempt = -jokerParameterNames.length;
3824
- _h.label = 3;
3825
- case 3:
3826
- if (!(attempt < maxAttempts)) return [3 /*break*/, 6];
3827
- return [5 /*yield**/, _loop_2(attempt)];
3828
- case 4:
3829
- state_1 = _h.sent();
3830
- switch (state_1) {
3831
- case "break-attempts": return [3 /*break*/, 6];
4048
+ attempt = -jokerParameterNames.length;
4049
+ _a.label = 1;
4050
+ case 1:
4051
+ if (!(attempt < maxAttempts)) return [3 /*break*/, 4];
4052
+ return [5 /*yield**/, _loop_1(attempt)];
4053
+ case 2:
4054
+ state_1 = _a.sent();
4055
+ switch (state_1) {
4056
+ case "break-attempts": return [3 /*break*/, 4];
4057
+ }
4058
+ _a.label = 3;
4059
+ case 3:
4060
+ attempt++;
4061
+ return [3 /*break*/, 1];
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];
4067
+ }
4068
+ });
4069
+ });
4070
+ }
4071
+ /**
4072
+ * TODO: Break into smaller functions
4073
+ */
4074
+
4075
+ /**
4076
+ * @@@
4077
+ *
4078
+ * @private internal utility of `createPipelineExecutor`
4079
+ */
4080
+ function executeFormatSubvalues(options) {
4081
+ return __awaiter(this, void 0, void 0, function () {
4082
+ var template, jokerParameterNames, parameters, priority, pipelineIdentification, settings, parameterValue, formatDefinition, subvalueDefinition, formatSettings, resultString;
4083
+ var _this = this;
4084
+ return __generator(this, function (_a) {
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];
4152
+ }
4153
+ });
4154
+ });
4155
+ }
4156
+
4157
+ /**
4158
+ * @@@
4159
+ *
4160
+ * @private internal utility of `createPipelineExecutor`
4161
+ */
4162
+ function getContextForTemplate(template) {
4163
+ return __awaiter(this, void 0, void 0, function () {
4164
+ return __generator(this, function (_a) {
4165
+ TODO_USE(template);
4166
+ return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
4167
+ });
4168
+ });
4169
+ }
4170
+
4171
+ /**
4172
+ * @@@
4173
+ *
4174
+ * @private internal utility of `createPipelineExecutor`
4175
+ */
4176
+ function getKnowledgeForTemplate(options) {
4177
+ return __awaiter(this, void 0, void 0, function () {
4178
+ var preparedPipeline, template;
4179
+ return __generator(this, function (_a) {
4180
+ preparedPipeline = options.preparedPipeline, template = options.template;
4181
+ // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
4182
+ TODO_USE(template);
4183
+ return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
4184
+ var content = _a.content;
4185
+ return "- ".concat(content);
4186
+ }).join('\n')];
4187
+ });
4188
+ });
4189
+ }
4190
+
4191
+ /**
4192
+ * @@@
4193
+ *
4194
+ * @private internal utility of `createPipelineExecutor`
4195
+ */
4196
+ function getSamplesForTemplate(template) {
4197
+ return __awaiter(this, void 0, void 0, function () {
4198
+ return __generator(this, function (_a) {
4199
+ // TODO: [♨] Implement Better - use real index and keyword search
4200
+ TODO_USE(template);
4201
+ return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
4202
+ });
4203
+ });
4204
+ }
4205
+
4206
+ /**
4207
+ * @@@
4208
+ *
4209
+ * @private internal utility of `createPipelineExecutor`
4210
+ */
4211
+ function getReservedParametersForTemplate(options) {
4212
+ return __awaiter(this, void 0, void 0, function () {
4213
+ var preparedPipeline, template, pipelineIdentification, context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_1, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
4214
+ var e_1, _a;
4215
+ return __generator(this, function (_b) {
4216
+ switch (_b.label) {
4217
+ case 0:
4218
+ preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
4219
+ return [4 /*yield*/, getContextForTemplate(template)];
4220
+ case 1:
4221
+ context = _b.sent();
4222
+ return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
4223
+ case 2:
4224
+ knowledge = _b.sent();
4225
+ return [4 /*yield*/, getSamplesForTemplate(template)];
4226
+ case 3:
4227
+ samples = _b.sent();
4228
+ currentDate = new Date().toISOString();
4229
+ modelName = RESERVED_PARAMETER_MISSING_VALUE;
4230
+ reservedParameters = {
4231
+ content: RESERVED_PARAMETER_RESTRICTED,
4232
+ context: context,
4233
+ knowledge: knowledge,
4234
+ samples: samples,
4235
+ currentDate: currentDate,
4236
+ modelName: modelName,
4237
+ };
4238
+ _loop_1 = function (parameterName) {
4239
+ if (reservedParameters[parameterName] === undefined) {
4240
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
4241
+ }
4242
+ };
4243
+ try {
4244
+ // Note: Doublecheck that ALL reserved parameters are defined:
4245
+ for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
4246
+ parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
4247
+ _loop_1(parameterName);
4248
+ }
4249
+ }
4250
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4251
+ finally {
4252
+ try {
4253
+ if (RESERVED_PARAMETER_NAMES_1_1 && !RESERVED_PARAMETER_NAMES_1_1.done && (_a = RESERVED_PARAMETER_NAMES_1.return)) _a.call(RESERVED_PARAMETER_NAMES_1);
4254
+ }
4255
+ finally { if (e_1) throw e_1.error; }
4256
+ }
4257
+ return [2 /*return*/, reservedParameters];
4258
+ }
4259
+ });
4260
+ });
4261
+ }
4262
+
4263
+ /**
4264
+ * @@@
4265
+ *
4266
+ * @private internal utility of `createPipelineExecutor`
4267
+ */
4268
+ function executeTemplate(options) {
4269
+ return __awaiter(this, void 0, void 0, function () {
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;
4271
+ var e_1, _f, _g;
4272
+ return __generator(this, function (_h) {
4273
+ switch (_h.label) {
4274
+ case 0:
4275
+ currentTemplate = options.currentTemplate, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, llmTools = options.llmTools, onProgress = options.onProgress, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
4276
+ maxExecutionAttempts = settings.maxExecutionAttempts;
4277
+ name = "pipeline-executor-frame-".concat(currentTemplate.name);
4278
+ title = currentTemplate.title;
4279
+ priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
4280
+ return [4 /*yield*/, onProgress({
4281
+ name: name,
4282
+ title: title,
4283
+ isStarted: false,
4284
+ isDone: false,
4285
+ templateType: currentTemplate.templateType,
4286
+ parameterName: currentTemplate.resultingParameterName,
4287
+ parameterValue: null,
4288
+ // <- [🍸]
4289
+ })];
4290
+ case 1:
4291
+ _h.sent();
4292
+ usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
4293
+ dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
4294
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
4295
+ if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
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)
4297
+ .map(function (name) { return "{".concat(name, "}"); })
4298
+ .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
4299
+ .map(function (name) { return "{".concat(name, "}"); })
4300
+ .join(', '), "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
4301
+ }
4302
+ _b = (_a = Object).freeze;
4303
+ _c = [{}];
4304
+ return [4 /*yield*/, getReservedParametersForTemplate({
4305
+ preparedPipeline: preparedPipeline,
4306
+ template: currentTemplate,
4307
+ pipelineIdentification: pipelineIdentification,
4308
+ })];
4309
+ case 2:
4310
+ definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
4311
+ definedParameterNames = new Set(Object.keys(definedParameters));
4312
+ parameters = {};
4313
+ _loop_1 = function (parameterName) {
4314
+ // Situation: Parameter is defined and used
4315
+ if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
4316
+ parameters[parameterName] = definedParameters[parameterName];
4317
+ }
4318
+ // Situation: Parameter is defined but NOT used
4319
+ else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
4320
+ // Situation: Parameter is NOT defined BUT used
4321
+ else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
4322
+ // Houston, we have a problem
4323
+ // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
4324
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
4325
+ }
4326
+ };
4327
+ try {
4328
+ // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
4329
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
4330
+ for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
4331
+ parameterName = _e.value;
4332
+ _loop_1(parameterName);
4333
+ }
3832
4334
  }
3833
- _h.label = 5;
3834
- case 5:
3835
- attempt++;
3836
- return [3 /*break*/, 3];
3837
- case 6:
3838
- //------------------------------------
3839
- /*
3840
-
3841
-
3842
-
3843
-
3844
-
3845
-
3846
-
3847
-
3848
-
3849
- */
3850
- //------------------------------------
3851
- if ($ongoingResult.$resultString === null) {
3852
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
4335
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4336
+ finally {
4337
+ try {
4338
+ if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
4339
+ }
4340
+ finally { if (e_1) throw e_1.error; }
3853
4341
  }
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
4343
+ Object.freeze(parameters);
4344
+ maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
4345
+ jokerParameterNames = currentTemplate.jokerParameterNames || [];
4346
+ preparedContent = (currentTemplate.preparedContent || '{content}')
4347
+ .split('{content}')
4348
+ .join(currentTemplate.content);
4349
+ return [4 /*yield*/, executeFormatSubvalues({
4350
+ jokerParameterNames: jokerParameterNames,
4351
+ priority: priority,
4352
+ maxAttempts: maxAttempts,
4353
+ preparedContent: preparedContent,
4354
+ parameters: parameters,
4355
+ template: currentTemplate,
4356
+ preparedPipeline: preparedPipeline,
4357
+ tools: tools,
4358
+ llmTools: llmTools,
4359
+ settings: settings,
4360
+ $executionReport: $executionReport,
4361
+ pipelineIdentification: pipelineIdentification,
4362
+ })];
4363
+ case 3:
4364
+ resultString = _h.sent();
3854
4365
  return [4 /*yield*/, onProgress({
3855
4366
  name: name,
3856
4367
  title: title,
@@ -3858,13 +4369,15 @@ function executeTemplate(options) {
3858
4369
  isDone: true,
3859
4370
  templateType: currentTemplate.templateType,
3860
4371
  parameterName: currentTemplate.resultingParameterName,
3861
- parameterValue: $ongoingResult.$resultString,
4372
+ parameterValue: resultString,
3862
4373
  // <- [🍸]
3863
4374
  })];
3864
- case 7:
4375
+ case 4:
3865
4376
  _h.sent();
3866
4377
  return [2 /*return*/, Object.freeze((_g = {},
3867
- _g[currentTemplate.resultingParameterName] = $ongoingResult.$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,
3868
4381
  _g))];
3869
4382
  }
3870
4383
  });
@@ -3873,6 +4386,9 @@ function executeTemplate(options) {
3873
4386
  /**
3874
4387
  * TODO: [🤹‍♂️]
3875
4388
  */
4389
+ /**
4390
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4391
+ */
3876
4392
 
3877
4393
  /**
3878
4394
  * @@@
@@ -3893,6 +4409,7 @@ function filterJustOutputParameters(options) {
3893
4409
  };
3894
4410
  try {
3895
4411
  // Note: Filter ONLY output parameters
4412
+ // TODO: [👩🏾‍🤝‍👩🏻] Maybe use here `mapAvailableToExpectedParameters`
3896
4413
  for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
3897
4414
  var isOutput = _a.isOutput;
3898
4415
  return isOutput;
@@ -4007,7 +4524,7 @@ function executePipeline(options) {
4007
4524
  return name === parameterName;
4008
4525
  });
4009
4526
  if (!(parameter === undefined)) return [3 /*break*/, 1];
4010
- 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 "); })));
4011
4528
  return [3 /*break*/, 4];
4012
4529
  case 1:
4013
4530
  if (!(parameter.isInput === false)) return [3 /*break*/, 4];
@@ -4019,10 +4536,10 @@ function executePipeline(options) {
4019
4536
  // Note: Wait a short time to prevent race conditions
4020
4537
  _h.sent();
4021
4538
  _h.label = 3;
4022
- 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 "); }), {
4023
4540
  isSuccessful: false,
4024
4541
  errors: __spreadArray([
4025
- 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 "); }))
4026
4543
  ], __read(errors), false).map(serializeError),
4027
4544
  warnings: warnings.map(serializeError),
4028
4545
  executionReport: executionReport,
@@ -4086,7 +4603,7 @@ function executePipeline(options) {
4086
4603
  case 0:
4087
4604
  if (loopLimit-- < 0) {
4088
4605
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
4089
- 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 "); }));
4090
4607
  }
4091
4608
  currentTemplate = unresovedTemplates_1.find(function (template) {
4092
4609
  return template.dependentParameterNames.every(function (name) {
@@ -4096,14 +4613,14 @@ function executePipeline(options) {
4096
4613
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
4097
4614
  throw new UnexpectedError(
4098
4615
  // TODO: [🐎] DRY
4099
- 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
4100
4617
  .map(function (_a) {
4101
4618
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
4102
4619
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
4103
4620
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
4104
4621
  .join(' and '));
4105
4622
  })
4106
- .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 "); }));
4107
4624
  case 1:
4108
4625
  if (!!currentTemplate) return [3 /*break*/, 3];
4109
4626
  /* [🤹‍♂️] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -4120,10 +4637,10 @@ function executePipeline(options) {
4120
4637
  llmTools: llmTools,
4121
4638
  onProgress: function (progress) {
4122
4639
  if (isReturned) {
4123
- 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)
4124
4641
  .split('\n')
4125
4642
  .map(function (line) { return "> ".concat(line); })
4126
- .join('\n')), "\n "); }));
4643
+ .join('\n')), "\n "); }));
4127
4644
  }
4128
4645
  if (onProgress) {
4129
4646
  onProgress(progress);
@@ -4131,7 +4648,7 @@ function executePipeline(options) {
4131
4648
  },
4132
4649
  settings: settings,
4133
4650
  $executionReport: executionReport,
4134
- 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 "); }),
4135
4652
  })
4136
4653
  .then(function (newParametersToPass) {
4137
4654
  parametersToPass = __assign(__assign({}, newParametersToPass), parametersToPass);
@@ -4140,6 +4657,8 @@ function executePipeline(options) {
4140
4657
  .then(function () {
4141
4658
  resolving_1 = resolving_1.filter(function (w) { return w !== work_1; });
4142
4659
  });
4660
+ // <- Note: Errors are catched here [3]
4661
+ // TODO: BUT if in multiple templates are errors, only the first one is catched so maybe we should catch errors here and save them to errors array here
4143
4662
  resolving_1.push(work_1);
4144
4663
  _j.label = 4;
4145
4664
  case 4: return [2 /*return*/];
@@ -4221,6 +4740,9 @@ function executePipeline(options) {
4221
4740
  });
4222
4741
  });
4223
4742
  }
4743
+ /**
4744
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4745
+ */
4224
4746
 
4225
4747
  /**
4226
4748
  * Creates executor function from pipeline and execution tools.
@@ -4232,7 +4754,7 @@ function executePipeline(options) {
4232
4754
  function createPipelineExecutor(options) {
4233
4755
  var _this = this;
4234
4756
  var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
4235
- 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;
4236
4758
  validatePipeline(pipeline);
4237
4759
  var pipelineIdentification = (function () {
4238
4760
  // Note: This is a 😐 implementation of [🚞]
@@ -4252,9 +4774,11 @@ function createPipelineExecutor(options) {
4252
4774
  else if (isNotPreparedWarningSupressed !== true) {
4253
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 "); }));
4254
4776
  }
4777
+ var runCount = 0;
4255
4778
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
4256
4779
  return __generator(this, function (_a) {
4257
- return [2 /*return*/, executePipeline({
4780
+ runCount++;
4781
+ return [2 /*return*/, /* not await */ executePipeline({
4258
4782
  pipeline: pipeline,
4259
4783
  preparedPipeline: preparedPipeline,
4260
4784
  setPreparedPipeline: function (newPreparedPipeline) {
@@ -4263,10 +4787,11 @@ function createPipelineExecutor(options) {
4263
4787
  inputParameters: inputParameters,
4264
4788
  tools: tools,
4265
4789
  onProgress: onProgress,
4266
- pipelineIdentification: pipelineIdentification,
4790
+ pipelineIdentification: spaceTrim$1(function (block) { return "\n ".concat(block(pipelineIdentification), "\n ").concat(runCount === 1 ? '' : "Run #".concat(runCount), "\n "); }),
4267
4791
  settings: {
4268
4792
  maxExecutionAttempts: maxExecutionAttempts,
4269
4793
  maxParallelCount: maxParallelCount,
4794
+ csvSettings: csvSettings,
4270
4795
  isVerbose: isVerbose,
4271
4796
  isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
4272
4797
  },
@@ -4275,6 +4800,9 @@ function createPipelineExecutor(options) {
4275
4800
  }); };
4276
4801
  return pipelineExecutor;
4277
4802
  }
4803
+ /**
4804
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4805
+ */
4278
4806
 
4279
4807
  /**
4280
4808
  * @@@
@@ -4326,7 +4854,7 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4326
4854
  outputParameters = result.outputParameters;
4327
4855
  knowledgePiecesRaw = outputParameters.knowledgePieces;
4328
4856
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
4329
- // <- TODO: !!!!! Smarter split and filter out empty pieces
4857
+ // <- TODO: [main] !!!!! Smarter split and filter out empty pieces
4330
4858
  if (isVerbose) {
4331
4859
  console.info('knowledgeTextPieces:', knowledgeTextPieces);
4332
4860
  }
@@ -4384,8 +4912,13 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4384
4912
  case 6: return [3 /*break*/, 8];
4385
4913
  case 7:
4386
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
+ }
4387
4920
  // TODO: [🟥] Detect browser / node and make it colorfull
4388
- 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");
4389
4922
  return [3 /*break*/, 8];
4390
4923
  case 8: return [2 /*return*/, {
4391
4924
  name: name,
@@ -4406,7 +4939,7 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4406
4939
  });
4407
4940
  }
4408
4941
  /**
4409
- * TODO: [🐝][🔼] !!! Export via `@promptbook/markdown`
4942
+ * TODO: [🐝][🔼][main] !!! Export via `@promptbook/markdown`
4410
4943
  * TODO: [🪂] Do it in parallel 11:11
4411
4944
  * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4412
4945
  */
@@ -4430,7 +4963,7 @@ function prepareKnowledgePieces(knowledgeSources, options) {
4430
4963
  var partialPieces, pieces;
4431
4964
  return __generator(this, function (_a) {
4432
4965
  switch (_a.label) {
4433
- 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
4434
4967
  options)];
4435
4968
  case 1:
4436
4969
  partialPieces = _a.sent();
@@ -4622,7 +5155,7 @@ function preparePersona(personaDescription, options) {
4622
5155
  });
4623
5156
  }
4624
5157
  /**
4625
- * 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
4626
5159
  * TODO: [🏢] !! Check validity of `modelName` in pipeline
4627
5160
  * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4628
5161
  * TODO: [🏢] !! Check validity of `temperature` in pipeline
@@ -4671,7 +5204,7 @@ function prepareTemplates(pipeline, options) {
4671
5204
  case 0:
4672
5205
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
4673
5206
  templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4674
- // 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)
4675
5208
  TODO_USE(parameters);
4676
5209
  templatesPrepared = new Array(
4677
5210
  // <- TODO: [🧱] Implement in a functional (not new Class) way
@@ -4703,7 +5236,7 @@ function prepareTemplates(pipeline, options) {
4703
5236
  /**
4704
5237
  * TODO: [🧠] Add context to each template (if missing)
4705
5238
  * TODO: [🧠] What is better name `prepareTemplate` or `prepareTemplateAndParameters`
4706
- * TODO: [♨] !!! Prepare index the samples and maybe templates
5239
+ * TODO: [♨][main] !!! Prepare index the samples and maybe templates
4707
5240
  * TODO: Write tests for `preparePipeline`
4708
5241
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4709
5242
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
@@ -4875,7 +5408,7 @@ var knowledgeCommandParser = {
4875
5408
  if (sourceContent === '') {
4876
5409
  throw new ParseError("Source is not defined");
4877
5410
  }
4878
- // TODO: !!!! Following checks should be applied every link in the `sourceContent`
5411
+ // TODO: [main] !!!! Following checks should be applied every link in the `sourceContent`
4879
5412
  if (sourceContent.startsWith('http://')) {
4880
5413
  throw new ParseError("Source is not secure");
4881
5414
  }
@@ -5060,7 +5593,7 @@ var templateCommandParser = {
5060
5593
  if (command.templateType === 'KNOWLEDGE') {
5061
5594
  knowledgeCommandParser.$applyToPipelineJson({
5062
5595
  type: 'KNOWLEDGE',
5063
- 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
5064
5597
  }, $pipelineJson);
5065
5598
  $templateJson.isTemplate = false;
5066
5599
  return;
@@ -5410,6 +5943,171 @@ function normalizeTo_SCREAMING_CASE(text) {
5410
5943
  * TODO: [🌺] Use some intermediate util splitWords
5411
5944
  */
5412
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
+
5413
6111
  /**
5414
6112
  * Parses the foreach command
5415
6113
  *
@@ -5439,15 +6137,16 @@ var foreachCommandParser = {
5439
6137
  /**
5440
6138
  * Link to discussion
5441
6139
  */
5442
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
6140
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/148',
5443
6141
  /**
5444
6142
  * Example usages of the FOREACH command
5445
6143
  */
5446
6144
  examples: [
5447
- 'FOREACH List Line `{customers}` -> `{customer}`',
5448
- 'FOR List Line `{customers}` -> `{customer}`',
5449
- 'EACH List Line `{customers}` -> `{customer}`',
5450
- // <- 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}`',
5451
6150
  ],
5452
6151
  /**
5453
6152
  * Parses the FOREACH command
@@ -5455,55 +6154,75 @@ var foreachCommandParser = {
5455
6154
  parse: function (input) {
5456
6155
  var args = input.args;
5457
6156
  var formatName = normalizeTo_SCREAMING_CASE(args[0] || '');
5458
- var cellName = normalizeTo_SCREAMING_CASE(args[1] || '');
5459
- var parameterNameWrapped = args[2];
6157
+ var subformatName = normalizeTo_SCREAMING_CASE(args[1] || '');
6158
+ var parameterNameArg = args[2] || '';
5460
6159
  var assignSign = args[3];
5461
- var subparameterNameWrapped = args[4];
5462
- if (![
5463
- 'LIST',
5464
- 'CSV',
5465
- // <- TODO: [🏢] Unhardcode formats
5466
- ].includes(formatName)) {
5467
- console.info({ args: args, formatName: formatName });
5468
- 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 "); }));
5469
6167
  // <- TODO: [🏢] List all supported format names
5470
6168
  }
5471
- if (![
5472
- 'LINE',
5473
- 'ROW',
5474
- 'COLUMN',
5475
- 'CELL',
5476
- // <- TODO: [🏢] Unhardcode format cells
5477
- ].includes(cellName)) {
5478
- console.info({ args: args, cellName: cellName });
5479
- throw new Error("Format ".concat(formatName, " does not support cell \"").concat(cellName, "\""));
5480
- // <- 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
5481
6178
  }
5482
6179
  if (assignSign !== '->') {
5483
- console.info({ args: args, assignSign: assignSign });
5484
- throw new Error("FOREACH command must have '->' to assign the value to the parameter");
5485
- }
5486
- // TODO: !!!!!! Replace with propper parameter name validation
5487
- if ((parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(0, 1)) !== '{' ||
5488
- (parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(parameterNameWrapped.length - 1, parameterNameWrapped.length)) !== '}') {
5489
- 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));
5490
- throw new Error("!!!!!! 1 Here will be error (with rules and precise error) from validateParameterName");
5491
- }
5492
- var parameterName = parameterNameWrapped.substring(1, parameterNameWrapped.length - 1);
5493
- // TODO: !!!!!! Replace with propper parameter name validation
5494
- if ((subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(0, 1)) !== '{' ||
5495
- (subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(subparameterNameWrapped.length - 1, subparameterNameWrapped.length)) !==
5496
- '}') {
5497
- console.info({ args: args, subparameterNameWrapped: subparameterNameWrapped });
5498
- throw new Error("!!!!!! 2 Here will be error (with rules and precise error) from validateParameterName");
5499
- }
5500
- 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
+ }
5501
6219
  return {
5502
6220
  type: 'FOREACH',
5503
6221
  formatName: formatName,
5504
- cellName: cellName,
6222
+ subformatName: subformatName,
5505
6223
  parameterName: parameterName,
5506
- subparameterName: subparameterName,
6224
+ inputSubparameterNames: inputSubparameterNames,
6225
+ outputSubparameterName: outputSubparameterName,
5507
6226
  };
5508
6227
  },
5509
6228
  /**
@@ -5512,11 +6231,17 @@ var foreachCommandParser = {
5512
6231
  * Note: `$` is used to indicate that this function mutates given `templateJson`
5513
6232
  */
5514
6233
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5515
- var formatName = command.formatName, cellName = command.cellName, parameterName = command.parameterName, subparameterName = command.subparameterName;
5516
- // TODO: !!!!!! Detect double use
5517
- // TODO: !!!!!! Detect usage with JOKER and don't allow it
5518
- $templateJson.foreach = { formatName: formatName, cellName: cellName, parameterName: parameterName, subparameterName: subparameterName };
5519
- 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
5520
6245
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
5521
6246
  },
5522
6247
  /**
@@ -5539,8 +6264,7 @@ var foreachCommandParser = {
5539
6264
  },
5540
6265
  };
5541
6266
  /**
5542
- * TODO: !!!!!! Comment console logs
5543
- * 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
5544
6268
  */
5545
6269
 
5546
6270
  /**
@@ -5650,12 +6374,11 @@ var jokerCommandParser = {
5650
6374
  */
5651
6375
  parse: function (input) {
5652
6376
  var args = input.args;
5653
- // TODO: !!!!!! Replace with propper parameter name validation
5654
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5655
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5656
- throw new ParseError("Invalid joker");
6377
+ if (args.length !== 1) {
6378
+ throw new ParseError("JOKE command expects exactly one parameter name");
5657
6379
  }
5658
- var parameterName = parametersMatch.groups.parameterName;
6380
+ var parameterNameArg = args[0] || '';
6381
+ var parameterName = validateParameterName(parameterNameArg);
5659
6382
  return {
5660
6383
  type: 'JOKER',
5661
6384
  parameterName: parameterName,
@@ -5730,6 +6453,9 @@ var modelCommandParser = {
5730
6453
  */
5731
6454
  parse: function (input) {
5732
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 "); });
5733
6459
  // TODO: Make this more elegant and dynamically
5734
6460
  if (normalized.startsWith('MODEL_VARIANT')) {
5735
6461
  if (normalized === 'MODEL_VARIANT_CHAT') {
@@ -5745,17 +6471,13 @@ var modelCommandParser = {
5745
6471
  key: 'modelVariant',
5746
6472
  value: 'COMPLETION',
5747
6473
  };
6474
+ // <- Note: [🤖]
5748
6475
  }
5749
6476
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
5750
- return {
5751
- type: 'MODEL',
5752
- key: 'modelVariant',
5753
- value: 'EMBEDDING',
5754
- };
5755
- // <- Note: [🤖]
6477
+ spaceTrim(function (block) { return "\n Embedding model can not be used in pipeline\n\n ".concat(block(availableVariantsMessage), "\n "); });
5756
6478
  }
5757
6479
  else {
5758
- 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 "); }));
5759
6481
  }
5760
6482
  }
5761
6483
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5880,14 +6602,13 @@ var parameterCommandParser = {
5880
6602
  * Parses the PARAMETER command
5881
6603
  */
5882
6604
  parse: function (input) {
5883
- var normalized = input.normalized, raw = input.raw;
5884
- var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5885
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5886
- throw new ParseError("Invalid parameter");
5887
- }
5888
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5889
- if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5890
- 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 "); }));
5891
6612
  }
5892
6613
  var isInput = normalized.startsWith('INPUT');
5893
6614
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5895,11 +6616,12 @@ var parameterCommandParser = {
5895
6616
  isInput = false;
5896
6617
  isOutput = false;
5897
6618
  }
5898
- // TODO: !!!!!! Add parameter name validation
6619
+ var parameterName = validateParameterName(parameterNameRaw);
6620
+ var parameterDescription = parameterDescriptionRaw.trim() || null;
5899
6621
  return {
5900
6622
  type: 'PARAMETER',
5901
6623
  parameterName: parameterName,
5902
- parameterDescription: parameterDescription.trim() || null,
6624
+ parameterDescription: parameterDescription,
5903
6625
  isInput: isInput,
5904
6626
  isOutput: isOutput,
5905
6627
  };
@@ -6224,6 +6946,7 @@ var promptbookVersionCommandParser = {
6224
6946
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6225
6947
  */
6226
6948
  $applyToPipelineJson: function (command, $pipelineJson) {
6949
+ // TODO: Warn if the version is overridden
6227
6950
  $pipelineJson.promptbookVersion = command.promptbookVersion;
6228
6951
  },
6229
6952
  /**
@@ -6706,7 +7429,9 @@ function parseCommand(raw, usagePlace) {
6706
7429
  for (var commandNameSegmentsCount = 0; commandNameSegmentsCount < Math.min(items.length, 3); commandNameSegmentsCount++) {
6707
7430
  var commandNameRaw = items.slice(0, commandNameSegmentsCount + 1).join('_');
6708
7431
  var args = items.slice(commandNameSegmentsCount + 1);
6709
- var rawArgs = raw.substring(commandNameRaw.length).trim();
7432
+ var rawArgs = raw
7433
+ .substring(commandNameRaw.length)
7434
+ .trim();
6710
7435
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6711
7436
  if (command !== null) {
6712
7437
  return command;
@@ -6717,7 +7442,9 @@ function parseCommand(raw, usagePlace) {
6717
7442
  {
6718
7443
  var commandNameRaw = items.slice(-1).join('_');
6719
7444
  var args = items.slice(0, -1); // <- Note: This is probbably not correct
6720
- var rawArgs = raw.substring(0, raw.length - commandNameRaw.length).trim();
7445
+ var rawArgs = raw
7446
+ .substring(0, raw.length - commandNameRaw.length)
7447
+ .trim();
6721
7448
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6722
7449
  if (command !== null) {
6723
7450
  return command;
@@ -6857,7 +7584,7 @@ function extractAllListItemsFromMarkdown(markdown) {
6857
7584
  function extractOneBlockFromMarkdown(markdown) {
6858
7585
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
6859
7586
  if (codeBlocks.length !== 1) {
6860
- 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 "); }));
6861
7588
  }
6862
7589
  return codeBlocks[0];
6863
7590
  }
@@ -7044,7 +7771,7 @@ function pipelineStringToJsonSync(pipelineString) {
7044
7771
  var $pipelineJson = {
7045
7772
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
7046
7773
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
7047
- promptbookVersion: PROMPTBOOK_VERSION,
7774
+ promptbookVersion: undefined /* <- Note: By default no explicit version */,
7048
7775
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
7049
7776
  parameters: [],
7050
7777
  templates: [],
@@ -7335,7 +8062,7 @@ function pipelineStringToJsonSync(pipelineString) {
7335
8062
  return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
7336
8063
  }
7337
8064
  /**
7338
- * TODO: !!!! Warn if used only sync version
8065
+ * TODO: [main] !!!! Warn if used only sync version
7339
8066
  * TODO: [🚞] Report here line/column of error
7340
8067
  * TODO: Use spaceTrim more effectively
7341
8068
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
@@ -7416,70 +8143,6 @@ function addAutoGeneratedSection(content, options) {
7416
8143
  * TODO: [🏛] This can be part of markdown builder
7417
8144
  */
7418
8145
 
7419
- /**
7420
- * @@@
7421
- *
7422
- * @param text @@@
7423
- * @param _isFirstLetterCapital @@@
7424
- * @returns @@@
7425
- * @example 'helloWorld'
7426
- * @example 'iLovePromptbook'
7427
- * @public exported from `@promptbook/utils`
7428
- */
7429
- function normalizeTo_camelCase(text, _isFirstLetterCapital) {
7430
- var e_1, _a;
7431
- if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
7432
- var charType;
7433
- var lastCharType = null;
7434
- var normalizedName = '';
7435
- try {
7436
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
7437
- var char = text_1_1.value;
7438
- var normalizedChar = void 0;
7439
- if (/^[a-z]$/.test(char)) {
7440
- charType = 'LOWERCASE';
7441
- normalizedChar = char;
7442
- }
7443
- else if (/^[A-Z]$/.test(char)) {
7444
- charType = 'UPPERCASE';
7445
- normalizedChar = char.toLowerCase();
7446
- }
7447
- else if (/^[0-9]$/.test(char)) {
7448
- charType = 'NUMBER';
7449
- normalizedChar = char;
7450
- }
7451
- else {
7452
- charType = 'OTHER';
7453
- normalizedChar = '';
7454
- }
7455
- if (!lastCharType) {
7456
- if (_isFirstLetterCapital) {
7457
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
7458
- }
7459
- }
7460
- else if (charType !== lastCharType &&
7461
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
7462
- !(lastCharType === 'NUMBER') &&
7463
- !(charType === 'NUMBER')) {
7464
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
7465
- }
7466
- normalizedName += normalizedChar;
7467
- lastCharType = charType;
7468
- }
7469
- }
7470
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
7471
- finally {
7472
- try {
7473
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
7474
- }
7475
- finally { if (e_1) throw e_1.error; }
7476
- }
7477
- return normalizedName;
7478
- }
7479
- /**
7480
- * TODO: [🌺] Use some intermediate util splitWords
7481
- */
7482
-
7483
8146
  /**
7484
8147
  * Creates a Mermaid graph based on the promptbook
7485
8148
  *
@@ -7536,9 +8199,9 @@ function renderPromptbookMermaid(pipelineJson, options) {
7536
8199
  return promptbookMermaid;
7537
8200
  }
7538
8201
  /**
7539
- * TODO: !!!!!! FOREACH in mermaid graph
7540
- * TODO: !!!!!! Knowledge in mermaid graph
7541
- * TODO: !!!!!! Personas in mermaid graph
8202
+ * TODO: !!!!! FOREACH in mermaid graph
8203
+ * TODO: !!!!! Knowledge in mermaid graph
8204
+ * TODO: !!!!! Personas in mermaid graph
7542
8205
  * TODO: Maybe use some Mermaid package instead of string templating
7543
8206
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
7544
8207
  */
@@ -7613,7 +8276,7 @@ function isSerializableAsJson(value) {
7613
8276
  }
7614
8277
  }
7615
8278
  /**
7616
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
8279
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
7617
8280
  * TODO: [🧠][💺] Can be done this on type-level?
7618
8281
  */
7619
8282
 
@@ -7680,21 +8343,41 @@ function usageToWorktime(usage) {
7680
8343
  * @public exported from `@promptbook/core`
7681
8344
  */
7682
8345
  function usageToHuman(usage) {
7683
- var report = 'Usage:';
8346
+ var reportItems = [];
7684
8347
  var uncertainNumberToHuman = function (_a) {
7685
8348
  var value = _a.value, isUncertain = _a.isUncertain;
7686
8349
  return "".concat(isUncertain ? 'approximately ' : '').concat(Math.round(value * 100) / 100);
7687
8350
  };
7688
- report += '\n' + "- Cost ".concat(uncertainNumberToHuman(usage.price), " USD");
7689
- report += '\n' + "- Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time");
7690
- 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 "); });
7691
8375
  }
7692
8376
  /**
7693
- * TODO: Use "$1" not "1 USD"
7694
- * TODO: Use markdown formatting like "Cost approximately **$1**"
7695
- * 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
7696
8380
  * TODO: [🧠] Maybe make from `uncertainNumberToHuman` separate exported utility
7697
- * TODO: When negligible usage, report "Negligible" or just don't report it
7698
8381
  * TODO: [🧠] Maybe use "~" instead of "approximately"
7699
8382
  * TODO: [🏛] Maybe make some markdown builder
7700
8383
  */
@@ -8343,8 +9026,8 @@ function formatNumber(value) {
8343
9026
  */
8344
9027
  function createMarkdownTable(table) {
8345
9028
  var columnWidths = table.reduce(function (widths, row) {
8346
- row.forEach(function (cell, columnIndex) {
8347
- var cellLength = cell.length;
9029
+ row.forEach(function (subformat, columnIndex) {
9030
+ var cellLength = subformat.length;
8348
9031
  if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
8349
9032
  widths[columnIndex] = cellLength;
8350
9033
  }
@@ -8352,12 +9035,12 @@ function createMarkdownTable(table) {
8352
9035
  return widths;
8353
9036
  }, []);
8354
9037
  var header = "| ".concat(table[0]
8355
- .map(function (cell, columnIndex) { return cell.padEnd(columnWidths[columnIndex]); })
9038
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
8356
9039
  .join(' | '), " |");
8357
9040
  var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
8358
9041
  var rows = table.slice(1).map(function (row) {
8359
- var paddedRow = row.map(function (cell, columnIndex) {
8360
- return cell.padEnd(columnWidths[columnIndex]);
9042
+ var paddedRow = row.map(function (subformat, columnIndex) {
9043
+ return subformat.padEnd(columnWidths[columnIndex]);
8361
9044
  });
8362
9045
  return "| ".concat(paddedRow.join(' | '), " |");
8363
9046
  });
@@ -8633,5 +9316,5 @@ function executionReportJsonToString(executionReportJson, options) {
8633
9316
  * TODO: [🧠] Should be in generated file GENERATOR_WARNING
8634
9317
  */
8635
9318
 
8636
- 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 };
8637
9320
  //# sourceMappingURL=index.es.js.map