@promptbook/node 0.92.0-3 → 0.92.0-31

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 (172) hide show
  1. package/esm/index.es.js +796 -426
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/browser.index.d.ts +2 -0
  4. package/esm/typings/src/_packages/core.index.d.ts +22 -6
  5. package/esm/typings/src/_packages/deepseek.index.d.ts +2 -0
  6. package/esm/typings/src/_packages/google.index.d.ts +2 -0
  7. package/esm/typings/src/_packages/types.index.d.ts +4 -2
  8. package/esm/typings/src/_packages/utils.index.d.ts +2 -0
  9. package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +1 -1
  10. package/esm/typings/src/collection/PipelineCollection.d.ts +0 -2
  11. package/esm/typings/src/collection/SimplePipelineCollection.d.ts +1 -1
  12. package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -6
  13. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +0 -2
  14. package/esm/typings/src/commands/FORMFACTOR/formfactorCommandParser.d.ts +1 -1
  15. package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
  16. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +36 -28
  17. package/esm/typings/src/config.d.ts +41 -11
  18. package/esm/typings/src/constants.d.ts +43 -2
  19. package/esm/typings/src/conversion/archive/loadArchive.d.ts +2 -2
  20. package/esm/typings/src/errors/0-BoilerplateError.d.ts +2 -2
  21. package/esm/typings/src/executables/$provideExecutablesForNode.d.ts +1 -1
  22. package/esm/typings/src/executables/apps/locateLibreoffice.d.ts +2 -1
  23. package/esm/typings/src/executables/apps/locatePandoc.d.ts +2 -1
  24. package/esm/typings/src/executables/locateApp.d.ts +2 -2
  25. package/esm/typings/src/executables/platforms/locateAppOnLinux.d.ts +2 -1
  26. package/esm/typings/src/executables/platforms/locateAppOnMacOs.d.ts +2 -1
  27. package/esm/typings/src/executables/platforms/locateAppOnWindows.d.ts +2 -1
  28. package/esm/typings/src/execution/AbstractTaskResult.d.ts +1 -1
  29. package/esm/typings/src/execution/CommonToolsOptions.d.ts +5 -1
  30. package/esm/typings/src/execution/LlmExecutionToolsConstructor.d.ts +2 -1
  31. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +4 -2
  32. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +12 -9
  33. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +13 -10
  34. package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +12 -9
  35. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +15 -3
  36. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +20 -14
  37. package/esm/typings/src/execution/createPipelineExecutor/computeCosineSimilarity.d.ts +13 -0
  38. package/esm/typings/src/execution/createPipelineExecutor/filterJustOutputParameters.d.ts +7 -6
  39. package/esm/typings/src/execution/createPipelineExecutor/getContextForTask.d.ts +5 -1
  40. package/esm/typings/src/execution/createPipelineExecutor/getExamplesForTask.d.ts +1 -1
  41. package/esm/typings/src/execution/createPipelineExecutor/getKnowledgeForTask.d.ts +21 -5
  42. package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTask.d.ts +19 -5
  43. package/esm/typings/src/execution/createPipelineExecutor/knowledgePiecesToString.d.ts +9 -0
  44. package/esm/typings/src/execution/translation/automatic-translate/automatic-translators/LindatAutomaticTranslator.d.ts +4 -4
  45. package/esm/typings/src/execution/utils/checkExpectations.d.ts +1 -1
  46. package/esm/typings/src/execution/utils/uncertainNumber.d.ts +3 -2
  47. package/esm/typings/src/formats/_common/{FormatDefinition.d.ts → FormatParser.d.ts} +8 -6
  48. package/esm/typings/src/formats/_common/FormatSubvalueParser.d.ts +66 -0
  49. package/esm/typings/src/formats/csv/CsvFormatParser.d.ts +17 -0
  50. package/esm/typings/src/formats/csv/CsvSettings.d.ts +2 -2
  51. package/esm/typings/src/formats/csv/utils/csvParse.d.ts +12 -0
  52. package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +1 -1
  53. package/esm/typings/src/formats/index.d.ts +2 -2
  54. package/esm/typings/src/formats/json/{JsonFormatDefinition.d.ts → JsonFormatParser.d.ts} +6 -6
  55. package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +1 -1
  56. package/esm/typings/src/formats/json/utils/jsonParse.d.ts +8 -0
  57. package/esm/typings/src/formats/text/{TextFormatDefinition.d.ts → TextFormatParser.d.ts} +7 -7
  58. package/esm/typings/src/formats/xml/XmlFormatParser.d.ts +19 -0
  59. package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +1 -1
  60. package/esm/typings/src/formfactors/_boilerplate/BoilerplateFormfactorDefinition.d.ts +3 -2
  61. package/esm/typings/src/formfactors/_common/AbstractFormfactorDefinition.d.ts +16 -7
  62. package/esm/typings/src/formfactors/_common/FormfactorDefinition.d.ts +3 -1
  63. package/esm/typings/src/formfactors/_common/string_formfactor_name.d.ts +2 -1
  64. package/esm/typings/src/formfactors/chatbot/ChatbotFormfactorDefinition.d.ts +2 -2
  65. package/esm/typings/src/formfactors/completion/CompletionFormfactorDefinition.d.ts +29 -0
  66. package/esm/typings/src/formfactors/generator/GeneratorFormfactorDefinition.d.ts +2 -1
  67. package/esm/typings/src/formfactors/generic/GenericFormfactorDefinition.d.ts +2 -2
  68. package/esm/typings/src/formfactors/index.d.ts +33 -8
  69. package/esm/typings/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +4 -2
  70. package/esm/typings/src/formfactors/sheets/SheetsFormfactorDefinition.d.ts +3 -2
  71. package/esm/typings/src/formfactors/translator/TranslatorFormfactorDefinition.d.ts +3 -2
  72. package/esm/typings/src/high-level-abstractions/index.d.ts +2 -2
  73. package/esm/typings/src/llm-providers/_common/register/$llmToolsMetadataRegister.d.ts +3 -3
  74. package/esm/typings/src/llm-providers/_common/register/$llmToolsRegister.d.ts +3 -3
  75. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +4 -4
  76. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +4 -3
  77. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +17 -4
  78. package/esm/typings/src/llm-providers/_common/register/LlmToolsConfiguration.d.ts +11 -4
  79. package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +27 -5
  80. package/esm/typings/src/llm-providers/_common/register/LlmToolsOptions.d.ts +9 -2
  81. package/esm/typings/src/llm-providers/_common/register/createLlmToolsFromConfiguration.d.ts +12 -3
  82. package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +10 -5
  83. package/esm/typings/src/llm-providers/_common/utils/cache/CacheLlmToolsOptions.d.ts +5 -3
  84. package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +3 -3
  85. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/limitTotalUsage.d.ts +5 -5
  86. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  87. package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +4 -0
  88. package/esm/typings/src/llm-providers/deepseek/deepseek-models.d.ts +23 -0
  89. package/esm/typings/src/llm-providers/google/google-models.d.ts +23 -0
  90. package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +4 -0
  91. package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
  92. package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +2 -2
  93. package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +2 -2
  94. package/esm/typings/src/migrations/migratePipeline.d.ts +9 -0
  95. package/esm/typings/src/other/templates/getBookTemplates.d.ts +2 -2
  96. package/esm/typings/src/personas/preparePersona.d.ts +1 -1
  97. package/esm/typings/src/pipeline/PipelineInterface/PipelineInterface.d.ts +3 -3
  98. package/esm/typings/src/pipeline/PipelineInterface/constants.d.ts +1 -1
  99. package/esm/typings/src/pipeline/PipelineInterface/getPipelineInterface.d.ts +1 -1
  100. package/esm/typings/src/pipeline/PipelineInterface/isPipelineImplementingInterface.d.ts +5 -4
  101. package/esm/typings/src/pipeline/PipelineInterface/isPipelineInterfacesEqual.d.ts +1 -1
  102. package/esm/typings/src/pipeline/PipelineJson/CommonTaskJson.d.ts +9 -6
  103. package/esm/typings/src/pipeline/PipelineJson/PersonaJson.d.ts +4 -2
  104. package/esm/typings/src/pipeline/PipelineJson/PipelineJson.d.ts +3 -2
  105. package/esm/typings/src/pipeline/PipelineString.d.ts +3 -1
  106. package/esm/typings/src/pipeline/book-notation.d.ts +2 -2
  107. package/esm/typings/src/postprocessing/utils/extractJsonBlock.d.ts +1 -1
  108. package/esm/typings/src/prepare/prepareTasks.d.ts +7 -4
  109. package/esm/typings/src/remote-server/openapi-types.d.ts +348 -6
  110. package/esm/typings/src/remote-server/openapi.d.ts +398 -4
  111. package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +2 -1
  112. package/esm/typings/src/scrapers/_boilerplate/BoilerplateScraper.d.ts +3 -3
  113. package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -1
  114. package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +1 -1
  115. package/esm/typings/src/scrapers/_common/Converter.d.ts +3 -1
  116. package/esm/typings/src/scrapers/_common/Scraper.d.ts +4 -3
  117. package/esm/typings/src/scrapers/_common/ScraperIntermediateSource.d.ts +4 -2
  118. package/esm/typings/src/scrapers/_common/register/$provideFilesystemForNode.d.ts +2 -1
  119. package/esm/typings/src/scrapers/_common/register/$provideScrapersForBrowser.d.ts +6 -3
  120. package/esm/typings/src/scrapers/_common/register/$provideScrapersForNode.d.ts +3 -5
  121. package/esm/typings/src/scrapers/_common/register/$scrapersMetadataRegister.d.ts +3 -3
  122. package/esm/typings/src/scrapers/_common/register/$scrapersRegister.d.ts +3 -2
  123. package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +8 -5
  124. package/esm/typings/src/scrapers/_common/register/ScraperConstructor.d.ts +2 -1
  125. package/esm/typings/src/scrapers/_common/utils/getScraperIntermediateSource.d.ts +6 -5
  126. package/esm/typings/src/scrapers/_common/utils/makeKnowledgeSourceHandler.d.ts +3 -1
  127. package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -1
  128. package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +2 -1
  129. package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +4 -1
  130. package/esm/typings/src/scrapers/markitdown/MarkitdownScraper.d.ts +1 -1
  131. package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +2 -1
  132. package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +3 -4
  133. package/esm/typings/src/scripting/javascript/postprocessing-functions.d.ts +5 -1
  134. package/esm/typings/src/storage/file-cache-storage/FileCacheStorage.d.ts +12 -5
  135. package/esm/typings/src/storage/file-cache-storage/FileCacheStorageOptions.d.ts +4 -2
  136. package/esm/typings/src/storage/file-cache-storage/utils/nameToSubfolderPath.d.ts +2 -1
  137. package/esm/typings/src/storage/local-storage/getIndexedDbStorage.d.ts +10 -0
  138. package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromIndexedDb.d.ts +7 -0
  139. package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromWebStorage.d.ts +2 -1
  140. package/esm/typings/src/types/IntermediateFilesStrategy.d.ts +2 -1
  141. package/esm/typings/src/types/ModelVariant.d.ts +5 -5
  142. package/esm/typings/src/types/typeAliases.d.ts +17 -13
  143. package/esm/typings/src/utils/$Register.d.ts +8 -7
  144. package/esm/typings/src/utils/editable/edit-pipeline-string/addPipelineCommand.d.ts +2 -2
  145. package/esm/typings/src/utils/editable/edit-pipeline-string/deflatePipeline.d.ts +4 -1
  146. package/esm/typings/src/utils/editable/utils/isFlatPipeline.d.ts +2 -1
  147. package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -1
  148. package/esm/typings/src/utils/expectation-counters/index.d.ts +1 -1
  149. package/esm/typings/src/utils/markdown/extractAllListItemsFromMarkdown.d.ts +1 -1
  150. package/esm/typings/src/utils/normalization/nameToUriPart.d.ts +4 -4
  151. package/esm/typings/src/utils/normalization/nameToUriParts.d.ts +4 -4
  152. package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +3 -3
  153. package/esm/typings/src/utils/normalization/normalizeTo_SCREAMING_CASE.d.ts +3 -3
  154. package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +4 -4
  155. package/esm/typings/src/utils/normalization/normalizeTo_snake_case.d.ts +3 -3
  156. package/esm/typings/src/utils/normalization/removeDiacritics.d.ts +3 -3
  157. package/esm/typings/src/utils/normalization/searchKeywords.d.ts +4 -1
  158. package/esm/typings/src/utils/normalization/titleToName.d.ts +4 -4
  159. package/esm/typings/src/utils/organization/empty_object.d.ts +2 -2
  160. package/esm/typings/src/utils/organization/just_empty_object.d.ts +4 -4
  161. package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +7 -7
  162. package/esm/typings/src/utils/serialization/clonePipeline.d.ts +4 -3
  163. package/esm/typings/src/utils/serialization/deepClone.d.ts +5 -1
  164. package/esm/typings/src/utils/validators/javascriptName/isValidJavascriptName.d.ts +3 -3
  165. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +5 -4
  166. package/esm/typings/src/version.d.ts +2 -1
  167. package/package.json +2 -2
  168. package/umd/index.umd.js +799 -429
  169. package/umd/index.umd.js.map +1 -1
  170. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +0 -31
  171. package/esm/typings/src/formats/csv/CsvFormatDefinition.d.ts +0 -17
  172. package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +0 -19
package/umd/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('fs/promises'), require('path'), require('spacetrim'), require('jszip'), require('prettier'), require('prettier/parser-html'), require('rxjs'), require('crypto'), require('waitasecond'), require('papaparse'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto-js'), require('mime-types'), require('child_process'), require('dotenv')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'colors', 'fs/promises', 'path', 'spacetrim', 'jszip', 'prettier', 'prettier/parser-html', 'rxjs', 'crypto', 'waitasecond', 'papaparse', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto-js', 'mime-types', 'child_process', 'dotenv'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-node"] = {}, global.colors, global.promises, global.path, global.spaceTrim, global.JSZip, global.prettier, global.parserHtml, global.rxjs, global.crypto, global.waitasecond, global.papaparse, global.hexEncoder, global.sha256, global.cryptoJs, global.mimeTypes, global.child_process, global.dotenv));
5
- })(this, (function (exports, colors, promises, path, spaceTrim, JSZip, prettier, parserHtml, rxjs, crypto, waitasecond, papaparse, hexEncoder, sha256, cryptoJs, mimeTypes, child_process, dotenv) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('fs/promises'), require('path'), require('spacetrim'), require('jszip'), require('prettier'), require('prettier/parser-html'), require('crypto'), require('rxjs'), require('waitasecond'), require('papaparse'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto-js'), require('mime-types'), require('child_process'), require('dotenv')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'colors', 'fs/promises', 'path', 'spacetrim', 'jszip', 'prettier', 'prettier/parser-html', 'crypto', 'rxjs', 'waitasecond', 'papaparse', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto-js', 'mime-types', 'child_process', 'dotenv'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-node"] = {}, global.colors, global.promises, global.path, global.spaceTrim, global.JSZip, global.prettier, global.parserHtml, global.crypto, global.rxjs, global.waitasecond, global.papaparse, global.hexEncoder, global.sha256, global.cryptoJs, global.mimeTypes, global.child_process, global.dotenv));
5
+ })(this, (function (exports, colors, promises, path, spaceTrim, JSZip, prettier, parserHtml, crypto, rxjs, waitasecond, papaparse, hexEncoder, sha256, cryptoJs, mimeTypes, child_process, dotenv) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -46,7 +46,7 @@
46
46
  * @generated
47
47
  * @see https://github.com/webgptorg/promptbook
48
48
  */
49
- const PROMPTBOOK_ENGINE_VERSION = '0.92.0-3';
49
+ const PROMPTBOOK_ENGINE_VERSION = '0.92.0-31';
50
50
  /**
51
51
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
52
52
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -117,6 +117,21 @@
117
117
  * @public exported from `@promptbook/core`
118
118
  */
119
119
  const DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
120
+ /**
121
+ * Threshold value that determines when a dataset is considered "big"
122
+ * and may require special handling or optimizations
123
+ *
124
+ * For example, when error occurs in one item of the big dataset, it will not fail the whole pipeline
125
+ *
126
+ * @public exported from `@promptbook/core`
127
+ */
128
+ const BIG_DATASET_TRESHOLD = 50;
129
+ /**
130
+ * Placeholder text used to represent a placeholder value of failed operation
131
+ *
132
+ * @public exported from `@promptbook/core`
133
+ */
134
+ const FAILED_VALUE_PLACEHOLDER = '!?';
120
135
  // <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
121
136
  /**
122
137
  * The maximum number of iterations for a loops
@@ -211,7 +226,7 @@
211
226
  const DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME = `index`;
212
227
  // <- TODO: [🧜‍♂️]
213
228
  /**
214
- * @@@
229
+ * Default settings for parsing and generating CSV files in Promptbook.
215
230
  *
216
231
  * @public exported from `@promptbook/core`
217
232
  */
@@ -222,19 +237,19 @@
222
237
  skipEmptyLines: true,
223
238
  });
224
239
  /**
225
- * @@@
240
+ * Controls whether verbose logging is enabled by default throughout the application.
226
241
  *
227
242
  * @public exported from `@promptbook/core`
228
243
  */
229
244
  let DEFAULT_IS_VERBOSE = false;
230
245
  /**
231
- * @@@
246
+ * Controls whether auto-installation of dependencies is enabled by default.
232
247
  *
233
248
  * @public exported from `@promptbook/core`
234
249
  */
235
250
  const DEFAULT_IS_AUTO_INSTALLED = false;
236
251
  /**
237
- * @@@
252
+ * Indicates whether pipeline logic validation is enabled. When true, the pipeline logic is checked for consistency.
238
253
  *
239
254
  * @private within the repository
240
255
  */
@@ -315,6 +330,42 @@
315
330
  }
316
331
  }
317
332
 
333
+ /**
334
+ * Converts a JavaScript Object Notation (JSON) string into an object.
335
+ *
336
+ * Note: This is wrapper around `JSON.parse()` with better error and type handling
337
+ *
338
+ * @public exported from `@promptbook/utils`
339
+ */
340
+ function jsonParse(value) {
341
+ if (value === undefined) {
342
+ throw new Error(`Can not parse JSON from undefined value.`);
343
+ }
344
+ else if (typeof value !== 'string') {
345
+ console.error('Can not parse JSON from non-string value.', { text: value });
346
+ throw new Error(spaceTrim__default["default"](`
347
+ Can not parse JSON from non-string value.
348
+
349
+ The value type: ${typeof value}
350
+ See more in console.
351
+ `));
352
+ }
353
+ try {
354
+ return JSON.parse(value);
355
+ }
356
+ catch (error) {
357
+ if (!(error instanceof Error)) {
358
+ throw error;
359
+ }
360
+ throw new Error(spaceTrim__default["default"]((block) => `
361
+ ${block(error.message)}
362
+
363
+ The JSON text:
364
+ ${block(value)}
365
+ `));
366
+ }
367
+ }
368
+
318
369
  /**
319
370
  * Orders JSON object by keys
320
371
  *
@@ -544,8 +595,12 @@
544
595
  */
545
596
 
546
597
  /**
547
- * @@@
598
+ * Creates a deep clone of the given object
599
+ *
600
+ * Note: This method only works for objects that are fully serializable to JSON and do not contain functions, Dates, or special types.
548
601
  *
602
+ * @param objectValue The object to clone.
603
+ * @returns A deep, writable clone of the input object.
549
604
  * @public exported from `@promptbook/utils`
550
605
  */
551
606
  function deepClone(objectValue) {
@@ -627,13 +682,13 @@
627
682
  */
628
683
  const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';
629
684
  /**
630
- * @@@
685
+ * Placeholder value indicating a parameter is missing its value.
631
686
  *
632
687
  * @private within the repository
633
688
  */
634
689
  const RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
635
690
  /**
636
- * @@@
691
+ * Placeholder value indicating a parameter is restricted and cannot be used directly.
637
692
  *
638
693
  * @private within the repository
639
694
  */
@@ -1104,7 +1159,7 @@
1104
1159
  if (!indexFile) {
1105
1160
  throw new UnexpectedError(`Archive does not contain 'index.book.json' file`);
1106
1161
  }
1107
- const collectionJson = JSON.parse(await indexFile.async('text'));
1162
+ const collectionJson = jsonParse(await indexFile.async('text'));
1108
1163
  for (const pipeline of collectionJson) {
1109
1164
  validatePipeline(pipeline);
1110
1165
  }
@@ -1114,7 +1169,7 @@
1114
1169
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
1115
1170
  */
1116
1171
 
1117
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou 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}\n```\n\n`-> {knowledgePieces}`\n"}],sourceFile:"./books/prepare-knowledge-from-markdown.book"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou 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}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book",formfactorName:"GENERIC",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}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book`\n- INPUT PARAMETER `{availableModelNames}` List of available model names separated by comma (,)\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou 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}\n```\n\n`-> {modelRequirements}`\n"}],sourceFile:"./books/prepare-persona.book"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book"}];
1172
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou 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}\n```\n\n`-> {knowledgePieces}`\n"}],sourceFile:"./books/prepare-knowledge-from-markdown.book"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou 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}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",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- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book",formfactorName:"GENERIC",parameters:[{name:"availableModels",description:"List of available model names together with their descriptions as JSON",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelsRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-model-requirements",title:"Make modelRequirements",content:"You are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n```json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n```\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with 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\nHere are the available models:\n\n```json\n{availableModels}\n```\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:"modelsRequirements",format:"JSON",dependentParameterNames:["availableModels","personaDescription"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book`\n- INPUT PARAMETER `{availableModels}` List of available model names together with their descriptions as JSON\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelsRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n\\`\\`\\`json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n\\`\\`\\`\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with 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\nHere are the available models:\n\n\\`\\`\\`json\n{availableModels}\n\\`\\`\\`\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}\n```\n\n`-> {modelsRequirements}`\n"}],sourceFile:"./books/prepare-persona.book"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book"}];
1118
1173
 
1119
1174
  /**
1120
1175
  * Checks if value is valid email
@@ -1184,7 +1239,7 @@
1184
1239
  * Function isValidJsonString will tell you if the string is valid JSON or not
1185
1240
  *
1186
1241
  * @param value The string to check
1187
- * @returns True if the string is a valid JSON string, false otherwise
1242
+ * @returns `true` if the string is a valid JSON string, false otherwise
1188
1243
  *
1189
1244
  * @public exported from `@promptbook/utils`
1190
1245
  */
@@ -1465,7 +1520,7 @@
1465
1520
  */
1466
1521
  function unpreparePipeline(pipeline) {
1467
1522
  let { personas, knowledgeSources, tasks } = pipeline;
1468
- personas = personas.map((persona) => ({ ...persona, modelRequirements: undefined, preparationIds: undefined }));
1523
+ personas = personas.map((persona) => ({ ...persona, modelsRequirements: undefined, preparationIds: undefined }));
1469
1524
  knowledgeSources = knowledgeSources.map((knowledgeSource) => ({ ...knowledgeSource, preparationIds: undefined }));
1470
1525
  tasks = tasks.map((task) => {
1471
1526
  let { dependentParameterNames } = task;
@@ -1506,7 +1561,7 @@
1506
1561
  /**
1507
1562
  * Constructs a pipeline collection from pipelines
1508
1563
  *
1509
- * @param pipelines @@@
1564
+ * @param pipelines Array of pipeline JSON objects to include in the collection
1510
1565
  *
1511
1566
  * Note: During the construction logic of all pipelines are validated
1512
1567
  * Note: It is not recommended to use this constructor directly, use `createCollectionFromJson` *(or other variant)* instead
@@ -1636,15 +1691,21 @@
1636
1691
  * @public exported from `@promptbook/core`
1637
1692
  */
1638
1693
  function isPipelinePrepared(pipeline) {
1639
- // Note: Ignoring `pipeline.preparations` @@@
1640
- // Note: Ignoring `pipeline.knowledgePieces` @@@
1694
+ // Note: Ignoring `pipeline.preparations`
1695
+ // Note: Ignoring `pipeline.knowledgePieces`
1641
1696
  if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
1697
+ // TODO: !!! Comment this out
1698
+ console.log('Pipeline is not prepared because title is undefined or empty', pipeline);
1642
1699
  return false;
1643
1700
  }
1644
- if (!pipeline.personas.every((persona) => persona.modelRequirements !== undefined)) {
1701
+ if (!pipeline.personas.every((persona) => persona.modelsRequirements !== undefined)) {
1702
+ // TODO: !!! Comment this out
1703
+ console.log('Pipeline is not prepared because personas are not prepared', pipeline.personas);
1645
1704
  return false;
1646
1705
  }
1647
1706
  if (!pipeline.knowledgeSources.every((knowledgeSource) => knowledgeSource.preparationIds !== undefined)) {
1707
+ // TODO: !!! Comment this out
1708
+ console.log('Pipeline is not prepared because knowledge sources are not prepared', pipeline.knowledgeSources);
1648
1709
  return false;
1649
1710
  }
1650
1711
  /*
@@ -1665,70 +1726,6 @@
1665
1726
  * - [♨] Are tasks prepared
1666
1727
  */
1667
1728
 
1668
- /**
1669
- * Generates random token
1670
- *
1671
- * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
1672
- *
1673
- * @private internal helper function
1674
- * @returns secure random token
1675
- */
1676
- function $randomToken(randomness) {
1677
- return crypto.randomBytes(randomness).toString('hex');
1678
- }
1679
- /**
1680
- * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
1681
- */
1682
-
1683
- /**
1684
- * Recursively converts JSON strings to JSON objects
1685
-
1686
- * @public exported from `@promptbook/utils`
1687
- */
1688
- function jsonStringsToJsons(object) {
1689
- if (object === null) {
1690
- return object;
1691
- }
1692
- if (Array.isArray(object)) {
1693
- return object.map(jsonStringsToJsons);
1694
- }
1695
- if (typeof object !== 'object') {
1696
- return object;
1697
- }
1698
- const newObject = { ...object };
1699
- for (const [key, value] of Object.entries(object)) {
1700
- if (typeof value === 'string' && isValidJsonString(value)) {
1701
- newObject[key] = JSON.parse(value);
1702
- }
1703
- else {
1704
- newObject[key] = jsonStringsToJsons(value);
1705
- }
1706
- }
1707
- return newObject;
1708
- }
1709
- /**
1710
- * TODO: Type the return type correctly
1711
- */
1712
-
1713
- /**
1714
- * This error indicates errors during the execution of the pipeline
1715
- *
1716
- * @public exported from `@promptbook/core`
1717
- */
1718
- class PipelineExecutionError extends Error {
1719
- constructor(message) {
1720
- // Added id parameter
1721
- super(message);
1722
- this.name = 'PipelineExecutionError';
1723
- // TODO: [🐙] DRY - Maybe $randomId
1724
- this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
1725
- Object.setPrototypeOf(this, PipelineExecutionError.prototype);
1726
- }
1727
- }
1728
- /**
1729
- * TODO: [🧠][🌂] Add id to all errors
1730
- */
1731
-
1732
1729
  /**
1733
1730
  * This error indicates problems parsing the format value
1734
1731
  *
@@ -1863,6 +1860,40 @@
1863
1860
  }
1864
1861
  }
1865
1862
 
1863
+ /**
1864
+ * Generates random token
1865
+ *
1866
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
1867
+ *
1868
+ * @private internal helper function
1869
+ * @returns secure random token
1870
+ */
1871
+ function $randomToken(randomness) {
1872
+ return crypto.randomBytes(randomness).toString('hex');
1873
+ }
1874
+ /**
1875
+ * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
1876
+ */
1877
+
1878
+ /**
1879
+ * This error indicates errors during the execution of the pipeline
1880
+ *
1881
+ * @public exported from `@promptbook/core`
1882
+ */
1883
+ class PipelineExecutionError extends Error {
1884
+ constructor(message) {
1885
+ // Added id parameter
1886
+ super(message);
1887
+ this.name = 'PipelineExecutionError';
1888
+ // TODO: [🐙] DRY - Maybe $randomId
1889
+ this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
1890
+ Object.setPrototypeOf(this, PipelineExecutionError.prototype);
1891
+ }
1892
+ }
1893
+ /**
1894
+ * TODO: [🧠][🌂] Add id to all errors
1895
+ */
1896
+
1866
1897
  /**
1867
1898
  * Error thrown when a fetch request fails
1868
1899
  *
@@ -1938,6 +1969,65 @@
1938
1969
  * Note: [💞] Ignore a discrepancy between file name and entity name
1939
1970
  */
1940
1971
 
1972
+ /**
1973
+ * Serializes an error into a [🚉] JSON-serializable object
1974
+ *
1975
+ * @public exported from `@promptbook/utils`
1976
+ */
1977
+ function serializeError(error) {
1978
+ const { name, message, stack } = error;
1979
+ const { id } = error;
1980
+ if (!Object.keys(ALL_ERRORS).includes(name)) {
1981
+ console.error(spaceTrim__default["default"]((block) => `
1982
+
1983
+ Cannot serialize error with name "${name}"
1984
+
1985
+ Authors of Promptbook probably forgot to add this error into the list of errors:
1986
+ https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
1987
+
1988
+
1989
+ ${block(stack || message)}
1990
+
1991
+ `));
1992
+ }
1993
+ return {
1994
+ name: name,
1995
+ message,
1996
+ stack,
1997
+ id, // Include id in the serialized object
1998
+ };
1999
+ }
2000
+
2001
+ /**
2002
+ * Recursively converts JSON strings to JSON objects
2003
+
2004
+ * @public exported from `@promptbook/utils`
2005
+ */
2006
+ function jsonStringsToJsons(object) {
2007
+ if (object === null) {
2008
+ return object;
2009
+ }
2010
+ if (Array.isArray(object)) {
2011
+ return object.map(jsonStringsToJsons);
2012
+ }
2013
+ if (typeof object !== 'object') {
2014
+ return object;
2015
+ }
2016
+ const newObject = { ...object };
2017
+ for (const [key, value] of Object.entries(object)) {
2018
+ if (typeof value === 'string' && isValidJsonString(value)) {
2019
+ newObject[key] = jsonParse(value);
2020
+ }
2021
+ else {
2022
+ newObject[key] = jsonStringsToJsons(value);
2023
+ }
2024
+ }
2025
+ return newObject;
2026
+ }
2027
+ /**
2028
+ * TODO: Type the return type correctly
2029
+ */
2030
+
1941
2031
  /**
1942
2032
  * Deserializes the error object
1943
2033
  *
@@ -2104,33 +2194,72 @@
2104
2194
  */
2105
2195
 
2106
2196
  /**
2107
- * Serializes an error into a [🚉] JSON-serializable object
2197
+ * Represents the uncertain value
2108
2198
  *
2109
- * @public exported from `@promptbook/utils`
2199
+ * @public exported from `@promptbook/core`
2200
+ */
2201
+ const ZERO_VALUE = $deepFreeze({ value: 0 });
2202
+ /**
2203
+ * Represents the uncertain value
2204
+ *
2205
+ * @public exported from `@promptbook/core`
2206
+ */
2207
+ const UNCERTAIN_ZERO_VALUE = $deepFreeze({ value: 0, isUncertain: true });
2208
+ /**
2209
+ * Represents the usage with no resources consumed
2210
+ *
2211
+ * @public exported from `@promptbook/core`
2212
+ */
2213
+ const ZERO_USAGE = $deepFreeze({
2214
+ price: ZERO_VALUE,
2215
+ input: {
2216
+ tokensCount: ZERO_VALUE,
2217
+ charactersCount: ZERO_VALUE,
2218
+ wordsCount: ZERO_VALUE,
2219
+ sentencesCount: ZERO_VALUE,
2220
+ linesCount: ZERO_VALUE,
2221
+ paragraphsCount: ZERO_VALUE,
2222
+ pagesCount: ZERO_VALUE,
2223
+ },
2224
+ output: {
2225
+ tokensCount: ZERO_VALUE,
2226
+ charactersCount: ZERO_VALUE,
2227
+ wordsCount: ZERO_VALUE,
2228
+ sentencesCount: ZERO_VALUE,
2229
+ linesCount: ZERO_VALUE,
2230
+ paragraphsCount: ZERO_VALUE,
2231
+ pagesCount: ZERO_VALUE,
2232
+ },
2233
+ });
2234
+ /**
2235
+ * Represents the usage with unknown resources consumed
2236
+ *
2237
+ * @public exported from `@promptbook/core`
2238
+ */
2239
+ const UNCERTAIN_USAGE = $deepFreeze({
2240
+ price: UNCERTAIN_ZERO_VALUE,
2241
+ input: {
2242
+ tokensCount: UNCERTAIN_ZERO_VALUE,
2243
+ charactersCount: UNCERTAIN_ZERO_VALUE,
2244
+ wordsCount: UNCERTAIN_ZERO_VALUE,
2245
+ sentencesCount: UNCERTAIN_ZERO_VALUE,
2246
+ linesCount: UNCERTAIN_ZERO_VALUE,
2247
+ paragraphsCount: UNCERTAIN_ZERO_VALUE,
2248
+ pagesCount: UNCERTAIN_ZERO_VALUE,
2249
+ },
2250
+ output: {
2251
+ tokensCount: UNCERTAIN_ZERO_VALUE,
2252
+ charactersCount: UNCERTAIN_ZERO_VALUE,
2253
+ wordsCount: UNCERTAIN_ZERO_VALUE,
2254
+ sentencesCount: UNCERTAIN_ZERO_VALUE,
2255
+ linesCount: UNCERTAIN_ZERO_VALUE,
2256
+ paragraphsCount: UNCERTAIN_ZERO_VALUE,
2257
+ pagesCount: UNCERTAIN_ZERO_VALUE,
2258
+ },
2259
+ });
2260
+ /**
2261
+ * Note: [💞] Ignore a discrepancy between file name and entity name
2110
2262
  */
2111
- function serializeError(error) {
2112
- const { name, message, stack } = error;
2113
- const { id } = error;
2114
- if (!Object.keys(ALL_ERRORS).includes(name)) {
2115
- console.error(spaceTrim__default["default"]((block) => `
2116
-
2117
- Cannot serialize error with name "${name}"
2118
-
2119
- Authors of Promptbook probably forgot to add this error into the list of errors:
2120
- https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
2121
-
2122
-
2123
- ${block(stack || message)}
2124
-
2125
- `));
2126
- }
2127
- return {
2128
- name: name,
2129
- message,
2130
- stack,
2131
- id, // Include id in the serialized object
2132
- };
2133
- }
2134
2263
 
2135
2264
  /**
2136
2265
  * Format either small or big number
@@ -2213,74 +2342,6 @@
2213
2342
  }
2214
2343
  }
2215
2344
 
2216
- /**
2217
- * Represents the uncertain value
2218
- *
2219
- * @public exported from `@promptbook/core`
2220
- */
2221
- const ZERO_VALUE = $deepFreeze({ value: 0 });
2222
- /**
2223
- * Represents the uncertain value
2224
- *
2225
- * @public exported from `@promptbook/core`
2226
- */
2227
- const UNCERTAIN_ZERO_VALUE = $deepFreeze({ value: 0, isUncertain: true });
2228
- /**
2229
- * Represents the usage with no resources consumed
2230
- *
2231
- * @public exported from `@promptbook/core`
2232
- */
2233
- const ZERO_USAGE = $deepFreeze({
2234
- price: ZERO_VALUE,
2235
- input: {
2236
- tokensCount: ZERO_VALUE,
2237
- charactersCount: ZERO_VALUE,
2238
- wordsCount: ZERO_VALUE,
2239
- sentencesCount: ZERO_VALUE,
2240
- linesCount: ZERO_VALUE,
2241
- paragraphsCount: ZERO_VALUE,
2242
- pagesCount: ZERO_VALUE,
2243
- },
2244
- output: {
2245
- tokensCount: ZERO_VALUE,
2246
- charactersCount: ZERO_VALUE,
2247
- wordsCount: ZERO_VALUE,
2248
- sentencesCount: ZERO_VALUE,
2249
- linesCount: ZERO_VALUE,
2250
- paragraphsCount: ZERO_VALUE,
2251
- pagesCount: ZERO_VALUE,
2252
- },
2253
- });
2254
- /**
2255
- * Represents the usage with unknown resources consumed
2256
- *
2257
- * @public exported from `@promptbook/core`
2258
- */
2259
- $deepFreeze({
2260
- price: UNCERTAIN_ZERO_VALUE,
2261
- input: {
2262
- tokensCount: UNCERTAIN_ZERO_VALUE,
2263
- charactersCount: UNCERTAIN_ZERO_VALUE,
2264
- wordsCount: UNCERTAIN_ZERO_VALUE,
2265
- sentencesCount: UNCERTAIN_ZERO_VALUE,
2266
- linesCount: UNCERTAIN_ZERO_VALUE,
2267
- paragraphsCount: UNCERTAIN_ZERO_VALUE,
2268
- pagesCount: UNCERTAIN_ZERO_VALUE,
2269
- },
2270
- output: {
2271
- tokensCount: UNCERTAIN_ZERO_VALUE,
2272
- charactersCount: UNCERTAIN_ZERO_VALUE,
2273
- wordsCount: UNCERTAIN_ZERO_VALUE,
2274
- sentencesCount: UNCERTAIN_ZERO_VALUE,
2275
- linesCount: UNCERTAIN_ZERO_VALUE,
2276
- paragraphsCount: UNCERTAIN_ZERO_VALUE,
2277
- pagesCount: UNCERTAIN_ZERO_VALUE,
2278
- },
2279
- });
2280
- /**
2281
- * Note: [💞] Ignore a discrepancy between file name and entity name
2282
- */
2283
-
2284
2345
  /**
2285
2346
  * Function `addUsage` will add multiple usages into one
2286
2347
  *
@@ -2489,7 +2550,7 @@
2489
2550
  }
2490
2551
 
2491
2552
  /**
2492
- * @@@
2553
+ * Contains configuration options for parsing and generating CSV files, such as delimiters and quoting rules.
2493
2554
  *
2494
2555
  * @public exported from `@promptbook/core`
2495
2556
  */
@@ -2498,11 +2559,29 @@
2498
2559
  // encoding: 'utf-8',
2499
2560
  });
2500
2561
 
2562
+ /**
2563
+ * Converts a CSV string into an object
2564
+ *
2565
+ * Note: This is wrapper around `papaparse.parse()` with better autohealing
2566
+ *
2567
+ * @private - for now until `@promptbook/csv` is released
2568
+ */
2569
+ function csvParse(value /* <- TODO: string_csv */, settings, schema /* <- TODO: Make CSV Schemas */) {
2570
+ settings = { ...settings, ...MANDATORY_CSV_SETTINGS };
2571
+ // Note: Autoheal invalid '\n' characters
2572
+ if (settings.newline && !settings.newline.includes('\r') && value.includes('\r')) {
2573
+ console.warn('CSV string contains carriage return characters, but in the CSV settings the `newline` setting does not include them. Autohealing the CSV string.');
2574
+ value = value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
2575
+ }
2576
+ const csv = papaparse.parse(value, settings);
2577
+ return csv;
2578
+ }
2579
+
2501
2580
  /**
2502
2581
  * Function to check if a string is valid CSV
2503
2582
  *
2504
2583
  * @param value The string to check
2505
- * @returns True if the string is a valid CSV string, false otherwise
2584
+ * @returns `true` if the string is a valid CSV string, false otherwise
2506
2585
  *
2507
2586
  * @public exported from `@promptbook/utils`
2508
2587
  */
@@ -2526,7 +2605,7 @@
2526
2605
  * @public exported from `@promptbook/core`
2527
2606
  * <- TODO: [🏢] Export from package `@promptbook/csv`
2528
2607
  */
2529
- const CsvFormatDefinition = {
2608
+ const CsvFormatParser = {
2530
2609
  formatName: 'CSV',
2531
2610
  aliases: ['SPREADSHEET', 'TABLE'],
2532
2611
  isValid(value, settings, schema) {
@@ -2538,12 +2617,12 @@
2538
2617
  heal(value, settings, schema) {
2539
2618
  throw new Error('Not implemented');
2540
2619
  },
2541
- subvalueDefinitions: [
2620
+ subvalueParsers: [
2542
2621
  {
2543
2622
  subvalueName: 'ROW',
2544
- async mapValues(value, outputParameterName, settings, mapCallback) {
2545
- // TODO: [👨🏾‍🤝‍👨🏼] DRY csv parsing
2546
- const csv = papaparse.parse(value, { ...settings, ...MANDATORY_CSV_SETTINGS });
2623
+ async mapValues(options) {
2624
+ const { value, outputParameterName, settings, mapCallback, onProgress } = options;
2625
+ const csv = csvParse(value, settings);
2547
2626
  if (csv.errors.length !== 0) {
2548
2627
  throw new CsvFormatError(spaceTrim__default["default"]((block) => `
2549
2628
  CSV parsing error
@@ -2558,23 +2637,37 @@
2558
2637
  ${block(value)}
2559
2638
  `));
2560
2639
  }
2561
- const mappedData = await Promise.all(csv.data.map(async (row, index) => {
2640
+ const mappedData = [];
2641
+ const length = csv.data.length;
2642
+ for (let index = 0; index < length; index++) {
2643
+ const row = csv.data[index];
2562
2644
  if (row[outputParameterName]) {
2563
2645
  throw new CsvFormatError(`Can not overwrite existing column "${outputParameterName}" in CSV row`);
2564
2646
  }
2565
- return {
2647
+ const mappedRow = {
2566
2648
  ...row,
2567
- [outputParameterName]: await mapCallback(row, index),
2649
+ [outputParameterName]: await mapCallback(row, index, length),
2568
2650
  };
2569
- }));
2651
+ mappedData.push(mappedRow);
2652
+ if (onProgress) {
2653
+ // Note: Report the CSV with all rows mapped so far
2654
+ /*
2655
+ // TODO: [🛕] Report progress with all the rows including the pending ones
2656
+ const progressData = mappedData.map((row, i) =>
2657
+ i > index ? { ...row, [outputParameterName]: PENDING_VALUE_PLACEHOLDER } : row,
2658
+ );
2659
+ */
2660
+ await onProgress(papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
2661
+ }
2662
+ }
2570
2663
  return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
2571
2664
  },
2572
2665
  },
2573
2666
  {
2574
2667
  subvalueName: 'CELL',
2575
- async mapValues(value, outputParameterName, settings, mapCallback) {
2576
- // TODO: [👨🏾‍🤝‍👨🏼] DRY csv parsing
2577
- const csv = papaparse.parse(value, { ...settings, ...MANDATORY_CSV_SETTINGS });
2668
+ async mapValues(options) {
2669
+ const { value, settings, mapCallback, onProgress } = options;
2670
+ const csv = csvParse(value, settings);
2578
2671
  if (csv.errors.length !== 0) {
2579
2672
  throw new CsvFormatError(spaceTrim__default["default"]((block) => `
2580
2673
  CSV parsing error
@@ -2590,9 +2683,9 @@
2590
2683
  `));
2591
2684
  }
2592
2685
  const mappedData = await Promise.all(csv.data.map(async (row, rowIndex) => {
2593
- return /* not await */ Promise.all(Object.entries(row).map(async ([key, value], columnIndex) => {
2686
+ return /* not await */ Promise.all(Object.entries(row).map(async ([key, value], columnIndex, array) => {
2594
2687
  const index = rowIndex * Object.keys(row).length + columnIndex;
2595
- return /* not await */ mapCallback({ [key]: value }, index);
2688
+ return /* not await */ mapCallback({ [key]: value }, index, array.length);
2596
2689
  }));
2597
2690
  }));
2598
2691
  return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
@@ -2601,10 +2694,10 @@
2601
2694
  ],
2602
2695
  };
2603
2696
  /**
2604
- * TODO: [🍓] In `CsvFormatDefinition` implement simple `isValid`
2605
- * TODO: [🍓] In `CsvFormatDefinition` implement partial `canBeValid`
2606
- * TODO: [🍓] In `CsvFormatDefinition` implement `heal
2607
- * TODO: [🍓] In `CsvFormatDefinition` implement `subvalueDefinitions`
2697
+ * TODO: [🍓] In `CsvFormatParser` implement simple `isValid`
2698
+ * TODO: [🍓] In `CsvFormatParser` implement partial `canBeValid`
2699
+ * TODO: [🍓] In `CsvFormatParser` implement `heal
2700
+ * TODO: [🍓] In `CsvFormatParser` implement `subvalueParsers`
2608
2701
  * TODO: [🏢] Allow to expect something inside CSV objects and other formats
2609
2702
  */
2610
2703
 
@@ -2613,7 +2706,7 @@
2613
2706
  *
2614
2707
  * @private still in development [🏢]
2615
2708
  */
2616
- const JsonFormatDefinition = {
2709
+ const JsonFormatParser = {
2617
2710
  formatName: 'JSON',
2618
2711
  mimeType: 'application/json',
2619
2712
  isValid(value, settings, schema) {
@@ -2625,28 +2718,28 @@
2625
2718
  heal(value, settings, schema) {
2626
2719
  throw new Error('Not implemented');
2627
2720
  },
2628
- subvalueDefinitions: [],
2721
+ subvalueParsers: [],
2629
2722
  };
2630
2723
  /**
2631
2724
  * TODO: [🧠] Maybe propper instance of object
2632
2725
  * TODO: [0] Make string_serialized_json
2633
2726
  * TODO: [1] Make type for JSON Settings and Schema
2634
2727
  * TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
2635
- * TODO: [🍓] In `JsonFormatDefinition` implement simple `isValid`
2636
- * TODO: [🍓] In `JsonFormatDefinition` implement partial `canBeValid`
2637
- * TODO: [🍓] In `JsonFormatDefinition` implement `heal
2638
- * TODO: [🍓] In `JsonFormatDefinition` implement `subvalueDefinitions`
2728
+ * TODO: [🍓] In `JsonFormatParser` implement simple `isValid`
2729
+ * TODO: [🍓] In `JsonFormatParser` implement partial `canBeValid`
2730
+ * TODO: [🍓] In `JsonFormatParser` implement `heal
2731
+ * TODO: [🍓] In `JsonFormatParser` implement `subvalueParsers`
2639
2732
  * TODO: [🏢] Allow to expect something inside JSON objects and other formats
2640
2733
  */
2641
2734
 
2642
2735
  /**
2643
2736
  * Definition for any text - this will be always valid
2644
2737
  *
2645
- * Note: This is not useful for validation, but for splitting and mapping with `subvalueDefinitions`
2738
+ * Note: This is not useful for validation, but for splitting and mapping with `subvalueParsers`
2646
2739
  *
2647
2740
  * @public exported from `@promptbook/core`
2648
2741
  */
2649
- const TextFormatDefinition = {
2742
+ const TextFormatParser = {
2650
2743
  formatName: 'TEXT',
2651
2744
  isValid(value) {
2652
2745
  return typeof value === 'string';
@@ -2655,19 +2748,20 @@
2655
2748
  return typeof partialValue === 'string';
2656
2749
  },
2657
2750
  heal() {
2658
- throw new UnexpectedError('It does not make sense to call `TextFormatDefinition.heal`');
2751
+ throw new UnexpectedError('It does not make sense to call `TextFormatParser.heal`');
2659
2752
  },
2660
- subvalueDefinitions: [
2753
+ subvalueParsers: [
2661
2754
  {
2662
2755
  subvalueName: 'LINE',
2663
- async mapValues(value, outputParameterName, settings, mapCallback) {
2756
+ async mapValues(options) {
2757
+ const { value, mapCallback, onProgress } = options;
2664
2758
  const lines = value.split('\n');
2665
- const mappedLines = await Promise.all(lines.map((lineContent, lineNumber) =>
2759
+ const mappedLines = await Promise.all(lines.map((lineContent, lineNumber, array) =>
2666
2760
  // TODO: [🧠] Maybe option to skip empty line
2667
2761
  /* not await */ mapCallback({
2668
2762
  lineContent,
2669
2763
  // TODO: [🧠] Maybe also put here `lineNumber`
2670
- }, lineNumber)));
2764
+ }, lineNumber, array.length)));
2671
2765
  return mappedLines.join('\n');
2672
2766
  },
2673
2767
  },
@@ -2677,10 +2771,10 @@
2677
2771
  /**
2678
2772
  * TODO: [1] Make type for XML Text and Schema
2679
2773
  * TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages available as subvalues
2680
- * TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
2681
- * TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
2682
- * TODO: [🍓] In `TextFormatDefinition` implement `heal
2683
- * TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
2774
+ * TODO: [🍓] In `TextFormatParser` implement simple `isValid`
2775
+ * TODO: [🍓] In `TextFormatParser` implement partial `canBeValid`
2776
+ * TODO: [🍓] In `TextFormatParser` implement `heal
2777
+ * TODO: [🍓] In `TextFormatParser` implement `subvalueParsers`
2684
2778
  * TODO: [🏢] Allow to expect something inside each item of list and other formats
2685
2779
  */
2686
2780
 
@@ -2688,7 +2782,7 @@
2688
2782
  * Function to check if a string is valid XML
2689
2783
  *
2690
2784
  * @param value
2691
- * @returns True if the string is a valid XML string, false otherwise
2785
+ * @returns `true` if the string is a valid XML string, false otherwise
2692
2786
  *
2693
2787
  * @public exported from `@promptbook/utils`
2694
2788
  */
@@ -2713,7 +2807,7 @@
2713
2807
  *
2714
2808
  * @private still in development [🏢]
2715
2809
  */
2716
- const XmlFormatDefinition = {
2810
+ const XmlFormatParser = {
2717
2811
  formatName: 'XML',
2718
2812
  mimeType: 'application/xml',
2719
2813
  isValid(value, settings, schema) {
@@ -2725,17 +2819,17 @@
2725
2819
  heal(value, settings, schema) {
2726
2820
  throw new Error('Not implemented');
2727
2821
  },
2728
- subvalueDefinitions: [],
2822
+ subvalueParsers: [],
2729
2823
  };
2730
2824
  /**
2731
2825
  * TODO: [🧠] Maybe propper instance of object
2732
2826
  * TODO: [0] Make string_serialized_xml
2733
2827
  * TODO: [1] Make type for XML Settings and Schema
2734
2828
  * TODO: [🧠] What to use for validating XMLs - XSD,...
2735
- * TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
2736
- * TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
2737
- * TODO: [🍓] In `XmlFormatDefinition` implement `heal
2738
- * TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
2829
+ * TODO: [🍓] In `XmlFormatParser` implement simple `isValid`
2830
+ * TODO: [🍓] In `XmlFormatParser` implement partial `canBeValid`
2831
+ * TODO: [🍓] In `XmlFormatParser` implement `heal
2832
+ * TODO: [🍓] In `XmlFormatParser` implement `subvalueParsers`
2739
2833
  * TODO: [🏢] Allow to expect something inside XML and other formats
2740
2834
  */
2741
2835
 
@@ -2744,24 +2838,19 @@
2744
2838
  *
2745
2839
  * @private internal index of `...` <- TODO [🏢]
2746
2840
  */
2747
- const FORMAT_DEFINITIONS = [
2748
- JsonFormatDefinition,
2749
- XmlFormatDefinition,
2750
- TextFormatDefinition,
2751
- CsvFormatDefinition,
2752
- ];
2841
+ const FORMAT_DEFINITIONS = [JsonFormatParser, XmlFormatParser, TextFormatParser, CsvFormatParser];
2753
2842
  /**
2754
2843
  * Note: [💞] Ignore a discrepancy between file name and entity name
2755
2844
  */
2756
2845
 
2757
2846
  /**
2758
- * Maps available parameters to expected parameters
2847
+ * Maps available parameters to expected parameters for a pipeline task.
2759
2848
  *
2760
2849
  * The strategy is:
2761
- * 1) @@@
2762
- * 2) @@@
2850
+ * 1) First, match parameters by name where both available and expected.
2851
+ * 2) Then, if there are unmatched expected and available parameters, map them by order.
2763
2852
  *
2764
- * @throws {PipelineExecutionError} @@@
2853
+ * @throws {PipelineExecutionError} If the number of unmatched expected and available parameters does not match, or mapping is ambiguous.
2765
2854
  * @private within the repository used in `createPipelineExecutor`
2766
2855
  */
2767
2856
  function mapAvailableToExpectedParameters(options) {
@@ -2784,7 +2873,7 @@
2784
2873
  else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) ;
2785
2874
  }
2786
2875
  if (expectedParameterNames.size === 0) {
2787
- // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
2876
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent accidental modifications after mapping
2788
2877
  Object.freeze(mappedParameters);
2789
2878
  return mappedParameters;
2790
2879
  }
@@ -2815,7 +2904,7 @@
2815
2904
  for (let i = 0; i < expectedParameterNames.size; i++) {
2816
2905
  mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
2817
2906
  }
2818
- // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
2907
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent accidental modifications after mapping
2819
2908
  Object.freeze(mappedParameters);
2820
2909
  return mappedParameters;
2821
2910
  }
@@ -3111,7 +3200,7 @@
3111
3200
  }
3112
3201
  /**
3113
3202
  * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
3114
- * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
3203
+ * TODO: [🏢] Make this logic part of `JsonFormatParser` or `isValidJsonString`
3115
3204
  */
3116
3205
 
3117
3206
  /**
@@ -3190,10 +3279,12 @@
3190
3279
  throw new PipelineExecutionError('Parameter is already opened or not closed');
3191
3280
  }
3192
3281
  if (parameters[parameterName] === undefined) {
3282
+ console.log('!!! templateParameters 1', { parameterName, template, parameters });
3193
3283
  throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
3194
3284
  }
3195
3285
  let parameterValue = parameters[parameterName];
3196
3286
  if (parameterValue === undefined) {
3287
+ console.log('!!! templateParameters 2', { parameterName, template, parameters });
3197
3288
  throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
3198
3289
  }
3199
3290
  parameterValue = valueToString(parameterValue);
@@ -3564,10 +3655,10 @@
3564
3655
  */
3565
3656
 
3566
3657
  /**
3567
- * @@@
3658
+ * Removes diacritic marks (accents) from characters in a string.
3568
3659
  *
3569
- * @param input @@@
3570
- * @returns @@@
3660
+ * @param input The string containing diacritics to be normalized.
3661
+ * @returns The string with diacritics removed or normalized.
3571
3662
  * @public exported from `@promptbook/utils`
3572
3663
  */
3573
3664
  function removeDiacritics(input) {
@@ -3610,7 +3701,7 @@
3610
3701
  PAGES: countPages,
3611
3702
  };
3612
3703
  /**
3613
- * TODO: [🧠][🤠] This should be probbably as part of `TextFormatDefinition`
3704
+ * TODO: [🧠][🤠] This should be probbably as part of `TextFormatParser`
3614
3705
  * Note: [💞] Ignore a discrepancy between file name and entity name
3615
3706
  */
3616
3707
 
@@ -3638,13 +3729,17 @@
3638
3729
  }
3639
3730
  /**
3640
3731
  * TODO: [💝] Unite object for expecting amount and format
3641
- * TODO: [🧠][🤠] This should be part of `TextFormatDefinition`
3732
+ * TODO: [🧠][🤠] This should be part of `TextFormatParser`
3642
3733
  * Note: [💝] and [🤠] are interconnected together
3643
3734
  */
3644
3735
 
3645
3736
  /**
3646
- * @@@
3737
+ * Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
3738
+ * (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
3739
+ * Throws errors if execution fails after all attempts.
3647
3740
  *
3741
+ * @param options - The options for execution, including task, parameters, pipeline, and configuration.
3742
+ * @returns The result string of the executed task.
3648
3743
  * @private internal utility of `createPipelineExecutor`
3649
3744
  */
3650
3745
  async function executeAttempts(options) {
@@ -3866,7 +3961,7 @@
3866
3961
  if (task.format) {
3867
3962
  if (task.format === 'JSON') {
3868
3963
  if (!isValidJsonString($ongoingTaskResult.$resultString || '')) {
3869
- // TODO: [🏢] Do more universally via `FormatDefinition`
3964
+ // TODO: [🏢] Do more universally via `FormatParser`
3870
3965
  try {
3871
3966
  $ongoingTaskResult.$resultString = extractJsonBlock($ongoingTaskResult.$resultString || '');
3872
3967
  }
@@ -3968,12 +4063,16 @@
3968
4063
  */
3969
4064
 
3970
4065
  /**
3971
- * @@@
4066
+ * Executes a pipeline task that requires mapping or iterating over subvalues of a parameter (such as rows in a CSV).
4067
+ * Handles format and subformat resolution, error handling, and progress reporting.
4068
+ *
4069
+ * @param options - Options for execution, including task details and progress callback.
4070
+ * @returns The result of the subvalue mapping or execution attempts.
3972
4071
  *
3973
4072
  * @private internal utility of `createPipelineExecutor`
3974
4073
  */
3975
4074
  async function executeFormatSubvalues(options) {
3976
- const { task, jokerParameterNames, parameters, priority, csvSettings, pipelineIdentification } = options;
4075
+ const { task, jokerParameterNames, parameters, priority, csvSettings, onProgress, pipelineIdentification } = options;
3977
4076
  if (task.foreach === undefined) {
3978
4077
  return /* not await */ executeAttempts(options);
3979
4078
  }
@@ -4004,16 +4103,16 @@
4004
4103
  ${block(pipelineIdentification)}
4005
4104
  `));
4006
4105
  }
4007
- const subvalueDefinition = formatDefinition.subvalueDefinitions.find((subvalueDefinition) => [subvalueDefinition.subvalueName, ...(subvalueDefinition.aliases || [])].includes(task.foreach.subformatName));
4008
- if (subvalueDefinition === undefined) {
4106
+ const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(task.foreach.subformatName));
4107
+ if (subvalueParser === undefined) {
4009
4108
  throw new UnexpectedError(
4010
4109
  // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4011
4110
  spaceTrim__default["default"]((block) => `
4012
4111
  Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
4013
4112
 
4014
4113
  Available subformat names for format "${formatDefinition.formatName}":
4015
- ${block(formatDefinition.subvalueDefinitions
4016
- .map((subvalueDefinition) => subvalueDefinition.subvalueName)
4114
+ ${block(formatDefinition.subvalueParsers
4115
+ .map((subvalueParser) => subvalueParser.subvalueName)
4017
4116
  .map((subvalueName) => `- ${subvalueName}`)
4018
4117
  .join('\n'))}
4019
4118
 
@@ -4027,53 +4126,83 @@
4027
4126
  formatSettings = csvSettings;
4028
4127
  // <- TODO: [🤹‍♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
4029
4128
  }
4030
- const resultString = await subvalueDefinition.mapValues(parameterValue, task.foreach.outputSubparameterName, formatSettings, async (subparameters, index) => {
4031
- let mappedParameters;
4032
- // TODO: [🤹‍♂️][🪂] Limit to N concurrent executions
4033
- // TODO: When done [🐚] Report progress also for each subvalue here
4034
- try {
4035
- mappedParameters = mapAvailableToExpectedParameters({
4036
- expectedParameters: Object.fromEntries(task.foreach.inputSubparameterNames.map((subparameterName) => [subparameterName, null])),
4037
- availableParameters: subparameters,
4038
- });
4039
- }
4040
- catch (error) {
4041
- if (!(error instanceof PipelineExecutionError)) {
4042
- throw error;
4129
+ const resultString = await subvalueParser.mapValues({
4130
+ value: parameterValue,
4131
+ outputParameterName: task.foreach.outputSubparameterName,
4132
+ settings: formatSettings,
4133
+ onProgress(partialResultString) {
4134
+ return onProgress(Object.freeze({
4135
+ [task.resultingParameterName]: partialResultString,
4136
+ }));
4137
+ },
4138
+ async mapCallback(subparameters, index, length) {
4139
+ let mappedParameters;
4140
+ try {
4141
+ mappedParameters = mapAvailableToExpectedParameters({
4142
+ expectedParameters: Object.fromEntries(task.foreach.inputSubparameterNames.map((subparameterName) => [subparameterName, null])),
4143
+ availableParameters: subparameters,
4144
+ });
4043
4145
  }
4044
- throw new PipelineExecutionError(spaceTrim__default["default"]((block) => `
4045
- ${error.message}
4146
+ catch (error) {
4147
+ if (!(error instanceof PipelineExecutionError)) {
4148
+ throw error;
4149
+ }
4150
+ const highLevelError = new PipelineExecutionError(spaceTrim__default["default"]((block) => `
4151
+ ${error.message}
4046
4152
 
4047
- This is error in FOREACH command
4048
- You have probbably passed wrong data to pipeline or wrong data was generated which are processed by FOREACH command
4153
+ This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
4154
+ You have probbably passed wrong data to pipeline or wrong data was generated which are processed by FOREACH command
4049
4155
 
4050
- ${block(pipelineIdentification)}
4051
- Subparameter index: ${index}
4052
- `));
4053
- }
4054
- const allSubparameters = {
4055
- ...parameters,
4056
- ...mappedParameters,
4057
- };
4058
- // Note: [👨‍👨‍👧] Now we can freeze `subparameters` because we are sure that all and only used parameters are defined and are not going to be changed
4059
- Object.freeze(allSubparameters);
4060
- const subresultString = await executeAttempts({
4061
- ...options,
4062
- priority: priority + index,
4063
- parameters: allSubparameters,
4064
- pipelineIdentification: spaceTrim__default["default"]((block) => `
4065
- ${block(pipelineIdentification)}
4066
- Subparameter index: ${index}
4067
- `),
4068
- });
4069
- return subresultString;
4156
+ ${block(pipelineIdentification)}
4157
+ `));
4158
+ if (length > BIG_DATASET_TRESHOLD) {
4159
+ console.error(highLevelError);
4160
+ return FAILED_VALUE_PLACEHOLDER;
4161
+ }
4162
+ throw highLevelError;
4163
+ }
4164
+ const allSubparameters = {
4165
+ ...parameters,
4166
+ ...mappedParameters,
4167
+ };
4168
+ Object.freeze(allSubparameters);
4169
+ try {
4170
+ const subresultString = await executeAttempts({
4171
+ ...options,
4172
+ priority: priority + index,
4173
+ parameters: allSubparameters,
4174
+ pipelineIdentification: spaceTrim__default["default"]((block) => `
4175
+ ${block(pipelineIdentification)}
4176
+ Subparameter index: ${index}
4177
+ `),
4178
+ });
4179
+ return subresultString;
4180
+ }
4181
+ catch (error) {
4182
+ if (length > BIG_DATASET_TRESHOLD) {
4183
+ console.error(spaceTrim__default["default"]((block) => `
4184
+ ${error.message}
4185
+
4186
+ This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
4187
+
4188
+ ${block(pipelineIdentification)}
4189
+ `));
4190
+ return FAILED_VALUE_PLACEHOLDER;
4191
+ }
4192
+ throw error;
4193
+ }
4194
+ },
4070
4195
  });
4071
4196
  return resultString;
4072
4197
  }
4073
4198
 
4074
4199
  /**
4075
- * @@@
4200
+ * Returns the context for a given task, typically used to provide additional information or variables
4201
+ * required for the execution of the task within a pipeline. The context is returned as a string value
4202
+ * that may include markdown formatting.
4076
4203
  *
4204
+ * @param task - The task for which the context is being generated. This should be a deeply immutable TaskJson object.
4205
+ * @returns The context as a string, formatted as markdown and parameter value.
4077
4206
  * @private internal utility of `createPipelineExecutor`
4078
4207
  */
4079
4208
  async function getContextForTask(task) {
@@ -4081,7 +4210,7 @@
4081
4210
  }
4082
4211
 
4083
4212
  /**
4084
- * @@@
4213
+ * Retrieves example values or templates for a given task, used to guide or validate pipeline execution.
4085
4214
  *
4086
4215
  * @private internal utility of `createPipelineExecutor`
4087
4216
  */
@@ -4090,25 +4219,127 @@
4090
4219
  }
4091
4220
 
4092
4221
  /**
4093
- * @@@
4222
+ * Computes the cosine similarity between two embedding vectors
4223
+ *
4224
+ * Note: This is helping function for RAG (retrieval-augmented generation)
4225
+ *
4226
+ * @param embeddingVector1
4227
+ * @param embeddingVector2
4228
+ * @returns Cosine similarity between the two vectors
4229
+ *
4230
+ * @public exported from `@promptbook/core`
4231
+ */
4232
+ function computeCosineSimilarity(embeddingVector1, embeddingVector2) {
4233
+ if (embeddingVector1.length !== embeddingVector2.length) {
4234
+ throw new TypeError('Embedding vectors must have the same length');
4235
+ }
4236
+ const dotProduct = embeddingVector1.reduce((sum, value, index) => sum + value * embeddingVector2[index], 0);
4237
+ const magnitude1 = Math.sqrt(embeddingVector1.reduce((sum, value) => sum + value * value, 0));
4238
+ const magnitude2 = Math.sqrt(embeddingVector2.reduce((sum, value) => sum + value * value, 0));
4239
+ return 1 - dotProduct / (magnitude1 * magnitude2);
4240
+ }
4241
+
4242
+ /**
4243
+ *
4244
+ * @param knowledgePieces
4245
+ * @returns
4246
+ *
4247
+ * @private internal utility of `createPipelineExecutor`
4248
+ */
4249
+ function knowledgePiecesToString(knowledgePieces) {
4250
+ return knowledgePieces
4251
+ .map((knowledgePiece) => {
4252
+ const { content } = knowledgePiece;
4253
+ return `- ${content}`;
4254
+ })
4255
+ .join('\n');
4256
+ // <- TODO: [🧠] Some smarter aggregation of knowledge pieces, single-line vs multi-line vs mixed
4257
+ }
4258
+
4259
+ /**
4260
+ * Retrieves the most relevant knowledge pieces for a given task using embedding-based similarity search.
4261
+ * This is where retrieval-augmented generation (RAG) is performed to enhance the task with external knowledge.
4094
4262
  *
4095
4263
  * @private internal utility of `createPipelineExecutor`
4096
4264
  */
4097
4265
  async function getKnowledgeForTask(options) {
4098
- const { preparedPipeline, task } = options;
4099
- return preparedPipeline.knowledgePieces.map(({ content }) => `- ${content}`).join('\n');
4100
- // <- TODO: [🧠] Some smart aggregation of knowledge pieces, single-line vs multi-line vs mixed
4266
+ const { tools, preparedPipeline, task, parameters } = options;
4267
+ const firstKnowlegePiece = preparedPipeline.knowledgePieces[0];
4268
+ const firstKnowlegeIndex = firstKnowlegePiece === null || firstKnowlegePiece === void 0 ? void 0 : firstKnowlegePiece.index[0];
4269
+ // <- TODO: Do not use just first knowledge piece and first index to determine embedding model, use also keyword search
4270
+ if (firstKnowlegePiece === undefined || firstKnowlegeIndex === undefined) {
4271
+ return ''; // <- Note: Np knowledge present, return empty string
4272
+ }
4273
+ try {
4274
+ // TODO: [🚐] Make arrayable LLMs -> single LLM DRY
4275
+ const _llms = arrayableToArray(tools.llm);
4276
+ const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
4277
+ const taskEmbeddingPrompt = {
4278
+ title: 'Knowledge Search',
4279
+ modelRequirements: {
4280
+ modelVariant: 'EMBEDDING',
4281
+ modelName: firstKnowlegeIndex.modelName,
4282
+ },
4283
+ content: task.content,
4284
+ parameters,
4285
+ };
4286
+ const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
4287
+ const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
4288
+ const { index } = knowledgePiece;
4289
+ const knowledgePieceIndex = index.find((i) => i.modelName === firstKnowlegeIndex.modelName);
4290
+ // <- TODO: Do not use just first knowledge piece and first index to determine embedding model
4291
+ if (knowledgePieceIndex === undefined) {
4292
+ return {
4293
+ content: knowledgePiece.content,
4294
+ relevance: 0,
4295
+ };
4296
+ }
4297
+ const relevance = computeCosineSimilarity(knowledgePieceIndex.position, taskEmbeddingResult.content);
4298
+ return {
4299
+ content: knowledgePiece.content,
4300
+ relevance,
4301
+ };
4302
+ });
4303
+ const knowledgePiecesSorted = knowledgePiecesWithRelevance.sort((a, b) => a.relevance - b.relevance);
4304
+ const knowledgePiecesLimited = knowledgePiecesSorted.slice(0, 5);
4305
+ console.log('!!! Embedding', {
4306
+ task,
4307
+ taskEmbeddingPrompt,
4308
+ taskEmbeddingResult,
4309
+ firstKnowlegePiece,
4310
+ firstKnowlegeIndex,
4311
+ knowledgePiecesWithRelevance,
4312
+ knowledgePiecesSorted,
4313
+ knowledgePiecesLimited,
4314
+ });
4315
+ return knowledgePiecesToString(knowledgePiecesLimited);
4316
+ }
4317
+ catch (error) {
4318
+ assertsError(error);
4319
+ console.error('Error in `getKnowledgeForTask`', error);
4320
+ // Note: If the LLM fails, just return all knowledge pieces
4321
+ return knowledgePiecesToString(preparedPipeline.knowledgePieces);
4322
+ }
4101
4323
  }
4324
+ /**
4325
+ * TODO: !!!! Verify if this is working
4326
+ * TODO: [♨] Implement Better - use keyword search
4327
+ * TODO: [♨] Examples of values
4328
+ */
4102
4329
 
4103
4330
  /**
4104
- * @@@
4331
+ * Retrieves all reserved parameters for a given pipeline task, including context, knowledge, examples, and metadata.
4332
+ * Ensures all reserved parameters are defined and throws if any are missing.
4333
+ *
4334
+ * @param options - Options including tools, pipeline, task, and context.
4335
+ * @returns An object containing all reserved parameters for the task.
4105
4336
  *
4106
4337
  * @private internal utility of `createPipelineExecutor`
4107
4338
  */
4108
4339
  async function getReservedParametersForTask(options) {
4109
- const { preparedPipeline, task, pipelineIdentification } = options;
4340
+ const { tools, preparedPipeline, task, parameters, pipelineIdentification } = options;
4110
4341
  const context = await getContextForTask(); // <- [🏍]
4111
- const knowledge = await getKnowledgeForTask({ preparedPipeline, task });
4342
+ const knowledge = await getKnowledgeForTask({ tools, preparedPipeline, task, parameters });
4112
4343
  const examples = await getExamplesForTask();
4113
4344
  const currentDate = new Date().toISOString(); // <- TODO: [🧠][💩] Better
4114
4345
  const modelName = RESERVED_PARAMETER_MISSING_VALUE;
@@ -4134,23 +4365,21 @@
4134
4365
  }
4135
4366
 
4136
4367
  /**
4137
- * @@@
4368
+ * Executes a single task within a pipeline, handling parameter validation, error checking, and progress reporting.
4369
+ *
4370
+ * @param options - Options for execution, including the task, pipeline, parameters, and callbacks.
4371
+ * @returns The output parameters produced by the task.
4138
4372
  *
4139
4373
  * @private internal utility of `createPipelineExecutor`
4140
4374
  */
4141
4375
  async function executeTask(options) {
4142
4376
  const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSupressed, } = options;
4143
4377
  const priority = preparedPipeline.tasks.length - preparedPipeline.tasks.indexOf(currentTask);
4144
- await onProgress({
4145
- outputParameters: {
4146
- [currentTask.resultingParameterName]: '', // <- TODO: [🧠] What is the best value here?
4147
- },
4148
- });
4149
4378
  // Note: Check consistency of used and dependent parameters which was also done in `validatePipeline`, but it’s good to doublecheck
4150
4379
  const usedParameterNames = extractParameterNamesFromTask(currentTask);
4151
4380
  const dependentParameterNames = new Set(currentTask.dependentParameterNames);
4152
4381
  // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
4153
- if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
4382
+ if (difference(union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)), new Set(RESERVED_PARAMETER_NAMES)).size !== 0) {
4154
4383
  throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
4155
4384
  Dependent parameters are not consistent with used parameters:
4156
4385
 
@@ -4170,9 +4399,11 @@
4170
4399
  }
4171
4400
  const definedParameters = Object.freeze({
4172
4401
  ...(await getReservedParametersForTask({
4402
+ tools,
4173
4403
  preparedPipeline,
4174
4404
  task: currentTask,
4175
4405
  pipelineIdentification,
4406
+ parameters: parametersToPass,
4176
4407
  })),
4177
4408
  ...parametersToPass,
4178
4409
  });
@@ -4218,6 +4449,7 @@
4218
4449
  preparedPipeline,
4219
4450
  tools,
4220
4451
  $executionReport,
4452
+ onProgress,
4221
4453
  pipelineIdentification,
4222
4454
  maxExecutionAttempts,
4223
4455
  maxParallelCount,
@@ -4245,7 +4477,8 @@
4245
4477
  */
4246
4478
 
4247
4479
  /**
4248
- * @@@
4480
+ * Filters and returns only the output parameters from the provided pipeline execution options.
4481
+ * Adds warnings for any expected output parameters that are missing.
4249
4482
  *
4250
4483
  * @private internal utility of `createPipelineExecutor`
4251
4484
  */
@@ -4270,9 +4503,12 @@
4270
4503
  }
4271
4504
 
4272
4505
  /**
4273
- * @@@
4506
+ * Executes an entire pipeline, resolving tasks in dependency order, handling errors, and reporting progress.
4274
4507
  *
4275
- * Note: This is not a `PipelineExecutor` (which is binded with one exact pipeline), but a utility function of `createPipelineExecutor` which creates `PipelineExecutor`
4508
+ * Note: This is not a `PipelineExecutor` (which is bound to a single pipeline), but a utility function used by `createPipelineExecutor` to create a `PipelineExecutor`.
4509
+ *
4510
+ * @param options - Options for execution, including input parameters, pipeline, and callbacks.
4511
+ * @returns The result of the pipeline execution, including output parameters, errors, and usage statistics.
4276
4512
  *
4277
4513
  * @private internal utility of `createPipelineExecutor`
4278
4514
  */
@@ -4595,6 +4831,22 @@
4595
4831
  cacheDirname,
4596
4832
  intermediateFilesStrategy,
4597
4833
  isAutoInstalled,
4834
+ }).catch((error) => {
4835
+ assertsError(error);
4836
+ return exportJson({
4837
+ name: 'pipelineExecutorResult',
4838
+ message: `Unuccessful PipelineExecutorResult, last catch`,
4839
+ order: [],
4840
+ value: {
4841
+ isSuccessful: false,
4842
+ errors: [serializeError(error)],
4843
+ warnings: [],
4844
+ usage: UNCERTAIN_USAGE,
4845
+ executionReport: null,
4846
+ outputParameters: {},
4847
+ preparedPipeline,
4848
+ },
4849
+ });
4598
4850
  });
4599
4851
  };
4600
4852
  const pipelineExecutor = (inputParameters) => createTask({
@@ -4726,27 +4978,48 @@
4726
4978
  pipeline: await collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book'),
4727
4979
  tools,
4728
4980
  });
4729
- // TODO: [🚐] Make arrayable LLMs -> single LLM DRY
4730
4981
  const _llms = arrayableToArray(tools.llm);
4731
4982
  const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
4732
- const availableModels = await llmTools.listModels();
4733
- const availableModelNames = availableModels
4983
+ const availableModels = (await llmTools.listModels())
4734
4984
  .filter(({ modelVariant }) => modelVariant === 'CHAT')
4735
- .map(({ modelName }) => modelName)
4736
- .join(',');
4737
- const result = await preparePersonaExecutor({ availableModelNames, personaDescription }).asPromise();
4985
+ .map(({ modelName, modelDescription }) => ({
4986
+ modelName,
4987
+ modelDescription,
4988
+ // <- Note: `modelTitle` and `modelVariant` is not relevant for this task
4989
+ }));
4990
+ const result = await preparePersonaExecutor({
4991
+ availableModels /* <- Note: Passing as JSON */,
4992
+ personaDescription,
4993
+ }).asPromise();
4738
4994
  const { outputParameters } = result;
4739
- const { modelRequirements: modelRequirementsRaw } = outputParameters;
4740
- const modelRequirements = JSON.parse(modelRequirementsRaw);
4995
+ const { modelsRequirements: modelsRequirementsJson } = outputParameters;
4996
+ let modelsRequirementsUnchecked = jsonParse(modelsRequirementsJson);
4741
4997
  if (isVerbose) {
4742
- console.info(`PERSONA ${personaDescription}`, modelRequirements);
4998
+ console.info(`PERSONA ${personaDescription}`, modelsRequirementsUnchecked);
4743
4999
  }
4744
- const { modelName, systemMessage, temperature } = modelRequirements;
4745
- return {
5000
+ if (!Array.isArray(modelsRequirementsUnchecked)) {
5001
+ // <- TODO: Book should have syntax and system to enforce shape of JSON
5002
+ modelsRequirementsUnchecked = [modelsRequirementsUnchecked];
5003
+ /*
5004
+ throw new UnexpectedError(
5005
+ spaceTrim(
5006
+ (block) => `
5007
+ Invalid \`modelsRequirements\`:
5008
+
5009
+ \`\`\`json
5010
+ ${block(JSON.stringify(modelsRequirementsUnchecked, null, 4))}
5011
+ \`\`\`
5012
+ `,
5013
+ ),
5014
+ );
5015
+ */
5016
+ }
5017
+ const modelsRequirements = modelsRequirementsUnchecked.map((modelRequirements) => ({
4746
5018
  modelVariant: 'CHAT',
4747
- modelName,
4748
- systemMessage,
4749
- temperature,
5019
+ ...modelRequirements,
5020
+ }));
5021
+ return {
5022
+ modelsRequirements,
4750
5023
  };
4751
5024
  }
4752
5025
  /**
@@ -4757,7 +5030,8 @@
4757
5030
  */
4758
5031
 
4759
5032
  /**
4760
- * @@@
5033
+ * Safely retrieves the global scope object (window in browser, global in Node.js)
5034
+ * regardless of the JavaScript environment in which the code is running
4761
5035
  *
4762
5036
  * Note: `$` is used to indicate that this function is not a pure function - it access global scope
4763
5037
  *
@@ -4768,10 +5042,10 @@
4768
5042
  }
4769
5043
 
4770
5044
  /**
4771
- * @@@
5045
+ * Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).
4772
5046
  *
4773
- * @param text @@@
4774
- * @returns @@@
5047
+ * @param text The text string to be converted to SCREAMING_CASE format.
5048
+ * @returns The normalized text in SCREAMING_CASE format.
4775
5049
  * @example 'HELLO_WORLD'
4776
5050
  * @example 'I_LOVE_PROMPTBOOK'
4777
5051
  * @public exported from `@promptbook/utils`
@@ -4823,10 +5097,10 @@
4823
5097
  */
4824
5098
 
4825
5099
  /**
4826
- * @@@
5100
+ * Normalizes a text string to snake_case format.
4827
5101
  *
4828
- * @param text @@@
4829
- * @returns @@@
5102
+ * @param text The text string to be converted to snake_case format.
5103
+ * @returns The normalized text in snake_case format.
4830
5104
  * @example 'hello_world'
4831
5105
  * @example 'i_love_promptbook'
4832
5106
  * @public exported from `@promptbook/utils`
@@ -4836,11 +5110,11 @@
4836
5110
  }
4837
5111
 
4838
5112
  /**
4839
- * Register is @@@
5113
+ * Global registry for storing and managing registered entities of a given type.
4840
5114
  *
4841
5115
  * Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
4842
5116
  *
4843
- * @private internal utility, exported are only signleton instances of this class
5117
+ * @private internal utility, exported are only singleton instances of this class
4844
5118
  */
4845
5119
  class $Register {
4846
5120
  constructor(registerName) {
@@ -4884,10 +5158,10 @@
4884
5158
  }
4885
5159
 
4886
5160
  /**
4887
- * @@@
5161
+ * Global registry for storing metadata about all available scrapers and converters.
4888
5162
  *
4889
- * Note: `$` is used to indicate that this interacts with the global scope
4890
- * @singleton Only one instance of each register is created per build, but thare can be more @@@
5163
+ * Note: `$` is used to indicate that this interacts with the global scope.
5164
+ * @singleton Only one instance of each register is created per build, but there can be more in different contexts (e.g., tests).
4891
5165
  * @public exported from `@promptbook/core`
4892
5166
  */
4893
5167
  const $scrapersMetadataRegister = new $Register('scrapers_metadata');
@@ -4896,10 +5170,11 @@
4896
5170
  */
4897
5171
 
4898
5172
  /**
4899
- * @@@
5173
+ * Registry for all available scrapers in the system.
5174
+ * Central point for registering and accessing different types of content scrapers.
4900
5175
  *
4901
5176
  * Note: `$` is used to indicate that this interacts with the global scope
4902
- * @singleton Only one instance of each register is created per build, but thare can be more @@@
5177
+ * @singleton Only one instance of each register is created per build, but there can be more than one in different build modules
4903
5178
  * @public exported from `@promptbook/core`
4904
5179
  */
4905
5180
  const $scrapersRegister = new $Register('scraper_constructors');
@@ -4995,10 +5270,10 @@
4995
5270
  */
4996
5271
 
4997
5272
  /**
4998
- * @@@
5273
+ * Converts a given text to kebab-case format.
4999
5274
  *
5000
- * @param text @@@
5001
- * @returns @@@
5275
+ * @param text The text to be converted.
5276
+ * @returns The kebab-case formatted string.
5002
5277
  * @example 'hello-world'
5003
5278
  * @example 'i-love-promptbook'
5004
5279
  * @public exported from `@promptbook/utils`
@@ -5067,7 +5342,8 @@
5067
5342
  */
5068
5343
 
5069
5344
  /**
5070
- * @@@
5345
+ * Converts a name to a properly formatted subfolder path for cache storage.
5346
+ * Handles normalization and path formatting to create consistent cache directory structures.
5071
5347
  *
5072
5348
  * @private for `FileCacheStorage`
5073
5349
  */
@@ -5147,11 +5423,11 @@
5147
5423
  }
5148
5424
 
5149
5425
  /**
5150
- * @@@
5426
+ * Converts a title string into a normalized name.
5151
5427
  *
5152
- * @param value @@@
5153
- * @returns @@@
5154
- * @example @@@
5428
+ * @param value The title string to be converted to a name.
5429
+ * @returns A normalized name derived from the input title.
5430
+ * @example 'Hello World!' -> 'hello-world'
5155
5431
  * @public exported from `@promptbook/utils`
5156
5432
  */
5157
5433
  function titleToName(value) {
@@ -5202,7 +5478,9 @@
5202
5478
  */
5203
5479
 
5204
5480
  /**
5205
- * @@@
5481
+ * Factory function that creates a handler for processing knowledge sources.
5482
+ * Provides standardized processing of different types of knowledge sources
5483
+ * across various scraper implementations.
5206
5484
  *
5207
5485
  * @public exported from `@promptbook/core`
5208
5486
  */
@@ -5309,7 +5587,7 @@
5309
5587
  > },
5310
5588
  */
5311
5589
  async asJson() {
5312
- return JSON.parse(await tools.fs.readFile(filename, 'utf-8'));
5590
+ return jsonParse(await tools.fs.readFile(filename, 'utf-8'));
5313
5591
  },
5314
5592
  async asText() {
5315
5593
  return await tools.fs.readFile(filename, 'utf-8');
@@ -5443,9 +5721,12 @@
5443
5721
  */
5444
5722
 
5445
5723
  /**
5446
- * @@@
5724
+ * Prepares tasks by adding knowledge to the prompt and ensuring all necessary parameters are included.
5447
5725
  *
5448
- * @public exported from `@promptbook/core`
5726
+ * @param tasks Sequence of tasks that are chained together to form a pipeline
5727
+ * @returns A promise that resolves to the prepared tasks.
5728
+ *
5729
+ * @private internal utility of `preparePipeline`
5449
5730
  */
5450
5731
  async function prepareTasks(pipeline, tools, options) {
5451
5732
  const { maxParallelCount = DEFAULT_MAX_PARALLEL_COUNT } = options;
@@ -5567,14 +5848,14 @@
5567
5848
  // TODO: [🖌][🧠] Implement some `mapAsync` function
5568
5849
  const preparedPersonas = new Array(personas.length);
5569
5850
  await forEachAsync(personas, { maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, async (persona, index) => {
5570
- const modelRequirements = await preparePersona(persona.description, { ...tools, llm: llmToolsWithUsage }, {
5851
+ const { modelsRequirements } = await preparePersona(persona.description, { ...tools, llm: llmToolsWithUsage }, {
5571
5852
  rootDirname,
5572
5853
  maxParallelCount /* <- TODO: [🪂] */,
5573
5854
  isVerbose,
5574
5855
  });
5575
5856
  const preparedPersona = {
5576
5857
  ...persona,
5577
- modelRequirements,
5858
+ modelsRequirements,
5578
5859
  preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id],
5579
5860
  // <- TODO: [🍙] Make some standard order of json properties
5580
5861
  };
@@ -5963,7 +6244,7 @@
5963
6244
  /**
5964
6245
  * Parses the boilerplate command
5965
6246
  *
5966
- * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.book` file
6247
+ * Note: @@ This command is used as boilerplate for new commands - it should NOT be used in any `.book` file
5967
6248
  *
5968
6249
  * @see `documentationUrl` for more details
5969
6250
  * @private within the commands folder
@@ -6351,11 +6632,11 @@
6351
6632
  };
6352
6633
 
6353
6634
  /**
6354
- * @@@
6635
+ * Normalizes a given text to camelCase format.
6355
6636
  *
6356
- * @param text @@@
6357
- * @param _isFirstLetterCapital @@@
6358
- * @returns @@@
6637
+ * @param text The text to be normalized.
6638
+ * @param _isFirstLetterCapital Whether the first letter should be capitalized.
6639
+ * @returns The camelCase formatted string.
6359
6640
  * @example 'helloWorld'
6360
6641
  * @example 'iLovePromptbook'
6361
6642
  * @public exported from `@promptbook/utils`
@@ -6426,11 +6707,12 @@
6426
6707
  }
6427
6708
 
6428
6709
  /**
6429
- * Function `validateParameterName` will @@@
6710
+ * Function `validateParameterName` will normalize and validate a parameter name for use in pipelines.
6711
+ * It removes diacritics, emojis, and quotes, normalizes to camelCase, and checks for reserved names and invalid characters.
6430
6712
  *
6431
- * @param parameterName @@@
6432
- * @returns @@@
6433
- * @throws {ParseError} @@@
6713
+ * @param parameterName The parameter name to validate and normalize.
6714
+ * @returns The validated and normalized parameter name.
6715
+ * @throws {ParseError} If the parameter name is empty, reserved, or contains invalid characters.
6434
6716
  * @private within the repository
6435
6717
  */
6436
6718
  function validateParameterName(parameterName) {
@@ -6500,8 +6782,6 @@
6500
6782
  /**
6501
6783
  * Parses the foreach command
6502
6784
  *
6503
- * Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.book` file
6504
- *
6505
6785
  * @see `documentationUrl` for more details
6506
6786
  * @public exported from `@promptbook/editable`
6507
6787
  */
@@ -6558,14 +6838,14 @@
6558
6838
  `));
6559
6839
  // <- TODO: [🏢] List all supported format names
6560
6840
  }
6561
- const subvalueDefinition = formatDefinition.subvalueDefinitions.find((subvalueDefinition) => [subvalueDefinition.subvalueName, ...(subvalueDefinition.aliases || [])].includes(subformatName));
6562
- if (subvalueDefinition === undefined) {
6841
+ const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(subformatName));
6842
+ if (subvalueParser === undefined) {
6563
6843
  throw new ParseError(spaceTrim__default["default"]((block) => `
6564
6844
  Unsupported subformat name "${subformatName}" for format "${formatName}"
6565
6845
 
6566
6846
  Available subformat names for format "${formatDefinition.formatName}":
6567
- ${block(formatDefinition.subvalueDefinitions
6568
- .map((subvalueDefinition) => subvalueDefinition.subvalueName)
6847
+ ${block(formatDefinition.subvalueParsers
6848
+ .map((subvalueParser) => subvalueParser.subvalueName)
6569
6849
  .map((subvalueName) => `- ${subvalueName}`)
6570
6850
  .join('\n'))}
6571
6851
  `));
@@ -6742,14 +7022,14 @@
6742
7022
  };
6743
7023
 
6744
7024
  /**
6745
- * @@@
7025
+ * Chatbot form factor definition for conversational interfaces that interact with users in a chat-like manner.
6746
7026
  *
6747
7027
  * @public exported from `@promptbook/core`
6748
7028
  */
6749
7029
  const ChatbotFormfactorDefinition = {
6750
7030
  name: 'CHATBOT',
6751
7031
  aliasNames: ['CHAT'],
6752
- description: `@@@`,
7032
+ description: `A chatbot form factor for conversational user interfaces.`,
6753
7033
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/174`,
6754
7034
  pipelineInterface: {
6755
7035
  inputParameters: [
@@ -6776,7 +7056,45 @@
6776
7056
  };
6777
7057
 
6778
7058
  /**
6779
- * Generator is form of app that @@@
7059
+ * Completion is formfactor that emulates completion models
7060
+ *
7061
+ * @public exported from `@promptbook/core`
7062
+ */
7063
+ const CompletionFormfactorDefinition = {
7064
+ name: 'COMPLETION',
7065
+ description: `Completion is formfactor that emulates completion models`,
7066
+ documentationUrl: `https://github.com/webgptorg/promptbook/discussions/@@`,
7067
+ // <- TODO: https://github.com/webgptorg/promptbook/discussions/new?category=concepts
7068
+ // "🔠 Completion Formfactor"
7069
+ pipelineInterface: {
7070
+ inputParameters: [
7071
+ {
7072
+ name: 'inputText',
7073
+ description: `Input text to be completed`,
7074
+ isInput: true,
7075
+ isOutput: false,
7076
+ },
7077
+ {
7078
+ name: 'instructions',
7079
+ description: `Additional instructions for the model, for example the required length, empty by default`,
7080
+ isInput: true,
7081
+ isOutput: false,
7082
+ },
7083
+ ],
7084
+ outputParameters: [
7085
+ {
7086
+ name: 'followingText',
7087
+ description: `Text that follows the input text`,
7088
+ isInput: false,
7089
+ isOutput: true,
7090
+ },
7091
+ ],
7092
+ },
7093
+ };
7094
+
7095
+ /**
7096
+ * Generator form factor represents an application that generates content or data based on user input or predefined rules.
7097
+ * This form factor is used for apps that produce outputs, such as text, images, or other media, based on provided input.
6780
7098
  *
6781
7099
  * @public exported from `@promptbook/core`
6782
7100
  */
@@ -6805,7 +7123,7 @@
6805
7123
  };
6806
7124
 
6807
7125
  /**
6808
- * @@@
7126
+ * Pipeline interface which is equivalent to `any`
6809
7127
  *
6810
7128
  * @see https://github.com/webgptorg/promptbook/discussions/171
6811
7129
  *
@@ -6820,13 +7138,13 @@
6820
7138
  */
6821
7139
 
6822
7140
  /**
6823
- * @@@
7141
+ * A generic pipeline
6824
7142
  *
6825
7143
  * @public exported from `@promptbook/core`
6826
7144
  */
6827
7145
  const GenericFormfactorDefinition = {
6828
7146
  name: 'GENERIC',
6829
- description: `@@@`,
7147
+ description: `A generic pipeline`,
6830
7148
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/173`,
6831
7149
  pipelineInterface: GENERIC_PIPELINE_INTERFACE,
6832
7150
  };
@@ -6861,17 +7179,20 @@
6861
7179
  };
6862
7180
 
6863
7181
  /**
6864
- * Matcher is form of app that @@@
7182
+ * Matcher is form of app that evaluates (spreadsheet) content against defined criteria or patterns,
7183
+ * determining if it matches or meets specific requirements. Used for classification,
7184
+ * validation, filtering, and quality assessment of inputs.
6865
7185
  *
6866
7186
  * @public exported from `@promptbook/core`
6867
7187
  */
6868
7188
  const MatcherFormfactorDefinition = {
6869
7189
  name: 'EXPERIMENTAL_MATCHER',
6870
- description: `@@@`,
7190
+ description: `An evaluation system that determines whether content meets specific criteria or patterns.
7191
+ Used for content validation, quality assessment, and intelligent filtering tasks. Currently in experimental phase.`,
6871
7192
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/177`,
6872
7193
  pipelineInterface: {
6873
7194
  inputParameters: [
6874
- /* @@@ */
7195
+ /* Input parameters for content to be matched and criteria to match against */
6875
7196
  {
6876
7197
  name: 'nonce',
6877
7198
  description: 'Just to prevent EXPERIMENTAL_MATCHER to be set as implicit formfactor',
@@ -6880,20 +7201,21 @@
6880
7201
  },
6881
7202
  ],
6882
7203
  outputParameters: [
6883
- /* @@@ */
7204
+ /* Output parameters containing match results, confidence scores, and relevant metadata */
6884
7205
  ],
6885
7206
  },
6886
7207
  };
6887
7208
 
6888
7209
  /**
6889
- * Sheets is form of app that @@@
7210
+ * Sheets is form of app that processes tabular data in CSV format, allowing transformation
7211
+ * and analysis of structured data through AI-powered operations
6890
7212
  *
6891
7213
  * @public exported from `@promptbook/core`
6892
7214
  */
6893
7215
  const SheetsFormfactorDefinition = {
6894
7216
  name: 'SHEETS',
6895
7217
  aliasNames: ['SHEETS', 'SHEET'],
6896
- description: `@@@`,
7218
+ description: `A formfactor for processing spreadsheet-like data in CSV format, enabling AI transformations on tabular data`,
6897
7219
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/176`,
6898
7220
  pipelineInterface: {
6899
7221
  inputParameters: [
@@ -6916,13 +7238,16 @@
6916
7238
  };
6917
7239
 
6918
7240
  /**
6919
- * Translator is form of app that @@@
7241
+ * Translator is form of app that transforms input text from one form to another,
7242
+ * such as language translation, style conversion, tone modification, or other text transformations.
6920
7243
  *
6921
7244
  * @public exported from `@promptbook/core`
6922
7245
  */
6923
7246
  const TranslatorFormfactorDefinition = {
6924
7247
  name: 'TRANSLATOR',
6925
- description: `@@@`,
7248
+ description: `A text transformation system that converts input content into different forms,
7249
+ including language translations, paraphrasing, style conversions, and tone adjustments.
7250
+ This form factor takes one input and produces one transformed output.`,
6926
7251
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/175`,
6927
7252
  pipelineInterface: {
6928
7253
  inputParameters: [
@@ -6959,6 +7284,8 @@
6959
7284
  MatcherFormfactorDefinition,
6960
7285
  GeneratorFormfactorDefinition,
6961
7286
  ImageGeneratorFormfactorDefinition,
7287
+ CompletionFormfactorDefinition,
7288
+ // <- [🛬] When making new formfactor, copy the _boilerplate and link it here
6962
7289
  ];
6963
7290
  /**
6964
7291
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -6967,7 +7294,7 @@
6967
7294
  /**
6968
7295
  * Parses the formfactor command
6969
7296
  *
6970
- * Note: @@@ This command is used as formfactor for new commands - it should NOT be used in any `.book` file
7297
+ * Note: This command is used as a formfactor for new commands and defines the app type format - it should NOT be used in any `.book` file
6971
7298
  *
6972
7299
  * @see `documentationUrl` for more details
6973
7300
  * @public exported from `@promptbook/editable`
@@ -6989,7 +7316,7 @@
6989
7316
  /**
6990
7317
  * Description of the FORMFACTOR command
6991
7318
  */
6992
- description: `@@`,
7319
+ description: `Specifies the application type and interface requirements that this promptbook should conform to`,
6993
7320
  /**
6994
7321
  * Link to documentation
6995
7322
  */
@@ -7132,8 +7459,7 @@
7132
7459
  };
7133
7460
 
7134
7461
  /**
7135
- * @@@
7136
- *
7462
+ * @see {@link ModelVariant}
7137
7463
  * @public exported from `@promptbook/core`
7138
7464
  */
7139
7465
  const MODEL_VARIANTS = ['COMPLETION', 'CHAT', 'EMBEDDING' /* <- TODO [🏳] */ /* <- [🤖] */];
@@ -7565,10 +7891,10 @@
7565
7891
  }
7566
7892
 
7567
7893
  /**
7568
- * @@@
7894
+ * Checks if the given value is a valid JavaScript identifier name.
7569
7895
  *
7570
- * @param javascriptName @@@
7571
- * @returns @@@
7896
+ * @param javascriptName The value to check for JavaScript identifier validity.
7897
+ * @returns `true` if the value is a valid JavaScript name, false otherwise.
7572
7898
  * @public exported from `@promptbook/utils`
7573
7899
  */
7574
7900
  function isValidJavascriptName(javascriptName) {
@@ -8048,7 +8374,10 @@
8048
8374
  `));
8049
8375
  }
8050
8376
  /**
8051
- * @@@
8377
+ * Generates a markdown-formatted message listing all supported commands
8378
+ * with their descriptions and documentation links
8379
+ *
8380
+ * @returns A formatted markdown string containing all available commands and their details
8052
8381
  */
8053
8382
  function getSupportedCommandsMessage() {
8054
8383
  return COMMANDS.flatMap(({ name, aliasNames, description, documentationUrl }) =>
@@ -8059,7 +8388,10 @@
8059
8388
  ]).join('\n');
8060
8389
  }
8061
8390
  /**
8062
- * @@@
8391
+ * Attempts to parse a command variant using the provided input parameters
8392
+ *
8393
+ * @param input Object containing command parsing information including raw command text and normalized values
8394
+ * @returns A parsed Command object if successful, or null if the command cannot be parsed
8063
8395
  */
8064
8396
  function parseCommandVariant(input) {
8065
8397
  const { commandNameRaw, usagePlace, normalized, args, raw, rawArgs } = input;
@@ -8106,7 +8438,7 @@
8106
8438
  }
8107
8439
 
8108
8440
  /**
8109
- * @@@
8441
+ * Extracts the interface (input and output parameters) from a pipeline.
8110
8442
  *
8111
8443
  * @deprecated https://github.com/webgptorg/promptbook/pull/186
8112
8444
  * @see https://github.com/webgptorg/promptbook/discussions/171
@@ -8139,7 +8471,7 @@
8139
8471
  }
8140
8472
 
8141
8473
  /**
8142
- * @@@
8474
+ * Checks if two pipeline interfaces are structurally identical.
8143
8475
  *
8144
8476
  * @deprecated https://github.com/webgptorg/promptbook/pull/186
8145
8477
  * @see https://github.com/webgptorg/promptbook/discussions/171
@@ -8171,10 +8503,11 @@
8171
8503
  }
8172
8504
 
8173
8505
  /**
8174
- * @@@
8506
+ * Checks if a given pipeline satisfies the requirements of a specified pipeline interface.
8175
8507
  *
8176
8508
  * @deprecated https://github.com/webgptorg/promptbook/pull/186
8177
8509
  * @see https://github.com/webgptorg/promptbook/discussions/171
8510
+ * @returns `true` if the pipeline implements the interface, `false` otherwise.
8178
8511
  *
8179
8512
  * @public exported from `@promptbook/core`
8180
8513
  */
@@ -8360,7 +8693,8 @@
8360
8693
  }
8361
8694
 
8362
8695
  /**
8363
- * @@@
8696
+ * Utility to determine if a pipeline string is in flat format.
8697
+ * A flat pipeline is a simple text without proper structure (headers, blocks, etc).
8364
8698
  *
8365
8699
  * @public exported from `@promptbook/editable`
8366
8700
  */
@@ -8381,7 +8715,10 @@
8381
8715
  }
8382
8716
 
8383
8717
  /**
8384
- * @@@
8718
+ * Converts a pipeline structure to its string representation.
8719
+ *
8720
+ * Transforms a flat, simple pipeline into a properly formatted pipeline string
8721
+ * with sections for title, prompt, and return statement.
8385
8722
  *
8386
8723
  * @public exported from `@promptbook/editable`
8387
8724
  */
@@ -8438,7 +8775,7 @@
8438
8775
  * Note: It can not work with html syntax and comments
8439
8776
  *
8440
8777
  * @param markdown any valid markdown
8441
- * @returns @@@
8778
+ * @returns An array of strings, each representing an individual list item found in the markdown
8442
8779
  * @public exported from `@promptbook/markdown-utils`
8443
8780
  */
8444
8781
  function extractAllListItemsFromMarkdown(markdown) {
@@ -9273,7 +9610,8 @@
9273
9610
  */
9274
9611
 
9275
9612
  /**
9276
- * @@@
9613
+ * Attempts to locate the specified application on a Linux system using the 'which' command.
9614
+ * Returns the path to the executable if found, or null otherwise.
9277
9615
  *
9278
9616
  * @private within the repository
9279
9617
  */
@@ -9293,7 +9631,8 @@
9293
9631
  */
9294
9632
 
9295
9633
  /**
9296
- * @@@
9634
+ * Provides filesystem access (for example for Node.js-based scrapers)
9635
+ * Creates a standardized filesystem interface that scrapers can use for file operations.
9297
9636
  *
9298
9637
  * @public exported from `@promptbook/node`
9299
9638
  */
@@ -9339,7 +9678,8 @@
9339
9678
  // eslint-disable-next-line @typescript-eslint/no-var-requires
9340
9679
  const userhome = require('userhome');
9341
9680
  /**
9342
- * @@@
9681
+ * Attempts to locate the specified application on a macOS system by checking standard application paths and using mdfind.
9682
+ * Returns the path to the executable if found, or null otherwise.
9343
9683
  *
9344
9684
  * @private within the repository
9345
9685
  */
@@ -9371,7 +9711,8 @@
9371
9711
  */
9372
9712
 
9373
9713
  /**
9374
- * @@@
9714
+ * Attempts to locate the specified application on a Windows system by searching common installation directories.
9715
+ * Returns the path to the executable if found, or null otherwise.
9375
9716
  *
9376
9717
  * @private within the repository
9377
9718
  */
@@ -9442,7 +9783,8 @@
9442
9783
  */
9443
9784
 
9444
9785
  /**
9445
- * @@@
9786
+ * Locates the LibreOffice executable on the current system by searching platform-specific paths.
9787
+ * Returns the path to the executable if found, or null otherwise.
9446
9788
  *
9447
9789
  * @private within the repository
9448
9790
  */
@@ -9460,7 +9802,8 @@
9460
9802
  */
9461
9803
 
9462
9804
  /**
9463
- * @@@
9805
+ * Locates the Pandoc executable on the current system by searching platform-specific paths.
9806
+ * Returns the path to the executable if found, or null otherwise.
9464
9807
  *
9465
9808
  * @private within the repository
9466
9809
  */
@@ -9478,7 +9821,7 @@
9478
9821
  */
9479
9822
 
9480
9823
  /**
9481
- * @@@
9824
+ * Provides paths to required executables (i.e. as Pandoc and LibreOffice) for Node.js environments.
9482
9825
  *
9483
9826
  * @public exported from `@promptbook/node`
9484
9827
  */
@@ -9498,10 +9841,10 @@
9498
9841
  */
9499
9842
 
9500
9843
  /**
9501
- * @@@
9844
+ * Register for LLM tools metadata.
9502
9845
  *
9503
9846
  * Note: `$` is used to indicate that this interacts with the global scope
9504
- * @singleton Only one instance of each register is created per build, but thare can be more @@@
9847
+ * @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.
9505
9848
  * @public exported from `@promptbook/core`
9506
9849
  */
9507
9850
  const $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
@@ -9529,10 +9872,10 @@
9529
9872
  */
9530
9873
 
9531
9874
  /**
9532
- * @@@
9875
+ * Register for LLM tools.
9533
9876
  *
9534
9877
  * Note: `$` is used to indicate that this interacts with the global scope
9535
- * @singleton Only one instance of each register is created per build, but thare can be more @@@
9878
+ * @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.
9536
9879
  * @public exported from `@promptbook/core`
9537
9880
  */
9538
9881
  const $llmToolsRegister = new $Register('llm_execution_tools_constructors');
@@ -9725,9 +10068,8 @@
9725
10068
  */
9726
10069
 
9727
10070
  /**
9728
- * @@@
10071
+ * Provides LLM tools configuration by reading environment variables.
9729
10072
  *
9730
- * @@@ .env
9731
10073
  * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
9732
10074
  *
9733
10075
  * It looks for environment variables:
@@ -9735,7 +10077,8 @@
9735
10077
  * - `process.env.ANTHROPIC_CLAUDE_API_KEY`
9736
10078
  * - ...
9737
10079
  *
9738
- * @returns @@@
10080
+ * @see Environment variables documentation or .env file for required variables.
10081
+ * @returns A promise that resolves to the LLM tools configuration, or null if configuration is incomplete or missing.
9739
10082
  * @public exported from `@promptbook/node`
9740
10083
  */
9741
10084
  async function $provideLlmToolsConfigurationFromEnv() {
@@ -9757,11 +10100,16 @@
9757
10100
  */
9758
10101
 
9759
10102
  /**
9760
- * @@@
10103
+ * Creates LLM execution tools from provided configuration objects
10104
+ *
10105
+ * Instantiates and configures LLM tool instances for each configuration entry,
10106
+ * combining them into a unified interface via MultipleLlmExecutionTools.
9761
10107
  *
9762
10108
  * Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
9763
10109
  *
9764
- * @returns @@@
10110
+ * @param configuration Array of LLM tool configurations to instantiate
10111
+ * @param options Additional options for configuring the LLM tools
10112
+ * @returns A unified interface combining all successfully instantiated LLM tools
9765
10113
  * @public exported from `@promptbook/core`
9766
10114
  */
9767
10115
  function createLlmToolsFromConfiguration(configuration, options = {}) {
@@ -9800,7 +10148,11 @@
9800
10148
  /**
9801
10149
  * TODO: [🎌] Together with `createLlmToolsFromConfiguration` + 'EXECUTION_TOOLS_CLASSES' gets to `@promptbook/core` ALL model providers, make this more efficient
9802
10150
  * TODO: [🧠][🎌] Dynamically install required providers
9803
- * TODO: @@@ write discussion about this - wizzard
10151
+ * TODO: We should implement an interactive configuration wizard that would:
10152
+ * 1. Detect which LLM providers are available in the environment
10153
+ * 2. Guide users through required configuration settings for each provider
10154
+ * 3. Allow testing connections before completing setup
10155
+ * 4. Generate appropriate configuration code for application integration
9804
10156
  * TODO: [🧠][🍛] Which name is better `createLlmToolsFromConfig` or `createLlmToolsFromConfiguration`?
9805
10157
  * TODO: [🧠] Is there some meaningfull way how to test this util
9806
10158
  * TODO: This should be maybe not under `_common` but under `utils`
@@ -9808,11 +10160,14 @@
9808
10160
  */
9809
10161
 
9810
10162
  /**
9811
- * @@@
10163
+ * Automatically configures LLM tools from environment variables in Node.js
10164
+ *
10165
+ * This utility function detects available LLM providers based on environment variables
10166
+ * and creates properly configured LLM execution tools for each detected provider.
9812
10167
  *
9813
10168
  * Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
9814
10169
  *
9815
- * @@@ .env
10170
+ * Supports environment variables from .env files when dotenv is configured
9816
10171
  * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
9817
10172
  *
9818
10173
  * It looks for environment variables:
@@ -9820,7 +10175,8 @@
9820
10175
  * - `process.env.ANTHROPIC_CLAUDE_API_KEY`
9821
10176
  * - ...
9822
10177
  *
9823
- * @returns @@@
10178
+ * @param options Configuration options for the LLM tools
10179
+ * @returns A unified interface containing all detected and configured LLM tools
9824
10180
  * @public exported from `@promptbook/node`
9825
10181
  */
9826
10182
  async function $provideLlmToolsFromEnv(options = {}) {
@@ -9846,7 +10202,16 @@
9846
10202
  return createLlmToolsFromConfiguration(configuration, options);
9847
10203
  }
9848
10204
  /**
9849
- * TODO: @@@ write `$provideLlmToolsFromEnv` vs `$provideLlmToolsConfigurationFromEnv` vs `createLlmToolsFromConfiguration`
10205
+ * TODO: The architecture for LLM tools configuration consists of three key functions:
10206
+ * 1. `$provideLlmToolsFromEnv` - High-level function that detects available providers from env vars and returns ready-to-use LLM tools
10207
+ * 2. `$provideLlmToolsConfigurationFromEnv` - Middle layer that extracts configuration objects from environment variables
10208
+ * 3. `createLlmToolsFromConfiguration` - Low-level function that instantiates LLM tools from explicit configuration
10209
+ *
10210
+ * This layered approach allows flexibility in how tools are configured:
10211
+ * - Use $provideLlmToolsFromEnv for automatic detection and setup in Node.js environments
10212
+ * - Use $provideLlmToolsConfigurationFromEnv to extract config objects for modification before instantiation
10213
+ * - Use createLlmToolsFromConfiguration for explicit control over tool configurations
10214
+ *
9850
10215
  * TODO: [🧠][🍛] Which name is better `$provideLlmToolsFromEnv` or `$provideLlmToolsFromEnvironment`?
9851
10216
  * TODO: [🧠] Is there some meaningfull way how to test this util
9852
10217
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
@@ -9856,11 +10221,9 @@
9856
10221
  */
9857
10222
 
9858
10223
  /**
9859
- * @@@
9860
- *
9861
- * 1) @@@
9862
- * 2) @@@
9863
- *
10224
+ * Provides a collection of scrapers optimized for Node.js environment.
10225
+ * 1) `provideScrapersForNode` use as default
10226
+ * 2) `provideScrapersForBrowser` use in limited browser environment *
9864
10227
  * @public exported from `@promptbook/node`
9865
10228
  */
9866
10229
  async function $provideScrapersForNode(tools, options) {
@@ -9967,11 +10330,11 @@
9967
10330
  }
9968
10331
 
9969
10332
  /**
9970
- * @@@
10333
+ * Converts a name string into a URI-compatible format.
9971
10334
  *
9972
- * @param name @@@
9973
- * @returns @@@
9974
- * @example @@@
10335
+ * @param name The string to be converted to a URI-compatible format.
10336
+ * @returns A URI-compatible string derived from the input name.
10337
+ * @example 'Hello World' -> 'hello-world'
9975
10338
  * @public exported from `@promptbook/utils`
9976
10339
  */
9977
10340
  function nameToUriPart(name) {
@@ -9985,11 +10348,11 @@
9985
10348
  }
9986
10349
 
9987
10350
  /**
9988
- * @@@
10351
+ * Converts a given name into URI-compatible parts.
9989
10352
  *
9990
- * @param name @@@
9991
- * @returns @@@
9992
- * @example @@@
10353
+ * @param name The name to be converted into URI parts.
10354
+ * @returns An array of URI-compatible parts derived from the name.
10355
+ * @example 'Example Name' -> ['example', 'name']
9993
10356
  * @public exported from `@promptbook/utils`
9994
10357
  */
9995
10358
  function nameToUriParts(name) {
@@ -10796,7 +11159,10 @@
10796
11159
  */
10797
11160
 
10798
11161
  /**
10799
- * @@@
11162
+ * A storage implementation that caches data in files organized in a directory structure.
11163
+ * Provides methods for retrieving, storing, and managing cached data on the filesystem.
11164
+ *
11165
+ * This class implements the PromptbookStorage interface for filesystem-based caching.
10800
11166
  *
10801
11167
  * @public exported from `@promptbook/node`
10802
11168
  */
@@ -10809,7 +11175,8 @@
10809
11175
  }
10810
11176
  }
10811
11177
  /**
10812
- * @@@
11178
+ * Converts a storage key to a filesystem path where the data should be stored.
11179
+ * Creates a consistent, deterministic file path based on the key string.
10813
11180
  */
10814
11181
  getFilenameForKey(key) {
10815
11182
  // TODO: [👬] DRY
@@ -10821,7 +11188,8 @@
10821
11188
  ...nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */), `${name.substring(0, MAX_FILENAME_LENGTH)}.json`);
10822
11189
  }
10823
11190
  /**
10824
- * @@@ Returns the current value associated with the given key, or null if the given key does not exist in the list associated with the object.
11191
+ * Returns the current value associated with the given key, or null if the given key does not exist.
11192
+ * Retrieves the cached data from the file system storage.
10825
11193
  */
10826
11194
  async getItem(key) {
10827
11195
  const filename = this.getFilenameForKey(key);
@@ -10829,12 +11197,13 @@
10829
11197
  return null;
10830
11198
  }
10831
11199
  const fileContent = await promises.readFile(filename, 'utf-8');
10832
- const value = JSON.parse(fileContent);
11200
+ const value = jsonParse(fileContent);
10833
11201
  // TODO: [🌗]
10834
11202
  return value;
10835
11203
  }
10836
11204
  /**
10837
- * @@@ Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
11205
+ * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
11206
+ * Persists data to the file system, creating necessary directory structure if it doesn't exist.
10838
11207
  */
10839
11208
  async setItem(key, value) {
10840
11209
  const filename = this.getFilenameForKey(key);
@@ -10846,7 +11215,8 @@
10846
11215
  await promises.writeFile(filename, fileContent, 'utf-8');
10847
11216
  }
10848
11217
  /**
10849
- * @@@ Removes the key/value pair with the given key from the list associated with the object, if a key/value pair with the given key exists.
11218
+ * Removes the key/value pair with the given key from the storage, if a key/value pair with the given key exists.
11219
+ * Deletes the corresponding file from the filesystem.
10850
11220
  */
10851
11221
  async removeItem(key) {
10852
11222
  const filename = this.getFilenameForKey(key);