@promptbook/pdf 0.94.0 → 0.98.0-10
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/README.md +6 -2
- package/esm/index.es.js +229 -168
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/anthropic-claude.index.d.ts +2 -2
- package/esm/typings/src/_packages/cli.index.d.ts +4 -0
- package/esm/typings/src/_packages/core.index.d.ts +2 -0
- package/esm/typings/src/_packages/openai.index.d.ts +10 -0
- package/esm/typings/src/_packages/types.index.d.ts +14 -4
- package/esm/typings/src/_packages/{wizzard.index.d.ts → wizard.index.d.ts} +6 -2
- package/esm/typings/src/cli/cli-commands/prettify.d.ts +1 -1
- package/esm/typings/src/cli/cli-commands/test-command.d.ts +1 -1
- package/esm/typings/src/config.d.ts +1 -1
- package/esm/typings/src/conversion/archive/loadArchive.d.ts +1 -1
- package/esm/typings/src/conversion/archive/saveArchive.d.ts +2 -2
- package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +1 -1
- package/esm/typings/src/dialogs/callback/CallbackInterfaceTools.d.ts +1 -1
- package/esm/typings/src/execution/AbstractTaskResult.d.ts +2 -2
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +8 -0
- package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorOptions.d.ts +1 -1
- package/esm/typings/src/execution/execution-report/ExecutionPromptReportJson.d.ts +2 -2
- package/esm/typings/src/execution/translation/automatic-translate/translateMessages.d.ts +1 -1
- package/esm/typings/src/execution/utils/validatePromptResult.d.ts +53 -0
- package/esm/typings/src/llm-providers/_common/register/{$provideLlmToolsForWizzardOrCli.d.ts → $provideLlmToolsForWizardOrCli.d.ts} +2 -2
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +2 -2
- package/esm/typings/src/llm-providers/anthropic-claude/register-configuration.d.ts +1 -1
- package/esm/typings/src/llm-providers/anthropic-claude/register-constructor.d.ts +1 -1
- package/esm/typings/src/llm-providers/azure-openai/register-configuration.d.ts +1 -1
- package/esm/typings/src/llm-providers/azure-openai/register-constructor.d.ts +1 -1
- package/esm/typings/src/llm-providers/deepseek/register-configuration.d.ts +1 -1
- package/esm/typings/src/llm-providers/deepseek/register-constructor.d.ts +1 -1
- package/esm/typings/src/llm-providers/google/register-configuration.d.ts +1 -1
- package/esm/typings/src/llm-providers/google/register-constructor.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/register-configuration.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/register-constructor.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +2 -2
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +4 -4
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionToolsOptions.d.ts +52 -0
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionToolsOptions.d.ts +3 -5
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +74 -0
- package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +13 -2
- package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +16 -2
- package/esm/typings/src/remote-server/socket-types/listModels/PromptbookServer_ListModels_Request.d.ts +1 -1
- package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/_boilerplate/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +2 -2
- package/esm/typings/src/scrapers/_common/prepareKnowledgePieces.d.ts +1 -1
- package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +1 -1
- package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/document/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/document/register-metadata.d.ts +2 -2
- package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/document-legacy/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/document-legacy/register-metadata.d.ts +2 -2
- package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +1 -4
- package/esm/typings/src/scrapers/markdown/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/markdown/register-metadata.d.ts +2 -2
- package/esm/typings/src/scrapers/markitdown/createMarkitdownScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/markitdown/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/markitdown/register-metadata.d.ts +2 -2
- package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/pdf/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/pdf/register-metadata.d.ts +2 -2
- package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/website/register-constructor.d.ts +1 -1
- package/esm/typings/src/scrapers/website/register-metadata.d.ts +2 -2
- package/esm/typings/src/types/typeAliases.d.ts +1 -1
- package/esm/typings/src/utils/files/listAllFiles.d.ts +1 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/esm/typings/src/{wizzard → wizard}/$getCompiledBook.d.ts +2 -2
- package/esm/typings/src/{wizzard/wizzard.d.ts → wizard/wizard.d.ts} +6 -6
- package/package.json +2 -14
- package/umd/index.umd.js +229 -168
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -26,7 +26,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
26
26
|
* @generated
|
|
27
27
|
* @see https://github.com/webgptorg/promptbook
|
|
28
28
|
*/
|
|
29
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.
|
|
29
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.98.0-10';
|
|
30
30
|
/**
|
|
31
31
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
32
32
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -175,7 +175,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹♂️]
|
|
|
175
175
|
*
|
|
176
176
|
* @public exported from `@promptbook/core`
|
|
177
177
|
*/
|
|
178
|
-
const DEFAULT_MAX_EXECUTION_ATTEMPTS =
|
|
178
|
+
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 7; // <- TODO: [🤹♂️]
|
|
179
179
|
// <- TODO: [🕝] Make also `BOOKS_DIRNAME_ALTERNATIVES`
|
|
180
180
|
// TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
|
|
181
181
|
/**
|
|
@@ -875,7 +875,7 @@ async function getScraperIntermediateSource(source, options) {
|
|
|
875
875
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
876
876
|
*/
|
|
877
877
|
|
|
878
|
-
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"}];
|
|
878
|
+
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 helpful 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 helpful 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"}];
|
|
879
879
|
|
|
880
880
|
/**
|
|
881
881
|
* Checks if value is valid email
|
|
@@ -1032,7 +1032,7 @@ function prettifyMarkdown(content) {
|
|
|
1032
1032
|
});
|
|
1033
1033
|
}
|
|
1034
1034
|
catch (error) {
|
|
1035
|
-
// TODO: [🟥] Detect browser / node and make it
|
|
1035
|
+
// TODO: [🟥] Detect browser / node and make it colorful
|
|
1036
1036
|
console.error('There was an error with prettifying the markdown, using the original as the fallback', {
|
|
1037
1037
|
error,
|
|
1038
1038
|
html: content,
|
|
@@ -1314,7 +1314,7 @@ function checkSerializableAsJson(options) {
|
|
|
1314
1314
|
else {
|
|
1315
1315
|
for (const [subName, subValue] of Object.entries(value)) {
|
|
1316
1316
|
if (subValue === undefined) {
|
|
1317
|
-
// Note: undefined in object is serializable - it is just
|
|
1317
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
1318
1318
|
continue;
|
|
1319
1319
|
}
|
|
1320
1320
|
checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
|
|
@@ -2004,7 +2004,7 @@ class SimplePipelineCollection {
|
|
|
2004
2004
|
|
|
2005
2005
|
Note: You have probably forgotten to run "ptbk make" to update the collection
|
|
2006
2006
|
Note: Pipelines with the same URL are not allowed
|
|
2007
|
-
Only
|
|
2007
|
+
Only exception is when the pipelines are identical
|
|
2008
2008
|
|
|
2009
2009
|
`));
|
|
2010
2010
|
}
|
|
@@ -2401,7 +2401,7 @@ function jsonParse(value) {
|
|
|
2401
2401
|
throw new Error(spaceTrim((block) => `
|
|
2402
2402
|
${block(error.message)}
|
|
2403
2403
|
|
|
2404
|
-
The JSON text:
|
|
2404
|
+
The expected JSON text:
|
|
2405
2405
|
${block(value)}
|
|
2406
2406
|
`));
|
|
2407
2407
|
}
|
|
@@ -2772,12 +2772,12 @@ function countUsage(llmTools) {
|
|
|
2772
2772
|
get title() {
|
|
2773
2773
|
return `${llmTools.title} (+usage)`;
|
|
2774
2774
|
// <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
|
|
2775
|
-
// <- TODO: [🧈][🧠] Does it make
|
|
2775
|
+
// <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
|
|
2776
2776
|
},
|
|
2777
2777
|
get description() {
|
|
2778
2778
|
return `${llmTools.description} (+usage)`;
|
|
2779
2779
|
// <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
|
|
2780
|
-
// <- TODO: [🧈][🧠] Does it make
|
|
2780
|
+
// <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
|
|
2781
2781
|
},
|
|
2782
2782
|
checkConfiguration() {
|
|
2783
2783
|
return /* not await */ llmTools.checkConfiguration();
|
|
@@ -3004,13 +3004,13 @@ function joinLlmExecutionTools(...llmExecutionTools) {
|
|
|
3004
3004
|
|
|
3005
3005
|
Technically, it's not an error, but it's probably not what you want because it does not make sense to use Promptbook without language models.
|
|
3006
3006
|
`);
|
|
3007
|
-
// TODO: [🟥] Detect browser / node and make it
|
|
3007
|
+
// TODO: [🟥] Detect browser / node and make it colorful
|
|
3008
3008
|
console.warn(warningMessage);
|
|
3009
3009
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
3010
3010
|
/*
|
|
3011
3011
|
return {
|
|
3012
3012
|
async listModels() {
|
|
3013
|
-
// TODO: [🟥] Detect browser / node and make it
|
|
3013
|
+
// TODO: [🟥] Detect browser / node and make it colorful
|
|
3014
3014
|
console.warn(
|
|
3015
3015
|
spaceTrim(
|
|
3016
3016
|
(block) => `
|
|
@@ -3286,17 +3286,17 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
3286
3286
|
* Mixes registered scrapers from $scrapersMetadataRegister and $scrapersRegister
|
|
3287
3287
|
*/
|
|
3288
3288
|
const all = [];
|
|
3289
|
-
for (const { packageName, className, mimeTypes, documentationUrl,
|
|
3289
|
+
for (const { packageName, className, mimeTypes, documentationUrl, isAvailableInBrowser, } of $scrapersMetadataRegister.list()) {
|
|
3290
3290
|
if (all.some((item) => item.packageName === packageName && item.className === className)) {
|
|
3291
3291
|
continue;
|
|
3292
3292
|
}
|
|
3293
|
-
all.push({ packageName, className, mimeTypes, documentationUrl,
|
|
3293
|
+
all.push({ packageName, className, mimeTypes, documentationUrl, isAvailableInBrowser });
|
|
3294
3294
|
}
|
|
3295
|
-
for (const { packageName, className, mimeTypes, documentationUrl,
|
|
3295
|
+
for (const { packageName, className, mimeTypes, documentationUrl, isAvailableInBrowser, } of $scrapersRegister.list()) {
|
|
3296
3296
|
if (all.some((item) => item.packageName === packageName && item.className === className)) {
|
|
3297
3297
|
continue;
|
|
3298
3298
|
}
|
|
3299
|
-
all.push({ packageName, className, mimeTypes, documentationUrl,
|
|
3299
|
+
all.push({ packageName, className, mimeTypes, documentationUrl, isAvailableInBrowser });
|
|
3300
3300
|
}
|
|
3301
3301
|
for (const { metadata } of availableScrapers) {
|
|
3302
3302
|
all.push(metadata);
|
|
@@ -3308,8 +3308,8 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
3308
3308
|
const isInstalled = $scrapersRegister
|
|
3309
3309
|
.list()
|
|
3310
3310
|
.find(({ packageName, className }) => metadata.packageName === packageName && metadata.className === className);
|
|
3311
|
-
const
|
|
3312
|
-
return { ...metadata, isMetadataAviailable, isInstalled,
|
|
3311
|
+
const isAvailableInTools = availableScrapers.some(({ metadata: { packageName, className } }) => metadata.packageName === packageName && metadata.className === className);
|
|
3312
|
+
return { ...metadata, isMetadataAviailable, isInstalled, isAvailableInTools };
|
|
3313
3313
|
});
|
|
3314
3314
|
if (metadata.length === 0) {
|
|
3315
3315
|
return spaceTrim(`
|
|
@@ -3322,7 +3322,7 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
3322
3322
|
return spaceTrim((block) => `
|
|
3323
3323
|
Available scrapers are:
|
|
3324
3324
|
${block(metadata
|
|
3325
|
-
.map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes,
|
|
3325
|
+
.map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvailableInBrowser, isAvailableInTools, }, i) => {
|
|
3326
3326
|
const more = [];
|
|
3327
3327
|
// TODO: [🧠] Maybe use `documentationUrl`
|
|
3328
3328
|
if (isMetadataAviailable) {
|
|
@@ -3331,16 +3331,16 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
3331
3331
|
if (isInstalled) {
|
|
3332
3332
|
more.push(`🟩 Installed`);
|
|
3333
3333
|
} // not else
|
|
3334
|
-
if (
|
|
3334
|
+
if (isAvailableInTools) {
|
|
3335
3335
|
more.push(`🟦 Available in tools`);
|
|
3336
3336
|
} // not else
|
|
3337
3337
|
if (!isMetadataAviailable && isInstalled) {
|
|
3338
3338
|
more.push(`When no metadata registered but scraper is installed, it is an unexpected behavior`);
|
|
3339
3339
|
} // not else
|
|
3340
|
-
if (!isInstalled &&
|
|
3340
|
+
if (!isInstalled && isAvailableInTools) {
|
|
3341
3341
|
more.push(`When the scraper is not installed but available in tools, it is an unexpected compatibility behavior`);
|
|
3342
3342
|
} // not else
|
|
3343
|
-
if (!
|
|
3343
|
+
if (!isAvailableInBrowser) {
|
|
3344
3344
|
more.push(`Not usable in browser`);
|
|
3345
3345
|
}
|
|
3346
3346
|
const moreText = more.length === 0 ? '' : ` *(${more.join('; ')})*`;
|
|
@@ -3680,7 +3680,7 @@ TODO: [🧊] This is how it can look in future
|
|
|
3680
3680
|
/**
|
|
3681
3681
|
* TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
|
|
3682
3682
|
* Put `knowledgePieces` into `PrepareKnowledgeOptions`
|
|
3683
|
-
* TODO: [🪂] More than max things can run in parallel by
|
|
3683
|
+
* TODO: [🪂] More than max things can run in parallel by accident [1,[2a,2b,_],[3a,3b,_]]
|
|
3684
3684
|
* TODO: [🧠][❎] Do here proper M:N mapping
|
|
3685
3685
|
* [x] One source can make multiple pieces
|
|
3686
3686
|
* [ ] One piece can have multiple sources
|
|
@@ -4488,6 +4488,77 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
4488
4488
|
return mappedParameters;
|
|
4489
4489
|
}
|
|
4490
4490
|
|
|
4491
|
+
/**
|
|
4492
|
+
* Replaces parameters in template with values from parameters object
|
|
4493
|
+
*
|
|
4494
|
+
* Note: This function is not places strings into string,
|
|
4495
|
+
* It's more complex and can handle this operation specifically for LLM models
|
|
4496
|
+
*
|
|
4497
|
+
* @param template the template with parameters in {curly} braces
|
|
4498
|
+
* @param parameters the object with parameters
|
|
4499
|
+
* @returns the template with replaced parameters
|
|
4500
|
+
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
4501
|
+
* @public exported from `@promptbook/utils`
|
|
4502
|
+
*/
|
|
4503
|
+
function templateParameters(template, parameters) {
|
|
4504
|
+
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
4505
|
+
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
4506
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
4507
|
+
}
|
|
4508
|
+
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
4509
|
+
// TODO: [🍵]
|
|
4510
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
4511
|
+
}
|
|
4512
|
+
}
|
|
4513
|
+
let replacedTemplates = template;
|
|
4514
|
+
let match;
|
|
4515
|
+
let loopLimit = LOOP_LIMIT;
|
|
4516
|
+
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
4517
|
+
.exec(replacedTemplates))) {
|
|
4518
|
+
if (loopLimit-- < 0) {
|
|
4519
|
+
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
4520
|
+
}
|
|
4521
|
+
const precol = match.groups.precol;
|
|
4522
|
+
const parameterName = match.groups.parameterName;
|
|
4523
|
+
if (parameterName === '') {
|
|
4524
|
+
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
4525
|
+
continue;
|
|
4526
|
+
}
|
|
4527
|
+
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
4528
|
+
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4529
|
+
}
|
|
4530
|
+
if (parameters[parameterName] === undefined) {
|
|
4531
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4532
|
+
}
|
|
4533
|
+
let parameterValue = parameters[parameterName];
|
|
4534
|
+
if (parameterValue === undefined) {
|
|
4535
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4536
|
+
}
|
|
4537
|
+
parameterValue = valueToString(parameterValue);
|
|
4538
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
4539
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
4540
|
+
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
4541
|
+
parameterValue = parameterValue
|
|
4542
|
+
.split('\n')
|
|
4543
|
+
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
4544
|
+
.join('\n');
|
|
4545
|
+
}
|
|
4546
|
+
replacedTemplates =
|
|
4547
|
+
replacedTemplates.substring(0, match.index + precol.length) +
|
|
4548
|
+
parameterValue +
|
|
4549
|
+
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
4550
|
+
}
|
|
4551
|
+
// [💫] Check if there are parameters that are not closed properly
|
|
4552
|
+
if (/{\w+$/.test(replacedTemplates)) {
|
|
4553
|
+
throw new PipelineExecutionError('Parameter is not closed');
|
|
4554
|
+
}
|
|
4555
|
+
// [💫] Check if there are parameters that are not opened properly
|
|
4556
|
+
if (/^\w+}/.test(replacedTemplates)) {
|
|
4557
|
+
throw new PipelineExecutionError('Parameter is not opened');
|
|
4558
|
+
}
|
|
4559
|
+
return replacedTemplates;
|
|
4560
|
+
}
|
|
4561
|
+
|
|
4491
4562
|
/**
|
|
4492
4563
|
* Extracts all code blocks from markdown.
|
|
4493
4564
|
*
|
|
@@ -4590,77 +4661,6 @@ function extractJsonBlock(markdown) {
|
|
|
4590
4661
|
* TODO: [🏢] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
4591
4662
|
*/
|
|
4592
4663
|
|
|
4593
|
-
/**
|
|
4594
|
-
* Replaces parameters in template with values from parameters object
|
|
4595
|
-
*
|
|
4596
|
-
* Note: This function is not places strings into string,
|
|
4597
|
-
* It's more complex and can handle this operation specifically for LLM models
|
|
4598
|
-
*
|
|
4599
|
-
* @param template the template with parameters in {curly} braces
|
|
4600
|
-
* @param parameters the object with parameters
|
|
4601
|
-
* @returns the template with replaced parameters
|
|
4602
|
-
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
4603
|
-
* @public exported from `@promptbook/utils`
|
|
4604
|
-
*/
|
|
4605
|
-
function templateParameters(template, parameters) {
|
|
4606
|
-
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
4607
|
-
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
4608
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
4609
|
-
}
|
|
4610
|
-
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
4611
|
-
// TODO: [🍵]
|
|
4612
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
4613
|
-
}
|
|
4614
|
-
}
|
|
4615
|
-
let replacedTemplates = template;
|
|
4616
|
-
let match;
|
|
4617
|
-
let loopLimit = LOOP_LIMIT;
|
|
4618
|
-
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
4619
|
-
.exec(replacedTemplates))) {
|
|
4620
|
-
if (loopLimit-- < 0) {
|
|
4621
|
-
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
4622
|
-
}
|
|
4623
|
-
const precol = match.groups.precol;
|
|
4624
|
-
const parameterName = match.groups.parameterName;
|
|
4625
|
-
if (parameterName === '') {
|
|
4626
|
-
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
4627
|
-
continue;
|
|
4628
|
-
}
|
|
4629
|
-
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
4630
|
-
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
4631
|
-
}
|
|
4632
|
-
if (parameters[parameterName] === undefined) {
|
|
4633
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4634
|
-
}
|
|
4635
|
-
let parameterValue = parameters[parameterName];
|
|
4636
|
-
if (parameterValue === undefined) {
|
|
4637
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
4638
|
-
}
|
|
4639
|
-
parameterValue = valueToString(parameterValue);
|
|
4640
|
-
// Escape curly braces in parameter values to prevent prompt-injection
|
|
4641
|
-
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
4642
|
-
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
4643
|
-
parameterValue = parameterValue
|
|
4644
|
-
.split('\n')
|
|
4645
|
-
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
4646
|
-
.join('\n');
|
|
4647
|
-
}
|
|
4648
|
-
replacedTemplates =
|
|
4649
|
-
replacedTemplates.substring(0, match.index + precol.length) +
|
|
4650
|
-
parameterValue +
|
|
4651
|
-
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
4652
|
-
}
|
|
4653
|
-
// [💫] Check if there are parameters that are not closed properly
|
|
4654
|
-
if (/{\w+$/.test(replacedTemplates)) {
|
|
4655
|
-
throw new PipelineExecutionError('Parameter is not closed');
|
|
4656
|
-
}
|
|
4657
|
-
// [💫] Check if there are parameters that are not opened properly
|
|
4658
|
-
if (/^\w+}/.test(replacedTemplates)) {
|
|
4659
|
-
throw new PipelineExecutionError('Parameter is not opened');
|
|
4660
|
-
}
|
|
4661
|
-
return replacedTemplates;
|
|
4662
|
-
}
|
|
4663
|
-
|
|
4664
4664
|
/**
|
|
4665
4665
|
* Counts number of characters in the text
|
|
4666
4666
|
*
|
|
@@ -4821,6 +4821,68 @@ function checkExpectations(expectations, value) {
|
|
|
4821
4821
|
* Note: [💝] and [🤠] are interconnected together
|
|
4822
4822
|
*/
|
|
4823
4823
|
|
|
4824
|
+
/**
|
|
4825
|
+
* Validates a prompt result against expectations and format requirements.
|
|
4826
|
+
* This function provides a common abstraction for result validation that can be used
|
|
4827
|
+
* by both execution logic and caching logic to ensure consistency.
|
|
4828
|
+
*
|
|
4829
|
+
* @param options - The validation options including result string, expectations, and format
|
|
4830
|
+
* @returns Validation result with processed string and validity status
|
|
4831
|
+
* @private internal function of `createPipelineExecutor` and `cacheLlmTools`
|
|
4832
|
+
*/
|
|
4833
|
+
function validatePromptResult(options) {
|
|
4834
|
+
const { resultString, expectations, format } = options;
|
|
4835
|
+
let processedResultString = resultString;
|
|
4836
|
+
let validationError;
|
|
4837
|
+
try {
|
|
4838
|
+
// TODO: [💝] Unite object for expecting amount and format
|
|
4839
|
+
if (format) {
|
|
4840
|
+
if (format === 'JSON') {
|
|
4841
|
+
if (!isValidJsonString(processedResultString)) {
|
|
4842
|
+
// TODO: [🏢] Do more universally via `FormatParser`
|
|
4843
|
+
try {
|
|
4844
|
+
processedResultString = extractJsonBlock(processedResultString);
|
|
4845
|
+
}
|
|
4846
|
+
catch (error) {
|
|
4847
|
+
keepUnused(error);
|
|
4848
|
+
throw new ExpectError(spaceTrim$1((block) => `
|
|
4849
|
+
Expected valid JSON string
|
|
4850
|
+
|
|
4851
|
+
The expected JSON text:
|
|
4852
|
+
${block(processedResultString)}
|
|
4853
|
+
`));
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4857
|
+
else {
|
|
4858
|
+
throw new UnexpectedError(`Unknown format "${format}"`);
|
|
4859
|
+
}
|
|
4860
|
+
}
|
|
4861
|
+
// TODO: [💝] Unite object for expecting amount and format
|
|
4862
|
+
if (expectations) {
|
|
4863
|
+
checkExpectations(expectations, processedResultString);
|
|
4864
|
+
}
|
|
4865
|
+
return {
|
|
4866
|
+
isValid: true,
|
|
4867
|
+
processedResultString,
|
|
4868
|
+
};
|
|
4869
|
+
}
|
|
4870
|
+
catch (error) {
|
|
4871
|
+
if (error instanceof ExpectError) {
|
|
4872
|
+
validationError = error;
|
|
4873
|
+
}
|
|
4874
|
+
else {
|
|
4875
|
+
// Re-throw non-ExpectError errors (like UnexpectedError)
|
|
4876
|
+
throw error;
|
|
4877
|
+
}
|
|
4878
|
+
return {
|
|
4879
|
+
isValid: false,
|
|
4880
|
+
processedResultString,
|
|
4881
|
+
error: validationError,
|
|
4882
|
+
};
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
|
|
4824
4886
|
/**
|
|
4825
4887
|
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
|
4826
4888
|
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
|
@@ -4838,17 +4900,18 @@ async function executeAttempts(options) {
|
|
|
4838
4900
|
$resultString: null,
|
|
4839
4901
|
$expectError: null,
|
|
4840
4902
|
$scriptPipelineExecutionErrors: [],
|
|
4903
|
+
$failedResults: [], // Track all failed attempts
|
|
4841
4904
|
};
|
|
4842
4905
|
// TODO: [🚐] Make arrayable LLMs -> single LLM DRY
|
|
4843
4906
|
const _llms = arrayableToArray(tools.llm);
|
|
4844
4907
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
4845
|
-
attempts: for (let
|
|
4846
|
-
const isJokerAttempt =
|
|
4847
|
-
const jokerParameterName = jokerParameterNames[jokerParameterNames.length +
|
|
4908
|
+
attempts: for (let attemptIndex = -jokerParameterNames.length; attemptIndex < maxAttempts; attemptIndex++) {
|
|
4909
|
+
const isJokerAttempt = attemptIndex < 0;
|
|
4910
|
+
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
|
|
4848
4911
|
// TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
4849
4912
|
if (isJokerAttempt && !jokerParameterName) {
|
|
4850
4913
|
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
4851
|
-
Joker not found in attempt ${
|
|
4914
|
+
Joker not found in attempt ${attemptIndex}
|
|
4852
4915
|
|
|
4853
4916
|
${block(pipelineIdentification)}
|
|
4854
4917
|
`));
|
|
@@ -5046,35 +5109,18 @@ async function executeAttempts(options) {
|
|
|
5046
5109
|
}
|
|
5047
5110
|
}
|
|
5048
5111
|
// TODO: [💝] Unite object for expecting amount and format
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
throw new ExpectError(spaceTrim$1((block) => `
|
|
5059
|
-
Expected valid JSON string
|
|
5060
|
-
|
|
5061
|
-
${block(
|
|
5062
|
-
/*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ '')}
|
|
5063
|
-
`));
|
|
5064
|
-
}
|
|
5065
|
-
}
|
|
5066
|
-
}
|
|
5067
|
-
else {
|
|
5068
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5069
|
-
Unknown format "${task.format}"
|
|
5070
|
-
|
|
5071
|
-
${block(pipelineIdentification)}
|
|
5072
|
-
`));
|
|
5112
|
+
// Use the common validation function for both format and expectations
|
|
5113
|
+
if (task.format || task.expectations) {
|
|
5114
|
+
const validationResult = validatePromptResult({
|
|
5115
|
+
resultString: $ongoingTaskResult.$resultString || '',
|
|
5116
|
+
expectations: task.expectations,
|
|
5117
|
+
format: task.format,
|
|
5118
|
+
});
|
|
5119
|
+
if (!validationResult.isValid) {
|
|
5120
|
+
throw validationResult.error;
|
|
5073
5121
|
}
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
if (task.expectations) {
|
|
5077
|
-
checkExpectations(task.expectations, $ongoingTaskResult.$resultString || '');
|
|
5122
|
+
// Update the result string in case format processing modified it (e.g., JSON extraction)
|
|
5123
|
+
$ongoingTaskResult.$resultString = validationResult.processedResultString;
|
|
5078
5124
|
}
|
|
5079
5125
|
break attempts;
|
|
5080
5126
|
}
|
|
@@ -5083,6 +5129,15 @@ async function executeAttempts(options) {
|
|
|
5083
5129
|
throw error;
|
|
5084
5130
|
}
|
|
5085
5131
|
$ongoingTaskResult.$expectError = error;
|
|
5132
|
+
// Store each failed attempt
|
|
5133
|
+
if (!Array.isArray($ongoingTaskResult.$failedResults)) {
|
|
5134
|
+
$ongoingTaskResult.$failedResults = [];
|
|
5135
|
+
}
|
|
5136
|
+
$ongoingTaskResult.$failedResults.push({
|
|
5137
|
+
attemptIndex,
|
|
5138
|
+
result: $ongoingTaskResult.$resultString,
|
|
5139
|
+
error: error,
|
|
5140
|
+
});
|
|
5086
5141
|
}
|
|
5087
5142
|
finally {
|
|
5088
5143
|
if (!isJokerAttempt &&
|
|
@@ -5104,35 +5159,41 @@ async function executeAttempts(options) {
|
|
|
5104
5159
|
});
|
|
5105
5160
|
}
|
|
5106
5161
|
}
|
|
5107
|
-
if ($ongoingTaskResult.$expectError !== null &&
|
|
5162
|
+
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
|
5163
|
+
// Note: Create a summary of all failures
|
|
5164
|
+
const failuresSummary = $ongoingTaskResult.$failedResults
|
|
5165
|
+
.map((failure) => spaceTrim$1((block) => {
|
|
5166
|
+
var _a, _b;
|
|
5167
|
+
return `
|
|
5168
|
+
Attempt ${failure.attemptIndex + 1}:
|
|
5169
|
+
Error ${((_a = failure.error) === null || _a === void 0 ? void 0 : _a.name) || ''}:
|
|
5170
|
+
${block((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message.split('\n').map((line) => `> ${line}`).join('\n'))}
|
|
5171
|
+
|
|
5172
|
+
Result:
|
|
5173
|
+
${block(failure.result === null
|
|
5174
|
+
? 'null'
|
|
5175
|
+
: spaceTrim$1(failure.result)
|
|
5176
|
+
.split('\n')
|
|
5177
|
+
.map((line) => `> ${line}`)
|
|
5178
|
+
.join('\n'))}
|
|
5179
|
+
`;
|
|
5180
|
+
}))
|
|
5181
|
+
.join('\n\n---\n\n');
|
|
5108
5182
|
throw new PipelineExecutionError(spaceTrim$1((block) => {
|
|
5109
|
-
var _a
|
|
5183
|
+
var _a;
|
|
5110
5184
|
return `
|
|
5111
5185
|
LLM execution failed ${maxExecutionAttempts}x
|
|
5112
5186
|
|
|
5113
5187
|
${block(pipelineIdentification)}
|
|
5114
5188
|
|
|
5115
|
-
---
|
|
5116
5189
|
The Prompt:
|
|
5117
5190
|
${block((((_a = $ongoingTaskResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
|
|
5118
5191
|
.split('\n')
|
|
5119
5192
|
.map((line) => `> ${line}`)
|
|
5120
5193
|
.join('\n'))}
|
|
5121
5194
|
|
|
5122
|
-
|
|
5123
|
-
${block(
|
|
5124
|
-
.split('\n')
|
|
5125
|
-
.map((line) => `> ${line}`)
|
|
5126
|
-
.join('\n'))}
|
|
5127
|
-
|
|
5128
|
-
Last result:
|
|
5129
|
-
${block($ongoingTaskResult.$resultString === null
|
|
5130
|
-
? 'null'
|
|
5131
|
-
: spaceTrim$1($ongoingTaskResult.$resultString)
|
|
5132
|
-
.split('\n')
|
|
5133
|
-
.map((line) => `> ${line}`)
|
|
5134
|
-
.join('\n'))}
|
|
5135
|
-
---
|
|
5195
|
+
All Failed Attempts:
|
|
5196
|
+
${block(failuresSummary)}
|
|
5136
5197
|
`;
|
|
5137
5198
|
}));
|
|
5138
5199
|
}
|
|
@@ -5352,10 +5413,10 @@ function knowledgePiecesToString(knowledgePieces) {
|
|
|
5352
5413
|
*/
|
|
5353
5414
|
async function getKnowledgeForTask(options) {
|
|
5354
5415
|
const { tools, preparedPipeline, task, parameters } = options;
|
|
5355
|
-
const
|
|
5356
|
-
const
|
|
5416
|
+
const firstKnowledgePiece = preparedPipeline.knowledgePieces[0];
|
|
5417
|
+
const firstKnowledgeIndex = firstKnowledgePiece === null || firstKnowledgePiece === void 0 ? void 0 : firstKnowledgePiece.index[0];
|
|
5357
5418
|
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model, use also keyword search
|
|
5358
|
-
if (
|
|
5419
|
+
if (firstKnowledgePiece === undefined || firstKnowledgeIndex === undefined) {
|
|
5359
5420
|
return ''; // <- Note: Np knowledge present, return empty string
|
|
5360
5421
|
}
|
|
5361
5422
|
try {
|
|
@@ -5366,7 +5427,7 @@ async function getKnowledgeForTask(options) {
|
|
|
5366
5427
|
title: 'Knowledge Search',
|
|
5367
5428
|
modelRequirements: {
|
|
5368
5429
|
modelVariant: 'EMBEDDING',
|
|
5369
|
-
modelName:
|
|
5430
|
+
modelName: firstKnowledgeIndex.modelName,
|
|
5370
5431
|
},
|
|
5371
5432
|
content: task.content,
|
|
5372
5433
|
parameters,
|
|
@@ -5374,7 +5435,7 @@ async function getKnowledgeForTask(options) {
|
|
|
5374
5435
|
const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
|
|
5375
5436
|
const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
|
|
5376
5437
|
const { index } = knowledgePiece;
|
|
5377
|
-
const knowledgePieceIndex = index.find((i) => i.modelName ===
|
|
5438
|
+
const knowledgePieceIndex = index.find((i) => i.modelName === firstKnowledgeIndex.modelName);
|
|
5378
5439
|
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model
|
|
5379
5440
|
if (knowledgePieceIndex === undefined) {
|
|
5380
5441
|
return {
|
|
@@ -5395,8 +5456,8 @@ async function getKnowledgeForTask(options) {
|
|
|
5395
5456
|
task,
|
|
5396
5457
|
taskEmbeddingPrompt,
|
|
5397
5458
|
taskEmbeddingResult,
|
|
5398
|
-
|
|
5399
|
-
|
|
5459
|
+
firstKnowledgePiece,
|
|
5460
|
+
firstKnowledgeIndex,
|
|
5400
5461
|
knowledgePiecesWithRelevance,
|
|
5401
5462
|
knowledgePiecesSorted,
|
|
5402
5463
|
knowledgePiecesLimited,
|
|
@@ -5465,7 +5526,7 @@ async function getReservedParametersForTask(options) {
|
|
|
5465
5526
|
* @private internal utility of `createPipelineExecutor`
|
|
5466
5527
|
*/
|
|
5467
5528
|
async function executeTask(options) {
|
|
5468
|
-
const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled,
|
|
5529
|
+
const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSuppressed, } = options;
|
|
5469
5530
|
const priority = preparedPipeline.tasks.length - preparedPipeline.tasks.indexOf(currentTask);
|
|
5470
5531
|
// Note: Check consistency of used and dependent parameters which was also done in `validatePipeline`, but it’s good to doublecheck
|
|
5471
5532
|
const usedParameterNames = extractParameterNamesFromTask(currentTask);
|
|
@@ -5553,7 +5614,7 @@ async function executeTask(options) {
|
|
|
5553
5614
|
cacheDirname,
|
|
5554
5615
|
intermediateFilesStrategy,
|
|
5555
5616
|
isAutoInstalled,
|
|
5556
|
-
|
|
5617
|
+
isNotPreparedWarningSuppressed,
|
|
5557
5618
|
});
|
|
5558
5619
|
await onProgress({
|
|
5559
5620
|
outputParameters: {
|
|
@@ -5648,7 +5709,7 @@ async function executePipeline(options) {
|
|
|
5648
5709
|
}
|
|
5649
5710
|
return exportJson({
|
|
5650
5711
|
name: `executionReport`,
|
|
5651
|
-
message: `
|
|
5712
|
+
message: `Unsuccessful PipelineExecutorResult (with missing parameter {${parameter.name}}) PipelineExecutorResult`,
|
|
5652
5713
|
order: [],
|
|
5653
5714
|
value: {
|
|
5654
5715
|
isSuccessful: false,
|
|
@@ -5685,7 +5746,7 @@ async function executePipeline(options) {
|
|
|
5685
5746
|
return exportJson({
|
|
5686
5747
|
name: 'pipelineExecutorResult',
|
|
5687
5748
|
message: spaceTrim$1((block) => `
|
|
5688
|
-
|
|
5749
|
+
Unsuccessful PipelineExecutorResult (with extra parameter {${parameter.name}}) PipelineExecutorResult
|
|
5689
5750
|
|
|
5690
5751
|
${block(pipelineIdentification)}
|
|
5691
5752
|
`),
|
|
@@ -5826,7 +5887,7 @@ async function executePipeline(options) {
|
|
|
5826
5887
|
}
|
|
5827
5888
|
return exportJson({
|
|
5828
5889
|
name: 'pipelineExecutorResult',
|
|
5829
|
-
message: `
|
|
5890
|
+
message: `Unsuccessful PipelineExecutorResult (with misc errors) PipelineExecutorResult`,
|
|
5830
5891
|
order: [],
|
|
5831
5892
|
value: {
|
|
5832
5893
|
isSuccessful: false,
|
|
@@ -5877,7 +5938,7 @@ async function executePipeline(options) {
|
|
|
5877
5938
|
* @public exported from `@promptbook/core`
|
|
5878
5939
|
*/
|
|
5879
5940
|
function createPipelineExecutor(options) {
|
|
5880
|
-
const { pipeline, tools, maxExecutionAttempts = DEFAULT_MAX_EXECUTION_ATTEMPTS, maxParallelCount = DEFAULT_MAX_PARALLEL_COUNT, csvSettings = DEFAULT_CSV_SETTINGS, isVerbose = DEFAULT_IS_VERBOSE,
|
|
5941
|
+
const { pipeline, tools, maxExecutionAttempts = DEFAULT_MAX_EXECUTION_ATTEMPTS, maxParallelCount = DEFAULT_MAX_PARALLEL_COUNT, csvSettings = DEFAULT_CSV_SETTINGS, isVerbose = DEFAULT_IS_VERBOSE, isNotPreparedWarningSuppressed = false, cacheDirname = DEFAULT_SCRAPE_CACHE_DIRNAME, intermediateFilesStrategy = DEFAULT_INTERMEDIATE_FILES_STRATEGY, isAutoInstalled = DEFAULT_IS_AUTO_INSTALLED, rootDirname = null, } = options;
|
|
5881
5942
|
validatePipeline(pipeline);
|
|
5882
5943
|
const pipelineIdentification = (() => {
|
|
5883
5944
|
// Note: This is a 😐 implementation of [🚞]
|
|
@@ -5894,7 +5955,7 @@ function createPipelineExecutor(options) {
|
|
|
5894
5955
|
if (isPipelinePrepared(pipeline)) {
|
|
5895
5956
|
preparedPipeline = pipeline;
|
|
5896
5957
|
}
|
|
5897
|
-
else if (
|
|
5958
|
+
else if (isNotPreparedWarningSuppressed !== true) {
|
|
5898
5959
|
console.warn(spaceTrim$1((block) => `
|
|
5899
5960
|
Pipeline is not prepared
|
|
5900
5961
|
|
|
@@ -5927,7 +5988,7 @@ function createPipelineExecutor(options) {
|
|
|
5927
5988
|
maxParallelCount,
|
|
5928
5989
|
csvSettings,
|
|
5929
5990
|
isVerbose,
|
|
5930
|
-
|
|
5991
|
+
isNotPreparedWarningSuppressed,
|
|
5931
5992
|
rootDirname,
|
|
5932
5993
|
cacheDirname,
|
|
5933
5994
|
intermediateFilesStrategy,
|
|
@@ -5936,7 +5997,7 @@ function createPipelineExecutor(options) {
|
|
|
5936
5997
|
assertsError(error);
|
|
5937
5998
|
return exportJson({
|
|
5938
5999
|
name: 'pipelineExecutorResult',
|
|
5939
|
-
message: `
|
|
6000
|
+
message: `Unsuccessful PipelineExecutorResult, last catch`,
|
|
5940
6001
|
order: [],
|
|
5941
6002
|
value: {
|
|
5942
6003
|
isSuccessful: false,
|
|
@@ -5974,7 +6035,7 @@ const markdownScraperMetadata = $deepFreeze({
|
|
|
5974
6035
|
className: 'MarkdownScraper',
|
|
5975
6036
|
mimeTypes: ['text/markdown', 'text/plain'],
|
|
5976
6037
|
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
|
|
5977
|
-
|
|
6038
|
+
isAvailableInBrowser: true,
|
|
5978
6039
|
// <- Note: [🌏] This is the only scraper which makes sense to be available in the browser, for scraping non-markdown sources in the browser use a remote server
|
|
5979
6040
|
requiredExecutables: [],
|
|
5980
6041
|
}); /* <- Note: [🤛] */
|
|
@@ -5984,7 +6045,7 @@ const markdownScraperMetadata = $deepFreeze({
|
|
|
5984
6045
|
* Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
|
|
5985
6046
|
*
|
|
5986
6047
|
* @public exported from `@promptbook/core`
|
|
5987
|
-
* @public exported from `@promptbook/
|
|
6048
|
+
* @public exported from `@promptbook/wizard`
|
|
5988
6049
|
* @public exported from `@promptbook/cli`
|
|
5989
6050
|
*/
|
|
5990
6051
|
$scrapersMetadataRegister.register(markdownScraperMetadata);
|
|
@@ -6083,7 +6144,7 @@ class MarkdownScraper {
|
|
|
6083
6144
|
}
|
|
6084
6145
|
// ---
|
|
6085
6146
|
if (!llmTools.callEmbeddingModel) {
|
|
6086
|
-
// TODO: [🟥] Detect browser / node and make it
|
|
6147
|
+
// TODO: [🟥] Detect browser / node and make it colorful
|
|
6087
6148
|
console.error('No callEmbeddingModel function provided');
|
|
6088
6149
|
}
|
|
6089
6150
|
else {
|
|
@@ -6109,7 +6170,7 @@ class MarkdownScraper {
|
|
|
6109
6170
|
if (!(error instanceof PipelineExecutionError)) {
|
|
6110
6171
|
throw error;
|
|
6111
6172
|
}
|
|
6112
|
-
// TODO: [🟥] Detect browser / node and make it
|
|
6173
|
+
// TODO: [🟥] Detect browser / node and make it colorful
|
|
6113
6174
|
console.error(error, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
|
|
6114
6175
|
}
|
|
6115
6176
|
return {
|
|
@@ -6145,7 +6206,7 @@ const markitdownScraperMetadata = $deepFreeze({
|
|
|
6145
6206
|
// 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
6146
6207
|
],
|
|
6147
6208
|
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
|
|
6148
|
-
|
|
6209
|
+
isAvailableInBrowser: false,
|
|
6149
6210
|
// <- Note: [🌏] Only `MarkdownScraper` makes sense to be available in the browser, for scraping non-markdown sources in the browser use a remote server
|
|
6150
6211
|
requiredExecutables: [],
|
|
6151
6212
|
}); /* <- Note: [🤛] */
|
|
@@ -6155,7 +6216,7 @@ const markitdownScraperMetadata = $deepFreeze({
|
|
|
6155
6216
|
* Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
|
|
6156
6217
|
*
|
|
6157
6218
|
* @public exported from `@promptbook/core`
|
|
6158
|
-
* @public exported from `@promptbook/
|
|
6219
|
+
* @public exported from `@promptbook/wizard`
|
|
6159
6220
|
* @public exported from `@promptbook/cli`
|
|
6160
6221
|
*/
|
|
6161
6222
|
$scrapersMetadataRegister.register(markitdownScraperMetadata);
|
|
@@ -6292,7 +6353,7 @@ const createMarkitdownScraper = Object.assign((tools, options) => {
|
|
|
6292
6353
|
*
|
|
6293
6354
|
* @public exported from `@promptbook/markitdown`
|
|
6294
6355
|
* @public exported from `@promptbook/pdf`
|
|
6295
|
-
* @public exported from `@promptbook/
|
|
6356
|
+
* @public exported from `@promptbook/wizard`
|
|
6296
6357
|
* @public exported from `@promptbook/cli`
|
|
6297
6358
|
*/
|
|
6298
6359
|
const _MarkitdownScraperRegistration = $scrapersRegister.register(createMarkitdownScraper);
|
|
@@ -6313,7 +6374,7 @@ const pdfScraperMetadata = $deepFreeze({
|
|
|
6313
6374
|
className: 'PdfScraper',
|
|
6314
6375
|
mimeTypes: ['application/pdf-DISABLED'],
|
|
6315
6376
|
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
|
|
6316
|
-
|
|
6377
|
+
isAvailableInBrowser: false,
|
|
6317
6378
|
// <- Note: [🌏] Only `MarkdownScraper` makes sense to be available in the browser, for scraping non-markdown sources in the browser use a remote server
|
|
6318
6379
|
requiredExecutables: [],
|
|
6319
6380
|
}); /* <- Note: [🤛] */
|
|
@@ -6323,7 +6384,7 @@ const pdfScraperMetadata = $deepFreeze({
|
|
|
6323
6384
|
* Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
|
|
6324
6385
|
*
|
|
6325
6386
|
* @public exported from `@promptbook/core`
|
|
6326
|
-
* @public exported from `@promptbook/
|
|
6387
|
+
* @public exported from `@promptbook/wizard`
|
|
6327
6388
|
* @public exported from `@promptbook/cli`
|
|
6328
6389
|
*/
|
|
6329
6390
|
$scrapersMetadataRegister.register(pdfScraperMetadata);
|
|
@@ -6398,7 +6459,7 @@ const createPdfScraper = Object.assign((tools, options) => {
|
|
|
6398
6459
|
* Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
|
|
6399
6460
|
*
|
|
6400
6461
|
* @public exported from `@promptbook/pdf`
|
|
6401
|
-
* @public exported from `@promptbook/
|
|
6462
|
+
* @public exported from `@promptbook/wizard`
|
|
6402
6463
|
* @public exported from `@promptbook/cli`
|
|
6403
6464
|
*/
|
|
6404
6465
|
const _PdfScraperRegistration = $scrapersRegister.register(createPdfScraper);
|