@promptbook/markdown-utils 0.92.0-3 → 0.92.0-30
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.
- package/esm/index.es.js +555 -274
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/browser.index.d.ts +2 -0
- package/esm/typings/src/_packages/core.index.d.ts +22 -6
- package/esm/typings/src/_packages/deepseek.index.d.ts +2 -0
- package/esm/typings/src/_packages/google.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +4 -2
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +1 -1
- package/esm/typings/src/collection/PipelineCollection.d.ts +0 -2
- package/esm/typings/src/collection/SimplePipelineCollection.d.ts +1 -1
- package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -6
- package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +0 -2
- package/esm/typings/src/commands/FORMFACTOR/formfactorCommandParser.d.ts +1 -1
- package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
- package/esm/typings/src/commands/_common/types/CommandParser.d.ts +36 -28
- package/esm/typings/src/config.d.ts +41 -11
- package/esm/typings/src/constants.d.ts +43 -2
- package/esm/typings/src/conversion/archive/loadArchive.d.ts +2 -2
- package/esm/typings/src/errors/0-BoilerplateError.d.ts +2 -2
- package/esm/typings/src/executables/$provideExecutablesForNode.d.ts +1 -1
- package/esm/typings/src/executables/apps/locateLibreoffice.d.ts +2 -1
- package/esm/typings/src/executables/apps/locatePandoc.d.ts +2 -1
- package/esm/typings/src/executables/platforms/locateAppOnLinux.d.ts +2 -1
- package/esm/typings/src/executables/platforms/locateAppOnMacOs.d.ts +2 -1
- package/esm/typings/src/executables/platforms/locateAppOnWindows.d.ts +2 -1
- package/esm/typings/src/execution/AbstractTaskResult.d.ts +1 -1
- package/esm/typings/src/execution/CommonToolsOptions.d.ts +5 -1
- package/esm/typings/src/execution/LlmExecutionToolsConstructor.d.ts +2 -1
- package/esm/typings/src/execution/PipelineExecutorResult.d.ts +4 -2
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +11 -8
- package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +15 -3
- package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +20 -14
- package/esm/typings/src/execution/createPipelineExecutor/computeCosineSimilarity.d.ts +13 -0
- package/esm/typings/src/execution/createPipelineExecutor/filterJustOutputParameters.d.ts +7 -6
- package/esm/typings/src/execution/createPipelineExecutor/getContextForTask.d.ts +5 -1
- package/esm/typings/src/execution/createPipelineExecutor/getExamplesForTask.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/getKnowledgeForTask.d.ts +21 -5
- package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTask.d.ts +19 -5
- package/esm/typings/src/execution/createPipelineExecutor/knowledgePiecesToString.d.ts +9 -0
- package/esm/typings/src/execution/translation/automatic-translate/automatic-translators/LindatAutomaticTranslator.d.ts +4 -4
- package/esm/typings/src/execution/utils/checkExpectations.d.ts +1 -1
- package/esm/typings/src/execution/utils/uncertainNumber.d.ts +3 -2
- package/esm/typings/src/formats/_common/{FormatDefinition.d.ts → FormatParser.d.ts} +8 -6
- package/esm/typings/src/formats/_common/FormatSubvalueParser.d.ts +66 -0
- package/esm/typings/src/formats/csv/CsvFormatParser.d.ts +17 -0
- package/esm/typings/src/formats/csv/CsvSettings.d.ts +2 -2
- package/esm/typings/src/formats/csv/utils/csvParse.d.ts +12 -0
- package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +1 -1
- package/esm/typings/src/formats/index.d.ts +2 -2
- package/esm/typings/src/formats/json/{JsonFormatDefinition.d.ts → JsonFormatParser.d.ts} +6 -6
- package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +1 -1
- package/esm/typings/src/formats/json/utils/jsonParse.d.ts +8 -0
- package/esm/typings/src/formats/text/{TextFormatDefinition.d.ts → TextFormatParser.d.ts} +7 -7
- package/esm/typings/src/formats/xml/XmlFormatParser.d.ts +19 -0
- package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +1 -1
- package/esm/typings/src/formfactors/_boilerplate/BoilerplateFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/formfactors/_common/AbstractFormfactorDefinition.d.ts +16 -7
- package/esm/typings/src/formfactors/_common/FormfactorDefinition.d.ts +3 -1
- package/esm/typings/src/formfactors/_common/string_formfactor_name.d.ts +2 -1
- package/esm/typings/src/formfactors/chatbot/ChatbotFormfactorDefinition.d.ts +2 -2
- package/esm/typings/src/formfactors/completion/CompletionFormfactorDefinition.d.ts +29 -0
- package/esm/typings/src/formfactors/generator/GeneratorFormfactorDefinition.d.ts +2 -1
- package/esm/typings/src/formfactors/generic/GenericFormfactorDefinition.d.ts +2 -2
- package/esm/typings/src/formfactors/index.d.ts +33 -8
- package/esm/typings/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +4 -2
- package/esm/typings/src/formfactors/sheets/SheetsFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/formfactors/translator/TranslatorFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/high-level-abstractions/index.d.ts +2 -2
- package/esm/typings/src/llm-providers/_common/register/$llmToolsMetadataRegister.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/register/$llmToolsRegister.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +4 -4
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +4 -3
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +17 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsConfiguration.d.ts +11 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +27 -5
- package/esm/typings/src/llm-providers/_common/register/LlmToolsOptions.d.ts +9 -2
- package/esm/typings/src/llm-providers/_common/register/createLlmToolsFromConfiguration.d.ts +12 -3
- package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +10 -5
- package/esm/typings/src/llm-providers/_common/utils/cache/CacheLlmToolsOptions.d.ts +5 -3
- package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/utils/count-total-usage/limitTotalUsage.d.ts +5 -5
- package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/deepseek/deepseek-models.d.ts +23 -0
- package/esm/typings/src/llm-providers/google/google-models.d.ts +23 -0
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +2 -2
- package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +2 -2
- package/esm/typings/src/migrations/migratePipeline.d.ts +9 -0
- package/esm/typings/src/other/templates/getBookTemplates.d.ts +2 -2
- package/esm/typings/src/personas/preparePersona.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/PipelineInterface.d.ts +3 -3
- package/esm/typings/src/pipeline/PipelineInterface/constants.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/getPipelineInterface.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/isPipelineImplementingInterface.d.ts +5 -4
- package/esm/typings/src/pipeline/PipelineInterface/isPipelineInterfacesEqual.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineJson/CommonTaskJson.d.ts +9 -6
- package/esm/typings/src/pipeline/PipelineJson/PersonaJson.d.ts +4 -2
- package/esm/typings/src/pipeline/PipelineJson/PipelineJson.d.ts +3 -2
- package/esm/typings/src/pipeline/PipelineString.d.ts +3 -1
- package/esm/typings/src/pipeline/book-notation.d.ts +2 -2
- package/esm/typings/src/postprocessing/utils/extractJsonBlock.d.ts +1 -1
- package/esm/typings/src/prepare/prepareTasks.d.ts +7 -4
- package/esm/typings/src/remote-server/openapi-types.d.ts +348 -6
- package/esm/typings/src/remote-server/openapi.d.ts +398 -4
- package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +2 -1
- package/esm/typings/src/scrapers/_boilerplate/BoilerplateScraper.d.ts +3 -3
- package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +1 -1
- package/esm/typings/src/scrapers/_common/Converter.d.ts +3 -1
- package/esm/typings/src/scrapers/_common/Scraper.d.ts +4 -3
- package/esm/typings/src/scrapers/_common/ScraperIntermediateSource.d.ts +4 -2
- package/esm/typings/src/scrapers/_common/register/$provideFilesystemForNode.d.ts +2 -1
- package/esm/typings/src/scrapers/_common/register/$provideScrapersForBrowser.d.ts +6 -3
- package/esm/typings/src/scrapers/_common/register/$provideScrapersForNode.d.ts +3 -5
- package/esm/typings/src/scrapers/_common/register/$scrapersMetadataRegister.d.ts +3 -3
- package/esm/typings/src/scrapers/_common/register/$scrapersRegister.d.ts +3 -2
- package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +8 -5
- package/esm/typings/src/scrapers/_common/register/ScraperConstructor.d.ts +2 -1
- package/esm/typings/src/scrapers/_common/utils/getScraperIntermediateSource.d.ts +6 -5
- package/esm/typings/src/scrapers/_common/utils/makeKnowledgeSourceHandler.d.ts +3 -1
- package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +2 -1
- package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +4 -1
- package/esm/typings/src/scrapers/markitdown/MarkitdownScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +2 -1
- package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +3 -4
- package/esm/typings/src/scripting/javascript/postprocessing-functions.d.ts +5 -1
- package/esm/typings/src/storage/file-cache-storage/FileCacheStorage.d.ts +12 -5
- package/esm/typings/src/storage/file-cache-storage/FileCacheStorageOptions.d.ts +4 -2
- package/esm/typings/src/storage/file-cache-storage/utils/nameToSubfolderPath.d.ts +2 -1
- package/esm/typings/src/storage/local-storage/getIndexedDbStorage.d.ts +10 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromIndexedDb.d.ts +7 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromWebStorage.d.ts +2 -1
- package/esm/typings/src/types/IntermediateFilesStrategy.d.ts +2 -1
- package/esm/typings/src/types/ModelVariant.d.ts +5 -5
- package/esm/typings/src/types/typeAliases.d.ts +17 -13
- package/esm/typings/src/utils/$Register.d.ts +8 -7
- package/esm/typings/src/utils/editable/edit-pipeline-string/addPipelineCommand.d.ts +2 -2
- package/esm/typings/src/utils/editable/edit-pipeline-string/deflatePipeline.d.ts +4 -1
- package/esm/typings/src/utils/editable/utils/isFlatPipeline.d.ts +2 -1
- package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -1
- package/esm/typings/src/utils/expectation-counters/index.d.ts +1 -1
- package/esm/typings/src/utils/markdown/extractAllListItemsFromMarkdown.d.ts +1 -1
- package/esm/typings/src/utils/normalization/nameToUriPart.d.ts +4 -4
- package/esm/typings/src/utils/normalization/nameToUriParts.d.ts +4 -4
- package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +3 -3
- package/esm/typings/src/utils/normalization/normalizeTo_SCREAMING_CASE.d.ts +3 -3
- package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +4 -4
- package/esm/typings/src/utils/normalization/normalizeTo_snake_case.d.ts +3 -3
- package/esm/typings/src/utils/normalization/removeDiacritics.d.ts +3 -3
- package/esm/typings/src/utils/normalization/searchKeywords.d.ts +4 -1
- package/esm/typings/src/utils/normalization/titleToName.d.ts +4 -4
- package/esm/typings/src/utils/organization/empty_object.d.ts +2 -2
- package/esm/typings/src/utils/organization/just_empty_object.d.ts +4 -4
- package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +7 -7
- package/esm/typings/src/utils/serialization/clonePipeline.d.ts +4 -3
- package/esm/typings/src/utils/serialization/deepClone.d.ts +5 -1
- package/esm/typings/src/utils/validators/javascriptName/isValidJavascriptName.d.ts +3 -3
- package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +5 -4
- package/esm/typings/src/version.d.ts +2 -1
- package/package.json +1 -1
- package/umd/index.umd.js +555 -274
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +0 -31
- package/esm/typings/src/formats/csv/CsvFormatDefinition.d.ts +0 -17
- package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +0 -19
package/umd/index.umd.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* @generated
|
|
26
26
|
* @see https://github.com/webgptorg/promptbook
|
|
27
27
|
*/
|
|
28
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-
|
|
28
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-30';
|
|
29
29
|
/**
|
|
30
30
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
31
31
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -231,6 +231,21 @@
|
|
|
231
231
|
* @public exported from `@promptbook/core`
|
|
232
232
|
*/
|
|
233
233
|
const DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
|
|
234
|
+
/**
|
|
235
|
+
* Threshold value that determines when a dataset is considered "big"
|
|
236
|
+
* and may require special handling or optimizations
|
|
237
|
+
*
|
|
238
|
+
* For example, when error occurs in one item of the big dataset, it will not fail the whole pipeline
|
|
239
|
+
*
|
|
240
|
+
* @public exported from `@promptbook/core`
|
|
241
|
+
*/
|
|
242
|
+
const BIG_DATASET_TRESHOLD = 50;
|
|
243
|
+
/**
|
|
244
|
+
* Placeholder text used to represent a placeholder value of failed operation
|
|
245
|
+
*
|
|
246
|
+
* @public exported from `@promptbook/core`
|
|
247
|
+
*/
|
|
248
|
+
const FAILED_VALUE_PLACEHOLDER = '!?';
|
|
234
249
|
// <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
|
|
235
250
|
/**
|
|
236
251
|
* The maximum number of iterations for a loops
|
|
@@ -310,7 +325,7 @@
|
|
|
310
325
|
const DEFAULT_SCRAPE_CACHE_DIRNAME = './.promptbook/scrape-cache';
|
|
311
326
|
// <- TODO: [🧜♂️]
|
|
312
327
|
/**
|
|
313
|
-
*
|
|
328
|
+
* Default settings for parsing and generating CSV files in Promptbook.
|
|
314
329
|
*
|
|
315
330
|
* @public exported from `@promptbook/core`
|
|
316
331
|
*/
|
|
@@ -321,19 +336,19 @@
|
|
|
321
336
|
skipEmptyLines: true,
|
|
322
337
|
});
|
|
323
338
|
/**
|
|
324
|
-
*
|
|
339
|
+
* Controls whether verbose logging is enabled by default throughout the application.
|
|
325
340
|
*
|
|
326
341
|
* @public exported from `@promptbook/core`
|
|
327
342
|
*/
|
|
328
343
|
let DEFAULT_IS_VERBOSE = false;
|
|
329
344
|
/**
|
|
330
|
-
*
|
|
345
|
+
* Controls whether auto-installation of dependencies is enabled by default.
|
|
331
346
|
*
|
|
332
347
|
* @public exported from `@promptbook/core`
|
|
333
348
|
*/
|
|
334
349
|
const DEFAULT_IS_AUTO_INSTALLED = false;
|
|
335
350
|
/**
|
|
336
|
-
*
|
|
351
|
+
* Indicates whether pipeline logic validation is enabled. When true, the pipeline logic is checked for consistency.
|
|
337
352
|
*
|
|
338
353
|
* @private within the repository
|
|
339
354
|
*/
|
|
@@ -466,7 +481,7 @@
|
|
|
466
481
|
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
467
482
|
*
|
|
468
483
|
* @param value The string to check
|
|
469
|
-
* @returns
|
|
484
|
+
* @returns `true` if the string is a valid JSON string, false otherwise
|
|
470
485
|
*
|
|
471
486
|
* @public exported from `@promptbook/utils`
|
|
472
487
|
*/
|
|
@@ -517,7 +532,7 @@
|
|
|
517
532
|
}
|
|
518
533
|
/**
|
|
519
534
|
* TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
|
|
520
|
-
* TODO: [🏢] Make this logic part of `
|
|
535
|
+
* TODO: [🏢] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
521
536
|
*/
|
|
522
537
|
|
|
523
538
|
/**
|
|
@@ -537,7 +552,7 @@
|
|
|
537
552
|
function keepUnused(...valuesToKeep) {
|
|
538
553
|
}
|
|
539
554
|
|
|
540
|
-
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"}];
|
|
555
|
+
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"}];
|
|
541
556
|
|
|
542
557
|
/**
|
|
543
558
|
* Checks if value is valid email
|
|
@@ -1016,8 +1031,12 @@
|
|
|
1016
1031
|
*/
|
|
1017
1032
|
|
|
1018
1033
|
/**
|
|
1019
|
-
*
|
|
1034
|
+
* Creates a deep clone of the given object
|
|
1020
1035
|
*
|
|
1036
|
+
* Note: This method only works for objects that are fully serializable to JSON and do not contain functions, Dates, or special types.
|
|
1037
|
+
*
|
|
1038
|
+
* @param objectValue The object to clone.
|
|
1039
|
+
* @returns A deep, writable clone of the input object.
|
|
1021
1040
|
* @public exported from `@promptbook/utils`
|
|
1022
1041
|
*/
|
|
1023
1042
|
function deepClone(objectValue) {
|
|
@@ -1099,13 +1118,13 @@
|
|
|
1099
1118
|
*/
|
|
1100
1119
|
const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';
|
|
1101
1120
|
/**
|
|
1102
|
-
*
|
|
1121
|
+
* Placeholder value indicating a parameter is missing its value.
|
|
1103
1122
|
*
|
|
1104
1123
|
* @private within the repository
|
|
1105
1124
|
*/
|
|
1106
1125
|
const RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
1107
1126
|
/**
|
|
1108
|
-
*
|
|
1127
|
+
* Placeholder value indicating a parameter is restricted and cannot be used directly.
|
|
1109
1128
|
*
|
|
1110
1129
|
* @private within the repository
|
|
1111
1130
|
*/
|
|
@@ -1563,7 +1582,7 @@
|
|
|
1563
1582
|
*/
|
|
1564
1583
|
function unpreparePipeline(pipeline) {
|
|
1565
1584
|
let { personas, knowledgeSources, tasks } = pipeline;
|
|
1566
|
-
personas = personas.map((persona) => ({ ...persona,
|
|
1585
|
+
personas = personas.map((persona) => ({ ...persona, modelsRequirements: undefined, preparationIds: undefined }));
|
|
1567
1586
|
knowledgeSources = knowledgeSources.map((knowledgeSource) => ({ ...knowledgeSource, preparationIds: undefined }));
|
|
1568
1587
|
tasks = tasks.map((task) => {
|
|
1569
1588
|
let { dependentParameterNames } = task;
|
|
@@ -1604,7 +1623,7 @@
|
|
|
1604
1623
|
/**
|
|
1605
1624
|
* Constructs a pipeline collection from pipelines
|
|
1606
1625
|
*
|
|
1607
|
-
* @param pipelines
|
|
1626
|
+
* @param pipelines Array of pipeline JSON objects to include in the collection
|
|
1608
1627
|
*
|
|
1609
1628
|
* Note: During the construction logic of all pipelines are validated
|
|
1610
1629
|
* Note: It is not recommended to use this constructor directly, use `createCollectionFromJson` *(or other variant)* instead
|
|
@@ -1768,15 +1787,21 @@
|
|
|
1768
1787
|
* @public exported from `@promptbook/core`
|
|
1769
1788
|
*/
|
|
1770
1789
|
function isPipelinePrepared(pipeline) {
|
|
1771
|
-
// Note: Ignoring `pipeline.preparations`
|
|
1772
|
-
// Note: Ignoring `pipeline.knowledgePieces`
|
|
1790
|
+
// Note: Ignoring `pipeline.preparations`
|
|
1791
|
+
// Note: Ignoring `pipeline.knowledgePieces`
|
|
1773
1792
|
if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
|
|
1793
|
+
// TODO: !!! Comment this out
|
|
1794
|
+
console.log('Pipeline is not prepared because title is undefined or empty', pipeline);
|
|
1774
1795
|
return false;
|
|
1775
1796
|
}
|
|
1776
|
-
if (!pipeline.personas.every((persona) => persona.
|
|
1797
|
+
if (!pipeline.personas.every((persona) => persona.modelsRequirements !== undefined)) {
|
|
1798
|
+
// TODO: !!! Comment this out
|
|
1799
|
+
console.log('Pipeline is not prepared because personas are not prepared', pipeline.personas);
|
|
1777
1800
|
return false;
|
|
1778
1801
|
}
|
|
1779
1802
|
if (!pipeline.knowledgeSources.every((knowledgeSource) => knowledgeSource.preparationIds !== undefined)) {
|
|
1803
|
+
// TODO: !!! Comment this out
|
|
1804
|
+
console.log('Pipeline is not prepared because knowledge sources are not prepared', pipeline.knowledgeSources);
|
|
1780
1805
|
return false;
|
|
1781
1806
|
}
|
|
1782
1807
|
/*
|
|
@@ -1797,36 +1822,6 @@
|
|
|
1797
1822
|
* - [♨] Are tasks prepared
|
|
1798
1823
|
*/
|
|
1799
1824
|
|
|
1800
|
-
/**
|
|
1801
|
-
* Recursively converts JSON strings to JSON objects
|
|
1802
|
-
|
|
1803
|
-
* @public exported from `@promptbook/utils`
|
|
1804
|
-
*/
|
|
1805
|
-
function jsonStringsToJsons(object) {
|
|
1806
|
-
if (object === null) {
|
|
1807
|
-
return object;
|
|
1808
|
-
}
|
|
1809
|
-
if (Array.isArray(object)) {
|
|
1810
|
-
return object.map(jsonStringsToJsons);
|
|
1811
|
-
}
|
|
1812
|
-
if (typeof object !== 'object') {
|
|
1813
|
-
return object;
|
|
1814
|
-
}
|
|
1815
|
-
const newObject = { ...object };
|
|
1816
|
-
for (const [key, value] of Object.entries(object)) {
|
|
1817
|
-
if (typeof value === 'string' && isValidJsonString(value)) {
|
|
1818
|
-
newObject[key] = JSON.parse(value);
|
|
1819
|
-
}
|
|
1820
|
-
else {
|
|
1821
|
-
newObject[key] = jsonStringsToJsons(value);
|
|
1822
|
-
}
|
|
1823
|
-
}
|
|
1824
|
-
return newObject;
|
|
1825
|
-
}
|
|
1826
|
-
/**
|
|
1827
|
-
* TODO: Type the return type correctly
|
|
1828
|
-
*/
|
|
1829
|
-
|
|
1830
1825
|
/**
|
|
1831
1826
|
* This error indicates problems parsing the format value
|
|
1832
1827
|
*
|
|
@@ -2036,6 +2031,101 @@
|
|
|
2036
2031
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2037
2032
|
*/
|
|
2038
2033
|
|
|
2034
|
+
/**
|
|
2035
|
+
* Serializes an error into a [🚉] JSON-serializable object
|
|
2036
|
+
*
|
|
2037
|
+
* @public exported from `@promptbook/utils`
|
|
2038
|
+
*/
|
|
2039
|
+
function serializeError(error) {
|
|
2040
|
+
const { name, message, stack } = error;
|
|
2041
|
+
const { id } = error;
|
|
2042
|
+
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
2043
|
+
console.error(spaceTrim__default["default"]((block) => `
|
|
2044
|
+
|
|
2045
|
+
Cannot serialize error with name "${name}"
|
|
2046
|
+
|
|
2047
|
+
Authors of Promptbook probably forgot to add this error into the list of errors:
|
|
2048
|
+
https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
${block(stack || message)}
|
|
2052
|
+
|
|
2053
|
+
`));
|
|
2054
|
+
}
|
|
2055
|
+
return {
|
|
2056
|
+
name: name,
|
|
2057
|
+
message,
|
|
2058
|
+
stack,
|
|
2059
|
+
id, // Include id in the serialized object
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
/**
|
|
2064
|
+
* Converts a JavaScript Object Notation (JSON) string into an object.
|
|
2065
|
+
*
|
|
2066
|
+
* Note: This is wrapper around `JSON.parse()` with better error and type handling
|
|
2067
|
+
*
|
|
2068
|
+
* @public exported from `@promptbook/utils`
|
|
2069
|
+
*/
|
|
2070
|
+
function jsonParse(value) {
|
|
2071
|
+
if (value === undefined) {
|
|
2072
|
+
throw new Error(`Can not parse JSON from undefined value.`);
|
|
2073
|
+
}
|
|
2074
|
+
else if (typeof value !== 'string') {
|
|
2075
|
+
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
2076
|
+
throw new Error(spaceTrim__default["default"](`
|
|
2077
|
+
Can not parse JSON from non-string value.
|
|
2078
|
+
|
|
2079
|
+
The value type: ${typeof value}
|
|
2080
|
+
See more in console.
|
|
2081
|
+
`));
|
|
2082
|
+
}
|
|
2083
|
+
try {
|
|
2084
|
+
return JSON.parse(value);
|
|
2085
|
+
}
|
|
2086
|
+
catch (error) {
|
|
2087
|
+
if (!(error instanceof Error)) {
|
|
2088
|
+
throw error;
|
|
2089
|
+
}
|
|
2090
|
+
throw new Error(spaceTrim__default["default"]((block) => `
|
|
2091
|
+
${block(error.message)}
|
|
2092
|
+
|
|
2093
|
+
The JSON text:
|
|
2094
|
+
${block(value)}
|
|
2095
|
+
`));
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
/**
|
|
2100
|
+
* Recursively converts JSON strings to JSON objects
|
|
2101
|
+
|
|
2102
|
+
* @public exported from `@promptbook/utils`
|
|
2103
|
+
*/
|
|
2104
|
+
function jsonStringsToJsons(object) {
|
|
2105
|
+
if (object === null) {
|
|
2106
|
+
return object;
|
|
2107
|
+
}
|
|
2108
|
+
if (Array.isArray(object)) {
|
|
2109
|
+
return object.map(jsonStringsToJsons);
|
|
2110
|
+
}
|
|
2111
|
+
if (typeof object !== 'object') {
|
|
2112
|
+
return object;
|
|
2113
|
+
}
|
|
2114
|
+
const newObject = { ...object };
|
|
2115
|
+
for (const [key, value] of Object.entries(object)) {
|
|
2116
|
+
if (typeof value === 'string' && isValidJsonString(value)) {
|
|
2117
|
+
newObject[key] = jsonParse(value);
|
|
2118
|
+
}
|
|
2119
|
+
else {
|
|
2120
|
+
newObject[key] = jsonStringsToJsons(value);
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
return newObject;
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* TODO: Type the return type correctly
|
|
2127
|
+
*/
|
|
2128
|
+
|
|
2039
2129
|
/**
|
|
2040
2130
|
* Deserializes the error object
|
|
2041
2131
|
*
|
|
@@ -2201,64 +2291,6 @@
|
|
|
2201
2291
|
* TODO: [🐚] Split into more files and make `PrepareTask` & `RemoteTask` + split the function
|
|
2202
2292
|
*/
|
|
2203
2293
|
|
|
2204
|
-
/**
|
|
2205
|
-
* Serializes an error into a [🚉] JSON-serializable object
|
|
2206
|
-
*
|
|
2207
|
-
* @public exported from `@promptbook/utils`
|
|
2208
|
-
*/
|
|
2209
|
-
function serializeError(error) {
|
|
2210
|
-
const { name, message, stack } = error;
|
|
2211
|
-
const { id } = error;
|
|
2212
|
-
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
2213
|
-
console.error(spaceTrim__default["default"]((block) => `
|
|
2214
|
-
|
|
2215
|
-
Cannot serialize error with name "${name}"
|
|
2216
|
-
|
|
2217
|
-
Authors of Promptbook probably forgot to add this error into the list of errors:
|
|
2218
|
-
https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
${block(stack || message)}
|
|
2222
|
-
|
|
2223
|
-
`));
|
|
2224
|
-
}
|
|
2225
|
-
return {
|
|
2226
|
-
name: name,
|
|
2227
|
-
message,
|
|
2228
|
-
stack,
|
|
2229
|
-
id, // Include id in the serialized object
|
|
2230
|
-
};
|
|
2231
|
-
}
|
|
2232
|
-
|
|
2233
|
-
/**
|
|
2234
|
-
* Async version of Array.forEach
|
|
2235
|
-
*
|
|
2236
|
-
* @param array - Array to iterate over
|
|
2237
|
-
* @param options - Options for the function
|
|
2238
|
-
* @param callbackfunction - Function to call for each item
|
|
2239
|
-
* @public exported from `@promptbook/utils`
|
|
2240
|
-
* @deprecated [🪂] Use queues instead
|
|
2241
|
-
*/
|
|
2242
|
-
async function forEachAsync(array, options, callbackfunction) {
|
|
2243
|
-
const { maxParallelCount = Infinity } = options;
|
|
2244
|
-
let index = 0;
|
|
2245
|
-
let runningTasks = [];
|
|
2246
|
-
const tasks = [];
|
|
2247
|
-
for (const item of array) {
|
|
2248
|
-
const currentIndex = index++;
|
|
2249
|
-
const task = callbackfunction(item, currentIndex, array);
|
|
2250
|
-
tasks.push(task);
|
|
2251
|
-
runningTasks.push(task);
|
|
2252
|
-
/* not await */ Promise.resolve(task).then(() => {
|
|
2253
|
-
runningTasks = runningTasks.filter((t) => t !== task);
|
|
2254
|
-
});
|
|
2255
|
-
if (maxParallelCount < runningTasks.length) {
|
|
2256
|
-
await Promise.race(runningTasks);
|
|
2257
|
-
}
|
|
2258
|
-
}
|
|
2259
|
-
await Promise.all(tasks);
|
|
2260
|
-
}
|
|
2261
|
-
|
|
2262
2294
|
/**
|
|
2263
2295
|
* Represents the uncertain value
|
|
2264
2296
|
*
|
|
@@ -2302,7 +2334,7 @@
|
|
|
2302
2334
|
*
|
|
2303
2335
|
* @public exported from `@promptbook/core`
|
|
2304
2336
|
*/
|
|
2305
|
-
$deepFreeze({
|
|
2337
|
+
const UNCERTAIN_USAGE = $deepFreeze({
|
|
2306
2338
|
price: UNCERTAIN_ZERO_VALUE,
|
|
2307
2339
|
input: {
|
|
2308
2340
|
tokensCount: UNCERTAIN_ZERO_VALUE,
|
|
@@ -2327,6 +2359,35 @@
|
|
|
2327
2359
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2328
2360
|
*/
|
|
2329
2361
|
|
|
2362
|
+
/**
|
|
2363
|
+
* Async version of Array.forEach
|
|
2364
|
+
*
|
|
2365
|
+
* @param array - Array to iterate over
|
|
2366
|
+
* @param options - Options for the function
|
|
2367
|
+
* @param callbackfunction - Function to call for each item
|
|
2368
|
+
* @public exported from `@promptbook/utils`
|
|
2369
|
+
* @deprecated [🪂] Use queues instead
|
|
2370
|
+
*/
|
|
2371
|
+
async function forEachAsync(array, options, callbackfunction) {
|
|
2372
|
+
const { maxParallelCount = Infinity } = options;
|
|
2373
|
+
let index = 0;
|
|
2374
|
+
let runningTasks = [];
|
|
2375
|
+
const tasks = [];
|
|
2376
|
+
for (const item of array) {
|
|
2377
|
+
const currentIndex = index++;
|
|
2378
|
+
const task = callbackfunction(item, currentIndex, array);
|
|
2379
|
+
tasks.push(task);
|
|
2380
|
+
runningTasks.push(task);
|
|
2381
|
+
/* not await */ Promise.resolve(task).then(() => {
|
|
2382
|
+
runningTasks = runningTasks.filter((t) => t !== task);
|
|
2383
|
+
});
|
|
2384
|
+
if (maxParallelCount < runningTasks.length) {
|
|
2385
|
+
await Promise.race(runningTasks);
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
await Promise.all(tasks);
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2330
2391
|
/**
|
|
2331
2392
|
* Function `addUsage` will add multiple usages into one
|
|
2332
2393
|
*
|
|
@@ -2673,27 +2734,48 @@
|
|
|
2673
2734
|
pipeline: await collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book'),
|
|
2674
2735
|
tools,
|
|
2675
2736
|
});
|
|
2676
|
-
// TODO: [🚐] Make arrayable LLMs -> single LLM DRY
|
|
2677
2737
|
const _llms = arrayableToArray(tools.llm);
|
|
2678
2738
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
2679
|
-
const availableModels = await llmTools.listModels()
|
|
2680
|
-
const availableModelNames = availableModels
|
|
2739
|
+
const availableModels = (await llmTools.listModels())
|
|
2681
2740
|
.filter(({ modelVariant }) => modelVariant === 'CHAT')
|
|
2682
|
-
.map(({ modelName }) =>
|
|
2683
|
-
|
|
2684
|
-
|
|
2741
|
+
.map(({ modelName, modelDescription }) => ({
|
|
2742
|
+
modelName,
|
|
2743
|
+
modelDescription,
|
|
2744
|
+
// <- Note: `modelTitle` and `modelVariant` is not relevant for this task
|
|
2745
|
+
}));
|
|
2746
|
+
const result = await preparePersonaExecutor({
|
|
2747
|
+
availableModels /* <- Note: Passing as JSON */,
|
|
2748
|
+
personaDescription,
|
|
2749
|
+
}).asPromise();
|
|
2685
2750
|
const { outputParameters } = result;
|
|
2686
|
-
const {
|
|
2687
|
-
|
|
2751
|
+
const { modelsRequirements: modelsRequirementsJson } = outputParameters;
|
|
2752
|
+
let modelsRequirementsUnchecked = jsonParse(modelsRequirementsJson);
|
|
2688
2753
|
if (isVerbose) {
|
|
2689
|
-
console.info(`PERSONA ${personaDescription}`,
|
|
2754
|
+
console.info(`PERSONA ${personaDescription}`, modelsRequirementsUnchecked);
|
|
2690
2755
|
}
|
|
2691
|
-
|
|
2692
|
-
|
|
2756
|
+
if (!Array.isArray(modelsRequirementsUnchecked)) {
|
|
2757
|
+
// <- TODO: Book should have syntax and system to enforce shape of JSON
|
|
2758
|
+
modelsRequirementsUnchecked = [modelsRequirementsUnchecked];
|
|
2759
|
+
/*
|
|
2760
|
+
throw new UnexpectedError(
|
|
2761
|
+
spaceTrim(
|
|
2762
|
+
(block) => `
|
|
2763
|
+
Invalid \`modelsRequirements\`:
|
|
2764
|
+
|
|
2765
|
+
\`\`\`json
|
|
2766
|
+
${block(JSON.stringify(modelsRequirementsUnchecked, null, 4))}
|
|
2767
|
+
\`\`\`
|
|
2768
|
+
`,
|
|
2769
|
+
),
|
|
2770
|
+
);
|
|
2771
|
+
*/
|
|
2772
|
+
}
|
|
2773
|
+
const modelsRequirements = modelsRequirementsUnchecked.map((modelRequirements) => ({
|
|
2693
2774
|
modelVariant: 'CHAT',
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2775
|
+
...modelRequirements,
|
|
2776
|
+
}));
|
|
2777
|
+
return {
|
|
2778
|
+
modelsRequirements,
|
|
2697
2779
|
};
|
|
2698
2780
|
}
|
|
2699
2781
|
/**
|
|
@@ -2704,7 +2786,8 @@
|
|
|
2704
2786
|
*/
|
|
2705
2787
|
|
|
2706
2788
|
/**
|
|
2707
|
-
*
|
|
2789
|
+
* Safely retrieves the global scope object (window in browser, global in Node.js)
|
|
2790
|
+
* regardless of the JavaScript environment in which the code is running
|
|
2708
2791
|
*
|
|
2709
2792
|
* Note: `$` is used to indicate that this function is not a pure function - it access global scope
|
|
2710
2793
|
*
|
|
@@ -2715,10 +2798,10 @@
|
|
|
2715
2798
|
}
|
|
2716
2799
|
|
|
2717
2800
|
/**
|
|
2718
|
-
*
|
|
2801
|
+
* Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).
|
|
2719
2802
|
*
|
|
2720
|
-
* @param text
|
|
2721
|
-
* @returns
|
|
2803
|
+
* @param text The text string to be converted to SCREAMING_CASE format.
|
|
2804
|
+
* @returns The normalized text in SCREAMING_CASE format.
|
|
2722
2805
|
* @example 'HELLO_WORLD'
|
|
2723
2806
|
* @example 'I_LOVE_PROMPTBOOK'
|
|
2724
2807
|
* @public exported from `@promptbook/utils`
|
|
@@ -2770,10 +2853,10 @@
|
|
|
2770
2853
|
*/
|
|
2771
2854
|
|
|
2772
2855
|
/**
|
|
2773
|
-
*
|
|
2856
|
+
* Normalizes a text string to snake_case format.
|
|
2774
2857
|
*
|
|
2775
|
-
* @param text
|
|
2776
|
-
* @returns
|
|
2858
|
+
* @param text The text string to be converted to snake_case format.
|
|
2859
|
+
* @returns The normalized text in snake_case format.
|
|
2777
2860
|
* @example 'hello_world'
|
|
2778
2861
|
* @example 'i_love_promptbook'
|
|
2779
2862
|
* @public exported from `@promptbook/utils`
|
|
@@ -2783,11 +2866,11 @@
|
|
|
2783
2866
|
}
|
|
2784
2867
|
|
|
2785
2868
|
/**
|
|
2786
|
-
*
|
|
2869
|
+
* Global registry for storing and managing registered entities of a given type.
|
|
2787
2870
|
*
|
|
2788
2871
|
* Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
|
|
2789
2872
|
*
|
|
2790
|
-
* @private internal utility, exported are only
|
|
2873
|
+
* @private internal utility, exported are only singleton instances of this class
|
|
2791
2874
|
*/
|
|
2792
2875
|
class $Register {
|
|
2793
2876
|
constructor(registerName) {
|
|
@@ -2831,10 +2914,10 @@
|
|
|
2831
2914
|
}
|
|
2832
2915
|
|
|
2833
2916
|
/**
|
|
2834
|
-
*
|
|
2917
|
+
* Global registry for storing metadata about all available scrapers and converters.
|
|
2835
2918
|
*
|
|
2836
|
-
* Note: `$` is used to indicate that this interacts with the global scope
|
|
2837
|
-
* @singleton Only one instance of each register is created per build, but
|
|
2919
|
+
* Note: `$` is used to indicate that this interacts with the global scope.
|
|
2920
|
+
* @singleton Only one instance of each register is created per build, but there can be more in different contexts (e.g., tests).
|
|
2838
2921
|
* @public exported from `@promptbook/core`
|
|
2839
2922
|
*/
|
|
2840
2923
|
const $scrapersMetadataRegister = new $Register('scrapers_metadata');
|
|
@@ -2843,10 +2926,11 @@
|
|
|
2843
2926
|
*/
|
|
2844
2927
|
|
|
2845
2928
|
/**
|
|
2846
|
-
*
|
|
2929
|
+
* Registry for all available scrapers in the system.
|
|
2930
|
+
* Central point for registering and accessing different types of content scrapers.
|
|
2847
2931
|
*
|
|
2848
2932
|
* Note: `$` is used to indicate that this interacts with the global scope
|
|
2849
|
-
* @singleton Only one instance of each register is created per build, but
|
|
2933
|
+
* @singleton Only one instance of each register is created per build, but there can be more than one in different build modules
|
|
2850
2934
|
* @public exported from `@promptbook/core`
|
|
2851
2935
|
*/
|
|
2852
2936
|
const $scrapersRegister = new $Register('scraper_constructors');
|
|
@@ -3186,10 +3270,10 @@
|
|
|
3186
3270
|
*/
|
|
3187
3271
|
|
|
3188
3272
|
/**
|
|
3189
|
-
*
|
|
3273
|
+
* Removes diacritic marks (accents) from characters in a string.
|
|
3190
3274
|
*
|
|
3191
|
-
* @param input
|
|
3192
|
-
* @returns
|
|
3275
|
+
* @param input The string containing diacritics to be normalized.
|
|
3276
|
+
* @returns The string with diacritics removed or normalized.
|
|
3193
3277
|
* @public exported from `@promptbook/utils`
|
|
3194
3278
|
*/
|
|
3195
3279
|
function removeDiacritics(input) {
|
|
@@ -3203,10 +3287,10 @@
|
|
|
3203
3287
|
*/
|
|
3204
3288
|
|
|
3205
3289
|
/**
|
|
3206
|
-
*
|
|
3290
|
+
* Converts a given text to kebab-case format.
|
|
3207
3291
|
*
|
|
3208
|
-
* @param text
|
|
3209
|
-
* @returns
|
|
3292
|
+
* @param text The text to be converted.
|
|
3293
|
+
* @returns The kebab-case formatted string.
|
|
3210
3294
|
* @example 'hello-world'
|
|
3211
3295
|
* @example 'i-love-promptbook'
|
|
3212
3296
|
* @public exported from `@promptbook/utils`
|
|
@@ -3275,7 +3359,8 @@
|
|
|
3275
3359
|
*/
|
|
3276
3360
|
|
|
3277
3361
|
/**
|
|
3278
|
-
*
|
|
3362
|
+
* Converts a name to a properly formatted subfolder path for cache storage.
|
|
3363
|
+
* Handles normalization and path formatting to create consistent cache directory structures.
|
|
3279
3364
|
*
|
|
3280
3365
|
* @private for `FileCacheStorage`
|
|
3281
3366
|
*/
|
|
@@ -3355,11 +3440,11 @@
|
|
|
3355
3440
|
}
|
|
3356
3441
|
|
|
3357
3442
|
/**
|
|
3358
|
-
*
|
|
3443
|
+
* Converts a title string into a normalized name.
|
|
3359
3444
|
*
|
|
3360
|
-
* @param value
|
|
3361
|
-
* @returns
|
|
3362
|
-
* @example
|
|
3445
|
+
* @param value The title string to be converted to a name.
|
|
3446
|
+
* @returns A normalized name derived from the input title.
|
|
3447
|
+
* @example 'Hello World!' -> 'hello-world'
|
|
3363
3448
|
* @public exported from `@promptbook/utils`
|
|
3364
3449
|
*/
|
|
3365
3450
|
function titleToName(value) {
|
|
@@ -3410,7 +3495,9 @@
|
|
|
3410
3495
|
*/
|
|
3411
3496
|
|
|
3412
3497
|
/**
|
|
3413
|
-
*
|
|
3498
|
+
* Factory function that creates a handler for processing knowledge sources.
|
|
3499
|
+
* Provides standardized processing of different types of knowledge sources
|
|
3500
|
+
* across various scraper implementations.
|
|
3414
3501
|
*
|
|
3415
3502
|
* @public exported from `@promptbook/core`
|
|
3416
3503
|
*/
|
|
@@ -3517,7 +3604,7 @@
|
|
|
3517
3604
|
> },
|
|
3518
3605
|
*/
|
|
3519
3606
|
async asJson() {
|
|
3520
|
-
return
|
|
3607
|
+
return jsonParse(await tools.fs.readFile(filename, 'utf-8'));
|
|
3521
3608
|
},
|
|
3522
3609
|
async asText() {
|
|
3523
3610
|
return await tools.fs.readFile(filename, 'utf-8');
|
|
@@ -3651,9 +3738,12 @@
|
|
|
3651
3738
|
*/
|
|
3652
3739
|
|
|
3653
3740
|
/**
|
|
3654
|
-
*
|
|
3741
|
+
* Prepares tasks by adding knowledge to the prompt and ensuring all necessary parameters are included.
|
|
3655
3742
|
*
|
|
3656
|
-
* @
|
|
3743
|
+
* @param tasks Sequence of tasks that are chained together to form a pipeline
|
|
3744
|
+
* @returns A promise that resolves to the prepared tasks.
|
|
3745
|
+
*
|
|
3746
|
+
* @private internal utility of `preparePipeline`
|
|
3657
3747
|
*/
|
|
3658
3748
|
async function prepareTasks(pipeline, tools, options) {
|
|
3659
3749
|
const { maxParallelCount = DEFAULT_MAX_PARALLEL_COUNT } = options;
|
|
@@ -3775,14 +3865,14 @@
|
|
|
3775
3865
|
// TODO: [🖌][🧠] Implement some `mapAsync` function
|
|
3776
3866
|
const preparedPersonas = new Array(personas.length);
|
|
3777
3867
|
await forEachAsync(personas, { maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, async (persona, index) => {
|
|
3778
|
-
const
|
|
3868
|
+
const { modelsRequirements } = await preparePersona(persona.description, { ...tools, llm: llmToolsWithUsage }, {
|
|
3779
3869
|
rootDirname,
|
|
3780
3870
|
maxParallelCount /* <- TODO: [🪂] */,
|
|
3781
3871
|
isVerbose,
|
|
3782
3872
|
});
|
|
3783
3873
|
const preparedPersona = {
|
|
3784
3874
|
...persona,
|
|
3785
|
-
|
|
3875
|
+
modelsRequirements,
|
|
3786
3876
|
preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id],
|
|
3787
3877
|
// <- TODO: [🍙] Make some standard order of json properties
|
|
3788
3878
|
};
|
|
@@ -4090,7 +4180,7 @@
|
|
|
4090
4180
|
}
|
|
4091
4181
|
|
|
4092
4182
|
/**
|
|
4093
|
-
*
|
|
4183
|
+
* Contains configuration options for parsing and generating CSV files, such as delimiters and quoting rules.
|
|
4094
4184
|
*
|
|
4095
4185
|
* @public exported from `@promptbook/core`
|
|
4096
4186
|
*/
|
|
@@ -4099,11 +4189,29 @@
|
|
|
4099
4189
|
// encoding: 'utf-8',
|
|
4100
4190
|
});
|
|
4101
4191
|
|
|
4192
|
+
/**
|
|
4193
|
+
* Converts a CSV string into an object
|
|
4194
|
+
*
|
|
4195
|
+
* Note: This is wrapper around `papaparse.parse()` with better autohealing
|
|
4196
|
+
*
|
|
4197
|
+
* @private - for now until `@promptbook/csv` is released
|
|
4198
|
+
*/
|
|
4199
|
+
function csvParse(value /* <- TODO: string_csv */, settings, schema /* <- TODO: Make CSV Schemas */) {
|
|
4200
|
+
settings = { ...settings, ...MANDATORY_CSV_SETTINGS };
|
|
4201
|
+
// Note: Autoheal invalid '\n' characters
|
|
4202
|
+
if (settings.newline && !settings.newline.includes('\r') && value.includes('\r')) {
|
|
4203
|
+
console.warn('CSV string contains carriage return characters, but in the CSV settings the `newline` setting does not include them. Autohealing the CSV string.');
|
|
4204
|
+
value = value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
4205
|
+
}
|
|
4206
|
+
const csv = papaparse.parse(value, settings);
|
|
4207
|
+
return csv;
|
|
4208
|
+
}
|
|
4209
|
+
|
|
4102
4210
|
/**
|
|
4103
4211
|
* Function to check if a string is valid CSV
|
|
4104
4212
|
*
|
|
4105
4213
|
* @param value The string to check
|
|
4106
|
-
* @returns
|
|
4214
|
+
* @returns `true` if the string is a valid CSV string, false otherwise
|
|
4107
4215
|
*
|
|
4108
4216
|
* @public exported from `@promptbook/utils`
|
|
4109
4217
|
*/
|
|
@@ -4127,7 +4235,7 @@
|
|
|
4127
4235
|
* @public exported from `@promptbook/core`
|
|
4128
4236
|
* <- TODO: [🏢] Export from package `@promptbook/csv`
|
|
4129
4237
|
*/
|
|
4130
|
-
const
|
|
4238
|
+
const CsvFormatParser = {
|
|
4131
4239
|
formatName: 'CSV',
|
|
4132
4240
|
aliases: ['SPREADSHEET', 'TABLE'],
|
|
4133
4241
|
isValid(value, settings, schema) {
|
|
@@ -4139,12 +4247,12 @@
|
|
|
4139
4247
|
heal(value, settings, schema) {
|
|
4140
4248
|
throw new Error('Not implemented');
|
|
4141
4249
|
},
|
|
4142
|
-
|
|
4250
|
+
subvalueParsers: [
|
|
4143
4251
|
{
|
|
4144
4252
|
subvalueName: 'ROW',
|
|
4145
|
-
async mapValues(
|
|
4146
|
-
|
|
4147
|
-
const csv =
|
|
4253
|
+
async mapValues(options) {
|
|
4254
|
+
const { value, outputParameterName, settings, mapCallback, onProgress } = options;
|
|
4255
|
+
const csv = csvParse(value, settings);
|
|
4148
4256
|
if (csv.errors.length !== 0) {
|
|
4149
4257
|
throw new CsvFormatError(spaceTrim__default["default"]((block) => `
|
|
4150
4258
|
CSV parsing error
|
|
@@ -4159,23 +4267,37 @@
|
|
|
4159
4267
|
${block(value)}
|
|
4160
4268
|
`));
|
|
4161
4269
|
}
|
|
4162
|
-
const mappedData =
|
|
4270
|
+
const mappedData = [];
|
|
4271
|
+
const length = csv.data.length;
|
|
4272
|
+
for (let index = 0; index < length; index++) {
|
|
4273
|
+
const row = csv.data[index];
|
|
4163
4274
|
if (row[outputParameterName]) {
|
|
4164
4275
|
throw new CsvFormatError(`Can not overwrite existing column "${outputParameterName}" in CSV row`);
|
|
4165
4276
|
}
|
|
4166
|
-
|
|
4277
|
+
const mappedRow = {
|
|
4167
4278
|
...row,
|
|
4168
|
-
[outputParameterName]: await mapCallback(row, index),
|
|
4279
|
+
[outputParameterName]: await mapCallback(row, index, length),
|
|
4169
4280
|
};
|
|
4170
|
-
|
|
4281
|
+
mappedData.push(mappedRow);
|
|
4282
|
+
if (onProgress) {
|
|
4283
|
+
// Note: Report the CSV with all rows mapped so far
|
|
4284
|
+
/*
|
|
4285
|
+
// TODO: [🛕] Report progress with all the rows including the pending ones
|
|
4286
|
+
const progressData = mappedData.map((row, i) =>
|
|
4287
|
+
i > index ? { ...row, [outputParameterName]: PENDING_VALUE_PLACEHOLDER } : row,
|
|
4288
|
+
);
|
|
4289
|
+
*/
|
|
4290
|
+
await onProgress(papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4171
4293
|
return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
|
|
4172
4294
|
},
|
|
4173
4295
|
},
|
|
4174
4296
|
{
|
|
4175
4297
|
subvalueName: 'CELL',
|
|
4176
|
-
async mapValues(
|
|
4177
|
-
|
|
4178
|
-
const csv =
|
|
4298
|
+
async mapValues(options) {
|
|
4299
|
+
const { value, settings, mapCallback, onProgress } = options;
|
|
4300
|
+
const csv = csvParse(value, settings);
|
|
4179
4301
|
if (csv.errors.length !== 0) {
|
|
4180
4302
|
throw new CsvFormatError(spaceTrim__default["default"]((block) => `
|
|
4181
4303
|
CSV parsing error
|
|
@@ -4191,9 +4313,9 @@
|
|
|
4191
4313
|
`));
|
|
4192
4314
|
}
|
|
4193
4315
|
const mappedData = await Promise.all(csv.data.map(async (row, rowIndex) => {
|
|
4194
|
-
return /* not await */ Promise.all(Object.entries(row).map(async ([key, value], columnIndex) => {
|
|
4316
|
+
return /* not await */ Promise.all(Object.entries(row).map(async ([key, value], columnIndex, array) => {
|
|
4195
4317
|
const index = rowIndex * Object.keys(row).length + columnIndex;
|
|
4196
|
-
return /* not await */ mapCallback({ [key]: value }, index);
|
|
4318
|
+
return /* not await */ mapCallback({ [key]: value }, index, array.length);
|
|
4197
4319
|
}));
|
|
4198
4320
|
}));
|
|
4199
4321
|
return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
|
|
@@ -4202,10 +4324,10 @@
|
|
|
4202
4324
|
],
|
|
4203
4325
|
};
|
|
4204
4326
|
/**
|
|
4205
|
-
* TODO: [🍓] In `
|
|
4206
|
-
* TODO: [🍓] In `
|
|
4207
|
-
* TODO: [🍓] In `
|
|
4208
|
-
* TODO: [🍓] In `
|
|
4327
|
+
* TODO: [🍓] In `CsvFormatParser` implement simple `isValid`
|
|
4328
|
+
* TODO: [🍓] In `CsvFormatParser` implement partial `canBeValid`
|
|
4329
|
+
* TODO: [🍓] In `CsvFormatParser` implement `heal
|
|
4330
|
+
* TODO: [🍓] In `CsvFormatParser` implement `subvalueParsers`
|
|
4209
4331
|
* TODO: [🏢] Allow to expect something inside CSV objects and other formats
|
|
4210
4332
|
*/
|
|
4211
4333
|
|
|
@@ -4214,7 +4336,7 @@
|
|
|
4214
4336
|
*
|
|
4215
4337
|
* @private still in development [🏢]
|
|
4216
4338
|
*/
|
|
4217
|
-
const
|
|
4339
|
+
const JsonFormatParser = {
|
|
4218
4340
|
formatName: 'JSON',
|
|
4219
4341
|
mimeType: 'application/json',
|
|
4220
4342
|
isValid(value, settings, schema) {
|
|
@@ -4226,28 +4348,28 @@
|
|
|
4226
4348
|
heal(value, settings, schema) {
|
|
4227
4349
|
throw new Error('Not implemented');
|
|
4228
4350
|
},
|
|
4229
|
-
|
|
4351
|
+
subvalueParsers: [],
|
|
4230
4352
|
};
|
|
4231
4353
|
/**
|
|
4232
4354
|
* TODO: [🧠] Maybe propper instance of object
|
|
4233
4355
|
* TODO: [0] Make string_serialized_json
|
|
4234
4356
|
* TODO: [1] Make type for JSON Settings and Schema
|
|
4235
4357
|
* TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
|
|
4236
|
-
* TODO: [🍓] In `
|
|
4237
|
-
* TODO: [🍓] In `
|
|
4238
|
-
* TODO: [🍓] In `
|
|
4239
|
-
* TODO: [🍓] In `
|
|
4358
|
+
* TODO: [🍓] In `JsonFormatParser` implement simple `isValid`
|
|
4359
|
+
* TODO: [🍓] In `JsonFormatParser` implement partial `canBeValid`
|
|
4360
|
+
* TODO: [🍓] In `JsonFormatParser` implement `heal
|
|
4361
|
+
* TODO: [🍓] In `JsonFormatParser` implement `subvalueParsers`
|
|
4240
4362
|
* TODO: [🏢] Allow to expect something inside JSON objects and other formats
|
|
4241
4363
|
*/
|
|
4242
4364
|
|
|
4243
4365
|
/**
|
|
4244
4366
|
* Definition for any text - this will be always valid
|
|
4245
4367
|
*
|
|
4246
|
-
* Note: This is not useful for validation, but for splitting and mapping with `
|
|
4368
|
+
* Note: This is not useful for validation, but for splitting and mapping with `subvalueParsers`
|
|
4247
4369
|
*
|
|
4248
4370
|
* @public exported from `@promptbook/core`
|
|
4249
4371
|
*/
|
|
4250
|
-
const
|
|
4372
|
+
const TextFormatParser = {
|
|
4251
4373
|
formatName: 'TEXT',
|
|
4252
4374
|
isValid(value) {
|
|
4253
4375
|
return typeof value === 'string';
|
|
@@ -4256,19 +4378,20 @@
|
|
|
4256
4378
|
return typeof partialValue === 'string';
|
|
4257
4379
|
},
|
|
4258
4380
|
heal() {
|
|
4259
|
-
throw new UnexpectedError('It does not make sense to call `
|
|
4381
|
+
throw new UnexpectedError('It does not make sense to call `TextFormatParser.heal`');
|
|
4260
4382
|
},
|
|
4261
|
-
|
|
4383
|
+
subvalueParsers: [
|
|
4262
4384
|
{
|
|
4263
4385
|
subvalueName: 'LINE',
|
|
4264
|
-
async mapValues(
|
|
4386
|
+
async mapValues(options) {
|
|
4387
|
+
const { value, mapCallback, onProgress } = options;
|
|
4265
4388
|
const lines = value.split('\n');
|
|
4266
|
-
const mappedLines = await Promise.all(lines.map((lineContent, lineNumber) =>
|
|
4389
|
+
const mappedLines = await Promise.all(lines.map((lineContent, lineNumber, array) =>
|
|
4267
4390
|
// TODO: [🧠] Maybe option to skip empty line
|
|
4268
4391
|
/* not await */ mapCallback({
|
|
4269
4392
|
lineContent,
|
|
4270
4393
|
// TODO: [🧠] Maybe also put here `lineNumber`
|
|
4271
|
-
}, lineNumber)));
|
|
4394
|
+
}, lineNumber, array.length)));
|
|
4272
4395
|
return mappedLines.join('\n');
|
|
4273
4396
|
},
|
|
4274
4397
|
},
|
|
@@ -4278,10 +4401,10 @@
|
|
|
4278
4401
|
/**
|
|
4279
4402
|
* TODO: [1] Make type for XML Text and Schema
|
|
4280
4403
|
* TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages available as subvalues
|
|
4281
|
-
* TODO: [🍓] In `
|
|
4282
|
-
* TODO: [🍓] In `
|
|
4283
|
-
* TODO: [🍓] In `
|
|
4284
|
-
* TODO: [🍓] In `
|
|
4404
|
+
* TODO: [🍓] In `TextFormatParser` implement simple `isValid`
|
|
4405
|
+
* TODO: [🍓] In `TextFormatParser` implement partial `canBeValid`
|
|
4406
|
+
* TODO: [🍓] In `TextFormatParser` implement `heal
|
|
4407
|
+
* TODO: [🍓] In `TextFormatParser` implement `subvalueParsers`
|
|
4285
4408
|
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
4286
4409
|
*/
|
|
4287
4410
|
|
|
@@ -4289,7 +4412,7 @@
|
|
|
4289
4412
|
* Function to check if a string is valid XML
|
|
4290
4413
|
*
|
|
4291
4414
|
* @param value
|
|
4292
|
-
* @returns
|
|
4415
|
+
* @returns `true` if the string is a valid XML string, false otherwise
|
|
4293
4416
|
*
|
|
4294
4417
|
* @public exported from `@promptbook/utils`
|
|
4295
4418
|
*/
|
|
@@ -4314,7 +4437,7 @@
|
|
|
4314
4437
|
*
|
|
4315
4438
|
* @private still in development [🏢]
|
|
4316
4439
|
*/
|
|
4317
|
-
const
|
|
4440
|
+
const XmlFormatParser = {
|
|
4318
4441
|
formatName: 'XML',
|
|
4319
4442
|
mimeType: 'application/xml',
|
|
4320
4443
|
isValid(value, settings, schema) {
|
|
@@ -4326,17 +4449,17 @@
|
|
|
4326
4449
|
heal(value, settings, schema) {
|
|
4327
4450
|
throw new Error('Not implemented');
|
|
4328
4451
|
},
|
|
4329
|
-
|
|
4452
|
+
subvalueParsers: [],
|
|
4330
4453
|
};
|
|
4331
4454
|
/**
|
|
4332
4455
|
* TODO: [🧠] Maybe propper instance of object
|
|
4333
4456
|
* TODO: [0] Make string_serialized_xml
|
|
4334
4457
|
* TODO: [1] Make type for XML Settings and Schema
|
|
4335
4458
|
* TODO: [🧠] What to use for validating XMLs - XSD,...
|
|
4336
|
-
* TODO: [🍓] In `
|
|
4337
|
-
* TODO: [🍓] In `
|
|
4338
|
-
* TODO: [🍓] In `
|
|
4339
|
-
* TODO: [🍓] In `
|
|
4459
|
+
* TODO: [🍓] In `XmlFormatParser` implement simple `isValid`
|
|
4460
|
+
* TODO: [🍓] In `XmlFormatParser` implement partial `canBeValid`
|
|
4461
|
+
* TODO: [🍓] In `XmlFormatParser` implement `heal
|
|
4462
|
+
* TODO: [🍓] In `XmlFormatParser` implement `subvalueParsers`
|
|
4340
4463
|
* TODO: [🏢] Allow to expect something inside XML and other formats
|
|
4341
4464
|
*/
|
|
4342
4465
|
|
|
@@ -4345,24 +4468,19 @@
|
|
|
4345
4468
|
*
|
|
4346
4469
|
* @private internal index of `...` <- TODO [🏢]
|
|
4347
4470
|
*/
|
|
4348
|
-
const FORMAT_DEFINITIONS = [
|
|
4349
|
-
JsonFormatDefinition,
|
|
4350
|
-
XmlFormatDefinition,
|
|
4351
|
-
TextFormatDefinition,
|
|
4352
|
-
CsvFormatDefinition,
|
|
4353
|
-
];
|
|
4471
|
+
const FORMAT_DEFINITIONS = [JsonFormatParser, XmlFormatParser, TextFormatParser, CsvFormatParser];
|
|
4354
4472
|
/**
|
|
4355
4473
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
4356
4474
|
*/
|
|
4357
4475
|
|
|
4358
4476
|
/**
|
|
4359
|
-
* Maps available parameters to expected parameters
|
|
4477
|
+
* Maps available parameters to expected parameters for a pipeline task.
|
|
4360
4478
|
*
|
|
4361
4479
|
* The strategy is:
|
|
4362
|
-
* 1)
|
|
4363
|
-
* 2)
|
|
4480
|
+
* 1) First, match parameters by name where both available and expected.
|
|
4481
|
+
* 2) Then, if there are unmatched expected and available parameters, map them by order.
|
|
4364
4482
|
*
|
|
4365
|
-
* @throws {PipelineExecutionError}
|
|
4483
|
+
* @throws {PipelineExecutionError} If the number of unmatched expected and available parameters does not match, or mapping is ambiguous.
|
|
4366
4484
|
* @private within the repository used in `createPipelineExecutor`
|
|
4367
4485
|
*/
|
|
4368
4486
|
function mapAvailableToExpectedParameters(options) {
|
|
@@ -4385,7 +4503,7 @@
|
|
|
4385
4503
|
else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) ;
|
|
4386
4504
|
}
|
|
4387
4505
|
if (expectedParameterNames.size === 0) {
|
|
4388
|
-
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent
|
|
4506
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent accidental modifications after mapping
|
|
4389
4507
|
Object.freeze(mappedParameters);
|
|
4390
4508
|
return mappedParameters;
|
|
4391
4509
|
}
|
|
@@ -4416,7 +4534,7 @@
|
|
|
4416
4534
|
for (let i = 0; i < expectedParameterNames.size; i++) {
|
|
4417
4535
|
mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
|
|
4418
4536
|
}
|
|
4419
|
-
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent
|
|
4537
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent accidental modifications after mapping
|
|
4420
4538
|
Object.freeze(mappedParameters);
|
|
4421
4539
|
return mappedParameters;
|
|
4422
4540
|
}
|
|
@@ -4461,10 +4579,12 @@
|
|
|
4461
4579
|
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4462
4580
|
}
|
|
4463
4581
|
if (parameters[parameterName] === undefined) {
|
|
4582
|
+
console.log('!!! templateParameters 1', { parameterName, template, parameters });
|
|
4464
4583
|
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4465
4584
|
}
|
|
4466
4585
|
let parameterValue = parameters[parameterName];
|
|
4467
4586
|
if (parameterValue === undefined) {
|
|
4587
|
+
console.log('!!! templateParameters 2', { parameterName, template, parameters });
|
|
4468
4588
|
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4469
4589
|
}
|
|
4470
4590
|
parameterValue = valueToString(parameterValue);
|
|
@@ -4620,7 +4740,7 @@
|
|
|
4620
4740
|
PAGES: countPages,
|
|
4621
4741
|
};
|
|
4622
4742
|
/**
|
|
4623
|
-
* TODO: [🧠][🤠] This should be probbably as part of `
|
|
4743
|
+
* TODO: [🧠][🤠] This should be probbably as part of `TextFormatParser`
|
|
4624
4744
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
4625
4745
|
*/
|
|
4626
4746
|
|
|
@@ -4648,13 +4768,17 @@
|
|
|
4648
4768
|
}
|
|
4649
4769
|
/**
|
|
4650
4770
|
* TODO: [💝] Unite object for expecting amount and format
|
|
4651
|
-
* TODO: [🧠][🤠] This should be part of `
|
|
4771
|
+
* TODO: [🧠][🤠] This should be part of `TextFormatParser`
|
|
4652
4772
|
* Note: [💝] and [🤠] are interconnected together
|
|
4653
4773
|
*/
|
|
4654
4774
|
|
|
4655
4775
|
/**
|
|
4656
|
-
*
|
|
4776
|
+
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
|
4777
|
+
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
|
4778
|
+
* Throws errors if execution fails after all attempts.
|
|
4657
4779
|
*
|
|
4780
|
+
* @param options - The options for execution, including task, parameters, pipeline, and configuration.
|
|
4781
|
+
* @returns The result string of the executed task.
|
|
4658
4782
|
* @private internal utility of `createPipelineExecutor`
|
|
4659
4783
|
*/
|
|
4660
4784
|
async function executeAttempts(options) {
|
|
@@ -4876,7 +5000,7 @@
|
|
|
4876
5000
|
if (task.format) {
|
|
4877
5001
|
if (task.format === 'JSON') {
|
|
4878
5002
|
if (!isValidJsonString($ongoingTaskResult.$resultString || '')) {
|
|
4879
|
-
// TODO: [🏢] Do more universally via `
|
|
5003
|
+
// TODO: [🏢] Do more universally via `FormatParser`
|
|
4880
5004
|
try {
|
|
4881
5005
|
$ongoingTaskResult.$resultString = extractJsonBlock($ongoingTaskResult.$resultString || '');
|
|
4882
5006
|
}
|
|
@@ -4978,12 +5102,16 @@
|
|
|
4978
5102
|
*/
|
|
4979
5103
|
|
|
4980
5104
|
/**
|
|
4981
|
-
*
|
|
5105
|
+
* Executes a pipeline task that requires mapping or iterating over subvalues of a parameter (such as rows in a CSV).
|
|
5106
|
+
* Handles format and subformat resolution, error handling, and progress reporting.
|
|
5107
|
+
*
|
|
5108
|
+
* @param options - Options for execution, including task details and progress callback.
|
|
5109
|
+
* @returns The result of the subvalue mapping or execution attempts.
|
|
4982
5110
|
*
|
|
4983
5111
|
* @private internal utility of `createPipelineExecutor`
|
|
4984
5112
|
*/
|
|
4985
5113
|
async function executeFormatSubvalues(options) {
|
|
4986
|
-
const { task, jokerParameterNames, parameters, priority, csvSettings, pipelineIdentification } = options;
|
|
5114
|
+
const { task, jokerParameterNames, parameters, priority, csvSettings, onProgress, pipelineIdentification } = options;
|
|
4987
5115
|
if (task.foreach === undefined) {
|
|
4988
5116
|
return /* not await */ executeAttempts(options);
|
|
4989
5117
|
}
|
|
@@ -5014,16 +5142,16 @@
|
|
|
5014
5142
|
${block(pipelineIdentification)}
|
|
5015
5143
|
`));
|
|
5016
5144
|
}
|
|
5017
|
-
const
|
|
5018
|
-
if (
|
|
5145
|
+
const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(task.foreach.subformatName));
|
|
5146
|
+
if (subvalueParser === undefined) {
|
|
5019
5147
|
throw new UnexpectedError(
|
|
5020
5148
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
5021
5149
|
spaceTrim__default["default"]((block) => `
|
|
5022
5150
|
Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
|
|
5023
5151
|
|
|
5024
5152
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
5025
|
-
${block(formatDefinition.
|
|
5026
|
-
.map((
|
|
5153
|
+
${block(formatDefinition.subvalueParsers
|
|
5154
|
+
.map((subvalueParser) => subvalueParser.subvalueName)
|
|
5027
5155
|
.map((subvalueName) => `- ${subvalueName}`)
|
|
5028
5156
|
.join('\n'))}
|
|
5029
5157
|
|
|
@@ -5037,53 +5165,83 @@
|
|
|
5037
5165
|
formatSettings = csvSettings;
|
|
5038
5166
|
// <- TODO: [🤹♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
|
|
5039
5167
|
}
|
|
5040
|
-
const resultString = await
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5168
|
+
const resultString = await subvalueParser.mapValues({
|
|
5169
|
+
value: parameterValue,
|
|
5170
|
+
outputParameterName: task.foreach.outputSubparameterName,
|
|
5171
|
+
settings: formatSettings,
|
|
5172
|
+
onProgress(partialResultString) {
|
|
5173
|
+
return onProgress(Object.freeze({
|
|
5174
|
+
[task.resultingParameterName]: partialResultString,
|
|
5175
|
+
}));
|
|
5176
|
+
},
|
|
5177
|
+
async mapCallback(subparameters, index, length) {
|
|
5178
|
+
let mappedParameters;
|
|
5179
|
+
try {
|
|
5180
|
+
mappedParameters = mapAvailableToExpectedParameters({
|
|
5181
|
+
expectedParameters: Object.fromEntries(task.foreach.inputSubparameterNames.map((subparameterName) => [subparameterName, null])),
|
|
5182
|
+
availableParameters: subparameters,
|
|
5183
|
+
});
|
|
5053
5184
|
}
|
|
5054
|
-
|
|
5055
|
-
|
|
5185
|
+
catch (error) {
|
|
5186
|
+
if (!(error instanceof PipelineExecutionError)) {
|
|
5187
|
+
throw error;
|
|
5188
|
+
}
|
|
5189
|
+
const highLevelError = new PipelineExecutionError(spaceTrim__default["default"]((block) => `
|
|
5190
|
+
${error.message}
|
|
5056
5191
|
|
|
5057
|
-
|
|
5058
|
-
|
|
5192
|
+
This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
5193
|
+
You have probbably passed wrong data to pipeline or wrong data was generated which are processed by FOREACH command
|
|
5059
5194
|
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5195
|
+
${block(pipelineIdentification)}
|
|
5196
|
+
`));
|
|
5197
|
+
if (length > BIG_DATASET_TRESHOLD) {
|
|
5198
|
+
console.error(highLevelError);
|
|
5199
|
+
return FAILED_VALUE_PLACEHOLDER;
|
|
5200
|
+
}
|
|
5201
|
+
throw highLevelError;
|
|
5202
|
+
}
|
|
5203
|
+
const allSubparameters = {
|
|
5204
|
+
...parameters,
|
|
5205
|
+
...mappedParameters,
|
|
5206
|
+
};
|
|
5207
|
+
Object.freeze(allSubparameters);
|
|
5208
|
+
try {
|
|
5209
|
+
const subresultString = await executeAttempts({
|
|
5210
|
+
...options,
|
|
5211
|
+
priority: priority + index,
|
|
5212
|
+
parameters: allSubparameters,
|
|
5213
|
+
pipelineIdentification: spaceTrim__default["default"]((block) => `
|
|
5214
|
+
${block(pipelineIdentification)}
|
|
5215
|
+
Subparameter index: ${index}
|
|
5216
|
+
`),
|
|
5217
|
+
});
|
|
5218
|
+
return subresultString;
|
|
5219
|
+
}
|
|
5220
|
+
catch (error) {
|
|
5221
|
+
if (length > BIG_DATASET_TRESHOLD) {
|
|
5222
|
+
console.error(spaceTrim__default["default"]((block) => `
|
|
5223
|
+
${error.message}
|
|
5224
|
+
|
|
5225
|
+
This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
5226
|
+
|
|
5227
|
+
${block(pipelineIdentification)}
|
|
5228
|
+
`));
|
|
5229
|
+
return FAILED_VALUE_PLACEHOLDER;
|
|
5230
|
+
}
|
|
5231
|
+
throw error;
|
|
5232
|
+
}
|
|
5233
|
+
},
|
|
5080
5234
|
});
|
|
5081
5235
|
return resultString;
|
|
5082
5236
|
}
|
|
5083
5237
|
|
|
5084
5238
|
/**
|
|
5085
|
-
*
|
|
5239
|
+
* Returns the context for a given task, typically used to provide additional information or variables
|
|
5240
|
+
* required for the execution of the task within a pipeline. The context is returned as a string value
|
|
5241
|
+
* that may include markdown formatting.
|
|
5086
5242
|
*
|
|
5243
|
+
* @param task - The task for which the context is being generated. This should be a deeply immutable TaskJson object.
|
|
5244
|
+
* @returns The context as a string, formatted as markdown and parameter value.
|
|
5087
5245
|
* @private internal utility of `createPipelineExecutor`
|
|
5088
5246
|
*/
|
|
5089
5247
|
async function getContextForTask(task) {
|
|
@@ -5091,7 +5249,7 @@
|
|
|
5091
5249
|
}
|
|
5092
5250
|
|
|
5093
5251
|
/**
|
|
5094
|
-
*
|
|
5252
|
+
* Retrieves example values or templates for a given task, used to guide or validate pipeline execution.
|
|
5095
5253
|
*
|
|
5096
5254
|
* @private internal utility of `createPipelineExecutor`
|
|
5097
5255
|
*/
|
|
@@ -5100,25 +5258,127 @@
|
|
|
5100
5258
|
}
|
|
5101
5259
|
|
|
5102
5260
|
/**
|
|
5103
|
-
*
|
|
5261
|
+
* Computes the cosine similarity between two embedding vectors
|
|
5262
|
+
*
|
|
5263
|
+
* Note: This is helping function for RAG (retrieval-augmented generation)
|
|
5264
|
+
*
|
|
5265
|
+
* @param embeddingVector1
|
|
5266
|
+
* @param embeddingVector2
|
|
5267
|
+
* @returns Cosine similarity between the two vectors
|
|
5268
|
+
*
|
|
5269
|
+
* @public exported from `@promptbook/core`
|
|
5270
|
+
*/
|
|
5271
|
+
function computeCosineSimilarity(embeddingVector1, embeddingVector2) {
|
|
5272
|
+
if (embeddingVector1.length !== embeddingVector2.length) {
|
|
5273
|
+
throw new TypeError('Embedding vectors must have the same length');
|
|
5274
|
+
}
|
|
5275
|
+
const dotProduct = embeddingVector1.reduce((sum, value, index) => sum + value * embeddingVector2[index], 0);
|
|
5276
|
+
const magnitude1 = Math.sqrt(embeddingVector1.reduce((sum, value) => sum + value * value, 0));
|
|
5277
|
+
const magnitude2 = Math.sqrt(embeddingVector2.reduce((sum, value) => sum + value * value, 0));
|
|
5278
|
+
return 1 - dotProduct / (magnitude1 * magnitude2);
|
|
5279
|
+
}
|
|
5280
|
+
|
|
5281
|
+
/**
|
|
5282
|
+
*
|
|
5283
|
+
* @param knowledgePieces
|
|
5284
|
+
* @returns
|
|
5285
|
+
*
|
|
5286
|
+
* @private internal utility of `createPipelineExecutor`
|
|
5287
|
+
*/
|
|
5288
|
+
function knowledgePiecesToString(knowledgePieces) {
|
|
5289
|
+
return knowledgePieces
|
|
5290
|
+
.map((knowledgePiece) => {
|
|
5291
|
+
const { content } = knowledgePiece;
|
|
5292
|
+
return `- ${content}`;
|
|
5293
|
+
})
|
|
5294
|
+
.join('\n');
|
|
5295
|
+
// <- TODO: [🧠] Some smarter aggregation of knowledge pieces, single-line vs multi-line vs mixed
|
|
5296
|
+
}
|
|
5297
|
+
|
|
5298
|
+
/**
|
|
5299
|
+
* Retrieves the most relevant knowledge pieces for a given task using embedding-based similarity search.
|
|
5300
|
+
* This is where retrieval-augmented generation (RAG) is performed to enhance the task with external knowledge.
|
|
5104
5301
|
*
|
|
5105
5302
|
* @private internal utility of `createPipelineExecutor`
|
|
5106
5303
|
*/
|
|
5107
5304
|
async function getKnowledgeForTask(options) {
|
|
5108
|
-
const { preparedPipeline, task } = options;
|
|
5109
|
-
|
|
5110
|
-
|
|
5305
|
+
const { tools, preparedPipeline, task, parameters } = options;
|
|
5306
|
+
const firstKnowlegePiece = preparedPipeline.knowledgePieces[0];
|
|
5307
|
+
const firstKnowlegeIndex = firstKnowlegePiece === null || firstKnowlegePiece === void 0 ? void 0 : firstKnowlegePiece.index[0];
|
|
5308
|
+
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model, use also keyword search
|
|
5309
|
+
if (firstKnowlegePiece === undefined || firstKnowlegeIndex === undefined) {
|
|
5310
|
+
return ''; // <- Note: Np knowledge present, return empty string
|
|
5311
|
+
}
|
|
5312
|
+
try {
|
|
5313
|
+
// TODO: [🚐] Make arrayable LLMs -> single LLM DRY
|
|
5314
|
+
const _llms = arrayableToArray(tools.llm);
|
|
5315
|
+
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
5316
|
+
const taskEmbeddingPrompt = {
|
|
5317
|
+
title: 'Knowledge Search',
|
|
5318
|
+
modelRequirements: {
|
|
5319
|
+
modelVariant: 'EMBEDDING',
|
|
5320
|
+
modelName: firstKnowlegeIndex.modelName,
|
|
5321
|
+
},
|
|
5322
|
+
content: task.content,
|
|
5323
|
+
parameters,
|
|
5324
|
+
};
|
|
5325
|
+
const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
|
|
5326
|
+
const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
|
|
5327
|
+
const { index } = knowledgePiece;
|
|
5328
|
+
const knowledgePieceIndex = index.find((i) => i.modelName === firstKnowlegeIndex.modelName);
|
|
5329
|
+
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model
|
|
5330
|
+
if (knowledgePieceIndex === undefined) {
|
|
5331
|
+
return {
|
|
5332
|
+
content: knowledgePiece.content,
|
|
5333
|
+
relevance: 0,
|
|
5334
|
+
};
|
|
5335
|
+
}
|
|
5336
|
+
const relevance = computeCosineSimilarity(knowledgePieceIndex.position, taskEmbeddingResult.content);
|
|
5337
|
+
return {
|
|
5338
|
+
content: knowledgePiece.content,
|
|
5339
|
+
relevance,
|
|
5340
|
+
};
|
|
5341
|
+
});
|
|
5342
|
+
const knowledgePiecesSorted = knowledgePiecesWithRelevance.sort((a, b) => a.relevance - b.relevance);
|
|
5343
|
+
const knowledgePiecesLimited = knowledgePiecesSorted.slice(0, 5);
|
|
5344
|
+
console.log('!!! Embedding', {
|
|
5345
|
+
task,
|
|
5346
|
+
taskEmbeddingPrompt,
|
|
5347
|
+
taskEmbeddingResult,
|
|
5348
|
+
firstKnowlegePiece,
|
|
5349
|
+
firstKnowlegeIndex,
|
|
5350
|
+
knowledgePiecesWithRelevance,
|
|
5351
|
+
knowledgePiecesSorted,
|
|
5352
|
+
knowledgePiecesLimited,
|
|
5353
|
+
});
|
|
5354
|
+
return knowledgePiecesToString(knowledgePiecesLimited);
|
|
5355
|
+
}
|
|
5356
|
+
catch (error) {
|
|
5357
|
+
assertsError(error);
|
|
5358
|
+
console.error('Error in `getKnowledgeForTask`', error);
|
|
5359
|
+
// Note: If the LLM fails, just return all knowledge pieces
|
|
5360
|
+
return knowledgePiecesToString(preparedPipeline.knowledgePieces);
|
|
5361
|
+
}
|
|
5111
5362
|
}
|
|
5363
|
+
/**
|
|
5364
|
+
* TODO: !!!! Verify if this is working
|
|
5365
|
+
* TODO: [♨] Implement Better - use keyword search
|
|
5366
|
+
* TODO: [♨] Examples of values
|
|
5367
|
+
*/
|
|
5112
5368
|
|
|
5113
5369
|
/**
|
|
5114
|
-
*
|
|
5370
|
+
* Retrieves all reserved parameters for a given pipeline task, including context, knowledge, examples, and metadata.
|
|
5371
|
+
* Ensures all reserved parameters are defined and throws if any are missing.
|
|
5372
|
+
*
|
|
5373
|
+
* @param options - Options including tools, pipeline, task, and context.
|
|
5374
|
+
* @returns An object containing all reserved parameters for the task.
|
|
5115
5375
|
*
|
|
5116
5376
|
* @private internal utility of `createPipelineExecutor`
|
|
5117
5377
|
*/
|
|
5118
5378
|
async function getReservedParametersForTask(options) {
|
|
5119
|
-
const { preparedPipeline, task, pipelineIdentification } = options;
|
|
5379
|
+
const { tools, preparedPipeline, task, parameters, pipelineIdentification } = options;
|
|
5120
5380
|
const context = await getContextForTask(); // <- [🏍]
|
|
5121
|
-
const knowledge = await getKnowledgeForTask({ preparedPipeline, task });
|
|
5381
|
+
const knowledge = await getKnowledgeForTask({ tools, preparedPipeline, task, parameters });
|
|
5122
5382
|
const examples = await getExamplesForTask();
|
|
5123
5383
|
const currentDate = new Date().toISOString(); // <- TODO: [🧠][💩] Better
|
|
5124
5384
|
const modelName = RESERVED_PARAMETER_MISSING_VALUE;
|
|
@@ -5144,23 +5404,21 @@
|
|
|
5144
5404
|
}
|
|
5145
5405
|
|
|
5146
5406
|
/**
|
|
5147
|
-
*
|
|
5407
|
+
* Executes a single task within a pipeline, handling parameter validation, error checking, and progress reporting.
|
|
5408
|
+
*
|
|
5409
|
+
* @param options - Options for execution, including the task, pipeline, parameters, and callbacks.
|
|
5410
|
+
* @returns The output parameters produced by the task.
|
|
5148
5411
|
*
|
|
5149
5412
|
* @private internal utility of `createPipelineExecutor`
|
|
5150
5413
|
*/
|
|
5151
5414
|
async function executeTask(options) {
|
|
5152
5415
|
const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSupressed, } = options;
|
|
5153
5416
|
const priority = preparedPipeline.tasks.length - preparedPipeline.tasks.indexOf(currentTask);
|
|
5154
|
-
await onProgress({
|
|
5155
|
-
outputParameters: {
|
|
5156
|
-
[currentTask.resultingParameterName]: '', // <- TODO: [🧠] What is the best value here?
|
|
5157
|
-
},
|
|
5158
|
-
});
|
|
5159
5417
|
// Note: Check consistency of used and dependent parameters which was also done in `validatePipeline`, but it’s good to doublecheck
|
|
5160
5418
|
const usedParameterNames = extractParameterNamesFromTask(currentTask);
|
|
5161
5419
|
const dependentParameterNames = new Set(currentTask.dependentParameterNames);
|
|
5162
5420
|
// TODO: [👩🏾🤝👩🏻] Use here `mapAvailableToExpectedParameters`
|
|
5163
|
-
if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
|
|
5421
|
+
if (difference(union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)), new Set(RESERVED_PARAMETER_NAMES)).size !== 0) {
|
|
5164
5422
|
throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
|
|
5165
5423
|
Dependent parameters are not consistent with used parameters:
|
|
5166
5424
|
|
|
@@ -5180,9 +5438,11 @@
|
|
|
5180
5438
|
}
|
|
5181
5439
|
const definedParameters = Object.freeze({
|
|
5182
5440
|
...(await getReservedParametersForTask({
|
|
5441
|
+
tools,
|
|
5183
5442
|
preparedPipeline,
|
|
5184
5443
|
task: currentTask,
|
|
5185
5444
|
pipelineIdentification,
|
|
5445
|
+
parameters: parametersToPass,
|
|
5186
5446
|
})),
|
|
5187
5447
|
...parametersToPass,
|
|
5188
5448
|
});
|
|
@@ -5228,6 +5488,7 @@
|
|
|
5228
5488
|
preparedPipeline,
|
|
5229
5489
|
tools,
|
|
5230
5490
|
$executionReport,
|
|
5491
|
+
onProgress,
|
|
5231
5492
|
pipelineIdentification,
|
|
5232
5493
|
maxExecutionAttempts,
|
|
5233
5494
|
maxParallelCount,
|
|
@@ -5255,7 +5516,8 @@
|
|
|
5255
5516
|
*/
|
|
5256
5517
|
|
|
5257
5518
|
/**
|
|
5258
|
-
*
|
|
5519
|
+
* Filters and returns only the output parameters from the provided pipeline execution options.
|
|
5520
|
+
* Adds warnings for any expected output parameters that are missing.
|
|
5259
5521
|
*
|
|
5260
5522
|
* @private internal utility of `createPipelineExecutor`
|
|
5261
5523
|
*/
|
|
@@ -5280,9 +5542,12 @@
|
|
|
5280
5542
|
}
|
|
5281
5543
|
|
|
5282
5544
|
/**
|
|
5283
|
-
*
|
|
5545
|
+
* Executes an entire pipeline, resolving tasks in dependency order, handling errors, and reporting progress.
|
|
5284
5546
|
*
|
|
5285
|
-
* Note: This is not a `PipelineExecutor` (which is
|
|
5547
|
+
* Note: This is not a `PipelineExecutor` (which is bound to a single pipeline), but a utility function used by `createPipelineExecutor` to create a `PipelineExecutor`.
|
|
5548
|
+
*
|
|
5549
|
+
* @param options - Options for execution, including input parameters, pipeline, and callbacks.
|
|
5550
|
+
* @returns The result of the pipeline execution, including output parameters, errors, and usage statistics.
|
|
5286
5551
|
*
|
|
5287
5552
|
* @private internal utility of `createPipelineExecutor`
|
|
5288
5553
|
*/
|
|
@@ -5605,6 +5870,22 @@
|
|
|
5605
5870
|
cacheDirname,
|
|
5606
5871
|
intermediateFilesStrategy,
|
|
5607
5872
|
isAutoInstalled,
|
|
5873
|
+
}).catch((error) => {
|
|
5874
|
+
assertsError(error);
|
|
5875
|
+
return exportJson({
|
|
5876
|
+
name: 'pipelineExecutorResult',
|
|
5877
|
+
message: `Unuccessful PipelineExecutorResult, last catch`,
|
|
5878
|
+
order: [],
|
|
5879
|
+
value: {
|
|
5880
|
+
isSuccessful: false,
|
|
5881
|
+
errors: [serializeError(error)],
|
|
5882
|
+
warnings: [],
|
|
5883
|
+
usage: UNCERTAIN_USAGE,
|
|
5884
|
+
executionReport: null,
|
|
5885
|
+
outputParameters: {},
|
|
5886
|
+
preparedPipeline,
|
|
5887
|
+
},
|
|
5888
|
+
});
|
|
5608
5889
|
});
|
|
5609
5890
|
};
|
|
5610
5891
|
const pipelineExecutor = (inputParameters) => createTask({
|
|
@@ -5786,7 +6067,7 @@
|
|
|
5786
6067
|
*/
|
|
5787
6068
|
|
|
5788
6069
|
/**
|
|
5789
|
-
*
|
|
6070
|
+
* Creates a scraper for markdown content.
|
|
5790
6071
|
*
|
|
5791
6072
|
* @public exported from `@promptbook/markdown-utils`
|
|
5792
6073
|
*/
|
|
@@ -5941,7 +6222,7 @@
|
|
|
5941
6222
|
* Note: It can not work with html syntax and comments
|
|
5942
6223
|
*
|
|
5943
6224
|
* @param markdown any valid markdown
|
|
5944
|
-
* @returns
|
|
6225
|
+
* @returns An array of strings, each representing an individual list item found in the markdown
|
|
5945
6226
|
* @public exported from `@promptbook/markdown-utils`
|
|
5946
6227
|
*/
|
|
5947
6228
|
function extractAllListItemsFromMarkdown(markdown) {
|