@promptbook/cli 0.74.0-7 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +5 -17
  2. package/bin/promptbook-cli.js +8 -2
  3. package/esm/index.es.js +256 -113
  4. package/esm/index.es.js.map +1 -1
  5. package/esm/typings/src/_packages/core.index.d.ts +5 -1
  6. package/esm/typings/src/_packages/utils.index.d.ts +4 -0
  7. package/esm/typings/src/cli/cli-commands/run.d.ts +1 -1
  8. package/esm/typings/src/cli/main.d.ts +4 -1
  9. package/esm/typings/src/cli/promptbookCli.d.ts +1 -1
  10. package/esm/typings/src/cli/test/ptbk.d.ts +1 -1
  11. package/esm/typings/src/collection/collectionToJson.test.d.ts +1 -1
  12. package/esm/typings/src/collection/constructors/createCollectionFromDirectory.d.ts +1 -1
  13. package/esm/typings/src/commands/BOOK_VERSION/BookVersionCommand.d.ts +1 -1
  14. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +2 -2
  15. package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
  16. package/esm/typings/src/config.d.ts +6 -0
  17. package/esm/typings/src/conversion/pipelineJsonToString.d.ts +3 -3
  18. package/esm/typings/src/conversion/pipelineStringToJson.d.ts +2 -2
  19. package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +2 -2
  20. package/esm/typings/src/conversion/utils/stringifyPipelineJson.d.ts +1 -1
  21. package/esm/typings/src/conversion/validation/_importPipeline.d.ts +7 -7
  22. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +1 -1
  23. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +1 -1
  24. package/esm/typings/src/storage/blackhole/BlackholeStorage.d.ts +33 -0
  25. package/esm/typings/src/storage/memory/MemoryStorage.d.ts +1 -1
  26. package/esm/typings/src/storage/{memory/utils → utils}/PrefixStorage.d.ts +1 -1
  27. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +6 -4
  28. package/esm/typings/src/types/PipelineJson/PreparationJson.d.ts +1 -1
  29. package/esm/typings/src/types/Prompt.d.ts +1 -1
  30. package/esm/typings/src/types/typeAliases.d.ts +2 -2
  31. package/esm/typings/src/utils/expectation-counters/config.d.ts +12 -0
  32. package/esm/typings/src/utils/expectation-counters/countLines.d.ts +2 -0
  33. package/esm/typings/src/utils/expectation-counters/countPages.d.ts +2 -0
  34. package/package.json +3 -3
  35. package/umd/index.umd.js +256 -113
  36. package/umd/index.umd.js.map +1 -1
  37. /package/esm/typings/src/storage/{memory → local-storage}/utils/makePromptbookStorageFromWebStorage.d.ts +0 -0
package/esm/index.es.js CHANGED
@@ -37,7 +37,7 @@ var BOOK_LANGUAGE_VERSION = '1.0.0';
37
37
  *
38
38
  * @see https://github.com/webgptorg/promptbook
39
39
  */
40
- var PROMPTBOOK_ENGINE_VERSION = '0.74.0-6';
40
+ var PROMPTBOOK_ENGINE_VERSION = '0.74.0-13';
41
41
  /**
42
42
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
43
43
  */
@@ -389,6 +389,12 @@ var GENERATOR_WARNING = "\u26A0\uFE0F WARNING: This code has been generated so t
389
389
  */
390
390
  var CLAIM = "Build responsible, controlled and transparent applications on top of LLM models!";
391
391
  // <- TODO: [🐊] Pick the best claim
392
+ /**
393
+ * When the title is not provided, the default title is used
394
+ *
395
+ * @public exported from `@promptbook/core`
396
+ */
397
+ var DEFAULT_TITLE = "Untitled";
392
398
  /**
393
399
  * Warning message for the generated sections and files files
394
400
  *
@@ -710,13 +716,13 @@ function capitalize(word) {
710
716
  /**
711
717
  * Converts promptbook in JSON format to string format
712
718
  *
713
- * @param pipelineJson Promptbook in JSON format (.ptbk.json)
714
- * @returns Promptbook in string format (.ptbk.md)
719
+ * @param pipelineJson Promptbook in JSON format (.book.json)
720
+ * @returns Promptbook in string format (.book.md)
715
721
  * @public exported from `@promptbook/core`
716
722
  */
717
723
  function pipelineJsonToString(pipelineJson) {
718
724
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
719
- var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, promptbookVersion = pipelineJson.promptbookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
725
+ var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, bookVersion = pipelineJson.bookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
720
726
  var pipelineString = "# ".concat(title);
721
727
  if (description) {
722
728
  pipelineString += '\n\n';
@@ -726,8 +732,10 @@ function pipelineJsonToString(pipelineJson) {
726
732
  if (pipelineUrl) {
727
733
  commands.push("PIPELINE URL ".concat(pipelineUrl));
728
734
  }
729
- commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
730
- // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
735
+ if (bookVersion !== "undefined") {
736
+ commands.push("BOOK VERSION ".concat(bookVersion));
737
+ }
738
+ // TODO: [main] !!!!! This increases size of the bundle and is probbably not necessary
731
739
  pipelineString = prettifyMarkdown(pipelineString);
732
740
  try {
733
741
  for (var _g = __values(parameters.filter(function (_a) {
@@ -907,7 +915,7 @@ function templateParameterJsonToString(templateParameterJson) {
907
915
  * TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
908
916
  * TODO: [🏛] Maybe make some markdown builder
909
917
  * TODO: [🏛] Escape all
910
- * TODO: [🧠] Should be in generated .ptbk.md file GENERATOR_WARNING
918
+ * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
911
919
  */
912
920
 
913
921
  /**
@@ -1545,7 +1553,7 @@ function joinLlmExecutionTools() {
1545
1553
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1546
1554
  */
1547
1555
 
1548
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\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"}];
1556
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.book.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.book.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\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.book.md"}];
1549
1557
 
1550
1558
  /**
1551
1559
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -1720,7 +1728,7 @@ function isValidPipelineUrl(url) {
1720
1728
  if (!url.startsWith('https://')) {
1721
1729
  return false;
1722
1730
  }
1723
- if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.ptbk.md') || url.endsWith('.ptbk'))) {
1731
+ if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.book.md') || url.endsWith('.ptbk'))) {
1724
1732
  return false;
1725
1733
  }
1726
1734
  if (url.includes('#')) {
@@ -1789,9 +1797,9 @@ function validatePipelineCore(pipeline) {
1789
1797
  // <- Note: [🚲]
1790
1798
  throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1791
1799
  }
1792
- if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1800
+ if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
1793
1801
  // <- Note: [🚲]
1794
- throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1802
+ throw new PipelineLogicError(spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.bookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1795
1803
  }
1796
1804
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
1797
1805
  if (!Array.isArray(pipeline.parameters)) {
@@ -3181,28 +3189,42 @@ function countCharacters(text) {
3181
3189
  return text.length;
3182
3190
  }
3183
3191
 
3192
+ /**
3193
+ * Number of characters per standard line with 11pt Arial font size.
3194
+ *
3195
+ * @public exported from `@promptbook/utils`
3196
+ */
3197
+ var CHARACTERS_PER_STANDARD_LINE = 63;
3198
+ /**
3199
+ * Number of lines per standard A4 page with 11pt Arial font size and standard margins and spacing.
3200
+ *
3201
+ * @public exported from `@promptbook/utils`
3202
+ */
3203
+ var LINES_PER_STANDARD_PAGE = 44;
3204
+
3184
3205
  /**
3185
3206
  * Counts number of lines in the text
3186
3207
  *
3208
+ * Note: This does not check only for the presence of newlines, but also for the length of the standard line.
3209
+ *
3187
3210
  * @public exported from `@promptbook/utils`
3188
3211
  */
3189
3212
  function countLines(text) {
3190
- if (text === '') {
3191
- return 0;
3192
- }
3193
- return text.split('\n').length;
3213
+ text = text.replace('\r\n', '\n');
3214
+ text = text.replace('\r', '\n');
3215
+ var lines = text.split('\n');
3216
+ return lines.reduce(function (count, line) { return count + Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE); }, 0);
3194
3217
  }
3195
3218
 
3196
3219
  /**
3197
3220
  * Counts number of pages in the text
3198
3221
  *
3222
+ * Note: This does not check only for the count of newlines, but also for the length of the standard line and length of the standard page.
3223
+ *
3199
3224
  * @public exported from `@promptbook/utils`
3200
3225
  */
3201
3226
  function countPages(text) {
3202
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
3203
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3204
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3205
- return pageCount;
3227
+ return Math.ceil(countLines(text) / LINES_PER_STANDARD_PAGE);
3206
3228
  }
3207
3229
 
3208
3230
  /**
@@ -3743,7 +3765,7 @@ function executeAttempts(options) {
3743
3765
  promptTitle: template.title,
3744
3766
  promptMessage: replaceParameters(template.description || '', parameters),
3745
3767
  defaultValue: replaceParameters(preparedContent, parameters),
3746
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3768
+ // TODO: [🧠] !! Figure out how to define placeholder in .book.md file
3747
3769
  placeholder: undefined,
3748
3770
  priority: priority,
3749
3771
  }))];
@@ -4309,7 +4331,7 @@ function executePipeline(options) {
4309
4331
  pipelineUrl: preparedPipeline.pipelineUrl,
4310
4332
  title: preparedPipeline.title,
4311
4333
  promptbookUsedVersion: PROMPTBOOK_ENGINE_VERSION,
4312
- promptbookRequestedVersion: preparedPipeline.promptbookVersion,
4334
+ promptbookRequestedVersion: preparedPipeline.bookVersion,
4313
4335
  description: preparedPipeline.description,
4314
4336
  promptExecutions: [],
4315
4337
  };
@@ -4658,7 +4680,7 @@ function preparePersona(personaDescription, tools, options) {
4658
4680
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
4659
4681
  _b = createPipelineExecutor;
4660
4682
  _c = {};
4661
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.ptbk.md')];
4683
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book.md')];
4662
4684
  case 1:
4663
4685
  preparePersonaExecutor = _b.apply(void 0, [(_c.pipeline = _d.sent(),
4664
4686
  _c.tools = tools,
@@ -5415,12 +5437,12 @@ TODO: [🧊] This is how it can look in future
5415
5437
  */
5416
5438
  function clonePipeline(pipeline) {
5417
5439
  // Note: Not using spread operator (...) because @@@
5418
- 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;
5440
+ var pipelineUrl = pipeline.pipelineUrl, sourceFile = pipeline.sourceFile, title = pipeline.title, bookVersion = pipeline.bookVersion, description = pipeline.description, parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, knowledgePieces = pipeline.knowledgePieces, personas = pipeline.personas, preparations = pipeline.preparations;
5419
5441
  return {
5420
5442
  pipelineUrl: pipelineUrl,
5421
5443
  sourceFile: sourceFile,
5422
5444
  title: title,
5423
- promptbookVersion: promptbookVersion,
5445
+ bookVersion: bookVersion,
5424
5446
  description: description,
5425
5447
  parameters: parameters,
5426
5448
  templates: templates,
@@ -5632,7 +5654,7 @@ var knowledgeCommandParser = {
5632
5654
  throw new ParseError("Source not valid");
5633
5655
  }
5634
5656
  if (sourceContent.startsWith('../') || sourceContent.startsWith('/') || /^[A-Z]:[\\/]+/i.test(sourceContent)) {
5635
- throw new ParseError("Source cannot be outside of the .ptbk.md folder");
5657
+ throw new ParseError("Source cannot be outside of the .book.md folder");
5636
5658
  }
5637
5659
  return {
5638
5660
  type: 'KNOWLEDGE',
@@ -6282,7 +6304,7 @@ function validateParameterName(parameterName) {
6282
6304
  /**
6283
6305
  * Parses the foreach command
6284
6306
  *
6285
- * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.ptbk.md` file
6307
+ * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.book.md` file
6286
6308
  *
6287
6309
  * @see `documentationUrl` for more details
6288
6310
  * @private within the commands folder
@@ -6432,7 +6454,7 @@ var foreachCommandParser = {
6432
6454
  },
6433
6455
  };
6434
6456
  /**
6435
- * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
6457
+ * TODO: [🍭] Make .book.md file with examples of the FOREACH with wrong parsing and logic
6436
6458
  */
6437
6459
 
6438
6460
  /**
@@ -7066,7 +7088,7 @@ var bookVersionCommandParser = {
7066
7088
  /**
7067
7089
  * Description of the BOOK_VERSION command
7068
7090
  */
7069
- description: "Which version of the Book language is the .ptbk.md using",
7091
+ description: "Which version of the Book language is the .book.md using",
7070
7092
  /**
7071
7093
  * Link to documentation
7072
7094
  */
@@ -7080,19 +7102,19 @@ var bookVersionCommandParser = {
7080
7102
  */
7081
7103
  parse: function (input) {
7082
7104
  var args = input.args;
7083
- var promptbookVersion = args.pop();
7084
- if (promptbookVersion === undefined) {
7105
+ var bookVersion = args.pop();
7106
+ if (bookVersion === undefined) {
7085
7107
  throw new ParseError("Version is required");
7086
7108
  }
7087
- if (!isValidPromptbookVersion(promptbookVersion)) {
7088
- throw new ParseError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
7109
+ if (!isValidPromptbookVersion(bookVersion)) {
7110
+ throw new ParseError("Invalid Promptbook version \"".concat(bookVersion, "\""));
7089
7111
  }
7090
7112
  if (args.length > 0 && !(((args.length === 1 && args[0]) || '').toUpperCase() === 'VERSION')) {
7091
7113
  throw new ParseError("Can not have more than one Promptbook version");
7092
7114
  }
7093
7115
  return {
7094
7116
  type: 'BOOK_VERSION',
7095
- promptbookVersion: promptbookVersion,
7117
+ bookVersion: bookVersion,
7096
7118
  };
7097
7119
  },
7098
7120
  /**
@@ -7102,7 +7124,7 @@ var bookVersionCommandParser = {
7102
7124
  */
7103
7125
  $applyToPipelineJson: function (command, $pipelineJson) {
7104
7126
  // TODO: Warn if the version is overridden
7105
- $pipelineJson.promptbookVersion = command.promptbookVersion;
7127
+ $pipelineJson.bookVersion = command.bookVersion;
7106
7128
  },
7107
7129
  /**
7108
7130
  * Converts the BOOK_VERSION command back to string
@@ -7155,9 +7177,9 @@ var urlCommandParser = {
7155
7177
  * Example usages of the URL command
7156
7178
  */
7157
7179
  examples: [
7158
- 'PIPELINE URL https://promptbook.studio/library/write-cv.ptbk.md',
7159
- 'URL https://promptbook.studio/library/write-cv.ptbk.md',
7160
- 'https://promptbook.studio/library/write-cv.ptbk.md',
7180
+ 'PIPELINE URL https://promptbook.studio/library/write-cv.book.md',
7181
+ 'URL https://promptbook.studio/library/write-cv.book.md',
7182
+ 'https://promptbook.studio/library/write-cv.book.md',
7161
7183
  ],
7162
7184
  /**
7163
7185
  * Parses the URL command
@@ -7358,7 +7380,7 @@ var instrumentCommandParser = {
7358
7380
  /**
7359
7381
  * Parses the boilerplate command
7360
7382
  *
7361
- * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.ptbk.md` file
7383
+ * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.book.md` file
7362
7384
  *
7363
7385
  * @see `documentationUrl` for more details
7364
7386
  * @private within the commands folder
@@ -7412,7 +7434,7 @@ var boilerplateCommandParser = {
7412
7434
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7413
7435
  */
7414
7436
  $applyToPipelineJson: function (command, $pipelineJson) {
7415
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7437
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7416
7438
  },
7417
7439
  /**
7418
7440
  * Apply the BOILERPLATE command to the `pipelineJson`
@@ -7420,7 +7442,7 @@ var boilerplateCommandParser = {
7420
7442
  * Note: `$` is used to indicate that this function mutates given `templateJson`
7421
7443
  */
7422
7444
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
7423
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7445
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7424
7446
  },
7425
7447
  /**
7426
7448
  * Converts the BOILERPLATE command back to string
@@ -7436,7 +7458,7 @@ var boilerplateCommandParser = {
7436
7458
  * Note: This is used in `pipelineJsonToString` utility
7437
7459
  */
7438
7460
  takeFromPipelineJson: function (pipelineJson) {
7439
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7461
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7440
7462
  },
7441
7463
  /**
7442
7464
  * Reads the BOILERPLATE command from the `TemplateJson`
@@ -7444,7 +7466,7 @@ var boilerplateCommandParser = {
7444
7466
  * Note: This is used in `pipelineJsonToString` utility
7445
7467
  */
7446
7468
  takeFromTemplateJson: function ($templateJson) {
7447
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7469
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7448
7470
  },
7449
7471
  };
7450
7472
 
@@ -7773,7 +7795,7 @@ function splitMarkdownIntoSections(markdown) {
7773
7795
  return;
7774
7796
  }
7775
7797
  if (!section.startsWith('#')) {
7776
- section = "# Untitled\n\n".concat(section);
7798
+ section = "# ".concat(DEFAULT_TITLE, "\n\n").concat(section);
7777
7799
  }
7778
7800
  sections.push(section);
7779
7801
  buffer = [];
@@ -7837,7 +7859,7 @@ function flattenMarkdown(markdown) {
7837
7859
  var e_1, _a;
7838
7860
  var sections = splitMarkdownIntoSections(markdown);
7839
7861
  if (sections.length === 0) {
7840
- return '# Untitled';
7862
+ return "# ".concat(DEFAULT_TITLE);
7841
7863
  }
7842
7864
  var flattenedMarkdown = '';
7843
7865
  var parsedSections = sections.map(parseMarkdownSection);
@@ -7848,7 +7870,7 @@ function flattenMarkdown(markdown) {
7848
7870
  }
7849
7871
  else {
7850
7872
  parsedSections.unshift(firstSection);
7851
- flattenedMarkdown += "# Untitled" + "\n\n"; // <- [🧠] Maybe 3 new lines?
7873
+ flattenedMarkdown += "# ".concat(DEFAULT_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
7852
7874
  }
7853
7875
  try {
7854
7876
  for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
@@ -7920,17 +7942,17 @@ function titleToName(value) {
7920
7942
  * Note: This function does not validate logic of the pipeline only the parsing
7921
7943
  * Note: This function acts as compilation process
7922
7944
  *
7923
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
7924
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
7945
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
7946
+ * @returns {Promptbook} compiled in JSON format (.book.json)
7925
7947
  * @throws {ParseError} if the promptbook string is not valid
7926
7948
  * @public exported from `@promptbook/core`
7927
7949
  */
7928
7950
  function pipelineStringToJsonSync(pipelineString) {
7929
- var e_1, _a, e_2, _b;
7951
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
7930
7952
  var $pipelineJson = {
7931
7953
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
7932
7954
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
7933
- promptbookVersion: undefined /* <- Note: By default no explicit version */,
7955
+ bookVersion: undefined /* <- Note: By default no explicit version */,
7934
7956
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
7935
7957
  parameters: [],
7936
7958
  templates: [],
@@ -7954,7 +7976,7 @@ function pipelineStringToJsonSync(pipelineString) {
7954
7976
  // =============================================================
7955
7977
  // Note: 1️⃣ Parsing of the markdown into object
7956
7978
  if (pipelineString.startsWith('#!')) {
7957
- var _c = __read(pipelineString.split('\n')), shebangLine_1 = _c[0], restLines = _c.slice(1);
7979
+ var _e = __read(pipelineString.split('\n')), shebangLine_1 = _e[0], restLines = _e.slice(1);
7958
7980
  if (!(shebangLine_1 || '').includes('ptbk')) {
7959
7981
  throw new ParseError(spaceTrim(function (block) { return "\n It seems that you try to parse a book file which has non-standard shebang line for book files:\n Shebang line must contain 'ptbk'\n\n You have:\n ".concat(block(shebangLine_1 || '(empty line)'), "\n\n It should look like this:\n #!/usr/bin/env ptbk\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
7960
7982
  }
@@ -7964,7 +7986,7 @@ function pipelineStringToJsonSync(pipelineString) {
7964
7986
  pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
7965
7987
  pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
7966
7988
  pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
7967
- var _d = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _d[0], pipelineSections = _d.slice(1); /* <- Note: [🥞] */
7989
+ var _f = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _f[0], pipelineSections = _f.slice(1); /* <- Note: [🥞] */
7968
7990
  if (pipelineHead === undefined) {
7969
7991
  throw new UnexpectedError(spaceTrim(function (block) { return "\n Pipeline head is not defined\n\n ".concat(block(getPipelineIdentification()), "\n\n This should never happen, because the pipeline already flattened\n "); }));
7970
7992
  }
@@ -7992,6 +8014,8 @@ function pipelineStringToJsonSync(pipelineString) {
7992
8014
  if (parameterDescription) {
7993
8015
  existingParameter.description = parameterDescription;
7994
8016
  }
8017
+ existingParameter.isInput = existingParameter.isInput || isInput;
8018
+ existingParameter.isOutput = existingParameter.isOutput || isOutput;
7995
8019
  }
7996
8020
  else {
7997
8021
  $pipelineJson.parameters.push({
@@ -8054,10 +8078,10 @@ function pipelineStringToJsonSync(pipelineString) {
8054
8078
  finally { if (e_1) throw e_1.error; }
8055
8079
  }
8056
8080
  var _loop_2 = function (section) {
8057
- var e_3, _e;
8081
+ var e_5, _l, e_6, _m;
8058
8082
  // TODO: Parse template description (the content out of the codeblock and lists)
8059
8083
  var listItems_2 = extractAllListItemsFromMarkdown(section.content);
8060
- var _f = extractOneBlockFromMarkdown(section.content), language = _f.language, content = _f.content;
8084
+ var _o = extractOneBlockFromMarkdown(section.content), language = _o.language, content = _o.content;
8061
8085
  // TODO: [🎾][1] DRY description
8062
8086
  var description_1 = section.content;
8063
8087
  // Note: Remove codeblocks - TODO: [🎾]
@@ -8098,7 +8122,7 @@ function pipelineStringToJsonSync(pipelineString) {
8098
8122
  }) === false) {
8099
8123
  templateCommandParser.$applyToTemplateJson({ type: 'TEMPLATE', templateType: 'PROMPT_TEMPLATE' }, $templateJson, $pipelineJson);
8100
8124
  }
8101
- var _loop_3 = function (listItem, command) {
8125
+ var _loop_4 = function (listItem, command) {
8102
8126
  var commandParser = getParserForCommand(command);
8103
8127
  if (commandParser.isUsedInPipelineTemplate !== true /* <- Note: [🦦][4] */) {
8104
8128
  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: [🚞]
@@ -8121,17 +8145,17 @@ function pipelineStringToJsonSync(pipelineString) {
8121
8145
  };
8122
8146
  try {
8123
8147
  // TODO [♓️] List commands and before apply order them to achieve order-agnostic commands
8124
- 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()) {
8125
- var _g = commands_1_1.value, listItem = _g.listItem, command = _g.command;
8126
- _loop_3(listItem, command);
8148
+ for (var commands_1 = (e_5 = void 0, __values(commands)), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) {
8149
+ var _p = commands_1_1.value, listItem = _p.listItem, command = _p.command;
8150
+ _loop_4(listItem, command);
8127
8151
  }
8128
8152
  }
8129
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
8153
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
8130
8154
  finally {
8131
8155
  try {
8132
- if (commands_1_1 && !commands_1_1.done && (_e = commands_1.return)) _e.call(commands_1);
8156
+ if (commands_1_1 && !commands_1_1.done && (_l = commands_1.return)) _l.call(commands_1);
8133
8157
  }
8134
- finally { if (e_3) throw e_3.error; }
8158
+ finally { if (e_5) throw e_5.error; }
8135
8159
  }
8136
8160
  // TODO: [🍧] Should be done in TEMPLATE command
8137
8161
  if ($templateJson.templateType === 'SCRIPT_TEMPLATE') {
@@ -8145,6 +8169,26 @@ function pipelineStringToJsonSync(pipelineString) {
8145
8169
  language;
8146
8170
  }
8147
8171
  $templateJson.dependentParameterNames = Array.from(extractParameterNamesFromTemplate($templateJson));
8172
+ try {
8173
+ for (var _q = (e_6 = void 0, __values($templateJson.dependentParameterNames)), _r = _q.next(); !_r.done; _r = _q.next()) {
8174
+ var parameterName = _r.value;
8175
+ // TODO: [🧠] This definition should be made first in the template
8176
+ defineParam({
8177
+ parameterName: parameterName,
8178
+ parameterDescription: null,
8179
+ isInput: false,
8180
+ isOutput: false,
8181
+ // <- Note: In this case null+false+false means that we do not know yet if it is input or output and we will set it later
8182
+ });
8183
+ }
8184
+ }
8185
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
8186
+ finally {
8187
+ try {
8188
+ if (_r && !_r.done && (_m = _q.return)) _m.call(_q);
8189
+ }
8190
+ finally { if (e_6) throw e_6.error; }
8191
+ }
8148
8192
  /*
8149
8193
  // TODO: [🍧] This should be checked in `MODEL` command + better error message
8150
8194
  if ($templateJson.templateType !== 'PROMPT_TEMPLATE' && $templateJson.modelRequirements !== undefined) {
@@ -8186,9 +8230,51 @@ function pipelineStringToJsonSync(pipelineString) {
8186
8230
  finally { if (e_2) throw e_2.error; }
8187
8231
  }
8188
8232
  // =============================================================
8189
- // Note: 5️⃣ Cleanup of undefined values
8233
+ // Note: 5️⃣ Mark parameters as INPUT if not explicitly set
8234
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isInput; })) {
8235
+ var _loop_3 = function (parameter) {
8236
+ var isThisParameterResulting = $pipelineJson.templates.some(function (template) { return template.resultingParameterName === parameter.name; });
8237
+ if (!isThisParameterResulting) {
8238
+ parameter.isInput = true;
8239
+ }
8240
+ };
8241
+ try {
8242
+ for (var _g = __values($pipelineJson.parameters), _h = _g.next(); !_h.done; _h = _g.next()) {
8243
+ var parameter = _h.value;
8244
+ _loop_3(parameter);
8245
+ }
8246
+ }
8247
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
8248
+ finally {
8249
+ try {
8250
+ if (_h && !_h.done && (_c = _g.return)) _c.call(_g);
8251
+ }
8252
+ finally { if (e_3) throw e_3.error; }
8253
+ }
8254
+ }
8255
+ // =============================================================
8256
+ // Note: 6️⃣ Mark all non-INPUT parameters as OUTPUT if any OUTPUT is not set
8257
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isOutput; })) {
8258
+ try {
8259
+ for (var _j = __values($pipelineJson.parameters), _k = _j.next(); !_k.done; _k = _j.next()) {
8260
+ var parameter = _k.value;
8261
+ if (!parameter.isInput) {
8262
+ parameter.isOutput = true;
8263
+ }
8264
+ }
8265
+ }
8266
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
8267
+ finally {
8268
+ try {
8269
+ if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
8270
+ }
8271
+ finally { if (e_4) throw e_4.error; }
8272
+ }
8273
+ }
8274
+ // =============================================================
8275
+ // Note: 7️⃣ Cleanup of undefined values
8190
8276
  $pipelineJson.templates.forEach(function (templates) {
8191
- var e_4, _a;
8277
+ var e_7, _a;
8192
8278
  try {
8193
8279
  for (var _b = __values(Object.entries(templates)), _c = _b.next(); !_c.done; _c = _b.next()) {
8194
8280
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8197,16 +8283,16 @@ function pipelineStringToJsonSync(pipelineString) {
8197
8283
  }
8198
8284
  }
8199
8285
  }
8200
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
8286
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
8201
8287
  finally {
8202
8288
  try {
8203
8289
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8204
8290
  }
8205
- finally { if (e_4) throw e_4.error; }
8291
+ finally { if (e_7) throw e_7.error; }
8206
8292
  }
8207
8293
  });
8208
8294
  $pipelineJson.parameters.forEach(function (parameter) {
8209
- var e_5, _a;
8295
+ var e_8, _a;
8210
8296
  try {
8211
8297
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
8212
8298
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8215,12 +8301,12 @@ function pipelineStringToJsonSync(pipelineString) {
8215
8301
  }
8216
8302
  }
8217
8303
  }
8218
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
8304
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
8219
8305
  finally {
8220
8306
  try {
8221
8307
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8222
8308
  }
8223
- finally { if (e_5) throw e_5.error; }
8309
+ finally { if (e_8) throw e_8.error; }
8224
8310
  }
8225
8311
  });
8226
8312
  // =============================================================
@@ -8249,10 +8335,10 @@ function pipelineStringToJsonSync(pipelineString) {
8249
8335
  * Note: This function does not validate logic of the pipeline only the parsing
8250
8336
  * Note: This function acts as compilation process
8251
8337
  *
8252
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8338
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
8253
8339
  * @param tools - Tools for the preparation and scraping - if not provided together with `llm`, the preparation will be skipped
8254
8340
  * @param options - Options and tools for the compilation
8255
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
8341
+ * @returns {Promptbook} compiled in JSON format (.book.json)
8256
8342
  * @throws {ParseError} if the promptbook string is not valid
8257
8343
  * @public exported from `@promptbook/core`
8258
8344
  */
@@ -9624,13 +9710,13 @@ function createCollectionFromDirectory(path, tools, options) {
9624
9710
  return [4 /*yield*/, listAllFiles(path, isRecursive, tools.fs)];
9625
9711
  case 1:
9626
9712
  fileNames = _b.sent();
9627
- // Note: First load all .ptbk.json and then .ptbk.md files
9628
- // .ptbk.json can be prepared so it is faster to load
9713
+ // Note: First load all .book.json and then .book.md files
9714
+ // .book.json can be prepared so it is faster to load
9629
9715
  fileNames.sort(function (a, b) {
9630
- if (a.endsWith('.ptbk.json') && b.endsWith('.ptbk.md')) {
9716
+ if (a.endsWith('.book.json') && b.endsWith('.book.md')) {
9631
9717
  return -1;
9632
9718
  }
9633
- if (a.endsWith('.ptbk.md') && b.endsWith('.ptbk.json')) {
9719
+ if (a.endsWith('.book.md') && b.endsWith('.book.json')) {
9634
9720
  return 1;
9635
9721
  }
9636
9722
  return 0;
@@ -9647,7 +9733,7 @@ function createCollectionFromDirectory(path, tools, options) {
9647
9733
  case 1:
9648
9734
  _e.trys.push([1, 8, , 9]);
9649
9735
  pipeline = null;
9650
- if (!fileName.endsWith('.ptbk.md')) return [3 /*break*/, 4];
9736
+ if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
9651
9737
  return [4 /*yield*/, readFile(fileName, 'utf-8')];
9652
9738
  case 2:
9653
9739
  pipelineString = (_e.sent());
@@ -9659,7 +9745,7 @@ function createCollectionFromDirectory(path, tools, options) {
9659
9745
  pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
9660
9746
  return [3 /*break*/, 7];
9661
9747
  case 4:
9662
- if (!fileName.endsWith('.ptbk.json')) return [3 /*break*/, 6];
9748
+ if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
9663
9749
  _d = (_c = JSON).parse;
9664
9750
  return [4 /*yield*/, readFile(fileName, 'utf-8')];
9665
9751
  case 5:
@@ -9827,7 +9913,7 @@ function stringifyPipelineJson(pipeline) {
9827
9913
  return pipelineJsonStringified;
9828
9914
  }
9829
9915
  /**
9830
- * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.ptbk.md
9916
+ * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.book.md
9831
9917
  * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
9832
9918
  * TODO: [🧠] Maybe more elegant solution than replacing via regex
9833
9919
  * TODO: [🍙] Make some standard order of json properties
@@ -10008,7 +10094,7 @@ var FileCacheStorage = /** @class */ (function () {
10008
10094
  */
10009
10095
 
10010
10096
  /**
10011
- * Stores
10097
+ * Stores data in memory (HEAP)
10012
10098
  *
10013
10099
  * @public exported from `@promptbook/core`
10014
10100
  */
@@ -10138,13 +10224,18 @@ function cacheLlmTools(llmTools, options) {
10138
10224
  promptResult = _c.sent();
10139
10225
  return [3 /*break*/, 11];
10140
10226
  case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
10141
- case 11: return [4 /*yield*/, storage.setItem(key, {
10227
+ case 11:
10228
+ // TODO: [🧠] !!!!! How to do timing in mixed cache / non-cache situation
10229
+ // promptResult.timing: FromtoItems
10230
+ return [4 /*yield*/, storage.setItem(key, {
10142
10231
  date: $currentDate(),
10143
10232
  promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
10144
10233
  prompt: prompt,
10145
10234
  promptResult: promptResult,
10146
10235
  })];
10147
10236
  case 12:
10237
+ // TODO: [🧠] !!!!! How to do timing in mixed cache / non-cache situation
10238
+ // promptResult.timing: FromtoItems
10148
10239
  _c.sent();
10149
10240
  return [2 /*return*/, promptResult];
10150
10241
  }
@@ -10552,7 +10643,7 @@ function prettifyPipelineString(pipelineString, options) {
10552
10643
  function initializePrettifyCommand(program) {
10553
10644
  var _this = this;
10554
10645
  var prettifyCommand = program.command('prettify');
10555
- prettifyCommand.description(spaceTrim$1("\n Iterates over `.ptbk.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
10646
+ prettifyCommand.description(spaceTrim$1("\n Iterates over `.book.md` files and does multiple enhancing operations on them:\n\n 1) Adds Mermaid graph\n 2) Prettifies the markdown\n "));
10556
10647
  prettifyCommand.argument('<filesGlob>',
10557
10648
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10558
10649
  'Pipelines to prettify as glob pattern');
@@ -10576,7 +10667,7 @@ function initializePrettifyCommand(program) {
10576
10667
  case 3:
10577
10668
  if (!!filenames_1_1.done) return [3 /*break*/, 10];
10578
10669
  filename = filenames_1_1.value;
10579
- if (!filename.endsWith('.ptbk.md') && isVerbose) {
10670
+ if (!filename.endsWith('.book.md') && isVerbose) {
10580
10671
  console.info(colors.gray("Skipping ".concat(filename)));
10581
10672
  return [3 /*break*/, 9];
10582
10673
  }
@@ -10975,25 +11066,29 @@ function initializeRunCommand(program) {
10975
11066
  runCommand.description(spaceTrim$1("\n Runs a pipeline\n "));
10976
11067
  // TODO: [🧅] DRY command arguments
10977
11068
  runCommand.argument('<path>',
10978
- // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .ptbk.md file
11069
+ // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .book.md file
10979
11070
  'Path to book file');
10980
11071
  runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
10981
11072
  runCommand.option('-v, --verbose', "Is output verbose", false);
10982
- runCommand.option('--no-interactive', "Input is not interactive", false);
11073
+ runCommand.option('--no-interactive', "Input is not interactive, if true you need to pass all the input parameters through --json");
11074
+ runCommand.option('-j, --json <json>', "Pass all or some input parameters as JSON record, if used the output is also returned as JSON");
10983
11075
  runCommand.option('-s, --save-report <path>', "Save report to file");
10984
- // TODO: !!!!!! Implement non-interactive mode - allow to pass input parameters as JSON
10985
- // TODO: !!!!!! JSON output
10986
11076
  runCommand.action(function (filePathRaw, options) { return __awaiter(_this, void 0, void 0, function () {
10987
- var isCacheReloaded, isVerbose, saveReport, prepareAndScrapeOptions, fs, filePath, filePathCandidates, filePathCandidates_1, filePathCandidates_1_1, filePathCandidate, e_1_1, llm, executables, tools, pipelineString, pipeline, error_1, pipelineExecutor, questions, response, inputParameters, result, isSuccessful, errors, warnings, outputParameters, executionReport, executionReportString, _a, _b, error, _c, _d, warning, _e, _f, key, value, separator;
11077
+ var isCacheReloaded, isInteractive, json, isVerbose, saveReport, inputParameters, prepareAndScrapeOptions, fs, filePath, filePathCandidates, filePathCandidates_1, filePathCandidates_1_1, filePathCandidate, e_1_1, llm, executables, tools, pipelineString, pipeline, error_1, pipelineExecutor, questions, response, result, isSuccessful, errors, warnings, outputParameters, executionReport, executionReportString, _a, _b, error, _c, _d, warning, _e, _f, key, value, separator;
10988
11078
  var e_1, _g, _h, e_2, _j, e_3, _k, e_4, _l;
10989
11079
  return __generator(this, function (_m) {
10990
11080
  switch (_m.label) {
10991
11081
  case 0:
10992
- isCacheReloaded = options.reload, options.interactive, isVerbose = options.verbose, saveReport = options.saveReport;
11082
+ isCacheReloaded = options.reload, isInteractive = options.interactive, json = options.json, isVerbose = options.verbose, saveReport = options.saveReport;
10993
11083
  if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
10994
11084
  console.error(colors.red("Report file must be .json or .md"));
10995
11085
  return [2 /*return*/, process.exit(1)];
10996
11086
  }
11087
+ inputParameters = {};
11088
+ if (json) {
11089
+ inputParameters = JSON.parse(json);
11090
+ // <- TODO: Maybe check shape of passed JSON and if its valid parameters Record
11091
+ }
10997
11092
  prepareAndScrapeOptions = {
10998
11093
  isVerbose: isVerbose,
10999
11094
  isCacheReloaded: isCacheReloaded,
@@ -11007,7 +11102,7 @@ function initializeRunCommand(program) {
11007
11102
  filePathRaw,
11008
11103
  "".concat(filePathRaw, ".md"),
11009
11104
  "".concat(filePathRaw, ".book.md"),
11010
- "".concat(filePathRaw, ".ptbk.md"),
11105
+ "".concat(filePathRaw, ".book.md"),
11011
11106
  ];
11012
11107
  _m.label = 1;
11013
11108
  case 1:
@@ -11111,8 +11206,8 @@ function initializeRunCommand(program) {
11111
11206
  tools: tools,
11112
11207
  isNotPreparedWarningSupressed: true,
11113
11208
  maxExecutionAttempts: 3,
11114
- // <- TODO: !!!!!! Why "LLM execution failed undefinedx"
11115
- maxParallelCount: 1, // <- TODO: !!!!!! Pass
11209
+ // <- TODO: Why "LLM execution failed undefinedx"
11210
+ maxParallelCount: 1, // <- TODO: Pass CLI argument
11116
11211
  });
11117
11212
  if (isVerbose) {
11118
11213
  console.info(colors.gray('--- Getting input parameters ---'));
@@ -11121,13 +11216,17 @@ function initializeRunCommand(program) {
11121
11216
  .filter(function (_a) {
11122
11217
  var isInput = _a.isInput;
11123
11218
  return isInput;
11219
+ })
11220
+ .filter(function (_a) {
11221
+ var name = _a.name;
11222
+ return typeof inputParameters[name] !== 'string';
11124
11223
  })
11125
11224
  .map(function (_a) {
11126
11225
  var name = _a.name, exampleValues = _a.exampleValues;
11127
11226
  var message = name;
11128
11227
  var initial = '';
11129
11228
  if (exampleValues && exampleValues.length > 0) {
11130
- var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1 && countCharacters(exampleValue) <= 30; });
11229
+ var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1; });
11131
11230
  if (exampleValuesFiltered.length !== 0) {
11132
11231
  message += " (e.g. ".concat(exampleValuesFiltered.join(', '), ")");
11133
11232
  }
@@ -11141,10 +11240,44 @@ function initializeRunCommand(program) {
11141
11240
  // TODO: Maybe use> validate: value => value < 18 ? `Forbidden` : true
11142
11241
  };
11143
11242
  });
11243
+ if (isInteractive === false && questions.length !== 0) {
11244
+ console.error(colors.red(spaceTrim$1(function (block) { return "\n When using --no-interactive you need to pass all the input parameters through --json\n\n You are missing:\n ".concat(block(pipeline.parameters
11245
+ .filter(function (_a) {
11246
+ var isInput = _a.isInput;
11247
+ return isInput;
11248
+ })
11249
+ .filter(function (_a) {
11250
+ var parameterName = _a.name;
11251
+ return !questions.some(function (_a) {
11252
+ var questionName = _a.name;
11253
+ return questionName === parameterName;
11254
+ });
11255
+ })
11256
+ .map(function (_a) {
11257
+ var name = _a.name, description = _a.description;
11258
+ return "- **".concat(name, "** ").concat(description);
11259
+ })
11260
+ .join('\n')), "\n\n Example:\n --json '").concat(JSON.stringify(Object.fromEntries(pipeline.parameters
11261
+ .filter(function (_a) {
11262
+ var isInput = _a.isInput;
11263
+ return isInput;
11264
+ })
11265
+ .map(function (_a) {
11266
+ var name = _a.name, exampleValues = _a.exampleValues;
11267
+ return [
11268
+ name,
11269
+ inputParameters[name] || (exampleValues || [])[0] || '...',
11270
+ ];
11271
+ })))
11272
+ .split("'")
11273
+ .join("\\'"), "'\n "); })));
11274
+ return [2 /*return*/, process.exit(1)];
11275
+ }
11144
11276
  return [4 /*yield*/, prompts(questions)];
11145
11277
  case 16:
11146
11278
  response = _m.sent();
11147
- inputParameters = response;
11279
+ inputParameters = __assign(__assign({}, inputParameters), response);
11280
+ // TODO: Maybe do some validation of the response (and --json argument which is passed)
11148
11281
  if (isVerbose) {
11149
11282
  console.info(colors.gray('--- Executing ---'));
11150
11283
  }
@@ -11181,7 +11314,9 @@ function initializeRunCommand(program) {
11181
11314
  console.info(colors.gray('--- Usage ---'));
11182
11315
  console.info(colors.cyan(usageToHuman(result.usage)));
11183
11316
  }
11184
- console.info(colors.gray('--- Result ---'));
11317
+ if (json === undefined || isVerbose === true) {
11318
+ console.info(colors.gray('--- Result ---'));
11319
+ }
11185
11320
  try {
11186
11321
  // TODO: [🧠] Should be errors or warnings shown first
11187
11322
  for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
@@ -11209,20 +11344,25 @@ function initializeRunCommand(program) {
11209
11344
  }
11210
11345
  finally { if (e_3) throw e_3.error; }
11211
11346
  }
11212
- try {
11213
- for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11214
- key = _f.value;
11215
- value = outputParameters[key] || colors.grey(colors.italic('(nothing)'));
11216
- separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11217
- console.info(colors.green(colors.bold(key) + separator + value));
11218
- }
11219
- }
11220
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
11221
- finally {
11347
+ if (json === undefined) {
11222
11348
  try {
11223
- if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11349
+ for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11350
+ key = _f.value;
11351
+ value = outputParameters[key] || colors.grey(colors.italic('(nothing)'));
11352
+ separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11353
+ console.info(colors.green(colors.bold(key) + separator + value));
11354
+ }
11224
11355
  }
11225
- finally { if (e_4) throw e_4.error; }
11356
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
11357
+ finally {
11358
+ try {
11359
+ if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11360
+ }
11361
+ finally { if (e_4) throw e_4.error; }
11362
+ }
11363
+ }
11364
+ else {
11365
+ console.info(JSON.stringify(outputParameters, null, 4));
11226
11366
  }
11227
11367
  return [2 /*return*/, process.exit(0)];
11228
11368
  }
@@ -11230,7 +11370,7 @@ function initializeRunCommand(program) {
11230
11370
  }); });
11231
11371
  }
11232
11372
  /**
11233
- * TODO: !!!!!! Catch and wrap all errors from CLI
11373
+ * TODO: !!!!! Catch and wrap all errors from CLI
11234
11374
  * TODO: [🧠] Pass `maxExecutionAttempts`, `csvSettings`
11235
11375
  * TODO: [🥃][main] !!! Allow `ptbk run` without configuring any llm tools
11236
11376
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
@@ -11245,7 +11385,7 @@ function initializeRunCommand(program) {
11245
11385
  function initializeTestCommand(program) {
11246
11386
  var _this = this;
11247
11387
  var testCommand = program.command('test');
11248
- testCommand.description(spaceTrim$1("\n Iterates over `.ptbk.md` and `.ptbk.json` and checks if they are parsable and logically valid\n "));
11388
+ testCommand.description(spaceTrim$1("\n Iterates over `.book.md` and `.book.json` and checks if they are parsable and logically valid\n "));
11249
11389
  testCommand.argument('<filesGlob>',
11250
11390
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
11251
11391
  'Pipelines to test as glob pattern');
@@ -11295,7 +11435,7 @@ function initializeTestCommand(program) {
11295
11435
  case 6:
11296
11436
  _f.trys.push([6, 13, , 14]);
11297
11437
  pipeline = void 0;
11298
- if (!filename.endsWith('.ptbk.md')) return [3 /*break*/, 9];
11438
+ if (!filename.endsWith('.book.md')) return [3 /*break*/, 9];
11299
11439
  return [4 /*yield*/, readFile(filename, 'utf-8')];
11300
11440
  case 7:
11301
11441
  pipelineMarkdown = (_f.sent());
@@ -11307,7 +11447,7 @@ function initializeTestCommand(program) {
11307
11447
  }
11308
11448
  _f.label = 9;
11309
11449
  case 9:
11310
- if (!filename.endsWith('.ptbk.json')) return [3 /*break*/, 11];
11450
+ if (!filename.endsWith('.book.json')) return [3 /*break*/, 11];
11311
11451
  _c = (_b = JSON).parse;
11312
11452
  return [4 /*yield*/, readFile(filename, 'utf-8')];
11313
11453
  case 10:
@@ -11394,13 +11534,16 @@ function promptbookCli() {
11394
11534
  });
11395
11535
  }
11396
11536
  /**
11397
- * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.ptbk.md` -> `ptbk ./foo.ptbk.md`
11537
+ * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.book.md` -> `ptbk ./foo.book.md`
11398
11538
  * TODO: [🥠] Do not export, its just for CLI script
11399
11539
  * TODO: [🕌] When more functionalities, rename
11400
11540
  * Note: 11:11
11401
11541
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
11402
11542
  */
11403
11543
 
11544
+ /**
11545
+ * Note: [🔺] Purpose of this file is to export CLI for production environment
11546
+ */
11404
11547
  /**
11405
11548
  * Hidden utilities which should not be used by external consumers.
11406
11549
  *
@@ -11408,7 +11551,7 @@ function promptbookCli() {
11408
11551
  */
11409
11552
  var _CLI = {
11410
11553
  // Note: [🥠]
11411
- _initialize: promptbookCli,
11554
+ _initialize_promptbookCli: promptbookCli,
11412
11555
  };
11413
11556
  /**
11414
11557
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
@@ -13962,7 +14105,7 @@ var MarkdownScraper = /** @class */ (function () {
13962
14105
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
13963
14106
  _d = createPipelineExecutor;
13964
14107
  _g = {};
13965
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md')];
14108
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md')];
13966
14109
  case 1:
13967
14110
  prepareKnowledgeFromMarkdownExecutor = _d.apply(void 0, [(_g.pipeline = _k.sent(),
13968
14111
  _g.tools = {
@@ -13971,7 +14114,7 @@ var MarkdownScraper = /** @class */ (function () {
13971
14114
  _g)]);
13972
14115
  _e = createPipelineExecutor;
13973
14116
  _h = {};
13974
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md')];
14117
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.book.md')];
13975
14118
  case 2:
13976
14119
  prepareTitleExecutor = _e.apply(void 0, [(_h.pipeline = _k.sent(),
13977
14120
  _h.tools = {
@@ -13980,7 +14123,7 @@ var MarkdownScraper = /** @class */ (function () {
13980
14123
  _h)]);
13981
14124
  _f = createPipelineExecutor;
13982
14125
  _j = {};
13983
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md')];
14126
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md')];
13984
14127
  case 3:
13985
14128
  prepareKeywordsExecutor = _f.apply(void 0, [(_j.pipeline = _k.sent(),
13986
14129
  _j.tools = {