@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/umd/index.umd.js CHANGED
@@ -49,7 +49,7 @@
49
49
  *
50
50
  * @see https://github.com/webgptorg/promptbook
51
51
  */
52
- var PROMPTBOOK_ENGINE_VERSION = '0.74.0-6';
52
+ var PROMPTBOOK_ENGINE_VERSION = '0.74.0-13';
53
53
  /**
54
54
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
55
55
  */
@@ -401,6 +401,12 @@
401
401
  */
402
402
  var CLAIM = "Build responsible, controlled and transparent applications on top of LLM models!";
403
403
  // <- TODO: [🐊] Pick the best claim
404
+ /**
405
+ * When the title is not provided, the default title is used
406
+ *
407
+ * @public exported from `@promptbook/core`
408
+ */
409
+ var DEFAULT_TITLE = "Untitled";
404
410
  /**
405
411
  * Warning message for the generated sections and files files
406
412
  *
@@ -722,13 +728,13 @@
722
728
  /**
723
729
  * Converts promptbook in JSON format to string format
724
730
  *
725
- * @param pipelineJson Promptbook in JSON format (.ptbk.json)
726
- * @returns Promptbook in string format (.ptbk.md)
731
+ * @param pipelineJson Promptbook in JSON format (.book.json)
732
+ * @returns Promptbook in string format (.book.md)
727
733
  * @public exported from `@promptbook/core`
728
734
  */
729
735
  function pipelineJsonToString(pipelineJson) {
730
736
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
731
- var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, promptbookVersion = pipelineJson.promptbookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
737
+ var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, bookVersion = pipelineJson.bookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, templates = pipelineJson.templates;
732
738
  var pipelineString = "# ".concat(title);
733
739
  if (description) {
734
740
  pipelineString += '\n\n';
@@ -738,8 +744,10 @@
738
744
  if (pipelineUrl) {
739
745
  commands.push("PIPELINE URL ".concat(pipelineUrl));
740
746
  }
741
- commands.push("PROMPTBOOK VERSION ".concat(promptbookVersion));
742
- // TODO: [main] !!! This increase size of the bundle and is probbably not necessary
747
+ if (bookVersion !== "undefined") {
748
+ commands.push("BOOK VERSION ".concat(bookVersion));
749
+ }
750
+ // TODO: [main] !!!!! This increases size of the bundle and is probbably not necessary
743
751
  pipelineString = prettifyMarkdown(pipelineString);
744
752
  try {
745
753
  for (var _g = __values(parameters.filter(function (_a) {
@@ -919,7 +927,7 @@
919
927
  * TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
920
928
  * TODO: [🏛] Maybe make some markdown builder
921
929
  * TODO: [🏛] Escape all
922
- * TODO: [🧠] Should be in generated .ptbk.md file GENERATOR_WARNING
930
+ * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
923
931
  */
924
932
 
925
933
  /**
@@ -1557,7 +1565,7 @@
1557
1565
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
1558
1566
  */
1559
1567
 
1560
- 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"}];
1568
+ 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"}];
1561
1569
 
1562
1570
  /**
1563
1571
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -1732,7 +1740,7 @@
1732
1740
  if (!url.startsWith('https://')) {
1733
1741
  return false;
1734
1742
  }
1735
- if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.ptbk.md') || url.endsWith('.ptbk'))) {
1743
+ if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.book.md') || url.endsWith('.ptbk'))) {
1736
1744
  return false;
1737
1745
  }
1738
1746
  if (url.includes('#')) {
@@ -1801,9 +1809,9 @@
1801
1809
  // <- Note: [🚲]
1802
1810
  throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid promptbook URL \"".concat(pipeline.pipelineUrl, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1803
1811
  }
1804
- if (pipeline.promptbookVersion !== undefined && !isValidPromptbookVersion(pipeline.promptbookVersion)) {
1812
+ if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
1805
1813
  // <- Note: [🚲]
1806
- throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.promptbookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1814
+ throw new PipelineLogicError(spaceTrim.spaceTrim(function (block) { return "\n Invalid Promptbook Version \"".concat(pipeline.bookVersion, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
1807
1815
  }
1808
1816
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
1809
1817
  if (!Array.isArray(pipeline.parameters)) {
@@ -3193,28 +3201,42 @@
3193
3201
  return text.length;
3194
3202
  }
3195
3203
 
3204
+ /**
3205
+ * Number of characters per standard line with 11pt Arial font size.
3206
+ *
3207
+ * @public exported from `@promptbook/utils`
3208
+ */
3209
+ var CHARACTERS_PER_STANDARD_LINE = 63;
3210
+ /**
3211
+ * Number of lines per standard A4 page with 11pt Arial font size and standard margins and spacing.
3212
+ *
3213
+ * @public exported from `@promptbook/utils`
3214
+ */
3215
+ var LINES_PER_STANDARD_PAGE = 44;
3216
+
3196
3217
  /**
3197
3218
  * Counts number of lines in the text
3198
3219
  *
3220
+ * Note: This does not check only for the presence of newlines, but also for the length of the standard line.
3221
+ *
3199
3222
  * @public exported from `@promptbook/utils`
3200
3223
  */
3201
3224
  function countLines(text) {
3202
- if (text === '') {
3203
- return 0;
3204
- }
3205
- return text.split('\n').length;
3225
+ text = text.replace('\r\n', '\n');
3226
+ text = text.replace('\r', '\n');
3227
+ var lines = text.split('\n');
3228
+ return lines.reduce(function (count, line) { return count + Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE); }, 0);
3206
3229
  }
3207
3230
 
3208
3231
  /**
3209
3232
  * Counts number of pages in the text
3210
3233
  *
3234
+ * 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.
3235
+ *
3211
3236
  * @public exported from `@promptbook/utils`
3212
3237
  */
3213
3238
  function countPages(text) {
3214
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
3215
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3216
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3217
- return pageCount;
3239
+ return Math.ceil(countLines(text) / LINES_PER_STANDARD_PAGE);
3218
3240
  }
3219
3241
 
3220
3242
  /**
@@ -3755,7 +3777,7 @@
3755
3777
  promptTitle: template.title,
3756
3778
  promptMessage: replaceParameters(template.description || '', parameters),
3757
3779
  defaultValue: replaceParameters(preparedContent, parameters),
3758
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3780
+ // TODO: [🧠] !! Figure out how to define placeholder in .book.md file
3759
3781
  placeholder: undefined,
3760
3782
  priority: priority,
3761
3783
  }))];
@@ -4321,7 +4343,7 @@
4321
4343
  pipelineUrl: preparedPipeline.pipelineUrl,
4322
4344
  title: preparedPipeline.title,
4323
4345
  promptbookUsedVersion: PROMPTBOOK_ENGINE_VERSION,
4324
- promptbookRequestedVersion: preparedPipeline.promptbookVersion,
4346
+ promptbookRequestedVersion: preparedPipeline.bookVersion,
4325
4347
  description: preparedPipeline.description,
4326
4348
  promptExecutions: [],
4327
4349
  };
@@ -4670,7 +4692,7 @@
4670
4692
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
4671
4693
  _b = createPipelineExecutor;
4672
4694
  _c = {};
4673
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.ptbk.md')];
4695
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book.md')];
4674
4696
  case 1:
4675
4697
  preparePersonaExecutor = _b.apply(void 0, [(_c.pipeline = _d.sent(),
4676
4698
  _c.tools = tools,
@@ -5427,12 +5449,12 @@
5427
5449
  */
5428
5450
  function clonePipeline(pipeline) {
5429
5451
  // Note: Not using spread operator (...) because @@@
5430
- 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;
5452
+ 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;
5431
5453
  return {
5432
5454
  pipelineUrl: pipelineUrl,
5433
5455
  sourceFile: sourceFile,
5434
5456
  title: title,
5435
- promptbookVersion: promptbookVersion,
5457
+ bookVersion: bookVersion,
5436
5458
  description: description,
5437
5459
  parameters: parameters,
5438
5460
  templates: templates,
@@ -5644,7 +5666,7 @@
5644
5666
  throw new ParseError("Source not valid");
5645
5667
  }
5646
5668
  if (sourceContent.startsWith('../') || sourceContent.startsWith('/') || /^[A-Z]:[\\/]+/i.test(sourceContent)) {
5647
- throw new ParseError("Source cannot be outside of the .ptbk.md folder");
5669
+ throw new ParseError("Source cannot be outside of the .book.md folder");
5648
5670
  }
5649
5671
  return {
5650
5672
  type: 'KNOWLEDGE',
@@ -6294,7 +6316,7 @@
6294
6316
  /**
6295
6317
  * Parses the foreach command
6296
6318
  *
6297
- * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.ptbk.md` file
6319
+ * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.book.md` file
6298
6320
  *
6299
6321
  * @see `documentationUrl` for more details
6300
6322
  * @private within the commands folder
@@ -6444,7 +6466,7 @@
6444
6466
  },
6445
6467
  };
6446
6468
  /**
6447
- * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
6469
+ * TODO: [🍭] Make .book.md file with examples of the FOREACH with wrong parsing and logic
6448
6470
  */
6449
6471
 
6450
6472
  /**
@@ -7078,7 +7100,7 @@
7078
7100
  /**
7079
7101
  * Description of the BOOK_VERSION command
7080
7102
  */
7081
- description: "Which version of the Book language is the .ptbk.md using",
7103
+ description: "Which version of the Book language is the .book.md using",
7082
7104
  /**
7083
7105
  * Link to documentation
7084
7106
  */
@@ -7092,19 +7114,19 @@
7092
7114
  */
7093
7115
  parse: function (input) {
7094
7116
  var args = input.args;
7095
- var promptbookVersion = args.pop();
7096
- if (promptbookVersion === undefined) {
7117
+ var bookVersion = args.pop();
7118
+ if (bookVersion === undefined) {
7097
7119
  throw new ParseError("Version is required");
7098
7120
  }
7099
- if (!isValidPromptbookVersion(promptbookVersion)) {
7100
- throw new ParseError("Invalid Promptbook version \"".concat(promptbookVersion, "\""));
7121
+ if (!isValidPromptbookVersion(bookVersion)) {
7122
+ throw new ParseError("Invalid Promptbook version \"".concat(bookVersion, "\""));
7101
7123
  }
7102
7124
  if (args.length > 0 && !(((args.length === 1 && args[0]) || '').toUpperCase() === 'VERSION')) {
7103
7125
  throw new ParseError("Can not have more than one Promptbook version");
7104
7126
  }
7105
7127
  return {
7106
7128
  type: 'BOOK_VERSION',
7107
- promptbookVersion: promptbookVersion,
7129
+ bookVersion: bookVersion,
7108
7130
  };
7109
7131
  },
7110
7132
  /**
@@ -7114,7 +7136,7 @@
7114
7136
  */
7115
7137
  $applyToPipelineJson: function (command, $pipelineJson) {
7116
7138
  // TODO: Warn if the version is overridden
7117
- $pipelineJson.promptbookVersion = command.promptbookVersion;
7139
+ $pipelineJson.bookVersion = command.bookVersion;
7118
7140
  },
7119
7141
  /**
7120
7142
  * Converts the BOOK_VERSION command back to string
@@ -7167,9 +7189,9 @@
7167
7189
  * Example usages of the URL command
7168
7190
  */
7169
7191
  examples: [
7170
- 'PIPELINE URL https://promptbook.studio/library/write-cv.ptbk.md',
7171
- 'URL https://promptbook.studio/library/write-cv.ptbk.md',
7172
- 'https://promptbook.studio/library/write-cv.ptbk.md',
7192
+ 'PIPELINE URL https://promptbook.studio/library/write-cv.book.md',
7193
+ 'URL https://promptbook.studio/library/write-cv.book.md',
7194
+ 'https://promptbook.studio/library/write-cv.book.md',
7173
7195
  ],
7174
7196
  /**
7175
7197
  * Parses the URL command
@@ -7370,7 +7392,7 @@
7370
7392
  /**
7371
7393
  * Parses the boilerplate command
7372
7394
  *
7373
- * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.ptbk.md` file
7395
+ * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.book.md` file
7374
7396
  *
7375
7397
  * @see `documentationUrl` for more details
7376
7398
  * @private within the commands folder
@@ -7424,7 +7446,7 @@
7424
7446
  * Note: `$` is used to indicate that this function mutates given `pipelineJson`
7425
7447
  */
7426
7448
  $applyToPipelineJson: function (command, $pipelineJson) {
7427
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7449
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7428
7450
  },
7429
7451
  /**
7430
7452
  * Apply the BOILERPLATE command to the `pipelineJson`
@@ -7432,7 +7454,7 @@
7432
7454
  * Note: `$` is used to indicate that this function mutates given `templateJson`
7433
7455
  */
7434
7456
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
7435
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7457
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7436
7458
  },
7437
7459
  /**
7438
7460
  * Converts the BOILERPLATE command back to string
@@ -7448,7 +7470,7 @@
7448
7470
  * Note: This is used in `pipelineJsonToString` utility
7449
7471
  */
7450
7472
  takeFromPipelineJson: function (pipelineJson) {
7451
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7473
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7452
7474
  },
7453
7475
  /**
7454
7476
  * Reads the BOILERPLATE command from the `TemplateJson`
@@ -7456,7 +7478,7 @@
7456
7478
  * Note: This is used in `pipelineJsonToString` utility
7457
7479
  */
7458
7480
  takeFromTemplateJson: function ($templateJson) {
7459
- throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .ptbk.md file");
7481
+ throw new ParseError("BOILERPLATE command is only for testing purposes and should not be used in the .book.md file");
7460
7482
  },
7461
7483
  };
7462
7484
 
@@ -7785,7 +7807,7 @@
7785
7807
  return;
7786
7808
  }
7787
7809
  if (!section.startsWith('#')) {
7788
- section = "# Untitled\n\n".concat(section);
7810
+ section = "# ".concat(DEFAULT_TITLE, "\n\n").concat(section);
7789
7811
  }
7790
7812
  sections.push(section);
7791
7813
  buffer = [];
@@ -7849,7 +7871,7 @@
7849
7871
  var e_1, _a;
7850
7872
  var sections = splitMarkdownIntoSections(markdown);
7851
7873
  if (sections.length === 0) {
7852
- return '# Untitled';
7874
+ return "# ".concat(DEFAULT_TITLE);
7853
7875
  }
7854
7876
  var flattenedMarkdown = '';
7855
7877
  var parsedSections = sections.map(parseMarkdownSection);
@@ -7860,7 +7882,7 @@
7860
7882
  }
7861
7883
  else {
7862
7884
  parsedSections.unshift(firstSection);
7863
- flattenedMarkdown += "# Untitled" + "\n\n"; // <- [🧠] Maybe 3 new lines?
7885
+ flattenedMarkdown += "# ".concat(DEFAULT_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
7864
7886
  }
7865
7887
  try {
7866
7888
  for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
@@ -7932,17 +7954,17 @@
7932
7954
  * Note: This function does not validate logic of the pipeline only the parsing
7933
7955
  * Note: This function acts as compilation process
7934
7956
  *
7935
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
7936
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
7957
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
7958
+ * @returns {Promptbook} compiled in JSON format (.book.json)
7937
7959
  * @throws {ParseError} if the promptbook string is not valid
7938
7960
  * @public exported from `@promptbook/core`
7939
7961
  */
7940
7962
  function pipelineStringToJsonSync(pipelineString) {
7941
- var e_1, _a, e_2, _b;
7963
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
7942
7964
  var $pipelineJson = {
7943
7965
  title: undefined /* <- Note: [🍙] Putting here placeholder to keep `title` on top at final JSON */,
7944
7966
  pipelineUrl: undefined /* <- Note: Putting here placeholder to keep `pipelineUrl` on top at final JSON */,
7945
- promptbookVersion: undefined /* <- Note: By default no explicit version */,
7967
+ bookVersion: undefined /* <- Note: By default no explicit version */,
7946
7968
  description: undefined /* <- Note: [🍙] Putting here placeholder to keep `description` on top at final JSON */,
7947
7969
  parameters: [],
7948
7970
  templates: [],
@@ -7966,7 +7988,7 @@
7966
7988
  // =============================================================
7967
7989
  // Note: 1️⃣ Parsing of the markdown into object
7968
7990
  if (pipelineString.startsWith('#!')) {
7969
- var _c = __read(pipelineString.split('\n')), shebangLine_1 = _c[0], restLines = _c.slice(1);
7991
+ var _e = __read(pipelineString.split('\n')), shebangLine_1 = _e[0], restLines = _e.slice(1);
7970
7992
  if (!(shebangLine_1 || '').includes('ptbk')) {
7971
7993
  throw new ParseError(spaceTrim.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 "); }));
7972
7994
  }
@@ -7976,7 +7998,7 @@
7976
7998
  pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
7977
7999
  pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
7978
8000
  pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
7979
- var _d = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _d[0], pipelineSections = _d.slice(1); /* <- Note: [🥞] */
8001
+ var _f = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _f[0], pipelineSections = _f.slice(1); /* <- Note: [🥞] */
7980
8002
  if (pipelineHead === undefined) {
7981
8003
  throw new UnexpectedError(spaceTrim.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 "); }));
7982
8004
  }
@@ -8004,6 +8026,8 @@
8004
8026
  if (parameterDescription) {
8005
8027
  existingParameter.description = parameterDescription;
8006
8028
  }
8029
+ existingParameter.isInput = existingParameter.isInput || isInput;
8030
+ existingParameter.isOutput = existingParameter.isOutput || isOutput;
8007
8031
  }
8008
8032
  else {
8009
8033
  $pipelineJson.parameters.push({
@@ -8066,10 +8090,10 @@
8066
8090
  finally { if (e_1) throw e_1.error; }
8067
8091
  }
8068
8092
  var _loop_2 = function (section) {
8069
- var e_3, _e;
8093
+ var e_5, _l, e_6, _m;
8070
8094
  // TODO: Parse template description (the content out of the codeblock and lists)
8071
8095
  var listItems_2 = extractAllListItemsFromMarkdown(section.content);
8072
- var _f = extractOneBlockFromMarkdown(section.content), language = _f.language, content = _f.content;
8096
+ var _o = extractOneBlockFromMarkdown(section.content), language = _o.language, content = _o.content;
8073
8097
  // TODO: [🎾][1] DRY description
8074
8098
  var description_1 = section.content;
8075
8099
  // Note: Remove codeblocks - TODO: [🎾]
@@ -8110,7 +8134,7 @@
8110
8134
  }) === false) {
8111
8135
  templateCommandParser.$applyToTemplateJson({ type: 'TEMPLATE', templateType: 'PROMPT_TEMPLATE' }, $templateJson, $pipelineJson);
8112
8136
  }
8113
- var _loop_3 = function (listItem, command) {
8137
+ var _loop_4 = function (listItem, command) {
8114
8138
  var commandParser = getParserForCommand(command);
8115
8139
  if (commandParser.isUsedInPipelineTemplate !== true /* <- Note: [🦦][4] */) {
8116
8140
  throw new ParseError(spaceTrim.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: [🚞]
@@ -8133,17 +8157,17 @@
8133
8157
  };
8134
8158
  try {
8135
8159
  // TODO [♓️] List commands and before apply order them to achieve order-agnostic commands
8136
- 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()) {
8137
- var _g = commands_1_1.value, listItem = _g.listItem, command = _g.command;
8138
- _loop_3(listItem, command);
8160
+ 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()) {
8161
+ var _p = commands_1_1.value, listItem = _p.listItem, command = _p.command;
8162
+ _loop_4(listItem, command);
8139
8163
  }
8140
8164
  }
8141
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
8165
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
8142
8166
  finally {
8143
8167
  try {
8144
- if (commands_1_1 && !commands_1_1.done && (_e = commands_1.return)) _e.call(commands_1);
8168
+ if (commands_1_1 && !commands_1_1.done && (_l = commands_1.return)) _l.call(commands_1);
8145
8169
  }
8146
- finally { if (e_3) throw e_3.error; }
8170
+ finally { if (e_5) throw e_5.error; }
8147
8171
  }
8148
8172
  // TODO: [🍧] Should be done in TEMPLATE command
8149
8173
  if ($templateJson.templateType === 'SCRIPT_TEMPLATE') {
@@ -8157,6 +8181,26 @@
8157
8181
  language;
8158
8182
  }
8159
8183
  $templateJson.dependentParameterNames = Array.from(extractParameterNamesFromTemplate($templateJson));
8184
+ try {
8185
+ for (var _q = (e_6 = void 0, __values($templateJson.dependentParameterNames)), _r = _q.next(); !_r.done; _r = _q.next()) {
8186
+ var parameterName = _r.value;
8187
+ // TODO: [🧠] This definition should be made first in the template
8188
+ defineParam({
8189
+ parameterName: parameterName,
8190
+ parameterDescription: null,
8191
+ isInput: false,
8192
+ isOutput: false,
8193
+ // <- 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
8194
+ });
8195
+ }
8196
+ }
8197
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
8198
+ finally {
8199
+ try {
8200
+ if (_r && !_r.done && (_m = _q.return)) _m.call(_q);
8201
+ }
8202
+ finally { if (e_6) throw e_6.error; }
8203
+ }
8160
8204
  /*
8161
8205
  // TODO: [🍧] This should be checked in `MODEL` command + better error message
8162
8206
  if ($templateJson.templateType !== 'PROMPT_TEMPLATE' && $templateJson.modelRequirements !== undefined) {
@@ -8198,9 +8242,51 @@
8198
8242
  finally { if (e_2) throw e_2.error; }
8199
8243
  }
8200
8244
  // =============================================================
8201
- // Note: 5️⃣ Cleanup of undefined values
8245
+ // Note: 5️⃣ Mark parameters as INPUT if not explicitly set
8246
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isInput; })) {
8247
+ var _loop_3 = function (parameter) {
8248
+ var isThisParameterResulting = $pipelineJson.templates.some(function (template) { return template.resultingParameterName === parameter.name; });
8249
+ if (!isThisParameterResulting) {
8250
+ parameter.isInput = true;
8251
+ }
8252
+ };
8253
+ try {
8254
+ for (var _g = __values($pipelineJson.parameters), _h = _g.next(); !_h.done; _h = _g.next()) {
8255
+ var parameter = _h.value;
8256
+ _loop_3(parameter);
8257
+ }
8258
+ }
8259
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
8260
+ finally {
8261
+ try {
8262
+ if (_h && !_h.done && (_c = _g.return)) _c.call(_g);
8263
+ }
8264
+ finally { if (e_3) throw e_3.error; }
8265
+ }
8266
+ }
8267
+ // =============================================================
8268
+ // Note: 6️⃣ Mark all non-INPUT parameters as OUTPUT if any OUTPUT is not set
8269
+ if ($pipelineJson.parameters.every(function (parameter) { return !parameter.isOutput; })) {
8270
+ try {
8271
+ for (var _j = __values($pipelineJson.parameters), _k = _j.next(); !_k.done; _k = _j.next()) {
8272
+ var parameter = _k.value;
8273
+ if (!parameter.isInput) {
8274
+ parameter.isOutput = true;
8275
+ }
8276
+ }
8277
+ }
8278
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
8279
+ finally {
8280
+ try {
8281
+ if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
8282
+ }
8283
+ finally { if (e_4) throw e_4.error; }
8284
+ }
8285
+ }
8286
+ // =============================================================
8287
+ // Note: 7️⃣ Cleanup of undefined values
8202
8288
  $pipelineJson.templates.forEach(function (templates) {
8203
- var e_4, _a;
8289
+ var e_7, _a;
8204
8290
  try {
8205
8291
  for (var _b = __values(Object.entries(templates)), _c = _b.next(); !_c.done; _c = _b.next()) {
8206
8292
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8209,16 +8295,16 @@
8209
8295
  }
8210
8296
  }
8211
8297
  }
8212
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
8298
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
8213
8299
  finally {
8214
8300
  try {
8215
8301
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8216
8302
  }
8217
- finally { if (e_4) throw e_4.error; }
8303
+ finally { if (e_7) throw e_7.error; }
8218
8304
  }
8219
8305
  });
8220
8306
  $pipelineJson.parameters.forEach(function (parameter) {
8221
- var e_5, _a;
8307
+ var e_8, _a;
8222
8308
  try {
8223
8309
  for (var _b = __values(Object.entries(parameter)), _c = _b.next(); !_c.done; _c = _b.next()) {
8224
8310
  var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
@@ -8227,12 +8313,12 @@
8227
8313
  }
8228
8314
  }
8229
8315
  }
8230
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
8316
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
8231
8317
  finally {
8232
8318
  try {
8233
8319
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
8234
8320
  }
8235
- finally { if (e_5) throw e_5.error; }
8321
+ finally { if (e_8) throw e_8.error; }
8236
8322
  }
8237
8323
  });
8238
8324
  // =============================================================
@@ -8261,10 +8347,10 @@
8261
8347
  * Note: This function does not validate logic of the pipeline only the parsing
8262
8348
  * Note: This function acts as compilation process
8263
8349
  *
8264
- * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8350
+ * @param pipelineString {Promptbook} in string markdown format (.book.md)
8265
8351
  * @param tools - Tools for the preparation and scraping - if not provided together with `llm`, the preparation will be skipped
8266
8352
  * @param options - Options and tools for the compilation
8267
- * @returns {Promptbook} compiled in JSON format (.ptbk.json)
8353
+ * @returns {Promptbook} compiled in JSON format (.book.json)
8268
8354
  * @throws {ParseError} if the promptbook string is not valid
8269
8355
  * @public exported from `@promptbook/core`
8270
8356
  */
@@ -9636,13 +9722,13 @@
9636
9722
  return [4 /*yield*/, listAllFiles(path$1, isRecursive, tools.fs)];
9637
9723
  case 1:
9638
9724
  fileNames = _b.sent();
9639
- // Note: First load all .ptbk.json and then .ptbk.md files
9640
- // .ptbk.json can be prepared so it is faster to load
9725
+ // Note: First load all .book.json and then .book.md files
9726
+ // .book.json can be prepared so it is faster to load
9641
9727
  fileNames.sort(function (a, b) {
9642
- if (a.endsWith('.ptbk.json') && b.endsWith('.ptbk.md')) {
9728
+ if (a.endsWith('.book.json') && b.endsWith('.book.md')) {
9643
9729
  return -1;
9644
9730
  }
9645
- if (a.endsWith('.ptbk.md') && b.endsWith('.ptbk.json')) {
9731
+ if (a.endsWith('.book.md') && b.endsWith('.book.json')) {
9646
9732
  return 1;
9647
9733
  }
9648
9734
  return 0;
@@ -9659,7 +9745,7 @@
9659
9745
  case 1:
9660
9746
  _e.trys.push([1, 8, , 9]);
9661
9747
  pipeline = null;
9662
- if (!fileName.endsWith('.ptbk.md')) return [3 /*break*/, 4];
9748
+ if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
9663
9749
  return [4 /*yield*/, promises.readFile(fileName, 'utf-8')];
9664
9750
  case 2:
9665
9751
  pipelineString = (_e.sent());
@@ -9671,7 +9757,7 @@
9671
9757
  pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
9672
9758
  return [3 /*break*/, 7];
9673
9759
  case 4:
9674
- if (!fileName.endsWith('.ptbk.json')) return [3 /*break*/, 6];
9760
+ if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
9675
9761
  _d = (_c = JSON).parse;
9676
9762
  return [4 /*yield*/, promises.readFile(fileName, 'utf-8')];
9677
9763
  case 5:
@@ -9839,7 +9925,7 @@
9839
9925
  return pipelineJsonStringified;
9840
9926
  }
9841
9927
  /**
9842
- * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.ptbk.md
9928
+ * TODO: [🐝] Not Working propperly @see https://promptbook.studio/examples/mixed-knowledge.book.md
9843
9929
  * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
9844
9930
  * TODO: [🧠] Maybe more elegant solution than replacing via regex
9845
9931
  * TODO: [🍙] Make some standard order of json properties
@@ -10020,7 +10106,7 @@
10020
10106
  */
10021
10107
 
10022
10108
  /**
10023
- * Stores
10109
+ * Stores data in memory (HEAP)
10024
10110
  *
10025
10111
  * @public exported from `@promptbook/core`
10026
10112
  */
@@ -10150,13 +10236,18 @@
10150
10236
  promptResult = _c.sent();
10151
10237
  return [3 /*break*/, 11];
10152
10238
  case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
10153
- case 11: return [4 /*yield*/, storage.setItem(key, {
10239
+ case 11:
10240
+ // TODO: [🧠] !!!!! How to do timing in mixed cache / non-cache situation
10241
+ // promptResult.timing: FromtoItems
10242
+ return [4 /*yield*/, storage.setItem(key, {
10154
10243
  date: $currentDate(),
10155
10244
  promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
10156
10245
  prompt: prompt,
10157
10246
  promptResult: promptResult,
10158
10247
  })];
10159
10248
  case 12:
10249
+ // TODO: [🧠] !!!!! How to do timing in mixed cache / non-cache situation
10250
+ // promptResult.timing: FromtoItems
10160
10251
  _c.sent();
10161
10252
  return [2 /*return*/, promptResult];
10162
10253
  }
@@ -10564,7 +10655,7 @@
10564
10655
  function initializePrettifyCommand(program) {
10565
10656
  var _this = this;
10566
10657
  var prettifyCommand = program.command('prettify');
10567
- prettifyCommand.description(spaceTrim__default["default"]("\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 "));
10658
+ prettifyCommand.description(spaceTrim__default["default"]("\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 "));
10568
10659
  prettifyCommand.argument('<filesGlob>',
10569
10660
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
10570
10661
  'Pipelines to prettify as glob pattern');
@@ -10588,7 +10679,7 @@
10588
10679
  case 3:
10589
10680
  if (!!filenames_1_1.done) return [3 /*break*/, 10];
10590
10681
  filename = filenames_1_1.value;
10591
- if (!filename.endsWith('.ptbk.md') && isVerbose) {
10682
+ if (!filename.endsWith('.book.md') && isVerbose) {
10592
10683
  console.info(colors__default["default"].gray("Skipping ".concat(filename)));
10593
10684
  return [3 /*break*/, 9];
10594
10685
  }
@@ -10987,25 +11078,29 @@
10987
11078
  runCommand.description(spaceTrim__default["default"]("\n Runs a pipeline\n "));
10988
11079
  // TODO: [🧅] DRY command arguments
10989
11080
  runCommand.argument('<path>',
10990
- // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .ptbk.md file
11081
+ // <- Note: [🧟‍♂️] This is NOT promptbook collection directory BUT direct path to .book.md file
10991
11082
  'Path to book file');
10992
11083
  runCommand.option('-r, --reload', "Call LLM models even if same prompt with result is in the cache", false);
10993
11084
  runCommand.option('-v, --verbose', "Is output verbose", false);
10994
- runCommand.option('--no-interactive', "Input is not interactive", false);
11085
+ runCommand.option('--no-interactive', "Input is not interactive, if true you need to pass all the input parameters through --json");
11086
+ runCommand.option('-j, --json <json>', "Pass all or some input parameters as JSON record, if used the output is also returned as JSON");
10995
11087
  runCommand.option('-s, --save-report <path>', "Save report to file");
10996
- // TODO: !!!!!! Implement non-interactive mode - allow to pass input parameters as JSON
10997
- // TODO: !!!!!! JSON output
10998
11088
  runCommand.action(function (filePathRaw, options) { return __awaiter(_this, void 0, void 0, function () {
10999
- 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;
11089
+ 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;
11000
11090
  var e_1, _g, _h, e_2, _j, e_3, _k, e_4, _l;
11001
11091
  return __generator(this, function (_m) {
11002
11092
  switch (_m.label) {
11003
11093
  case 0:
11004
- isCacheReloaded = options.reload, options.interactive, isVerbose = options.verbose, saveReport = options.saveReport;
11094
+ isCacheReloaded = options.reload, isInteractive = options.interactive, json = options.json, isVerbose = options.verbose, saveReport = options.saveReport;
11005
11095
  if (saveReport && !saveReport.endsWith('.json') && !saveReport.endsWith('.md')) {
11006
11096
  console.error(colors__default["default"].red("Report file must be .json or .md"));
11007
11097
  return [2 /*return*/, process.exit(1)];
11008
11098
  }
11099
+ inputParameters = {};
11100
+ if (json) {
11101
+ inputParameters = JSON.parse(json);
11102
+ // <- TODO: Maybe check shape of passed JSON and if its valid parameters Record
11103
+ }
11009
11104
  prepareAndScrapeOptions = {
11010
11105
  isVerbose: isVerbose,
11011
11106
  isCacheReloaded: isCacheReloaded,
@@ -11019,7 +11114,7 @@
11019
11114
  filePathRaw,
11020
11115
  "".concat(filePathRaw, ".md"),
11021
11116
  "".concat(filePathRaw, ".book.md"),
11022
- "".concat(filePathRaw, ".ptbk.md"),
11117
+ "".concat(filePathRaw, ".book.md"),
11023
11118
  ];
11024
11119
  _m.label = 1;
11025
11120
  case 1:
@@ -11123,8 +11218,8 @@
11123
11218
  tools: tools,
11124
11219
  isNotPreparedWarningSupressed: true,
11125
11220
  maxExecutionAttempts: 3,
11126
- // <- TODO: !!!!!! Why "LLM execution failed undefinedx"
11127
- maxParallelCount: 1, // <- TODO: !!!!!! Pass
11221
+ // <- TODO: Why "LLM execution failed undefinedx"
11222
+ maxParallelCount: 1, // <- TODO: Pass CLI argument
11128
11223
  });
11129
11224
  if (isVerbose) {
11130
11225
  console.info(colors__default["default"].gray('--- Getting input parameters ---'));
@@ -11133,13 +11228,17 @@
11133
11228
  .filter(function (_a) {
11134
11229
  var isInput = _a.isInput;
11135
11230
  return isInput;
11231
+ })
11232
+ .filter(function (_a) {
11233
+ var name = _a.name;
11234
+ return typeof inputParameters[name] !== 'string';
11136
11235
  })
11137
11236
  .map(function (_a) {
11138
11237
  var name = _a.name, exampleValues = _a.exampleValues;
11139
11238
  var message = name;
11140
11239
  var initial = '';
11141
11240
  if (exampleValues && exampleValues.length > 0) {
11142
- var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1 && countCharacters(exampleValue) <= 30; });
11241
+ var exampleValuesFiltered = exampleValues.filter(function (exampleValue) { return countLines(exampleValue) <= 1; });
11143
11242
  if (exampleValuesFiltered.length !== 0) {
11144
11243
  message += " (e.g. ".concat(exampleValuesFiltered.join(', '), ")");
11145
11244
  }
@@ -11153,10 +11252,44 @@
11153
11252
  // TODO: Maybe use> validate: value => value < 18 ? `Forbidden` : true
11154
11253
  };
11155
11254
  });
11255
+ if (isInteractive === false && questions.length !== 0) {
11256
+ console.error(colors__default["default"].red(spaceTrim__default["default"](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
11257
+ .filter(function (_a) {
11258
+ var isInput = _a.isInput;
11259
+ return isInput;
11260
+ })
11261
+ .filter(function (_a) {
11262
+ var parameterName = _a.name;
11263
+ return !questions.some(function (_a) {
11264
+ var questionName = _a.name;
11265
+ return questionName === parameterName;
11266
+ });
11267
+ })
11268
+ .map(function (_a) {
11269
+ var name = _a.name, description = _a.description;
11270
+ return "- **".concat(name, "** ").concat(description);
11271
+ })
11272
+ .join('\n')), "\n\n Example:\n --json '").concat(JSON.stringify(Object.fromEntries(pipeline.parameters
11273
+ .filter(function (_a) {
11274
+ var isInput = _a.isInput;
11275
+ return isInput;
11276
+ })
11277
+ .map(function (_a) {
11278
+ var name = _a.name, exampleValues = _a.exampleValues;
11279
+ return [
11280
+ name,
11281
+ inputParameters[name] || (exampleValues || [])[0] || '...',
11282
+ ];
11283
+ })))
11284
+ .split("'")
11285
+ .join("\\'"), "'\n "); })));
11286
+ return [2 /*return*/, process.exit(1)];
11287
+ }
11156
11288
  return [4 /*yield*/, prompts__default["default"](questions)];
11157
11289
  case 16:
11158
11290
  response = _m.sent();
11159
- inputParameters = response;
11291
+ inputParameters = __assign(__assign({}, inputParameters), response);
11292
+ // TODO: Maybe do some validation of the response (and --json argument which is passed)
11160
11293
  if (isVerbose) {
11161
11294
  console.info(colors__default["default"].gray('--- Executing ---'));
11162
11295
  }
@@ -11193,7 +11326,9 @@
11193
11326
  console.info(colors__default["default"].gray('--- Usage ---'));
11194
11327
  console.info(colors__default["default"].cyan(usageToHuman(result.usage)));
11195
11328
  }
11196
- console.info(colors__default["default"].gray('--- Result ---'));
11329
+ if (json === undefined || isVerbose === true) {
11330
+ console.info(colors__default["default"].gray('--- Result ---'));
11331
+ }
11197
11332
  try {
11198
11333
  // TODO: [🧠] Should be errors or warnings shown first
11199
11334
  for (_a = __values(errors || []), _b = _a.next(); !_b.done; _b = _a.next()) {
@@ -11221,20 +11356,25 @@
11221
11356
  }
11222
11357
  finally { if (e_3) throw e_3.error; }
11223
11358
  }
11224
- try {
11225
- for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11226
- key = _f.value;
11227
- value = outputParameters[key] || colors__default["default"].grey(colors__default["default"].italic('(nothing)'));
11228
- separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11229
- console.info(colors__default["default"].green(colors__default["default"].bold(key) + separator + value));
11230
- }
11231
- }
11232
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
11233
- finally {
11359
+ if (json === undefined) {
11234
11360
  try {
11235
- if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11361
+ for (_e = __values(Object.keys(outputParameters)), _f = _e.next(); !_f.done; _f = _e.next()) {
11362
+ key = _f.value;
11363
+ value = outputParameters[key] || colors__default["default"].grey(colors__default["default"].italic('(nothing)'));
11364
+ separator = countLines(value) > 1 || countWords(value) > 100 ? ':\n' : ': ';
11365
+ console.info(colors__default["default"].green(colors__default["default"].bold(key) + separator + value));
11366
+ }
11236
11367
  }
11237
- finally { if (e_4) throw e_4.error; }
11368
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
11369
+ finally {
11370
+ try {
11371
+ if (_f && !_f.done && (_l = _e.return)) _l.call(_e);
11372
+ }
11373
+ finally { if (e_4) throw e_4.error; }
11374
+ }
11375
+ }
11376
+ else {
11377
+ console.info(JSON.stringify(outputParameters, null, 4));
11238
11378
  }
11239
11379
  return [2 /*return*/, process.exit(0)];
11240
11380
  }
@@ -11242,7 +11382,7 @@
11242
11382
  }); });
11243
11383
  }
11244
11384
  /**
11245
- * TODO: !!!!!! Catch and wrap all errors from CLI
11385
+ * TODO: !!!!! Catch and wrap all errors from CLI
11246
11386
  * TODO: [🧠] Pass `maxExecutionAttempts`, `csvSettings`
11247
11387
  * TODO: [🥃][main] !!! Allow `ptbk run` without configuring any llm tools
11248
11388
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
@@ -11257,7 +11397,7 @@
11257
11397
  function initializeTestCommand(program) {
11258
11398
  var _this = this;
11259
11399
  var testCommand = program.command('test');
11260
- testCommand.description(spaceTrim__default["default"]("\n Iterates over `.ptbk.md` and `.ptbk.json` and checks if they are parsable and logically valid\n "));
11400
+ testCommand.description(spaceTrim__default["default"]("\n Iterates over `.book.md` and `.book.json` and checks if they are parsable and logically valid\n "));
11261
11401
  testCommand.argument('<filesGlob>',
11262
11402
  // <- TODO: [🧟‍♂️] Unite path to promptbook collection argument
11263
11403
  'Pipelines to test as glob pattern');
@@ -11307,7 +11447,7 @@
11307
11447
  case 6:
11308
11448
  _f.trys.push([6, 13, , 14]);
11309
11449
  pipeline = void 0;
11310
- if (!filename.endsWith('.ptbk.md')) return [3 /*break*/, 9];
11450
+ if (!filename.endsWith('.book.md')) return [3 /*break*/, 9];
11311
11451
  return [4 /*yield*/, promises.readFile(filename, 'utf-8')];
11312
11452
  case 7:
11313
11453
  pipelineMarkdown = (_f.sent());
@@ -11319,7 +11459,7 @@
11319
11459
  }
11320
11460
  _f.label = 9;
11321
11461
  case 9:
11322
- if (!filename.endsWith('.ptbk.json')) return [3 /*break*/, 11];
11462
+ if (!filename.endsWith('.book.json')) return [3 /*break*/, 11];
11323
11463
  _c = (_b = JSON).parse;
11324
11464
  return [4 /*yield*/, promises.readFile(filename, 'utf-8')];
11325
11465
  case 10:
@@ -11406,13 +11546,16 @@
11406
11546
  });
11407
11547
  }
11408
11548
  /**
11409
- * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.ptbk.md` -> `ptbk ./foo.ptbk.md`
11549
+ * TODO: [🧠] Maybe `run` command the default, instead of `ptbk run ./foo.book.md` -> `ptbk ./foo.book.md`
11410
11550
  * TODO: [🥠] Do not export, its just for CLI script
11411
11551
  * TODO: [🕌] When more functionalities, rename
11412
11552
  * Note: 11:11
11413
11553
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
11414
11554
  */
11415
11555
 
11556
+ /**
11557
+ * Note: [🔺] Purpose of this file is to export CLI for production environment
11558
+ */
11416
11559
  /**
11417
11560
  * Hidden utilities which should not be used by external consumers.
11418
11561
  *
@@ -11420,7 +11563,7 @@
11420
11563
  */
11421
11564
  var _CLI = {
11422
11565
  // Note: [🥠]
11423
- _initialize: promptbookCli,
11566
+ _initialize_promptbookCli: promptbookCli,
11424
11567
  };
11425
11568
  /**
11426
11569
  * Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
@@ -13974,7 +14117,7 @@
13974
14117
  collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
13975
14118
  _d = createPipelineExecutor;
13976
14119
  _g = {};
13977
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md')];
14120
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md')];
13978
14121
  case 1:
13979
14122
  prepareKnowledgeFromMarkdownExecutor = _d.apply(void 0, [(_g.pipeline = _k.sent(),
13980
14123
  _g.tools = {
@@ -13983,7 +14126,7 @@
13983
14126
  _g)]);
13984
14127
  _e = createPipelineExecutor;
13985
14128
  _h = {};
13986
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md')];
14129
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.book.md')];
13987
14130
  case 2:
13988
14131
  prepareTitleExecutor = _e.apply(void 0, [(_h.pipeline = _k.sent(),
13989
14132
  _h.tools = {
@@ -13992,7 +14135,7 @@
13992
14135
  _h)]);
13993
14136
  _f = createPipelineExecutor;
13994
14137
  _j = {};
13995
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md')];
14138
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md')];
13996
14139
  case 3:
13997
14140
  prepareKeywordsExecutor = _f.apply(void 0, [(_j.pipeline = _k.sent(),
13998
14141
  _j.tools = {