@promptbook/core 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 +1025 -394
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/promptbook-collection/index.d.ts +0 -3
  5. package/esm/typings/src/_packages/core.index.d.ts +12 -0
  6. package/esm/typings/src/_packages/types.index.d.ts +6 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +4 -4
  8. package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
  9. package/esm/typings/src/collection/constructors/createCollectionFromUrl.d.ts +1 -1
  10. package/esm/typings/src/commands/FOREACH/ForeachCommand.d.ts +1 -1
  11. package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -5
  12. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +1 -2
  13. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  14. package/esm/typings/src/config.d.ts +11 -4
  15. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +1 -1
  16. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -3
  17. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +6 -5
  18. package/esm/typings/src/errors/AbstractFormatError.d.ts +11 -0
  19. package/esm/typings/src/execution/PipelineExecutor.d.ts +1 -0
  20. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +5 -6
  21. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTemplateResult.d.ts +24 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorSettings.d.ts +7 -0
  23. package/esm/typings/src/execution/createPipelineExecutor/00-createPipelineExecutor.d.ts +3 -0
  24. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +4 -1
  25. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +3 -0
  26. package/esm/typings/src/execution/createPipelineExecutor/{30-executeFormatCells.d.ts → 30-executeFormatSubvalues.d.ts} +2 -2
  27. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +2 -8
  28. package/esm/typings/src/execution/embeddingVectorToString.d.ts +1 -1
  29. package/esm/typings/src/execution/utils/checkExpectations.d.ts +2 -0
  30. package/esm/typings/src/execution/utils/usageToHuman.d.ts +3 -4
  31. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +14 -15
  32. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +31 -0
  33. package/esm/typings/src/formats/csv/{ListFormatDefinition.d.ts → CsvFormatDefinition.d.ts} +6 -3
  34. package/esm/typings/src/formats/csv/CsvFormatError.d.ts +10 -0
  35. package/esm/typings/src/formats/csv/CsvSettings.d.ts +13 -0
  36. package/esm/typings/src/formats/index.d.ts +1 -1
  37. package/esm/typings/src/formats/json/JsonFormatDefinition.d.ts +4 -3
  38. package/esm/typings/src/formats/text/TextFormatDefinition.d.ts +19 -0
  39. package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +4 -3
  40. package/esm/typings/src/knowledge/prepare-knowledge/markdown/prepareKnowledgeFromMarkdown.d.ts +1 -1
  41. package/esm/typings/src/knowledge/prepare-knowledge/pdf/prepareKnowledgeFromPdf.d.ts +1 -1
  42. package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +1 -1
  43. package/esm/typings/src/llm-providers/anthropic-claude/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 +1033 -397
  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/umd/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('prettier'), require('prettier/parser-html'), require('waitasecond'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('moment')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'prettier', 'prettier/parser-html', 'waitasecond', 'crypto-js/enc-hex', 'crypto-js/sha256', 'moment'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-core"] = {}, global.spaceTrim, global.prettier, global.parserHtml, global.waitasecond, global.hexEncoder, global.sha256, global.moment));
5
- })(this, (function (exports, spaceTrim, prettier, parserHtml, waitasecond, hexEncoder, sha256, moment) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('prettier'), require('prettier/parser-html'), require('waitasecond'), require('papaparse'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('moment')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'prettier', 'prettier/parser-html', 'waitasecond', 'papaparse', 'crypto-js/enc-hex', 'crypto-js/sha256', 'moment'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-core"] = {}, global.spaceTrim, global.prettier, global.parserHtml, global.waitasecond, global.papaparse, global.hexEncoder, global.sha256, global.moment));
5
+ })(this, (function (exports, spaceTrim, prettier, parserHtml, waitasecond, papaparse, hexEncoder, sha256, moment) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -16,8 +16,8 @@
16
16
  /**
17
17
  * The version of the Promptbook library
18
18
  */
19
- var PROMPTBOOK_VERSION = '0.69.0-7';
20
- // TODO: !!!! List here all the versions and annotate + put into script
19
+ var PROMPTBOOK_VERSION = '0.69.0-21';
20
+ // TODO: [main] !!!! List here all the versions and annotate + put into script
21
21
 
22
22
  /*! *****************************************************************************
23
23
  Copyright (c) Microsoft Corporation.
@@ -229,7 +229,7 @@
229
229
  commands.push("PIPELINE URL ".concat(pipelineUrl));
230
230
  }
231
231
  commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
232
- // TODO: !!! This increase size of the bundle and is probbably not necessary
232
+ // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
233
233
  pipelineString = prettifyMarkdown(pipelineString);
234
234
  try {
235
235
  for (var _g = __values(parameters.filter(function (_a) {
@@ -377,12 +377,12 @@
377
377
  pipelineString += '```' + contentLanguage;
378
378
  pipelineString += '\n';
379
379
  pipelineString += spaceTrim__default["default"](content);
380
- // <- TODO: !!! Escape
380
+ // <- TODO: [main] !!! Escape
381
381
  // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
382
382
  pipelineString += '\n';
383
383
  pipelineString += '```';
384
384
  pipelineString += '\n\n';
385
- pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: !!! If the parameter here has description, add it and use templateParameterJsonToString
385
+ pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use templateParameterJsonToString
386
386
  }
387
387
  }
388
388
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -602,7 +602,7 @@
602
602
  }
603
603
  /**
604
604
  * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
605
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
605
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
606
606
  * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
607
607
  */
608
608
 
@@ -673,14 +673,14 @@
673
673
  var MAX_FILENAME_LENGTH = 30;
674
674
  /**
675
675
  * @@@
676
- * TODO: [🐝] !!! Use
676
+ * TODO: [🐝][main] !!! Use
677
677
  *
678
678
  * @public exported from `@promptbook/core`
679
679
  */
680
680
  var MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH = 3;
681
681
  /**
682
682
  * @@@
683
- * TODO: [🐝] !!! Use
683
+ * TODO: [🐝][main] !!! Use
684
684
  *
685
685
  * @public exported from `@promptbook/core`
686
686
  */
@@ -753,6 +753,17 @@
753
753
  */
754
754
  var DEFAULT_REMOTE_URL_PATH = '/promptbook/socket.io';
755
755
  // <- TODO: [🧜‍♂️]
756
+ /**
757
+ * @@@
758
+ *
759
+ * @public exported from `@promptbook/core`
760
+ */
761
+ var DEFAULT_CSV_SETTINGS = Object.freeze({
762
+ delimiter: ',',
763
+ quoteChar: '"',
764
+ newline: '\n',
765
+ skipEmptyLines: true,
766
+ });
756
767
  /**
757
768
  * @@@
758
769
  *
@@ -845,7 +856,7 @@
845
856
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
846
857
  return false;
847
858
  }
848
- // <- TODO: !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
859
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
849
860
  return true;
850
861
  }
851
862
 
@@ -1014,7 +1025,7 @@
1014
1025
  // <- Note: [🚲]
1015
1026
  throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1016
1027
  }
1017
- if (!isValidPromptbookVersion(pipeline.promptbookVersion)) {
1028
+ if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1018
1029
  // <- Note: [🚲]
1019
1030
  throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1020
1031
  }
@@ -1197,6 +1208,7 @@
1197
1208
  }
1198
1209
  }
1199
1210
  /**
1211
+ * TODO: !!!!! [🧞‍♀️] Do not allow joker + foreach
1200
1212
  * TODO: [🧠] Work with promptbookVersion
1201
1213
  * TODO: Use here some json-schema, Zod or something similar and change it to:
1202
1214
  * > /**
@@ -1208,11 +1220,11 @@
1208
1220
  * > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
1209
1221
  */
1210
1222
  /**
1211
- * TODO: [🐣] !!!! Validate that all samples match expectations
1212
- * TODO: [🐣][🐝] !!!! Validate that knowledge is valid (non-void)
1213
- * TODO: [🐣] !!!! Validate that persona can be used only with CHAT variant
1214
- * TODO: [🐣] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1215
- * TODO: [🐣] !!!! Validate that reserved parameter is not used as joker
1223
+ * TODO: [🐣][main] !!!! Validate that all samples match expectations
1224
+ * TODO: [🐣][🐝][main] !!!! Validate that knowledge is valid (non-void)
1225
+ * TODO: [🐣][main] !!!! Validate that persona can be used only with CHAT variant
1226
+ * TODO: [🐣][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1227
+ * TODO: [🐣][main] !!!! Validate that reserved parameter is not used as joker
1216
1228
  * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
1217
1229
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
1218
1230
  */
@@ -1526,7 +1538,7 @@
1526
1538
  });
1527
1539
  }
1528
1540
  /**
1529
- * TODO: !!!! [🧠] Library precompilation and do not mix markdown and json promptbooks
1541
+ * TODO: [main] !!!! [🧠] Library precompilation and do not mix markdown and json promptbooks
1530
1542
  */
1531
1543
 
1532
1544
  /**
@@ -1823,7 +1835,7 @@
1823
1835
  });
1824
1836
  }
1825
1837
 
1826
- 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"}];
1838
+ 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"}];
1827
1839
 
1828
1840
  var defaultDiacriticsRemovalMap = [
1829
1841
  {
@@ -2374,7 +2386,7 @@
2374
2386
  return true;
2375
2387
  }
2376
2388
  /**
2377
- * TODO: [🔃] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2389
+ * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2378
2390
  * TODO: [🐠] Maybe base this on `makeValidator`
2379
2391
  * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2380
2392
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
@@ -2426,9 +2438,10 @@
2426
2438
  });
2427
2439
  Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2428
2440
  get: function () {
2429
- return this.llmExecutionTools
2430
- .map(function (tools, index) { return "".concat(index + 1, ") ").concat(tools.title, " ").concat(tools.description || ''); })
2431
- .join('\n');
2441
+ return this.llmExecutionTools.map(function (_a, index) {
2442
+ var title = _a.title;
2443
+ return "".concat(index + 1, ") `").concat(title, "`");
2444
+ }).join('\n');
2432
2445
  },
2433
2446
  enumerable: false,
2434
2447
  configurable: true
@@ -2626,9 +2639,7 @@
2626
2639
  throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
2627
2640
  }
2628
2641
  else {
2629
- throw new PipelineExecutionError(spaceTrim__default["default"](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
2630
- .map(function (tools) { return "- ".concat(tools.title, " ").concat(tools.description || ''); })
2631
- .join('\n')), "\n\n "); }));
2642
+ throw new PipelineExecutionError(spaceTrim__default["default"](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 "); }));
2632
2643
  }
2633
2644
  }
2634
2645
  });
@@ -2770,47 +2781,47 @@
2770
2781
  * @public exported from `@promptbook/utils`
2771
2782
  */
2772
2783
  function extractParameterNamesFromTemplate(template) {
2773
- var e_1, _a, e_2, _b, e_3, _c;
2784
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
2774
2785
  var title = template.title, description = template.description, templateType = template.templateType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames, foreach = template.foreach;
2775
2786
  var parameterNames = new Set();
2776
2787
  try {
2777
- 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()) {
2778
- var parameterName = _e.value;
2788
+ 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()) {
2789
+ var parameterName = _f.value;
2779
2790
  parameterNames.add(parameterName);
2780
2791
  }
2781
2792
  }
2782
2793
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2783
2794
  finally {
2784
2795
  try {
2785
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2796
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
2786
2797
  }
2787
2798
  finally { if (e_1) throw e_1.error; }
2788
2799
  }
2789
2800
  if (templateType === 'SCRIPT_TEMPLATE') {
2790
2801
  try {
2791
- for (var _f = __values(extractVariables(content)), _g = _f.next(); !_g.done; _g = _f.next()) {
2792
- var parameterName = _g.value;
2802
+ for (var _g = __values(extractVariables(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
2803
+ var parameterName = _h.value;
2793
2804
  parameterNames.add(parameterName);
2794
2805
  }
2795
2806
  }
2796
2807
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
2797
2808
  finally {
2798
2809
  try {
2799
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2810
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
2800
2811
  }
2801
2812
  finally { if (e_2) throw e_2.error; }
2802
2813
  }
2803
2814
  }
2804
2815
  try {
2805
- for (var _h = __values(jokerParameterNames || []), _j = _h.next(); !_j.done; _j = _h.next()) {
2806
- var jokerName = _j.value;
2816
+ for (var _j = __values(jokerParameterNames || []), _k = _j.next(); !_k.done; _k = _j.next()) {
2817
+ var jokerName = _k.value;
2807
2818
  parameterNames.add(jokerName);
2808
2819
  }
2809
2820
  }
2810
2821
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
2811
2822
  finally {
2812
2823
  try {
2813
- if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
2824
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
2814
2825
  }
2815
2826
  finally { if (e_3) throw e_3.error; }
2816
2827
  }
@@ -2818,10 +2829,22 @@
2818
2829
  // <- Note {websiteContent} is used in `preparedContent`
2819
2830
  // Note: [🍭] Fixing dependent subparameterName from FOREACH command
2820
2831
  if (foreach !== undefined) {
2821
- if (parameterNames.has(foreach.subparameterName)) {
2822
- parameterNames.delete(foreach.subparameterName);
2823
- parameterNames.add(foreach.parameterName);
2824
- // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2832
+ try {
2833
+ for (var _l = __values(foreach.inputSubparameterNames), _m = _l.next(); !_m.done; _m = _l.next()) {
2834
+ var subparameterName = _m.value;
2835
+ if (parameterNames.has(subparameterName)) {
2836
+ parameterNames.delete(subparameterName);
2837
+ parameterNames.add(foreach.parameterName);
2838
+ // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2839
+ }
2840
+ }
2841
+ }
2842
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2843
+ finally {
2844
+ try {
2845
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
2846
+ }
2847
+ finally { if (e_4) throw e_4.error; }
2825
2848
  }
2826
2849
  }
2827
2850
  return parameterNames;
@@ -2905,6 +2928,183 @@
2905
2928
  return union;
2906
2929
  }
2907
2930
 
2931
+ /**
2932
+ * Just marks a place of place where should be something implemented
2933
+ * No side effects.
2934
+ *
2935
+ * Note: It can be usefull suppressing eslint errors of unused variables
2936
+ *
2937
+ * @param value any values
2938
+ * @returns void
2939
+ * @private within the repository
2940
+ */
2941
+ function TODO_USE() {
2942
+ var value = [];
2943
+ for (var _i = 0; _i < arguments.length; _i++) {
2944
+ value[_i] = arguments[_i];
2945
+ }
2946
+ }
2947
+
2948
+ /**
2949
+ * This error indicates problems parsing the format value
2950
+ *
2951
+ * For example, when the format value is not a valid JSON or CSV
2952
+ * This is not thrown directly but in extended classes
2953
+ *
2954
+ * @public exported from `@promptbook/core`
2955
+ */
2956
+ var AbstractFormatError = /** @class */ (function (_super) {
2957
+ __extends(AbstractFormatError, _super);
2958
+ // Note: To allow instanceof do not put here error `name`
2959
+ // public readonly name = 'AbstractFormatError';
2960
+ function AbstractFormatError(message) {
2961
+ var _this = _super.call(this, message) || this;
2962
+ Object.setPrototypeOf(_this, AbstractFormatError.prototype);
2963
+ return _this;
2964
+ }
2965
+ return AbstractFormatError;
2966
+ }(Error));
2967
+
2968
+ /**
2969
+ * This error indicates problem with parsing of CSV
2970
+ *
2971
+ * @public exported from `@promptbook/core`
2972
+ */
2973
+ var CsvFormatError = /** @class */ (function (_super) {
2974
+ __extends(CsvFormatError, _super);
2975
+ function CsvFormatError(message) {
2976
+ var _this = _super.call(this, message) || this;
2977
+ _this.name = 'CsvFormatError';
2978
+ Object.setPrototypeOf(_this, CsvFormatError.prototype);
2979
+ return _this;
2980
+ }
2981
+ return CsvFormatError;
2982
+ }(AbstractFormatError));
2983
+
2984
+ /**
2985
+ * @@@
2986
+ *
2987
+ * @public exported from `@promptbook/core`
2988
+ */
2989
+ var MANDATORY_CSV_SETTINGS = Object.freeze({
2990
+ header: true,
2991
+ // encoding: 'utf8',
2992
+ });
2993
+
2994
+ /**
2995
+ * Definition for CSV spreadsheet
2996
+ *
2997
+ * @public exported from `@promptbook/core`
2998
+ * <- TODO: [🏢] Export from package `@promptbook/csv`
2999
+ */
3000
+ var CsvFormatDefinition = {
3001
+ formatName: 'CSV',
3002
+ aliases: ['SPREADSHEET', 'TABLE'],
3003
+ isValid: function (value, settings, schema) {
3004
+ // TODO: Implement CSV validation
3005
+ TODO_USE(value /* <- TODO: Use value here */);
3006
+ TODO_USE(settings /* <- TODO: Use settings here */);
3007
+ TODO_USE(schema /* <- TODO: Use schema here */);
3008
+ return true;
3009
+ },
3010
+ canBeValid: function (partialValue, settings, schema) {
3011
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3012
+ TODO_USE(settings /* <- TODO: Use settings here */);
3013
+ TODO_USE(schema /* <- TODO: Use schema here */);
3014
+ return true;
3015
+ },
3016
+ heal: function (value, settings, schema) {
3017
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3018
+ TODO_USE(settings /* <- TODO: Use settings here */);
3019
+ TODO_USE(schema /* <- TODO: Use schema here */);
3020
+ throw new Error('Not implemented');
3021
+ },
3022
+ subvalueDefinitions: [
3023
+ {
3024
+ subvalueName: 'ROW',
3025
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3026
+ return __awaiter(this, void 0, void 0, function () {
3027
+ var csv, mappedData;
3028
+ var _this = this;
3029
+ return __generator(this, function (_a) {
3030
+ switch (_a.label) {
3031
+ case 0:
3032
+ csv = papaparse.parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
3033
+ if (csv.errors.length !== 0) {
3034
+ throw new CsvFormatError(spaceTrim__default["default"](function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
3035
+ }
3036
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, index) { return __awaiter(_this, void 0, void 0, function () {
3037
+ var _a, _b;
3038
+ var _c;
3039
+ return __generator(this, function (_d) {
3040
+ switch (_d.label) {
3041
+ case 0:
3042
+ if (row[outputParameterName]) {
3043
+ throw new CsvFormatError("Can not overwrite existing column \"".concat(outputParameterName, "\" in CSV row"));
3044
+ }
3045
+ _a = [__assign({}, row)];
3046
+ _c = {};
3047
+ _b = outputParameterName;
3048
+ return [4 /*yield*/, mapCallback(row, index)];
3049
+ case 1: return [2 /*return*/, __assign.apply(void 0, _a.concat([(_c[_b] = _d.sent(), _c)]))];
3050
+ }
3051
+ });
3052
+ }); }))];
3053
+ case 1:
3054
+ mappedData = _a.sent();
3055
+ return [2 /*return*/, papaparse.unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
3056
+ }
3057
+ });
3058
+ });
3059
+ },
3060
+ },
3061
+ {
3062
+ subvalueName: 'CELL',
3063
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3064
+ return __awaiter(this, void 0, void 0, function () {
3065
+ var csv, mappedData;
3066
+ var _this = this;
3067
+ return __generator(this, function (_a) {
3068
+ switch (_a.label) {
3069
+ case 0:
3070
+ csv = papaparse.parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
3071
+ if (csv.errors.length !== 0) {
3072
+ throw new CsvFormatError(spaceTrim__default["default"](function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
3073
+ }
3074
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, rowIndex) { return __awaiter(_this, void 0, void 0, function () {
3075
+ var _this = this;
3076
+ return __generator(this, function (_a) {
3077
+ return [2 /*return*/, /* not await */ Promise.all(Object.entries(row).map(function (_a, columnIndex) {
3078
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
3079
+ return __awaiter(_this, void 0, void 0, function () {
3080
+ var index;
3081
+ var _c;
3082
+ return __generator(this, function (_d) {
3083
+ index = rowIndex * Object.keys(row).length + columnIndex;
3084
+ return [2 /*return*/, /* not await */ mapCallback((_c = {}, _c[key] = value, _c), index)];
3085
+ });
3086
+ });
3087
+ }))];
3088
+ });
3089
+ }); }))];
3090
+ case 1:
3091
+ mappedData = _a.sent();
3092
+ return [2 /*return*/, papaparse.unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
3093
+ }
3094
+ });
3095
+ });
3096
+ },
3097
+ },
3098
+ ],
3099
+ };
3100
+ /**
3101
+ * TODO: [🍓] In `CsvFormatDefinition` implement simple `isValid`
3102
+ * TODO: [🍓] In `CsvFormatDefinition` implement partial `canBeValid`
3103
+ * TODO: [🍓] In `CsvFormatDefinition` implement `heal
3104
+ * TODO: [🍓] In `CsvFormatDefinition` implement `subvalueDefinitions`
3105
+ * TODO: [🏢] Allow to expect something inside CSV objects and other formats
3106
+ */
3107
+
2908
3108
  /**
2909
3109
  * Function isValidJsonString will tell you if the string is valid JSON or not
2910
3110
  *
@@ -2926,6 +3126,222 @@
2926
3126
  }
2927
3127
  }
2928
3128
 
3129
+ /**
3130
+ * Definition for JSON format
3131
+ *
3132
+ * @private still in development [🏢]
3133
+ */
3134
+ var JsonFormatDefinition = {
3135
+ formatName: 'JSON',
3136
+ mimeType: 'application/json',
3137
+ isValid: function (value, settings, schema) {
3138
+ TODO_USE(schema /* <- TODO: Use schema here */);
3139
+ TODO_USE(settings /* <- TODO: Use settings here */);
3140
+ return isValidJsonString(value);
3141
+ },
3142
+ canBeValid: function (partialValue, settings, schema) {
3143
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3144
+ TODO_USE(settings /* <- TODO: Use settings here */);
3145
+ TODO_USE(schema /* <- TODO: Use schema here */);
3146
+ return true;
3147
+ },
3148
+ heal: function (value, settings, schema) {
3149
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3150
+ TODO_USE(settings /* <- TODO: Use settings here */);
3151
+ TODO_USE(schema /* <- TODO: Use schema here */);
3152
+ throw new Error('Not implemented');
3153
+ },
3154
+ subvalueDefinitions: [],
3155
+ };
3156
+ /**
3157
+ * TODO: [🧠] Maybe propper instance of object
3158
+ * TODO: [0] Make string_serialized_json
3159
+ * TODO: [1] Make type for JSON Settings and Schema
3160
+ * TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
3161
+ * TODO: [🍓] In `JsonFormatDefinition` implement simple `isValid`
3162
+ * TODO: [🍓] In `JsonFormatDefinition` implement partial `canBeValid`
3163
+ * TODO: [🍓] In `JsonFormatDefinition` implement `heal
3164
+ * TODO: [🍓] In `JsonFormatDefinition` implement `subvalueDefinitions`
3165
+ * TODO: [🏢] Allow to expect something inside JSON objects and other formats
3166
+ */
3167
+
3168
+ /**
3169
+ * Definition for any text - this will be always valid
3170
+ *
3171
+ * Note: This is not useful for validation, but for splitting and mapping with `subvalueDefinitions`
3172
+ *
3173
+ * @public exported from `@promptbook/core`
3174
+ */
3175
+ var TextFormatDefinition = {
3176
+ formatName: 'TEXT',
3177
+ isValid: function (value) {
3178
+ return typeof value === 'string';
3179
+ },
3180
+ canBeValid: function (partialValue) {
3181
+ return typeof partialValue === 'string';
3182
+ },
3183
+ heal: function () {
3184
+ throw new UnexpectedError('It does not make sense to call `TextFormatDefinition.heal`');
3185
+ },
3186
+ subvalueDefinitions: [
3187
+ {
3188
+ subvalueName: 'LINE',
3189
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
3190
+ return __awaiter(this, void 0, void 0, function () {
3191
+ var lines, mappedLines;
3192
+ return __generator(this, function (_a) {
3193
+ switch (_a.label) {
3194
+ case 0:
3195
+ lines = value.split('\n');
3196
+ return [4 /*yield*/, Promise.all(lines.map(function (lineContent, lineNumber) {
3197
+ // TODO: [🧠] Maybe option to skip empty line
3198
+ /* not await */ return mapCallback({
3199
+ lineContent: lineContent,
3200
+ // TODO: [🧠] Maybe also put here `lineNumber`
3201
+ }, lineNumber);
3202
+ }))];
3203
+ case 1:
3204
+ mappedLines = _a.sent();
3205
+ return [2 /*return*/, mappedLines.join('\n')];
3206
+ }
3207
+ });
3208
+ });
3209
+ },
3210
+ },
3211
+ // <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3212
+ ],
3213
+ };
3214
+ /**
3215
+ * TODO: [1] Make type for XML Text and Schema
3216
+ * TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3217
+ * TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
3218
+ * TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
3219
+ * TODO: [🍓] In `TextFormatDefinition` implement `heal
3220
+ * TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
3221
+ * TODO: [🏢] Allow to expect something inside each item of list and other formats
3222
+ */
3223
+
3224
+ /**
3225
+ * Definition for XML format
3226
+ *
3227
+ * @private still in development [🏢]
3228
+ */
3229
+ var XmlFormatDefinition = {
3230
+ formatName: 'XML',
3231
+ mimeType: 'application/xml',
3232
+ isValid: function (value, settings, schema) {
3233
+ TODO_USE(value /* <- TODO: Use value here */);
3234
+ TODO_USE(settings /* <- TODO: Use settings here */);
3235
+ TODO_USE(schema /* <- TODO: Use schema here */);
3236
+ return true;
3237
+ },
3238
+ canBeValid: function (partialValue, settings, schema) {
3239
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3240
+ TODO_USE(settings /* <- TODO: Use settings here */);
3241
+ TODO_USE(schema /* <- TODO: Use schema here */);
3242
+ return true;
3243
+ },
3244
+ heal: function (value, settings, schema) {
3245
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3246
+ TODO_USE(settings /* <- TODO: Use settings here */);
3247
+ TODO_USE(schema /* <- TODO: Use schema here */);
3248
+ throw new Error('Not implemented');
3249
+ },
3250
+ subvalueDefinitions: [],
3251
+ };
3252
+ /**
3253
+ * TODO: [🧠] Maybe propper instance of object
3254
+ * TODO: [0] Make string_serialized_xml
3255
+ * TODO: [1] Make type for XML Settings and Schema
3256
+ * TODO: [🧠] What to use for validating XMLs - XSD,...
3257
+ * TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
3258
+ * TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
3259
+ * TODO: [🍓] In `XmlFormatDefinition` implement `heal
3260
+ * TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
3261
+ * TODO: [🏢] Allow to expect something inside XML and other formats
3262
+ */
3263
+
3264
+ /**
3265
+ * Definitions for all formats supported by Promptbook
3266
+ *
3267
+ * @private internal index of `...` <- TODO [🏢]
3268
+ */
3269
+ var FORMAT_DEFINITIONS = [
3270
+ JsonFormatDefinition,
3271
+ XmlFormatDefinition,
3272
+ TextFormatDefinition,
3273
+ CsvFormatDefinition,
3274
+ ];
3275
+
3276
+ /**
3277
+ * Maps available parameters to expected parameters
3278
+ *
3279
+ * The strategy is:
3280
+ * 1) @@@
3281
+ * 2) @@@
3282
+ *
3283
+ * @throws {PipelineExecutionError} @@@
3284
+ * @private within the repository used in `createPipelineExecutor`
3285
+ */
3286
+ function mapAvailableToExpectedParameters(options) {
3287
+ var e_1, _a;
3288
+ var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
3289
+ var availableParametersNames = new Set(Object.keys(availableParameters));
3290
+ var expectedParameterNames = new Set(Object.keys(expectedParameters));
3291
+ var mappedParameters = {};
3292
+ try {
3293
+ // Phase 1️⃣: Matching mapping
3294
+ for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
3295
+ var parameterName = _c.value;
3296
+ // Situation: Parameter is available and expected
3297
+ if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3298
+ mappedParameters[parameterName] = availableParameters[parameterName];
3299
+ // <- Note: [👩‍👩‍👧] Maybe detect parameter collision here?
3300
+ availableParametersNames.delete(parameterName);
3301
+ expectedParameterNames.delete(parameterName);
3302
+ }
3303
+ // Situation: Parameter is available but NOT expected
3304
+ else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
3305
+ // [🐱‍👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
3306
+ }
3307
+ // Situation: Parameter is NOT available BUT expected
3308
+ else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3309
+ // Do nothing here - this will be maybe fixed in the non-matching mapping
3310
+ }
3311
+ }
3312
+ }
3313
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3314
+ finally {
3315
+ try {
3316
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3317
+ }
3318
+ finally { if (e_1) throw e_1.error; }
3319
+ }
3320
+ if (expectedParameterNames.size === 0) {
3321
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3322
+ Object.freeze(mappedParameters);
3323
+ return mappedParameters;
3324
+ }
3325
+ // Phase 2️⃣: Non-matching mapping
3326
+ if (expectedParameterNames.size !== availableParametersNames.size) {
3327
+ throw new PipelineExecutionError(spaceTrim__default["default"](function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
3328
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3329
+ .join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
3330
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3331
+ .join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
3332
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3333
+ .join('\n')), "\n\n "); }));
3334
+ }
3335
+ var expectedParameterNamesArray = Array.from(expectedParameterNames);
3336
+ var availableParametersNamesArray = Array.from(availableParametersNames);
3337
+ for (var i = 0; i < expectedParameterNames.size; i++) {
3338
+ mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
3339
+ }
3340
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3341
+ Object.freeze(mappedParameters);
3342
+ return mappedParameters;
3343
+ }
3344
+
2929
3345
  /**
2930
3346
  * Extracts all code blocks from markdown.
2931
3347
  *
@@ -3231,6 +3647,9 @@
3231
3647
  LINES: countLines,
3232
3648
  PAGES: countPages,
3233
3649
  };
3650
+ /**
3651
+ * TODO: [🧠][🤠] This should be probbably as part of `TextFormatDefinition`
3652
+ */
3234
3653
 
3235
3654
  /**
3236
3655
  * Function checkExpectations will check if the expectations on given value are met
@@ -3289,6 +3708,8 @@
3289
3708
  }
3290
3709
  /**
3291
3710
  * TODO: [💝] Unite object for expecting amount and format
3711
+ * TODO: [🧠][🤠] This should be part of `TextFormatDefinition`
3712
+ * Note: [💝] and [🤠] are interconnected together
3292
3713
  */
3293
3714
 
3294
3715
  /**
@@ -3298,58 +3719,66 @@
3298
3719
  */
3299
3720
  function executeAttempts(options) {
3300
3721
  return __awaiter(this, void 0, void 0, function () {
3301
- var $ongoingTemplateResult, jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, _loop_1, attempt, state_1;
3722
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3302
3723
  return __generator(this, function (_a) {
3303
3724
  switch (_a.label) {
3304
3725
  case 0:
3305
- $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;
3726
+ 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;
3306
3727
  maxExecutionAttempts = settings.maxExecutionAttempts;
3728
+ $ongoingTemplateResult = {
3729
+ $result: null,
3730
+ $resultString: null,
3731
+ $expectError: null,
3732
+ $scriptPipelineExecutionErrors: [],
3733
+ };
3307
3734
  _loop_1 = function (attempt) {
3308
- 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;
3309
- var e_1, _r, e_3, _s, e_2, _t;
3310
- return __generator(this, function (_u) {
3311
- switch (_u.label) {
3735
+ 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;
3736
+ var e_1, _q, e_3, _r, e_2, _s;
3737
+ return __generator(this, function (_t) {
3738
+ switch (_t.label) {
3312
3739
  case 0:
3313
3740
  isJokerAttempt = attempt < 0;
3314
3741
  jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3315
- // TODO: [🧠] !!!!!! JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3742
+ // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3316
3743
  if (isJokerAttempt && !jokerParameterName) {
3317
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3744
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3318
3745
  }
3319
3746
  $ongoingTemplateResult.$result = null;
3320
3747
  $ongoingTemplateResult.$resultString = null;
3321
3748
  $ongoingTemplateResult.$expectError = null;
3322
3749
  if (isJokerAttempt) {
3323
3750
  if (parameters[jokerParameterName] === undefined) {
3324
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3751
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3325
3752
  // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3326
3753
  }
3327
3754
  else {
3328
3755
  $ongoingTemplateResult.$resultString = parameters[jokerParameterName];
3329
3756
  }
3330
3757
  }
3331
- _u.label = 1;
3758
+ _t.label = 1;
3332
3759
  case 1:
3333
- _u.trys.push([1, 44, 45, 46]);
3334
- if (!!isJokerAttempt) return [3 /*break*/, 26];
3760
+ _t.trys.push([1, 43, 44, 45]);
3761
+ if (!!isJokerAttempt) return [3 /*break*/, 25];
3335
3762
  _b = template.templateType;
3336
3763
  switch (_b) {
3337
3764
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3338
3765
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3339
- case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3340
- case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3766
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 11];
3767
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 22];
3341
3768
  }
3342
- return [3 /*break*/, 25];
3769
+ return [3 /*break*/, 24];
3343
3770
  case 2:
3344
3771
  $ongoingTemplateResult.$resultString = replaceParameters(preparedContent, parameters);
3345
- return [3 /*break*/, 26];
3772
+ return [3 /*break*/, 25];
3346
3773
  case 3:
3347
3774
  modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (template.modelRequirements || {}));
3348
3775
  $ongoingTemplateResult.$prompt = {
3349
3776
  title: template.title,
3350
3777
  pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3351
3778
  ? preparedPipeline.pipelineUrl
3352
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name),
3779
+ : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name
3780
+ // <- TODO: Here should be maybe also subformat index to distinguish between same template with different subformat values
3781
+ ),
3353
3782
  parameters: parameters,
3354
3783
  content: preparedContent,
3355
3784
  modelRequirements: modelRequirements,
@@ -3367,67 +3796,57 @@
3367
3796
  case 'COMPLETION': return [3 /*break*/, 6];
3368
3797
  case 'EMBEDDING': return [3 /*break*/, 8];
3369
3798
  }
3370
- return [3 /*break*/, 10];
3799
+ return [3 /*break*/, 9];
3371
3800
  case 4:
3372
3801
  _d = $ongoingTemplateResult;
3373
3802
  return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3374
3803
  case 5:
3375
- _d.$chatResult = _u.sent();
3804
+ _d.$chatResult = _t.sent();
3376
3805
  // TODO: [🍬] Destroy chatThread
3377
3806
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$chatResult;
3378
3807
  $ongoingTemplateResult.$resultString = $ongoingTemplateResult.$chatResult.content;
3379
- return [3 /*break*/, 11];
3808
+ return [3 /*break*/, 10];
3380
3809
  case 6:
3381
3810
  _e = $ongoingTemplateResult;
3382
3811
  return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3383
3812
  case 7:
3384
- _e.$completionResult = _u.sent();
3813
+ _e.$completionResult = _t.sent();
3385
3814
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
3386
3815
  $ongoingTemplateResult.$resultString =
3387
3816
  $ongoingTemplateResult.$completionResult.content;
3388
- return [3 /*break*/, 11];
3389
- case 8:
3390
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3391
- _f = $ongoingTemplateResult;
3392
- return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze($ongoingTemplateResult.$prompt))];
3393
- case 9:
3394
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3395
- _f.$embeddingResult = _u.sent();
3396
- $ongoingTemplateResult.$result = $ongoingTemplateResult.$embeddingResult;
3397
- $ongoingTemplateResult.$resultString =
3398
- $ongoingTemplateResult.$embeddingResult.content.join(',');
3399
- return [3 /*break*/, 11];
3400
- case 10: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3401
- case 11: return [3 /*break*/, 26];
3402
- case 12:
3817
+ return [3 /*break*/, 10];
3818
+ case 8: throw new PipelineExecutionError(spaceTrim.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 "); }));
3819
+ case 9: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3820
+ case 10: return [3 /*break*/, 25];
3821
+ case 11:
3403
3822
  if (arrayableToArray(tools.script).length === 0) {
3404
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3823
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3405
3824
  }
3406
3825
  if (!template.contentLanguage) {
3407
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3826
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3408
3827
  }
3409
- _u.label = 13;
3828
+ _t.label = 12;
3829
+ case 12:
3830
+ _t.trys.push([12, 19, 20, 21]);
3831
+ _f = (e_1 = void 0, __values(arrayableToArray(tools.script))), _g = _f.next();
3832
+ _t.label = 13;
3410
3833
  case 13:
3411
- _u.trys.push([13, 20, 21, 22]);
3412
- _g = (e_1 = void 0, __values(arrayableToArray(tools.script))), _h = _g.next();
3413
- _u.label = 14;
3834
+ if (!!_g.done) return [3 /*break*/, 18];
3835
+ scriptTools = _g.value;
3836
+ _t.label = 14;
3414
3837
  case 14:
3415
- if (!!_h.done) return [3 /*break*/, 19];
3416
- scriptTools = _h.value;
3417
- _u.label = 15;
3418
- case 15:
3419
- _u.trys.push([15, 17, , 18]);
3420
- _j = $ongoingTemplateResult;
3838
+ _t.trys.push([14, 16, , 17]);
3839
+ _h = $ongoingTemplateResult;
3421
3840
  return [4 /*yield*/, scriptTools.execute($deepFreeze({
3422
3841
  scriptLanguage: template.contentLanguage,
3423
3842
  script: preparedContent,
3424
3843
  parameters: parameters,
3425
3844
  }))];
3845
+ case 15:
3846
+ _h.$resultString = _t.sent();
3847
+ return [3 /*break*/, 18];
3426
3848
  case 16:
3427
- _j.$resultString = _u.sent();
3428
- return [3 /*break*/, 19];
3429
- case 17:
3430
- error_1 = _u.sent();
3849
+ error_1 = _t.sent();
3431
3850
  if (!(error_1 instanceof Error)) {
3432
3851
  throw error_1;
3433
3852
  }
@@ -3435,39 +3854,39 @@
3435
3854
  throw error_1;
3436
3855
  }
3437
3856
  $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_1);
3438
- return [3 /*break*/, 18];
3439
- case 18:
3440
- _h = _g.next();
3441
- return [3 /*break*/, 14];
3442
- case 19: return [3 /*break*/, 22];
3443
- case 20:
3444
- e_1_1 = _u.sent();
3857
+ return [3 /*break*/, 17];
3858
+ case 17:
3859
+ _g = _f.next();
3860
+ return [3 /*break*/, 13];
3861
+ case 18: return [3 /*break*/, 21];
3862
+ case 19:
3863
+ e_1_1 = _t.sent();
3445
3864
  e_1 = { error: e_1_1 };
3446
- return [3 /*break*/, 22];
3447
- case 21:
3865
+ return [3 /*break*/, 21];
3866
+ case 20:
3448
3867
  try {
3449
- if (_h && !_h.done && (_r = _g.return)) _r.call(_g);
3868
+ if (_g && !_g.done && (_q = _f.return)) _q.call(_f);
3450
3869
  }
3451
3870
  finally { if (e_1) throw e_1.error; }
3452
3871
  return [7 /*endfinally*/];
3453
- case 22:
3872
+ case 21:
3454
3873
  if ($ongoingTemplateResult.$resultString !== null) {
3455
- return [3 /*break*/, 26];
3874
+ return [3 /*break*/, 25];
3456
3875
  }
3457
3876
  if ($ongoingTemplateResult.$scriptPipelineExecutionErrors.length === 1) {
3458
3877
  throw $ongoingTemplateResult.$scriptPipelineExecutionErrors[0];
3459
3878
  }
3460
3879
  else {
3461
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3880
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3462
3881
  .map(function (error) { return '- ' + error.message; })
3463
- .join('\n\n')), "\n "); }));
3882
+ .join('\n\n')), "\n "); }));
3464
3883
  }
3465
- case 23:
3884
+ case 22:
3466
3885
  if (tools.userInterface === undefined) {
3467
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3886
+ throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3468
3887
  }
3469
3888
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3470
- _k = $ongoingTemplateResult;
3889
+ _j = $ongoingTemplateResult;
3471
3890
  return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3472
3891
  promptTitle: template.title,
3473
3892
  promptMessage: replaceParameters(template.description || '', parameters),
@@ -3476,34 +3895,34 @@
3476
3895
  placeholder: undefined,
3477
3896
  priority: priority,
3478
3897
  }))];
3479
- case 24:
3898
+ case 23:
3480
3899
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3481
- _k.$resultString = _u.sent();
3482
- return [3 /*break*/, 26];
3483
- case 25: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3900
+ _j.$resultString = _t.sent();
3901
+ return [3 /*break*/, 25];
3902
+ case 24: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3903
+ case 25:
3904
+ if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 42];
3905
+ _t.label = 26;
3484
3906
  case 26:
3485
- if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 43];
3486
- _u.label = 27;
3907
+ _t.trys.push([26, 40, 41, 42]);
3908
+ _k = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _l = _k.next();
3909
+ _t.label = 27;
3487
3910
  case 27:
3488
- _u.trys.push([27, 41, 42, 43]);
3489
- _l = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _m = _l.next();
3490
- _u.label = 28;
3491
- case 28:
3492
- if (!!_m.done) return [3 /*break*/, 40];
3493
- functionName = _m.value;
3911
+ if (!!_l.done) return [3 /*break*/, 39];
3912
+ functionName = _l.value;
3494
3913
  postprocessingError = null;
3495
- _u.label = 29;
3914
+ _t.label = 28;
3915
+ case 28:
3916
+ _t.trys.push([28, 35, 36, 37]);
3917
+ _m = (e_2 = void 0, __values(arrayableToArray(tools.script))), _o = _m.next();
3918
+ _t.label = 29;
3496
3919
  case 29:
3497
- _u.trys.push([29, 36, 37, 38]);
3498
- _o = (e_2 = void 0, __values(arrayableToArray(tools.script))), _p = _o.next();
3499
- _u.label = 30;
3920
+ if (!!_o.done) return [3 /*break*/, 34];
3921
+ scriptTools = _o.value;
3922
+ _t.label = 30;
3500
3923
  case 30:
3501
- if (!!_p.done) return [3 /*break*/, 35];
3502
- scriptTools = _p.value;
3503
- _u.label = 31;
3504
- case 31:
3505
- _u.trys.push([31, 33, , 34]);
3506
- _q = $ongoingTemplateResult;
3924
+ _t.trys.push([30, 32, , 33]);
3925
+ _p = $ongoingTemplateResult;
3507
3926
  return [4 /*yield*/, scriptTools.execute({
3508
3927
  scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3509
3928
  script: "".concat(functionName, "(resultString)"),
@@ -3512,12 +3931,12 @@
3512
3931
  // Note: No ...parametersForTemplate, because working with result only
3513
3932
  },
3514
3933
  })];
3515
- case 32:
3516
- _q.$resultString = _u.sent();
3934
+ case 31:
3935
+ _p.$resultString = _t.sent();
3517
3936
  postprocessingError = null;
3518
- return [3 /*break*/, 35];
3519
- case 33:
3520
- error_2 = _u.sent();
3937
+ return [3 /*break*/, 34];
3938
+ case 32:
3939
+ error_2 = _t.sent();
3521
3940
  if (!(error_2 instanceof Error)) {
3522
3941
  throw error_2;
3523
3942
  }
@@ -3526,41 +3945,41 @@
3526
3945
  }
3527
3946
  postprocessingError = error_2;
3528
3947
  $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_2);
3529
- return [3 /*break*/, 34];
3530
- case 34:
3531
- _p = _o.next();
3532
- return [3 /*break*/, 30];
3533
- case 35: return [3 /*break*/, 38];
3534
- case 36:
3535
- e_2_1 = _u.sent();
3948
+ return [3 /*break*/, 33];
3949
+ case 33:
3950
+ _o = _m.next();
3951
+ return [3 /*break*/, 29];
3952
+ case 34: return [3 /*break*/, 37];
3953
+ case 35:
3954
+ e_2_1 = _t.sent();
3536
3955
  e_2 = { error: e_2_1 };
3537
- return [3 /*break*/, 38];
3538
- case 37:
3956
+ return [3 /*break*/, 37];
3957
+ case 36:
3539
3958
  try {
3540
- if (_p && !_p.done && (_t = _o.return)) _t.call(_o);
3959
+ if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3541
3960
  }
3542
3961
  finally { if (e_2) throw e_2.error; }
3543
3962
  return [7 /*endfinally*/];
3544
- case 38:
3963
+ case 37:
3545
3964
  if (postprocessingError) {
3546
3965
  throw postprocessingError;
3547
3966
  }
3548
- _u.label = 39;
3549
- case 39:
3550
- _m = _l.next();
3551
- return [3 /*break*/, 28];
3552
- case 40: return [3 /*break*/, 43];
3553
- case 41:
3554
- e_3_1 = _u.sent();
3967
+ _t.label = 38;
3968
+ case 38:
3969
+ _l = _k.next();
3970
+ return [3 /*break*/, 27];
3971
+ case 39: return [3 /*break*/, 42];
3972
+ case 40:
3973
+ e_3_1 = _t.sent();
3555
3974
  e_3 = { error: e_3_1 };
3556
- return [3 /*break*/, 43];
3557
- case 42:
3975
+ return [3 /*break*/, 42];
3976
+ case 41:
3558
3977
  try {
3559
- if (_m && !_m.done && (_s = _l.return)) _s.call(_l);
3978
+ if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3560
3979
  }
3561
3980
  finally { if (e_3) throw e_3.error; }
3562
3981
  return [7 /*endfinally*/];
3563
- case 43:
3982
+ case 42:
3564
3983
  // TODO: [💝] Unite object for expecting amount and format
3565
3984
  if (template.format) {
3566
3985
  if (template.format === 'JSON') {
@@ -3571,13 +3990,13 @@
3571
3990
  }
3572
3991
  catch (error) {
3573
3992
  keepUnused(error);
3574
- throw new ExpectError(spaceTrim.spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3575
- /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3993
+ throw new ExpectError(spaceTrim.spaceTrim(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3994
+ /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3576
3995
  }
3577
3996
  }
3578
3997
  }
3579
3998
  else {
3580
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3999
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3581
4000
  }
3582
4001
  }
3583
4002
  // TODO: [💝] Unite object for expecting amount and format
@@ -3585,14 +4004,14 @@
3585
4004
  checkExpectations(template.expectations, $ongoingTemplateResult.$resultString || '');
3586
4005
  }
3587
4006
  return [2 /*return*/, "break-attempts"];
3588
- case 44:
3589
- error_3 = _u.sent();
4007
+ case 43:
4008
+ error_3 = _t.sent();
3590
4009
  if (!(error_3 instanceof ExpectError)) {
3591
4010
  throw error_3;
3592
4011
  }
3593
4012
  $ongoingTemplateResult.$expectError = error_3;
3594
- return [3 /*break*/, 46];
3595
- case 45:
4013
+ return [3 /*break*/, 45];
4014
+ case 44:
3596
4015
  if (!isJokerAttempt &&
3597
4016
  template.templateType === 'PROMPT_TEMPLATE' &&
3598
4017
  $ongoingTemplateResult.$prompt
@@ -3609,22 +4028,22 @@
3609
4028
  });
3610
4029
  }
3611
4030
  return [7 /*endfinally*/];
3612
- case 46:
4031
+ case 45:
3613
4032
  if ($ongoingTemplateResult.$expectError !== null && attempt === maxAttempts - 1) {
3614
4033
  throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) {
3615
4034
  var _a, _b, _c;
3616
- 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) || '')
4035
+ 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) || '')
3617
4036
  .split('\n')
3618
4037
  .map(function (line) { return "> ".concat(line); })
3619
- .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) || '')
4038
+ .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) || '')
3620
4039
  .split('\n')
3621
4040
  .map(function (line) { return "> ".concat(line); })
3622
- .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
4041
+ .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
3623
4042
  ? 'null'
3624
4043
  : $ongoingTemplateResult.$resultString
3625
4044
  .split('\n')
3626
4045
  .map(function (line) { return "> ".concat(line); })
3627
- .join('\n')), "\n ---\n ");
4046
+ .join('\n')), "\n ---\n ");
3628
4047
  }));
3629
4048
  }
3630
4049
  return [2 /*return*/];
@@ -3645,7 +4064,11 @@
3645
4064
  case 3:
3646
4065
  attempt++;
3647
4066
  return [3 /*break*/, 1];
3648
- case 4: return [2 /*return*/];
4067
+ case 4:
4068
+ if ($ongoingTemplateResult.$resultString === null) {
4069
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
4070
+ }
4071
+ return [2 /*return*/, $ongoingTemplateResult.$resultString];
3649
4072
  }
3650
4073
  });
3651
4074
  });
@@ -3659,36 +4082,83 @@
3659
4082
  *
3660
4083
  * @private internal utility of `createPipelineExecutor`
3661
4084
  */
3662
- function executeFormatCells(options) {
4085
+ function executeFormatSubvalues(options) {
3663
4086
  return __awaiter(this, void 0, void 0, function () {
3664
- var template;
4087
+ var template, jokerParameterNames, parameters, priority, pipelineIdentification, settings, parameterValue, formatDefinition, subvalueDefinition, formatSettings, resultString;
4088
+ var _this = this;
3665
4089
  return __generator(this, function (_a) {
3666
- template = options.template;
3667
- if (template.foreach === undefined) {
3668
- return [2 /*return*/, /* not await */ executeAttempts(options)];
4090
+ switch (_a.label) {
4091
+ case 0:
4092
+ template = options.template, jokerParameterNames = options.jokerParameterNames, parameters = options.parameters, priority = options.priority, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
4093
+ if (template.foreach === undefined) {
4094
+ return [2 /*return*/, /* not await */ executeAttempts(options)];
4095
+ }
4096
+ if (jokerParameterNames.length !== 0) {
4097
+ throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
4098
+ }
4099
+ parameterValue = parameters[template.foreach.parameterName] || '';
4100
+ formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
4101
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(template.foreach.formatName);
4102
+ });
4103
+ if (formatDefinition === undefined) {
4104
+ throw new UnexpectedError(
4105
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4106
+ spaceTrim__default["default"](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; })
4107
+ .map(function (formatName) { return "- ".concat(formatName); })
4108
+ .join('\n')), "\n\n [\u26F7] This should never happen because format name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
4109
+ }
4110
+ subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
4111
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(template.foreach.subformatName);
4112
+ });
4113
+ if (subvalueDefinition === undefined) {
4114
+ throw new UnexpectedError(
4115
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4116
+ spaceTrim__default["default"](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
4117
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
4118
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
4119
+ .join('\n')), "\n\n [\u26F7] This should never happen because subformat name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
4120
+ }
4121
+ if (formatDefinition.formatName === 'CSV') {
4122
+ formatSettings = settings.csvSettings;
4123
+ // <- TODO: [🤹‍♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
4124
+ }
4125
+ return [4 /*yield*/, subvalueDefinition.mapValues(parameterValue, template.foreach.outputSubparameterName, formatSettings, function (subparameters, index) { return __awaiter(_this, void 0, void 0, function () {
4126
+ var mappedParameters, allSubparameters, subresultString;
4127
+ return __generator(this, function (_a) {
4128
+ switch (_a.label) {
4129
+ case 0:
4130
+ // TODO: [🤹‍♂️][🪂] Limit to N concurrent executions
4131
+ // TODO: When done [🐚] Report progress also for each subvalue here
4132
+ try {
4133
+ mappedParameters = mapAvailableToExpectedParameters({
4134
+ expectedParameters: Object.fromEntries(template.foreach.inputSubparameterNames.map(function (subparameterName) { return [subparameterName, null]; })),
4135
+ availableParameters: subparameters,
4136
+ });
4137
+ }
4138
+ catch (error) {
4139
+ if (!(error instanceof PipelineExecutionError)) {
4140
+ throw error;
4141
+ }
4142
+ throw new PipelineExecutionError(spaceTrim__default["default"](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 "); }));
4143
+ }
4144
+ allSubparameters = __assign(__assign({}, parameters), mappedParameters);
4145
+ // 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
4146
+ Object.freeze(allSubparameters);
4147
+ return [4 /*yield*/, executeAttempts(__assign(__assign({}, options), { priority: priority + index, parameters: allSubparameters, pipelineIdentification: spaceTrim__default["default"](function (block) { return "\n ".concat(block(pipelineIdentification), "\n Subparameter index: ").concat(index, "\n "); }) }))];
4148
+ case 1:
4149
+ subresultString = _a.sent();
4150
+ return [2 /*return*/, subresultString];
4151
+ }
4152
+ });
4153
+ }); })];
4154
+ case 1:
4155
+ resultString = _a.sent();
4156
+ return [2 /*return*/, resultString];
3669
4157
  }
3670
- throw new NotYetImplementedError('FOREACH execution not implemented yet');
3671
4158
  });
3672
4159
  });
3673
4160
  }
3674
4161
 
3675
- /**
3676
- * Just marks a place of place where should be something implemented
3677
- * No side effects.
3678
- *
3679
- * Note: It can be usefull suppressing eslint errors of unused variables
3680
- *
3681
- * @param value any values
3682
- * @returns void
3683
- * @private within the repository
3684
- */
3685
- function TODO_USE() {
3686
- var value = [];
3687
- for (var _i = 0; _i < arguments.length; _i++) {
3688
- value[_i] = arguments[_i];
3689
- }
3690
- }
3691
-
3692
4162
  /**
3693
4163
  * @@@
3694
4164
  *
@@ -3802,7 +4272,7 @@
3802
4272
  */
3803
4273
  function executeTemplate(options) {
3804
4274
  return __awaiter(this, void 0, void 0, function () {
3805
- 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;
4275
+ 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;
3806
4276
  var e_1, _f, _g;
3807
4277
  return __generator(this, function (_h) {
3808
4278
  switch (_h.label) {
@@ -3826,12 +4296,13 @@
3826
4296
  _h.sent();
3827
4297
  usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3828
4298
  dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
4299
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3829
4300
  if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3830
- throw new UnexpectedError(spaceTrim.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)
4301
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n Dependent parameters:\n ".concat(Array.from(dependentParameterNames)
3831
4302
  .map(function (name) { return "{".concat(name, "}"); })
3832
4303
  .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3833
4304
  .map(function (name) { return "{".concat(name, "}"); })
3834
- .join(', '), "\n\n "); }));
4305
+ .join(', '), "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3835
4306
  }
3836
4307
  _b = (_a = Object).freeze;
3837
4308
  _c = [{}];
@@ -3860,6 +4331,7 @@
3860
4331
  };
3861
4332
  try {
3862
4333
  // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
4334
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3863
4335
  for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3864
4336
  parameterName = _e.value;
3865
4337
  _loop_1(parameterName);
@@ -3872,22 +4344,14 @@
3872
4344
  }
3873
4345
  finally { if (e_1) throw e_1.error; }
3874
4346
  }
3875
- // 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
4347
+ // 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
3876
4348
  Object.freeze(parameters);
3877
- $ongoingTemplateResult = {
3878
- $result: null,
3879
- $resultString: null,
3880
- $expectError: null,
3881
- $scriptPipelineExecutionErrors: [],
3882
- };
3883
4349
  maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3884
4350
  jokerParameterNames = currentTemplate.jokerParameterNames || [];
3885
4351
  preparedContent = (currentTemplate.preparedContent || '{content}')
3886
4352
  .split('{content}')
3887
4353
  .join(currentTemplate.content);
3888
- // <- TODO: [🍵] Use here `replaceParameters` to replace {websiteContent} with option to ignore missing parameters
3889
- return [4 /*yield*/, executeFormatCells({
3890
- $ongoingTemplateResult: $ongoingTemplateResult,
4354
+ return [4 /*yield*/, executeFormatSubvalues({
3891
4355
  jokerParameterNames: jokerParameterNames,
3892
4356
  priority: priority,
3893
4357
  maxAttempts: maxAttempts,
@@ -3902,11 +4366,7 @@
3902
4366
  pipelineIdentification: pipelineIdentification,
3903
4367
  })];
3904
4368
  case 3:
3905
- // <- TODO: [🍵] Use here `replaceParameters` to replace {websiteContent} with option to ignore missing parameters
3906
- _h.sent();
3907
- if ($ongoingTemplateResult.$resultString === null) {
3908
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3909
- }
4369
+ resultString = _h.sent();
3910
4370
  return [4 /*yield*/, onProgress({
3911
4371
  name: name,
3912
4372
  title: title,
@@ -3914,13 +4374,15 @@
3914
4374
  isDone: true,
3915
4375
  templateType: currentTemplate.templateType,
3916
4376
  parameterName: currentTemplate.resultingParameterName,
3917
- parameterValue: $ongoingTemplateResult.$resultString,
4377
+ parameterValue: resultString,
3918
4378
  // <- [🍸]
3919
4379
  })];
3920
4380
  case 4:
3921
4381
  _h.sent();
3922
4382
  return [2 /*return*/, Object.freeze((_g = {},
3923
- _g[currentTemplate.resultingParameterName] = $ongoingTemplateResult.$resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */,
4383
+ _g[currentTemplate.resultingParameterName] =
4384
+ // <- Note: [👩‍👩‍👧] No need to detect parameter collision here because pipeline checks logic consistency during construction
4385
+ resultString,
3924
4386
  _g))];
3925
4387
  }
3926
4388
  });
@@ -3929,6 +4391,9 @@
3929
4391
  /**
3930
4392
  * TODO: [🤹‍♂️]
3931
4393
  */
4394
+ /**
4395
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4396
+ */
3932
4397
 
3933
4398
  /**
3934
4399
  * @@@
@@ -3949,6 +4414,7 @@
3949
4414
  };
3950
4415
  try {
3951
4416
  // Note: Filter ONLY output parameters
4417
+ // TODO: [👩🏾‍🤝‍👩🏻] Maybe use here `mapAvailableToExpectedParameters`
3952
4418
  for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
3953
4419
  var isOutput = _a.isOutput;
3954
4420
  return isOutput;
@@ -4063,7 +4529,7 @@
4063
4529
  return name === parameterName;
4064
4530
  });
4065
4531
  if (!(parameter === undefined)) return [3 /*break*/, 1];
4066
- warnings.push(new PipelineExecutionError(spaceTrim.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 "); })));
4532
+ warnings.push(new PipelineExecutionError(spaceTrim.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 "); })));
4067
4533
  return [3 /*break*/, 4];
4068
4534
  case 1:
4069
4535
  if (!(parameter.isInput === false)) return [3 /*break*/, 4];
@@ -4075,10 +4541,10 @@
4075
4541
  // Note: Wait a short time to prevent race conditions
4076
4542
  _h.sent();
4077
4543
  _h.label = 3;
4078
- case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim.spaceTrim(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4544
+ case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim.spaceTrim(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4079
4545
  isSuccessful: false,
4080
4546
  errors: __spreadArray([
4081
- new PipelineExecutionError(spaceTrim.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 "); }))
4547
+ new PipelineExecutionError(spaceTrim.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 "); }))
4082
4548
  ], __read(errors), false).map(serializeError),
4083
4549
  warnings: warnings.map(serializeError),
4084
4550
  executionReport: executionReport,
@@ -4142,7 +4608,7 @@
4142
4608
  case 0:
4143
4609
  if (loopLimit-- < 0) {
4144
4610
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
4145
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4611
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4146
4612
  }
4147
4613
  currentTemplate = unresovedTemplates_1.find(function (template) {
4148
4614
  return template.dependentParameterNames.every(function (name) {
@@ -4152,14 +4618,14 @@
4152
4618
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
4153
4619
  throw new UnexpectedError(
4154
4620
  // TODO: [🐎] DRY
4155
- spaceTrim.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
4621
+ spaceTrim.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
4156
4622
  .map(function (_a) {
4157
4623
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
4158
4624
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
4159
4625
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
4160
4626
  .join(' and '));
4161
4627
  })
4162
- .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 "); }));
4628
+ .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 "); }));
4163
4629
  case 1:
4164
4630
  if (!!currentTemplate) return [3 /*break*/, 3];
4165
4631
  /* [🤹‍♂️] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -4176,10 +4642,10 @@
4176
4642
  llmTools: llmTools,
4177
4643
  onProgress: function (progress) {
4178
4644
  if (isReturned) {
4179
- throw new UnexpectedError(spaceTrim.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)
4645
+ throw new UnexpectedError(spaceTrim.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)
4180
4646
  .split('\n')
4181
4647
  .map(function (line) { return "> ".concat(line); })
4182
- .join('\n')), "\n "); }));
4648
+ .join('\n')), "\n "); }));
4183
4649
  }
4184
4650
  if (onProgress) {
4185
4651
  onProgress(progress);
@@ -4187,7 +4653,7 @@
4187
4653
  },
4188
4654
  settings: settings,
4189
4655
  $executionReport: executionReport,
4190
- pipelineIdentification: pipelineIdentification,
4656
+ pipelineIdentification: spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Template name: ").concat(currentTemplate.name, "\n Template title: ").concat(currentTemplate.title, "\n "); }),
4191
4657
  })
4192
4658
  .then(function (newParametersToPass) {
4193
4659
  parametersToPass = __assign(__assign({}, newParametersToPass), parametersToPass);
@@ -4279,6 +4745,9 @@
4279
4745
  });
4280
4746
  });
4281
4747
  }
4748
+ /**
4749
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4750
+ */
4282
4751
 
4283
4752
  /**
4284
4753
  * Creates executor function from pipeline and execution tools.
@@ -4290,7 +4759,7 @@
4290
4759
  function createPipelineExecutor(options) {
4291
4760
  var _this = this;
4292
4761
  var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
4293
- 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;
4762
+ 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;
4294
4763
  validatePipeline(pipeline);
4295
4764
  var pipelineIdentification = (function () {
4296
4765
  // Note: This is a 😐 implementation of [🚞]
@@ -4310,9 +4779,11 @@
4310
4779
  else if (isNotPreparedWarningSupressed !== true) {
4311
4780
  console.warn(spaceTrim.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 "); }));
4312
4781
  }
4782
+ var runCount = 0;
4313
4783
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
4314
4784
  return __generator(this, function (_a) {
4315
- return [2 /*return*/, executePipeline({
4785
+ runCount++;
4786
+ return [2 /*return*/, /* not await */ executePipeline({
4316
4787
  pipeline: pipeline,
4317
4788
  preparedPipeline: preparedPipeline,
4318
4789
  setPreparedPipeline: function (newPreparedPipeline) {
@@ -4321,10 +4792,11 @@
4321
4792
  inputParameters: inputParameters,
4322
4793
  tools: tools,
4323
4794
  onProgress: onProgress,
4324
- pipelineIdentification: pipelineIdentification,
4795
+ pipelineIdentification: spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n ").concat(runCount === 1 ? '' : "Run #".concat(runCount), "\n "); }),
4325
4796
  settings: {
4326
4797
  maxExecutionAttempts: maxExecutionAttempts,
4327
4798
  maxParallelCount: maxParallelCount,
4799
+ csvSettings: csvSettings,
4328
4800
  isVerbose: isVerbose,
4329
4801
  isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
4330
4802
  },
@@ -4333,6 +4805,9 @@
4333
4805
  }); };
4334
4806
  return pipelineExecutor;
4335
4807
  }
4808
+ /**
4809
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4810
+ */
4336
4811
 
4337
4812
  /**
4338
4813
  * @@@
@@ -4384,7 +4859,7 @@
4384
4859
  outputParameters = result.outputParameters;
4385
4860
  knowledgePiecesRaw = outputParameters.knowledgePieces;
4386
4861
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
4387
- // <- TODO: !!!!! Smarter split and filter out empty pieces
4862
+ // <- TODO: [main] !!!!! Smarter split and filter out empty pieces
4388
4863
  if (isVerbose) {
4389
4864
  console.info('knowledgeTextPieces:', knowledgeTextPieces);
4390
4865
  }
@@ -4442,8 +4917,13 @@
4442
4917
  case 6: return [3 /*break*/, 8];
4443
4918
  case 7:
4444
4919
  error_1 = _c.sent();
4920
+ // Note: Here is expected error:
4921
+ // > PipelineExecutionError: You have not provided any `LlmExecutionTools` that support model variant "EMBEDDING
4922
+ if (!(error_1 instanceof PipelineExecutionError)) {
4923
+ throw error_1;
4924
+ }
4445
4925
  // TODO: [🟥] Detect browser / node and make it colorfull
4446
- console.error(error_1);
4926
+ console.error(error_1, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
4447
4927
  return [3 /*break*/, 8];
4448
4928
  case 8: return [2 /*return*/, {
4449
4929
  name: name,
@@ -4464,7 +4944,7 @@
4464
4944
  });
4465
4945
  }
4466
4946
  /**
4467
- * TODO: [🐝][🔼] !!! Export via `@promptbook/markdown`
4947
+ * TODO: [🐝][🔼][main] !!! Export via `@promptbook/markdown`
4468
4948
  * TODO: [🪂] Do it in parallel 11:11
4469
4949
  * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4470
4950
  */
@@ -4488,7 +4968,7 @@
4488
4968
  var partialPieces, pieces;
4489
4969
  return __generator(this, function (_a) {
4490
4970
  switch (_a.label) {
4491
- case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4971
+ case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝][main] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4492
4972
  options)];
4493
4973
  case 1:
4494
4974
  partialPieces = _a.sent();
@@ -4680,7 +5160,7 @@
4680
5160
  });
4681
5161
  }
4682
5162
  /**
4683
- * TODO: [🔃] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
5163
+ * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4684
5164
  * TODO: [🏢] !! Check validity of `modelName` in pipeline
4685
5165
  * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4686
5166
  * TODO: [🏢] !! Check validity of `temperature` in pipeline
@@ -4729,7 +5209,7 @@
4729
5209
  case 0:
4730
5210
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
4731
5211
  templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4732
- // TODO: !!!!! Apply samples to each template (if missing and is for the template defined)
5212
+ // TODO: [main] !!!!! Apply samples to each template (if missing and is for the template defined)
4733
5213
  TODO_USE(parameters);
4734
5214
  templatesPrepared = new Array(
4735
5215
  // <- TODO: [🧱] Implement in a functional (not new Class) way
@@ -4761,7 +5241,7 @@
4761
5241
  /**
4762
5242
  * TODO: [🧠] Add context to each template (if missing)
4763
5243
  * TODO: [🧠] What is better name `prepareTemplate` or `prepareTemplateAndParameters`
4764
- * TODO: [♨] !!! Prepare index the samples and maybe templates
5244
+ * TODO: [♨][main] !!! Prepare index the samples and maybe templates
4765
5245
  * TODO: Write tests for `preparePipeline`
4766
5246
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4767
5247
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
@@ -4933,7 +5413,7 @@
4933
5413
  if (sourceContent === '') {
4934
5414
  throw new ParseError("Source is not defined");
4935
5415
  }
4936
- // TODO: !!!! Following checks should be applied every link in the `sourceContent`
5416
+ // TODO: [main] !!!! Following checks should be applied every link in the `sourceContent`
4937
5417
  if (sourceContent.startsWith('http://')) {
4938
5418
  throw new ParseError("Source is not secure");
4939
5419
  }
@@ -5118,7 +5598,7 @@
5118
5598
  if (command.templateType === 'KNOWLEDGE') {
5119
5599
  knowledgeCommandParser.$applyToPipelineJson({
5120
5600
  type: 'KNOWLEDGE',
5121
- sourceContent: $templateJson.content, // <- TODO: [🐝] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
5601
+ sourceContent: $templateJson.content, // <- TODO: [🐝][main] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
5122
5602
  }, $pipelineJson);
5123
5603
  $templateJson.isTemplate = false;
5124
5604
  return;
@@ -5468,6 +5948,171 @@
5468
5948
  * TODO: [🌺] Use some intermediate util splitWords
5469
5949
  */
5470
5950
 
5951
+ /**
5952
+ * @@@
5953
+ *
5954
+ * @param text @@@
5955
+ * @param _isFirstLetterCapital @@@
5956
+ * @returns @@@
5957
+ * @example 'helloWorld'
5958
+ * @example 'iLovePromptbook'
5959
+ * @public exported from `@promptbook/utils`
5960
+ */
5961
+ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
5962
+ var e_1, _a;
5963
+ if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
5964
+ var charType;
5965
+ var lastCharType = null;
5966
+ var normalizedName = '';
5967
+ try {
5968
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5969
+ var char = text_1_1.value;
5970
+ var normalizedChar = void 0;
5971
+ if (/^[a-z]$/.test(char)) {
5972
+ charType = 'LOWERCASE';
5973
+ normalizedChar = char;
5974
+ }
5975
+ else if (/^[A-Z]$/.test(char)) {
5976
+ charType = 'UPPERCASE';
5977
+ normalizedChar = char.toLowerCase();
5978
+ }
5979
+ else if (/^[0-9]$/.test(char)) {
5980
+ charType = 'NUMBER';
5981
+ normalizedChar = char;
5982
+ }
5983
+ else {
5984
+ charType = 'OTHER';
5985
+ normalizedChar = '';
5986
+ }
5987
+ if (!lastCharType) {
5988
+ if (_isFirstLetterCapital) {
5989
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
5990
+ }
5991
+ }
5992
+ else if (charType !== lastCharType &&
5993
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
5994
+ !(lastCharType === 'NUMBER') &&
5995
+ !(charType === 'NUMBER')) {
5996
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
5997
+ }
5998
+ normalizedName += normalizedChar;
5999
+ lastCharType = charType;
6000
+ }
6001
+ }
6002
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6003
+ finally {
6004
+ try {
6005
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
6006
+ }
6007
+ finally { if (e_1) throw e_1.error; }
6008
+ }
6009
+ return normalizedName;
6010
+ }
6011
+ /**
6012
+ * TODO: [🌺] Use some intermediate util splitWords
6013
+ */
6014
+
6015
+ /**
6016
+ * Removes quotes from a string
6017
+ *
6018
+ * Tip: This is very usefull for post-processing of the result of the LLM model
6019
+ * Note: This function removes only the same quotes from the beginning and the end of the string
6020
+ * Note: There are two simmilar functions:
6021
+ * - `removeQuotes` which removes only bounding quotes
6022
+ * - `unwrapResult` which removes whole introduce sentence
6023
+ *
6024
+ * @param text optionally quoted text
6025
+ * @returns text without quotes
6026
+ * @public exported from `@promptbook/utils`
6027
+ */
6028
+ function removeQuotes(text) {
6029
+ if (text.startsWith('"') && text.endsWith('"')) {
6030
+ return text.slice(1, -1);
6031
+ }
6032
+ if (text.startsWith('\'') && text.endsWith('\'')) {
6033
+ return text.slice(1, -1);
6034
+ }
6035
+ return text;
6036
+ }
6037
+
6038
+ /**
6039
+ * Function `validateParameterName` will @@@
6040
+ *
6041
+ * @param parameterName @@@
6042
+ * @returns @@@
6043
+ * @throws {ParseError} @@@
6044
+ * @private within the repository
6045
+ */
6046
+ function validateParameterName(parameterName) {
6047
+ var e_1, _a;
6048
+ var rawParameterName = parameterName;
6049
+ try {
6050
+ for (var _b = __values([
6051
+ ['`', '`'],
6052
+ ['{', '}'],
6053
+ ['[', ']'],
6054
+ ['(', ')'],
6055
+ ['<', '>'],
6056
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
6057
+ var _d = __read(_c.value, 2), start = _d[0], end = _d[1];
6058
+ if (parameterName.substring(0, 1) === start &&
6059
+ parameterName.substring(parameterName.length - 1, parameterName.length) === end
6060
+ // <- TODO: More universal that 1 character
6061
+ ) {
6062
+ parameterName = parameterName.substring(1, parameterName.length - 1);
6063
+ // <- TODO: More universal that 1 character
6064
+ }
6065
+ }
6066
+ }
6067
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6068
+ finally {
6069
+ try {
6070
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
6071
+ }
6072
+ finally { if (e_1) throw e_1.error; }
6073
+ }
6074
+ // TODO: [🐠] Following try-catch block should be part of common validators logic
6075
+ try {
6076
+ /*
6077
+ Note: We don't need to check for spaces because we are going to normalize the parameter name to camelCase
6078
+ if (parameterName.includes(' ')) {
6079
+ throw new ParseError(`Parameter name cannot contain spaces`);
6080
+ }
6081
+ */
6082
+ if (parameterName.includes('.')) {
6083
+ throw new ParseError("Parameter name cannot contain dots");
6084
+ }
6085
+ if (parameterName.includes('/') || parameterName.includes('\\')) {
6086
+ throw new ParseError("Parameter name cannot contain slashes");
6087
+ }
6088
+ if (parameterName.includes('(') ||
6089
+ parameterName.includes(')') ||
6090
+ parameterName.includes('{') ||
6091
+ parameterName.includes('}') ||
6092
+ parameterName.includes('[') ||
6093
+ parameterName.includes(']')) {
6094
+ throw new ParseError("Parameter name cannot contain braces");
6095
+ }
6096
+ parameterName = removeDiacritics(parameterName);
6097
+ parameterName = removeEmojis(parameterName);
6098
+ parameterName = removeQuotes(parameterName);
6099
+ parameterName = normalizeTo_camelCase(parameterName);
6100
+ if (parameterName === '') {
6101
+ throw new ParseError("Parameter name cannot be empty");
6102
+ }
6103
+ if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
6104
+ throw new ParseError("{".concat(parameterName, "} is a reserved parameter name"));
6105
+ }
6106
+ }
6107
+ catch (error) {
6108
+ if (!(error instanceof ParseError)) {
6109
+ throw error;
6110
+ }
6111
+ throw new ParseError(spaceTrim__default["default"](function (block) { return "\n ".concat(block(error.message), "\n\n Tried to validate parameter name:\n ").concat(block(rawParameterName), "\n "); }));
6112
+ }
6113
+ return parameterName;
6114
+ }
6115
+
5471
6116
  /**
5472
6117
  * Parses the foreach command
5473
6118
  *
@@ -5497,15 +6142,16 @@
5497
6142
  /**
5498
6143
  * Link to discussion
5499
6144
  */
5500
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
6145
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/148',
5501
6146
  /**
5502
6147
  * Example usages of the FOREACH command
5503
6148
  */
5504
6149
  examples: [
5505
- 'FOREACH List Line `{customers}` -> `{customer}`',
5506
- 'FOR List Line `{customers}` -> `{customer}`',
5507
- 'EACH List Line `{customers}` -> `{customer}`',
5508
- // <- TODO: [🍭] !!!!!! More
6150
+ 'FOREACH Text Line `{customers}` -> `{customer}`',
6151
+ 'FOREACH Csv Cell `{customers}` -> `{cell}`',
6152
+ 'FOREACH Csv Row `{customers}` -> `{firstName}`, `{lastName}`, `+{email}`',
6153
+ 'FOR Text Line `{customers}` -> `{customer}`',
6154
+ 'EACH Text Line `{customers}` -> `{customer}`',
5509
6155
  ],
5510
6156
  /**
5511
6157
  * Parses the FOREACH command
@@ -5513,55 +6159,75 @@
5513
6159
  parse: function (input) {
5514
6160
  var args = input.args;
5515
6161
  var formatName = normalizeTo_SCREAMING_CASE(args[0] || '');
5516
- var cellName = normalizeTo_SCREAMING_CASE(args[1] || '');
5517
- var parameterNameWrapped = args[2];
6162
+ var subformatName = normalizeTo_SCREAMING_CASE(args[1] || '');
6163
+ var parameterNameArg = args[2] || '';
5518
6164
  var assignSign = args[3];
5519
- var subparameterNameWrapped = args[4];
5520
- if (![
5521
- 'LIST',
5522
- 'CSV',
5523
- // <- TODO: [🏢] Unhardcode formats
5524
- ].includes(formatName)) {
5525
- console.info({ args: args, formatName: formatName });
5526
- throw new Error("Unsupported format \"".concat(formatName, "\""));
6165
+ var formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
6166
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(formatName);
6167
+ });
6168
+ if (formatDefinition === undefined) {
6169
+ throw new ParseError(spaceTrim__default["default"](function (block) { return "\n Unsupported format \"".concat(formatName, "\"\n\n Available formats:\n ").concat(block(FORMAT_DEFINITIONS.map(function (formatDefinition) { return formatDefinition.formatName; })
6170
+ .map(function (formatName) { return "- ".concat(formatName); })
6171
+ .join('\n')), "\n "); }));
5527
6172
  // <- TODO: [🏢] List all supported format names
5528
6173
  }
5529
- if (![
5530
- 'LINE',
5531
- 'ROW',
5532
- 'COLUMN',
5533
- 'CELL',
5534
- // <- TODO: [🏢] Unhardcode format cells
5535
- ].includes(cellName)) {
5536
- console.info({ args: args, cellName: cellName });
5537
- throw new Error("Format ".concat(formatName, " does not support cell \"").concat(cellName, "\""));
5538
- // <- TODO: [🏢] List all supported cell names for the format
6174
+ var subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
6175
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(subformatName);
6176
+ });
6177
+ if (subvalueDefinition === undefined) {
6178
+ throw new ParseError(spaceTrim__default["default"](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
6179
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
6180
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
6181
+ .join('\n')), "\n "); }));
6182
+ // <- TODO: [🏢] List all supported subformat names for the format
5539
6183
  }
5540
6184
  if (assignSign !== '->') {
5541
- console.info({ args: args, assignSign: assignSign });
5542
- throw new Error("FOREACH command must have '->' to assign the value to the parameter");
5543
- }
5544
- // TODO: !!!!!! Replace with propper parameter name validation
5545
- if ((parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(0, 1)) !== '{' ||
5546
- (parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(parameterNameWrapped.length - 1, parameterNameWrapped.length)) !== '}') {
5547
- 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));
5548
- throw new Error("!!!!!! 1 Here will be error (with rules and precise error) from validateParameterName");
5549
- }
5550
- var parameterName = parameterNameWrapped.substring(1, parameterNameWrapped.length - 1);
5551
- // TODO: !!!!!! Replace with propper parameter name validation
5552
- if ((subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(0, 1)) !== '{' ||
5553
- (subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(subparameterNameWrapped.length - 1, subparameterNameWrapped.length)) !==
5554
- '}') {
5555
- console.info({ args: args, subparameterNameWrapped: subparameterNameWrapped });
5556
- throw new Error("!!!!!! 2 Here will be error (with rules and precise error) from validateParameterName");
5557
- }
5558
- var subparameterName = subparameterNameWrapped.substring(1, subparameterNameWrapped.length - 1);
6185
+ throw new ParseError("FOREACH command must have '->' to assign the value to the parameter");
6186
+ }
6187
+ var parameterName = validateParameterName(parameterNameArg);
6188
+ var outputSubparameterName = null;
6189
+ // TODO: [4] DRY
6190
+ var inputSubparameterNames = args
6191
+ .slice(4)
6192
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6193
+ .filter(function (parameterName) { return !parameterName.includes('+'); })
6194
+ .filter(function (parameterName) { return parameterName !== ''; })
6195
+ .map(validateParameterName);
6196
+ // TODO: [4] DRY
6197
+ var outputSubparameterNames = args
6198
+ .slice(4)
6199
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6200
+ .filter(function (parameterName) { return parameterName.includes('+'); })
6201
+ .map(function (parameterName) { return parameterName.split('+').join(''); })
6202
+ .map(validateParameterName);
6203
+ if (outputSubparameterNames.length === 1) {
6204
+ outputSubparameterName = outputSubparameterNames[0];
6205
+ }
6206
+ else if (outputSubparameterNames.length > 1) {
6207
+ throw new ParseError("FOREACH command can not have more than one output subparameter");
6208
+ }
6209
+ if (inputSubparameterNames.length === 0) {
6210
+ throw new ParseError("FOREACH command must have at least one input subparameter");
6211
+ }
6212
+ if (outputSubparameterName === null) {
6213
+ // TODO: Following code should be unhardcoded from here and moved to the format definition
6214
+ if (formatName === 'CSV' && subformatName === 'CELL') {
6215
+ outputSubparameterName = 'newCell';
6216
+ }
6217
+ else if (formatName === 'TEXT' && subformatName === 'LINE') {
6218
+ outputSubparameterName = 'newLine';
6219
+ }
6220
+ else {
6221
+ throw new ParseError(spaceTrim__default["default"]("\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 ")));
6222
+ }
6223
+ }
5559
6224
  return {
5560
6225
  type: 'FOREACH',
5561
6226
  formatName: formatName,
5562
- cellName: cellName,
6227
+ subformatName: subformatName,
5563
6228
  parameterName: parameterName,
5564
- subparameterName: subparameterName,
6229
+ inputSubparameterNames: inputSubparameterNames,
6230
+ outputSubparameterName: outputSubparameterName,
5565
6231
  };
5566
6232
  },
5567
6233
  /**
@@ -5570,11 +6236,17 @@
5570
6236
  * Note: `$` is used to indicate that this function mutates given `templateJson`
5571
6237
  */
5572
6238
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5573
- var formatName = command.formatName, cellName = command.cellName, parameterName = command.parameterName, subparameterName = command.subparameterName;
5574
- // TODO: !!!!!! Detect double use
5575
- // TODO: !!!!!! Detect usage with JOKER and don't allow it
5576
- $templateJson.foreach = { formatName: formatName, cellName: cellName, parameterName: parameterName, subparameterName: subparameterName };
5577
- keepUnused($pipelineJson); // <- TODO: !!!!!! BUT Maybe register subparameter from foreach into parameters of the pipeline
6239
+ var formatName = command.formatName, subformatName = command.subformatName, parameterName = command.parameterName, inputSubparameterNames = command.inputSubparameterNames, outputSubparameterName = command.outputSubparameterName;
6240
+ // TODO: [🍭] Detect double use
6241
+ // TODO: [🍭] Detect usage with JOKER and don't allow it
6242
+ $templateJson.foreach = {
6243
+ formatName: formatName,
6244
+ subformatName: subformatName,
6245
+ parameterName: parameterName,
6246
+ inputSubparameterNames: inputSubparameterNames,
6247
+ outputSubparameterName: outputSubparameterName,
6248
+ };
6249
+ keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
5578
6250
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
5579
6251
  },
5580
6252
  /**
@@ -5597,8 +6269,7 @@
5597
6269
  },
5598
6270
  };
5599
6271
  /**
5600
- * TODO: !!!!!! Comment console logs
5601
- * TODO: [🍭] !!!!!! Make .ptbk.md file with examples of the FOREACH command and also with wrong parsing and logic
6272
+ * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
5602
6273
  */
5603
6274
 
5604
6275
  /**
@@ -5708,12 +6379,11 @@
5708
6379
  */
5709
6380
  parse: function (input) {
5710
6381
  var args = input.args;
5711
- // TODO: !!!!!! Replace with propper parameter name validation
5712
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5713
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5714
- throw new ParseError("Invalid joker");
6382
+ if (args.length !== 1) {
6383
+ throw new ParseError("JOKE command expects exactly one parameter name");
5715
6384
  }
5716
- var parameterName = parametersMatch.groups.parameterName;
6385
+ var parameterNameArg = args[0] || '';
6386
+ var parameterName = validateParameterName(parameterNameArg);
5717
6387
  return {
5718
6388
  type: 'JOKER',
5719
6389
  parameterName: parameterName,
@@ -5788,6 +6458,9 @@
5788
6458
  */
5789
6459
  parse: function (input) {
5790
6460
  var args = input.args, normalized = input.normalized;
6461
+ var availableVariantsMessage = spaceTrim__default["default"](function (block) { return "\n Available variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) {
6462
+ return "- ".concat(variantName).concat(variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)');
6463
+ }).join('\n')), "\n "); });
5791
6464
  // TODO: Make this more elegant and dynamically
5792
6465
  if (normalized.startsWith('MODEL_VARIANT')) {
5793
6466
  if (normalized === 'MODEL_VARIANT_CHAT') {
@@ -5803,17 +6476,13 @@
5803
6476
  key: 'modelVariant',
5804
6477
  value: 'COMPLETION',
5805
6478
  };
6479
+ // <- Note: [🤖]
5806
6480
  }
5807
6481
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
5808
- return {
5809
- type: 'MODEL',
5810
- key: 'modelVariant',
5811
- value: 'EMBEDDING',
5812
- };
5813
- // <- Note: [🤖]
6482
+ spaceTrim__default["default"](function (block) { return "\n Embedding model can not be used in pipeline\n\n ".concat(block(availableVariantsMessage), "\n "); });
5814
6483
  }
5815
6484
  else {
5816
- throw new ParseError(spaceTrim__default["default"](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 "); }));
6485
+ throw new ParseError(spaceTrim__default["default"](function (block) { return "\n Unknown model variant in command:\n\n ".concat(block(availableVariantsMessage), "\n "); }));
5817
6486
  }
5818
6487
  }
5819
6488
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5938,14 +6607,13 @@
5938
6607
  * Parses the PARAMETER command
5939
6608
  */
5940
6609
  parse: function (input) {
5941
- var normalized = input.normalized, raw = input.raw;
5942
- var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5943
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5944
- throw new ParseError("Invalid parameter");
5945
- }
5946
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5947
- if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5948
- throw new ParseError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
6610
+ var normalized = input.normalized, args = input.args, raw = input.raw;
6611
+ var parameterNameRaw = args.shift() || '';
6612
+ var parameterDescriptionRaw = args.join(' ');
6613
+ // <- TODO: When [🥶] fixed, change to:
6614
+ // > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
6615
+ if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
6616
+ throw new ParseError(spaceTrim__default["default"](function (block) { return "\n Parameter {".concat(parameterNameRaw, "} can not contain another parameter in description\n\n The description:\n ").concat(block(parameterDescriptionRaw), "\n "); }));
5949
6617
  }
5950
6618
  var isInput = normalized.startsWith('INPUT');
5951
6619
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5953,11 +6621,12 @@
5953
6621
  isInput = false;
5954
6622
  isOutput = false;
5955
6623
  }
5956
- // TODO: !!!!!! Add parameter name validation
6624
+ var parameterName = validateParameterName(parameterNameRaw);
6625
+ var parameterDescription = parameterDescriptionRaw.trim() || null;
5957
6626
  return {
5958
6627
  type: 'PARAMETER',
5959
6628
  parameterName: parameterName,
5960
- parameterDescription: parameterDescription.trim() || null,
6629
+ parameterDescription: parameterDescription,
5961
6630
  isInput: isInput,
5962
6631
  isOutput: isOutput,
5963
6632
  };
@@ -6282,6 +6951,7 @@
6282
6951
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
6283
6952
  */
6284
6953
  $applyToPipelineJson: function (command, $pipelineJson) {
6954
+ // TODO: Warn if the version is overridden
6285
6955
  $pipelineJson.promptbookVersion = command.promptbookVersion;
6286
6956
  },
6287
6957
  /**
@@ -6764,7 +7434,9 @@
6764
7434
  for (var commandNameSegmentsCount = 0; commandNameSegmentsCount < Math.min(items.length, 3); commandNameSegmentsCount++) {
6765
7435
  var commandNameRaw = items.slice(0, commandNameSegmentsCount + 1).join('_');
6766
7436
  var args = items.slice(commandNameSegmentsCount + 1);
6767
- var rawArgs = raw.substring(commandNameRaw.length).trim();
7437
+ var rawArgs = raw
7438
+ .substring(commandNameRaw.length)
7439
+ .trim();
6768
7440
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6769
7441
  if (command !== null) {
6770
7442
  return command;
@@ -6775,7 +7447,9 @@
6775
7447
  {
6776
7448
  var commandNameRaw = items.slice(-1).join('_');
6777
7449
  var args = items.slice(0, -1); // <- Note: This is probbably not correct
6778
- var rawArgs = raw.substring(0, raw.length - commandNameRaw.length).trim();
7450
+ var rawArgs = raw
7451
+ .substring(0, raw.length - commandNameRaw.length)
7452
+ .trim();
6779
7453
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6780
7454
  if (command !== null) {
6781
7455
  return command;
@@ -6915,7 +7589,7 @@
6915
7589
  function extractOneBlockFromMarkdown(markdown) {
6916
7590
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
6917
7591
  if (codeBlocks.length !== 1) {
6918
- throw new ParseError(spaceTrim__default["default"](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 "); }));
7592
+ throw new ParseError(spaceTrim__default["default"](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 "); }));
6919
7593
  }
6920
7594
  return codeBlocks[0];
6921
7595
  }
@@ -7102,7 +7776,7 @@
7102
7776
  var $pipelineJson = {
7103
7777
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
7104
7778
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
7105
- promptbookVersion: PROMPTBOOK_VERSION,
7779
+ promptbookVersion: undefined /* <- Note: By default no explicit version */,
7106
7780
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
7107
7781
  parameters: [],
7108
7782
  templates: [],
@@ -7393,7 +8067,7 @@
7393
8067
  return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
7394
8068
  }
7395
8069
  /**
7396
- * TODO: !!!! Warn if used only sync version
8070
+ * TODO: [main] !!!! Warn if used only sync version
7397
8071
  * TODO: [🚞] Report here line/column of error
7398
8072
  * TODO: Use spaceTrim more effectively
7399
8073
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
@@ -7474,70 +8148,6 @@
7474
8148
  * TODO: [🏛] This can be part of markdown builder
7475
8149
  */
7476
8150
 
7477
- /**
7478
- * @@@
7479
- *
7480
- * @param text @@@
7481
- * @param _isFirstLetterCapital @@@
7482
- * @returns @@@
7483
- * @example 'helloWorld'
7484
- * @example 'iLovePromptbook'
7485
- * @public exported from `@promptbook/utils`
7486
- */
7487
- function normalizeTo_camelCase(text, _isFirstLetterCapital) {
7488
- var e_1, _a;
7489
- if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
7490
- var charType;
7491
- var lastCharType = null;
7492
- var normalizedName = '';
7493
- try {
7494
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
7495
- var char = text_1_1.value;
7496
- var normalizedChar = void 0;
7497
- if (/^[a-z]$/.test(char)) {
7498
- charType = 'LOWERCASE';
7499
- normalizedChar = char;
7500
- }
7501
- else if (/^[A-Z]$/.test(char)) {
7502
- charType = 'UPPERCASE';
7503
- normalizedChar = char.toLowerCase();
7504
- }
7505
- else if (/^[0-9]$/.test(char)) {
7506
- charType = 'NUMBER';
7507
- normalizedChar = char;
7508
- }
7509
- else {
7510
- charType = 'OTHER';
7511
- normalizedChar = '';
7512
- }
7513
- if (!lastCharType) {
7514
- if (_isFirstLetterCapital) {
7515
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
7516
- }
7517
- }
7518
- else if (charType !== lastCharType &&
7519
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
7520
- !(lastCharType === 'NUMBER') &&
7521
- !(charType === 'NUMBER')) {
7522
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
7523
- }
7524
- normalizedName += normalizedChar;
7525
- lastCharType = charType;
7526
- }
7527
- }
7528
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
7529
- finally {
7530
- try {
7531
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
7532
- }
7533
- finally { if (e_1) throw e_1.error; }
7534
- }
7535
- return normalizedName;
7536
- }
7537
- /**
7538
- * TODO: [🌺] Use some intermediate util splitWords
7539
- */
7540
-
7541
8151
  /**
7542
8152
  * Creates a Mermaid graph based on the promptbook
7543
8153
  *
@@ -7594,9 +8204,9 @@
7594
8204
  return promptbookMermaid;
7595
8205
  }
7596
8206
  /**
7597
- * TODO: !!!!!! FOREACH in mermaid graph
7598
- * TODO: !!!!!! Knowledge in mermaid graph
7599
- * TODO: !!!!!! Personas in mermaid graph
8207
+ * TODO: !!!!! FOREACH in mermaid graph
8208
+ * TODO: !!!!! Knowledge in mermaid graph
8209
+ * TODO: !!!!! Personas in mermaid graph
7600
8210
  * TODO: Maybe use some Mermaid package instead of string templating
7601
8211
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
7602
8212
  */
@@ -7671,7 +8281,7 @@
7671
8281
  }
7672
8282
  }
7673
8283
  /**
7674
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
8284
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
7675
8285
  * TODO: [🧠][💺] Can be done this on type-level?
7676
8286
  */
7677
8287
 
@@ -7738,21 +8348,41 @@
7738
8348
  * @public exported from `@promptbook/core`
7739
8349
  */
7740
8350
  function usageToHuman(usage) {
7741
- var report = 'Usage:';
8351
+ var reportItems = [];
7742
8352
  var uncertainNumberToHuman = function (_a) {
7743
8353
  var value = _a.value, isUncertain = _a.isUncertain;
7744
8354
  return "".concat(isUncertain ? 'approximately ' : '').concat(Math.round(value * 100) / 100);
7745
8355
  };
7746
- report += '\n' + "- Cost ".concat(uncertainNumberToHuman(usage.price), " USD");
7747
- report += '\n' + "- Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time");
7748
- return spaceTrim__default["default"](report);
8356
+ if (usage.price.value > 0.01
8357
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻] Configure negligible value - default value to config + value to `UsageToHumanSettings`
8358
+ ) {
8359
+ reportItems.push("Cost ".concat(uncertainNumberToHuman(usage.price), " USD"));
8360
+ }
8361
+ else {
8362
+ reportItems.push("Negligible cost");
8363
+ }
8364
+ var worktime = usageToWorktime(usage);
8365
+ if (worktime.value >
8366
+ 1 / 60
8367
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻]
8368
+ ) {
8369
+ reportItems.push("Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time"));
8370
+ // TODO: [🍓][🧞‍♂️] Show minutes, seconds, days NOT 0.1 hours
8371
+ }
8372
+ if (usage.output.charactersCount.value > 0) {
8373
+ reportItems.push("Written ".concat(uncertainNumberToHuman(usage.output.charactersCount), " characters"));
8374
+ }
8375
+ if (reportItems.length === 0) {
8376
+ // Note: For negligible usage, we report at least something
8377
+ reportItems.push('Negligible');
8378
+ }
8379
+ return spaceTrim__default["default"](function (block) { return "\n Usage:\n ".concat(block(reportItems.map(function (item) { return "- ".concat(item); }).join('\n')), "\n "); });
7749
8380
  }
7750
8381
  /**
7751
- * TODO: Use "$1" not "1 USD"
7752
- * TODO: Use markdown formatting like "Cost approximately **$1**"
7753
- * TODO: Report in minutes, seconds, days NOT 0.1 hours
8382
+ * TODO: [🍓][🧞‍♂️] Use "$1" not "1 USD"
8383
+ * TODO: [🍓][🧞‍♂️] Use markdown formatting like "Cost approximately **$1**"
8384
+ * TODO: [🍓][🧞‍♂️] Report in minutes, seconds, days NOT 0.1 hours
7754
8385
  * TODO: [🧠] Maybe make from `uncertainNumberToHuman` separate exported utility
7755
- * TODO: When negligible usage, report "Negligible" or just don't report it
7756
8386
  * TODO: [🧠] Maybe use "~" instead of "approximately"
7757
8387
  * TODO: [🏛] Maybe make some markdown builder
7758
8388
  */
@@ -8401,8 +9031,8 @@
8401
9031
  */
8402
9032
  function createMarkdownTable(table) {
8403
9033
  var columnWidths = table.reduce(function (widths, row) {
8404
- row.forEach(function (cell, columnIndex) {
8405
- var cellLength = cell.length;
9034
+ row.forEach(function (subformat, columnIndex) {
9035
+ var cellLength = subformat.length;
8406
9036
  if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
8407
9037
  widths[columnIndex] = cellLength;
8408
9038
  }
@@ -8410,12 +9040,12 @@
8410
9040
  return widths;
8411
9041
  }, []);
8412
9042
  var header = "| ".concat(table[0]
8413
- .map(function (cell, columnIndex) { return cell.padEnd(columnWidths[columnIndex]); })
9043
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
8414
9044
  .join(' | '), " |");
8415
9045
  var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
8416
9046
  var rows = table.slice(1).map(function (row) {
8417
- var paddedRow = row.map(function (cell, columnIndex) {
8418
- return cell.padEnd(columnWidths[columnIndex]);
9047
+ var paddedRow = row.map(function (subformat, columnIndex) {
9048
+ return subformat.padEnd(columnWidths[columnIndex]);
8419
9049
  });
8420
9050
  return "| ".concat(paddedRow.join(' | '), " |");
8421
9051
  });
@@ -8693,9 +9323,13 @@
8693
9323
 
8694
9324
  exports.$llmToolsMetadataRegister = $llmToolsMetadataRegister;
8695
9325
  exports.$llmToolsRegister = $llmToolsRegister;
9326
+ exports.AbstractFormatError = AbstractFormatError;
8696
9327
  exports.CLAIM = CLAIM;
8697
9328
  exports.CallbackInterfaceTools = CallbackInterfaceTools;
8698
9329
  exports.CollectionError = CollectionError;
9330
+ exports.CsvFormatDefinition = CsvFormatDefinition;
9331
+ exports.CsvFormatError = CsvFormatError;
9332
+ exports.DEFAULT_CSV_SETTINGS = DEFAULT_CSV_SETTINGS;
8699
9333
  exports.DEFAULT_REMOTE_URL = DEFAULT_REMOTE_URL;
8700
9334
  exports.DEFAULT_REMOTE_URL_PATH = DEFAULT_REMOTE_URL_PATH;
8701
9335
  exports.ERRORS = ERRORS;
@@ -8706,6 +9340,7 @@
8706
9340
  exports.ExpectError = ExpectError;
8707
9341
  exports.IS_VERBOSE = IS_VERBOSE;
8708
9342
  exports.LimitReachedError = LimitReachedError;
9343
+ exports.MANDATORY_CSV_SETTINGS = MANDATORY_CSV_SETTINGS;
8709
9344
  exports.MAX_EXECUTION_ATTEMPTS = MAX_EXECUTION_ATTEMPTS;
8710
9345
  exports.MAX_FILENAME_LENGTH = MAX_FILENAME_LENGTH;
8711
9346
  exports.MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH = MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH;
@@ -8724,6 +9359,7 @@
8724
9359
  exports.PrefixStorage = PrefixStorage;
8725
9360
  exports.RESERVED_PARAMETER_NAMES = RESERVED_PARAMETER_NAMES;
8726
9361
  exports.TemplateTypes = TemplateTypes;
9362
+ exports.TextFormatDefinition = TextFormatDefinition;
8727
9363
  exports.UnexpectedError = UnexpectedError;
8728
9364
  exports.ZERO_USAGE = ZERO_USAGE;
8729
9365
  exports._AnthropicClaudeMetadataRegistration = _AnthropicClaudeMetadataRegistration;