@promptbook/cli 0.69.0-8 → 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 (71) hide show
  1. package/README.md +4 -1
  2. package/esm/index.es.js +1076 -397
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/promptbook-collection/index.d.ts +0 -3
  5. package/esm/typings/src/_packages/core.index.d.ts +12 -0
  6. package/esm/typings/src/_packages/types.index.d.ts +6 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +4 -4
  8. package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
  9. package/esm/typings/src/collection/constructors/createCollectionFromUrl.d.ts +1 -1
  10. package/esm/typings/src/commands/FOREACH/ForeachCommand.d.ts +1 -1
  11. package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -5
  12. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +1 -2
  13. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  14. package/esm/typings/src/config.d.ts +11 -4
  15. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +1 -1
  16. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -3
  17. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +6 -5
  18. package/esm/typings/src/errors/AbstractFormatError.d.ts +11 -0
  19. package/esm/typings/src/execution/PipelineExecutor.d.ts +1 -0
  20. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +5 -6
  21. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTemplateResult.d.ts +24 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorSettings.d.ts +7 -0
  23. package/esm/typings/src/execution/createPipelineExecutor/00-createPipelineExecutor.d.ts +3 -0
  24. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +4 -1
  25. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +3 -0
  26. package/esm/typings/src/execution/createPipelineExecutor/{30-executeFormatCells.d.ts → 30-executeFormatSubvalues.d.ts} +2 -2
  27. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +2 -8
  28. package/esm/typings/src/execution/embeddingVectorToString.d.ts +1 -1
  29. package/esm/typings/src/execution/utils/checkExpectations.d.ts +2 -0
  30. package/esm/typings/src/execution/utils/usageToHuman.d.ts +3 -4
  31. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +14 -15
  32. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +31 -0
  33. package/esm/typings/src/formats/csv/{ListFormatDefinition.d.ts → CsvFormatDefinition.d.ts} +6 -3
  34. package/esm/typings/src/formats/csv/CsvFormatError.d.ts +10 -0
  35. package/esm/typings/src/formats/csv/CsvSettings.d.ts +13 -0
  36. package/esm/typings/src/formats/index.d.ts +1 -1
  37. package/esm/typings/src/formats/json/JsonFormatDefinition.d.ts +4 -3
  38. package/esm/typings/src/formats/text/TextFormatDefinition.d.ts +19 -0
  39. package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +4 -3
  40. package/esm/typings/src/knowledge/prepare-knowledge/markdown/prepareKnowledgeFromMarkdown.d.ts +1 -1
  41. package/esm/typings/src/knowledge/prepare-knowledge/pdf/prepareKnowledgeFromPdf.d.ts +1 -1
  42. package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +1 -1
  43. package/esm/typings/src/llm-providers/anthropic-claude/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 +1079 -401
  66. package/umd/index.umd.js.map +1 -1
  67. package/esm/typings/src/formats/list/ListFormatDefinition.d.ts +0 -16
  68. /package/esm/typings/src/utils/{extractParameterNames.test.d.ts → parameters/extractParameterNames.test.d.ts} +0 -0
  69. /package/esm/typings/src/{execution/utils/usageToHuman.test.d.ts → utils/parameters/mapAvailableToExpectedParameters.test.d.ts} +0 -0
  70. /package/esm/typings/src/utils/{replaceParameters.test.d.ts → parameters/replaceParameters.test.d.ts} +0 -0
  71. /package/esm/typings/src/{personas/preparePersona.test.d.ts → utils/validators/parameterName/validateParameterName.test.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -6,6 +6,7 @@ import { stat, access, constants, readdir, readFile, writeFile, mkdir, unlink }
6
6
  import { join as join$1, dirname } from 'path';
7
7
  import { format } from 'prettier';
8
8
  import parserHtml from 'prettier/parser-html';
9
+ import { unparse, parse } from 'papaparse';
9
10
  import hexEncoder from 'crypto-js/enc-hex';
10
11
  import sha256 from 'crypto-js/sha256';
11
12
  import { join } from 'path/posix';
@@ -20,8 +21,8 @@ import OpenAI from 'openai';
20
21
  /**
21
22
  * The version of the Promptbook library
22
23
  */
23
- var PROMPTBOOK_VERSION = '0.69.0-7';
24
- // TODO: !!!! List here all the versions and annotate + put into script
24
+ var PROMPTBOOK_VERSION = '0.69.0-21';
25
+ // TODO: [main] !!!! List here all the versions and annotate + put into script
25
26
 
26
27
  /*! *****************************************************************************
27
28
  Copyright (c) Microsoft Corporation.
@@ -356,7 +357,7 @@ function checkSerializableAsJson(name, value) {
356
357
  }
357
358
  /**
358
359
  * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
359
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
360
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
360
361
  * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
361
362
  */
362
363
 
@@ -502,6 +503,17 @@ var DEFAULT_REMOTE_URL = 'https://api.pavolhejny.com/';
502
503
  */
503
504
  var DEFAULT_REMOTE_URL_PATH = '/promptbook/socket.io';
504
505
  // <- TODO: [🧜‍♂️]
506
+ /**
507
+ * @@@
508
+ *
509
+ * @public exported from `@promptbook/core`
510
+ */
511
+ var DEFAULT_CSV_SETTINGS = Object.freeze({
512
+ delimiter: ',',
513
+ quoteChar: '"',
514
+ newline: '\n',
515
+ skipEmptyLines: true,
516
+ });
505
517
  /**
506
518
  * @@@
507
519
  *
@@ -670,7 +682,7 @@ function pipelineJsonToString(pipelineJson) {
670
682
  commands.push("PIPELINE URL ".concat(pipelineUrl));
671
683
  }
672
684
  commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
673
- // TODO: !!! This increase size of the bundle and is probbably not necessary
685
+ // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
674
686
  pipelineString = prettifyMarkdown(pipelineString);
675
687
  try {
676
688
  for (var _g = __values(parameters.filter(function (_a) {
@@ -818,12 +830,12 @@ function pipelineJsonToString(pipelineJson) {
818
830
  pipelineString += '```' + contentLanguage;
819
831
  pipelineString += '\n';
820
832
  pipelineString += spaceTrim$1(content);
821
- // <- TODO: !!! Escape
833
+ // <- TODO: [main] !!! Escape
822
834
  // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
823
835
  pipelineString += '\n';
824
836
  pipelineString += '```';
825
837
  pipelineString += '\n\n';
826
- pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: !!! If the parameter here has description, add it and use templateParameterJsonToString
838
+ pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use templateParameterJsonToString
827
839
  }
828
840
  }
829
841
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -1050,7 +1062,7 @@ function forEachAsync(array, options, callbackfunction) {
1050
1062
  });
1051
1063
  }
1052
1064
 
1053
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.69.0-7",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
1065
+ 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"}];
1054
1066
 
1055
1067
  /**
1056
1068
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -1125,7 +1137,7 @@ function isValidPromptbookVersion(version) {
1125
1137
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
1126
1138
  return false;
1127
1139
  }
1128
- // <- TODO: !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
1140
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
1129
1141
  return true;
1130
1142
  }
1131
1143
 
@@ -1294,7 +1306,7 @@ function validatePipelineCore(pipeline) {
1294
1306
  // <- Note: [🚲]
1295
1307
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1296
1308
  }
1297
- if (!isValidPromptbookVersion(pipeline.promptbookVersion)) {
1309
+ if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1298
1310
  // <- Note: [🚲]
1299
1311
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1300
1312
  }
@@ -1477,6 +1489,7 @@ function validatePipelineCore(pipeline) {
1477
1489
  }
1478
1490
  }
1479
1491
  /**
1492
+ * TODO: !!!!! [🧞‍♀️] Do not allow joker + foreach
1480
1493
  * TODO: [🧠] Work with promptbookVersion
1481
1494
  * TODO: Use here some json-schema, Zod or something similar and change it to:
1482
1495
  * > /**
@@ -1488,11 +1501,11 @@ function validatePipelineCore(pipeline) {
1488
1501
  * > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
1489
1502
  */
1490
1503
  /**
1491
- * TODO: [🐣] !!!! Validate that all samples match expectations
1492
- * TODO: [🐣][🐝] !!!! Validate that knowledge is valid (non-void)
1493
- * TODO: [🐣] !!!! Validate that persona can be used only with CHAT variant
1494
- * TODO: [🐣] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1495
- * TODO: [🐣] !!!! Validate that reserved parameter is not used as joker
1504
+ * TODO: [🐣][main] !!!! Validate that all samples match expectations
1505
+ * TODO: [🐣][🐝][main] !!!! Validate that knowledge is valid (non-void)
1506
+ * TODO: [🐣][main] !!!! Validate that persona can be used only with CHAT variant
1507
+ * TODO: [🐣][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1508
+ * TODO: [🐣][main] !!!! Validate that reserved parameter is not used as joker
1496
1509
  * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
1497
1510
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
1498
1511
  */
@@ -2220,7 +2233,7 @@ function isPipelinePrepared(pipeline) {
2220
2233
  return true;
2221
2234
  }
2222
2235
  /**
2223
- * TODO: [🔃] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2236
+ * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2224
2237
  * TODO: [🐠] Maybe base this on `makeValidator`
2225
2238
  * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2226
2239
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
@@ -2272,9 +2285,10 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2272
2285
  });
2273
2286
  Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2274
2287
  get: function () {
2275
- return this.llmExecutionTools
2276
- .map(function (tools, index) { return "".concat(index + 1, ") ").concat(tools.title, " ").concat(tools.description || ''); })
2277
- .join('\n');
2288
+ return this.llmExecutionTools.map(function (_a, index) {
2289
+ var title = _a.title;
2290
+ return "".concat(index + 1, ") `").concat(title, "`");
2291
+ }).join('\n');
2278
2292
  },
2279
2293
  enumerable: false,
2280
2294
  configurable: true
@@ -2472,9 +2486,7 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2472
2486
  throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
2473
2487
  }
2474
2488
  else {
2475
- throw new PipelineExecutionError(spaceTrim$1(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
2476
- .map(function (tools) { return "- ".concat(tools.title, " ").concat(tools.description || ''); })
2477
- .join('\n')), "\n\n "); }));
2489
+ throw new PipelineExecutionError(spaceTrim$1(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 "); }));
2478
2490
  }
2479
2491
  }
2480
2492
  });
@@ -2616,47 +2628,47 @@ function extractVariables(script) {
2616
2628
  * @public exported from `@promptbook/utils`
2617
2629
  */
2618
2630
  function extractParameterNamesFromTemplate(template) {
2619
- var e_1, _a, e_2, _b, e_3, _c;
2631
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
2620
2632
  var title = template.title, description = template.description, templateType = template.templateType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames, foreach = template.foreach;
2621
2633
  var parameterNames = new Set();
2622
2634
  try {
2623
- 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()) {
2624
- var parameterName = _e.value;
2635
+ 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()) {
2636
+ var parameterName = _f.value;
2625
2637
  parameterNames.add(parameterName);
2626
2638
  }
2627
2639
  }
2628
2640
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2629
2641
  finally {
2630
2642
  try {
2631
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2643
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
2632
2644
  }
2633
2645
  finally { if (e_1) throw e_1.error; }
2634
2646
  }
2635
2647
  if (templateType === 'SCRIPT_TEMPLATE') {
2636
2648
  try {
2637
- for (var _f = __values(extractVariables(content)), _g = _f.next(); !_g.done; _g = _f.next()) {
2638
- var parameterName = _g.value;
2649
+ for (var _g = __values(extractVariables(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
2650
+ var parameterName = _h.value;
2639
2651
  parameterNames.add(parameterName);
2640
2652
  }
2641
2653
  }
2642
2654
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
2643
2655
  finally {
2644
2656
  try {
2645
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2657
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
2646
2658
  }
2647
2659
  finally { if (e_2) throw e_2.error; }
2648
2660
  }
2649
2661
  }
2650
2662
  try {
2651
- for (var _h = __values(jokerParameterNames || []), _j = _h.next(); !_j.done; _j = _h.next()) {
2652
- var jokerName = _j.value;
2663
+ for (var _j = __values(jokerParameterNames || []), _k = _j.next(); !_k.done; _k = _j.next()) {
2664
+ var jokerName = _k.value;
2653
2665
  parameterNames.add(jokerName);
2654
2666
  }
2655
2667
  }
2656
2668
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
2657
2669
  finally {
2658
2670
  try {
2659
- if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
2671
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
2660
2672
  }
2661
2673
  finally { if (e_3) throw e_3.error; }
2662
2674
  }
@@ -2664,10 +2676,22 @@ function extractParameterNamesFromTemplate(template) {
2664
2676
  // <- Note {websiteContent} is used in `preparedContent`
2665
2677
  // Note: [🍭] Fixing dependent subparameterName from FOREACH command
2666
2678
  if (foreach !== undefined) {
2667
- if (parameterNames.has(foreach.subparameterName)) {
2668
- parameterNames.delete(foreach.subparameterName);
2669
- parameterNames.add(foreach.parameterName);
2670
- // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2679
+ try {
2680
+ for (var _l = __values(foreach.inputSubparameterNames), _m = _l.next(); !_m.done; _m = _l.next()) {
2681
+ var subparameterName = _m.value;
2682
+ if (parameterNames.has(subparameterName)) {
2683
+ parameterNames.delete(subparameterName);
2684
+ parameterNames.add(foreach.parameterName);
2685
+ // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2686
+ }
2687
+ }
2688
+ }
2689
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2690
+ finally {
2691
+ try {
2692
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
2693
+ }
2694
+ finally { if (e_4) throw e_4.error; }
2671
2695
  }
2672
2696
  }
2673
2697
  return parameterNames;
@@ -2751,6 +2775,183 @@ function union() {
2751
2775
  return union;
2752
2776
  }
2753
2777
 
2778
+ /**
2779
+ * Just marks a place of place where should be something implemented
2780
+ * No side effects.
2781
+ *
2782
+ * Note: It can be usefull suppressing eslint errors of unused variables
2783
+ *
2784
+ * @param value any values
2785
+ * @returns void
2786
+ * @private within the repository
2787
+ */
2788
+ function TODO_USE() {
2789
+ var value = [];
2790
+ for (var _i = 0; _i < arguments.length; _i++) {
2791
+ value[_i] = arguments[_i];
2792
+ }
2793
+ }
2794
+
2795
+ /**
2796
+ * This error indicates problems parsing the format value
2797
+ *
2798
+ * For example, when the format value is not a valid JSON or CSV
2799
+ * This is not thrown directly but in extended classes
2800
+ *
2801
+ * @public exported from `@promptbook/core`
2802
+ */
2803
+ var AbstractFormatError = /** @class */ (function (_super) {
2804
+ __extends(AbstractFormatError, _super);
2805
+ // Note: To allow instanceof do not put here error `name`
2806
+ // public readonly name = 'AbstractFormatError';
2807
+ function AbstractFormatError(message) {
2808
+ var _this = _super.call(this, message) || this;
2809
+ Object.setPrototypeOf(_this, AbstractFormatError.prototype);
2810
+ return _this;
2811
+ }
2812
+ return AbstractFormatError;
2813
+ }(Error));
2814
+
2815
+ /**
2816
+ * This error indicates problem with parsing of CSV
2817
+ *
2818
+ * @public exported from `@promptbook/core`
2819
+ */
2820
+ var CsvFormatError = /** @class */ (function (_super) {
2821
+ __extends(CsvFormatError, _super);
2822
+ function CsvFormatError(message) {
2823
+ var _this = _super.call(this, message) || this;
2824
+ _this.name = 'CsvFormatError';
2825
+ Object.setPrototypeOf(_this, CsvFormatError.prototype);
2826
+ return _this;
2827
+ }
2828
+ return CsvFormatError;
2829
+ }(AbstractFormatError));
2830
+
2831
+ /**
2832
+ * @@@
2833
+ *
2834
+ * @public exported from `@promptbook/core`
2835
+ */
2836
+ var MANDATORY_CSV_SETTINGS = Object.freeze({
2837
+ header: true,
2838
+ // encoding: 'utf8',
2839
+ });
2840
+
2841
+ /**
2842
+ * Definition for CSV spreadsheet
2843
+ *
2844
+ * @public exported from `@promptbook/core`
2845
+ * <- TODO: [🏢] Export from package `@promptbook/csv`
2846
+ */
2847
+ var CsvFormatDefinition = {
2848
+ formatName: 'CSV',
2849
+ aliases: ['SPREADSHEET', 'TABLE'],
2850
+ isValid: function (value, settings, schema) {
2851
+ // TODO: Implement CSV validation
2852
+ TODO_USE(value /* <- TODO: Use value here */);
2853
+ TODO_USE(settings /* <- TODO: Use settings here */);
2854
+ TODO_USE(schema /* <- TODO: Use schema here */);
2855
+ return true;
2856
+ },
2857
+ canBeValid: function (partialValue, settings, schema) {
2858
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2859
+ TODO_USE(settings /* <- TODO: Use settings here */);
2860
+ TODO_USE(schema /* <- TODO: Use schema here */);
2861
+ return true;
2862
+ },
2863
+ heal: function (value, settings, schema) {
2864
+ TODO_USE(value /* <- TODO: Use partialValue here */);
2865
+ TODO_USE(settings /* <- TODO: Use settings here */);
2866
+ TODO_USE(schema /* <- TODO: Use schema here */);
2867
+ throw new Error('Not implemented');
2868
+ },
2869
+ subvalueDefinitions: [
2870
+ {
2871
+ subvalueName: 'ROW',
2872
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
2873
+ return __awaiter(this, void 0, void 0, function () {
2874
+ var csv, mappedData;
2875
+ var _this = this;
2876
+ return __generator(this, function (_a) {
2877
+ switch (_a.label) {
2878
+ case 0:
2879
+ csv = parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
2880
+ if (csv.errors.length !== 0) {
2881
+ throw new CsvFormatError(spaceTrim$1(function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
2882
+ }
2883
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, index) { return __awaiter(_this, void 0, void 0, function () {
2884
+ var _a, _b;
2885
+ var _c;
2886
+ return __generator(this, function (_d) {
2887
+ switch (_d.label) {
2888
+ case 0:
2889
+ if (row[outputParameterName]) {
2890
+ throw new CsvFormatError("Can not overwrite existing column \"".concat(outputParameterName, "\" in CSV row"));
2891
+ }
2892
+ _a = [__assign({}, row)];
2893
+ _c = {};
2894
+ _b = outputParameterName;
2895
+ return [4 /*yield*/, mapCallback(row, index)];
2896
+ case 1: return [2 /*return*/, __assign.apply(void 0, _a.concat([(_c[_b] = _d.sent(), _c)]))];
2897
+ }
2898
+ });
2899
+ }); }))];
2900
+ case 1:
2901
+ mappedData = _a.sent();
2902
+ return [2 /*return*/, unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
2903
+ }
2904
+ });
2905
+ });
2906
+ },
2907
+ },
2908
+ {
2909
+ subvalueName: 'CELL',
2910
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
2911
+ return __awaiter(this, void 0, void 0, function () {
2912
+ var csv, mappedData;
2913
+ var _this = this;
2914
+ return __generator(this, function (_a) {
2915
+ switch (_a.label) {
2916
+ case 0:
2917
+ csv = parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
2918
+ if (csv.errors.length !== 0) {
2919
+ throw new CsvFormatError(spaceTrim$1(function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
2920
+ }
2921
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, rowIndex) { return __awaiter(_this, void 0, void 0, function () {
2922
+ var _this = this;
2923
+ return __generator(this, function (_a) {
2924
+ return [2 /*return*/, /* not await */ Promise.all(Object.entries(row).map(function (_a, columnIndex) {
2925
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
2926
+ return __awaiter(_this, void 0, void 0, function () {
2927
+ var index;
2928
+ var _c;
2929
+ return __generator(this, function (_d) {
2930
+ index = rowIndex * Object.keys(row).length + columnIndex;
2931
+ return [2 /*return*/, /* not await */ mapCallback((_c = {}, _c[key] = value, _c), index)];
2932
+ });
2933
+ });
2934
+ }))];
2935
+ });
2936
+ }); }))];
2937
+ case 1:
2938
+ mappedData = _a.sent();
2939
+ return [2 /*return*/, unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
2940
+ }
2941
+ });
2942
+ });
2943
+ },
2944
+ },
2945
+ ],
2946
+ };
2947
+ /**
2948
+ * TODO: [🍓] In `CsvFormatDefinition` implement simple `isValid`
2949
+ * TODO: [🍓] In `CsvFormatDefinition` implement partial `canBeValid`
2950
+ * TODO: [🍓] In `CsvFormatDefinition` implement `heal
2951
+ * TODO: [🍓] In `CsvFormatDefinition` implement `subvalueDefinitions`
2952
+ * TODO: [🏢] Allow to expect something inside CSV objects and other formats
2953
+ */
2954
+
2754
2955
  /**
2755
2956
  * Function isValidJsonString will tell you if the string is valid JSON or not
2756
2957
  *
@@ -2772,6 +2973,222 @@ function isValidJsonString(value /* <- [👨‍⚖️] */) {
2772
2973
  }
2773
2974
  }
2774
2975
 
2976
+ /**
2977
+ * Definition for JSON format
2978
+ *
2979
+ * @private still in development [🏢]
2980
+ */
2981
+ var JsonFormatDefinition = {
2982
+ formatName: 'JSON',
2983
+ mimeType: 'application/json',
2984
+ isValid: function (value, settings, schema) {
2985
+ TODO_USE(schema /* <- TODO: Use schema here */);
2986
+ TODO_USE(settings /* <- TODO: Use settings here */);
2987
+ return isValidJsonString(value);
2988
+ },
2989
+ canBeValid: function (partialValue, settings, schema) {
2990
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2991
+ TODO_USE(settings /* <- TODO: Use settings here */);
2992
+ TODO_USE(schema /* <- TODO: Use schema here */);
2993
+ return true;
2994
+ },
2995
+ heal: function (value, settings, schema) {
2996
+ TODO_USE(value /* <- TODO: Use partialValue here */);
2997
+ TODO_USE(settings /* <- TODO: Use settings here */);
2998
+ TODO_USE(schema /* <- TODO: Use schema here */);
2999
+ throw new Error('Not implemented');
3000
+ },
3001
+ subvalueDefinitions: [],
3002
+ };
3003
+ /**
3004
+ * TODO: [🧠] Maybe propper instance of object
3005
+ * TODO: [0] Make string_serialized_json
3006
+ * TODO: [1] Make type for JSON Settings and Schema
3007
+ * TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
3008
+ * TODO: [🍓] In `JsonFormatDefinition` implement simple `isValid`
3009
+ * TODO: [🍓] In `JsonFormatDefinition` implement partial `canBeValid`
3010
+ * TODO: [🍓] In `JsonFormatDefinition` implement `heal
3011
+ * TODO: [🍓] In `JsonFormatDefinition` implement `subvalueDefinitions`
3012
+ * TODO: [🏢] Allow to expect something inside JSON objects and other formats
3013
+ */
3014
+
3015
+ /**
3016
+ * Definition for any text - this will be always valid
3017
+ *
3018
+ * Note: This is not useful for validation, but for splitting and mapping with `subvalueDefinitions`
3019
+ *
3020
+ * @public exported from `@promptbook/core`
3021
+ */
3022
+ var TextFormatDefinition = {
3023
+ formatName: 'TEXT',
3024
+ isValid: function (value) {
3025
+ return typeof value === 'string';
3026
+ },
3027
+ canBeValid: function (partialValue) {
3028
+ return typeof partialValue === 'string';
3029
+ },
3030
+ heal: function () {
3031
+ throw new UnexpectedError('It does not make sense to call `TextFormatDefinition.heal`');
3032
+ },
3033
+ subvalueDefinitions: [
3034
+ {
3035
+ subvalueName: 'LINE',
3036
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3037
+ return __awaiter(this, void 0, void 0, function () {
3038
+ var lines, mappedLines;
3039
+ return __generator(this, function (_a) {
3040
+ switch (_a.label) {
3041
+ case 0:
3042
+ lines = value.split('\n');
3043
+ return [4 /*yield*/, Promise.all(lines.map(function (lineContent, lineNumber) {
3044
+ // TODO: [🧠] Maybe option to skip empty line
3045
+ /* not await */ return mapCallback({
3046
+ lineContent: lineContent,
3047
+ // TODO: [🧠] Maybe also put here `lineNumber`
3048
+ }, lineNumber);
3049
+ }))];
3050
+ case 1:
3051
+ mappedLines = _a.sent();
3052
+ return [2 /*return*/, mappedLines.join('\n')];
3053
+ }
3054
+ });
3055
+ });
3056
+ },
3057
+ },
3058
+ // <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3059
+ ],
3060
+ };
3061
+ /**
3062
+ * TODO: [1] Make type for XML Text and Schema
3063
+ * TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3064
+ * TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
3065
+ * TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
3066
+ * TODO: [🍓] In `TextFormatDefinition` implement `heal
3067
+ * TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
3068
+ * TODO: [🏢] Allow to expect something inside each item of list and other formats
3069
+ */
3070
+
3071
+ /**
3072
+ * Definition for XML format
3073
+ *
3074
+ * @private still in development [🏢]
3075
+ */
3076
+ var XmlFormatDefinition = {
3077
+ formatName: 'XML',
3078
+ mimeType: 'application/xml',
3079
+ isValid: function (value, settings, schema) {
3080
+ TODO_USE(value /* <- TODO: Use value here */);
3081
+ TODO_USE(settings /* <- TODO: Use settings here */);
3082
+ TODO_USE(schema /* <- TODO: Use schema here */);
3083
+ return true;
3084
+ },
3085
+ canBeValid: function (partialValue, settings, schema) {
3086
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3087
+ TODO_USE(settings /* <- TODO: Use settings here */);
3088
+ TODO_USE(schema /* <- TODO: Use schema here */);
3089
+ return true;
3090
+ },
3091
+ heal: function (value, settings, schema) {
3092
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3093
+ TODO_USE(settings /* <- TODO: Use settings here */);
3094
+ TODO_USE(schema /* <- TODO: Use schema here */);
3095
+ throw new Error('Not implemented');
3096
+ },
3097
+ subvalueDefinitions: [],
3098
+ };
3099
+ /**
3100
+ * TODO: [🧠] Maybe propper instance of object
3101
+ * TODO: [0] Make string_serialized_xml
3102
+ * TODO: [1] Make type for XML Settings and Schema
3103
+ * TODO: [🧠] What to use for validating XMLs - XSD,...
3104
+ * TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
3105
+ * TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
3106
+ * TODO: [🍓] In `XmlFormatDefinition` implement `heal
3107
+ * TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
3108
+ * TODO: [🏢] Allow to expect something inside XML and other formats
3109
+ */
3110
+
3111
+ /**
3112
+ * Definitions for all formats supported by Promptbook
3113
+ *
3114
+ * @private internal index of `...` <- TODO [🏢]
3115
+ */
3116
+ var FORMAT_DEFINITIONS = [
3117
+ JsonFormatDefinition,
3118
+ XmlFormatDefinition,
3119
+ TextFormatDefinition,
3120
+ CsvFormatDefinition,
3121
+ ];
3122
+
3123
+ /**
3124
+ * Maps available parameters to expected parameters
3125
+ *
3126
+ * The strategy is:
3127
+ * 1) @@@
3128
+ * 2) @@@
3129
+ *
3130
+ * @throws {PipelineExecutionError} @@@
3131
+ * @private within the repository used in `createPipelineExecutor`
3132
+ */
3133
+ function mapAvailableToExpectedParameters(options) {
3134
+ var e_1, _a;
3135
+ var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
3136
+ var availableParametersNames = new Set(Object.keys(availableParameters));
3137
+ var expectedParameterNames = new Set(Object.keys(expectedParameters));
3138
+ var mappedParameters = {};
3139
+ try {
3140
+ // Phase 1️⃣: Matching mapping
3141
+ for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
3142
+ var parameterName = _c.value;
3143
+ // Situation: Parameter is available and expected
3144
+ if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3145
+ mappedParameters[parameterName] = availableParameters[parameterName];
3146
+ // <- Note: [👩‍👩‍👧] Maybe detect parameter collision here?
3147
+ availableParametersNames.delete(parameterName);
3148
+ expectedParameterNames.delete(parameterName);
3149
+ }
3150
+ // Situation: Parameter is available but NOT expected
3151
+ else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
3152
+ // [🐱‍👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
3153
+ }
3154
+ // Situation: Parameter is NOT available BUT expected
3155
+ else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3156
+ // Do nothing here - this will be maybe fixed in the non-matching mapping
3157
+ }
3158
+ }
3159
+ }
3160
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3161
+ finally {
3162
+ try {
3163
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3164
+ }
3165
+ finally { if (e_1) throw e_1.error; }
3166
+ }
3167
+ if (expectedParameterNames.size === 0) {
3168
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3169
+ Object.freeze(mappedParameters);
3170
+ return mappedParameters;
3171
+ }
3172
+ // Phase 2️⃣: Non-matching mapping
3173
+ if (expectedParameterNames.size !== availableParametersNames.size) {
3174
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
3175
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3176
+ .join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
3177
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3178
+ .join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
3179
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3180
+ .join('\n')), "\n\n "); }));
3181
+ }
3182
+ var expectedParameterNamesArray = Array.from(expectedParameterNames);
3183
+ var availableParametersNamesArray = Array.from(availableParametersNames);
3184
+ for (var i = 0; i < expectedParameterNames.size; i++) {
3185
+ mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
3186
+ }
3187
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3188
+ Object.freeze(mappedParameters);
3189
+ return mappedParameters;
3190
+ }
3191
+
2775
3192
  /**
2776
3193
  * Extracts all code blocks from markdown.
2777
3194
  *
@@ -3077,6 +3494,9 @@ var CountUtils = {
3077
3494
  LINES: countLines,
3078
3495
  PAGES: countPages,
3079
3496
  };
3497
+ /**
3498
+ * TODO: [🧠][🤠] This should be probbably as part of `TextFormatDefinition`
3499
+ */
3080
3500
 
3081
3501
  /**
3082
3502
  * Function checkExpectations will check if the expectations on given value are met
@@ -3113,6 +3533,8 @@ function checkExpectations(expectations, value) {
3113
3533
  }
3114
3534
  /**
3115
3535
  * TODO: [💝] Unite object for expecting amount and format
3536
+ * TODO: [🧠][🤠] This should be part of `TextFormatDefinition`
3537
+ * Note: [💝] and [🤠] are interconnected together
3116
3538
  */
3117
3539
 
3118
3540
  /**
@@ -3122,58 +3544,66 @@ function checkExpectations(expectations, value) {
3122
3544
  */
3123
3545
  function executeAttempts(options) {
3124
3546
  return __awaiter(this, void 0, void 0, function () {
3125
- var $ongoingTemplateResult, jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, _loop_1, attempt, state_1;
3547
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3126
3548
  return __generator(this, function (_a) {
3127
3549
  switch (_a.label) {
3128
3550
  case 0:
3129
- $ongoingTemplateResult = options.$ongoingTemplateResult, jokerParameterNames = options.jokerParameterNames, priority = options.priority, maxAttempts = options.maxAttempts, preparedContent = options.preparedContent, parameters = options.parameters, template = options.template, preparedPipeline = options.preparedPipeline, tools = options.tools, llmTools = options.llmTools, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3551
+ 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;
3130
3552
  maxExecutionAttempts = settings.maxExecutionAttempts;
3553
+ $ongoingTemplateResult = {
3554
+ $result: null,
3555
+ $resultString: null,
3556
+ $expectError: null,
3557
+ $scriptPipelineExecutionErrors: [],
3558
+ };
3131
3559
  _loop_1 = function (attempt) {
3132
- var isJokerAttempt, jokerParameterName, _b, modelRequirements, _c, _d, _e, _f, _g, _h, scriptTools, _j, error_1, e_1_1, _k, _l, _m, functionName, postprocessingError, _o, _p, scriptTools, _q, error_2, e_2_1, e_3_1, error_3;
3133
- var e_1, _r, e_3, _s, e_2, _t;
3134
- return __generator(this, function (_u) {
3135
- switch (_u.label) {
3560
+ 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;
3561
+ var e_1, _q, e_3, _r, e_2, _s;
3562
+ return __generator(this, function (_t) {
3563
+ switch (_t.label) {
3136
3564
  case 0:
3137
3565
  isJokerAttempt = attempt < 0;
3138
3566
  jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3139
- // TODO: [🧠] !!!!!! JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3567
+ // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3140
3568
  if (isJokerAttempt && !jokerParameterName) {
3141
- throw new UnexpectedError(spaceTrim(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3569
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3142
3570
  }
3143
3571
  $ongoingTemplateResult.$result = null;
3144
3572
  $ongoingTemplateResult.$resultString = null;
3145
3573
  $ongoingTemplateResult.$expectError = null;
3146
3574
  if (isJokerAttempt) {
3147
3575
  if (parameters[jokerParameterName] === undefined) {
3148
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3576
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3149
3577
  // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3150
3578
  }
3151
3579
  else {
3152
3580
  $ongoingTemplateResult.$resultString = parameters[jokerParameterName];
3153
3581
  }
3154
3582
  }
3155
- _u.label = 1;
3583
+ _t.label = 1;
3156
3584
  case 1:
3157
- _u.trys.push([1, 44, 45, 46]);
3158
- if (!!isJokerAttempt) return [3 /*break*/, 26];
3585
+ _t.trys.push([1, 43, 44, 45]);
3586
+ if (!!isJokerAttempt) return [3 /*break*/, 25];
3159
3587
  _b = template.templateType;
3160
3588
  switch (_b) {
3161
3589
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3162
3590
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3163
- case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3164
- case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3591
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 11];
3592
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 22];
3165
3593
  }
3166
- return [3 /*break*/, 25];
3594
+ return [3 /*break*/, 24];
3167
3595
  case 2:
3168
3596
  $ongoingTemplateResult.$resultString = replaceParameters(preparedContent, parameters);
3169
- return [3 /*break*/, 26];
3597
+ return [3 /*break*/, 25];
3170
3598
  case 3:
3171
3599
  modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (template.modelRequirements || {}));
3172
3600
  $ongoingTemplateResult.$prompt = {
3173
3601
  title: template.title,
3174
3602
  pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3175
3603
  ? preparedPipeline.pipelineUrl
3176
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name),
3604
+ : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name
3605
+ // <- TODO: Here should be maybe also subformat index to distinguish between same template with different subformat values
3606
+ ),
3177
3607
  parameters: parameters,
3178
3608
  content: preparedContent,
3179
3609
  modelRequirements: modelRequirements,
@@ -3191,67 +3621,57 @@ function executeAttempts(options) {
3191
3621
  case 'COMPLETION': return [3 /*break*/, 6];
3192
3622
  case 'EMBEDDING': return [3 /*break*/, 8];
3193
3623
  }
3194
- return [3 /*break*/, 10];
3624
+ return [3 /*break*/, 9];
3195
3625
  case 4:
3196
3626
  _d = $ongoingTemplateResult;
3197
3627
  return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3198
3628
  case 5:
3199
- _d.$chatResult = _u.sent();
3629
+ _d.$chatResult = _t.sent();
3200
3630
  // TODO: [🍬] Destroy chatThread
3201
3631
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$chatResult;
3202
3632
  $ongoingTemplateResult.$resultString = $ongoingTemplateResult.$chatResult.content;
3203
- return [3 /*break*/, 11];
3633
+ return [3 /*break*/, 10];
3204
3634
  case 6:
3205
3635
  _e = $ongoingTemplateResult;
3206
3636
  return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3207
3637
  case 7:
3208
- _e.$completionResult = _u.sent();
3638
+ _e.$completionResult = _t.sent();
3209
3639
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
3210
3640
  $ongoingTemplateResult.$resultString =
3211
3641
  $ongoingTemplateResult.$completionResult.content;
3212
- return [3 /*break*/, 11];
3213
- case 8:
3214
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3215
- _f = $ongoingTemplateResult;
3216
- return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze($ongoingTemplateResult.$prompt))];
3217
- case 9:
3218
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3219
- _f.$embeddingResult = _u.sent();
3220
- $ongoingTemplateResult.$result = $ongoingTemplateResult.$embeddingResult;
3221
- $ongoingTemplateResult.$resultString =
3222
- $ongoingTemplateResult.$embeddingResult.content.join(',');
3223
- return [3 /*break*/, 11];
3224
- case 10: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3225
- case 11: return [3 /*break*/, 26];
3226
- case 12:
3642
+ return [3 /*break*/, 10];
3643
+ case 8: throw new PipelineExecutionError(spaceTrim(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 "); }));
3644
+ case 9: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3645
+ case 10: return [3 /*break*/, 25];
3646
+ case 11:
3227
3647
  if (arrayableToArray(tools.script).length === 0) {
3228
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3648
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3229
3649
  }
3230
3650
  if (!template.contentLanguage) {
3231
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3651
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3232
3652
  }
3233
- _u.label = 13;
3653
+ _t.label = 12;
3654
+ case 12:
3655
+ _t.trys.push([12, 19, 20, 21]);
3656
+ _f = (e_1 = void 0, __values(arrayableToArray(tools.script))), _g = _f.next();
3657
+ _t.label = 13;
3234
3658
  case 13:
3235
- _u.trys.push([13, 20, 21, 22]);
3236
- _g = (e_1 = void 0, __values(arrayableToArray(tools.script))), _h = _g.next();
3237
- _u.label = 14;
3659
+ if (!!_g.done) return [3 /*break*/, 18];
3660
+ scriptTools = _g.value;
3661
+ _t.label = 14;
3238
3662
  case 14:
3239
- if (!!_h.done) return [3 /*break*/, 19];
3240
- scriptTools = _h.value;
3241
- _u.label = 15;
3242
- case 15:
3243
- _u.trys.push([15, 17, , 18]);
3244
- _j = $ongoingTemplateResult;
3663
+ _t.trys.push([14, 16, , 17]);
3664
+ _h = $ongoingTemplateResult;
3245
3665
  return [4 /*yield*/, scriptTools.execute($deepFreeze({
3246
3666
  scriptLanguage: template.contentLanguage,
3247
3667
  script: preparedContent,
3248
3668
  parameters: parameters,
3249
3669
  }))];
3670
+ case 15:
3671
+ _h.$resultString = _t.sent();
3672
+ return [3 /*break*/, 18];
3250
3673
  case 16:
3251
- _j.$resultString = _u.sent();
3252
- return [3 /*break*/, 19];
3253
- case 17:
3254
- error_1 = _u.sent();
3674
+ error_1 = _t.sent();
3255
3675
  if (!(error_1 instanceof Error)) {
3256
3676
  throw error_1;
3257
3677
  }
@@ -3259,39 +3679,39 @@ function executeAttempts(options) {
3259
3679
  throw error_1;
3260
3680
  }
3261
3681
  $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_1);
3262
- return [3 /*break*/, 18];
3263
- case 18:
3264
- _h = _g.next();
3265
- return [3 /*break*/, 14];
3266
- case 19: return [3 /*break*/, 22];
3267
- case 20:
3268
- e_1_1 = _u.sent();
3682
+ return [3 /*break*/, 17];
3683
+ case 17:
3684
+ _g = _f.next();
3685
+ return [3 /*break*/, 13];
3686
+ case 18: return [3 /*break*/, 21];
3687
+ case 19:
3688
+ e_1_1 = _t.sent();
3269
3689
  e_1 = { error: e_1_1 };
3270
- return [3 /*break*/, 22];
3271
- case 21:
3690
+ return [3 /*break*/, 21];
3691
+ case 20:
3272
3692
  try {
3273
- if (_h && !_h.done && (_r = _g.return)) _r.call(_g);
3693
+ if (_g && !_g.done && (_q = _f.return)) _q.call(_f);
3274
3694
  }
3275
3695
  finally { if (e_1) throw e_1.error; }
3276
3696
  return [7 /*endfinally*/];
3277
- case 22:
3697
+ case 21:
3278
3698
  if ($ongoingTemplateResult.$resultString !== null) {
3279
- return [3 /*break*/, 26];
3699
+ return [3 /*break*/, 25];
3280
3700
  }
3281
3701
  if ($ongoingTemplateResult.$scriptPipelineExecutionErrors.length === 1) {
3282
3702
  throw $ongoingTemplateResult.$scriptPipelineExecutionErrors[0];
3283
3703
  }
3284
3704
  else {
3285
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3705
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3286
3706
  .map(function (error) { return '- ' + error.message; })
3287
- .join('\n\n')), "\n "); }));
3707
+ .join('\n\n')), "\n "); }));
3288
3708
  }
3289
- case 23:
3709
+ case 22:
3290
3710
  if (tools.userInterface === undefined) {
3291
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3711
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3292
3712
  }
3293
3713
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3294
- _k = $ongoingTemplateResult;
3714
+ _j = $ongoingTemplateResult;
3295
3715
  return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3296
3716
  promptTitle: template.title,
3297
3717
  promptMessage: replaceParameters(template.description || '', parameters),
@@ -3300,34 +3720,34 @@ function executeAttempts(options) {
3300
3720
  placeholder: undefined,
3301
3721
  priority: priority,
3302
3722
  }))];
3303
- case 24:
3723
+ case 23:
3304
3724
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3305
- _k.$resultString = _u.sent();
3306
- return [3 /*break*/, 26];
3307
- case 25: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3725
+ _j.$resultString = _t.sent();
3726
+ return [3 /*break*/, 25];
3727
+ case 24: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3728
+ case 25:
3729
+ if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 42];
3730
+ _t.label = 26;
3308
3731
  case 26:
3309
- if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 43];
3310
- _u.label = 27;
3732
+ _t.trys.push([26, 40, 41, 42]);
3733
+ _k = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _l = _k.next();
3734
+ _t.label = 27;
3311
3735
  case 27:
3312
- _u.trys.push([27, 41, 42, 43]);
3313
- _l = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _m = _l.next();
3314
- _u.label = 28;
3315
- case 28:
3316
- if (!!_m.done) return [3 /*break*/, 40];
3317
- functionName = _m.value;
3736
+ if (!!_l.done) return [3 /*break*/, 39];
3737
+ functionName = _l.value;
3318
3738
  postprocessingError = null;
3319
- _u.label = 29;
3739
+ _t.label = 28;
3740
+ case 28:
3741
+ _t.trys.push([28, 35, 36, 37]);
3742
+ _m = (e_2 = void 0, __values(arrayableToArray(tools.script))), _o = _m.next();
3743
+ _t.label = 29;
3320
3744
  case 29:
3321
- _u.trys.push([29, 36, 37, 38]);
3322
- _o = (e_2 = void 0, __values(arrayableToArray(tools.script))), _p = _o.next();
3323
- _u.label = 30;
3745
+ if (!!_o.done) return [3 /*break*/, 34];
3746
+ scriptTools = _o.value;
3747
+ _t.label = 30;
3324
3748
  case 30:
3325
- if (!!_p.done) return [3 /*break*/, 35];
3326
- scriptTools = _p.value;
3327
- _u.label = 31;
3328
- case 31:
3329
- _u.trys.push([31, 33, , 34]);
3330
- _q = $ongoingTemplateResult;
3749
+ _t.trys.push([30, 32, , 33]);
3750
+ _p = $ongoingTemplateResult;
3331
3751
  return [4 /*yield*/, scriptTools.execute({
3332
3752
  scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3333
3753
  script: "".concat(functionName, "(resultString)"),
@@ -3336,12 +3756,12 @@ function executeAttempts(options) {
3336
3756
  // Note: No ...parametersForTemplate, because working with result only
3337
3757
  },
3338
3758
  })];
3339
- case 32:
3340
- _q.$resultString = _u.sent();
3759
+ case 31:
3760
+ _p.$resultString = _t.sent();
3341
3761
  postprocessingError = null;
3342
- return [3 /*break*/, 35];
3343
- case 33:
3344
- error_2 = _u.sent();
3762
+ return [3 /*break*/, 34];
3763
+ case 32:
3764
+ error_2 = _t.sent();
3345
3765
  if (!(error_2 instanceof Error)) {
3346
3766
  throw error_2;
3347
3767
  }
@@ -3350,41 +3770,41 @@ function executeAttempts(options) {
3350
3770
  }
3351
3771
  postprocessingError = error_2;
3352
3772
  $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_2);
3353
- return [3 /*break*/, 34];
3354
- case 34:
3355
- _p = _o.next();
3356
- return [3 /*break*/, 30];
3357
- case 35: return [3 /*break*/, 38];
3358
- case 36:
3359
- e_2_1 = _u.sent();
3773
+ return [3 /*break*/, 33];
3774
+ case 33:
3775
+ _o = _m.next();
3776
+ return [3 /*break*/, 29];
3777
+ case 34: return [3 /*break*/, 37];
3778
+ case 35:
3779
+ e_2_1 = _t.sent();
3360
3780
  e_2 = { error: e_2_1 };
3361
- return [3 /*break*/, 38];
3362
- case 37:
3781
+ return [3 /*break*/, 37];
3782
+ case 36:
3363
3783
  try {
3364
- if (_p && !_p.done && (_t = _o.return)) _t.call(_o);
3784
+ if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3365
3785
  }
3366
3786
  finally { if (e_2) throw e_2.error; }
3367
3787
  return [7 /*endfinally*/];
3368
- case 38:
3788
+ case 37:
3369
3789
  if (postprocessingError) {
3370
3790
  throw postprocessingError;
3371
3791
  }
3372
- _u.label = 39;
3373
- case 39:
3374
- _m = _l.next();
3375
- return [3 /*break*/, 28];
3376
- case 40: return [3 /*break*/, 43];
3377
- case 41:
3378
- e_3_1 = _u.sent();
3792
+ _t.label = 38;
3793
+ case 38:
3794
+ _l = _k.next();
3795
+ return [3 /*break*/, 27];
3796
+ case 39: return [3 /*break*/, 42];
3797
+ case 40:
3798
+ e_3_1 = _t.sent();
3379
3799
  e_3 = { error: e_3_1 };
3380
- return [3 /*break*/, 43];
3381
- case 42:
3800
+ return [3 /*break*/, 42];
3801
+ case 41:
3382
3802
  try {
3383
- if (_m && !_m.done && (_s = _l.return)) _s.call(_l);
3803
+ if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3384
3804
  }
3385
3805
  finally { if (e_3) throw e_3.error; }
3386
3806
  return [7 /*endfinally*/];
3387
- case 43:
3807
+ case 42:
3388
3808
  // TODO: [💝] Unite object for expecting amount and format
3389
3809
  if (template.format) {
3390
3810
  if (template.format === 'JSON') {
@@ -3395,13 +3815,13 @@ function executeAttempts(options) {
3395
3815
  }
3396
3816
  catch (error) {
3397
3817
  keepUnused(error);
3398
- throw new ExpectError(spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3399
- /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3818
+ throw new ExpectError(spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3819
+ /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3400
3820
  }
3401
3821
  }
3402
3822
  }
3403
3823
  else {
3404
- throw new UnexpectedError(spaceTrim(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3824
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3405
3825
  }
3406
3826
  }
3407
3827
  // TODO: [💝] Unite object for expecting amount and format
@@ -3409,14 +3829,14 @@ function executeAttempts(options) {
3409
3829
  checkExpectations(template.expectations, $ongoingTemplateResult.$resultString || '');
3410
3830
  }
3411
3831
  return [2 /*return*/, "break-attempts"];
3412
- case 44:
3413
- error_3 = _u.sent();
3832
+ case 43:
3833
+ error_3 = _t.sent();
3414
3834
  if (!(error_3 instanceof ExpectError)) {
3415
3835
  throw error_3;
3416
3836
  }
3417
3837
  $ongoingTemplateResult.$expectError = error_3;
3418
- return [3 /*break*/, 46];
3419
- case 45:
3838
+ return [3 /*break*/, 45];
3839
+ case 44:
3420
3840
  if (!isJokerAttempt &&
3421
3841
  template.templateType === 'PROMPT_TEMPLATE' &&
3422
3842
  $ongoingTemplateResult.$prompt
@@ -3433,22 +3853,22 @@ function executeAttempts(options) {
3433
3853
  });
3434
3854
  }
3435
3855
  return [7 /*endfinally*/];
3436
- case 46:
3856
+ case 45:
3437
3857
  if ($ongoingTemplateResult.$expectError !== null && attempt === maxAttempts - 1) {
3438
3858
  throw new PipelineExecutionError(spaceTrim(function (block) {
3439
3859
  var _a, _b, _c;
3440
- 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) || '')
3860
+ 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) || '')
3441
3861
  .split('\n')
3442
3862
  .map(function (line) { return "> ".concat(line); })
3443
- .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) || '')
3863
+ .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) || '')
3444
3864
  .split('\n')
3445
3865
  .map(function (line) { return "> ".concat(line); })
3446
- .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
3866
+ .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
3447
3867
  ? 'null'
3448
3868
  : $ongoingTemplateResult.$resultString
3449
3869
  .split('\n')
3450
3870
  .map(function (line) { return "> ".concat(line); })
3451
- .join('\n')), "\n ---\n ");
3871
+ .join('\n')), "\n ---\n ");
3452
3872
  }));
3453
3873
  }
3454
3874
  return [2 /*return*/];
@@ -3469,7 +3889,11 @@ function executeAttempts(options) {
3469
3889
  case 3:
3470
3890
  attempt++;
3471
3891
  return [3 /*break*/, 1];
3472
- case 4: return [2 /*return*/];
3892
+ case 4:
3893
+ if ($ongoingTemplateResult.$resultString === null) {
3894
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3895
+ }
3896
+ return [2 /*return*/, $ongoingTemplateResult.$resultString];
3473
3897
  }
3474
3898
  });
3475
3899
  });
@@ -3483,36 +3907,83 @@ function executeAttempts(options) {
3483
3907
  *
3484
3908
  * @private internal utility of `createPipelineExecutor`
3485
3909
  */
3486
- function executeFormatCells(options) {
3910
+ function executeFormatSubvalues(options) {
3487
3911
  return __awaiter(this, void 0, void 0, function () {
3488
- var template;
3912
+ var template, jokerParameterNames, parameters, priority, pipelineIdentification, settings, parameterValue, formatDefinition, subvalueDefinition, formatSettings, resultString;
3913
+ var _this = this;
3489
3914
  return __generator(this, function (_a) {
3490
- template = options.template;
3491
- if (template.foreach === undefined) {
3492
- return [2 /*return*/, /* not await */ executeAttempts(options)];
3915
+ switch (_a.label) {
3916
+ case 0:
3917
+ template = options.template, jokerParameterNames = options.jokerParameterNames, parameters = options.parameters, priority = options.priority, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
3918
+ if (template.foreach === undefined) {
3919
+ return [2 /*return*/, /* not await */ executeAttempts(options)];
3920
+ }
3921
+ if (jokerParameterNames.length !== 0) {
3922
+ throw new UnexpectedError(spaceTrim$1(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 "); }));
3923
+ }
3924
+ parameterValue = parameters[template.foreach.parameterName] || '';
3925
+ formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
3926
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(template.foreach.formatName);
3927
+ });
3928
+ if (formatDefinition === undefined) {
3929
+ throw new UnexpectedError(
3930
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
3931
+ spaceTrim$1(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; })
3932
+ .map(function (formatName) { return "- ".concat(formatName); })
3933
+ .join('\n')), "\n\n [\u26F7] This should never happen because format name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
3934
+ }
3935
+ subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
3936
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(template.foreach.subformatName);
3937
+ });
3938
+ if (subvalueDefinition === undefined) {
3939
+ throw new UnexpectedError(
3940
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
3941
+ spaceTrim$1(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
3942
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
3943
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
3944
+ .join('\n')), "\n\n [\u26F7] This should never happen because subformat name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
3945
+ }
3946
+ if (formatDefinition.formatName === 'CSV') {
3947
+ formatSettings = settings.csvSettings;
3948
+ // <- TODO: [🤹‍♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
3949
+ }
3950
+ return [4 /*yield*/, subvalueDefinition.mapValues(parameterValue, template.foreach.outputSubparameterName, formatSettings, function (subparameters, index) { return __awaiter(_this, void 0, void 0, function () {
3951
+ var mappedParameters, allSubparameters, subresultString;
3952
+ return __generator(this, function (_a) {
3953
+ switch (_a.label) {
3954
+ case 0:
3955
+ // TODO: [🤹‍♂️][🪂] Limit to N concurrent executions
3956
+ // TODO: When done [🐚] Report progress also for each subvalue here
3957
+ try {
3958
+ mappedParameters = mapAvailableToExpectedParameters({
3959
+ expectedParameters: Object.fromEntries(template.foreach.inputSubparameterNames.map(function (subparameterName) { return [subparameterName, null]; })),
3960
+ availableParameters: subparameters,
3961
+ });
3962
+ }
3963
+ catch (error) {
3964
+ if (!(error instanceof PipelineExecutionError)) {
3965
+ throw error;
3966
+ }
3967
+ throw new PipelineExecutionError(spaceTrim$1(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 "); }));
3968
+ }
3969
+ allSubparameters = __assign(__assign({}, parameters), mappedParameters);
3970
+ // 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
3971
+ Object.freeze(allSubparameters);
3972
+ return [4 /*yield*/, executeAttempts(__assign(__assign({}, options), { priority: priority + index, parameters: allSubparameters, pipelineIdentification: spaceTrim$1(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Subparameter index: ").concat(index, "\n "); }) }))];
3973
+ case 1:
3974
+ subresultString = _a.sent();
3975
+ return [2 /*return*/, subresultString];
3976
+ }
3977
+ });
3978
+ }); })];
3979
+ case 1:
3980
+ resultString = _a.sent();
3981
+ return [2 /*return*/, resultString];
3493
3982
  }
3494
- throw new NotYetImplementedError('FOREACH execution not implemented yet');
3495
3983
  });
3496
3984
  });
3497
3985
  }
3498
3986
 
3499
- /**
3500
- * Just marks a place of place where should be something implemented
3501
- * No side effects.
3502
- *
3503
- * Note: It can be usefull suppressing eslint errors of unused variables
3504
- *
3505
- * @param value any values
3506
- * @returns void
3507
- * @private within the repository
3508
- */
3509
- function TODO_USE() {
3510
- var value = [];
3511
- for (var _i = 0; _i < arguments.length; _i++) {
3512
- value[_i] = arguments[_i];
3513
- }
3514
- }
3515
-
3516
3987
  /**
3517
3988
  * @@@
3518
3989
  *
@@ -3626,7 +4097,7 @@ function getReservedParametersForTemplate(options) {
3626
4097
  */
3627
4098
  function executeTemplate(options) {
3628
4099
  return __awaiter(this, void 0, void 0, function () {
3629
- var currentTemplate, preparedPipeline, parametersToPass, tools, llmTools, onProgress, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, $ongoingTemplateResult, maxAttempts, jokerParameterNames, preparedContent;
4100
+ 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;
3630
4101
  var e_1, _f, _g;
3631
4102
  return __generator(this, function (_h) {
3632
4103
  switch (_h.label) {
@@ -3650,12 +4121,13 @@ function executeTemplate(options) {
3650
4121
  _h.sent();
3651
4122
  usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3652
4123
  dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
4124
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3653
4125
  if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3654
- throw new UnexpectedError(spaceTrim(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)
4126
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n Dependent parameters:\n ".concat(Array.from(dependentParameterNames)
3655
4127
  .map(function (name) { return "{".concat(name, "}"); })
3656
4128
  .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3657
4129
  .map(function (name) { return "{".concat(name, "}"); })
3658
- .join(', '), "\n\n "); }));
4130
+ .join(', '), "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3659
4131
  }
3660
4132
  _b = (_a = Object).freeze;
3661
4133
  _c = [{}];
@@ -3684,6 +4156,7 @@ function executeTemplate(options) {
3684
4156
  };
3685
4157
  try {
3686
4158
  // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
4159
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3687
4160
  for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3688
4161
  parameterName = _e.value;
3689
4162
  _loop_1(parameterName);
@@ -3696,22 +4169,14 @@ function executeTemplate(options) {
3696
4169
  }
3697
4170
  finally { if (e_1) throw e_1.error; }
3698
4171
  }
3699
- // 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
4172
+ // 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
3700
4173
  Object.freeze(parameters);
3701
- $ongoingTemplateResult = {
3702
- $result: null,
3703
- $resultString: null,
3704
- $expectError: null,
3705
- $scriptPipelineExecutionErrors: [],
3706
- };
3707
4174
  maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3708
4175
  jokerParameterNames = currentTemplate.jokerParameterNames || [];
3709
4176
  preparedContent = (currentTemplate.preparedContent || '{content}')
3710
4177
  .split('{content}')
3711
4178
  .join(currentTemplate.content);
3712
- // <- TODO: [🍵] Use here `replaceParameters` to replace {websiteContent} with option to ignore missing parameters
3713
- return [4 /*yield*/, executeFormatCells({
3714
- $ongoingTemplateResult: $ongoingTemplateResult,
4179
+ return [4 /*yield*/, executeFormatSubvalues({
3715
4180
  jokerParameterNames: jokerParameterNames,
3716
4181
  priority: priority,
3717
4182
  maxAttempts: maxAttempts,
@@ -3726,11 +4191,7 @@ function executeTemplate(options) {
3726
4191
  pipelineIdentification: pipelineIdentification,
3727
4192
  })];
3728
4193
  case 3:
3729
- // <- TODO: [🍵] Use here `replaceParameters` to replace {websiteContent} with option to ignore missing parameters
3730
- _h.sent();
3731
- if ($ongoingTemplateResult.$resultString === null) {
3732
- throw new UnexpectedError(spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3733
- }
4194
+ resultString = _h.sent();
3734
4195
  return [4 /*yield*/, onProgress({
3735
4196
  name: name,
3736
4197
  title: title,
@@ -3738,13 +4199,15 @@ function executeTemplate(options) {
3738
4199
  isDone: true,
3739
4200
  templateType: currentTemplate.templateType,
3740
4201
  parameterName: currentTemplate.resultingParameterName,
3741
- parameterValue: $ongoingTemplateResult.$resultString,
4202
+ parameterValue: resultString,
3742
4203
  // <- [🍸]
3743
4204
  })];
3744
4205
  case 4:
3745
4206
  _h.sent();
3746
4207
  return [2 /*return*/, Object.freeze((_g = {},
3747
- _g[currentTemplate.resultingParameterName] = $ongoingTemplateResult.$resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */,
4208
+ _g[currentTemplate.resultingParameterName] =
4209
+ // <- Note: [👩‍👩‍👧] No need to detect parameter collision here because pipeline checks logic consistency during construction
4210
+ resultString,
3748
4211
  _g))];
3749
4212
  }
3750
4213
  });
@@ -3753,6 +4216,9 @@ function executeTemplate(options) {
3753
4216
  /**
3754
4217
  * TODO: [🤹‍♂️]
3755
4218
  */
4219
+ /**
4220
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4221
+ */
3756
4222
 
3757
4223
  /**
3758
4224
  * @@@
@@ -3773,6 +4239,7 @@ function filterJustOutputParameters(options) {
3773
4239
  };
3774
4240
  try {
3775
4241
  // Note: Filter ONLY output parameters
4242
+ // TODO: [👩🏾‍🤝‍👩🏻] Maybe use here `mapAvailableToExpectedParameters`
3776
4243
  for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
3777
4244
  var isOutput = _a.isOutput;
3778
4245
  return isOutput;
@@ -3887,7 +4354,7 @@ function executePipeline(options) {
3887
4354
  return name === parameterName;
3888
4355
  });
3889
4356
  if (!(parameter === undefined)) return [3 /*break*/, 1];
3890
- warnings.push(new PipelineExecutionError(spaceTrim(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
4357
+ warnings.push(new PipelineExecutionError(spaceTrim(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
3891
4358
  return [3 /*break*/, 4];
3892
4359
  case 1:
3893
4360
  if (!(parameter.isInput === false)) return [3 /*break*/, 4];
@@ -3899,10 +4366,10 @@ function executePipeline(options) {
3899
4366
  // Note: Wait a short time to prevent race conditions
3900
4367
  _h.sent();
3901
4368
  _h.label = 3;
3902
- case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4369
+ case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
3903
4370
  isSuccessful: false,
3904
4371
  errors: __spreadArray([
3905
- new PipelineExecutionError(spaceTrim(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
4372
+ new PipelineExecutionError(spaceTrim(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
3906
4373
  ], __read(errors), false).map(serializeError),
3907
4374
  warnings: warnings.map(serializeError),
3908
4375
  executionReport: executionReport,
@@ -3966,7 +4433,7 @@ function executePipeline(options) {
3966
4433
  case 0:
3967
4434
  if (loopLimit-- < 0) {
3968
4435
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
3969
- throw new UnexpectedError(spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4436
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
3970
4437
  }
3971
4438
  currentTemplate = unresovedTemplates_1.find(function (template) {
3972
4439
  return template.dependentParameterNames.every(function (name) {
@@ -3976,14 +4443,14 @@ function executePipeline(options) {
3976
4443
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
3977
4444
  throw new UnexpectedError(
3978
4445
  // TODO: [🐎] DRY
3979
- spaceTrim(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
4446
+ spaceTrim(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
3980
4447
  .map(function (_a) {
3981
4448
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
3982
4449
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
3983
4450
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
3984
4451
  .join(' and '));
3985
4452
  })
3986
- .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 "); }));
4453
+ .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 "); }));
3987
4454
  case 1:
3988
4455
  if (!!currentTemplate) return [3 /*break*/, 3];
3989
4456
  /* [🤹‍♂️] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -4000,10 +4467,10 @@ function executePipeline(options) {
4000
4467
  llmTools: llmTools,
4001
4468
  onProgress: function (progress) {
4002
4469
  if (isReturned) {
4003
- throw new UnexpectedError(spaceTrim(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)
4470
+ throw new UnexpectedError(spaceTrim(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)
4004
4471
  .split('\n')
4005
4472
  .map(function (line) { return "> ".concat(line); })
4006
- .join('\n')), "\n "); }));
4473
+ .join('\n')), "\n "); }));
4007
4474
  }
4008
4475
  if (onProgress) {
4009
4476
  onProgress(progress);
@@ -4011,7 +4478,7 @@ function executePipeline(options) {
4011
4478
  },
4012
4479
  settings: settings,
4013
4480
  $executionReport: executionReport,
4014
- pipelineIdentification: pipelineIdentification,
4481
+ pipelineIdentification: spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Template name: ").concat(currentTemplate.name, "\n Template title: ").concat(currentTemplate.title, "\n "); }),
4015
4482
  })
4016
4483
  .then(function (newParametersToPass) {
4017
4484
  parametersToPass = __assign(__assign({}, newParametersToPass), parametersToPass);
@@ -4103,6 +4570,9 @@ function executePipeline(options) {
4103
4570
  });
4104
4571
  });
4105
4572
  }
4573
+ /**
4574
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4575
+ */
4106
4576
 
4107
4577
  /**
4108
4578
  * Creates executor function from pipeline and execution tools.
@@ -4114,7 +4584,7 @@ function executePipeline(options) {
4114
4584
  function createPipelineExecutor(options) {
4115
4585
  var _this = this;
4116
4586
  var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
4117
- 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;
4587
+ 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;
4118
4588
  validatePipeline(pipeline);
4119
4589
  var pipelineIdentification = (function () {
4120
4590
  // Note: This is a 😐 implementation of [🚞]
@@ -4134,9 +4604,11 @@ function createPipelineExecutor(options) {
4134
4604
  else if (isNotPreparedWarningSupressed !== true) {
4135
4605
  console.warn(spaceTrim(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 "); }));
4136
4606
  }
4607
+ var runCount = 0;
4137
4608
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
4138
4609
  return __generator(this, function (_a) {
4139
- return [2 /*return*/, executePipeline({
4610
+ runCount++;
4611
+ return [2 /*return*/, /* not await */ executePipeline({
4140
4612
  pipeline: pipeline,
4141
4613
  preparedPipeline: preparedPipeline,
4142
4614
  setPreparedPipeline: function (newPreparedPipeline) {
@@ -4145,10 +4617,11 @@ function createPipelineExecutor(options) {
4145
4617
  inputParameters: inputParameters,
4146
4618
  tools: tools,
4147
4619
  onProgress: onProgress,
4148
- pipelineIdentification: pipelineIdentification,
4620
+ pipelineIdentification: spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n ").concat(runCount === 1 ? '' : "Run #".concat(runCount), "\n "); }),
4149
4621
  settings: {
4150
4622
  maxExecutionAttempts: maxExecutionAttempts,
4151
4623
  maxParallelCount: maxParallelCount,
4624
+ csvSettings: csvSettings,
4152
4625
  isVerbose: isVerbose,
4153
4626
  isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
4154
4627
  },
@@ -4157,6 +4630,9 @@ function createPipelineExecutor(options) {
4157
4630
  }); };
4158
4631
  return pipelineExecutor;
4159
4632
  }
4633
+ /**
4634
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4635
+ */
4160
4636
 
4161
4637
  /**
4162
4638
  * @@@
@@ -4208,7 +4684,7 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4208
4684
  outputParameters = result.outputParameters;
4209
4685
  knowledgePiecesRaw = outputParameters.knowledgePieces;
4210
4686
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
4211
- // <- TODO: !!!!! Smarter split and filter out empty pieces
4687
+ // <- TODO: [main] !!!!! Smarter split and filter out empty pieces
4212
4688
  if (isVerbose) {
4213
4689
  console.info('knowledgeTextPieces:', knowledgeTextPieces);
4214
4690
  }
@@ -4266,8 +4742,13 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4266
4742
  case 6: return [3 /*break*/, 8];
4267
4743
  case 7:
4268
4744
  error_1 = _c.sent();
4745
+ // Note: Here is expected error:
4746
+ // > PipelineExecutionError: You have not provided any `LlmExecutionTools` that support model variant "EMBEDDING
4747
+ if (!(error_1 instanceof PipelineExecutionError)) {
4748
+ throw error_1;
4749
+ }
4269
4750
  // TODO: [🟥] Detect browser / node and make it colorfull
4270
- console.error(error_1);
4751
+ console.error(error_1, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
4271
4752
  return [3 /*break*/, 8];
4272
4753
  case 8: return [2 /*return*/, {
4273
4754
  name: name,
@@ -4288,7 +4769,7 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4288
4769
  });
4289
4770
  }
4290
4771
  /**
4291
- * TODO: [🐝][🔼] !!! Export via `@promptbook/markdown`
4772
+ * TODO: [🐝][🔼][main] !!! Export via `@promptbook/markdown`
4292
4773
  * TODO: [🪂] Do it in parallel 11:11
4293
4774
  * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4294
4775
  */
@@ -4312,7 +4793,7 @@ function prepareKnowledgePieces(knowledgeSources, options) {
4312
4793
  var partialPieces, pieces;
4313
4794
  return __generator(this, function (_a) {
4314
4795
  switch (_a.label) {
4315
- case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4796
+ case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝][main] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4316
4797
  options)];
4317
4798
  case 1:
4318
4799
  partialPieces = _a.sent();
@@ -4504,7 +4985,7 @@ function preparePersona(personaDescription, options) {
4504
4985
  });
4505
4986
  }
4506
4987
  /**
4507
- * TODO: [🔃] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4988
+ * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4508
4989
  * TODO: [🏢] !! Check validity of `modelName` in pipeline
4509
4990
  * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4510
4991
  * TODO: [🏢] !! Check validity of `temperature` in pipeline
@@ -4553,7 +5034,7 @@ function prepareTemplates(pipeline, options) {
4553
5034
  case 0:
4554
5035
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
4555
5036
  templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4556
- // TODO: !!!!! Apply samples to each template (if missing and is for the template defined)
5037
+ // TODO: [main] !!!!! Apply samples to each template (if missing and is for the template defined)
4557
5038
  TODO_USE(parameters);
4558
5039
  templatesPrepared = new Array(
4559
5040
  // <- TODO: [🧱] Implement in a functional (not new Class) way
@@ -4585,7 +5066,7 @@ function prepareTemplates(pipeline, options) {
4585
5066
  /**
4586
5067
  * TODO: [🧠] Add context to each template (if missing)
4587
5068
  * TODO: [🧠] What is better name `prepareTemplate` or `prepareTemplateAndParameters`
4588
- * TODO: [♨] !!! Prepare index the samples and maybe templates
5069
+ * TODO: [♨][main] !!! Prepare index the samples and maybe templates
4589
5070
  * TODO: Write tests for `preparePipeline`
4590
5071
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4591
5072
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
@@ -4757,7 +5238,7 @@ var knowledgeCommandParser = {
4757
5238
  if (sourceContent === '') {
4758
5239
  throw new ParseError("Source is not defined");
4759
5240
  }
4760
- // TODO: !!!! Following checks should be applied every link in the `sourceContent`
5241
+ // TODO: [main] !!!! Following checks should be applied every link in the `sourceContent`
4761
5242
  if (sourceContent.startsWith('http://')) {
4762
5243
  throw new ParseError("Source is not secure");
4763
5244
  }
@@ -4960,7 +5441,7 @@ var templateCommandParser = {
4960
5441
  if (command.templateType === 'KNOWLEDGE') {
4961
5442
  knowledgeCommandParser.$applyToPipelineJson({
4962
5443
  type: 'KNOWLEDGE',
4963
- sourceContent: $templateJson.content, // <- TODO: [🐝] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
5444
+ sourceContent: $templateJson.content, // <- TODO: [🐝][main] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
4964
5445
  }, $pipelineJson);
4965
5446
  $templateJson.isTemplate = false;
4966
5447
  return;
@@ -5310,6 +5791,171 @@ function normalizeTo_SCREAMING_CASE(text) {
5310
5791
  * TODO: [🌺] Use some intermediate util splitWords
5311
5792
  */
5312
5793
 
5794
+ /**
5795
+ * @@@
5796
+ *
5797
+ * @param text @@@
5798
+ * @param _isFirstLetterCapital @@@
5799
+ * @returns @@@
5800
+ * @example 'helloWorld'
5801
+ * @example 'iLovePromptbook'
5802
+ * @public exported from `@promptbook/utils`
5803
+ */
5804
+ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
5805
+ var e_1, _a;
5806
+ if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
5807
+ var charType;
5808
+ var lastCharType = null;
5809
+ var normalizedName = '';
5810
+ try {
5811
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5812
+ var char = text_1_1.value;
5813
+ var normalizedChar = void 0;
5814
+ if (/^[a-z]$/.test(char)) {
5815
+ charType = 'LOWERCASE';
5816
+ normalizedChar = char;
5817
+ }
5818
+ else if (/^[A-Z]$/.test(char)) {
5819
+ charType = 'UPPERCASE';
5820
+ normalizedChar = char.toLowerCase();
5821
+ }
5822
+ else if (/^[0-9]$/.test(char)) {
5823
+ charType = 'NUMBER';
5824
+ normalizedChar = char;
5825
+ }
5826
+ else {
5827
+ charType = 'OTHER';
5828
+ normalizedChar = '';
5829
+ }
5830
+ if (!lastCharType) {
5831
+ if (_isFirstLetterCapital) {
5832
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
5833
+ }
5834
+ }
5835
+ else if (charType !== lastCharType &&
5836
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
5837
+ !(lastCharType === 'NUMBER') &&
5838
+ !(charType === 'NUMBER')) {
5839
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
5840
+ }
5841
+ normalizedName += normalizedChar;
5842
+ lastCharType = charType;
5843
+ }
5844
+ }
5845
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5846
+ finally {
5847
+ try {
5848
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
5849
+ }
5850
+ finally { if (e_1) throw e_1.error; }
5851
+ }
5852
+ return normalizedName;
5853
+ }
5854
+ /**
5855
+ * TODO: [🌺] Use some intermediate util splitWords
5856
+ */
5857
+
5858
+ /**
5859
+ * Removes quotes from a string
5860
+ *
5861
+ * Tip: This is very usefull for post-processing of the result of the LLM model
5862
+ * Note: This function removes only the same quotes from the beginning and the end of the string
5863
+ * Note: There are two simmilar functions:
5864
+ * - `removeQuotes` which removes only bounding quotes
5865
+ * - `unwrapResult` which removes whole introduce sentence
5866
+ *
5867
+ * @param text optionally quoted text
5868
+ * @returns text without quotes
5869
+ * @public exported from `@promptbook/utils`
5870
+ */
5871
+ function removeQuotes(text) {
5872
+ if (text.startsWith('"') && text.endsWith('"')) {
5873
+ return text.slice(1, -1);
5874
+ }
5875
+ if (text.startsWith('\'') && text.endsWith('\'')) {
5876
+ return text.slice(1, -1);
5877
+ }
5878
+ return text;
5879
+ }
5880
+
5881
+ /**
5882
+ * Function `validateParameterName` will @@@
5883
+ *
5884
+ * @param parameterName @@@
5885
+ * @returns @@@
5886
+ * @throws {ParseError} @@@
5887
+ * @private within the repository
5888
+ */
5889
+ function validateParameterName(parameterName) {
5890
+ var e_1, _a;
5891
+ var rawParameterName = parameterName;
5892
+ try {
5893
+ for (var _b = __values([
5894
+ ['`', '`'],
5895
+ ['{', '}'],
5896
+ ['[', ']'],
5897
+ ['(', ')'],
5898
+ ['<', '>'],
5899
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
5900
+ var _d = __read(_c.value, 2), start = _d[0], end = _d[1];
5901
+ if (parameterName.substring(0, 1) === start &&
5902
+ parameterName.substring(parameterName.length - 1, parameterName.length) === end
5903
+ // <- TODO: More universal that 1 character
5904
+ ) {
5905
+ parameterName = parameterName.substring(1, parameterName.length - 1);
5906
+ // <- TODO: More universal that 1 character
5907
+ }
5908
+ }
5909
+ }
5910
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5911
+ finally {
5912
+ try {
5913
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
5914
+ }
5915
+ finally { if (e_1) throw e_1.error; }
5916
+ }
5917
+ // TODO: [🐠] Following try-catch block should be part of common validators logic
5918
+ try {
5919
+ /*
5920
+ Note: We don't need to check for spaces because we are going to normalize the parameter name to camelCase
5921
+ if (parameterName.includes(' ')) {
5922
+ throw new ParseError(`Parameter name cannot contain spaces`);
5923
+ }
5924
+ */
5925
+ if (parameterName.includes('.')) {
5926
+ throw new ParseError("Parameter name cannot contain dots");
5927
+ }
5928
+ if (parameterName.includes('/') || parameterName.includes('\\')) {
5929
+ throw new ParseError("Parameter name cannot contain slashes");
5930
+ }
5931
+ if (parameterName.includes('(') ||
5932
+ parameterName.includes(')') ||
5933
+ parameterName.includes('{') ||
5934
+ parameterName.includes('}') ||
5935
+ parameterName.includes('[') ||
5936
+ parameterName.includes(']')) {
5937
+ throw new ParseError("Parameter name cannot contain braces");
5938
+ }
5939
+ parameterName = removeDiacritics(parameterName);
5940
+ parameterName = removeEmojis(parameterName);
5941
+ parameterName = removeQuotes(parameterName);
5942
+ parameterName = normalizeTo_camelCase(parameterName);
5943
+ if (parameterName === '') {
5944
+ throw new ParseError("Parameter name cannot be empty");
5945
+ }
5946
+ if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
5947
+ throw new ParseError("{".concat(parameterName, "} is a reserved parameter name"));
5948
+ }
5949
+ }
5950
+ catch (error) {
5951
+ if (!(error instanceof ParseError)) {
5952
+ throw error;
5953
+ }
5954
+ throw new ParseError(spaceTrim$1(function (block) { return "\n ".concat(block(error.message), "\n\n Tried to validate parameter name:\n ").concat(block(rawParameterName), "\n "); }));
5955
+ }
5956
+ return parameterName;
5957
+ }
5958
+
5313
5959
  /**
5314
5960
  * Parses the foreach command
5315
5961
  *
@@ -5339,15 +5985,16 @@ var foreachCommandParser = {
5339
5985
  /**
5340
5986
  * Link to discussion
5341
5987
  */
5342
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5988
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/148',
5343
5989
  /**
5344
5990
  * Example usages of the FOREACH command
5345
5991
  */
5346
5992
  examples: [
5347
- 'FOREACH List Line `{customers}` -> `{customer}`',
5348
- 'FOR List Line `{customers}` -> `{customer}`',
5349
- 'EACH List Line `{customers}` -> `{customer}`',
5350
- // <- TODO: [🍭] !!!!!! More
5993
+ 'FOREACH Text Line `{customers}` -> `{customer}`',
5994
+ 'FOREACH Csv Cell `{customers}` -> `{cell}`',
5995
+ 'FOREACH Csv Row `{customers}` -> `{firstName}`, `{lastName}`, `+{email}`',
5996
+ 'FOR Text Line `{customers}` -> `{customer}`',
5997
+ 'EACH Text Line `{customers}` -> `{customer}`',
5351
5998
  ],
5352
5999
  /**
5353
6000
  * Parses the FOREACH command
@@ -5355,55 +6002,75 @@ var foreachCommandParser = {
5355
6002
  parse: function (input) {
5356
6003
  var args = input.args;
5357
6004
  var formatName = normalizeTo_SCREAMING_CASE(args[0] || '');
5358
- var cellName = normalizeTo_SCREAMING_CASE(args[1] || '');
5359
- var parameterNameWrapped = args[2];
6005
+ var subformatName = normalizeTo_SCREAMING_CASE(args[1] || '');
6006
+ var parameterNameArg = args[2] || '';
5360
6007
  var assignSign = args[3];
5361
- var subparameterNameWrapped = args[4];
5362
- if (![
5363
- 'LIST',
5364
- 'CSV',
5365
- // <- TODO: [🏢] Unhardcode formats
5366
- ].includes(formatName)) {
5367
- console.info({ args: args, formatName: formatName });
5368
- throw new Error("Unsupported format \"".concat(formatName, "\""));
6008
+ var formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
6009
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(formatName);
6010
+ });
6011
+ if (formatDefinition === undefined) {
6012
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Unsupported format \"".concat(formatName, "\"\n\n Available formats:\n ").concat(block(FORMAT_DEFINITIONS.map(function (formatDefinition) { return formatDefinition.formatName; })
6013
+ .map(function (formatName) { return "- ".concat(formatName); })
6014
+ .join('\n')), "\n "); }));
5369
6015
  // <- TODO: [🏢] List all supported format names
5370
6016
  }
5371
- if (![
5372
- 'LINE',
5373
- 'ROW',
5374
- 'COLUMN',
5375
- 'CELL',
5376
- // <- TODO: [🏢] Unhardcode format cells
5377
- ].includes(cellName)) {
5378
- console.info({ args: args, cellName: cellName });
5379
- throw new Error("Format ".concat(formatName, " does not support cell \"").concat(cellName, "\""));
5380
- // <- TODO: [🏢] List all supported cell names for the format
6017
+ var subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
6018
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(subformatName);
6019
+ });
6020
+ if (subvalueDefinition === undefined) {
6021
+ throw new ParseError(spaceTrim$1(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
6022
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
6023
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
6024
+ .join('\n')), "\n "); }));
6025
+ // <- TODO: [🏢] List all supported subformat names for the format
5381
6026
  }
5382
6027
  if (assignSign !== '->') {
5383
- console.info({ args: args, assignSign: assignSign });
5384
- throw new Error("FOREACH command must have '->' to assign the value to the parameter");
5385
- }
5386
- // TODO: !!!!!! Replace with propper parameter name validation
5387
- if ((parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(0, 1)) !== '{' ||
5388
- (parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(parameterNameWrapped.length - 1, parameterNameWrapped.length)) !== '}') {
5389
- 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));
5390
- throw new Error("!!!!!! 1 Here will be error (with rules and precise error) from validateParameterName");
5391
- }
5392
- var parameterName = parameterNameWrapped.substring(1, parameterNameWrapped.length - 1);
5393
- // TODO: !!!!!! Replace with propper parameter name validation
5394
- if ((subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(0, 1)) !== '{' ||
5395
- (subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(subparameterNameWrapped.length - 1, subparameterNameWrapped.length)) !==
5396
- '}') {
5397
- console.info({ args: args, subparameterNameWrapped: subparameterNameWrapped });
5398
- throw new Error("!!!!!! 2 Here will be error (with rules and precise error) from validateParameterName");
5399
- }
5400
- var subparameterName = subparameterNameWrapped.substring(1, subparameterNameWrapped.length - 1);
6028
+ throw new ParseError("FOREACH command must have '->' to assign the value to the parameter");
6029
+ }
6030
+ var parameterName = validateParameterName(parameterNameArg);
6031
+ var outputSubparameterName = null;
6032
+ // TODO: [4] DRY
6033
+ var inputSubparameterNames = args
6034
+ .slice(4)
6035
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6036
+ .filter(function (parameterName) { return !parameterName.includes('+'); })
6037
+ .filter(function (parameterName) { return parameterName !== ''; })
6038
+ .map(validateParameterName);
6039
+ // TODO: [4] DRY
6040
+ var outputSubparameterNames = args
6041
+ .slice(4)
6042
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6043
+ .filter(function (parameterName) { return parameterName.includes('+'); })
6044
+ .map(function (parameterName) { return parameterName.split('+').join(''); })
6045
+ .map(validateParameterName);
6046
+ if (outputSubparameterNames.length === 1) {
6047
+ outputSubparameterName = outputSubparameterNames[0];
6048
+ }
6049
+ else if (outputSubparameterNames.length > 1) {
6050
+ throw new ParseError("FOREACH command can not have more than one output subparameter");
6051
+ }
6052
+ if (inputSubparameterNames.length === 0) {
6053
+ throw new ParseError("FOREACH command must have at least one input subparameter");
6054
+ }
6055
+ if (outputSubparameterName === null) {
6056
+ // TODO: Following code should be unhardcoded from here and moved to the format definition
6057
+ if (formatName === 'CSV' && subformatName === 'CELL') {
6058
+ outputSubparameterName = 'newCell';
6059
+ }
6060
+ else if (formatName === 'TEXT' && subformatName === 'LINE') {
6061
+ outputSubparameterName = 'newLine';
6062
+ }
6063
+ else {
6064
+ throw new ParseError(spaceTrim$1("\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 ")));
6065
+ }
6066
+ }
5401
6067
  return {
5402
6068
  type: 'FOREACH',
5403
6069
  formatName: formatName,
5404
- cellName: cellName,
6070
+ subformatName: subformatName,
5405
6071
  parameterName: parameterName,
5406
- subparameterName: subparameterName,
6072
+ inputSubparameterNames: inputSubparameterNames,
6073
+ outputSubparameterName: outputSubparameterName,
5407
6074
  };
5408
6075
  },
5409
6076
  /**
@@ -5412,11 +6079,17 @@ var foreachCommandParser = {
5412
6079
  * Note: `$` is used to indicate that this function mutates given `templateJson`
5413
6080
  */
5414
6081
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5415
- var formatName = command.formatName, cellName = command.cellName, parameterName = command.parameterName, subparameterName = command.subparameterName;
5416
- // TODO: !!!!!! Detect double use
5417
- // TODO: !!!!!! Detect usage with JOKER and don't allow it
5418
- $templateJson.foreach = { formatName: formatName, cellName: cellName, parameterName: parameterName, subparameterName: subparameterName };
5419
- keepUnused($pipelineJson); // <- TODO: !!!!!! BUT Maybe register subparameter from foreach into parameters of the pipeline
6082
+ var formatName = command.formatName, subformatName = command.subformatName, parameterName = command.parameterName, inputSubparameterNames = command.inputSubparameterNames, outputSubparameterName = command.outputSubparameterName;
6083
+ // TODO: [🍭] Detect double use
6084
+ // TODO: [🍭] Detect usage with JOKER and don't allow it
6085
+ $templateJson.foreach = {
6086
+ formatName: formatName,
6087
+ subformatName: subformatName,
6088
+ parameterName: parameterName,
6089
+ inputSubparameterNames: inputSubparameterNames,
6090
+ outputSubparameterName: outputSubparameterName,
6091
+ };
6092
+ keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
5420
6093
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
5421
6094
  },
5422
6095
  /**
@@ -5439,8 +6112,7 @@ var foreachCommandParser = {
5439
6112
  },
5440
6113
  };
5441
6114
  /**
5442
- * TODO: !!!!!! Comment console logs
5443
- * TODO: [🍭] !!!!!! Make .ptbk.md file with examples of the FOREACH command and also with wrong parsing and logic
6115
+ * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
5444
6116
  */
5445
6117
 
5446
6118
  /**
@@ -5550,12 +6222,11 @@ var jokerCommandParser = {
5550
6222
  */
5551
6223
  parse: function (input) {
5552
6224
  var args = input.args;
5553
- // TODO: !!!!!! Replace with propper parameter name validation
5554
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5555
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5556
- throw new ParseError("Invalid joker");
6225
+ if (args.length !== 1) {
6226
+ throw new ParseError("JOKE command expects exactly one parameter name");
5557
6227
  }
5558
- var parameterName = parametersMatch.groups.parameterName;
6228
+ var parameterNameArg = args[0] || '';
6229
+ var parameterName = validateParameterName(parameterNameArg);
5559
6230
  return {
5560
6231
  type: 'JOKER',
5561
6232
  parameterName: parameterName,
@@ -5630,6 +6301,9 @@ var modelCommandParser = {
5630
6301
  */
5631
6302
  parse: function (input) {
5632
6303
  var args = input.args, normalized = input.normalized;
6304
+ var availableVariantsMessage = spaceTrim$1(function (block) { return "\n Available variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) {
6305
+ return "- ".concat(variantName).concat(variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)');
6306
+ }).join('\n')), "\n "); });
5633
6307
  // TODO: Make this more elegant and dynamically
5634
6308
  if (normalized.startsWith('MODEL_VARIANT')) {
5635
6309
  if (normalized === 'MODEL_VARIANT_CHAT') {
@@ -5645,17 +6319,13 @@ var modelCommandParser = {
5645
6319
  key: 'modelVariant',
5646
6320
  value: 'COMPLETION',
5647
6321
  };
6322
+ // <- Note: [🤖]
5648
6323
  }
5649
6324
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
5650
- return {
5651
- type: 'MODEL',
5652
- key: 'modelVariant',
5653
- value: 'EMBEDDING',
5654
- };
5655
- // <- Note: [🤖]
6325
+ spaceTrim$1(function (block) { return "\n Embedding model can not be used in pipeline\n\n ".concat(block(availableVariantsMessage), "\n "); });
5656
6326
  }
5657
6327
  else {
5658
- throw new ParseError(spaceTrim$1(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 "); }));
6328
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Unknown model variant in command:\n\n ".concat(block(availableVariantsMessage), "\n "); }));
5659
6329
  }
5660
6330
  }
5661
6331
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5780,14 +6450,13 @@ var parameterCommandParser = {
5780
6450
  * Parses the PARAMETER command
5781
6451
  */
5782
6452
  parse: function (input) {
5783
- var normalized = input.normalized, raw = input.raw;
5784
- var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5785
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5786
- throw new ParseError("Invalid parameter");
5787
- }
5788
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5789
- if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5790
- throw new ParseError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
6453
+ var normalized = input.normalized, args = input.args, raw = input.raw;
6454
+ var parameterNameRaw = args.shift() || '';
6455
+ var parameterDescriptionRaw = args.join(' ');
6456
+ // <- TODO: When [🥶] fixed, change to:
6457
+ // > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
6458
+ if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
6459
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameterNameRaw, "} can not contain another parameter in description\n\n The description:\n ").concat(block(parameterDescriptionRaw), "\n "); }));
5791
6460
  }
5792
6461
  var isInput = normalized.startsWith('INPUT');
5793
6462
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5795,11 +6464,12 @@ var parameterCommandParser = {
5795
6464
  isInput = false;
5796
6465
  isOutput = false;
5797
6466
  }
5798
- // TODO: !!!!!! Add parameter name validation
6467
+ var parameterName = validateParameterName(parameterNameRaw);
6468
+ var parameterDescription = parameterDescriptionRaw.trim() || null;
5799
6469
  return {
5800
6470
  type: 'PARAMETER',
5801
6471
  parameterName: parameterName,
5802
- parameterDescription: parameterDescription.trim() || null,
6472
+ parameterDescription: parameterDescription,
5803
6473
  isInput: isInput,
5804
6474
  isOutput: isOutput,
5805
6475
  };
@@ -6124,6 +6794,7 @@ var promptbookVersionCommandParser = {
6124
6794
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6125
6795
  */
6126
6796
  $applyToPipelineJson: function (command, $pipelineJson) {
6797
+ // TODO: Warn if the version is overridden
6127
6798
  $pipelineJson.promptbookVersion = command.promptbookVersion;
6128
6799
  },
6129
6800
  /**
@@ -6606,7 +7277,9 @@ function parseCommand(raw, usagePlace) {
6606
7277
  for (var commandNameSegmentsCount = 0; commandNameSegmentsCount < Math.min(items.length, 3); commandNameSegmentsCount++) {
6607
7278
  var commandNameRaw = items.slice(0, commandNameSegmentsCount + 1).join('_');
6608
7279
  var args = items.slice(commandNameSegmentsCount + 1);
6609
- var rawArgs = raw.substring(commandNameRaw.length).trim();
7280
+ var rawArgs = raw
7281
+ .substring(commandNameRaw.length)
7282
+ .trim();
6610
7283
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6611
7284
  if (command !== null) {
6612
7285
  return command;
@@ -6617,7 +7290,9 @@ function parseCommand(raw, usagePlace) {
6617
7290
  {
6618
7291
  var commandNameRaw = items.slice(-1).join('_');
6619
7292
  var args = items.slice(0, -1); // <- Note: This is probbably not correct
6620
- var rawArgs = raw.substring(0, raw.length - commandNameRaw.length).trim();
7293
+ var rawArgs = raw
7294
+ .substring(0, raw.length - commandNameRaw.length)
7295
+ .trim();
6621
7296
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6622
7297
  if (command !== null) {
6623
7298
  return command;
@@ -6757,7 +7432,7 @@ function extractAllListItemsFromMarkdown(markdown) {
6757
7432
  function extractOneBlockFromMarkdown(markdown) {
6758
7433
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
6759
7434
  if (codeBlocks.length !== 1) {
6760
- throw new ParseError(spaceTrim$1(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 "); }));
7435
+ throw new ParseError(spaceTrim$1(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 "); }));
6761
7436
  }
6762
7437
  return codeBlocks[0];
6763
7438
  }
@@ -6944,7 +7619,7 @@ function pipelineStringToJsonSync(pipelineString) {
6944
7619
  var $pipelineJson = {
6945
7620
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
6946
7621
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
6947
- promptbookVersion: PROMPTBOOK_VERSION,
7622
+ promptbookVersion: undefined /* <- Note: By default no explicit version */,
6948
7623
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
6949
7624
  parameters: [],
6950
7625
  templates: [],
@@ -7235,7 +7910,7 @@ function pipelineStringToJsonSync(pipelineString) {
7235
7910
  return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
7236
7911
  }
7237
7912
  /**
7238
- * TODO: !!!! Warn if used only sync version
7913
+ * TODO: [main] !!!! Warn if used only sync version
7239
7914
  * TODO: [🚞] Report here line/column of error
7240
7915
  * TODO: Use spaceTrim more effectively
7241
7916
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
@@ -7740,7 +8415,7 @@ function isSerializableAsJson(value) {
7740
8415
  }
7741
8416
  }
7742
8417
  /**
7743
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
8418
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
7744
8419
  * TODO: [🧠][💺] Can be done this on type-level?
7745
8420
  */
7746
8421
 
@@ -7797,21 +8472,41 @@ function usageToWorktime(usage) {
7797
8472
  * @public exported from `@promptbook/core`
7798
8473
  */
7799
8474
  function usageToHuman(usage) {
7800
- var report = 'Usage:';
8475
+ var reportItems = [];
7801
8476
  var uncertainNumberToHuman = function (_a) {
7802
8477
  var value = _a.value, isUncertain = _a.isUncertain;
7803
8478
  return "".concat(isUncertain ? 'approximately ' : '').concat(Math.round(value * 100) / 100);
7804
8479
  };
7805
- report += '\n' + "- Cost ".concat(uncertainNumberToHuman(usage.price), " USD");
7806
- report += '\n' + "- Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time");
7807
- return spaceTrim$1(report);
8480
+ if (usage.price.value > 0.01
8481
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻] Configure negligible value - default value to config + value to `UsageToHumanSettings`
8482
+ ) {
8483
+ reportItems.push("Cost ".concat(uncertainNumberToHuman(usage.price), " USD"));
8484
+ }
8485
+ else {
8486
+ reportItems.push("Negligible cost");
8487
+ }
8488
+ var worktime = usageToWorktime(usage);
8489
+ if (worktime.value >
8490
+ 1 / 60
8491
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻]
8492
+ ) {
8493
+ reportItems.push("Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time"));
8494
+ // TODO: [🍓][🧞‍♂️] Show minutes, seconds, days NOT 0.1 hours
8495
+ }
8496
+ if (usage.output.charactersCount.value > 0) {
8497
+ reportItems.push("Written ".concat(uncertainNumberToHuman(usage.output.charactersCount), " characters"));
8498
+ }
8499
+ if (reportItems.length === 0) {
8500
+ // Note: For negligible usage, we report at least something
8501
+ reportItems.push('Negligible');
8502
+ }
8503
+ return spaceTrim$1(function (block) { return "\n Usage:\n ".concat(block(reportItems.map(function (item) { return "- ".concat(item); }).join('\n')), "\n "); });
7808
8504
  }
7809
8505
  /**
7810
- * TODO: Use "$1" not "1 USD"
7811
- * TODO: Use markdown formatting like "Cost approximately **$1**"
7812
- * TODO: Report in minutes, seconds, days NOT 0.1 hours
8506
+ * TODO: [🍓][🧞‍♂️] Use "$1" not "1 USD"
8507
+ * TODO: [🍓][🧞‍♂️] Use markdown formatting like "Cost approximately **$1**"
8508
+ * TODO: [🍓][🧞‍♂️] Report in minutes, seconds, days NOT 0.1 hours
7813
8509
  * TODO: [🧠] Maybe make from `uncertainNumberToHuman` separate exported utility
7814
- * TODO: When negligible usage, report "Negligible" or just don't report it
7815
8510
  * TODO: [🧠] Maybe use "~" instead of "approximately"
7816
8511
  * TODO: [🏛] Maybe make some markdown builder
7817
8512
  */
@@ -8581,7 +9276,7 @@ function initializeMakeCommand(program) {
8581
9276
  });
8582
9277
  }
8583
9278
  /**
8584
- * TODO: [🥃] !!! Allow `ptbk make` without configuring any llm tools
9279
+ * TODO: [🥃][main] !!! Allow `ptbk make` without configuring any llm tools
8585
9280
  * TODO: Maybe remove this command - "about" command should be enough?
8586
9281
  * TODO: [0] DRY Javascript and typescript - Maybe make ONLY typescript and for javascript just remove types
8587
9282
  * Note: [🟡] This code should never be published outside of `@promptbook/cli`
@@ -8615,70 +9310,6 @@ function addAutoGeneratedSection(content, options) {
8615
9310
  * TODO: [🏛] This can be part of markdown builder
8616
9311
  */
8617
9312
 
8618
- /**
8619
- * @@@
8620
- *
8621
- * @param text @@@
8622
- * @param _isFirstLetterCapital @@@
8623
- * @returns @@@
8624
- * @example 'helloWorld'
8625
- * @example 'iLovePromptbook'
8626
- * @public exported from `@promptbook/utils`
8627
- */
8628
- function normalizeTo_camelCase(text, _isFirstLetterCapital) {
8629
- var e_1, _a;
8630
- if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
8631
- var charType;
8632
- var lastCharType = null;
8633
- var normalizedName = '';
8634
- try {
8635
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
8636
- var char = text_1_1.value;
8637
- var normalizedChar = void 0;
8638
- if (/^[a-z]$/.test(char)) {
8639
- charType = 'LOWERCASE';
8640
- normalizedChar = char;
8641
- }
8642
- else if (/^[A-Z]$/.test(char)) {
8643
- charType = 'UPPERCASE';
8644
- normalizedChar = char.toLowerCase();
8645
- }
8646
- else if (/^[0-9]$/.test(char)) {
8647
- charType = 'NUMBER';
8648
- normalizedChar = char;
8649
- }
8650
- else {
8651
- charType = 'OTHER';
8652
- normalizedChar = '';
8653
- }
8654
- if (!lastCharType) {
8655
- if (_isFirstLetterCapital) {
8656
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
8657
- }
8658
- }
8659
- else if (charType !== lastCharType &&
8660
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
8661
- !(lastCharType === 'NUMBER') &&
8662
- !(charType === 'NUMBER')) {
8663
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
8664
- }
8665
- normalizedName += normalizedChar;
8666
- lastCharType = charType;
8667
- }
8668
- }
8669
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
8670
- finally {
8671
- try {
8672
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
8673
- }
8674
- finally { if (e_1) throw e_1.error; }
8675
- }
8676
- return normalizedName;
8677
- }
8678
- /**
8679
- * TODO: [🌺] Use some intermediate util splitWords
8680
- */
8681
-
8682
9313
  /**
8683
9314
  * Creates a Mermaid graph based on the promptbook
8684
9315
  *
@@ -8735,9 +9366,9 @@ function renderPromptbookMermaid(pipelineJson, options) {
8735
9366
  return promptbookMermaid;
8736
9367
  }
8737
9368
  /**
8738
- * TODO: !!!!!! FOREACH in mermaid graph
8739
- * TODO: !!!!!! Knowledge in mermaid graph
8740
- * TODO: !!!!!! Personas in mermaid graph
9369
+ * TODO: !!!!! FOREACH in mermaid graph
9370
+ * TODO: !!!!! Knowledge in mermaid graph
9371
+ * TODO: !!!!! Personas in mermaid graph
8741
9372
  * TODO: Maybe use some Mermaid package instead of string templating
8742
9373
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
8743
9374
  */
@@ -9063,7 +9694,7 @@ var RemoteLlmExecutionTools = /** @class */ (function () {
9063
9694
  socket.on('connect', function () {
9064
9695
  resolve(socket);
9065
9696
  });
9066
- // TODO: !!!! Better timeout handling
9697
+ // TODO: [main] !!!! Better timeout handling
9067
9698
  setTimeout(function () {
9068
9699
  reject(new Error("Timeout while connecting to ".concat(_this.options.remoteUrl)));
9069
9700
  }, CONNECTION_TIMEOUT_MS);
@@ -9243,11 +9874,11 @@ var ANTHROPIC_CLAUDE_MODELS = $asDeeplyFrozenSerializableJson('ANTHROPIC_CLAUDE_
9243
9874
  output: computeUsage("$2.40 / 1M tokens"),
9244
9875
  },
9245
9876
  },
9246
- // TODO: !!! Claude 1 and 2 has also completion versions - ask Hoagy
9877
+ // TODO: [main] !!! Claude 1 and 2 has also completion versions - ask Hoagy
9247
9878
  ]);
9248
9879
  /**
9249
9880
  * Note: [🤖] Add models of new variant
9250
- * TODO: [🧠] !!! Add embedding models OR Anthropic has only chat+completion models?
9881
+ * TODO: [🧠][main] !!! Add embedding models OR Anthropic has only chat+completion models?
9251
9882
  * TODO: [🧠] Some mechanism to propagate unsureness
9252
9883
  * TODO: [🧠][👮‍♀️] Put here more info like description, isVision, trainingDateCutoff, languages, strengths ( Top-level performance, intelligence, fluency, and understanding), contextWindow,...
9253
9884
  * TODO: [🎰] Some mechanism to auto-update available models
@@ -9456,7 +10087,7 @@ var AnthropicClaudeExecutionTools = /** @class */ (function () {
9456
10087
  resultContent = contentBlock.text;
9457
10088
  // eslint-disable-next-line prefer-const
9458
10089
  complete = getCurrentIsoDate();
9459
- usage = computeAnthropicClaudeUsage(content, '', rawResponse);
10090
+ usage = computeAnthropicClaudeUsage(rawPromptContent || '', resultContent || '', rawResponse);
9460
10091
  return [2 /*return*/, $asDeeplyFrozenSerializableJson('AnthropicClaudeExecutionTools ChatPromptResult', {
9461
10092
  content: resultContent,
9462
10093
  modelName: rawResponse.model,
@@ -9603,8 +10234,8 @@ var createAnthropicClaudeExecutionTools = Object.assign(function (options) {
9603
10234
  className: 'AnthropicClaudeExecutionTools',
9604
10235
  });
9605
10236
  /**
9606
- * TODO: [🧠] !!!! Make anonymous this with all LLM providers
9607
- * TODO: [🧠][🧱] !!!! Maybe change all `new AnthropicClaudeExecutionTools` -> `createAnthropicClaudeExecutionTools` in manual
10237
+ * TODO: [🧠][main] !!!! Make anonymous this with all LLM providers
10238
+ * TODO: [🧠][🧱][main] !!!! Maybe change all `new AnthropicClaudeExecutionTools` -> `createAnthropicClaudeExecutionTools` in manual
9608
10239
  * TODO: [🧠] Maybe auto-detect usage in browser and determine default value of `isProxied`
9609
10240
  * TODO: [🦺] Is there some way how to put `packageName` and `className` on top and function definition on bottom?
9610
10241
  * TODO: [🎶] Naming "constructor" vs "creator" vs "factory"
@@ -9982,6 +10613,7 @@ var OPENAI_MODELS = $asDeeplyFrozenSerializableJson('OPENAI_MODELS', [
9982
10613
  prompt: computeUsage("$5.00 / 1M tokens"),
9983
10614
  output: computeUsage("$15.00 / 1M tokens"),
9984
10615
  },
10616
+ //TODO: [main] !!! Add gpt-4o-mini-2024-07-18 and all others to be up to date
9985
10617
  },
9986
10618
  /**/
9987
10619
  /**/
@@ -9996,6 +10628,51 @@ var OPENAI_MODELS = $asDeeplyFrozenSerializableJson('OPENAI_MODELS', [
9996
10628
  },
9997
10629
  /**/
9998
10630
  /**/
10631
+ {
10632
+ modelVariant: 'CHAT',
10633
+ modelTitle: 'o1-preview',
10634
+ modelName: 'o1-preview',
10635
+ pricing: {
10636
+ prompt: computeUsage("$15.00 / 1M tokens"),
10637
+ output: computeUsage("$60.00 / 1M tokens"),
10638
+ },
10639
+ },
10640
+ /**/
10641
+ /**/
10642
+ {
10643
+ modelVariant: 'CHAT',
10644
+ modelTitle: 'o1-preview-2024-09-12',
10645
+ modelName: 'o1-preview-2024-09-12',
10646
+ // <- TODO: [main] !!! Some better system to organize theese date suffixes and versions
10647
+ pricing: {
10648
+ prompt: computeUsage("$15.00 / 1M tokens"),
10649
+ output: computeUsage("$60.00 / 1M tokens"),
10650
+ },
10651
+ },
10652
+ /**/
10653
+ /**/
10654
+ {
10655
+ modelVariant: 'CHAT',
10656
+ modelTitle: 'o1-mini',
10657
+ modelName: 'o1-mini',
10658
+ pricing: {
10659
+ prompt: computeUsage("$3.00 / 1M tokens"),
10660
+ output: computeUsage("$12.00 / 1M tokens"),
10661
+ },
10662
+ },
10663
+ /**/
10664
+ /**/
10665
+ {
10666
+ modelVariant: 'CHAT',
10667
+ modelTitle: 'o1-mini-2024-09-12',
10668
+ modelName: 'o1-mini-2024-09-12',
10669
+ pricing: {
10670
+ prompt: computeUsage("$3.00 / 1M tokens"),
10671
+ output: computeUsage("$12.00 / 1M tokens"),
10672
+ },
10673
+ },
10674
+ /**/
10675
+ /**/
9999
10676
  {
10000
10677
  modelVariant: 'CHAT',
10001
10678
  modelTitle: 'gpt-3.5-turbo-16k-0613',
@@ -10084,7 +10761,7 @@ var AzureOpenAiExecutionTools = /** @class */ (function () {
10084
10761
  AzureOpenAiExecutionTools.prototype.listModels = function () {
10085
10762
  return __awaiter(this, void 0, void 0, function () {
10086
10763
  return __generator(this, function (_a) {
10087
- // TODO: !!! Do here some filtering which models are really available as deployment
10764
+ // TODO: [main] !!! Do here some filtering which models are really available as deployment
10088
10765
  // @see https://management.azure.com/subscriptions/subscriptionId/resourceGroups/resourceGroupName/providers/Microsoft.CognitiveServices/accounts/accountName/deployments?api-version=2023-05-01
10089
10766
  return [2 /*return*/, OPENAI_MODELS.map(function (_a) {
10090
10767
  var modelTitle = _a.modelTitle, modelName = _a.modelName, modelVariant = _a.modelVariant;
@@ -10570,7 +11247,7 @@ var OpenAiExecutionTools = /** @class */ (function () {
10570
11247
  resultContent = rawResponse.choices[0].message.content;
10571
11248
  // eslint-disable-next-line prefer-const
10572
11249
  complete = getCurrentIsoDate();
10573
- usage = computeOpenAiUsage(content, resultContent || '', rawResponse);
11250
+ usage = computeOpenAiUsage(content || '', resultContent || '', rawResponse);
10574
11251
  if (resultContent === null) {
10575
11252
  throw new PipelineExecutionError('No response message from OpenAI');
10576
11253
  }
@@ -10642,7 +11319,7 @@ var OpenAiExecutionTools = /** @class */ (function () {
10642
11319
  resultContent = rawResponse.choices[0].text;
10643
11320
  // eslint-disable-next-line prefer-const
10644
11321
  complete = getCurrentIsoDate();
10645
- usage = computeOpenAiUsage(content, resultContent || '', rawResponse);
11322
+ usage = computeOpenAiUsage(content || '', resultContent || '', rawResponse);
10646
11323
  return [2 /*return*/, $asDeeplyFrozenSerializableJson('OpenAiExecutionTools CompletionPromptResult', {
10647
11324
  content: resultContent,
10648
11325
  modelName: rawResponse.model || modelName,
@@ -10702,7 +11379,9 @@ var OpenAiExecutionTools = /** @class */ (function () {
10702
11379
  resultContent = rawResponse.data[0].embedding;
10703
11380
  // eslint-disable-next-line prefer-const
10704
11381
  complete = getCurrentIsoDate();
10705
- usage = computeOpenAiUsage(content, '', rawResponse);
11382
+ usage = computeOpenAiUsage(content || '', '',
11383
+ // <- Note: Embedding does not have result content
11384
+ rawResponse);
10706
11385
  return [2 /*return*/, $asDeeplyFrozenSerializableJson('OpenAiExecutionTools EmbeddingPromptResult', {
10707
11386
  content: resultContent,
10708
11387
  modelName: rawResponse.model || modelName,
@@ -10773,7 +11452,7 @@ var OpenAiExecutionTools = /** @class */ (function () {
10773
11452
  * @public exported from `@promptbook/openai`
10774
11453
  */
10775
11454
  var createOpenAiExecutionTools = Object.assign(function (options) {
10776
- // TODO: [🧠] !!!! If browser, auto add `dangerouslyAllowBrowser`
11455
+ // TODO: [🧠][main] !!!! If browser, auto add `dangerouslyAllowBrowser`
10777
11456
  if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {
10778
11457
  options = __assign(__assign({}, options), { dangerouslyAllowBrowser: true });
10779
11458
  }