@promptbook/node 0.67.9 → 0.68.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +2 -2
  2. package/esm/index.es.js +1204 -628
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/promptbook-collection/index.d.ts +7 -16
  5. package/esm/typings/src/_packages/core.index.d.ts +2 -2
  6. package/esm/typings/src/_packages/types.index.d.ts +20 -24
  7. package/esm/typings/src/_packages/utils.index.d.ts +2 -2
  8. package/esm/typings/src/commands/BLOCK/BlockTypes.d.ts +1 -1
  9. package/esm/typings/src/commands/BLOCK/blockCommandParser.d.ts +2 -2
  10. package/esm/typings/src/commands/EXPECT/ExpectCommand.d.ts +14 -6
  11. package/esm/typings/src/commands/EXPECT/expectCommandParser.d.ts +2 -2
  12. package/esm/typings/src/commands/FOREACH/ForeachCommand.d.ts +9 -0
  13. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +14 -0
  14. package/esm/typings/src/commands/{EXPECT/ExpectFormatCommand.d.ts → FORMAT/FormatCommand.d.ts} +2 -2
  15. package/esm/typings/src/commands/FORMAT/formatCommand.test.d.ts +1 -0
  16. package/esm/typings/src/commands/FORMAT/formatCommandParser.d.ts +9 -0
  17. package/esm/typings/src/commands/JOKER/jokerCommandParser.d.ts +2 -2
  18. package/esm/typings/src/commands/KNOWLEDGE/knowledgeCommandParser.d.ts +2 -2
  19. package/esm/typings/src/commands/MODEL/modelCommandParser.d.ts +2 -2
  20. package/esm/typings/src/commands/PARAMETER/parameterCommandParser.d.ts +2 -2
  21. package/esm/typings/src/commands/PERSONA/personaCommandParser.d.ts +2 -2
  22. package/esm/typings/src/commands/POSTPROCESS/postprocessCommandParser.d.ts +2 -2
  23. package/esm/typings/src/commands/PROMPTBOOK_VERSION/promptbookVersionCommandParser.d.ts +2 -2
  24. package/esm/typings/src/commands/URL/urlCommandParser.d.ts +2 -2
  25. package/esm/typings/src/commands/X_ACTION/actionCommandParser.d.ts +2 -2
  26. package/esm/typings/src/commands/X_INSTRUMENT/instrumentCommandParser.d.ts +2 -2
  27. package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +6 -4
  28. package/esm/typings/src/commands/_common/parseCommand.d.ts +1 -1
  29. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +137 -30
  30. package/esm/typings/src/commands/index.d.ts +1 -1
  31. package/esm/typings/src/conversion/pipelineJsonToString.d.ts +1 -1
  32. package/esm/typings/src/conversion/pipelineStringToJson.d.ts +1 -1
  33. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +2 -2
  34. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +2 -2
  35. package/esm/typings/src/conversion/utils/extractParameterNamesFromTemplate.d.ts +14 -0
  36. package/esm/typings/src/conversion/utils/extractParameterNamesFromTemplate.test.d.ts +1 -0
  37. package/esm/typings/src/conversion/utils/extractVariables.d.ts +1 -1
  38. package/esm/typings/src/conversion/utils/stringifyPipelineJson.d.ts +1 -1
  39. package/esm/typings/src/errors/{ParsingError.d.ts → ParseError.d.ts} +5 -2
  40. package/esm/typings/src/errors/index.d.ts +2 -2
  41. package/esm/typings/src/execution/CommonExecutionToolsOptions.d.ts +5 -0
  42. package/esm/typings/src/execution/PromptResult.d.ts +2 -0
  43. package/esm/typings/src/execution/PromptResultUsage.d.ts +1 -1
  44. package/esm/typings/src/execution/createPipelineExecutor.d.ts +1 -1
  45. package/esm/typings/src/knowledge/dialogs/simple-prompt/SimplePromptInterfaceTools.d.ts +1 -1
  46. package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +1 -1
  47. package/esm/typings/src/postprocessing/utils/extractBlock.d.ts +2 -2
  48. package/esm/typings/src/postprocessing/utils/extractJsonBlock.d.ts +3 -3
  49. package/esm/typings/src/prepare/prepareTemplates.d.ts +3 -4
  50. package/esm/typings/src/prepare/unpreparePipeline.d.ts +1 -1
  51. package/esm/typings/src/storage/_common/PromptbookStorage.d.ts +1 -1
  52. package/esm/typings/src/storage/utils/PrefixStorage.d.ts +1 -1
  53. package/esm/typings/src/types/ModelRequirements.d.ts +2 -0
  54. package/esm/typings/src/types/PipelineJson/DialogTemplateJson.d.ts +13 -0
  55. package/esm/typings/src/types/PipelineJson/Expectations.d.ts +1 -1
  56. package/esm/typings/src/types/PipelineJson/KnowledgePieceJson.d.ts +1 -1
  57. package/esm/typings/src/types/PipelineJson/KnowledgeSourceJson.d.ts +1 -1
  58. package/esm/typings/src/types/PipelineJson/{PromptTemplateParameterJson.d.ts → ParameterJson.d.ts} +2 -2
  59. package/esm/typings/src/types/PipelineJson/PersonaJson.d.ts +1 -1
  60. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +10 -5
  61. package/esm/typings/src/types/PipelineJson/PreparationJson.d.ts +1 -1
  62. package/esm/typings/src/types/PipelineJson/PromptTemplateJson.d.ts +20 -9
  63. package/esm/typings/src/types/PipelineJson/{ScriptJson.d.ts → ScriptTemplateJson.d.ts} +4 -4
  64. package/esm/typings/src/types/PipelineJson/SimpleTemplateJson.d.ts +3 -3
  65. package/esm/typings/src/types/PipelineJson/TemplateJson.d.ts +11 -0
  66. package/esm/typings/src/types/PipelineJson/{PromptTemplateJsonCommon.d.ts → TemplateJsonCommon.d.ts} +3 -4
  67. package/esm/typings/src/types/Prompt.d.ts +4 -2
  68. package/esm/typings/src/utils/markdown/addAutoGeneratedSection.d.ts +1 -0
  69. package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +1 -1
  70. package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
  71. package/esm/typings/src/utils/organization/___and___.d.ts +7 -0
  72. package/esm/typings/src/utils/organization/{___.d.ts → ___or___.d.ts} +1 -1
  73. package/esm/typings/src/utils/parseNumber.d.ts +1 -1
  74. package/esm/typings/src/utils/serialization/clonePipeline.d.ts +1 -1
  75. package/package.json +2 -2
  76. package/umd/index.umd.js +1204 -628
  77. package/umd/index.umd.js.map +1 -1
  78. package/esm/typings/src/commands/EXPECT/ExpectAmountCommand.d.ts +0 -17
  79. package/esm/typings/src/conversion/utils/extractParameterNamesFromPromptTemplate.d.ts +0 -14
  80. package/esm/typings/src/types/PipelineJson/LlmTemplateJson.d.ts +0 -27
  81. package/esm/typings/src/types/PipelineJson/PromptDialogJson.d.ts +0 -14
  82. /package/esm/typings/src/{conversion/utils/extractParameterNamesFromPromptTemplate.test.d.ts → commands/FOREACH/foreachCommand.test.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -14,7 +14,7 @@ import * as dotenv from 'dotenv';
14
14
  /**
15
15
  * The version of the Promptbook library
16
16
  */
17
- var PROMPTBOOK_VERSION = '0.67.8';
17
+ var PROMPTBOOK_VERSION = '0.68.0-0';
18
18
  // TODO: !!!! List here all the versions and annotate + put into script
19
19
 
20
20
  /*! *****************************************************************************
@@ -482,7 +482,7 @@ function capitalize(word) {
482
482
  */
483
483
  function pipelineJsonToString(pipelineJson) {
484
484
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
485
- var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, promptbookVersion = pipelineJson.promptbookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, promptTemplates = pipelineJson.promptTemplates;
485
+ var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, promptbookVersion = pipelineJson.promptbookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
486
486
  var pipelineString = "# ".concat(title);
487
487
  if (description) {
488
488
  pipelineString += '\n\n';
@@ -502,7 +502,7 @@ function pipelineJsonToString(pipelineJson) {
502
502
  return isInput;
503
503
  })), _h = _g.next(); !_h.done; _h = _g.next()) {
504
504
  var parameter = _h.value;
505
- commands.push("INPUT PARAMETER ".concat(promptTemplateParameterJsonToString(parameter)));
505
+ commands.push("INPUT PARAMETER ".concat(templateParameterJsonToString(parameter)));
506
506
  }
507
507
  }
508
508
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -518,7 +518,7 @@ function pipelineJsonToString(pipelineJson) {
518
518
  return isOutput;
519
519
  })), _k = _j.next(); !_k.done; _k = _j.next()) {
520
520
  var parameter = _k.value;
521
- commands.push("OUTPUT PARAMETER ".concat(promptTemplateParameterJsonToString(parameter)));
521
+ commands.push("OUTPUT PARAMETER ".concat(templateParameterJsonToString(parameter)));
522
522
  }
523
523
  }
524
524
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
@@ -531,13 +531,13 @@ function pipelineJsonToString(pipelineJson) {
531
531
  pipelineString += '\n\n';
532
532
  pipelineString += commands.map(function (command) { return "- ".concat(command); }).join('\n');
533
533
  try {
534
- for (var promptTemplates_1 = __values(promptTemplates), promptTemplates_1_1 = promptTemplates_1.next(); !promptTemplates_1_1.done; promptTemplates_1_1 = promptTemplates_1.next()) {
535
- var promptTemplate = promptTemplates_1_1.value;
534
+ for (var templates_1 = __values(templates), templates_1_1 = templates_1.next(); !templates_1_1.done; templates_1_1 = templates_1.next()) {
535
+ var template = templates_1_1.value;
536
536
  var
537
537
  /* Note: Not using:> name, */
538
- title_1 = promptTemplate.title, description_1 = promptTemplate.description,
538
+ title_1 = template.title, description_1 = template.description,
539
539
  /* Note: dependentParameterNames, */
540
- jokers = promptTemplate.jokerParameterNames, blockType = promptTemplate.blockType, content = promptTemplate.content, postprocessing = promptTemplate.postprocessingFunctionNames, expectations = promptTemplate.expectations, expectFormat = promptTemplate.expectFormat, resultingParameterName = promptTemplate.resultingParameterName;
540
+ jokers = template.jokerParameterNames, blockType = template.blockType, content = template.content, postprocessing = template.postprocessingFunctionNames, expectations = template.expectations, format = template.format, resultingParameterName = template.resultingParameterName;
541
541
  pipelineString += '\n\n';
542
542
  pipelineString += "## ".concat(title_1);
543
543
  if (description_1) {
@@ -548,7 +548,7 @@ function pipelineJsonToString(pipelineJson) {
548
548
  var commands_1 = [];
549
549
  var contentLanguage = 'text';
550
550
  if (blockType === 'PROMPT_TEMPLATE') {
551
- var modelRequirements = promptTemplate.modelRequirements;
551
+ var modelRequirements = template.modelRequirements;
552
552
  var _l = modelRequirements || {}, modelName = _l.modelName, modelVariant = _l.modelVariant;
553
553
  commands_1.push("EXECUTE PROMPT TEMPLATE");
554
554
  if (modelVariant) {
@@ -562,17 +562,17 @@ function pipelineJsonToString(pipelineJson) {
562
562
  commands_1.push("SIMPLE TEMPLATE");
563
563
  // Note: Nothing special here
564
564
  }
565
- else if (blockType === 'SCRIPT') {
565
+ else if (blockType === 'SCRIPT_TEMPLATE') {
566
566
  commands_1.push("EXECUTE SCRIPT");
567
- if (promptTemplate.contentLanguage) {
568
- contentLanguage = promptTemplate.contentLanguage;
567
+ if (template.contentLanguage) {
568
+ contentLanguage = template.contentLanguage;
569
569
  }
570
570
  else {
571
571
  contentLanguage = '';
572
572
  }
573
573
  }
574
- else if (blockType === 'PROMPT_DIALOG') {
575
- commands_1.push("PROMPT DIALOG");
574
+ else if (blockType === 'DIALOG_TEMPLATE') {
575
+ commands_1.push("DIALOG BLOCK");
576
576
  // Note: Nothing special here
577
577
  } // <- }else if([🅱]
578
578
  if (jokers) {
@@ -630,10 +630,10 @@ function pipelineJsonToString(pipelineJson) {
630
630
  finally { if (e_6) throw e_6.error; }
631
631
  }
632
632
  } /* not else */
633
- if (expectFormat) {
634
- if (expectFormat === 'JSON') {
633
+ if (format) {
634
+ if (format === 'JSON') {
635
635
  // TODO: @deprecated remove
636
- commands_1.push("EXPECT JSON");
636
+ commands_1.push("FORMAT JSON");
637
637
  }
638
638
  } /* not else */
639
639
  pipelineString += '\n\n';
@@ -647,13 +647,13 @@ function pipelineJsonToString(pipelineJson) {
647
647
  pipelineString += '\n';
648
648
  pipelineString += '```';
649
649
  pipelineString += '\n\n';
650
- pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: !!! If the parameter here has description, add it and use promptTemplateParameterJsonToString
650
+ pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: !!! If the parameter here has description, add it and use templateParameterJsonToString
651
651
  }
652
652
  }
653
653
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
654
654
  finally {
655
655
  try {
656
- if (promptTemplates_1_1 && !promptTemplates_1_1.done && (_c = promptTemplates_1.return)) _c.call(promptTemplates_1);
656
+ if (templates_1_1 && !templates_1_1.done && (_c = templates_1.return)) _c.call(templates_1);
657
657
  }
658
658
  finally { if (e_3) throw e_3.error; }
659
659
  }
@@ -662,8 +662,8 @@ function pipelineJsonToString(pipelineJson) {
662
662
  /**
663
663
  * @private internal utility of `pipelineJsonToString`
664
664
  */
665
- function promptTemplateParameterJsonToString(promptTemplateParameterJson) {
666
- var name = promptTemplateParameterJson.name, description = promptTemplateParameterJson.description;
665
+ function templateParameterJsonToString(templateParameterJson) {
666
+ var name = templateParameterJson.name, description = templateParameterJson.description;
667
667
  var parameterString = "{".concat(name, "}");
668
668
  if (description) {
669
669
  parameterString = "".concat(parameterString, " ").concat(description);
@@ -671,7 +671,7 @@ function promptTemplateParameterJsonToString(promptTemplateParameterJson) {
671
671
  return parameterString;
672
672
  }
673
673
  /**
674
- * TODO: !!!! Implement new features and commands into `promptTemplateParameterJsonToString`
674
+ * TODO: !!!!!! Implement new features and commands into `templateParameterJsonToString`
675
675
  * TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
676
676
  * TODO: [🏛] Maybe make some markdown builder
677
677
  * TODO: [🏛] Escape all
@@ -874,23 +874,26 @@ function forEachAsync(array, options, callbackfunction) {
874
874
  });
875
875
  }
876
876
 
877
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.67.8",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT"},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}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],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.67.8",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT"},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}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],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.67.8",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT"},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}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],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.67.8",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}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT"},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}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
877
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.68.0-0",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{blockType:"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.68.0-0",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{blockType:"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.68.0-0",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{blockType:"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.68.0-0",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:[{blockType:"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"}];
878
878
 
879
879
  /**
880
880
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
881
881
  *
882
882
  * @public exported from `@promptbook/core`
883
883
  */
884
- var ParsingError = /** @class */ (function (_super) {
885
- __extends(ParsingError, _super);
886
- function ParsingError(message) {
884
+ var ParseError = /** @class */ (function (_super) {
885
+ __extends(ParseError, _super);
886
+ function ParseError(message) {
887
887
  var _this = _super.call(this, message) || this;
888
- _this.name = 'ParsingError';
889
- Object.setPrototypeOf(_this, ParsingError.prototype);
888
+ _this.name = 'ParseError';
889
+ Object.setPrototypeOf(_this, ParseError.prototype);
890
890
  return _this;
891
891
  }
892
- return ParsingError;
892
+ return ParseError;
893
893
  }(Error));
894
+ /**
895
+ * TODO: Maybe split `ParseError` and `ApplyError`
896
+ */
894
897
 
895
898
  /**
896
899
  * This error indicates that the promptbook object has valid syntax but contains logical errors (like circular dependencies)
@@ -1102,12 +1105,12 @@ function validatePipeline(pipeline) {
1102
1105
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
1103
1106
  if (!Array.isArray(pipeline.parameters)) {
1104
1107
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
1105
- throw new ParsingError(spaceTrim(function (block) { return "\n Promptbook is valid JSON but with wrong structure\n\n `promptbook.parameters` expected to be an array, but got ".concat(typeof pipeline.parameters, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1108
+ throw new ParseError(spaceTrim(function (block) { return "\n Promptbook is valid JSON but with wrong structure\n\n `promptbook.parameters` expected to be an array, but got ".concat(typeof pipeline.parameters, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1106
1109
  }
1107
1110
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
1108
- if (!Array.isArray(pipeline.promptTemplates)) {
1111
+ if (!Array.isArray(pipeline.templates)) {
1109
1112
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
1110
- throw new ParsingError(spaceTrim(function (block) { return "\n Promptbook is valid JSON but with wrong structure\n\n `promptbook.promptTemplates` expected to be an array, but got ".concat(typeof pipeline.promptTemplates, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1113
+ throw new ParseError(spaceTrim(function (block) { return "\n Promptbook is valid JSON but with wrong structure\n\n `promptbook.templates` expected to be an array, but got ".concat(typeof pipeline.templates, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1111
1114
  }
1112
1115
  var _loop_1 = function (parameter) {
1113
1116
  if (parameter.isInput && parameter.isOutput) {
@@ -1116,12 +1119,12 @@ function validatePipeline(pipeline) {
1116
1119
  // Note: Testing that parameter is either intermediate or output BUT not created and unused
1117
1120
  if (!parameter.isInput &&
1118
1121
  !parameter.isOutput &&
1119
- !pipeline.promptTemplates.some(function (template) { return template.dependentParameterNames.includes(parameter.name); })) {
1122
+ !pipeline.templates.some(function (template) { return template.dependentParameterNames.includes(parameter.name); })) {
1120
1123
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Parameter {".concat(parameter.name, "} is created but not used\n\n You can declare {").concat(parameter.name, "} as output parameter by adding in the header:\n - OUTPUT PARAMETER `{").concat(parameter.name, "}` ").concat(parameter.description || '', "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
1121
1124
  }
1122
1125
  // Note: Testing that parameter is either input or result of some template
1123
1126
  if (!parameter.isInput &&
1124
- !pipeline.promptTemplates.some(function (template) { return template.resultingParameterName === parameter.name; })) {
1127
+ !pipeline.templates.some(function (template) { return template.resultingParameterName === parameter.name; })) {
1125
1128
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Parameter {".concat(parameter.name, "} is declared but not defined\n\n You can do one of these:\n - Remove declaration of {").concat(parameter.name, "}\n - Add prompt template that results in -> {").concat(parameter.name, "}\n\n ").concat(block(pipelineIdentification), "\n "); }));
1126
1129
  }
1127
1130
  };
@@ -1157,7 +1160,7 @@ function validatePipeline(pipeline) {
1157
1160
  }
1158
1161
  definedParameters.add(template.resultingParameterName);
1159
1162
  if (template.jokerParameterNames && template.jokerParameterNames.length > 0) {
1160
- if (!template.expectFormat &&
1163
+ if (!template.format &&
1161
1164
  !template.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
1162
1165
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Joker parameters are used for {".concat(template.resultingParameterName, "} but no expectations are defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
1163
1166
  }
@@ -1209,7 +1212,7 @@ function validatePipeline(pipeline) {
1209
1212
  };
1210
1213
  try {
1211
1214
  // Note: Checking each template individually
1212
- for (var _f = __values(pipeline.promptTemplates), _g = _f.next(); !_g.done; _g = _f.next()) {
1215
+ for (var _f = __values(pipeline.templates), _g = _f.next(); !_g.done; _g = _f.next()) {
1213
1216
  var template = _g.value;
1214
1217
  _loop_2(template);
1215
1218
  }
@@ -1245,8 +1248,7 @@ function validatePipeline(pipeline) {
1245
1248
  }
1246
1249
  finally { if (e_3) throw e_3.error; }
1247
1250
  }
1248
- var unresovedTemplates = __spreadArray([], __read(pipeline.promptTemplates), false);
1249
- // <- TODO: [🧠][🥜]
1251
+ var unresovedTemplates = __spreadArray([], __read(pipeline.templates), false);
1250
1252
  var loopLimit = LOOP_LIMIT;
1251
1253
  var _loop_3 = function () {
1252
1254
  if (loopLimit-- < 0) {
@@ -1259,14 +1261,14 @@ function validatePipeline(pipeline) {
1259
1261
  if (currentlyResovedTemplates.length === 0) {
1260
1262
  throw new PipelineLogicError(
1261
1263
  // TODO: [🐎] DRY
1262
- spaceTrim(function (block) { return "\n\n Can not resolve some parameters:\n Either you are using a parameter that is not defined, or there are some circular dependencies.\n\n Can not resolve:\n ".concat(block(unresovedTemplates
1264
+ spaceTrim(function (block) { return "\n\n Can not resolve some parameters:\n Either you are using a parameter that is not defined, or there are some circular dependencies.\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates
1263
1265
  .map(function (_a) {
1264
1266
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
1265
1267
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
1266
1268
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
1267
1269
  .join(' and '));
1268
1270
  })
1269
- .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameters.map(function (name) { return "- Parameter {".concat(name, "}"); }).join('\n')), "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1271
+ .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameters.map(function (name) { return "- Parameter {".concat(name, "}"); }).join('\n')), "\n\n\n "); }));
1270
1272
  }
1271
1273
  resovedParameters = __spreadArray(__spreadArray([], __read(resovedParameters), false), __read(currentlyResovedTemplates.map(function (_a) {
1272
1274
  var resultingParameterName = _a.resultingParameterName;
@@ -1366,23 +1368,23 @@ function extractParameterNames(template) {
1366
1368
  * @public exported from `@promptbook/core`
1367
1369
  */
1368
1370
  function unpreparePipeline(pipeline) {
1369
- var personas = pipeline.personas, knowledgeSources = pipeline.knowledgeSources, promptTemplates = pipeline.promptTemplates;
1371
+ var personas = pipeline.personas, knowledgeSources = pipeline.knowledgeSources, templates = pipeline.templates;
1370
1372
  personas = personas.map(function (persona) { return (__assign(__assign({}, persona), { modelRequirements: undefined, preparationIds: undefined })); });
1371
1373
  knowledgeSources = knowledgeSources.map(function (knowledgeSource) { return (__assign(__assign({}, knowledgeSource), { preparationIds: undefined })); });
1372
- promptTemplates = promptTemplates.map(function (promptTemplate) {
1373
- var dependentParameterNames = promptTemplate.dependentParameterNames;
1374
- var parameterNames = extractParameterNames(promptTemplate.preparedContent || '');
1374
+ templates = templates.map(function (template) {
1375
+ var dependentParameterNames = template.dependentParameterNames;
1376
+ var parameterNames = extractParameterNames(template.preparedContent || '');
1375
1377
  dependentParameterNames = dependentParameterNames.filter(function (dependentParameterName) { return !parameterNames.has(dependentParameterName); });
1376
- var promptTemplateUnprepared = __assign(__assign({}, promptTemplate), { dependentParameterNames: dependentParameterNames });
1377
- delete promptTemplateUnprepared.preparedContent;
1378
- return promptTemplateUnprepared;
1378
+ var templateUnprepared = __assign(__assign({}, template), { dependentParameterNames: dependentParameterNames });
1379
+ delete templateUnprepared.preparedContent;
1380
+ return templateUnprepared;
1379
1381
  });
1380
- return $asDeeplyFrozenSerializableJson('Unprepared PipelineJson', __assign(__assign({}, pipeline), { promptTemplates: promptTemplates, knowledgeSources: knowledgeSources, knowledgePieces: [], personas: personas, preparations: [] }));
1382
+ return $asDeeplyFrozenSerializableJson('Unprepared PipelineJson', __assign(__assign({}, pipeline), { templates: templates, knowledgeSources: knowledgeSources, knowledgePieces: [], personas: personas, preparations: [] }));
1381
1383
  }
1382
1384
  /**
1383
1385
  * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
1384
1386
  * TODO: Write tests for `preparePipeline`
1385
- * TODO: [🍙] Make some standart order of json properties
1387
+ * TODO: [🍙] Make some standard order of json properties
1386
1388
  */
1387
1389
 
1388
1390
  /**
@@ -1964,7 +1966,7 @@ var ERRORS = {
1964
1966
  LimitReachedError: LimitReachedError,
1965
1967
  NotFoundError: NotFoundError,
1966
1968
  NotYetImplementedError: NotYetImplementedError,
1967
- ParsingError: ParsingError,
1969
+ ParseError: ParseError,
1968
1970
  PipelineExecutionError: PipelineExecutionError,
1969
1971
  PipelineLogicError: PipelineLogicError,
1970
1972
  PipelineUrlError: PipelineUrlError,
@@ -2021,7 +2023,7 @@ function assertsExecutionSuccessful(executionResult) {
2021
2023
  *
2022
2024
  * @param script from which to extract the variables
2023
2025
  * @returns the list of variable names
2024
- * @throws {ParsingError} if the script is invalid
2026
+ * @throws {ParseError} if the script is invalid
2025
2027
  * @public exported from `@promptbook/utils`
2026
2028
  */
2027
2029
  function extractVariables(script) {
@@ -2057,7 +2059,7 @@ function extractVariables(script) {
2057
2059
  if (!(error instanceof Error)) {
2058
2060
  throw error;
2059
2061
  }
2060
- throw new ParsingError(spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.toString()), "}\n "); }));
2062
+ throw new ParseError(spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.toString()), "}\n "); }));
2061
2063
  }
2062
2064
  return variables;
2063
2065
  }
@@ -2068,14 +2070,14 @@ function extractVariables(script) {
2068
2070
  /**
2069
2071
  * Parses the prompt template and returns the set of all used parameters
2070
2072
  *
2071
- * @param promptTemplate the template with used parameters
2073
+ * @param template the template with used parameters
2072
2074
  * @returns the set of parameter names
2073
- * @throws {ParsingError} if the script is invalid
2075
+ * @throws {ParseError} if the script is invalid
2074
2076
  * @public exported from `@promptbook/utils`
2075
2077
  */
2076
- function extractParameterNamesFromPromptTemplate(promptTemplate) {
2078
+ function extractParameterNamesFromTemplate(template) {
2077
2079
  var e_1, _a, e_2, _b, e_3, _c;
2078
- var title = promptTemplate.title, description = promptTemplate.description, blockType = promptTemplate.blockType, content = promptTemplate.content, preparedContent = promptTemplate.preparedContent, jokerParameterNames = promptTemplate.jokerParameterNames;
2080
+ var title = template.title, description = template.description, blockType = template.blockType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames;
2079
2081
  var parameterNames = new Set();
2080
2082
  try {
2081
2083
  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()) {
@@ -2090,7 +2092,7 @@ function extractParameterNamesFromPromptTemplate(promptTemplate) {
2090
2092
  }
2091
2093
  finally { if (e_1) throw e_1.error; }
2092
2094
  }
2093
- if (blockType === 'SCRIPT') {
2095
+ if (blockType === 'SCRIPT_TEMPLATE') {
2094
2096
  try {
2095
2097
  for (var _f = __values(extractVariables(content)), _g = _f.next(); !_g.done; _g = _f.next()) {
2096
2098
  var parameterName = _g.value;
@@ -2468,7 +2470,7 @@ function joinLlmExecutionTools() {
2468
2470
  *
2469
2471
  * @param markdown any valid markdown
2470
2472
  * @returns code blocks with language and content
2471
- * @throws {ParsingError} if block is not closed properly
2473
+ * @throws {ParseError} if block is not closed properly
2472
2474
  * @public exported from `@promptbook/markdown-utils`
2473
2475
  */
2474
2476
  function extractAllBlocksFromMarkdown(markdown) {
@@ -2504,7 +2506,7 @@ function extractAllBlocksFromMarkdown(markdown) {
2504
2506
  }
2505
2507
  else {
2506
2508
  if (language !== null) {
2507
- throw new ParsingError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
2509
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
2508
2510
  }
2509
2511
  codeBlocks.push(currentCodeBlock);
2510
2512
  currentCodeBlock = null;
@@ -2526,7 +2528,7 @@ function extractAllBlocksFromMarkdown(markdown) {
2526
2528
  finally { if (e_1) throw e_1.error; }
2527
2529
  }
2528
2530
  if (currentCodeBlock !== null) {
2529
- throw new ParsingError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
2531
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
2530
2532
  }
2531
2533
  return codeBlocks;
2532
2534
  }
@@ -2538,8 +2540,8 @@ function extractAllBlocksFromMarkdown(markdown) {
2538
2540
  * Extracts extracts exactly one valid JSON code block
2539
2541
  *
2540
2542
  * - When given string is a valid JSON as it is, it just returns it
2541
- * - When there is no JSON code block the function throws a `ParsingError`
2542
- * - When there are multiple JSON code blocks the function throws a `ParsingError`
2543
+ * - When there is no JSON code block the function throws a `ParseError`
2544
+ * - When there are multiple JSON code blocks the function throws a `ParseError`
2543
2545
  *
2544
2546
  * Note: It is not important if marked as ```json BUT if it is VALID JSON
2545
2547
  * Note: There are multiple simmilar function:
@@ -2549,7 +2551,7 @@ function extractAllBlocksFromMarkdown(markdown) {
2549
2551
  * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2550
2552
  *
2551
2553
  * @public exported from `@promptbook/markdown-utils`
2552
- * @throws {ParsingError} if there is no valid JSON block in the markdown
2554
+ * @throws {ParseError} if there is no valid JSON block in the markdown
2553
2555
  */
2554
2556
  function extractJsonBlock(markdown) {
2555
2557
  if (isValidJsonString(markdown)) {
@@ -2588,8 +2590,8 @@ function isPipelinePrepared(pipeline) {
2588
2590
  return false;
2589
2591
  }
2590
2592
  /*
2591
- TODO: [🧠][🍫] `promptTemplates` can not be determined if they are fully prepared SO ignoring them
2592
- > if (!pipeline.promptTemplates.every(({ preparedContent }) => preparedContent === undefined)) {
2593
+ TODO: [🧠][🍫] `templates` can not be determined if they are fully prepared SO ignoring them
2594
+ > if (!pipeline.templates.every(({ preparedContent }) => preparedContent === undefined)) {
2593
2595
  > return false;
2594
2596
  > }
2595
2597
  */
@@ -2976,8 +2978,7 @@ function createPipelineExecutor(options) {
2976
2978
  }
2977
2979
  var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
2978
2980
  // TODO: !!! Extract to separate functions and files - ALL FUNCTIONS BELOW
2979
- function getContextForTemplate(// <- TODO: [🧠][🥜]
2980
- template) {
2981
+ function getContextForTemplate(template) {
2981
2982
  return __awaiter(this, void 0, void 0, function () {
2982
2983
  return __generator(this, function (_a) {
2983
2984
  TODO_USE(template);
@@ -2985,8 +2986,7 @@ function createPipelineExecutor(options) {
2985
2986
  });
2986
2987
  });
2987
2988
  }
2988
- function getKnowledgeForTemplate(// <- TODO: [🧠][🥜]
2989
- template) {
2989
+ function getKnowledgeForTemplate(template) {
2990
2990
  return __awaiter(this, void 0, void 0, function () {
2991
2991
  return __generator(this, function (_a) {
2992
2992
  // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
@@ -2998,8 +2998,7 @@ function createPipelineExecutor(options) {
2998
2998
  });
2999
2999
  });
3000
3000
  }
3001
- function getSamplesForTemplate(// <- TODO: [🧠][🥜]
3002
- template) {
3001
+ function getSamplesForTemplate(template) {
3003
3002
  return __awaiter(this, void 0, void 0, function () {
3004
3003
  return __generator(this, function (_a) {
3005
3004
  // TODO: [♨] Implement Better - use real index and keyword search
@@ -3066,7 +3065,7 @@ function createPipelineExecutor(options) {
3066
3065
  case 0:
3067
3066
  name = "pipeline-executor-frame-".concat(currentTemplate.name);
3068
3067
  title = currentTemplate.title;
3069
- priority = preparedPipeline.promptTemplates.length - preparedPipeline.promptTemplates.indexOf(currentTemplate);
3068
+ priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
3070
3069
  if (!(onProgress !== undefined) /* <- [3] */) return [3 /*break*/, 2]; /* <- [3] */
3071
3070
  progress_1 = {
3072
3071
  name: name,
@@ -3089,7 +3088,7 @@ function createPipelineExecutor(options) {
3089
3088
  _h.sent();
3090
3089
  _h.label = 2;
3091
3090
  case 2:
3092
- usedParameterNames = extractParameterNamesFromPromptTemplate(currentTemplate);
3091
+ usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3093
3092
  dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
3094
3093
  if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3095
3094
  throw new UnexpectedError(spaceTrim(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Dependent parameters:\n ").concat(Array.from(dependentParameterNames)
@@ -3138,13 +3137,13 @@ function createPipelineExecutor(options) {
3138
3137
  result = null;
3139
3138
  resultString = null;
3140
3139
  expectError = null;
3141
- maxAttempts = currentTemplate.blockType === 'PROMPT_DIALOG' ? Infinity : maxExecutionAttempts;
3140
+ maxAttempts = currentTemplate.blockType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3142
3141
  jokerParameterNames = currentTemplate.jokerParameterNames || [];
3143
3142
  preparedContent = (currentTemplate.preparedContent || '{content}')
3144
3143
  .split('{content}')
3145
3144
  .join(currentTemplate.content);
3146
3145
  _loop_5 = function (attempt) {
3147
- var isJokerAttempt, jokerParameterName, _j, _k, _l, _m, scriptTools, error_2, e_5_1, _o, _p, functionName, postprocessingError, _q, _r, scriptTools, error_3, e_6_1, e_7_1, error_4;
3146
+ var isJokerAttempt, jokerParameterName, _j, modelRequirements, _k, _l, _m, scriptTools, error_2, e_5_1, _o, _p, functionName, postprocessingError, _q, _r, scriptTools, error_3, e_6_1, e_7_1, error_4;
3148
3147
  var e_5, _s, e_7, _t, e_6, _u;
3149
3148
  return __generator(this, function (_v) {
3150
3149
  switch (_v.label) {
@@ -3174,14 +3173,15 @@ function createPipelineExecutor(options) {
3174
3173
  switch (_j) {
3175
3174
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3176
3175
  case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3177
- case 'SCRIPT': return [3 /*break*/, 12];
3178
- case 'PROMPT_DIALOG': return [3 /*break*/, 23];
3176
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3177
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3179
3178
  }
3180
3179
  return [3 /*break*/, 25];
3181
3180
  case 2:
3182
3181
  resultString = replaceParameters(preparedContent, parameters);
3183
3182
  return [3 /*break*/, 26];
3184
3183
  case 3:
3184
+ modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (pipeline.defaultModelRequirements || {})), (currentTemplate.modelRequirements || {}));
3185
3185
  prompt = {
3186
3186
  title: currentTemplate.title,
3187
3187
  pipelineUrl: "".concat(preparedPipeline.pipelineUrl
@@ -3189,15 +3189,15 @@ function createPipelineExecutor(options) {
3189
3189
  : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
3190
3190
  parameters: parameters,
3191
3191
  content: preparedContent,
3192
- modelRequirements: currentTemplate.modelRequirements,
3192
+ modelRequirements: modelRequirements,
3193
3193
  expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3194
3194
  var name = _a.name;
3195
3195
  return name === currentTemplate.personaName;
3196
3196
  }) || {})), currentTemplate.expectations),
3197
- expectFormat: currentTemplate.expectFormat,
3197
+ format: currentTemplate.format,
3198
3198
  postprocessingFunctionNames: currentTemplate.postprocessingFunctionNames,
3199
3199
  }; // <- TODO: Not very good type guard
3200
- _k = currentTemplate.modelRequirements.modelVariant;
3200
+ _k = modelRequirements.modelVariant;
3201
3201
  switch (_k) {
3202
3202
  case 'CHAT': return [3 /*break*/, 4];
3203
3203
  case 'COMPLETION': return [3 /*break*/, 6];
@@ -3223,7 +3223,8 @@ function createPipelineExecutor(options) {
3223
3223
  result = embeddingResult;
3224
3224
  resultString = embeddingResult.content.join(',');
3225
3225
  return [3 /*break*/, 11];
3226
- case 10: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n\n "); }));
3226
+ case 10: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown model variant \"".concat(currentTemplate.modelRequirements
3227
+ .modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3227
3228
  case 11: return [3 /*break*/, 26];
3228
3229
  case 12:
3229
3230
  if (arrayableToArray(tools.script).length === 0) {
@@ -3302,7 +3303,7 @@ function createPipelineExecutor(options) {
3302
3303
  priority: priority,
3303
3304
  }))];
3304
3305
  case 24:
3305
- // TODO: [🌹] When making next attempt for `PROMPT DIALOG`, preserve the previous user input
3306
+ // TODO: [🌹] When making next attempt for `DIALOG BLOCK`, preserve the previous user input
3306
3307
  resultString = _v.sent();
3307
3308
  return [3 /*break*/, 26];
3308
3309
  case 25: throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Unknown execution type \"".concat(currentTemplate.blockType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
@@ -3388,8 +3389,8 @@ function createPipelineExecutor(options) {
3388
3389
  return [7 /*endfinally*/];
3389
3390
  case 43:
3390
3391
  // TODO: [💝] Unite object for expecting amount and format
3391
- if (currentTemplate.expectFormat) {
3392
- if (currentTemplate.expectFormat === 'JSON') {
3392
+ if (currentTemplate.format) {
3393
+ if (currentTemplate.format === 'JSON') {
3393
3394
  if (!isValidJsonString(resultString || '')) {
3394
3395
  // TODO: [🏢] Do more universally via `FormatDefinition`
3395
3396
  try {
@@ -3403,7 +3404,7 @@ function createPipelineExecutor(options) {
3403
3404
  }
3404
3405
  }
3405
3406
  else {
3406
- throw new UnexpectedError(spaceTrim(function (block) { return "\n Unknown expectFormat \"".concat(currentTemplate.expectFormat, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3407
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Unknown format \"".concat(currentTemplate.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3407
3408
  }
3408
3409
  }
3409
3410
  // TODO: [💝] Unite object for expecting amount and format
@@ -3679,7 +3680,7 @@ function createPipelineExecutor(options) {
3679
3680
  var name = _a.name;
3680
3681
  return name;
3681
3682
  });
3682
- unresovedTemplates_1 = __spreadArray([], __read(preparedPipeline.promptTemplates), false);
3683
+ unresovedTemplates_1 = __spreadArray([], __read(preparedPipeline.templates), false);
3683
3684
  resolving_1 = [];
3684
3685
  loopLimit = LOOP_LIMIT;
3685
3686
  _loop_2 = function () {
@@ -3800,7 +3801,7 @@ function createPipelineExecutor(options) {
3800
3801
  * TODO: [🧠][🌳] Use here `countTotalUsage` and put preparation and prepared pipiline to report
3801
3802
  * TODO: [🪂] Use maxParallelCount here (not only pass to `preparePipeline`)
3802
3803
  * TODO: [♈] Probbably move expectations from templates to parameters
3803
- * TODO: [🧠] When not meet expectations in PROMPT_DIALOG, make some way to tell the user
3804
+ * TODO: [🧠] When not meet expectations in DIALOG_TEMPLATE, make some way to tell the user
3804
3805
  * TODO: [👧] Strongly type the executors to avoid need of remove nullables whtn noUncheckedIndexedAccess in tsconfig.json
3805
3806
  * Note: CreatePipelineExecutorOptions are just connected to PipelineExecutor so do not extract to types folder
3806
3807
  * TODO: [🧠][3] transparent = (report intermediate parameters) / opaque execution = (report only output parameters) progress reporting mode
@@ -4170,7 +4171,7 @@ function preparePersona(personaDescription, options) {
4170
4171
  */
4171
4172
  function clonePipeline(pipeline) {
4172
4173
  // Note: Not using spread operator (...) because @@@
4173
- var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, promptbookVersion = pipeline.promptbookVersion, description = pipeline.description, parameters = pipeline.parameters, promptTemplates = pipeline.promptTemplates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
4174
+ var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, promptbookVersion = pipeline.promptbookVersion, description = pipeline.description, parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
4174
4175
  return {
4175
4176
  pipelineUrl: pipelineUrl,
4176
4177
  sourceFile: sourceFile,
@@ -4178,7 +4179,7 @@ function clonePipeline(pipeline) {
4178
4179
  promptbookVersion: promptbookVersion,
4179
4180
  description: description,
4180
4181
  parameters: parameters,
4181
- promptTemplates: promptTemplates,
4182
+ templates: templates,
4182
4183
  knowledgeSources: knowledgeSources,
4183
4184
  knowledgePieces: knowledgePieces,
4184
4185
  personas: personas,
@@ -4186,7 +4187,7 @@ function clonePipeline(pipeline) {
4186
4187
  };
4187
4188
  }
4188
4189
  /**
4189
- * TODO: [🍙] Make some standart order of json properties
4190
+ * TODO: [🍙] Make some standard order of json properties
4190
4191
  */
4191
4192
 
4192
4193
  /**
@@ -4196,19 +4197,19 @@ function clonePipeline(pipeline) {
4196
4197
  */
4197
4198
  function prepareTemplates(pipeline, options) {
4198
4199
  return __awaiter(this, void 0, void 0, function () {
4199
- var _a, maxParallelCount, promptTemplates, parameters, knowledgePiecesCount, promptTemplatesPrepared;
4200
+ var _a, maxParallelCount, templates, parameters, knowledgePiecesCount, templatesPrepared;
4200
4201
  var _this = this;
4201
4202
  return __generator(this, function (_b) {
4202
4203
  switch (_b.label) {
4203
4204
  case 0:
4204
4205
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
4205
- promptTemplates = pipeline.promptTemplates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4206
+ templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
4206
4207
  // TODO: !!!!! Apply samples to each template (if missing and is for the template defined)
4207
4208
  TODO_USE(parameters);
4208
- promptTemplatesPrepared = new Array(
4209
+ templatesPrepared = new Array(
4209
4210
  // <- TODO: [🧱] Implement in a functional (not new Class) way
4210
- promptTemplates.length);
4211
- return [4 /*yield*/, forEachAsync(promptTemplates, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (template, index) { return __awaiter(_this, void 0, void 0, function () {
4211
+ templates.length);
4212
+ return [4 /*yield*/, forEachAsync(templates, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (template, index) { return __awaiter(_this, void 0, void 0, function () {
4212
4213
  var dependentParameterNames, preparedContent, preparedTemplate;
4213
4214
  return __generator(this, function (_a) {
4214
4215
  dependentParameterNames = template.dependentParameterNames;
@@ -4221,13 +4222,13 @@ function prepareTemplates(pipeline, options) {
4221
4222
  ], false);
4222
4223
  }
4223
4224
  preparedTemplate = __assign(__assign({}, template), { dependentParameterNames: dependentParameterNames, preparedContent: preparedContent });
4224
- promptTemplatesPrepared[index] = preparedTemplate;
4225
+ templatesPrepared[index] = preparedTemplate;
4225
4226
  return [2 /*return*/];
4226
4227
  });
4227
4228
  }); })];
4228
4229
  case 1:
4229
4230
  _b.sent();
4230
- return [2 /*return*/, { promptTemplatesPrepared: promptTemplatesPrepared }];
4231
+ return [2 /*return*/, { templatesPrepared: templatesPrepared }];
4231
4232
  }
4232
4233
  });
4233
4234
  });
@@ -4240,7 +4241,6 @@ function prepareTemplates(pipeline, options) {
4240
4241
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
4241
4242
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
4242
4243
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
4243
- * TODO: [🧠][🥜]
4244
4244
  */
4245
4245
 
4246
4246
  /**
@@ -4253,12 +4253,12 @@ function prepareTemplates(pipeline, options) {
4253
4253
  */
4254
4254
  function preparePipeline(pipeline, options) {
4255
4255
  return __awaiter(this, void 0, void 0, function () {
4256
- var llmTools, _a, maxParallelCount, _b, isVerbose, parameters, promptTemplates,
4256
+ var llmTools, _a, maxParallelCount, _b, isVerbose, parameters, templates,
4257
4257
  /*
4258
4258
  <- TODO: [🧠][🪑] `promptbookVersion` */
4259
4259
  knowledgeSources /*
4260
4260
  <- TODO: [🧊] `knowledgePieces` */, personas /*
4261
- <- TODO: [🧊] `preparations` */, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, promptTemplatesPrepared /* TODO: parameters: parametersPrepared*/;
4261
+ <- TODO: [🧊] `preparations` */, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, templatesPrepared /* TODO: parameters: parametersPrepared*/;
4262
4262
  var _this = this;
4263
4263
  return __generator(this, function (_c) {
4264
4264
  switch (_c.label) {
@@ -4267,7 +4267,7 @@ function preparePipeline(pipeline, options) {
4267
4267
  return [2 /*return*/, pipeline];
4268
4268
  }
4269
4269
  llmTools = options.llmTools, _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a, _b = options.isVerbose, isVerbose = _b === void 0 ? IS_VERBOSE : _b;
4270
- parameters = pipeline.parameters, promptTemplates = pipeline.promptTemplates, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas;
4270
+ parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas;
4271
4271
  llmToolsWithUsage = countTotalUsage(llmTools);
4272
4272
  currentPreparation = {
4273
4273
  id: 1,
@@ -4313,7 +4313,7 @@ function preparePipeline(pipeline, options) {
4313
4313
  knowledgePiecesPrepared = partialknowledgePiecesPrepared.map(function (piece) { return (__assign(__assign({}, piece), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
4314
4314
  return [4 /*yield*/, prepareTemplates({
4315
4315
  parameters: parameters,
4316
- promptTemplates: promptTemplates,
4316
+ templates: templates,
4317
4317
  knowledgePiecesCount: knowledgePiecesPrepared.length,
4318
4318
  }, {
4319
4319
  llmTools: llmToolsWithUsage,
@@ -4321,11 +4321,11 @@ function preparePipeline(pipeline, options) {
4321
4321
  isVerbose: isVerbose,
4322
4322
  })];
4323
4323
  case 3:
4324
- promptTemplatesPrepared = (_c.sent()).promptTemplatesPrepared;
4324
+ templatesPrepared = (_c.sent()).templatesPrepared;
4325
4325
  // ----- /Templates preparation -----
4326
4326
  // Note: Count total usage
4327
4327
  currentPreparation.usage = llmToolsWithUsage.getTotalUsage();
4328
- return [2 /*return*/, $asDeeplyFrozenSerializableJson('Prepared PipelineJson', __assign(__assign({}, clonePipeline(pipeline)), { promptTemplates: promptTemplatesPrepared, knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, personas: preparedPersonas, preparations: preparations }))];
4328
+ return [2 /*return*/, $asDeeplyFrozenSerializableJson('Prepared PipelineJson', __assign(__assign({}, clonePipeline(pipeline)), { templates: templatesPrepared, knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, personas: preparedPersonas, preparations: preparations }))];
4329
4329
  }
4330
4330
  });
4331
4331
  });
@@ -4379,7 +4379,8 @@ var knowledgeCommandParser = {
4379
4379
  /**
4380
4380
  * BOILERPLATE command can be used in:
4381
4381
  */
4382
- usagePlaces: ['PIPELINE_HEAD'],
4382
+ isUsedInPipelineHead: true,
4383
+ isUsedInPipelineTemplate: false,
4383
4384
  /**
4384
4385
  * Description of the KNOWLEDGE command
4385
4386
  */
@@ -4405,17 +4406,17 @@ var knowledgeCommandParser = {
4405
4406
  var args = input.args;
4406
4407
  var sourceContent = spaceTrim$1(args[0] || '');
4407
4408
  if (sourceContent === '') {
4408
- throw new ParsingError("Source is not defined");
4409
+ throw new ParseError("Source is not defined");
4409
4410
  }
4410
4411
  // TODO: !!!! Following checks should be applied every link in the `sourceContent`
4411
4412
  if (sourceContent.startsWith('http://')) {
4412
- throw new ParsingError("Source is not secure");
4413
+ throw new ParseError("Source is not secure");
4413
4414
  }
4414
4415
  if (!(isValidFilePath(sourceContent) || isValidUrl(sourceContent))) {
4415
- throw new ParsingError("Source not valid");
4416
+ throw new ParseError("Source not valid");
4416
4417
  }
4417
4418
  if (sourceContent.startsWith('../') || sourceContent.startsWith('/') || /^[A-Z]:[\\/]+/i.test(sourceContent)) {
4418
- throw new ParsingError("Source cannot be outside of the .ptbk.md folder");
4419
+ throw new ParseError("Source cannot be outside of the .ptbk.md folder");
4419
4420
  }
4420
4421
  return {
4421
4422
  type: 'KNOWLEDGE',
@@ -4423,194 +4424,40 @@ var knowledgeCommandParser = {
4423
4424
  };
4424
4425
  },
4425
4426
  /**
4426
- * Note: Prototype of [🍧] (remove this comment after full implementation)
4427
+ * Apply the KNOWLEDGE command to the `pipelineJson`
4428
+ *
4429
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
4427
4430
  */
4428
- applyToPipelineJson: function (personaCommand, subjects) {
4429
- var sourceContent = personaCommand.sourceContent;
4430
- var pipelineJson = subjects.pipelineJson;
4431
+ $applyToPipelineJson: function (command, $pipelineJson) {
4432
+ var sourceContent = command.sourceContent;
4431
4433
  var name = 'source-' + sha256(hexEncoder.parse(JSON.stringify(sourceContent))).toString( /* hex */);
4432
4434
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
4433
4435
  // <- TODO: This should be replaced with a better name later in preparation (done with some propper LLM summarization)
4434
- pipelineJson.knowledgeSources.push({
4436
+ $pipelineJson.knowledgeSources.push({
4435
4437
  name: name,
4436
4438
  sourceContent: sourceContent,
4437
4439
  });
4438
4440
  },
4439
- };
4440
-
4441
- /**
4442
- * Parses the persona command
4443
- *
4444
- * @see ./PERSONA-README.md for more details
4445
- * @private within the commands folder
4446
- */
4447
- var personaCommandParser = {
4448
- /**
4449
- * Name of the command
4450
- */
4451
- name: 'PERSONA',
4452
- /**
4453
- * Aliases for the PERSONA command
4454
- */
4455
- aliasNames: ['PERSON'],
4456
- /**
4457
- * PERSONA command can be used in:
4458
- */
4459
- usagePlaces: ['PIPELINE_HEAD', 'PIPELINE_TEMPLATE'],
4460
- /**
4461
- * Description of the PERSONA command
4462
- */
4463
- description: "Persona command is used to specify who the system is, it will be transformed into system message, top_t,...",
4464
- /**
4465
- * Link to discussion
4466
- */
4467
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/22',
4468
- /**
4469
- * Example usages of the PERSONA command
4470
- */
4471
- examples: ['PERSONA Jane, skilled copywriter', 'PERSONA Joe, male 28 years old, programmer'],
4472
4441
  /**
4473
- * Parses the PERSONA command
4442
+ * Converts the KNOWLEDGE command back to string
4443
+ *
4444
+ * Note: This is used in `pipelineJsonToString` utility
4474
4445
  */
4475
- parse: function (input) {
4476
- var rawArgs = input.rawArgs;
4477
- var _a = __read(rawArgs.split(/[,;:]/, 2), 2), personaNameRaw = _a[0], personaDescriptionRaw = _a[1];
4478
- var personaName = (personaNameRaw || '').trim();
4479
- if (personaName === '') {
4480
- throw new ParsingError("You must set name for the persona");
4481
- }
4482
- var personaDescription = (personaDescriptionRaw || '').trim();
4483
- if (personaDescription === '') {
4484
- personaDescription = null;
4485
- }
4486
- return {
4487
- type: 'PERSONA',
4488
- personaName: personaName,
4489
- personaDescription: personaDescription,
4490
- };
4446
+ stringify: function (command) {
4447
+ keepUnused(command);
4448
+ return "!!!!!!";
4491
4449
  },
4492
4450
  /**
4493
- * Note: Prototype of [🍧] (remove this comment after full implementation)
4451
+ * Reads the KNOWLEDGE command from the `PipelineJson`
4452
+ *
4453
+ * Note: This is used in `pipelineJsonToString` utility
4494
4454
  */
4495
- applyToPipelineJson: function (personaCommand, subjects) {
4496
- var personaName = personaCommand.personaName, personaDescription = personaCommand.personaDescription;
4497
- var pipelineJson = subjects.pipelineJson, templateJson = subjects.templateJson;
4498
- if (templateJson !== null) {
4499
- if (templateJson.blockType !== 'PROMPT_TEMPLATE') {
4500
- throw new ParsingError("PERSONA command can be used only in PROMPT_TEMPLATE block");
4501
- }
4502
- templateJson.personaName = personaName;
4503
- }
4504
- var persona = pipelineJson.personas.find(function (persona) { return persona.name === personaName; });
4505
- if (persona === undefined) {
4506
- pipelineJson.personas.push({
4507
- name: personaName,
4508
- description: personaDescription || '',
4509
- });
4510
- return;
4511
- }
4512
- if (persona.description === personaDescription) {
4513
- return;
4514
- }
4515
- if (personaDescription === null) {
4516
- return;
4517
- }
4518
- if (persona.description === '') {
4519
- persona.description = personaDescription;
4520
- return;
4521
- }
4522
- console.warn(spaceTrim$1("\n\n Persona \"".concat(personaName, "\" is defined multiple times with different description:\n\n First definition:\n ").concat(persona.description, "\n\n Second definition:\n ").concat(personaDescription, "\n\n ")));
4523
- persona.description += spaceTrim$1('\n\n' + personaDescription);
4455
+ takeFromPipelineJson: function (pipelineJson) {
4456
+ keepUnused(pipelineJson);
4457
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
4524
4458
  },
4525
4459
  };
4526
4460
 
4527
- /**
4528
- * Removes Markdown formatting tags from a string.
4529
- *
4530
- * @param {string} str - The string to remove Markdown tags from.
4531
- * @returns {string} The input string with all Markdown tags removed.
4532
- * @public exported from `@promptbook/markdown-utils`
4533
- */
4534
- function removeMarkdownFormatting(str) {
4535
- // Remove bold formatting
4536
- str = str.replace(/\*\*(.*?)\*\*/g, '$1');
4537
- // Remove italic formatting
4538
- str = str.replace(/\*(.*?)\*/g, '$1');
4539
- // Remove code formatting
4540
- str = str.replace(/`(.*?)`/g, '$1');
4541
- return str;
4542
- }
4543
-
4544
- /**
4545
- * @@@
4546
- *
4547
- * @param text @@@
4548
- * @returns @@@
4549
- * @example 'HELLO_WORLD'
4550
- * @example 'I_LOVE_PROMPTBOOK'
4551
- * @public exported from `@promptbook/utils`
4552
- */
4553
- function normalizeTo_SCREAMING_CASE(text) {
4554
- var e_1, _a;
4555
- var charType;
4556
- var lastCharType = 'OTHER';
4557
- var normalizedName = '';
4558
- try {
4559
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
4560
- var char = text_1_1.value;
4561
- var normalizedChar = void 0;
4562
- if (/^[a-z]$/.test(char)) {
4563
- charType = 'LOWERCASE';
4564
- normalizedChar = char.toUpperCase();
4565
- }
4566
- else if (/^[A-Z]$/.test(char)) {
4567
- charType = 'UPPERCASE';
4568
- normalizedChar = char;
4569
- }
4570
- else if (/^[0-9]$/.test(char)) {
4571
- charType = 'NUMBER';
4572
- normalizedChar = char;
4573
- }
4574
- else if (/^\/$/.test(char)) {
4575
- charType = 'SLASH';
4576
- normalizedChar = char;
4577
- }
4578
- else {
4579
- charType = 'OTHER';
4580
- normalizedChar = '_';
4581
- }
4582
- if (charType !== lastCharType &&
4583
- !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
4584
- !(lastCharType === 'NUMBER') &&
4585
- !(charType === 'NUMBER')) {
4586
- normalizedName += '_';
4587
- }
4588
- normalizedName += normalizedChar;
4589
- lastCharType = charType;
4590
- }
4591
- }
4592
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
4593
- finally {
4594
- try {
4595
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
4596
- }
4597
- finally { if (e_1) throw e_1.error; }
4598
- }
4599
- normalizedName = normalizedName.replace(/_+/g, '_');
4600
- normalizedName = normalizedName.replace(/_?\/_?/g, '/');
4601
- normalizedName = normalizedName.replace(/^_/, '');
4602
- normalizedName = normalizedName.replace(/_$/, '');
4603
- return normalizedName;
4604
- }
4605
- /**
4606
- * TODO: Tests
4607
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
4608
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
4609
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
4610
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
4611
- * TODO: [🌺] Use some intermediate util splitWords
4612
- */
4613
-
4614
4461
  /**
4615
4462
  * Block type describes the way how the block is blockd
4616
4463
  *
@@ -4620,8 +4467,8 @@ function normalizeTo_SCREAMING_CASE(text) {
4620
4467
  var BlockTypes = [
4621
4468
  'PROMPT_TEMPLATE',
4622
4469
  'SIMPLE_TEMPLATE',
4623
- 'SCRIPT',
4624
- 'PROMPT_DIALOG',
4470
+ 'SCRIPT_TEMPLATE',
4471
+ 'DIALOG_TEMPLATE',
4625
4472
  'SAMPLE',
4626
4473
  'KNOWLEDGE',
4627
4474
  'INSTRUMENT',
@@ -4646,8 +4493,8 @@ var blockCommandParser = {
4646
4493
  aliasNames: [
4647
4494
  'PROMPT_TEMPLATE',
4648
4495
  'SIMPLE_TEMPLATE',
4649
- 'SCRIPT',
4650
- 'PROMPT_DIALOG',
4496
+ 'SCRIPT_TEMPLATE',
4497
+ 'DIALOG_TEMPLATE',
4651
4498
  'SAMPLE',
4652
4499
  'EXAMPLE',
4653
4500
  'KNOWLEDGE',
@@ -4662,7 +4509,8 @@ var blockCommandParser = {
4662
4509
  /**
4663
4510
  * BOILERPLATE command can be used in:
4664
4511
  */
4665
- usagePlaces: ['PIPELINE_TEMPLATE'],
4512
+ isUsedInPipelineHead: false,
4513
+ isUsedInPipelineTemplate: true,
4666
4514
  /**
4667
4515
  * Description of the BLOCK command
4668
4516
  */
@@ -4675,19 +4523,24 @@ var blockCommandParser = {
4675
4523
  * Example usages of the BLOCK command
4676
4524
  */
4677
4525
  examples: [
4678
- 'Prompt template BLOCK',
4679
- 'Prompt template',
4680
- 'Simple template BLOCK',
4681
- 'Simple template',
4682
- 'Script BLOCK',
4683
- 'Script',
4684
- 'Prompt dialog BLOCK',
4685
- 'Prompt dialog',
4686
- 'Sample BLOCK',
4687
- 'Sample',
4688
- 'Example BLOCK',
4689
- 'Example',
4690
- 'Knowledge BLOCK',
4526
+ // Recommended form:
4527
+ 'PROMPT BLOCK',
4528
+ 'SIMPLE BLOCK',
4529
+ 'SCRIPT BLOCK',
4530
+ 'DIALOG BLOCK',
4531
+ // <- [🅱]
4532
+ // Long form:
4533
+ 'PROMPT TEMPLATE BLOCK',
4534
+ 'SIMPLE TEMPLATE BLOCK',
4535
+ 'SCRIPT TEMPLATE BLOCK',
4536
+ 'DIALOG TEMPLATE BLOCK',
4537
+ // <- [🅱]
4538
+ // Reversed form:
4539
+ 'BLOCK PROMPT TEMPLATE',
4540
+ 'BLOCK SIMPLE TEMPLATE',
4541
+ 'BLOCK SCRIPT TEMPLATE',
4542
+ 'BLOCK DIALOG TEMPLATE',
4543
+ // <- [🅱]
4691
4544
  // 'Knowledge', // <- Note: [⛱] For execution blocks which are also separate commands shortcut does not work
4692
4545
  //---
4693
4546
  /* Note: Not implemented block types will be in examples in future -> */
@@ -4705,9 +4558,9 @@ var blockCommandParser = {
4705
4558
  parse: function (input) {
4706
4559
  var normalized = input.normalized;
4707
4560
  normalized = normalized.split('EXAMPLE').join('SAMPLE');
4708
- var blockTypes = BlockTypes.filter(function (blockType) { return normalized.includes(blockType); });
4561
+ var blockTypes = BlockTypes.filter(function (blockType) { return normalized.includes(blockType.split('_TEMPLATE').join('')); });
4709
4562
  if (blockTypes.length !== 1) {
4710
- throw new ParsingError(spaceTrim$1(function (block) { return "\n Unknown block type in BLOCK command\n\n Supported block types are:\n ".concat(block(BlockTypes.join(', ')), "\n "); }));
4563
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Unknown block type in BLOCK command\n\n Supported block types are:\n ".concat(block(BlockTypes.join(', ')), "\n "); }));
4711
4564
  }
4712
4565
  var blockType = blockTypes[0];
4713
4566
  return {
@@ -4715,6 +4568,94 @@ var blockCommandParser = {
4715
4568
  blockType: blockType,
4716
4569
  };
4717
4570
  },
4571
+ /**
4572
+ * Apply the BLOCK command to the `pipelineJson`
4573
+ *
4574
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
4575
+ */
4576
+ $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
4577
+ // TODO: !!!!!! Test multiple / no block type
4578
+ if ($templateJson.isBlockTypeSet === true) {
4579
+ throw new ParseError("Block type is already defined in the prompt template. It can be defined only once.");
4580
+ }
4581
+ $templateJson.isBlockTypeSet = true;
4582
+ // TODO: !!!!!! Rearrange better - but at bottom and unwrap from function
4583
+ var expectResultingParameterName = function () {
4584
+ if ($templateJson.resultingParameterName) {
4585
+ return;
4586
+ }
4587
+ throw new ParseError(" Template section must end with -> {parameterName}");
4588
+ };
4589
+ if ($templateJson.content === undefined) {
4590
+ throw new UnexpectedError("Content is missing in the templateJson - probbably commands are applied in wrong order");
4591
+ }
4592
+ if (command.blockType === 'SAMPLE') {
4593
+ expectResultingParameterName();
4594
+ var parameter = $pipelineJson.parameters.find(function (param) { return param.name === $templateJson.resultingParameterName; });
4595
+ if (parameter === undefined) {
4596
+ throw new ParseError("Can not find parameter {".concat($templateJson.resultingParameterName, "} to assign sample value on it"));
4597
+ }
4598
+ parameter.sampleValues = parameter.sampleValues || [];
4599
+ parameter.sampleValues.push($templateJson.content);
4600
+ // TODO: !!!!!! How to implement this?
4601
+ // continue templates;
4602
+ $templateJson.isTemplateBlock = false;
4603
+ return;
4604
+ }
4605
+ if (command.blockType === 'KNOWLEDGE') {
4606
+ knowledgeCommandParser.$applyToPipelineJson({
4607
+ type: 'KNOWLEDGE',
4608
+ sourceContent: $templateJson.content, // <- TODO: [🐝] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
4609
+ }, $pipelineJson);
4610
+ // TODO: !!!!!! How to implement this?
4611
+ // continue templates;
4612
+ $templateJson.isTemplateBlock = false;
4613
+ return;
4614
+ }
4615
+ if (command.blockType === 'ACTION') {
4616
+ console.error(new NotYetImplementedError('Actions are not implemented yet'));
4617
+ // TODO: !!!!!! How to implement this?
4618
+ // continue templates;
4619
+ $templateJson.isTemplateBlock = false;
4620
+ return;
4621
+ }
4622
+ if (command.blockType === 'INSTRUMENT') {
4623
+ console.error(new NotYetImplementedError('Instruments are not implemented yet'));
4624
+ // TODO: !!!!!! How to implement this?
4625
+ // continue templates;
4626
+ $templateJson.isTemplateBlock = false;
4627
+ return;
4628
+ }
4629
+ expectResultingParameterName();
4630
+ $templateJson.blockType = command.blockType;
4631
+ /*
4632
+ TODO: !!!!!! Chat model variant should be applied in `createPipelineExecutor`
4633
+ if (command.blockType ==='PROMPT_TEMPLATE' && templateModelRequirements.modelVariant === undefined) {
4634
+ templateModelRequirements.modelVariant = 'CHAT';
4635
+ }
4636
+ */
4637
+ // !!!!!!
4638
+ // isBlockTypeSet = true; //<- Note: [2]
4639
+ $templateJson.isTemplateBlock = true;
4640
+ },
4641
+ /**
4642
+ * Converts the BLOCK command back to string
4643
+ *
4644
+ * Note: This is used in `pipelineJsonToString` utility
4645
+ */
4646
+ stringify: function (command) {
4647
+ keepUnused(command);
4648
+ return "!!!!!!";
4649
+ },
4650
+ /**
4651
+ * Reads the BLOCK command from the `TemplateJson`
4652
+ *
4653
+ * Note: This is used in `pipelineJsonToString` utility
4654
+ */
4655
+ takeFromTemplateJson: function ($templateJson) {
4656
+ keepUnused($templateJson);
4657
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
4658
+ },
4718
4659
  };
4719
4660
 
4720
4661
  /**
@@ -4725,7 +4666,7 @@ var blockCommandParser = {
4725
4666
  */
4726
4667
  var EXPECTATION_UNITS = ['CHARACTERS', 'WORDS', 'SENTENCES', 'LINES', 'PARAGRAPHS', 'PAGES'];
4727
4668
  /**
4728
- * TODO: [💝] Unite object for expecting amount and format - remove expectFormat
4669
+ * TODO: [💝] Unite object for expecting amount and format - remove format
4729
4670
  */
4730
4671
 
4731
4672
  /**
@@ -4735,7 +4676,7 @@ var EXPECTATION_UNITS = ['CHARACTERS', 'WORDS', 'SENTENCES', 'LINES', 'PARAGRAPH
4735
4676
  * Note: it also works only with decimal numbers
4736
4677
  *
4737
4678
  * @returns parsed number
4738
- * @throws {ParsingError} if the value is not a number
4679
+ * @throws {ParseError} if the value is not a number
4739
4680
  *
4740
4681
  * @public exported from `@promptbook/utils`
4741
4682
  */
@@ -4771,7 +4712,7 @@ function parseNumber(value) {
4771
4712
  var numerator = parseNumber(numerator_);
4772
4713
  var denominator = parseNumber(denominator_);
4773
4714
  if (denominator === 0) {
4774
- throw new ParsingError("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
4715
+ throw new ParseError("Unable to parse number from \"".concat(originalValue, "\" because denominator is zero"));
4775
4716
  }
4776
4717
  return numerator / denominator;
4777
4718
  }
@@ -4783,11 +4724,11 @@ function parseNumber(value) {
4783
4724
  return parseNumber(significand) * Math.pow(10, parseNumber(exponent));
4784
4725
  }
4785
4726
  if (!/^[0-9.]+$/.test(value) || value.split('.').length > 2) {
4786
- throw new ParsingError("Unable to parse number from \"".concat(originalValue, "\""));
4727
+ throw new ParseError("Unable to parse number from \"".concat(originalValue, "\""));
4787
4728
  }
4788
4729
  var num = parseFloat(value);
4789
4730
  if (isNaN(num)) {
4790
- throw new ParsingError("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
4731
+ throw new ParseError("Unexpected NaN when parsing number from \"".concat(originalValue, "\""));
4791
4732
  }
4792
4733
  return num;
4793
4734
  }
@@ -4810,9 +4751,10 @@ var expectCommandParser = {
4810
4751
  /**
4811
4752
  * BOILERPLATE command can be used in:
4812
4753
  */
4813
- usagePlaces: ['PIPELINE_TEMPLATE'],
4754
+ isUsedInPipelineHead: false,
4755
+ isUsedInPipelineTemplate: true,
4814
4756
  /**
4815
- * Description of the EXPECT command
4757
+ * Description of the FORMAT command
4816
4758
  */
4817
4759
  description: spaceTrim$1("\n Expect command describes the desired output of the prompt template (after post-processing)\n It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.\n "),
4818
4760
  /**
@@ -4820,7 +4762,7 @@ var expectCommandParser = {
4820
4762
  */
4821
4763
  documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/30',
4822
4764
  /**
4823
- * Example usages of the EXPECT command
4765
+ * Example usages of the FORMAT command
4824
4766
  */
4825
4767
  examples: [
4826
4768
  'EXPECT MIN 100 Characters',
@@ -4828,22 +4770,13 @@ var expectCommandParser = {
4828
4770
  'EXPECT EXACTLY 3 Sentences',
4829
4771
  'EXPECT EXACTLY 1 Paragraph',
4830
4772
  // <- TODO: 'EXPECT 1 Paragraph',
4831
- 'Expect JSON',
4832
4773
  ],
4833
4774
  /**
4834
- * Parses the EXPECT command
4775
+ * Parses the FORMAT command
4835
4776
  */
4836
4777
  parse: function (input) {
4837
4778
  var e_1, _a;
4838
- var args = input.args, normalized = input.normalized;
4839
- if (normalized.startsWith('EXPECT_JSON')) {
4840
- return {
4841
- type: 'EXPECT_FORMAT',
4842
- format: 'JSON',
4843
- };
4844
- // <- TODO: [🦽] Why this is constantly removed by repair-imports.ts
4845
- // [🥤]
4846
- }
4779
+ var args = input.args;
4847
4780
  try {
4848
4781
  var sign = void 0;
4849
4782
  var signRaw = args.shift();
@@ -4857,15 +4790,15 @@ var expectCommandParser = {
4857
4790
  sign = 'MAXIMUM';
4858
4791
  }
4859
4792
  else {
4860
- throw new ParsingError("Invalid sign \"".concat(signRaw, "\", expected EXACTLY, MIN or MAX"));
4793
+ throw new ParseError("Invalid sign \"".concat(signRaw, "\", expected EXACTLY, MIN or MAX"));
4861
4794
  }
4862
4795
  var amountRaw = args.shift();
4863
4796
  var amount = parseNumber(amountRaw);
4864
4797
  if (amount < 0) {
4865
- throw new ParsingError('Amount must be positive number or zero');
4798
+ throw new ParseError('Amount must be positive number or zero');
4866
4799
  }
4867
4800
  if (amount !== Math.floor(amount)) {
4868
- throw new ParsingError('Amount must be whole number');
4801
+ throw new ParseError('Amount must be whole number');
4869
4802
  }
4870
4803
  var unitRaw = args.shift();
4871
4804
  var unit = undefined;
@@ -4880,7 +4813,7 @@ var expectCommandParser = {
4880
4813
  if (new RegExp("^".concat(existingUnitText.toLowerCase())).test(unitRaw.toLowerCase()) ||
4881
4814
  new RegExp("^".concat(unitRaw.toLowerCase())).test(existingUnitText.toLowerCase())) {
4882
4815
  if (unit !== undefined) {
4883
- throw new ParsingError("Ambiguous unit \"".concat(unitRaw, "\""));
4816
+ throw new ParseError("Ambiguous unit \"".concat(unitRaw, "\""));
4884
4817
  }
4885
4818
  unit = existingUnit;
4886
4819
  }
@@ -4894,10 +4827,10 @@ var expectCommandParser = {
4894
4827
  finally { if (e_1) throw e_1.error; }
4895
4828
  }
4896
4829
  if (unit === undefined) {
4897
- throw new ParsingError("Invalid unit \"".concat(unitRaw, "\""));
4830
+ throw new ParseError("Invalid unit \"".concat(unitRaw, "\""));
4898
4831
  }
4899
4832
  return {
4900
- type: 'EXPECT_AMOUNT',
4833
+ type: 'EXPECT',
4901
4834
  sign: sign,
4902
4835
  unit: unit,
4903
4836
  amount: amount,
@@ -4907,97 +4840,321 @@ var expectCommandParser = {
4907
4840
  if (!(error instanceof Error)) {
4908
4841
  throw error;
4909
4842
  }
4910
- throw new ParsingError(spaceTrim$1(function (block) {
4911
- return "\n Invalid EXPECT command\n ".concat(block(error.message), ":\n ");
4843
+ throw new ParseError(spaceTrim$1(function (block) {
4844
+ return "\n Invalid FORMAT command\n ".concat(block(error.message), ":\n ");
4912
4845
  }));
4913
4846
  }
4914
4847
  },
4848
+ /**
4849
+ * Apply the FORMAT command to the `pipelineJson`
4850
+ *
4851
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
4852
+ */
4853
+ $applyToTemplateJson: function (command, $templateJson) {
4854
+ // eslint-disable-next-line no-case-declarations
4855
+ var unit = command.unit.toLowerCase();
4856
+ $templateJson.expectations = $templateJson.expectations || {};
4857
+ $templateJson.expectations[unit] = $templateJson.expectations[unit] || {};
4858
+ if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
4859
+ if ($templateJson.expectations[unit].min !== undefined) {
4860
+ throw new ParseError("Already defined minumum ".concat($templateJson.expectations[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
4861
+ }
4862
+ $templateJson.expectations[unit].min = command.amount;
4863
+ } /* not else */
4864
+ if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
4865
+ if ($templateJson.expectations[unit].max !== undefined) {
4866
+ throw new ParseError("Already defined maximum ".concat($templateJson.expectations[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
4867
+ }
4868
+ $templateJson.expectations[unit].max = command.amount;
4869
+ }
4870
+ },
4871
+ /**
4872
+ * Converts the FORMAT command back to string
4873
+ *
4874
+ * Note: This is used in `pipelineJsonToString` utility
4875
+ */
4876
+ stringify: function (command) {
4877
+ keepUnused(command);
4878
+ return "!!!!!!";
4879
+ },
4880
+ /**
4881
+ * Reads the FORMAT command from the `TemplateJson`
4882
+ *
4883
+ * Note: This is used in `pipelineJsonToString` utility
4884
+ */
4885
+ takeFromTemplateJson: function ($templateJson) {
4886
+ keepUnused($templateJson);
4887
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
4888
+ },
4915
4889
  };
4916
4890
 
4917
4891
  /**
4918
- * Parses the joker command
4892
+ * Parses the foreach command
4919
4893
  *
4920
- * @see ./JOKER-README.md for more details
4894
+ * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.ptbk.md` file
4895
+ *
4896
+ * @see ./FOREACH-README.md for more details <- TODO: @@@ Write theese README files OR remove this link + add annotation here (to all commands)
4921
4897
  * @private within the commands folder
4922
4898
  */
4923
- var jokerCommandParser = {
4899
+ var foreachCommandParser = {
4924
4900
  /**
4925
4901
  * Name of the command
4926
4902
  */
4927
- name: 'JOKER',
4903
+ name: 'FOREACH',
4928
4904
  /**
4929
- * BOILERPLATE command can be used in:
4905
+ * Aliases for the FOREACH command
4930
4906
  */
4931
- usagePlaces: ['PIPELINE_TEMPLATE'],
4907
+ aliasNames: ['FOR', 'EACH'],
4932
4908
  /**
4933
- * Description of the JOKER command
4909
+ * FOREACH command can be used in:
4934
4910
  */
4935
- description: "Joker parameter is used instead of executing the prompt template if it meet the expectations requirements",
4911
+ isUsedInPipelineHead: false,
4912
+ isUsedInPipelineTemplate: true,
4913
+ /**
4914
+ * Description of the FOREACH command
4915
+ */
4916
+ description: "@@",
4936
4917
  /**
4937
4918
  * Link to discussion
4938
4919
  */
4939
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/66',
4920
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
4940
4921
  /**
4941
- * Example usages of the JOKER command
4922
+ * Example usages of the FOREACH command
4942
4923
  */
4943
- examples: ['JOKER {documentTitle}'],
4924
+ examples: [
4925
+ 'FOREACH List Line -> `{customer}`',
4926
+ 'FOR List Line -> `{customer}`',
4927
+ 'EACH List Line -> `{customer}`',
4928
+ // <- TODO: [🍭] More
4929
+ ],
4944
4930
  /**
4945
- * Parses the JOKER command
4931
+ * Parses the FOREACH command
4946
4932
  */
4947
4933
  parse: function (input) {
4948
4934
  var args = input.args;
4949
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
4950
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
4951
- throw new ParsingError("Invalid joker");
4952
- }
4953
- var parameterName = parametersMatch.groups.parameterName;
4935
+ keepUnused(args);
4936
+ // <- TODO: [🍭] Implement
4954
4937
  return {
4955
- type: 'JOKER',
4956
- parameterName: parameterName,
4938
+ type: 'FOREACH',
4957
4939
  };
4958
4940
  },
4941
+ /**
4942
+ * Apply the FOREACH command to the `pipelineJson`
4943
+ *
4944
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
4945
+ */
4946
+ $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
4947
+ keepUnused(command, $templateJson, $pipelineJson);
4948
+ // <- TODO: [🍭] Implement
4949
+ },
4950
+ /**
4951
+ * Converts the FOREACH command back to string
4952
+ *
4953
+ * Note: This is used in `pipelineJsonToString` utility
4954
+ */
4955
+ stringify: function (command) {
4956
+ keepUnused(command);
4957
+ return "";
4958
+ // <- TODO: [🍭] Implement
4959
+ },
4960
+ /**
4961
+ * Reads the FOREACH command from the `TemplateJson`
4962
+ *
4963
+ * Note: This is used in `pipelineJsonToString` utility
4964
+ */
4965
+ takeFromTemplateJson: function ($templateJson) {
4966
+ keepUnused($templateJson);
4967
+ return [];
4968
+ // <- TODO: [🍭] Implement
4969
+ },
4959
4970
  };
4960
-
4961
4971
  /**
4962
- * @@@
4963
- *
4964
- * @public exported from `@promptbook/core`
4972
+ * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH command and also with wrong syntax and logic
4965
4973
  */
4966
- var MODEL_VARIANTS = ['COMPLETION', 'CHAT', 'EMBEDDING' /* <- TODO [🏳] */ /* <- [🤖] */];
4967
4974
 
4968
4975
  /**
4969
- * Parses the model command
4976
+ * Parses the format command
4970
4977
  *
4971
- * @see ./MODEL-README.md for more details
4978
+ * @see ./FORMAT-README.md for more details
4972
4979
  * @private within the commands folder
4973
4980
  */
4974
- var modelCommandParser = {
4981
+ var formatCommandParser = {
4975
4982
  /**
4976
4983
  * Name of the command
4977
4984
  */
4978
- name: 'MODEL',
4985
+ name: 'FORMAT',
4979
4986
  /**
4980
4987
  * BOILERPLATE command can be used in:
4981
4988
  */
4982
- usagePlaces: [
4983
- 'PIPELINE_HEAD',
4984
- // <- TODO: [🧠][❔] Should there be possibility to set MODEL for entire pipeline?
4985
- 'PIPELINE_TEMPLATE',
4986
- ],
4989
+ isUsedInPipelineHead: false,
4990
+ isUsedInPipelineTemplate: true,
4987
4991
  /**
4988
- * Description of the MODEL command
4992
+ * Description of the FORMAT command
4989
4993
  */
4990
- description: "Tells which model and modelRequirements to use for the prompt template execution",
4994
+ description: spaceTrim$1("\n Format command describes the desired output of the prompt template (after post-processing)\n It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.\n "),
4991
4995
  /**
4992
4996
  * Link to discussion
4993
4997
  */
4994
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/67',
4998
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/30',
4995
4999
  /**
4996
- * Example usages of the MODEL command
5000
+ * Example usages of the FORMAT command
4997
5001
  */
4998
- examples: ['MODEL VARIANT Chat', 'MODEL NAME `gpt-4`'],
5002
+ examples: ['FORMAT JSON'],
4999
5003
  /**
5000
- * Parses the MODEL command
5004
+ * Parses the FORMAT command
5005
+ */
5006
+ parse: function (input) {
5007
+ var normalized = input.normalized;
5008
+ if (!normalized.startsWith('FORMAT_JSON')) {
5009
+ throw new ParseError("For now only JSON format is supported, in future we will support more formats");
5010
+ }
5011
+ return {
5012
+ type: 'FORMAT',
5013
+ format: 'JSON',
5014
+ };
5015
+ // <- TODO: [🦽] Why this is constantly removed by repair-imports.ts
5016
+ // [🥤]
5017
+ },
5018
+ /**
5019
+ * Apply the FORMAT command to the `pipelineJson`
5020
+ *
5021
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5022
+ */
5023
+ $applyToTemplateJson: function (command, $templateJson) {
5024
+ if ($templateJson.format !== undefined && command.format !== $templateJson.format) {
5025
+ throw new ParseError("Format format is already defined to \"".concat($templateJson.format, "\".\n Now you try to redefine it by \"").concat(command.format, "\""));
5026
+ }
5027
+ $templateJson.format = command.format;
5028
+ },
5029
+ /**
5030
+ * Converts the FORMAT command back to string
5031
+ *
5032
+ * Note: This is used in `pipelineJsonToString` utility
5033
+ */
5034
+ stringify: function (command) {
5035
+ keepUnused(command);
5036
+ return "!!!!!!";
5037
+ },
5038
+ /**
5039
+ * Reads the FORMAT command from the `TemplateJson`
5040
+ *
5041
+ * Note: This is used in `pipelineJsonToString` utility
5042
+ */
5043
+ takeFromTemplateJson: function ($templateJson) {
5044
+ keepUnused($templateJson);
5045
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5046
+ },
5047
+ };
5048
+
5049
+ /**
5050
+ * Parses the joker command
5051
+ *
5052
+ * @see ./JOKER-README.md for more details
5053
+ * @private within the commands folder
5054
+ */
5055
+ var jokerCommandParser = {
5056
+ /**
5057
+ * Name of the command
5058
+ */
5059
+ name: 'JOKER',
5060
+ /**
5061
+ * BOILERPLATE command can be used in:
5062
+ */
5063
+ isUsedInPipelineHead: false,
5064
+ isUsedInPipelineTemplate: true,
5065
+ /**
5066
+ * Description of the JOKER command
5067
+ */
5068
+ description: "Joker parameter is used instead of executing the prompt template if it meet the expectations requirements",
5069
+ /**
5070
+ * Link to discussion
5071
+ */
5072
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/66',
5073
+ /**
5074
+ * Example usages of the JOKER command
5075
+ */
5076
+ examples: ['JOKER {documentTitle}'],
5077
+ /**
5078
+ * Parses the JOKER command
5079
+ */
5080
+ parse: function (input) {
5081
+ var args = input.args;
5082
+ var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5083
+ if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5084
+ throw new ParseError("Invalid joker");
5085
+ }
5086
+ var parameterName = parametersMatch.groups.parameterName;
5087
+ return {
5088
+ type: 'JOKER',
5089
+ parameterName: parameterName,
5090
+ };
5091
+ },
5092
+ /**
5093
+ * Apply the JOKER command to the `pipelineJson`
5094
+ *
5095
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5096
+ */
5097
+ $applyToTemplateJson: function (command, $templateJson) {
5098
+ $templateJson.jokerParameterNames = $templateJson.jokerParameterNames || [];
5099
+ $templateJson.jokerParameterNames.push(command.parameterName);
5100
+ },
5101
+ /**
5102
+ * Converts the JOKER command back to string
5103
+ *
5104
+ * Note: This is used in `pipelineJsonToString` utility
5105
+ */
5106
+ stringify: function (command) {
5107
+ keepUnused(command);
5108
+ return "!!!!!!";
5109
+ },
5110
+ /**
5111
+ * Reads the JOKER command from the `TemplateJson`
5112
+ *
5113
+ * Note: This is used in `pipelineJsonToString` utility
5114
+ */
5115
+ takeFromTemplateJson: function ($templateJson) {
5116
+ keepUnused($templateJson);
5117
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5118
+ },
5119
+ };
5120
+
5121
+ /**
5122
+ * @@@
5123
+ *
5124
+ * @public exported from `@promptbook/core`
5125
+ */
5126
+ var MODEL_VARIANTS = ['COMPLETION', 'CHAT', 'EMBEDDING' /* <- TODO [🏳] */ /* <- [🤖] */];
5127
+
5128
+ /**
5129
+ * Parses the model command
5130
+ *
5131
+ * @see ./MODEL-README.md for more details
5132
+ * @private within the commands folder
5133
+ */
5134
+ var modelCommandParser = {
5135
+ /**
5136
+ * Name of the command
5137
+ */
5138
+ name: 'MODEL',
5139
+ /**
5140
+ * BOILERPLATE command can be used in:
5141
+ */
5142
+ isUsedInPipelineHead: true,
5143
+ isUsedInPipelineTemplate: true,
5144
+ /**
5145
+ * Description of the MODEL command
5146
+ */
5147
+ description: "Tells which model and modelRequirements to use for the prompt template execution",
5148
+ /**
5149
+ * Link to discussion
5150
+ */
5151
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/67',
5152
+ /**
5153
+ * Example usages of the MODEL command
5154
+ */
5155
+ examples: ['MODEL VARIANT Chat', 'MODEL NAME `gpt-4`'],
5156
+ /**
5157
+ * Parses the MODEL command
5001
5158
  */
5002
5159
  parse: function (input) {
5003
5160
  var args = input.args, normalized = input.normalized;
@@ -5026,7 +5183,7 @@ var modelCommandParser = {
5026
5183
  // <- Note: [🤖]
5027
5184
  }
5028
5185
  else {
5029
- throw new ParsingError(spaceTrim$1(function (block) { return "\n Unknown model variant in command:\n\n Supported variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) { return "- ".concat(variantName); }).join('\n')), "\n "); }));
5186
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Unknown model variant in command:\n\n Supported variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) { return "- ".concat(variantName); }).join('\n')), "\n "); }));
5030
5187
  }
5031
5188
  }
5032
5189
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5037,9 +5194,60 @@ var modelCommandParser = {
5037
5194
  };
5038
5195
  }
5039
5196
  else {
5040
- throw new ParsingError(spaceTrim$1(function (block) { return "\n Unknown model key in command.\n\n Supported model keys are:\n ".concat(block(['variant', 'name'].join(', ')), "\n\n Example:\n\n - MODEL VARIANT Chat\n - MODEL NAME gpt-4\n "); }));
5197
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Unknown model key in command.\n\n Supported model keys are:\n ".concat(block(['variant', 'name'].join(', ')), "\n\n Example:\n\n - MODEL VARIANT Chat\n - MODEL NAME gpt-4\n "); }));
5041
5198
  }
5042
5199
  },
5200
+ /**
5201
+ * Apply the MODEL command to the `pipelineJson`
5202
+ *
5203
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5204
+ */
5205
+ $applyToPipelineJson: function (command, $pipelineJson) {
5206
+ // TODO: !!!!!! Error on redefine
5207
+ $pipelineJson.defaultModelRequirements = $pipelineJson.defaultModelRequirements || {};
5208
+ $pipelineJson.defaultModelRequirements[command.key] = command.value;
5209
+ },
5210
+ /**
5211
+ * Apply the MODEL command to the `pipelineJson`
5212
+ *
5213
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5214
+ */
5215
+ $applyToTemplateJson: function (command, $templateJson) {
5216
+ if ($templateJson.blockType !== 'PROMPT_TEMPLATE') {
5217
+ throw new ParseError("MODEL command can only be used in PROMPT_TEMPLATE block");
5218
+ }
5219
+ // TODO: !!!!!! Error on redefine
5220
+ // TODO: Warn if setting same as default in `$pipelineJson`
5221
+ $templateJson.modelRequirements = $templateJson.modelRequirements || {};
5222
+ $templateJson.modelRequirements[command.key] = command.value;
5223
+ },
5224
+ /**
5225
+ * Converts the MODEL command back to string
5226
+ *
5227
+ * Note: This is used in `pipelineJsonToString` utility
5228
+ */
5229
+ stringify: function (command) {
5230
+ keepUnused(command);
5231
+ return "!!!!!!";
5232
+ },
5233
+ /**
5234
+ * Reads the MODEL command from the `PipelineJson`
5235
+ *
5236
+ * Note: This is used in `pipelineJsonToString` utility
5237
+ */
5238
+ takeFromPipelineJson: function (pipelineJson) {
5239
+ keepUnused(pipelineJson);
5240
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5241
+ },
5242
+ /**
5243
+ * Reads the MODEL command from the `TemplateJson`
5244
+ *
5245
+ * Note: This is used in `pipelineJsonToString` utility
5246
+ */
5247
+ takeFromTemplateJson: function ($templateJson) {
5248
+ keepUnused($templateJson);
5249
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5250
+ },
5043
5251
  };
5044
5252
 
5045
5253
  /**
@@ -5063,7 +5271,8 @@ var parameterCommandParser = {
5063
5271
  /**
5064
5272
  * BOILERPLATE command can be used in:
5065
5273
  */
5066
- usagePlaces: ['PIPELINE_HEAD', 'PIPELINE_TEMPLATE'],
5274
+ isUsedInPipelineHead: true,
5275
+ isUsedInPipelineTemplate: true,
5067
5276
  /**
5068
5277
  * Description of the PARAMETER command
5069
5278
  */
@@ -5083,11 +5292,11 @@ var parameterCommandParser = {
5083
5292
  var normalized = input.normalized, raw = input.raw;
5084
5293
  var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5085
5294
  if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5086
- throw new ParsingError("Invalid parameter");
5295
+ throw new ParseError("Invalid parameter");
5087
5296
  }
5088
5297
  var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5089
5298
  if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5090
- throw new ParsingError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
5299
+ throw new ParseError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
5091
5300
  }
5092
5301
  var isInput = normalized.startsWith('INPUT');
5093
5302
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5103,8 +5312,177 @@ var parameterCommandParser = {
5103
5312
  isOutput: isOutput,
5104
5313
  };
5105
5314
  },
5315
+ /**
5316
+ * Apply the PARAMETER command to the `pipelineJson`
5317
+ *
5318
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5319
+ */
5320
+ $applyToPipelineJson: function (command, $pipelineJson) {
5321
+ keepUnused(command, $pipelineJson);
5322
+ // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
5323
+ },
5324
+ /**
5325
+ * Apply the PARAMETER command to the `pipelineJson`
5326
+ *
5327
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5328
+ */
5329
+ $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5330
+ keepUnused(command, $templateJson, $pipelineJson);
5331
+ // Note: [🍣] Do nothing, its application is implemented separately in `pipelineStringToJsonSync`
5332
+ },
5333
+ /**
5334
+ * Converts the PARAMETER command back to string
5335
+ *
5336
+ * Note: This is used in `pipelineJsonToString` utility
5337
+ */
5338
+ stringify: function (command) {
5339
+ keepUnused(command);
5340
+ return "!!!!!!";
5341
+ },
5342
+ /**
5343
+ * Reads the PARAMETER command from the `PipelineJson`
5344
+ *
5345
+ * Note: This is used in `pipelineJsonToString` utility
5346
+ */
5347
+ takeFromPipelineJson: function (pipelineJson) {
5348
+ keepUnused(pipelineJson);
5349
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5350
+ },
5351
+ /**
5352
+ * Reads the PARAMETER command from the `TemplateJson`
5353
+ *
5354
+ * Note: This is used in `pipelineJsonToString` utility
5355
+ */
5356
+ takeFromTemplateJson: function ($templateJson) {
5357
+ keepUnused($templateJson);
5358
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5359
+ },
5106
5360
  };
5107
5361
 
5362
+ /**
5363
+ * Parses the persona command
5364
+ *
5365
+ * @see ./PERSONA-README.md for more details
5366
+ * @private within the commands folder
5367
+ */
5368
+ var personaCommandParser = {
5369
+ /**
5370
+ * Name of the command
5371
+ */
5372
+ name: 'PERSONA',
5373
+ /**
5374
+ * Aliases for the PERSONA command
5375
+ */
5376
+ aliasNames: ['PERSON'],
5377
+ /**
5378
+ * PERSONA command can be used in:
5379
+ */
5380
+ isUsedInPipelineHead: true,
5381
+ isUsedInPipelineTemplate: true,
5382
+ /**
5383
+ * Description of the PERSONA command
5384
+ */
5385
+ description: "Persona command is used to specify who the system is, it will be transformed into system message, top_t,...",
5386
+ /**
5387
+ * Link to discussion
5388
+ */
5389
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/22',
5390
+ /**
5391
+ * Example usages of the PERSONA command
5392
+ */
5393
+ examples: ['PERSONA Jane, skilled copywriter', 'PERSONA Joe, male 28 years old, programmer'],
5394
+ /**
5395
+ * Parses the PERSONA command
5396
+ */
5397
+ parse: function (input) {
5398
+ var rawArgs = input.rawArgs;
5399
+ var _a = __read(rawArgs.split(/[,;:]/, 2), 2), personaNameRaw = _a[0], personaDescriptionRaw = _a[1];
5400
+ var personaName = (personaNameRaw || '').trim();
5401
+ if (personaName === '') {
5402
+ throw new ParseError("You must set name for the persona");
5403
+ }
5404
+ var personaDescription = (personaDescriptionRaw || '').trim();
5405
+ if (personaDescription === '') {
5406
+ personaDescription = null;
5407
+ }
5408
+ return {
5409
+ type: 'PERSONA',
5410
+ personaName: personaName,
5411
+ personaDescription: personaDescription,
5412
+ };
5413
+ },
5414
+ /**
5415
+ * Apply the PERSONA command to the `pipelineJson`
5416
+ *
5417
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5418
+ */
5419
+ $applyToPipelineJson: function (command, $pipelineJson) {
5420
+ $applyToTemplateJson(command, null, $pipelineJson);
5421
+ },
5422
+ $applyToTemplateJson: $applyToTemplateJson,
5423
+ /**
5424
+ * Converts the PERSONA command back to string
5425
+ *
5426
+ * Note: This is used in `pipelineJsonToString` utility
5427
+ */
5428
+ stringify: function (command) {
5429
+ keepUnused(command);
5430
+ return "!!!!!!";
5431
+ },
5432
+ /**
5433
+ * Reads the PERSONA command from the `PipelineJson`
5434
+ *
5435
+ * Note: This is used in `pipelineJsonToString` utility
5436
+ */
5437
+ takeFromPipelineJson: function (pipelineJson) {
5438
+ keepUnused(pipelineJson);
5439
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5440
+ },
5441
+ /**
5442
+ * Reads the PERSONA command from the `TemplateJson`
5443
+ *
5444
+ * Note: This is used in `pipelineJsonToString` utility
5445
+ */
5446
+ takeFromTemplateJson: function ($templateJson) {
5447
+ keepUnused($templateJson);
5448
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5449
+ },
5450
+ };
5451
+ /**
5452
+ * Apply the PERSONA command to the `pipelineJson`
5453
+ *
5454
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5455
+ */
5456
+ function $applyToTemplateJson(command, $templateJson, $pipelineJson) {
5457
+ var personaName = command.personaName, personaDescription = command.personaDescription;
5458
+ if ($templateJson !== null) {
5459
+ if ($templateJson.blockType !== 'PROMPT_TEMPLATE') {
5460
+ throw new ParseError("PERSONA command can be used only in PROMPT_TEMPLATE block");
5461
+ }
5462
+ $templateJson.personaName = personaName;
5463
+ }
5464
+ var persona = $pipelineJson.personas.find(function (persona) { return persona.name === personaName; });
5465
+ if (persona === undefined) {
5466
+ $pipelineJson.personas.push({
5467
+ name: personaName,
5468
+ description: personaDescription || '',
5469
+ });
5470
+ return;
5471
+ }
5472
+ if (persona.description === personaDescription) {
5473
+ return;
5474
+ }
5475
+ if (personaDescription === null) {
5476
+ return;
5477
+ }
5478
+ if (persona.description === '') {
5479
+ persona.description = personaDescription;
5480
+ return;
5481
+ }
5482
+ console.warn(spaceTrim$1("\n\n Persona \"".concat(personaName, "\" is defined multiple times with different description:\n\n First definition:\n ").concat(persona.description, "\n\n Second definition:\n ").concat(personaDescription, "\n\n ")));
5483
+ persona.description += spaceTrim$1('\n\n' + personaDescription);
5484
+ }
5485
+
5108
5486
  /**
5109
5487
  * @@@
5110
5488
  *
@@ -5134,7 +5512,8 @@ var postprocessCommandParser = {
5134
5512
  /**
5135
5513
  * BOILERPLATE command can be used in:
5136
5514
  */
5137
- usagePlaces: ['PIPELINE_TEMPLATE'],
5515
+ isUsedInPipelineHead: false,
5516
+ isUsedInPipelineTemplate: true,
5138
5517
  /**
5139
5518
  * Description of the POSTPROCESS command
5140
5519
  */
@@ -5156,19 +5535,46 @@ var postprocessCommandParser = {
5156
5535
  var args = input.args;
5157
5536
  var functionName = args.pop();
5158
5537
  if (functionName === undefined) {
5159
- throw new ParsingError("Postprocess function name is required");
5538
+ throw new ParseError("Postprocess function name is required");
5160
5539
  }
5161
5540
  if (!isValidJavascriptName(functionName)) {
5162
- throw new ParsingError("Invalid postprocess function name \"".concat(functionName, "\""));
5541
+ throw new ParseError("Invalid postprocess function name \"".concat(functionName, "\""));
5163
5542
  }
5164
5543
  if (args.length > 0) {
5165
- throw new ParsingError("Can not have more than one postprocess function");
5544
+ throw new ParseError("Can not have more than one postprocess function");
5166
5545
  }
5167
5546
  return {
5168
5547
  type: 'POSTPROCESS',
5169
5548
  functionName: functionName,
5170
5549
  };
5171
5550
  },
5551
+ /**
5552
+ * Apply the POSTPROCESS command to the `pipelineJson`
5553
+ *
5554
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5555
+ */
5556
+ $applyToTemplateJson: function (command, $templateJson) {
5557
+ $templateJson.postprocessingFunctionNames = $templateJson.postprocessingFunctionNames || [];
5558
+ $templateJson.postprocessingFunctionNames.push(command.functionName);
5559
+ },
5560
+ /**
5561
+ * Converts the POSTPROCESS command back to string
5562
+ *
5563
+ * Note: This is used in `pipelineJsonToString` utility
5564
+ */
5565
+ stringify: function (command) {
5566
+ keepUnused(command);
5567
+ return "!!!!!!";
5568
+ },
5569
+ /**
5570
+ * Reads the POSTPROCESS command from the `TemplateJson`
5571
+ *
5572
+ * Note: This is used in `pipelineJsonToString` utility
5573
+ */
5574
+ takeFromTemplateJson: function ($templateJson) {
5575
+ keepUnused($templateJson);
5576
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5577
+ },
5172
5578
  };
5173
5579
 
5174
5580
  /**
@@ -5186,7 +5592,8 @@ var promptbookVersionCommandParser = {
5186
5592
  /**
5187
5593
  * BOILERPLATE command can be used in:
5188
5594
  */
5189
- usagePlaces: ['PIPELINE_HEAD'],
5595
+ isUsedInPipelineHead: true,
5596
+ isUsedInPipelineTemplate: false,
5190
5597
  /**
5191
5598
  * Description of the PROMPTBOOK_VERSION command
5192
5599
  */
@@ -5206,19 +5613,45 @@ var promptbookVersionCommandParser = {
5206
5613
  var args = input.args;
5207
5614
  var promptbookVersion = args.pop();
5208
5615
  if (promptbookVersion === undefined) {
5209
- throw new ParsingError("Version is required");
5616
+ throw new ParseError("Version is required");
5210
5617
  }
5211
5618
  if (!isValidPromptbookVersion(promptbookVersion)) {
5212
- throw new ParsingError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
5619
+ throw new ParseError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
5213
5620
  }
5214
5621
  if (args.length > 0) {
5215
- throw new ParsingError("Can not have more than one Promptbook version");
5622
+ throw new ParseError("Can not have more than one Promptbook version");
5216
5623
  }
5217
5624
  return {
5218
5625
  type: 'PROMPTBOOK_VERSION',
5219
5626
  promptbookVersion: promptbookVersion,
5220
5627
  };
5221
5628
  },
5629
+ /**
5630
+ * Apply the PROMPTBOOK_VERSION command to the `pipelineJson`
5631
+ *
5632
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5633
+ */
5634
+ $applyToPipelineJson: function (command, $pipelineJson) {
5635
+ $pipelineJson.promptbookVersion = command.promptbookVersion;
5636
+ },
5637
+ /**
5638
+ * Converts the PROMPTBOOK_VERSION command back to string
5639
+ *
5640
+ * Note: This is used in `pipelineJsonToString` utility
5641
+ */
5642
+ stringify: function (command) {
5643
+ keepUnused(command);
5644
+ return "!!!!!!";
5645
+ },
5646
+ /**
5647
+ * Reads the PROMPTBOOK_VERSION command from the `PipelineJson`
5648
+ *
5649
+ * Note: This is used in `pipelineJsonToString` utility
5650
+ */
5651
+ takeFromPipelineJson: function (pipelineJson) {
5652
+ keepUnused(pipelineJson);
5653
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5654
+ },
5222
5655
  };
5223
5656
 
5224
5657
  /**
@@ -5240,7 +5673,8 @@ var urlCommandParser = {
5240
5673
  /**
5241
5674
  * BOILERPLATE command can be used in:
5242
5675
  */
5243
- usagePlaces: ['PIPELINE_HEAD'],
5676
+ isUsedInPipelineHead: true,
5677
+ isUsedInPipelineTemplate: false,
5244
5678
  /**
5245
5679
  * Description of the URL command
5246
5680
  */
@@ -5264,23 +5698,23 @@ var urlCommandParser = {
5264
5698
  var args = input.args;
5265
5699
  var pipelineUrl = args.pop();
5266
5700
  if (pipelineUrl === undefined) {
5267
- throw new ParsingError("URL is required");
5701
+ throw new ParseError("URL is required");
5268
5702
  }
5269
5703
  // TODO: [🧠][🚲] This should be maybe tested as logic not syntax
5270
5704
  if (!isValidPipelineUrl(pipelineUrl)) {
5271
- throw new ParsingError("Invalid pipeline URL \"".concat(pipelineUrl, "\""));
5705
+ throw new ParseError("Invalid pipeline URL \"".concat(pipelineUrl, "\""));
5272
5706
  }
5273
5707
  if (args.length > 0) {
5274
- throw new ParsingError("Can not have more than one pipeline URL");
5708
+ throw new ParseError("Can not have more than one pipeline URL");
5275
5709
  }
5276
5710
  /*
5277
5711
  TODO: [🐠 Maybe more info from `isValidPipelineUrl`:
5278
5712
  if (pipelineUrl.protocol !== 'https:') {
5279
- throw new ParsingError(`Protocol must be HTTPS`);
5713
+ throw new ParseError(`Protocol must be HTTPS`);
5280
5714
  }
5281
5715
 
5282
5716
  if (pipelineUrl.hash !== '') {
5283
- throw new ParsingError(
5717
+ throw new ParseError(
5284
5718
  spaceTrim(
5285
5719
  `
5286
5720
  URL must not contain hash
@@ -5295,6 +5729,32 @@ var urlCommandParser = {
5295
5729
  pipelineUrl: new URL(pipelineUrl),
5296
5730
  };
5297
5731
  },
5732
+ /**
5733
+ * Apply the URL command to the `pipelineJson`
5734
+ *
5735
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5736
+ */
5737
+ $applyToPipelineJson: function (command, $pipelineJson) {
5738
+ $pipelineJson.pipelineUrl = command.pipelineUrl.href;
5739
+ },
5740
+ /**
5741
+ * Converts the URL command back to string
5742
+ *
5743
+ * Note: This is used in `pipelineJsonToString` utility
5744
+ */
5745
+ stringify: function (command) {
5746
+ keepUnused(command);
5747
+ return "!!!!!!";
5748
+ },
5749
+ /**
5750
+ * Reads the URL command from the `PipelineJson`
5751
+ *
5752
+ * Note: This is used in `pipelineJsonToString` utility
5753
+ */
5754
+ takeFromPipelineJson: function (pipelineJson) {
5755
+ keepUnused(pipelineJson);
5756
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5757
+ },
5298
5758
  };
5299
5759
 
5300
5760
  /**
@@ -5311,7 +5771,8 @@ var actionCommandParser = {
5311
5771
  /**
5312
5772
  * ACTION command can be used in:
5313
5773
  */
5314
- usagePlaces: ['PIPELINE_HEAD', 'PIPELINE_TEMPLATE'],
5774
+ isUsedInPipelineHead: true,
5775
+ isUsedInPipelineTemplate: false,
5315
5776
  /**
5316
5777
  * Description of the ACTION command
5317
5778
  */
@@ -5334,6 +5795,33 @@ var actionCommandParser = {
5334
5795
  type: 'ACTION',
5335
5796
  };
5336
5797
  },
5798
+ /**
5799
+ * Apply the ACTION command to the `pipelineJson`
5800
+ *
5801
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5802
+ */
5803
+ $applyToPipelineJson: function (command, $pipelineJson) {
5804
+ keepUnused(command, $pipelineJson);
5805
+ console.error(new NotYetImplementedError('Actions are not implemented yet'));
5806
+ },
5807
+ /**
5808
+ * Converts the ACTION command back to string
5809
+ *
5810
+ * Note: This is used in `pipelineJsonToString` utility
5811
+ */
5812
+ stringify: function (command) {
5813
+ keepUnused(command);
5814
+ return "!!!!!!";
5815
+ },
5816
+ /**
5817
+ * Reads the ACTION command from the `PipelineJson`
5818
+ *
5819
+ * Note: This is used in `pipelineJsonToString` utility
5820
+ */
5821
+ takeFromPipelineJson: function (pipelineJson) {
5822
+ keepUnused(pipelineJson);
5823
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5824
+ },
5337
5825
  };
5338
5826
 
5339
5827
  /**
@@ -5350,7 +5838,8 @@ var instrumentCommandParser = {
5350
5838
  /**
5351
5839
  * INSTRUMENT command can be used in:
5352
5840
  */
5353
- usagePlaces: ['PIPELINE_HEAD', 'PIPELINE_TEMPLATE'],
5841
+ isUsedInPipelineHead: true,
5842
+ isUsedInPipelineTemplate: false,
5354
5843
  /**
5355
5844
  * Description of the INSTRUMENT command
5356
5845
  */
@@ -5373,12 +5862,41 @@ var instrumentCommandParser = {
5373
5862
  type: 'INSTRUMENT',
5374
5863
  };
5375
5864
  },
5865
+ /**
5866
+ * Apply the INSTRUMENT command to the `pipelineJson`
5867
+ *
5868
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5869
+ */
5870
+ $applyToPipelineJson: function (command, $pipelineJson) {
5871
+ keepUnused(command, $pipelineJson);
5872
+ console.error(new NotYetImplementedError('Instruments are not implemented yet'));
5873
+ },
5874
+ /**
5875
+ * Converts the INSTRUMENT command back to string
5876
+ *
5877
+ * Note: This is used in `pipelineJsonToString` utility
5878
+ */
5879
+ stringify: function (command) {
5880
+ keepUnused(command);
5881
+ return "!!!!!!";
5882
+ },
5883
+ /**
5884
+ * Reads the INSTRUMENT command from the `PipelineJson`
5885
+ *
5886
+ * Note: This is used in `pipelineJsonToString` utility
5887
+ */
5888
+ takeFromPipelineJson: function (pipelineJson) {
5889
+ keepUnused(pipelineJson);
5890
+ throw new NotYetImplementedError("Not implemented yet !!!!!!");
5891
+ },
5376
5892
  };
5377
5893
 
5378
5894
  /**
5379
5895
  * Parses the boilerplate command
5380
5896
  *
5381
- * @see ./BOILERPLATE-README.md for more details
5897
+ * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.ptbk.md` file
5898
+ *
5899
+ * @see ./BOILERPLATE-README.md for more details <- TODO: @@@ Write theese README files OR remove this link + add annotation here (to all commands)
5382
5900
  * @private within the commands folder
5383
5901
  */
5384
5902
  var boilerplateCommandParser = {
@@ -5393,7 +5911,8 @@ var boilerplateCommandParser = {
5393
5911
  /**
5394
5912
  * BOILERPLATE command can be used in:
5395
5913
  */
5396
- usagePlaces: ['PIPELINE_HEAD', 'PIPELINE_TEMPLATE'],
5914
+ isUsedInPipelineHead: true,
5915
+ isUsedInPipelineTemplate: true,
5397
5916
  /**
5398
5917
  * Description of the BOILERPLATE command
5399
5918
  */
@@ -5412,20 +5931,65 @@ var boilerplateCommandParser = {
5412
5931
  parse: function (input) {
5413
5932
  var args = input.args;
5414
5933
  if (args.length !== 1) {
5415
- throw new ParsingError("BOILERPLATE command requires exactly one argument");
5934
+ throw new ParseError("BOILERPLATE command requires exactly one argument");
5416
5935
  }
5417
5936
  var value = args[0].toLowerCase();
5418
5937
  if (value.includes('brr')) {
5419
- throw new ParsingError("BOILERPLATE value can not contain brr");
5938
+ throw new ParseError("BOILERPLATE value can not contain brr");
5420
5939
  }
5421
5940
  return {
5422
5941
  type: 'BOILERPLATE',
5423
5942
  value: value,
5424
5943
  };
5425
5944
  },
5945
+ /**
5946
+ * Apply the BOILERPLATE command to the `pipelineJson`
5947
+ *
5948
+ * Note: `$` is used to indicate that this function mutates given `pipelineJson`
5949
+ */
5950
+ $applyToPipelineJson: function (command, $pipelineJson) {
5951
+ keepUnused(command, $pipelineJson);
5952
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
5953
+ },
5954
+ /**
5955
+ * Apply the BOILERPLATE command to the `pipelineJson`
5956
+ *
5957
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5958
+ */
5959
+ $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5960
+ keepUnused(command, $templateJson, $pipelineJson);
5961
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
5962
+ },
5963
+ /**
5964
+ * Converts the BOILERPLATE command back to string
5965
+ *
5966
+ * Note: This is used in `pipelineJsonToString` utility
5967
+ */
5968
+ stringify: function (command) {
5969
+ keepUnused(command);
5970
+ return "!!!!!!";
5971
+ },
5972
+ /**
5973
+ * Reads the BOILERPLATE command from the `PipelineJson`
5974
+ *
5975
+ * Note: This is used in `pipelineJsonToString` utility
5976
+ */
5977
+ takeFromPipelineJson: function (pipelineJson) {
5978
+ keepUnused(pipelineJson);
5979
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
5980
+ },
5981
+ /**
5982
+ * Reads the BOILERPLATE command from the `TemplateJson`
5983
+ *
5984
+ * Note: This is used in `pipelineJsonToString` utility
5985
+ */
5986
+ takeFromTemplateJson: function ($templateJson) {
5987
+ keepUnused($templateJson);
5988
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
5989
+ },
5426
5990
  };
5427
5991
  /**
5428
- * TODO: [💐] Implement BOILERPLATE command into `pipelineStringToJsonSync` function
5992
+ * TODO: !!!!!! Make .ptbk.md file with examples of the BOILERPLATE command and fail
5429
5993
  */
5430
5994
 
5431
5995
  /**
@@ -5436,6 +6000,7 @@ var boilerplateCommandParser = {
5436
6000
  var COMMANDS = [
5437
6001
  blockCommandParser,
5438
6002
  expectCommandParser,
6003
+ formatCommandParser,
5439
6004
  jokerCommandParser,
5440
6005
  modelCommandParser,
5441
6006
  parameterCommandParser,
@@ -5446,20 +6011,108 @@ var COMMANDS = [
5446
6011
  actionCommandParser,
5447
6012
  instrumentCommandParser,
5448
6013
  personaCommandParser,
6014
+ foreachCommandParser,
5449
6015
  boilerplateCommandParser, // <- TODO: !! Only in development, remove in production
5450
6016
  ];
5451
6017
 
6018
+ /**
6019
+ * Removes Markdown formatting tags from a string.
6020
+ *
6021
+ * @param {string} str - The string to remove Markdown tags from.
6022
+ * @returns {string} The input string with all Markdown tags removed.
6023
+ * @public exported from `@promptbook/markdown-utils`
6024
+ */
6025
+ function removeMarkdownFormatting(str) {
6026
+ // Remove bold formatting
6027
+ str = str.replace(/\*\*(.*?)\*\*/g, '$1');
6028
+ // Remove italic formatting
6029
+ str = str.replace(/\*(.*?)\*/g, '$1');
6030
+ // Remove code formatting
6031
+ str = str.replace(/`(.*?)`/g, '$1');
6032
+ return str;
6033
+ }
6034
+
6035
+ /**
6036
+ * @@@
6037
+ *
6038
+ * @param text @@@
6039
+ * @returns @@@
6040
+ * @example 'HELLO_WORLD'
6041
+ * @example 'I_LOVE_PROMPTBOOK'
6042
+ * @public exported from `@promptbook/utils`
6043
+ */
6044
+ function normalizeTo_SCREAMING_CASE(text) {
6045
+ var e_1, _a;
6046
+ var charType;
6047
+ var lastCharType = 'OTHER';
6048
+ var normalizedName = '';
6049
+ try {
6050
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
6051
+ var char = text_1_1.value;
6052
+ var normalizedChar = void 0;
6053
+ if (/^[a-z]$/.test(char)) {
6054
+ charType = 'LOWERCASE';
6055
+ normalizedChar = char.toUpperCase();
6056
+ }
6057
+ else if (/^[A-Z]$/.test(char)) {
6058
+ charType = 'UPPERCASE';
6059
+ normalizedChar = char;
6060
+ }
6061
+ else if (/^[0-9]$/.test(char)) {
6062
+ charType = 'NUMBER';
6063
+ normalizedChar = char;
6064
+ }
6065
+ else if (/^\/$/.test(char)) {
6066
+ charType = 'SLASH';
6067
+ normalizedChar = char;
6068
+ }
6069
+ else {
6070
+ charType = 'OTHER';
6071
+ normalizedChar = '_';
6072
+ }
6073
+ if (charType !== lastCharType &&
6074
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
6075
+ !(lastCharType === 'NUMBER') &&
6076
+ !(charType === 'NUMBER')) {
6077
+ normalizedName += '_';
6078
+ }
6079
+ normalizedName += normalizedChar;
6080
+ lastCharType = charType;
6081
+ }
6082
+ }
6083
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6084
+ finally {
6085
+ try {
6086
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
6087
+ }
6088
+ finally { if (e_1) throw e_1.error; }
6089
+ }
6090
+ normalizedName = normalizedName.replace(/_+/g, '_');
6091
+ normalizedName = normalizedName.replace(/_?\/_?/g, '/');
6092
+ normalizedName = normalizedName.replace(/^_/, '');
6093
+ normalizedName = normalizedName.replace(/_$/, '');
6094
+ return normalizedName;
6095
+ }
6096
+ /**
6097
+ * TODO: Tests
6098
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
6099
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
6100
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
6101
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
6102
+ * TODO: [🌺] Use some intermediate util splitWords
6103
+ */
6104
+
5452
6105
  /**
5453
6106
  * Parses one line of ul/ol to command
5454
6107
  *
5455
6108
  * @returns parsed command object
5456
- * @throws {ParsingError} if the command is invalid
6109
+ * @throws {ParseError} if the command is invalid
5457
6110
  *
5458
6111
  * @private within the pipelineStringToJson
5459
6112
  */
5460
6113
  function parseCommand(raw, usagePlace) {
5461
6114
  if (raw.includes('\n') || raw.includes('\r')) {
5462
- throw new ParsingError('Command can not contain new line characters' /* <- TODO: [🚞] */);
6115
+ throw new ParseError('Command can not contain new line characters' /* <- TODO: [🚞] */);
5463
6116
  }
5464
6117
  var normalized = raw.trim();
5465
6118
  normalized = normalized.split('`').join('');
@@ -5496,7 +6149,7 @@ function parseCommand(raw, usagePlace) {
5496
6149
  .map(removeMarkdownFormatting)
5497
6150
  .map(function (item) { return item.trim(); });
5498
6151
  if (items.length === 0 || items[0] === '') {
5499
- throw new ParsingError(spaceTrim(function (block) {
6152
+ throw new ParseError(spaceTrim(function (block) {
5500
6153
  return "\n Malformed command:\n\n - ".concat(raw, "\n\n Supported commands are:\n ").concat(block(getSupportedCommandsMessage()), "\n\n ");
5501
6154
  }));
5502
6155
  }
@@ -5523,7 +6176,7 @@ function parseCommand(raw, usagePlace) {
5523
6176
  return command;
5524
6177
  }
5525
6178
  }
5526
- throw new ParsingError(spaceTrim(function (block) {
6179
+ throw new ParseError(spaceTrim(function (block) {
5527
6180
  return "\n Malformed or unknown command:\n\n - ".concat(raw, "\n\n Supported commands are:\n ").concat(block(getSupportedCommandsMessage()), "\n\n ");
5528
6181
  }));
5529
6182
  }
@@ -5533,6 +6186,7 @@ function parseCommand(raw, usagePlace) {
5533
6186
  function getSupportedCommandsMessage() {
5534
6187
  return COMMANDS.flatMap(function (_a) {
5535
6188
  var name = _a.name, aliasNames = _a.aliasNames, description = _a.description, documentationUrl = _a.documentationUrl;
6189
+ // <- Note: [🦦] Its strange that this type assertion is needed
5536
6190
  return __spreadArray([
5537
6191
  "- **".concat(name, "** ").concat(description, ", see [discussion](").concat(documentationUrl, ")")
5538
6192
  ], __read((aliasNames || []).map(function (aliasName) { return " - **".concat(aliasName, "** Alias for **").concat(name, "**"); })), false);
@@ -5546,27 +6200,34 @@ function parseCommandVariant(input) {
5546
6200
  var commandNameRaw = input.commandNameRaw, usagePlace = input.usagePlace, normalized = input.normalized, args = input.args, raw = input.raw, rawArgs = input.rawArgs;
5547
6201
  var commandName = normalizeTo_SCREAMING_CASE(commandNameRaw);
5548
6202
  var _loop_1 = function (commandParser) {
5549
- var name_1 = commandParser.name, aliasNames = commandParser.aliasNames, deprecatedNames = commandParser.deprecatedNames, parse = commandParser.parse;
6203
+ // <- Note: [🦦] Its strange that this type assertion is needed
6204
+ var name_1 = commandParser.name, isUsedInPipelineHead = commandParser.isUsedInPipelineHead, isUsedInPipelineTemplate = commandParser.isUsedInPipelineTemplate, aliasNames = commandParser.aliasNames, deprecatedNames = commandParser.deprecatedNames, parse = commandParser.parse;
6205
+ if (just(false)) {
6206
+ keepUnused( /* for better indentation */);
6207
+ }
6208
+ else if (usagePlace === 'PIPELINE_HEAD' && !isUsedInPipelineHead) {
6209
+ return "continue";
6210
+ }
6211
+ else if (usagePlace === 'PIPELINE_TEMPLATE' && !isUsedInPipelineTemplate) {
6212
+ return "continue";
6213
+ }
5550
6214
  var names = __spreadArray(__spreadArray([name_1], __read((aliasNames || [])), false), __read((deprecatedNames || [])), false);
5551
6215
  if (names.includes(commandName)) {
5552
6216
  try {
5553
6217
  return { value: parse({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args }) };
5554
6218
  }
5555
6219
  catch (error) {
5556
- if (!(error instanceof ParsingError)) {
6220
+ if (!(error instanceof ParseError)) {
5557
6221
  throw error;
5558
6222
  }
5559
- throw new ParsingError(spaceTrim(function (block) {
6223
+ throw new ParseError(spaceTrim(function (block) {
5560
6224
  return "\n Invalid ".concat(commandName, " command:\n ").concat(block(error.message), "\n\n - ").concat(raw, "\n\n Usage of ").concat(commandName, ":\n ").concat(block(commandParser.examples.map(function (example) { return "- ".concat(example); }).join('\n')), "\n\n All supported commands are:\n ").concat(block(getSupportedCommandsMessage()), "\n\n ");
5561
6225
  }));
5562
6226
  }
5563
6227
  }
5564
6228
  };
5565
6229
  try {
5566
- for (var _b = __values(COMMANDS.filter(function (_a) {
5567
- var places = _a.usagePlaces;
5568
- return places.includes(usagePlace);
5569
- })), _c = _b.next(); !_c.done; _c = _b.next()) {
6230
+ for (var _b = __values(COMMANDS), _c = _b.next(); !_c.done; _c = _b.next()) {
5570
6231
  var commandParser = _c.value;
5571
6232
  var state_1 = _loop_1(commandParser);
5572
6233
  if (typeof state_1 === "object")
@@ -5633,7 +6294,7 @@ function extractAllListItemsFromMarkdown(markdown) {
5633
6294
  /**
5634
6295
  * Extracts exactly ONE code block from markdown.
5635
6296
  *
5636
- * - When there are multiple or no code blocks the function throws a `ParsingError`
6297
+ * - When there are multiple or no code blocks the function throws a `ParseError`
5637
6298
  *
5638
6299
  * Note: There are multiple simmilar function:
5639
6300
  * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
@@ -5644,12 +6305,12 @@ function extractAllListItemsFromMarkdown(markdown) {
5644
6305
  * @param markdown any valid markdown
5645
6306
  * @returns code block with language and content
5646
6307
  * @public exported from `@promptbook/markdown-utils`
5647
- * @throws {ParsingError} if there is not exactly one code block in the markdown
6308
+ * @throws {ParseError} if there is not exactly one code block in the markdown
5648
6309
  */
5649
6310
  function extractOneBlockFromMarkdown(markdown) {
5650
6311
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
5651
6312
  if (codeBlocks.length !== 1) {
5652
- throw new ParsingError(spaceTrim$1(function (block) { return "\n There should be exactly 1 code block, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
6313
+ throw new ParseError(spaceTrim$1(function (block) { return "\n There should be exactly 1 code block, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
5653
6314
  }
5654
6315
  return codeBlocks[0];
5655
6316
  }
@@ -5666,13 +6327,13 @@ function parseMarkdownSection(value) {
5666
6327
  var _a, _b;
5667
6328
  var lines = value.split('\n');
5668
6329
  if (!lines[0].startsWith('#')) {
5669
- throw new ParsingError('Markdown section must start with heading');
6330
+ throw new ParseError('Markdown section must start with heading');
5670
6331
  }
5671
6332
  var title = lines[0].replace(/^#+\s*/, '');
5672
6333
  var level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
5673
6334
  var content = spaceTrim$1(lines.slice(1).join('\n'));
5674
6335
  if (level < 1 || level > 6) {
5675
- throw new ParsingError('Markdown section must have heading level between 1 and 6');
6336
+ throw new ParseError('Markdown section must have heading level between 1 and 6');
5676
6337
  }
5677
6338
  return { title: title, level: level, content: content };
5678
6339
  }
@@ -5828,31 +6489,32 @@ function removeContentComments(content) {
5828
6489
  *
5829
6490
  * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
5830
6491
  * @returns {Promptbook} compiled in JSON format (.ptbk.json)
5831
- * @throws {ParsingError} if the promptbook string is not valid
6492
+ * @throws {ParseError} if the promptbook string is not valid
5832
6493
  * @public exported from `@promptbook/core`
5833
6494
  */
5834
6495
  function pipelineStringToJsonSync(pipelineString) {
5835
6496
  var e_1, _a, e_2, _b;
5836
- var pipelineJson = {
5837
- title: undefined /* <- Note: Putting here placeholder to keep `title` on top at final JSON */,
6497
+ var $pipelineJson = {
6498
+ title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
5838
6499
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
5839
6500
  promptbookVersion: PROMPTBOOK_VERSION,
5840
- description: undefined /* <- Note: Putting here placeholder to keep `description` on top at final JSON */,
6501
+ description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
5841
6502
  parameters: [],
5842
- promptTemplates: [],
6503
+ templates: [],
5843
6504
  knowledgeSources: [],
5844
6505
  knowledgePieces: [],
5845
6506
  personas: [],
5846
6507
  preparations: [],
6508
+ // <- TODO: [🍙] Some standard order of properties
5847
6509
  };
5848
6510
  function getPipelineIdentification() {
5849
6511
  // Note: This is a 😐 implementation of [🚞]
5850
6512
  var _ = [];
5851
- if (pipelineJson.sourceFile !== undefined) {
5852
- _.push("File: ".concat(pipelineJson.sourceFile));
6513
+ if ($pipelineJson.sourceFile !== undefined) {
6514
+ _.push("File: ".concat($pipelineJson.sourceFile));
5853
6515
  }
5854
- if (pipelineJson.pipelineUrl !== undefined) {
5855
- _.push("Url: ".concat(pipelineJson.pipelineUrl));
6516
+ if ($pipelineJson.pipelineUrl !== undefined) {
6517
+ _.push("Url: ".concat($pipelineJson.pipelineUrl));
5856
6518
  }
5857
6519
  return _.join('\n');
5858
6520
  }
@@ -5877,14 +6539,14 @@ function pipelineStringToJsonSync(pipelineString) {
5877
6539
  var defineParam = function (parameterCommand) {
5878
6540
  var parameterName = parameterCommand.parameterName, parameterDescription = parameterCommand.parameterDescription, isInput = parameterCommand.isInput, isOutput = parameterCommand.isOutput;
5879
6541
  if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
5880
- throw new ParsingError(spaceTrim(function (block) { return "\n Parameter name {".concat(parameterName, "} is reserved and cannot be used as resulting parameter name\n\n ").concat(block(getPipelineIdentification()), "\n "); }) /* <- TODO: [🚞] */);
6542
+ throw new ParseError(spaceTrim(function (block) { return "\n Parameter name {".concat(parameterName, "} is reserved and cannot be used as resulting parameter name\n\n ").concat(block(getPipelineIdentification()), "\n "); }) /* <- TODO: [🚞] */);
5881
6543
  }
5882
- var existingParameter = pipelineJson.parameters.find(function (parameter) { return parameter.name === parameterName; });
6544
+ var existingParameter = $pipelineJson.parameters.find(function (parameter) { return parameter.name === parameterName; });
5883
6545
  if (existingParameter &&
5884
6546
  existingParameter.description &&
5885
6547
  existingParameter.description !== parameterDescription &&
5886
6548
  parameterDescription) {
5887
- throw new ParsingError(spaceTrim(function (block) { return "\n Parameter {".concat(parameterName, "} is defined multiple times with different description:\n\n ").concat(block(getPipelineIdentification()), "\n\n First definition:\n ").concat(block(existingParameter.description || '[undefined]'), "\n\n Second definition:\n ").concat(block(parameterDescription || '[undefined]'), "\n "); }));
6549
+ throw new ParseError(spaceTrim(function (block) { return "\n Parameter {".concat(parameterName, "} is defined multiple times with different description:\n\n ").concat(block(getPipelineIdentification()), "\n\n First definition:\n ").concat(block(existingParameter.description || '[undefined]'), "\n\n Second definition:\n ").concat(block(parameterDescription || '[undefined]'), "\n "); }));
5888
6550
  }
5889
6551
  if (existingParameter) {
5890
6552
  if (parameterDescription) {
@@ -5892,7 +6554,7 @@ function pipelineStringToJsonSync(pipelineString) {
5892
6554
  }
5893
6555
  }
5894
6556
  else {
5895
- pipelineJson.parameters.push({
6557
+ $pipelineJson.parameters.push({
5896
6558
  name: parameterName,
5897
6559
  description: parameterDescription || undefined,
5898
6560
  isInput: isInput,
@@ -5902,7 +6564,7 @@ function pipelineStringToJsonSync(pipelineString) {
5902
6564
  };
5903
6565
  // =============================================================
5904
6566
  // Note: 3️⃣ Process pipeline head
5905
- pipelineJson.title = pipelineHead.title;
6567
+ $pipelineJson.title = pipelineHead.title;
5906
6568
  // TODO: [🎾][1] DRY description
5907
6569
  var description = pipelineHead.content;
5908
6570
  // Note: Remove codeblocks - TODO: [🎾] Make util removeAllBlocksFromMarkdown (exported from `@promptbool/utils`)
@@ -5914,43 +6576,31 @@ function pipelineStringToJsonSync(pipelineString) {
5914
6576
  if (description === '') {
5915
6577
  description = undefined;
5916
6578
  }
5917
- pipelineJson.description = description;
5918
- var defaultModelRequirements = {};
6579
+ $pipelineJson.description = description;
5919
6580
  var listItems = extractAllListItemsFromMarkdown(pipelineHead.content);
5920
6581
  var _loop_1 = function (listItem) {
6582
+ // TODO: [🥥] Maybe move this logic to `$parseAndApplyPipelineHeadCommands`
5921
6583
  var command = parseCommand(listItem, 'PIPELINE_HEAD');
5922
- switch (command.type) {
5923
- // TODO: [🍧] Use here applyToPipelineJson and remove switch statement
5924
- case 'MODEL':
5925
- defaultModelRequirements[command.key] = command.value;
5926
- break;
5927
- case 'PARAMETER':
5928
- defineParam(command);
5929
- break;
5930
- case 'PROMPTBOOK_VERSION':
5931
- pipelineJson.promptbookVersion = command.promptbookVersion;
5932
- break;
5933
- case 'URL':
5934
- pipelineJson.pipelineUrl = command.pipelineUrl.href;
5935
- break;
5936
- case 'KNOWLEDGE':
5937
- knowledgeCommandParser.applyToPipelineJson(command, { pipelineJson: pipelineJson, templateJson: null });
5938
- break;
5939
- case 'ACTION':
5940
- console.error(new NotYetImplementedError('Actions are not implemented yet'));
5941
- break;
5942
- case 'INSTRUMENT':
5943
- console.error(new NotYetImplementedError('Instruments are not implemented yet'));
5944
- break;
5945
- case 'PERSONA':
5946
- personaCommandParser.applyToPipelineJson(command, { pipelineJson: pipelineJson, templateJson: null });
5947
- // <- Note: Prototype of [🍧] (remove this comment after full implementation)
5948
- break;
5949
- case 'BOILERPLATE':
5950
- throw new ParsingError(spaceTrim(function (block) { return "\n BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file\n\n ".concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
5951
- // <- [💐]
5952
- default:
5953
- throw new ParsingError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " is not allowed in the head of the promptbook ONLY at the pipeline template\n\n ").concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
6584
+ var commandParser = COMMANDS.find(function (commandParser) { return commandParser.name === command.type; });
6585
+ if (commandParser === undefined) {
6586
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " parser is not found \uD83C\uDF4E\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
6587
+ }
6588
+ if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
6589
+ throw new ParseError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " is not allowed in the head of the promptbook ONLY at the pipeline template\n\n ").concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
6590
+ }
6591
+ try {
6592
+ commandParser.$applyToPipelineJson(command, $pipelineJson);
6593
+ // <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitelly
6594
+ }
6595
+ catch (error) {
6596
+ if (!(error instanceof ParseError)) {
6597
+ throw error;
6598
+ }
6599
+ throw new ParseError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " failed to apply to the pipeline\n\n The error:\n ").concat(block(error.message), "\n\n Raw command:\n - ").concat(listItem, "\n\n Usage of ").concat(command.type, ":\n ").concat(block(commandParser.examples.map(function (example) { return "- ".concat(example); }).join('\n')), "\n\n ").concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
6600
+ }
6601
+ if (command.type === 'PARAMETER') {
6602
+ defineParam(command);
6603
+ // <- Note: [🍣]
5954
6604
  }
5955
6605
  };
5956
6606
  try {
@@ -5969,27 +6619,7 @@ function pipelineStringToJsonSync(pipelineString) {
5969
6619
  var _loop_2 = function (section) {
5970
6620
  var e_3, _d;
5971
6621
  // TODO: Parse prompt template description (the content out of the codeblock and lists)
5972
- var templateModelRequirements = __assign({}, defaultModelRequirements);
5973
- var listItems_3 = extractAllListItemsFromMarkdown(section.content);
5974
- var lastLine = section.content.split('\n').pop();
5975
- var resultingParameterNameMatch = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im.exec(lastLine);
5976
- var resultingParameterName = null;
5977
- if (resultingParameterNameMatch &&
5978
- resultingParameterNameMatch.groups !== undefined &&
5979
- resultingParameterNameMatch.groups.resultingParamName !== undefined) {
5980
- resultingParameterName = resultingParameterNameMatch.groups.resultingParamName;
5981
- }
5982
- var expectResultingParameterName = function () {
5983
- if (resultingParameterName !== null) {
5984
- return resultingParameterName;
5985
- }
5986
- throw new ParsingError(spaceTrim(function (block) { return "\n Template section must end with -> {parameterName}\n\n ".concat(block(getPipelineIdentification()), "\n\n Invalid section:\n ").concat(block(
5987
- // TODO: Show code of invalid sections each time + DRY
5988
- section.content
5989
- .split('\n')
5990
- .map(function (line) { return " | ".concat(line); } /* <- TODO: [🚞] */)
5991
- .join('\n')), "\n "); }));
5992
- };
6622
+ var listItems_2 = extractAllListItemsFromMarkdown(section.content);
5993
6623
  var _e = extractOneBlockFromMarkdown(section.content), language = _e.language, content = _e.content;
5994
6624
  // TODO: [🎾][1] DRY description
5995
6625
  var description_1 = section.content;
@@ -6002,176 +6632,121 @@ function pipelineStringToJsonSync(pipelineString) {
6002
6632
  if (description_1 === '') {
6003
6633
  description_1 = undefined;
6004
6634
  }
6005
- var templateJson = {
6006
- blockType: 'PROMPT_TEMPLATE',
6635
+ var $templateJson = {
6636
+ isBlockTypeSet: false,
6637
+ isTemplateBlock: true,
6638
+ blockType: undefined /* <- Note: [🍙] Putting here placeholder to keep `blockType` on top at final JSON */,
6007
6639
  name: titleToName(section.title),
6008
6640
  title: section.title,
6009
6641
  description: description_1,
6010
- modelRequirements: templateModelRequirements,
6011
6642
  content: content,
6643
+ // <- TODO: [🍙] Some standard order of properties
6012
6644
  };
6013
- /**
6014
- * This is nessesary because block type can be
6015
- * - Set zero times, so anticipate 'PROMPT_TEMPLATE'
6016
- * - Set one time
6017
- * - Set more times - throw error
6018
- *
6019
- * Note: [2]
6020
- */
6021
- var isBlockTypeSet = false;
6022
- var _loop_3 = function (listItem) {
6023
- var command = parseCommand(listItem, 'PIPELINE_TEMPLATE');
6024
- // TODO [🍧][♓️] List commands and before apply order them
6025
- switch (command.type) {
6026
- // TODO: [🍧] Use here applyToPipelineJson and remove switch statement
6027
- case 'BLOCK':
6028
- if (isBlockTypeSet) {
6029
- throw new ParsingError(spaceTrim(function (block) { return "\n Block type is already defined in the prompt template. It can be defined only once.\n\n ".concat(block(getPipelineIdentification()), "\n "); }));
6030
- }
6031
- if (command.blockType === 'SAMPLE') {
6032
- expectResultingParameterName();
6033
- var parameter = pipelineJson.parameters.find(function (param) { return param.name === resultingParameterName; });
6034
- if (parameter === undefined) {
6035
- throw new ParsingError(spaceTrim(function (block) { return "\n Can not find parameter {".concat(resultingParameterName, "} to assign sample value\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
6036
- }
6037
- parameter.sampleValues = parameter.sampleValues || [];
6038
- parameter.sampleValues.push(content);
6039
- return "continue-templates";
6040
- }
6041
- if (command.blockType === 'KNOWLEDGE') {
6042
- knowledgeCommandParser.applyToPipelineJson({
6043
- type: 'KNOWLEDGE',
6044
- sourceContent: content, // <- TODO: [🐝] !!! Work with KNOWLEDGE which not referring to the source file or website, but its content itself
6045
- }, {
6046
- pipelineJson: pipelineJson,
6047
- templateJson: templateJson,
6048
- });
6049
- return "continue-templates";
6050
- }
6051
- if (command.blockType === 'ACTION') {
6052
- console.error(new NotYetImplementedError('Actions are not implemented yet'));
6053
- return "continue-templates";
6054
- }
6055
- if (command.blockType === 'INSTRUMENT') {
6056
- console.error(new NotYetImplementedError('Instruments are not implemented yet'));
6057
- return "continue-templates";
6058
- }
6059
- expectResultingParameterName();
6060
- templateJson.blockType = command.blockType;
6061
- isBlockTypeSet = true; //<- Note: [2]
6062
- break;
6063
- case 'EXPECT_AMOUNT':
6064
- // eslint-disable-next-line no-case-declarations
6065
- var unit_1 = command.unit.toLowerCase();
6066
- templateJson.expectations = templateJson.expectations || {};
6067
- templateJson.expectations[unit_1] = templateJson.expectations[unit_1] || {};
6068
- if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
6069
- if (templateJson.expectations[unit_1].min !== undefined) {
6070
- throw new ParsingError(spaceTrim(function (block) { return "\n Already defined minumum ".concat(templateJson.expectations[unit_1].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount, "\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
6071
- }
6072
- templateJson.expectations[unit_1].min = command.amount;
6073
- } /* not else */
6074
- if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
6075
- if (templateJson.expectations[unit_1].max !== undefined) {
6076
- throw new ParsingError(spaceTrim(function (block) { return "\n Already defined maximum ".concat(templateJson.expectations[unit_1].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount, "\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
6077
- }
6078
- templateJson.expectations[unit_1].max = command.amount;
6079
- }
6080
- break;
6081
- case 'EXPECT_FORMAT':
6082
- if (templateJson.expectFormat !== undefined && command.format !== templateJson.expectFormat) {
6083
- throw new ParsingError(spaceTrim(function (block) { return "\n Expect format is already defined to \"".concat(templateJson.expectFormat, "\".\n Now you try to redefine it by \"").concat(command.format, "\".\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
6084
- }
6085
- templateJson.expectFormat = command.format;
6086
- break;
6087
- case 'JOKER':
6088
- templateJson.jokerParameterNames = templateJson.jokerParameterNames || [];
6089
- templateJson.jokerParameterNames.push(command.parameterName);
6090
- break;
6091
- case 'MODEL':
6092
- templateModelRequirements[command.key] = command.value;
6093
- break;
6094
- case 'PARAMETER':
6095
- // Note: This is just for detecting resulitng parameter name
6096
- defineParam(command);
6097
- break;
6098
- case 'POSTPROCESS':
6099
- templateJson.postprocessingFunctionNames = templateJson.postprocessingFunctionNames || [];
6100
- templateJson.postprocessingFunctionNames.push(command.functionName);
6101
- break;
6102
- case 'KNOWLEDGE':
6103
- // TODO: [👙] The knowledge is maybe relevant for just this template
6104
- knowledgeCommandParser.applyToPipelineJson(command, { pipelineJson: pipelineJson, templateJson: templateJson });
6105
- break;
6106
- case 'ACTION':
6107
- // TODO: [👙] The action is maybe relevant for just this template
6108
- console.error(new NotYetImplementedError('Actions are not implemented yet'));
6109
- break;
6110
- case 'INSTRUMENT':
6111
- // TODO: [👙] The instrument is maybe relevant for just this template
6112
- console.error(new NotYetImplementedError('Instruments are not implemented yet'));
6113
- break;
6114
- case 'PERSONA':
6115
- personaCommandParser.applyToPipelineJson(command, { pipelineJson: pipelineJson, templateJson: templateJson });
6116
- // <- Note: Prototype of [🍧] (remove this comment after full implementation)
6117
- break;
6118
- case 'BOILERPLATE':
6119
- console.error(new ParsingError(spaceTrim(function (block) { return "\n BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file\n\n ".concat(block(getPipelineIdentification()), "\n "); })));
6120
- break;
6121
- // <- [💐]
6122
- default:
6123
- throw new ParsingError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " is not allowed in the block of the prompt template ONLY at the head of the pipeline\n\n ").concat(block(getPipelineIdentification()), "\n\n "); }));
6645
+ var lastLine = section.content.split('\n').pop();
6646
+ var resultingParameterNameMatch = /^->\s*\{(?<resultingParamName>[a-z0-9_]+)\}/im.exec(lastLine);
6647
+ if (resultingParameterNameMatch &&
6648
+ resultingParameterNameMatch.groups !== undefined &&
6649
+ resultingParameterNameMatch.groups.resultingParamName !== undefined) {
6650
+ $templateJson.resultingParameterName = resultingParameterNameMatch.groups.resultingParamName;
6651
+ }
6652
+ // TODO: [🥥] Maybe move this logic to `$parseAndApplyPipelineTemplateCommands`
6653
+ var commands = listItems_2.map(function (listItem) { return ({
6654
+ listItem: listItem,
6655
+ command: parseCommand(listItem, 'PIPELINE_TEMPLATE'),
6656
+ }); });
6657
+ // Note: If block type is not set, set it to 'PROMPT_TEMPLATE'
6658
+ if (commands.some(function (_a) {
6659
+ var command = _a.command;
6660
+ return command.type === 'BLOCK';
6661
+ }) === false) {
6662
+ blockCommandParser.$applyToTemplateJson({ type: 'BLOCK', blockType: 'PROMPT_TEMPLATE' }, $templateJson, $pipelineJson);
6663
+ }
6664
+ var _loop_3 = function (listItem, command) {
6665
+ var commandParser = COMMANDS.find(function (commandParser) { return commandParser.name === command.type; });
6666
+ if (commandParser === undefined) {
6667
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " parser is not found \uD83C\uDF4F\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
6668
+ }
6669
+ if (commandParser.isUsedInPipelineTemplate !== true /* <- Note: [🦦][4] */) {
6670
+ throw new ParseError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " is not allowed in the template of the promptbook ONLY at the pipeline head\n\n ").concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
6671
+ }
6672
+ try {
6673
+ commandParser.$applyToTemplateJson(
6674
+ // <- Note: [🦦] Its strange that this assertion must be here, [🦦][4] should do this assertion implicitelly
6675
+ command, $templateJson, $pipelineJson);
6676
+ }
6677
+ catch (error) {
6678
+ if (!(error instanceof ParseError)) {
6679
+ throw error;
6680
+ }
6681
+ throw new ParseError(spaceTrim(function (block) { return "\n Command ".concat(command.type, " failed to apply to the template\n\n The error:\n ").concat(block(error.message), "\n\n Current state of the template:\n ").concat(block(JSON.stringify($templateJson, null, 4)), "\n <- Maybe wrong order of commands?\n\n Raw command:\n - ").concat(listItem, "\n\n Usage of ").concat(command.type, ":\n ").concat(block(commandParser.examples.map(function (example) { return "- ".concat(example); }).join('\n')), "\n\n ").concat(block(getPipelineIdentification()), "\n "); })); // <- TODO: [🚞]
6682
+ }
6683
+ // TODO: !!!!!! Multiple problematic things in BLOCK command - blockCommandParser.$applyToTemplateJson
6684
+ if (command.type === 'PARAMETER') {
6685
+ defineParam(command);
6686
+ // <- Note: [🍣]
6124
6687
  }
6125
6688
  };
6126
6689
  try {
6127
- for (var listItems_2 = (e_3 = void 0, __values(listItems_3)), listItems_2_1 = listItems_2.next(); !listItems_2_1.done; listItems_2_1 = listItems_2.next()) {
6128
- var listItem = listItems_2_1.value;
6129
- var state_2 = _loop_3(listItem);
6130
- switch (state_2) {
6131
- case "continue-templates": return state_2;
6132
- }
6690
+ // TODO: !!!!!! Test error situation when `PERSONA` is used before `SIMPLE BLOCK`
6691
+ // TODO: !!!!!! Test error situation when `MODEL` is used before `SIMPLE BLOCK`
6692
+ // TODO [♓️] List commands and before apply order them
6693
+ for (var commands_1 = (e_3 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
6694
+ var _f = commands_1_1.value, listItem = _f.listItem, command = _f.command;
6695
+ _loop_3(listItem, command);
6133
6696
  }
6134
6697
  }
6135
6698
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
6136
6699
  finally {
6137
6700
  try {
6138
- if (listItems_2_1 && !listItems_2_1.done && (_d = listItems_2.return)) _d.call(listItems_2);
6701
+ if (commands_1_1 && !commands_1_1.done && (_d = commands_1.return)) _d.call(commands_1);
6139
6702
  }
6140
6703
  finally { if (e_3) throw e_3.error; }
6141
6704
  }
6142
- // TODO: [🍧] Should be done in BLOCK command
6143
- if (templateJson.blockType === 'SCRIPT') {
6705
+ // TODO: [🍧] !!!!!! Should be done in BLOCK command
6706
+ if ($templateJson.blockType === 'SCRIPT_TEMPLATE') {
6144
6707
  if (!language) {
6145
- throw new ParsingError(spaceTrim(function (block) { return "\n You must specify the language of the script in the prompt template\n\n ".concat(block(getPipelineIdentification()), "\n "); }));
6708
+ throw new ParseError(spaceTrim(function (block) { return "\n You must specify the language of the script in the prompt template\n\n ".concat(block(getPipelineIdentification()), "\n "); }));
6146
6709
  }
6147
6710
  if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
6148
- throw new ParsingError(spaceTrim(function (block) { return "\n Script language ".concat(language, " is not supported.\n\n Supported languages are:\n ").concat(block(SUPPORTED_SCRIPT_LANGUAGES.join(', ')), "\n\n "); }));
6711
+ throw new ParseError(spaceTrim(function (block) { return "\n Script language ".concat(language, " is not supported.\n\n Supported languages are:\n ").concat(block(SUPPORTED_SCRIPT_LANGUAGES.join(', ')), "\n\n "); }));
6149
6712
  }
6150
- templateJson.contentLanguage = language;
6713
+ $templateJson.contentLanguage =
6714
+ language;
6151
6715
  }
6152
- // TODO: [🍧][❔] Should be done in BLOCK command
6153
- if (templateModelRequirements.modelVariant === undefined) {
6154
- templateModelRequirements.modelVariant = 'CHAT';
6716
+ $templateJson.dependentParameterNames = Array.from(extractParameterNamesFromTemplate($templateJson));
6717
+ /*
6718
+ // TODO: [🍧] !!!!!! This should be checked in `MODEL` command + better error message
6719
+ // TODO: [🍧] !!!!!! Write error `.ptbk.md` file for `MODEL` and `PERSONA` command used in non-prompt template
6720
+ // TODO: [🍧] !!!!!! `PERSONA` command should behave same as `MODEL` command - only usable in prompt template
6721
+ if ($templateJson.blockType !== 'PROMPT_TEMPLATE' && $templateJson.modelRequirements !== undefined) {
6722
+ throw new UnexpectedError(
6723
+ spaceTrim(
6724
+ (block) => `
6725
+ Model requirements are defined for the block type ${
6726
+ $templateJson.blockType
6727
+ } which is not a prompt template
6728
+
6729
+ This should be avoided by the \`modelCommandParser\`
6730
+
6731
+ ${block(getPipelineIdentification())}
6732
+ `,
6733
+ ),
6734
+ );
6155
6735
  }
6156
- templateJson.dependentParameterNames = Array.from(extractParameterNamesFromPromptTemplate(templateJson));
6157
- // TODO: [🍧][❔] Remove this condition - modelRequirements should be put here via BLOCK command not removed when PROMPT_TEMPLATE
6158
- if (templateJson.blockType !== 'PROMPT_TEMPLATE') {
6159
- delete templateJson.modelRequirements;
6736
+ */
6737
+ if ($templateJson.isTemplateBlock) {
6738
+ delete $templateJson.isBlockTypeSet;
6739
+ delete $templateJson.isTemplateBlock;
6740
+ // TODO: [🍙] Maybe do reorder of `$templateJson` here
6741
+ $pipelineJson.templates.push($templateJson);
6160
6742
  }
6161
- // TODO: [🍧] Make this better - for example each command parser can call and apply this
6162
- templateJson.resultingParameterName = expectResultingParameterName( /* <- Note: This is once more redundant */);
6163
- // TODO: [🍧] What actually about preparation and pushing the block into `promptTemplates`
6164
- pipelineJson.promptTemplates.push(templateJson);
6165
6743
  };
6166
6744
  try {
6167
6745
  // =============================================================
6168
6746
  // Note: 4️⃣ Process each template of the pipeline
6169
- templates: for (var pipelineSections_1 = __values(pipelineSections), pipelineSections_1_1 = pipelineSections_1.next(); !pipelineSections_1_1.done; pipelineSections_1_1 = pipelineSections_1.next()) {
6747
+ /* TODO: !!!!!! Remove `templates:` */ for (var pipelineSections_1 = __values(pipelineSections), pipelineSections_1_1 = pipelineSections_1.next(); !pipelineSections_1_1.done; pipelineSections_1_1 = pipelineSections_1.next()) {
6170
6748
  var section = pipelineSections_1_1.value;
6171
- var state_1 = _loop_2(section);
6172
- switch (state_1) {
6173
- case "continue-templates": continue templates;
6174
- }
6749
+ _loop_2(section);
6175
6750
  }
6176
6751
  }
6177
6752
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
@@ -6183,13 +6758,13 @@ function pipelineStringToJsonSync(pipelineString) {
6183
6758
  }
6184
6759
  // =============================================================
6185
6760
  // Note: 5️⃣ Cleanup of undefined values
6186
- pipelineJson.promptTemplates.forEach(function (promptTemplates) {
6761
+ $pipelineJson.templates.forEach(function (templates) {
6187
6762
  var e_4, _a;
6188
6763
  try {
6189
- for (var _b = __values(Object.entries(promptTemplates)), _c = _b.next(); !_c.done; _c = _b.next()) {
6764
+ for (var _b = __values(Object.entries(templates)), _c = _b.next(); !_c.done; _c = _b.next()) {
6190
6765
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
6191
6766
  if (value === undefined) {
6192
- delete promptTemplates[key];
6767
+ delete templates[key];
6193
6768
  }
6194
6769
  }
6195
6770
  }
@@ -6201,7 +6776,7 @@ function pipelineStringToJsonSync(pipelineString) {
6201
6776
  finally { if (e_4) throw e_4.error; }
6202
6777
  }
6203
6778
  });
6204
- pipelineJson.parameters.forEach(function (parameter) {
6779
+ $pipelineJson.parameters.forEach(function (parameter) {
6205
6780
  var e_5, _a;
6206
6781
  try {
6207
6782
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
@@ -6220,7 +6795,8 @@ function pipelineStringToJsonSync(pipelineString) {
6220
6795
  }
6221
6796
  });
6222
6797
  // =============================================================
6223
- return $asDeeplyFrozenSerializableJson('pipelineJson', pipelineJson);
6798
+ // TODO: [🍙] Maybe do reorder of `$pipelineJson` here
6799
+ return $asDeeplyFrozenSerializableJson('pipelineJson', $pipelineJson);
6224
6800
  }
6225
6801
  /**
6226
6802
  * TODO: !!!! Warn if used only sync version
@@ -6230,7 +6806,7 @@ function pipelineStringToJsonSync(pipelineString) {
6230
6806
  * TODO: [🥞] Not optimal parsing because `splitMarkdownIntoSections` is executed twice with same string, once through `flattenMarkdown` and second directly here
6231
6807
  * TODO: [♈] Probbably move expectations from templates to parameters
6232
6808
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
6233
- * TODO: [🍙] Make some standart order of json properties
6809
+ * TODO: [🍙] Make some standard order of json properties
6234
6810
  */
6235
6811
 
6236
6812
  /**
@@ -6247,7 +6823,7 @@ function pipelineStringToJsonSync(pipelineString) {
6247
6823
  * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
6248
6824
  * @param options - Options and tools for the compilation
6249
6825
  * @returns {Promptbook} compiled in JSON format (.ptbk.json)
6250
- * @throws {ParsingError} if the promptbook string is not valid
6826
+ * @throws {ParseError} if the promptbook string is not valid
6251
6827
  * @public exported from `@promptbook/core`
6252
6828
  */
6253
6829
  function pipelineStringToJson(pipelineString, options) {
@@ -7034,7 +7610,7 @@ function stringifyPipelineJson(pipeline) {
7034
7610
  * TODO: [🐝] Not Working propperly @see https://promptbook.studio/samples/mixed-knowledge.ptbk.md
7035
7611
  * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
7036
7612
  * TODO: [🧠] Maybe more elegant solution than replacing via regex
7037
- * TODO: [🍙] Make some standart order of json properties
7613
+ * TODO: [🍙] Make some standard order of json properties
7038
7614
  */
7039
7615
 
7040
7616
  /**