@promptbook/node 0.69.0-7 → 0.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +4 -1
  2. package/esm/index.es.js +1510 -783
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/promptbook-collection/index.d.ts +0 -3
  5. package/esm/typings/src/_packages/core.index.d.ts +12 -0
  6. package/esm/typings/src/_packages/types.index.d.ts +6 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +4 -4
  8. package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
  9. package/esm/typings/src/collection/constructors/createCollectionFromUrl.d.ts +1 -1
  10. package/esm/typings/src/commands/FOREACH/ForeachCommand.d.ts +1 -1
  11. package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -5
  12. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +1 -2
  13. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  14. package/esm/typings/src/config.d.ts +11 -4
  15. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +1 -1
  16. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -3
  17. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +6 -5
  18. package/esm/typings/src/errors/AbstractFormatError.d.ts +11 -0
  19. package/esm/typings/src/execution/PipelineExecutor.d.ts +1 -0
  20. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +5 -6
  21. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTemplateResult.d.ts +45 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorSettings.d.ts +10 -0
  23. package/esm/typings/src/execution/createPipelineExecutor/00-createPipelineExecutor.d.ts +3 -0
  24. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +5 -2
  25. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +3 -0
  26. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +15 -0
  27. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +74 -0
  28. package/esm/typings/src/execution/embeddingVectorToString.d.ts +1 -1
  29. package/esm/typings/src/execution/utils/checkExpectations.d.ts +2 -0
  30. package/esm/typings/src/execution/utils/usageToHuman.d.ts +3 -4
  31. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +14 -15
  32. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +31 -0
  33. package/esm/typings/src/formats/csv/{ListFormatDefinition.d.ts → CsvFormatDefinition.d.ts} +6 -3
  34. package/esm/typings/src/formats/csv/CsvFormatError.d.ts +10 -0
  35. package/esm/typings/src/formats/csv/CsvSettings.d.ts +13 -0
  36. package/esm/typings/src/formats/index.d.ts +1 -1
  37. package/esm/typings/src/formats/json/JsonFormatDefinition.d.ts +4 -3
  38. package/esm/typings/src/formats/text/TextFormatDefinition.d.ts +19 -0
  39. package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +4 -3
  40. package/esm/typings/src/knowledge/prepare-knowledge/markdown/prepareKnowledgeFromMarkdown.d.ts +1 -1
  41. package/esm/typings/src/knowledge/prepare-knowledge/pdf/prepareKnowledgeFromPdf.d.ts +1 -1
  42. package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +1 -1
  43. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  44. package/esm/typings/src/llm-providers/anthropic-claude/createAnthropicClaudeExecutionTools.d.ts +2 -2
  45. package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +2 -2
  46. package/esm/typings/src/llm-providers/openai/playground/playground.d.ts +1 -1
  47. package/esm/typings/src/personas/preparePersona.d.ts +1 -1
  48. package/esm/typings/src/prepare/isPipelinePrepared.d.ts +1 -1
  49. package/esm/typings/src/prepare/prepareTemplates.d.ts +1 -1
  50. package/esm/typings/src/types/PipelineJson/ParameterJson.d.ts +1 -1
  51. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +1 -1
  52. package/esm/typings/src/types/execution-report/ExecutionReportJson.d.ts +0 -3
  53. package/esm/typings/src/types/execution-report/executionReportJsonToString.d.ts +2 -1
  54. package/esm/typings/src/types/typeAliases.d.ts +1 -1
  55. package/esm/typings/src/utils/expectation-counters/index.d.ts +3 -0
  56. package/esm/typings/src/utils/organization/{f.d.ts → empty_object.d.ts} +5 -1
  57. package/esm/typings/src/utils/organization/just_empty_object.d.ts +12 -0
  58. package/esm/typings/src/utils/{extractParameterNames.d.ts → parameters/extractParameterNames.d.ts} +2 -2
  59. package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +27 -0
  60. package/esm/typings/src/utils/{replaceParameters.d.ts → parameters/replaceParameters.d.ts} +2 -2
  61. package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +1 -1
  62. package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +1 -1
  63. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +10 -0
  64. package/package.json +18 -13
  65. package/umd/index.umd.js +1513 -787
  66. package/umd/index.umd.js.map +1 -1
  67. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatCell.d.ts +0 -30
  68. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempt.d.ts +0 -30
  69. package/esm/typings/src/formats/list/ListFormatDefinition.d.ts +0 -16
  70. /package/esm/typings/src/utils/{extractParameterNames.test.d.ts → parameters/extractParameterNames.test.d.ts} +0 -0
  71. /package/esm/typings/src/{execution/utils/usageToHuman.test.d.ts → utils/parameters/mapAvailableToExpectedParameters.test.d.ts} +0 -0
  72. /package/esm/typings/src/utils/{replaceParameters.test.d.ts → parameters/replaceParameters.test.d.ts} +0 -0
  73. /package/esm/typings/src/{personas/preparePersona.test.d.ts → utils/validators/parameterName/validateParameterName.test.d.ts} +0 -0
package/umd/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('fs/promises'), require('path'), require('spacetrim'), require('prettier'), require('prettier/parser-html'), require('waitasecond'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('path/posix'), require('dotenv')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'colors', 'fs/promises', 'path', 'spacetrim', 'prettier', 'prettier/parser-html', 'waitasecond', 'crypto-js/enc-hex', 'crypto-js/sha256', 'path/posix', 'dotenv'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-node"] = {}, global.colors, global.promises, global.path, global.spaceTrim, global.prettier, global.parserHtml, global.waitasecond, global.hexEncoder, global.sha256, global.posix, global.dotenv));
5
- })(this, (function (exports, colors, promises, path, spaceTrim, prettier, parserHtml, waitasecond, hexEncoder, sha256, posix, dotenv) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('fs/promises'), require('path'), require('spacetrim'), require('prettier'), require('prettier/parser-html'), require('waitasecond'), require('papaparse'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('path/posix'), require('dotenv')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'colors', 'fs/promises', 'path', 'spacetrim', 'prettier', 'prettier/parser-html', 'waitasecond', 'papaparse', 'crypto-js/enc-hex', 'crypto-js/sha256', 'path/posix', 'dotenv'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-node"] = {}, global.colors, global.promises, global.path, global.spaceTrim, global.prettier, global.parserHtml, global.waitasecond, global.papaparse, global.hexEncoder, global.sha256, global.posix, global.dotenv));
5
+ })(this, (function (exports, colors, promises, path, spaceTrim, prettier, parserHtml, waitasecond, papaparse, hexEncoder, sha256, posix, dotenv) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -35,8 +35,8 @@
35
35
  /**
36
36
  * The version of the Promptbook library
37
37
  */
38
- var PROMPTBOOK_VERSION = '0.69.0-6';
39
- // TODO: !!!! List here all the versions and annotate + put into script
38
+ var PROMPTBOOK_VERSION = '0.69.0-21';
39
+ // TODO: [main] !!!! List here all the versions and annotate + put into script
40
40
 
41
41
  /*! *****************************************************************************
42
42
  Copyright (c) Microsoft Corporation.
@@ -346,7 +346,7 @@
346
346
  }
347
347
  /**
348
348
  * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
349
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
349
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
350
350
  * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
351
351
  */
352
352
 
@@ -388,13 +388,13 @@
388
388
  *
389
389
  * @public exported from `@promptbook/core`
390
390
  */
391
- var MAX_PARALLEL_COUNT = 5;
391
+ var MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹‍♂️]
392
392
  /**
393
393
  * The maximum number of attempts to execute LLM task before giving up
394
394
  *
395
395
  * @public exported from `@promptbook/core`
396
396
  */
397
- var MAX_EXECUTION_ATTEMPTS = 3;
397
+ var MAX_EXECUTION_ATTEMPTS = 3; // <- TODO: [🤹‍♂️]
398
398
  /**
399
399
  * The maximum length of the (generated) filename
400
400
  *
@@ -442,6 +442,17 @@
442
442
  */
443
443
  var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
444
444
  // <- TODO: [🧜‍♂️]
445
+ /**
446
+ * @@@
447
+ *
448
+ * @public exported from `@promptbook/core`
449
+ */
450
+ var DEFAULT_CSV_SETTINGS = Object.freeze({
451
+ delimiter: ',',
452
+ quoteChar: '"',
453
+ newline: '\n',
454
+ skipEmptyLines: true,
455
+ });
445
456
  /**
446
457
  * @@@
447
458
  *
@@ -525,7 +536,7 @@
525
536
  commands.push("PIPELINE URL ".concat(pipelineUrl));
526
537
  }
527
538
  commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
528
- // TODO: !!! This increase size of the bundle and is probbably not necessary
539
+ // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
529
540
  pipelineString = prettifyMarkdown(pipelineString);
530
541
  try {
531
542
  for (var _g = __values(parameters.filter(function (_a) {
@@ -673,12 +684,12 @@
673
684
  pipelineString += '```' + contentLanguage;
674
685
  pipelineString += '\n';
675
686
  pipelineString += spaceTrim__default["default"](content);
676
- // <- TODO: !!! Escape
687
+ // <- TODO: [main] !!! Escape
677
688
  // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
678
689
  pipelineString += '\n';
679
690
  pipelineString += '```';
680
691
  pipelineString += '\n\n';
681
- pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: !!! If the parameter here has description, add it and use templateParameterJsonToString
692
+ pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use templateParameterJsonToString
682
693
  }
683
694
  }
684
695
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -905,7 +916,7 @@
905
916
  });
906
917
  }
907
918
 
908
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.69.0-6",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.69.0-6",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.69.0-6",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.69.0-6",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
919
+ 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"}];
909
920
 
910
921
  /**
911
922
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -980,7 +991,7 @@
980
991
  if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
981
992
  return false;
982
993
  }
983
- // <- TODO: !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
994
+ // <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_VERSIONS
984
995
  return true;
985
996
  }
986
997
 
@@ -1149,7 +1160,7 @@
1149
1160
  // <- Note: [🚲]
1150
1161
  throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1151
1162
  }
1152
- if (!isValidPromptbookVersion(pipeline.promptbookVersion)) {
1163
+ if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1153
1164
  // <- Note: [🚲]
1154
1165
  throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1155
1166
  }
@@ -1332,6 +1343,7 @@
1332
1343
  }
1333
1344
  }
1334
1345
  /**
1346
+ * TODO: !!!!! [🧞‍♀️] Do not allow joker + foreach
1335
1347
  * TODO: [🧠] Work with promptbookVersion
1336
1348
  * TODO: Use here some json-schema, Zod or something similar and change it to:
1337
1349
  * > /**
@@ -1343,11 +1355,11 @@
1343
1355
  * > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
1344
1356
  */
1345
1357
  /**
1346
- * TODO: [🐣] !!!! Validate that all samples match expectations
1347
- * TODO: [🐣][🐝] !!!! Validate that knowledge is valid (non-void)
1348
- * TODO: [🐣] !!!! Validate that persona can be used only with CHAT variant
1349
- * TODO: [🐣] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1350
- * TODO: [🐣] !!!! Validate that reserved parameter is not used as joker
1358
+ * TODO: [🐣][main] !!!! Validate that all samples match expectations
1359
+ * TODO: [🐣][🐝][main] !!!! Validate that knowledge is valid (non-void)
1360
+ * TODO: [🐣][main] !!!! Validate that persona can be used only with CHAT variant
1361
+ * TODO: [🐣][main] !!!! Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
1362
+ * TODO: [🐣][main] !!!! Validate that reserved parameter is not used as joker
1351
1363
  * TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
1352
1364
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
1353
1365
  */
@@ -2091,7 +2103,7 @@
2091
2103
  return true;
2092
2104
  }
2093
2105
  /**
2094
- * TODO: [🔃] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2106
+ * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2095
2107
  * TODO: [🐠] Maybe base this on `makeValidator`
2096
2108
  * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2097
2109
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
@@ -2100,6 +2112,23 @@
2100
2112
  * - [♨] Are templates prepared
2101
2113
  */
2102
2114
 
2115
+ /**
2116
+ * Serializes an error into a [🚉] JSON-serializable object
2117
+ *
2118
+ * @public exported from `@promptbook/utils`
2119
+ */
2120
+ function serializeError(error) {
2121
+ var name = error.name, message = error.message, stack = error.stack;
2122
+ if (!__spreadArray(['Error'], __read(Object.keys(ERRORS)), false).includes(name)) {
2123
+ throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
2124
+ }
2125
+ return {
2126
+ name: name,
2127
+ message: message,
2128
+ stack: stack,
2129
+ };
2130
+ }
2131
+
2103
2132
  /**
2104
2133
  * Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
2105
2134
  *
@@ -2126,9 +2155,10 @@
2126
2155
  });
2127
2156
  Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2128
2157
  get: function () {
2129
- return this.llmExecutionTools
2130
- .map(function (tools, index) { return "".concat(index + 1, ") ").concat(tools.title, " ").concat(tools.description || ''); })
2131
- .join('\n');
2158
+ return this.llmExecutionTools.map(function (_a, index) {
2159
+ var title = _a.title;
2160
+ return "".concat(index + 1, ") `").concat(title, "`");
2161
+ }).join('\n');
2132
2162
  },
2133
2163
  enumerable: false,
2134
2164
  configurable: true
@@ -2326,9 +2356,7 @@
2326
2356
  throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
2327
2357
  }
2328
2358
  else {
2329
- 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
2330
- .map(function (tools) { return "- ".concat(tools.title, " ").concat(tools.description || ''); })
2331
- .join('\n')), "\n\n "); }));
2359
+ 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 "); }));
2332
2360
  }
2333
2361
  }
2334
2362
  });
@@ -2393,23 +2421,6 @@
2393
2421
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
2394
2422
  */
2395
2423
 
2396
- /**
2397
- * Serializes an error into a [🚉] JSON-serializable object
2398
- *
2399
- * @public exported from `@promptbook/utils`
2400
- */
2401
- function serializeError(error) {
2402
- var name = error.name, message = error.message, stack = error.stack;
2403
- if (!__spreadArray(['Error'], __read(Object.keys(ERRORS)), false).includes(name)) {
2404
- throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
2405
- }
2406
- return {
2407
- name: name,
2408
- message: message,
2409
- stack: stack,
2410
- };
2411
- }
2412
-
2413
2424
  /**
2414
2425
  * Takes an item or an array of items and returns an array of items
2415
2426
  *
@@ -2487,47 +2498,47 @@
2487
2498
  * @public exported from `@promptbook/utils`
2488
2499
  */
2489
2500
  function extractParameterNamesFromTemplate(template) {
2490
- var e_1, _a, e_2, _b, e_3, _c;
2501
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
2491
2502
  var title = template.title, description = template.description, templateType = template.templateType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames, foreach = template.foreach;
2492
2503
  var parameterNames = new Set();
2493
2504
  try {
2494
- 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()) {
2495
- var parameterName = _e.value;
2505
+ 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()) {
2506
+ var parameterName = _f.value;
2496
2507
  parameterNames.add(parameterName);
2497
2508
  }
2498
2509
  }
2499
2510
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2500
2511
  finally {
2501
2512
  try {
2502
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2513
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
2503
2514
  }
2504
2515
  finally { if (e_1) throw e_1.error; }
2505
2516
  }
2506
2517
  if (templateType === 'SCRIPT_TEMPLATE') {
2507
2518
  try {
2508
- for (var _f = __values(extractVariables(content)), _g = _f.next(); !_g.done; _g = _f.next()) {
2509
- var parameterName = _g.value;
2519
+ for (var _g = __values(extractVariables(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
2520
+ var parameterName = _h.value;
2510
2521
  parameterNames.add(parameterName);
2511
2522
  }
2512
2523
  }
2513
2524
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
2514
2525
  finally {
2515
2526
  try {
2516
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2527
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
2517
2528
  }
2518
2529
  finally { if (e_2) throw e_2.error; }
2519
2530
  }
2520
2531
  }
2521
2532
  try {
2522
- for (var _h = __values(jokerParameterNames || []), _j = _h.next(); !_j.done; _j = _h.next()) {
2523
- var jokerName = _j.value;
2533
+ for (var _j = __values(jokerParameterNames || []), _k = _j.next(); !_k.done; _k = _j.next()) {
2534
+ var jokerName = _k.value;
2524
2535
  parameterNames.add(jokerName);
2525
2536
  }
2526
2537
  }
2527
2538
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
2528
2539
  finally {
2529
2540
  try {
2530
- if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
2541
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
2531
2542
  }
2532
2543
  finally { if (e_3) throw e_3.error; }
2533
2544
  }
@@ -2535,10 +2546,22 @@
2535
2546
  // <- Note {websiteContent} is used in `preparedContent`
2536
2547
  // Note: [🍭] Fixing dependent subparameterName from FOREACH command
2537
2548
  if (foreach !== undefined) {
2538
- if (parameterNames.has(foreach.subparameterName)) {
2539
- parameterNames.delete(foreach.subparameterName);
2540
- parameterNames.add(foreach.parameterName);
2541
- // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2549
+ try {
2550
+ for (var _l = __values(foreach.inputSubparameterNames), _m = _l.next(); !_m.done; _m = _l.next()) {
2551
+ var subparameterName = _m.value;
2552
+ if (parameterNames.has(subparameterName)) {
2553
+ parameterNames.delete(subparameterName);
2554
+ parameterNames.add(foreach.parameterName);
2555
+ // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2556
+ }
2557
+ }
2558
+ }
2559
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2560
+ finally {
2561
+ try {
2562
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
2563
+ }
2564
+ finally { if (e_4) throw e_4.error; }
2542
2565
  }
2543
2566
  }
2544
2567
  return parameterNames;
@@ -2548,188 +2571,656 @@
2548
2571
  */
2549
2572
 
2550
2573
  /**
2551
- * Function isValidJsonString will tell you if the string is valid JSON or not
2574
+ * Create difference set of two sets.
2552
2575
  *
2576
+ * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
2553
2577
  * @public exported from `@promptbook/utils`
2554
2578
  */
2555
- function isValidJsonString(value /* <- [👨‍⚖️] */) {
2579
+ function difference(a, b, isEqual) {
2580
+ var e_1, _a;
2581
+ if (isEqual === void 0) { isEqual = function (a, b) { return a === b; }; }
2582
+ var diff = new Set();
2583
+ var _loop_1 = function (itemA) {
2584
+ if (!Array.from(b).some(function (itemB) { return isEqual(itemA, itemB); })) {
2585
+ diff.add(itemA);
2586
+ }
2587
+ };
2556
2588
  try {
2557
- JSON.parse(value);
2558
- return true;
2559
- }
2560
- catch (error) {
2561
- if (!(error instanceof Error)) {
2562
- throw error;
2589
+ for (var _b = __values(Array.from(a)), _c = _b.next(); !_c.done; _c = _b.next()) {
2590
+ var itemA = _c.value;
2591
+ _loop_1(itemA);
2563
2592
  }
2564
- if (error.message.includes('Unexpected token')) {
2565
- return false;
2593
+ }
2594
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2595
+ finally {
2596
+ try {
2597
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2566
2598
  }
2567
- return false;
2599
+ finally { if (e_1) throw e_1.error; }
2568
2600
  }
2601
+ return diff;
2569
2602
  }
2603
+ /**
2604
+ * TODO: [🧠][💯] Maybe also implement symmetricDifference
2605
+ */
2570
2606
 
2571
2607
  /**
2572
- * Extracts all code blocks from markdown.
2573
- *
2574
- * Note: There are multiple simmilar function:
2575
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2576
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2577
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2578
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2608
+ * Creates a new set with all elements that are present in either set
2579
2609
  *
2580
- * @param markdown any valid markdown
2581
- * @returns code blocks with language and content
2582
- * @throws {ParseError} if block is not closed properly
2583
- * @public exported from `@promptbook/markdown-utils`
2610
+ * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
2611
+ * @public exported from `@promptbook/utils`
2584
2612
  */
2585
- function extractAllBlocksFromMarkdown(markdown) {
2586
- var e_1, _a;
2587
- var codeBlocks = [];
2588
- var lines = markdown.split('\n');
2589
- // Note: [0] Ensure that the last block notated by gt > will be closed
2590
- lines.push('');
2591
- var currentCodeBlock = null;
2613
+ function union() {
2614
+ var e_1, _a, e_2, _b;
2615
+ var sets = [];
2616
+ for (var _i = 0; _i < arguments.length; _i++) {
2617
+ sets[_i] = arguments[_i];
2618
+ }
2619
+ var union = new Set();
2592
2620
  try {
2593
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
2594
- var line = lines_1_1.value;
2595
- if (line.startsWith('> ') || line === '>') {
2596
- if (currentCodeBlock === null) {
2597
- currentCodeBlock = { blockNotation: '>', language: null, content: '' };
2598
- } /* not else */
2599
- if (currentCodeBlock.blockNotation === '>') {
2600
- if (currentCodeBlock.content !== '') {
2601
- currentCodeBlock.content += '\n';
2602
- }
2603
- currentCodeBlock.content += line.slice(2);
2604
- }
2605
- }
2606
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
2607
- codeBlocks.push(currentCodeBlock);
2608
- currentCodeBlock = null;
2609
- }
2610
- /* not else */
2611
- if (line.startsWith('```')) {
2612
- var language = line.slice(3).trim() || null;
2613
- if (currentCodeBlock === null) {
2614
- currentCodeBlock = { blockNotation: '```', language: language, content: '' };
2615
- }
2616
- else {
2617
- if (language !== null) {
2618
- throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
2619
- }
2620
- codeBlocks.push(currentCodeBlock);
2621
- currentCodeBlock = null;
2621
+ for (var sets_1 = __values(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
2622
+ var set = sets_1_1.value;
2623
+ try {
2624
+ for (var _c = (e_2 = void 0, __values(Array.from(set))), _d = _c.next(); !_d.done; _d = _c.next()) {
2625
+ var item = _d.value;
2626
+ union.add(item);
2622
2627
  }
2623
2628
  }
2624
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
2625
- if (currentCodeBlock.content !== '') {
2626
- currentCodeBlock.content += '\n';
2629
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2630
+ finally {
2631
+ try {
2632
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
2627
2633
  }
2628
- currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
2634
+ finally { if (e_2) throw e_2.error; }
2629
2635
  }
2630
2636
  }
2631
2637
  }
2632
2638
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2633
2639
  finally {
2634
2640
  try {
2635
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
2641
+ if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
2636
2642
  }
2637
2643
  finally { if (e_1) throw e_1.error; }
2638
2644
  }
2639
- if (currentCodeBlock !== null) {
2640
- throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
2641
- }
2642
- return codeBlocks;
2645
+ return union;
2643
2646
  }
2644
- /**
2645
- * TODO: Maybe name for `blockNotation` instead of '```' and '>'
2646
- */
2647
2647
 
2648
2648
  /**
2649
- * Extracts extracts exactly one valid JSON code block
2650
- *
2651
- * - When given string is a valid JSON as it is, it just returns it
2652
- * - When there is no JSON code block the function throws a `ParseError`
2653
- * - When there are multiple JSON code blocks the function throws a `ParseError`
2649
+ * Just marks a place of place where should be something implemented
2650
+ * No side effects.
2654
2651
  *
2655
- * Note: It is not important if marked as ```json BUT if it is VALID JSON
2656
- * Note: There are multiple simmilar function:
2657
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2658
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2659
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2660
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2652
+ * Note: It can be usefull suppressing eslint errors of unused variables
2661
2653
  *
2662
- * @public exported from `@promptbook/markdown-utils`
2663
- * @throws {ParseError} if there is no valid JSON block in the markdown
2654
+ * @param value any values
2655
+ * @returns void
2656
+ * @private within the repository
2664
2657
  */
2665
- function extractJsonBlock(markdown) {
2666
- if (isValidJsonString(markdown)) {
2667
- return markdown;
2668
- }
2669
- var codeBlocks = extractAllBlocksFromMarkdown(markdown);
2670
- var jsonBlocks = codeBlocks.filter(function (_a) {
2671
- var content = _a.content;
2672
- return isValidJsonString(content);
2673
- });
2674
- if (jsonBlocks.length === 0) {
2675
- throw new Error('There is no valid JSON block in the markdown');
2676
- }
2677
- if (jsonBlocks.length > 1) {
2678
- throw new Error('There are multiple JSON code blocks in the markdown');
2658
+ function TODO_USE() {
2659
+ var value = [];
2660
+ for (var _i = 0; _i < arguments.length; _i++) {
2661
+ value[_i] = arguments[_i];
2679
2662
  }
2680
- return jsonBlocks[0].content;
2681
2663
  }
2682
- /**
2683
- * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
2684
- * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
2685
- */
2686
2664
 
2687
2665
  /**
2688
- * Just says that the variable is not used but should be kept
2689
- * No side effects.
2690
- *
2691
- * Note: It can be usefull for:
2666
+ * This error indicates problems parsing the format value
2692
2667
  *
2693
- * 1) Suppressing eager optimization of unused imports
2694
- * 2) Suppressing eslint errors of unused variables in the tests
2695
- * 3) Keeping the type of the variable for type testing
2668
+ * For example, when the format value is not a valid JSON or CSV
2669
+ * This is not thrown directly but in extended classes
2696
2670
  *
2697
- * @param value any values
2698
- * @returns void
2699
- * @private within the repository
2671
+ * @public exported from `@promptbook/core`
2700
2672
  */
2701
- function keepUnused() {
2702
- var valuesToKeep = [];
2703
- for (var _i = 0; _i < arguments.length; _i++) {
2704
- valuesToKeep[_i] = arguments[_i];
2673
+ var AbstractFormatError = /** @class */ (function (_super) {
2674
+ __extends(AbstractFormatError, _super);
2675
+ // Note: To allow instanceof do not put here error `name`
2676
+ // public readonly name = 'AbstractFormatError';
2677
+ function AbstractFormatError(message) {
2678
+ var _this = _super.call(this, message) || this;
2679
+ Object.setPrototypeOf(_this, AbstractFormatError.prototype);
2680
+ return _this;
2705
2681
  }
2706
- }
2682
+ return AbstractFormatError;
2683
+ }(Error));
2707
2684
 
2708
2685
  /**
2709
- * Replaces parameters in template with values from parameters object
2686
+ * This error indicates problem with parsing of CSV
2710
2687
  *
2711
- * @param template the template with parameters in {curly} braces
2712
- * @param parameters the object with parameters
2713
- * @returns the template with replaced parameters
2714
- * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
2715
- * @public exported from `@promptbook/utils`
2688
+ * @public exported from `@promptbook/core`
2716
2689
  */
2717
- function replaceParameters(template, parameters) {
2718
- var e_1, _a;
2719
- try {
2720
- for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
2721
- var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
2722
- if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
2723
- throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
2724
- }
2725
- else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
2726
- // TODO: [🍵]
2727
- throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
2728
- }
2729
- }
2690
+ var CsvFormatError = /** @class */ (function (_super) {
2691
+ __extends(CsvFormatError, _super);
2692
+ function CsvFormatError(message) {
2693
+ var _this = _super.call(this, message) || this;
2694
+ _this.name = 'CsvFormatError';
2695
+ Object.setPrototypeOf(_this, CsvFormatError.prototype);
2696
+ return _this;
2730
2697
  }
2731
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2732
- finally {
2698
+ return CsvFormatError;
2699
+ }(AbstractFormatError));
2700
+
2701
+ /**
2702
+ * @@@
2703
+ *
2704
+ * @public exported from `@promptbook/core`
2705
+ */
2706
+ var MANDATORY_CSV_SETTINGS = Object.freeze({
2707
+ header: true,
2708
+ // encoding: 'utf8',
2709
+ });
2710
+
2711
+ /**
2712
+ * Definition for CSV spreadsheet
2713
+ *
2714
+ * @public exported from `@promptbook/core`
2715
+ * <- TODO: [🏢] Export from package `@promptbook/csv`
2716
+ */
2717
+ var CsvFormatDefinition = {
2718
+ formatName: 'CSV',
2719
+ aliases: ['SPREADSHEET', 'TABLE'],
2720
+ isValid: function (value, settings, schema) {
2721
+ // TODO: Implement CSV validation
2722
+ TODO_USE(value /* <- TODO: Use value here */);
2723
+ TODO_USE(settings /* <- TODO: Use settings here */);
2724
+ TODO_USE(schema /* <- TODO: Use schema here */);
2725
+ return true;
2726
+ },
2727
+ canBeValid: function (partialValue, settings, schema) {
2728
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2729
+ TODO_USE(settings /* <- TODO: Use settings here */);
2730
+ TODO_USE(schema /* <- TODO: Use schema here */);
2731
+ return true;
2732
+ },
2733
+ heal: function (value, settings, schema) {
2734
+ TODO_USE(value /* <- TODO: Use partialValue here */);
2735
+ TODO_USE(settings /* <- TODO: Use settings here */);
2736
+ TODO_USE(schema /* <- TODO: Use schema here */);
2737
+ throw new Error('Not implemented');
2738
+ },
2739
+ subvalueDefinitions: [
2740
+ {
2741
+ subvalueName: 'ROW',
2742
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
2743
+ return __awaiter(this, void 0, void 0, function () {
2744
+ var csv, mappedData;
2745
+ var _this = this;
2746
+ return __generator(this, function (_a) {
2747
+ switch (_a.label) {
2748
+ case 0:
2749
+ csv = papaparse.parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
2750
+ if (csv.errors.length !== 0) {
2751
+ 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 "); }));
2752
+ }
2753
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, index) { return __awaiter(_this, void 0, void 0, function () {
2754
+ var _a, _b;
2755
+ var _c;
2756
+ return __generator(this, function (_d) {
2757
+ switch (_d.label) {
2758
+ case 0:
2759
+ if (row[outputParameterName]) {
2760
+ throw new CsvFormatError("Can not overwrite existing column \"".concat(outputParameterName, "\" in CSV row"));
2761
+ }
2762
+ _a = [__assign({}, row)];
2763
+ _c = {};
2764
+ _b = outputParameterName;
2765
+ return [4 /*yield*/, mapCallback(row, index)];
2766
+ case 1: return [2 /*return*/, __assign.apply(void 0, _a.concat([(_c[_b] = _d.sent(), _c)]))];
2767
+ }
2768
+ });
2769
+ }); }))];
2770
+ case 1:
2771
+ mappedData = _a.sent();
2772
+ return [2 /*return*/, papaparse.unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
2773
+ }
2774
+ });
2775
+ });
2776
+ },
2777
+ },
2778
+ {
2779
+ subvalueName: 'CELL',
2780
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
2781
+ return __awaiter(this, void 0, void 0, function () {
2782
+ var csv, mappedData;
2783
+ var _this = this;
2784
+ return __generator(this, function (_a) {
2785
+ switch (_a.label) {
2786
+ case 0:
2787
+ csv = papaparse.parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
2788
+ if (csv.errors.length !== 0) {
2789
+ 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 "); }));
2790
+ }
2791
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, rowIndex) { return __awaiter(_this, void 0, void 0, function () {
2792
+ var _this = this;
2793
+ return __generator(this, function (_a) {
2794
+ return [2 /*return*/, /* not await */ Promise.all(Object.entries(row).map(function (_a, columnIndex) {
2795
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
2796
+ return __awaiter(_this, void 0, void 0, function () {
2797
+ var index;
2798
+ var _c;
2799
+ return __generator(this, function (_d) {
2800
+ index = rowIndex * Object.keys(row).length + columnIndex;
2801
+ return [2 /*return*/, /* not await */ mapCallback((_c = {}, _c[key] = value, _c), index)];
2802
+ });
2803
+ });
2804
+ }))];
2805
+ });
2806
+ }); }))];
2807
+ case 1:
2808
+ mappedData = _a.sent();
2809
+ return [2 /*return*/, papaparse.unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
2810
+ }
2811
+ });
2812
+ });
2813
+ },
2814
+ },
2815
+ ],
2816
+ };
2817
+ /**
2818
+ * TODO: [🍓] In `CsvFormatDefinition` implement simple `isValid`
2819
+ * TODO: [🍓] In `CsvFormatDefinition` implement partial `canBeValid`
2820
+ * TODO: [🍓] In `CsvFormatDefinition` implement `heal
2821
+ * TODO: [🍓] In `CsvFormatDefinition` implement `subvalueDefinitions`
2822
+ * TODO: [🏢] Allow to expect something inside CSV objects and other formats
2823
+ */
2824
+
2825
+ /**
2826
+ * Function isValidJsonString will tell you if the string is valid JSON or not
2827
+ *
2828
+ * @public exported from `@promptbook/utils`
2829
+ */
2830
+ function isValidJsonString(value /* <- [👨‍⚖️] */) {
2831
+ try {
2832
+ JSON.parse(value);
2833
+ return true;
2834
+ }
2835
+ catch (error) {
2836
+ if (!(error instanceof Error)) {
2837
+ throw error;
2838
+ }
2839
+ if (error.message.includes('Unexpected token')) {
2840
+ return false;
2841
+ }
2842
+ return false;
2843
+ }
2844
+ }
2845
+
2846
+ /**
2847
+ * Definition for JSON format
2848
+ *
2849
+ * @private still in development [🏢]
2850
+ */
2851
+ var JsonFormatDefinition = {
2852
+ formatName: 'JSON',
2853
+ mimeType: 'application/json',
2854
+ isValid: function (value, settings, schema) {
2855
+ TODO_USE(schema /* <- TODO: Use schema here */);
2856
+ TODO_USE(settings /* <- TODO: Use settings here */);
2857
+ return isValidJsonString(value);
2858
+ },
2859
+ canBeValid: function (partialValue, settings, schema) {
2860
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2861
+ TODO_USE(settings /* <- TODO: Use settings here */);
2862
+ TODO_USE(schema /* <- TODO: Use schema here */);
2863
+ return true;
2864
+ },
2865
+ heal: function (value, settings, schema) {
2866
+ TODO_USE(value /* <- TODO: Use partialValue here */);
2867
+ TODO_USE(settings /* <- TODO: Use settings here */);
2868
+ TODO_USE(schema /* <- TODO: Use schema here */);
2869
+ throw new Error('Not implemented');
2870
+ },
2871
+ subvalueDefinitions: [],
2872
+ };
2873
+ /**
2874
+ * TODO: [🧠] Maybe propper instance of object
2875
+ * TODO: [0] Make string_serialized_json
2876
+ * TODO: [1] Make type for JSON Settings and Schema
2877
+ * TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
2878
+ * TODO: [🍓] In `JsonFormatDefinition` implement simple `isValid`
2879
+ * TODO: [🍓] In `JsonFormatDefinition` implement partial `canBeValid`
2880
+ * TODO: [🍓] In `JsonFormatDefinition` implement `heal
2881
+ * TODO: [🍓] In `JsonFormatDefinition` implement `subvalueDefinitions`
2882
+ * TODO: [🏢] Allow to expect something inside JSON objects and other formats
2883
+ */
2884
+
2885
+ /**
2886
+ * Definition for any text - this will be always valid
2887
+ *
2888
+ * Note: This is not useful for validation, but for splitting and mapping with `subvalueDefinitions`
2889
+ *
2890
+ * @public exported from `@promptbook/core`
2891
+ */
2892
+ var TextFormatDefinition = {
2893
+ formatName: 'TEXT',
2894
+ isValid: function (value) {
2895
+ return typeof value === 'string';
2896
+ },
2897
+ canBeValid: function (partialValue) {
2898
+ return typeof partialValue === 'string';
2899
+ },
2900
+ heal: function () {
2901
+ throw new UnexpectedError('It does not make sense to call `TextFormatDefinition.heal`');
2902
+ },
2903
+ subvalueDefinitions: [
2904
+ {
2905
+ subvalueName: 'LINE',
2906
+ mapValues: function (value, outputParameterName, settings, mapCallback) {
2907
+ return __awaiter(this, void 0, void 0, function () {
2908
+ var lines, mappedLines;
2909
+ return __generator(this, function (_a) {
2910
+ switch (_a.label) {
2911
+ case 0:
2912
+ lines = value.split('\n');
2913
+ return [4 /*yield*/, Promise.all(lines.map(function (lineContent, lineNumber) {
2914
+ // TODO: [🧠] Maybe option to skip empty line
2915
+ /* not await */ return mapCallback({
2916
+ lineContent: lineContent,
2917
+ // TODO: [🧠] Maybe also put here `lineNumber`
2918
+ }, lineNumber);
2919
+ }))];
2920
+ case 1:
2921
+ mappedLines = _a.sent();
2922
+ return [2 /*return*/, mappedLines.join('\n')];
2923
+ }
2924
+ });
2925
+ });
2926
+ },
2927
+ },
2928
+ // <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
2929
+ ],
2930
+ };
2931
+ /**
2932
+ * TODO: [1] Make type for XML Text and Schema
2933
+ * TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
2934
+ * TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
2935
+ * TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
2936
+ * TODO: [🍓] In `TextFormatDefinition` implement `heal
2937
+ * TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
2938
+ * TODO: [🏢] Allow to expect something inside each item of list and other formats
2939
+ */
2940
+
2941
+ /**
2942
+ * Definition for XML format
2943
+ *
2944
+ * @private still in development [🏢]
2945
+ */
2946
+ var XmlFormatDefinition = {
2947
+ formatName: 'XML',
2948
+ mimeType: 'application/xml',
2949
+ isValid: function (value, settings, schema) {
2950
+ TODO_USE(value /* <- TODO: Use value here */);
2951
+ TODO_USE(settings /* <- TODO: Use settings here */);
2952
+ TODO_USE(schema /* <- TODO: Use schema here */);
2953
+ return true;
2954
+ },
2955
+ canBeValid: function (partialValue, settings, schema) {
2956
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2957
+ TODO_USE(settings /* <- TODO: Use settings here */);
2958
+ TODO_USE(schema /* <- TODO: Use schema here */);
2959
+ return true;
2960
+ },
2961
+ heal: function (value, settings, schema) {
2962
+ TODO_USE(value /* <- TODO: Use partialValue here */);
2963
+ TODO_USE(settings /* <- TODO: Use settings here */);
2964
+ TODO_USE(schema /* <- TODO: Use schema here */);
2965
+ throw new Error('Not implemented');
2966
+ },
2967
+ subvalueDefinitions: [],
2968
+ };
2969
+ /**
2970
+ * TODO: [🧠] Maybe propper instance of object
2971
+ * TODO: [0] Make string_serialized_xml
2972
+ * TODO: [1] Make type for XML Settings and Schema
2973
+ * TODO: [🧠] What to use for validating XMLs - XSD,...
2974
+ * TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
2975
+ * TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
2976
+ * TODO: [🍓] In `XmlFormatDefinition` implement `heal
2977
+ * TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
2978
+ * TODO: [🏢] Allow to expect something inside XML and other formats
2979
+ */
2980
+
2981
+ /**
2982
+ * Definitions for all formats supported by Promptbook
2983
+ *
2984
+ * @private internal index of `...` <- TODO [🏢]
2985
+ */
2986
+ var FORMAT_DEFINITIONS = [
2987
+ JsonFormatDefinition,
2988
+ XmlFormatDefinition,
2989
+ TextFormatDefinition,
2990
+ CsvFormatDefinition,
2991
+ ];
2992
+
2993
+ /**
2994
+ * Maps available parameters to expected parameters
2995
+ *
2996
+ * The strategy is:
2997
+ * 1) @@@
2998
+ * 2) @@@
2999
+ *
3000
+ * @throws {PipelineExecutionError} @@@
3001
+ * @private within the repository used in `createPipelineExecutor`
3002
+ */
3003
+ function mapAvailableToExpectedParameters(options) {
3004
+ var e_1, _a;
3005
+ var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
3006
+ var availableParametersNames = new Set(Object.keys(availableParameters));
3007
+ var expectedParameterNames = new Set(Object.keys(expectedParameters));
3008
+ var mappedParameters = {};
3009
+ try {
3010
+ // Phase 1️⃣: Matching mapping
3011
+ for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
3012
+ var parameterName = _c.value;
3013
+ // Situation: Parameter is available and expected
3014
+ if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3015
+ mappedParameters[parameterName] = availableParameters[parameterName];
3016
+ // <- Note: [👩‍👩‍👧] Maybe detect parameter collision here?
3017
+ availableParametersNames.delete(parameterName);
3018
+ expectedParameterNames.delete(parameterName);
3019
+ }
3020
+ // Situation: Parameter is available but NOT expected
3021
+ else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
3022
+ // [🐱‍👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
3023
+ }
3024
+ // Situation: Parameter is NOT available BUT expected
3025
+ else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3026
+ // Do nothing here - this will be maybe fixed in the non-matching mapping
3027
+ }
3028
+ }
3029
+ }
3030
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3031
+ finally {
3032
+ try {
3033
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3034
+ }
3035
+ finally { if (e_1) throw e_1.error; }
3036
+ }
3037
+ if (expectedParameterNames.size === 0) {
3038
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3039
+ Object.freeze(mappedParameters);
3040
+ return mappedParameters;
3041
+ }
3042
+ // Phase 2️⃣: Non-matching mapping
3043
+ if (expectedParameterNames.size !== availableParametersNames.size) {
3044
+ 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)
3045
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3046
+ .join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
3047
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3048
+ .join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
3049
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3050
+ .join('\n')), "\n\n "); }));
3051
+ }
3052
+ var expectedParameterNamesArray = Array.from(expectedParameterNames);
3053
+ var availableParametersNamesArray = Array.from(availableParametersNames);
3054
+ for (var i = 0; i < expectedParameterNames.size; i++) {
3055
+ mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
3056
+ }
3057
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3058
+ Object.freeze(mappedParameters);
3059
+ return mappedParameters;
3060
+ }
3061
+
3062
+ /**
3063
+ * Extracts all code blocks from markdown.
3064
+ *
3065
+ * Note: There are multiple simmilar function:
3066
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
3067
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
3068
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
3069
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
3070
+ *
3071
+ * @param markdown any valid markdown
3072
+ * @returns code blocks with language and content
3073
+ * @throws {ParseError} if block is not closed properly
3074
+ * @public exported from `@promptbook/markdown-utils`
3075
+ */
3076
+ function extractAllBlocksFromMarkdown(markdown) {
3077
+ var e_1, _a;
3078
+ var codeBlocks = [];
3079
+ var lines = markdown.split('\n');
3080
+ // Note: [0] Ensure that the last block notated by gt > will be closed
3081
+ lines.push('');
3082
+ var currentCodeBlock = null;
3083
+ try {
3084
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
3085
+ var line = lines_1_1.value;
3086
+ if (line.startsWith('> ') || line === '>') {
3087
+ if (currentCodeBlock === null) {
3088
+ currentCodeBlock = { blockNotation: '>', language: null, content: '' };
3089
+ } /* not else */
3090
+ if (currentCodeBlock.blockNotation === '>') {
3091
+ if (currentCodeBlock.content !== '') {
3092
+ currentCodeBlock.content += '\n';
3093
+ }
3094
+ currentCodeBlock.content += line.slice(2);
3095
+ }
3096
+ }
3097
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
3098
+ codeBlocks.push(currentCodeBlock);
3099
+ currentCodeBlock = null;
3100
+ }
3101
+ /* not else */
3102
+ if (line.startsWith('```')) {
3103
+ var language = line.slice(3).trim() || null;
3104
+ if (currentCodeBlock === null) {
3105
+ currentCodeBlock = { blockNotation: '```', language: language, content: '' };
3106
+ }
3107
+ else {
3108
+ if (language !== null) {
3109
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
3110
+ }
3111
+ codeBlocks.push(currentCodeBlock);
3112
+ currentCodeBlock = null;
3113
+ }
3114
+ }
3115
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
3116
+ if (currentCodeBlock.content !== '') {
3117
+ currentCodeBlock.content += '\n';
3118
+ }
3119
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
3120
+ }
3121
+ }
3122
+ }
3123
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3124
+ finally {
3125
+ try {
3126
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
3127
+ }
3128
+ finally { if (e_1) throw e_1.error; }
3129
+ }
3130
+ if (currentCodeBlock !== null) {
3131
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
3132
+ }
3133
+ return codeBlocks;
3134
+ }
3135
+ /**
3136
+ * TODO: Maybe name for `blockNotation` instead of '```' and '>'
3137
+ */
3138
+
3139
+ /**
3140
+ * Extracts extracts exactly one valid JSON code block
3141
+ *
3142
+ * - When given string is a valid JSON as it is, it just returns it
3143
+ * - When there is no JSON code block the function throws a `ParseError`
3144
+ * - When there are multiple JSON code blocks the function throws a `ParseError`
3145
+ *
3146
+ * Note: It is not important if marked as ```json BUT if it is VALID JSON
3147
+ * Note: There are multiple simmilar function:
3148
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
3149
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
3150
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
3151
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
3152
+ *
3153
+ * @public exported from `@promptbook/markdown-utils`
3154
+ * @throws {ParseError} if there is no valid JSON block in the markdown
3155
+ */
3156
+ function extractJsonBlock(markdown) {
3157
+ if (isValidJsonString(markdown)) {
3158
+ return markdown;
3159
+ }
3160
+ var codeBlocks = extractAllBlocksFromMarkdown(markdown);
3161
+ var jsonBlocks = codeBlocks.filter(function (_a) {
3162
+ var content = _a.content;
3163
+ return isValidJsonString(content);
3164
+ });
3165
+ if (jsonBlocks.length === 0) {
3166
+ throw new Error('There is no valid JSON block in the markdown');
3167
+ }
3168
+ if (jsonBlocks.length > 1) {
3169
+ throw new Error('There are multiple JSON code blocks in the markdown');
3170
+ }
3171
+ return jsonBlocks[0].content;
3172
+ }
3173
+ /**
3174
+ * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
3175
+ * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
3176
+ */
3177
+
3178
+ /**
3179
+ * Just says that the variable is not used but should be kept
3180
+ * No side effects.
3181
+ *
3182
+ * Note: It can be usefull for:
3183
+ *
3184
+ * 1) Suppressing eager optimization of unused imports
3185
+ * 2) Suppressing eslint errors of unused variables in the tests
3186
+ * 3) Keeping the type of the variable for type testing
3187
+ *
3188
+ * @param value any values
3189
+ * @returns void
3190
+ * @private within the repository
3191
+ */
3192
+ function keepUnused() {
3193
+ var valuesToKeep = [];
3194
+ for (var _i = 0; _i < arguments.length; _i++) {
3195
+ valuesToKeep[_i] = arguments[_i];
3196
+ }
3197
+ }
3198
+
3199
+ /**
3200
+ * Replaces parameters in template with values from parameters object
3201
+ *
3202
+ * @param template the template with parameters in {curly} braces
3203
+ * @param parameters the object with parameters
3204
+ * @returns the template with replaced parameters
3205
+ * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
3206
+ * @public exported from `@promptbook/utils`
3207
+ */
3208
+ function replaceParameters(template, parameters) {
3209
+ var e_1, _a;
3210
+ try {
3211
+ for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
3212
+ var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
3213
+ if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
3214
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
3215
+ }
3216
+ else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
3217
+ // TODO: [🍵]
3218
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
3219
+ }
3220
+ }
3221
+ }
3222
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3223
+ finally {
2733
3224
  try {
2734
3225
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2735
3226
  }
@@ -2784,81 +3275,6 @@
2784
3275
  return replacedTemplate;
2785
3276
  }
2786
3277
 
2787
- /**
2788
- * Create difference set of two sets.
2789
- *
2790
- * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
2791
- * @public exported from `@promptbook/utils`
2792
- */
2793
- function difference(a, b, isEqual) {
2794
- var e_1, _a;
2795
- if (isEqual === void 0) { isEqual = function (a, b) { return a === b; }; }
2796
- var diff = new Set();
2797
- var _loop_1 = function (itemA) {
2798
- if (!Array.from(b).some(function (itemB) { return isEqual(itemA, itemB); })) {
2799
- diff.add(itemA);
2800
- }
2801
- };
2802
- try {
2803
- for (var _b = __values(Array.from(a)), _c = _b.next(); !_c.done; _c = _b.next()) {
2804
- var itemA = _c.value;
2805
- _loop_1(itemA);
2806
- }
2807
- }
2808
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2809
- finally {
2810
- try {
2811
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2812
- }
2813
- finally { if (e_1) throw e_1.error; }
2814
- }
2815
- return diff;
2816
- }
2817
- /**
2818
- * TODO: [🧠][💯] Maybe also implement symmetricDifference
2819
- */
2820
-
2821
- /**
2822
- * Creates a new set with all elements that are present in either set
2823
- *
2824
- * @deprecated use new javascript set methods instead @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
2825
- * @public exported from `@promptbook/utils`
2826
- */
2827
- function union() {
2828
- var e_1, _a, e_2, _b;
2829
- var sets = [];
2830
- for (var _i = 0; _i < arguments.length; _i++) {
2831
- sets[_i] = arguments[_i];
2832
- }
2833
- var union = new Set();
2834
- try {
2835
- for (var sets_1 = __values(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
2836
- var set = sets_1_1.value;
2837
- try {
2838
- for (var _c = (e_2 = void 0, __values(Array.from(set))), _d = _c.next(); !_d.done; _d = _c.next()) {
2839
- var item = _d.value;
2840
- union.add(item);
2841
- }
2842
- }
2843
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
2844
- finally {
2845
- try {
2846
- if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
2847
- }
2848
- finally { if (e_2) throw e_2.error; }
2849
- }
2850
- }
2851
- }
2852
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2853
- finally {
2854
- try {
2855
- if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
2856
- }
2857
- finally { if (e_1) throw e_1.error; }
2858
- }
2859
- return union;
2860
- }
2861
-
2862
3278
  /**
2863
3279
  * Counts number of characters in the text
2864
3280
  *
@@ -2948,6 +3364,9 @@
2948
3364
  LINES: countLines,
2949
3365
  PAGES: countPages,
2950
3366
  };
3367
+ /**
3368
+ * TODO: [🧠][🤠] This should be probbably as part of `TextFormatDefinition`
3369
+ */
2951
3370
 
2952
3371
  /**
2953
3372
  * Function checkExpectations will check if the expectations on given value are met
@@ -2969,447 +3388,250 @@
2969
3388
  if (min && amount < min) {
2970
3389
  throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
2971
3390
  } /* not else */
2972
- if (max && amount > max) {
2973
- throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
2974
- }
2975
- }
2976
- }
2977
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2978
- finally {
2979
- try {
2980
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2981
- }
2982
- finally { if (e_1) throw e_1.error; }
2983
- }
2984
- }
2985
- /**
2986
- * TODO: [💝] Unite object for expecting amount and format
2987
- */
2988
-
2989
- /**
2990
- * Just marks a place of place where should be something implemented
2991
- * No side effects.
2992
- *
2993
- * Note: It can be usefull suppressing eslint errors of unused variables
2994
- *
2995
- * @param value any values
2996
- * @returns void
2997
- * @private within the repository
2998
- */
2999
- function TODO_USE() {
3000
- var value = [];
3001
- for (var _i = 0; _i < arguments.length; _i++) {
3002
- value[_i] = arguments[_i];
3003
- }
3004
- }
3005
-
3006
- /**
3007
- * @@@
3008
- *
3009
- * @private internal utility of `createPipelineExecutor`
3010
- */
3011
- function getContextForTemplate(template) {
3012
- return __awaiter(this, void 0, void 0, function () {
3013
- return __generator(this, function (_a) {
3014
- TODO_USE(template);
3015
- return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
3016
- });
3017
- });
3018
- }
3019
-
3020
- /**
3021
- * @@@
3022
- *
3023
- * @private internal utility of `createPipelineExecutor`
3024
- */
3025
- function getKnowledgeForTemplate(options) {
3026
- return __awaiter(this, void 0, void 0, function () {
3027
- var preparedPipeline, template;
3028
- return __generator(this, function (_a) {
3029
- preparedPipeline = options.preparedPipeline, template = options.template;
3030
- // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
3031
- TODO_USE(template);
3032
- return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
3033
- var content = _a.content;
3034
- return "- ".concat(content);
3035
- }).join('\n')];
3036
- });
3037
- });
3038
- }
3039
-
3040
- /**
3041
- * @@@
3042
- *
3043
- * @private internal utility of `createPipelineExecutor`
3044
- */
3045
- function getSamplesForTemplate(template) {
3046
- return __awaiter(this, void 0, void 0, function () {
3047
- return __generator(this, function (_a) {
3048
- // TODO: [♨] Implement Better - use real index and keyword search
3049
- TODO_USE(template);
3050
- return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
3051
- });
3052
- });
3053
- }
3054
-
3055
- /**
3056
- * @@@
3057
- *
3058
- * @private internal utility of `createPipelineExecutor`
3059
- */
3060
- function getReservedParametersForTemplate(options) {
3061
- return __awaiter(this, void 0, void 0, function () {
3062
- var preparedPipeline, template, pipelineIdentification, context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_1, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
3063
- var e_1, _a;
3064
- return __generator(this, function (_b) {
3065
- switch (_b.label) {
3066
- case 0:
3067
- preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
3068
- return [4 /*yield*/, getContextForTemplate(template)];
3069
- case 1:
3070
- context = _b.sent();
3071
- return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
3072
- case 2:
3073
- knowledge = _b.sent();
3074
- return [4 /*yield*/, getSamplesForTemplate(template)];
3075
- case 3:
3076
- samples = _b.sent();
3077
- currentDate = new Date().toISOString();
3078
- modelName = RESERVED_PARAMETER_MISSING_VALUE;
3079
- reservedParameters = {
3080
- content: RESERVED_PARAMETER_RESTRICTED,
3081
- context: context,
3082
- knowledge: knowledge,
3083
- samples: samples,
3084
- currentDate: currentDate,
3085
- modelName: modelName,
3086
- };
3087
- _loop_1 = function (parameterName) {
3088
- if (reservedParameters[parameterName] === undefined) {
3089
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3090
- }
3091
- };
3092
- try {
3093
- // Note: Doublecheck that ALL reserved parameters are defined:
3094
- for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
3095
- parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
3096
- _loop_1(parameterName);
3097
- }
3098
- }
3099
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3100
- finally {
3101
- try {
3102
- if (RESERVED_PARAMETER_NAMES_1_1 && !RESERVED_PARAMETER_NAMES_1_1.done && (_a = RESERVED_PARAMETER_NAMES_1.return)) _a.call(RESERVED_PARAMETER_NAMES_1);
3103
- }
3104
- finally { if (e_1) throw e_1.error; }
3105
- }
3106
- return [2 /*return*/, reservedParameters];
3391
+ if (max && amount > max) {
3392
+ throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
3107
3393
  }
3108
- });
3109
- });
3394
+ }
3395
+ }
3396
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3397
+ finally {
3398
+ try {
3399
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3400
+ }
3401
+ finally { if (e_1) throw e_1.error; }
3402
+ }
3110
3403
  }
3404
+ /**
3405
+ * TODO: [💝] Unite object for expecting amount and format
3406
+ * TODO: [🧠][🤠] This should be part of `TextFormatDefinition`
3407
+ * Note: [💝] and [🤠] are interconnected together
3408
+ */
3111
3409
 
3112
3410
  /**
3113
3411
  * @@@
3114
3412
  *
3115
3413
  * @private internal utility of `createPipelineExecutor`
3116
3414
  */
3117
- function executeTemplate(options) {
3415
+ function executeAttempts(options) {
3118
3416
  return __awaiter(this, void 0, void 0, function () {
3119
- var currentTemplate, preparedPipeline, parametersToPass, tools, llmTools, onProgress, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, $ongoingResult, maxAttempts, jokerParameterNames, preparedContent, _loop_2, attempt, state_1;
3120
- var e_1, _f, _g;
3121
- return __generator(this, function (_h) {
3122
- switch (_h.label) {
3417
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3418
+ return __generator(this, function (_a) {
3419
+ switch (_a.label) {
3123
3420
  case 0:
3124
- currentTemplate = options.currentTemplate, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, llmTools = options.llmTools, onProgress = options.onProgress, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3421
+ 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;
3125
3422
  maxExecutionAttempts = settings.maxExecutionAttempts;
3126
- name = "pipeline-executor-frame-".concat(currentTemplate.name);
3127
- title = currentTemplate.title;
3128
- priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
3129
- return [4 /*yield*/, onProgress({
3130
- name: name,
3131
- title: title,
3132
- isStarted: false,
3133
- isDone: false,
3134
- templateType: currentTemplate.templateType,
3135
- parameterName: currentTemplate.resultingParameterName,
3136
- parameterValue: null,
3137
- // <- [🍸]
3138
- })];
3139
- case 1:
3140
- _h.sent();
3141
- usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3142
- dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
3143
- if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3144
- 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)
3145
- .map(function (name) { return "{".concat(name, "}"); })
3146
- .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3147
- .map(function (name) { return "{".concat(name, "}"); })
3148
- .join(', '), "\n\n "); }));
3149
- }
3150
- _b = (_a = Object).freeze;
3151
- _c = [{}];
3152
- return [4 /*yield*/, getReservedParametersForTemplate({
3153
- preparedPipeline: preparedPipeline,
3154
- template: currentTemplate,
3155
- pipelineIdentification: pipelineIdentification,
3156
- })];
3157
- case 2:
3158
- definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
3159
- definedParameterNames = new Set(Object.keys(definedParameters));
3160
- parameters = {};
3161
- _loop_1 = function (parameterName) {
3162
- // Situation: Parameter is defined and used
3163
- if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3164
- parameters[parameterName] = definedParameters[parameterName];
3165
- }
3166
- // Situation: Parameter is defined but NOT used
3167
- else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
3168
- // Situation: Parameter is NOT defined BUT used
3169
- else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3170
- // Houston, we have a problem
3171
- // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
3172
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3173
- }
3174
- };
3175
- try {
3176
- // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
3177
- for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3178
- parameterName = _e.value;
3179
- _loop_1(parameterName);
3180
- }
3181
- }
3182
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3183
- finally {
3184
- try {
3185
- if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
3186
- }
3187
- finally { if (e_1) throw e_1.error; }
3188
- }
3189
- // 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
3190
- Object.freeze(parameters);
3191
- $ongoingResult = {
3423
+ $ongoingTemplateResult = {
3192
3424
  $result: null,
3193
3425
  $resultString: null,
3194
3426
  $expectError: null,
3195
3427
  $scriptPipelineExecutionErrors: [],
3196
3428
  };
3197
- maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3198
- jokerParameterNames = currentTemplate.jokerParameterNames || [];
3199
- preparedContent = (currentTemplate.preparedContent || '{content}')
3200
- .split('{content}')
3201
- .join(currentTemplate.content);
3202
- _loop_2 = function (attempt) {
3203
- var isJokerAttempt, jokerParameterName, _j, modelRequirements, _k, _l, _m, _o, _p, _q, scriptTools, _r, error_1, e_2_1, _s, _t, _u, functionName, postprocessingError, _v, _w, scriptTools, _x, error_2, e_3_1, e_4_1, error_3;
3204
- var e_2, _y, e_4, _z, e_3, _0;
3205
- return __generator(this, function (_1) {
3206
- switch (_1.label) {
3429
+ _loop_1 = function (attempt) {
3430
+ 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;
3431
+ var e_1, _q, e_3, _r, e_2, _s;
3432
+ return __generator(this, function (_t) {
3433
+ switch (_t.label) {
3207
3434
  case 0:
3208
3435
  isJokerAttempt = attempt < 0;
3209
3436
  jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3210
- // TODO: [🧠] !!!!!! JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3437
+ // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3211
3438
  if (isJokerAttempt && !jokerParameterName) {
3212
3439
  throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3213
3440
  }
3214
- $ongoingResult.$result = null;
3215
- $ongoingResult.$resultString = null;
3216
- $ongoingResult.$expectError = null;
3441
+ $ongoingTemplateResult.$result = null;
3442
+ $ongoingTemplateResult.$resultString = null;
3443
+ $ongoingTemplateResult.$expectError = null;
3217
3444
  if (isJokerAttempt) {
3218
3445
  if (parameters[jokerParameterName] === undefined) {
3219
3446
  throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3220
3447
  // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3221
3448
  }
3222
3449
  else {
3223
- $ongoingResult.$resultString = parameters[jokerParameterName];
3450
+ $ongoingTemplateResult.$resultString = parameters[jokerParameterName];
3224
3451
  }
3225
3452
  }
3226
- _1.label = 1;
3453
+ _t.label = 1;
3227
3454
  case 1:
3228
- _1.trys.push([1, 44, 45, 46]);
3229
- if (!!isJokerAttempt) return [3 /*break*/, 26];
3230
- _j = currentTemplate.templateType;
3231
- switch (_j) {
3455
+ _t.trys.push([1, 43, 44, 45]);
3456
+ if (!!isJokerAttempt) return [3 /*break*/, 25];
3457
+ _b = template.templateType;
3458
+ switch (_b) {
3232
3459
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3233
3460
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3234
- case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3235
- case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3461
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 11];
3462
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 22];
3236
3463
  }
3237
- return [3 /*break*/, 25];
3464
+ return [3 /*break*/, 24];
3238
3465
  case 2:
3239
- $ongoingResult.$resultString = replaceParameters(preparedContent, parameters);
3240
- return [3 /*break*/, 26];
3466
+ $ongoingTemplateResult.$resultString = replaceParameters(preparedContent, parameters);
3467
+ return [3 /*break*/, 25];
3241
3468
  case 3:
3242
- modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (currentTemplate.modelRequirements || {}));
3243
- $ongoingResult.$prompt = {
3244
- title: currentTemplate.title,
3469
+ modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (template.modelRequirements || {}));
3470
+ $ongoingTemplateResult.$prompt = {
3471
+ title: template.title,
3245
3472
  pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3246
3473
  ? preparedPipeline.pipelineUrl
3247
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
3474
+ : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name
3475
+ // <- TODO: Here should be maybe also subformat index to distinguish between same template with different subformat values
3476
+ ),
3248
3477
  parameters: parameters,
3249
3478
  content: preparedContent,
3250
3479
  modelRequirements: modelRequirements,
3251
3480
  expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3252
3481
  var name = _a.name;
3253
- return name === currentTemplate.personaName;
3254
- }) || {})), currentTemplate.expectations),
3255
- format: currentTemplate.format,
3256
- postprocessingFunctionNames: currentTemplate.postprocessingFunctionNames,
3482
+ return name === template.personaName;
3483
+ }) ||
3484
+ {})), template.expectations),
3485
+ format: template.format,
3486
+ postprocessingFunctionNames: template.postprocessingFunctionNames,
3257
3487
  }; // <- TODO: Not very good type guard
3258
- _k = modelRequirements.modelVariant;
3259
- switch (_k) {
3488
+ _c = modelRequirements.modelVariant;
3489
+ switch (_c) {
3260
3490
  case 'CHAT': return [3 /*break*/, 4];
3261
3491
  case 'COMPLETION': return [3 /*break*/, 6];
3262
3492
  case 'EMBEDDING': return [3 /*break*/, 8];
3263
3493
  }
3264
- return [3 /*break*/, 10];
3494
+ return [3 /*break*/, 9];
3265
3495
  case 4:
3266
- _l = $ongoingResult;
3267
- return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingResult.$prompt))];
3496
+ _d = $ongoingTemplateResult;
3497
+ return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3268
3498
  case 5:
3269
- _l.$chatResult = _1.sent();
3499
+ _d.$chatResult = _t.sent();
3270
3500
  // TODO: [🍬] Destroy chatThread
3271
- $ongoingResult.$result = $ongoingResult.$chatResult;
3272
- $ongoingResult.$resultString = $ongoingResult.$chatResult.content;
3273
- return [3 /*break*/, 11];
3501
+ $ongoingTemplateResult.$result = $ongoingTemplateResult.$chatResult;
3502
+ $ongoingTemplateResult.$resultString = $ongoingTemplateResult.$chatResult.content;
3503
+ return [3 /*break*/, 10];
3274
3504
  case 6:
3275
- _m = $ongoingResult;
3276
- return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingResult.$prompt))];
3505
+ _e = $ongoingTemplateResult;
3506
+ return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3277
3507
  case 7:
3278
- _m.$completionResult = _1.sent();
3279
- $ongoingResult.$result = $ongoingResult.$completionResult;
3280
- $ongoingResult.$resultString = $ongoingResult.$completionResult.content;
3281
- return [3 /*break*/, 11];
3282
- case 8:
3283
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3284
- _o = $ongoingResult;
3285
- return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze($ongoingResult.$prompt))];
3286
- case 9:
3287
- // TODO: [🧠] This is weird, embedding model can not be used such a way in the pipeline
3288
- _o.$embeddingResult = _1.sent();
3289
- $ongoingResult.$result = $ongoingResult.$embeddingResult;
3290
- $ongoingResult.$resultString = $ongoingResult.$embeddingResult.content.join(',');
3291
- return [3 /*break*/, 11];
3292
- case 10: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3293
- case 11: return [3 /*break*/, 26];
3294
- case 12:
3508
+ _e.$completionResult = _t.sent();
3509
+ $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
3510
+ $ongoingTemplateResult.$resultString =
3511
+ $ongoingTemplateResult.$completionResult.content;
3512
+ return [3 /*break*/, 10];
3513
+ 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 "); }));
3514
+ 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 "); }));
3515
+ case 10: return [3 /*break*/, 25];
3516
+ case 11:
3295
3517
  if (arrayableToArray(tools.script).length === 0) {
3296
3518
  throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3297
3519
  }
3298
- if (!currentTemplate.contentLanguage) {
3299
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(currentTemplate.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3520
+ if (!template.contentLanguage) {
3521
+ 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 "); }));
3300
3522
  }
3301
- _1.label = 13;
3523
+ _t.label = 12;
3524
+ case 12:
3525
+ _t.trys.push([12, 19, 20, 21]);
3526
+ _f = (e_1 = void 0, __values(arrayableToArray(tools.script))), _g = _f.next();
3527
+ _t.label = 13;
3302
3528
  case 13:
3303
- _1.trys.push([13, 20, 21, 22]);
3304
- _p = (e_2 = void 0, __values(arrayableToArray(tools.script))), _q = _p.next();
3305
- _1.label = 14;
3529
+ if (!!_g.done) return [3 /*break*/, 18];
3530
+ scriptTools = _g.value;
3531
+ _t.label = 14;
3306
3532
  case 14:
3307
- if (!!_q.done) return [3 /*break*/, 19];
3308
- scriptTools = _q.value;
3309
- _1.label = 15;
3310
- case 15:
3311
- _1.trys.push([15, 17, , 18]);
3312
- _r = $ongoingResult;
3533
+ _t.trys.push([14, 16, , 17]);
3534
+ _h = $ongoingTemplateResult;
3313
3535
  return [4 /*yield*/, scriptTools.execute($deepFreeze({
3314
- scriptLanguage: currentTemplate.contentLanguage,
3536
+ scriptLanguage: template.contentLanguage,
3315
3537
  script: preparedContent,
3316
3538
  parameters: parameters,
3317
3539
  }))];
3540
+ case 15:
3541
+ _h.$resultString = _t.sent();
3542
+ return [3 /*break*/, 18];
3318
3543
  case 16:
3319
- _r.$resultString = _1.sent();
3320
- return [3 /*break*/, 19];
3321
- case 17:
3322
- error_1 = _1.sent();
3544
+ error_1 = _t.sent();
3323
3545
  if (!(error_1 instanceof Error)) {
3324
3546
  throw error_1;
3325
3547
  }
3326
3548
  if (error_1 instanceof UnexpectedError) {
3327
3549
  throw error_1;
3328
3550
  }
3329
- $ongoingResult.$scriptPipelineExecutionErrors.push(error_1);
3330
- return [3 /*break*/, 18];
3331
- case 18:
3332
- _q = _p.next();
3333
- return [3 /*break*/, 14];
3334
- case 19: return [3 /*break*/, 22];
3551
+ $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_1);
3552
+ return [3 /*break*/, 17];
3553
+ case 17:
3554
+ _g = _f.next();
3555
+ return [3 /*break*/, 13];
3556
+ case 18: return [3 /*break*/, 21];
3557
+ case 19:
3558
+ e_1_1 = _t.sent();
3559
+ e_1 = { error: e_1_1 };
3560
+ return [3 /*break*/, 21];
3335
3561
  case 20:
3336
- e_2_1 = _1.sent();
3337
- e_2 = { error: e_2_1 };
3338
- return [3 /*break*/, 22];
3339
- case 21:
3340
3562
  try {
3341
- if (_q && !_q.done && (_y = _p.return)) _y.call(_p);
3563
+ if (_g && !_g.done && (_q = _f.return)) _q.call(_f);
3342
3564
  }
3343
- finally { if (e_2) throw e_2.error; }
3565
+ finally { if (e_1) throw e_1.error; }
3344
3566
  return [7 /*endfinally*/];
3345
- case 22:
3346
- if ($ongoingResult.$resultString !== null) {
3347
- return [3 /*break*/, 26];
3567
+ case 21:
3568
+ if ($ongoingTemplateResult.$resultString !== null) {
3569
+ return [3 /*break*/, 25];
3348
3570
  }
3349
- if ($ongoingResult.$scriptPipelineExecutionErrors.length === 1) {
3350
- throw $ongoingResult.$scriptPipelineExecutionErrors[0];
3571
+ if ($ongoingTemplateResult.$scriptPipelineExecutionErrors.length === 1) {
3572
+ throw $ongoingTemplateResult.$scriptPipelineExecutionErrors[0];
3351
3573
  }
3352
3574
  else {
3353
- throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Script execution failed ".concat($ongoingResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingResult.$scriptPipelineExecutionErrors
3575
+ 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
3354
3576
  .map(function (error) { return '- ' + error.message; })
3355
3577
  .join('\n\n')), "\n "); }));
3356
3578
  }
3357
- case 23:
3579
+ case 22:
3358
3580
  if (tools.userInterface === undefined) {
3359
3581
  throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3360
3582
  }
3361
3583
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3362
- _s = $ongoingResult;
3584
+ _j = $ongoingTemplateResult;
3363
3585
  return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3364
- promptTitle: currentTemplate.title,
3365
- promptMessage: replaceParameters(currentTemplate.description || '', parameters),
3586
+ promptTitle: template.title,
3587
+ promptMessage: replaceParameters(template.description || '', parameters),
3366
3588
  defaultValue: replaceParameters(preparedContent, parameters),
3367
3589
  // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3368
3590
  placeholder: undefined,
3369
3591
  priority: priority,
3370
3592
  }))];
3371
- case 24:
3593
+ case 23:
3372
3594
  // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3373
- _s.$resultString = _1.sent();
3374
- return [3 /*break*/, 26];
3375
- case 25: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown execution type \"".concat(currentTemplate.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3595
+ _j.$resultString = _t.sent();
3596
+ return [3 /*break*/, 25];
3597
+ case 24: throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3598
+ case 25:
3599
+ if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 42];
3600
+ _t.label = 26;
3376
3601
  case 26:
3377
- if (!(!isJokerAttempt && currentTemplate.postprocessingFunctionNames)) return [3 /*break*/, 43];
3378
- _1.label = 27;
3602
+ _t.trys.push([26, 40, 41, 42]);
3603
+ _k = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _l = _k.next();
3604
+ _t.label = 27;
3379
3605
  case 27:
3380
- _1.trys.push([27, 41, 42, 43]);
3381
- _t = (e_4 = void 0, __values(currentTemplate.postprocessingFunctionNames)), _u = _t.next();
3382
- _1.label = 28;
3383
- case 28:
3384
- if (!!_u.done) return [3 /*break*/, 40];
3385
- functionName = _u.value;
3606
+ if (!!_l.done) return [3 /*break*/, 39];
3607
+ functionName = _l.value;
3386
3608
  postprocessingError = null;
3387
- _1.label = 29;
3609
+ _t.label = 28;
3610
+ case 28:
3611
+ _t.trys.push([28, 35, 36, 37]);
3612
+ _m = (e_2 = void 0, __values(arrayableToArray(tools.script))), _o = _m.next();
3613
+ _t.label = 29;
3388
3614
  case 29:
3389
- _1.trys.push([29, 36, 37, 38]);
3390
- _v = (e_3 = void 0, __values(arrayableToArray(tools.script))), _w = _v.next();
3391
- _1.label = 30;
3615
+ if (!!_o.done) return [3 /*break*/, 34];
3616
+ scriptTools = _o.value;
3617
+ _t.label = 30;
3392
3618
  case 30:
3393
- if (!!_w.done) return [3 /*break*/, 35];
3394
- scriptTools = _w.value;
3395
- _1.label = 31;
3396
- case 31:
3397
- _1.trys.push([31, 33, , 34]);
3398
- _x = $ongoingResult;
3619
+ _t.trys.push([30, 32, , 33]);
3620
+ _p = $ongoingTemplateResult;
3399
3621
  return [4 /*yield*/, scriptTools.execute({
3400
3622
  scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3401
3623
  script: "".concat(functionName, "(resultString)"),
3402
3624
  parameters: {
3403
- resultString: $ongoingResult.$resultString || '',
3625
+ resultString: $ongoingTemplateResult.$resultString || '',
3404
3626
  // Note: No ...parametersForTemplate, because working with result only
3405
3627
  },
3406
3628
  })];
3407
- case 32:
3408
- _x.$resultString = _1.sent();
3629
+ case 31:
3630
+ _p.$resultString = _t.sent();
3409
3631
  postprocessingError = null;
3410
- return [3 /*break*/, 35];
3411
- case 33:
3412
- error_2 = _1.sent();
3632
+ return [3 /*break*/, 34];
3633
+ case 32:
3634
+ error_2 = _t.sent();
3413
3635
  if (!(error_2 instanceof Error)) {
3414
3636
  throw error_2;
3415
3637
  }
@@ -3417,49 +3639,49 @@
3417
3639
  throw error_2;
3418
3640
  }
3419
3641
  postprocessingError = error_2;
3420
- $ongoingResult.$scriptPipelineExecutionErrors.push(error_2);
3421
- return [3 /*break*/, 34];
3422
- case 34:
3423
- _w = _v.next();
3424
- return [3 /*break*/, 30];
3425
- case 35: return [3 /*break*/, 38];
3642
+ $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_2);
3643
+ return [3 /*break*/, 33];
3644
+ case 33:
3645
+ _o = _m.next();
3646
+ return [3 /*break*/, 29];
3647
+ case 34: return [3 /*break*/, 37];
3648
+ case 35:
3649
+ e_2_1 = _t.sent();
3650
+ e_2 = { error: e_2_1 };
3651
+ return [3 /*break*/, 37];
3426
3652
  case 36:
3427
- e_3_1 = _1.sent();
3428
- e_3 = { error: e_3_1 };
3429
- return [3 /*break*/, 38];
3430
- case 37:
3431
3653
  try {
3432
- if (_w && !_w.done && (_0 = _v.return)) _0.call(_v);
3654
+ if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3433
3655
  }
3434
- finally { if (e_3) throw e_3.error; }
3656
+ finally { if (e_2) throw e_2.error; }
3435
3657
  return [7 /*endfinally*/];
3436
- case 38:
3658
+ case 37:
3437
3659
  if (postprocessingError) {
3438
3660
  throw postprocessingError;
3439
3661
  }
3440
- _1.label = 39;
3441
- case 39:
3442
- _u = _t.next();
3443
- return [3 /*break*/, 28];
3444
- case 40: return [3 /*break*/, 43];
3662
+ _t.label = 38;
3663
+ case 38:
3664
+ _l = _k.next();
3665
+ return [3 /*break*/, 27];
3666
+ case 39: return [3 /*break*/, 42];
3667
+ case 40:
3668
+ e_3_1 = _t.sent();
3669
+ e_3 = { error: e_3_1 };
3670
+ return [3 /*break*/, 42];
3445
3671
  case 41:
3446
- e_4_1 = _1.sent();
3447
- e_4 = { error: e_4_1 };
3448
- return [3 /*break*/, 43];
3449
- case 42:
3450
3672
  try {
3451
- if (_u && !_u.done && (_z = _t.return)) _z.call(_t);
3673
+ if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3452
3674
  }
3453
- finally { if (e_4) throw e_4.error; }
3675
+ finally { if (e_3) throw e_3.error; }
3454
3676
  return [7 /*endfinally*/];
3455
- case 43:
3677
+ case 42:
3456
3678
  // TODO: [💝] Unite object for expecting amount and format
3457
- if (currentTemplate.format) {
3458
- if (currentTemplate.format === 'JSON') {
3459
- if (!isValidJsonString($ongoingResult.$resultString || '')) {
3679
+ if (template.format) {
3680
+ if (template.format === 'JSON') {
3681
+ if (!isValidJsonString($ongoingTemplateResult.$resultString || '')) {
3460
3682
  // TODO: [🏢] Do more universally via `FormatDefinition`
3461
3683
  try {
3462
- $ongoingResult.$resultString = extractJsonBlock($ongoingResult.$resultString || '');
3684
+ $ongoingTemplateResult.$resultString = extractJsonBlock($ongoingTemplateResult.$resultString || '');
3463
3685
  }
3464
3686
  catch (error) {
3465
3687
  keepUnused(error);
@@ -3469,49 +3691,51 @@
3469
3691
  }
3470
3692
  }
3471
3693
  else {
3472
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Unknown format \"".concat(currentTemplate.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3694
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3473
3695
  }
3474
3696
  }
3475
3697
  // TODO: [💝] Unite object for expecting amount and format
3476
- if (currentTemplate.expectations) {
3477
- checkExpectations(currentTemplate.expectations, $ongoingResult.$resultString || '');
3698
+ if (template.expectations) {
3699
+ checkExpectations(template.expectations, $ongoingTemplateResult.$resultString || '');
3478
3700
  }
3479
3701
  return [2 /*return*/, "break-attempts"];
3480
- case 44:
3481
- error_3 = _1.sent();
3702
+ case 43:
3703
+ error_3 = _t.sent();
3482
3704
  if (!(error_3 instanceof ExpectError)) {
3483
3705
  throw error_3;
3484
3706
  }
3485
- $ongoingResult.$expectError = error_3;
3486
- return [3 /*break*/, 46];
3487
- case 45:
3707
+ $ongoingTemplateResult.$expectError = error_3;
3708
+ return [3 /*break*/, 45];
3709
+ case 44:
3488
3710
  if (!isJokerAttempt &&
3489
- currentTemplate.templateType === 'PROMPT_TEMPLATE' &&
3490
- $ongoingResult.$prompt
3711
+ template.templateType === 'PROMPT_TEMPLATE' &&
3712
+ $ongoingTemplateResult.$prompt
3491
3713
  // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
3492
3714
  // In that case we don’t want to make a report about it because it’s not a llm execution error
3493
3715
  ) {
3494
3716
  // TODO: [🧠] Maybe put other templateTypes into report
3495
3717
  $executionReport.promptExecutions.push({
3496
- prompt: __assign({}, $ongoingResult.$prompt),
3497
- result: $ongoingResult.$result || undefined,
3498
- error: $ongoingResult.$expectError === null ? undefined : serializeError($ongoingResult.$expectError),
3718
+ prompt: __assign({}, $ongoingTemplateResult.$prompt),
3719
+ result: $ongoingTemplateResult.$result || undefined,
3720
+ error: $ongoingTemplateResult.$expectError === null
3721
+ ? undefined
3722
+ : serializeError($ongoingTemplateResult.$expectError),
3499
3723
  });
3500
3724
  }
3501
3725
  return [7 /*endfinally*/];
3502
- case 46:
3503
- if ($ongoingResult.$expectError !== null && attempt === maxAttempts - 1) {
3726
+ case 45:
3727
+ if ($ongoingTemplateResult.$expectError !== null && attempt === maxAttempts - 1) {
3504
3728
  throw new PipelineExecutionError(spaceTrim.spaceTrim(function (block) {
3505
3729
  var _a, _b, _c;
3506
- return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block(pipelineIdentification), "\n\n ---\n The Prompt:\n ").concat(block((((_a = $ongoingResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
3730
+ 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) || '')
3507
3731
  .split('\n')
3508
3732
  .map(function (line) { return "> ".concat(line); })
3509
- .join('\n')), "\n\n Last error ").concat(((_b = $ongoingResult.$expectError) === null || _b === void 0 ? void 0 : _b.name) || '', ":\n ").concat(block((((_c = $ongoingResult.$expectError) === null || _c === void 0 ? void 0 : _c.message) || '')
3733
+ .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) || '')
3510
3734
  .split('\n')
3511
3735
  .map(function (line) { return "> ".concat(line); })
3512
- .join('\n')), "\n\n Last result:\n ").concat(block($ongoingResult.$resultString === null
3736
+ .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
3513
3737
  ? 'null'
3514
- : $ongoingResult.$resultString
3738
+ : $ongoingTemplateResult.$resultString
3515
3739
  .split('\n')
3516
3740
  .map(function (line) { return "> ".concat(line); })
3517
3741
  .join('\n')), "\n ---\n ");
@@ -3522,36 +3746,322 @@
3522
3746
  });
3523
3747
  };
3524
3748
  attempt = -jokerParameterNames.length;
3525
- _h.label = 3;
3749
+ _a.label = 1;
3750
+ case 1:
3751
+ if (!(attempt < maxAttempts)) return [3 /*break*/, 4];
3752
+ return [5 /*yield**/, _loop_1(attempt)];
3753
+ case 2:
3754
+ state_1 = _a.sent();
3755
+ switch (state_1) {
3756
+ case "break-attempts": return [3 /*break*/, 4];
3757
+ }
3758
+ _a.label = 3;
3759
+ case 3:
3760
+ attempt++;
3761
+ return [3 /*break*/, 1];
3762
+ case 4:
3763
+ if ($ongoingTemplateResult.$resultString === null) {
3764
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3765
+ }
3766
+ return [2 /*return*/, $ongoingTemplateResult.$resultString];
3767
+ }
3768
+ });
3769
+ });
3770
+ }
3771
+ /**
3772
+ * TODO: Break into smaller functions
3773
+ */
3774
+
3775
+ /**
3776
+ * @@@
3777
+ *
3778
+ * @private internal utility of `createPipelineExecutor`
3779
+ */
3780
+ function executeFormatSubvalues(options) {
3781
+ return __awaiter(this, void 0, void 0, function () {
3782
+ var template, jokerParameterNames, parameters, priority, pipelineIdentification, settings, parameterValue, formatDefinition, subvalueDefinition, formatSettings, resultString;
3783
+ var _this = this;
3784
+ return __generator(this, function (_a) {
3785
+ switch (_a.label) {
3786
+ case 0:
3787
+ template = options.template, jokerParameterNames = options.jokerParameterNames, parameters = options.parameters, priority = options.priority, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
3788
+ if (template.foreach === undefined) {
3789
+ return [2 /*return*/, /* not await */ executeAttempts(options)];
3790
+ }
3791
+ if (jokerParameterNames.length !== 0) {
3792
+ 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 "); }));
3793
+ }
3794
+ parameterValue = parameters[template.foreach.parameterName] || '';
3795
+ formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
3796
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(template.foreach.formatName);
3797
+ });
3798
+ if (formatDefinition === undefined) {
3799
+ throw new UnexpectedError(
3800
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
3801
+ 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; })
3802
+ .map(function (formatName) { return "- ".concat(formatName); })
3803
+ .join('\n')), "\n\n [\u26F7] This should never happen because format name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
3804
+ }
3805
+ subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
3806
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(template.foreach.subformatName);
3807
+ });
3808
+ if (subvalueDefinition === undefined) {
3809
+ throw new UnexpectedError(
3810
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
3811
+ 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
3812
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
3813
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
3814
+ .join('\n')), "\n\n [\u26F7] This should never happen because subformat name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
3815
+ }
3816
+ if (formatDefinition.formatName === 'CSV') {
3817
+ formatSettings = settings.csvSettings;
3818
+ // <- TODO: [🤹‍♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
3819
+ }
3820
+ return [4 /*yield*/, subvalueDefinition.mapValues(parameterValue, template.foreach.outputSubparameterName, formatSettings, function (subparameters, index) { return __awaiter(_this, void 0, void 0, function () {
3821
+ var mappedParameters, allSubparameters, subresultString;
3822
+ return __generator(this, function (_a) {
3823
+ switch (_a.label) {
3824
+ case 0:
3825
+ // TODO: [🤹‍♂️][🪂] Limit to N concurrent executions
3826
+ // TODO: When done [🐚] Report progress also for each subvalue here
3827
+ try {
3828
+ mappedParameters = mapAvailableToExpectedParameters({
3829
+ expectedParameters: Object.fromEntries(template.foreach.inputSubparameterNames.map(function (subparameterName) { return [subparameterName, null]; })),
3830
+ availableParameters: subparameters,
3831
+ });
3832
+ }
3833
+ catch (error) {
3834
+ if (!(error instanceof PipelineExecutionError)) {
3835
+ throw error;
3836
+ }
3837
+ 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 "); }));
3838
+ }
3839
+ allSubparameters = __assign(__assign({}, parameters), mappedParameters);
3840
+ // 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
3841
+ Object.freeze(allSubparameters);
3842
+ 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 "); }) }))];
3843
+ case 1:
3844
+ subresultString = _a.sent();
3845
+ return [2 /*return*/, subresultString];
3846
+ }
3847
+ });
3848
+ }); })];
3849
+ case 1:
3850
+ resultString = _a.sent();
3851
+ return [2 /*return*/, resultString];
3852
+ }
3853
+ });
3854
+ });
3855
+ }
3856
+
3857
+ /**
3858
+ * @@@
3859
+ *
3860
+ * @private internal utility of `createPipelineExecutor`
3861
+ */
3862
+ function getContextForTemplate(template) {
3863
+ return __awaiter(this, void 0, void 0, function () {
3864
+ return __generator(this, function (_a) {
3865
+ TODO_USE(template);
3866
+ return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
3867
+ });
3868
+ });
3869
+ }
3870
+
3871
+ /**
3872
+ * @@@
3873
+ *
3874
+ * @private internal utility of `createPipelineExecutor`
3875
+ */
3876
+ function getKnowledgeForTemplate(options) {
3877
+ return __awaiter(this, void 0, void 0, function () {
3878
+ var preparedPipeline, template;
3879
+ return __generator(this, function (_a) {
3880
+ preparedPipeline = options.preparedPipeline, template = options.template;
3881
+ // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
3882
+ TODO_USE(template);
3883
+ return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
3884
+ var content = _a.content;
3885
+ return "- ".concat(content);
3886
+ }).join('\n')];
3887
+ });
3888
+ });
3889
+ }
3890
+
3891
+ /**
3892
+ * @@@
3893
+ *
3894
+ * @private internal utility of `createPipelineExecutor`
3895
+ */
3896
+ function getSamplesForTemplate(template) {
3897
+ return __awaiter(this, void 0, void 0, function () {
3898
+ return __generator(this, function (_a) {
3899
+ // TODO: [♨] Implement Better - use real index and keyword search
3900
+ TODO_USE(template);
3901
+ return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
3902
+ });
3903
+ });
3904
+ }
3905
+
3906
+ /**
3907
+ * @@@
3908
+ *
3909
+ * @private internal utility of `createPipelineExecutor`
3910
+ */
3911
+ function getReservedParametersForTemplate(options) {
3912
+ return __awaiter(this, void 0, void 0, function () {
3913
+ var preparedPipeline, template, pipelineIdentification, context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_1, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
3914
+ var e_1, _a;
3915
+ return __generator(this, function (_b) {
3916
+ switch (_b.label) {
3917
+ case 0:
3918
+ preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
3919
+ return [4 /*yield*/, getContextForTemplate(template)];
3920
+ case 1:
3921
+ context = _b.sent();
3922
+ return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
3923
+ case 2:
3924
+ knowledge = _b.sent();
3925
+ return [4 /*yield*/, getSamplesForTemplate(template)];
3526
3926
  case 3:
3527
- if (!(attempt < maxAttempts)) return [3 /*break*/, 6];
3528
- return [5 /*yield**/, _loop_2(attempt)];
3529
- case 4:
3530
- state_1 = _h.sent();
3531
- switch (state_1) {
3532
- case "break-attempts": return [3 /*break*/, 6];
3927
+ samples = _b.sent();
3928
+ currentDate = new Date().toISOString();
3929
+ modelName = RESERVED_PARAMETER_MISSING_VALUE;
3930
+ reservedParameters = {
3931
+ content: RESERVED_PARAMETER_RESTRICTED,
3932
+ context: context,
3933
+ knowledge: knowledge,
3934
+ samples: samples,
3935
+ currentDate: currentDate,
3936
+ modelName: modelName,
3937
+ };
3938
+ _loop_1 = function (parameterName) {
3939
+ if (reservedParameters[parameterName] === undefined) {
3940
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3941
+ }
3942
+ };
3943
+ try {
3944
+ // Note: Doublecheck that ALL reserved parameters are defined:
3945
+ for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
3946
+ parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
3947
+ _loop_1(parameterName);
3948
+ }
3533
3949
  }
3534
- _h.label = 5;
3535
- case 5:
3536
- attempt++;
3537
- return [3 /*break*/, 3];
3538
- case 6:
3539
- //------------------------------------
3540
- /*
3541
-
3542
-
3543
-
3544
-
3545
-
3546
-
3547
-
3548
-
3549
-
3550
- */
3551
- //------------------------------------
3552
- if ($ongoingResult.$resultString === null) {
3553
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
3950
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3951
+ finally {
3952
+ try {
3953
+ if (RESERVED_PARAMETER_NAMES_1_1 && !RESERVED_PARAMETER_NAMES_1_1.done && (_a = RESERVED_PARAMETER_NAMES_1.return)) _a.call(RESERVED_PARAMETER_NAMES_1);
3954
+ }
3955
+ finally { if (e_1) throw e_1.error; }
3956
+ }
3957
+ return [2 /*return*/, reservedParameters];
3958
+ }
3959
+ });
3960
+ });
3961
+ }
3962
+
3963
+ /**
3964
+ * @@@
3965
+ *
3966
+ * @private internal utility of `createPipelineExecutor`
3967
+ */
3968
+ function executeTemplate(options) {
3969
+ return __awaiter(this, void 0, void 0, function () {
3970
+ 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;
3971
+ var e_1, _f, _g;
3972
+ return __generator(this, function (_h) {
3973
+ switch (_h.label) {
3974
+ case 0:
3975
+ currentTemplate = options.currentTemplate, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, llmTools = options.llmTools, onProgress = options.onProgress, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3976
+ maxExecutionAttempts = settings.maxExecutionAttempts;
3977
+ name = "pipeline-executor-frame-".concat(currentTemplate.name);
3978
+ title = currentTemplate.title;
3979
+ priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
3980
+ return [4 /*yield*/, onProgress({
3981
+ name: name,
3982
+ title: title,
3983
+ isStarted: false,
3984
+ isDone: false,
3985
+ templateType: currentTemplate.templateType,
3986
+ parameterName: currentTemplate.resultingParameterName,
3987
+ parameterValue: null,
3988
+ // <- [🍸]
3989
+ })];
3990
+ case 1:
3991
+ _h.sent();
3992
+ usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3993
+ dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
3994
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
3995
+ if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3996
+ 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)
3997
+ .map(function (name) { return "{".concat(name, "}"); })
3998
+ .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3999
+ .map(function (name) { return "{".concat(name, "}"); })
4000
+ .join(', '), "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
4001
+ }
4002
+ _b = (_a = Object).freeze;
4003
+ _c = [{}];
4004
+ return [4 /*yield*/, getReservedParametersForTemplate({
4005
+ preparedPipeline: preparedPipeline,
4006
+ template: currentTemplate,
4007
+ pipelineIdentification: pipelineIdentification,
4008
+ })];
4009
+ case 2:
4010
+ definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
4011
+ definedParameterNames = new Set(Object.keys(definedParameters));
4012
+ parameters = {};
4013
+ _loop_1 = function (parameterName) {
4014
+ // Situation: Parameter is defined and used
4015
+ if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
4016
+ parameters[parameterName] = definedParameters[parameterName];
4017
+ }
4018
+ // Situation: Parameter is defined but NOT used
4019
+ else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
4020
+ // Situation: Parameter is NOT defined BUT used
4021
+ else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
4022
+ // Houston, we have a problem
4023
+ // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
4024
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
4025
+ }
4026
+ };
4027
+ try {
4028
+ // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
4029
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
4030
+ for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
4031
+ parameterName = _e.value;
4032
+ _loop_1(parameterName);
4033
+ }
4034
+ }
4035
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4036
+ finally {
4037
+ try {
4038
+ if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
4039
+ }
4040
+ finally { if (e_1) throw e_1.error; }
3554
4041
  }
4042
+ // 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
4043
+ Object.freeze(parameters);
4044
+ maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
4045
+ jokerParameterNames = currentTemplate.jokerParameterNames || [];
4046
+ preparedContent = (currentTemplate.preparedContent || '{content}')
4047
+ .split('{content}')
4048
+ .join(currentTemplate.content);
4049
+ return [4 /*yield*/, executeFormatSubvalues({
4050
+ jokerParameterNames: jokerParameterNames,
4051
+ priority: priority,
4052
+ maxAttempts: maxAttempts,
4053
+ preparedContent: preparedContent,
4054
+ parameters: parameters,
4055
+ template: currentTemplate,
4056
+ preparedPipeline: preparedPipeline,
4057
+ tools: tools,
4058
+ llmTools: llmTools,
4059
+ settings: settings,
4060
+ $executionReport: $executionReport,
4061
+ pipelineIdentification: pipelineIdentification,
4062
+ })];
4063
+ case 3:
4064
+ resultString = _h.sent();
3555
4065
  return [4 /*yield*/, onProgress({
3556
4066
  name: name,
3557
4067
  title: title,
@@ -3559,13 +4069,15 @@
3559
4069
  isDone: true,
3560
4070
  templateType: currentTemplate.templateType,
3561
4071
  parameterName: currentTemplate.resultingParameterName,
3562
- parameterValue: $ongoingResult.$resultString,
4072
+ parameterValue: resultString,
3563
4073
  // <- [🍸]
3564
4074
  })];
3565
- case 7:
4075
+ case 4:
3566
4076
  _h.sent();
3567
4077
  return [2 /*return*/, Object.freeze((_g = {},
3568
- _g[currentTemplate.resultingParameterName] = $ongoingResult.$resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */,
4078
+ _g[currentTemplate.resultingParameterName] =
4079
+ // <- Note: [👩‍👩‍👧] No need to detect parameter collision here because pipeline checks logic consistency during construction
4080
+ resultString,
3569
4081
  _g))];
3570
4082
  }
3571
4083
  });
@@ -3574,6 +4086,9 @@
3574
4086
  /**
3575
4087
  * TODO: [🤹‍♂️]
3576
4088
  */
4089
+ /**
4090
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4091
+ */
3577
4092
 
3578
4093
  /**
3579
4094
  * @@@
@@ -3594,6 +4109,7 @@
3594
4109
  };
3595
4110
  try {
3596
4111
  // Note: Filter ONLY output parameters
4112
+ // TODO: [👩🏾‍🤝‍👩🏻] Maybe use here `mapAvailableToExpectedParameters`
3597
4113
  for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
3598
4114
  var isOutput = _a.isOutput;
3599
4115
  return isOutput;
@@ -3708,7 +4224,7 @@
3708
4224
  return name === parameterName;
3709
4225
  });
3710
4226
  if (!(parameter === undefined)) return [3 /*break*/, 1];
3711
- 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 "); })));
4227
+ 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 "); })));
3712
4228
  return [3 /*break*/, 4];
3713
4229
  case 1:
3714
4230
  if (!(parameter.isInput === false)) return [3 /*break*/, 4];
@@ -3720,10 +4236,10 @@
3720
4236
  // Note: Wait a short time to prevent race conditions
3721
4237
  _h.sent();
3722
4238
  _h.label = 3;
3723
- 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 "); }), {
4239
+ 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 "); }), {
3724
4240
  isSuccessful: false,
3725
4241
  errors: __spreadArray([
3726
- 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 "); }))
4242
+ 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 "); }))
3727
4243
  ], __read(errors), false).map(serializeError),
3728
4244
  warnings: warnings.map(serializeError),
3729
4245
  executionReport: executionReport,
@@ -3787,7 +4303,7 @@
3787
4303
  case 0:
3788
4304
  if (loopLimit-- < 0) {
3789
4305
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
3790
- throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4306
+ throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
3791
4307
  }
3792
4308
  currentTemplate = unresovedTemplates_1.find(function (template) {
3793
4309
  return template.dependentParameterNames.every(function (name) {
@@ -3797,14 +4313,14 @@
3797
4313
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
3798
4314
  throw new UnexpectedError(
3799
4315
  // TODO: [🐎] DRY
3800
- 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
4316
+ 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
3801
4317
  .map(function (_a) {
3802
4318
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
3803
4319
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
3804
4320
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
3805
4321
  .join(' and '));
3806
4322
  })
3807
- .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 "); }));
4323
+ .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 "); }));
3808
4324
  case 1:
3809
4325
  if (!!currentTemplate) return [3 /*break*/, 3];
3810
4326
  /* [🤹‍♂️] */ return [4 /*yield*/, Promise.race(resolving_1)];
@@ -3821,10 +4337,10 @@
3821
4337
  llmTools: llmTools,
3822
4338
  onProgress: function (progress) {
3823
4339
  if (isReturned) {
3824
- 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)
4340
+ 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)
3825
4341
  .split('\n')
3826
4342
  .map(function (line) { return "> ".concat(line); })
3827
- .join('\n')), "\n "); }));
4343
+ .join('\n')), "\n "); }));
3828
4344
  }
3829
4345
  if (onProgress) {
3830
4346
  onProgress(progress);
@@ -3832,7 +4348,7 @@
3832
4348
  },
3833
4349
  settings: settings,
3834
4350
  $executionReport: executionReport,
3835
- pipelineIdentification: pipelineIdentification,
4351
+ pipelineIdentification: spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Template name: ").concat(currentTemplate.name, "\n Template title: ").concat(currentTemplate.title, "\n "); }),
3836
4352
  })
3837
4353
  .then(function (newParametersToPass) {
3838
4354
  parametersToPass = __assign(__assign({}, newParametersToPass), parametersToPass);
@@ -3841,6 +4357,8 @@
3841
4357
  .then(function () {
3842
4358
  resolving_1 = resolving_1.filter(function (w) { return w !== work_1; });
3843
4359
  });
4360
+ // <- Note: Errors are catched here [3]
4361
+ // TODO: BUT if in multiple templates are errors, only the first one is catched so maybe we should catch errors here and save them to errors array here
3844
4362
  resolving_1.push(work_1);
3845
4363
  _j.label = 4;
3846
4364
  case 4: return [2 /*return*/];
@@ -3922,6 +4440,9 @@
3922
4440
  });
3923
4441
  });
3924
4442
  }
4443
+ /**
4444
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4445
+ */
3925
4446
 
3926
4447
  /**
3927
4448
  * Creates executor function from pipeline and execution tools.
@@ -3933,7 +4454,7 @@
3933
4454
  function createPipelineExecutor(options) {
3934
4455
  var _this = this;
3935
4456
  var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
3936
- 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;
4457
+ 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;
3937
4458
  validatePipeline(pipeline);
3938
4459
  var pipelineIdentification = (function () {
3939
4460
  // Note: This is a 😐 implementation of [🚞]
@@ -3953,9 +4474,11 @@
3953
4474
  else if (isNotPreparedWarningSupressed !== true) {
3954
4475
  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 "); }));
3955
4476
  }
4477
+ var runCount = 0;
3956
4478
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
3957
4479
  return __generator(this, function (_a) {
3958
- return [2 /*return*/, executePipeline({
4480
+ runCount++;
4481
+ return [2 /*return*/, /* not await */ executePipeline({
3959
4482
  pipeline: pipeline,
3960
4483
  preparedPipeline: preparedPipeline,
3961
4484
  setPreparedPipeline: function (newPreparedPipeline) {
@@ -3964,10 +4487,11 @@
3964
4487
  inputParameters: inputParameters,
3965
4488
  tools: tools,
3966
4489
  onProgress: onProgress,
3967
- pipelineIdentification: pipelineIdentification,
4490
+ pipelineIdentification: spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n ").concat(runCount === 1 ? '' : "Run #".concat(runCount), "\n "); }),
3968
4491
  settings: {
3969
4492
  maxExecutionAttempts: maxExecutionAttempts,
3970
4493
  maxParallelCount: maxParallelCount,
4494
+ csvSettings: csvSettings,
3971
4495
  isVerbose: isVerbose,
3972
4496
  isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
3973
4497
  },
@@ -3976,6 +4500,9 @@
3976
4500
  }); };
3977
4501
  return pipelineExecutor;
3978
4502
  }
4503
+ /**
4504
+ * TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
4505
+ */
3979
4506
 
3980
4507
  /**
3981
4508
  * @@@
@@ -4027,7 +4554,7 @@
4027
4554
  outputParameters = result.outputParameters;
4028
4555
  knowledgePiecesRaw = outputParameters.knowledgePieces;
4029
4556
  knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
4030
- // <- TODO: !!!!! Smarter split and filter out empty pieces
4557
+ // <- TODO: [main] !!!!! Smarter split and filter out empty pieces
4031
4558
  if (isVerbose) {
4032
4559
  console.info('knowledgeTextPieces:', knowledgeTextPieces);
4033
4560
  }
@@ -4085,8 +4612,13 @@
4085
4612
  case 6: return [3 /*break*/, 8];
4086
4613
  case 7:
4087
4614
  error_1 = _c.sent();
4615
+ // Note: Here is expected error:
4616
+ // > PipelineExecutionError: You have not provided any `LlmExecutionTools` that support model variant "EMBEDDING
4617
+ if (!(error_1 instanceof PipelineExecutionError)) {
4618
+ throw error_1;
4619
+ }
4088
4620
  // TODO: [🟥] Detect browser / node and make it colorfull
4089
- console.error(error_1);
4621
+ console.error(error_1, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
4090
4622
  return [3 /*break*/, 8];
4091
4623
  case 8: return [2 /*return*/, {
4092
4624
  name: name,
@@ -4107,7 +4639,7 @@
4107
4639
  });
4108
4640
  }
4109
4641
  /**
4110
- * TODO: [🐝][🔼] !!! Export via `@promptbook/markdown`
4642
+ * TODO: [🐝][🔼][main] !!! Export via `@promptbook/markdown`
4111
4643
  * TODO: [🪂] Do it in parallel 11:11
4112
4644
  * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4113
4645
  */
@@ -4131,7 +4663,7 @@
4131
4663
  var partialPieces, pieces;
4132
4664
  return __generator(this, function (_a) {
4133
4665
  switch (_a.label) {
4134
- case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4666
+ case 0: return [4 /*yield*/, prepareKnowledgeFromMarkdown(knowledgeSource.sourceContent, // <- TODO: [🐝][main] !!! Unhardcode markdown, detect which type it is - BE AWARE of big package size
4135
4667
  options)];
4136
4668
  case 1:
4137
4669
  partialPieces = _a.sent();
@@ -4323,7 +4855,7 @@
4323
4855
  });
4324
4856
  }
4325
4857
  /**
4326
- * TODO: [🔃] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4858
+ * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4327
4859
  * TODO: [🏢] !! Check validity of `modelName` in pipeline
4328
4860
  * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4329
4861
  * TODO: [🏢] !! Check validity of `temperature` in pipeline
@@ -4372,7 +4904,7 @@
4372
4904
  case 0:
4373
4905
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
4374
4906
  templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4375
- // TODO: !!!!! Apply samples to each template (if missing and is for the template defined)
4907
+ // TODO: [main] !!!!! Apply samples to each template (if missing and is for the template defined)
4376
4908
  TODO_USE(parameters);
4377
4909
  templatesPrepared = new Array(
4378
4910
  // <- TODO: [🧱] Implement in a functional (not new Class) way
@@ -4404,7 +4936,7 @@
4404
4936
  /**
4405
4937
  * TODO: [🧠] Add context to each template (if missing)
4406
4938
  * TODO: [🧠] What is better name `prepareTemplate` or `prepareTemplateAndParameters`
4407
- * TODO: [♨] !!! Prepare index the samples and maybe templates
4939
+ * TODO: [♨][main] !!! Prepare index the samples and maybe templates
4408
4940
  * TODO: Write tests for `preparePipeline`
4409
4941
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4410
4942
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
@@ -4576,7 +5108,7 @@
4576
5108
  if (sourceContent === '') {
4577
5109
  throw new ParseError("Source is not defined");
4578
5110
  }
4579
- // TODO: !!!! Following checks should be applied every link in the `sourceContent`
5111
+ // TODO: [main] !!!! Following checks should be applied every link in the `sourceContent`
4580
5112
  if (sourceContent.startsWith('http://')) {
4581
5113
  throw new ParseError("Source is not secure");
4582
5114
  }
@@ -4779,7 +5311,7 @@
4779
5311
  if (command.templateType === 'KNOWLEDGE') {
4780
5312
  knowledgeCommandParser.$applyToPipelineJson({
4781
5313
  type: 'KNOWLEDGE',
4782
- sourceContent: $templateJson.content, // <- TODO: [🐝] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
5314
+ sourceContent: $templateJson.content, // <- TODO: [🐝][main] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
4783
5315
  }, $pipelineJson);
4784
5316
  $templateJson.isTemplate = false;
4785
5317
  return;
@@ -5129,6 +5661,171 @@
5129
5661
  * TODO: [🌺] Use some intermediate util splitWords
5130
5662
  */
5131
5663
 
5664
+ /**
5665
+ * @@@
5666
+ *
5667
+ * @param text @@@
5668
+ * @param _isFirstLetterCapital @@@
5669
+ * @returns @@@
5670
+ * @example 'helloWorld'
5671
+ * @example 'iLovePromptbook'
5672
+ * @public exported from `@promptbook/utils`
5673
+ */
5674
+ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
5675
+ var e_1, _a;
5676
+ if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
5677
+ var charType;
5678
+ var lastCharType = null;
5679
+ var normalizedName = '';
5680
+ try {
5681
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5682
+ var char = text_1_1.value;
5683
+ var normalizedChar = void 0;
5684
+ if (/^[a-z]$/.test(char)) {
5685
+ charType = 'LOWERCASE';
5686
+ normalizedChar = char;
5687
+ }
5688
+ else if (/^[A-Z]$/.test(char)) {
5689
+ charType = 'UPPERCASE';
5690
+ normalizedChar = char.toLowerCase();
5691
+ }
5692
+ else if (/^[0-9]$/.test(char)) {
5693
+ charType = 'NUMBER';
5694
+ normalizedChar = char;
5695
+ }
5696
+ else {
5697
+ charType = 'OTHER';
5698
+ normalizedChar = '';
5699
+ }
5700
+ if (!lastCharType) {
5701
+ if (_isFirstLetterCapital) {
5702
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
5703
+ }
5704
+ }
5705
+ else if (charType !== lastCharType &&
5706
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
5707
+ !(lastCharType === 'NUMBER') &&
5708
+ !(charType === 'NUMBER')) {
5709
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
5710
+ }
5711
+ normalizedName += normalizedChar;
5712
+ lastCharType = charType;
5713
+ }
5714
+ }
5715
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5716
+ finally {
5717
+ try {
5718
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
5719
+ }
5720
+ finally { if (e_1) throw e_1.error; }
5721
+ }
5722
+ return normalizedName;
5723
+ }
5724
+ /**
5725
+ * TODO: [🌺] Use some intermediate util splitWords
5726
+ */
5727
+
5728
+ /**
5729
+ * Removes quotes from a string
5730
+ *
5731
+ * Tip: This is very usefull for post-processing of the result of the LLM model
5732
+ * Note: This function removes only the same quotes from the beginning and the end of the string
5733
+ * Note: There are two simmilar functions:
5734
+ * - `removeQuotes` which removes only bounding quotes
5735
+ * - `unwrapResult` which removes whole introduce sentence
5736
+ *
5737
+ * @param text optionally quoted text
5738
+ * @returns text without quotes
5739
+ * @public exported from `@promptbook/utils`
5740
+ */
5741
+ function removeQuotes(text) {
5742
+ if (text.startsWith('"') && text.endsWith('"')) {
5743
+ return text.slice(1, -1);
5744
+ }
5745
+ if (text.startsWith('\'') && text.endsWith('\'')) {
5746
+ return text.slice(1, -1);
5747
+ }
5748
+ return text;
5749
+ }
5750
+
5751
+ /**
5752
+ * Function `validateParameterName` will @@@
5753
+ *
5754
+ * @param parameterName @@@
5755
+ * @returns @@@
5756
+ * @throws {ParseError} @@@
5757
+ * @private within the repository
5758
+ */
5759
+ function validateParameterName(parameterName) {
5760
+ var e_1, _a;
5761
+ var rawParameterName = parameterName;
5762
+ try {
5763
+ for (var _b = __values([
5764
+ ['`', '`'],
5765
+ ['{', '}'],
5766
+ ['[', ']'],
5767
+ ['(', ')'],
5768
+ ['<', '>'],
5769
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
5770
+ var _d = __read(_c.value, 2), start = _d[0], end = _d[1];
5771
+ if (parameterName.substring(0, 1) === start &&
5772
+ parameterName.substring(parameterName.length - 1, parameterName.length) === end
5773
+ // <- TODO: More universal that 1 character
5774
+ ) {
5775
+ parameterName = parameterName.substring(1, parameterName.length - 1);
5776
+ // <- TODO: More universal that 1 character
5777
+ }
5778
+ }
5779
+ }
5780
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5781
+ finally {
5782
+ try {
5783
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
5784
+ }
5785
+ finally { if (e_1) throw e_1.error; }
5786
+ }
5787
+ // TODO: [🐠] Following try-catch block should be part of common validators logic
5788
+ try {
5789
+ /*
5790
+ Note: We don't need to check for spaces because we are going to normalize the parameter name to camelCase
5791
+ if (parameterName.includes(' ')) {
5792
+ throw new ParseError(`Parameter name cannot contain spaces`);
5793
+ }
5794
+ */
5795
+ if (parameterName.includes('.')) {
5796
+ throw new ParseError("Parameter name cannot contain dots");
5797
+ }
5798
+ if (parameterName.includes('/') || parameterName.includes('\\')) {
5799
+ throw new ParseError("Parameter name cannot contain slashes");
5800
+ }
5801
+ if (parameterName.includes('(') ||
5802
+ parameterName.includes(')') ||
5803
+ parameterName.includes('{') ||
5804
+ parameterName.includes('}') ||
5805
+ parameterName.includes('[') ||
5806
+ parameterName.includes(']')) {
5807
+ throw new ParseError("Parameter name cannot contain braces");
5808
+ }
5809
+ parameterName = removeDiacritics(parameterName);
5810
+ parameterName = removeEmojis(parameterName);
5811
+ parameterName = removeQuotes(parameterName);
5812
+ parameterName = normalizeTo_camelCase(parameterName);
5813
+ if (parameterName === '') {
5814
+ throw new ParseError("Parameter name cannot be empty");
5815
+ }
5816
+ if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
5817
+ throw new ParseError("{".concat(parameterName, "} is a reserved parameter name"));
5818
+ }
5819
+ }
5820
+ catch (error) {
5821
+ if (!(error instanceof ParseError)) {
5822
+ throw error;
5823
+ }
5824
+ 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 "); }));
5825
+ }
5826
+ return parameterName;
5827
+ }
5828
+
5132
5829
  /**
5133
5830
  * Parses the foreach command
5134
5831
  *
@@ -5158,15 +5855,16 @@
5158
5855
  /**
5159
5856
  * Link to discussion
5160
5857
  */
5161
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5858
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/148',
5162
5859
  /**
5163
5860
  * Example usages of the FOREACH command
5164
5861
  */
5165
5862
  examples: [
5166
- 'FOREACH List Line `{customers}` -> `{customer}`',
5167
- 'FOR List Line `{customers}` -> `{customer}`',
5168
- 'EACH List Line `{customers}` -> `{customer}`',
5169
- // <- TODO: [🍭] !!!!!! More
5863
+ 'FOREACH Text Line `{customers}` -> `{customer}`',
5864
+ 'FOREACH Csv Cell `{customers}` -> `{cell}`',
5865
+ 'FOREACH Csv Row `{customers}` -> `{firstName}`, `{lastName}`, `+{email}`',
5866
+ 'FOR Text Line `{customers}` -> `{customer}`',
5867
+ 'EACH Text Line `{customers}` -> `{customer}`',
5170
5868
  ],
5171
5869
  /**
5172
5870
  * Parses the FOREACH command
@@ -5174,55 +5872,75 @@
5174
5872
  parse: function (input) {
5175
5873
  var args = input.args;
5176
5874
  var formatName = normalizeTo_SCREAMING_CASE(args[0] || '');
5177
- var cellName = normalizeTo_SCREAMING_CASE(args[1] || '');
5178
- var parameterNameWrapped = args[2];
5875
+ var subformatName = normalizeTo_SCREAMING_CASE(args[1] || '');
5876
+ var parameterNameArg = args[2] || '';
5179
5877
  var assignSign = args[3];
5180
- var subparameterNameWrapped = args[4];
5181
- if (![
5182
- 'LIST',
5183
- 'CSV',
5184
- // <- TODO: [🏢] Unhardcode formats
5185
- ].includes(formatName)) {
5186
- console.info({ args: args, formatName: formatName });
5187
- throw new Error("Unsupported format \"".concat(formatName, "\""));
5878
+ var formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
5879
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(formatName);
5880
+ });
5881
+ if (formatDefinition === undefined) {
5882
+ 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; })
5883
+ .map(function (formatName) { return "- ".concat(formatName); })
5884
+ .join('\n')), "\n "); }));
5188
5885
  // <- TODO: [🏢] List all supported format names
5189
5886
  }
5190
- if (![
5191
- 'LINE',
5192
- 'ROW',
5193
- 'COLUMN',
5194
- 'CELL',
5195
- // <- TODO: [🏢] Unhardcode format cells
5196
- ].includes(cellName)) {
5197
- console.info({ args: args, cellName: cellName });
5198
- throw new Error("Format ".concat(formatName, " does not support cell \"").concat(cellName, "\""));
5199
- // <- TODO: [🏢] List all supported cell names for the format
5887
+ var subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
5888
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(subformatName);
5889
+ });
5890
+ if (subvalueDefinition === undefined) {
5891
+ 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
5892
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
5893
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
5894
+ .join('\n')), "\n "); }));
5895
+ // <- TODO: [🏢] List all supported subformat names for the format
5200
5896
  }
5201
5897
  if (assignSign !== '->') {
5202
- console.info({ args: args, assignSign: assignSign });
5203
- throw new Error("FOREACH command must have '->' to assign the value to the parameter");
5204
- }
5205
- // TODO: !!!!!! Replace with propper parameter name validation
5206
- if ((parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(0, 1)) !== '{' ||
5207
- (parameterNameWrapped === null || parameterNameWrapped === void 0 ? void 0 : parameterNameWrapped.substring(parameterNameWrapped.length - 1, parameterNameWrapped.length)) !== '}') {
5208
- 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));
5209
- throw new Error("!!!!!! 1 Here will be error (with rules and precise error) from validateParameterName");
5210
- }
5211
- var parameterName = parameterNameWrapped.substring(1, parameterNameWrapped.length - 1);
5212
- // TODO: !!!!!! Replace with propper parameter name validation
5213
- if ((subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(0, 1)) !== '{' ||
5214
- (subparameterNameWrapped === null || subparameterNameWrapped === void 0 ? void 0 : subparameterNameWrapped.substring(subparameterNameWrapped.length - 1, subparameterNameWrapped.length)) !==
5215
- '}') {
5216
- console.info({ args: args, subparameterNameWrapped: subparameterNameWrapped });
5217
- throw new Error("!!!!!! 2 Here will be error (with rules and precise error) from validateParameterName");
5218
- }
5219
- var subparameterName = subparameterNameWrapped.substring(1, subparameterNameWrapped.length - 1);
5898
+ throw new ParseError("FOREACH command must have '->' to assign the value to the parameter");
5899
+ }
5900
+ var parameterName = validateParameterName(parameterNameArg);
5901
+ var outputSubparameterName = null;
5902
+ // TODO: [4] DRY
5903
+ var inputSubparameterNames = args
5904
+ .slice(4)
5905
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
5906
+ .filter(function (parameterName) { return !parameterName.includes('+'); })
5907
+ .filter(function (parameterName) { return parameterName !== ''; })
5908
+ .map(validateParameterName);
5909
+ // TODO: [4] DRY
5910
+ var outputSubparameterNames = args
5911
+ .slice(4)
5912
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
5913
+ .filter(function (parameterName) { return parameterName.includes('+'); })
5914
+ .map(function (parameterName) { return parameterName.split('+').join(''); })
5915
+ .map(validateParameterName);
5916
+ if (outputSubparameterNames.length === 1) {
5917
+ outputSubparameterName = outputSubparameterNames[0];
5918
+ }
5919
+ else if (outputSubparameterNames.length > 1) {
5920
+ throw new ParseError("FOREACH command can not have more than one output subparameter");
5921
+ }
5922
+ if (inputSubparameterNames.length === 0) {
5923
+ throw new ParseError("FOREACH command must have at least one input subparameter");
5924
+ }
5925
+ if (outputSubparameterName === null) {
5926
+ // TODO: Following code should be unhardcoded from here and moved to the format definition
5927
+ if (formatName === 'CSV' && subformatName === 'CELL') {
5928
+ outputSubparameterName = 'newCell';
5929
+ }
5930
+ else if (formatName === 'TEXT' && subformatName === 'LINE') {
5931
+ outputSubparameterName = 'newLine';
5932
+ }
5933
+ else {
5934
+ 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 ")));
5935
+ }
5936
+ }
5220
5937
  return {
5221
5938
  type: 'FOREACH',
5222
5939
  formatName: formatName,
5223
- cellName: cellName,
5940
+ subformatName: subformatName,
5224
5941
  parameterName: parameterName,
5225
- subparameterName: subparameterName,
5942
+ inputSubparameterNames: inputSubparameterNames,
5943
+ outputSubparameterName: outputSubparameterName,
5226
5944
  };
5227
5945
  },
5228
5946
  /**
@@ -5231,11 +5949,17 @@
5231
5949
  * Note: `$` is used to indicate that this function mutates given `templateJson`
5232
5950
  */
5233
5951
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5234
- var formatName = command.formatName, cellName = command.cellName, parameterName = command.parameterName, subparameterName = command.subparameterName;
5235
- // TODO: !!!!!! Detect double use
5236
- // TODO: !!!!!! Detect usage with JOKER and don't allow it
5237
- $templateJson.foreach = { formatName: formatName, cellName: cellName, parameterName: parameterName, subparameterName: subparameterName };
5238
- keepUnused($pipelineJson); // <- TODO: !!!!!! BUT Maybe register subparameter from foreach into parameters of the pipeline
5952
+ var formatName = command.formatName, subformatName = command.subformatName, parameterName = command.parameterName, inputSubparameterNames = command.inputSubparameterNames, outputSubparameterName = command.outputSubparameterName;
5953
+ // TODO: [🍭] Detect double use
5954
+ // TODO: [🍭] Detect usage with JOKER and don't allow it
5955
+ $templateJson.foreach = {
5956
+ formatName: formatName,
5957
+ subformatName: subformatName,
5958
+ parameterName: parameterName,
5959
+ inputSubparameterNames: inputSubparameterNames,
5960
+ outputSubparameterName: outputSubparameterName,
5961
+ };
5962
+ keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
5239
5963
  // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
5240
5964
  },
5241
5965
  /**
@@ -5258,8 +5982,7 @@
5258
5982
  },
5259
5983
  };
5260
5984
  /**
5261
- * TODO: !!!!!! Comment console logs
5262
- * TODO: [🍭] !!!!!! Make .ptbk.md file with examples of the FOREACH command and also with wrong parsing and logic
5985
+ * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
5263
5986
  */
5264
5987
 
5265
5988
  /**
@@ -5369,12 +6092,11 @@
5369
6092
  */
5370
6093
  parse: function (input) {
5371
6094
  var args = input.args;
5372
- // TODO: !!!!!! Replace with propper parameter name validation
5373
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5374
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5375
- throw new ParseError("Invalid joker");
6095
+ if (args.length !== 1) {
6096
+ throw new ParseError("JOKE command expects exactly one parameter name");
5376
6097
  }
5377
- var parameterName = parametersMatch.groups.parameterName;
6098
+ var parameterNameArg = args[0] || '';
6099
+ var parameterName = validateParameterName(parameterNameArg);
5378
6100
  return {
5379
6101
  type: 'JOKER',
5380
6102
  parameterName: parameterName,
@@ -5449,6 +6171,9 @@
5449
6171
  */
5450
6172
  parse: function (input) {
5451
6173
  var args = input.args, normalized = input.normalized;
6174
+ var availableVariantsMessage = spaceTrim__default["default"](function (block) { return "\n Available variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) {
6175
+ return "- ".concat(variantName).concat(variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)');
6176
+ }).join('\n')), "\n "); });
5452
6177
  // TODO: Make this more elegant and dynamically
5453
6178
  if (normalized.startsWith('MODEL_VARIANT')) {
5454
6179
  if (normalized === 'MODEL_VARIANT_CHAT') {
@@ -5464,17 +6189,13 @@
5464
6189
  key: 'modelVariant',
5465
6190
  value: 'COMPLETION',
5466
6191
  };
6192
+ // <- Note: [🤖]
5467
6193
  }
5468
6194
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
5469
- return {
5470
- type: 'MODEL',
5471
- key: 'modelVariant',
5472
- value: 'EMBEDDING',
5473
- };
5474
- // <- Note: [🤖]
6195
+ spaceTrim__default["default"](function (block) { return "\n Embedding model can not be used in pipeline\n\n ".concat(block(availableVariantsMessage), "\n "); });
5475
6196
  }
5476
6197
  else {
5477
- 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 "); }));
6198
+ throw new ParseError(spaceTrim__default["default"](function (block) { return "\n Unknown model variant in command:\n\n ".concat(block(availableVariantsMessage), "\n "); }));
5478
6199
  }
5479
6200
  }
5480
6201
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5599,14 +6320,13 @@
5599
6320
  * Parses the PARAMETER command
5600
6321
  */
5601
6322
  parse: function (input) {
5602
- var normalized = input.normalized, raw = input.raw;
5603
- var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5604
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5605
- throw new ParseError("Invalid parameter");
5606
- }
5607
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5608
- if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5609
- throw new ParseError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
6323
+ var normalized = input.normalized, args = input.args, raw = input.raw;
6324
+ var parameterNameRaw = args.shift() || '';
6325
+ var parameterDescriptionRaw = args.join(' ');
6326
+ // <- TODO: When [🥶] fixed, change to:
6327
+ // > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
6328
+ if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
6329
+ 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 "); }));
5610
6330
  }
5611
6331
  var isInput = normalized.startsWith('INPUT');
5612
6332
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5614,11 +6334,12 @@
5614
6334
  isInput = false;
5615
6335
  isOutput = false;
5616
6336
  }
5617
- // TODO: !!!!!! Add parameter name validation
6337
+ var parameterName = validateParameterName(parameterNameRaw);
6338
+ var parameterDescription = parameterDescriptionRaw.trim() || null;
5618
6339
  return {
5619
6340
  type: 'PARAMETER',
5620
6341
  parameterName: parameterName,
5621
- parameterDescription: parameterDescription.trim() || null,
6342
+ parameterDescription: parameterDescription,
5622
6343
  isInput: isInput,
5623
6344
  isOutput: isOutput,
5624
6345
  };
@@ -5943,6 +6664,7 @@
5943
6664
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5944
6665
  */
5945
6666
  $applyToPipelineJson: function (command, $pipelineJson) {
6667
+ // TODO: Warn if the version is overridden
5946
6668
  $pipelineJson.promptbookVersion = command.promptbookVersion;
5947
6669
  },
5948
6670
  /**
@@ -6425,7 +7147,9 @@
6425
7147
  for (var commandNameSegmentsCount = 0; commandNameSegmentsCount < Math.min(items.length, 3); commandNameSegmentsCount++) {
6426
7148
  var commandNameRaw = items.slice(0, commandNameSegmentsCount + 1).join('_');
6427
7149
  var args = items.slice(commandNameSegmentsCount + 1);
6428
- var rawArgs = raw.substring(commandNameRaw.length).trim();
7150
+ var rawArgs = raw
7151
+ .substring(commandNameRaw.length)
7152
+ .trim();
6429
7153
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6430
7154
  if (command !== null) {
6431
7155
  return command;
@@ -6436,7 +7160,9 @@
6436
7160
  {
6437
7161
  var commandNameRaw = items.slice(-1).join('_');
6438
7162
  var args = items.slice(0, -1); // <- Note: This is probbably not correct
6439
- var rawArgs = raw.substring(0, raw.length - commandNameRaw.length).trim();
7163
+ var rawArgs = raw
7164
+ .substring(0, raw.length - commandNameRaw.length)
7165
+ .trim();
6440
7166
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6441
7167
  if (command !== null) {
6442
7168
  return command;
@@ -6576,7 +7302,7 @@
6576
7302
  function extractOneBlockFromMarkdown(markdown) {
6577
7303
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
6578
7304
  if (codeBlocks.length !== 1) {
6579
- 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 "); }));
7305
+ 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 "); }));
6580
7306
  }
6581
7307
  return codeBlocks[0];
6582
7308
  }
@@ -6763,7 +7489,7 @@
6763
7489
  var $pipelineJson = {
6764
7490
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
6765
7491
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
6766
- promptbookVersion: PROMPTBOOK_VERSION,
7492
+ promptbookVersion: undefined /* <- Note: By default no explicit version */,
6767
7493
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
6768
7494
  parameters: [],
6769
7495
  templates: [],
@@ -7054,7 +7780,7 @@
7054
7780
  return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
7055
7781
  }
7056
7782
  /**
7057
- * TODO: !!!! Warn if used only sync version
7783
+ * TODO: [main] !!!! Warn if used only sync version
7058
7784
  * TODO: [🚞] Report here line/column of error
7059
7785
  * TODO: Use spaceTrim more effectively
7060
7786
  * TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
@@ -7837,7 +8563,7 @@
7837
8563
  }
7838
8564
  }
7839
8565
  /**
7840
- * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
8566
+ * TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
7841
8567
  * TODO: [🧠][💺] Can be done this on type-level?
7842
8568
  */
7843
8569